Merge tag 'staging-pull-request' of https://gitlab.com/peterx/qemu into staging

Migration/Memory Pull for 10.2

- PeterX's fix on tls warning for preempt channel when migratino completes
- Arun's series to enhance error reporting for vTPM and migration framework
- PeterX's patch to cleanup multifd send TLS BYE messages
- Juraj's fix on postcopy start state transition when switchover failed
- Yanfei's fix to migrate APIC before VFIO-PCI to avoid irq fallbacks
- Dan's cleanup to simplify error reporting in qemu_fill_buffer()
- PeterM's fix on address space leak when cpu hot plug / unplug
- Steve's cpr-exec wholeset

# -----BEGIN PGP SIGNATURE-----
#
# iIgEABYKADAWIQS5GE3CDMRX2s990ak7X8zN86vXBgUCaN/uIhIccGV0ZXJ4QHJl
# ZGhhdC5jb20ACgkQO1/MzfOr1wZ+mAEA1l2RS9sZS1W3vXQMCNb+Nu8Uo2p+e5Qj
# Uu6J0WVV+XsBANtzGZk2UM/frqlABywW3/ozJ4qBvIPKo758Mr6/lqUH
# =asUv
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 03 Oct 2025 08:39:14 AM PDT
# gpg:                using EDDSA key B9184DC20CC457DACF7DD1A93B5FCCCDF3ABD706
# gpg:                issuer "peterx@redhat.com"
# gpg: Good signature from "Peter Xu <xzpeter@gmail.com>" [unknown]
# gpg:                 aka "Peter Xu <peterx@redhat.com>" [unknown]
# gpg: WARNING: The key's User ID is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: B918 4DC2 0CC4 57DA CF7D  D1A9 3B5F CCCD F3AB D706

