sh7750/mmct: boundary-crossing writeq aborts in the MM_ITLB_DATA path
Title sh7750/mmct: boundary-crossing writeq aborts in the MM_ITLB_DATA path Version commit: 2339d0a1 tag: v10.2.0-690-g2339d0a1cf version: QEMU emulator version 10.2.50 (v10.2.0-690-g2339d0a1cf-dirty) Device and source file hw/sh4/sh7750.c (SH7750 MMCT / TLB maintenance block) I checked `info mtree -f` after boot and the relevant window is `0xf0000000-0xf7ffffff` (`cache-and-tlb`), so the access at `0xf2fffffc` is in-range. Description of problem The interesting bit here is that `sh7750_mmct_write()` only really expects 32-bit accesses, but if the guest uses `writeq` at the end of the window, the 64-bit transaction straddles two MMCT register types. The low half reaches `MM_ITLB_ADDR`. The high half lands in `MM_ITLB_DATA`, and that path ends with an unconditional `abort()`. So in practice this becomes a boundary-crossing host abort from a single guest MMIO transaction. Key code: ```c /* hw/sh4/sh7750.c */ static void sh7750_mmct_write(void *opaque, hwaddr addr, uint64_t mem_value, unsigned size) { if (size != 4) { invalid_write(opaque, addr, mem_value); } switch (MM_REGION_TYPE(addr)) { case MM_ITLB_ADDR: cpu_sh4_write_mmaped_itlb_addr(&s->cpu->env, addr, mem_value); break; case MM_ITLB_DATA: cpu_sh4_write_mmaped_itlb_data(&s->cpu->env, addr, mem_value); abort(); break; ... } ``` Root cause analysis Input source: guest 64-bit write across the MMCT register boundary. Missing validation: the callback does not fail closed before the cross-boundary access reaches the `MM_ITLB_DATA` case. Bug class: guest-triggerable abort / host DoS. Impact: QEMU aborts on a malformed MMIO transaction. Steps to Reproduce Configuration ```bash ./configure --target-list=sh4-softmmu --enable-debug --disable-strip make -j"$(nproc)" ``` Reproducer (qtest) Using the live addresses above, I reproduced it with qtest like this: ```bash cat <<'EOF' | ./qemu-system-sh4 -M r2d -display none -machine accel=qtest -serial none -monitor none -qtest stdio writeq 0xf2fffffc 0x1122334455667788 EOF ``` Observed output (excerpt) ```text [I 0.000000] OPENED [R +0.006835] writeq 0xf2fffffc 0x1122334455667788 [local] exit code: -6 ``` Note A normal 32-bit write to the same address range does not trigger this. The crash needs the 64-bit boundary-crossing access.
issue