[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1115486: trixie-pu: package qemu/1:10.0.4+ds-0+deb13u1



Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: qemu@packages.debian.org, pkg-qemu-devel@lists.alioth.debian.org
Control: affects -1 + src:qemu
User: release.debian.org@packages.debian.org
Usertags: pu

[ Reason ]
There's a new upstream stable/bugfix release of qemu 10.0.x
series, - 10.0.4, which fixes a number of various bugs all
over the place.

[ Tests ]
This release works fine on/with a pile of my test virtual machines
(which includes several versions of windows, several versions
of debian, and 2 FreeBSD VMs).  Additionally, it is used on our
site in production.

[ Risks ]
Usually qemu stable series are rather low risk.  It is still
possible to break things, - however, the changes are focused,
and most of them are rather obvious or at least understandable.
Additionally, all changes were picked up from the upstream
master branch where they've tested in different contexts and
environments too.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[ Changes ]
The debian/changelog is below, in the debdiff (first in there).

[ Other info ]
Instead of the finall difference, it might be easier to review the
upstream changes as individual git commits, which are available at
https://salsa.debian.org/qemu-team/qemu/-/commits/upstream/10.0.4+ds
(up to v10.0.3 tag, which is already in trixie).

The debdiff between version currently in trixie, and the proposed
version, is below.

Thanks,

/mjt

diff -Nru qemu-10.0.3+ds/debian/changelog qemu-10.0.4+ds/debian/changelog
--- qemu-10.0.3+ds/debian/changelog	2025-08-21 18:23:38.000000000 +0300
+++ qemu-10.0.4+ds/debian/changelog	2025-09-10 09:50:46.000000000 +0300
@@ -1,3 +1,100 @@
+qemu (1:10.0.4+ds-0+deb13u1) trixie; urgency=medium
+
+  * new upstream stable/bugfix release:
+   - Update version for 10.0.4 release
+   - block/curl: fix curl internal handles handling
+     (Closes: #1111809)
+   - hw/gpio/pca9554: Avoid leak in pca9554_set_pin()
+   - hw/ppc: Fix build error with CONFIG_POWERNV disabled
+   - target/mips: fix TLB huge page check to use 64-bit shift
+   - linux-user/mips: Select M14Kc CPU to run microMIPS binaries
+   - linux-user/mips: Select 74Kf CPU to run MIPS16e binaries
+   - elf: Add EF_MIPS_ARCH_ASE definitions
+   - e1000e: Prevent crash from legacy interrupt firing after MSI-X enable
+   - Revert "tests/qtest: use qos_printf instead of g_test_message"
+   - vfio scsi ui: Error-check qio_channel_socket_connect_sync() the same way
+   - i386/kvm/vmsr_energy: Plug memory leak on failure to connect socket
+   - qga: Fix truncated output handling in guest-exec status reporting
+   - qga-vss: Write hex value of error in log
+   - qga/installer: Remove QGA VSS if QGA installation failed
+   - hw/arm/stm32f205_soc: Don't leak TYPE_OR_IRQ objects
+   - qemu/atomic: Finish renaming atomic128-cas.h headers
+   - scripts/kernel-doc: Avoid new Perl precedence warning
+   - target/arm: Trap PMCR when MDCR_EL2.TPMCR is set
+   - hw/intc/arm_gicv3_kvm: preserve pending interrupts during cpr
+   - linux-user: Add strace for rseq
+   - i386/tcg/svm: fix incorrect canonicalization
+   - python: mkvenv: fix messages printed by mkvenv
+   - hw/uefi: open json file in binary mode
+   - hw/uefi: check access for first variable
+   - hw/uefi: return success for notifications
+   - hw/uefi: clear uefi-vars buffer in uefi_vars_write callback
+   - mkvenv: Support pip 25.2
+   - hw/sd/ssi-sd: Return noise (dummy byte) when no card connected
+   - qemu-iotests: Ignore indentation in Killed messages
+   - rbd: Fix .bdrv_get_specific_info implementation
+   - hw/nvme: cap MDTS value for internal limitation
+   - hw/nvme: revert CMIC behavior
+   - hw/nvme: fix namespace attachment
+   - target/loongarch: Fix [X]VLDI raising exception incorrectly
+   - ui/curses: Fix infinite loop on windows
+   - ppc/xive2: Fix treatment of PIPR in CPPR update
+   - ppc/xive2: Fix irq preempted by lower priority group irq
+   - ppc/xive2: Reset Generation Flipped bit on END Cache Watch
+   - ppc/xive: Fix PHYS NSR ring matching
+   - ppc/xive2: fix context push calculation of IPB priority
+   - ppc/xive2: Remote VSDs need to match on forwarding address
+   - ppc/xive2: Fix calculation of END queue sizes
+   - ppc/xive: Report access size in XIVE TM operation error logs
+   - ppc/xive: Fix xive trace event output
+   - target/i386/cpu: Move addressable ID encoding out of compat property
+     in CPUID[0x1]
+   - i386/cpu: Fix cpu number overflow in CPUID.01H.EBX[23:16]
+   - i386/cpu: Fix number of addressable IDs field for CPUID.01H.EBX[23:16]
+   - i386/cpu: Move adjustment of CPUID_EXT_PDCM before feature_dependencies[]
+     check
+   - Revert "i386/cpu: Fix cpu number overflow in CPUID.01H.EBX[23:16]"
+     (The 5 changes above Closes: #1095935 in 10.0.x)
+   - qga: correctly write to /sys/power/state on linux
+     (Closes: #1108387)
+   - scripts/make-release: Go back to cloning all the EDK2 submodules
+   - target/arm: add support for 64-bit PMCCNTR in AArch32 mode
+   - hw/ssi/aspeed_smc: Fix incorrect FMC_WDT2 register read on AST1030
+   - target/arm: Fix handling of setting SVE registers from gdb
+   - target/arm: Fix big-endian handling of NEON gdb remote debugging
+   - hw/intc/arm_gicv3_kvm: Write all 1's to clear enable/active
+   - hw/i386/amd_iommu: Move IOAPIC memory region initialization to the end
+   - intel_iommu: Allow both Status Write and Interrupt Flag in QI wait
+   - pcie_sriov: Fix configuration and state synchronization
+   - virtio-net: Fix VLAN filter table reset timing
+   - vhost: Do not abort on log-stop error
+   - vhost: Do not abort on log-start error
+   - virtio: fix off-by-one and invalid access in virtqueue_ordered_fill
+   - target/loongarch: Fix valid virtual address checking
+   - target/riscv: Restrict midelegh access to S-mode harts
+   - target/riscv: Restrict mideleg/medeleg/medelegh access to S-mode harts
+   - intc/riscv_aplic: Fix target register read when source is inactive
+   - target/riscv: Fix pmp range wraparound on zero
+   - target/riscv: Fix exception type when VU accesses supervisor CSRs
+   - target/riscv: do not call GETPC() in check_ret_from_m_mode()
+   - linux-user/strace.list: add riscv_hwprobe entry
+   - roms/Makefile: fix npcmNxx_bootrom build rules
+   - system/physmem: fix use-after-free with dispatch
+   - hw/net/cadence_gem: fix register mask initialization
+   - target/mips: Only update MVPControl.EVP bit if executed by master VPE
+   - docs/user: clarify user-mode expects the same OS
+   - linux-user/aarch64: Support TPIDR2_MAGIC signal frame record
+   - linux-user/aarch64: Clear TPIDR2_EL0 when delivering signals
+   - target/i386: fix width of third operand of VINSERTx128
+   - hw/display/qxl-render.c: fix qxl_unpack_chunks() chunk size calculation
+   - host-utils: Drop workaround for buggy Apple Clang __builtin_subcll()
+  * drop patches included upstream:
+   - hw-display-qxl-render.c-fix-qxl_unpack_chunks-chunk-.patch
+   - pcie_sriov-Fix-configuration-and-state-synchronizati.patch
+   - system-physmem-fix-use-after-free-with-dispatch.patch
+
+ -- Michael Tokarev <mjt@tls.msk.ru>  Wed, 10 Sep 2025 09:50:46 +0300
+
 qemu (1:10.0.3+ds-0+deb13u1) trixie; urgency=medium
 
   * new upstream stable/bugfix release:
diff -Nru qemu-10.0.3+ds/debian/control.mk qemu-10.0.4+ds/debian/control.mk
--- qemu-10.0.3+ds/debian/control.mk	2025-08-21 18:23:38.000000000 +0300
+++ qemu-10.0.4+ds/debian/control.mk	2025-09-10 09:50:46.000000000 +0300
@@ -9,7 +9,7 @@
 
 # since some files and/or lists differ from version to version,
 # ensure we have the expected qemu version, or else scream loudly
-checked-version := 10.0.3+ds
+checked-version := 10.0.4+ds
 # version of last vdso change for d/control Depends field:
 vdso-version := 1:9.2.0~rc3+ds-1~
 
diff -Nru qemu-10.0.3+ds/debian/patches/hw-display-qxl-render.c-fix-qxl_unpack_chunks-chunk-.patch qemu-10.0.4+ds/debian/patches/hw-display-qxl-render.c-fix-qxl_unpack_chunks-chunk-.patch
--- qemu-10.0.3+ds/debian/patches/hw-display-qxl-render.c-fix-qxl_unpack_chunks-chunk-.patch	2025-08-21 18:23:38.000000000 +0300
+++ qemu-10.0.4+ds/debian/patches/hw-display-qxl-render.c-fix-qxl_unpack_chunks-chunk-.patch	1970-01-01 03:00:00.000000000 +0300
@@ -1,51 +0,0 @@
-From: Michael Tokarev <mjt@tls.msk.ru>
-Date: Fri, 21 Feb 2025 16:34:52 +0300
-Subject: hw/display/qxl-render.c: fix qxl_unpack_chunks() chunk size calculation
-Forwarded: https://lore.kernel.org/qemu-devel/20250221134856.478806-1-mjt@tls.msk.ru/T/#u
-Bug: https://gitlab.com/qemu-project/qemu/-/issues/1628
-
-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
-Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
----
- 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;
--- 
-2.39.5
-
diff -Nru qemu-10.0.3+ds/debian/patches/pcie_sriov-Fix-configuration-and-state-synchronizati.patch qemu-10.0.4+ds/debian/patches/pcie_sriov-Fix-configuration-and-state-synchronizati.patch
--- qemu-10.0.3+ds/debian/patches/pcie_sriov-Fix-configuration-and-state-synchronizati.patch	2025-08-21 18:23:38.000000000 +0300
+++ qemu-10.0.4+ds/debian/patches/pcie_sriov-Fix-configuration-and-state-synchronizati.patch	1970-01-01 03:00:00.000000000 +0300
@@ -1,122 +0,0 @@
-From: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
-Date: Sun, 27 Jul 2025 15:50:08 +0900
-Subject: pcie_sriov: Fix configuration and state synchronization
-Origin: upstream, https://gitlab.com/qemu-project/qemu/-/commit/cad9aa6fbdccd95e56e10cfa57c354a20a333717
-Forwarded: not-needed
-Bug-Debian: https://bugs.debian.org/1109989
-
-Fix issues in PCIe SR-IOV configuration register handling that caused
-inconsistent internal state due to improper write mask handling and
-incorrect migration behavior.
-
-Two main problems were identified:
-
-1. VF Enable bit write mask handling:
-   pcie_sriov_config_write() incorrectly assumed that its val parameter
-   was already masked, causing it to ignore the actual write mask.
-   This led to the VF Enable bit being processed even when masked,
-   resulting in incorrect VF registration/unregistration. It is
-   identified as CVE-2025-54567.
-
-2. Migration state inconsistency:
-   pcie_sriov_pf_post_load() unconditionally called register_vfs()
-   regardless of the VF Enable bit state, creating inconsistent
-   internal state when VFs should not be enabled. Additionally,
-   it failed to properly update the NumVFs write mask based on
-   the current configuration. It is identified as CVE-2025-54566.
-
-Root cause analysis revealed that both functions relied on incorrect
-special-case assumptions instead of properly reading and consuming
-the actual configuration values. This change introduces a unified
-consume_config() function that reads actual configuration values and
-synchronize the internal state without special-case assumptions.
-
-The solution only adds register read overhead in non-hot-path code
-while ensuring correct SR-IOV state management across configuration
-writes and migration scenarios.
-
-Fixes: 5e7dd17e4348 ("pcie_sriov: Remove num_vfs from PCIESriovPF")
-Fixes: f9efcd47110d ("pcie_sriov: Register VFs after migration")
-Fixes: CVE-2025-54566
-Fixes: CVE-2025-54567
-Cc: qemu-stable@nongnu.org
-Reported-by: Corentin BAYET <corentin.bayet@reversetactics.com>
-Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
-Message-Id: <20250727-wmask-v2-1-394910b1c0b6@rsg.ci.i.u-tokyo.ac.jp>
-Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
-Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-(cherry picked from commit cad9aa6fbdccd95e56e10cfa57c354a20a333717)
-(Mjt: context fix)
-Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
----
- hw/pci/pcie_sriov.c | 42 +++++++++++++++++++++++-------------------
- 1 file changed, 23 insertions(+), 19 deletions(-)
-
-diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
-index 1eb4358256..dd4fbaea46 100644
---- a/hw/pci/pcie_sriov.c
-+++ b/hw/pci/pcie_sriov.c
-@@ -211,6 +211,27 @@ static void unregister_vfs(PCIDevice *dev)
-     pci_set_word(dev->wmask + dev->exp.sriov_cap + PCI_SRIOV_NUM_VF, 0xffff);
- }
- 
-+static void consume_config(PCIDevice *dev)
-+{
-+    uint8_t *cfg = dev->config + dev->exp.sriov_cap;
-+
-+    if (pci_get_word(cfg + PCI_SRIOV_CTRL) & PCI_SRIOV_CTRL_VFE) {
-+        register_vfs(dev);
-+    } else {
-+        uint8_t *wmask = dev->wmask + dev->exp.sriov_cap;
-+        uint16_t num_vfs = pci_get_word(cfg + PCI_SRIOV_NUM_VF);
-+        uint16_t wmask_val = PCI_SRIOV_CTRL_MSE | PCI_SRIOV_CTRL_ARI;
-+
-+        unregister_vfs(dev);
-+
-+        if (num_vfs <= pci_get_word(cfg + PCI_SRIOV_TOTAL_VF)) {
-+            wmask_val |= PCI_SRIOV_CTRL_VFE;
-+        }
-+
-+        pci_set_word(wmask + PCI_SRIOV_CTRL, wmask_val);
-+    }
-+}
-+
- void pcie_sriov_config_write(PCIDevice *dev, uint32_t address,
-                              uint32_t val, int len)
- {
-@@ -228,30 +249,13 @@ void pcie_sriov_config_write(PCIDevice *dev, uint32_t address,
-     trace_sriov_config_write(dev->name, PCI_SLOT(dev->devfn),
-                              PCI_FUNC(dev->devfn), off, val, len);
- 
--    if (range_covers_byte(off, len, PCI_SRIOV_CTRL)) {
--        if (val & PCI_SRIOV_CTRL_VFE) {
--            register_vfs(dev);
--        } else {
--            unregister_vfs(dev);
--        }
--    } else if (range_covers_byte(off, len, PCI_SRIOV_NUM_VF)) {
--        uint8_t *cfg = dev->config + sriov_cap;
--        uint8_t *wmask = dev->wmask + sriov_cap;
--        uint16_t num_vfs = pci_get_word(cfg + PCI_SRIOV_NUM_VF);
--        uint16_t wmask_val = PCI_SRIOV_CTRL_MSE | PCI_SRIOV_CTRL_ARI;
--
--        if (num_vfs <= pci_get_word(cfg + PCI_SRIOV_TOTAL_VF)) {
--            wmask_val |= PCI_SRIOV_CTRL_VFE;
--        }
--
--        pci_set_word(wmask + PCI_SRIOV_CTRL, wmask_val);
--    }
-+    consume_config(dev);
- }
- 
- void pcie_sriov_pf_post_load(PCIDevice *dev)
- {
-     if (dev->exp.sriov_cap) {
--        register_vfs(dev);
-+        consume_config(dev);
-     }
- }
- 
--- 
-2.47.2
-
diff -Nru qemu-10.0.3+ds/debian/patches/series qemu-10.0.4+ds/debian/patches/series
--- qemu-10.0.3+ds/debian/patches/series	2025-08-21 18:23:38.000000000 +0300
+++ qemu-10.0.4+ds/debian/patches/series	2025-09-10 09:50:46.000000000 +0300
@@ -15,6 +15,3 @@
 slof-ensure-ld-is-called-with-C-locale.patch
 qemu-img-options.patch
 disable-pycotap.patch
-hw-display-qxl-render.c-fix-qxl_unpack_chunks-chunk-.patch
-system-physmem-fix-use-after-free-with-dispatch.patch
-pcie_sriov-Fix-configuration-and-state-synchronizati.patch
diff -Nru qemu-10.0.3+ds/debian/patches/system-physmem-fix-use-after-free-with-dispatch.patch qemu-10.0.4+ds/debian/patches/system-physmem-fix-use-after-free-with-dispatch.patch
--- qemu-10.0.3+ds/debian/patches/system-physmem-fix-use-after-free-with-dispatch.patch	2025-08-21 18:23:38.000000000 +0300
+++ qemu-10.0.4+ds/debian/patches/system-physmem-fix-use-after-free-with-dispatch.patch	1970-01-01 03:00:00.000000000 +0300
@@ -1,126 +0,0 @@
-From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
-Subject: system/physmem: fix use-after-free with dispatch
-Date: Thu, 24 Jul 2025 09:11:42 -0700
-Message-ID: <20250724161142.2803091-1-pierrick.bouvier@linaro.org>
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-Bug-Debian: https://bugs.debian.org/1106792
-Origin: upstream, https://lore.kernel.org/qemu-devel/afddf3fc-5561-40b4-b61c-1301b079b0b8@tls.msk.ru/T/#t
-Forwarded: not-needed
-
-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 this patch [1] 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
-
-Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3040
-Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
-Reviewed-by: Richard Henderson <richard.henderson@linaro.org> 
-Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
-Tested-by: Michael Tokarev <mjt@tls.msk.ru>
----
- system/physmem.c | 15 +++------------
- 1 file changed, 3 insertions(+), 12 deletions(-)
-
-diff --git a/system/physmem.c b/system/physmem.c
-index 130c148ffb5..e5dd760e0bc 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.
-      *
--- 
-2.47.2
-
-
diff -Nru qemu-10.0.3+ds/VERSION qemu-10.0.4+ds/VERSION
--- qemu-10.0.3+ds/VERSION	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/VERSION	2025-09-09 19:21:41.000000000 +0300
@@ -1 +1 @@
-10.0.3
+10.0.4
diff -Nru qemu-10.0.3+ds/block/curl.c qemu-10.0.4+ds/block/curl.c
--- qemu-10.0.3+ds/block/curl.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/block/curl.c	2025-09-09 19:21:41.000000000 +0300
@@ -162,13 +162,9 @@
 static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
                         void *userp, void *sp)
 {
-    BDRVCURLState *s;
-    CURLState *state = NULL;
+    BDRVCURLState *s = userp;
     CURLSocket *socket;
 
-    curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **)&state);
-    s = state->s;
-
     socket = g_hash_table_lookup(s->sockets, GINT_TO_POINTER(fd));
     if (!socket) {
         socket = g_new0(CURLSocket, 1);
@@ -605,6 +601,7 @@
     assert(!s->multi);
     s->multi = curl_multi_init();
     s->aio_context = new_context;
+    curl_multi_setopt(s->multi, CURLMOPT_SOCKETDATA, s);
     curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb);
     curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, s);
     curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, curl_timer_cb);
diff -Nru qemu-10.0.3+ds/block/rbd.c qemu-10.0.4+ds/block/rbd.c
--- qemu-10.0.3+ds/block/rbd.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/block/rbd.c	2025-09-09 19:21:41.000000000 +0300
@@ -99,6 +99,14 @@
     char *namespace;
     uint64_t image_size;
     uint64_t object_size;
+
+    /*
+     * If @bs->encrypted is true, this is the encryption format actually loaded
+     * at the librbd level. If it is false, it is the result of probing.
+     * RBD_IMAGE_ENCRYPTION_FORMAT__MAX means that encryption is not enabled and
+     * probing didn't find any known encryption header either.
+     */
+    RbdImageEncryptionFormat encryption_format;
 } BDRVRBDState;
 
 typedef struct RBDTask {
@@ -471,10 +479,12 @@
     return 0;
 }
 
-static int qemu_rbd_encryption_load(rbd_image_t image,
+static int qemu_rbd_encryption_load(BlockDriverState *bs,
+                                    rbd_image_t image,
                                     RbdEncryptionOptions *encrypt,
                                     Error **errp)
 {
+    BDRVRBDState *s = bs->opaque;
     int r = 0;
     g_autofree char *passphrase = NULL;
     rbd_encryption_luks1_format_options_t luks_opts;
@@ -545,15 +555,19 @@
         error_setg_errno(errp, -r, "encryption load fail");
         return r;
     }
+    bs->encrypted = true;
+    s->encryption_format = encrypt->format;
 
     return 0;
 }
 
 #ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
-static int qemu_rbd_encryption_load2(rbd_image_t image,
+static int qemu_rbd_encryption_load2(BlockDriverState *bs,
+                                     rbd_image_t image,
                                      RbdEncryptionOptions *encrypt,
                                      Error **errp)
 {
+    BDRVRBDState *s = bs->opaque;
     int r = 0;
     int encrypt_count = 1;
     int i;
@@ -639,6 +653,8 @@
         error_setg_errno(errp, -r, "layered encryption load fail");
         goto exit;
     }
+    bs->encrypted = true;
+    s->encryption_format = encrypt->format;
 
 exit:
     for (i = 0; i < encrypt_count; ++i) {
@@ -672,6 +688,45 @@
 #endif
 #endif
 
+/*
+ * For an image without encryption enabled on the rbd layer, probe the start of
+ * the image if it could be opened as an encrypted image so that we can display
+ * it when the user queries the node (most importantly in qemu-img).
+ *
+ * If the guest writes an encryption header to its disk after this probing, this
+ * won't be reflected when queried, but that's okay. There is no reason why the
+ * user should want to apply encryption at the rbd level while the image is
+ * still in use. This is just guest data.
+ */
+static void qemu_rbd_encryption_probe(BlockDriverState *bs)
+{
+    BDRVRBDState *s = bs->opaque;
+    char buf[RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN] = {0};
+    int r;
+
+    assert(s->encryption_format == RBD_IMAGE_ENCRYPTION_FORMAT__MAX);
+
+    r = rbd_read(s->image, 0,
+                 RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN, buf);
+    if (r < RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) {
+        return;
+    }
+
+    if (memcmp(buf, rbd_luks_header_verification,
+               RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
+        s->encryption_format = RBD_IMAGE_ENCRYPTION_FORMAT_LUKS;
+    } else if (memcmp(buf, rbd_luks2_header_verification,
+               RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
+        s->encryption_format = RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
+    } else if (memcmp(buf, rbd_layered_luks_header_verification,
+               RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
+        s->encryption_format = RBD_IMAGE_ENCRYPTION_FORMAT_LUKS;
+    } else if (memcmp(buf, rbd_layered_luks2_header_verification,
+               RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
+        s->encryption_format = RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
+    }
+}
+
 /* FIXME Deprecate and remove keypairs or make it available in QMP. */
 static int qemu_rbd_do_create(BlockdevCreateOptions *options,
                               const char *keypairs, const char *password_secret,
@@ -1134,17 +1189,18 @@
         goto failed_open;
     }
 
+    s->encryption_format = RBD_IMAGE_ENCRYPTION_FORMAT__MAX;
     if (opts->encrypt) {
 #ifdef LIBRBD_SUPPORTS_ENCRYPTION
         if (opts->encrypt->parent) {
 #ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
-            r = qemu_rbd_encryption_load2(s->image, opts->encrypt, errp);
+            r = qemu_rbd_encryption_load2(bs, s->image, opts->encrypt, errp);
 #else
             r = -ENOTSUP;
             error_setg(errp, "RBD library does not support layered encryption");
 #endif
         } else {
-            r = qemu_rbd_encryption_load(s->image, opts->encrypt, errp);
+            r = qemu_rbd_encryption_load(bs, s->image, opts->encrypt, errp);
         }
         if (r < 0) {
             goto failed_post_open;
@@ -1154,6 +1210,8 @@
         error_setg(errp, "RBD library does not support image encryption");
         goto failed_post_open;
 #endif
+    } else {
+        qemu_rbd_encryption_probe(bs);
     }
 
     r = rbd_stat(s->image, &info, sizeof(info));
@@ -1413,17 +1471,6 @@
 {
     BDRVRBDState *s = bs->opaque;
     ImageInfoSpecific *spec_info;
-    char buf[RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN] = {0};
-    int r;
-
-    if (s->image_size >= RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) {
-        r = rbd_read(s->image, 0,
-                     RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN, buf);
-        if (r < 0) {
-            error_setg_errno(errp, -r, "cannot read image start for probe");
-            return NULL;
-        }
-    }
 
     spec_info = g_new(ImageInfoSpecific, 1);
     *spec_info = (ImageInfoSpecific){
@@ -1431,28 +1478,13 @@
         .u.rbd.data = g_new0(ImageInfoSpecificRbd, 1),
     };
 
-    if (memcmp(buf, rbd_luks_header_verification,
-               RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
-        spec_info->u.rbd.data->encryption_format =
-                RBD_IMAGE_ENCRYPTION_FORMAT_LUKS;
-        spec_info->u.rbd.data->has_encryption_format = true;
-    } else if (memcmp(buf, rbd_luks2_header_verification,
-               RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
-        spec_info->u.rbd.data->encryption_format =
-                RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
-        spec_info->u.rbd.data->has_encryption_format = true;
-    } else if (memcmp(buf, rbd_layered_luks_header_verification,
-               RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
-        spec_info->u.rbd.data->encryption_format =
-                RBD_IMAGE_ENCRYPTION_FORMAT_LUKS;
-        spec_info->u.rbd.data->has_encryption_format = true;
-    } else if (memcmp(buf, rbd_layered_luks2_header_verification,
-               RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
-        spec_info->u.rbd.data->encryption_format =
-                RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
-        spec_info->u.rbd.data->has_encryption_format = true;
+    if (s->encryption_format == RBD_IMAGE_ENCRYPTION_FORMAT__MAX) {
+        assert(!bs->encrypted);
     } else {
-        spec_info->u.rbd.data->has_encryption_format = false;
+        ImageInfoSpecificRbd *rbd_info = spec_info->u.rbd.data;
+
+        rbd_info->has_encryption_format = true;
+        rbd_info->encryption_format = s->encryption_format;
     }
 
     return spec_info;
diff -Nru qemu-10.0.3+ds/docs/user/index.rst qemu-10.0.4+ds/docs/user/index.rst
--- qemu-10.0.3+ds/docs/user/index.rst	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/docs/user/index.rst	2025-09-09 19:21:41.000000000 +0300
@@ -5,8 +5,9 @@
 -------------------
 
 This section of the manual is the overall guide for users using QEMU
-for user-mode emulation.  In this mode, QEMU can launch
-processes compiled for one CPU on another CPU.
+for user-mode emulation. In this mode, QEMU can launch programs
+compiled for one CPU architecture on the same Operating System (OS)
+but running on a different CPU architecture.
 
 .. toctree::
    :maxdepth: 2
diff -Nru qemu-10.0.3+ds/host/include/aarch64/host/atomic128-cas.h qemu-10.0.4+ds/host/include/aarch64/host/atomic128-cas.h
--- qemu-10.0.3+ds/host/include/aarch64/host/atomic128-cas.h	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/host/include/aarch64/host/atomic128-cas.h	1970-01-01 03:00:00.000000000 +0300
@@ -1,45 +0,0 @@
-/*
- * SPDX-License-Identifier: GPL-2.0-or-later
- * Compare-and-swap for 128-bit atomic operations, AArch64 version.
- *
- * Copyright (C) 2018, 2023 Linaro, Ltd.
- *
- * See docs/devel/atomics.rst for discussion about the guarantees each
- * atomic primitive is meant to provide.
- */
-
-#ifndef AARCH64_ATOMIC128_CAS_H
-#define AARCH64_ATOMIC128_CAS_H
-
-/* Through gcc 10, aarch64 has no support for 128-bit atomics.  */
-#if defined(CONFIG_ATOMIC128) || defined(CONFIG_CMPXCHG128)
-#include "host/include/generic/host/atomic128-cas.h.inc"
-#else
-static inline Int128 atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new)
-{
-    uint64_t cmpl = int128_getlo(cmp), cmph = int128_gethi(cmp);
-    uint64_t newl = int128_getlo(new), newh = int128_gethi(new);
-    uint64_t oldl, oldh;
-    uint32_t tmp;
-
-    asm("0: ldaxp %[oldl], %[oldh], %[mem]\n\t"
-        "cmp %[oldl], %[cmpl]\n\t"
-        "ccmp %[oldh], %[cmph], #0, eq\n\t"
-        "b.ne 1f\n\t"
-        "stlxp %w[tmp], %[newl], %[newh], %[mem]\n\t"
-        "cbnz %w[tmp], 0b\n"
-        "1:"
-        : [mem] "+m"(*ptr), [tmp] "=&r"(tmp),
-          [oldl] "=&r"(oldl), [oldh] "=&r"(oldh)
-        : [cmpl] "r"(cmpl), [cmph] "r"(cmph),
-          [newl] "r"(newl), [newh] "r"(newh)
-        : "memory", "cc");
-
-    return int128_make128(oldl, oldh);
-}
-
-# define CONFIG_CMPXCHG128 1
-# define HAVE_CMPXCHG128 1
-#endif
-
-#endif /* AARCH64_ATOMIC128_CAS_H */
diff -Nru qemu-10.0.3+ds/host/include/aarch64/host/atomic128-cas.h.inc qemu-10.0.4+ds/host/include/aarch64/host/atomic128-cas.h.inc
--- qemu-10.0.3+ds/host/include/aarch64/host/atomic128-cas.h.inc	1970-01-01 03:00:00.000000000 +0300
+++ qemu-10.0.4+ds/host/include/aarch64/host/atomic128-cas.h.inc	2025-09-09 19:21:41.000000000 +0300
@@ -0,0 +1,45 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Compare-and-swap for 128-bit atomic operations, AArch64 version.
+ *
+ * Copyright (C) 2018, 2023 Linaro, Ltd.
+ *
+ * See docs/devel/atomics.rst for discussion about the guarantees each
+ * atomic primitive is meant to provide.
+ */
+
+#ifndef AARCH64_ATOMIC128_CAS_H
+#define AARCH64_ATOMIC128_CAS_H
+
+/* Through gcc 10, aarch64 has no support for 128-bit atomics.  */
+#if defined(CONFIG_ATOMIC128) || defined(CONFIG_CMPXCHG128)
+#include "host/include/generic/host/atomic128-cas.h.inc"
+#else
+static inline Int128 atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new)
+{
+    uint64_t cmpl = int128_getlo(cmp), cmph = int128_gethi(cmp);
+    uint64_t newl = int128_getlo(new), newh = int128_gethi(new);
+    uint64_t oldl, oldh;
+    uint32_t tmp;
+
+    asm("0: ldaxp %[oldl], %[oldh], %[mem]\n\t"
+        "cmp %[oldl], %[cmpl]\n\t"
+        "ccmp %[oldh], %[cmph], #0, eq\n\t"
+        "b.ne 1f\n\t"
+        "stlxp %w[tmp], %[newl], %[newh], %[mem]\n\t"
+        "cbnz %w[tmp], 0b\n"
+        "1:"
+        : [mem] "+m"(*ptr), [tmp] "=&r"(tmp),
+          [oldl] "=&r"(oldl), [oldh] "=&r"(oldh)
+        : [cmpl] "r"(cmpl), [cmph] "r"(cmph),
+          [newl] "r"(newl), [newh] "r"(newh)
+        : "memory", "cc");
+
+    return int128_make128(oldl, oldh);
+}
+
+# define CONFIG_CMPXCHG128 1
+# define HAVE_CMPXCHG128 1
+#endif
+
+#endif /* AARCH64_ATOMIC128_CAS_H */
diff -Nru qemu-10.0.3+ds/hw/arm/stm32f205_soc.c qemu-10.0.4+ds/hw/arm/stm32f205_soc.c
--- qemu-10.0.3+ds/hw/arm/stm32f205_soc.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/arm/stm32f205_soc.c	2025-09-09 19:21:41.000000000 +0300
@@ -66,7 +66,7 @@
                                 TYPE_STM32F2XX_TIMER);
     }
 
-    s->adc_irqs = OR_IRQ(object_new(TYPE_OR_IRQ));
+    object_initialize_child(obj, "adc-irq-orgate", &s->adc_irqs, TYPE_OR_IRQ);
 
     for (i = 0; i < STM_NUM_ADCS; i++) {
         object_initialize_child(obj, "adc[*]", &s->adc[i], TYPE_STM32F2XX_ADC);
@@ -171,12 +171,12 @@
     }
 
     /* ADC 1 to 3 */
-    object_property_set_int(OBJECT(s->adc_irqs), "num-lines", STM_NUM_ADCS,
+    object_property_set_int(OBJECT(&s->adc_irqs), "num-lines", STM_NUM_ADCS,
                             &error_abort);
-    if (!qdev_realize(DEVICE(s->adc_irqs), NULL, errp)) {
+    if (!qdev_realize(DEVICE(&s->adc_irqs), NULL, errp)) {
         return;
     }
-    qdev_connect_gpio_out(DEVICE(s->adc_irqs), 0,
+    qdev_connect_gpio_out(DEVICE(&s->adc_irqs), 0,
                           qdev_get_gpio_in(armv7m, ADC_IRQ));
 
     for (i = 0; i < STM_NUM_ADCS; i++) {
@@ -187,7 +187,7 @@
         busdev = SYS_BUS_DEVICE(dev);
         sysbus_mmio_map(busdev, 0, adc_addr[i]);
         sysbus_connect_irq(busdev, 0,
-                           qdev_get_gpio_in(DEVICE(s->adc_irqs), i));
+                           qdev_get_gpio_in(DEVICE(&s->adc_irqs), i));
     }
 
     /* SPI 1 and 2 */
diff -Nru qemu-10.0.3+ds/hw/display/qxl-render.c qemu-10.0.4+ds/hw/display/qxl-render.c
--- qemu-10.0.3+ds/hw/display/qxl-render.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/display/qxl-render.c	2025-09-09 19:21:41.000000000 +0300
@@ -222,6 +222,7 @@
     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 @@
         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;
diff -Nru qemu-10.0.3+ds/hw/gpio/pca9554.c qemu-10.0.4+ds/hw/gpio/pca9554.c
--- qemu-10.0.3+ds/hw/gpio/pca9554.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/gpio/pca9554.c	2025-09-09 19:21:41.000000000 +0300
@@ -177,7 +177,7 @@
     PCA9554State *s = PCA9554(obj);
     int pin, rc, val;
     uint8_t state, mask;
-    char *state_str;
+    g_autofree char *state_str = NULL;
 
     if (!visit_type_str(v, name, &state_str, errp)) {
         return;
diff -Nru qemu-10.0.3+ds/hw/i386/amd_iommu.c qemu-10.0.4+ds/hw/i386/amd_iommu.c
--- qemu-10.0.3+ds/hw/i386/amd_iommu.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/i386/amd_iommu.c	2025-09-09 19:21:41.000000000 +0300
@@ -1620,9 +1620,6 @@
         return;
     }
 
-    /* Pseudo address space under root PCI bus. */
-    x86ms->ioapic_as = amdvi_host_dma_iommu(bus, s, AMDVI_IOAPIC_SB_DEVID);
-
     /* set up MMIO */
     memory_region_init_io(&s->mr_mmio, OBJECT(s), &mmio_mem_ops, s,
                           "amdvi-mmio", AMDVI_MMIO_SIZE);
@@ -1645,6 +1642,9 @@
     memory_region_add_subregion_overlap(&s->mr_sys, AMDVI_INT_ADDR_FIRST,
                                         &s->mr_ir, 1);
 
+    /* Pseudo address space under root PCI bus. */
+    x86ms->ioapic_as = amdvi_host_dma_iommu(bus, s, AMDVI_IOAPIC_SB_DEVID);
+
     if (kvm_enabled() && x86ms->apic_id_limit > 255 && !s->xtsup) {
         error_report("AMD IOMMU with x2APIC configuration requires xtsup=on");
         exit(EXIT_FAILURE);
diff -Nru qemu-10.0.3+ds/hw/i386/intel_iommu.c qemu-10.0.4+ds/hw/i386/intel_iommu.c
--- qemu-10.0.3+ds/hw/i386/intel_iommu.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/i386/intel_iommu.c	2025-09-09 19:21:41.000000000 +0300
@@ -2830,6 +2830,7 @@
 {
     uint64_t mask[4] = {VTD_INV_DESC_WAIT_RSVD_LO, VTD_INV_DESC_WAIT_RSVD_HI,
                         VTD_INV_DESC_ALL_ONE, VTD_INV_DESC_ALL_ONE};
+    bool ret = true;
 
     if (!vtd_inv_desc_reserved_check(s, inv_desc, mask, false,
                                      __func__, "wait")) {
@@ -2841,8 +2842,6 @@
         uint32_t status_data = (uint32_t)(inv_desc->lo >>
                                VTD_INV_DESC_WAIT_DATA_SHIFT);
 
-        assert(!(inv_desc->lo & VTD_INV_DESC_WAIT_IF));
-
         /* FIXME: need to be masked with HAW? */
         dma_addr_t status_addr = inv_desc->hi;
         trace_vtd_inv_desc_wait_sw(status_addr, status_data);
@@ -2851,18 +2850,22 @@
                              &status_data, sizeof(status_data),
                              MEMTXATTRS_UNSPECIFIED)) {
             trace_vtd_inv_desc_wait_write_fail(inv_desc->hi, inv_desc->lo);
-            return false;
+            ret = false;
         }
-    } else if (inv_desc->lo & VTD_INV_DESC_WAIT_IF) {
+    }
+
+    if (inv_desc->lo & VTD_INV_DESC_WAIT_IF) {
         /* Interrupt flag */
         vtd_generate_completion_event(s);
-    } else {
+    }
+
+    if (!(inv_desc->lo & (VTD_INV_DESC_WAIT_IF | VTD_INV_DESC_WAIT_SW))) {
         error_report_once("%s: invalid wait desc: hi=%"PRIx64", lo=%"PRIx64
                           " (unknown type)", __func__, inv_desc->hi,
                           inv_desc->lo);
         return false;
     }
-    return true;
+    return ret;
 }
 
 static bool vtd_process_context_cache_desc(IntelIOMMUState *s,
diff -Nru qemu-10.0.3+ds/hw/intc/arm_gicv3_kvm.c qemu-10.0.4+ds/hw/intc/arm_gicv3_kvm.c
--- qemu-10.0.3+ds/hw/intc/arm_gicv3_kvm.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/intc/arm_gicv3_kvm.c	2025-09-09 19:21:41.000000000 +0300
@@ -30,6 +30,7 @@
 #include "gicv3_internal.h"
 #include "vgic_common.h"
 #include "migration/blocker.h"
+#include "migration/misc.h"
 #include "qom/object.h"
 #include "target/arm/cpregs.h"
 
@@ -294,7 +295,7 @@
          * the 1 bits.
          */
         if (clroffset != 0) {
-            reg = 0;
+            reg = ~0;
             kvm_gicd_access(s, clroffset, &reg, true);
             clroffset += 4;
         }
@@ -777,6 +778,17 @@
     }
 }
 
+static int kvm_arm_gicv3_notifier(NotifierWithReturn *notifier,
+                                  MigrationEvent *e, Error **errp)
+{
+    if (e->type == MIG_EVENT_PRECOPY_DONE) {
+        GICv3State *s = container_of(notifier, GICv3State, cpr_notifier);
+        return kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
+                                 KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES,
+                                 NULL, true, errp);
+    }
+    return 0;
+}
 
 static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
 {
@@ -890,6 +902,9 @@
     if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
                               KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES)) {
         qemu_add_vm_change_state_handler(vm_change_state_handler, s);
+        migration_add_notifier_mode(&s->cpr_notifier,
+                                    kvm_arm_gicv3_notifier,
+                                    MIG_MODE_CPR_TRANSFER);
     }
 }
 
diff -Nru qemu-10.0.3+ds/hw/intc/pnv_xive2.c qemu-10.0.4+ds/hw/intc/pnv_xive2.c
--- qemu-10.0.3+ds/hw/intc/pnv_xive2.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/intc/pnv_xive2.c	2025-09-09 19:21:41.000000000 +0300
@@ -101,12 +101,10 @@
 }
 
 /*
- * Remote access to controllers. HW uses MMIOs. For now, a simple scan
- * of the chips is good enough.
- *
- * TODO: Block scope support
+ * Remote access to INT controllers. HW uses MMIOs(?). For now, a simple
+ * scan of all the chips INT controller is good enough.
  */
-static PnvXive2 *pnv_xive2_get_remote(uint8_t blk)
+static PnvXive2 *pnv_xive2_get_remote(uint32_t vsd_type, hwaddr fwd_addr)
 {
     PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
     int i;
@@ -115,10 +113,23 @@
         Pnv10Chip *chip10 = PNV10_CHIP(pnv->chips[i]);
         PnvXive2 *xive = &chip10->xive;
 
-        if (pnv_xive2_block_id(xive) == blk) {
+        /*
+         * Is this the XIVE matching the forwarded VSD address is for this
+         * VSD type
+         */
+        if ((vsd_type == VST_ESB   && fwd_addr == xive->esb_base) ||
+            (vsd_type == VST_END   && fwd_addr == xive->end_base)  ||
+            ((vsd_type == VST_NVP ||
+              vsd_type == VST_NVG) && fwd_addr == xive->nvpg_base) ||
+            (vsd_type == VST_NVC   && fwd_addr == xive->nvc_base)) {
             return xive;
         }
     }
+
+    qemu_log_mask(LOG_GUEST_ERROR,
+                 "XIVE: >>>>> %s vsd_type %u  fwd_addr 0x%"HWADDR_PRIx
+                  " NOT FOUND\n",
+                  __func__, vsd_type, fwd_addr);
     return NULL;
 }
 
@@ -251,8 +262,7 @@
 
     /* Remote VST access */
     if (GETFIELD(VSD_MODE, vsd) == VSD_MODE_FORWARD) {
-        xive = pnv_xive2_get_remote(blk);
-
+        xive = pnv_xive2_get_remote(type, (vsd & VSD_ADDRESS_MASK));
         return xive ? pnv_xive2_vst_addr(xive, type, blk, idx) : 0;
     }
 
@@ -1315,10 +1325,11 @@
     case VC_ENDC_WATCH3_DATA0:
         /*
          * Load DATA registers from cache with data requested by the
-         * SPEC register
+         * SPEC register.  Clear gen_flipped bit in word 1.
          */
         watch_engine = (offset - VC_ENDC_WATCH0_DATA0) >> 6;
         pnv_xive2_end_cache_load(xive, watch_engine);
+        xive->vc_regs[reg] &= ~(uint64_t)END2_W1_GEN_FLIPPED;
         val = xive->vc_regs[reg];
         break;
 
diff -Nru qemu-10.0.3+ds/hw/intc/riscv_aplic.c qemu-10.0.4+ds/hw/intc/riscv_aplic.c
--- qemu-10.0.3+ds/hw/intc/riscv_aplic.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/intc/riscv_aplic.c	2025-09-09 19:21:41.000000000 +0300
@@ -628,7 +628,7 @@
 
 static uint64_t riscv_aplic_read(void *opaque, hwaddr addr, unsigned size)
 {
-    uint32_t irq, word, idc;
+    uint32_t irq, word, idc, sm;
     RISCVAPLICState *aplic = opaque;
 
     /* Reads must be 4 byte words */
@@ -696,6 +696,10 @@
     } else if ((APLIC_TARGET_BASE <= addr) &&
             (addr < (APLIC_TARGET_BASE + (aplic->num_irqs - 1) * 4))) {
         irq = ((addr - APLIC_TARGET_BASE) >> 2) + 1;
+        sm = aplic->sourcecfg[irq] & APLIC_SOURCECFG_SM_MASK;
+        if (sm == APLIC_SOURCECFG_SM_INACTIVE) {
+            return 0;
+        }
         return aplic->target[irq];
     } else if (!aplic->msimode && (APLIC_IDC_BASE <= addr) &&
             (addr < (APLIC_IDC_BASE + aplic->num_harts * APLIC_IDC_SIZE))) {
diff -Nru qemu-10.0.3+ds/hw/intc/trace-events qemu-10.0.4+ds/hw/intc/trace-events
--- qemu-10.0.3+ds/hw/intc/trace-events	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/intc/trace-events	2025-09-09 19:21:41.000000000 +0300
@@ -274,9 +274,9 @@
 kvm_xive_source_reset(uint32_t srcno) "IRQ 0x%x"
 
 # xive.c
-xive_tctx_accept(uint32_t index, uint8_t ring, uint8_t ipb, uint8_t pipr, uint8_t cppr, uint8_t nsr) "target=%d ring=0x%x IBP=0x%02x PIPR=0x%02x CPPR=0x%02x NSR=0x%02x ACK"
-xive_tctx_notify(uint32_t index, uint8_t ring, uint8_t ipb, uint8_t pipr, uint8_t cppr, uint8_t nsr) "target=%d ring=0x%x IBP=0x%02x PIPR=0x%02x CPPR=0x%02x NSR=0x%02x raise !"
-xive_tctx_set_cppr(uint32_t index, uint8_t ring, uint8_t ipb, uint8_t pipr, uint8_t cppr, uint8_t nsr) "target=%d ring=0x%x IBP=0x%02x PIPR=0x%02x new CPPR=0x%02x NSR=0x%02x"
+xive_tctx_accept(uint32_t index, uint8_t ring, uint8_t ipb, uint8_t pipr, uint8_t cppr, uint8_t nsr) "target=%d ring=0x%x IPB=0x%02x PIPR=0x%02x CPPR=0x%02x NSR=0x%02x ACK"
+xive_tctx_notify(uint32_t index, uint8_t ring, uint8_t ipb, uint8_t pipr, uint8_t cppr, uint8_t nsr) "target=%d ring=0x%x IPB=0x%02x PIPR=0x%02x CPPR=0x%02x NSR=0x%02x raise !"
+xive_tctx_set_cppr(uint32_t index, uint8_t ring, uint8_t ipb, uint8_t pipr, uint8_t cppr, uint8_t nsr) "target=%d ring=0x%x IPB=0x%02x PIPR=0x%02x new CPPR=0x%02x NSR=0x%02x"
 xive_source_esb_read(uint64_t addr, uint32_t srcno, uint64_t value) "@0x%"PRIx64" IRQ 0x%x val=0x%"PRIx64
 xive_source_esb_write(uint64_t addr, uint32_t srcno, uint64_t value) "@0x%"PRIx64" IRQ 0x%x val=0x%"PRIx64
 xive_router_end_notify(uint8_t end_blk, uint32_t end_idx, uint32_t end_data) "END 0x%02x/0x%04x -> enqueue 0x%08x"
diff -Nru qemu-10.0.3+ds/hw/intc/xive.c qemu-10.0.4+ds/hw/intc/xive.c
--- qemu-10.0.3+ds/hw/intc/xive.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/intc/xive.c	2025-09-09 19:21:41.000000000 +0300
@@ -54,7 +54,8 @@
         uint8_t *alt_regs;
 
         /* POOL interrupt uses IPB in QW2, POOL ring */
-        if ((ring == TM_QW3_HV_PHYS) && (nsr & (TM_QW3_NSR_HE_POOL << 6))) {
+        if ((ring == TM_QW3_HV_PHYS) &&
+            ((nsr & TM_QW3_NSR_HE) == (TM_QW3_NSR_HE_POOL << 6))) {
             alt_ring = TM_QW2_HV_POOL;
         } else {
             alt_ring = ring;
@@ -326,7 +327,7 @@
      */
     if (size < 4 || !mask || ring_offset == TM_QW0_USER) {
         qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid write access at TIMA @%"
-                      HWADDR_PRIx"\n", offset);
+                      HWADDR_PRIx" size %d\n", offset, size);
         return;
     }
 
@@ -357,7 +358,7 @@
      */
     if (size < 4 || !mask || ring_offset == TM_QW0_USER) {
         qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid read access at TIMA @%"
-                      HWADDR_PRIx"\n", offset);
+                      HWADDR_PRIx" size %d\n", offset, size);
         return -1;
     }
 
@@ -688,7 +689,7 @@
         xto = xive_tm_find_op(tctx->xptr, offset, size, true);
         if (!xto) {
             qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid write access at TIMA "
-                          "@%"HWADDR_PRIx"\n", offset);
+                          "@%"HWADDR_PRIx" size %d\n", offset, size);
         } else {
             xto->write_handler(xptr, tctx, offset, value, size);
         }
@@ -727,7 +728,7 @@
         xto = xive_tm_find_op(tctx->xptr, offset, size, false);
         if (!xto) {
             qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid read access to TIMA"
-                          "@%"HWADDR_PRIx"\n", offset);
+                          "@%"HWADDR_PRIx" size %d\n", offset, size);
             return -1;
         }
         ret = xto->read_handler(xptr, tctx, offset, size);
