* [PULL 1/6] hw/net/xilinx_axienet: Don't write checksums off end of packet
2026-07-28 9:40 [PULL 0/6] Misc HW patches for 2026-07-28 Philippe Mathieu-Daudé
@ 2026-07-28 9:40 ` Philippe Mathieu-Daudé
2026-07-28 9:40 ` [PULL 2/6] hw/sd/sdhci: Extract uSDHC-specific quirk Philippe Mathieu-Daudé
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-07-28 9:40 UTC (permalink / raw)
To: qemu-devel
From: Peter Maydell <peter.maydell@linaro.org>
The xilinx_axienet device has ethernet checksum offloading, with a
mode where the guest provides the offsets within the packet where
the data to be checksummed starts, and where the final checksum
should be written into the packet.
We don't sanity check the TX_CSINSERT offset before writing the
checksum data into it, which means the guest can pass us a value that
is larger than the packet itself and cause us to write the checksum
off the end of the buffer. We also don't explicitly check the
TX_CSBEGIN offset; this doesn't currently cause any problems because
we will pass a negative length to net_checksum_add() which does
nothing, but it's a potential trap for the future if the type
used for the length gets changed to be unsigned.
Explicitly check the offsets. The datasheet doesn't say what happens
if the guest misprograms this, so we choose to log an error and send
the packet as-is.
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3599
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260706162704.787495-1-peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
hw/net/xilinx_axienet.c | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index 9f5f65ecfac..d35f4a847d6 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -922,20 +922,27 @@ xilinx_axienet_data_stream_push(StreamSink *obj, uint8_t *buf, size_t size,
if (s->hdr[0] & 1) {
unsigned int start_off = s->hdr[1] >> 16;
unsigned int write_off = s->hdr[1] & 0xffff;
- uint32_t tmp_csum;
- uint16_t csum;
- tmp_csum = net_checksum_add(s->txpos - start_off,
- buf + start_off);
- /* Accumulate the seed. */
- tmp_csum += s->hdr[2] & 0xffff;
+ if (start_off > s->txpos || write_off + 2 > s->txpos) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: offsets outside packet, skipping checksum\n",
+ TYPE_XILINX_AXI_ENET);
+ } else {
+ uint32_t tmp_csum;
+ uint16_t csum;
- /* Fold the 32bit partial checksum. */
- csum = net_checksum_finish(tmp_csum);
+ tmp_csum = net_checksum_add(s->txpos - start_off,
+ buf + start_off);
+ /* Accumulate the seed. */
+ tmp_csum += s->hdr[2] & 0xffff;
- /* Writeback. */
- buf[write_off] = csum >> 8;
- buf[write_off + 1] = csum & 0xff;
+ /* Fold the 32bit partial checksum. */
+ csum = net_checksum_finish(tmp_csum);
+
+ /* Writeback. */
+ buf[write_off] = csum >> 8;
+ buf[write_off + 1] = csum & 0xff;
+ }
}
qemu_send_packet(qemu_get_queue(s->nic), buf, s->txpos);
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PULL 2/6] hw/sd/sdhci: Extract uSDHC-specific quirk
2026-07-28 9:40 [PULL 0/6] Misc HW patches for 2026-07-28 Philippe Mathieu-Daudé
2026-07-28 9:40 ` [PULL 1/6] hw/net/xilinx_axienet: Don't write checksums off end of packet Philippe Mathieu-Daudé
@ 2026-07-28 9:40 ` Philippe Mathieu-Daudé
2026-07-28 9:40 ` [PULL 3/6] hw/net/e1000e: recalculate rx_desc_len on migration load Philippe Mathieu-Daudé
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-07-28 9:40 UTC (permalink / raw)
To: qemu-devel
From: Bernhard Beschow <shentey@gmail.com>
In Linux, the ESDHC_MIX_CTRL quirk is guarded by esdhc_is_usdhc() while
the eSDHC code path uses the standard SDHC interface. Extract the quirk
into a new `usdhc_write()` function.
Fixes file system corruption on emulated i.MX53 where Linux'
esdhc_is_usdhc() returns false. The same likely happens on e500 and
imx25-pdk machines.
Cc: qemu-stable@nongnu.org
Fixes: 75e98bc4f859 ("hw/sd/sdhci: Add TYPE_FSL_ESDHC_BE")
Reviewed-by: Bin Meng <bin.meng@processmission.com>
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Message-ID: <20260720201133.24796-3-shentey@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
hw/sd/sdhci.c | 73 +++++++++++++++++++++++++++++++--------------------
1 file changed, 44 insertions(+), 29 deletions(-)
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index c86dfa281f4..e58a6103970 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1795,34 +1795,6 @@ esdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
sdhci_write(opaque, offset, value, size);
break;
- case ESDHC_MIX_CTRL:
- /*
- * So, when SD/MMC stack in Linux tries to write to "Transfer
- * Mode Register", ESDHC i.MX quirk code will translate it
- * into a write to ESDHC_MIX_CTRL, so we do the opposite in
- * order to get where we started
- *
- * Note that Auto CMD23 Enable bit is located in a wrong place
- * on i.MX, but since it is not used by QEMU we do not care.
- *
- * We don't want to call sdhci_write(.., SDHC_TRNMOD, ...)
- * here because it will result in a call to
- * sdhci_send_command(s) which we don't want.
- *
- */
- s->trnmod = value & UINT16_MAX;
- break;
- case SDHC_TRNMOD:
- /*
- * Similar to above, but this time a write to "Command
- * Register" will be translated into a 4-byte write to
- * "Transfer Mode register" where lower 16-bit of value would
- * be set to zero. So what we do is fill those bits with
- * cached value from s->trnmod and let the SDHCI
- * infrastructure handle the rest
- */
- sdhci_write(opaque, offset, val | s->trnmod, size);
- break;
case SDHC_BLKSIZE:
/*
* ESDHCI does not implement "Host SDMA Buffer Boundary", and
@@ -1891,9 +1863,52 @@ static void fsl_esdhc_le_init(Object *obj)
qdev_prop_set_uint8(dev, "sd-spec-version", 2);
}
+static void
+usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
+{
+ SDHCIState *s = SYSBUS_SDHCI(opaque);
+ uint32_t value = (uint32_t)val;
+
+ switch (offset) {
+ case ESDHC_MIX_CTRL:
+ /*
+ * So, when SD/MMC stack in Linux tries to write to "Transfer
+ * Mode Register", uSDHC i.MX quirk code will translate it
+ * into a write to ESDHC_MIX_CTRL, so we do the opposite in
+ * order to get where we started.
+ *
+ * Note that Auto CMD23 Enable bit is located in a wrong place
+ * on i.MX, but since it is not used by QEMU we do not care.
+ *
+ * We don't want to call sdhci_write(.., SDHC_TRNMOD, ...)
+ * here because it will result in a call to
+ * sdhci_send_command(s) which we don't want.
+ *
+ */
+ s->trnmod = value & UINT16_MAX;
+ break;
+
+ case SDHC_TRNMOD:
+ /*
+ * Similar to above, but this time a write to "Command
+ * Register" will be translated into a 4-byte write to
+ * "Transfer Mode register" where lower 16-bit of value would
+ * be set to zero. So what we do is fill those bits with
+ * cached value from s->trnmod and let the SDHCI
+ * infrastructure handle the rest
+ */
+ sdhci_write(opaque, offset, val | s->trnmod, size);
+ break;
+
+ default:
+ esdhc_write(opaque, offset, val, size);
+ break;
+ }
+}
+
static const MemoryRegionOps usdhc_mmio_ops = {
.read = esdhc_read,
- .write = esdhc_write,
+ .write = usdhc_write,
.valid = {
.min_access_size = 1,
.max_access_size = 4,
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PULL 3/6] hw/net/e1000e: recalculate rx_desc_len on migration load
2026-07-28 9:40 [PULL 0/6] Misc HW patches for 2026-07-28 Philippe Mathieu-Daudé
2026-07-28 9:40 ` [PULL 1/6] hw/net/xilinx_axienet: Don't write checksums off end of packet Philippe Mathieu-Daudé
2026-07-28 9:40 ` [PULL 2/6] hw/sd/sdhci: Extract uSDHC-specific quirk Philippe Mathieu-Daudé
@ 2026-07-28 9:40 ` Philippe Mathieu-Daudé
2026-07-28 9:40 ` [PULL 4/6] hw/net/igb: " Philippe Mathieu-Daudé
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-07-28 9:40 UTC (permalink / raw)
To: qemu-devel
From: Laurent Vivier <lvivier@redhat.com>
rx_desc_len is migrated as a raw uint8_t from the stream, but it
is a derived value that can be computed from the register state
in core.mac[RFCTL] and core.mac[RCTL]. A crafted migration stream
can set rx_desc_len to an invalid value (e.g. 64), causing a stack
buffer overflow in e1000e_write_packet_to_guest() which copies
rx_desc_len bytes into a 32-byte stack union.
Recalculate rx_desc_len and other derived values from the register
state in post_load, ignoring the untrusted values from the stream.
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3869
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Message-ID: <20260722112449.1386162-2-lvivier@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
hw/net/e1000e_core.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
index 46e156a5ddc..b87a9f167a7 100644
--- a/hw/net/e1000e_core.c
+++ b/hw/net/e1000e_core.c
@@ -1948,6 +1948,16 @@ e1000e_calc_rxdesclen(E1000ECore *core)
trace_e1000e_rx_desc_len(core->rx_desc_len);
}
+static void
+e1000e_calc_rxconf(E1000ECore *core)
+{
+ e1000e_parse_rxbufsize(core);
+ e1000e_calc_rxdesclen(core);
+ core->rxbuf_min_shift =
+ ((core->mac[RCTL] / E1000_RCTL_RDMTS_QUAT) & 3) + 1 +
+ E1000_RING_DESC_LEN_SHIFT;
+}
+
static void
e1000e_set_rx_control(E1000ECore *core, int index, uint32_t val)
{
@@ -1955,11 +1965,7 @@ e1000e_set_rx_control(E1000ECore *core, int index, uint32_t val)
trace_e1000e_rx_set_rctl(core->mac[RCTL]);
if (val & E1000_RCTL_EN) {
- e1000e_parse_rxbufsize(core);
- e1000e_calc_rxdesclen(core);
- core->rxbuf_min_shift = ((val / E1000_RCTL_RDMTS_QUAT) & 3) + 1 +
- E1000_RING_DESC_LEN_SHIFT;
-
+ e1000e_calc_rxconf(core);
e1000e_start_recv(core);
}
}
@@ -3557,5 +3563,7 @@ e1000e_core_post_load(E1000ECore *core)
e1000e_intrmgr_resume(core);
e1000e_autoneg_resume(core);
+ e1000e_calc_rxconf(core);
+
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PULL 4/6] hw/net/igb: recalculate rx_desc_len on migration load
2026-07-28 9:40 [PULL 0/6] Misc HW patches for 2026-07-28 Philippe Mathieu-Daudé
` (2 preceding siblings ...)
2026-07-28 9:40 ` [PULL 3/6] hw/net/e1000e: recalculate rx_desc_len on migration load Philippe Mathieu-Daudé
@ 2026-07-28 9:40 ` Philippe Mathieu-Daudé
2026-07-28 9:40 ` [PULL 5/6] target/sparc: set reg window data structures currently after vmstate load Philippe Mathieu-Daudé
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-07-28 9:40 UTC (permalink / raw)
To: qemu-devel
From: Laurent Vivier <lvivier@redhat.com>
rx_desc_len is migrated as a raw uint8_t from the stream but is a
derived value. Currently igb_rx_use_legacy_descriptor() is a stub
that always returns false, so rx_desc_len is always set to
sizeof(union e1000_adv_rx_desc). Recalculate it in post_load to
prevent a crafted migration stream from setting an invalid value.
Cc: qemu-stable@nongnu.org
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Message-ID: <20260722112449.1386162-3-lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
hw/net/igb_core.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
index 45d8fd795b8..2a488390735 100644
--- a/hw/net/igb_core.c
+++ b/hw/net/igb_core.c
@@ -4548,5 +4548,7 @@ igb_core_post_load(IGBCore *core)
igb_intrmgr_resume(core);
igb_autoneg_resume(core);
+ igb_calc_rxdesclen(core);
+
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PULL 5/6] target/sparc: set reg window data structures currently after vmstate load
2026-07-28 9:40 [PULL 0/6] Misc HW patches for 2026-07-28 Philippe Mathieu-Daudé
` (3 preceding siblings ...)
2026-07-28 9:40 ` [PULL 4/6] hw/net/igb: " Philippe Mathieu-Daudé
@ 2026-07-28 9:40 ` Philippe Mathieu-Daudé
2026-07-28 9:40 ` [PULL 6/6] tests/functional/ppc: skip remote interrupts test if -net user not built Philippe Mathieu-Daudé
2026-07-28 15:31 ` [PULL 0/6] Misc HW patches for 2026-07-28 Stefan Hajnoczi
6 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-07-28 9:40 UTC (permalink / raw)
To: qemu-devel
From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
In the SPARC CPU state, env->regwptr points into the env->regbase
array at wherever the architectural CWP (current window pointer) says
we are in the register windows. We don't migrate this directly,
since it's a host pointer, so we must ensure it is set up again
after migration load.
We also have to deal with a special case when CWP is (nwindows - 1).
In this case, while running we keep the "in" register data for this
window in a temporary location at the end of the regbase[] array, so
that generated code doesn't have to special case this "wrap around"
case. In cpu_pre_save() we call cpu_set_cwp() to force a copy of the
wrapped data from its temporary location into the architectural
location in window 0's "out" registers. We then migrate only
(nwindows * 16) entries in the regbase[] array. So on the
destination we need to copy the "in" register data back to its
temporary location again.
For 32-bit SPARC we get this right, because the CWP is in the PSR.
The get_psr() function does:
env->cwp = 0;
cpu_put_psr_raw(env, val);
which causes cpu_put_psr_raw() to call cpu_set_cwp() in a way that
sets up both regwptr and the wrapped-register data.
However, for 64-bit SPARC the CWP is not in the PSR, and
cpu_put_psr_raw() will not call cpu_set_cwp(). This leaves the guest
register state in a corrupted state, and the guest will likely crash
on the destination if it didn't happen to be executing with CWP == 0.
Fix this by adding a custom vmstate_cwp VMStateInfo with corresponding
get_cwp() and put_cwp() helpers which does the same for the 64-bit
case.
Cc: qemu-stable@nongnu.org
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Message-ID: <20260725123411.993099-1-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
target/sparc/machine.c | 40 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 39 insertions(+), 1 deletion(-)
diff --git a/target/sparc/machine.c b/target/sparc/machine.c
index 5f402e098cf..0d5d79b5e7b 100644
--- a/target/sparc/machine.c
+++ b/target/sparc/machine.c
@@ -151,6 +151,37 @@ static const VMStateInfo vmstate_xcc = {
.get = get_xcc,
.put = put_xcc,
};
+
+static int get_cwp(QEMUFile *f, void *opaque, size_t size,
+ const VMStateField *field)
+{
+ SPARCCPU *cpu = opaque;
+ CPUSPARCState *env = &cpu->env;
+ uint32_t val = qemu_get_be32(f);
+
+ /* needed to ensure that the wrapping registers are correctly updated */
+ env->cwp = 0;
+ cpu_set_cwp(env, val);
+
+ return 0;
+}
+
+static int put_cwp(QEMUFile *f, void *opaque, size_t size,
+ const VMStateField *field, JSONWriter *vmdesc)
+{
+ SPARCCPU *cpu = opaque;
+ CPUSPARCState *env = &cpu->env;
+ uint32_t val = env->cwp;
+
+ qemu_put_be32(f, val);
+ return 0;
+}
+
+static const VMStateInfo vmstate_cwp = {
+ .name = "uint32",
+ .get = get_cwp,
+ .put = put_cwp,
+};
#else
static bool fq_needed(void *opaque)
{
@@ -286,7 +317,14 @@ const VMStateDescription vmstate_sparc_cpu = {
VMSTATE_CPU_TIMER(env.hstick, SPARCCPU),
/* On SPARC32 env.psrpil and env.cwp are migrated as part of the PSR */
VMSTATE_UINT32(env.psrpil, SPARCCPU),
- VMSTATE_UINT32(env.cwp, SPARCCPU),
+ {
+ .name = "env.cwp",
+ .version_id = 0,
+ .size = sizeof(uint32_t),
+ .info = &vmstate_cwp,
+ .flags = VMS_SINGLE,
+ .offset = 0,
+ },
#endif
VMSTATE_END_OF_LIST()
},
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PULL 6/6] tests/functional/ppc: skip remote interrupts test if -net user not built
2026-07-28 9:40 [PULL 0/6] Misc HW patches for 2026-07-28 Philippe Mathieu-Daudé
` (4 preceding siblings ...)
2026-07-28 9:40 ` [PULL 5/6] target/sparc: set reg window data structures currently after vmstate load Philippe Mathieu-Daudé
@ 2026-07-28 9:40 ` Philippe Mathieu-Daudé
2026-07-28 15:31 ` [PULL 0/6] Misc HW patches for 2026-07-28 Stefan Hajnoczi
6 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-07-28 9:40 UTC (permalink / raw)
To: qemu-devel
From: Shivang Upadhyay <shivangu@linux.ibm.com>
While running remote interrupts test, without libslirp-devel installed,
facing the following panic logs.
File
...
raise VMLaunchFailure(
...<3 lines>...
) from exc
...
Output: qemu-system-ppc64: -netdev user,id=net0: network backend
'user' is not compiled into this binary
Adding netdev user requirement for this test.
Suggested-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Reviewed-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Suggested-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Fixes: 63f5ba80921 ("tests/functional: Add remote interrupts test for PowerNV")
Signed-off-by: Shivang Upadhyay <shivangu@linux.ibm.com>
Tested-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Message-ID: <20260728074612.42397-1-shivangu@linux.ibm.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
tests/functional/ppc64/test_powernv.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/functional/ppc64/test_powernv.py b/tests/functional/ppc64/test_powernv.py
index bac2017e18d..f3e05e4d381 100755
--- a/tests/functional/ppc64/test_powernv.py
+++ b/tests/functional/ppc64/test_powernv.py
@@ -90,6 +90,7 @@ def test_linux_smt_boot(self):
def test_linux_remote_interrupts(self):
self.require_accelerator("tcg")
+ self.require_netdev('user')
self.set_machine('powernv')
# Have below setup in this test:
--
2.53.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PULL 0/6] Misc HW patches for 2026-07-28
2026-07-28 9:40 [PULL 0/6] Misc HW patches for 2026-07-28 Philippe Mathieu-Daudé
` (5 preceding siblings ...)
2026-07-28 9:40 ` [PULL 6/6] tests/functional/ppc: skip remote interrupts test if -net user not built Philippe Mathieu-Daudé
@ 2026-07-28 15:31 ` Stefan Hajnoczi
6 siblings, 0 replies; 8+ messages in thread
From: Stefan Hajnoczi @ 2026-07-28 15:31 UTC (permalink / raw)
To: Philippe Mathieu-Daudé; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 116 bytes --]
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/11.1 for any user-visible changes.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread