From 4de9440f87fbb3f2f31d366e1ef7379e79c41e6b Mon Sep 17 00:00:00 2001 From: Thomas Lamprecht Date: Fri, 22 Apr 2022 10:22:39 +0200 Subject: [PATCH] various stable backports Signed-off-by: Thomas Lamprecht --- ...-map-leaking-on-error-during-receive.patch | 38 +++++ ...rrect-calls-of-log_global_start-stop.patch | 86 ++++++++++ ...acpi-fix-OEM-ID-OEM-Table-ID-padding.patch | 59 +++++++ ...ch-the-virqueue-element-in-case-of-e.patch | 55 +++++++ ...t-user-remove-VirtQ-notifier-restore.patch | 98 ++++++++++++ ...host-user-fix-VirtQ-notifier-cleanup.patch | 149 ++++++++++++++++++ ...ondition-for-iommu_platform-not-supp.patch | 101 ++++++++++++ debian/patches/series | 7 + 8 files changed, 593 insertions(+) create mode 100644 debian/patches/extra/0011-virtio-net-fix-map-leaking-on-error-during-receive.patch create mode 100644 debian/patches/extra/0012-memory-Fix-incorrect-calls-of-log_global_start-stop.patch create mode 100644 debian/patches/extra/0013-acpi-fix-OEM-ID-OEM-Table-ID-padding.patch create mode 100644 debian/patches/extra/0014-vhost-vsock-detach-the-virqueue-element-in-case-of-e.patch create mode 100644 debian/patches/extra/0015-vhost-user-remove-VirtQ-notifier-restore.patch create mode 100644 debian/patches/extra/0016-vhost-user-fix-VirtQ-notifier-cleanup.patch create mode 100644 debian/patches/extra/0017-virtio-fix-the-condition-for-iommu_platform-not-supp.patch diff --git a/debian/patches/extra/0011-virtio-net-fix-map-leaking-on-error-during-receive.patch b/debian/patches/extra/0011-virtio-net-fix-map-leaking-on-error-during-receive.patch new file mode 100644 index 0000000..02e7bab --- /dev/null +++ b/debian/patches/extra/0011-virtio-net-fix-map-leaking-on-error-during-receive.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Tue, 8 Mar 2022 10:42:51 +0800 +Subject: [PATCH] virtio-net: fix map leaking on error during receive + +Commit bedd7e93d0196 ("virtio-net: fix use after unmap/free for sg") +tries to fix the use after free of the sg by caching the virtqueue +elements in an array and unmap them at once after receiving the +packets, But it forgot to unmap the cached elements on error which +will lead to leaking of mapping and other unexpected results. + +Fixing this by detaching the cached elements on error. This addresses +CVE-2022-26353. + +Reported-by: Victor Tom +Cc: qemu-stable@nongnu.org +Fixes: CVE-2022-26353 +Fixes: bedd7e93d0196 ("virtio-net: fix use after unmap/free for sg") +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Jason Wang +(cherry picked from commit abe300d9d894f7138e1af7c8e9c88c04bfe98b37) +Signed-off-by: Thomas Lamprecht +--- + hw/net/virtio-net.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index f2014d5ea0..e1f4748831 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -1862,6 +1862,7 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, + + err: + for (j = 0; j < i; j++) { ++ virtqueue_detach_element(q->rx_vq, elems[j], lens[j]); + g_free(elems[j]); + } + diff --git a/debian/patches/extra/0012-memory-Fix-incorrect-calls-of-log_global_start-stop.patch b/debian/patches/extra/0012-memory-Fix-incorrect-calls-of-log_global_start-stop.patch new file mode 100644 index 0000000..b1e97e5 --- /dev/null +++ b/debian/patches/extra/0012-memory-Fix-incorrect-calls-of-log_global_start-stop.patch @@ -0,0 +1,86 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Tue, 30 Nov 2021 16:00:28 +0800 +Subject: [PATCH] memory: Fix incorrect calls of log_global_start/stop +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We should only call the log_global_start/stop when the global dirty track +bitmask changes from zero<->non-zero. + +No real issue reported for this yet probably because no immediate user to +enable both dirty rate measurement and migration at the same time. However +it'll be good to be prepared for it. + +Fixes: 63b41db4bc ("memory: make global_dirty_tracking a bitmask") +Cc: qemu-stable@nongnu.org +Cc: Hyman Huang +Cc: Paolo Bonzini +Cc: Dr. David Alan Gilbert +Cc: Juan Quintela +Cc: David Hildenbrand +Signed-off-by: Peter Xu +Reviewed-by: David Hildenbrand +Message-Id: <20211130080028.6474-1-peterx@redhat.com> +Signed-off-by: Philippe Mathieu-Daudé +(cherry picked from commit 7b0538ed3a22ce30817f818449d10701fb0821f9) +Signed-off-by: Thomas Lamprecht +--- + softmmu/memory.c | 27 ++++++++++++++------------- + 1 file changed, 14 insertions(+), 13 deletions(-) + +diff --git a/softmmu/memory.c b/softmmu/memory.c +index 7340e19ff5..81d4bf1454 100644 +--- a/softmmu/memory.c ++++ b/softmmu/memory.c +@@ -2773,6 +2773,8 @@ static VMChangeStateEntry *vmstate_change; + + void memory_global_dirty_log_start(unsigned int flags) + { ++ unsigned int old_flags = global_dirty_tracking; ++ + if (vmstate_change) { + qemu_del_vm_change_state_handler(vmstate_change); + vmstate_change = NULL; +@@ -2781,15 +2783,14 @@ void memory_global_dirty_log_start(unsigned int flags) + assert(flags && !(flags & (~GLOBAL_DIRTY_MASK))); + assert(!(global_dirty_tracking & flags)); + global_dirty_tracking |= flags; +- + trace_global_dirty_changed(global_dirty_tracking); + +- MEMORY_LISTENER_CALL_GLOBAL(log_global_start, Forward); +- +- /* Refresh DIRTY_MEMORY_MIGRATION bit. */ +- memory_region_transaction_begin(); +- memory_region_update_pending = true; +- memory_region_transaction_commit(); ++ if (!old_flags) { ++ MEMORY_LISTENER_CALL_GLOBAL(log_global_start, Forward); ++ memory_region_transaction_begin(); ++ memory_region_update_pending = true; ++ memory_region_transaction_commit(); ++ } + } + + static void memory_global_dirty_log_do_stop(unsigned int flags) +@@ -2800,12 +2801,12 @@ static void memory_global_dirty_log_do_stop(unsigned int flags) + + trace_global_dirty_changed(global_dirty_tracking); + +- /* Refresh DIRTY_MEMORY_MIGRATION bit. */ +- memory_region_transaction_begin(); +- memory_region_update_pending = true; +- memory_region_transaction_commit(); +- +- MEMORY_LISTENER_CALL_GLOBAL(log_global_stop, Reverse); ++ if (!global_dirty_tracking) { ++ memory_region_transaction_begin(); ++ memory_region_update_pending = true; ++ memory_region_transaction_commit(); ++ MEMORY_LISTENER_CALL_GLOBAL(log_global_stop, Reverse); ++ } + } + + static void memory_vm_change_state_handler(void *opaque, bool running, diff --git a/debian/patches/extra/0013-acpi-fix-OEM-ID-OEM-Table-ID-padding.patch b/debian/patches/extra/0013-acpi-fix-OEM-ID-OEM-Table-ID-padding.patch new file mode 100644 index 0000000..3696302 --- /dev/null +++ b/debian/patches/extra/0013-acpi-fix-OEM-ID-OEM-Table-ID-padding.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Igor Mammedov +Date: Wed, 12 Jan 2022 08:03:31 -0500 +Subject: [PATCH] acpi: fix OEM ID/OEM Table ID padding + +Commit [2] broke original '\0' padding of OEM ID and OEM Table ID +fields in headers of ACPI tables. While it doesn't have impact on +default values since QEMU uses 6 and 8 characters long values +respectively, it broke usecase where IDs are provided on QEMU CLI. +It shouldn't affect guest (but may cause licensing verification +issues in guest OS). +One of the broken usecases is user supplied SLIC table with IDs +shorter than max possible length, where [2] mangles IDs with extra +spaces in RSDT and FADT tables whereas guest OS expects those to +mirror the respective values of the used SLIC table. + +Fix it by replacing whitespace padding with '\0' padding in +accordance with [1] and expectations of guest OS + +1) ACPI spec, v2.0b + 17.2 AML Grammar Definition + ... + //OEM ID of up to 6 characters. If the OEM ID is + //shorter than 6 characters, it can be terminated + //with a NULL character. + +2) +Fixes: 602b458201 ("acpi: Permit OEM ID and OEM table ID fields to be changed") +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/707 +Reported-by: Dmitry V. Orekhov +Signed-off-by: Igor Mammedov +Cc: qemu-stable@nongnu.org +Message-Id: <20220112130332.1648664-4-imammedo@redhat.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Ani Sinha +Tested-by: Dmitry V. Orekhov dima.orekhov@gmail.com +(cherry picked from commit 748c030f360a940fe0c9382c8ca1649096c3a80d) +Signed-off-by: Thomas Lamprecht +--- + hw/acpi/aml-build.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c +index b3b3310df3..65148d5b9d 100644 +--- a/hw/acpi/aml-build.c ++++ b/hw/acpi/aml-build.c +@@ -1724,9 +1724,9 @@ void acpi_table_begin(AcpiTable *desc, GArray *array) + build_append_int_noprefix(array, 0, 4); /* Length */ + build_append_int_noprefix(array, desc->rev, 1); /* Revision */ + build_append_int_noprefix(array, 0, 1); /* Checksum */ +- build_append_padded_str(array, desc->oem_id, 6, ' '); /* OEMID */ ++ build_append_padded_str(array, desc->oem_id, 6, '\0'); /* OEMID */ + /* OEM Table ID */ +- build_append_padded_str(array, desc->oem_table_id, 8, ' '); ++ build_append_padded_str(array, desc->oem_table_id, 8, '\0'); + build_append_int_noprefix(array, 1, 4); /* OEM Revision */ + g_array_append_vals(array, ACPI_BUILD_APPNAME8, 4); /* Creator ID */ + build_append_int_noprefix(array, 1, 4); /* Creator Revision */ diff --git a/debian/patches/extra/0014-vhost-vsock-detach-the-virqueue-element-in-case-of-e.patch b/debian/patches/extra/0014-vhost-vsock-detach-the-virqueue-element-in-case-of-e.patch new file mode 100644 index 0000000..35482c8 --- /dev/null +++ b/debian/patches/extra/0014-vhost-vsock-detach-the-virqueue-element-in-case-of-e.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Stefano Garzarella +Date: Mon, 28 Feb 2022 10:50:58 +0100 +Subject: [PATCH] vhost-vsock: detach the virqueue element in case of error + +In vhost_vsock_common_send_transport_reset(), if an element popped from +the virtqueue is invalid, we should call virtqueue_detach_element() to +detach it from the virtqueue before freeing its memory. + +Fixes: fc0b9b0e1c ("vhost-vsock: add virtio sockets device") +Fixes: CVE-2022-26354 +Cc: qemu-stable@nongnu.org +Reported-by: VictorV +Signed-off-by: Stefano Garzarella +Message-Id: <20220228095058.27899-1-sgarzare@redhat.com> +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 8d1b247f3748ac4078524130c6d7ae42b6140aaf) +Signed-off-by: Thomas Lamprecht +--- + hw/virtio/vhost-vsock-common.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c +index 3f3771274e..ed706681ac 100644 +--- a/hw/virtio/vhost-vsock-common.c ++++ b/hw/virtio/vhost-vsock-common.c +@@ -153,19 +153,23 @@ static void vhost_vsock_common_send_transport_reset(VHostVSockCommon *vvc) + if (elem->out_num) { + error_report("invalid vhost-vsock event virtqueue element with " + "out buffers"); +- goto out; ++ goto err; + } + + if (iov_from_buf(elem->in_sg, elem->in_num, 0, + &event, sizeof(event)) != sizeof(event)) { + error_report("vhost-vsock event virtqueue element is too short"); +- goto out; ++ goto err; + } + + virtqueue_push(vq, elem, sizeof(event)); + virtio_notify(VIRTIO_DEVICE(vvc), vq); + +-out: ++ g_free(elem); ++ return; ++ ++err: ++ virtqueue_detach_element(vq, elem, 0); + g_free(elem); + } + diff --git a/debian/patches/extra/0015-vhost-user-remove-VirtQ-notifier-restore.patch b/debian/patches/extra/0015-vhost-user-remove-VirtQ-notifier-restore.patch new file mode 100644 index 0000000..d6d0877 --- /dev/null +++ b/debian/patches/extra/0015-vhost-user-remove-VirtQ-notifier-restore.patch @@ -0,0 +1,98 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xueming Li +Date: Mon, 7 Feb 2022 15:19:28 +0800 +Subject: [PATCH] vhost-user: remove VirtQ notifier restore + +Notifier set when vhost-user backend asks qemu to mmap an FD and +offset. When vhost-user backend restart or getting killed, VQ notifier +FD and mmap addresses become invalid. After backend restart, MR contains +the invalid address will be restored and fail on notifier access. + +On the other hand, qemu should munmap the notifier, release underlying +hardware resources to enable backend restart and allocate hardware +notifier resources correctly. + +Qemu shouldn't reference and use resources of disconnected backend. + +This patch removes VQ notifier restore, uses the default vhost-user +notifier to avoid invalid address access. + +After backend restart, the backend should ask qemu to install a hardware +notifier if needed. + +Fixes: 44866521bd6e ("vhost-user: support registering external host notifiers") +Cc: qemu-stable@nongnu.org +Signed-off-by: Xueming Li +Message-Id: <20220207071929.527149-2-xuemingl@nvidia.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit e867144b73b3c5009266b6df07d5ff44acfb82c3) +Signed-off-by: Thomas Lamprecht +--- + hw/virtio/vhost-user.c | 19 +------------------ + include/hw/virtio/vhost-user.h | 1 - + 2 files changed, 1 insertion(+), 19 deletions(-) + +diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c +index bf6e50223c..c671719e9b 100644 +--- a/hw/virtio/vhost-user.c ++++ b/hw/virtio/vhost-user.c +@@ -1143,19 +1143,6 @@ static int vhost_user_set_vring_num(struct vhost_dev *dev, + return vhost_set_vring(dev, VHOST_USER_SET_VRING_NUM, ring); + } + +-static void vhost_user_host_notifier_restore(struct vhost_dev *dev, +- int queue_idx) +-{ +- struct vhost_user *u = dev->opaque; +- VhostUserHostNotifier *n = &u->user->notifier[queue_idx]; +- VirtIODevice *vdev = dev->vdev; +- +- if (n->addr && !n->set) { +- virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, true); +- n->set = true; +- } +-} +- + static void vhost_user_host_notifier_remove(struct vhost_dev *dev, + int queue_idx) + { +@@ -1163,17 +1150,14 @@ static void vhost_user_host_notifier_remove(struct vhost_dev *dev, + VhostUserHostNotifier *n = &u->user->notifier[queue_idx]; + VirtIODevice *vdev = dev->vdev; + +- if (n->addr && n->set) { ++ if (n->addr) { + virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, false); +- n->set = false; + } + } + + static int vhost_user_set_vring_base(struct vhost_dev *dev, + struct vhost_vring_state *ring) + { +- vhost_user_host_notifier_restore(dev, ring->index); +- + return vhost_set_vring(dev, VHOST_USER_SET_VRING_BASE, ring); + } + +@@ -1538,7 +1522,6 @@ static int vhost_user_slave_handle_vring_host_notifier(struct vhost_dev *dev, + } + + n->addr = addr; +- n->set = true; + + return 0; + } +diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h +index a9abca3288..f6012b2078 100644 +--- a/include/hw/virtio/vhost-user.h ++++ b/include/hw/virtio/vhost-user.h +@@ -14,7 +14,6 @@ + typedef struct VhostUserHostNotifier { + MemoryRegion mr; + void *addr; +- bool set; + } VhostUserHostNotifier; + + typedef struct VhostUserState { diff --git a/debian/patches/extra/0016-vhost-user-fix-VirtQ-notifier-cleanup.patch b/debian/patches/extra/0016-vhost-user-fix-VirtQ-notifier-cleanup.patch new file mode 100644 index 0000000..25a9644 --- /dev/null +++ b/debian/patches/extra/0016-vhost-user-fix-VirtQ-notifier-cleanup.patch @@ -0,0 +1,149 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xueming Li +Date: Mon, 7 Feb 2022 15:19:29 +0800 +Subject: [PATCH] vhost-user: fix VirtQ notifier cleanup + +When vhost-user device cleanup, remove notifier MR and munmaps notifier +address in the event-handling thread, VM CPU thread writing the notifier +in concurrent fails with an error of accessing invalid address. It +happens because MR is still being referenced and accessed in another +thread while the underlying notifier mmap address is being freed and +becomes invalid. + +This patch calls RCU and munmap notifiers in the callback after the +memory flatview update finish. + +Fixes: 44866521bd6e ("vhost-user: support registering external host notifiers") +Cc: qemu-stable@nongnu.org +Signed-off-by: Xueming Li +Message-Id: <20220207071929.527149-3-xuemingl@nvidia.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 0b0af4d62f7002b31cd7b2762b26d2fcb76bb2ba) +Signed-off-by: Thomas Lamprecht +--- + hw/virtio/vhost-user.c | 48 ++++++++++++++++++++-------------- + include/hw/virtio/vhost-user.h | 2 ++ + 2 files changed, 31 insertions(+), 19 deletions(-) + +diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c +index c671719e9b..ed5f9a5471 100644 +--- a/hw/virtio/vhost-user.c ++++ b/hw/virtio/vhost-user.c +@@ -25,6 +25,7 @@ + #include "migration/migration.h" + #include "migration/postcopy-ram.h" + #include "trace.h" ++#include "exec/ramblock.h" + + #include + #include +@@ -1143,15 +1144,26 @@ static int vhost_user_set_vring_num(struct vhost_dev *dev, + return vhost_set_vring(dev, VHOST_USER_SET_VRING_NUM, ring); + } + +-static void vhost_user_host_notifier_remove(struct vhost_dev *dev, +- int queue_idx) ++static void vhost_user_host_notifier_free(VhostUserHostNotifier *n) + { +- struct vhost_user *u = dev->opaque; +- VhostUserHostNotifier *n = &u->user->notifier[queue_idx]; +- VirtIODevice *vdev = dev->vdev; ++ assert(n && n->unmap_addr); ++ munmap(n->unmap_addr, qemu_real_host_page_size); ++ n->unmap_addr = NULL; ++} ++ ++static void vhost_user_host_notifier_remove(VhostUserState *user, ++ VirtIODevice *vdev, int queue_idx) ++{ ++ VhostUserHostNotifier *n = &user->notifier[queue_idx]; + + if (n->addr) { +- virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, false); ++ if (vdev) { ++ virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, false); ++ } ++ assert(!n->unmap_addr); ++ n->unmap_addr = n->addr; ++ n->addr = NULL; ++ call_rcu(n, vhost_user_host_notifier_free, rcu); + } + } + +@@ -1190,8 +1202,9 @@ static int vhost_user_get_vring_base(struct vhost_dev *dev, + .payload.state = *ring, + .hdr.size = sizeof(msg.payload.state), + }; ++ struct vhost_user *u = dev->opaque; + +- vhost_user_host_notifier_remove(dev, ring->index); ++ vhost_user_host_notifier_remove(u->user, dev->vdev, ring->index); + + if (vhost_user_write(dev, &msg, NULL, 0) < 0) { + return -1; +@@ -1486,12 +1499,7 @@ static int vhost_user_slave_handle_vring_host_notifier(struct vhost_dev *dev, + + n = &user->notifier[queue_idx]; + +- if (n->addr) { +- virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, false); +- object_unparent(OBJECT(&n->mr)); +- munmap(n->addr, page_size); +- n->addr = NULL; +- } ++ vhost_user_host_notifier_remove(user, vdev, queue_idx); + + if (area->u64 & VHOST_USER_VRING_NOFD_MASK) { + return 0; +@@ -1510,9 +1518,12 @@ static int vhost_user_slave_handle_vring_host_notifier(struct vhost_dev *dev, + + name = g_strdup_printf("vhost-user/host-notifier@%p mmaps[%d]", + user, queue_idx); +- if (!n->mr.ram) /* Don't init again after suspend. */ ++ if (!n->mr.ram) { /* Don't init again after suspend. */ + memory_region_init_ram_device_ptr(&n->mr, OBJECT(vdev), name, + page_size, addr); ++ } else { ++ n->mr.ram_block->host = addr; ++ } + g_free(name); + + if (virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, true)) { +@@ -2460,17 +2471,16 @@ bool vhost_user_init(VhostUserState *user, CharBackend *chr, Error **errp) + void vhost_user_cleanup(VhostUserState *user) + { + int i; ++ VhostUserHostNotifier *n; + + if (!user->chr) { + return; + } + memory_region_transaction_begin(); + for (i = 0; i < VIRTIO_QUEUE_MAX; i++) { +- if (user->notifier[i].addr) { +- object_unparent(OBJECT(&user->notifier[i].mr)); +- munmap(user->notifier[i].addr, qemu_real_host_page_size); +- user->notifier[i].addr = NULL; +- } ++ n = &user->notifier[i]; ++ vhost_user_host_notifier_remove(user, NULL, i); ++ object_unparent(OBJECT(&n->mr)); + } + memory_region_transaction_commit(); + user->chr = NULL; +diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h +index f6012b2078..e44a41bb70 100644 +--- a/include/hw/virtio/vhost-user.h ++++ b/include/hw/virtio/vhost-user.h +@@ -12,8 +12,10 @@ + #include "hw/virtio/virtio.h" + + typedef struct VhostUserHostNotifier { ++ struct rcu_head rcu; + MemoryRegion mr; + void *addr; ++ void *unmap_addr; + } VhostUserHostNotifier; + + typedef struct VhostUserState { diff --git a/debian/patches/extra/0017-virtio-fix-the-condition-for-iommu_platform-not-supp.patch b/debian/patches/extra/0017-virtio-fix-the-condition-for-iommu_platform-not-supp.patch new file mode 100644 index 0000000..a1b56e1 --- /dev/null +++ b/debian/patches/extra/0017-virtio-fix-the-condition-for-iommu_platform-not-supp.patch @@ -0,0 +1,101 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Halil Pasic +Date: Mon, 7 Feb 2022 12:28:57 +0100 +Subject: [PATCH] virtio: fix the condition for iommu_platform not supported + +The commit 04ceb61a40 ("virtio: Fail if iommu_platform is requested, but +unsupported") claims to fail the device hotplug when iommu_platform +is requested, but not supported by the (vhost) device. On the first +glance the condition for detecting that situation looks perfect, but +because a certain peculiarity of virtio_platform it ain't. + +In fact the aforementioned commit introduces a regression. It breaks +virtio-fs support for Secure Execution, and most likely also for AMD SEV +or any other confidential guest scenario that relies encrypted guest +memory. The same also applies to any other vhost device that does not +support _F_ACCESS_PLATFORM. + +The peculiarity is that iommu_platform and _F_ACCESS_PLATFORM collates +"device can not access all of the guest RAM" and "iova != gpa, thus +device needs to translate iova". + +Confidential guest technologies currently rely on the device/hypervisor +offering _F_ACCESS_PLATFORM, so that, after the feature has been +negotiated, the guest grants access to the portions of memory the +device needs to see. So in for confidential guests, generally, +_F_ACCESS_PLATFORM is about the restricted access to memory, but not +about the addresses used being something else than guest physical +addresses. + +This is the very reason for which commit f7ef7e6e3b ("vhost: correctly +turn on VIRTIO_F_IOMMU_PLATFORM") fences _F_ACCESS_PLATFORM from the +vhost device that does not need it, because on the vhost interface it +only means "I/O address translation is needed". + +This patch takes inspiration from f7ef7e6e3b ("vhost: correctly turn on +VIRTIO_F_IOMMU_PLATFORM"), and uses the same condition for detecting the +situation when _F_ACCESS_PLATFORM is requested, but no I/O translation +by the device, and thus no device capability is needed. In this +situation claiming that the device does not support iommu_plattform=on +is counter-productive. So let us stop doing that! + +Signed-off-by: Halil Pasic +Reported-by: Jakob Naucke +Fixes: 04ceb61a40 ("virtio: Fail if iommu_platform is requested, but +unsupported") +Acked-by: Cornelia Huck +Reviewed-by: Daniel Henrique Barboza +Tested-by: Daniel Henrique Barboza +Cc: Kevin Wolf +Cc: qemu-stable@nongnu.org + +Message-Id: <20220207112857.607829-1-pasic@linux.ibm.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Acked-by: Jason Wang +(cherry picked from commit e65902a913bf31ba79a83a3bd3621108b85cf645) +Signed-off-by: Thomas Lamprecht +--- + hw/virtio/virtio-bus.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c +index d23db98c56..0f69d1c742 100644 +--- a/hw/virtio/virtio-bus.c ++++ b/hw/virtio/virtio-bus.c +@@ -48,6 +48,7 @@ void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp) + VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); + bool has_iommu = virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM); ++ bool vdev_has_iommu; + Error *local_err = NULL; + + DPRINTF("%s: plug device.\n", qbus->name); +@@ -69,11 +70,6 @@ void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp) + return; + } + +- if (has_iommu && !virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) { +- error_setg(errp, "iommu_platform=true is not supported by the device"); +- return; +- } +- + if (klass->device_plugged != NULL) { + klass->device_plugged(qbus->parent, &local_err); + } +@@ -82,9 +78,15 @@ void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp) + return; + } + ++ vdev_has_iommu = virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM); + if (klass->get_dma_as != NULL && has_iommu) { + virtio_add_feature(&vdev->host_features, VIRTIO_F_IOMMU_PLATFORM); + vdev->dma_as = klass->get_dma_as(qbus->parent); ++ if (!vdev_has_iommu && vdev->dma_as != &address_space_memory) { ++ error_setg(errp, ++ "iommu_platform=true is not supported by the device"); ++ return; ++ } + } else { + vdev->dma_as = &address_space_memory; + } diff --git a/debian/patches/series b/debian/patches/series index ef3a33a..da79654 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -8,6 +8,13 @@ extra/0007-block-nbd-Delete-reconnect-delay-timer-when-done.patch extra/0008-block-nbd-Assert-there-are-no-timers-when-closed.patch extra/0009-block-nbd-Move-s-ioc-on-AioContext-change.patch extra/0010-acpi-fix-QEMU-crash-when-started-with-SLIC-table.patch +extra/0011-virtio-net-fix-map-leaking-on-error-during-receive.patch +extra/0012-memory-Fix-incorrect-calls-of-log_global_start-stop.patch +extra/0013-acpi-fix-OEM-ID-OEM-Table-ID-padding.patch +extra/0014-vhost-vsock-detach-the-virqueue-element-in-case-of-e.patch +extra/0015-vhost-user-remove-VirtQ-notifier-restore.patch +extra/0016-vhost-user-fix-VirtQ-notifier-cleanup.patch +extra/0017-virtio-fix-the-condition-for-iommu_platform-not-supp.patch bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch