diff --git a/hypervisor/arch/x86/guest/guest_memory.c b/hypervisor/arch/x86/guest/guest_memory.c index 6c3c85db4..0b9934272 100644 --- a/hypervisor/arch/x86/guest/guest_memory.c +++ b/hypervisor/arch/x86/guest/guest_memory.c @@ -211,7 +211,7 @@ static int32_t local_gva2gpa_pae(struct acrn_vcpu *vcpu, struct page_walk_info * uint64_t addr; int32_t ret = -EFAULT; - addr = pw_info->top_entry & 0xFFFFFFF0U; + addr = get_pae_pdpt_addr(pw_info->top_entry); base = (uint64_t *)gpa2hva(vcpu->vm, addr); if (base != NULL) { index = (gva >> 30U) & 0x3UL; diff --git a/hypervisor/arch/x86/guest/virtual_cr.c b/hypervisor/arch/x86/guest/virtual_cr.c index 64ba58f4c..397400b0c 100644 --- a/hypervisor/arch/x86/guest/virtual_cr.c +++ b/hypervisor/arch/x86/guest/virtual_cr.c @@ -43,7 +43,7 @@ static void load_pdptrs(const struct acrn_vcpu *vcpu) { uint64_t guest_cr3 = exec_vmread(VMX_GUEST_CR3); /* TODO: check whether guest cr3 is valid */ - uint64_t *guest_cr3_hva = (uint64_t *)gpa2hva(vcpu->vm, guest_cr3); + uint64_t *guest_cr3_hva = (uint64_t *)gpa2hva(vcpu->vm, get_pae_pdpt_addr(guest_cr3)); stac(); exec_vmwrite64(VMX_GUEST_PDPTE0_FULL, get_pgentry(guest_cr3_hva + 0UL)); diff --git a/hypervisor/include/arch/x86/mmu.h b/hypervisor/include/arch/x86/mmu.h index 2df20f526..b307e03b2 100644 --- a/hypervisor/include/arch/x86/mmu.h +++ b/hypervisor/include/arch/x86/mmu.h @@ -176,6 +176,11 @@ static inline void clflush(volatile void *p) asm volatile ("clflush (%0)" :: "r"(p)); } +/* get PDPT address from CR3 vaule in PAE mode */ +static inline uint64_t get_pae_pdpt_addr(uint64_t cr3) +{ + return (cr3 & 0xFFFFFFE0UL); +} /** * @}