diff --git a/SOURCES/kvm-virtio-Drop-out-of-coroutine-context-in-virtio_load.patch b/SOURCES/kvm-virtio-Drop-out-of-coroutine-context-in-virtio_load.patch new file mode 100644 index 0000000..20a99e5 --- /dev/null +++ b/SOURCES/kvm-virtio-Drop-out-of-coroutine-context-in-virtio_load.patch @@ -0,0 +1,151 @@ +From b99a7e5e5631af3ee806fd0d78d7c7056eb559b5 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 5 Sep 2023 16:50:02 +0200 +Subject: [PATCH] virtio: Drop out of coroutine context in virtio_load() + +RH-Author: Kevin Wolf +RH-MergeRequest: 319: virtio: Drop out of coroutine context in virtio_load() [9.3.0.z 0day] +RH-Jira: RHEL-4453 +RH-Acked-by: Hanna Czenczek +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [1/1] 6ae1d5a464e27bfaf892e093febcaf211a1ff5ec + +virtio_load() as a whole should run in coroutine context because it +reads from the migration stream and we don't want this to block. + +However, it calls virtio_set_features_nocheck() and devices don't +expect their .set_features callback to run in a coroutine and therefore +call functions that may not be called in coroutine context. To fix this, +drop out of coroutine context for calling virtio_set_features_nocheck(). + +Without this fix, the following crash was reported: + + #0 __pthread_kill_implementation (threadid=, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44 + #1 0x00007efc738c05d3 in __pthread_kill_internal (signo=6, threadid=) at pthread_kill.c:78 + #2 0x00007efc73873d26 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 + #3 0x00007efc738477f3 in __GI_abort () at abort.c:79 + #4 0x00007efc7384771b in __assert_fail_base (fmt=0x7efc739dbcb8 "", assertion=assertion@entry=0x560aebfbf5cf "!qemu_in_coroutine()", + file=file@entry=0x560aebfcd2d4 "../block/graph-lock.c", line=line@entry=275, function=function@entry=0x560aebfcd34d "void bdrv_graph_rdlock_main_loop(void)") at assert.c:92 + #5 0x00007efc7386ccc6 in __assert_fail (assertion=0x560aebfbf5cf "!qemu_in_coroutine()", file=0x560aebfcd2d4 "../block/graph-lock.c", line=275, + function=0x560aebfcd34d "void bdrv_graph_rdlock_main_loop(void)") at assert.c:101 + #6 0x0000560aebcd8dd6 in bdrv_register_buf () + #7 0x0000560aeb97ed97 in ram_block_added.llvm () + #8 0x0000560aebb8303f in ram_block_add.llvm () + #9 0x0000560aebb834fa in qemu_ram_alloc_internal.llvm () + #10 0x0000560aebb2ac98 in vfio_region_mmap () + #11 0x0000560aebb3ea0f in vfio_bars_register () + #12 0x0000560aebb3c628 in vfio_realize () + #13 0x0000560aeb90f0c2 in pci_qdev_realize () + #14 0x0000560aebc40305 in device_set_realized () + #15 0x0000560aebc48e07 in property_set_bool.llvm () + #16 0x0000560aebc46582 in object_property_set () + #17 0x0000560aebc4cd58 in object_property_set_qobject () + #18 0x0000560aebc46ba7 in object_property_set_bool () + #19 0x0000560aeb98b3ca in qdev_device_add_from_qdict () + #20 0x0000560aebb1fbaf in virtio_net_set_features () + #21 0x0000560aebb46b51 in virtio_set_features_nocheck () + #22 0x0000560aebb47107 in virtio_load () + #23 0x0000560aeb9ae7ce in vmstate_load_state () + #24 0x0000560aeb9d2ee9 in qemu_loadvm_state_main () + #25 0x0000560aeb9d45e1 in qemu_loadvm_state () + #26 0x0000560aeb9bc32c in process_incoming_migration_co.llvm () + #27 0x0000560aebeace56 in coroutine_trampoline.llvm () + +Cc: qemu-stable@nongnu.org +Buglink: https://issues.redhat.com/browse/RHEL-832 +Signed-off-by: Kevin Wolf +Message-ID: <20230905145002.46391-3-kwolf@redhat.com> +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Kevin Wolf +(cherry picked from commit 92e2e6a867334a990f8d29f07ca34e3162fdd6ec) +Signed-off-by: Kevin Wolf +--- + hw/virtio/virtio.c | 45 ++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 40 insertions(+), 5 deletions(-) + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index 98c4819fcc..0010a9a5f1 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -2825,8 +2825,9 @@ static int virtio_device_put(QEMUFile *f, void *opaque, size_t size, + } + + /* A wrapper for use as a VMState .get function */ +-static int virtio_device_get(QEMUFile *f, void *opaque, size_t size, +- const VMStateField *field) ++static int coroutine_mixed_fn ++virtio_device_get(QEMUFile *f, void *opaque, size_t size, ++ const VMStateField *field) + { + VirtIODevice *vdev = VIRTIO_DEVICE(opaque); + DeviceClass *dc = DEVICE_CLASS(VIRTIO_DEVICE_GET_CLASS(vdev)); +@@ -2853,6 +2854,39 @@ static int virtio_set_features_nocheck(VirtIODevice *vdev, uint64_t val) + return bad ? -1 : 0; + } + ++typedef struct VirtioSetFeaturesNocheckData { ++ Coroutine *co; ++ VirtIODevice *vdev; ++ uint64_t val; ++ int ret; ++} VirtioSetFeaturesNocheckData; ++ ++static void virtio_set_features_nocheck_bh(void *opaque) ++{ ++ VirtioSetFeaturesNocheckData *data = opaque; ++ ++ data->ret = virtio_set_features_nocheck(data->vdev, data->val); ++ aio_co_wake(data->co); ++} ++ ++static int coroutine_mixed_fn ++virtio_set_features_nocheck_maybe_co(VirtIODevice *vdev, uint64_t val) ++{ ++ if (qemu_in_coroutine()) { ++ VirtioSetFeaturesNocheckData data = { ++ .co = qemu_coroutine_self(), ++ .vdev = vdev, ++ .val = val, ++ }; ++ aio_bh_schedule_oneshot(qemu_get_current_aio_context(), ++ virtio_set_features_nocheck_bh, &data); ++ qemu_coroutine_yield(); ++ return data.ret; ++ } else { ++ return virtio_set_features_nocheck(vdev, val); ++ } ++} ++ + int virtio_set_features(VirtIODevice *vdev, uint64_t val) + { + int ret; +@@ -2906,7 +2940,8 @@ size_t virtio_get_config_size(const VirtIOConfigSizeParams *params, + return config_size; + } + +-int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id) ++int coroutine_mixed_fn ++virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id) + { + int i, ret; + int32_t config_len; +@@ -3023,14 +3058,14 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id) + * host_features. + */ + uint64_t features64 = vdev->guest_features; +- if (virtio_set_features_nocheck(vdev, features64) < 0) { ++ if (virtio_set_features_nocheck_maybe_co(vdev, features64) < 0) { + error_report("Features 0x%" PRIx64 " unsupported. " + "Allowed features: 0x%" PRIx64, + features64, vdev->host_features); + return -1; + } + } else { +- if (virtio_set_features_nocheck(vdev, features) < 0) { ++ if (virtio_set_features_nocheck_maybe_co(vdev, features) < 0) { + error_report("Features 0x%x unsupported. " + "Allowed features: 0x%" PRIx64, + features, vdev->host_features); +-- +2.39.3 + diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec index f831cdd..c338d99 100644 --- a/SPECS/qemu-kvm.spec +++ b/SPECS/qemu-kvm.spec @@ -149,7 +149,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \ Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm Version: 8.0.0 -Release: 16%{?rcrel}%{?dist}%{?cc_suffix} +Release: 16%{?rcrel}%{?dist}%{?cc_suffix}.1 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped # Epoch 15 used for RHEL 8 # Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5) @@ -556,6 +556,8 @@ Patch196: kvm-migration-Move-more-initializations-to-migrate_init.patch Patch197: kvm-migration-Add-.save_prepare-handler-to-struct-SaveVM.patch # For bz#2229868 - [vfio migration]Disable postcopy for VM with migratable vfio device Patch198: kvm-vfio-migration-Block-VFIO-migration-with-postcopy-mi.patch +# For RHEL-4453 - qemu-kvm crashed when migrating guest with failover vf [rhel-9.3.0.z] +Patch199: kvm-virtio-Drop-out-of-coroutine-context-in-virtio_load.patch %if %{have_clang} BuildRequires: clang @@ -1617,6 +1619,11 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog +* Mon Oct 09 2023 Miroslav Rezanina - 8.0.0-16.el9_3.1 +- kvm-virtio-Drop-out-of-coroutine-context-in-virtio_load.patch [RHEL-4453] +- Resolves: RHEL-4453 + (qemu-kvm crashed when migrating guest with failover vf [rhel-9.3.0.z]) + * Mon Sep 18 2023 Miroslav Rezanina - 8.0.0-16.el9_3 - kvm-migration-Add-migration-prefix-to-functions-in-targe.patch [bz#2229868] - kvm-migration-Move-more-initializations-to-migrate_init.patch [bz#2229868]