From 4b1a0d72a297531630f41d35c2d45fe9de6263d4 Mon Sep 17 00:00:00 2001 From: Evan Reichard Date: Wed, 22 Jul 2026 19:05:42 -0400 Subject: [PATCH] wasm-emu: document narrowed 32-bit store-TCI panic fix Default browser path now keeps only 32-bit qemu store TBs on TCI. Normal raw-SD reader-open passes, while ?nostoretci still reproduces the original 0x4201e210 load fault as a negative control. --- docs/wasm-inflate-panic.md | 27 +++++++++++++++++++++++++++ third_party/qemu | 2 +- web/app.js | 4 +--- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/docs/wasm-inflate-panic.md b/docs/wasm-inflate-panic.md index e78c2cf..ed4a056 100644 --- a/docs/wasm-inflate-panic.md +++ b/docs/wasm-inflate-panic.md @@ -407,3 +407,30 @@ same-module `BLOCK_PTR` chain — caused an app-init interrupt-watchdog timeout, so it is not viable as-is. A narrower fix should target state materialization (flush/reload live guest register state at compiled TB boundaries or before helper/exception-visible points) rather than disabling chaining wholesale. + +## E14: narrowed production fix — only 32-bit store TBs stay TCI + +The blanket upstream qemu-wasm fallback interpreted every store-containing TB. +The width interaction tests show that is broader than necessary: + +- all stores compiled (`?nostoretci`) -> exact crash remains (`MEPC 0x4201e210`, + invalid read near `0x3FCB80xx`) +- only 8-bit qemu store TBs interpreted -> reader-open passes +- only 32-bit qemu store TBs interpreted -> reader-open passes + +Production now keeps only **32-bit qemu store TBs** on TCI; 8/16/64-bit store +TBs compile normally. This breaks the bad 8-bit/32-bit compiled-store +interaction while preserving more dynamic WASM promotion than the blanket +store-TCI fallback. `?nostoretci` remains as the normal-speed all-compiled +negative-control repro and still crashes at the original panic. + +Validation: + +```text +normal URL: browser raw-sd test passed, open example.txt took 36.8s +?nostoretci: Load access fault, MEPC 0x4201e210, invalid read 0x3FCB80A5 +``` + +This fixes the browser panic without disabling dynamic promotion globally. The +remaining upstream-quality improvement would be eliminating the 32-bit store-TCI +subset entirely by finding the exact cross-width/shared-memory state bug. diff --git a/third_party/qemu b/third_party/qemu index b3ffe97..59a198d 160000 --- a/third_party/qemu +++ b/third_party/qemu @@ -1 +1 @@ -Subproject commit b3ffe97fb30fa2f72be4a678a9130edc90a85a27 +Subproject commit 59a198dcf8deb9da15a21ff39b9e42bd89c9af38 diff --git a/web/app.js b/web/app.js index f17d332..8865948 100644 --- a/web/app.js +++ b/web/app.js @@ -463,9 +463,7 @@ async function boot(file, variant, setStatus) { const { default: createQemu } = await import(qemuUrl); const params = new URL(location.href).searchParams; - const qemuLogFlags = params.has('trace') - ? 'guest_errors,unimp,in_asm' - : 'guest_errors,unimp'; + const qemuLogFlags = [params.has('trace') ? 'guest_errors,unimp,in_asm' : 'guest_errors,unimp', params.has('nochain') ? 'nochain' : ''].filter(Boolean).join(','); // icount throttles TCG ~4.7x here and starves the guest watchdog; off by default. ?icount restores it. const icount = params.has('icount') ? ['-icount', 'shift=auto,align=off,sleep=off'] : []; const options = {