zynqmp/efuse: valid MMIO write aborts on a bad owner cast
Title
zynqmp/efuse: valid MMIO write aborts on a bad owner cast
Version
commit: 2339d0a1 tag: v10.2.0-690-g2339d0a1cf version: v10.2.0-690-g2339d0a1cf-dirty
Device and source file
hw/nvram/xlnx-zynqmp-efuse.c (`xlnx-zynqmp-efuse` on `xlnx-zcu102`)
After starting the board, `info mtree -f` shows the accessed register in `0xffcc0000-0xffcc10ff` (`xlnx-zynqmp-efuse`), so the access at `0xffcc0004` is in-range.
Description of problem
This is the same ownership mismatch pattern again, this time in the ZynqMP eFuse device.
The write callback uses `reg_array->mem.owner` and casts it to `XLNX_ZYNQMP_EFUSE`. But the register framework stored the real device in `r->opaque` and made the `MemoryRegion` owner be `OBJECT(r_array)`.
So a perfectly valid write to `CFG` never reaches the register backend. The process dies on the cast first.
Key code:
```c
/* hw/nvram/xlnx-zynqmp-efuse.c */
static void zynqmp_efuse_reg_write(void *opaque, hwaddr addr,
uint64_t data, unsigned size)
{
RegisterInfoArray *reg_array = opaque;
Object *dev;
dev = reg_array->mem.owner;
assert(dev);
s = XLNX_ZYNQMP_EFUSE(dev);
...
}
/* hw/core/register.c */
r->opaque = owner;
memory_region_init_io(&r_array->mem, OBJECT(r_array), ops, r_array,
device_prefix, memory_size);
```
Root cause analysis
Input source: legal guest MMIO write to the ZynqMP eFuse register space. Missing validation: the write path reconstructs the device from `reg_array->mem.owner`, but that owner is the helper object. Bug class: invalid object cast / host abort. Impact: the first in-range write aborts QEMU.
Steps to Reproduce
Configuration
```bash
# make sure pixman is enabled, otherwise xlnx-zcu102 is not available
./configure --target-list=aarch64-softmmu --enable-debug --disable-strip
make -j"$(nproc)"
```
Reproducer (qtest)
With the runtime layout confirmed first, this is the qtest sequence I used:
```bash
cat <<'EOF' | ./qemu-system-aarch64 -audio none -display none -machine accel=qtest -M xlnx-zcu102 -nographic -monitor none -serial none -nodefaults -qtest stdio
writel 0xffcc0004 0x00000000
EOF
```
Observed output (excerpt)
```text
[I 0.000000] OPENED
[R +0.097631] writel 0xffcc0004 0x00000000
/home/ubuntu/qemu_bug/qemu-2339d0a1cfac6ecc667e6e062a593865c1541c35/include/hw/nvram/xlnx-zynqmp-efuse.h:33:XLNX_ZYNQMP_EFUSE: Object 0x5c4be3f0fc00 is not an instance of type xlnx-zynqmp-efuse
[local] exit code: 134
```
issue