diff --git a/docs/wasm-inflate-panic.md b/docs/wasm-inflate-panic.md index 1947a3a..48d167e 100644 --- a/docs/wasm-inflate-panic.md +++ b/docs/wasm-inflate-panic.md @@ -794,3 +794,46 @@ 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. + + +## E35-E38: TB dump and narrowed production fallback + +Added `?dumpstpc=LO-HI`, which dumps generated WASM modules for TBs in a PC +window. In browser runs the dump is emitted as hex in `_scratch/browser-raw-sd.log` +and reconstructed with `wasm2wat`. + +The relevant dump shows the failing region is split into small restartable TBs +with qemu load/store slow-path helper machinery. The important isolation remains +runtime behavior rather than static shape: interpreting the fault-path TB window +prevents the TLB corruption; compiling it allows a valid DRAM page's TLB entry +to flip to `TLB_MMIO`/`xlat_section=0`. + +Tested a firmware-independent fallback class: + +- compile pure store TBs; +- keep mixed store+load/helper TBs TCI. + +Rationale: the bad `uzlib_uncompress` TB is a mixed memory/helper TB, and pure +store TBs were exonerated by the earlier per-TB and whole-execution differential +runs. + +Results: + +- `?nostoretci&storehelpertci`: 4 clean passes plus 1 post-reader close timeout, + with no corruption signature. +- New default (mixed store+load/helper TBs TCI, pure store TBs compiled): 3/3 + clean reader-open passes (`44.5s`, `44.5s`, `46.5s`). +- Negative control `?nostoretci`: still crashes at the original + `0x4201e210`/`0x3FCB80xx` signature. + +This drops the blanket "all store TBs TCI" fallback and replaces it with the +smallest currently validated generic rule. It is still a conservative fallback, +not a full codegen fix: the root bug remains in compiled mixed memory/helper TBs +corrupting the softmmu TLB arrays. + +New debug knobs: + +- `?dumpstpc=LO-HI` dumps generated WASM for TBs in a PC window. +- `?storehelpertci` re-enables the mixed store+load/helper fallback even under + `?nostoretci` for A/B testing. +- `?tlbguard=open` remains a negative probe; it did not catch the corruption. diff --git a/third_party/qemu b/third_party/qemu index e4a6de0..29cab65 160000 --- a/third_party/qemu +++ b/third_party/qemu @@ -1 +1 @@ -Subproject commit e4a6de07c63b20116af697f4ac6ba678c9208626 +Subproject commit 29cab65aff64ba1399850431e7697f0b82920e97 diff --git a/web/app.js b/web/app.js index 3a88974..db2bf57 100644 --- a/web/app.js +++ b/web/app.js @@ -504,12 +504,17 @@ async function boot(file, variant, setStatus) { 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('storehelpertci')) options._wasm_set_store_helper_tci(); 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('stpc')) { const [lo, hi] = params.get('stpc').split('-').map(v => Number(v)); options._wasm_set_store_pc_window(lo >>> 0, hi >>> 0); } + if (params.has('dumpstpc')) { + const [lo, hi] = params.get('dumpstpc').split('-').map(v => Number(v)); + options._wasm_set_dump_pc_window(lo >>> 0, hi >>> 0); + } options.FS.mkdirTree('/bios'); options.FS.mkdirTree('/var/tmp'); options.FS.writeFile('/bios/esp32c3-rom.bin', rom);