[PATCH 0/2] hw/arm/raspi4b: fix watchdog and GENET bugs hit by modern distro kernels
Marcelo Manzo <[email protected]> Sat, 25 Jul 2026 19:11:40 -0400
| Newsgroups | org.nongnu.qemu-arm,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
Follow-up to "hw/arm/bcm2838_pcie: make PCI device enumeration actually work" [1]. That series (plus the GENET/RNG200/thermal work before it) got a real Raspberry Pi 4 SoC far enough to boot official, unmodified Raspberry Pi OS releases end to end under raspi4b -- not just the functional-test suite's minimal 2019-era kernel+initrd. Doing that surfaced two further bugs that only show up with a modern distro's systemd actually driving the hardware, both on paths the existing tests don't exercise: 1. hw/misc/bcm2835_powermgt: the RSTC register's write-config bits (0x30) being set to the "full reset" value (0x20) does not mean "reset now" on real hardware -- it arms the watchdog so a reset happens only if the WDOG countdown register is not refreshed before it expires. QEMU's model treated any such RSTC write as an immediate reset. This is dormant on lighter userspace, but Debian 13/Trixie's systemd (257) writes to RSTC during routine early-boot watchdog probing, causing an immediate spurious reset a few seconds into boot. Combined with -no-reboot this looks exactly like a QEMU crash from the outside: clean exit, no panic, no guest reboot message, the last log line being the RSTC/WDOG write itself. Fixed by actually implementing the watchdog as a QEMUTimer that only fires -- and only then requests a reset/shutdown -- after the real timeout computed from the WDOG register. 2. hw/net/bcm2838_genet: three related per-ring DMA bugs. RDMA_CTRL writes never updated any per-ring status at all (only TDMA_CTRL updated a single overall DISABLED bit); enabling a ring didn't flush packets queued while it was disabled; and the RX fallback path hardcoded the last/default ring with no check that it was actually active. Bullseye and Bookworm's kernels default to that last ring, so this was invisible with them, but Trixie's 6.18 kernel actively uses rings 0-4 and never enables the default ring, so every unfiltered packet was silently dropped -- no DHCP lease, no usable networking. Fixed by tracking a real per-ring enable bitmask for both directions, flushing queued packets when a ring is enabled, and falling back to scanning for the first actually- active ring instead of assuming the last one. Testing: rather than only the functional-test kernel, I booted three official Raspberry Pi OS Lite arm64 releases end to end against the patched raspi4b machine -- Bullseye (5.15.61-v8+), Bookworm (6.12.25+rpt-rpi-v8), and Trixie (6.18.34+rpt-rpi-v8) -- each with a clean boot (no crash/reboot loop), a DHCP lease obtained over GENET, working SSH login, and an error log containing nothing beyond the expected "hardware QEMU doesn't emulate" noise (VideoCore/VCHI, camera/codec/audio probes, GPIO regulators, Bluetooth UART, EEPROM check) on all three. Before patch 1, Trixie reset within seconds of boot; before patch 2, Trixie booted but never got a network address. Bullseye and Bookworm were unaffected either way, which is exactly why these bugs went unnoticed until a newer kernel exercised these specific paths. I did not add a functional test for either fix: reliably triggering them needs a real systemd doing real early-boot watchdog/network setup, which the existing test kernel/initrd (a minimal 2019 busybox environment) doesn't exercise, and downloading a full modern distro image isn't practical for the functional-test asset infrastructure. Happy to take suggestions on a lighter-weight way to cover this if one exists. checkpatch.pl is clean (0 errors, 0 warnings) on both patches, and the series builds standalone from a clean worktree (--target-list=aarch64-softmmu). [1] https://patchwork.kernel.org/project/qemu-devel/cover/[email protected]/ Marcelo Manzo (2): hw/misc/bcm2835_powermgt: implement a real watchdog timer hw/net/bcm2838_genet: fix per-ring DMA status and RX ring selection hw/misc/bcm2835_powermgt.c | 49 +++++++++++++++++++++++------- hw/net/bcm2838_genet.c | 24 +++++++++++++-- include/hw/misc/bcm2835_powermgt.h | 2 ++ include/hw/net/bcm2838_genet.h | 2 ++ 4 files changed, 63 insertions(+), 14 deletions(-) -- 2.47.1