summaryrefslogtreecommitdiffstats
path: root/debian/patches/v7.2.15.diff
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/v7.2.15.diff')
-rw-r--r--debian/patches/v7.2.15.diff1245
1 files changed, 1245 insertions, 0 deletions
diff --git a/debian/patches/v7.2.15.diff b/debian/patches/v7.2.15.diff
new file mode 100644
index 00000000..bdebfb92
--- /dev/null
+++ b/debian/patches/v7.2.15.diff
@@ -0,0 +1,1245 @@
+Subject: v7.2.15
+Date: Thu Nov 21 00:11:28 2024 +0300
+From: Michael Tokarev <mjt@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));