Version in base suite: 7.2+dfsg-7+deb12u7 Version in overlay suite: 7.2+dfsg-7+deb12u8 Base version: qemu_7.2+dfsg-7+deb12u8 Target version: qemu_7.2+dfsg-7+deb12u9 Base file: /srv/ftp-master.debian.org/ftp/pool/main/q/qemu/qemu_7.2+dfsg-7+deb12u8.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/q/qemu/qemu_7.2+dfsg-7+deb12u9.dsc changelog | 58 + patches/series | 1 patches/v7.2.15.diff | 1245 +++++++++++++++++++++++++++++++++++++ qemu-user-static.lintian-overrides | 2 rules | 14 5 files changed, 1312 insertions(+), 8 deletions(-) diff -Nru qemu-7.2+dfsg/debian/changelog qemu-7.2+dfsg/debian/changelog --- qemu-7.2+dfsg/debian/changelog 2024-11-01 13:50:46.000000000 +0000 +++ qemu-7.2+dfsg/debian/changelog 2024-11-25 17:37:50.000000000 +0000 @@ -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 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 13:50:46.000000000 +0000 +++ qemu-7.2+dfsg/debian/patches/series 2024-11-25 17:37:50.000000000 +0000 @@ -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 00:00:00.000000000 +0000 +++ qemu-7.2+dfsg/debian/patches/v7.2.15.diff 2024-11-25 17:37:50.000000000 +0000 @@ -0,0 +1,1245 @@ +Subject: v7.2.15 +Date: Thu Nov 21 00:11:28 2024 +0300 +From: Michael Tokarev +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[\w\s]+)\s+)?" +- "(?P\w+)" +- "\((?P[^)]*)\)" +- "\s*" +- "(?:(?:(?P\".+),)?\s*(?P\".+))?" +- "\s*") ++ _CRE = re.compile(r"((?P[\w\s]+)\s+)?" ++ r"(?P\w+)" ++ r"\((?P[^)]*)\)" ++ r"\s*" ++ r"(?:(?:(?P\".+),)?\s*(?P\".+))?" ++ 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 13:50:46.000000000 +0000 +++ qemu-7.2+dfsg/debian/qemu-user-static.lintian-overrides 2024-11-25 17:37:50.000000000 +0000 @@ -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 13:50:46.000000000 +0000 +++ qemu-7.2+dfsg/debian/rules 2024-11-25 17:37:50.000000000 +0000 @@ -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