Skip to content

LATX, fix: Translate 64-bit XSAVE and XRSTOR variants - #528

Merged
LaurenIsACoder merged 1 commit into
lat-opensource:masterfrom
xiangzhai:523
Oct 27, 2026
Merged

LaurenIsACoder merged 1 commit into
lat-opensource:masterfrom
xiangzhai:523

Conversation

@xiangzhai

Copy link
Copy Markdown
Contributor

Summary / 变更说明

由分析 #523 复现 issue: 在 AOSC 16K、4K页内核运行 /usr/lib/wine/x86_64-windows/notepad.exe 点击菜单:帮助 -> 关于记事本,均100%复现阻塞。

修复 Wine x86-64 notepad.exe 在“帮助 → 关于记事本”以及 Ctrl+F 打开对话框时
主窗口阻塞、对话框不可见的问题。

根因是 LATX 没有翻译 x86-64 的 64 位 XSAVE/XRSTOR 变体。Wine 的 syscall
dispatcher 在进入 win32u 系统调用前用 xsave64 保存 XMM6–XMM15,返回时从
syscall frame 恢复;LATX 只登记了 XSAVE、XSAVEOPT、XRSTOR,没有
XSAVE64、XSAVEOPT64、XRSTOR64。因此保存没有发生,dispatcher 返回时把
XMM6–XMM15 恢复成 frame 中的零值。

在 user32!DIALOG_CreateIndirect 中,对话框尺寸在 ClientToScreen 调用期间
保存在 XMM6 中。XMM6 被清零后,CreateWindowExW 收到 0×0 尺寸,X11 创建出
1×1 的模态窗口,主窗口因此表现为阻塞。该问题不限于“关于记事本”:Ctrl+F
“查找”对话框同样为 1×1。

本 PR 的变更:

  • target/i386/latx/translator/translate.c:将 XSAVE64、XSAVEOPT64、
    XRSTOR64 映射到已有的 32 位变体 wrapper,与现有
    FXSAVE64/FXRSTOR64 的处理方式一致。
  • tests/integration/xsave64-roundtrip.S:新增 x86-64 回归测试,设置
    XMM6/XMM7,执行 xsave64 检查保存区,再设置新值并执行 xrstor64
    检查恢复。
  • tests/integration/registrations/avx/meson.build:注册
    test-xsave64-roundtrip,由 test-avx-regressions.py 在 JIT、cold AOT、
    hot AOT 三种路径运行。
  • target/i386/latx/optimization/hbr.c、hbr-xmm-semantics.json、
    hbr-xmm-semantics.inc 及 HBR audit/metrics 测试:将三个新指令纳入 SHBR
    语义清单,保持 translator mnemonic 审计和覆盖率统计一致。

XSAVEC64/XSAVES64/XRSTORS64 没有对应的 QEMU helper,本次不映射。
实测 Wine 的 user_shared_data 中 XState.CompactionEnabled 未启用,
dispatcher 走 xsave64 分支而不是 xsavec64,因此不影响本 issue;若以后
启用 compaction,需要作为独立工作处理。

Why HBR is updated / 为什么需要修改 HBR

translate.c 只决定指令“能不能执行”;HBR/SHBR 还需要知道它对 XMM/YMM
状态的数据流语义,才能安全地做高 128 位相关的优化和状态复用。因此新增
XSAVE64/XSAVEOPT64/XRSTOR64 后,HBR 侧必须同步:

  1. 审计门禁要求同步
    scripts/latx_hbr_audit.py 会解析 translate.c 中的
    TRANS_FUNC_GEN(...),对 translator mnemonic 集合计算 SHA-256,并与
    hbr-xmm-semantics.json 的期望值比较;同时检查计数、inventory 覆盖和
    生成的规则表。新增三个 mnemonic 后,完整性检查报:

    translator mnemonic set drift: expected ... actual ...
    

    直接导致 test-latx-hbr-audit 和 test-latx-hbr-metrics 失败。

  2. HBR 优化需要正确的隐式 XMM 语义
    这三个指令会读写全部 XMM 状态:

    • XSAVE64/XSAVEOPT64:隐式读取全部 XMM(保存状态);
    • XRSTOR64:隐式读写全部 XMM(恢复状态)。

    如果 HBR 不把它们标记为 implicit-all-XMM,优化器可能错误地认为 XMM
    高 128 位在指令前后保持不变,进而做出不安全的消除或复用。它们必须与
    已有的 32 位 XSAVE/XSAVEOPT/XRSTOR 使用相同策略。