diff -Nru qemu-10.0.3+ds/hw/intc/xive2.c qemu-10.0.4+ds/hw/intc/xive2.c
--- qemu-10.0.3+ds/hw/intc/xive2.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/intc/xive2.c	2025-09-09 19:21:41.000000000 +0300
@@ -188,12 +188,27 @@
                            (uint32_t) xive_get_field64(EAS2_END_DATA, eas->w));
 }
 
+#define XIVE2_QSIZE_CHUNK_CL    128
+#define XIVE2_QSIZE_CHUNK_4k   4096
+/* Calculate max number of queue entries for an END */
+static uint32_t xive2_end_get_qentries(Xive2End *end)
+{
+    uint32_t w3 = end->w3;
+    uint32_t qsize = xive_get_field32(END2_W3_QSIZE, w3);
+    if (xive_get_field32(END2_W3_CL, w3)) {
+        g_assert(qsize <= 4);
+        return (XIVE2_QSIZE_CHUNK_CL << qsize) / sizeof(uint32_t);
+    } else {
+        g_assert(qsize <= 12);
+        return (XIVE2_QSIZE_CHUNK_4k << qsize) / sizeof(uint32_t);
+    }
+}
+
 void xive2_end_queue_pic_print_info(Xive2End *end, uint32_t width, GString *buf)
 {
     uint64_t qaddr_base = xive2_end_qaddr(end);
-    uint32_t qsize = xive_get_field32(END2_W3_QSIZE, end->w3);
     uint32_t qindex = xive_get_field32(END2_W1_PAGE_OFF, end->w1);
-    uint32_t qentries = 1 << (qsize + 10);
+    uint32_t qentries = xive2_end_get_qentries(end);
     int i;
 
     /*
@@ -223,8 +238,7 @@
     uint64_t qaddr_base = xive2_end_qaddr(end);
     uint32_t qindex = xive_get_field32(END2_W1_PAGE_OFF, end->w1);
     uint32_t qgen = xive_get_field32(END2_W1_GENERATION, end->w1);
-    uint32_t qsize = xive_get_field32(END2_W3_QSIZE, end->w3);
-    uint32_t qentries = 1 << (qsize + 10);
+    uint32_t qentries = xive2_end_get_qentries(end);
 
     uint32_t nvx_blk = xive_get_field32(END2_W6_VP_BLOCK, end->w6);
     uint32_t nvx_idx = xive_get_field32(END2_W6_VP_OFFSET, end->w6);
@@ -341,13 +355,12 @@
 static void xive2_end_enqueue(Xive2End *end, uint32_t data)
 {
     uint64_t qaddr_base = xive2_end_qaddr(end);
-    uint32_t qsize = xive_get_field32(END2_W3_QSIZE, end->w3);
     uint32_t qindex = xive_get_field32(END2_W1_PAGE_OFF, end->w1);
     uint32_t qgen = xive_get_field32(END2_W1_GENERATION, end->w1);
 
     uint64_t qaddr = qaddr_base + (qindex << 2);
     uint32_t qdata = cpu_to_be32((qgen << 31) | (data & 0x7fffffff));
-    uint32_t qentries = 1 << (qsize + 10);
+    uint32_t qentries = xive2_end_get_qentries(end);
 
     if (dma_memory_write(&address_space_memory, qaddr, &qdata, sizeof(qdata),
                          MEMTXATTRS_UNSPECIFIED)) {
@@ -361,8 +374,8 @@
         qgen ^= 1;
         end->w1 = xive_set_field32(END2_W1_GENERATION, end->w1, qgen);
 
-        /* TODO(PowerNV): reset GF bit on a cache watch operation */
-        end->w1 = xive_set_field32(END2_W1_GEN_FLIPPED, end->w1, qgen);
+        /* Set gen flipped to 1, it gets reset on a cache watch operation */
+        end->w1 = xive_set_field32(END2_W1_GEN_FLIPPED, end->w1, 1);
     }
     end->w1 = xive_set_field32(END2_W1_PAGE_OFF, end->w1, qindex);
 }
@@ -822,8 +835,9 @@
         nvp.w2 = xive_set_field32(NVP2_W2_IPB, nvp.w2, 0);
         xive2_router_write_nvp(xrtr, nvp_blk, nvp_idx, &nvp, 2);
     }