* tag 'staging-pull-request' of https://gitlab.com/peterx/qemu: (45 commits)
  migration-test: test cpr-exec
  vfio: cpr-exec mode
  migration: cpr-exec docs
  migration: cpr-exec mode
  migration: cpr-exec save and load
  migration: cpr-exec-command parameter
  oslib: qemu_clear_cloexec
  migration: add cpr_walk_fd
  migration: multi-mode notifier
  migration: simplify error reporting after channel read
  physmem: Destroy all CPU AddressSpaces on unrealize
  memory: New AS helper to serialize destroy+free
  include/system/memory.h: Clarify address_space_destroy() behaviour
  migration: ensure APIC is loaded prior to VFIO PCI devices
  migration: Fix state transition in postcopy_start() error handling
  migration/multifd/tls: Cleanup BYE message processing on sender side
  migration: HMP: Adjust the order of output fields
  migration: Make migration_has_failed() work even for CANCELLING
  io/crypto: Move tls premature termination handling into QIO layer
  backends/tpm: Propagate vTPM error on migration failure
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson
2025-10-04 09:10:58 -07:00
58 changed files with 1352 additions and 410 deletions
+3 -7
View File
@@ -110,6 +110,7 @@
typedef struct QCryptoTLSSession QCryptoTLSSession;
#define QCRYPTO_TLS_SESSION_ERR_BLOCK -2
#define QCRYPTO_TLS_SESSION_PREMATURE_TERMINATION -3
/**
* qcrypto_tls_session_new:
@@ -259,7 +260,6 @@ ssize_t qcrypto_tls_session_write(QCryptoTLSSession *sess,
* @sess: the TLS session object
* @buf: to fill with plain text received
* @len: the length of @buf
* @gracefulTermination: treat premature termination as graceful EOF
* @errp: pointer to hold returned error object
*
* Receive up to @len bytes of data from the remote peer
@@ -267,22 +267,18 @@ ssize_t qcrypto_tls_session_write(QCryptoTLSSession *sess,
* qcrypto_tls_session_set_callbacks(), decrypt it and
* store it in @buf.
*
* If @gracefulTermination is true, then a premature termination
* of the TLS session will be treated as indicating EOF, as
* opposed to an error.
*
* It is an error to call this before
* qcrypto_tls_session_handshake() returns
* QCRYPTO_TLS_HANDSHAKE_COMPLETE
*
* Returns: the number of bytes received,
* or QCRYPTO_TLS_SESSION_ERR_BLOCK if the receive would block,
* or -1 on error.
* or QCRYPTO_TLS_SESSION_PREMATURE_TERMINATION if a premature termination
* is detected, or -1 on error.
*/
ssize_t qcrypto_tls_session_read(QCryptoTLSSession *sess,
char *buf,
size_t len,
bool gracefulTermination,
Error **errp);
/**
+5 -5
View File
@@ -123,13 +123,13 @@ size_t qemu_ram_pagesize_largest(void);
void cpu_address_space_init(CPUState *cpu, int asidx,
const char *prefix, MemoryRegion *mr);
/**
* cpu_address_space_destroy:
* @cpu: CPU for which address space needs to be destroyed
* @asidx: integer index of this address space
* cpu_destroy_address_spaces:
* @cpu: CPU for which address spaces need to be destroyed
*
* Note that with KVM only one address space is supported.
* Destroy all address spaces associated with this CPU; this
* is called as part of unrealizing the CPU.
*/
void cpu_address_space_destroy(CPUState *cpu, int asidx);
void cpu_destroy_address_spaces(CPUState *cpu);
void cpu_physical_memory_rw(hwaddr addr, void *buf,
hwaddr len, bool is_write);
-1
View File
@@ -515,7 +515,6 @@ struct CPUState {
QSIMPLEQ_HEAD(, qemu_work_item) work_list;
struct CPUAddressSpace *cpu_ases;
int cpu_ases_count;
int num_ases;
AddressSpace *as;
MemoryRegion *memory;
+1 -1
View File
@@ -25,7 +25,7 @@ void migrate_start_colo_process(MigrationState *s);
bool migration_in_colo_state(void);
/* loadvm */
int migration_incoming_enable_colo(void);
int migration_incoming_enable_colo(Error **errp);
void migration_incoming_disable_colo(void);
bool migration_incoming_colo_enabled(void);
bool migration_incoming_in_colo_state(void);
+10
View File
@@ -34,6 +34,9 @@ void cpr_resave_fd(const char *name, int id, int fd);
int cpr_open_fd(const char *path, int flags, const char *name, int id,
Error **errp);
typedef bool (*cpr_walk_fd_cb)(int fd);
bool cpr_walk_fd(cpr_walk_fd_cb cb);
MigMode cpr_get_incoming_mode(void);
void cpr_set_incoming_mode(MigMode mode);
bool cpr_is_incoming(void);
@@ -50,4 +53,11 @@ int cpr_get_fd_param(const char *name, const char *fdname, int index,
QEMUFile *cpr_transfer_output(MigrationChannel *channel, Error **errp);
QEMUFile *cpr_transfer_input(MigrationChannel *channel, Error **errp);
void cpr_exec_init(void);
QEMUFile *cpr_exec_output(Error **errp);
QEMUFile *cpr_exec_input(Error **errp);
void cpr_exec_persist_state(QEMUFile *f);
bool cpr_exec_has_state(void);
void cpr_exec_unpersist_state(void);
void cpr_exec_unpreserve_fds(void);
#endif
+12
View File
@@ -95,7 +95,19 @@ void migration_add_notifier(NotifierWithReturn *notify,
void migration_add_notifier_mode(NotifierWithReturn *notify,
MigrationNotifyFunc func, MigMode mode);
/*
* Same as migration_add_notifier, but applies to all @mode in the argument
* list. The list is terminated by -1 or MIG_MODE_ALL. For the latter,
* the notifier is added for all modes.
*/
void migration_add_notifier_modes(NotifierWithReturn *notify,
MigrationNotifyFunc func, MigMode mode, ...);
/*
* Remove a notifier from all modes.
*/
void migration_remove_notifier(NotifierWithReturn *notify);
void migration_file_set_error(int ret, Error *err);
/* True if incoming migration entered POSTCOPY_INCOMING_DISCARD */
+16 -3
View File
@@ -163,6 +163,7 @@ typedef enum {
MIG_PRI_IOMMU, /* Must happen before PCI devices */
MIG_PRI_PCI_BUS, /* Must happen before IOMMU */
MIG_PRI_VIRTIO_MEM, /* Must happen before IOMMU */
MIG_PRI_APIC, /* Must happen before PCI devices */
MIG_PRI_GICV3_ITS, /* Must happen before PCI devices */
MIG_PRI_GICV3, /* Must happen before the ITS */
MIG_PRI_MAX,
@@ -200,14 +201,28 @@ struct VMStateDescription {
* exclusive. For this reason, also early_setup VMSDs are migrated in a
* QEMU_VM_SECTION_FULL section, while save_setup() data is migrated in
* a QEMU_VM_SECTION_START section.
*
* There are duplicate impls of the post/pre save/load hooks.
* New impls should preferentally use 'errp' variants of these
* methods and existing impls incrementally converted.
* The variants without 'errp' are intended to be removed
* once all usage is converted.
*
* For the errp variants,
* Returns: 0 on success,
* <0 on error where -value is an error number from errno.h
*/
bool early_setup;
int version_id;
int minimum_version_id;
MigrationPriority priority;
int (*pre_load)(void *opaque);
int (*pre_load_errp)(void *opaque, Error **errp);
int (*post_load)(void *opaque, int version_id);
int (*post_load_errp)(void *opaque, int version_id, Error **errp);
int (*pre_save)(void *opaque);
int (*pre_save_errp)(void *opaque, Error **errp);
int (*post_save)(void *opaque);
bool (*needed)(void *opaque);
bool (*dev_unplug_pending)(void *opaque);
@@ -1206,10 +1221,8 @@ extern const VMStateInfo vmstate_info_qlist;
}
int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, int version_id);
void *opaque, int version_id, Error **errp);
int vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, JSONWriter *vmdesc);
int vmstate_save_state_with_err(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, JSONWriter *vmdesc, Error **errp);
int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, JSONWriter *vmdesc,
+9
View File
@@ -689,6 +689,15 @@ ssize_t qemu_write_full(int fd, const void *buf, size_t count)
void qemu_set_cloexec(int fd);
bool qemu_set_blocking(int fd, bool block, Error **errp);
/*
* Clear FD_CLOEXEC for a descriptor.
*
* The caller must guarantee that no other fork+exec's occur before the
* exec that is intended to inherit this descriptor, eg by suspending CPUs
* and blocking monitor commands.
*/
void qemu_clear_cloexec(int fd);
/* Return a dynamically allocated directory path that is appropriate for storing
* local state.
*
+21 -3
View File
@@ -2727,14 +2727,32 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name);
/**
* address_space_destroy: destroy an address space
*
* Releases all resources associated with an address space. After an address space
* is destroyed, its root memory region (given by address_space_init()) may be destroyed
* as well.
* Releases all resources associated with an address space. After an
* address space is destroyed, the reference the AddressSpace had to
* its root memory region is dropped, which may result in the
* destruction of that memory region as well.
*
* Note that destruction of the AddressSpace is done via RCU;
* it is therefore not valid to free the memory the AddressSpace
* struct is in until after that RCU callback has completed.
* If you want to g_free() the AddressSpace after destruction you
* can do that with address_space_destroy_free().
*
* @as: address space to be destroyed
*/
void address_space_destroy(AddressSpace *as);
/**
* address_space_destroy_free: destroy an address space and free it
*
* This does the same thing as address_space_destroy(), and then also
* frees (via g_free()) the AddressSpace itself once the destruction
* is complete.
*
* @as: address space to be destroyed
*/
void address_space_destroy_free(AddressSpace *as);
/**
* address_space_remove_listeners: unregister all listeners of an address space
*