Skip to content

page_table: relocate the page table region's own identity mapping - #135

Merged
Chris Oo (chris-oo) merged 1 commit into
microsoft:mainfrom
benhillis:pt-reloc-own-region
Sep 3, 2026
Merged

page_table: relocate the page table region's own identity mapping#135
Chris Oo (chris-oo) merged 1 commit into
microsoft:mainfrom
benhillis:pt-reloc-own-region

Conversation

@benhillis

Copy link
Copy Markdown
Member

The page table region is declared relocatable by its own IGVM_VHS_PAGE_TABLE_RELOCATION header, and the spec requires the page table to stay identity mapped (VA = PA):

The page table must map the address space as identity mapped, with VA = PA.

Page table entries that map ranges that have been relocated are also further fixed up. The entry must be moved to the new identity mapped VA corresponding to where the region was relocated to.

build moves the region and fixes up the root, but only fixed up leaf entries against the caller-supplied relocation_offsets, which per its own doc comment describe other ranges. A leaf entry mapping the page table region was therefore left at its pre-relocation VA, so the relocated root ended up unmapped.

This was masked whenever the leaf covering the page table region also happened to overlap a caller-supplied range, which is the common case. It only reproduces when the region starts exactly on a large page boundary and so has no overlap — for a 2 MiB leaf that is roughly 1 in 512, decided by unrelated image growth.

Found via OpenHCL, where it triple faulted VTL2 on the first page table access with no IDT loaded:

triple fault vtl=Vtl2 vp=0x0
  faulting instruction "mov r13,[r12+0FF8h]"
  r12=0x1a4a00000  cr3=0x1a4a00000  cr2=0x80  idtr base=0 limit=ffff

Fixed in build, which already knows the region (gpa, size) and its offset, so consumers cannot get this wrong.

Adds builder_relocates_own_region, which relocates a page table whose only leaf maps the region itself with no caller-supplied ranges, and asserts the new location is identity mapped and the stale mapping is gone. Without the fix it fails with the relocated root unmapped.

The page table region is declared relocatable by its own header and the
spec requires it stay identity mapped (VA = PA). `build` moved the
region and fixed up the root, but only fixed up leaf entries against the
caller-supplied ranges, which per the documented contract describe other
regions. A leaf mapping the page table region was therefore left at its
pre-relocation VA, leaving the relocated root unmapped.

This was masked whenever the leaf covering the page table region also
happened to overlap a caller-supplied range, so it only reproduced when
the region started exactly on a large page boundary.

Fix it up in `build`, which already knows the region and its offset, so
consumers cannot get this wrong.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@benhillis
Ben Hillis (benhillis) requested a review from a team as a code owner September 3, 2026 21:09
@chris-oo
Chris Oo (chris-oo) merged commit b7e717d into microsoft:main Sep 3, 2026
6 checks passed
Ben Hillis (benhillis) added a commit to microsoft/openvmm that referenced this pull request Sep 4, 2026
Updates IGVM to microsoft/igvm#135 so relocation also fixes the page
table region's own identity mapping.

Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Copilot-Session: ee248446-5a9b-4674-9840-636045767f48
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.

3 participants