Skip to content

loader: fix page table relocation identity mapping - #4380

Closed
Ben Hillis (benhillis) wants to merge 1 commit into
microsoft:release/1.8.2607from
benhillis:backport/1.8.2607/pt-align-fix
Closed

loader: fix page table relocation identity mapping#4380
Ben Hillis (benhillis) wants to merge 1 commit into
microsoft:release/1.8.2607from
benhillis:backport/1.8.2607/pt-align-fix

Conversation

@benhillis

@benhillis Ben Hillis (benhillis) commented Sep 3, 2026

Copy link
Copy Markdown
Member

Backport of the page table relocation fix to release/1.8.2607. Opened ahead of the main PR because 1.8 is currently red.

A relocating loader must keep the page table region identity mapped (VA = PA) after it moves it. Both the OpenVMM loader and the Hyper-V loader only fixed up identity map entries against the IGVM_VHS_RELOCATABLE_REGION range, so a page table region starting exactly on a large page boundary kept its pre-relocation VA, leaving the relocated root unmapped:

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

Latent — the region start is the running total of everything loaded before it, so unrelated image growth decides whether it lands on the boundary. 1.8 landed on 0xca00000 and every test that relocates VTL2 failed.

Two commits:

  1. Loader fix. Include the page table region in the relocation map so its own identity mapping is fixed up. Correct at any alignment.
  2. Image-side mitigation. Pad by a page so the region never starts on a large page boundary. Needed because already-shipped Hyper-V loaders have the same defect and cannot be fixed from here. The two regions stay disjoint, as the spec requires.

The upstream crate fix is microsoft/igvm#135, which fixes this for all consumers of PageTableRelocationBuilder; the Hyper-V loader needs an equivalent fix separately.

The paravisor page table region is placed immediately after the
relocation region and is deliberately excluded from it, but the boot
identity map uses large pages. A loader performing relocation only fixes
up a leaf entry when the region it maps overlaps the relocation region
(igvm PageTableRelocationBuilder::recurse_fixup uses RangeMap::get_range,
which matches on overlap).

When the page table region happens to begin exactly on a large page
boundary, the leaf entry mapping it does not overlap the relocation
region at all and is left identity mapped at its pre-relocation address.
cr3 and the page table pages themselves are relocated, so the relocated
cr3 has no mapping and the first access to the page tables through the
identity map faults with no IDT loaded, triple faulting the VP during
boot shim startup.

This has been latent and only reproduces when unrelated image growth
lands the region on the boundary. Pad by a page so the page table region
always shares a large page with the relocation region.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings September 3, 2026 18:22
@benhillis
Ben Hillis (benhillis) requested a review from a team as a code owner September 3, 2026 18:22
@github-actions github-actions Bot added the release_1.8.2607 Targets the release/1.8.2607 branch. label Sep 3, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The change affects early boot/relocation behavior where failures are severe (triple faults) and should receive final human review despite the small diff.

Pull request overview

This PR backports a boot-shim relocation fix into the 1.8 release branch by ensuring the page-table region does not begin exactly on a large-page (2 MiB) boundary, preventing a relocated cr3 from becoming unmapped under large-page identity mapping.

Changes:

  • Add a conditional 4 KiB pad in the x64 loader when the post-relocation offset lands on a 2 MiB boundary, so the page-table region shares the same 2 MiB leaf mapping as the relocation region.
  • Apply the same conditional padding logic in the arm64 loader (using Arm64PageSize::Large as the large-page size).
  • Add detailed in-code rationale documenting the relocation/identity-map interaction that causes the triple fault.
File summaries
File Description
vm/loader/src/paravisor.rs Adds conditional 4 KiB padding before the page-table region for x64 and arm64 to avoid large-page-boundary mis-relocation and prevent early triple faults.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@benhillis

Copy link
Copy Markdown
Member Author

Main PR: #4382

@benhillis Ben Hillis (benhillis) changed the title [1.8] loader: keep the page table region off a large page boundary loader: fix page table relocation identity mapping Sep 3, 2026
@benhillis

Copy link
Copy Markdown
Member Author

Superseded by #4384, which carries both the loader fix and the image-side mitigation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release_1.8.2607 Targets the release/1.8.2607 branch.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants