wasm-emu: document concrete TLB-array corruption path (E23-E31)
This commit is contained in:
@@ -674,3 +674,71 @@ across the relevant call/branch, and whether the wasm backend emits the
|
||||
corresponding store. The observed bug is now specifically: **compiled globals and
|
||||
`CPUArchState` are allowed to diverge, and the wasm backend exposes stale env to
|
||||
helper/exception-visible code when store TBs stay compiled.**
|
||||
|
||||
|
||||
## E23-E31: concrete TLB-array corruption
|
||||
|
||||
Added `FAULTTRACE`/`TLBTRACE` under `?ramrace=open` to inspect the exact failing
|
||||
load path.
|
||||
|
||||
Key observations from crashing `?nostoretci&ramrace=open` runs:
|
||||
|
||||
1. The faulting guest address (`0x3fcb8004`/`0x3fcb80a6`) is valid ESP32-C3 DRAM.
|
||||
2. TLB fill resolves the page correctly as RAM:
|
||||
|
||||
```text
|
||||
FAULTTRACE tlb_fill vaddr=0x3fcb8000 paddr=0x3fcb8000 asidx=0 prot=0x3
|
||||
mr=esp32c3.iram ram=1 romd=0 xlat=0x3c000
|
||||
FAULTTRACE tlb_store index=56 iotlb=0x9c000 addr_page=0x3fcb8000
|
||||
stored_xlat=0xffffffffc03e4000 phys=0x3fcb8000
|
||||
FAULTTRACE mmu_lookup1 addr=0x3fcb8000 index=56 maybe_resized=1
|
||||
tlb_addr=0x3fcb8000 flags=0x0 full_xlat=0xffffffffc03e4000 addend=0xc19d4000
|
||||
```
|
||||
|
||||
3. Before the next byte load on the same page, the compact TLB and full TLB entry
|
||||
are corrupted:
|
||||
|
||||
```text
|
||||
FAULTTRACE mmu_lookup1 addr=0x3fcb8004 index=56 maybe_resized=0
|
||||
tlb_addr=0x3fcb8200 flags=0x200 full_xlat=0x0 addend=0xc0348000
|
||||
FAULTTRACE mmio_read addr=0x3fcb8004 xlat_section=0x0 mr=(null) ram=0
|
||||
```
|
||||
|
||||
`0x200` is `TLB_MMIO`, so the vCPU incorrectly dispatches a DRAM read through
|
||||
the MMIO/unassigned path. This is why the access is rejected even though the
|
||||
guest address is in DRAM.
|
||||
|
||||
The corruption happens inside the active compiled TB before it returns, so the
|
||||
post-TB scanner only sees the last good state. The faulting firmware sequence is
|
||||
in `uzlib_uncompress`:
|
||||
|
||||
```text
|
||||
4201e18c: lw a3,56(s0)
|
||||
4201e18e: lw a5,24(s0)
|
||||
4201e190: lw a4,52(s0)
|
||||
4201e194: addi a2,a5,1
|
||||
4201e198: sw a2,24(s0)
|
||||
4201e19a: add a3,a3,a4
|
||||
4201e19c: lbu a4,0(a3) # faults after TLB entry was corrupted
|
||||
4201e1a0: sb a4,0(a5)
|
||||
```
|
||||
|
||||
The compiled store at `0x4201e198` is now the prime suspect: it likely writes
|
||||
through a bad host address into the TLB arrays, changing the same page's TLB
|
||||
entry from RAM to MMIO and zeroing `fulltlb[index].xlat_section`. That matches
|
||||
why blanket store-TCI works: the C/TCI store path does not corrupt the TLB arrays.
|
||||
|
||||
### Current root-cause statement
|
||||
|
||||
The bug is no longer just "nondeterministic race". It is specifically:
|
||||
|
||||
> compiled wasm store fast-path sometimes computes/uses a bad host address and
|
||||
> writes into the vCPU softmmu TLB arrays (`CPUTLBEntry`/`CPUTLBEntryFull`),
|
||||
> causing the immediately following load from valid DRAM to be treated as MMIO
|
||||
> with `xlat_section=0`.
|
||||
|
||||
Still unknown: why the store fast path obtains the bad host address. Candidate
|
||||
remaining causes: stale/corrupted TLB addend for the store's page, wasm32
|
||||
address truncation/sign-extension around addends, or an in-TB ordering bug in the
|
||||
compiled store TLB lookup. The next focused probe is to trace the store fast-path
|
||||
host address for the `0x4201e198` TB before the `i64.store32` executes.
|
||||
|
||||
Vendored
+1
-1
Submodule third_party/qemu updated: 346c789851...cd3f083fb0
Reference in New Issue
Block a user