+    /* IPB bits in the backlog are merged with the TIMA IPB bits */
     regs[TM_IPB] |= ipb;
-    backlog_prio = xive_ipb_to_pipr(ipb);
+    backlog_prio = xive_ipb_to_pipr(regs[TM_IPB]);
     backlog_level = 0;
 
     first_group = xive_get_field32(NVP2_W0_PGOFIRST, nvp.w0);
@@ -981,7 +995,9 @@
             }
         }
     }
-    regs[TM_PIPR] = pipr_min;
+
+    /* PIPR should not be set to a value greater than CPPR */
+    regs[TM_PIPR] = (pipr_min > cppr) ? cppr : pipr_min;
 
     rc = xive2_tctx_get_nvp_indexes(tctx, ring_min, &nvp_blk, &nvp_idx);
     if (rc) {
@@ -1269,7 +1285,7 @@
      * priority to know if the thread can take the interrupt now or if
      * it is precluded.
      */
-    if (priority < alt_regs[TM_CPPR]) {
+    if (priority < alt_regs[TM_PIPR]) {
         return false;
     }
     return true;
diff -Nru qemu-10.0.3+ds/hw/net/cadence_gem.c qemu-10.0.4+ds/hw/net/cadence_gem.c
--- qemu-10.0.3+ds/hw/net/cadence_gem.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/net/cadence_gem.c	2025-09-09 19:21:41.000000000 +0300
@@ -1756,6 +1756,7 @@
         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 @@
 
     DB_PRINT("\n");
 
-    gem_init_register_masks(s);
     memory_region_init_io(&s->iomem, OBJECT(s), &gem_ops, s,
                           "enet", sizeof(s->regs));
 
diff -Nru qemu-10.0.3+ds/hw/net/e1000e_core.c qemu-10.0.4+ds/hw/net/e1000e_core.c
--- qemu-10.0.3+ds/hw/net/e1000e_core.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/net/e1000e_core.c	2025-09-09 19:21:41.000000000 +0300
@@ -341,11 +341,6 @@
 {
     uint32_t res;
 
-    if (msix_enabled(core->owner)) {
-        assert(core->delayed_causes == 0);
-        return 0;
-    }
-
     res = core->delayed_causes;
     core->delayed_causes = 0;
 
diff -Nru qemu-10.0.3+ds/hw/net/virtio-net.c qemu-10.0.4+ds/hw/net/virtio-net.c
--- qemu-10.0.3+ds/hw/net/virtio-net.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/net/virtio-net.c	2025-09-09 19:21:41.000000000 +0300
@@ -997,8 +997,9 @@
         vhost_net_save_acked_features(nc->peer);
     }
 
-    if (!virtio_has_feature(features, VIRTIO_NET_F_CTRL_VLAN)) {
-        memset(n->vlans, 0xff, MAX_VLAN >> 3);
+    if (virtio_has_feature(vdev->guest_features ^ features, VIRTIO_NET_F_CTRL_VLAN)) {
+        bool vlan = virtio_has_feature(features, VIRTIO_NET_F_CTRL_VLAN);
+        memset(n->vlans, vlan ? 0 : 0xff, MAX_VLAN >> 3);
     }
 
     if (virtio_has_feature(features, VIRTIO_NET_F_STANDBY)) {
@@ -3896,6 +3897,7 @@
     n->mac_table.macs = g_malloc0(MAC_TABLE_ENTRIES * ETH_ALEN);
 
     n->vlans = g_malloc0(MAX_VLAN >> 3);
+    memset(n->vlans, 0xff, MAX_VLAN >> 3);
 
     nc = qemu_get_queue(n->nic);
     nc->rxfilter_notify_enabled = 1;
@@ -3986,7 +3988,6 @@
     memset(n->mac_table.macs, 0, MAC_TABLE_ENTRIES * ETH_ALEN);
     memcpy(&n->mac[0], &n->nic->conf->macaddr, sizeof(n->mac));
     qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
-    memset(n->vlans, 0, MAX_VLAN >> 3);
 
     /* Flush any async TX */
     for (i = 0;  i < n->max_queue_pairs; i++) {
diff -Nru qemu-10.0.3+ds/hw/nvme/ctrl.c qemu-10.0.4+ds/hw/nvme/ctrl.c
--- qemu-10.0.3+ds/hw/nvme/ctrl.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/nvme/ctrl.c	2025-09-09 19:21:41.000000000 +0300
@@ -6816,7 +6816,7 @@
 
         switch (sel) {
         case NVME_NS_ATTACHMENT_ATTACH:
-            if (nvme_ns(n, nsid)) {
+            if (nvme_ns(ctrl, nsid)) {
                 return NVME_NS_ALREADY_ATTACHED | NVME_DNR;
             }
 
@@ -6824,7 +6824,7 @@
                 return NVME_NS_PRIVATE | NVME_DNR;
             }
 
-            if (!nvme_csi_supported(n, ns->csi)) {
+            if (!nvme_csi_supported(ctrl, ns->csi)) {
                 return NVME_IOCS_NOT_SUPPORTED | NVME_DNR;
             }
 
@@ -6834,6 +6834,10 @@
             break;
 
         case NVME_NS_ATTACHMENT_DETACH:
+            if (!nvme_ns(ctrl, nsid)) {
+                return NVME_NS_NOT_ATTACHED | NVME_DNR;
+            }
+
             nvme_detach_ns(ctrl, ns);
             nvme_update_dsm_limits(ctrl, NULL);
 
@@ -8335,6 +8339,11 @@
         host_memory_backend_set_mapped(n->pmr.dev, true);
     }
 
+    if (!n->params.mdts || ((1 << n->params.mdts) + 1) > IOV_MAX) {
+        error_setg(errp, "mdts exceeds IOV_MAX");
+        return false;
+    }
+
     if (n->params.zasl > n->params.mdts) {
         error_setg(errp, "zoned.zasl (Zone Append Size Limit) must be less "
                    "than or equal to mdts (Maximum Data Transfer Size)");
@@ -8776,7 +8785,7 @@
     uint8_t *pci_conf = pci_dev->config;
     uint64_t cap = ldq_le_p(&n->bar.cap);
     NvmeSecCtrlEntry *sctrl = nvme_sctrl(n);
-    uint32_t ctratt;
+    uint32_t ctratt = le32_to_cpu(id->ctratt);
     uint16_t oacs;
 
     memcpy(n->cse.acs, nvme_cse_acs_default, sizeof(n->cse.acs));
@@ -8794,10 +8803,11 @@
 
     id->oaes = cpu_to_le32(NVME_OAES_NS_ATTR);
 
-    ctratt = NVME_CTRATT_ELBAS;
+    ctratt |= NVME_CTRATT_ELBAS;
     if (n->params.ctratt.mem) {
         ctratt |= NVME_CTRATT_MEM;
     }
+    id->ctratt = cpu_to_le32(ctratt);
 
     id->rab = 6;
 
@@ -8880,17 +8890,6 @@
     id->psd[0].enlat = cpu_to_le32(0x10);
     id->psd[0].exlat = cpu_to_le32(0x4);
 
-    id->cmic |= NVME_CMIC_MULTI_CTRL;
-    ctratt |= NVME_CTRATT_ENDGRPS;
-
-    id->endgidmax = cpu_to_le16(0x1);
-
-    if (n->subsys->endgrp.fdp.enabled) {
-        ctratt |= NVME_CTRATT_FDPS;
-    }
-
-    id->ctratt = cpu_to_le32(ctratt);
-
     NVME_CAP_SET_MQES(cap, n->params.mqes);
     NVME_CAP_SET_CQR(cap, 1);
     NVME_CAP_SET_TO(cap, 0xf);
@@ -8923,6 +8922,20 @@
         }
 
         n->subsys = NVME_SUBSYS(dev);
+    } else {
+        NvmeIdCtrl *id = &n->id_ctrl;
+        uint32_t ctratt = le32_to_cpu(id->ctratt);
+
+        id->cmic |= NVME_CMIC_MULTI_CTRL;
+        ctratt |= NVME_CTRATT_ENDGRPS;
+
+        id->endgidmax = cpu_to_le16(0x1);
+
+        if (n->subsys->endgrp.fdp.enabled) {
+            ctratt |= NVME_CTRATT_FDPS;
+        }
+
+        id->ctratt = cpu_to_le32(ctratt);
     }
 
     cntlid = nvme_subsys_register_ctrl(n, errp);
diff -Nru qemu-10.0.3+ds/hw/pci/pcie_sriov.c qemu-10.0.4+ds/hw/pci/pcie_sriov.c
--- qemu-10.0.3+ds/hw/pci/pcie_sriov.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/pci/pcie_sriov.c	2025-09-09 19:21:41.000000000 +0300
@@ -211,6 +211,27 @@
     pci_set_word(dev->wmask + dev->exp.sriov_cap + PCI_SRIOV_NUM_VF, 0xffff);
 }
 
+static void consume_config(PCIDevice *dev)
+{
+    uint8_t *cfg = dev->config + dev->exp.sriov_cap;
+
+    if (pci_get_word(cfg + PCI_SRIOV_CTRL) & PCI_SRIOV_CTRL_VFE) {
+        register_vfs(dev);
+    } else {
+        uint8_t *wmask = dev->wmask + dev->exp.sriov_cap;
+        uint16_t num_vfs = pci_get_word(cfg + PCI_SRIOV_NUM_VF);
+        uint16_t wmask_val = PCI_SRIOV_CTRL_MSE | PCI_SRIOV_CTRL_ARI;
+
+        unregister_vfs(dev);
+
+        if (num_vfs <= pci_get_word(cfg + PCI_SRIOV_TOTAL_VF)) {
+            wmask_val |= PCI_SRIOV_CTRL_VFE;
+        }
+
+        pci_set_word(wmask + PCI_SRIOV_CTRL, wmask_val);
+    }
+}
+
 void pcie_sriov_config_write(PCIDevice *dev, uint32_t address,
                              uint32_t val, int len)
 {
@@ -228,30 +249,13 @@
     trace_sriov_config_write(dev->name, PCI_SLOT(dev->devfn),
                              PCI_FUNC(dev->devfn), off, val, len);
 
-    if (range_covers_byte(off, len, PCI_SRIOV_CTRL)) {
-        if (val & PCI_SRIOV_CTRL_VFE) {
-            register_vfs(dev);
-        } else {
-            unregister_vfs(dev);
-        }
-    } else if (range_covers_byte(off, len, PCI_SRIOV_NUM_VF)) {
-        uint8_t *cfg = dev->config + sriov_cap;
-        uint8_t *wmask = dev->wmask + sriov_cap;
-        uint16_t num_vfs = pci_get_word(cfg + PCI_SRIOV_NUM_VF);
-        uint16_t wmask_val = PCI_SRIOV_CTRL_MSE | PCI_SRIOV_CTRL_ARI;
-
-        if (num_vfs <= pci_get_word(cfg + PCI_SRIOV_TOTAL_VF)) {
-            wmask_val |= PCI_SRIOV_CTRL_VFE;
-        }
-
-        pci_set_word(wmask + PCI_SRIOV_CTRL, wmask_val);
-    }
+    consume_config(dev);
 }
 
 void pcie_sriov_pf_post_load(PCIDevice *dev)
 {
     if (dev->exp.sriov_cap) {
-        register_vfs(dev);
+        consume_config(dev);
     }
 }
 
diff -Nru qemu-10.0.3+ds/hw/ppc/pnv.c qemu-10.0.4+ds/hw/ppc/pnv.c
--- qemu-10.0.3+ds/hw/ppc/pnv.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/ppc/pnv.c	2025-09-09 19:21:41.000000000 +0300
@@ -21,6 +21,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/datadir.h"
+#include "qemu/log.h"
 #include "qemu/units.h"
 #include "qemu/cutils.h"
 #include "qapi/error.h"
@@ -1794,12 +1795,83 @@
     }
 }
 
+static uint64_t pnv_handle_sprd_load(CPUPPCState *env)
+{
+    PowerPCCPU *cpu = env_archcpu(env);
+    PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
+    uint64_t sprc = env->spr[SPR_POWER_SPRC];
+
+    if (pc->big_core) {
+        pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
+    }
+
+    switch (sprc & 0x3e0) {
+    case 0: /* SCRATCH0-3 */
+    case 1: /* SCRATCH4-7 */
+        return pc->scratch[(sprc >> 3) & 0x7];
+
+    case 0x1e0: /* core thread state */
+        if (env->excp_model == POWERPC_EXCP_POWER9) {
+            /*
+             * Only implement for POWER9 because skiboot uses it to check
+             * big-core mode. Other bits are unimplemented so we would
+             * prefer to get unimplemented message on POWER10 if it were
+             * used anywhere.
+             */
+            if (pc->big_core) {
+                return PPC_BIT(63);
+            } else {
+                return 0;
+            }
+        }
+        /* fallthru */
+
+    default:
+        qemu_log_mask(LOG_UNIMP, "mfSPRD: Unimplemented SPRC:0x"
+                                  TARGET_FMT_lx"\n", sprc);
+        break;
+    }
+    return 0;
+}
+
+static void pnv_handle_sprd_store(CPUPPCState *env, uint64_t val)
+{
+    PowerPCCPU *cpu = env_archcpu(env);
+    uint64_t sprc = env->spr[SPR_POWER_SPRC];
+    PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
+    int nr;
+
+    if (pc->big_core) {
+        pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
+    }
+
+    switch (sprc & 0x3e0) {
+    case 0: /* SCRATCH0-3 */
+    case 1: /* SCRATCH4-7 */
+        /*
+         * Log stores to SCRATCH, because some firmware uses these for
+         * debugging and logging, but they would normally be read by the BMC,
+         * which is not implemented in QEMU yet. This gives a way to get at the
+         * information. Could also dump these upon checkstop.
+         */
+        nr = (sprc >> 3) & 0x7;
+        pc->scratch[nr] = val;
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "mtSPRD: Unimplemented SPRC:0x"
+                                  TARGET_FMT_lx"\n", sprc);
+        break;
+    }
+}
+
 static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
 {
     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
     Pnv9Chip *chip9 = PNV9_CHIP(dev);
     PnvChip *chip = PNV_CHIP(dev);
     Pnv9Psi *psi9 = &chip9->psi;
+    PowerPCCPU *cpu;
+    PowerPCCPUClass *cpu_class;
     Error *local_err = NULL;
     int i;
 
@@ -1827,6 +1899,12 @@
         return;
     }
 
+    /* Set handlers for Special registers, such as SPRD */
+    cpu = chip->cores[0]->threads[0];
+    cpu_class = POWERPC_CPU_GET_CLASS(cpu);
+    cpu_class->load_sprd = pnv_handle_sprd_load;
+    cpu_class->store_sprd = pnv_handle_sprd_store;
+
     /* XIVE interrupt controller (POWER9) */
     object_property_set_int(OBJECT(&chip9->xive), "ic-bar",
                             PNV9_XIVE_IC_BASE(chip), &error_fatal);
@@ -2078,6 +2156,8 @@
     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
     PnvChip *chip = PNV_CHIP(dev);
     Pnv10Chip *chip10 = PNV10_CHIP(dev);
+    PowerPCCPU *cpu;
+    PowerPCCPUClass *cpu_class;
     Error *local_err = NULL;
     int i;
 
@@ -2105,6 +2185,12 @@
         return;
     }
 
+    /* Set handlers for Special registers, such as SPRD */
+    cpu = chip->cores[0]->threads[0];
+    cpu_class = POWERPC_CPU_GET_CLASS(cpu);
+    cpu_class->load_sprd = pnv_handle_sprd_load;
+    cpu_class->store_sprd = pnv_handle_sprd_store;
+
     /* XIVE2 interrupt controller (POWER10) */
     object_property_set_int(OBJECT(&chip10->xive), "ic-bar",
                             PNV10_XIVE2_IC_BASE(chip), &error_fatal);
diff -Nru qemu-10.0.3+ds/hw/sd/ssi-sd.c qemu-10.0.4+ds/hw/sd/ssi-sd.c
--- qemu-10.0.3+ds/hw/sd/ssi-sd.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/sd/ssi-sd.c	2025-09-09 19:21:41.000000000 +0300
@@ -106,6 +106,10 @@
     SDRequest request;
     uint8_t longresp[16];
 
+    if (!sdbus_get_inserted(&s->sdbus)) {
+        return SSI_DUMMY;
+    }
+
     /*
      * Special case: allow CMD12 (STOP TRANSMISSION) while reading data.
      *
diff -Nru qemu-10.0.3+ds/hw/ssi/aspeed_smc.c qemu-10.0.4+ds/hw/ssi/aspeed_smc.c
--- qemu-10.0.3+ds/hw/ssi/aspeed_smc.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/ssi/aspeed_smc.c	2025-09-09 19:21:41.000000000 +0300
@@ -1857,7 +1857,8 @@
     asc->resets            = aspeed_1030_fmc_resets;
     asc->flash_window_base = 0x80000000;
     asc->flash_window_size = 0x10000000;
-    asc->features          = ASPEED_SMC_FEATURE_DMA;
+    asc->features          = ASPEED_SMC_FEATURE_DMA |
+                             ASPEED_SMC_FEATURE_WDT_CONTROL;
     asc->dma_flash_mask    = 0x0FFFFFFC;
     asc->dma_dram_mask     = 0x000BFFFC;
     asc->dma_start_length  = 1;
diff -Nru qemu-10.0.3+ds/hw/uefi/var-service-core.c qemu-10.0.4+ds/hw/uefi/var-service-core.c
--- qemu-10.0.3+ds/hw/uefi/var-service-core.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/uefi/var-service-core.c	2025-09-09 19:21:41.000000000 +0300
@@ -259,8 +259,8 @@
         uv->buf_size = val;
         g_free(uv->buffer);
         g_free(uv->pio_xfer_buffer);
-        uv->buffer = g_malloc(uv->buf_size);
-        uv->pio_xfer_buffer = g_malloc(uv->buf_size);
+        uv->buffer = g_malloc0(uv->buf_size);
+        uv->pio_xfer_buffer = g_malloc0(uv->buf_size);
         break;
     case UEFI_VARS_REG_DMA_BUFFER_ADDR_LO:
         uv->buf_addr_lo = val;
diff -Nru qemu-10.0.3+ds/hw/uefi/var-service-json.c qemu-10.0.4+ds/hw/uefi/var-service-json.c
--- qemu-10.0.3+ds/hw/uefi/var-service-json.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/uefi/var-service-json.c	2025-09-09 19:21:41.000000000 +0300
@@ -172,7 +172,7 @@
 void uefi_vars_json_init(uefi_vars_state *uv, Error **errp)
 {
     if (uv->jsonfile) {
-        uv->jsonfd = qemu_create(uv->jsonfile, O_RDWR, 0666, errp);
+        uv->jsonfd = qemu_create(uv->jsonfile, O_RDWR | O_BINARY, 0666, errp);
     }
 }
 
diff -Nru qemu-10.0.3+ds/hw/uefi/var-service-vars.c qemu-10.0.4+ds/hw/uefi/var-service-vars.c
--- qemu-10.0.3+ds/hw/uefi/var-service-vars.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/uefi/var-service-vars.c	2025-09-09 19:21:41.000000000 +0300
@@ -357,6 +357,9 @@
     if (uefi_strlen(name, nv->name_size) == 0) {
         /* empty string -> first */
         var = QTAILQ_FIRST(&uv->variables);
