The legacy jit CPU feature reproducibly stops making guest boot progress immediately after the IRIX 6.5.22 kernel banner on a native Linux/aarch64 build. The emulator remains CPU-active and continues compiling/promoting JIT blocks, but the serial console never reaches The system is coming up. or a login prompt.
The same current Iris revision, disk, PROM, NVRAM, machine configuration, and fresh-overlay procedure reach login with the interpreter/lightning build and with jitv2.
Revision and host
- Iris
main: cfd1728d11efcf16de6072bcd7e3f158b7df19c7 (fix lui-addiu-ori opcode fusion when first instruction is in bd slot) - Host hardware: Apple M1 Pro
- Host OS: macOS 26.5.2 (Darwin 25.5.0, arm64)
- Container runtime: Docker 29.7.2, native
linux/arm64 - Container kernel: LinuxKit 6.12.76,
aarch64 - Rust:
1.99.0-nightly (d453bdd8f 2026-08-14) - Cranelift: 0.134.3
- Generated
Cargo.lock SHA-256:
b953d6606cfde79637e088c910b7ad5c0c01fba649986d5488b873692712057c
There is no amd64 container or Rosetta/QEMU translation layer in this test: both the container and the Iris executable are aarch64.
Guest and media
- Machine profile:
indy_ip24 - CPU/memory profile: R4400, 256 MiB
- Unmodified vendor IRIX 6.5.22 installation from the published worker image
ghcr.io/sgidevnet/irix-worker@sha256:6be7c6c3f92d15705f2d08a3d1b919d6f6241b5364ced22ae0d962820e4724cd - Disk SHA-256:
a31113aae5a0c27ba2ca2ac567c76659608329ba7d0de0243d358f3571a690f5 - Guest banner:
IRIX Release 6.5 IP22 Version 10070055 System V - Embedded Iris PROM
- Disk overlay enabled
Each run starts with a newly created, empty snapshot/CAS volume. The image has no jit-profile.bin, and no saved JIT profile is supplied.
Build
cargo build --release --locked \
--features chd,jit,rex-jit \
--bin iris --bin iris-ci
The tested iris binary reports:
iris: build features: jit rex-jit tlbvmap chd
Its SHA-256 is:
ba162566d598cb005b697e5964cc26018a96fb3c382f4c01099211019b6d964b
Configuration
headless = trueno_audio = trueci = trueci_socket = "/tmp/iris.sock"banks = [128, 128, 0, 0]
nvram = "/path/to/nvram.bin"serial_log = "/tmp/console.log"
[machine]
profile = "indy_ip24"
[jit]
enabled = true
[scsi.1]
path = "/path/to/indy.chd"cdrom = falseoverlay = true
No other JIT settings are specified, so the current defaults apply:
max_tier = 2compile_stores = falseverify = falseprobe = 500probe_min = 100
JitConfig::apply_env() converts this to IRIS_JIT=1, IRIS_JIT_MAX_TIER=2, and IRIS_JIT_NO_STORES=1 before machine creation.
Reproduction
- Remove any saved snapshot, COW overlay, CAS, and JIT profile.
- Start Iris with the build and configuration above.
- Wait for the serial login prompt.
Two independent clean runs both reached the release banner and then produced no further serial output for the remainder of a 600-second login wait:
Running power-on diagnostics...
Starting up the system...
To perform system maintenance instead, press <Esc>
IRIX Release 6.5 IP22 Version 10070055 System V
Copyright 1987-2003 Silicon Graphics, Inc.
All Rights Reserved.
The two console logs are byte-identical (314 bytes, SHA-256 69edecbe81dab5cb3d6493d77daae9a3a4ce63c239b3c35e131be5d768c1ecaf). There is no guest panic or Memory fault message in either run.
This is not an idle or crashed emulator. Iris continued consuming one host core, compiling blocks, and promoting tiers. The final periodic status from each run was:
JIT: 860007684 total (2.8% jit), 1135 blocks, 329↑ 0↓ 0⟲, probe=100(eff 100), pc=ffffffff88005840
JIT: 850008199 total (2.7% jit), 1185 blocks, 356↑ 0↓ 0⟲, probe=100(eff 100), pc=ffffffff88005840
Both waits ended only because iris-ci serial-wait reached its 600,000 ms deadline waiting for console login:.
Expected result and controls
A chd,lightning,rex-jit build from the exact same commit and base image reached login using the same procedure.
A chd,lightning,rex-jit,jitv2 build also reached login in two independent fresh runs. Its logs show JITv2 actively compiled at least 50,000 functions in each run, so those were not interpreter-only controls.
Aside: Architecture support
The README currently describes the legacy engine as translating MIPS to native x86_64. The implementation, however, uses cranelift_native::builder(), selects the host calling convention, and contains explicit aarch64 policies for speculative graduation and helper-diamond limits. It therefore builds and runs an aarch64 code generator rather than emitting x86_64 code on this host.
If Linux/aarch64 is intentionally unsupported for the legacy JIT, an explicit build-time or startup rejection would avoid silent guest misexecution. If it is intended to work, this appears to be an aarch64-specific boot regression.
Possibly related prior work
The repository already documents a legacy-JIT corruption class that can surface as an IRIX kernel TLB miss, plus architecture-specific Cranelift helper-diamond limits:
This reproduction differs in that it uses Linux/aarch64, a fresh stock 6.5.22 boot with no persisted profile, store compilation disabled, and stalls without printing a TLB-miss panic.
The legacy
jitCPU feature reproducibly stops making guest boot progress immediately after the IRIX 6.5.22 kernel banner on a native Linux/aarch64 build. The emulator remains CPU-active and continues compiling/promoting JIT blocks, but the serial console never reachesThe system is coming up.or a login prompt.The same current Iris revision, disk, PROM, NVRAM, machine configuration, and fresh-overlay procedure reach login with the interpreter/
lightningbuild and withjitv2.Revision and host
main:cfd1728d11efcf16de6072bcd7e3f158b7df19c7(fix lui-addiu-ori opcode fusion when first instruction is in bd slot)linux/arm64aarch641.99.0-nightly (d453bdd8f 2026-08-14)Cargo.lockSHA-256:b953d6606cfde79637e088c910b7ad5c0c01fba649986d5488b873692712057cThere is no amd64 container or Rosetta/QEMU translation layer in this test: both the container and the Iris executable are aarch64.
Guest and media
indy_ip24ghcr.io/sgidevnet/irix-worker@sha256:6be7c6c3f92d15705f2d08a3d1b919d6f6241b5364ced22ae0d962820e4724cda31113aae5a0c27ba2ca2ac567c76659608329ba7d0de0243d358f3571a690f5IRIX Release 6.5 IP22 Version 10070055 System VEach run starts with a newly created, empty snapshot/CAS volume. The image has no
jit-profile.bin, and no saved JIT profile is supplied.Build
The tested
irisbinary reports:Its SHA-256 is:
Configuration
No other JIT settings are specified, so the current defaults apply:
max_tier = 2compile_stores = falseverify = falseprobe = 500probe_min = 100JitConfig::apply_env()converts this toIRIS_JIT=1,IRIS_JIT_MAX_TIER=2, andIRIS_JIT_NO_STORES=1before machine creation.Reproduction
Two independent clean runs both reached the release banner and then produced no further serial output for the remainder of a 600-second login wait:
The two console logs are byte-identical (314 bytes, SHA-256
69edecbe81dab5cb3d6493d77daae9a3a4ce63c239b3c35e131be5d768c1ecaf). There is no guest panic orMemory faultmessage in either run.This is not an idle or crashed emulator. Iris continued consuming one host core, compiling blocks, and promoting tiers. The final periodic status from each run was:
Both waits ended only because
iris-ci serial-waitreached its 600,000 ms deadline waiting forconsole login:.Expected result and controls
A
chd,lightning,rex-jitbuild from the exact same commit and base image reached login using the same procedure.A
chd,lightning,rex-jit,jitv2build also reached login in two independent fresh runs. Its logs show JITv2 actively compiled at least 50,000 functions in each run, so those were not interpreter-only controls.Aside: Architecture support
The README currently describes the legacy engine as translating MIPS to native x86_64. The implementation, however, uses
cranelift_native::builder(), selects the host calling convention, and contains explicit aarch64 policies for speculative graduation and helper-diamond limits. It therefore builds and runs an aarch64 code generator rather than emitting x86_64 code on this host.If Linux/aarch64 is intentionally unsupported for the legacy JIT, an explicit build-time or startup rejection would avoid silent guest misexecution. If it is intended to work, this appears to be an aarch64-specific boot regression.
Possibly related prior work
The repository already documents a legacy-JIT corruption class that can surface as an IRIX kernel TLB miss, plus architecture-specific Cranelift helper-diamond limits:
rules/jit/premiere-windows-tlbmiss-not-disk.mdrules/jit/cranelift-regalloc2-helper-diamond-limit-is-platform-dependent.mdThis reproduction differs in that it uses Linux/aarch64, a fresh stock 6.5.22 boot with no persisted profile, store compilation disabled, and stalls without printing a TLB-miss panic.