--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: bookworm-pu: package qemu/1:7.2+dfsg-7+deb12u14
- From: Michael Tokarev <mjt@tls.msk.ru>
- Date: Thu, 10 Jul 2025 09:45:36 +0300
- Message-id: <175212993696.1700724.17435486055383239699.reportbug@localhost>
Package: release.debian.org
Severity: normal
Tags: bookworm
X-Debbugs-Cc: qemu@packages.debian.org, pkg-qemu-devel@lists.alioth.debian.org
Control: affects -1 + src:qemu
User: release.debian.org@packages.debian.org
Usertags: pu
[ Reason ]
There's a new upstrem stable/bugfix release of qemu since
the last upload, fixing a set of various bugs found to date.
It would be nice to have it all in debian too.
[ Tests ]
As usual, this release has passed both the automatic tests
(mostly upstream testsuite) and various manual tests I usually
perform for qemu. This version is used on production locally
for quite some time now, with no issues found.
[ Risks ]
Since the number of fixes is rather small this time, and all
the fixes are focused, there's little risk of breaking something.
However there's always a risk, - if there are any new issues,
we'll deal with them promptly.
[ 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 ]
Each upstream change is generated by a command like:
git diff --patch-with-stat v7.2.17..v7.2.18
and can be verified against the upstream git repository
(mirrored on salsa).
A commit log with explanation of each change is available at
https://salsa.debian.org/qemu-team/qemu/-/commits/stable-7.2/
(between v7.2.17 and v7.2.18 tags).
A complete debdiff (with d/changelog at the top) is below.
[ Other info ]
Historically, qemu version number in debian did not include
the 3rd, minor, part, having only 2-component version like
7.2. This is why the upstream changes are applied as patches.
I switched to using complete 3-component upstream version after
bookworm release.
Thanks,
/mjt
diff -Nru qemu-7.2+dfsg/debian/changelog qemu-7.2+dfsg/debian/changelog
--- qemu-7.2+dfsg/debian/changelog 2025-05-03 12:06:15.000000000 +0300
+++ qemu-7.2+dfsg/debian/changelog 2025-07-10 09:25:36.000000000 +0300
@@ -1,3 +1,32 @@
+qemu (1:7.2+dfsg-7+deb12u14) bookworm; urgency=medium
+
+ * v7.2.18:
+ - Update version for 7.2.18 release
+ - qapi/misc-target: Fix the doc to distinguish
+ query-sgx and query-sgx-capabilities
+ - common-user/host/riscv: use tail pseudoinstruction for calling tail
+ - virtio: Call set_features during reset
+ - 9pfs: fix FD leak and reduce latency of v9fs_reclaim_fd()
+ - 9pfs: fix concurrent v9fs_reclaim_fd() calls
+ - hw/i2c/imx: Always set interrupt status bit if interrupt condition occurs
+ - hw/gpio/imx_gpio: Fix interpretation of GDIR polarity
+ - target/arm: Don't assert() for ISB/SB inside IT block
+ - target/avr: Improve decode of LDS, STS
+ - target/i386/hvf: fix lflags_to_rflags
+ - plugins/loader: fix deadlock when resetting/uninstalling a plugin
+ - smbios: Fix buffer overrun when using path= option
+ - virtio-net: Fix num_buffers for version 1
+ - migration: fix SEEK_CUR offset calculation in qio_channel_block_seek
+ - target/mips: Simplify and fix update_pagemask
+ - target/mips: Require even maskbits in update_pagemask
+ - target/mips: Revert TARGET_PAGE_BITS_VARY
+ - target/avr: Fix buffer read in avr_print_insn
+ - hw/pci-host/designware: Fix ATU_UPPER_TARGET register access
+ - hw/rtc/goldfish: keep time offset when resetting
+ - Makefile: "make dist" generates a .xz, not .bz2
+
+ -- Michael Tokarev <mjt@tls.msk.ru> Thu, 10 Jul 2025 09:25:36 +0300
+
qemu (1:7.2+dfsg-7+deb12u13) bookworm; urgency=medium
* v7.2.17:
diff -Nru qemu-7.2+dfsg/debian/patches/series qemu-7.2+dfsg/debian/patches/series
--- qemu-7.2+dfsg/debian/patches/series 2025-05-03 12:05:44.000000000 +0300
+++ qemu-7.2+dfsg/debian/patches/series 2025-07-10 09:22:23.000000000 +0300
@@ -15,6 +15,7 @@
v7.2.15.diff
v7.2.16.diff
v7.2.17.diff
+v7.2.18.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.18.diff qemu-7.2+dfsg/debian/patches/v7.2.18.diff
--- qemu-7.2+dfsg/debian/patches/v7.2.18.diff 1970-01-01 03:00:00.000000000 +0300
+++ qemu-7.2+dfsg/debian/patches/v7.2.18.diff 2025-07-10 09:22:14.000000000 +0300
@@ -0,0 +1,590 @@
+Subject: v7.2.18
+Date: Mon May 26 10:32:24 2025 +0300
+From: Michael Tokarev <mjt@tls.msk.ru>
+Forwarded: not-needed
+
+This is a difference between upstream qemu v7.2.17
+and upstream qemu v7.2.18.
+
+ Makefile | 6 ++---
+ VERSION | 2 +-
+ common-user/host/riscv/safe-syscall.inc.S | 4 ++--
+ hw/9pfs/9p.c | 39 ++++++++++++++++++++++++-------
+ hw/9pfs/9p.h | 1 +
+ hw/gpio/imx_gpio.c | 2 +-
+ hw/i2c/imx_i2c.c | 11 ++++-----
+ hw/mips/fuloong2e.c | 1 -
+ hw/mips/loongson3_virt.c | 1 -
+ hw/net/virtio-net.c | 2 ++
+ hw/pci-host/designware.c | 2 +-
+ hw/rtc/goldfish_rtc.c | 13 +++++------
+ hw/smbios/smbios.c | 3 +++
+ hw/virtio/virtio.c | 4 +++-
+ migration/channel-block.c | 2 +-
+ plugins/loader.c | 2 +-
+ qapi/misc-target.json | 4 ++--
+ target/arm/translate.c | 3 ++-
+ target/avr/disas.c | 21 +++++++++++------
+ target/avr/insn.decode | 7 ++----
+ target/avr/translate.c | 2 --
+ target/i386/hvf/x86_flags.c | 1 +
+ target/mips/cpu-param.h | 5 ----
+ target/mips/tcg/sysemu/cp0_helper.c | 32 ++++++++-----------------
+ target/mips/tcg/sysemu/tlb_helper.c | 4 ++--
+ target/mips/tcg/tcg-internal.h | 2 +-
+ 26 files changed, 94 insertions(+), 82 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index a48103cc8a..d5aecb9418 100644
+--- a/Makefile
++++ b/Makefile
+@@ -213,10 +213,10 @@ clean: recurse-clean
+
+ VERSION = $(shell cat $(SRC_PATH)/VERSION)
+
+-dist: qemu-$(VERSION).tar.bz2
++dist: qemu-$(VERSION).tar.xz
+
+-qemu-%.tar.bz2:
+- $(SRC_PATH)/scripts/make-release "$(SRC_PATH)" "$(patsubst qemu-%.tar.bz2,%,$@)"
++qemu-%.tar.xz:
++ $(SRC_PATH)/scripts/make-release "$(SRC_PATH)" "$(patsubst qemu-%.tar.xz,%,$@)"
+
+ distclean: clean recurse-distclean
+ -$(quiet-@)test -f build.ninja && $(NINJA) $(NINJAFLAGS) -t clean -g || :
+diff --git a/VERSION b/VERSION
+index a961ff94f2..eca46b131d 100644
+--- a/VERSION
++++ b/VERSION
+@@ -1 +1 @@
+-7.2.17
++7.2.18
+diff --git a/common-user/host/riscv/safe-syscall.inc.S b/common-user/host/riscv/safe-syscall.inc.S
+index dfe83c300e..c8b81e33d0 100644
+--- a/common-user/host/riscv/safe-syscall.inc.S
++++ b/common-user/host/riscv/safe-syscall.inc.S
+@@ -69,11 +69,11 @@ safe_syscall_end:
+
+ /* code path setting errno */
+ 0: neg a0, a0
+- j safe_syscall_set_errno_tail
++ tail safe_syscall_set_errno_tail
+
+ /* code path when we didn't execute the syscall */
+ 2: li a0, QEMU_ERESTARTSYS
+- j safe_syscall_set_errno_tail
++ tail safe_syscall_set_errno_tail
+
+ .cfi_endproc
+ .size safe_syscall_base, .-safe_syscall_base
+diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
+index d950ad6de6..e7cfc77071 100644
+--- a/hw/9pfs/9p.c
++++ b/hw/9pfs/9p.c
+@@ -440,16 +440,24 @@ void coroutine_fn v9fs_reclaim_fd(V9fsPDU *pdu)
+ V9fsFidState *f;
+ GHashTableIter iter;
+ gpointer fid;
++ int err;
++ int nclosed = 0;
++
++ /* prevent multiple coroutines running this function simultaniously */
++ if (s->reclaiming) {
++ return;
++ }
++ s->reclaiming = true;
+
+ g_hash_table_iter_init(&iter, s->fids);
+
+ QSLIST_HEAD(, V9fsFidState) reclaim_list =
+ QSLIST_HEAD_INITIALIZER(reclaim_list);
+
++ /* Pick FIDs to be closed, collect them on reclaim_list. */
+ while (g_hash_table_iter_next(&iter, &fid, (gpointer *) &f)) {
+ /*
+- * Unlink fids cannot be reclaimed. Check
+- * for them and skip them. Also skip fids
++ * Unlinked fids cannot be reclaimed, skip those, and also skip fids
+ * currently being operated on.
+ */
+ if (f->ref || f->flags & FID_NON_RECLAIMABLE) {
+@@ -499,23 +507,34 @@ void coroutine_fn v9fs_reclaim_fd(V9fsPDU *pdu)
+ }
+ }
+ /*
+- * Now close the fid in reclaim list. Free them if they
+- * are already clunked.
++ * Close the picked FIDs altogether on a background I/O driver thread. Do
++ * this all at once to keep latency (i.e. amount of thread hops between main
++ * thread <-> fs driver background thread) as low as possible.
+ */
++ v9fs_co_run_in_worker({
++ QSLIST_FOREACH(f, &reclaim_list, reclaim_next) {
++ err = (f->fid_type == P9_FID_DIR) ?
++ s->ops->closedir(&s->ctx, &f->fs_reclaim) :
++ s->ops->close(&s->ctx, &f->fs_reclaim);
++ if (!err) {
++ /* total_open_fd must only be mutated on main thread */
++ nclosed++;
++ }
++ }
++ });
++ total_open_fd -= nclosed;
++ /* Free the closed FIDs. */
+ while (!QSLIST_EMPTY(&reclaim_list)) {
+ f = QSLIST_FIRST(&reclaim_list);
+ QSLIST_REMOVE(&reclaim_list, f, V9fsFidState, reclaim_next);
+- if (f->fid_type == P9_FID_FILE) {
+- v9fs_co_close(pdu, &f->fs_reclaim);
+- } else if (f->fid_type == P9_FID_DIR) {
+- v9fs_co_closedir(pdu, &f->fs_reclaim);
+- }
+ /*
+ * Now drop the fid reference, free it
+ * if clunked.
+ */
+ put_fid(pdu, f);
+ }
++
++ s->reclaiming = false;
+ }
+
+ /*
+@@ -4300,6 +4319,8 @@ int v9fs_device_realize_common(V9fsState *s, const V9fsTransport *t,
+ s->ctx.fst = &fse->fst;
+ fsdev_throttle_init(s->ctx.fst);
+
++ s->reclaiming = false;
++
+ rc = 0;
+ out:
+ if (rc) {
+diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
+index 2fce4140d1..1f0449f305 100644
+--- a/hw/9pfs/9p.h
++++ b/hw/9pfs/9p.h
+@@ -363,6 +363,7 @@ struct V9fsState {
+ uint64_t qp_ndevices; /* Amount of entries in qpd_table. */
+ uint16_t qp_affix_next;
+ uint64_t qp_fullpath_next;
++ bool reclaiming;
+ };
+
+ /* 9p2000.L open flags */
+diff --git a/hw/gpio/imx_gpio.c b/hw/gpio/imx_gpio.c
+index c7f98b7bb1..ee5eca6b89 100644
+--- a/hw/gpio/imx_gpio.c
++++ b/hw/gpio/imx_gpio.c
+@@ -79,7 +79,7 @@ static void imx_gpio_update_int(IMXGPIOState *s)
+ static void imx_gpio_set_int_line(IMXGPIOState *s, int line, IMXGPIOLevel level)
+ {
+ /* if this signal isn't configured as an input signal, nothing to do */
+- if (!extract32(s->gdir, line, 1)) {
++ if (extract32(s->gdir, line, 1)) {
+ return;
+ }
+
+diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
+index 9792583fea..64dbea41ee 100644
+--- a/hw/i2c/imx_i2c.c
++++ b/hw/i2c/imx_i2c.c
+@@ -90,13 +90,12 @@ static void imx_i2c_reset(DeviceState *dev)
+
+ static inline void imx_i2c_raise_interrupt(IMXI2CState *s)
+ {
+- /*
+- * raise an interrupt if the device is enabled and it is configured
+- * to generate some interrupts.
+- */
+- if (imx_i2c_is_enabled(s) && imx_i2c_interrupt_is_enabled(s)) {
++ if (imx_i2c_is_enabled(s)) {
+ s->i2sr |= I2SR_IIF;
+- qemu_irq_raise(s->irq);
++
++ if (imx_i2c_interrupt_is_enabled(s)) {
++ qemu_irq_raise(s->irq);
++ }
+ }
+ }
+
+diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
+index 34befa5dd5..dbd26df00b 100644
+--- a/hw/mips/fuloong2e.c
++++ b/hw/mips/fuloong2e.c
+@@ -336,7 +336,6 @@ static void mips_fuloong2e_machine_init(MachineClass *mc)
+ mc->default_cpu_type = MIPS_CPU_TYPE_NAME("Loongson-2E");
+ mc->default_ram_size = 256 * MiB;
+ mc->default_ram_id = "fuloong2e.ram";
+- mc->minimum_page_bits = 14;
+ }
+
+ DEFINE_MACHINE("fuloong2e", mips_fuloong2e_machine_init)
+diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
+index b4f6bff1b8..dc94e21438 100644
+--- a/hw/mips/loongson3_virt.c
++++ b/hw/mips/loongson3_virt.c
+@@ -616,7 +616,6 @@ static void loongson3v_machine_class_init(ObjectClass *oc, void *data)
+ mc->max_cpus = LOONGSON_MAX_VCPUS;
+ mc->default_ram_id = "loongson3.highram";
+ mc->default_ram_size = 1600 * MiB;
+- mc->minimum_page_bits = 14;
+ }
+
+ static const TypeInfo loongson3_machine_types[] = {
+diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
+index 204a80ec71..0ba1db5b14 100644
+--- a/hw/net/virtio-net.c
++++ b/hw/net/virtio-net.c
+@@ -1914,6 +1914,8 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf,
+ sg, elem->in_num,
+ offsetof(typeof(mhdr), num_buffers),
+ sizeof(mhdr.num_buffers));
++ } else {
++ mhdr.num_buffers = cpu_to_le16(1);
+ }
+
+ receive_header(n, sg, elem->in_num, buf, size);
+diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
+index c235b9daa3..2156c7f9de 100644
+--- a/hw/pci-host/designware.c
++++ b/hw/pci-host/designware.c
+@@ -362,7 +362,7 @@ static void designware_pcie_root_config_write(PCIDevice *d, uint32_t address,
+
+ case DESIGNWARE_PCIE_ATU_UPPER_TARGET:
+ viewport->target &= 0x00000000FFFFFFFFULL;
+- viewport->target |= val;
++ viewport->target |= (uint64_t)val << 32;
+ break;
+
+ case DESIGNWARE_PCIE_ATU_LIMIT:
+diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
+index 81cc942b46..84778bbc36 100644
+--- a/hw/rtc/goldfish_rtc.c
++++ b/hw/rtc/goldfish_rtc.c
+@@ -239,15 +239,8 @@ static const VMStateDescription goldfish_rtc_vmstate = {
+ static void goldfish_rtc_reset(DeviceState *dev)
+ {
+ GoldfishRTCState *s = GOLDFISH_RTC(dev);
+- struct tm tm;
+
+ timer_del(s->timer);
+-
+- qemu_get_timedate(&tm, 0);
+- s->tick_offset = mktimegm(&tm);
+- s->tick_offset *= NANOSECONDS_PER_SECOND;
+- s->tick_offset -= qemu_clock_get_ns(rtc_clock);
+- s->tick_offset_vmstate = 0;
+ s->alarm_next = 0;
+ s->alarm_running = 0;
+ s->irq_pending = 0;
+@@ -258,6 +251,7 @@ static void goldfish_rtc_realize(DeviceState *d, Error **errp)
+ {
+ SysBusDevice *dev = SYS_BUS_DEVICE(d);
+ GoldfishRTCState *s = GOLDFISH_RTC(d);
++ struct tm tm;
+
+ memory_region_init_io(&s->iomem, OBJECT(s),
+ &goldfish_rtc_ops[s->big_endian], s,
+@@ -267,6 +261,11 @@ static void goldfish_rtc_realize(DeviceState *d, Error **errp)
+ sysbus_init_irq(dev, &s->irq);
+
+ s->timer = timer_new_ns(rtc_clock, goldfish_rtc_interrupt, s);
++
++ qemu_get_timedate(&tm, 0);
++ s->tick_offset = mktimegm(&tm);
++ s->tick_offset *= NANOSECONDS_PER_SECOND;
++ s->tick_offset -= qemu_clock_get_ns(rtc_clock);
+ }
+
+ static Property goldfish_rtc_properties[] = {
+diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
+index 9f4d007d96..44a88ab69d 100644
+--- a/hw/smbios/smbios.c
++++ b/hw/smbios/smbios.c
+@@ -1221,6 +1221,9 @@ static int save_opt_one(void *opaque,
+ g_byte_array_append(data, (guint8 *)buf, ret);
+ }
+
++ buf[0] = '\0';
++ g_byte_array_append(data, (guint8 *)buf, 1);
++
+ qemu_close(fd);
+
+ *opt->dest = g_renew(char *, *opt->dest, (*opt->ndest) + 1);
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index d0d13f4766..5914f839ea 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -2578,6 +2578,8 @@ void virtio_queue_enable(VirtIODevice *vdev, uint32_t queue_index)
+ }
+ }
+
++static int virtio_set_features_nocheck(VirtIODevice *vdev, uint64_t val);
++
+ void virtio_reset(void *opaque)
+ {
+ VirtIODevice *vdev = opaque;
+@@ -2600,7 +2602,7 @@ void virtio_reset(void *opaque)
+ vdev->start_on_kick = false;
+ vdev->started = false;
+ vdev->broken = false;
+- vdev->guest_features = 0;
++ virtio_set_features_nocheck(vdev, 0);
+ vdev->queue_sel = 0;
+ vdev->status = 0;
+ vdev->disabled = false;
+diff --git a/migration/channel-block.c b/migration/channel-block.c
+index f4ab53acdb..81ec5c6ac6 100644
+--- a/migration/channel-block.c
++++ b/migration/channel-block.c
+@@ -122,7 +122,7 @@ qio_channel_block_seek(QIOChannel *ioc,
+ bioc->offset = offset;
+ break;
+ case SEEK_CUR:
+- bioc->offset += whence;
++ bioc->offset += offset;
+ break;
+ case SEEK_END:
+ error_setg(errp, "Size of VMstate region is unknown");
+diff --git a/plugins/loader.c b/plugins/loader.c
+index 88c30bde2d..370fe54836 100644
+--- a/plugins/loader.c
++++ b/plugins/loader.c
+@@ -374,7 +374,7 @@ static void plugin_reset_destroy(struct qemu_plugin_reset_data *data)
+ {
+ qemu_rec_mutex_lock(&plugin.lock);
+ plugin_reset_destroy__locked(data);
+- qemu_rec_mutex_lock(&plugin.lock);
++ qemu_rec_mutex_unlock(&plugin.lock);
+ }
+
+ static void plugin_flush_destroy(CPUState *cpu, run_on_cpu_data arg)
+diff --git a/qapi/misc-target.json b/qapi/misc-target.json
+index 4944c0528f..d3a6ce355e 100644
+--- a/qapi/misc-target.json
++++ b/qapi/misc-target.json
+@@ -352,7 +352,7 @@
+ ##
+ # @query-sgx:
+ #
+-# Returns information about SGX
++# Returns information about configured SGX capabilities of guest
+ #
+ # Returns: @SGXInfo
+ #
+@@ -372,7 +372,7 @@
+ ##
+ # @query-sgx-capabilities:
+ #
+-# Returns information from host SGX capabilities
++# Returns information about SGX capabilities of host
+ #
+ # Returns: @SGXInfo
+ #
+diff --git a/target/arm/translate.c b/target/arm/translate.c
+index 10dfa11a2b..ed9ed8ed0a 100644
+--- a/target/arm/translate.c
++++ b/target/arm/translate.c
+@@ -9545,7 +9545,8 @@ static bool arm_check_ss_active(DisasContext *dc)
+
+ static void arm_post_translate_insn(DisasContext *dc)
+ {
+- if (dc->condjmp && dc->base.is_jmp == DISAS_NEXT) {
++ if (dc->condjmp &&
++ (dc->base.is_jmp == DISAS_NEXT || dc->base.is_jmp == DISAS_TOO_MANY)) {
+ if (dc->pc_save != dc->condlabel.pc_save) {
+ gen_update_pc(dc, dc->condlabel.pc_save - dc->pc_save);
+ }
+diff --git a/target/avr/disas.c b/target/avr/disas.c
+index b7689e8d7c..d341030174 100644
+--- a/target/avr/disas.c
++++ b/target/avr/disas.c
+@@ -68,28 +68,35 @@ static bool decode_insn(DisasContext *ctx, uint16_t insn);
+
+ int avr_print_insn(bfd_vma addr, disassemble_info *info)
+ {
+- DisasContext ctx;
++ DisasContext ctx = { info };
+ DisasContext *pctx = &ctx;
+ bfd_byte buffer[4];
+ uint16_t insn;
+ int status;
+
+- ctx.info = info;
+-
+- status = info->read_memory_func(addr, buffer, 4, info);
++ status = info->read_memory_func(addr, buffer, 2, info);
+ if (status != 0) {
+ info->memory_error_func(status, addr, info);
+ return -1;
+ }
+ insn = bfd_getl16(buffer);
+- ctx.next_word = bfd_getl16(buffer + 2);
+- ctx.next_word_used = false;
++
++ status = info->read_memory_func(addr + 2, buffer + 2, 2, info);
++ if (status == 0) {
++ ctx.next_word = bfd_getl16(buffer + 2);
++ }
+
+ if (!decode_insn(&ctx, insn)) {
+ output(".db", "0x%02x, 0x%02x", buffer[0], buffer[1]);
+ }
+
+- return ctx.next_word_used ? 4 : 2;
++ if (!ctx.next_word_used) {
++ return 2;
++ } else if (status == 0) {
++ return 4;
++ }
++ info->memory_error_func(status, addr + 2, info);
++ return -1;
+ }
+
+
+diff --git a/target/avr/insn.decode b/target/avr/insn.decode
+index 482c23ad0c..cc302249db 100644
+--- a/target/avr/insn.decode
++++ b/target/avr/insn.decode
+@@ -118,11 +118,8 @@ BRBC 1111 01 ....... ... @op_bit_imm
+ @io_rd_imm .... . .. ..... .... &rd_imm rd=%rd imm=%io_imm
+ @ldst_d .. . . .. . rd:5 . ... &rd_imm imm=%ldst_d_imm
+
+-# The 16-bit immediate is completely in the next word.
+-# Fields cannot be defined with no bits, so we cannot play
+-# the same trick and append to a zero-bit value.
+-# Defer reading the immediate until trans_{LDS,STS}.
+-@ldst_s .... ... rd:5 .... imm=0
++%ldst_imm !function=next_word
++@ldst_s .... ... rd:5 .... imm=%ldst_imm
+
+ MOV 0010 11 . ..... .... @op_rd_rr
+ MOVW 0000 0001 .... .... &rd_rr rd=%rd_d rr=%rr_d
+diff --git a/target/avr/translate.c b/target/avr/translate.c
+index 2bed56f135..a1bfa500bf 100644
+--- a/target/avr/translate.c
++++ b/target/avr/translate.c
+@@ -1690,7 +1690,6 @@ static bool trans_LDS(DisasContext *ctx, arg_LDS *a)
+ TCGv Rd = cpu_r[a->rd];
+ TCGv addr = tcg_temp_new_i32();
+ TCGv H = cpu_rampD;
+- a->imm = next_word(ctx);
+
+ tcg_gen_mov_tl(addr, H); /* addr = H:M:L */
+ tcg_gen_shli_tl(addr, addr, 16);
+@@ -1925,7 +1924,6 @@ static bool trans_STS(DisasContext *ctx, arg_STS *a)
+ TCGv Rd = cpu_r[a->rd];
+ TCGv addr = tcg_temp_new_i32();
+ TCGv H = cpu_rampD;
+- a->imm = next_word(ctx);
+
+ tcg_gen_mov_tl(addr, H); /* addr = H:M:L */
+ tcg_gen_shli_tl(addr, addr, 16);
+diff --git a/target/i386/hvf/x86_flags.c b/target/i386/hvf/x86_flags.c
+index 03d6de5efc..fedc70a1b8 100644
+--- a/target/i386/hvf/x86_flags.c
++++ b/target/i386/hvf/x86_flags.c
+@@ -293,6 +293,7 @@ void set_SF(CPUX86State *env, bool val)
+
+ void lflags_to_rflags(CPUX86State *env)
+ {
++ env->eflags &= ~(CC_C|CC_P|CC_A|CC_Z|CC_S|CC_O);
+ env->eflags |= get_CF(env) ? CC_C : 0;
+ env->eflags |= get_PF(env) ? CC_P : 0;
+ env->eflags |= get_AF(env) ? CC_A : 0;
+diff --git a/target/mips/cpu-param.h b/target/mips/cpu-param.h
+index f4c76994ea..4d9f4297f1 100644
+--- a/target/mips/cpu-param.h
++++ b/target/mips/cpu-param.h
+@@ -23,12 +23,7 @@
+ # define TARGET_VIRT_ADDR_SPACE_BITS 32
+ #endif
+ #endif
+-#ifdef CONFIG_USER_ONLY
+ #define TARGET_PAGE_BITS 12
+-#else
+-#define TARGET_PAGE_BITS_VARY
+-#define TARGET_PAGE_BITS_MIN 12
+-#endif
+ #define NB_MMU_MODES 4
+
+ #endif
+diff --git a/target/mips/tcg/sysemu/cp0_helper.c b/target/mips/tcg/sysemu/cp0_helper.c
+index 5da1124589..80260ecd8a 100644
+--- a/target/mips/tcg/sysemu/cp0_helper.c
++++ b/target/mips/tcg/sysemu/cp0_helper.c
+@@ -887,36 +887,24 @@ void helper_mtc0_memorymapid(CPUMIPSState *env, target_ulong arg1)
+ }
+ }
+
+-void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask)
++uint32_t compute_pagemask(uint32_t val)
+ {
+- uint32_t mask;
+- int maskbits;
+-
+ /* Don't care MASKX as we don't support 1KB page */
+- mask = extract32((uint32_t)arg1, CP0PM_MASK, 16);
+- maskbits = cto32(mask);
++ uint32_t mask = extract32(val, CP0PM_MASK, 16);
++ int maskbits = cto32(mask);
+
+- /* Ensure no more set bit after first zero */
+- if ((mask >> maskbits) != 0) {
+- goto invalid;
+- }
+- /* We don't support VTLB entry smaller than target page */
+- if ((maskbits + TARGET_PAGE_BITS_MIN) < TARGET_PAGE_BITS) {
+- goto invalid;
++ /* Ensure no more set bit after first zero, and maskbits even. */
++ if ((mask >> maskbits) == 0 && maskbits % 2 == 0) {
++ return mask << CP0PM_MASK;
++ } else {
++ /* When invalid, set to default target page size. */
++ return 0;
+ }
+- env->CP0_PageMask = mask << CP0PM_MASK;
+-
+- return;
+-
+-invalid:
+- /* When invalid, set to default target page size. */
+- mask = (~TARGET_PAGE_MASK >> TARGET_PAGE_BITS_MIN);
+- env->CP0_PageMask = mask << CP0PM_MASK;
+ }
+
+ void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1)
+ {
+- update_pagemask(env, arg1, &env->CP0_PageMask);
++ env->CP0_PageMask = compute_pagemask(arg1);
+ }
+
+ void helper_mtc0_pagegrain(CPUMIPSState *env, target_ulong arg1)
+diff --git a/target/mips/tcg/sysemu/tlb_helper.c b/target/mips/tcg/sysemu/tlb_helper.c
+index 9d16859c0a..cce3dcdc0e 100644
+--- a/target/mips/tcg/sysemu/tlb_helper.c
++++ b/target/mips/tcg/sysemu/tlb_helper.c
+@@ -877,8 +877,8 @@ refill:
+ break;
+ }
+ }
+- pw_pagemask = m >> TARGET_PAGE_BITS_MIN;
+- update_pagemask(env, pw_pagemask << CP0PM_MASK, &pw_pagemask);
++ pw_pagemask = m >> TARGET_PAGE_BITS;
++ pw_pagemask = compute_pagemask(pw_pagemask << CP0PM_MASK);
+ pw_entryhi = (address & ~0x1fff) | (env->CP0_EntryHi & 0xFF);
+ {
+ target_ulong tmp_entryhi = env->CP0_EntryHi;
+diff --git a/target/mips/tcg/tcg-internal.h b/target/mips/tcg/tcg-internal.h
+index aef032c48d..be398665e6 100644
+--- a/target/mips/tcg/tcg-internal.h
++++ b/target/mips/tcg/tcg-internal.h
+@@ -45,7 +45,7 @@ bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
+
+ void mmu_init(CPUMIPSState *env, const mips_def_t *def);
+
+-void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask);
++uint32_t compute_pagemask(uint32_t val);
+
+ void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra);
+ uint32_t cpu_mips_get_random(CPUMIPSState *env);
--- End Message ---