Why does this x86_64 self-modifying loop work on bare metal / QEMU, but Segfaults only on native Linux under high CPU load? #203834
Replies: 1 comment
|
Hi @studioframes! This issue comes down to two hardware-level phenomena on modern x86_64 CPUs: Store Buffer vs. IFU race conditions and Cache-Line Tearing. 1. Store Buffer vs. IFU (Stale Data)The Instruction Fetch Unit (IFU) fetches from L1i and does not snoop the CPU's local Store Buffer. Under heavy CPU load, the updated immediate value written by 2. Cache-Line Tearing (Segfaults)Your 8-byte immediate ( Why QEMU works: QEMU (TCG) translates blocks sequentially and invalidates Translation Blocks synchronously, bypassing store buffer mechanics entirely. How to Fix ItOption A: Avoid SMC in Tight Loops (Recommended) mov rax, 0x1122334455667788
.loop:
; ... do work ...
add rax, 1
dec rbx
jnz .loopOption B: Alignment + Serialization (If SMC is required)
.loop:
mov rax, 0x1122334455667788
patch_target equ $ - 8
add qword [rel patch_target], 1
mfence
serialize ; or cpuid on older CPUs
dec rbx
jnz .loop |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
🏷️ Discussion Type
Question
💬 Feature/Topic Area
Assembly / x86_64 Architecture
Body
Hey everyone,
I'm writing a lightweight x86_64 JIT engine, and I ran into a bizarre hardware/kernel-level issue that I can't wrap my head around.
I have a small routine that dynamically patches its own immediate values inside a loop:
The Problem:
.textsegment as readable, writable, and executable (-z execstack/mprotect(PROT_READ | PROT_WRITE | PROT_EXEC)).Segmentation fault (core dumped)or executes with stale data insideRAXon every ~5th run.Is this an L1 Instruction Cache (i-cache) pipeline coherency issue where the CPU prefetches the unpatched instruction before
add qwordcommits to memory, or am I violating alignment requirements for RIP-relative addressing on 64-bit ModR/M bytes?Do I need an explicit
MFENCE/SERIALIZEinstruction here, or is Linux handling page fault permissions asynchronously?Guidelines
All reactions