Skip to content

target/i386: emulate LAM in TCG

Tim qemu-devel 1 version New

Get series with b4
b4 am [email protected]

Versions newest first

  1. v1 Latest4 patches 0 repliesNew

Patches in v1 No applies recorded yet

#Subject and filesSizeRepliesApplied
1/4target/i386: mask the PML5 table address taken from CR3target/i386/helper.c target/i386/tcg/system/excp_helper.c+3 -20 replies
2/4accel/tcg: compare large pages under the flush maskaccel/tcg/cputlb.c+3 -10 replies
3/4target/i386: emulate LAM in TCGtarget/i386/cpu.c target/i386/cpu.h target/i386/helper.c +3 more+102 -90 replies
4/4tests/tcg/x86_64: add a LAM system testtests/tcg/x86_64/system/boot.S tests/tcg/x86_64/system/lam.c tests/tcg/x86_64/system/meson.build+826 -00 replies

Reviews trailers per patch

No Reviewed-by, Acked-by or Tested-by trailers for v1 yet.

Read the v1 thread

Cover letter [PATCH 0/4] target/i386: emulate LAM in TCG

This series emulates LAM in TCG for x86_64 system mode and reports it in "-cpu max". linux-user support will follow in a separate series.

Patch 1 keeps the CR3 LAM bits out of the PML5 table address. Patch 2 makes the large-page check in tlb_flush_range_locked() compare under the flush mask, as agreed in [2]. Patch 3 is the LAM emulation, and patch 4 adds a system-mode test.

The design follows the RFC thread [1]:

- On a TLB miss, get_physical_address() masks the address and runs the canonical check and the page walk on the result. The entry is installed under the tagged address, so each tag of a page has its own entry. INVLPG and INVLPGA flush every tagged alias with tlb_flush_page_bits_by_mmuidx(), and a change of CR4.LAM_SUP flushes the TLB.

- Instruction fetches are not masked. If masking changes the address, an entry filled by a data access is not executable, and an entry filled by a fetch is not readable or writable.

- Exceptions do not report the tagged address, which answers Richard's question [3]. On #PF, CR2 receives the masked address (SDM Vol. 3A, section 4.4.3), and #GP reports no address.

- gdbstub, monitor, and qemu_plugin_translate_vaddr() translate a tagged address as a data access does.

Known gaps:

- Data breakpoints on an untagged address do not fire for accesses through a tagged alias.

- With LAM_U48 and 5-level paging, gdbstub, monitor, and qemu_plugin_translate_vaddr() translate an instruction address at or above 2^47 as a data address, not as a fetch does.

[1] https://lists.nongnu.org/archive/html/qemu-devel/2026-10/msg01840.html
[2] https://lists.nongnu.org/archive/html/qemu-devel/2026-11/msg01599.html
[3] https://lists.nongnu.org/archive/html/qemu-devel/2026-10/msg05620.html

Tim (4):
target/i386: mask the PML5 table address taken from CR3 accel/tcg: compare large pages under the flush mask target/i386: emulate LAM in TCG tests/tcg/x86_64: add a LAM system test

 accel/tcg/cputlb.c                   |   4 +-
 target/i386/cpu.c                    |   2 +-
 target/i386/cpu.h                    |  46 ++
 target/i386/helper.c                 |   8 +-
 target/i386/tcg/system/excp_helper.c |  33 +-
 target/i386/tcg/system/misc_helper.c |  24 +-
 target/i386/tcg/system/svm_helper.c  |   3 +-
 tests/tcg/x86_64/system/boot.S       |  14 +
 tests/tcg/x86_64/system/lam.c        | 797 +++++++++++++++++++++++++++
 tests/tcg/x86_64/system/meson.build  |  15 +
 10 files changed, 934 insertions(+), 12 deletions(-)
 create mode 100644 tests/tcg/x86_64/system/lam.c
Signature · 1 line
2.47.3