mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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:
+21
-19
@@ -819,7 +819,8 @@ static int tpm_emulator_get_state_blobs(TPMEmulator *tpm_emu)
|
||||
static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
|
||||
uint32_t type,
|
||||
TPMSizedBuffer *tsb,
|
||||
uint32_t flags)
|
||||
uint32_t flags,
|
||||
Error **errp)
|
||||
{
|
||||
ssize_t n;
|
||||
ptm_setstate pss;
|
||||
@@ -838,17 +839,18 @@ static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
|
||||
/* write the header only */
|
||||
if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_STATEBLOB, &pss,
|
||||
offsetof(ptm_setstate, u.req.data), 0, 0) < 0) {
|
||||
error_report("tpm-emulator: could not set state blob type %d : %s",
|
||||
type, strerror(errno));
|
||||
error_setg_errno(errp, errno,
|
||||
"tpm-emulator: could not set state blob type %d",
|
||||
type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* now the body */
|
||||
n = qemu_chr_fe_write_all(&tpm_emu->ctrl_chr, tsb->buffer, tsb->size);
|
||||
if (n != tsb->size) {
|
||||
error_report("tpm-emulator: Writing the stateblob (type %d) "
|
||||
"failed; could not write %u bytes, but only %zd",
|
||||
type, tsb->size, n);
|
||||
error_setg(errp, "tpm-emulator: Writing the stateblob (type %d) "
|
||||
"failed; could not write %u bytes, but only %zd",
|
||||
type, tsb->size, n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -856,17 +858,17 @@ static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
|
||||
n = qemu_chr_fe_read_all(&tpm_emu->ctrl_chr,
|
||||
(uint8_t *)&pss, sizeof(pss.u.resp));
|
||||
if (n != sizeof(pss.u.resp)) {
|
||||
error_report("tpm-emulator: Reading response from writing stateblob "
|
||||
"(type %d) failed; expected %zu bytes, got %zd", type,
|
||||
sizeof(pss.u.resp), n);
|
||||
error_setg(errp, "tpm-emulator: Reading response from writing "
|
||||
"stateblob (type %d) failed; expected %zu bytes, "
|
||||
"got %zd", type, sizeof(pss.u.resp), n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tpm_result = be32_to_cpu(pss.u.resp.tpm_result);
|
||||
if (tpm_result != 0) {
|
||||
error_report("tpm-emulator: Setting the stateblob (type %d) failed "
|
||||
"with a TPM error 0x%x %s", type, tpm_result,
|
||||
tpm_emulator_strerror(tpm_result));
|
||||
error_setg(errp, "tpm-emulator: Setting the stateblob (type %d) "
|
||||
"failed with a TPM error 0x%x %s", type, tpm_result,
|
||||
tpm_emulator_strerror(tpm_result));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -880,7 +882,7 @@ static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
|
||||
*
|
||||
* Returns a negative errno code in case of error.
|
||||
*/
|
||||
static int tpm_emulator_set_state_blobs(TPMBackend *tb)
|
||||
static int tpm_emulator_set_state_blobs(TPMBackend *tb, Error **errp)
|
||||
{
|
||||
TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
|
||||
TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;
|
||||
@@ -894,13 +896,13 @@ static int tpm_emulator_set_state_blobs(TPMBackend *tb)
|
||||
|
||||
if (tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_PERMANENT,
|
||||
&state_blobs->permanent,
|
||||
state_blobs->permanent_flags) < 0 ||
|
||||
state_blobs->permanent_flags, errp) < 0 ||
|
||||
tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_VOLATILE,
|
||||
&state_blobs->volatil,
|
||||
state_blobs->volatil_flags) < 0 ||
|
||||
state_blobs->volatil_flags, errp) < 0 ||
|
||||
tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_SAVESTATE,
|
||||
&state_blobs->savestate,
|
||||
state_blobs->savestate_flags) < 0) {
|
||||
state_blobs->savestate_flags, errp) < 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -948,12 +950,12 @@ static void tpm_emulator_vm_state_change(void *opaque, bool running,
|
||||
*
|
||||
* Returns negative errno codes in case of error.
|
||||
*/
|
||||
static int tpm_emulator_post_load(void *opaque, int version_id)
|
||||
static int tpm_emulator_post_load(void *opaque, int version_id, Error **errp)
|
||||
{
|
||||
TPMBackend *tb = opaque;
|
||||
int ret;
|
||||
|
||||
ret = tpm_emulator_set_state_blobs(tb);
|
||||
ret = tpm_emulator_set_state_blobs(tb, errp);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -969,7 +971,7 @@ static const VMStateDescription vmstate_tpm_emulator = {
|
||||
.name = "tpm-emulator",
|
||||
.version_id = 0,
|
||||
.pre_save = tpm_emulator_pre_save,
|
||||
.post_load = tpm_emulator_post_load,
|
||||
.post_load_errp = tpm_emulator_post_load,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_UINT32(state_blobs.permanent_flags, TPMEmulator),
|
||||
VMSTATE_UINT32(state_blobs.permanent.size, TPMEmulator),
|
||||
|
||||
+2
-5
@@ -552,7 +552,6 @@ ssize_t
|
||||
qcrypto_tls_session_read(QCryptoTLSSession *session,
|
||||
char *buf,
|
||||
size_t len,
|
||||
bool gracefulTermination,
|
||||
Error **errp)
|
||||
{
|
||||
ssize_t ret;
|
||||
@@ -570,9 +569,8 @@ qcrypto_tls_session_read(QCryptoTLSSession *session,
|
||||
if (ret < 0) {
|
||||
if (ret == GNUTLS_E_AGAIN) {
|
||||
return QCRYPTO_TLS_SESSION_ERR_BLOCK;
|
||||
} else if ((ret == GNUTLS_E_PREMATURE_TERMINATION) &&
|
||||
gracefulTermination){
|
||||
return 0;
|
||||
} else if (ret == GNUTLS_E_PREMATURE_TERMINATION) {
|
||||
return QCRYPTO_TLS_SESSION_PREMATURE_TERMINATION;
|
||||
} else {
|
||||
if (session->rerr) {
|
||||
error_propagate(errp, session->rerr);
|
||||
@@ -789,7 +787,6 @@ ssize_t
|
||||
qcrypto_tls_session_read(QCryptoTLSSession *sess,
|
||||
char *buf,
|
||||
size_t len,
|
||||
bool gracefulTermination,
|
||||
Error **errp)
|
||||
{
|
||||
error_setg(errp, "TLS requires GNUTLS support");
|
||||
|
||||
@@ -5,7 +5,7 @@ CPR is the umbrella name for a set of migration modes in which the
|
||||
VM is migrated to a new QEMU instance on the same host. It is
|
||||
intended for use when the goal is to update host software components
|
||||
that run the VM, such as QEMU or even the host kernel. At this time,
|
||||
the cpr-reboot and cpr-transfer modes are available.
|
||||
the cpr-reboot, cpr-transfer, and cpr-exec modes are available.
|
||||
|
||||
Because QEMU is restarted on the same host, with access to the same
|
||||
local devices, CPR is allowed in certain cases where normal migration
|
||||
@@ -324,3 +324,113 @@ descriptors from old to new QEMU. In the future, descriptors for
|
||||
vhost, and char devices could be transferred,
|
||||
preserving those devices and their kernel state without interruption,
|
||||
even if they do not explicitly support live migration.
|
||||
|
||||
cpr-exec mode
|
||||
-------------
|
||||
|
||||
In this mode, QEMU stops the VM, writes VM state to the migration
|
||||
URI, and directly exec's a new version of QEMU on the same host,
|
||||
replacing the original process while retaining its PID. Guest RAM is
|
||||
preserved in place, albeit with new virtual addresses. The user
|
||||
completes the migration by specifying the ``-incoming`` option, and
|
||||
by issuing the ``migrate-incoming`` command if necessary; see details
|
||||
below.
|
||||
|
||||
This mode supports VFIO/IOMMUFD devices by preserving device
|
||||
descriptors and hence kernel state across the exec, even for devices
|
||||
that do not support live migration.
|
||||
|
||||
Because the old and new QEMU instances are not active concurrently,
|
||||
the URI cannot be a type that streams data from one instance to the
|
||||
other.
|
||||
|
||||
This mode does not require a channel of type ``cpr``. The information
|
||||
that is passed over that channel for cpr-transfer mode is instead
|
||||
serialized to a memfd, the number of the fd is saved in the
|
||||
QEMU_CPR_EXEC_STATE environment variable during the exec of new QEMU.
|
||||
and new QEMU mmaps the memfd.
|
||||
|
||||
Usage
|
||||
^^^^^
|
||||
|
||||
Arguments for the new QEMU process are taken from the
|
||||
@cpr-exec-command parameter. The first argument should be the
|
||||
path of a new QEMU binary, or a prefix command that exec's the
|
||||
new QEMU binary, and the arguments should include the ''-incoming''
|
||||
option.
|
||||
|
||||
Memory backend objects must have the ``share=on`` attribute.
|
||||
The VM must be started with the ``-machine aux-ram-share=on`` option.
|
||||
|
||||
Outgoing:
|
||||
* Set the migration mode parameter to ``cpr-exec``.
|
||||
* Set the ``cpr-exec-command`` parameter.
|
||||
* Issue the ``migrate`` command. It is recommended that the URI be
|
||||
a ``file`` type, but one can use other types such as ``exec``,
|
||||
provided the command captures all the data from the outgoing side,
|
||||
and provides all the data to the incoming side.
|
||||
|
||||
Incoming:
|
||||
* You do not need to explicitly start new QEMU. It is started as
|
||||
a side effect of the migrate command above.
|
||||
* If the VM was running when the outgoing ``migrate`` command was
|
||||
issued, then QEMU automatically resumes VM execution.
|
||||
|
||||
Example 1: incoming URI
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In these examples, we simply restart the same version of QEMU, but in
|
||||
a real scenario one would set a new QEMU binary path in
|
||||
cpr-exec-command.
|
||||
|
||||
::
|
||||
|
||||
# qemu-kvm -monitor stdio
|
||||
-object memory-backend-memfd,id=ram0,size=4G
|
||||
-machine memory-backend=ram0
|
||||
-machine aux-ram-share=on
|
||||
...
|
||||
|
||||
QEMU 10.2.50 monitor - type 'help' for more information
|
||||
(qemu) info status
|
||||
VM status: running
|
||||
(qemu) migrate_set_parameter mode cpr-exec
|
||||
(qemu) migrate_set_parameter cpr-exec-command qemu-kvm ... -incoming file:vm.state
|
||||
(qemu) migrate -d file:vm.state
|
||||
(qemu) QEMU 10.2.50 monitor - type 'help' for more information
|
||||
(qemu) info status
|
||||
VM status: running
|
||||
|
||||
Example 2: incoming defer
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
::
|
||||
|
||||
# qemu-kvm -monitor stdio
|
||||
-object memory-backend-memfd,id=ram0,size=4G
|
||||
-machine memory-backend=ram0
|
||||
-machine aux-ram-share=on
|
||||
...
|
||||
|
||||
QEMU 10.2.50 monitor - type 'help' for more information
|
||||
(qemu) info status
|
||||
VM status: running
|
||||
(qemu) migrate_set_parameter mode cpr-exec
|
||||
(qemu) migrate_set_parameter cpr-exec-command qemu-kvm ... -incoming defer
|
||||
(qemu) migrate -d file:vm.state
|
||||
(qemu) QEMU 10.2.50 monitor - type 'help' for more information
|
||||
(qemu) info status
|
||||
status: paused (inmigrate)
|
||||
(qemu) migrate_incoming file:vm.state
|
||||
(qemu) info status
|
||||
VM status: running
|
||||
|
||||
Caveats
|
||||
^^^^^^^
|
||||
|
||||
cpr-exec mode may not be used with postcopy, background-snapshot,
|
||||
or COLO.
|
||||
|
||||
cpr-exec mode requires permission to use the exec system call, which
|
||||
is denied by certain sandbox options, such as spawn.
|
||||
|
||||
The guest pause time increases for large guest RAM backed by small pages.
|
||||
|
||||
@@ -444,6 +444,25 @@ The functions to do that are inside a vmstate definition, and are called:
|
||||
This function is called after we save the state of one device
|
||||
(even upon failure, unless the call to pre_save returned an error).
|
||||
|
||||
Following are the errp variants of these functions.
|
||||
|
||||
- ``int (*pre_load_errp)(void *opaque, Error **errp);``
|
||||
|
||||
This function is called before we load the state of one device.
|
||||
|
||||
- ``int (*post_load_errp)(void *opaque, int version_id, Error **errp);``
|
||||
|
||||
This function is called after we load the state of one device.
|
||||
|
||||
- ``int (*pre_save_errp)(void *opaque, Error **errp);``
|
||||
|
||||
This function is called before we save the state of one device.
|
||||
|
||||
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.
|
||||
|
||||
Example: You can look at hpet.c, that uses the first three functions
|
||||
to massage the state that is transferred.
|
||||
|
||||
|
||||
+1
-1
@@ -1009,7 +1009,7 @@ ERST
|
||||
|
||||
{
|
||||
.name = "migrate_set_parameter",
|
||||
.args_type = "parameter:s,value:s",
|
||||
.args_type = "parameter:s,value:S",
|
||||
.params = "parameter value",
|
||||
.help = "Set the parameter for migration",
|
||||
.cmd = hmp_migrate_set_parameter,
|
||||
|
||||
@@ -294,6 +294,7 @@ void cpu_exec_unrealizefn(CPUState *cpu)
|
||||
* accel_cpu_common_unrealize, which may free fields using call_rcu.
|
||||
*/
|
||||
accel_cpu_common_unrealize(cpu);
|
||||
cpu_destroy_address_spaces(cpu);
|
||||
}
|
||||
|
||||
static void cpu_common_initfn(Object *obj)
|
||||
|
||||
@@ -1248,7 +1248,8 @@ static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
|
||||
}
|
||||
qemu_put_be32(f, 0); /* end of list */
|
||||
|
||||
return vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL);
|
||||
return vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL,
|
||||
&error_fatal);
|
||||
}
|
||||
|
||||
static bool virtio_gpu_load_restore_mapping(VirtIOGPU *g,
|
||||
@@ -1347,7 +1348,7 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
|
||||
}
|
||||
|
||||
/* load & apply scanout state */
|
||||
vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1);
|
||||
vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1, &error_fatal);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -379,6 +379,7 @@ static const VMStateDescription vmstate_apic_common = {
|
||||
.pre_load = apic_pre_load,
|
||||
.pre_save = apic_dispatch_pre_save,
|
||||
.post_load = apic_dispatch_post_load,
|
||||
.priority = MIG_PRI_APIC,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_UINT32(apicbase, APICCommonState),
|
||||
VMSTATE_UINT8(id, APICCommonState),
|
||||
|
||||
+3
-2
@@ -926,7 +926,7 @@ void pci_device_save(PCIDevice *s, QEMUFile *f)
|
||||
* This makes us compatible with old devices
|
||||
* which never set or clear this bit. */
|
||||
s->config[PCI_STATUS] &= ~PCI_STATUS_INTERRUPT;
|
||||
vmstate_save_state(f, &vmstate_pci_device, s, NULL);
|
||||
vmstate_save_state(f, &vmstate_pci_device, s, NULL, &error_fatal);
|
||||
/* Restore the interrupt status bit. */
|
||||
pci_update_irq_status(s);
|
||||
}
|
||||
@@ -934,7 +934,8 @@ void pci_device_save(PCIDevice *s, QEMUFile *f)
|
||||
int pci_device_load(PCIDevice *s, QEMUFile *f)
|
||||
{
|
||||
int ret;
|
||||
ret = vmstate_load_state(f, &vmstate_pci_device, s, s->version_id);
|
||||
ret = vmstate_load_state(f, &vmstate_pci_device, s, s->version_id,
|
||||
&error_fatal);
|
||||
/* Restore the interrupt status bit. */
|
||||
pci_update_irq_status(s);
|
||||
return ret;
|
||||
|
||||
@@ -1130,13 +1130,13 @@ static int virtio_ccw_load_queue(DeviceState *d, int n, QEMUFile *f)
|
||||
static void virtio_ccw_save_config(DeviceState *d, QEMUFile *f)
|
||||
{
|
||||
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||
vmstate_save_state(f, &vmstate_virtio_ccw_dev, dev, NULL);
|
||||
vmstate_save_state(f, &vmstate_virtio_ccw_dev, dev, NULL, &error_fatal);
|
||||
}
|
||||
|
||||
static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f)
|
||||
{
|
||||
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||
return vmstate_load_state(f, &vmstate_virtio_ccw_dev, dev, 1);
|
||||
return vmstate_load_state(f, &vmstate_virtio_ccw_dev, dev, 1, &error_fatal);
|
||||
}
|
||||
|
||||
static void virtio_ccw_pre_plugged(DeviceState *d, Error **errp)
|
||||
|
||||
@@ -630,7 +630,7 @@ static void vscsi_save_request(QEMUFile *f, SCSIRequest *sreq)
|
||||
vscsi_req *req = sreq->hba_private;
|
||||
assert(req->active);
|
||||
|
||||
vmstate_save_state(f, &vmstate_spapr_vscsi_req, req, NULL);
|
||||
vmstate_save_state(f, &vmstate_spapr_vscsi_req, req, NULL, &error_fatal);
|
||||
|
||||
trace_spapr_vscsi_save_request(req->qtag, req->cur_desc_num,
|
||||
req->cur_desc_offset);
|
||||
@@ -642,15 +642,17 @@ static void *vscsi_load_request(QEMUFile *f, SCSIRequest *sreq)
|
||||
VSCSIState *s = VIO_SPAPR_VSCSI_DEVICE(bus->qbus.parent);
|
||||
vscsi_req *req;
|
||||
int rc;
|
||||
Error *local_err = NULL;
|
||||
|
||||
assert(sreq->tag < VSCSI_REQ_LIMIT);
|
||||
req = &s->reqs[sreq->tag];
|
||||
assert(!req->active);
|
||||
|
||||
memset(req, 0, sizeof(*req));
|
||||
rc = vmstate_load_state(f, &vmstate_spapr_vscsi_req, req, 1);
|
||||
rc = vmstate_load_state(f, &vmstate_spapr_vscsi_req, req, 1, &local_err);
|
||||
if (rc) {
|
||||
fprintf(stderr, "VSCSI: failed loading request tag#%u\n", sreq->tag);
|
||||
error_report_err(local_err);
|
||||
return NULL;
|
||||
}
|
||||
assert(req->active);
|
||||
|
||||
@@ -972,7 +972,8 @@ static bool vfio_legacy_attach_device(const char *name, VFIODevice *vbasedev,
|
||||
error_setg(&vbasedev->cpr.mdev_blocker,
|
||||
"CPR does not support vfio mdev %s", vbasedev->name);
|
||||
if (migrate_add_blocker_modes(&vbasedev->cpr.mdev_blocker, errp,
|
||||
MIG_MODE_CPR_TRANSFER, -1) < 0) {
|
||||
MIG_MODE_CPR_TRANSFER, MIG_MODE_CPR_EXEC,
|
||||
-1) < 0) {
|
||||
goto hiod_unref_exit;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +159,8 @@ bool vfio_iommufd_cpr_register_iommufd(IOMMUFDBackend *be, Error **errp)
|
||||
|
||||
if (!vfio_cpr_supported(be, cpr_blocker)) {
|
||||
return migrate_add_blocker_modes(cpr_blocker, errp,
|
||||
MIG_MODE_CPR_TRANSFER, -1) == 0;
|
||||
MIG_MODE_CPR_TRANSFER,
|
||||
MIG_MODE_CPR_EXEC, -1) == 0;
|
||||
}
|
||||
|
||||
vmstate_register(NULL, -1, &iommufd_cpr_vmstate, be);
|
||||
|
||||
@@ -179,16 +179,17 @@ bool vfio_legacy_cpr_register_container(VFIOLegacyContainer *container,
|
||||
|
||||
if (!vfio_cpr_supported(container, cpr_blocker)) {
|
||||
return migrate_add_blocker_modes(cpr_blocker, errp,
|
||||
MIG_MODE_CPR_TRANSFER, -1) == 0;
|
||||
MIG_MODE_CPR_TRANSFER,
|
||||
MIG_MODE_CPR_EXEC, -1) == 0;
|
||||
}
|
||||
|
||||
vfio_cpr_add_kvm_notifier();
|
||||
|
||||
vmstate_register(NULL, -1, &vfio_container_vmstate, container);
|
||||
|
||||
migration_add_notifier_mode(&container->cpr.transfer_notifier,
|
||||
vfio_cpr_fail_notifier,
|
||||
MIG_MODE_CPR_TRANSFER);
|
||||
migration_add_notifier_modes(&container->cpr.transfer_notifier,
|
||||
vfio_cpr_fail_notifier,
|
||||
MIG_MODE_CPR_TRANSFER, MIG_MODE_CPR_EXEC, -1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+7
-6
@@ -195,9 +195,10 @@ static int vfio_cpr_kvm_close_notifier(NotifierWithReturn *notifier,
|
||||
void vfio_cpr_add_kvm_notifier(void)
|
||||
{
|
||||
if (!kvm_close_notifier.notify) {
|
||||
migration_add_notifier_mode(&kvm_close_notifier,
|
||||
vfio_cpr_kvm_close_notifier,
|
||||
MIG_MODE_CPR_TRANSFER);
|
||||
migration_add_notifier_modes(&kvm_close_notifier,
|
||||
vfio_cpr_kvm_close_notifier,
|
||||
MIG_MODE_CPR_TRANSFER, MIG_MODE_CPR_EXEC,
|
||||
-1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,9 +283,9 @@ static int vfio_cpr_pci_notifier(NotifierWithReturn *notifier,
|
||||
|
||||
void vfio_cpr_pci_register_device(VFIOPCIDevice *vdev)
|
||||
{
|
||||
migration_add_notifier_mode(&vdev->cpr.transfer_notifier,
|
||||
vfio_cpr_pci_notifier,
|
||||
MIG_MODE_CPR_TRANSFER);
|
||||
migration_add_notifier_modes(&vdev->cpr.transfer_notifier,
|
||||
vfio_cpr_pci_notifier,
|
||||
MIG_MODE_CPR_TRANSFER, MIG_MODE_CPR_EXEC, -1);
|
||||
}
|
||||
|
||||
void vfio_cpr_pci_unregister_device(VFIOPCIDevice *vdev)
|
||||
|
||||
+6
-3
@@ -2821,8 +2821,8 @@ static int vfio_pci_save_config(VFIODevice *vbasedev, QEMUFile *f, Error **errp)
|
||||
{
|
||||
VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev);
|
||||
|
||||
return vmstate_save_state_with_err(f, &vmstate_vfio_pci_config, vdev, NULL,
|
||||
errp);
|
||||
return vmstate_save_state(f, &vmstate_vfio_pci_config, vdev, NULL,
|
||||
errp);
|
||||
}
|
||||
|
||||
static int vfio_pci_load_config(VFIODevice *vbasedev, QEMUFile *f)
|
||||
@@ -2831,13 +2831,16 @@ static int vfio_pci_load_config(VFIODevice *vbasedev, QEMUFile *f)
|
||||
PCIDevice *pdev = PCI_DEVICE(vdev);
|
||||
pcibus_t old_addr[PCI_NUM_REGIONS - 1];
|
||||
int bar, ret;
|
||||
Error *local_err = NULL;
|
||||
|
||||
for (bar = 0; bar < PCI_ROM_SLOT; bar++) {
|
||||
old_addr[bar] = pdev->io_regions[bar].addr;
|
||||
}
|
||||
|
||||
ret = vmstate_load_state(f, &vmstate_vfio_pci_config, vdev, 1);
|
||||
ret = vmstate_load_state(f, &vmstate_vfio_pci_config, vdev, 1,
|
||||
&local_err);
|
||||
if (ret) {
|
||||
error_report_err(local_err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/log.h"
|
||||
#include "trace.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
static bool virtio_mmio_ioeventfd_enabled(DeviceState *d)
|
||||
{
|
||||
@@ -612,14 +613,14 @@ static void virtio_mmio_save_extra_state(DeviceState *opaque, QEMUFile *f)
|
||||
{
|
||||
VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
|
||||
|
||||
vmstate_save_state(f, &vmstate_virtio_mmio, proxy, NULL);
|
||||
vmstate_save_state(f, &vmstate_virtio_mmio, proxy, NULL, &error_fatal);
|
||||
}
|
||||
|
||||
static int virtio_mmio_load_extra_state(DeviceState *opaque, QEMUFile *f)
|
||||
{
|
||||
VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
|
||||
|
||||
return vmstate_load_state(f, &vmstate_virtio_mmio, proxy, 1);
|
||||
return vmstate_load_state(f, &vmstate_virtio_mmio, proxy, 1, &error_fatal);
|
||||
}
|
||||
|
||||
static bool virtio_mmio_has_extra_state(DeviceState *opaque)
|
||||
|
||||
@@ -154,14 +154,14 @@ static void virtio_pci_save_extra_state(DeviceState *d, QEMUFile *f)
|
||||
{
|
||||
VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
|
||||
|
||||
vmstate_save_state(f, &vmstate_virtio_pci, proxy, NULL);
|
||||
vmstate_save_state(f, &vmstate_virtio_pci, proxy, NULL, &error_fatal);
|
||||
}
|
||||
|
||||
static int virtio_pci_load_extra_state(DeviceState *d, QEMUFile *f)
|
||||
{
|
||||
VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
|
||||
|
||||
return vmstate_load_state(f, &vmstate_virtio_pci, proxy, 1);
|
||||
return vmstate_load_state(f, &vmstate_virtio_pci, proxy, 1, &error_fatal);
|
||||
}
|
||||
|
||||
static void virtio_pci_save_queue(DeviceState *d, int n, QEMUFile *f)
|
||||
|
||||
+9
-4
@@ -2992,6 +2992,7 @@ int virtio_save(VirtIODevice *vdev, QEMUFile *f)
|
||||
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
|
||||
uint32_t guest_features_lo = (vdev->guest_features & 0xffffffff);
|
||||
int i;
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (k->save_config) {
|
||||
k->save_config(qbus->parent, f);
|
||||
@@ -3035,14 +3036,15 @@ int virtio_save(VirtIODevice *vdev, QEMUFile *f)
|
||||
}
|
||||
|
||||
if (vdc->vmsd) {
|
||||
int ret = vmstate_save_state(f, vdc->vmsd, vdev, NULL);
|
||||
int ret = vmstate_save_state(f, vdc->vmsd, vdev, NULL, &local_err);
|
||||
if (ret) {
|
||||
error_report_err(local_err);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Subsections */
|
||||
return vmstate_save_state(f, &vmstate_virtio, vdev, NULL);
|
||||
return vmstate_save_state(f, &vmstate_virtio, vdev, NULL, &error_fatal);
|
||||
}
|
||||
|
||||
/* A wrapper for use as a VMState .put function */
|
||||
@@ -3235,6 +3237,7 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
|
||||
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
|
||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
||||
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
|
||||
Error *local_err = NULL;
|
||||
|
||||
/*
|
||||
* We poison the endianness to ensure it does not get used before
|
||||
@@ -3327,15 +3330,17 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
|
||||
}
|
||||
|
||||
if (vdc->vmsd) {
|
||||
ret = vmstate_load_state(f, vdc->vmsd, vdev, version_id);
|
||||
ret = vmstate_load_state(f, vdc->vmsd, vdev, version_id, &local_err);
|
||||
if (ret) {
|
||||
error_report_err(local_err);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Subsections */
|
||||
ret = vmstate_load_state(f, &vmstate_virtio, vdev, 1);
|
||||
ret = vmstate_load_state(f, &vmstate_virtio, vdev, 1, &local_err);
|
||||
if (ret) {
|
||||
error_report_err(local_err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user