wasm-emu: isolate compiled-store corruption to uzlib fault-path TB (E32-E34)
This commit is contained in:
@@ -742,3 +742,55 @@ 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
|
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
|
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.
|
host address for the `0x4201e198` TB before the `i64.store32` executes.
|
||||||
|
|
||||||
|
|
||||||
|
## E32-E34: fault-path TB isolation
|
||||||
|
|
||||||
|
Tried a narrow compiled-store guard (`?tlbguard=open`) that forces a store fast
|
||||||
|
path to the C helper if the computed host address lands inside the vCPU TLB
|
||||||
|
arrays. It did **not** suppress the crash, even though the guard range included
|
||||||
|
`fulltlb[56]`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
TLBGUARD range lo=0x13e8000 hi=0x353c000
|
||||||
|
```
|
||||||
|
|
||||||
|
So the corrupting write is not caught as a normal compiled `qemu_st` fast-path
|
||||||
|
whose final host pointer falls directly inside that TLB-array range. The
|
||||||
|
corruption still appears between the TLB fill and the following byte load.
|
||||||
|
|
||||||
|
Added `?stpc=LO-HI`, an opt-in PC-window override that interprets only
|
||||||
|
store-containing TBs whose start PC lands in the window, while `?nostoretci`
|
||||||
|
keeps every other store TB compiled.
|
||||||
|
|
||||||
|
Results:
|
||||||
|
|
||||||
|
- plain `?nostoretci`: still crashes at the original signature.
|
||||||
|
- `?nostoretci&stpc=0x4201e180-0x4201e220`: **3/3 pass**
|
||||||
|
(`open example.txt` about 46-52s).
|
||||||
|
- wider/narrowed windows around `uzlib_uncompress` also pass as long as they
|
||||||
|
include the fault-path TB start.
|
||||||
|
|
||||||
|
This pins the corruption to compiled execution of the `uzlib_uncompress` TB that
|
||||||
|
contains the copy-loop sequence around:
|
||||||
|
|
||||||
|
```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)
|
||||||
|
4201e1a0: sb a4,0(a5)
|
||||||
|
```
|
||||||
|
|
||||||
|
The PC-window override is firmware-specific and **not** a production fix, but it
|
||||||
|
is now the smallest positive isolation: one compiled store-containing TB in the
|
||||||
|
inflate copy loop is sufficient to corrupt the vCPU TLB entry; interpreting that
|
||||||
|
TB avoids the crash while preserving compiled stores elsewhere.
|
||||||
|
|
||||||
|
Next useful step: dump or instrument the generated WASM for this exact TB and
|
||||||
|
inspect the `sw a2,24(s0)` / following `lbu` fast-path sequence. The current
|
||||||
|
node dump helper only captures early boot TBs, so late-reader TB dumping needs a
|
||||||
|
browser/open-window trigger or a PC-filtered `wasm_dump_module` path.
|
||||||
|
|||||||
@@ -171,6 +171,8 @@ try:
|
|||||||
driver.execute_script('window.xteinkEnableRamrace && window.xteinkEnableRamrace()')
|
driver.execute_script('window.xteinkEnableRamrace && window.xteinkEnableRamrace()')
|
||||||
if 'stateflush=open' in url:
|
if 'stateflush=open' in url:
|
||||||
driver.execute_script('window.xteinkEnableStateflush && window.xteinkEnableStateflush()')
|
driver.execute_script('window.xteinkEnableStateflush && window.xteinkEnableStateflush()')
|
||||||
|
if 'tlbguard=open' in url:
|
||||||
|
driver.execute_script('window.xteinkEnableTlbguard && window.xteinkEnableTlbguard()')
|
||||||
open_start = time.monotonic()
|
open_start = time.monotonic()
|
||||||
press(confirm, 'opening example.txt')
|
press(confirm, 'opening example.txt')
|
||||||
open_seconds = time.monotonic() - open_start
|
open_seconds = time.monotonic() - open_start
|
||||||
|
|||||||
Vendored
+1
-1
Submodule third_party/qemu updated: cd3f083fb0...e4a6de07c6
@@ -501,8 +501,15 @@ async function boot(file, variant, setStatus) {
|
|||||||
if (params.get('stateflush') === 'open') {
|
if (params.get('stateflush') === 'open') {
|
||||||
window.xteinkEnableStateflush = () => options._wasm_stateflush_enable();
|
window.xteinkEnableStateflush = () => options._wasm_stateflush_enable();
|
||||||
} else if (params.has('stateflush')) options._wasm_stateflush_enable();
|
} else if (params.has('stateflush')) options._wasm_stateflush_enable();
|
||||||
|
if (params.get('tlbguard') === 'open') {
|
||||||
|
window.xteinkEnableTlbguard = () => options._wasm_tlb_guard_enable();
|
||||||
|
} else if (params.has('tlbguard')) options._wasm_tlb_guard_enable();
|
||||||
if (params.has('sthash')) options._wasm_set_store_tci_hash(Number(params.get('sthash')) || 1);
|
if (params.has('sthash')) options._wasm_set_store_tci_hash(Number(params.get('sthash')) || 1);
|
||||||
if (params.has('stcmask')) options._wasm_set_store_bisect(Number(params.get('stcw')) || 0, Number(params.get('stcmask')) >>> 0, (Number(params.get('stcval')) || 0) >>> 0);
|
if (params.has('stcmask')) options._wasm_set_store_bisect(Number(params.get('stcw')) || 0, Number(params.get('stcmask')) >>> 0, (Number(params.get('stcval')) || 0) >>> 0);
|
||||||
|
if (params.has('stpc')) {
|
||||||
|
const [lo, hi] = params.get('stpc').split('-').map(v => Number(v));
|
||||||
|
options._wasm_set_store_pc_window(lo >>> 0, hi >>> 0);
|
||||||
|
}
|
||||||
options.FS.mkdirTree('/bios');
|
options.FS.mkdirTree('/bios');
|
||||||
options.FS.mkdirTree('/var/tmp');
|
options.FS.mkdirTree('/var/tmp');
|
||||||
options.FS.writeFile('/bios/esp32c3-rom.bin', rom);
|
options.FS.writeFile('/bios/esp32c3-rom.bin', rom);
|
||||||
|
|||||||
Reference in New Issue
Block a user