diff --git a/vm/loader/src/paravisor.rs b/vm/loader/src/paravisor.rs index 0cffa3c6b28..bf682d50f25 100644 --- a/vm/loader/src/paravisor.rs +++ b/vm/loader/src/paravisor.rs @@ -483,6 +483,13 @@ where )?; offset += heap_size; + // Relocating loaders only fix up identity map entries that overlap the + // relocation region, so keep the page table region sharing a large page + // with it. Otherwise the relocated cr3 is unmapped and VTL2 triple faults. + if offset.is_multiple_of(X64_LARGE_PAGE_SIZE) { + offset += HV_PAGE_SIZE; + } + // The end of memory used by the loader, excluding pagetables. let end_of_underhill_mem = offset; @@ -1242,6 +1249,12 @@ where )?; next_addr += heap_size; + // Keep the page table region sharing a large page with the relocation + // region, so the identity map entry covering it is relocated with it. + if next_addr.is_multiple_of(u64::from(Arm64PageSize::Large)) { + next_addr += HV_PAGE_SIZE; + } + // The end of memory used by the loader, excluding pagetables. let end_of_underhill_mem = next_addr;