diff options
author | V3n3RiX <venerix@koprulu.sector> | 2022-06-29 12:04:12 +0100 |
---|---|---|
committer | V3n3RiX <venerix@koprulu.sector> | 2022-06-29 12:04:12 +0100 |
commit | 0f558761aa2dee1017b4751e4017205e015a9560 (patch) | |
tree | 037df795519468a25d9362b4e95cdaeb84eb1cf9 /app-emulation/qemu/files | |
parent | 752d6256e5204b958b0ef7905675a940b5e9172f (diff) |
gentoo resync : 29.12.2022
Diffstat (limited to 'app-emulation/qemu/files')
5 files changed, 276 insertions, 268 deletions
diff --git a/app-emulation/qemu/files/qemu-6.2.0-also-build-virtfs-proxy-helper.patch b/app-emulation/qemu/files/qemu-6.2.0-also-build-virtfs-proxy-helper.patch deleted file mode 100644 index af220802069c..000000000000 --- a/app-emulation/qemu/files/qemu-6.2.0-also-build-virtfs-proxy-helper.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 42e53a0aadb76dfa7c11cd3b14eb4a41efba9bbe Mon Sep 17 00:00:00 2001 -From: Matthias Maier <tamiko@43-1.org> -Date: Tue, 11 Jan 2022 07:20:31 -0600 -Subject: [PATCH] also build virtfs-proxy-helper - -The Gentoo ebuild splits the qemu build into a softmmu, user and tool -phase in order to be able to build and link some of the qemu emulators -statically. This unfortunately has the consequence that we never -configure with "have_virtfs" and "have_tools" at the same time. - -As a workaround, simply build the virtfs userland unconditionally. After -all, it is a tiny executable ---- - meson.build | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/meson.build b/meson.build -index fbe856700..d6918b04c 100644 ---- a/meson.build -+++ b/meson.build -@@ -1390,7 +1390,7 @@ have_virtfs = (targetos == 'linux' and - libattr.found() and - libcap_ng.found()) - --have_virtfs_proxy_helper = have_virtfs and have_tools -+have_virtfs_proxy_helper = have_tools and libcap_ng.found() - - - - if get_option('virtfs').enabled() - if not have_virtfs --- -2.34.1 - diff --git a/app-emulation/qemu/files/qemu-6.2.0-glibc-2.35-rseq-seccomp-virtiofsd.patch b/app-emulation/qemu/files/qemu-6.2.0-glibc-2.35-rseq-seccomp-virtiofsd.patch deleted file mode 100644 index 156d94b0f57e..000000000000 --- a/app-emulation/qemu/files/qemu-6.2.0-glibc-2.35-rseq-seccomp-virtiofsd.patch +++ /dev/null @@ -1,61 +0,0 @@ -https://gitlab.com/qemu/qemu/-/commit/7b223e38603de3a75602e14914d26f9d4baf52eb.patch -https://bugs.gentoo.org/836300 - -From 7b223e38603de3a75602e14914d26f9d4baf52eb Mon Sep 17 00:00:00 2001 -From: Christian Ehrhardt <christian.ehrhardt@canonical.com> -Date: Wed, 9 Feb 2022 12:14:56 +0100 -Subject: [PATCH] tools/virtiofsd: Add rseq syscall to the seccomp allowlist - -The virtiofsd currently crashes when used with glibc 2.35. -That is due to the rseq system call being added to every thread -creation [1][2]. - -[1]: https://www.efficios.com/blog/2019/02/08/linux-restartable-sequences/ -[2]: https://sourceware.org/pipermail/libc-alpha/2022-February/136040.html - -This happens not at daemon start, but when a guest connects - - /usr/lib/qemu/virtiofsd -f --socket-path=/tmp/testvfsd -o sandbox=chroot \ - -o source=/var/guests/j-virtiofs --socket-group=kvm - virtio_session_mount: Waiting for vhost-user socket connection... - # start ok, now guest will connect - virtio_session_mount: Received vhost-user socket connection - virtio_loop: Entry - fv_queue_set_started: qidx=0 started=1 - fv_queue_set_started: qidx=1 started=1 - Bad system call (core dumped) - -We have to put rseq on the seccomp allowlist to avoid that the daemon -is crashing in this case. - -Reported-by: Michael Hudson-Doyle <michael.hudson@canonical.com> -Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com> -Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> -Message-id: 20220209111456.3328420-1-christian.ehrhardt@canonical.com - -[Moved rseq to its alphabetically ordered position in the seccomp -allowlist. ---Stefan] -Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> ---- - tools/virtiofsd/passthrough_seccomp.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/tools/virtiofsd/passthrough_seccomp.c b/tools/virtiofsd/passthrough_seccomp.c -index a3ce9f898d..2bc0127b69 100644 ---- a/tools/virtiofsd/passthrough_seccomp.c -+++ b/tools/virtiofsd/passthrough_seccomp.c -@@ -91,6 +91,9 @@ static const int syscall_allowlist[] = { - SCMP_SYS(renameat2), - SCMP_SYS(removexattr), - SCMP_SYS(restart_syscall), -+#ifdef __NR_rseq -+ SCMP_SYS(rseq), /* required since glibc 2.35 */ -+#endif - SCMP_SYS(rt_sigaction), - SCMP_SYS(rt_sigprocmask), - SCMP_SYS(rt_sigreturn), --- -GitLab - - diff --git a/app-emulation/qemu/files/qemu-6.2.0-user-SLIC-crash.patch b/app-emulation/qemu/files/qemu-6.2.0-user-SLIC-crash.patch deleted file mode 100644 index 76809782b5f7..000000000000 --- a/app-emulation/qemu/files/qemu-6.2.0-user-SLIC-crash.patch +++ /dev/null @@ -1,173 +0,0 @@ -Gentoo bug: https://bugs.gentoo.org/830170 -Upstream bug: https://gitlab.com/qemu-project/qemu/-/issues/786 -Patches taken from -https://lore.kernel.org/qemu-devel/20211227193120.1084176-1-imammedo@redhat.com/ - -commit dce6c86f54eab61028e110497c222e73381379df -Author: Igor Mammedov <imammedo@redhat.com> -Date: Mon Dec 27 14:31:17 2021 -0500 - - acpi: fix QEMU crash when started with SLIC table - - if QEMU is started with used provided SLIC table blob, - - -acpitable sig=SLIC,oem_id='CRASH ',oem_table_id="ME",oem_rev=00002210,asl_compiler_id="",asl_compiler_rev=00000000,data=/dev/null - it will assert with: - - hw/acpi/aml-build.c:61:build_append_padded_str: assertion failed: (len <= maxlen) - - and following backtrace: - - ... - build_append_padded_str (array=0x555556afe320, str=0x555556afdb2e "CRASH ME", maxlen=0x6, pad=0x20) at hw/acpi/aml-build.c:61 - acpi_table_begin (desc=0x7fffffffd1b0, array=0x555556afe320) at hw/acpi/aml-build.c:1727 - build_fadt (tbl=0x555556afe320, linker=0x555557ca3830, f=0x7fffffffd318, oem_id=0x555556afdb2e "CRASH ME", oem_table_id=0x555556afdb34 "ME") at hw/acpi/aml-build.c:2064 - ... - - which happens due to acpi_table_begin() expecting NULL terminated - oem_id and oem_table_id strings, which is normally the case, but - in case of user provided SLIC table, oem_id points to table's blob - directly and as result oem_id became longer than expected. - - Fix issue by handling oem_id consistently and make acpi_get_slic_oem() - return NULL terminated strings. - - PS: - After [1] refactoring, oem_id semantics became inconsistent, where - NULL terminated string was coming from machine and old way pointer - into byte array coming from -acpitable option. That used to work - since build_header() wasn't expecting NULL terminated string and - blindly copied the 1st 6 bytes only. - - However commit [2] broke that by replacing build_header() with - acpi_table_begin(), which was expecting NULL terminated string - and was checking oem_id size. - - 1) 602b45820 ("acpi: Permit OEM ID and OEM table ID fields to be changed") - 2) - Fixes: 4b56e1e4eb08 ("acpi: build_fadt: use acpi_table_begin()/acpi_table_end() instead of build_header()") - Resolves: https://gitlab.com/qemu-project/qemu/-/issues/786 - Signed-off-by: Igor Mammedov <imammedo@redhat.com> - -diff --git a/hw/acpi/core.c b/hw/acpi/core.c -index 1e004d0078..3e811bf03c 100644 ---- a/hw/acpi/core.c -+++ b/hw/acpi/core.c -@@ -345,8 +345,8 @@ int acpi_get_slic_oem(AcpiSlicOem *oem) - struct acpi_table_header *hdr = (void *)(u - sizeof(hdr->_length)); - - if (memcmp(hdr->sig, "SLIC", 4) == 0) { -- oem->id = hdr->oem_id; -- oem->table_id = hdr->oem_table_id; -+ oem->id = g_strndup(hdr->oem_id, 6); -+ oem->table_id = g_strndup(hdr->oem_table_id, 8); - return 0; - } - } -diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c -index a99c6e4fe3..570f82997b 100644 ---- a/hw/i386/acpi-build.c -+++ b/hw/i386/acpi-build.c -@@ -2721,6 +2721,8 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) - - /* Cleanup memory that's no longer used. */ - g_array_free(table_offsets, true); -+ g_free(slic_oem.id); -+ g_free(slic_oem.table_id); - } - - static void acpi_ram_update(MemoryRegion *mr, GArray *data) - -commit a22de122ad03ea40953ad0328b2c3e31002d8052 -Author: Igor Mammedov <imammedo@redhat.com> -Date: Mon Dec 27 14:31:18 2021 -0500 - - tests: acpi: whitelist expected blobs before changing them - - Signed-off-by: Igor Mammedov <imammedo@redhat.com> - -diff --git a/tests/data/acpi/q35/FACP.slic b/tests/data/acpi/q35/FACP.slic -new file mode 100644 -index 0000000000..f6a864cc86 -Binary files /dev/null and b/tests/data/acpi/q35/FACP.slic differ -diff --git a/tests/data/acpi/q35/SLIC.slic b/tests/data/acpi/q35/SLIC.slic -new file mode 100644 -index 0000000000..e69de29bb2 -diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h -index dfb8523c8b..49dbf8fa3e 100644 ---- a/tests/qtest/bios-tables-test-allowed-diff.h -+++ b/tests/qtest/bios-tables-test-allowed-diff.h -@@ -1 +1,3 @@ - /* List of comma-separated changed AML files to ignore */ -+"tests/data/acpi/q35/FACP.slic", -+"tests/data/acpi/q35/SLIC.slic", - -commit cb913395d76f8fdfd7f1d0c8ea77d4710821bbd3 -Author: Igor Mammedov <imammedo@redhat.com> -Date: Mon Dec 27 14:31:19 2021 -0500 - - tests: acpi: add SLIC table test - - When user uses '-acpitable' to add SLIC table, some ACPI - tables (FADT) will change its 'Oem ID'/'Oem Table ID' fields to - match that of SLIC. Test makes sure thati QEMU handles - those fields correctly when SLIC table is added with - '-acpitable' option. - - Signed-off-by: Igor Mammedov <imammedo@redhat.com> - -diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c -index 258874167e..ae7ef13ec7 100644 ---- a/tests/qtest/bios-tables-test.c -+++ b/tests/qtest/bios-tables-test.c -@@ -1567,6 +1567,19 @@ static void test_acpi_oem_fields_virt(void) - g_free(args); - } - -+static void test_acpi_q35_slic(void) -+{ -+ test_data data = { -+ .machine = MACHINE_Q35, -+ .variant = ".slic", -+ }; -+ -+ test_acpi_one("-acpitable sig=SLIC,oem_id='CRASH ',oem_table_id='ME'," -+ "oem_rev=00002210,asl_compiler_id='qemu'," -+ "asl_compiler_rev=00000000,data=/dev/null", -+ &data); -+ free_test_data(&data); -+} - - int main(int argc, char *argv[]) - { -@@ -1639,6 +1652,7 @@ int main(int argc, char *argv[]) - qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic); - qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar); - } -+ qtest_add_func("acpi/q35/slic", test_acpi_q35_slic); - } else if (strcmp(arch, "aarch64") == 0) { - if (has_tcg) { - qtest_add_func("acpi/virt", test_acpi_virt_tcg); - -commit ffba261306370e0ad8506401b104be5fa4749ade -Author: Igor Mammedov <imammedo@redhat.com> -Date: Mon Dec 27 14:31:20 2021 -0500 - - tests: acpi: SLIC: update expected blobs - - Signed-off-by: Igor Mammedov <imammedo@redhat.com> - -diff --git a/tests/data/acpi/q35/FACP.slic b/tests/data/acpi/q35/FACP.slic -index f6a864cc86..891fd4b784 100644 -Binary files a/tests/data/acpi/q35/FACP.slic and b/tests/data/acpi/q35/FACP.slic differ -diff --git a/tests/data/acpi/q35/SLIC.slic b/tests/data/acpi/q35/SLIC.slic -index e69de29bb2..fd26592e24 100644 -Binary files a/tests/data/acpi/q35/SLIC.slic and b/tests/data/acpi/q35/SLIC.slic differ -diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h -index 49dbf8fa3e..dfb8523c8b 100644 ---- a/tests/qtest/bios-tables-test-allowed-diff.h -+++ b/tests/qtest/bios-tables-test-allowed-diff.h -@@ -1,3 +1 @@ - /* List of comma-separated changed AML files to ignore */ --"tests/data/acpi/q35/FACP.slic", --"tests/data/acpi/q35/SLIC.slic", diff --git a/app-emulation/qemu/files/qemu-7.0.0-pci-overflow-fortify-source-3.patch b/app-emulation/qemu/files/qemu-7.0.0-pci-overflow-fortify-source-3.patch new file mode 100644 index 000000000000..767f66243fcc --- /dev/null +++ b/app-emulation/qemu/files/qemu-7.0.0-pci-overflow-fortify-source-3.patch @@ -0,0 +1,94 @@ +https://bugs.gentoo.org/849587 +https://bugzilla.opensuse.org/show_bug.cgi?id=1199924 +https://lists.gnu.org/archive/html/qemu-devel/2022-05/msg06183.html + +From qemu-devel Tue May 31 11:47:07 2022 +From: Claudio Fontana <cfontana () suse ! de> +Date: Tue, 31 May 2022 11:47:07 +0000 +To: qemu-devel +Subject: [PATCH] pci: fix overflow in snprintf string formatting +Message-Id: <20220531114707.18830-1-cfontana () suse ! de> +X-MARC-Message: https://marc.info/?l=qemu-devel&m=165399772310578 + +the code in pcibus_get_fw_dev_path contained the potential for a +stack buffer overflow of 1 byte, potentially writing to the stack an +extra NUL byte. + +This overflow could happen if the PCI slot is >= 0x10000000, +and the PCI function is >= 0x10000000, due to the size parameter +of snprintf being incorrectly calculated in the call: + + if (PCI_FUNC(d->devfn)) + snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn)); + +since the off obtained from a previous call to snprintf is added +instead of subtracted from the total available size of the buffer. + +Without the accurate size guard from snprintf, we end up writing in the +worst case: + +name (32) + "@" (1) + SLOT (8) + "," (1) + FUNC (8) + term NUL (1) = 51 bytes + +In order to provide something more robust, replace all of the code in +pcibus_get_fw_dev_path with a single call to g_strdup_printf, +so there is no need to rely on manual calculations. + +Found by compiling QEMU with FORTIFY_SOURCE=3 as the error: + +*** buffer overflow detected ***: terminated + +Thread 1 "qemu-system-x86" received signal SIGABRT, Aborted. +[Switching to Thread 0x7ffff642c380 (LWP 121307)] +0x00007ffff71ff55c in __pthread_kill_implementation () from /lib64/libc.so.6 +(gdb) bt + #0 0x00007ffff71ff55c in __pthread_kill_implementation () at /lib64/libc.so.6 + #1 0x00007ffff71ac6f6 in raise () at /lib64/libc.so.6 + #2 0x00007ffff7195814 in abort () at /lib64/libc.so.6 + #3 0x00007ffff71f279e in __libc_message () at /lib64/libc.so.6 + #4 0x00007ffff729767a in __fortify_fail () at /lib64/libc.so.6 + #5 0x00007ffff7295c36 in () at /lib64/libc.so.6 + #6 0x00007ffff72957f5 in __snprintf_chk () at /lib64/libc.so.6 + #7 0x0000555555b1c1fd in pcibus_get_fw_dev_path () + #8 0x0000555555f2bde4 in qdev_get_fw_dev_path_helper.constprop () + #9 0x0000555555f2bd86 in qdev_get_fw_dev_path_helper.constprop () + #10 0x00005555559a6e5d in get_boot_device_path () + #11 0x00005555559a712c in get_boot_devices_list () + #12 0x0000555555b1a3d0 in fw_cfg_machine_reset () + #13 0x0000555555bf4c2d in pc_machine_reset () + #14 0x0000555555c66988 in qemu_system_reset () + #15 0x0000555555a6dff6 in qdev_machine_creation_done () + #16 0x0000555555c79186 in qmp_x_exit_preconfig.part () + #17 0x0000555555c7b459 in qemu_init () + #18 0x0000555555960a29 in main () + +Found-by: Dario Faggioli <Dario Faggioli <dfaggioli@suse.com> +Found-by: Martin Liška <martin.liska@suse.com> +Cc: qemu-stable@nongnu.org +Signed-off-by: Claudio Fontana <cfontana@suse.de> +--- a/hw/pci/pci.c ++++ b/hw/pci/pci.c +@@ -2640,15 +2640,15 @@ static char *pci_dev_fw_name(DeviceState *dev, char *buf, int len) + static char *pcibus_get_fw_dev_path(DeviceState *dev) + { + PCIDevice *d = (PCIDevice *)dev; +- char path[50], name[33]; +- int off; +- +- off = snprintf(path, sizeof(path), "%s@%x", +- pci_dev_fw_name(dev, name, sizeof name), +- PCI_SLOT(d->devfn)); +- if (PCI_FUNC(d->devfn)) +- snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn)); +- return g_strdup(path); ++ char name[33]; ++ int has_func = !!PCI_FUNC(d->devfn); ++ ++ return g_strdup_printf("%s@%x%s%.*x", ++ pci_dev_fw_name(dev, name, sizeof(name)), ++ PCI_SLOT(d->devfn), ++ has_func ? "," : "", ++ has_func, ++ PCI_FUNC(d->devfn)); + } + + static char *pcibus_get_dev_path(DeviceState *dev) diff --git a/app-emulation/qemu/files/qemu-7.0.0-virtio-scsi-fixes.patch b/app-emulation/qemu/files/qemu-7.0.0-virtio-scsi-fixes.patch new file mode 100644 index 000000000000..9ec6ede80896 --- /dev/null +++ b/app-emulation/qemu/files/qemu-7.0.0-virtio-scsi-fixes.patch @@ -0,0 +1,182 @@ +https://bugs.gentoo.org/849500 +https://gitlab.com/qemu-project/qemu/-/commit/2f743ef6366c2df4ef51ef3ae318138cdc0125ab.patch +https://gitlab.com/qemu-project/qemu/-/commit/38738f7dbbda90fbc161757b7f4be35b52205552.patch + +From: Stefan Hajnoczi <stefanha@redhat.com> +Date: Wed, 27 Apr 2022 15:35:36 +0100 +Subject: [PATCH] virtio-scsi: fix ctrl and event handler functions in + dataplane mode + +Commit f34e8d8b8d48d73f36a67b6d5e492ef9784b5012 ("virtio-scsi: prepare +virtio_scsi_handle_cmd for dataplane") prepared the virtio-scsi cmd +virtqueue handler function to be used in both the dataplane and +non-datpalane code paths. + +It failed to convert the ctrl and event virtqueue handler functions, +which are not designed to be called from the dataplane code path but +will be since the ioeventfd is set up for those virtqueues when +dataplane starts. + +Convert the ctrl and event virtqueue handler functions now so they +operate correctly when called from the dataplane code path. Avoid code +duplication by extracting this code into a helper function. + +Fixes: f34e8d8b8d48d73f36a67b6d5e492ef9784b5012 ("virtio-scsi: prepare virtio_scsi_handle_cmd for dataplane") +Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> +Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> +Message-id: 20220427143541.119567-2-stefanha@redhat.com +[Fixed s/by used/be used/ typo pointed out by Michael Tokarev +<mjt@tls.msk.ru>. +--Stefan] +Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> +--- a/hw/scsi/virtio-scsi.c ++++ b/hw/scsi/virtio-scsi.c +@@ -472,16 +472,32 @@ bool virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq) + return progress; + } + ++/* ++ * If dataplane is configured but not yet started, do so now and return true on ++ * success. ++ * ++ * Dataplane is started by the core virtio code but virtqueue handler functions ++ * can also be invoked when a guest kicks before DRIVER_OK, so this helper ++ * function helps us deal with manually starting ioeventfd in that case. ++ */ ++static bool virtio_scsi_defer_to_dataplane(VirtIOSCSI *s) ++{ ++ if (!s->ctx || s->dataplane_started) { ++ return false; ++ } ++ ++ virtio_device_start_ioeventfd(&s->parent_obj.parent_obj); ++ return !s->dataplane_fenced; ++} ++ + static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) + { + VirtIOSCSI *s = (VirtIOSCSI *)vdev; + +- if (s->ctx) { +- virtio_device_start_ioeventfd(vdev); +- if (!s->dataplane_fenced) { +- return; +- } ++ if (virtio_scsi_defer_to_dataplane(s)) { ++ return; + } ++ + virtio_scsi_acquire(s); + virtio_scsi_handle_ctrl_vq(s, vq); + virtio_scsi_release(s); +@@ -720,12 +736,10 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq) + /* use non-QOM casts in the data path */ + VirtIOSCSI *s = (VirtIOSCSI *)vdev; + +- if (s->ctx && !s->dataplane_started) { +- virtio_device_start_ioeventfd(vdev); +- if (!s->dataplane_fenced) { +- return; +- } ++ if (virtio_scsi_defer_to_dataplane(s)) { ++ return; + } ++ + virtio_scsi_acquire(s); + virtio_scsi_handle_cmd_vq(s, vq); + virtio_scsi_release(s); +@@ -855,12 +869,10 @@ static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq) + { + VirtIOSCSI *s = VIRTIO_SCSI(vdev); + +- if (s->ctx) { +- virtio_device_start_ioeventfd(vdev); +- if (!s->dataplane_fenced) { +- return; +- } ++ if (virtio_scsi_defer_to_dataplane(s)) { ++ return; + } ++ + virtio_scsi_acquire(s); + virtio_scsi_handle_event_vq(s, vq); + virtio_scsi_release(s); +GitLab + +From: Stefan Hajnoczi <stefanha@redhat.com> +Date: Wed, 27 Apr 2022 15:35:37 +0100 +Subject: [PATCH] virtio-scsi: don't waste CPU polling the event virtqueue + +The virtio-scsi event virtqueue is not emptied by its handler function. +This is typical for rx virtqueues where the device uses buffers when +some event occurs (e.g. a packet is received, an error condition +happens, etc). + +Polling non-empty virtqueues wastes CPU cycles. We are not waiting for +new buffers to become available, we are waiting for an event to occur, +so it's a misuse of CPU resources to poll for buffers. + +Introduce the new virtio_queue_aio_attach_host_notifier_no_poll() API, +which is identical to virtio_queue_aio_attach_host_notifier() except +that it does not poll the virtqueue. + +Before this patch the following command-line consumed 100% CPU in the +IOThread polling and calling virtio_scsi_handle_event(): + + $ qemu-system-x86_64 -M accel=kvm -m 1G -cpu host \ + --object iothread,id=iothread0 \ + --device virtio-scsi-pci,iothread=iothread0 \ + --blockdev file,filename=test.img,aio=native,cache.direct=on,node-name=drive0 \ + --device scsi-hd,drive=drive0 + +After this patch CPU is no longer wasted. + +Reported-by: Nir Soffer <nsoffer@redhat.com> +Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> +Tested-by: Nir Soffer <nsoffer@redhat.com> +Message-id: 20220427143541.119567-3-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> +--- a/hw/scsi/virtio-scsi-dataplane.c ++++ b/hw/scsi/virtio-scsi-dataplane.c +@@ -138,7 +138,7 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev) + + aio_context_acquire(s->ctx); + virtio_queue_aio_attach_host_notifier(vs->ctrl_vq, s->ctx); +- virtio_queue_aio_attach_host_notifier(vs->event_vq, s->ctx); ++ virtio_queue_aio_attach_host_notifier_no_poll(vs->event_vq, s->ctx); + + for (i = 0; i < vs->conf.num_queues; i++) { + virtio_queue_aio_attach_host_notifier(vs->cmd_vqs[i], s->ctx); +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -3534,6 +3534,19 @@ void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx) + virtio_queue_host_notifier_aio_poll_end); + } + ++/* ++ * Same as virtio_queue_aio_attach_host_notifier() but without polling. Use ++ * this for rx virtqueues and similar cases where the virtqueue handler ++ * function does not pop all elements. When the virtqueue is left non-empty ++ * polling consumes CPU cycles and should not be used. ++ */ ++void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext *ctx) ++{ ++ aio_set_event_notifier(ctx, &vq->host_notifier, true, ++ virtio_queue_host_notifier_read, ++ NULL, NULL); ++} ++ + void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx) + { + aio_set_event_notifier(ctx, &vq->host_notifier, true, NULL, NULL, NULL); +--- a/include/hw/virtio/virtio.h ++++ b/include/hw/virtio/virtio.h +@@ -317,6 +317,7 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq); + void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled); + void virtio_queue_host_notifier_read(EventNotifier *n); + void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx); ++void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext *ctx); + void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx); + VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector); + VirtQueue *virtio_vector_next_queue(VirtQueue *vq); +GitLab |