From e895095c78ab877d40df2dd31ee79d85757d963b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 27 Apr 2021 15:33:37 +0200 Subject: [PATCH 1/9] target/mips: Only update MVPControl.EVP bit if executed by master VPE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the 'MIPS MT Application-Specific Extension' manual: If the VPE executing the instruction is not a Master VPE, with the MVP bit of the VPEConf0 register set, the EVP bit is unchanged by the instruction. Modify the DVPE/EVPE opcodes to only update the MVPControl.EVP bit if executed on a master VPE. Cc: qemu-stable@nongnu.org Reported-by: Hansni Bu Buglink: https://bugs.launchpad.net/qemu/+bug/1926277 Fixes: f249412c749 ("mips: Add MT halting and waking of VPEs") Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Jiaxun Yang Message-ID: <20210427133343.159718-1-f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé --- target/mips/tcg/system/cp0_helper.c | 32 ++++++++++++++++------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/target/mips/tcg/system/cp0_helper.c b/target/mips/tcg/system/cp0_helper.c index 101b1e65fd..b69e70d7fc 100644 --- a/target/mips/tcg/system/cp0_helper.c +++ b/target/mips/tcg/system/cp0_helper.c @@ -1562,12 +1562,14 @@ target_ulong helper_dvpe(CPUMIPSState *env) CPUState *other_cs = first_cpu; target_ulong prev = env->mvp->CP0_MVPControl; - CPU_FOREACH(other_cs) { - MIPSCPU *other_cpu = MIPS_CPU(other_cs); - /* Turn off all VPEs except the one executing the dvpe. */ - if (&other_cpu->env != env) { - other_cpu->env.mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP); - mips_vpe_sleep(other_cpu); + if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) { + CPU_FOREACH(other_cs) { + MIPSCPU *other_cpu = MIPS_CPU(other_cs); + /* Turn off all VPEs except the one executing the dvpe. */ + if (&other_cpu->env != env) { + other_cpu->env.mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP); + mips_vpe_sleep(other_cpu); + } } } return prev; @@ -1578,15 +1580,17 @@ target_ulong helper_evpe(CPUMIPSState *env) CPUState *other_cs = first_cpu; target_ulong prev = env->mvp->CP0_MVPControl; - CPU_FOREACH(other_cs) { - MIPSCPU *other_cpu = MIPS_CPU(other_cs); + if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) { + CPU_FOREACH(other_cs) { + MIPSCPU *other_cpu = MIPS_CPU(other_cs); - if (&other_cpu->env != env - /* If the VPE is WFI, don't disturb its sleep. */ - && !mips_vpe_is_wfi(other_cpu)) { - /* Enable the VPE. */ - other_cpu->env.mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP); - mips_vpe_wake(other_cpu); /* And wake it up. */ + if (&other_cpu->env != env + /* If the VPE is WFI, don't disturb its sleep. */ + && !mips_vpe_is_wfi(other_cpu)) { + /* Enable the VPE. */ + other_cpu->env.mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP); + mips_vpe_wake(other_cpu); /* And wake it up. */ + } } } return prev; From 8e8cb3b5722babe7e7b597b3805bf09f24ed6979 Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Fri, 21 Feb 2025 16:48:56 +0300 Subject: [PATCH 2/9] hw/display/qxl-render: fix qxl_unpack_chunks() chunk size calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case of multiple chunks, code in qxl_unpack_chunks() takes size of the wrong (next in the chain) chunk, instead of using current chunk size. This leads to wrong number of bytes being copied, and to crashes if next chunk size is larger than the current one. Based on the code by Gao Yong. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1628 Tested-by: Thaddeus Hogan Tested-by: Vadim Zeitlin Signed-off-by: Michael Tokarev Reviewed-by: Thomas Huth Message-ID: <20250221134856.478806-1-mjt@tls.msk.ru> Signed-off-by: Philippe Mathieu-Daudé --- hw/display/qxl-render.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c index eda6d3de37..c6a9ac1da1 100644 --- a/hw/display/qxl-render.c +++ b/hw/display/qxl-render.c @@ -222,6 +222,7 @@ static void qxl_unpack_chunks(void *dest, size_t size, PCIQXLDevice *qxl, uint32_t max_chunks = 32; size_t offset = 0; size_t bytes; + QXLPHYSICAL next_chunk_phys = 0; for (;;) { bytes = MIN(size - offset, chunk->data_size); @@ -230,7 +231,15 @@ static void qxl_unpack_chunks(void *dest, size_t size, PCIQXLDevice *qxl, if (offset == size) { return; } - chunk = qxl_phys2virt(qxl, chunk->next_chunk, group_id, + next_chunk_phys = chunk->next_chunk; + /* fist time, only get the next chunk's data size */ + chunk = qxl_phys2virt(qxl, next_chunk_phys, group_id, + sizeof(QXLDataChunk)); + if (!chunk) { + return; + } + /* second time, check data size and get data */ + chunk = qxl_phys2virt(qxl, next_chunk_phys, group_id, sizeof(QXLDataChunk) + chunk->data_size); if (!chunk) { return; From 962316a6a339367e187b4728ef131ec6e635f364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 8 Jul 2025 10:55:33 +0200 Subject: [PATCH 3/9] hw/vfio/vfio-migration: Remove unnecessary 'qemu/typedefs.h' include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "qemu/typedefs.h" is already included by "qemu/osdep.h". Reviewed-by: Cédric Le Goater Signed-off-by: Philippe Mathieu-Daudé Message-ID: <20250708085859.7885-3-philmd@linaro.org> --- hw/vfio/vfio-migration-internal.h | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/vfio/vfio-migration-internal.h b/hw/vfio/vfio-migration-internal.h index 54141e27e6..814fbd9eba 100644 --- a/hw/vfio/vfio-migration-internal.h +++ b/hw/vfio/vfio-migration-internal.h @@ -13,7 +13,6 @@ #include #endif -#include "qemu/typedefs.h" #include "qemu/notify.h" /* From b496a392fec656d8e7af81c496efa3d45fd59023 Mon Sep 17 00:00:00 2001 From: Pierrick Bouvier Date: Fri, 25 Jul 2025 13:17:28 -0700 Subject: [PATCH 4/9] migration: rename target.c to vfio.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pierrick Bouvier Reviewed-by: Richard Henderson Acked-by: Fabiano Rosas Reviewed-by: Peter Xu Message-ID: <20250725201729.17100-3-pierrick.bouvier@linaro.org> Signed-off-by: Philippe Mathieu-Daudé --- migration/meson.build | 2 +- migration/{target.c => vfio.c} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename migration/{target.c => vfio.c} (90%) diff --git a/migration/meson.build b/migration/meson.build index 9aa48b290e..276da3be5a 100644 --- a/migration/meson.build +++ b/migration/meson.build @@ -51,4 +51,4 @@ system_ss.add(when: qatzip, if_true: files('multifd-qatzip.c')) specific_ss.add(when: 'CONFIG_SYSTEM_ONLY', if_true: files('ram.c', - 'target.c')) + 'vfio.c')) diff --git a/migration/target.c b/migration/vfio.c similarity index 90% rename from migration/target.c rename to migration/vfio.c index 12fd399f0c..0b64e49ef0 100644 --- a/migration/target.c +++ b/migration/vfio.c @@ -1,5 +1,5 @@ /* - * QEMU live migration - functions that need to be compiled target-specific + * QEMU live migration - VFIO * * This work is licensed under the terms of the GNU GPL, version 2 * or (at your option) any later version. From 2bfcd27e00a49da2efa5d703121b94cd9cd4948b Mon Sep 17 00:00:00 2001 From: Luc Michel Date: Wed, 16 Jul 2025 11:53:43 +0200 Subject: [PATCH 5/9] hw/net/cadence_gem: fix register mask initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The gem_init_register_masks function was called at init time but it relies on the num-priority-queues property. Call it at realize time instead. Cc: qemu-stable@nongnu.org Fixes: 4c70e32f05f ("net: cadence_gem: Define access permission for interrupt registers") Signed-off-by: Luc Michel Reviewed-by: Francisco Iglesias Reviewed-by: Sai Pavan Boddu Message-ID: <20250716095432.81923-2-luc.michel@amd.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/net/cadence_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c index 50025d5a6f..44446666de 100644 --- a/hw/net/cadence_gem.c +++ b/hw/net/cadence_gem.c @@ -1756,6 +1756,7 @@ static void gem_realize(DeviceState *dev, Error **errp) sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]); } + gem_init_register_masks(s); qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_gem_info, &s->conf, @@ -1776,7 +1777,6 @@ static void gem_init(Object *obj) DB_PRINT("\n"); - gem_init_register_masks(s); memory_region_init_io(&s->iomem, OBJECT(s), &gem_ops, s, "enet", sizeof(s->regs)); From 014bb30d218ef0d91c300324dec99138e999e32d Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Thu, 17 Jul 2025 15:02:07 -0700 Subject: [PATCH 6/9] hw/xen/passthrough: add missing error-report include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commit cfcacbab38e ("xen/passthrough: use gsi to map pirq when dom0 is PVH") an `error_report` was added to this file, but the corresponding include of `qemu/error-report.h` was missed. This only becomes apparent when building against Xen 4.20+ with trace backend log disabled. Fixes: cfcacbab38e4 (xen/passthrough: use gsi to map pirq when dom0 is PVH) Signed-off-by: Adam Williamson Reviewed-by: Markus Armbruster Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20250717220207.171040-1-awilliam@redhat.com> [PMD: Improved commit description, added Fixes: tag] Signed-off-by: Philippe Mathieu-Daudé --- hw/xen/xen_pt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index 9d16644d82..006b5b55f2 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -54,6 +54,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" +#include "qemu/error-report.h" #include #include "hw/pci/pci.h" From 2865bf1c5795371ef441e9029bc22566ccff8299 Mon Sep 17 00:00:00 2001 From: Pierrick Bouvier Date: Thu, 24 Jul 2025 09:11:42 -0700 Subject: [PATCH 7/9] system/physmem: fix use-after-free with dispatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A use-after-free bug was reported when booting a Linux kernel during the pci setup phase. It's quite hard to reproduce (needs smp, and favored by having several pci devices with BAR and specific Linux config, which is Debian default one in this case). After investigation (see the associated bug ticket), it appears that, under specific conditions, we might access a cached AddressSpaceDispatch that was reclaimed by RCU thread meanwhile. In the Linux boot scenario, during the pci phase, memory region are destroyed/recreated, resulting in exposition of the bug. The core of the issue is that we cache the dispatch associated to current cpu in cpu->cpu_ases[asidx].memory_dispatch. It is updated with tcg_commit, which runs asynchronously on a given cpu. At some point, we leave the rcu critial section, and the RCU thread starts reclaiming it, but tcg_commit is not yet invoked, resulting in the use-after-free. It's not the first problem around this area, and commit 0d58c660689 [1] ("softmmu: Use async_run_on_cpu in tcg_commit") already tried to address it. It did a good job, but it seems that we found a specific situation where it's not enough. This patch takes a simple approach: remove the cached value creating the issue, and make sure we always get the current mapping for address space, using address_space_to_dispatch(cpu->cpu_ases[asidx].as). It's equivalent to qatomic_rcu_read(&as->current_map)->dispatch; This is not really costly, we just need two dereferences, including one atomic (rcu) read, which is negligible considering we are already on mmu slow path anyway. Note that tcg_commit is still needed, as it's taking care of flushing TLB, removing previously mapped entries. Another solution would be to cache directly values under the dispatch (dispatch themselves are not ref counted), keep an active reference on associated memory section, and release it when appropriate (tricky). Given the time already spent debugging this area now and previously, I strongly prefer eliminating the root of the issue, instead of adding more complexity for a hypothetical performance gain. RCU is precisely used to ensure good performance when reading data, so caching is not as beneficial as it might seem IMHO. [1] https://gitlab.com/qemu-project/qemu/-/commit/0d58c660689f6da1e3feff8a997014003d928b3b Cc: qemu-stable@nongnu.org Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3040 Signed-off-by: Pierrick Bouvier Reviewed-by: Richard Henderson Reviewed-by: Michael Tokarev Tested-by: Michael Tokarev Message-ID: <20250724161142.2803091-1-pierrick.bouvier@linaro.org> Signed-off-by: Philippe Mathieu-Daudé --- system/physmem.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/system/physmem.c b/system/physmem.c index 130c148ffb..e5dd760e0b 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -165,13 +165,11 @@ static bool ram_is_cpr_compatible(RAMBlock *rb); * CPUAddressSpace: all the information a CPU needs about an AddressSpace * @cpu: the CPU whose AddressSpace this is * @as: the AddressSpace itself - * @memory_dispatch: its dispatch pointer (cached, RCU protected) * @tcg_as_listener: listener for tracking changes to the AddressSpace */ typedef struct CPUAddressSpace { CPUState *cpu; AddressSpace *as; - struct AddressSpaceDispatch *memory_dispatch; MemoryListener tcg_as_listener; } CPUAddressSpace; @@ -692,7 +690,7 @@ address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr orig_addr, IOMMUTLBEntry iotlb; int iommu_idx; hwaddr addr = orig_addr; - AddressSpaceDispatch *d = cpu->cpu_ases[asidx].memory_dispatch; + AddressSpaceDispatch *d = address_space_to_dispatch(cpu->cpu_ases[asidx].as); for (;;) { section = address_space_translate_internal(d, addr, &addr, plen, false); @@ -753,7 +751,7 @@ MemoryRegionSection *iotlb_to_section(CPUState *cpu, { int asidx = cpu_asidx_from_attrs(cpu, attrs); CPUAddressSpace *cpuas = &cpu->cpu_ases[asidx]; - AddressSpaceDispatch *d = cpuas->memory_dispatch; + AddressSpaceDispatch *d = address_space_to_dispatch(cpuas->as); int section_index = index & ~TARGET_PAGE_MASK; MemoryRegionSection *ret; @@ -2780,9 +2778,6 @@ static void tcg_log_global_after_sync(MemoryListener *listener) static void tcg_commit_cpu(CPUState *cpu, run_on_cpu_data data) { - CPUAddressSpace *cpuas = data.host_ptr; - - cpuas->memory_dispatch = address_space_to_dispatch(cpuas->as); tlb_flush(cpu); } @@ -2798,11 +2793,7 @@ static void tcg_commit(MemoryListener *listener) cpu = cpuas->cpu; /* - * Defer changes to as->memory_dispatch until the cpu is quiescent. - * Otherwise we race between (1) other cpu threads and (2) ongoing - * i/o for the current cpu thread, with data cached by mmu_lookup(). - * - * In addition, queueing the work function will kick the cpu back to + * Queueing the work function will kick the cpu back to * the main loop, which will end the RCU critical section and reclaim * the memory data structures. * From 653a75a9d7f957c4ba9387d1a54bccfdce49cb9c Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Mon, 28 Jul 2025 00:55:07 +0300 Subject: [PATCH 8/9] roms/Makefile: fix npcmNxx_bootrom build rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit 70ce076fa6dff60, the actual rom source dirs are subdirs of vbootrom/ submodule, not in top-level of it. Fixes: 70ce076fa6dff60 "roms: Update vbootrom to 1287b6e" Fixes: 269b7effd90 ("pc-bios: Add NPCM8XX vBootrom") Cc: qemu-stable@nongnu.org Signed-off-by: Michael Tokarev Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Message-ID: <20250727215511.807880-1-mjt@tls.msk.ru> Signed-off-by: Philippe Mathieu-Daudé --- roms/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/roms/Makefile b/roms/Makefile index beff58d9d5..6af68a922f 100644 --- a/roms/Makefile +++ b/roms/Makefile @@ -193,12 +193,12 @@ qboot: cp qboot/build/bios.bin ../pc-bios/qboot.rom npcm7xx_bootrom: - $(MAKE) -C vbootrom CROSS_COMPILE=$(arm_cross_prefix) - cp vbootrom/npcm7xx_bootrom.bin ../pc-bios/npcm7xx_bootrom.bin + $(MAKE) -C vbootrom/npcm7xx CROSS_COMPILE=$(arm_cross_prefix) + cp vbootrom/npcm7xx/npcm7xx_bootrom.bin ../pc-bios/npcm7xx_bootrom.bin npcm8xx_bootrom: - $(MAKE) -C vbootrom CROSS_COMPILE=$(aarch64_cross_prefix) - cp vbootrom/npcm8xx_bootrom.bin ../pc-bios/npcm8xx_bootrom.bin + $(MAKE) -C vbootrom/npcm8xx CROSS_COMPILE=$(aarch64_cross_prefix) + cp vbootrom/npcm8xx/npcm8xx_bootrom.bin ../pc-bios/npcm8xx_bootrom.bin hppa-firmware: $(MAKE) -C seabios-hppa parisc From 67e4808403471427b73c8d2c3f4273d64908f480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= Date: Mon, 28 Jul 2025 11:05:18 +0200 Subject: [PATCH 9/9] hw/display/sm501: fix missing error-report.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "qemu/error-report.h" was previously implicitly included. This is no longer the case following 012842c075520dbe1bd96a2fdcf4e218874ba443. However, the issue predates this change as `error-report.h` should have been included when the `warn_report` call was introduced. Fixes: fa140b9562 ("hw/sm501: allow compiling without PIXMAN") Signed-off-by: Clément Chigot Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Daniel P. Berrangé Message-ID: <20250728090518.963573-1-chigot@adacore.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/display/sm501.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/display/sm501.c b/hw/display/sm501.c index 6d2f18684c..bc091b3c9f 100644 --- a/hw/display/sm501.c +++ b/hw/display/sm501.c @@ -26,6 +26,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" #include "qapi/error.h" +#include "qemu/error-report.h" #include "qemu/log.h" #include "qemu/module.h" #include "hw/usb/hcd-ohci.h"