+        while (var && !check_access(uv, var)) {
+            var = QTAILQ_NEXT(var, next);
+        }
         if (!var) {
             return uefi_vars_mm_error(mhdr, mvar, EFI_NOT_FOUND);
         }
@@ -702,12 +705,14 @@
     case SMM_VARIABLE_FUNCTION_READY_TO_BOOT:
         trace_uefi_event("ready-to-boot");
         uv->ready_to_boot = true;
+        mvar->status = EFI_SUCCESS;
         length = 0;
         break;
 
     case SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE:
         trace_uefi_event("exit-boot-service");
         uv->exit_boot_service = true;
+        mvar->status = EFI_SUCCESS;
         length = 0;
         break;
 
diff -Nru qemu-10.0.3+ds/hw/virtio/vhost.c qemu-10.0.4+ds/hw/virtio/vhost.c
--- qemu-10.0.3+ds/hw/virtio/vhost.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/virtio/vhost.c	2025-09-09 19:21:41.000000000 +0300
@@ -1111,7 +1111,8 @@
 
     r = vhost_migration_log(listener, true);
     if (r < 0) {
-        abort();
+        error_setg_errno(errp, -r, "vhost: Failed to start logging");
+        return false;
     }
     return true;
 }
@@ -1122,7 +1123,8 @@
 
     r = vhost_migration_log(listener, false);
     if (r < 0) {
-        abort();
+        /* Not fatal, so report it, but take no further action */
+        warn_report("vhost: Failed to stop logging");
     }
 }
 
