mirror of
https://github.com/RhapsodiOS/RhapsodiOS.git
synced 2026-11-03 22:01:40 -07:00
[GH-ISSUE #71] QEMU TCG: x87 FSAVE/FRSTOR across a page boundary writes mantissas into the next physical page (kernel pcb workaround done; user programs still affected) #66
Labels
No labels
bug
documentation
enhancement
enhancement
good first issue
help wanted
help wanted
pull-request
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
github-starred/RhapsodiOS#66
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @raynorpat on GitHub (Oct 20, 2026).
Original GitHub issue: https://github.com/RhapsodiOS/RhapsodiOS/issues/71
Symptom
Under QEMU's software CPU emulation (TCG), x87
FSAVE/FNSAVE(andFRSTOR) to a 108-byte save area that crosses a 4 KB page boundary, with fewer than 8 bytes of the area on the first page, writes each 8-byte register mantissa into the next physical page instead of the next virtual page. That page belongs to someone else. The exponents and the environment block go to the right place.This silently corrupts unrelated memory. In this project it showed up as:
mmap syncread-back with 8 zeroed bytes, 2 intact bytes, then 8 zeroed bytes, atoff=0x10036(FP register 3's slot, 0x18 + 30);Cause
target/i386/tcg/access.caccess_ptr(). The bounds checkoffset <= ac->size1 - lenunderflows when fewer thanlenbytes remain on the first page, so the 8-byte store is taken as fitting in the first page's mapping and runs into the following physical page.fpstatesat at offset 124 instruct pcb(machdep/i386/thread.h:157) and pcbs are 16-byte aligned. A pcb at page offset 0xf80 putfpstateat 0xffc. Everyfnsave/frstorfor that thread (fp_support.c:290, :345, :383) then sprayed 8 mantissas at offsets 0x18 + 10*i of an unrelated physical page.Kernel workaround (done)
c54056db9:fpstateis__attribute__((aligned(16))), so a 108-byte save area never leaves fewer than 8 bytes on a page. Merged into ffs-perf in4fd6d07b6.With an FPU burner keeping a signature in all 8 x87 registers while 150 processes churn (
vm/work/ext2-sync/fpburn.c, guest RAM scanhz.py):Still open
FSAVE/FRSTORon a save area of its own placed this way is still corrupted under QEMU TCG.vm/work/ext2-sync/fsavetest.cshows it in 1000 of 1000 attempts. The kernel can't prevent that.Related: #65, #67, #68 (one-off stress failures worth re-running on a kernel with
c54056db9).@raynorpat commented on GitHub (Oct 30, 2026):
Going to close this as a wontfix