Version in base suite: 7.2+dfsg-7+deb12u12 Version in overlay suite: 7.2+dfsg-7+deb12u12 Base version: qemu_7.2+dfsg-7+deb12u12 Target version: qemu_7.2+dfsg-7+deb12u13 Base file: /srv/ftp-master.debian.org/ftp/pool/main/q/qemu/qemu_7.2+dfsg-7+deb12u12.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/q/qemu/qemu_7.2+dfsg-7+deb12u13.dsc changelog | 78 ++ patches/series | 2 patches/v7.2.16.diff | 1368 +++++++++++++++++++++++++++++++++++++++++++++++++ patches/v7.2.17.diff | 1397 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 2845 insertions(+) diff -Nru qemu-7.2+dfsg/debian/changelog qemu-7.2+dfsg/debian/changelog --- qemu-7.2+dfsg/debian/changelog 2025-01-04 14:47:54.000000000 +0000 +++ qemu-7.2+dfsg/debian/changelog 2025-05-03 09:06:15.000000000 +0000 @@ -1,3 +1,81 @@ +qemu (1:7.2+dfsg-7+deb12u13) bookworm; urgency=medium + + * v7.2.17: + - Update version for 7.2.17 release + - hw/misc/aspeed_hace: Fix buffer overflow in has_padding function + - target/ppc: Fix e200 duplicate SPRs + - vdpa: Allow vDPA to work on big-endian machine + - vdpa: Fix endian bugs in shadow virtqueue + - target/arm: Simplify pstate_sm check in sve_access_check + - target/arm: Make DisasContext.{fp, sve}_access_checked tristate + - util/cacheflush: Make first DSB unconditional on aarch64 + - ui/cocoa: Temporarily ignore annoying deprecated declaration warnings + - docs: Rename default-configs to configs + - block: Zero block driver state before reopening + - hw/net/smc91c111: Don't allow data register access to overrun buffer + - hw/net/smc91c111: Sanitize packet length on tx + - hw/net/smc91c111: Sanitize packet numbers + - hw/net/smc91c111: Ignore attempt to pop from empty RX fifo + - ppc/pnv/occ: Fix common area sensor offsets + - hw/gpio: npcm7xx: fixup out-of-bounds access + - block/qed: fix use-after-free by nullifying timer pointer after free + - goldfish_rtc: Fix tick_offset migration + - target/riscv: throw debug exception before page fault + - target/riscv/debug.c: use wp size = 4 for 32-bit CPUs + - target/riscv: rvv: Fix unexpected behavior of vector reduction + instructions when vl is 0 + - cryptodev/vhost: allocate CryptoDevBackendVhost using g_mem0() + - amd_iommu: Use correct bitmask to set capability BAR + - hw/i386/amd_iommu: Explicit use of AMDVI_BASE_ADDR in amdvi_init + - amd_iommu: Use correct DTE field for interrupt passthrough + - Kconfig: Extract CONFIG_USB_CHIPIDEA from CONFIG_IMX + - hw/intc/arm_gicv3_cpuif: Don't downgrade monitor traps for AArch32 EL3 + - target/arm: Make CP_ACCESS_TRAPs to AArch32 EL3 be Monitor traps + - target/arm: Report correct syndrome for UNDEFINED LOR sysregs when NS=0 + - target/arm: Report correct syndrome for UNDEFINED S1E2 AT ops at EL3 + - target/arm: Report correct syndrome for UNDEFINED CNTPS_*_EL1 + from EL2 and NS EL1 + - target/sparc: Fix gdbstub incorrectly handling registers f32-f62 + - ui/sdl2: reenable the SDL2 Windows keyboard hook procedure + - linux-user: Do not define struct sched_attr if libc headers do + * v7.2.16: + - Update version for 7.2.16 release + - hw/usb/canokey: Fix buffer overflow for OUT packet + - target/arm: arm_reset_sve_state() should set FPSR, not FPCR + - tests: acpi: update expected blobs + - pci: acpi: Windows 'PCI Label Id' bug workaround + - tests: acpi: whitelist expected blobs + - pci/msix: Fix msix pba read vector poll end calculation + - pci: ensure valid link status bits for downstream ports + - hw/usb/hcd-xhci-pci: Use modulo to select MSI vector as per spec + - backends/cryptodev-vhost-user: Fix local_error leaks + - target/i386/cpu: Fix notes for CPU models + - docs: Correct release of TCG trace-events removal + - s390x/s390-virtio-ccw: don't crash on weird RAM sizes + - meson.build: Disallow libnfs v6 to fix the broken macOS build + - hw/intc/arm_gicv3_its: Zero initialize local DTEntry etc structs + - x86/loader: only patch linux kernels + - fuzz: specify audiodev for usb-audio + - tcg/riscv: Fix StoreStore barrier generation + - hw/openrisc/openrisc_sim: keep serial@90000000 as default + - target/ppc: Fix non-maskable interrupt while halted + - tests/9p: also check 'Tgetattr' in 'use-after-unlink' test + - 9pfs: fix 'Tgetattr' after unlink + - 9pfs: remove obsolete comment in v9fs_getattr() + - tests/9p: add 'use-after-unlink' test + - tests/9p: add missing Rgetattr response name + - tests/9p: fix Rreaddir response name + - scsi: megasas: Internal cdbs have 16-byte length + - ssh: Do not switch session to non-blocking mode + - qdev: Fix set_pci_devfn() to visit option only once + - virtio-net: Fix size check in dhclient workaround + - cirrus-ci: Remove MSYS2 jobs duplicated with gitlab-ci + - hw/intc/loongarch_extioi: Use set_bit32() and clear_bit32() for s->isr + - bitops.h: Define bit operations on 'uint32_t' arrays + - hw/intc/openpic: Avoid taking address of out-of-bounds array index + + -- Michael Tokarev Sat, 03 May 2025 12:06:15 +0300 + qemu (1:7.2+dfsg-7+deb12u12) bookworm; urgency=medium * mark-internal-codegen-functions-hidden.patch: diff -Nru qemu-7.2+dfsg/debian/patches/series qemu-7.2+dfsg/debian/patches/series --- qemu-7.2+dfsg/debian/patches/series 2025-01-04 14:47:49.000000000 +0000 +++ qemu-7.2+dfsg/debian/patches/series 2025-05-03 09:05:44.000000000 +0000 @@ -13,6 +13,8 @@ v7.2.13.diff v7.2.14.diff v7.2.15.diff +v7.2.16.diff +v7.2.17.diff microvm-default-machine-type.patch skip-meson-pc-bios.diff linux-user-binfmt-P.diff diff -Nru qemu-7.2+dfsg/debian/patches/v7.2.16.diff qemu-7.2+dfsg/debian/patches/v7.2.16.diff --- qemu-7.2+dfsg/debian/patches/v7.2.16.diff 1970-01-01 00:00:00.000000000 +0000 +++ qemu-7.2+dfsg/debian/patches/v7.2.16.diff 2025-05-03 09:05:44.000000000 +0000 @@ -0,0 +1,1368 @@ +Subject: v7.2.16 +Date: Sat Feb 8 14:26:26 2025 +0300 +From: Michael Tokarev +Forwarded: not-needed + +This is a difference between upstream qemu v7.2.15 +and upstream qemu v7.2.16. + + .cirrus.yml | 109 ---------------- + MAINTAINERS | 3 +- + VERSION | 2 +- + backends/cryptodev-vhost-user.c | 3 +- + block/ssh.c | 3 - + docs/about/removed-features.rst | 4 +- + hw/9pfs/9p.c | 12 +- + hw/core/qdev-properties-system.c | 54 +++++--- + hw/i386/acpi-build.c | 33 +++-- + hw/i386/x86.c | 2 +- + hw/intc/arm_gicv3_its.c | 44 +++---- + hw/intc/loongarch_extioi.c | 9 +- + hw/intc/openpic.c | 15 +-- + hw/net/virtio-net.c | 5 +- + hw/openrisc/openrisc_sim.c | 26 +++- + hw/pci/msix.c | 2 +- + hw/pci/pcie.c | 12 +- + hw/s390x/s390-virtio-ccw.c | 11 ++ + hw/scsi/megasas.c | 14 +-- + hw/usb/canokey.c | 6 +- + hw/usb/canokey.h | 4 - + hw/usb/hcd-xhci-pci.c | 1 + + include/qemu/bitmap.h | 8 ++ + include/qemu/bitops.h | 172 +++++++++++++++++++++++++- + meson.build | 2 +- + target/arm/sme_helper.c | 2 +- + target/i386/cpu.c | 3 +- + target/ppc/excp_helper.c | 7 ++ + tcg/riscv/tcg-target.c.inc | 2 +- + tests/data/acpi/pc/DSDT | Bin 6458 -> 6476 bytes + tests/data/acpi/pc/DSDT.acpierst | Bin 6418 -> 6436 bytes + tests/data/acpi/pc/DSDT.acpihmat | Bin 7783 -> 7801 bytes + tests/data/acpi/pc/DSDT.bridge | Bin 9532 -> 9550 bytes + tests/data/acpi/pc/DSDT.cphp | Bin 6922 -> 6940 bytes + tests/data/acpi/pc/DSDT.dimmpxm | Bin 8112 -> 8130 bytes + tests/data/acpi/pc/DSDT.hpbridge | Bin 6418 -> 6436 bytes + tests/data/acpi/pc/DSDT.ipmikcs | Bin 6530 -> 6548 bytes + tests/data/acpi/pc/DSDT.memhp | Bin 7817 -> 7835 bytes + tests/data/acpi/pc/DSDT.nohpet | Bin 6316 -> 6334 bytes + tests/data/acpi/pc/DSDT.numamem | Bin 6464 -> 6482 bytes + tests/data/acpi/pc/DSDT.roothp | Bin 6656 -> 6674 bytes + tests/data/acpi/q35/DSDT | Bin 8310 -> 8328 bytes + tests/data/acpi/q35/DSDT.acpierst | Bin 8327 -> 8345 bytes + tests/data/acpi/q35/DSDT.acpihmat | Bin 9635 -> 9653 bytes + tests/data/acpi/q35/DSDT.acpihmat-noinitiator | Bin 8589 -> 8607 bytes + tests/data/acpi/q35/DSDT.applesmc | Bin 8356 -> 8374 bytes + tests/data/acpi/q35/DSDT.bridge | Bin 11439 -> 11457 bytes + tests/data/acpi/q35/DSDT.core-count2 | Bin 32450 -> 32468 bytes + tests/data/acpi/q35/DSDT.cphp | Bin 8774 -> 8792 bytes + tests/data/acpi/q35/DSDT.cxl | Bin 9637 -> 9655 bytes + tests/data/acpi/q35/DSDT.dimmpxm | Bin 9964 -> 9982 bytes + tests/data/acpi/q35/DSDT.ipmibt | Bin 8385 -> 8403 bytes + tests/data/acpi/q35/DSDT.ipmismbus | Bin 8398 -> 8416 bytes + tests/data/acpi/q35/DSDT.ivrs | Bin 8327 -> 8345 bytes + tests/data/acpi/q35/DSDT.memhp | Bin 9669 -> 9687 bytes + tests/data/acpi/q35/DSDT.mmio64 | Bin 9440 -> 9458 bytes + tests/data/acpi/q35/DSDT.multi-bridge | Bin 8630 -> 8648 bytes + tests/data/acpi/q35/DSDT.nohpet | Bin 8168 -> 8186 bytes + tests/data/acpi/q35/DSDT.numamem | Bin 8316 -> 8334 bytes + tests/data/acpi/q35/DSDT.pvpanic-isa | Bin 8411 -> 8429 bytes + tests/data/acpi/q35/DSDT.tis.tpm12 | Bin 8916 -> 8934 bytes + tests/data/acpi/q35/DSDT.tis.tpm2 | Bin 8942 -> 8960 bytes + tests/data/acpi/q35/DSDT.viot | Bin 9419 -> 9437 bytes + tests/data/acpi/q35/DSDT.xapic | Bin 35673 -> 35691 bytes + tests/qtest/fuzz/generic_fuzz_configs.h | 3 +- + tests/qtest/libqos/virtio-9p-client.c | 3 +- + tests/qtest/virtio-9p-test.c | 46 +++++++ + 67 files changed, 393 insertions(+), 229 deletions(-) + +diff --git a/.cirrus.yml b/.cirrus.yml +deleted file mode 100644 +index 4895987da4..0000000000 +--- a/.cirrus.yml ++++ /dev/null +@@ -1,109 +0,0 @@ +-env: +- CIRRUS_CLONE_DEPTH: 1 +- +-windows_msys2_task: +- timeout_in: 90m +- windows_container: +- image: cirrusci/windowsservercore:2019 +- os_version: 2019 +- cpu: 8 +- memory: 8G +- env: +- CIRRUS_SHELL: powershell +- MSYS: winsymlinks:native +- MSYSTEM: MINGW64 +- MSYS2_URL: https://github.com/msys2/msys2-installer/releases/download/2022-06-03/msys2-base-x86_64-20220603.sfx.exe +- MSYS2_FINGERPRINT: 0 +- MSYS2_PACKAGES: " +- diffutils git grep make pkg-config sed +- mingw-w64-x86_64-python +- mingw-w64-x86_64-python-sphinx +- mingw-w64-x86_64-toolchain +- mingw-w64-x86_64-SDL2 +- mingw-w64-x86_64-SDL2_image +- mingw-w64-x86_64-gtk3 +- mingw-w64-x86_64-glib2 +- mingw-w64-x86_64-ninja +- mingw-w64-x86_64-jemalloc +- mingw-w64-x86_64-lzo2 +- mingw-w64-x86_64-zstd +- mingw-w64-x86_64-libjpeg-turbo +- mingw-w64-x86_64-pixman +- mingw-w64-x86_64-libgcrypt +- mingw-w64-x86_64-libpng +- mingw-w64-x86_64-libssh +- mingw-w64-x86_64-snappy +- mingw-w64-x86_64-libusb +- mingw-w64-x86_64-usbredir +- mingw-w64-x86_64-libtasn1 +- mingw-w64-x86_64-nettle +- mingw-w64-x86_64-cyrus-sasl +- mingw-w64-x86_64-curl +- mingw-w64-x86_64-gnutls +- mingw-w64-x86_64-libnfs +- " +- CHERE_INVOKING: 1 +- msys2_cache: +- folder: C:\tools\archive +- reupload_on_changes: false +- # These env variables are used to generate fingerprint to trigger the cache procedure +- # If wanna to force re-populate msys2, increase MSYS2_FINGERPRINT +- fingerprint_script: +- - | +- echo $env:CIRRUS_TASK_NAME +- echo $env:MSYS2_URL +- echo $env:MSYS2_FINGERPRINT +- echo $env:MSYS2_PACKAGES +- populate_script: +- - | +- md -Force C:\tools\archive\pkg +- $start_time = Get-Date +- bitsadmin /transfer msys_download /dynamic /download /priority FOREGROUND $env:MSYS2_URL C:\tools\archive\base.exe +- Write-Output "Download time taken: $((Get-Date).Subtract($start_time))" +- cd C:\tools +- C:\tools\archive\base.exe -y +- del -Force C:\tools\archive\base.exe +- Write-Output "Base install time taken: $((Get-Date).Subtract($start_time))" +- $start_time = Get-Date +- +- ((Get-Content -path C:\tools\msys64\etc\\post-install\\07-pacman-key.post -Raw) -replace '--refresh-keys', '--version') | Set-Content -Path C:\tools\msys64\etc\\post-install\\07-pacman-key.post +- C:\tools\msys64\usr\bin\bash.exe -lc "sed -i 's/^CheckSpace/#CheckSpace/g' /etc/pacman.conf" +- C:\tools\msys64\usr\bin\bash.exe -lc "export" +- C:\tools\msys64\usr\bin\pacman.exe --noconfirm -Sy +- echo Y | C:\tools\msys64\usr\bin\pacman.exe --noconfirm -Suu --overwrite=* +- taskkill /F /FI "MODULES eq msys-2.0.dll" +- tasklist +- C:\tools\msys64\usr\bin\bash.exe -lc "mv -f /etc/pacman.conf.pacnew /etc/pacman.conf || true" +- C:\tools\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Syuu --overwrite=*" +- Write-Output "Core install time taken: $((Get-Date).Subtract($start_time))" +- $start_time = Get-Date +- +- C:\tools\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -S --needed $env:MSYS2_PACKAGES" +- Write-Output "Package install time taken: $((Get-Date).Subtract($start_time))" +- $start_time = Get-Date +- +- del -Force -ErrorAction SilentlyContinue C:\tools\msys64\etc\mtab +- del -Force -ErrorAction SilentlyContinue C:\tools\msys64\dev\fd +- del -Force -ErrorAction SilentlyContinue C:\tools\msys64\dev\stderr +- del -Force -ErrorAction SilentlyContinue C:\tools\msys64\dev\stdin +- del -Force -ErrorAction SilentlyContinue C:\tools\msys64\dev\stdout +- del -Force -Recurse -ErrorAction SilentlyContinue C:\tools\msys64\var\cache\pacman\pkg +- tar cf C:\tools\archive\msys64.tar -C C:\tools\ msys64 +- +- Write-Output "Package archive time taken: $((Get-Date).Subtract($start_time))" +- del -Force -Recurse -ErrorAction SilentlyContinue c:\tools\msys64 +- install_script: +- - | +- $start_time = Get-Date +- cd C:\tools +- ls C:\tools\archive\msys64.tar +- tar xf C:\tools\archive\msys64.tar +- Write-Output "Extract msys2 time taken: $((Get-Date).Subtract($start_time))" +- script: +- - C:\tools\msys64\usr\bin\bash.exe -lc "mkdir build" +- - C:\tools\msys64\usr\bin\bash.exe -lc "cd build && ../configure --python=python3" +- - C:\tools\msys64\usr\bin\bash.exe -lc "cd build && make -j8" +- - exit $LastExitCode +- test_script: +- - C:\tools\msys64\usr\bin\bash.exe -lc "cd build && make V=1 check" +- - exit $LastExitCode +diff --git a/MAINTAINERS b/MAINTAINERS +index e688db1f55..83c4eacc66 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -3731,8 +3731,7 @@ W: https://cirrus-ci.com/github/qemu/qemu + Windows Hosted Continuous Integration + M: Yonggang Luo + S: Maintained +-F: .cirrus.yml +-W: https://cirrus-ci.com/github/qemu/qemu ++F: .gitlab-ci.d/windows.yml + + Guest Test Compilation Support + M: Alex Bennée +diff --git a/VERSION b/VERSION +index cc53d22108..a1f5232276 100644 +--- a/VERSION ++++ b/VERSION +@@ -1 +1 @@ +-7.2.15 ++7.2.16 +diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c +index ab3028e045..518f18b838 100644 +--- a/backends/cryptodev-vhost-user.c ++++ b/backends/cryptodev-vhost-user.c +@@ -283,8 +283,7 @@ static int cryptodev_vhost_user_create_session( + break; + + default: +- error_setg(&local_error, "Unsupported opcode :%" PRIu32 "", +- sess_info->op_code); ++ error_report("Unsupported opcode :%" PRIu32 "", sess_info->op_code); + return -VIRTIO_CRYPTO_NOTSUPP; + } + +diff --git a/block/ssh.c b/block/ssh.c +index 04726d4ecb..c90d705453 100644 +--- a/block/ssh.c ++++ b/block/ssh.c +@@ -859,9 +859,6 @@ static int ssh_file_open(BlockDriverState *bs, QDict *options, int bdrv_flags, + goto err; + } + +- /* Go non-blocking. */ +- ssh_set_blocking(s->session, 0); +- + if (s->attrs->type == SSH_FILEXFER_TYPE_REGULAR) { + bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE; + } +diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst +index 63df9848fd..93cc6e47b6 100644 +--- a/docs/about/removed-features.rst ++++ b/docs/about/removed-features.rst +@@ -702,8 +702,8 @@ reason the maintainers strongly suspected no one actually used it. + TCG introspection features + -------------------------- + +-TCG trace-events (since 6.2) +-'''''''''''''''''''''''''''' ++TCG trace-events (removed in 7.0) ++''''''''''''''''''''''''''''''''' + + The ability to add new TCG trace points had bit rotted and as the + feature can be replicated with TCG plugins it was removed. If +diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c +index 51ad5bfb11..d950ad6de6 100644 +--- a/hw/9pfs/9p.c ++++ b/hw/9pfs/9p.c +@@ -1605,11 +1605,13 @@ static void coroutine_fn v9fs_getattr(void *opaque) + retval = -ENOENT; + goto out_nofid; + } +- /* +- * Currently we only support BASIC fields in stat, so there is no +- * need to look at request_mask. +- */ +- retval = v9fs_co_lstat(pdu, &fidp->path, &stbuf); ++ if ((fidp->fid_type == P9_FID_FILE && fidp->fs.fd != -1) || ++ (fidp->fid_type == P9_FID_DIR && fidp->fs.dir.stream)) ++ { ++ retval = v9fs_co_fstat(pdu, fidp, &stbuf); ++ } else { ++ retval = v9fs_co_lstat(pdu, &fidp->path, &stbuf); ++ } + if (retval < 0) { + goto out; + } +diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c +index a91f60567a..d350789e76 100644 +--- a/hw/core/qdev-properties-system.c ++++ b/hw/core/qdev-properties-system.c +@@ -740,39 +740,57 @@ static void set_pci_devfn(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) + { + Property *prop = opaque; ++ g_autofree GenericAlternate *alt; + int32_t value, *ptr = object_field_prop_ptr(obj, prop); + unsigned int slot, fn, n; +- char *str; ++ g_autofree char *str = NULL; ++ ++ if (!visit_start_alternate(v, name, &alt, sizeof(*alt), errp)) { ++ return; ++ } ++ ++ switch (alt->type) { ++ case QTYPE_QSTRING: ++ if (!visit_type_str(v, name, &str, errp)) { ++ goto out; ++ } ++ ++ if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) { ++ fn = 0; ++ if (sscanf(str, "%x%n", &slot, &n) != 1) { ++ goto invalid; ++ } ++ } ++ if (str[n] != '\0' || fn > 7 || slot > 31) { ++ goto invalid; ++ } ++ *ptr = slot << 3 | fn; ++ break; + +- if (!visit_type_str(v, name, &str, NULL)) { ++ case QTYPE_QNUM: + if (!visit_type_int32(v, name, &value, errp)) { +- return; ++ goto out; + } + if (value < -1 || value > 255) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + name ? name : "null", "a value between -1 and 255"); +- return; ++ goto out; + } + *ptr = value; +- return; +- } ++ break; + +- if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) { +- fn = 0; +- if (sscanf(str, "%x%n", &slot, &n) != 1) { +- goto invalid; +- } +- } +- if (str[n] != '\0' || fn > 7 || slot > 31) { +- goto invalid; ++ default: ++ error_setg(errp, "Invalid parameter type for '%s', expected int or str", ++ name ? name : "null"); ++ goto out; + } +- *ptr = slot << 3 | fn; +- g_free(str); +- return; ++ ++ goto out; + + invalid: + error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str); +- g_free(str); ++out: ++ visit_end_alternate(v, (void **) &alt); + } + + static int print_pci_devfn(Object *obj, Property *prop, char *dest, +diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c +index f9cdacadb1..79b68f2218 100644 +--- a/hw/i386/acpi-build.c ++++ b/hw/i386/acpi-build.c +@@ -541,6 +541,7 @@ static Aml *aml_pci_pdsm(void) + Aml *acpi_index = aml_local(2); + Aml *zero = aml_int(0); + Aml *one = aml_int(1); ++ Aml *not_supp = aml_int(0xFFFFFFFF); + Aml *func = aml_arg(2); + Aml *rev = aml_arg(1); + Aml *params = aml_arg(4); +@@ -586,7 +587,7 @@ static Aml *aml_pci_pdsm(void) + */ + ifctx1 = aml_if(aml_lnot( + aml_or(aml_equal(acpi_index, zero), +- aml_equal(acpi_index, aml_int(0xFFFFFFFF)), NULL) ++ aml_equal(acpi_index, not_supp), NULL) + )); + { + /* have supported functions */ +@@ -612,18 +613,30 @@ static Aml *aml_pci_pdsm(void) + { + Aml *pkg = aml_package(2); + +- aml_append(pkg, zero); +- /* +- * optional, if not impl. should return null string +- */ +- aml_append(pkg, aml_string("%s", "")); +- aml_append(ifctx, aml_store(pkg, ret)); +- + aml_append(ifctx, aml_store(aml_call2("AIDX", bnum, sunum), acpi_index)); ++ aml_append(ifctx, aml_store(pkg, ret)); + /* +- * update acpi-index to actual value ++ * Windows calls func=7 without checking if it's available, ++ * as workaround Microsoft has suggested to return invalid for func7 ++ * Package, so return 2 elements package but only initialize elements ++ * when acpi_index is supported and leave them uninitialized, which ++ * leads elements to being Uninitialized ObjectType and should trip ++ * Windows into discarding result as an unexpected and prevent setting ++ * bogus 'PCI Label' on the device. + */ +- aml_append(ifctx, aml_store(acpi_index, aml_index(ret, zero))); ++ ifctx1 = aml_if(aml_lnot(aml_lor( ++ aml_equal(acpi_index, zero), aml_equal(acpi_index, not_supp) ++ ))); ++ { ++ aml_append(ifctx1, aml_store(acpi_index, aml_index(ret, zero))); ++ /* ++ * optional, if not impl. should return null string ++ */ ++ aml_append(ifctx1, aml_store(aml_string("%s", ""), ++ aml_index(ret, one))); ++ } ++ aml_append(ifctx, ifctx1); ++ + aml_append(ifctx, aml_return(ret)); + } + +diff --git a/hw/i386/x86.c b/hw/i386/x86.c +index 80be3032cc..a2925821c5 100644 +--- a/hw/i386/x86.c ++++ b/hw/i386/x86.c +@@ -1084,7 +1084,7 @@ void x86_load_linux(X86MachineState *x86ms, + * kernel on the other side of the fw_cfg interface matches the hash of the + * file the user passed in. + */ +- if (!sev_enabled()) { ++ if (!sev_enabled() && protocol > 0) { + memcpy(setup, header, MIN(sizeof(header), setup_size)); + } + +diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c +index 2ff21ed6bb..05b63a0848 100644 +--- a/hw/intc/arm_gicv3_its.c ++++ b/hw/intc/arm_gicv3_its.c +@@ -468,7 +468,7 @@ static ItsCmdResult lookup_vte(GICv3ITSState *s, const char *who, + static ItsCmdResult process_its_cmd_phys(GICv3ITSState *s, const ITEntry *ite, + int irqlevel) + { +- CTEntry cte; ++ CTEntry cte = {}; + ItsCmdResult cmdres; + + cmdres = lookup_cte(s, __func__, ite->icid, &cte); +@@ -482,7 +482,7 @@ static ItsCmdResult process_its_cmd_phys(GICv3ITSState *s, const ITEntry *ite, + static ItsCmdResult process_its_cmd_virt(GICv3ITSState *s, const ITEntry *ite, + int irqlevel) + { +- VTEntry vte; ++ VTEntry vte = {}; + ItsCmdResult cmdres; + + cmdres = lookup_vte(s, __func__, ite->vpeid, &vte); +@@ -517,8 +517,8 @@ static ItsCmdResult process_its_cmd_virt(GICv3ITSState *s, const ITEntry *ite, + static ItsCmdResult do_process_its_cmd(GICv3ITSState *s, uint32_t devid, + uint32_t eventid, ItsCmdType cmd) + { +- DTEntry dte; +- ITEntry ite; ++ DTEntry dte = {}; ++ ITEntry ite = {}; + ItsCmdResult cmdres; + int irqlevel; + +@@ -586,8 +586,8 @@ static ItsCmdResult process_mapti(GICv3ITSState *s, const uint64_t *cmdpkt, + uint32_t pIntid = 0; + uint64_t num_eventids; + uint16_t icid = 0; +- DTEntry dte; +- ITEntry ite; ++ DTEntry dte = {}; ++ ITEntry ite = {}; + + devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT; + eventid = cmdpkt[1] & EVENTID_MASK; +@@ -654,8 +654,8 @@ static ItsCmdResult process_vmapti(GICv3ITSState *s, const uint64_t *cmdpkt, + { + uint32_t devid, eventid, vintid, doorbell, vpeid; + uint32_t num_eventids; +- DTEntry dte; +- ITEntry ite; ++ DTEntry dte = {}; ++ ITEntry ite = {}; + + if (!its_feature_virtual(s)) { + return CMD_CONTINUE; +@@ -764,7 +764,7 @@ static bool update_cte(GICv3ITSState *s, uint16_t icid, const CTEntry *cte) + static ItsCmdResult process_mapc(GICv3ITSState *s, const uint64_t *cmdpkt) + { + uint16_t icid; +- CTEntry cte; ++ CTEntry cte = {}; + + icid = cmdpkt[2] & ICID_MASK; + cte.valid = cmdpkt[2] & CMD_FIELD_VALID_MASK; +@@ -825,7 +825,7 @@ static bool update_dte(GICv3ITSState *s, uint32_t devid, const DTEntry *dte) + static ItsCmdResult process_mapd(GICv3ITSState *s, const uint64_t *cmdpkt) + { + uint32_t devid; +- DTEntry dte; ++ DTEntry dte = {}; + + devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT; + dte.size = cmdpkt[1] & SIZE_MASK; +@@ -889,9 +889,9 @@ static ItsCmdResult process_movi(GICv3ITSState *s, const uint64_t *cmdpkt) + { + uint32_t devid, eventid; + uint16_t new_icid; +- DTEntry dte; +- CTEntry old_cte, new_cte; +- ITEntry old_ite; ++ DTEntry dte = {}; ++ CTEntry old_cte = {}, new_cte = {}; ++ ITEntry old_ite = {}; + ItsCmdResult cmdres; + + devid = FIELD_EX64(cmdpkt[0], MOVI_0, DEVICEID); +@@ -968,7 +968,7 @@ static bool update_vte(GICv3ITSState *s, uint32_t vpeid, const VTEntry *vte) + + static ItsCmdResult process_vmapp(GICv3ITSState *s, const uint64_t *cmdpkt) + { +- VTEntry vte; ++ VTEntry vte = {}; + uint32_t vpeid; + + if (!its_feature_virtual(s)) { +@@ -1033,7 +1033,7 @@ static void vmovp_callback(gpointer data, gpointer opaque) + */ + GICv3ITSState *s = data; + VmovpCallbackData *cbdata = opaque; +- VTEntry vte; ++ VTEntry vte = {}; + ItsCmdResult cmdres; + + cmdres = lookup_vte(s, __func__, cbdata->vpeid, &vte); +@@ -1088,9 +1088,9 @@ static ItsCmdResult process_vmovi(GICv3ITSState *s, const uint64_t *cmdpkt) + { + uint32_t devid, eventid, vpeid, doorbell; + bool doorbell_valid; +- DTEntry dte; +- ITEntry ite; +- VTEntry old_vte, new_vte; ++ DTEntry dte = {}; ++ ITEntry ite = {}; ++ VTEntry old_vte = {}, new_vte = {}; + ItsCmdResult cmdres; + + if (!its_feature_virtual(s)) { +@@ -1189,10 +1189,10 @@ static ItsCmdResult process_vinvall(GICv3ITSState *s, const uint64_t *cmdpkt) + static ItsCmdResult process_inv(GICv3ITSState *s, const uint64_t *cmdpkt) + { + uint32_t devid, eventid; +- ITEntry ite; +- DTEntry dte; +- CTEntry cte; +- VTEntry vte; ++ ITEntry ite = {}; ++ DTEntry dte = {}; ++ CTEntry cte = {}; ++ VTEntry vte = {}; + ItsCmdResult cmdres; + + devid = FIELD_EX64(cmdpkt[0], INV_0, DEVICEID); +diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c +index 4b8ec3f28a..fe17c7e0b1 100644 +--- a/hw/intc/loongarch_extioi.c ++++ b/hw/intc/loongarch_extioi.c +@@ -56,14 +56,9 @@ static void extioi_setirq(void *opaque, int irq, int level) + LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); + trace_loongarch_extioi_setirq(irq, level); + if (level) { +- /* +- * s->isr should be used in vmstate structure, +- * but it not support 'unsigned long', +- * so we have to switch it. +- */ +- set_bit(irq, (unsigned long *)s->isr); ++ set_bit32(irq, s->isr); + } else { +- clear_bit(irq, (unsigned long *)s->isr); ++ clear_bit32(irq, s->isr); + } + extioi_update_irq(s, irq, level); + } +diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c +index c757adbe53..adc79abbe5 100644 +--- a/hw/intc/openpic.c ++++ b/hw/intc/openpic.c +@@ -1035,13 +1035,14 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr, + s_IRQ = IRQ_get_next(opp, &dst->servicing); + /* Check queued interrupts. */ + n_IRQ = IRQ_get_next(opp, &dst->raised); +- src = &opp->src[n_IRQ]; +- if (n_IRQ != -1 && +- (s_IRQ == -1 || +- IVPR_PRIORITY(src->ivpr) > dst->servicing.priority)) { +- DPRINTF("Raise OpenPIC INT output cpu %d irq %d", +- idx, n_IRQ); +- qemu_irq_raise(opp->dst[idx].irqs[OPENPIC_OUTPUT_INT]); ++ if (n_IRQ != -1) { ++ src = &opp->src[n_IRQ]; ++ if (s_IRQ == -1 || ++ IVPR_PRIORITY(src->ivpr) > dst->servicing.priority) { ++ DPRINTF("Raise OpenPIC INT output cpu %d irq %d", ++ idx, n_IRQ); ++ qemu_irq_raise(opp->dst[idx].irqs[OPENPIC_OUTPUT_INT]); ++ } + } + break; + default: +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index 925a5c319e..204a80ec71 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -1647,8 +1647,11 @@ static void virtio_net_hdr_swap(VirtIODevice *vdev, struct virtio_net_hdr *hdr) + static void work_around_broken_dhclient(struct virtio_net_hdr *hdr, + uint8_t *buf, size_t size) + { ++ size_t csum_size = ETH_HLEN + sizeof(struct ip_header) + ++ sizeof(struct udp_header); ++ + if ((hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && /* missing csum */ +- (size > 27 && size < 1500) && /* normal sized MTU */ ++ (size >= csum_size && size < 1500) && /* normal sized MTU */ + (buf[12] == 0x08 && buf[13] == 0x00) && /* ethertype == IPv4 */ + (buf[23] == 17) && /* ip.protocol == UDP */ + (buf[34] == 0 && buf[35] == 67)) { /* udp.srcport == bootps */ +diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c +index 35da123aef..dc1fea8cd8 100644 +--- a/hw/openrisc/openrisc_sim.c ++++ b/hw/openrisc/openrisc_sim.c +@@ -248,7 +248,7 @@ static void openrisc_sim_serial_init(Or1ksimState *state, hwaddr base, + void *fdt = state->fdt; + char *nodename; + qemu_irq serial_irq; +- char alias[sizeof("uart0")]; ++ char alias[sizeof("serial0")]; + int i; + + if (num_cpus > 1) { +@@ -263,7 +263,7 @@ static void openrisc_sim_serial_init(Or1ksimState *state, hwaddr base, + serial_irq = get_cpu_irq(cpus, 0, irq_pin); + } + serial_mm_init(get_system_memory(), base, 0, serial_irq, 115200, +- serial_hd(OR1KSIM_UART_COUNT - uart_idx - 1), ++ serial_hd(uart_idx), + DEVICE_NATIVE_ENDIAN); + + /* Add device tree node for serial. */ +@@ -275,10 +275,13 @@ static void openrisc_sim_serial_init(Or1ksimState *state, hwaddr base, + qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", OR1KSIM_CLK_MHZ); + qemu_fdt_setprop(fdt, nodename, "big-endian", NULL, 0); + +- /* The /chosen node is created during fdt creation. */ +- qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename); +- snprintf(alias, sizeof(alias), "uart%d", uart_idx); ++ if (uart_idx == 0) { ++ /* The /chosen node is created during fdt creation. */ ++ qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename); ++ } ++ snprintf(alias, sizeof(alias), "serial%d", uart_idx); + qemu_fdt_setprop_string(fdt, "/aliases", alias, nodename); ++ + g_free(nodename); + } + +@@ -326,11 +329,22 @@ static void openrisc_sim_init(MachineState *machine) + smp_cpus, cpus, OR1KSIM_OMPIC_IRQ); + } + +- for (n = 0; n < OR1KSIM_UART_COUNT; ++n) ++ /* ++ * We create the UART nodes starting with the highest address and ++ * working downwards, because in QEMU the DTB nodes end up in the ++ * DTB in reverse order of creation. Correctly-written guest software ++ * will not care about the node order (it will look at stdout-path ++ * or the alias nodes), but for the benefit of guest software which ++ * just looks for the first UART node in the DTB, make sure the ++ * lowest-address UART (which is QEMU's first serial port) appears ++ * first in the DTB. ++ */ ++ for (n = OR1KSIM_UART_COUNT - 1; n >= 0; n--) { + openrisc_sim_serial_init(state, or1ksim_memmap[OR1KSIM_UART].base + + or1ksim_memmap[OR1KSIM_UART].size * n, + or1ksim_memmap[OR1KSIM_UART].size, + smp_cpus, cpus, OR1KSIM_UART_IRQ, n); ++ } + + load_addr = openrisc_load_kernel(ram_size, kernel_filename, + &boot_info.bootstrap_pc); +diff --git a/hw/pci/msix.c b/hw/pci/msix.c +index 4b258566d4..20e39e51b4 100644 +--- a/hw/pci/msix.c ++++ b/hw/pci/msix.c +@@ -241,7 +241,7 @@ static uint64_t msix_pba_mmio_read(void *opaque, hwaddr addr, + PCIDevice *dev = opaque; + if (dev->msix_vector_poll_notifier) { + unsigned vector_start = addr * 8; +- unsigned vector_end = MIN(addr + size * 8, dev->msix_entries_nr); ++ unsigned vector_end = MIN((addr + size) * 8, dev->msix_entries_nr); + dev->msix_vector_poll_notifier(dev, vector_start, vector_end); + } + +diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c +index 68a62da0b5..9ffc625cc2 100644 +--- a/hw/pci/pcie.c ++++ b/hw/pci/pcie.c +@@ -999,18 +999,22 @@ void pcie_sync_bridge_lnk(PCIDevice *bridge_dev) + if ((lnksta & PCI_EXP_LNKSTA_NLW) > (lnkcap & PCI_EXP_LNKCAP_MLW)) { + lnksta &= ~PCI_EXP_LNKSTA_NLW; + lnksta |= lnkcap & PCI_EXP_LNKCAP_MLW; +- } else if (!(lnksta & PCI_EXP_LNKSTA_NLW)) { +- lnksta |= QEMU_PCI_EXP_LNKSTA_NLW(QEMU_PCI_EXP_LNK_X1); + } + + if ((lnksta & PCI_EXP_LNKSTA_CLS) > (lnkcap & PCI_EXP_LNKCAP_SLS)) { + lnksta &= ~PCI_EXP_LNKSTA_CLS; + lnksta |= lnkcap & PCI_EXP_LNKCAP_SLS; +- } else if (!(lnksta & PCI_EXP_LNKSTA_CLS)) { +- lnksta |= QEMU_PCI_EXP_LNKSTA_CLS(QEMU_PCI_EXP_LNK_2_5GT); + } + } + ++ if (!(lnksta & PCI_EXP_LNKSTA_NLW)) { ++ lnksta |= QEMU_PCI_EXP_LNKSTA_NLW(QEMU_PCI_EXP_LNK_X1); ++ } ++ ++ if (!(lnksta & PCI_EXP_LNKSTA_CLS)) { ++ lnksta |= QEMU_PCI_EXP_LNKSTA_CLS(QEMU_PCI_EXP_LNK_2_5GT); ++ } ++ + pci_word_test_and_clear_mask(exp_cap + PCI_EXP_LNKSTA, + PCI_EXP_LNKSTA_CLS | PCI_EXP_LNKSTA_NLW); + pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA, lnksta & +diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c +index 16899a1814..e163ff7d05 100644 +--- a/hw/s390x/s390-virtio-ccw.c ++++ b/hw/s390x/s390-virtio-ccw.c +@@ -171,6 +171,17 @@ static void s390_memory_init(MemoryRegion *ram) + { + MemoryRegion *sysmem = get_system_memory(); + ++ if (!QEMU_IS_ALIGNED(memory_region_size(ram), 1 * MiB)) { ++ /* ++ * SCLP cannot possibly expose smaller granularity right now and KVM ++ * cannot handle smaller granularity. As we don't support NUMA, the ++ * region size directly corresponds to machine->ram_size, and the region ++ * is a single RAM memory region. ++ */ ++ error_report("ram size must be multiples of 1 MiB"); ++ exit(EXIT_FAILURE); ++ } ++ + /* allocate RAM for core */ + memory_region_add_subregion(sysmem, 0, ram); + +diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c +index 9cbbb16121..d624866bb6 100644 +--- a/hw/scsi/megasas.c ++++ b/hw/scsi/megasas.c +@@ -1780,7 +1780,7 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd) + uint8_t cdb[16]; + int len; + struct SCSIDevice *sdev = NULL; +- int target_id, lun_id, cdb_len; ++ int target_id, lun_id; + + lba_count = le32_to_cpu(cmd->frame->io.header.data_len); + lba_start_lo = le32_to_cpu(cmd->frame->io.lba_lo); +@@ -1789,7 +1789,6 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd) + + target_id = cmd->frame->header.target_id; + lun_id = cmd->frame->header.lun_id; +- cdb_len = cmd->frame->header.cdb_len; + + if (target_id < MFI_MAX_LD && lun_id == 0) { + sdev = scsi_device_find(&s->bus, 0, target_id, lun_id); +@@ -1804,15 +1803,6 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd) + return MFI_STAT_DEVICE_NOT_FOUND; + } + +- if (cdb_len > 16) { +- trace_megasas_scsi_invalid_cdb_len( +- mfi_frame_desc(frame_cmd), 1, target_id, lun_id, cdb_len); +- megasas_write_sense(cmd, SENSE_CODE(INVALID_OPCODE)); +- cmd->frame->header.scsi_status = CHECK_CONDITION; +- s->event_count++; +- return MFI_STAT_SCSI_DONE_WITH_ERROR; +- } +- + cmd->iov_size = lba_count * sdev->blocksize; + if (megasas_map_sgl(s, cmd, &cmd->frame->io.sgl)) { + megasas_write_sense(cmd, SENSE_CODE(TARGET_FAILURE)); +@@ -1823,7 +1813,7 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd) + + megasas_encode_lba(cdb, lba_start, lba_count, is_write); + cmd->req = scsi_req_new(sdev, cmd->index, +- lun_id, cdb, cdb_len, cmd); ++ lun_id, cdb, sizeof(cdb), cmd); + if (!cmd->req) { + trace_megasas_scsi_req_alloc_failed( + mfi_frame_desc(frame_cmd), target_id, lun_id); +diff --git a/hw/usb/canokey.c b/hw/usb/canokey.c +index bbc5da07b5..5abb8db771 100644 +--- a/hw/usb/canokey.c ++++ b/hw/usb/canokey.c +@@ -197,8 +197,8 @@ static void canokey_handle_data(USBDevice *dev, USBPacket *p) + switch (p->pid) { + case USB_TOKEN_OUT: + trace_canokey_handle_data_out(ep_out, p->iov.size); +- usb_packet_copy(p, key->ep_out_buffer[ep_out], p->iov.size); + out_pos = 0; ++ /* segment packet into (possibly multiple) ep_out */ + while (out_pos != p->iov.size) { + /* + * key->ep_out[ep_out] set by prepare_receive +@@ -207,8 +207,8 @@ static void canokey_handle_data(USBDevice *dev, USBPacket *p) + * to be the buffer length + */ + out_len = MIN(p->iov.size - out_pos, key->ep_out_size[ep_out]); +- memcpy(key->ep_out[ep_out], +- key->ep_out_buffer[ep_out] + out_pos, out_len); ++ /* usb_packet_copy would update the pos offset internally */ ++ usb_packet_copy(p, key->ep_out[ep_out], out_len); + out_pos += out_len; + /* update ep_out_size to actual len */ + key->ep_out_size[ep_out] = out_len; +diff --git a/hw/usb/canokey.h b/hw/usb/canokey.h +index 24cf304203..fdcad10f80 100644 +--- a/hw/usb/canokey.h ++++ b/hw/usb/canokey.h +@@ -24,8 +24,6 @@ + #define CANOKEY_EP_NUM 3 + /* BULK/INTR IN can be up to 1352 bytes, e.g. get key info */ + #define CANOKEY_EP_IN_BUFFER_SIZE 2048 +-/* BULK OUT can be up to 270 bytes, e.g. PIV import cert */ +-#define CANOKEY_EP_OUT_BUFFER_SIZE 512 + + typedef enum { + CANOKEY_EP_IN_WAIT, +@@ -59,8 +57,6 @@ typedef struct CanoKeyState { + /* OUT pointer to canokey recv buffer */ + uint8_t *ep_out[CANOKEY_EP_NUM]; + uint32_t ep_out_size[CANOKEY_EP_NUM]; +- /* For large BULK OUT, multiple write to ep_out is needed */ +- uint8_t ep_out_buffer[CANOKEY_EP_NUM][CANOKEY_EP_OUT_BUFFER_SIZE]; + + /* Properties */ + char *file; /* canokey-file */ +diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c +index 643d4643e4..560ce582b2 100644 +--- a/hw/usb/hcd-xhci-pci.c ++++ b/hw/usb/hcd-xhci-pci.c +@@ -74,6 +74,7 @@ static bool xhci_pci_intr_raise(XHCIState *xhci, int n, bool level) + } + + if (msi_enabled(pci_dev) && level) { ++ n %= msi_nr_vectors_allocated(pci_dev); + msi_notify(pci_dev, n); + return true; + } +diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h +index 3ccb00865f..1f35e0193f 100644 +--- a/include/qemu/bitmap.h ++++ b/include/qemu/bitmap.h +@@ -69,6 +69,14 @@ + #define DECLARE_BITMAP(name,bits) \ + unsigned long name[BITS_TO_LONGS(bits)] + ++/* ++ * This is for use with the bit32 versions of set_bit() etc; ++ * we don't currently support the full range of bitmap operations ++ * on bitmaps backed by an array of uint32_t. ++ */ ++#define DECLARE_BITMAP32(name, bits) \ ++ uint32_t name[BITS_TO_U32S(bits)] ++ + #define small_nbits(nbits) \ + ((nbits) <= BITS_PER_LONG) + +diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h +index 03213ce952..888ac7f0e6 100644 +--- a/include/qemu/bitops.h ++++ b/include/qemu/bitops.h +@@ -18,16 +18,47 @@ + + #define BITS_PER_BYTE CHAR_BIT + #define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE) ++#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) ++#define BITS_TO_U32S(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(uint32_t)) + + #define BIT(nr) (1UL << (nr)) + #define BIT_ULL(nr) (1ULL << (nr)) +-#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +-#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) +-#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) + + #define MAKE_64BIT_MASK(shift, length) \ + (((~0ULL) >> (64 - (length))) << (shift)) + ++/** ++ * DOC: Functions operating on arrays of bits ++ * ++ * We provide a set of functions which work on arbitrary-length arrays of ++ * bits. These come in several flavours which vary in what the type of the ++ * underlying storage for the bits is: ++ * ++ * - Bits stored in an array of 'unsigned long': set_bit(), clear_bit(), etc ++ * - Bits stored in an array of 'uint32_t': set_bit32(), clear_bit32(), etc ++ * ++ * Because the 'unsigned long' type has a size which varies between ++ * host systems, the versions using 'uint32_t' are often preferable. ++ * This is particularly the case in a device model where there may ++ * be some guest-visible register view of the bit array. ++ * ++ * We do not currently implement uint32_t versions of find_last_bit(), ++ * find_next_bit(), find_next_zero_bit(), find_first_bit() or ++ * find_first_zero_bit(), because we haven't yet needed them. If you ++ * need them you should implement them similarly to the 'unsigned long' ++ * versions. ++ * ++ * You can declare a bitmap to be used with these functions via the ++ * DECLARE_BITMAP and DECLARE_BITMAP32 macros in bitmap.h. ++ */ ++ ++/** ++ * DOC: 'unsigned long' bit array APIs ++ */ ++ ++#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) ++#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) ++ + /** + * set_bit - Set a bit in memory + * @nr: the bit to set +@@ -211,6 +242,141 @@ static inline unsigned long find_first_zero_bit(const unsigned long *addr, + return find_next_zero_bit(addr, size, 0); + } + ++/** ++ * DOC: 'uint32_t' bit array APIs ++ */ ++ ++#define BIT32_MASK(nr) (1UL << ((nr) % 32)) ++#define BIT32_WORD(nr) ((nr) / 32) ++ ++/** ++ * set_bit32 - Set a bit in memory ++ * @nr: the bit to set ++ * @addr: the address to start counting from ++ */ ++static inline void set_bit32(long nr, uint32_t *addr) ++{ ++ uint32_t mask = BIT32_MASK(nr); ++ uint32_t *p = addr + BIT32_WORD(nr); ++ ++ *p |= mask; ++} ++ ++/** ++ * set_bit32_atomic - Set a bit in memory atomically ++ * @nr: the bit to set ++ * @addr: the address to start counting from ++ */ ++static inline void set_bit32_atomic(long nr, uint32_t *addr) ++{ ++ uint32_t mask = BIT32_MASK(nr); ++ uint32_t *p = addr + BIT32_WORD(nr); ++ ++ qatomic_or(p, mask); ++} ++ ++/** ++ * clear_bit32 - Clears a bit in memory ++ * @nr: Bit to clear ++ * @addr: Address to start counting from ++ */ ++static inline void clear_bit32(long nr, uint32_t *addr) ++{ ++ uint32_t mask = BIT32_MASK(nr); ++ uint32_t *p = addr + BIT32_WORD(nr); ++ ++ *p &= ~mask; ++} ++ ++/** ++ * clear_bit32_atomic - Clears a bit in memory atomically ++ * @nr: Bit to clear ++ * @addr: Address to start counting from ++ */ ++static inline void clear_bit32_atomic(long nr, uint32_t *addr) ++{ ++ uint32_t mask = BIT32_MASK(nr); ++ uint32_t *p = addr + BIT32_WORD(nr); ++ ++ return qatomic_and(p, ~mask); ++} ++ ++/** ++ * change_bit32 - Toggle a bit in memory ++ * @nr: Bit to change ++ * @addr: Address to start counting from ++ */ ++static inline void change_bit32(long nr, uint32_t *addr) ++{ ++ uint32_t mask = BIT32_MASK(nr); ++ uint32_t *p = addr + BIT32_WORD(nr); ++ ++ *p ^= mask; ++} ++ ++/** ++ * test_and_set_bit32 - Set a bit and return its old value ++ * @nr: Bit to set ++ * @addr: Address to count from ++ */ ++static inline int test_and_set_bit32(long nr, uint32_t *addr) ++{ ++ uint32_t mask = BIT32_MASK(nr); ++ uint32_t *p = addr + BIT32_WORD(nr); ++ uint32_t old = *p; ++ ++ *p = old | mask; ++ return (old & mask) != 0; ++} ++ ++/** ++ * test_and_clear_bit32 - Clear a bit and return its old value ++ * @nr: Bit to clear ++ * @addr: Address to count from ++ */ ++static inline int test_and_clear_bit32(long nr, uint32_t *addr) ++{ ++ uint32_t mask = BIT32_MASK(nr); ++ uint32_t *p = addr + BIT32_WORD(nr); ++ uint32_t old = *p; ++ ++ *p = old & ~mask; ++ return (old & mask) != 0; ++} ++ ++/** ++ * test_and_change_bit32 - Change a bit and return its old value ++ * @nr: Bit to change ++ * @addr: Address to count from ++ */ ++static inline int test_and_change_bit32(long nr, uint32_t *addr) ++{ ++ uint32_t mask = BIT32_MASK(nr); ++ uint32_t *p = addr + BIT32_WORD(nr); ++ uint32_t old = *p; ++ ++ *p = old ^ mask; ++ return (old & mask) != 0; ++} ++ ++/** ++ * test_bit32 - Determine whether a bit is set ++ * @nr: bit number to test ++ * @addr: Address to start counting from ++ */ ++static inline int test_bit32(long nr, const uint32_t *addr) ++{ ++ return 1U & (addr[BIT32_WORD(nr)] >> (nr & 31)); ++} ++ ++/** ++ * DOC: Miscellaneous bit operations on single values ++ * ++ * These functions are a collection of useful operations ++ * (rotations, bit extract, bit deposit, etc) on single ++ * integer values. ++ */ ++ + /** + * rol8 - rotate an 8-bit value left + * @word: value to rotate +diff --git a/meson.build b/meson.build +index 16dc9627e0..c0608332cd 100644 +--- a/meson.build ++++ b/meson.build +@@ -580,7 +580,7 @@ endif + + libnfs = not_found + if not get_option('libnfs').auto() or have_block +- libnfs = dependency('libnfs', version: '>=1.9.3', ++ libnfs = dependency('libnfs', version: ['>=1.9.3', '<6.0.0'], + required: get_option('libnfs'), + method: 'pkg-config', kwargs: static_kwargs) + endif +diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c +index 98a4840970..fd5625c87e 100644 +--- a/target/arm/sme_helper.c ++++ b/target/arm/sme_helper.c +@@ -35,7 +35,7 @@ void arm_reset_sve_state(CPUARMState *env) + memset(env->vfp.zregs, 0, sizeof(env->vfp.zregs)); + /* Recall that FFR is stored as pregs[16]. */ + memset(env->vfp.pregs, 0, sizeof(env->vfp.pregs)); +- vfp_set_fpcr(env, 0x0800009f); ++ vfp_set_fpsr(env, 0x0800009f); + } + + void helper_set_pstate_sm(CPUARMState *env, uint32_t i) +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 9c3e64c54b..489ab9cd41 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -3044,6 +3044,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { + }, + { + .version = 4, ++ .note = "IBRS, EPT switching, no TSX", + .props = (PropValue[]) { + { "vmx-eptp-switching", "on" }, + { /* end of list */ } +@@ -3178,7 +3179,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { + }, + }, + { .version = 4, +- .note = "ARCH_CAPABILITIES, no TSX", ++ .note = "ARCH_CAPABILITIES, EPT switching, no TSX", + .props = (PropValue[]) { + { "vmx-eptp-switching", "on" }, + { /* end of list */ } +diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c +index 839d95c1eb..037efc04af 100644 +--- a/target/ppc/excp_helper.c ++++ b/target/ppc/excp_helper.c +@@ -2511,10 +2511,16 @@ static void ppc_deliver_interrupt(CPUPPCState *env, int interrupt) + } + } + ++/* ++ * system reset is not delivered via normal irq method, so have to set ++ * halted = 0 to resume CPU running if it was halted. Possibly we should ++ * move it over to using PPC_INTERRUPT_RESET rather than async_run_on_cpu. ++ */ + void ppc_cpu_do_system_reset(CPUState *cs) + { + PowerPCCPU *cpu = POWERPC_CPU(cs); + ++ cs->halted = 0; + powerpc_excp(cpu, POWERPC_EXCP_RESET); + } + +@@ -2536,6 +2542,7 @@ void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector) + + /* Anything for nested required here? MSR[HV] bit? */ + ++ cs->halted = 0; + powerpc_set_excp_state(cpu, vector, msr); + } + +diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc +index 81a83e45b1..e91a7aaf0e 100644 +--- a/tcg/riscv/tcg-target.c.inc ++++ b/tcg/riscv/tcg-target.c.inc +@@ -838,7 +838,7 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0) + insn |= 0x02100000; + } + if (a0 & TCG_MO_ST_ST) { +- insn |= 0x02200000; ++ insn |= 0x01100000; + } + tcg_out32(s, insn); + } +diff --git a/tests/data/acpi/pc/DSDT b/tests/data/acpi/pc/DSDT +index b688686dc3..246bcadaa7 100644 +Binary files a/tests/data/acpi/pc/DSDT and b/tests/data/acpi/pc/DSDT differ +diff --git a/tests/data/acpi/pc/DSDT.acpierst b/tests/data/acpi/pc/DSDT.acpierst +index 86259be9d1..3074cecb6c 100644 +Binary files a/tests/data/acpi/pc/DSDT.acpierst and b/tests/data/acpi/pc/DSDT.acpierst differ +diff --git a/tests/data/acpi/pc/DSDT.acpihmat b/tests/data/acpi/pc/DSDT.acpihmat +index e2cc2a6fc9..0a32881d58 100644 +Binary files a/tests/data/acpi/pc/DSDT.acpihmat and b/tests/data/acpi/pc/DSDT.acpihmat differ +diff --git a/tests/data/acpi/pc/DSDT.bridge b/tests/data/acpi/pc/DSDT.bridge +index 75016fd4b7..95c12aa316 100644 +Binary files a/tests/data/acpi/pc/DSDT.bridge and b/tests/data/acpi/pc/DSDT.bridge differ +diff --git a/tests/data/acpi/pc/DSDT.cphp b/tests/data/acpi/pc/DSDT.cphp +index 53eb0dd7d4..ac40cbc595 100644 +Binary files a/tests/data/acpi/pc/DSDT.cphp and b/tests/data/acpi/pc/DSDT.cphp differ +diff --git a/tests/data/acpi/pc/DSDT.dimmpxm b/tests/data/acpi/pc/DSDT.dimmpxm +index 9089d994e0..b8b62cf9e9 100644 +Binary files a/tests/data/acpi/pc/DSDT.dimmpxm and b/tests/data/acpi/pc/DSDT.dimmpxm differ +diff --git a/tests/data/acpi/pc/DSDT.hpbridge b/tests/data/acpi/pc/DSDT.hpbridge +index 86259be9d1..3074cecb6c 100644 +Binary files a/tests/data/acpi/pc/DSDT.hpbridge and b/tests/data/acpi/pc/DSDT.hpbridge differ +diff --git a/tests/data/acpi/pc/DSDT.ipmikcs b/tests/data/acpi/pc/DSDT.ipmikcs +index 39427103aa..40edcc0f94 100644 +Binary files a/tests/data/acpi/pc/DSDT.ipmikcs and b/tests/data/acpi/pc/DSDT.ipmikcs differ +diff --git a/tests/data/acpi/pc/DSDT.memhp b/tests/data/acpi/pc/DSDT.memhp +index 987a263339..b2a7fd0dbd 100644 +Binary files a/tests/data/acpi/pc/DSDT.memhp and b/tests/data/acpi/pc/DSDT.memhp differ +diff --git a/tests/data/acpi/pc/DSDT.nohpet b/tests/data/acpi/pc/DSDT.nohpet +index fc7598b762..713aae4d8a 100644 +Binary files a/tests/data/acpi/pc/DSDT.nohpet and b/tests/data/acpi/pc/DSDT.nohpet differ +diff --git a/tests/data/acpi/pc/DSDT.numamem b/tests/data/acpi/pc/DSDT.numamem +index 85af400cdb..70b44ec476 100644 +Binary files a/tests/data/acpi/pc/DSDT.numamem and b/tests/data/acpi/pc/DSDT.numamem differ +diff --git a/tests/data/acpi/pc/DSDT.roothp b/tests/data/acpi/pc/DSDT.roothp +index 545512adfa..1030c94cc5 100644 +Binary files a/tests/data/acpi/pc/DSDT.roothp and b/tests/data/acpi/pc/DSDT.roothp differ +diff --git a/tests/data/acpi/q35/DSDT b/tests/data/acpi/q35/DSDT +index 2771bcea89..5c2b505163 100644 +Binary files a/tests/data/acpi/q35/DSDT and b/tests/data/acpi/q35/DSDT differ +diff --git a/tests/data/acpi/q35/DSDT.acpierst b/tests/data/acpi/q35/DSDT.acpierst +index b45abca7c2..1fd50e1c8b 100644 +Binary files a/tests/data/acpi/q35/DSDT.acpierst and b/tests/data/acpi/q35/DSDT.acpierst differ +diff --git a/tests/data/acpi/q35/DSDT.acpihmat b/tests/data/acpi/q35/DSDT.acpihmat +index d90fd4723a..c224736325 100644 +Binary files a/tests/data/acpi/q35/DSDT.acpihmat and b/tests/data/acpi/q35/DSDT.acpihmat differ +diff --git a/tests/data/acpi/q35/DSDT.acpihmat-noinitiator b/tests/data/acpi/q35/DSDT.acpihmat-noinitiator +index 279fafa821..ecdb94cc67 100644 +Binary files a/tests/data/acpi/q35/DSDT.acpihmat-noinitiator and b/tests/data/acpi/q35/DSDT.acpihmat-noinitiator differ +diff --git a/tests/data/acpi/q35/DSDT.applesmc b/tests/data/acpi/q35/DSDT.applesmc +index fdf6d14428..241a02dcf4 100644 +Binary files a/tests/data/acpi/q35/DSDT.applesmc and b/tests/data/acpi/q35/DSDT.applesmc differ +diff --git a/tests/data/acpi/q35/DSDT.bridge b/tests/data/acpi/q35/DSDT.bridge +index b41a4dddc0..bb41a3c218 100644 +Binary files a/tests/data/acpi/q35/DSDT.bridge and b/tests/data/acpi/q35/DSDT.bridge differ +diff --git a/tests/data/acpi/q35/DSDT.core-count2 b/tests/data/acpi/q35/DSDT.core-count2 +index 375aceed6b..5e0da94644 100644 +Binary files a/tests/data/acpi/q35/DSDT.core-count2 and b/tests/data/acpi/q35/DSDT.core-count2 differ +diff --git a/tests/data/acpi/q35/DSDT.cphp b/tests/data/acpi/q35/DSDT.cphp +index a0ecafc36c..6d64cd51f6 100644 +Binary files a/tests/data/acpi/q35/DSDT.cphp and b/tests/data/acpi/q35/DSDT.cphp differ +diff --git a/tests/data/acpi/q35/DSDT.cxl b/tests/data/acpi/q35/DSDT.cxl +index 267709e4e4..737e5a2447 100644 +Binary files a/tests/data/acpi/q35/DSDT.cxl and b/tests/data/acpi/q35/DSDT.cxl differ +diff --git a/tests/data/acpi/q35/DSDT.dimmpxm b/tests/data/acpi/q35/DSDT.dimmpxm +index f0659716e3..665a0c88ff 100644 +Binary files a/tests/data/acpi/q35/DSDT.dimmpxm and b/tests/data/acpi/q35/DSDT.dimmpxm differ +diff --git a/tests/data/acpi/q35/DSDT.ipmibt b/tests/data/acpi/q35/DSDT.ipmibt +index 9c52529919..25ddd90f8e 100644 +Binary files a/tests/data/acpi/q35/DSDT.ipmibt and b/tests/data/acpi/q35/DSDT.ipmibt differ +diff --git a/tests/data/acpi/q35/DSDT.ipmismbus b/tests/data/acpi/q35/DSDT.ipmismbus +index 3f32dffdbf..3367016d9a 100644 +Binary files a/tests/data/acpi/q35/DSDT.ipmismbus and b/tests/data/acpi/q35/DSDT.ipmismbus differ +diff --git a/tests/data/acpi/q35/DSDT.ivrs b/tests/data/acpi/q35/DSDT.ivrs +index b45abca7c2..1fd50e1c8b 100644 +Binary files a/tests/data/acpi/q35/DSDT.ivrs and b/tests/data/acpi/q35/DSDT.ivrs differ +diff --git a/tests/data/acpi/q35/DSDT.memhp b/tests/data/acpi/q35/DSDT.memhp +index 28a192c69a..bfd2278260 100644 +Binary files a/tests/data/acpi/q35/DSDT.memhp and b/tests/data/acpi/q35/DSDT.memhp differ +diff --git a/tests/data/acpi/q35/DSDT.mmio64 b/tests/data/acpi/q35/DSDT.mmio64 +index 8fda921296..5b50f66a1e 100644 +Binary files a/tests/data/acpi/q35/DSDT.mmio64 and b/tests/data/acpi/q35/DSDT.mmio64 differ +diff --git a/tests/data/acpi/q35/DSDT.multi-bridge b/tests/data/acpi/q35/DSDT.multi-bridge +index 3dba4d8436..2f37a6f8b6 100644 +Binary files a/tests/data/acpi/q35/DSDT.multi-bridge and b/tests/data/acpi/q35/DSDT.multi-bridge differ +diff --git a/tests/data/acpi/q35/DSDT.nohpet b/tests/data/acpi/q35/DSDT.nohpet +index b116947dac..5c17ed809d 100644 +Binary files a/tests/data/acpi/q35/DSDT.nohpet and b/tests/data/acpi/q35/DSDT.nohpet differ +diff --git a/tests/data/acpi/q35/DSDT.numamem b/tests/data/acpi/q35/DSDT.numamem +index 5eb6159d5f..e92f2a0c7a 100644 +Binary files a/tests/data/acpi/q35/DSDT.numamem and b/tests/data/acpi/q35/DSDT.numamem differ +diff --git a/tests/data/acpi/q35/DSDT.pvpanic-isa b/tests/data/acpi/q35/DSDT.pvpanic-isa +index 908e7b6606..308ed32bf0 100644 +Binary files a/tests/data/acpi/q35/DSDT.pvpanic-isa and b/tests/data/acpi/q35/DSDT.pvpanic-isa differ +diff --git a/tests/data/acpi/q35/DSDT.tis.tpm12 b/tests/data/acpi/q35/DSDT.tis.tpm12 +index ce2c2c29c2..a7ec593951 100644 +Binary files a/tests/data/acpi/q35/DSDT.tis.tpm12 and b/tests/data/acpi/q35/DSDT.tis.tpm12 differ +diff --git a/tests/data/acpi/q35/DSDT.tis.tpm2 b/tests/data/acpi/q35/DSDT.tis.tpm2 +index e9e4b7f6ed..ee242eceba 100644 +Binary files a/tests/data/acpi/q35/DSDT.tis.tpm2 and b/tests/data/acpi/q35/DSDT.tis.tpm2 differ +diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot +index 6b436f9cd9..60451836ff 100644 +Binary files a/tests/data/acpi/q35/DSDT.viot and b/tests/data/acpi/q35/DSDT.viot differ +diff --git a/tests/data/acpi/q35/DSDT.xapic b/tests/data/acpi/q35/DSDT.xapic +index f47f091222..9f96175d93 100644 +Binary files a/tests/data/acpi/q35/DSDT.xapic and b/tests/data/acpi/q35/DSDT.xapic differ +diff --git a/tests/qtest/fuzz/generic_fuzz_configs.h b/tests/qtest/fuzz/generic_fuzz_configs.h +index a825b78c14..4c3235311b 100644 +--- a/tests/qtest/fuzz/generic_fuzz_configs.h ++++ b/tests/qtest/fuzz/generic_fuzz_configs.h +@@ -143,7 +143,8 @@ const generic_fuzz_config predefined_configs[] = { + "-chardev null,id=cd0 -chardev null,id=cd1 " + "-device usb-braille,chardev=cd0 -device usb-ccid -device usb-ccid " + "-device usb-kbd -device usb-mouse -device usb-serial,chardev=cd1 " +- "-device usb-tablet -device usb-wacom-tablet -device usb-audio", ++ "-device usb-tablet -device usb-wacom-tablet " ++ "-device usb-audio,audiodev=snd0 -audiodev none,id=snd0", + .objects = "*usb* *uhci* *xhci*", + },{ + .name = "pc-i440fx", +diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c +index e4a368e036..340e704d24 100644 +--- a/tests/qtest/libqos/virtio-9p-client.c ++++ b/tests/qtest/libqos/virtio-9p-client.c +@@ -235,10 +235,11 @@ static const char *rmessage_name(uint8_t id) + id == P9_RMKDIR ? "RMKDIR" : + id == P9_RLCREATE ? "RLCREATE" : + id == P9_RSYMLINK ? "RSYMLINK" : ++ id == P9_RGETATTR ? "RGETATTR" : + id == P9_RLINK ? "RLINK" : + id == P9_RUNLINKAT ? "RUNLINKAT" : + id == P9_RFLUSH ? "RFLUSH" : +- id == P9_RREADDIR ? "READDIR" : ++ id == P9_RREADDIR ? "RREADDIR" : + ""; + } + +diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c +index 65e69491e5..86ff86409c 100644 +--- a/tests/qtest/virtio-9p-test.c ++++ b/tests/qtest/virtio-9p-test.c +@@ -693,6 +693,50 @@ static void fs_unlinkat_hardlink(void *obj, void *data, + g_assert(stat(real_file, &st_real) == 0); + } + ++static void fs_use_after_unlink(void *obj, void *data, ++ QGuestAllocator *t_alloc) ++{ ++ QVirtio9P *v9p = obj; ++ v9fs_set_allocator(t_alloc); ++ static const uint32_t write_count = P9_MAX_SIZE / 2; ++ g_autofree char *real_file = virtio_9p_test_path("09/doa_file"); ++ g_autofree char *buf = g_malloc0(write_count); ++ struct stat st_file; ++ struct v9fs_attr attr; ++ uint32_t fid_file; ++ uint32_t count; ++ ++ tattach({ .client = v9p }); ++ ++ /* create a file "09/doa_file" and make sure it exists and is regular */ ++ tmkdir({ .client = v9p, .atPath = "/", .name = "09" }); ++ tlcreate({ .client = v9p, .atPath = "09", .name = "doa_file" }); ++ g_assert(stat(real_file, &st_file) == 0); ++ g_assert((st_file.st_mode & S_IFMT) == S_IFREG); ++ ++ /* request a FID for that regular file that we can work with next */ ++ fid_file = twalk({ ++ .client = v9p, .fid = 0, .path = "09/doa_file" ++ }).newfid; ++ g_assert(fid_file != 0); ++ ++ /* now first open the file in write mode before ... */ ++ tlopen({ .client = v9p, .fid = fid_file, .flags = O_WRONLY }); ++ /* ... removing the file from file system */ ++ tunlinkat({ .client = v9p, .atPath = "09", .name = "doa_file" }); ++ ++ /* file is removed, but we still have it open, so this should succeed */ ++ tgetattr({ ++ .client = v9p, .fid = fid_file, .request_mask = P9_GETATTR_BASIC, ++ .rgetattr.attr = &attr ++ }); ++ count = twrite({ ++ .client = v9p, .fid = fid_file, .offset = 0, .count = write_count, ++ .data = buf ++ }).count; ++ g_assert_cmpint(count, ==, write_count); ++} ++ + static void *assign_9p_local_driver(GString *cmd_line, void *arg) + { + virtio_9p_assign_local_driver(cmd_line, "security_model=mapped-xattr"); +@@ -756,6 +800,8 @@ static void register_virtio_9p_test(void) + qos_add_test("local/hardlink_file", "virtio-9p", fs_hardlink_file, &opts); + qos_add_test("local/unlinkat_hardlink", "virtio-9p", fs_unlinkat_hardlink, + &opts); ++ qos_add_test("local/use_after_unlink", "virtio-9p", fs_use_after_unlink, ++ &opts); + } + + libqos_init(register_virtio_9p_test); diff -Nru qemu-7.2+dfsg/debian/patches/v7.2.17.diff qemu-7.2+dfsg/debian/patches/v7.2.17.diff --- qemu-7.2+dfsg/debian/patches/v7.2.17.diff 1970-01-01 00:00:00.000000000 +0000 +++ qemu-7.2+dfsg/debian/patches/v7.2.17.diff 2025-05-03 09:05:44.000000000 +0000 @@ -0,0 +1,1397 @@ +Subject: v7.2.17 +Date: Wed Mar 26 12:13:29 2025 +0300 +From: Michael Tokarev +Forwarded: not-needed + +This is a difference between upstream qemu v7.2.16 +and upstream qemu v7.2.17. + + VERSION | 2 +- + backends/cryptodev-vhost.c | 2 +- + block/qed.c | 1 + + block/snapshot.c | 1 + + docs/devel/build-system.rst | 10 +-- + docs/devel/kconfig.rst | 16 ++-- + hw/arm/Kconfig | 6 +- + hw/gpio/npcm7xx_gpio.c | 3 +- + hw/i386/amd_iommu.c | 10 +-- + hw/i386/amd_iommu.h | 2 +- + hw/intc/arm_gicv3_cpuif.c | 9 --- + hw/misc/aspeed_hace.c | 5 ++ + hw/net/smc91c111.c | 149 +++++++++++++++++++++++++++++++++---- + hw/ppc/pnv_occ.c | 33 ++++---- + hw/rtc/goldfish_rtc.c | 43 ++++------- + hw/usb/Kconfig | 4 + + hw/usb/meson.build | 2 +- + hw/virtio/vhost-shadow-virtqueue.c | 18 +++-- + linux-user/syscall.c | 4 +- + net/vhost-vdpa.c | 13 ++++ + target/arm/cpu.h | 1 + + target/arm/helper.c | 21 ++++-- + target/arm/op_helper.c | 13 +++- + target/arm/translate-a64.c | 37 ++++----- + target/arm/translate-a64.h | 2 +- + target/arm/translate.h | 10 ++- + target/ppc/cpu_init.c | 8 -- + target/riscv/cpu_helper.c | 18 +++++ + target/riscv/debug.c | 6 +- + target/riscv/vector_helper.c | 8 +- + target/sparc/gdbstub.c | 18 ++++- + ui/cocoa.m | 5 ++ + ui/meson.build | 2 - + ui/sdl2.c | 26 ------- + util/cacheflush.c | 4 +- + 35 files changed, 333 insertions(+), 179 deletions(-) + +diff --git a/VERSION b/VERSION +index a1f5232276..a961ff94f2 100644 +--- a/VERSION ++++ b/VERSION +@@ -1 +1 @@ +-7.2.16 ++7.2.17 +diff --git a/backends/cryptodev-vhost.c b/backends/cryptodev-vhost.c +index 572f87b3be..af1d232a9e 100644 +--- a/backends/cryptodev-vhost.c ++++ b/backends/cryptodev-vhost.c +@@ -54,7 +54,7 @@ cryptodev_vhost_init( + CryptoDevBackendVhost *crypto; + Error *local_err = NULL; + +- crypto = g_new(CryptoDevBackendVhost, 1); ++ crypto = g_new0(CryptoDevBackendVhost, 1); + crypto->dev.max_queues = 1; + crypto->dev.nvqs = 1; + crypto->dev.vqs = crypto->vqs; +diff --git a/block/qed.c b/block/qed.c +index 2f36ad342c..1ebb00fe04 100644 +--- a/block/qed.c ++++ b/block/qed.c +@@ -340,6 +340,7 @@ static void bdrv_qed_detach_aio_context(BlockDriverState *bs) + + qed_cancel_need_check_timer(s); + timer_free(s->need_check_timer); ++ s->need_check_timer = NULL; + } + + static void bdrv_qed_attach_aio_context(BlockDriverState *bs, +diff --git a/block/snapshot.c b/block/snapshot.c +index 86e29ca59f..2f6c35f7eb 100644 +--- a/block/snapshot.c ++++ b/block/snapshot.c +@@ -286,6 +286,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs, + bdrv_unref_child(bs, fallback); + + ret = bdrv_snapshot_goto(fallback_bs, snapshot_id, errp); ++ memset(bs->opaque, 0, drv->instance_size); + open_ret = drv->bdrv_open(bs, options, bs->open_flags, &local_err); + qobject_unref(options); + if (open_ret < 0) { +diff --git a/docs/devel/build-system.rst b/docs/devel/build-system.rst +index 1894721743..21fff65d28 100644 +--- a/docs/devel/build-system.rst ++++ b/docs/devel/build-system.rst +@@ -193,7 +193,7 @@ Target-dependent emulator sourcesets: + Each emulator also includes sources for files in the ``hw/`` and ``target/`` + subdirectories. The subdirectory used for each emulator comes + from the target's definition of ``TARGET_BASE_ARCH`` or (if missing) +- ``TARGET_ARCH``, as found in ``default-configs/targets/*.mak``. ++ ``TARGET_ARCH``, as found in ``configs/targets/*.mak``. + + Each subdirectory in ``hw/`` adds one sourceset to the ``hw_arch`` dictionary, + for example:: +@@ -250,8 +250,8 @@ Utility sourcesets: + The following files concur in the definition of which files are linked + into each emulator: + +-``default-configs/devices/*.mak`` +- The files under ``default-configs/devices/`` control the boards and devices ++``configs/devices/*.mak`` ++ The files under ``configs/devices/`` control the boards and devices + that are built into each QEMU system emulation targets. They merely contain + a list of config variable definitions such as:: + +@@ -260,11 +260,11 @@ into each emulator: + CONFIG_XLNX_VERSAL=y + + ``*/Kconfig`` +- These files are processed together with ``default-configs/devices/*.mak`` and ++ These files are processed together with ``configs/devices/*.mak`` and + describe the dependencies between various features, subsystems and + device models. They are described in :ref:`kconfig` + +-``default-configs/targets/*.mak`` ++``configs/targets/*.mak`` + These files mostly define symbols that appear in the ``*-config-target.h`` + file for each emulator [#cfgtarget]_. However, the ``TARGET_ARCH`` + and ``TARGET_BASE_ARCH`` will also be used to select the ``hw/`` and +diff --git a/docs/devel/kconfig.rst b/docs/devel/kconfig.rst +index 69674d008a..ba5e1f399a 100644 +--- a/docs/devel/kconfig.rst ++++ b/docs/devel/kconfig.rst +@@ -38,7 +38,7 @@ originated in the Linux kernel, though it was heavily simplified and + the handling of dependencies is stricter in QEMU. + + Unlike Linux, there is no user interface to edit the configuration, which +-is instead specified in per-target files under the ``default-configs/`` ++is instead specified in per-target files under the ``configs/`` + directory of the QEMU source tree. This is because, unlike Linux, + configuration and dependencies can be treated as a black box when building + QEMU; the default configuration that QEMU ships with should be okay in +@@ -103,7 +103,7 @@ directives can be included: + **default value**: ``default [if ]`` + + Default values are assigned to the config symbol if no other value was +- set by the user via ``default-configs/*.mak`` files, and only if ++ set by the user via ``configs/*.mak`` files, and only if + ``select`` or ``depends on`` directives do not force the value to true + or false respectively. ```` can be ``y`` or ``n``; it cannot + be an arbitrary Boolean expression. However, a condition for applying +@@ -119,7 +119,7 @@ directives can be included: + This is similar to ``select`` as it applies a lower limit of ``y`` + to another symbol. However, the lower limit is only a default + and the "implied" symbol's value may still be set to ``n`` from a +- ``default-configs/*.mak`` files. The following two examples are ++ ``configs/*.mak`` files. The following two examples are + equivalent:: + + config FOO +@@ -146,7 +146,7 @@ declares its dependencies in different ways: + bool + + Subsystems always default to false (they have no ``default`` directive) +- and are never visible in ``default-configs/*.mak`` files. It's ++ and are never visible in ``configs/*.mak`` files. It's + up to other symbols to ``select`` whatever subsystems they require. + + They sometimes have ``select`` directives to bring in other required +@@ -229,7 +229,7 @@ declares its dependencies in different ways: + cannot be started at all without it. It should be listed under + ``imply`` if (depending on the QEMU command line) the board may or + may not be started without it. Boards also default to false; they are +- enabled by the ``default-configs/*.mak`` for the target they apply to. ++ enabled by the ``configs/*.mak`` for the target they apply to. + + **internal elements** + +@@ -241,18 +241,18 @@ declares its dependencies in different ways: + + Internal elements group code that is useful in several boards or + devices. They are usually enabled with ``select`` and in turn select +- other elements; they are never visible in ``default-configs/*.mak`` ++ other elements; they are never visible in ``configs/*.mak`` + files, and often not even in the Makefile. + + Writing and modifying default configurations + -------------------------------------------- + + In addition to the Kconfig files under hw/, each target also includes +-a file called ``default-configs/TARGETNAME-softmmu.mak``. These files ++a file called ``configs/TARGETNAME-softmmu.mak``. These files + initialize some Kconfig variables to non-default values and provide the + starting point to turn on devices and subsystems. + +-A file in ``default-configs/`` looks like the following example:: ++A file in ``configs/`` looks like the following example:: + + # Default configuration for alpha-softmmu + +diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig +index 17fcde8e1c..837d0c5d41 100644 +--- a/hw/arm/Kconfig ++++ b/hw/arm/Kconfig +@@ -300,7 +300,7 @@ config ZYNQ + select PL330 + select SDHCI + select SSI_M25P80 +- select USB_EHCI_SYSBUS ++ select USB_CHIPIDEA + select XILINX # UART + select XILINX_AXI + select XILINX_SPI +@@ -416,6 +416,7 @@ config FSL_IMX25 + select IMX + select IMX_FEC + select IMX_I2C ++ select USB_CHIPIDEA + select WDT_IMX2 + select SDHCI + +@@ -438,6 +439,7 @@ config FSL_IMX6 + select IMX_USBPHY + select WDT_IMX2 + select SDHCI ++ select USB_CHIPIDEA + + config ASPEED_SOC + bool +@@ -488,6 +490,7 @@ config FSL_IMX7 + select PCI_EXPRESS_DESIGNWARE + select SDHCI + select UNIMP ++ select USB_CHIPIDEA + + config ARM_SMMUV3 + bool +@@ -501,6 +504,7 @@ config FSL_IMX6UL + select IMX_I2C + select WDT_IMX2 + select SDHCI ++ select USB_CHIPIDEA + select UNIMP + + config MICROBIT +diff --git a/hw/gpio/npcm7xx_gpio.c b/hw/gpio/npcm7xx_gpio.c +index 3376901ab1..c75f9e073d 100644 +--- a/hw/gpio/npcm7xx_gpio.c ++++ b/hw/gpio/npcm7xx_gpio.c +@@ -220,8 +220,6 @@ static void npcm7xx_gpio_regs_write(void *opaque, hwaddr addr, uint64_t v, + return; + } + +- diff = s->regs[reg] ^ value; +- + switch (reg) { + case NPCM7XX_GPIO_TLOCK1: + case NPCM7XX_GPIO_TLOCK2: +@@ -242,6 +240,7 @@ static void npcm7xx_gpio_regs_write(void *opaque, hwaddr addr, uint64_t v, + case NPCM7XX_GPIO_PU: + case NPCM7XX_GPIO_PD: + case NPCM7XX_GPIO_IEM: ++ diff = s->regs[reg] ^ value; + s->regs[reg] = value; + npcm7xx_gpio_update_pins(s, diff); + break; +diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c +index 02597db1e1..d68e85b606 100644 +--- a/hw/i386/amd_iommu.c ++++ b/hw/i386/amd_iommu.c +@@ -1279,15 +1279,15 @@ static int amdvi_int_remap_msi(AMDVIState *iommu, + ret = -AMDVI_IR_ERR; + break; + case AMDVI_IOAPIC_INT_TYPE_NMI: +- pass = dte[3] & AMDVI_DEV_NMI_PASS_MASK; ++ pass = dte[2] & AMDVI_DEV_NMI_PASS_MASK; + trace_amdvi_ir_delivery_mode("nmi"); + break; + case AMDVI_IOAPIC_INT_TYPE_INIT: +- pass = dte[3] & AMDVI_DEV_INT_PASS_MASK; ++ pass = dte[2] & AMDVI_DEV_INT_PASS_MASK; + trace_amdvi_ir_delivery_mode("init"); + break; + case AMDVI_IOAPIC_INT_TYPE_EINT: +- pass = dte[3] & AMDVI_DEV_EINT_PASS_MASK; ++ pass = dte[2] & AMDVI_DEV_EINT_PASS_MASK; + trace_amdvi_ir_delivery_mode("eint"); + break; + default: +@@ -1514,9 +1514,9 @@ static void amdvi_init(AMDVIState *s) + /* reset AMDVI specific capabilities, all r/o */ + pci_set_long(s->pci.dev.config + s->capab_offset, AMDVI_CAPAB_FEATURES); + pci_set_long(s->pci.dev.config + s->capab_offset + AMDVI_CAPAB_BAR_LOW, +- s->mmio.addr & ~(0xffff0000)); ++ AMDVI_BASE_ADDR & MAKE_64BIT_MASK(14, 18)); + pci_set_long(s->pci.dev.config + s->capab_offset + AMDVI_CAPAB_BAR_HIGH, +- (s->mmio.addr & ~(0xffff)) >> 16); ++ AMDVI_BASE_ADDR >> 32); + pci_set_long(s->pci.dev.config + s->capab_offset + AMDVI_CAPAB_RANGE, + 0xff000000); + pci_set_long(s->pci.dev.config + s->capab_offset + AMDVI_CAPAB_MISC, 0); +diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h +index 210a37dfb1..1899e9aee1 100644 +--- a/hw/i386/amd_iommu.h ++++ b/hw/i386/amd_iommu.h +@@ -185,7 +185,7 @@ + AMDVI_CAPAB_FLAG_HTTUNNEL | AMDVI_CAPAB_EFR_SUP) + + /* AMDVI default address */ +-#define AMDVI_BASE_ADDR 0xfed80000 ++#define AMDVI_BASE_ADDR 0xfed80000ULL + + /* page management constants */ + #define AMDVI_PAGE_SHIFT 12 +diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c +index 9811fb3fb4..8d36f57f3d 100644 +--- a/hw/intc/arm_gicv3_cpuif.c ++++ b/hw/intc/arm_gicv3_cpuif.c +@@ -2097,9 +2097,6 @@ static CPAccessResult gicv3_irqfiq_access(CPUARMState *env, + } + } + +- if (r == CP_ACCESS_TRAP_EL3 && !arm_el_is_aa64(env, 3)) { +- r = CP_ACCESS_TRAP; +- } + return r; + } + +@@ -2162,9 +2159,6 @@ static CPAccessResult gicv3_fiq_access(CPUARMState *env, + } + } + +- if (r == CP_ACCESS_TRAP_EL3 && !arm_el_is_aa64(env, 3)) { +- r = CP_ACCESS_TRAP; +- } + return r; + } + +@@ -2201,9 +2195,6 @@ static CPAccessResult gicv3_irq_access(CPUARMState *env, + } + } + +- if (r == CP_ACCESS_TRAP_EL3 && !arm_el_is_aa64(env, 3)) { +- r = CP_ACCESS_TRAP; +- } + return r; + } + +diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c +index 69175e972d..11bd25708e 100644 +--- a/hw/misc/aspeed_hace.c ++++ b/hw/misc/aspeed_hace.c +@@ -123,6 +123,11 @@ static bool has_padding(AspeedHACEState *s, struct iovec *iov, + if (*total_msg_len <= s->total_req_len) { + uint32_t padding_size = s->total_req_len - *total_msg_len; + uint8_t *padding = iov->iov_base; ++ ++ if (padding_size > req_len) { ++ return false; ++ } ++ + *pad_offset = req_len - padding_size; + if (padding[*pad_offset] == 0x80) { + return true; +diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c +index 4eda971ef3..81e5c823d1 100644 +--- a/hw/net/smc91c111.c ++++ b/hw/net/smc91c111.c +@@ -13,6 +13,7 @@ + #include "net/net.h" + #include "hw/irq.h" + #include "hw/net/smc91c111.h" ++#include "hw/registerfields.h" + #include "hw/qdev-properties.h" + #include "qapi/error.h" + #include "qemu/log.h" +@@ -23,6 +24,13 @@ + + /* Number of 2k memory pages available. */ + #define NUM_PACKETS 4 ++/* ++ * Maximum size of a data frame, including the leading status word ++ * and byte count fields and the trailing CRC, last data byte ++ * and control byte (per figure 8-1 in the Microchip Technology ++ * LAN91C111 datasheet). ++ */ ++#define MAX_PACKET_SIZE 2048 + + #define TYPE_SMC91C111 "smc91c111" + OBJECT_DECLARE_SIMPLE_TYPE(smc91c111_state, SMC91C111) +@@ -119,6 +127,18 @@ static const VMStateDescription vmstate_smc91c111 = { + #define RS_TOOSHORT 0x0400 + #define RS_MULTICAST 0x0001 + ++FIELD(PTR, PTR, 0, 11) ++FIELD(PTR, NOT_EMPTY, 11, 1) ++FIELD(PTR, RESERVED, 12, 1) ++FIELD(PTR, READ, 13, 1) ++FIELD(PTR, AUTOINCR, 14, 1) ++FIELD(PTR, RCV, 15, 1) ++ ++static inline bool packetnum_valid(int packet_num) ++{ ++ return packet_num >= 0 && packet_num < NUM_PACKETS; ++} ++ + /* Update interrupt status. */ + static void smc91c111_update(smc91c111_state *s) + { +@@ -183,6 +203,15 @@ static void smc91c111_pop_rx_fifo(smc91c111_state *s) + { + int i; + ++ if (s->rx_fifo_len == 0) { ++ /* ++ * The datasheet doesn't document what the behaviour is if the ++ * guest tries to pop an empty RX FIFO, and there's no obvious ++ * error status register to report it. Just ignore the attempt. ++ */ ++ return; ++ } ++ + s->rx_fifo_len--; + if (s->rx_fifo_len) { + for (i = 0; i < s->rx_fifo_len; i++) +@@ -210,12 +239,33 @@ static void smc91c111_pop_tx_fifo_done(smc91c111_state *s) + /* Release the memory allocated to a packet. */ + static void smc91c111_release_packet(smc91c111_state *s, int packet) + { ++ if (!packetnum_valid(packet)) { ++ /* ++ * Data sheet doesn't document behaviour in this guest error ++ * case, and there is no error status register to report it. ++ * Log and ignore the attempt. ++ */ ++ qemu_log_mask(LOG_GUEST_ERROR, ++ "smc91c111: attempt to release invalid packet %d\n", ++ packet); ++ return; ++ } + s->allocated &= ~(1 << packet); + if (s->tx_alloc == 0x80) + smc91c111_tx_alloc(s); + smc91c111_flush_queued_packets(s); + } + ++static void smc91c111_complete_tx_packet(smc91c111_state *s, int packetnum) ++{ ++ if (s->ctr & CTR_AUTO_RELEASE) { ++ /* Race? */ ++ smc91c111_release_packet(s, packetnum); ++ } else if (s->tx_fifo_done_len < NUM_PACKETS) { ++ s->tx_fifo_done[s->tx_fifo_done_len++] = packetnum; ++ } ++} ++ + /* Flush the TX FIFO. */ + static void smc91c111_do_tx(smc91c111_state *s) + { +@@ -231,12 +281,25 @@ static void smc91c111_do_tx(smc91c111_state *s) + return; + for (i = 0; i < s->tx_fifo_len; i++) { + packetnum = s->tx_fifo[i]; ++ /* queue_tx checked the packet number was valid */ ++ assert(packetnum_valid(packetnum)); + p = &s->data[packetnum][0]; + /* Set status word. */ + *(p++) = 0x01; + *(p++) = 0x40; + len = *(p++); + len |= ((int)*(p++)) << 8; ++ if (len > MAX_PACKET_SIZE) { ++ /* ++ * Datasheet doesn't say what to do here, and there is no ++ * relevant tx error condition listed. Log, and drop the packet. ++ */ ++ qemu_log_mask(LOG_GUEST_ERROR, ++ "smc91c111: tx packet with bad length %d, dropping\n", ++ len); ++ smc91c111_complete_tx_packet(s, packetnum); ++ continue; ++ } + len -= 6; + control = p[len + 1]; + if (control & 0x20) +@@ -265,11 +328,7 @@ static void smc91c111_do_tx(smc91c111_state *s) + } + } + #endif +- if (s->ctr & CTR_AUTO_RELEASE) +- /* Race? */ +- smc91c111_release_packet(s, packetnum); +- else if (s->tx_fifo_done_len < NUM_PACKETS) +- s->tx_fifo_done[s->tx_fifo_done_len++] = packetnum; ++ smc91c111_complete_tx_packet(s, packetnum); + qemu_send_packet(qemu_get_queue(s->nic), p, len); + } + s->tx_fifo_len = 0; +@@ -279,6 +338,17 @@ static void smc91c111_do_tx(smc91c111_state *s) + /* Add a packet to the TX FIFO. */ + static void smc91c111_queue_tx(smc91c111_state *s, int packet) + { ++ if (!packetnum_valid(packet)) { ++ /* ++ * Datasheet doesn't document behaviour in this error case, and ++ * there's no error status register we could report it in. ++ * Log and ignore. ++ */ ++ qemu_log_mask(LOG_GUEST_ERROR, ++ "smc91c111: attempt to queue invalid packet %d\n", ++ packet); ++ return; ++ } + if (s->tx_fifo_len == NUM_PACKETS) + return; + s->tx_fifo[s->tx_fifo_len++] = packet; +@@ -310,6 +380,49 @@ static void smc91c111_reset(DeviceState *dev) + #define SET_LOW(name, val) s->name = (s->name & 0xff00) | val + #define SET_HIGH(name, val) s->name = (s->name & 0xff) | (val << 8) + ++/* ++ * The pointer register's pointer is an 11 bit value (so it exactly ++ * indexes a 2048-byte data frame). Add the specified offset to it, ++ * wrapping around at the 2048 byte mark, and return the resulting ++ * wrapped value. There are flag bits in the top part of the register, ++ * but we can ignore them here as the mask will mask them out. ++ */ ++static int ptr_reg_add(smc91c111_state *s, int offset) ++{ ++ return (s->ptr + offset) & R_PTR_PTR_MASK; ++} ++ ++/* ++ * For an access to the Data Register at @offset, return the ++ * required offset into the packet's data frame. This will ++ * perform the pointer register autoincrement if required, and ++ * guarantees to return an in-bounds offset. ++ */ ++static int data_reg_ptr(smc91c111_state *s, int offset) ++{ ++ int p; ++ ++ if (s->ptr & R_PTR_AUTOINCR_MASK) { ++ /* ++ * Autoincrement: use the current pointer value, and ++ * increment the pointer register's pointer field. ++ */ ++ p = FIELD_EX32(s->ptr, PTR, PTR); ++ s->ptr = FIELD_DP32(s->ptr, PTR, PTR, ptr_reg_add(s, 1)); ++ } else { ++ /* ++ * No autoincrement: register offset determines which ++ * byte we're addressing. Setting the pointer to the top ++ * of the data buffer and then using the pointer wrapping ++ * to read the bottom byte of the buffer is not something ++ * sensible guest software will do, but the datasheet ++ * doesn't say what the behaviour is, so we don't forbid it. ++ */ ++ p = ptr_reg_add(s, offset & 3); ++ } ++ return p; ++} ++ + static void smc91c111_writeb(void *opaque, hwaddr offset, + uint32_t value) + { +@@ -449,12 +562,14 @@ static void smc91c111_writeb(void *opaque, hwaddr offset, + n = s->rx_fifo[0]; + else + n = s->packet_num; +- p = s->ptr & 0x07ff; +- if (s->ptr & 0x4000) { +- s->ptr = (s->ptr & 0xf800) | ((s->ptr + 1) & 0x7ff); +- } else { +- p += (offset & 3); ++ if (!packetnum_valid(n)) { ++ /* Datasheet doesn't document what to do here */ ++ qemu_log_mask(LOG_GUEST_ERROR, ++ "smc91c111: attempt to write data to invalid packet %d\n", ++ n); ++ return; + } ++ p = data_reg_ptr(s, offset); + s->data[n][p] = value; + } + return; +@@ -597,12 +712,14 @@ static uint32_t smc91c111_readb(void *opaque, hwaddr offset) + n = s->rx_fifo[0]; + else + n = s->packet_num; +- p = s->ptr & 0x07ff; +- if (s->ptr & 0x4000) { +- s->ptr = (s->ptr & 0xf800) | ((s->ptr + 1) & 0x07ff); +- } else { +- p += (offset & 3); ++ if (!packetnum_valid(n)) { ++ /* Datasheet doesn't document what to do here */ ++ qemu_log_mask(LOG_GUEST_ERROR, ++ "smc91c111: attempt to read data from invalid packet %d\n", ++ n); ++ return 0; + } ++ p = data_reg_ptr(s, offset); + return s->data[n][p]; + } + case 12: /* Interrupt status. */ +@@ -705,6 +822,8 @@ static ssize_t smc91c111_receive(NetClientState *nc, const uint8_t *buf, size_t + return -1; + s->rx_fifo[s->rx_fifo_len++] = packetnum; + ++ /* allocate_packet() will not hand us back an invalid packet number */ ++ assert(packetnum_valid(packetnum)); + p = &s->data[packetnum][0]; + /* ??? Multicast packets? */ + status = 0; +diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c +index 9fa6d91d31..fe00a62b94 100644 +--- a/hw/ppc/pnv_occ.c ++++ b/hw/ppc/pnv_occ.c +@@ -32,22 +32,21 @@ + #define OCB_OCI_OCCMISC_OR 0x4022 + + /* OCC sensors */ +-#define OCC_SENSOR_DATA_BLOCK_OFFSET 0x580000 +-#define OCC_SENSOR_DATA_VALID 0x580001 +-#define OCC_SENSOR_DATA_VERSION 0x580002 +-#define OCC_SENSOR_DATA_READING_VERSION 0x580004 +-#define OCC_SENSOR_DATA_NR_SENSORS 0x580008 +-#define OCC_SENSOR_DATA_NAMES_OFFSET 0x580010 +-#define OCC_SENSOR_DATA_READING_PING_OFFSET 0x580014 +-#define OCC_SENSOR_DATA_READING_PONG_OFFSET 0x58000c +-#define OCC_SENSOR_DATA_NAME_LENGTH 0x58000d +-#define OCC_SENSOR_NAME_STRUCTURE_TYPE 0x580023 +-#define OCC_SENSOR_LOC_CORE 0x580022 +-#define OCC_SENSOR_LOC_GPU 0x580020 +-#define OCC_SENSOR_TYPE_POWER 0x580003 +-#define OCC_SENSOR_NAME 0x580005 +-#define HWMON_SENSORS_MASK 0x58001e +-#define SLW_IMAGE_BASE 0x0 ++#define OCC_SENSOR_DATA_BLOCK_OFFSET 0x0000 ++#define OCC_SENSOR_DATA_VALID 0x0001 ++#define OCC_SENSOR_DATA_VERSION 0x0002 ++#define OCC_SENSOR_DATA_READING_VERSION 0x0004 ++#define OCC_SENSOR_DATA_NR_SENSORS 0x0008 ++#define OCC_SENSOR_DATA_NAMES_OFFSET 0x0010 ++#define OCC_SENSOR_DATA_READING_PING_OFFSET 0x0014 ++#define OCC_SENSOR_DATA_READING_PONG_OFFSET 0x000c ++#define OCC_SENSOR_DATA_NAME_LENGTH 0x000d ++#define OCC_SENSOR_NAME_STRUCTURE_TYPE 0x0023 ++#define OCC_SENSOR_LOC_CORE 0x0022 ++#define OCC_SENSOR_LOC_GPU 0x0020 ++#define OCC_SENSOR_TYPE_POWER 0x0003 ++#define OCC_SENSOR_NAME 0x0005 ++#define HWMON_SENSORS_MASK 0x001e + + static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val) + { +@@ -129,8 +128,6 @@ static uint64_t pnv_occ_common_area_read(void *opaque, hwaddr addr, + case HWMON_SENSORS_MASK: + case OCC_SENSOR_LOC_GPU: + return 0x8e00; +- case SLW_IMAGE_BASE: +- return 0x1000000000000000; + } + return 0; + } +diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c +index 19a56402a0..81cc942b46 100644 +--- a/hw/rtc/goldfish_rtc.c ++++ b/hw/rtc/goldfish_rtc.c +@@ -178,38 +178,21 @@ static void goldfish_rtc_write(void *opaque, hwaddr offset, + trace_goldfish_rtc_write(offset, value); + } + +-static int goldfish_rtc_pre_save(void *opaque) +-{ +- uint64_t delta; +- GoldfishRTCState *s = opaque; +- +- /* +- * We want to migrate this offset, which sounds straightforward. +- * Unfortunately, we cannot directly pass tick_offset because +- * rtc_clock on destination Host might not be same source Host. +- * +- * To tackle, this we pass tick_offset relative to vm_clock from +- * source Host and make it relative to rtc_clock at destination Host. +- */ +- delta = qemu_clock_get_ns(rtc_clock) - +- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); +- s->tick_offset_vmstate = s->tick_offset + delta; +- +- return 0; +-} +- + static int goldfish_rtc_post_load(void *opaque, int version_id) + { +- uint64_t delta; + GoldfishRTCState *s = opaque; + +- /* +- * We extract tick_offset from tick_offset_vmstate by doing +- * reverse math compared to pre_save() function. +- */ +- delta = qemu_clock_get_ns(rtc_clock) - +- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); +- s->tick_offset = s->tick_offset_vmstate - delta; ++ if (version_id < 3) { ++ /* ++ * Previous versions didn't migrate tick_offset directly. Instead, they ++ * migrated tick_offset_vmstate, which is a recalculation based on ++ * QEMU_CLOCK_VIRTUAL. We use tick_offset_vmstate when migrating from ++ * older versions. ++ */ ++ uint64_t delta = qemu_clock_get_ns(rtc_clock) - ++ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ++ s->tick_offset = s->tick_offset_vmstate - delta; ++ } + + goldfish_rtc_set_alarm(s); + +@@ -239,8 +222,7 @@ static const MemoryRegionOps goldfish_rtc_ops[2] = { + + static const VMStateDescription goldfish_rtc_vmstate = { + .name = TYPE_GOLDFISH_RTC, +- .version_id = 2, +- .pre_save = goldfish_rtc_pre_save, ++ .version_id = 3, + .post_load = goldfish_rtc_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT64(tick_offset_vmstate, GoldfishRTCState), +@@ -249,6 +231,7 @@ static const VMStateDescription goldfish_rtc_vmstate = { + VMSTATE_UINT32(irq_pending, GoldfishRTCState), + VMSTATE_UINT32(irq_enabled, GoldfishRTCState), + VMSTATE_UINT32(time_high, GoldfishRTCState), ++ VMSTATE_UINT64_V(tick_offset, GoldfishRTCState, 3), + VMSTATE_END_OF_LIST() + } + }; +diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig +index ce4f433976..db17750a64 100644 +--- a/hw/usb/Kconfig ++++ b/hw/usb/Kconfig +@@ -138,3 +138,7 @@ config XLNX_USB_SUBSYS + bool + default y if XLNX_VERSAL + select USB_DWC3 ++ ++config USB_CHIPIDEA ++ bool ++ select USB_EHCI_SYSBUS +diff --git a/hw/usb/meson.build b/hw/usb/meson.build +index 793df42e21..ed5d0ad7e5 100644 +--- a/hw/usb/meson.build ++++ b/hw/usb/meson.build +@@ -25,9 +25,9 @@ softmmu_ss.add(when: 'CONFIG_USB_XHCI_NEC', if_true: files('hcd-xhci-nec.c')) + softmmu_ss.add(when: 'CONFIG_USB_MUSB', if_true: files('hcd-musb.c')) + softmmu_ss.add(when: 'CONFIG_USB_DWC2', if_true: files('hcd-dwc2.c')) + softmmu_ss.add(when: 'CONFIG_USB_DWC3', if_true: files('hcd-dwc3.c')) ++softmmu_ss.add(when: 'CONFIG_USB_CHIPIDEA', if_true: files('chipidea.c')) + + softmmu_ss.add(when: 'CONFIG_TUSB6010', if_true: files('tusb6010.c')) +-softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('chipidea.c')) + softmmu_ss.add(when: 'CONFIG_IMX_USBPHY', if_true: files('imx-usb-phy.c')) + softmmu_ss.add(when: 'CONFIG_VT82C686', if_true: files('vt82c686-uhci-pci.c')) + specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-usb2-ctrl-regs.c')) +diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c +index d422418f2d..20dcc7d2a0 100644 +--- a/hw/virtio/vhost-shadow-virtqueue.c ++++ b/hw/virtio/vhost-shadow-virtqueue.c +@@ -165,10 +165,10 @@ static bool vhost_svq_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg, + descs[i].len = cpu_to_le32(iovec[n].iov_len); + + last = i; +- i = cpu_to_le16(svq->desc_next[i]); ++ i = svq->desc_next[i]; + } + +- svq->free_head = le16_to_cpu(svq->desc_next[last]); ++ svq->free_head = svq->desc_next[last]; + return true; + } + +@@ -228,10 +228,12 @@ static void vhost_svq_kick(VhostShadowVirtqueue *svq) + smp_mb(); + + if (virtio_vdev_has_feature(svq->vdev, VIRTIO_RING_F_EVENT_IDX)) { +- uint16_t avail_event = *(uint16_t *)(&svq->vring.used->ring[svq->vring.num]); ++ uint16_t avail_event = le16_to_cpu( ++ *(uint16_t *)(&svq->vring.used->ring[svq->vring.num])); + needs_kick = vring_need_event(avail_event, svq->shadow_avail_idx, svq->shadow_avail_idx - 1); + } else { +- needs_kick = !(svq->vring.used->flags & VRING_USED_F_NO_NOTIFY); ++ needs_kick = ++ !(svq->vring.used->flags & cpu_to_le16(VRING_USED_F_NO_NOTIFY)); + } + + if (!needs_kick) { +@@ -365,7 +367,7 @@ static bool vhost_svq_more_used(VhostShadowVirtqueue *svq) + return true; + } + +- svq->shadow_used_idx = cpu_to_le16(*(volatile uint16_t *)used_idx); ++ svq->shadow_used_idx = le16_to_cpu(*(volatile uint16_t *)used_idx); + + return svq->last_used_idx != svq->shadow_used_idx; + } +@@ -383,7 +385,7 @@ static bool vhost_svq_enable_notification(VhostShadowVirtqueue *svq) + { + if (virtio_vdev_has_feature(svq->vdev, VIRTIO_RING_F_EVENT_IDX)) { + uint16_t *used_event = (uint16_t *)&svq->vring.avail->ring[svq->vring.num]; +- *used_event = svq->shadow_used_idx; ++ *used_event = cpu_to_le16(svq->shadow_used_idx); + } else { + svq->vring.avail->flags &= ~cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT); + } +@@ -408,7 +410,7 @@ static uint16_t vhost_svq_last_desc_of_chain(const VhostShadowVirtqueue *svq, + uint16_t num, uint16_t i) + { + for (uint16_t j = 0; j < (num - 1); ++j) { +- i = le16_to_cpu(svq->desc_next[i]); ++ i = svq->desc_next[i]; + } + + return i; +@@ -670,7 +672,7 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, + svq->desc_state = g_new0(SVQDescState, svq->vring.num); + svq->desc_next = g_new0(uint16_t, svq->vring.num); + for (unsigned i = 0; i < svq->vring.num - 1; i++) { +- svq->desc_next[i] = cpu_to_le16(i + 1); ++ svq->desc_next[i] = i + 1; + } + } + +diff --git a/linux-user/syscall.c b/linux-user/syscall.c +index 236076e647..737065c28c 100644 +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -352,7 +352,8 @@ _syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len, + #define __NR_sys_sched_setaffinity __NR_sched_setaffinity + _syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len, + unsigned long *, user_mask_ptr); +-/* sched_attr is not defined in glibc */ ++/* sched_attr is not defined in glibc < 2.41 */ ++#ifndef SCHED_ATTR_SIZE_VER0 + struct sched_attr { + uint32_t size; + uint32_t sched_policy; +@@ -365,6 +366,7 @@ struct sched_attr { + uint32_t sched_util_min; + uint32_t sched_util_max; + }; ++#endif + #define __NR_sys_sched_getattr __NR_sched_getattr + _syscall4(int, sys_sched_getattr, pid_t, pid, struct sched_attr *, attr, + unsigned int, size, unsigned int, flags); +diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c +index 1b1a27de02..fcc9406a20 100644 +--- a/net/vhost-vdpa.c ++++ b/net/vhost-vdpa.c +@@ -203,6 +203,18 @@ static bool vhost_vdpa_has_ufo(NetClientState *nc) + + } + ++/* ++ * FIXME: vhost_vdpa doesn't have an API to "set h/w endianness". But it's ++ * reasonable to assume that h/w is LE by default, because LE is what ++ * virtio 1.0 and later ask for. So, this function just says "yes, the h/w is ++ * LE". Otherwise, on a BE machine, higher-level code would mistakely think ++ * the h/w is BE and can't support VDPA for a virtio 1.0 client. ++ */ ++static int vhost_vdpa_set_vnet_le(NetClientState *nc, bool enable) ++{ ++ return 0; ++} ++ + static bool vhost_vdpa_check_peer_type(NetClientState *nc, ObjectClass *oc, + Error **errp) + { +@@ -230,6 +242,7 @@ static NetClientInfo net_vhost_vdpa_info = { + .cleanup = vhost_vdpa_cleanup, + .has_vnet_hdr = vhost_vdpa_has_vnet_hdr, + .has_ufo = vhost_vdpa_has_ufo, ++ .set_vnet_le = vhost_vdpa_set_vnet_le, + .check_peer_type = vhost_vdpa_check_peer_type, + }; + +diff --git a/target/arm/cpu.h b/target/arm/cpu.h +index a9cd7178f8..32b0bf8e2d 100644 +--- a/target/arm/cpu.h ++++ b/target/arm/cpu.h +@@ -57,6 +57,7 @@ + #define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */ + #define EXCP_DIVBYZERO 23 /* v7M DIVBYZERO UsageFault */ + #define EXCP_VSERR 24 ++#define EXCP_MON_TRAP 29 /* AArch32 trap to Monitor mode */ + /* NB: add new EXCP_ defines to the array in arm_log_exception() too */ + + #define ARMV7M_EXCP_RESET 1 +diff --git a/target/arm/helper.c b/target/arm/helper.c +index 5c22626b80..6cffbcb276 100644 +--- a/target/arm/helper.c ++++ b/target/arm/helper.c +@@ -2505,7 +2505,7 @@ static CPAccessResult gt_stimer_access(CPUARMState *env, + switch (arm_current_el(env)) { + case 1: + if (!arm_is_secure(env)) { +- return CP_ACCESS_TRAP; ++ return CP_ACCESS_TRAP_UNCATEGORIZED; + } + if (!(env->cp15.scr_el3 & SCR_ST)) { + return CP_ACCESS_TRAP_EL3; +@@ -2513,7 +2513,7 @@ static CPAccessResult gt_stimer_access(CPUARMState *env, + return CP_ACCESS_OK; + case 0: + case 2: +- return CP_ACCESS_TRAP; ++ return CP_ACCESS_TRAP_UNCATEGORIZED; + case 3: + return CP_ACCESS_OK; + default: +@@ -3516,7 +3516,7 @@ static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri, + { + if (arm_current_el(env) == 3 && + !(env->cp15.scr_el3 & (SCR_NS | SCR_EEL2))) { +- return CP_ACCESS_TRAP; ++ return CP_ACCESS_TRAP_UNCATEGORIZED; + } + return CP_ACCESS_OK; + } +@@ -6650,8 +6650,8 @@ static CPAccessResult access_lor_other(CPUARMState *env, + const ARMCPRegInfo *ri, bool isread) + { + if (arm_is_secure_below_el3(env)) { +- /* Access denied in secure mode. */ +- return CP_ACCESS_TRAP; ++ /* UNDEF if SCR_EL3.NS == 0 */ ++ return CP_ACCESS_TRAP_UNCATEGORIZED; + } + return access_lor_ns(env, ri, isread); + } +@@ -9475,6 +9475,7 @@ void arm_log_exception(CPUState *cs) + [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault", + [EXCP_DIVBYZERO] = "v7M DIVBYZERO UsageFault", + [EXCP_VSERR] = "Virtual SERR", ++ [EXCP_MON_TRAP] = "Monitor Trap", + }; + + if (idx >= 0 && idx < ARRAY_SIZE(excnames)) { +@@ -10036,6 +10037,16 @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs) + mask = CPSR_A | CPSR_I | CPSR_F; + offset = 0; + break; ++ case EXCP_MON_TRAP: ++ new_mode = ARM_CPU_MODE_MON; ++ addr = 0x04; ++ mask = CPSR_A | CPSR_I | CPSR_F; ++ if (env->thumb) { ++ offset = 2; ++ } else { ++ offset = 4; ++ } ++ break; + default: + cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index); + return; /* Never happens. Keep compiler happy. */ +diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c +index 70672bcd9f..9b07c79392 100644 +--- a/target/arm/op_helper.c ++++ b/target/arm/op_helper.c +@@ -631,6 +631,7 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome, + const ARMCPRegInfo *ri = rip; + CPAccessResult res = CP_ACCESS_OK; + int target_el; ++ uint32_t excp; + + if (arm_feature(env, ARM_FEATURE_XSCALE) && ri->cp < 14 + && extract32(env->cp15.c15_cpar, ri->cp, 1) == 0) { +@@ -667,8 +668,18 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome, + } + + fail: ++ excp = EXCP_UDEF; + switch (res & ~CP_ACCESS_EL_MASK) { + case CP_ACCESS_TRAP: ++ /* ++ * If EL3 is AArch32 then there's no syndrome register; the cases ++ * where we would raise a SystemAccessTrap to AArch64 EL3 all become ++ * raising a Monitor trap exception. (Because there's no visible ++ * syndrome it doesn't matter what we pass to raise_exception().) ++ */ ++ if ((res & CP_ACCESS_EL_MASK) == 3 && !arm_el_is_aa64(env, 3)) { ++ excp = EXCP_MON_TRAP; ++ } + break; + case CP_ACCESS_TRAP_UNCATEGORIZED: + if (cpu_isar_feature(aa64_ids, cpu) && isread && +@@ -702,7 +713,7 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome, + g_assert_not_reached(); + } + +- raise_exception(env, EXCP_UDEF, syndrome, target_el); ++ raise_exception(env, excp, syndrome, target_el); + } + + void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value) +diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c +index f0b8db7ce5..190574cb29 100644 +--- a/target/arm/translate-a64.c ++++ b/target/arm/translate-a64.c +@@ -1176,14 +1176,14 @@ static bool fp_access_check_only(DisasContext *s) + { + if (s->fp_excp_el) { + assert(!s->fp_access_checked); +- s->fp_access_checked = true; ++ s->fp_access_checked = -1; + + gen_exception_insn_el(s, 0, EXCP_UDEF, + syn_fp_access_trap(1, 0xe, false, 0), + s->fp_excp_el); + return false; + } +- s->fp_access_checked = true; ++ s->fp_access_checked = 1; + return true; + } + +@@ -1208,23 +1208,23 @@ static bool fp_access_check(DisasContext *s) + bool sve_access_check(DisasContext *s) + { + if (s->pstate_sm || !dc_isar_feature(aa64_sve, s)) { ++ bool ret; ++ + assert(dc_isar_feature(aa64_sme, s)); +- if (!sme_sm_enabled_check(s)) { +- goto fail_exit; +- } +- } else if (s->sve_excp_el) { ++ ret = sme_sm_enabled_check(s); ++ s->sve_access_checked = (ret ? 1 : -1); ++ return ret; ++ } ++ if (s->sve_excp_el) { ++ /* Assert that we only raise one exception per instruction. */ ++ assert(!s->sve_access_checked); + gen_exception_insn_el(s, 0, EXCP_UDEF, + syn_sve_access_trap(), s->sve_excp_el); +- goto fail_exit; ++ s->sve_access_checked = -1; ++ return false; + } +- s->sve_access_checked = true; ++ s->sve_access_checked = 1; + return fp_access_check(s); +- +- fail_exit: +- /* Assert that we only raise one exception per instruction. */ +- assert(!s->sve_access_checked); +- s->sve_access_checked = true; +- return false; + } + + /* +@@ -1252,8 +1252,9 @@ bool sme_enabled_check(DisasContext *s) + * sme_excp_el by itself for cpregs access checks. + */ + if (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el) { +- s->fp_access_checked = true; +- return sme_access_check(s); ++ bool ret = sme_access_check(s); ++ s->fp_access_checked = (ret ? 1 : -1); ++ return ret; + } + return fp_access_check_only(s); + } +@@ -14870,8 +14871,8 @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) + s->insn = insn; + s->base.pc_next = pc + 4; + +- s->fp_access_checked = false; +- s->sve_access_checked = false; ++ s->fp_access_checked = 0; ++ s->sve_access_checked = 0; + + if (s->pstate_il) { + /* +diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h +index ad3762d1ac..f01d2d973c 100644 +--- a/target/arm/translate-a64.h ++++ b/target/arm/translate-a64.h +@@ -66,7 +66,7 @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write, + static inline void assert_fp_access_checked(DisasContext *s) + { + #ifdef CONFIG_DEBUG_TCG +- if (unlikely(!s->fp_access_checked || s->fp_excp_el)) { ++ if (unlikely(s->fp_access_checked <= 0)) { + fprintf(stderr, "target-arm: FP access check missing for " + "instruction 0x%08x\n", s->insn); + abort(); +diff --git a/target/arm/translate.h b/target/arm/translate.h +index 3cdc7dbc2f..3856df8060 100644 +--- a/target/arm/translate.h ++++ b/target/arm/translate.h +@@ -85,15 +85,19 @@ typedef struct DisasContext { + uint64_t features; /* CPU features bits */ + bool aarch64; + bool thumb; +- /* Because unallocated encodings generate different exception syndrome ++ /* ++ * Because unallocated encodings generate different exception syndrome + * information from traps due to FP being disabled, we can't do a single + * "is fp access disabled" check at a high level in the decode tree. + * To help in catching bugs where the access check was forgotten in some + * code path, we set this flag when the access check is done, and assert + * that it is set at the point where we actually touch the FP regs. ++ * 0: not checked, ++ * 1: checked, access ok ++ * -1: checked, access denied + */ +- bool fp_access_checked; +- bool sve_access_checked; ++ int8_t fp_access_checked; ++ int8_t sve_access_checked; + /* ARMv8 single-step state (this is distinct from the QEMU gdbstub + * single-step support). + */ +diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c +index 294a18a5b7..3f22e0b02e 100644 +--- a/target/ppc/cpu_init.c ++++ b/target/ppc/cpu_init.c +@@ -2712,14 +2712,6 @@ static void init_proc_e200(CPUPPCState *env) + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); /* TOFIX */ +- spr_register(env, SPR_BOOKE_DSRR0, "DSRR0", +- SPR_NOACCESS, SPR_NOACCESS, +- &spr_read_generic, &spr_write_generic, +- 0x00000000); +- spr_register(env, SPR_BOOKE_DSRR1, "DSRR1", +- SPR_NOACCESS, SPR_NOACCESS, +- &spr_read_generic, &spr_write_generic, +- 0x00000000); + #if !defined(CONFIG_USER_ONLY) + env->nb_tlb = 64; + env->nb_ways = 1; +diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c +index 278d163803..b68327e13f 100644 +--- a/target/riscv/cpu_helper.c ++++ b/target/riscv/cpu_helper.c +@@ -25,6 +25,7 @@ + #include "exec/exec-all.h" + #include "instmap.h" + #include "tcg/tcg-op.h" ++#include "hw/core/tcg-cpu-ops.h" + #include "trace.h" + #include "semihosting/common-semi.h" + #include "cpu_bits.h" +@@ -1345,6 +1346,23 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, + } else if (probe) { + return false; + } else { ++ int wp_access = 0; ++ ++ if (access_type == MMU_DATA_LOAD) { ++ wp_access |= BP_MEM_READ; ++ } else if (access_type == MMU_DATA_STORE) { ++ wp_access |= BP_MEM_WRITE; ++ } ++ ++ /* ++ * If a watchpoint isn't found for 'addr' this will ++ * be a no-op and we'll resume the mmu_exception path. ++ * Otherwise we'll throw a debug exception and execution ++ * will continue elsewhere. ++ */ ++ cpu_check_watchpoint(cs, address, size, MEMTXATTRS_UNSPECIFIED, ++ wp_access, retaddr); ++ + raise_mmu_exception(env, address, access_type, pmp_violation, + first_stage_error, + riscv_cpu_virt_enabled(env) || +diff --git a/target/riscv/debug.c b/target/riscv/debug.c +index 26ea764407..cf71b52899 100644 +--- a/target/riscv/debug.c ++++ b/target/riscv/debug.c +@@ -305,7 +305,7 @@ static void type2_breakpoint_insert(CPURISCVState *env, target_ulong index) + bool enabled = type2_breakpoint_enabled(ctrl); + CPUState *cs = env_cpu(env); + int flags = BP_CPU | BP_STOP_BEFORE_ACCESS; +- uint32_t size; ++ uint32_t size, def_size; + + if (!enabled) { + return; +@@ -328,7 +328,9 @@ static void type2_breakpoint_insert(CPURISCVState *env, target_ulong index) + cpu_watchpoint_insert(cs, addr, size, flags, + &env->cpu_watchpoint[index]); + } else { +- cpu_watchpoint_insert(cs, addr, 8, flags, ++ def_size = riscv_cpu_mxl(env) == MXL_RV64 ? 8 : 4; ++ ++ cpu_watchpoint_insert(cs, addr, def_size, flags, + &env->cpu_watchpoint[index]); + } + } +diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c +index a6ac61c724..d2fe96e5c8 100644 +--- a/target/riscv/vector_helper.c ++++ b/target/riscv/vector_helper.c +@@ -4621,7 +4621,9 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ + } \ + s1 = OP(s1, (TD)s2); \ + } \ +- *((TD *)vd + HD(0)) = s1; \ ++ if (vl > 0) { \ ++ *((TD *)vd + HD(0)) = s1; \ ++ } \ + env->vstart = 0; \ + /* set tail elements to 1s */ \ + vext_set_elems_1s(vd, vta, esz, vlenb); \ +@@ -4707,7 +4709,9 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ + } \ + s1 = OP(s1, (TD)s2, &env->fp_status); \ + } \ +- *((TD *)vd + HD(0)) = s1; \ ++ if (vl > 0) { \ ++ *((TD *)vd + HD(0)) = s1; \ ++ } \ + env->vstart = 0; \ + /* set tail elements to 1s */ \ + vext_set_elems_1s(vd, vta, esz, vlenb); \ +diff --git a/target/sparc/gdbstub.c b/target/sparc/gdbstub.c +index 5d1e808e8c..2bbc494d81 100644 +--- a/target/sparc/gdbstub.c ++++ b/target/sparc/gdbstub.c +@@ -80,8 +80,13 @@ int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) + } + } + if (n < 80) { +- /* f32-f62 (double width, even numbers only) */ +- return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll); ++ /* f32-f62 (16 double width registers, even register numbers only) ++ * n == 64: f32 : env->fpr[16] ++ * n == 65: f34 : env->fpr[17] ++ * etc... ++ * n == 79: f62 : env->fpr[31] ++ */ ++ return gdb_get_reg64(mem_buf, env->fpr[(n - 64) + 16].ll); + } + switch (n) { + case 80: +@@ -174,8 +179,13 @@ int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) + } + return 4; + } else if (n < 80) { +- /* f32-f62 (double width, even numbers only) */ +- env->fpr[(n - 32) / 2].ll = tmp; ++ /* f32-f62 (16 double width registers, even register numbers only) ++ * n == 64: f32 : env->fpr[16] ++ * n == 65: f34 : env->fpr[17] ++ * etc... ++ * n == 79: f62 : env->fpr[31] ++ */ ++ env->fpr[(n - 64) + 16].ll = tmp; + } else { + switch (n) { + case 80: +diff --git a/ui/cocoa.m b/ui/cocoa.m +index c41689e951..54acf14794 100644 +--- a/ui/cocoa.m ++++ b/ui/cocoa.m +@@ -549,6 +549,9 @@ - (void) setContentDimensions + } + } + ++#pragma clang diagnostic push ++#pragma clang diagnostic ignored "-Wdeprecated-declarations" ++ + - (void) updateUIInfoLocked + { + /* Must be called with the iothread lock, i.e. via updateUIInfo */ +@@ -594,6 +597,8 @@ - (void) updateUIInfoLocked + dpy_set_ui_info(dcl.con, &info, TRUE); + } + ++#pragma clang diagnostic pop ++ + - (void) updateUIInfo + { + if (!allow_events) { +diff --git a/ui/meson.build b/ui/meson.build +index 76c6644b3f..7756760789 100644 +--- a/ui/meson.build ++++ b/ui/meson.build +@@ -110,8 +110,6 @@ if gtk.found() + endif + + if sdl.found() +- softmmu_ss.add(when: 'CONFIG_WIN32', if_true: files('win32-kbd-hook.c')) +- + sdl_ss = ss.source_set() + sdl_ss.add(sdl, sdl_image, pixman, glib, files( + 'sdl2-2d.c', +diff --git a/ui/sdl2.c b/ui/sdl2.c +index fc7e8639c2..f9e7402151 100644 +--- a/ui/sdl2.c ++++ b/ui/sdl2.c +@@ -32,7 +32,6 @@ + #include "sysemu/runstate.h" + #include "sysemu/runstate-action.h" + #include "sysemu/sysemu.h" +-#include "ui/win32-kbd-hook.h" + #include "qemu/log.h" + + static int sdl2_num_outputs; +@@ -231,7 +230,6 @@ static void sdl_grab_start(struct sdl2_console *scon) + } + SDL_SetWindowGrab(scon->real_window, SDL_TRUE); + gui_grab = 1; +- win32_kbd_set_grab(true); + sdl_update_caption(scon); + } + +@@ -239,7 +237,6 @@ static void sdl_grab_end(struct sdl2_console *scon) + { + SDL_SetWindowGrab(scon->real_window, SDL_FALSE); + gui_grab = 0; +- win32_kbd_set_grab(false); + sdl_show_cursor(scon); + sdl_update_caption(scon); + } +@@ -340,19 +337,6 @@ static int get_mod_state(void) + } + } + +-static void *sdl2_win32_get_hwnd(struct sdl2_console *scon) +-{ +-#ifdef CONFIG_WIN32 +- SDL_SysWMinfo info; +- +- SDL_VERSION(&info.version); +- if (SDL_GetWindowWMInfo(scon->real_window, &info)) { +- return info.info.win.window; +- } +-#endif +- return NULL; +-} +- + static void handle_keydown(SDL_Event *ev) + { + int win; +@@ -576,10 +560,6 @@ static void handle_windowevent(SDL_Event *ev) + sdl2_redraw(scon); + break; + case SDL_WINDOWEVENT_FOCUS_GAINED: +- win32_kbd_set_grab(gui_grab); +- if (qemu_console_is_graphic(scon->dcl.con)) { +- win32_kbd_set_window(sdl2_win32_get_hwnd(scon)); +- } + /* fall through */ + case SDL_WINDOWEVENT_ENTER: + if (!gui_grab && (qemu_input_is_absolute() || absolute_enabled)) { +@@ -595,9 +575,6 @@ static void handle_windowevent(SDL_Event *ev) + scon->ignore_hotkeys = get_mod_state(); + break; + case SDL_WINDOWEVENT_FOCUS_LOST: +- if (qemu_console_is_graphic(scon->dcl.con)) { +- win32_kbd_set_window(NULL); +- } + if (gui_grab && !gui_fullscreen) { + sdl_grab_end(scon); + } +@@ -849,10 +826,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o) + #ifdef SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR /* only available since SDL 2.0.8 */ + SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"); + #endif +-#ifndef CONFIG_WIN32 +- /* QEMU uses its own low level keyboard hook procecure on Windows */ + SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "1"); +-#endif + #ifdef SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED + SDL_SetHint(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, "0"); + #endif +diff --git a/util/cacheflush.c b/util/cacheflush.c +index 2c2c73e085..9b1debd1c1 100644 +--- a/util/cacheflush.c ++++ b/util/cacheflush.c +@@ -264,9 +264,11 @@ void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len) + for (p = rw & -dcache_lsize; p < rw + len; p += dcache_lsize) { + asm volatile("dc\tcvau, %0" : : "r" (p) : "memory"); + } +- asm volatile("dsb\tish" : : : "memory"); + } + ++ /* DSB unconditionally to ensure any outstanding writes are committed. */ ++ asm volatile("dsb\tish" : : : "memory"); ++ + /* + * If CTR_EL0.DIC is enabled, Instruction cache cleaning to the Point + * of Unification is not required for instruction to data coherence.