具体同步内容:

  • hbr-xmm-semantics.json:将三个指令加入 legacy inventory,配置
    implicit-read-all / implicit-read-write-all,并更新计数与 mnemonic
    哈希;
  • hbr.c:在 apply_implicit_semantic() 和
    has_implicit_semantic() 中加入对应 case,使运行时真正采用这些语义;
  • hbr-xmm-semantics.inc:由 JSON 重新生成规则表;
  • test_latx_hbr_audit.py/test_latx_hbr_metrics.py:更新审计和覆盖率
    期望值(translator_supported 1098→1101、相关计数 774→777、生成规则
    519→522)。

简言之:translate.c 让新指令“能跑”,HBR 相关修改让它们“被正确分析和
优化”,并让项目强制的语义审计保持通过;这不是单纯为了更新哈希。

Validation / 验证

Root cause evidence / 根因证据

Wine trace 中对话框模板和 AdjustWindowRectEx 输入都是正确的,但
CreateWindowExW 收到 0×0 尺寸:

trace:dialog:DIALOG_ParseTemplate32 DIALOG 15, 40, 225, 152, 0
trace:dialog:DIALOG_CreateIndirect units = 10,21
trace:system:AdjustWindowRectEx ((0,0)-(563,399)) 90c800c4 0 00010001
trace:win:WIN_CreateWindowEx L"关于 %s" #8002->L"#32770" ... 376,281 0x0 ...
trace:win:NtUserCreateWindowEx ... x 376, y 281, cx 0, cy 0 ...

user32!DIALOG_CreateIndirect 在 AdjustWindowRectEx 后用 psubd 把尺寸放入
XMM6,随后调用 ClientToScreen;Wine x86-64 dispatcher 的
__wine_syscall_dispatcher 使用 xsave64 保存 XMM6–XMM15,并用
movaps 0x1c0(%rcx),%xmm6 ... 0x250(%rcx),%xmm15 恢复。

freestanding x86-64 指令测试(不经过 Wine)复现了 LATX 的缺口:

指令 保存 XMM6/XMM7 恢复 XMM6/XMM7
xsave / xrstor(无 REX.W) 正确 正确
xsave64 / xrstor64(REX.W) 保存为 0 不恢复
xsaveopt64 保存为 0 不恢复
fxsave64 / fxrstor64 正确 正确

编码差异仅为 REX.W:

0f ae 23        xsave  (%rbx)
48 0f ae 23     xsave64 (%rbx)

修复前用户可见结果为 1×1 的 关于 记事本 窗口;修复后为正常尺寸并完整
绘制控件。

Regression tests / 回归测试

新增测试在修复前为 RED,修复后为 GREEN:

# 修复前(旧 /home/zhaixiang/latx-x86_64)
python3 tests/integration/test-avx-regressions.py \
  /home/zhaixiang/latx-x86_64 tests/integration/xsave64-roundtrip.S
  FAIL: xsave64-roundtrip.S (guest exit 1)

# 修复后
python3 tests/integration/test-avx-regressions.py \
  /home/zhaixiang/latx-x86_64 tests/integration/xsave64-roundtrip.S
  PASS: xsave64-roundtrip.S

# JIT + cold AOT + hot AOT,同时运行相邻 AVX 回归
python3 tests/integration/test-avx-regressions.py \
  build64/latx-x86_64 \
  tests/integration/ymmh-tb-fallthrough.S \
  tests/integration/avx128-shuffle.S \
  tests/integration/vcomis-jcc.S \
  tests/integration/xsave64-roundtrip.S
  PASS: ymmh-tb-fallthrough.S
  PASS: avx128-shuffle.S
  PASS: vcomis-jcc.S
  PASS: xsave64-roundtrip.S

