Skip to content

LATX, fix: Avoid LL/SC lowering for locked i386 operations - #420

Draft
baibaidashixiong wants to merge 1 commit into
lat-opensource:masterfrom
baibaidashixiong:steam/pr-i386-lock-lowering-futex-main
Draft

LATX, fix: Avoid LL/SC lowering for locked i386 operations#420
baibaidashixiong wants to merge 1 commit into
lat-opensource:masterfrom
baibaidashixiong:steam/pr-i386-lock-lowering-futex-main

Conversation

@baibaidashixiong

Copy link
Copy Markdown
Contributor

Summary / 变更说明

  • Steam's i386 runtime on LoongArch received EFAULT from a private
    FUTEX_WAIT even though the guest futex word remained mapped. The root
    cause is not the futex syscall itself: an unaligned i386 LOCK operand can
    enter the LL/SC interpreter fallback, which temporarily mremaps the host
    page. A concurrent host futex wait can observe that short-lived unmapped
    window.
  • Use software-lock lowering for all locked i386 instruction translators,
    including the previously separate LOCK CMPXCHG8B path. i386 uses one
    process-local lock rather than a 64-byte hash, because overlapping x86
    operands can start in different hash stripes. x86-64 keeps its existing
    lowering.
  • Release the current i386 lock owner on every nonlocal CPU-loop exit, so a
    guest page fault cannot strand the lock. This is a root-cause repair: it
    removes the temporary page migration instead of retrying a failed futex.
  • The single i386 regression combines unaligned LOCK INC, LOCK CMPXCHG8B,
    private FUTEX_WAIT and FUTEX_WAIT_BITSET, a cross-stripe overlap check,
    and a PROT_NONE fault-cleanup check. It runs the complete
    LATX_AOT=0/1 × LATX_KZT=0/1 matrix with an isolated temporary HOME for
    AOT cache files.
  • The process-local lock covers the Steam/private-mapping case. Cross-process
    MAP_SHARED x86 LOCK atomicity needs a separate shared-lock design.

Validation / 验证

  • ninja -C build32 latx-i386: passed on LoongArch64.
  • ninja -C build64 latx-x86_64: passed on LoongArch64.
  • Focused product test: all four LATX_AOT=0/1 × LATX_KZT=0/1 combinations
    passed. The AOT=1 passes share the temporary cache directory after its
    first creation.
  • Product strace of the focused test observed roughly 100,000 futex calls
    for each KZT mode, with zero futex EFAULT results and zero mremap calls.
  • meson test -C build32-tests --suite latx-integration --print-errorlogs:
    passed on the PR branch (5/5) and again after integration (6/6).
  • git diff --check: passed. Independent review found no blocking issue;
    it verified the i386 LOCK paths, CMPXCHG8B, cross-stripe overlap, and
    nonlocal-exit cleanup.
  • No performance result is claimed. The change addresses an exceptional
    correctness path rather than a throughput optimization.

Checklist / 检查项

  • I have read CONTRIBUTING.md. / 我已阅读 CONTRIBUTING.md
  • Every commit contains a DCO sign-off (git commit -s). /
    每个提交都包含 DCO 签署(git commit -s)。
  • I have included relevant build or test results, or explained why they
    are not applicable. /
    我已提供相关构建或测试结果,或说明了不适用的原因。

Steam's i386 runtime on LoongArch can receive EFAULT from a private
FUTEX_WAIT while its guest futex word remains mapped.  An unaligned i386
LOCK operand takes the LL/SC fallback through the instruction interpreter,
which temporarily mremaps the guest host page and exposes that transient
fault to a concurrent host futex wait.

Select software-lock lowering for all locked i386 instruction translators.
Use one process-local LATX lock instead of the 64-byte hash, since overlapping
x86 operands can begin in adjacent hash stripes.  Release the current CPU
owner token on every nonlocal CPU-loop exit so a guest page fault cannot
strand the lock.

Signed-off-by: zqz <OrzZzznn@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant