From 3de6afef49449c487256dc6238649ba0f0508789 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 6 Nov 2025 15:19:59 +0000 Subject: [PATCH 1/9] qtest: Allow and ignore blank lines in input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the code that reads the qtest protocol commands insists that every input line has a command. If it receives a line with nothing but whitespace it will trip an assertion in qtest_process_command(). This is a little awkward for the case where we are feeding qtest a set of bug-reproduction commands via standard input or a file, because it means you need to be careful not to leave a blank line at the start or the end when cutting and pasting the command sequence from a bug report. Change the code to allow and ignore blank lines in the input. Signed-off-by: Peter Maydell Reviewed-by: Fabiano Rosas Message-ID: <20251106151959.1088095-1-peter.maydell@linaro.org> Signed-off-by: Philippe Mathieu-Daudé --- system/qtest.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/system/qtest.c b/system/qtest.c index cbeb7f3772..67e2385f4b 100644 --- a/system/qtest.c +++ b/system/qtest.c @@ -69,6 +69,9 @@ static void *qtest_server_send_opaque; * so clients should always handle many async messages before the response * comes in. * + * Extra ASCII space characters in command inputs are permitted and ignored. + * Lines containing only spaces are permitted and ignored. + * * Valid requests * ^^^^^^^^^^^^^^ * @@ -367,7 +370,11 @@ static void qtest_process_command(CharFrontend *chr, gchar **words) fprintf(qtest_log_fp, "\n"); } - g_assert(command); + if (!command) { + /* Input line was blank: ignore it */ + return; + } + if (strcmp(words[0], "irq_intercept_out") == 0 || strcmp(words[0], "irq_intercept_in") == 0) { DeviceState *dev; From ef44cc0a762438ebc84c4997a5ce29c6f00622c3 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 7 Nov 2025 13:10:44 +0000 Subject: [PATCH 2/9] hw/pci: Make msix_init take a uint32_t for nentries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit msix_init() and msix_init_exclusive_bar() take an "unsigned short" argument for the number of MSI-X vectors to try to use. This is big enough for the maximum permitted number of vectors, which is 2048. Unfortunately, we have several devices (most notably virtio) which allow the user to specify the desired number of vectors, and which use uint32_t properties for this. If the user sets the property to a value that is too big for a uint16_t, the value will be truncated when it is passed to msix_init(), and msix_init() may then return success if the truncated value is a valid one. The resulting mismatch between the number of vectors the msix code thinks the device has and the number of vectors the device itself thinks it has can cause assertions, such as the one in issue 2631, where "-device virtio-mouse-pci,vectors=19923041" is interpreted by msix as "97 vectors" and by the virtio-pci layer as "19923041 vectors"; a guest attempt to access vector 97 thus passes the virtio-pci bounds checking and hits an essertion in msix_vector_use(). Avoid this by making msix_init() and its wrapper function msix_init_exclusive_bar() take the number of vectors as a uint32_t. The erroneous command line will now produce the warning qemu-system-i386: -device virtio-mouse-pci,vectors=19923041: warning: unable to init msix vectors to 19923041 and proceed without crashing. (The virtio device warns and falls back to not using MSIX, rather than complaining that the option is not a valid value this is the same as the existing behaviour for values that are beyond the MSI-X maximum possible value but fit into a 16-bit integer, like 2049.) To ensure this doesn't result in potential overflows in calculation of the BAR size in msix_init_exclusive_bar(), we duplicate the nentries error-check from msix_init() at the top of msix_init_exclusive_bar(), so we know nentries is sane before we start using it. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2631 Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20251107131044.1321637-1-peter.maydell@linaro.org> Signed-off-by: Philippe Mathieu-Daudé --- hw/pci/msix.c | 10 ++++++++-- include/hw/pci/msix.h | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/hw/pci/msix.c b/hw/pci/msix.c index 8c7f6709e2..b35476d057 100644 --- a/hw/pci/msix.c +++ b/hw/pci/msix.c @@ -318,7 +318,7 @@ static void msix_mask_all(struct PCIDevice *dev, unsigned nentries) * also means a programming error, except device assignment, which can check * if a real HW is broken. */ -int msix_init(struct PCIDevice *dev, unsigned short nentries, +int msix_init(struct PCIDevice *dev, uint32_t nentries, MemoryRegion *table_bar, uint8_t table_bar_nr, unsigned table_offset, MemoryRegion *pba_bar, uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos, @@ -392,7 +392,7 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries, return 0; } -int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries, +int msix_init_exclusive_bar(PCIDevice *dev, uint32_t nentries, uint8_t bar_nr, Error **errp) { int ret; @@ -401,6 +401,12 @@ int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries, uint32_t bar_pba_offset = bar_size / 2; uint32_t bar_pba_size = QEMU_ALIGN_UP(nentries, 64) / 8; + /* Sanity-check nentries before we use it in BAR size calculations */ + if (nentries < 1 || nentries > PCI_MSIX_FLAGS_QSIZE + 1) { + error_setg(errp, "The number of MSI-X vectors is invalid"); + return -EINVAL; + } + /* * Migration compatibility dictates that this remains a 4k * BAR with the vector table in the lower half and PBA in diff --git a/include/hw/pci/msix.h b/include/hw/pci/msix.h index 11ef9454c1..551a2bcfe7 100644 --- a/include/hw/pci/msix.h +++ b/include/hw/pci/msix.h @@ -7,12 +7,12 @@ void msix_set_message(PCIDevice *dev, int vector, MSIMessage msg); MSIMessage msix_get_message(PCIDevice *dev, unsigned int vector); -int msix_init(PCIDevice *dev, unsigned short nentries, +int msix_init(PCIDevice *dev, uint32_t nentries, MemoryRegion *table_bar, uint8_t table_bar_nr, unsigned table_offset, MemoryRegion *pba_bar, uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos, Error **errp); -int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries, +int msix_init_exclusive_bar(PCIDevice *dev, uint32_t nentries, uint8_t bar_nr, Error **errp); void msix_write_config(PCIDevice *dev, uint32_t address, uint32_t val, int len); From a5da8dd90b9cdc308f053b2543ebf5368c12ce49 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Fri, 21 Nov 2025 16:44:16 +0800 Subject: [PATCH 3/9] docs/deprecated: Remove undeprecated SMP description MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Unsupported 'parameter=1' SMP configuration" was proposed to be deprecated in the commit 54c4ea8f3ae6 ("hw/core/machine-smp: Deprecate unsupported "parameter=1" SMP configurations"). But the related code was reverted later in the commit 9d7950edb0cd ("hw/core: allow parameter=1 for SMP topology on any machine"). Thus, this SMP behavior is still valid and is not actually deprecated. Remove outdated document descriptions. Reported-by: Markus Armbruster Signed-off-by: Zhao Liu Reviewed-by: Markus Armbruster Message-ID: <20251121084416.1031466-1-zhao1.liu@intel.com> Signed-off-by: Philippe Mathieu-Daudé --- docs/about/deprecated.rst | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst index 30ab72b2a4..9386cffba2 100644 --- a/docs/about/deprecated.rst +++ b/docs/about/deprecated.rst @@ -54,20 +54,6 @@ as short-form boolean values, and passed to plugins as ``arg_name=on``. However, short-form booleans are deprecated and full explicit ``arg_name=on`` form is preferred. -``-smp`` (Unsupported "parameter=1" SMP configurations) (since 9.0) -''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' - -Specified CPU topology parameters must be supported by the machine. - -In the SMP configuration, users should provide the CPU topology parameters that -are supported by the target machine. - -However, historically it was allowed for users to specify the unsupported -topology parameter as "1", which is meaningless. So support for this kind of -configurations (e.g. -smp drawers=1,books=1,clusters=1 for x86 PC machine) is -marked deprecated since 9.0, users have to ensure that all the topology members -described with -smp are supported by the target machine. - QEMU Machine Protocol (QMP) commands ------------------------------------ From 622a0c9dee44f7a6c51e80644a3c5f3b132fbb7e Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 21 Nov 2025 13:14:25 +0100 Subject: [PATCH 4/9] hw/usb: Convert to qemu_create() for a better error message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The error message changes from open FILENAME failed to Could not create 'FILENAME': REASON where REASON is the value of strerror(errno). Signed-off-by: Markus Armbruster Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20251121121438.1249498-3-armbru@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/usb/bus.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/usb/bus.c b/hw/usb/bus.c index 8dd2ce415e..714e33989f 100644 --- a/hw/usb/bus.c +++ b/hw/usb/bus.c @@ -259,10 +259,9 @@ static void usb_qdev_realize(DeviceState *qdev, Error **errp) } if (dev->pcap_filename) { - int fd = qemu_open_old(dev->pcap_filename, - O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, 0666); + int fd = qemu_create(dev->pcap_filename, + O_WRONLY | O_TRUNC | O_BINARY, 0666, errp); if (fd < 0) { - error_setg(errp, "open %s failed", dev->pcap_filename); usb_qdev_unrealize(qdev); return; } From 6d85f1d4492f0ef7347c488ae1d7f6f03a892573 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 21 Nov 2025 13:14:29 +0100 Subject: [PATCH 5/9] hw/scsi: Use error_setg_file_open() for a better error message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The error message changes from vhost-scsi: open vhost char device failed: REASON to Could not open '/dev/vhost-scsi': REASON I think the exact file name is more useful to know than the file's purpose. We could put back the "vhost-scsi: " prefix with error_prepend(). Not worth the bother. Signed-off-by: Markus Armbruster Reviewed-by: Dr. David Alan Gilbert Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20251121121438.1249498-7-armbru@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/scsi/vhost-scsi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c index cdf405b0f8..239138c931 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -245,8 +245,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp) } else { vhostfd = open("/dev/vhost-scsi", O_RDWR); if (vhostfd < 0) { - error_setg(errp, "vhost-scsi: open vhost char device failed: %s", - strerror(errno)); + error_setg_file_open(errp, errno, "/dev/vhost-scsi"); return; } } From 77f4f14e08184b47f1356269ae2c5db039d16af2 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 21 Nov 2025 13:14:30 +0100 Subject: [PATCH 6/9] hw/virtio: Use error_setg_file_open() for a better error message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The error message changes from vhost-vsock: failed to open vhost device: REASON to Could not open '/dev/vhost-vsock': REASON I think the exact file name is more useful to know than the file's purpose. Signed-off-by: Markus Armbruster Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20251121121438.1249498-8-armbru@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/virtio/vhost-vsock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c index 107d88babe..7940b60d8a 100644 --- a/hw/virtio/vhost-vsock.c +++ b/hw/virtio/vhost-vsock.c @@ -153,8 +153,7 @@ static void vhost_vsock_device_realize(DeviceState *dev, Error **errp) } else { vhostfd = open("/dev/vhost-vsock", O_RDWR); if (vhostfd < 0) { - error_setg_errno(errp, errno, - "vhost-vsock: failed to open vhost device"); + error_setg_file_open(errp, errno, "/dev/vhost-vsock"); return; } From 78d66a25c54339b370d2062826c8a011012ab6c0 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 24 Nov 2025 17:34:07 +0000 Subject: [PATCH 7/9] replay: Improve assert in replay_char_read_all_load() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In replay_char_read_all_load() we get a buffer and size from the replay log. We know the size has to fit an int because of how we write the log. However the way we assert this is wrong: we cast the size_t from replay_get_array() to an int and then check that it is non-negative. This misses cases where an over-large size is truncated into a positive value by the cast. Replace the assertion with checking that the size is in-range before doing the cast. Coverity complained about the possible overflow: CID 1643440. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20251124173407.50124-1-peter.maydell@linaro.org> Signed-off-by: Philippe Mathieu-Daudé --- replay/replay-char.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/replay/replay-char.c b/replay/replay-char.c index 81dc416e98..4e58dd154a 100644 --- a/replay/replay-char.c +++ b/replay/replay-char.c @@ -126,8 +126,8 @@ int replay_char_read_all_load(uint8_t *buf) int res; replay_get_array(buf, &size); replay_finish_event(); + assert(size <= INT_MAX); res = (int)size; - assert(res >= 0); return res; } else if (replay_next_event_is(EVENT_CHAR_READ_ALL_ERROR)) { int res = replay_get_dword(); From 98ee8aa92e930a447c6108d4689f0bf8b535359d Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Mon, 24 Nov 2025 14:14:08 -0500 Subject: [PATCH 8/9] hw/core/machine: Provide a description for aux-ram-share property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was forgotten when being introduced in commit 91792807d1 ("machine: aux-ram-share option"). Cc: qemu-stable@nongnu.org Reported-by: Peter Maydell Signed-off-by: Peter Xu Reviewed-by: Fabiano Rosas Message-ID: <20251124191408.783473-1-peterx@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/core/machine.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/core/machine.c b/hw/core/machine.c index 06e0c9a179..27372bb01e 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -1204,6 +1204,8 @@ static void machine_class_init(ObjectClass *oc, const void *data) object_class_property_add_bool(oc, "aux-ram-share", machine_get_aux_ram_share, machine_set_aux_ram_share); + object_class_property_set_description(oc, "aux-ram-share", + "Use anonymous shared memory for auxiliary guest RAMs"); #endif object_class_property_add_bool(oc, "usb", From 57756aa01fe52c50d655929c43d9a80f8214cf1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 25 Nov 2025 15:26:31 +0100 Subject: [PATCH 9/9] hw/aspeed/{xdma, rtc, sdhci}: Fix endianness to DEVICE_LITTLE_ENDIAN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the XDMA, RTC and SDHCI device models of the Aspeed SoCs were first introduced, their MMIO regions inherited of a DEVICE_NATIVE_ENDIAN endianness. It should be DEVICE_LITTLE_ENDIAN. Fix that. Signed-off-by: Cédric Le Goater Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20251125142631.676689-1-clg@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/misc/aspeed_xdma.c | 2 +- hw/rtc/aspeed_rtc.c | 2 +- hw/sd/aspeed_sdhci.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/misc/aspeed_xdma.c b/hw/misc/aspeed_xdma.c index cc03c422b0..c448ad32ff 100644 --- a/hw/misc/aspeed_xdma.c +++ b/hw/misc/aspeed_xdma.c @@ -113,7 +113,7 @@ static void aspeed_xdma_write(void *opaque, hwaddr addr, uint64_t val, static const MemoryRegionOps aspeed_xdma_ops = { .read = aspeed_xdma_read, .write = aspeed_xdma_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, .valid.min_access_size = 4, .valid.max_access_size = 4, }; diff --git a/hw/rtc/aspeed_rtc.c b/hw/rtc/aspeed_rtc.c index c4feea23a0..6793e253f4 100644 --- a/hw/rtc/aspeed_rtc.c +++ b/hw/rtc/aspeed_rtc.c @@ -131,7 +131,7 @@ static void aspeed_rtc_reset(DeviceState *d) static const MemoryRegionOps aspeed_rtc_ops = { .read = aspeed_rtc_read, .write = aspeed_rtc_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, }; static const VMStateDescription vmstate_aspeed_rtc = { diff --git a/hw/sd/aspeed_sdhci.c b/hw/sd/aspeed_sdhci.c index fc38ad39ce..f5c0c4956a 100644 --- a/hw/sd/aspeed_sdhci.c +++ b/hw/sd/aspeed_sdhci.c @@ -124,7 +124,7 @@ static void aspeed_sdhci_write(void *opaque, hwaddr addr, uint64_t val, static const MemoryRegionOps aspeed_sdhci_ops = { .read = aspeed_sdhci_read, .write = aspeed_sdhci_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, .valid.min_access_size = 4, .valid.max_access_size = 4, };