Semantics / 语义验证

  • 指令级:xsave64/xrstor64 现在与 xsave/xrstor 一样能正确保存和恢复
    XMM6/XMM7;xsaveopt64 同样正常;fxsave64 原有行为不变。
  • Wine ABI 级:用 native PE 测试程序在 Wine 中调用
    GetDesktopWindow、ClientToScreen、GetSystemMetrics,调用前后
    XMM6/XMM7 均保持测试模式值;修复前这些调用会把它们清零。
  • 应用级:原复现“帮助 → 关于记事本”现在显示完整对话框(X client 区
    563×399,内部 AdjustWindowRectEx 后窗口尺寸 569×431),控件和 Wine
    开发者列表均正常绘制;关闭后主窗口恢复响应。Ctrl+F “查找”对话框
    显示为 552×132。

Full suites / 完整套件

使用全新的 Meson 构建目录(x86_64 + i386,--enable-tests,
--enable-latx-avx-opt,--optimize-O1)运行;.asm AVX fixture 使用本地
构建的 nasm 2.16.03 加入 PATH。

# lat-pr-fast
LATX_RUNTIME_TEST_SKIP_GUEST_EXECUTION=1 meson test \
  -C <build64-tests> --suite lat-pr-fast --print-errorlogs
  Ok: 51  Fail: 0

# latx-integration
meson test -C <build64-tests> --suite latx-integration \
  --print-errorlogs --num-processes 4
  Ok: 72  Fail: 8  Skipped: 22

test-xsave64-roundtrip 在 JIT、cold AOT、hot AOT 三种路径均通过。
latx-integration 的 8 个失败均为既有环境/工具链问题,不是本变更引入:

  • 5 个 test-rip-relative-cache-*:测试注册把 LATX_AVX_PREBUILT 设为
    空字符串,runner 的 argparse 将 Path('') 变成 .,误走 prebuilt
    路径;不设置该环境变量直接运行同一 fixture 可以通过。
  • 1 个 test-avx-single-instruction:clang 22 无法汇编其中的
    avx-regression-vround-boundaries.S(“cannot use more than one symbol
    in memory operand”);同一组其余 13 个 fixture 均通过。
  • 1 个 test-prctl-x86-privileged:clang 22 的 freestanding 链接缺少
    memset 符号。
  • 1 个 test-prctl-x86-semantics:p 用例返回 52;用修复前的备份二进制
    运行结果相同,属于既有环境行为。

22 个 SKIP 是需要额外权限、namespace 或内核特性的测试(exit 77),属于
环境跳过的预期结果。

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. /
    我已提供相关构建或测试结果,或说明了不适用的原因。

Translate XSAVE64, XSAVEOPT64, and XRSTOR64 with the existing XSAVE/XRSTOR wrappers, matching the FXSAVE64/FXRSTOR64 handling. Wine's x86-64 syscall dispatcher uses xsave64 to preserve the non-volatile XMM6-XMM15 registers across win32u calls. The missing translation left those registers zeroed, so notepad's About and Find dialogs were created with zero size and appeared as invisible 1x1 modal windows.

Add an x86-64 integration regression that round-trips XMM6/XMM7 through xsave64/xrstor64 in JIT, cold AOT, and hot AOT paths.

Update the SHBR inventory, implicit-semantics model, and audit expectations for the new 64-bit XSAVE variants so translator coverage stays consistent.

Classify the 64-bit XSAVE variants as required softfpu regions so LATX_SOFTFPU=2 saves and restores XMM and high GPR state around the helpers.

Fixes Wine notepad Help->About and Ctrl+F on LoongArch hosts.

Signed-off-by: Leslie Zhai <xiangzhai83@gmail.com>
@LaurenIsACoder
LaurenIsACoder merged commit f3079a4 into lat-opensource:master Oct 27, 2026
26 checks passed
@xiangzhai

Copy link
Copy Markdown
Contributor Author

Thanks!

@xiangzhai
xiangzhai deleted the 523 branch October 27, 2026 12:53
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.

2 participants