--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian....@packages.debian.org
Usertags: pu
X-Debbugs-Cc: q...@packages.debian.org, pkg-qemu-de...@lists.alioth.debian.org
Control: affects -1 + src:qemu
[ Reason ]
There's a new qemu stable/bugfix release (7.2.15) since the previous
debian qemu release (accepted into s-p-u), fixing a number of various
issues as usual. It would be nice to have these fixes in debian too,
so debian users will benefit from the qemu stable series.
Also, this debian qemu release addresses an old issue, fixed long time
ago in sid/testing, but which has been forgotten to be fixed in stable, -
this is a newly reported incarnation #1087822 of an old issue #1053101.
This issue resulted in stable kernel patch being reverted.
[ Tests ]
Both upstream automatic tests are passed, and my usual share of
quick real-life tests too (a bunch of qemu/kvm guests which I
test for every new qemu release).
[ Risks ]
The risks do exists obviously, however we're trying hard to minimize
possible risks as much as possible by carefully selecting which changes
to pick and how to do that.
[ Checklist ]
[x] *all* changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in (old)stable
[x] the issue is verified as fixed in unstable
[ Changes ]
All changes except one comes from the upstream repository,
which is also mirrored on salsa:
https://salsa.debian.org/qemu-team/qemu/-/commits/stable-7.2/
In this case the talk is about v7.2.14 and v7.2.15 tags.
Complete changelog is below (a part of debdiff, at the top).
[ Other info ]
Historically, qemu in debian were built with base upstream release
plus stable/bugfix patches (7.2.orig.tar.gz which corresponds to
upstream 7.2.0 plus 7.2.1..7.2.2..7.2.3 etc patches). I don't
remember why this has been done this way, and changed it to include
complete 3-component upstream version tarball past bookworm, but
continue this scheme in bookworm stable.
Some of the upstream changes are about testuite/CI (.gitlab-ci.d/,
tests/) which are not relevant for Debian, but does not affect Debian
either.
[ Debdiff ]
is attached. The change for #1087822 is at the end, it is to stop
using --disable-pie on all architectures except i386 (where libc
is not built with -fPIE flag so the link fails).
Thanks,
/mjt
diff -Nru qemu-7.2+dfsg/debian/changelog qemu-7.2+dfsg/debian/changelog
--- qemu-7.2+dfsg/debian/changelog 2024-11-01 16:50:46.000000000 +0300
+++ qemu-7.2+dfsg/debian/changelog 2024-11-25 20:37:50.000000000 +0300
@@ -1,3 +1,61 @@
+qemu (1:7.2+dfsg-7+deb12u9) bookworm; urgency=medium
+
+ * re-enable (upstream default) --static-pie linking for qemu-user-static
+ binaries. This has been disabled due to a mistake (LP:#1908331), has been
+ re-enabled in later debian qemu releases. Disabling static-pie leads to
+ qemu binaries using fixed address which has high chance to clash with
+ something in the emulated binary address space, and hence makes qemu-user
+ generally crashy. But this change has been forgotten in bookworm. With
+ recent bookworm kernel updates (6.1.112, with changes to KASLR), these
+ qemu-user-static crashes has become too common. Also add lintian-override
+ about not-static-enough binaries.
+ Closes: #1087822, #1053101
+ * update to upstream 7.2.15 stable/bugfix release, v7.2.15.diff,
+ https://gitlab.com/qemu-project/qemu/-/commits/v7.2.15 :
+ - Update version for 7.2.15 release
+ - usb-hub: Fix handling port power control messages
+ - hw/audio/hda: fix memory leak on audio setup
+ - hw/misc/mos6522: Fix bad class definition of the MOS6522 device
+ - tcg: Allow top bit of SIMD_DATA_BITS to be set in simd_desc()
+ - target/arm: Drop user-only special case in sve_stN_r
+ - linux-user: Fix setreuid and setregid to use direct syscalls
+ - target/i386: Fix legacy page table walk
+ - 9pfs: fix crash on 'Treaddir' request
+ - hw/nvme: fix handling of over-committed queues
+ - target/arm: Fix SVE SDOT/UDOT/USDOT (4-way, indexed)
+ - target/ppc: Set ctx->opcode for decode_insn32()
+ - target/riscv: Fix vcompress with rvv_ta_all_1s
+ - hw/intc/riscv_aplic: Check and update pending when write sourcecfg
+ - hw/intc/riscv_aplic: Fix in_clrip[x] read emulation
+ - target/riscv: Set vtype.vill on CPU reset
+ - hw/intc: Don't clear pending bits on IRQ lowering
+ - target/riscv: Correct SXL return value for RV32 in RV64 QEMU
+ - target/riscv/csr.c: Fix an access to VXSAT
+ - target/arm: Don't assert in regime_is_user() for E10 mmuidx values
+ - net/tap-win32: Fix gcc 14 format truncation errors
+ - Fix calculation of minimum in colo_compare_tcp
+ - gitlab: make check-[dco|patch] a little more verbose
+ - linux-user/ppc: Fix sigmask endianness issue in sigreturn
+ - target/i386: Walk NPT in guest real mode
+ - target/i386: Avoid unreachable variable declaration in mmu_translate()
+ - tcg: Reset data_gen_ptr correctly
+ - raw-format: Fix error message for invalid offset/size
+ - tests: Wait for migration completion on destination QEMU
+ to avoid failures
+ - KVM: Dynamic sized kvm memslots array
+ - hw/audio/hda: free timer on exit
+ - hw/intc/arm_gicv3_cpuif: Add cast to match the documentation
+ - scsi: fetch unit attention when creating the request
+ - linux-user: Fix parse_elf_properties GNU0_MAGIC check
+ - linux-user/flatload: Take mmap_lock in load_flt_binary()
+ - tracetool: avoid invalid escape in Python string
+ - fuzz: disable leak-detection for oss-fuzz builds
+ - block/reqlist: allow adding overlapping requests
+ - target/ppc: Fix lxvx/stxvx facility check
+ - softmmu/physmem.c: Keep transaction attribute in address_space_map()
+
+ -- Michael Tokarev <m...@tls.msk.ru> Mon, 25 Nov 2024 20:37:50 +0300
+
qemu (1:7.2+dfsg-7+deb12u8) bookworm; urgency=medium
* update to upstream 7.2.14 stable/bugfix release, v7.2.14.diff,
diff -Nru qemu-7.2+dfsg/debian/patches/series
qemu-7.2+dfsg/debian/patches/series
--- qemu-7.2+dfsg/debian/patches/series 2024-11-01 16:50:46.000000000 +0300
+++ qemu-7.2+dfsg/debian/patches/series 2024-11-25 20:37:50.000000000 +0300
@@ -12,6 +12,7 @@
v7.2.12.diff
v7.2.13.diff
v7.2.14.diff
+v7.2.15.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.15.diff
qemu-7.2+dfsg/debian/patches/v7.2.15.diff
--- qemu-7.2+dfsg/debian/patches/v7.2.15.diff 1970-01-01 03:00:00.000000000
+0300
+++ qemu-7.2+dfsg/debian/patches/v7.2.15.diff 2024-11-25 20:37:50.000000000
+0300
@@ -0,0 +1,1245 @@
+Subject: v7.2.15
+Date: Thu Nov 21 00:11:28 2024 +0300
+From: Michael Tokarev <m...@tls.msk.ru>
+Forwarded: not-needed
+
+This is a difference between upstream qemu v7.2.14
+and upstream qemu v7.2.15.
+
+ .gitlab-ci.d/check-dco.py | 5 +-
+ .gitlab-ci.d/check-patch.py | 5 +-
+ VERSION | 2 +-
+ accel/kvm/kvm-all.c | 88 +++++++++++++++++++++++++++++-------
+ accel/kvm/trace-events | 1 +
+ block/copy-before-write.c | 3 +-
+ block/raw-format.c | 4 +-
+ block/reqlist.c | 2 -
+ hw/9pfs/9p.c | 5 ++
+ hw/audio/hda-codec.c | 14 +++---
+ hw/intc/arm_gicv3_cpuif.c | 2 +-
+ hw/intc/riscv_aplic.c | 38 ++++++++++++++--
+ hw/intc/sifive_plic.c | 6 ++-
+ hw/nvme/ctrl.c | 21 +++++----
+ hw/scsi/scsi-bus.c | 36 +++++++++++++--
+ hw/usb/dev-hub.c | 1 +
+ include/hw/misc/mos6522.h | 2 +-
+ include/hw/scsi/scsi.h | 1 +
+ include/sysemu/kvm_int.h | 1 +
+ linux-user/elfload.c | 12 ++---
+ linux-user/flatload.c | 3 ++
+ linux-user/ppc/signal.c | 2 +-
+ linux-user/syscall.c | 20 ++++++--
+ net/colo-compare.c | 3 +-
+ net/tap-win32.c | 15 +++---
+ scripts/oss-fuzz/build.sh | 1 +
+ scripts/tracetool/__init__.py | 14 +++---
+ scripts/tracetool/format/log_stap.py | 2 +-
+ softmmu/physmem.c | 2 +-
+ target/arm/internals.h | 5 +-
+ target/arm/sve_helper.c | 4 --
+ target/arm/vec_helper.c | 9 +++-
+ target/i386/cpu.h | 1 +
+ target/i386/tcg/seg_helper.c | 2 +-
+ target/i386/tcg/sysemu/excp_helper.c | 19 ++++++--
+ target/ppc/translate.c | 3 +-
+ target/ppc/translate/vsx-impl.c.inc | 2 +-
+ target/riscv/cpu.c | 1 +
+ target/riscv/cpu.h | 5 +-
+ target/riscv/csr.c | 4 +-
+ target/riscv/vector_helper.c | 2 +-
+ tcg/tcg-op-gvec.c | 15 +++++-
+ tcg/tcg.c | 2 +-
+ tests/qtest/tpm-tests.c | 2 +-
+ 44 files changed, 276 insertions(+), 111 deletions(-)
+
+diff --git a/.gitlab-ci.d/check-dco.py b/.gitlab-ci.d/check-dco.py
+index b929571eed..8780d73e31 100755
+--- a/.gitlab-ci.d/check-dco.py
++++ b/.gitlab-ci.d/check-dco.py
+@@ -19,10 +19,9 @@
+ reponame = os.path.basename(cwd)
+ repourl = "https://gitlab.com/%s/%s.git" % (namespace, reponame)
+
++print(f"adding upstream git repo @ {repourl}")
+ subprocess.check_call(["git", "remote", "add", "check-dco", repourl])
+-subprocess.check_call(["git", "fetch", "check-dco", "stable-7.2"],
+- stdout=subprocess.DEVNULL,
+- stderr=subprocess.DEVNULL)
++subprocess.check_call(["git", "fetch", "check-dco", "stable-7.2"])
+
+ ancestor = subprocess.check_output(["git", "merge-base",
+ "check-dco/stable-7.2", "HEAD"],
+diff --git a/.gitlab-ci.d/check-patch.py b/.gitlab-ci.d/check-patch.py
+index 39e2b403c9..68c549a146 100755
+--- a/.gitlab-ci.d/check-patch.py
++++ b/.gitlab-ci.d/check-patch.py
+@@ -19,13 +19,12 @@
+ reponame = os.path.basename(cwd)
+ repourl = "https://gitlab.com/%s/%s.git" % (namespace, reponame)
+
++print(f"adding upstream git repo @ {repourl}")
+ # GitLab CI environment does not give us any direct info about the
+ # base for the user's branch. We thus need to figure out a common
+ # ancestor between the user's branch and current git master.
+ subprocess.check_call(["git", "remote", "add", "check-patch", repourl])
+-subprocess.check_call(["git", "fetch", "check-patch", "master"],
+- stdout=subprocess.DEVNULL,
+- stderr=subprocess.DEVNULL)
++subprocess.check_call(["git", "fetch", "check-patch", "master"])
+
+ ancestor = subprocess.check_output(["git", "merge-base",
+ "check-patch/master", "HEAD"],
+diff --git a/VERSION b/VERSION
+index 0755f425a1..cc53d22108 100644
+--- a/VERSION
++++ b/VERSION
+@@ -1 +1 @@
+-7.2.14
++7.2.15
+diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
+index 0a127ece11..370ecab785 100644
+--- a/accel/kvm/kvm-all.c
++++ b/accel/kvm/kvm-all.c
+@@ -77,6 +77,9 @@
+ do { } while (0)
+ #endif
+
++/* Default num of memslots to be allocated when VM starts */
++#define KVM_MEMSLOTS_NR_ALLOC_DEFAULT 16
++
+ struct KVMParkedVcpu {
+ unsigned long vcpu_id;
+ int kvm_fd;
+@@ -172,6 +175,57 @@ void kvm_resample_fd_notify(int gsi)
+ }
+ }
+
++/**
++ * kvm_slots_grow(): Grow the slots[] array in the KVMMemoryListener
++ *
++ * @kml: The KVMMemoryListener* to grow the slots[] array
++ * @nr_slots_new: The new size of slots[] array
++ *
++ * Returns: True if the array grows larger, false otherwise.
++ */
++static bool kvm_slots_grow(KVMMemoryListener *kml, unsigned int nr_slots_new)
++{
++ unsigned int i, cur = kml->nr_slots_allocated;
++ KVMSlot *slots;
++
++ if (nr_slots_new > kvm_state->nr_slots) {
++ nr_slots_new = kvm_state->nr_slots;
++ }
++
++ if (cur >= nr_slots_new) {
++ /* Big enough, no need to grow, or we reached max */
++ return false;
++ }
++
++ if (cur == 0) {
++ slots = g_new0(KVMSlot, nr_slots_new);
++ } else {
++ assert(kml->slots);
++ slots = g_renew(KVMSlot, kml->slots, nr_slots_new);
++ /*
++ * g_renew() doesn't initialize extended buffers, however kvm
++ * memslots require fields to be zero-initialized. E.g. pointers,
++ * memory_size field, etc.
++ */
++ memset(&slots[cur], 0x0, sizeof(slots[0]) * (nr_slots_new - cur));
++ }
++
++ for (i = cur; i < nr_slots_new; i++) {
++ slots[i].slot = i;
++ }
++
++ kml->slots = slots;
++ kml->nr_slots_allocated = nr_slots_new;
++ trace_kvm_slots_grow(cur, nr_slots_new);
++
++ return true;
++}
++
++static bool kvm_slots_double(KVMMemoryListener *kml)
++{
++ return kvm_slots_grow(kml, kml->nr_slots_allocated * 2);
++}
++
+ int kvm_get_max_memslots(void)
+ {
+ KVMState *s = KVM_STATE(current_accel());
+@@ -182,15 +236,26 @@ int kvm_get_max_memslots(void)
+ /* Called with KVMMemoryListener.slots_lock held */
+ static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml)
+ {
+- KVMState *s = kvm_state;
++ unsigned int n;
+ int i;
+
+- for (i = 0; i < s->nr_slots; i++) {
++ for (i = 0; i < kml->nr_slots_allocated; i++) {
+ if (kml->slots[i].memory_size == 0) {
+ return &kml->slots[i];
+ }
+ }
+
++ /*
++ * If no free slots, try to grow first by doubling. Cache the old size
++ * here to avoid another round of search: if the grow succeeded, it
++ * means slots[] now must have the existing "n" slots occupied,
++ * followed by one or more free slots starting from slots[n].
++ */
++ n = kml->nr_slots_allocated;
++ if (kvm_slots_double(kml)) {
++ return &kml->slots[n];
++ }
++
+ return NULL;
+ }
+
+@@ -224,10 +289,9 @@ static KVMSlot
*kvm_lookup_matching_slot(KVMMemoryListener *kml,
+ hwaddr start_addr,
+ hwaddr size)
+ {
+- KVMState *s = kvm_state;
+ int i;
+
+- for (i = 0; i < s->nr_slots; i++) {
++ for (i = 0; i < kml->nr_slots_allocated; i++) {
+ KVMSlot *mem = &kml->slots[i];
+
+ if (start_addr == mem->start_addr && size == mem->memory_size) {
+@@ -269,7 +333,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void
*ram,
+ int i, ret = 0;
+
+ kvm_slots_lock();
+- for (i = 0; i < s->nr_slots; i++) {
++ for (i = 0; i < kml->nr_slots_allocated; i++) {
+ KVMSlot *mem = &kml->slots[i];
+
+ if (ram >= mem->ram && ram < mem->ram + mem->memory_size) {
+@@ -991,7 +1055,7 @@ static int kvm_physical_log_clear(KVMMemoryListener *kml,
+
+ kvm_slots_lock();
+
+- for (i = 0; i < s->nr_slots; i++) {
++ for (i = 0; i < kml->nr_slots_allocated; i++) {
+ mem = &kml->slots[i];
+ /* Discard slots that are empty or do not overlap the section */
+ if (!mem->memory_size ||
+@@ -1482,19 +1546,14 @@ static void kvm_log_sync(MemoryListener *listener,
+ static void kvm_log_sync_global(MemoryListener *l)
+ {
+ KVMMemoryListener *kml = container_of(l, KVMMemoryListener, listener);
+- KVMState *s = kvm_state;
+ KVMSlot *mem;
+ int i;
+
+ /* Flush all kernel dirty addresses into KVMSlot dirty bitmap */
+ kvm_dirty_ring_flush();
+
+- /*
+- * TODO: make this faster when nr_slots is big while there are
+- * only a few used slots (small VMs).
+- */
+ kvm_slots_lock();
+- for (i = 0; i < s->nr_slots; i++) {
++ for (i = 0; i < kml->nr_slots_allocated; i++) {
+ mem = &kml->slots[i];
+ if (mem->memory_size && mem->flags & KVM_MEM_LOG_DIRTY_PAGES) {
+ kvm_slot_sync_dirty_pages(mem);
+@@ -1603,12 +1662,9 @@ void kvm_memory_listener_register(KVMState *s,
KVMMemoryListener *kml,
+ {
+ int i;
+
+- kml->slots = g_new0(KVMSlot, s->nr_slots);
+ kml->as_id = as_id;
+
+- for (i = 0; i < s->nr_slots; i++) {
+- kml->slots[i].slot = i;
+- }
++ kvm_slots_grow(kml, KVM_MEMSLOTS_NR_ALLOC_DEFAULT);
+
+ kml->listener.region_add = kvm_region_add;
+ kml->listener.region_del = kvm_region_del;
+diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
+index 399aaeb0ec..a1965a50c5 100644
+--- a/accel/kvm/trace-events
++++ b/accel/kvm/trace-events
+@@ -26,3 +26,4 @@ kvm_dirty_ring_reap(uint64_t count, int64_t t) "reaped
%"PRIu64" pages (took %"P
+ kvm_dirty_ring_reaper_kick(const char *reason) "%s"
+ kvm_dirty_ring_flush(int finished) "%d"
+
++kvm_slots_grow(unsigned int old, unsigned int new) "%u -> %u"
+diff --git a/block/copy-before-write.c b/block/copy-before-write.c
+index 4abaa7339e..8748aad5a4 100644
+--- a/block/copy-before-write.c
++++ b/block/copy-before-write.c
+@@ -64,7 +64,8 @@ typedef struct BDRVCopyBeforeWriteState {
+
+ /*
+ * @frozen_read_reqs: current read requests for fleecing user in bs->file
+- * node. These areas must not be rewritten by guest.
++ * node. These areas must not be rewritten by guest. There can be multiple
++ * overlapping read requests.
+ */
+ BlockReqList frozen_read_reqs;
+
+diff --git a/block/raw-format.c b/block/raw-format.c
+index a68014ef0b..f3fc604f92 100644
+--- a/block/raw-format.c
++++ b/block/raw-format.c
+@@ -110,7 +110,7 @@ static int raw_apply_options(BlockDriverState *bs,
BDRVRawState *s,
+ if (offset > real_size) {
+ error_setg(errp, "Offset (%" PRIu64 ") cannot be greater than "
+ "size of the containing file (%" PRId64 ")",
+- s->offset, real_size);
++ offset, real_size);
+ return -EINVAL;
+ }
+
+@@ -118,7 +118,7 @@ static int raw_apply_options(BlockDriverState *bs,
BDRVRawState *s,
+ error_setg(errp, "The sum of offset (%" PRIu64 ") and size "
+ "(%" PRIu64 ") has to be smaller or equal to the "
+ " actual size of the containing file (%" PRId64 ")",
+- s->offset, s->size, real_size);
++ offset, size, real_size);
+ return -EINVAL;
+ }
+
+diff --git a/block/reqlist.c b/block/reqlist.c
+index 08cb57cfa4..098e807378 100644
+--- a/block/reqlist.c
++++ b/block/reqlist.c
+@@ -20,8 +20,6 @@
+ void reqlist_init_req(BlockReqList *reqs, BlockReq *req, int64_t offset,
+ int64_t bytes)
+ {
+- assert(!reqlist_find_conflict(reqs, offset, bytes));
+-
+ *req = (BlockReq) {
+ .offset = offset,
+ .bytes = bytes,
+diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
+index 072cf67956..51ad5bfb11 100644
+--- a/hw/9pfs/9p.c
++++ b/hw/9pfs/9p.c
+@@ -2596,6 +2596,11 @@ static void coroutine_fn v9fs_readdir(void *opaque)
+ retval = -EINVAL;
+ goto out_nofid;
+ }
++ if (fidp->fid_type != P9_FID_DIR) {
++ warn_report_once("9p: bad client: T_readdir on non-directory stream");
++ retval = -ENOTDIR;
++ goto out;
++ }
+ if (!fidp->fs.dir.stream) {
+ retval = -EINVAL;
+ goto out;
+diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c
+index 0f66754b6a..5c75a3a59a 100644
+--- a/hw/audio/hda-codec.c
++++ b/hw/audio/hda-codec.c
+@@ -488,8 +488,7 @@ static void hda_audio_setup(HDAAudioStream *st)
+ if (st->output) {
+ if (use_timer) {
+ cb = hda_audio_output_cb;
+- st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+- hda_audio_output_timer, st);
++ timer_del(st->buft);
+ } else {
+ cb = hda_audio_compat_output_cb;
+ }
+@@ -498,8 +497,7 @@ static void hda_audio_setup(HDAAudioStream *st)
+ } else {
+ if (use_timer) {
+ cb = hda_audio_input_cb;
+- st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+- hda_audio_input_timer, st);
++ timer_del(st->buft);
+ } else {
+ cb = hda_audio_compat_input_cb;
+ }
+@@ -722,8 +720,12 @@ static int hda_audio_init(HDACodecDevice *hda, const
struct desc_codec *desc)
+ st->gain_right = QEMU_HDA_AMP_STEPS;
+ st->compat_bpos = sizeof(st->compat_buf);
+ st->output = true;
++ st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL,
++ hda_audio_output_timer, st);
+ } else {
+ st->output = false;
++ st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL,
++ hda_audio_input_timer, st);
+ }
+ st->format = AC_FMT_TYPE_PCM | AC_FMT_BITS_16 |
+ (1 << AC_FMT_CHAN_SHIFT);
+@@ -747,9 +749,7 @@ static void hda_audio_exit(HDACodecDevice *hda)
+ if (st->node == NULL) {
+ continue;
+ }
+- if (a->use_timer) {
+- timer_del(st->buft);
+- }
++ timer_free(st->buft);
+ if (st->output) {
+ AUD_close_out(&a->card, st->voice.out);
+ } else {
+diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
+index ddfbc69d65..9811fb3fb4 100644
+--- a/hw/intc/arm_gicv3_cpuif.c
++++ b/hw/intc/arm_gicv3_cpuif.c
+@@ -751,7 +751,7 @@ static void icv_activate_vlpi(GICv3CPUState *cs)
+ int regno = aprbit / 32;
+ int regbit = aprbit % 32;
+
+- cs->ich_apr[cs->hppvlpi.grp][regno] |= (1 << regbit);
++ cs->ich_apr[cs->hppvlpi.grp][regno] |= (1U << regbit);
+ gicv3_redist_vlpi_pending(cs, cs->hppvlpi.irq, 0);
+ }
+
+diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
+index 961caff7b6..153827a056 100644
+--- a/hw/intc/riscv_aplic.c
++++ b/hw/intc/riscv_aplic.c
+@@ -148,18 +148,42 @@
+
+ #define APLIC_IDC_CLAIMI 0x1c
+
++static bool riscv_aplic_irq_rectified_val(RISCVAPLICState *aplic,
++ uint32_t irq)
++{
++ uint32_t sourcecfg, sm, raw_input, irq_inverted;
++
++ if (!irq || aplic->num_irqs <= irq) {
++ return false;
++ }
++
++ sourcecfg = aplic->sourcecfg[irq];
++ if (sourcecfg & APLIC_SOURCECFG_D) {
++ return false;
++ }
++
++ sm = sourcecfg & APLIC_SOURCECFG_SM_MASK;
++ if (sm == APLIC_SOURCECFG_SM_INACTIVE) {
++ return false;
++ }
++
++ raw_input = (aplic->state[irq] & APLIC_ISTATE_INPUT) ? 1 : 0;
++ irq_inverted = (sm == APLIC_SOURCECFG_SM_LEVEL_LOW ||
++ sm == APLIC_SOURCECFG_SM_EDGE_FALL) ? 1 : 0;
++
++ return !!(raw_input ^ irq_inverted);
++}
++
+ static uint32_t riscv_aplic_read_input_word(RISCVAPLICState *aplic,
+ uint32_t word)
+ {
+- uint32_t i, irq, ret = 0;
++ uint32_t i, irq, rectified_val, ret = 0;
+
+ for (i = 0; i < 32; i++) {
+ irq = word * 32 + i;
+- if (!irq || aplic->num_irqs <= irq) {
+- continue;
+- }
+
+- ret |= ((aplic->state[irq] & APLIC_ISTATE_INPUT) ? 1 : 0) << i;
++ rectified_val = riscv_aplic_irq_rectified_val(aplic, irq);
++ ret |= rectified_val << i;
+ }
+
+ return ret;
+@@ -665,6 +689,10 @@ static void riscv_aplic_write(void *opaque, hwaddr addr,
uint64_t value,
+ (aplic->sourcecfg[irq] == 0)) {
+ riscv_aplic_set_pending_raw(aplic, irq, false);
+ riscv_aplic_set_enabled_raw(aplic, irq, false);
++ } else {
++ if (riscv_aplic_irq_rectified_val(aplic, irq)) {
++ riscv_aplic_set_pending_raw(aplic, irq, true);
++ }
+ }
+ } else if (aplic->mmode && aplic->msimode &&
+ (addr == APLIC_MMSICFGADDR)) {
+diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
+index c2dfacf028..7a42c4b792 100644
+--- a/hw/intc/sifive_plic.c
++++ b/hw/intc/sifive_plic.c
+@@ -331,8 +331,10 @@ static void sifive_plic_irq_request(void *opaque, int
irq, int level)
+ {
+ SiFivePLICState *s = opaque;
+
+- sifive_plic_set_pending(s, irq, level > 0);
+- sifive_plic_update(s);
++ if (level > 0) {
++ sifive_plic_set_pending(s, irq, true);
++ sifive_plic_update(s);
++ }
+ }
+
+ static void sifive_plic_realize(DeviceState *dev, Error **errp)
+diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
+index ed56ad40b3..5710392e30 100644
+--- a/hw/nvme/ctrl.c
++++ b/hw/nvme/ctrl.c
+@@ -1385,9 +1385,16 @@ static void nvme_post_cqes(void *opaque)
+ stl_le_p(&n->bar.csts, NVME_CSTS_FAILED);
+ break;
+ }
++
+ QTAILQ_REMOVE(&cq->req_list, req, entry);
++
+ nvme_inc_cq_tail(cq);
+ nvme_sg_unmap(&req->sg);
++
++ if (QTAILQ_EMPTY(&sq->req_list) && !nvme_sq_empty(sq)) {
++ qemu_bh_schedule(sq->bh);
++ }
++
+ QTAILQ_INSERT_TAIL(&sq->req_list, req, entry);
+ }
+ if (cq->tail != cq->head) {
+@@ -6792,7 +6799,6 @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr,
int val)
+ /* Completion queue doorbell write */
+
+ uint16_t new_head = val & 0xffff;
+- int start_sqs;
+ NvmeCQueue *cq;
+
+ qid = (addr - (0x1000 + (1 << 2))) >> 3;
+@@ -6843,19 +6849,16 @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr,
int val)
+
+ trace_pci_nvme_mmio_doorbell_cq(cq->cqid, new_head);
+
+- start_sqs = nvme_cq_full(cq) ? 1 : 0;
++ /* scheduled deferred cqe posting if queue was previously full */
++ if (nvme_cq_full(cq)) {
++ qemu_bh_schedule(cq->bh);
++ }
++
+ cq->head = new_head;
+ if (!qid && n->dbbuf_enabled) {
+ pci_dma_write(&n->parent_obj, cq->db_addr, &cq->head,
+ sizeof(cq->head));
+ }
+- if (start_sqs) {
+- NvmeSQueue *sq;
+- QTAILQ_FOREACH(sq, &cq->sq_list, entry) {
+- qemu_bh_schedule(sq->bh);
+- }
+- qemu_bh_schedule(cq->bh);
+- }
+
+ if (cq->tail == cq->head) {
+ if (cq->irq_enabled) {
+diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
+index e5c9f7a53d..e76bfbd47b 100644
+--- a/hw/scsi/scsi-bus.c
++++ b/hw/scsi/scsi-bus.c
+@@ -413,19 +413,35 @@ static const struct SCSIReqOps reqops_invalid_opcode = {
+
+ /* SCSIReqOps implementation for unit attention conditions. */
+
+-static int32_t scsi_unit_attention(SCSIRequest *req, uint8_t *buf)
++static void scsi_fetch_unit_attention_sense(SCSIRequest *req)
+ {
++ SCSISense *ua = NULL;
++
+ if (req->dev->unit_attention.key == UNIT_ATTENTION) {
+- scsi_req_build_sense(req, req->dev->unit_attention);
++ ua = &req->dev->unit_attention;
+ } else if (req->bus->unit_attention.key == UNIT_ATTENTION) {
+- scsi_req_build_sense(req, req->bus->unit_attention);
++ ua = &req->bus->unit_attention;
+ }
++
++ /*
++ * Fetch the unit attention sense immediately so that another
++ * scsi_req_new does not use reqops_unit_attention.
++ */
++ if (ua) {
++ scsi_req_build_sense(req, *ua);
++ *ua = SENSE_CODE(NO_SENSE);
++ }
++}
++
++static int32_t scsi_unit_attention(SCSIRequest *req, uint8_t *buf)
++{
+ scsi_req_complete(req, CHECK_CONDITION);
+ return 0;
+ }
+
+ static const struct SCSIReqOps reqops_unit_attention = {
+ .size = sizeof(SCSIRequest),
++ .init_req = scsi_fetch_unit_attention_sense,
+ .send_command = scsi_unit_attention
+ };
+
+@@ -699,6 +715,11 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops,
SCSIDevice *d,
+ object_ref(OBJECT(d));
+ object_ref(OBJECT(qbus->parent));
+ notifier_list_init(&req->cancel_notifiers);
++
++ if (reqops->init_req) {
++ reqops->init_req(req);
++ }
++
+ trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
+ return req;
+ }
+@@ -798,6 +819,15 @@ uint8_t *scsi_req_get_buf(SCSIRequest *req)
+ static void scsi_clear_unit_attention(SCSIRequest *req)
+ {
+ SCSISense *ua;
++
++ /*
++ * scsi_fetch_unit_attention_sense() already cleaned the unit attention
++ * in this case.
++ */
++ if (req->ops == &reqops_unit_attention) {
++ return;
++ }
++
+ if (req->dev->unit_attention.key != UNIT_ATTENTION &&
+ req->bus->unit_attention.key != UNIT_ATTENTION) {
+ return;
+diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
+index a6b50dbc8d..ccedd2bcd2 100644
+--- a/hw/usb/dev-hub.c
++++ b/hw/usb/dev-hub.c
+@@ -479,6 +479,7 @@ static void usb_hub_handle_control(USBDevice *dev,
USBPacket *p,
+ usb_hub_port_clear(port, PORT_STAT_SUSPEND);
+ port->wPortChange = 0;
+ }
++ break;
+ default:
+ goto fail;
+ }
+diff --git a/include/hw/misc/mos6522.h b/include/hw/misc/mos6522.h
+index 0bc22a8395..1183d404e9 100644
+--- a/include/hw/misc/mos6522.h
++++ b/include/hw/misc/mos6522.h
+@@ -155,7 +155,7 @@ struct MOS6522State {
+ OBJECT_DECLARE_TYPE(MOS6522State, MOS6522DeviceClass, MOS6522)
+
+ struct MOS6522DeviceClass {
+- DeviceClass parent_class;
++ SysBusDeviceClass parent_class;
+
+ DeviceReset parent_reset;
+ void (*portB_write)(MOS6522State *dev);
+diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
+index 6ea4b64fe7..60bc32da32 100644
+--- a/include/hw/scsi/scsi.h
++++ b/include/hw/scsi/scsi.h
+@@ -108,6 +108,7 @@ int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int
msf, int session_num);
+ /* scsi-bus.c */
+ struct SCSIReqOps {
+ size_t size;
++ void (*init_req)(SCSIRequest *req);
+ void (*free_req)(SCSIRequest *req);
+ int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
+ void (*read_data)(SCSIRequest *req);
+diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
+index 3b4adcdc10..269c925cb1 100644
+--- a/include/sysemu/kvm_int.h
++++ b/include/sysemu/kvm_int.h
+@@ -34,6 +34,7 @@ typedef struct KVMSlot
+ typedef struct KVMMemoryListener {
+ MemoryListener listener;
+ KVMSlot *slots;
++ unsigned int nr_slots_allocated;
+ int as_id;
+ } KVMMemoryListener;
+
+diff --git a/linux-user/elfload.c b/linux-user/elfload.c
+index 87895847ec..97528a13ed 100644
+--- a/linux-user/elfload.c
++++ b/linux-user/elfload.c
+@@ -2899,11 +2899,11 @@ static bool parse_elf_properties(int image_fd,
+ }
+
+ /*
+- * The contents of a valid PT_GNU_PROPERTY is a sequence
+- * of uint32_t -- swap them all now.
++ * The contents of a valid PT_GNU_PROPERTY is a sequence of uint32_t.
++ * Swap most of them now, beyond the header and namesz.
+ */
+ #ifdef BSWAP_NEEDED
+- for (int i = 0; i < n / 4; i++) {
++ for (int i = 4; i < n / 4; i++) {
+ bswap32s(note.data + i);
+ }
+ #endif
+@@ -2913,15 +2913,15 @@ static bool parse_elf_properties(int image_fd,
+ * immediately follows nhdr and is thus at the 4th word. Further, all
+ * of the inputs to the kernel's round_up are multiples of 4.
+ */
+- if (note.nhdr.n_type != NT_GNU_PROPERTY_TYPE_0 ||
+- note.nhdr.n_namesz != NOTE_NAME_SZ ||
++ if (tswap32(note.nhdr.n_type) != NT_GNU_PROPERTY_TYPE_0 ||
++ tswap32(note.nhdr.n_namesz) != NOTE_NAME_SZ ||
+ note.data[3] != GNU0_MAGIC) {
+ error_setg(errp, "Invalid note in PT_GNU_PROPERTY");
+ return false;
+ }
+ off = sizeof(note.nhdr) + NOTE_NAME_SZ;
+
+- datasz = note.nhdr.n_descsz + off;
++ datasz = tswap32(note.nhdr.n_descsz) + off;
+ if (datasz > n) {
+ error_setg(errp, "Invalid note size in PT_GNU_PROPERTY");
+ return false;
+diff --git a/linux-user/flatload.c b/linux-user/flatload.c
+index e99570ca18..7f243500b3 100644
+--- a/linux-user/flatload.c
++++ b/linux-user/flatload.c
+@@ -747,7 +747,10 @@ int load_flt_binary(struct linux_binprm *bprm, struct
image_info *info)
+ stack_len += (bprm->envc + 1) * 4; /* the envp array */
+
+
++ mmap_lock();
+ res = load_flat_file(bprm, libinfo, 0, &stack_len);
++ mmap_unlock();
++
+ if (is_error(res)) {
+ return res;
+ }
+diff --git a/linux-user/ppc/signal.c b/linux-user/ppc/signal.c
+index 07729c1653..6968c817dc 100644
+--- a/linux-user/ppc/signal.c
++++ b/linux-user/ppc/signal.c
+@@ -617,7 +617,7 @@ static int do_setcontext(struct target_ucontext *ucp,
CPUPPCState *env, int sig)
+ if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
+ return 1;
+
+- target_to_host_sigset_internal(&blocked, &set);
++ target_to_host_sigset(&blocked, &set);
+ set_sigmask(&blocked);
+ restore_user_regs(env, mcp, sig);
+
+diff --git a/linux-user/syscall.c b/linux-user/syscall.c
+index 53c46ae951..236076e647 100644
+--- a/linux-user/syscall.c
++++ b/linux-user/syscall.c
+@@ -7233,12 +7233,24 @@ static inline int tswapid(int id)
+ #else
+ #define __NR_sys_setgroups __NR_setgroups
+ #endif
++#ifdef __NR_sys_setreuid32
++#define __NR_sys_setreuid __NR_setreuid32
++#else
++#define __NR_sys_setreuid __NR_setreuid
++#endif
++#ifdef __NR_sys_setregid32
++#define __NR_sys_setregid __NR_setregid32
++#else
++#define __NR_sys_setregid __NR_setregid
++#endif
+
+ _syscall1(int, sys_setuid, uid_t, uid)
+ _syscall1(int, sys_setgid, gid_t, gid)
+ _syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
+ _syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
+ _syscall2(int, sys_setgroups, int, size, gid_t *, grouplist)
++_syscall2(int, sys_setreuid, uid_t, ruid, uid_t, euid);
++_syscall2(int, sys_setregid, gid_t, rgid, gid_t, egid);
+
+ void syscall_init(void)
+ {
+@@ -11399,9 +11411,9 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int
num, abi_long arg1,
+ return get_errno(high2lowgid(getegid()));
+ #endif
+ case TARGET_NR_setreuid:
+- return get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
++ return get_errno(sys_setreuid(low2highuid(arg1), low2highuid(arg2)));
+ case TARGET_NR_setregid:
+- return get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
++ return get_errno(sys_setregid(low2highgid(arg1), low2highgid(arg2)));
+ case TARGET_NR_getgroups:
+ {
+ int gidsetsize = arg1;
+@@ -11731,11 +11743,11 @@ static abi_long do_syscall1(CPUArchState *cpu_env,
int num, abi_long arg1,
+ #endif
+ #ifdef TARGET_NR_setreuid32
+ case TARGET_NR_setreuid32:
+- return get_errno(setreuid(arg1, arg2));
++ return get_errno(sys_setreuid(arg1, arg2));
+ #endif
+ #ifdef TARGET_NR_setregid32
+ case TARGET_NR_setregid32:
+- return get_errno(setregid(arg1, arg2));
++ return get_errno(sys_setregid(arg1, arg2));
+ #endif
+ #ifdef TARGET_NR_getgroups32
+ case TARGET_NR_getgroups32:
+diff --git a/net/colo-compare.c b/net/colo-compare.c
+index 787c740f14..ccc5206084 100644
+--- a/net/colo-compare.c
++++ b/net/colo-compare.c
+@@ -413,8 +413,7 @@ static void colo_compare_tcp(CompareState *s, Connection
*conn)
+ * can ensure that the packet's payload is acknowledged by
+ * primary and secondary.
+ */
+- uint32_t min_ack = conn->pack - conn->sack > 0 ?
+- conn->sack : conn->pack;
++ uint32_t min_ack = MIN(conn->pack, conn->sack);
+
+ pri:
+ if (g_queue_is_empty(&conn->primary_list)) {
+diff --git a/net/tap-win32.c b/net/tap-win32.c
+index a49c28ba5d..16c21d971a 100644
+--- a/net/tap-win32.c
++++ b/net/tap-win32.c
+@@ -214,7 +214,7 @@ static int is_tap_win32_dev(const char *guid)
+
+ for (;;) {
+ char enum_name[256];
+- char unit_string[256];
++ g_autofree char *unit_string = NULL;
+ HKEY unit_key;
+ char component_id_string[] = "ComponentId";
+ char component_id[256];
+@@ -239,8 +239,7 @@ static int is_tap_win32_dev(const char *guid)
+ return FALSE;
+ }
+
+- snprintf (unit_string, sizeof(unit_string), "%s\\%s",
+- ADAPTER_KEY, enum_name);
++ unit_string = g_strdup_printf("%s\\%s", ADAPTER_KEY, enum_name);
+
+ status = RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+@@ -315,7 +314,7 @@ static int get_device_guid(
+ while (!stop)
+ {
+ char enum_name[256];
+- char connection_string[256];
++ g_autofree char *connection_string = NULL;
+ HKEY connection_key;
+ char name_data[256];
+ DWORD name_type;
+@@ -338,9 +337,7 @@ static int get_device_guid(
+ return -1;
+ }
+
+- snprintf(connection_string,
+- sizeof(connection_string),
+- "%s\\%s\\Connection",
++ connection_string = g_strdup_printf("%s\\%s\\Connection",
+ NETWORK_CONNECTIONS_KEY, enum_name);
+
+ status = RegOpenKeyEx(
+@@ -595,7 +592,7 @@ static void tap_win32_free_buffer(tap_win32_overlapped_t
*overlapped,
+ static int tap_win32_open(tap_win32_overlapped_t **phandle,
+ const char *preferred_name)
+ {
+- char device_path[256];
++ g_autofree char *device_path = NULL;
+ char device_guid[0x100];
+ int rc;
+ HANDLE handle;
+@@ -617,7 +614,7 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle,
+ if (rc)
+ return -1;
+
+- snprintf (device_path, sizeof(device_path), "%s%s%s",
++ device_path = g_strdup_printf("%s%s%s",
+ USERMODEDEVICEDIR,
+ device_guid,
+ TAPSUFFIX);
+diff --git a/scripts/oss-fuzz/build.sh b/scripts/oss-fuzz/build.sh
+index 3bda0d72c7..6c2a546994 100755
+--- a/scripts/oss-fuzz/build.sh
++++ b/scripts/oss-fuzz/build.sh
+@@ -92,6 +92,7 @@ make install DESTDIR=$DEST_DIR/qemu-bundle
+ rm -rf $DEST_DIR/qemu-bundle/opt/qemu-oss-fuzz/bin
+ rm -rf $DEST_DIR/qemu-bundle/opt/qemu-oss-fuzz/libexec
+
++export ASAN_OPTIONS=detect_leaks=0
+ targets=$(./qemu-fuzz-i386 | grep generic-fuzz | awk '$1 ~ /\*/ {print $2}')
+ base_copy="$DEST_DIR/qemu-fuzz-i386-target-$(echo "$targets" | head -n 1)"
+
+diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
+index cd46e7597c..e31aaedcbb 100644
+--- a/scripts/tracetool/__init__.py
++++ b/scripts/tracetool/__init__.py
+@@ -223,12 +223,12 @@ class Event(object):
+
+ """
+
+- _CRE = re.compile("((?P<props>[\w\s]+)\s+)?"
+- "(?P<name>\w+)"
+- "\((?P<args>[^)]*)\)"
+- "\s*"
+- "(?:(?:(?P<fmt_trans>\".+),)?\s*(?P<fmt>\".+))?"
+- "\s*")
++ _CRE = re.compile(r"((?P<props>[\w\s]+)\s+)?"
++ r"(?P<name>\w+)"
++ r"\((?P<args>[^)]*)\)"
++ r"\s*"
++ r"(?:(?:(?P<fmt_trans>\".+),)?\s*(?P<fmt>\".+))?"
++ r"\s*")
+
+ _VALID_PROPS = set(["disable", "vcpu"])
+
+@@ -339,7 +339,7 @@ def __repr__(self):
+ fmt)
+ # Star matching on PRI is dangerous as one might have multiple
+ # arguments with that format, hence the non-greedy version of it.
+- _FMT = re.compile("(%[\d\.]*\w+|%.*?PRI\S+)")
++ _FMT = re.compile(r"(%[\d\.]*\w+|%.*?PRI\S+)")
+
+ def formats(self):
+ """List conversion specifiers in the argument print format string."""
+diff --git a/scripts/tracetool/format/log_stap.py
b/scripts/tracetool/format/log_stap.py
+index 0b6549d534..b49afababd 100644
+--- a/scripts/tracetool/format/log_stap.py
++++ b/scripts/tracetool/format/log_stap.py
+@@ -83,7 +83,7 @@ def c_fmt_to_stap(fmt):
+ # and "%ll" is not valid at all. Similarly the size_t
+ # based "%z" size qualifier is not valid. We just
+ # strip all size qualifiers for sanity.
+- fmt = re.sub("%(\d*)(l+|z)(x|u|d)", "%\\1\\3", "".join(bits))
++ fmt = re.sub(r"%(\d*)(l+|z)(x|u|d)", r"%\1\3", "".join(bits))
+ return fmt
+
+ def generate(events, backend, group):
+diff --git a/softmmu/physmem.c b/softmmu/physmem.c
+index 5b176581f6..b96534ea16 100644
+--- a/softmmu/physmem.c
++++ b/softmmu/physmem.c
+@@ -3245,7 +3245,7 @@ void *address_space_map(AddressSpace *as,
+ memory_region_ref(mr);
+ bounce.mr = mr;
+ if (!is_write) {
+- flatview_read(fv, addr, MEMTXATTRS_UNSPECIFIED,
++ flatview_read(fv, addr, attrs,
+ bounce.buffer, l);
+ }
+
+diff --git a/target/arm/internals.h b/target/arm/internals.h
+index 3c7ff51c99..bdd89ae21e 100644
+--- a/target/arm/internals.h
++++ b/target/arm/internals.h
+@@ -723,6 +723,7 @@ static inline uint32_t regime_el(CPUARMState *env,
ARMMMUIdx mmu_idx)
+ static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
+ {
+ switch (mmu_idx) {
++ case ARMMMUIdx_E10_0:
+ case ARMMMUIdx_E20_0:
+ case ARMMMUIdx_Stage1_E0:
+ case ARMMMUIdx_MUser:
+@@ -732,10 +733,6 @@ static inline bool regime_is_user(CPUARMState *env,
ARMMMUIdx mmu_idx)
+ return true;
+ default:
+ return false;
+- case ARMMMUIdx_E10_0:
+- case ARMMMUIdx_E10_1:
+- case ARMMMUIdx_E10_1_PAN:
+- g_assert_not_reached();
+ }
+ }
+
+diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
+index 45a93755fe..989257416e 100644
+--- a/target/arm/sve_helper.c
++++ b/target/arm/sve_helper.c
+@@ -6309,9 +6309,6 @@ void sve_stN_r(CPUARMState *env, uint64_t *vg,
target_ulong addr,
+
+ flags = info.page[0].flags | info.page[1].flags;
+ if (unlikely(flags != 0)) {
+-#ifdef CONFIG_USER_ONLY
+- g_assert_not_reached();
+-#else
+ /*
+ * At least one page includes MMIO.
+ * Any bus operation can fail with cpu_transaction_failed,
+@@ -6342,7 +6339,6 @@ void sve_stN_r(CPUARMState *env, uint64_t *vg,
target_ulong addr,
+ } while (reg_off & 63);
+ } while (reg_off <= reg_last);
+ return;
+-#endif
+ }
+
+ mem_off = info.mem_off_first[0];
+diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
+index 859366e264..77678aca78 100644
+--- a/target/arm/vec_helper.c
++++ b/target/arm/vec_helper.c
+@@ -691,6 +691,13 @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *va,
uint32_t desc) \
+ { \
+ intptr_t i = 0, opr_sz = simd_oprsz(desc); \
+ intptr_t opr_sz_n = opr_sz / sizeof(TYPED); \
++ /* \
++ * Special case: opr_sz == 8 from AA64/AA32 advsimd means the \
++ * first iteration might not be a full 16 byte segment. But \
++ * for vector lengths beyond that this must be SVE and we know \
++ * opr_sz is a multiple of 16, so we need not clamp segend \
++ * to opr_sz_n when we advance it at the end of the loop. \
++ */ \
+ intptr_t segend = MIN(16 / sizeof(TYPED), opr_sz_n); \
+ intptr_t index = simd_data(desc); \
+ TYPED *d = vd, *a = va; \
+@@ -708,7 +715,7 @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *va,
uint32_t desc) \
+ n[i * 4 + 2] * m2 + \
+ n[i * 4 + 3] * m3); \
+ } while (++i < segend); \
+- segend = i + 4; \
++ segend = i + (16 / sizeof(TYPED)); \
+ } while (i < opr_sz_n); \
+ clear_tail(d, opr_sz, simd_maxsz(desc)); \
+ }
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index 326649ca99..59c39fe527 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -336,6 +336,7 @@ typedef enum X86Seg {
+ #define PG_MODE_PKE (1 << 17)
+ #define PG_MODE_PKS (1 << 18)
+ #define PG_MODE_SMEP (1 << 19)
++#define PG_MODE_PG (1 << 20)
+
+ #define MCG_CTL_P (1ULL<<8) /* MCG_CAP register available */
+ #define MCG_SER_P (1ULL<<24) /* MCA recovery/new status bits */
+diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
+index 539189b4d1..1fa334a743 100644
+--- a/target/i386/tcg/seg_helper.c
++++ b/target/i386/tcg/seg_helper.c
+@@ -30,7 +30,7 @@
+
+ int get_pg_mode(CPUX86State *env)
+ {
+- int pg_mode = 0;
++ int pg_mode = PG_MODE_PG;
+ if (!(env->cr[0] & CR0_PG_MASK)) {
+ return 0;
+ }
+diff --git a/target/i386/tcg/sysemu/excp_helper.c
b/target/i386/tcg/sysemu/excp_helper.c
+index 5f13252d68..9e9e02e1ad 100644
+--- a/target/i386/tcg/sysemu/excp_helper.c
++++ b/target/i386/tcg/sysemu/excp_helper.c
+@@ -146,6 +146,8 @@ static bool mmu_translate(CPUX86State *env, const
TranslateParams *in,
+ hwaddr pte_addr, paddr;
+ uint32_t pkr;
+ int page_size;
++ int error_code;
++ int prot;
+
+ restart_all:
+ rsvd_mask = ~MAKE_64BIT_MASK(0, env_archcpu(env)->phys_bits);
+@@ -294,7 +296,7 @@ static bool mmu_translate(CPUX86State *env, const
TranslateParams *in,
+ /* combine pde and pte nx, user and rw protections */
+ ptep &= pte ^ PG_NX_MASK;
+ page_size = 4096;
+- } else {
++ } else if (pg_mode & PG_MODE_PG) {
+ /*
+ * Page table level 2
+ */
+@@ -339,6 +341,15 @@ static bool mmu_translate(CPUX86State *env, const
TranslateParams *in,
+ ptep &= pte | PG_NX_MASK;
+ page_size = 4096;
+ rsvd_mask = 0;
++ } else {
++ /*
++ * No paging (real mode), let's tentatively resolve the address as 1:1
++ * here, but conditionally still perform an NPT walk on it later.
++ */
++ page_size = 0x40000000;
++ paddr = in->addr;
++ prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
++ goto stage2;
+ }
+
+ do_check_protect:
+@@ -354,7 +365,7 @@ do_check_protect_pse36:
+ goto do_fault_protect;
+ }
+
+- int prot = 0;
++ prot = 0;
+ if (!is_mmu_index_smap(in->mmu_idx) || !(ptep & PG_USER_MASK)) {
+ prot |= PAGE_READ;
+ if ((ptep & PG_RW_MASK) || !(is_user || (pg_mode & PG_MODE_WP))) {
+@@ -416,6 +427,7 @@ do_check_protect_pse36:
+
+ /* merge offset within page */
+ paddr = (pte & PG_ADDRESS_MASK & ~(page_size - 1)) | (addr & (page_size -
1));
++ stage2:
+
+ /*
+ * Note that NPT is walked (for both paging structures and final guest
+@@ -464,7 +476,6 @@ do_check_protect_pse36:
+ out->page_size = page_size;
+ return true;
+
+- int error_code;
+ do_fault_rsvd:
+ error_code = PG_ERROR_RSVD_MASK;
+ goto do_fault_cont;
+@@ -558,7 +569,7 @@ static bool get_physical_address(CPUX86State *env, vaddr
addr,
+ addr = (uint32_t)addr;
+ }
+
+- if (likely(env->cr[0] & CR0_PG_MASK)) {
++ if (likely(env->cr[0] & CR0_PG_MASK || use_stage2)) {
+ in.cr3 = env->cr[3];
+ in.mmu_idx = mmu_idx;
+ in.ptw_idx = use_stage2 ? MMU_NESTED_IDX : MMU_PHYS_IDX;
+diff --git a/target/ppc/translate.c b/target/ppc/translate.c
+index 90f749a728..5ab6c5c861 100644
+--- a/target/ppc/translate.c
++++ b/target/ppc/translate.c
+@@ -7455,8 +7455,6 @@ static bool decode_legacy(PowerPCCPU *cpu, DisasContext
*ctx, uint32_t insn)
+ opc_handler_t **table, *handler;
+ uint32_t inval;
+
+- ctx->opcode = insn;
+-
+ LOG_DISAS("translate opcode %08x (%02x %02x %02x %02x) (%s)\n",
+ insn, opc1(insn), opc2(insn), opc3(insn), opc4(insn),
+ ctx->le_mode ? "little" : "big");
+@@ -7587,6 +7585,7 @@ static void ppc_tr_translate_insn(DisasContextBase
*dcbase, CPUState *cs)
+ ctx->base.pc_next = pc += 4;
+
+ if (!is_prefix_insn(ctx, insn)) {
++ ctx->opcode = insn;
+ ok = (decode_insn32(ctx, insn) ||
+ decode_legacy(cpu, ctx, insn));
+ } else if ((pc & 63) == 0) {
+diff --git a/target/ppc/translate/vsx-impl.c.inc
b/target/ppc/translate/vsx-impl.c.inc
+index de1709809d..9e10291010 100644
+--- a/target/ppc/translate/vsx-impl.c.inc
++++ b/target/ppc/translate/vsx-impl.c.inc
+@@ -2542,7 +2542,7 @@ static bool do_lstxv_PLS_D(DisasContext *ctx, arg_PLS_D
*a,
+
+ static bool do_lstxv_X(DisasContext *ctx, arg_X *a, bool store, bool paired)
+ {
+- if (paired || a->rt >= 32) {
++ if (paired || a->rt < 32) {
+ REQUIRE_VSX(ctx);
+ } else {
+ REQUIRE_VECTOR(ctx);
+diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
+index d14e95c9dc..0808cbdb19 100644
+--- a/target/riscv/cpu.c
++++ b/target/riscv/cpu.c
+@@ -581,6 +581,7 @@ static void riscv_cpu_reset(DeviceState *dev)
+ cs->exception_index = RISCV_EXCP_NONE;
+ env->load_res = -1;
+ set_default_nan_mode(1, &env->fp_status);
++ env->vill = true;
+
+ #ifndef CONFIG_USER_ONLY
+ if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
+diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
+index 3a9e25053f..039f25dc6e 100644
+--- a/target/riscv/cpu.h
++++ b/target/riscv/cpu.h
+@@ -675,8 +675,11 @@ static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env)
+ #ifdef CONFIG_USER_ONLY
+ return env->misa_mxl;
+ #else
+- return get_field(env->mstatus, MSTATUS64_SXL);
++ if (env->misa_mxl != MXL_RV32) {
++ return get_field(env->mstatus, MSTATUS64_SXL);
++ }
+ #endif
++ return MXL_RV32;
+ }
+ #endif
+
+diff --git a/target/riscv/csr.c b/target/riscv/csr.c
+index 15dba5f653..7a3bc7bea6 100644
+--- a/target/riscv/csr.c
++++ b/target/riscv/csr.c
+@@ -494,7 +494,7 @@ static RISCVException write_vxrm(CPURISCVState *env, int
csrno,
+ static RISCVException read_vxsat(CPURISCVState *env, int csrno,
+ target_ulong *val)
+ {
+- *val = env->vxsat;
++ *val = env->vxsat & BIT(0);
+ return RISCV_EXCP_NONE;
+ }
+
+@@ -504,7 +504,7 @@ static RISCVException write_vxsat(CPURISCVState *env, int
csrno,
+ #if !defined(CONFIG_USER_ONLY)
+ env->mstatus |= MSTATUS_VS;
+ #endif
+- env->vxsat = val;
++ env->vxsat = val & BIT(0);
+ return RISCV_EXCP_NONE;
+ }
+
+diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
+index 0020b9a95d..a6ac61c724 100644
+--- a/target/riscv/vector_helper.c
++++ b/target/riscv/vector_helper.c
+@@ -5273,7 +5273,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void
*vs2, \
+ } \
+ env->vstart = 0; \
+ /* set tail elements to 1s */ \
+- vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz); \
++ vext_set_elems_1s(vd, vta, num * esz, total_elems * esz); \
+ }
+
+ /* Compress into vd elements of vs2 where vs1 is enabled */
+diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
+index 079a761b04..63bcfcb1eb 100644
+--- a/tcg/tcg-op-gvec.c
++++ b/tcg/tcg-op-gvec.c
+@@ -88,7 +88,20 @@ uint32_t simd_desc(uint32_t oprsz, uint32_t maxsz, int32_t
data)
+ uint32_t desc = 0;
+
+ check_size_align(oprsz, maxsz, 0);
+- tcg_debug_assert(data == sextract32(data, 0, SIMD_DATA_BITS));
++
++ /*
++ * We want to check that 'data' will fit into SIMD_DATA_BITS.
++ * However, some callers want to treat the data as a signed
++ * value (which they can later get back with simd_data())
++ * and some want to treat it as an unsigned value.
++ * So here we assert only that the data will fit into the
++ * field in at least one way. This means that some invalid
++ * values from the caller will not be detected, e.g. if the
++ * caller wants to handle the value as a signed integer but
++ * incorrectly passes us 1 << (SIMD_DATA_BITS - 1).
++ */
++ tcg_debug_assert(data == sextract32(data, 0, SIMD_DATA_BITS) ||
++ data == extract32(data, 0, SIMD_DATA_BITS));
+
+ oprsz = (oprsz / 8) - 1;
+ maxsz = (maxsz / 8) - 1;
+diff --git a/tcg/tcg.c b/tcg/tcg.c
+index 436fcf6ebd..e7aa02c447 100644
+--- a/tcg/tcg.c
++++ b/tcg/tcg.c
+@@ -716,7 +716,6 @@ TranslationBlock *tcg_tb_alloc(TCGContext *s)
+ goto retry;
+ }
+ qatomic_set(&s->code_gen_ptr, next);
+- s->data_gen_ptr = NULL;
+ return tb;
+ }
+
+@@ -4249,6 +4248,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb,
target_ulong pc_start)
+ */
+ s->code_buf = tcg_splitwx_to_rw(tb->tc.ptr);
+ s->code_ptr = s->code_buf;
++ s->data_gen_ptr = NULL;
+
+ #ifdef TCG_TARGET_NEED_LDST_LABELS
+ QSIMPLEQ_INIT(&s->ldst_labels);
+diff --git a/tests/qtest/tpm-tests.c b/tests/qtest/tpm-tests.c
+index 25073d1f9e..7ea9038f60 100644
+--- a/tests/qtest/tpm-tests.c
++++ b/tests/qtest/tpm-tests.c
+@@ -114,7 +114,7 @@ void tpm_test_swtpm_migration_test(const char
*src_tpm_path,
+ sizeof(tpm_pcrread_resp));
+
+ tpm_util_migrate(src_qemu, uri);
+- tpm_util_wait_for_migration_complete(src_qemu);
++ tpm_util_wait_for_migration_complete(dst_qemu);
+
+ tpm_util_pcrread(dst_qemu, tx, tpm_pcrread_resp,
+ sizeof(tpm_pcrread_resp));
diff -Nru qemu-7.2+dfsg/debian/qemu-user-static.lintian-overrides
qemu-7.2+dfsg/debian/qemu-user-static.lintian-overrides
--- qemu-7.2+dfsg/debian/qemu-user-static.lintian-overrides 2024-11-01
16:50:46.000000000 +0300
+++ qemu-7.2+dfsg/debian/qemu-user-static.lintian-overrides 2024-11-25
20:37:50.000000000 +0300
@@ -1,2 +1,4 @@
qemu-user-static: spelling-error-in-binary addd add *usr/bin/qemu-*-static*
qemu-user-static: spelling-error-in-binary nott not *usr/bin/qemu-*-static*
+# these are static-pic executables, not shared executables:
+qemu-user-static: shared-library-lacks-prerequisites *usr/bin/qemu-*-static*
diff -Nru qemu-7.2+dfsg/debian/rules qemu-7.2+dfsg/debian/rules
--- qemu-7.2+dfsg/debian/rules 2024-11-01 16:50:46.000000000 +0300
+++ qemu-7.2+dfsg/debian/rules 2024-11-25 20:37:50.000000000 +0300
@@ -353,17 +353,15 @@
configure-user-static: b/user-static/configured
b/user-static/configured: configure
# do not use debian/configure-opts here, all optional stuff will be enabled
-# automatically, dependencies are already verified in the main build
-# by default this would detect linker option --static-pie, but that
-# breaks some use cases of qemu-static builds (LP: #1908331), therefore
-# add --disable-pie to get "real static" builds.
-# With gcc-12, compiler is unable to build static qemu-aarch64 anymore with no
extra options,
-# see https://sourceware.org/bugzilla/show_bug.cgi?id=29514 , so we add
-no-pie there.
+# See LP:#1908331 for --static-pie (the default in qemu) and #1053101
+# See https://sourceware.org/bugzilla/show_bug.cgi?id=29514
+# use --disable-pie on i386 for now due to #1056739
rm -rf b/user-static; mkdir b/user-static
cd b/user-static && \
../../configure ${common_configure_opts} \
- --extra-cflags="${extra-cflags}$(if $(filter
${DEB_HOST_ARCH},arm64), -fno-pie -no-pie,)" \
- --static --disable-pie --disable-system --disable-xen \
+ --static \
+ $(if $(filter i386,${DEB_HOST_ARCH}),--disable-pie) \
+ --disable-system --disable-xen \
--target-list="$(addsuffix -linux-user,${user_targets})"
touch $@
build-user-static: b/user-static/built
--- End Message ---