diff -Nru qemu-10.0.3+ds/hw/virtio/virtio.c qemu-10.0.4+ds/hw/virtio/virtio.c
--- qemu-10.0.3+ds/hw/virtio/virtio.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/hw/virtio/virtio.c	2025-09-09 19:21:41.000000000 +0300
@@ -929,18 +929,18 @@
 static void virtqueue_ordered_fill(VirtQueue *vq, const VirtQueueElement *elem,
                                    unsigned int len)
 {
-    unsigned int i, steps, max_steps;
+    unsigned int i, steps, max_steps, ndescs;
 
     i = vq->used_idx % vq->vring.num;
     steps = 0;
     /*
-     * We shouldn't need to increase 'i' by more than the distance
-     * between used_idx and last_avail_idx.
+     * We shouldn't need to increase 'i' by more than or equal to
+     * the distance between used_idx and last_avail_idx (max_steps).
      */
     max_steps = (vq->last_avail_idx - vq->used_idx) % vq->vring.num;
 
     /* Search for element in vq->used_elems */
-    while (steps <= max_steps) {
+    while (steps < max_steps) {
         /* Found element, set length and mark as filled */
         if (vq->used_elems[i].index == elem->index) {
             vq->used_elems[i].len = len;
@@ -948,8 +948,18 @@
             break;
         }
 
-        i += vq->used_elems[i].ndescs;
-        steps += vq->used_elems[i].ndescs;
+        ndescs = vq->used_elems[i].ndescs;
+
+        /* Defensive sanity check */
+        if (unlikely(ndescs == 0 || ndescs > vq->vring.num)) {
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "%s: %s invalid ndescs %u at position %u\n",
+                          __func__, vq->vdev->name, ndescs, i);
+            return;
+        }
+
+        i += ndescs;
+        steps += ndescs;
 
         if (i >= vq->vring.num) {
             i -= vq->vring.num;
diff -Nru qemu-10.0.3+ds/include/elf.h qemu-10.0.4+ds/include/elf.h
--- qemu-10.0.3+ds/include/elf.h	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/include/elf.h	2025-09-09 19:21:41.000000000 +0300
@@ -56,6 +56,13 @@
 #define EF_MIPS_ARCH_32R6     0x90000000      /* MIPS32r6 code.  */
 #define EF_MIPS_ARCH_64R6     0xa0000000      /* MIPS64r6 code.  */
 
+/* MIPS Architectural Extensions. */
+#define EF_MIPS_ARCH_ASE      0x0f000000
+
+#define EF_MIPS_ARCH_ASE_MICROMIPS 0x02000000
+#define EF_MIPS_ARCH_ASE_M16  0x04000000
+#define EF_MIPS_ARCH_ASE_MDMX 0x08000000
+
 /* The ABI of a file. */
 #define EF_MIPS_ABI_O32       0x00001000      /* O32 ABI.  */
 #define EF_MIPS_ABI_O64       0x00002000      /* O32 extended for 64 bit.  */
diff -Nru qemu-10.0.3+ds/include/hw/arm/stm32f205_soc.h qemu-10.0.4+ds/include/hw/arm/stm32f205_soc.h
--- qemu-10.0.3+ds/include/hw/arm/stm32f205_soc.h	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/include/hw/arm/stm32f205_soc.h	2025-09-09 19:21:41.000000000 +0300
@@ -59,7 +59,7 @@
     STM32F2XXADCState adc[STM_NUM_ADCS];
     STM32F2XXSPIState spi[STM_NUM_SPIS];
 
-    OrIRQState *adc_irqs;
+    OrIRQState adc_irqs;
 
     MemoryRegion sram;
     MemoryRegion flash;
diff -Nru qemu-10.0.3+ds/include/hw/intc/arm_gicv3_common.h qemu-10.0.4+ds/include/hw/intc/arm_gicv3_common.h
--- qemu-10.0.3+ds/include/hw/intc/arm_gicv3_common.h	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/include/hw/intc/arm_gicv3_common.h	2025-09-09 19:21:41.000000000 +0300
@@ -27,6 +27,7 @@
 #include "hw/sysbus.h"
 #include "hw/intc/arm_gic_common.h"
 #include "qom/object.h"
+#include "qemu/notify.h"
 
 /*
  * Maximum number of possible interrupts, determined by the GIC architecture.
@@ -270,6 +271,8 @@
     GICv3CPUState *cpu;
     /* List of all ITSes connected to this GIC */
     GPtrArray *itslist;
+
+    NotifierWithReturn cpr_notifier;
 };
 
 #define GICV3_BITMAP_ACCESSORS(BMP)                                     \
diff -Nru qemu-10.0.3+ds/include/hw/ppc/xive2_regs.h qemu-10.0.4+ds/include/hw/ppc/xive2_regs.h
--- qemu-10.0.3+ds/include/hw/ppc/xive2_regs.h	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/include/hw/ppc/xive2_regs.h	2025-09-09 19:21:41.000000000 +0300
@@ -87,6 +87,7 @@
 #define END2_W2_EQ_ADDR_HI         PPC_BITMASK32(8, 31)
         uint32_t       w3;
 #define END2_W3_EQ_ADDR_LO         PPC_BITMASK32(0, 24)
+#define END2_W3_CL                 PPC_BIT32(27)
 #define END2_W3_QSIZE              PPC_BITMASK32(28, 31)
         uint32_t       w4;
 #define END2_W4_END_BLOCK          PPC_BITMASK32(4, 7)
diff -Nru qemu-10.0.3+ds/include/qemu/compiler.h qemu-10.0.4+ds/include/qemu/compiler.h
--- qemu-10.0.3+ds/include/qemu/compiler.h	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/include/qemu/compiler.h	2025-09-09 19:21:41.000000000 +0300
@@ -182,19 +182,6 @@
 #define QEMU_DISABLE_CFI
 #endif
 
-/*
- * Apple clang version 14 has a bug in its __builtin_subcll(); define
- * BUILTIN_SUBCLL_BROKEN for the offending versions so we can avoid it.
- * When a version of Apple clang which has this bug fixed is released
- * we can add an upper bound to this check.
- * See https://gitlab.com/qemu-project/qemu/-/issues/1631
- * and https://gitlab.com/qemu-project/qemu/-/issues/1659 for details.
- * The bug never made it into any upstream LLVM releases, only Apple ones.
- */
-#if defined(__apple_build_version__) && __clang_major__ >= 14
-#define BUILTIN_SUBCLL_BROKEN
-#endif
-
 #if __has_attribute(annotate)
 #define QEMU_ANNOTATE(x) __attribute__((annotate(x)))
 #else
diff -Nru qemu-10.0.3+ds/include/qemu/host-utils.h qemu-10.0.4+ds/include/qemu/host-utils.h
--- qemu-10.0.3+ds/include/qemu/host-utils.h	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/include/qemu/host-utils.h	2025-09-09 19:21:41.000000000 +0300
@@ -677,7 +677,7 @@
  */
 static inline uint64_t usub64_borrow(uint64_t x, uint64_t y, bool *pborrow)
 {
-#if __has_builtin(__builtin_subcll) && !defined(BUILTIN_SUBCLL_BROKEN)
+#if __has_builtin(__builtin_subcll)
     unsigned long long b = *pborrow;
     x = __builtin_subcll(x, y, b, &b);
     *pborrow = b & 1;
diff -Nru qemu-10.0.3+ds/linux-user/aarch64/signal.c qemu-10.0.4+ds/linux-user/aarch64/signal.c
--- qemu-10.0.3+ds/linux-user/aarch64/signal.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/linux-user/aarch64/signal.c	2025-09-09 19:21:41.000000000 +0300
@@ -121,6 +121,13 @@
 #define TARGET_ZA_SIG_CONTEXT_SIZE(VQ) \
     TARGET_ZA_SIG_ZAV_OFFSET(VQ, VQ * TARGET_SVE_VQ_BYTES)
 
+#define TARGET_TPIDR2_MAGIC 0x54504902
+
+struct target_tpidr2_context {
+    struct target_aarch64_ctx head;
+    uint64_t tpidr2;
+};
+
 struct target_rt_sigframe {
     struct target_siginfo info;
     struct target_ucontext uc;
@@ -253,6 +260,14 @@
     }
 }
 
+static void target_setup_tpidr2_record(struct target_tpidr2_context *tpidr2,
+                                       CPUARMState *env)
+{
+    __put_user(TARGET_TPIDR2_MAGIC, &tpidr2->head.magic);
+    __put_user(sizeof(struct target_tpidr2_context), &tpidr2->head.size);
+    __put_user(env->cp15.tpidr2_el0, &tpidr2->tpidr2);
+}
+
 static void target_restore_general_frame(CPUARMState *env,
                                          struct target_rt_sigframe *sf)
 {
@@ -403,6 +418,12 @@
     return true;
 }
 
+static void target_restore_tpidr2_record(CPUARMState *env,
+                                         struct target_tpidr2_context *tpidr2)
+{
+    __get_user(env->cp15.tpidr2_el0, &tpidr2->tpidr2);
+}
+
 static int target_restore_sigframe(CPUARMState *env,
                                    struct target_rt_sigframe *sf)
 {
@@ -410,6 +431,7 @@
     struct target_fpsimd_context *fpsimd = NULL;
     struct target_sve_context *sve = NULL;
     struct target_za_context *za = NULL;
+    struct target_tpidr2_context *tpidr2 = NULL;
     uint64_t extra_datap = 0;
     bool used_extra = false;
     int sve_size = 0;
@@ -460,6 +482,14 @@
             za_size = size;
             break;
 
+        case TARGET_TPIDR2_MAGIC:
+            if (tpidr2 || size != sizeof(struct target_tpidr2_context) ||
+                !cpu_isar_feature(aa64_sme, env_archcpu(env))) {
+                goto err;
+            }
+            tpidr2 = (struct target_tpidr2_context *)ctx;
+            break;
+
         case TARGET_EXTRA_MAGIC:
             if (extra || size != sizeof(struct target_extra_context)) {
                 goto err;
@@ -497,6 +527,9 @@
     if (za && !target_restore_za_record(env, za, za_size, &svcr)) {
         goto err;
     }
+    if (tpidr2) {
+        target_restore_tpidr2_record(env, tpidr2);
+    }
     if (env->svcr != svcr) {
         env->svcr = svcr;
         arm_rebuild_hflags(env);
@@ -568,8 +601,8 @@
         .total_size = offsetof(struct target_rt_sigframe,
                                uc.tuc_mcontext.__reserved),
     };
-    int fpsimd_ofs, fr_ofs, sve_ofs = 0, za_ofs = 0;
-    int sve_size = 0, za_size = 0;
+    int fpsimd_ofs, fr_ofs, sve_ofs = 0, za_ofs = 0, tpidr2_ofs = 0;
+    int sve_size = 0, za_size = 0, tpidr2_size = 0;
     struct target_rt_sigframe *frame;
     struct target_rt_frame_record *fr;
     abi_ulong frame_addr, return_addr;
@@ -585,6 +618,8 @@
         sve_ofs = alloc_sigframe_space(sve_size, &layout);
     }
     if (cpu_isar_feature(aa64_sme, env_archcpu(env))) {
+        tpidr2_size = sizeof(struct target_tpidr2_context);
+        tpidr2_ofs = alloc_sigframe_space(tpidr2_size, &layout);
         /* ZA state needs saving only if it is enabled.  */
         if (FIELD_EX64(env->svcr, SVCR, ZA)) {
             za_size = TARGET_ZA_SIG_CONTEXT_SIZE(sme_vq(env));
@@ -644,6 +679,9 @@
     if (za_ofs) {
         target_setup_za_record((void *)frame + za_ofs, env, za_size);
     }
+    if (tpidr2_ofs) {
+        target_setup_tpidr2_record((void *)frame + tpidr2_ofs, env);
+    }
 
     /* Set up the stack frame for unwinding.  */
     fr = (void *)frame + fr_ofs;
@@ -666,8 +704,12 @@
         env->btype = 2;
     }
 
-    /* Invoke the signal handler with both SM and ZA disabled. */
+    /*
+     * Invoke the signal handler with a clean SME state: both SM and ZA
+     * disabled and TPIDR2_EL0 cleared.
+     */
     aarch64_set_svcr(env, 0, R_SVCR_SM_MASK | R_SVCR_ZA_MASK);
+    env->cp15.tpidr2_el0 = 0;
 
     if (info) {
         frame->info = *info;
diff -Nru qemu-10.0.3+ds/linux-user/mips/target_elf.h qemu-10.0.4+ds/linux-user/mips/target_elf.h
--- qemu-10.0.3+ds/linux-user/mips/target_elf.h	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/linux-user/mips/target_elf.h	2025-09-09 19:21:41.000000000 +0300
@@ -12,6 +12,12 @@
     if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) {
         return "mips32r6-generic";
     }
+    if ((eflags & EF_MIPS_ARCH_ASE) == EF_MIPS_ARCH_ASE_MICROMIPS) {
+        return "M14Kc";
+    }
+    if ((eflags & EF_MIPS_ARCH_ASE) == EF_MIPS_ARCH_ASE_M16) {
+        return "74Kf";
+    }
     if (eflags & EF_MIPS_NAN2008) {
         return "P5600";
     }
diff -Nru qemu-10.0.3+ds/linux-user/strace.list qemu-10.0.4+ds/linux-user/strace.list
--- qemu-10.0.3+ds/linux-user/strace.list	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/linux-user/strace.list	2025-09-09 19:21:41.000000000 +0300
@@ -1716,3 +1716,9 @@
 { TARGET_NR_clock_gettime64, "clock_gettime64" , NULL, print_clock_gettime64,
                            print_syscall_ret_clock_gettime64 },
 #endif
+#ifdef TARGET_NR_riscv_hwprobe
+{ TARGET_NR_riscv_hwprobe, "riscv_hwprobe" , "%s(%p,%d,%d,%d,%d,%d)", NULL, NULL },
+#endif
+#ifdef TARGET_NR_rseq
+{ TARGET_NR_rseq, "rseq" , "%s(%p,%u,%d,%#x)", NULL, NULL },
+#endif
diff -Nru qemu-10.0.3+ds/python/scripts/mkvenv.py qemu-10.0.4+ds/python/scripts/mkvenv.py
--- qemu-10.0.3+ds/python/scripts/mkvenv.py	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/python/scripts/mkvenv.py	2025-09-09 19:21:41.000000000 +0300
@@ -84,6 +84,7 @@
     Sequence,
     Tuple,
     Union,
+    cast,
 )
 import venv
 
@@ -94,17 +95,39 @@
 HAVE_DISTLIB = True
 try:
     import distlib.scripts
-    import distlib.version
 except ImportError:
     try:
         # Reach into pip's cookie jar.  pylint and flake8 don't understand
         # that these imports will be used via distlib.xxx.
         from pip._vendor import distlib
         import pip._vendor.distlib.scripts  # noqa, pylint: disable=unused-import
-        import pip._vendor.distlib.version  # noqa, pylint: disable=unused-import
     except ImportError:
         HAVE_DISTLIB = False
 
+# pip 25.2 does not vendor distlib.version, but it uses vendored
+# packaging.version
+HAVE_DISTLIB_VERSION = True
+try:
+    import distlib.version  # pylint: disable=ungrouped-imports
+except ImportError:
+    try:
+        # pylint: disable=unused-import,ungrouped-imports
+        import pip._vendor.distlib.version  # noqa
+    except ImportError:
+        HAVE_DISTLIB_VERSION = False
+
+HAVE_PACKAGING_VERSION = True
+try:
+    # Do not bother importing non-vendored packaging, because it is not
+    # in stdlib.
+    from pip._vendor import packaging
+    # pylint: disable=unused-import
+    import pip._vendor.packaging.requirements  # noqa
+    import pip._vendor.packaging.version  # noqa
+except ImportError:
+    HAVE_PACKAGING_VERSION = False
+
+
 # Try to load tomllib, with a fallback to tomli.
 # HAVE_TOMLLIB is checked below, just-in-time, so that mkvenv does not fail
 # outside the venv or before a potential call to ensurepip in checkpip().
@@ -133,6 +156,43 @@
     """An Exception class we can't confuse with a builtin."""
 
 
+class Matcher:
+    """Compatibility appliance for version/requirement string parsing."""
+    def __init__(self, name_and_constraint: str):
+        """Create a matcher from a requirement-like string."""
+        if HAVE_DISTLIB_VERSION:
+            self._m = distlib.version.LegacyMatcher(name_and_constraint)
+        elif HAVE_PACKAGING_VERSION:
+            self._m = packaging.requirements.Requirement(name_and_constraint)
+        else:
+            raise Ouch("found neither distlib.version nor packaging.version")
+        self.name = self._m.name
+
+    def match(self, version_str: str) -> bool:
+        """Return True if `version` satisfies the stored constraint."""
+        if HAVE_DISTLIB_VERSION:
+            return cast(
+                bool,
+                self._m.match(distlib.version.LegacyVersion(version_str))
+            )
+
+        assert HAVE_PACKAGING_VERSION
+        return cast(
+            bool,
+            self._m.specifier.contains(
+                packaging.version.Version(version_str), prereleases=True
+            )
+        )
+
+    def __str__(self) -> str:
+        """String representation delegated to the backend."""
+        return str(self._m)
+
+    def __repr__(self) -> str:
+        """Stable debug representation delegated to the backend."""
+        return repr(self._m)
+
+
 class QemuEnvBuilder(venv.EnvBuilder):
     """
     An extension of venv.EnvBuilder for building QEMU's configure-time venv.
@@ -669,7 +729,7 @@
     canary = None
     for name, info in group.items():
         constraint = _make_version_constraint(info, False)
-        matcher = distlib.version.LegacyMatcher(name + constraint)
+        matcher = Matcher(name + constraint)
         print(f"mkvenv: checking for {matcher}", file=sys.stderr)
 
         dist: Optional[Distribution] = None
@@ -683,7 +743,7 @@
             # Always pass installed package to pip, so that they can be
             # updated if the requested version changes
             or not _is_system_package(dist)
-            or not matcher.match(distlib.version.LegacyVersion(dist.version))
+            or not matcher.match(dist.version)
         ):
             absent.append(name + _make_version_constraint(info, True))
             if len(absent) == 1:
diff -Nru qemu-10.0.3+ds/qapi/block-core.json qemu-10.0.4+ds/qapi/block-core.json
--- qemu-10.0.3+ds/qapi/block-core.json	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/qapi/block-core.json	2025-09-09 19:21:41.000000000 +0300
@@ -158,7 +158,14 @@
 ##
 # @ImageInfoSpecificRbd:
 #
-# @encryption-format: Image encryption format
+# @encryption-format: Image encryption format. If encryption is enabled for the
+#     image (see encrypted in BlockNodeInfo), this is the actual format in which the
+#     image is accessed. If encryption is not enabled, this is the result of
+#     probing when the image was opened, to give a suggestion which encryption
+#     format could be enabled. Note that probing results can be changed by the
+#     guest by writing a (possibly partial) encryption format header to the
+#     image, so don't treat this information as trusted if the guest is not
+#     trusted.
 #
 # Since: 6.1
 ##
diff -Nru qemu-10.0.3+ds/qga/commands-linux.c qemu-10.0.4+ds/qga/commands-linux.c
--- qemu-10.0.3+ds/qga/commands-linux.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/qga/commands-linux.c	2025-09-09 19:21:41.000000000 +0300
@@ -1400,20 +1400,22 @@
 
 static void linux_sys_state_suspend(SuspendMode mode, Error **errp)
 {
-    g_autoptr(GError) local_gerr = NULL;
     const char *sysfile_strs[3] = {"disk", "mem", NULL};
     const char *sysfile_str = sysfile_strs[mode];
+    int fd;
 
     if (!sysfile_str) {
         error_setg(errp, "unknown guest suspend mode");
         return;
     }
 
-    if (!g_file_set_contents(LINUX_SYS_STATE_FILE, sysfile_str,
-                             -1, &local_gerr)) {
-        error_setg(errp, "suspend: cannot write to '%s': %s",
-                   LINUX_SYS_STATE_FILE, local_gerr->message);
-        return;
+    fd = open(LINUX_SYS_STATE_FILE, O_WRONLY);
+    if (fd < 0 || write(fd, sysfile_str, strlen(sysfile_str)) < 0) {
+        error_setg(errp, "suspend: cannot write to '%s': %m",
+                   LINUX_SYS_STATE_FILE);
+    }
+    if (fd >= 0) {
+        close(fd);
     }
 }
 
diff -Nru qemu-10.0.3+ds/qga/commands.c qemu-10.0.4+ds/qga/commands.c
--- qemu-10.0.3+ds/qga/commands.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/qga/commands.c	2025-09-09 19:21:41.000000000 +0300
@@ -205,13 +205,15 @@
 #endif
         if (gei->out.length > 0) {
             ges->out_data = g_base64_encode(gei->out.data, gei->out.length);
-            ges->has_out_truncated = gei->out.truncated;
+            ges->has_out_truncated = true;
+            ges->out_truncated = gei->out.truncated;
         }
         g_free(gei->out.data);
 
         if (gei->err.length > 0) {
             ges->err_data = g_base64_encode(gei->err.data, gei->err.length);
-            ges->has_err_truncated = gei->err.truncated;
+            ges->has_err_truncated = true;
+            ges->err_truncated = gei->err.truncated;
         }
         g_free(gei->err.data);
 
diff -Nru qemu-10.0.3+ds/qga/installer/qemu-ga.wxs qemu-10.0.4+ds/qga/installer/qemu-ga.wxs
--- qemu-10.0.3+ds/qga/installer/qemu-ga.wxs	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/qga/installer/qemu-ga.wxs	2025-09-09 19:21:41.000000000 +0300
@@ -151,6 +151,14 @@
               Return="check"
               >
     </CustomAction>
+    <CustomAction Id="UnRegisterCom_Rollback"
+              ExeCommand='"[qemu_ga_directory]qga-vss.dll",DLLCOMUnregister'
+              Execute="rollback"
+              Property="rundll"
+              Impersonate="no"
+              Return="check"
+              >
+    </CustomAction>
     <?endif?>
 
     <Feature Id="QEMUFeature" Title="QEMU Guest Agent" Level="1">
@@ -174,8 +182,19 @@
 
     <InstallExecuteSequence>
       <?ifdef var.InstallVss?>
-      <Custom Action="UnRegisterCom" After="StopServices">Installed</Custom>
-      <Custom Action="RegisterCom" After="InstallServices">NOT REMOVE</Custom>
+        <!-- Use explicit Sequence number to provide an absolute position in the sequence-->
+        <!-- This is needed to set "UnRegisterCom_Rollback" before "RegisterCom" and after "InstallFiles"-->
+        <!-- but, Wix detect this double condition incorrectly -->
+
+        <!-- UnRegisterCom_Rollback (for install rollback): at 5849, right before RegisterCom (5850)-->
+        <!-- Runs only if the installation fails and rolls back-->
+        <Custom Action="UnRegisterCom_Rollback" Sequence="5849">NOT REMOVE</Custom>
+
+        <!-- RegisterCom (for install): at 5850, right after InstallFiles (5849) (old: After="InstallServices")-->
+        <Custom Action="RegisterCom" Sequence="5850">NOT REMOVE</Custom>
+
+        <!-- UnRegisterCom (for uninstall): at 1901, right after StopServices (1900) (old: After="StopServices")-->
+        <Custom Action="UnRegisterCom" Sequence="1901">Installed</Custom>
       <?endif?>
     </InstallExecuteSequence>
   </Product>
diff -Nru qemu-10.0.3+ds/qga/vss-win32/requester.cpp qemu-10.0.4+ds/qga/vss-win32/requester.cpp
--- qemu-10.0.3+ds/qga/vss-win32/requester.cpp	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/qga/vss-win32/requester.cpp	2025-09-09 19:21:41.000000000 +0300
@@ -28,8 +28,9 @@
 
 #define err_set(e, err, fmt, ...) {                                         \
     (e)->error_setg_win32_wrapper((e)->errp, __FILE__, __LINE__, __func__,  \
-                                   err, fmt, ## __VA_ARGS__);               \
-    qga_debug(fmt, ## __VA_ARGS__);                                         \
+                                   err, fmt ": Windows error 0x%lx",        \
+                                   ## __VA_ARGS__, err);                    \
+    qga_debug(fmt ": Windows error 0x%lx", ## __VA_ARGS__, err);            \
 }
 /* Bad idea, works only when (e)->errp != NULL: */
 #define err_is_set(e) ((e)->errp && *(e)->errp)
diff -Nru qemu-10.0.3+ds/roms/Makefile qemu-10.0.4+ds/roms/Makefile
--- qemu-10.0.3+ds/roms/Makefile	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/roms/Makefile	2025-09-09 19:21:41.000000000 +0300
@@ -193,12 +193,12 @@
 	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
diff -Nru qemu-10.0.3+ds/scripts/kernel-doc qemu-10.0.4+ds/scripts/kernel-doc
--- qemu-10.0.3+ds/scripts/kernel-doc	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/scripts/kernel-doc	2025-09-09 19:21:41.000000000 +0300
@@ -1594,13 +1594,12 @@
 
 	if ($type eq "" && $param =~ /\.\.\.$/)
 	{
-	    if (!$param =~ /\w\.\.\.$/) {
-	      # handles unnamed variable parameters
-	      $param = "...";
-	    }
-	    elsif ($param =~ /\w\.\.\.$/) {
+	    if ($param =~ /\w\.\.\.$/) {
 	      # for named variable parameters of the form `x...`, remove the dots
 	      $param =~ s/\.\.\.$//;
+	    } else {
+	      # handles unnamed variable parameters
+	      $param = "...";
 	    }
 	    if (!defined $parameterdescs{$param} || $parameterdescs{$param} eq "") {
 		$parameterdescs{$param} = "variable arguments";
diff -Nru qemu-10.0.3+ds/scripts/make-release qemu-10.0.4+ds/scripts/make-release
--- qemu-10.0.3+ds/scripts/make-release	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/scripts/make-release	2025-09-09 19:21:41.000000000 +0300
@@ -61,17 +61,15 @@
 (cd roms/skiboot && ./make_version.sh > .version)
 # Fetch edk2 submodule's submodules, since it won't have access to them via
 # the tarball later.
-#
-# A more uniform way to handle this sort of situation would be nice, but we
-# don't necessarily have much control over how a submodule handles its
-# submodule dependencies, so we continue to handle these on a case-by-case
-# basis for now.
-(cd roms/edk2 && \
-    git submodule update --init --depth 1 -- \
-        ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3 \
-        BaseTools/Source/C/BrotliCompress/brotli \
-        CryptoPkg/Library/OpensslLib/openssl \
-        MdeModulePkg/Library/BrotliCustomDecompressLib/brotli)
+
+# As recommended by the EDK2 readme, we don't use --recursive here.
+# EDK2 won't use any code or feature from a submodule of a submodule,
+# so we don't need to add them to the tarball.
+# Although we don't necessarily need all of the submodules that EDK2
+# has, we clone them all, to avoid running into problems where EDK2
+# adds a new submodule or changes its use of an existing one and
+# the sources we ship in the tarball then fail to build.
+(cd roms/edk2 && git submodule update --init --depth 1)
 popd
 
 exclude=(--exclude=.git)
diff -Nru qemu-10.0.3+ds/scsi/pr-manager-helper.c qemu-10.0.4+ds/scsi/pr-manager-helper.c
--- qemu-10.0.3+ds/scsi/pr-manager-helper.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/scsi/pr-manager-helper.c	2025-09-09 19:21:41.000000000 +0300
@@ -105,20 +105,15 @@
         .u.q_unix.path = path
     };
     QIOChannelSocket *sioc = qio_channel_socket_new();
-    Error *local_err = NULL;
-
     uint32_t flags;
     int r;
 
     assert(!pr_mgr->ioc);
     qio_channel_set_name(QIO_CHANNEL(sioc), "pr-manager-helper");
-    qio_channel_socket_connect_sync(sioc,
-                                    &saddr,
-                                    &local_err);
+    r = qio_channel_socket_connect_sync(sioc, &saddr, errp);
     g_free(path);
-    if (local_err) {
+    if (r < 0) {
         object_unref(OBJECT(sioc));
-        error_propagate(errp, local_err);
         return -ENOTCONN;
     }
 
diff -Nru qemu-10.0.3+ds/subprojects/libvduse/include/compiler.h qemu-10.0.4+ds/subprojects/libvduse/include/compiler.h
--- qemu-10.0.3+ds/subprojects/libvduse/include/compiler.h	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/subprojects/libvduse/include/compiler.h	2025-09-09 19:21:41.000000000 +0300
@@ -182,19 +182,6 @@
 #define QEMU_DISABLE_CFI
 #endif
 
-/*
- * Apple clang version 14 has a bug in its __builtin_subcll(); define
- * BUILTIN_SUBCLL_BROKEN for the offending versions so we can avoid it.
- * When a version of Apple clang which has this bug fixed is released
- * we can add an upper bound to this check.
- * See https://gitlab.com/qemu-project/qemu/-/issues/1631
- * and https://gitlab.com/qemu-project/qemu/-/issues/1659 for details.
- * The bug never made it into any upstream LLVM releases, only Apple ones.
- */
-#if defined(__apple_build_version__) && __clang_major__ >= 14
-#define BUILTIN_SUBCLL_BROKEN
-#endif
-
 #if __has_attribute(annotate)
 #define QEMU_ANNOTATE(x) __attribute__((annotate(x)))
 #else
diff -Nru qemu-10.0.3+ds/subprojects/libvhost-user/include/compiler.h qemu-10.0.4+ds/subprojects/libvhost-user/include/compiler.h
--- qemu-10.0.3+ds/subprojects/libvhost-user/include/compiler.h	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/subprojects/libvhost-user/include/compiler.h	2025-09-09 19:21:41.000000000 +0300
@@ -182,19 +182,6 @@
 #define QEMU_DISABLE_CFI
 #endif
 
-/*
- * Apple clang version 14 has a bug in its __builtin_subcll(); define
- * BUILTIN_SUBCLL_BROKEN for the offending versions so we can avoid it.
- * When a version of Apple clang which has this bug fixed is released
- * we can add an upper bound to this check.
- * See https://gitlab.com/qemu-project/qemu/-/issues/1631
- * and https://gitlab.com/qemu-project/qemu/-/issues/1659 for details.
- * The bug never made it into any upstream LLVM releases, only Apple ones.
- */
-#if defined(__apple_build_version__) && __clang_major__ >= 14
-#define BUILTIN_SUBCLL_BROKEN
-#endif
-
 #if __has_attribute(annotate)
 #define QEMU_ANNOTATE(x) __attribute__((annotate(x)))
 #else
diff -Nru qemu-10.0.3+ds/system/physmem.c qemu-10.0.4+ds/system/physmem.c
--- qemu-10.0.3+ds/system/physmem.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/system/physmem.c	2025-09-09 19:21:41.000000000 +0300
@@ -164,13 +164,11 @@
  * 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;
 
@@ -689,7 +687,7 @@
     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);
@@ -2673,7 +2671,7 @@
 {
     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;
 
@@ -2750,9 +2748,6 @@
 
 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);
 }
 
@@ -2768,11 +2763,7 @@
     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.
      *
diff -Nru qemu-10.0.3+ds/target/arm/gdbstub64.c qemu-10.0.4+ds/target/arm/gdbstub64.c
--- qemu-10.0.3+ds/target/arm/gdbstub64.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/target/arm/gdbstub64.c	2025-09-09 19:21:41.000000000 +0300
@@ -111,8 +111,22 @@
         /* 128 bit FP register */
         {
             uint64_t *q = aa64_vfp_qreg(env, reg);
-            q[0] = ldq_le_p(buf);
-            q[1] = ldq_le_p(buf + 8);
+
+            /*
+             * On the wire these are target-endian 128 bit values.
+             * In the CPU state these are host-order uint64_t values
+             * with the least-significant one first. This means they're
+             * the other way around for target_words_bigendian() (which is
+             * only true for us for aarch64_be-linux-user).
+             */
+            if (target_words_bigendian()) {
+                q[1] = ldq_p(buf);
+                q[0] = ldq_p(buf + 8);
+            } else{
+                q[0] = ldq_p(buf);
+                q[1] = ldq_p(buf + 8);
+            }
+
             return 16;
         }
     case 32:
@@ -188,10 +202,17 @@
     case 0 ... 31:
     {
         int vq, len = 0;
-        uint64_t *p = (uint64_t *) buf;
         for (vq = 0; vq < cpu->sve_max_vq; vq++) {
-            env->vfp.zregs[reg].d[vq * 2 + 1] = *p++;
-            env->vfp.zregs[reg].d[vq * 2] = *p++;
+            if (target_words_bigendian()) {
+                env->vfp.zregs[reg].d[vq * 2 + 1] = ldq_p(buf);
+                buf += 8;
+                env->vfp.zregs[reg].d[vq * 2] = ldq_p(buf);
+            } else{
+                env->vfp.zregs[reg].d[vq * 2] = ldq_p(buf);
+                buf += 8;
+                env->vfp.zregs[reg].d[vq * 2 + 1] = ldq_p(buf);
+            }
+            buf += 8;
             len += 16;
         }
         return len;
@@ -206,9 +227,9 @@
     {
         int preg = reg - 34;
         int vq, len = 0;
-        uint64_t *p = (uint64_t *) buf;
         for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
-            env->vfp.pregs[preg].p[vq / 4] = *p++;
+            env->vfp.pregs[preg].p[vq / 4] = ldq_p(buf);
+            buf += 8;
             len += 8;
         }
         return len;
diff -Nru qemu-10.0.3+ds/target/arm/helper.c qemu-10.0.4+ds/target/arm/helper.c
--- qemu-10.0.3+ds/target/arm/helper.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/target/arm/helper.c	2025-09-09 19:21:41.000000000 +0300
@@ -870,22 +870,27 @@
     return supported_event_map[number] != UNSUPPORTED_EVENT;
 }
 
-static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
-                                   bool isread)
+static CPAccessResult do_pmreg_access(CPUARMState *env, bool is_pmcr)
 {
     /*
      * Performance monitor registers user accessibility is controlled
-     * by PMUSERENR. MDCR_EL2.TPM and MDCR_EL3.TPM allow configurable
+     * by PMUSERENR. MDCR_EL2.TPM/TPMCR and MDCR_EL3.TPM allow configurable
      * trapping to EL2 or EL3 for other accesses.
      */
     int el = arm_current_el(env);
-    uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
 
     if (el == 0 && !(env->cp15.c9_pmuserenr & 1)) {
         return CP_ACCESS_TRAP_EL1;
     }
-    if (el < 2 && (mdcr_el2 & MDCR_TPM)) {
-        return CP_ACCESS_TRAP_EL2;
+    if (el < 2) {
+        uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
+
+        if (mdcr_el2 & MDCR_TPM) {
+            return CP_ACCESS_TRAP_EL2;
+        }
+        if (is_pmcr && (mdcr_el2 & MDCR_TPMCR)) {
+            return CP_ACCESS_TRAP_EL2;
+        }
     }
     if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TPM)) {
         return CP_ACCESS_TRAP_EL3;
@@ -894,6 +899,19 @@
     return CP_ACCESS_OK;
 }
 
+static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
+                                   bool isread)
+{
+    return do_pmreg_access(env, false);
+}
+
+static CPAccessResult pmreg_access_pmcr(CPUARMState *env,
+                                        const ARMCPRegInfo *ri,
+                                        bool isread)
+{
+    return do_pmreg_access(env, true);
+}
+
 static CPAccessResult pmreg_access_xevcntr(CPUARMState *env,
                                            const ARMCPRegInfo *ri,
                                            bool isread)
@@ -1946,11 +1964,6 @@
       .fgt = FGT_PMSELR_EL0,
       .fieldoffset = offsetof(CPUARMState, cp15.c9_pmselr),
       .writefn = pmselr_write, .raw_writefn = raw_write, },
-    { .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0,
-      .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_ALIAS | ARM_CP_IO,
-      .fgt = FGT_PMCCNTR_EL0,
-      .readfn = pmccntr_read, .writefn = pmccntr_write32,
-      .accessfn = pmreg_access_ccntr },
     { .name = "PMCCNTR_EL0", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 0,
       .access = PL0_RW, .accessfn = pmreg_access_ccntr,
@@ -6834,14 +6847,14 @@
         .fgt = FGT_PMCR_EL0,
         .type = ARM_CP_IO | ARM_CP_ALIAS,
         .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
-        .accessfn = pmreg_access,
+        .accessfn = pmreg_access_pmcr,
         .readfn = pmcr_read, .raw_readfn = raw_read,
         .writefn = pmcr_write, .raw_writefn = raw_write,
     };
     ARMCPRegInfo pmcr64 = {
         .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
         .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
-        .access = PL0_RW, .accessfn = pmreg_access,
+        .access = PL0_RW, .accessfn = pmreg_access_pmcr,
         .fgt = FGT_PMCR_EL0,
         .type = ARM_CP_IO,
         .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
@@ -6849,9 +6862,26 @@
         .readfn = pmcr_read, .raw_readfn = raw_read,
         .writefn = pmcr_write, .raw_writefn = raw_write,
     };
+    /*
+     * 32-bit AArch32 PMCCNTR. We don't expose this to GDB if the
+     * new-in-v8 PMUv3 64-bit AArch32 PMCCNTR register is implemented
+     * (as that will provide the GDB user's view of "PMCCNTR").
+     */
+    ARMCPRegInfo pmccntr = {
+        .name = "PMCCNTR",
+        .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0,
+        .access = PL0_RW, .accessfn = pmreg_access_ccntr,
+        .resetvalue = 0, .type = ARM_CP_ALIAS | ARM_CP_IO,
+        .fgt = FGT_PMCCNTR_EL0,
+        .readfn = pmccntr_read, .writefn = pmccntr_write32,
+    };
+    if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+        pmccntr.type |= ARM_CP_NO_GDB;
+    }
 
     define_one_arm_cp_reg(cpu, &pmcr);
     define_one_arm_cp_reg(cpu, &pmcr64);
+    define_one_arm_cp_reg(cpu, &pmccntr);
     for (i = 0; i < pmcrn; i++) {
         char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
         char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
@@ -8162,6 +8192,13 @@
               .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
               .fgt = FGT_PMCEIDN_EL0,
               .resetvalue = cpu->pmceid1 },
+            /* AArch32 64-bit PMCCNTR view: added in PMUv3 with Armv8 */
+            { .name = "PMCCNTR", .state = ARM_CP_STATE_AA32,
+              .cp = 15, .crm = 9, .opc1 = 0,
+              .access = PL0_RW, .accessfn = pmreg_access_ccntr, .resetvalue = 0,
+              .type = ARM_CP_ALIAS | ARM_CP_IO | ARM_CP_64BIT,
+              .fgt = FGT_PMCCNTR_EL0, .readfn = pmccntr_read,
+              .writefn = pmccntr_write,  },
         };
 #ifdef CONFIG_USER_ONLY
         static const ARMCPRegUserSpaceInfo v8_user_idregs[] = {
diff -Nru qemu-10.0.3+ds/target/i386/cpu.c qemu-10.0.4+ds/target/i386/cpu.c
--- qemu-10.0.3+ds/target/i386/cpu.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/target/i386/cpu.c	2025-09-09 19:21:41.000000000 +0300
@@ -6835,11 +6835,21 @@
         }
         *edx = env->features[FEAT_1_EDX];
         if (threads_per_pkg > 1) {
+            uint32_t num;
+
+            /*
+             * For CPUID.01H.EBX[Bits 23-16], AMD requires logical processor
+             * count, but Intel needs maximum number of addressable IDs for
+             * logical processors per package.
+             */
+            if ((IS_INTEL_CPU(env) || IS_ZHAOXIN_CPU(env))) {
+                num = 1 << apicid_pkg_offset(topo_info);
+            } else {
+                num = threads_per_pkg;
+            }
+
             /* Fixup overflow: max value for bits 23-16 is 255. */
-            *ebx |= MIN(threads_per_pkg, 255) << 16;
-        }
-        if (!cpu->enable_pmu) {
-            *ecx &= ~CPUID_EXT_PDCM;
+            *ebx |= MIN(num, 255) << 16;
         }
         break;
     case 2:
@@ -7830,6 +7840,10 @@
         }
     }
 
+    if (!cpu->enable_pmu) {
+        env->features[FEAT_1_ECX] &= ~CPUID_EXT_PDCM;
+    }
+
     for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) {
         FeatureDep *d = &feature_dependencies[i];
         if (!(env->features[d->from.index] & d->from.mask)) {
diff -Nru qemu-10.0.3+ds/target/i386/kvm/vmsr_energy.c qemu-10.0.4+ds/target/i386/kvm/vmsr_energy.c
--- qemu-10.0.3+ds/target/i386/kvm/vmsr_energy.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/target/i386/kvm/vmsr_energy.c	2025-09-09 19:21:41.000000000 +0300
@@ -67,13 +67,9 @@
     };
 
     QIOChannelSocket *sioc = qio_channel_socket_new();
-    Error *local_err = NULL;
 
     qio_channel_set_name(QIO_CHANNEL(sioc), "vmsr-helper");
-    qio_channel_socket_connect_sync(sioc,
-                                    &saddr,
-                                    &local_err);
-    if (local_err) {
+    if (qio_channel_socket_connect_sync(sioc, &saddr, NULL) < 0) {
         /* Close socket. */
         qio_channel_close(QIO_CHANNEL(sioc), NULL);
         object_unref(OBJECT(sioc));
diff -Nru qemu-10.0.3+ds/target/i386/tcg/decode-new.c.inc qemu-10.0.4+ds/target/i386/tcg/decode-new.c.inc
--- qemu-10.0.3+ds/target/i386/tcg/decode-new.c.inc	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/target/i386/tcg/decode-new.c.inc	2025-09-09 19:21:41.000000000 +0300
@@ -878,10 +878,10 @@
     [0x0e] = X86_OP_ENTRY4(VPBLENDW,   V,x,  H,x,  W,x,  vex4 cpuid(SSE41) avx2_256 p_66),
     [0x0f] = X86_OP_ENTRY4(PALIGNR,    V,x,  H,x,  W,x,  vex4 cpuid(SSSE3) mmx avx2_256 p_00_66),
 
-    [0x18] = X86_OP_ENTRY4(VINSERTx128,  V,qq, H,qq, W,qq, vex6 chk(W0) cpuid(AVX) p_66),
+    [0x18] = X86_OP_ENTRY4(VINSERTx128,  V,qq, H,qq, W,dq, vex6 chk(W0) cpuid(AVX) p_66),
     [0x19] = X86_OP_ENTRY3(VEXTRACTx128, W,dq, V,qq, I,b,  vex6 chk(W0) cpuid(AVX) p_66),
 
-    [0x38] = X86_OP_ENTRY4(VINSERTx128,  V,qq, H,qq, W,qq, vex6 chk(W0) cpuid(AVX2) p_66),
+    [0x38] = X86_OP_ENTRY4(VINSERTx128,  V,qq, H,qq, W,dq, vex6 chk(W0) cpuid(AVX2) p_66),
     [0x39] = X86_OP_ENTRY3(VEXTRACTx128, W,dq, V,qq, I,b,  vex6 chk(W0) cpuid(AVX2) p_66),
 
     /* Listed incorrectly as type 4 */
diff -Nru qemu-10.0.3+ds/target/i386/tcg/system/svm_helper.c qemu-10.0.4+ds/target/i386/tcg/system/svm_helper.c
--- qemu-10.0.3+ds/target/i386/tcg/system/svm_helper.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/target/i386/tcg/system/svm_helper.c	2025-09-09 19:21:41.000000000 +0300
@@ -49,7 +49,7 @@
 static inline void svm_canonicalization(CPUX86State *env, target_ulong *seg_base)
 {
     uint16_t shift_amt = 64 - cpu_x86_virtual_addr_width(env);
-    *seg_base = ((((long) *seg_base) << shift_amt) >> shift_amt);
+    *seg_base = (((int64_t) *seg_base) << shift_amt) >> shift_amt;
 }
 
 static void svm_load_seg(CPUX86State *env, int mmu_idx, hwaddr addr,
diff -Nru qemu-10.0.3+ds/target/loongarch/cpu_helper.c qemu-10.0.4+ds/target/loongarch/cpu_helper.c
--- qemu-10.0.3+ds/target/loongarch/cpu_helper.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/target/loongarch/cpu_helper.c	2025-09-09 19:21:41.000000000 +0300
@@ -299,8 +299,8 @@
     }
 
     /* Check valid extension */
-    addr_high = sextract64(address, TARGET_VIRT_ADDR_SPACE_BITS, 16);
-    if (!(addr_high == 0 || addr_high == -1)) {
+    addr_high = (int64_t)address >> (TARGET_VIRT_ADDR_SPACE_BITS - 1);
+    if (!(addr_high == 0 || addr_high == -1ULL)) {
         return TLBRET_BADADDR;
     }
 
diff -Nru qemu-10.0.3+ds/target/loongarch/tcg/insn_trans/trans_vec.c.inc qemu-10.0.4+ds/target/loongarch/tcg/insn_trans/trans_vec.c.inc
--- qemu-10.0.3+ds/target/loongarch/tcg/insn_trans/trans_vec.c.inc	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/target/loongarch/tcg/insn_trans/trans_vec.c.inc	2025-09-09 19:21:41.000000000 +0300
@@ -3585,7 +3585,9 @@
     int sel, vece;
     uint64_t value;
 
-    if (!check_valid_vldi_mode(a)) {
+    sel = (a->imm >> 12) & 0x1;
+
+    if (sel && !check_valid_vldi_mode(a)) {
         generate_exception(ctx, EXCCODE_INE);
         return true;
     }
@@ -3594,8 +3596,6 @@
         return true;
     }
 
-    sel = (a->imm >> 12) & 0x1;
-
     if (sel) {
         value = vldi_get_value(ctx, a->imm);
         vece = MO_64;
diff -Nru qemu-10.0.3+ds/target/mips/tcg/system/cp0_helper.c qemu-10.0.4+ds/target/mips/tcg/system/cp0_helper.c
--- qemu-10.0.3+ds/target/mips/tcg/system/cp0_helper.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/target/mips/tcg/system/cp0_helper.c	2025-09-09 19:21:41.000000000 +0300
@@ -1561,12 +1561,14 @@
     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;
@@ -1577,15 +1579,17 @@
     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;
diff -Nru qemu-10.0.3+ds/target/mips/tcg/system/tlb_helper.c qemu-10.0.4+ds/target/mips/tcg/system/tlb_helper.c
--- qemu-10.0.3+ds/target/mips/tcg/system/tlb_helper.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/target/mips/tcg/system/tlb_helper.c	2025-09-09 19:21:41.000000000 +0300
@@ -652,7 +652,7 @@
         return 0;
     }
 
-    if ((entry & (1 << psn)) && hugepg) {
+    if (extract64(entry, psn, 1) && hugepg) {
         *huge_page = true;
         *hgpg_directory_hit = true;
         entry = get_tlb_entry_layout(env, entry, leaf_mop, pf_ptew);
diff -Nru qemu-10.0.3+ds/target/ppc/cpu.h qemu-10.0.4+ds/target/ppc/cpu.h
--- qemu-10.0.3+ds/target/ppc/cpu.h	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/target/ppc/cpu.h	2025-09-09 19:21:41.000000000 +0300
@@ -1520,6 +1520,10 @@
     void (*init_proc)(CPUPPCState *env);
     int  (*check_pow)(CPUPPCState *env);
     int  (*check_attn)(CPUPPCState *env);
+
+    /* Handlers to be set by the machine initialising the chips */
+    uint64_t (*load_sprd)(CPUPPCState *env);
+    void (*store_sprd)(CPUPPCState *env, uint64_t val);
 };
 
 static inline bool ppc_cpu_core_single_threaded(CPUState *cs)
diff -Nru qemu-10.0.3+ds/target/ppc/misc_helper.c qemu-10.0.4+ds/target/ppc/misc_helper.c
--- qemu-10.0.3+ds/target/ppc/misc_helper.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/target/ppc/misc_helper.c	2025-09-09 19:21:41.000000000 +0300
@@ -329,69 +329,22 @@
      * accessed by powernv machines.
      */
     PowerPCCPU *cpu = env_archcpu(env);
-    PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
-    target_ulong sprc = env->spr[SPR_POWER_SPRC];
+    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
 
-    if (pc->big_core) {
-        pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
+    if (pcc->load_sprd) {
+        return pcc->load_sprd(env);
     }
 
-    switch (sprc & 0x3e0) {
-    case 0: /* SCRATCH0-3 */
-    case 1: /* SCRATCH4-7 */
-        return pc->scratch[(sprc >> 3) & 0x7];
-
-    case 0x1e0: /* core thread state */
-        if (env->excp_model == POWERPC_EXCP_POWER9) {
-            /*
-             * Only implement for POWER9 because skiboot uses it to check
-             * big-core mode. Other bits are unimplemented so we would
-             * prefer to get unimplemented message on POWER10 if it were
-             * used anywhere.
-             */
-            if (pc->big_core) {
-                return PPC_BIT(63);
-            } else {
-                return 0;
-            }
-        }
-        /* fallthru */
-
-    default:
-        qemu_log_mask(LOG_UNIMP, "mfSPRD: Unimplemented SPRC:0x"
-                                  TARGET_FMT_lx"\n", sprc);
-        break;
-    }
     return 0;
 }
 
 void helper_store_sprd(CPUPPCState *env, target_ulong val)
 {
-    target_ulong sprc = env->spr[SPR_POWER_SPRC];
     PowerPCCPU *cpu = env_archcpu(env);
-    PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
-    int nr;
-
-    if (pc->big_core) {
-        pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
-    }
+    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
 
-    switch (sprc & 0x3e0) {
-    case 0: /* SCRATCH0-3 */
-    case 1: /* SCRATCH4-7 */
-        /*
-         * Log stores to SCRATCH, because some firmware uses these for
-         * debugging and logging, but they would normally be read by the BMC,
-         * which is not implemented in QEMU yet. This gives a way to get at the
-         * information. Could also dump these upon checkstop.
-         */
-        nr = (sprc >> 3) & 0x7;
-        pc->scratch[nr] = val;
-        break;
-    default:
-        qemu_log_mask(LOG_UNIMP, "mtSPRD: Unimplemented SPRC:0x"
-                                  TARGET_FMT_lx"\n", sprc);
-        break;
+    if (pcc->store_sprd) {
+        return pcc->store_sprd(env, val);
     }
 }
 
diff -Nru qemu-10.0.3+ds/target/riscv/csr.c qemu-10.0.4+ds/target/riscv/csr.c
--- qemu-10.0.3+ds/target/riscv/csr.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/target/riscv/csr.c	2025-09-09 19:21:41.000000000 +0300
@@ -372,8 +372,11 @@
 static RISCVException aia_smode32(CPURISCVState *env, int csrno)
 {
     int ret;
+    int csr_priv = get_field(csrno, 0x300);
 
-    if (!riscv_cpu_cfg(env)->ext_ssaia) {
+    if (csr_priv == PRV_M && !riscv_cpu_cfg(env)->ext_smaia) {
+        return RISCV_EXCP_ILLEGAL_INST;
+    } else if (!riscv_cpu_cfg(env)->ext_ssaia) {
         return RISCV_EXCP_ILLEGAL_INST;
     }
 
@@ -5498,7 +5501,7 @@
 
     csr_priv = get_field(csrno, 0x300);
     if (!env->debugger && (effective_priv < csr_priv)) {
-        if (csr_priv == (PRV_S + 1) && env->virt_enabled) {
+        if (csr_priv <= (PRV_S + 1) && env->virt_enabled) {
             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
         }
         return RISCV_EXCP_ILLEGAL_INST;
@@ -5783,8 +5786,8 @@
                           NULL,                read_mstatus_i128           },
     [CSR_MISA]        = { "misa",       any,   read_misa,    write_misa,
                           NULL,                read_misa_i128              },
-    [CSR_MIDELEG]     = { "mideleg",    any,   NULL, NULL,   rmw_mideleg   },
-    [CSR_MEDELEG]     = { "medeleg",    any,   read_medeleg, write_medeleg },
+    [CSR_MIDELEG]     = { "mideleg",    smode,   NULL, NULL,   rmw_mideleg   },
+    [CSR_MEDELEG]     = { "medeleg",    smode,   read_medeleg, write_medeleg },
     [CSR_MIE]         = { "mie",        any,   NULL, NULL,   rmw_mie       },
     [CSR_MTVEC]       = { "mtvec",      any,   read_mtvec,   write_mtvec   },
     [CSR_MCOUNTEREN]  = { "mcounteren", umode, read_mcounteren,
@@ -5792,7 +5795,7 @@
 
     [CSR_MSTATUSH]    = { "mstatush",   any32, read_mstatush,
                           write_mstatush                                   },
-    [CSR_MEDELEGH]    = { "medelegh",   any32, read_zero, write_ignore,
+    [CSR_MEDELEGH]    = { "medelegh",   smode32, read_zero, write_ignore,
                           .min_priv_ver = PRIV_VERSION_1_13_0              },
     [CSR_HEDELEGH]    = { "hedelegh",   hmode32, read_hedelegh, write_hedelegh,
                           .min_priv_ver = PRIV_VERSION_1_13_0              },
@@ -5832,7 +5835,7 @@
     [CSR_MVIP]     = { "mvip",     aia_any, NULL, NULL, rmw_mvip    },
 
     /* Machine-Level High-Half CSRs (AIA) */
-    [CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh },
+    [CSR_MIDELEGH] = { "midelegh", aia_smode32, NULL, NULL, rmw_midelegh },
     [CSR_MIEH]     = { "mieh",     aia_any32, NULL, NULL, rmw_mieh     },
     [CSR_MVIENH]   = { "mvienh",   aia_any32, NULL, NULL, rmw_mvienh   },
     [CSR_MVIPH]    = { "mviph",    aia_any32, NULL, NULL, rmw_mviph    },
diff -Nru qemu-10.0.3+ds/target/riscv/op_helper.c qemu-10.0.4+ds/target/riscv/op_helper.c
--- qemu-10.0.3+ds/target/riscv/op_helper.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/target/riscv/op_helper.c	2025-09-09 19:21:41.000000000 +0300
@@ -353,21 +353,22 @@
 }
 
 static void check_ret_from_m_mode(CPURISCVState *env, target_ulong retpc,
-                                  target_ulong prev_priv)
+                                  target_ulong prev_priv,
+                                  uintptr_t ra)
 {
     if (!(env->priv >= PRV_M)) {
-        riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+        riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra);
     }
 
     if (!riscv_cpu_allow_16bit_insn(&env_archcpu(env)->cfg,
                                     env->priv_ver,
                                     env->misa_ext) && (retpc & 0x3)) {
-        riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
+        riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, ra);
     }
 
     if (riscv_cpu_cfg(env)->pmp &&
         !pmp_get_num_rules(env) && (prev_priv != PRV_M)) {
-        riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
+        riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, ra);
     }
 }
 static target_ulong ssdbltrp_mxret(CPURISCVState *env, target_ulong mstatus,
@@ -392,8 +393,9 @@
     target_ulong retpc = env->mepc;
     uint64_t mstatus = env->mstatus;
     target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
+    uintptr_t ra = GETPC();
 
-    check_ret_from_m_mode(env, retpc, prev_priv);
+    check_ret_from_m_mode(env, retpc, prev_priv, ra);
 
     target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV) &&
                              (prev_priv != PRV_M);
@@ -441,8 +443,9 @@
     target_ulong retpc = env->mnepc;
     target_ulong prev_priv = get_field(env->mnstatus, MNSTATUS_MNPP);
     target_ulong prev_virt;
+    uintptr_t ra = GETPC();
 
-    check_ret_from_m_mode(env, retpc, prev_priv);
+    check_ret_from_m_mode(env, retpc, prev_priv, ra);
 
     prev_virt = get_field(env->mnstatus, MNSTATUS_MNPV) &&
                 (prev_priv != PRV_M);
diff -Nru qemu-10.0.3+ds/target/riscv/pmp.c qemu-10.0.4+ds/target/riscv/pmp.c
--- qemu-10.0.3+ds/target/riscv/pmp.c	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/target/riscv/pmp.c	2025-09-09 19:21:41.000000000 +0300
@@ -206,11 +206,12 @@
         break;
 
     case PMP_AMATCH_TOR:
-        sa = prev_addr << 2; /* shift up from [xx:0] to [xx+2:2] */
-        ea = (this_addr << 2) - 1u;
-        if (sa > ea) {
+        if (prev_addr >= this_addr) {
             sa = ea = 0u;
+            break;
         }
+        sa = prev_addr << 2; /* shift up from [xx:0] to [xx+2:2] */
+        ea = (this_addr << 2) - 1u;
         break;
 
     case PMP_AMATCH_NA4:
diff -Nru qemu-10.0.3+ds/tests/qemu-iotests/039.out qemu-10.0.4+ds/tests/qemu-iotests/039.out
--- qemu-10.0.3+ds/tests/qemu-iotests/039.out	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/tests/qemu-iotests/039.out	2025-09-09 19:21:41.000000000 +0300
@@ -11,7 +11,7 @@
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
 wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed                  ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
 incompatible_features     [0]
 ERROR cluster 5 refcount=0 reference=1
 ERROR OFLAG_COPIED data cluster: l2_entry=8000000000050000 refcount=0
@@ -46,7 +46,7 @@
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
 wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed                  ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
 incompatible_features     [0]
 ERROR cluster 5 refcount=0 reference=1
 Rebuilding refcount structure
@@ -60,7 +60,7 @@
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
 wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed                  ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
 incompatible_features     []
 No errors were found on the image.
 
@@ -79,7 +79,7 @@
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
 wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed                  ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
 incompatible_features     [0]
 ERROR cluster 5 refcount=0 reference=1
 ERROR OFLAG_COPIED data cluster: l2_entry=8000000000050000 refcount=0
@@ -89,7 +89,7 @@
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
 wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed                  ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
 incompatible_features     []
 No errors were found on the image.
 *** done
diff -Nru qemu-10.0.3+ds/tests/qemu-iotests/061.out qemu-10.0.4+ds/tests/qemu-iotests/061.out
--- qemu-10.0.3+ds/tests/qemu-iotests/061.out	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/tests/qemu-iotests/061.out	2025-09-09 19:21:41.000000000 +0300
@@ -118,7 +118,7 @@
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed                  ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
 magic                     0x514649fb
 version                   3
 backing_file_offset       0x0
@@ -304,7 +304,7 @@
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed                  ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
 magic                     0x514649fb
 version                   3
 backing_file_offset       0x0
diff -Nru qemu-10.0.3+ds/tests/qemu-iotests/137.out qemu-10.0.4+ds/tests/qemu-iotests/137.out
--- qemu-10.0.3+ds/tests/qemu-iotests/137.out	2025-07-24 00:05:28.000000000 +0300
+++ qemu-10.0.4+ds/tests/qemu-iotests/137.out	2025-09-09 19:21:41.000000000 +0300
@@ -35,7 +35,7 @@
 qemu-io: Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
 wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed                  ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
 OK: Dirty bit not set
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 qemu-io: Parameter 'lazy-refcounts' expects 'on' or 'off'
diff -Nru qemu-10.0.3+ds/tests/qemu-iotests/common.filter qemu-10.0.4+ds/tests/qemu-iotests/common.filter
--- qemu-10.0.3+ds/tests/qemu-iotests/common.filter	2025-07-24 00:05:29.000000000 +0300
+++ qemu-10.0.4+ds/tests/qemu-iotests/common.filter	2025-09-09 19:21:41.000000000 +0300
@@ -74,7 +74,7 @@
 {
     _filter_win32 | \
     gsed -e "s/[0-9]* ops\; [0-9/:. sec]* ([0-9/.inf]* [EPTGMKiBbytes]*\/sec and [0-9/.inf]* ops\/sec)/X ops\; XX:XX:XX.X (XXX YYY\/sec and XXX ops\/sec)/" \
-        -e "s/: line [0-9][0-9]*:  *[0-9][0-9]*\( Aborted\| Killed\)/:\1/" \
+        -e "s/: line [0-9][0-9]*:  *[0-9][0-9]*\( Aborted\| Killed\) \{2,\}/:\1 /" \
         -e "s/qemu-io> //g"
 }
 
diff -Nru qemu-10.0.3+ds/tests/qtest/qos-test.c qemu-10.0.4+ds/tests/qtest/qos-test.c
--- qemu-10.0.3+ds/tests/qtest/qos-test.c	2025-07-24 00:05:29.000000000 +0300
+++ qemu-10.0.4+ds/tests/qtest/qos-test.c	2025-09-09 19:21:42.000000000 +0300
@@ -328,11 +328,6 @@
 int main(int argc, char **argv, char** envp)
 {
     g_test_init(&argc, &argv, NULL);
-
-    if (g_test_subprocess()) {
-        qos_printf("qos_test running single test in subprocess\n");
-    }
-
     if (g_test_verbose()) {
         qos_printf("ENVIRONMENT VARIABLES: {\n");
         for (char **env = envp; *env != 0; env++) {
diff -Nru qemu-10.0.3+ds/tests/qtest/vhost-user-test.c qemu-10.0.4+ds/tests/qtest/vhost-user-test.c
--- qemu-10.0.3+ds/tests/qtest/vhost-user-test.c	2025-07-24 00:05:29.000000000 +0300
+++ qemu-10.0.4+ds/tests/qtest/vhost-user-test.c	2025-09-09 19:21:42.000000000 +0300
@@ -26,7 +26,6 @@
 #include "libqos/virtio-pci.h"
 
 #include "libqos/malloc-pc.h"
-#include "libqos/qgraph_internal.h"
 #include "hw/virtio/virtio-net.h"
 
 #include "standard-headers/linux/vhost_types.h"
@@ -345,7 +344,7 @@
     }
 
     if (size != VHOST_USER_HDR_SIZE) {
-        qos_printf("%s: Wrong message size received %d\n", __func__, size);
+        g_test_message("Wrong message size received %d", size);
         return;
     }
 
@@ -356,8 +355,8 @@
         p += VHOST_USER_HDR_SIZE;
         size = qemu_chr_fe_read_all(chr, p, msg.size);
         if (size != msg.size) {
-            qos_printf("%s: Wrong message size received %d != %d\n",
-                       __func__, size, msg.size);
+            g_test_message("Wrong message size received %d != %d",
+                           size, msg.size);
             goto out;
         }
     }
@@ -393,7 +392,7 @@
          * We don't need to do anything here, the remote is just
          * letting us know it is in charge. Just log it.
          */
-        qos_printf("set_owner: start of session\n");
+        g_test_message("set_owner: start of session\n");
         break;
 
     case VHOST_USER_GET_PROTOCOL_FEATURES:
@@ -419,7 +418,7 @@
          * the remote end to send this. There is no handshake reply so
          * just log the details for debugging.
          */
-        qos_printf("set_protocol_features: 0x%"PRIx64 "\n", msg.payload.u64);
+        g_test_message("set_protocol_features: 0x%"PRIx64 "\n", msg.payload.u64);
         break;
 
         /*
@@ -427,11 +426,11 @@
          * address of the vrings but we can simply report them.
          */
     case VHOST_USER_SET_VRING_NUM:
-        qos_printf("set_vring_num: %d/%d\n",
+        g_test_message("set_vring_num: %d/%d\n",
                    msg.payload.state.index, msg.payload.state.num);
         break;
     case VHOST_USER_SET_VRING_ADDR:
-        qos_printf("set_vring_addr: 0x%"PRIx64"/0x%"PRIx64"/0x%"PRIx64"\n",
+        g_test_message("set_vring_addr: 0x%"PRIx64"/0x%"PRIx64"/0x%"PRIx64"\n",
                    msg.payload.addr.avail_user_addr,
                    msg.payload.addr.desc_user_addr,
                    msg.payload.addr.used_user_addr);
@@ -464,7 +463,7 @@
     case VHOST_USER_SET_VRING_CALL:
         /* consume the fd */
         if (!qemu_chr_fe_get_msgfds(chr, &fd, 1) && fd < 0) {
-            qos_printf("call fd: %d, do not set non-blocking\n", fd);
+            g_test_message("call fd: %d, do not set non-blocking\n", fd);
             break;
         }
         /*
@@ -510,12 +509,12 @@
          * fully functioning vhost-user we would enable/disable the
          * vring monitoring.
          */
-        qos_printf("set_vring(%d)=%s\n", msg.payload.state.index,
+        g_test_message("set_vring(%d)=%s\n", msg.payload.state.index,
                    msg.payload.state.num ? "enabled" : "disabled");
         break;
 
     default:
-        qos_printf("vhost-user: un-handled message: %d\n", msg.request);
+        g_test_message("vhost-user: un-handled message: %d\n", msg.request);
         break;
     }
 
@@ -539,7 +538,7 @@
     }
 
     if (access(path, R_OK | W_OK | X_OK)) {
-        qos_printf("access on path (%s): %s", path, strerror(errno));
+        g_test_message("access on path (%s): %s", path, strerror(errno));
         g_test_fail();
         return NULL;
     }
@@ -549,13 +548,13 @@
     } while (ret != 0 && errno == EINTR);
 
     if (ret != 0) {
-        qos_printf("statfs on path (%s): %s", path, strerror(errno));
+        g_test_message("statfs on path (%s): %s", path, strerror(errno));
         g_test_fail();
         return NULL;
     }
 
     if (fs.f_type != HUGETLBFS_MAGIC) {
-        qos_printf("Warning: path not on HugeTLBFS: %s", path);
+        g_test_message("Warning: path not on HugeTLBFS: %s", path);
         g_test_fail();
         return NULL;
     }
diff -Nru qemu-10.0.3+ds/ui/curses.c qemu-10.0.4+ds/ui/curses.c
--- qemu-10.0.3+ds/ui/curses.c	2025-07-24 00:05:29.000000000 +0300
+++ qemu-10.0.4+ds/ui/curses.c	2025-09-09 19:21:42.000000000 +0300
@@ -265,7 +265,8 @@
 
 static void curses_refresh(DisplayChangeListener *dcl)
 {
-    int chr, keysym, keycode, keycode_alt;
+    wint_t chr = 0;
+    int keysym, keycode, keycode_alt;
     enum maybe_keycode maybe_keycode = CURSES_KEYCODE;
 
     curses_winch_check();
@@ -284,8 +285,9 @@
         /* while there are any pending key strokes to process */
         chr = console_getch(&maybe_keycode);
 
-        if (chr == -1)
+        if (chr == WEOF) {
             break;
+        }
 
 #ifdef KEY_RESIZE
         /* this shouldn't occur when we use a custom SIGWINCH handler */
@@ -304,9 +306,9 @@
         /* alt or esc key */
         if (keycode == 1) {
             enum maybe_keycode next_maybe_keycode = CURSES_KEYCODE;
-            int nextchr = console_getch(&next_maybe_keycode);
+            wint_t nextchr = console_getch(&next_maybe_keycode);
 
-            if (nextchr != -1) {
+            if (nextchr != WEOF) {
                 chr = nextchr;
                 maybe_keycode = next_maybe_keycode;
                 keycode_alt = ALT;
diff -Nru qemu-10.0.3+ds/ui/input-barrier.c qemu-10.0.4+ds/ui/input-barrier.c
--- qemu-10.0.3+ds/ui/input-barrier.c	2025-07-24 00:05:29.000000000 +0300
+++ qemu-10.0.4+ds/ui/input-barrier.c	2025-09-09 19:21:42.000000000 +0300
@@ -490,7 +490,6 @@
 static void input_barrier_complete(UserCreatable *uc, Error **errp)
 {
     InputBarrier *ib = INPUT_BARRIER(uc);
-    Error *local_err = NULL;
 
     if (!ib->name) {
         error_setg(errp, QERR_MISSING_PARAMETER, "name");
@@ -506,9 +505,7 @@
     ib->sioc = qio_channel_socket_new();
     qio_channel_set_name(QIO_CHANNEL(ib->sioc), "barrier-client");
 
-    qio_channel_socket_connect_sync(ib->sioc, &ib->saddr, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
+    if (qio_channel_socket_connect_sync(ib->sioc, &ib->saddr, errp) < 0) {
         return;
     }
 


Reply to: