Skip to content
This repository has been archived by the owner on Jan 28, 2023. It is now read-only.

Fixed PAE issues #152

Merged
merged 2 commits into from
Jan 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion core/include/vcpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ struct vcpu_t {
uint64_t fs_base_dirty : 1;
uint64_t interruptibility_dirty : 1;
uint64_t pcpu_ctls_dirty : 1;
uint64_t padding : 46;
uint64_t pae_pdpt_dirty : 1;
uint64_t padding : 45;
};

/* For TSC offseting feature*/
Expand Down
17 changes: 11 additions & 6 deletions core/page_walker.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,8 @@ uint32_t pw_perform_page_walk(
first_table = pw_retrieve_table_from_cr3(cr3, is_pae, is_lme);

if (is_pae) {
uint8_t *pdpt_page_hva;

if (is_lme) {
pml4t_gpa = first_table;
#ifdef CONFIG_HAX_EPT2
Expand Down Expand Up @@ -655,21 +657,24 @@ uint32_t pw_perform_page_walk(
}

#ifdef CONFIG_HAX_EPT2
pdpt_hva = gpa_space_map_page(&vcpu->vm->gpa_space,
pdpt_gpa >> PG_ORDER_4K,
&pdpt_kmap, NULL);
pdpt_page_hva = gpa_space_map_page(&vcpu->vm->gpa_space,
pdpt_gpa >> PG_ORDER_4K,
&pdpt_kmap, NULL);
#else // !CONFIG_HAX_EPT2
#ifdef HAX_ARCH_X86_32
pdpt_hva = hax_map_gpfn(vcpu->vm, pdpt_gpa >> 12, is_kernel, cr3, 1);
pdpt_page_hva = hax_map_gpfn(vcpu->vm, pdpt_gpa >> 12, is_kernel, cr3, 1);
#else
pdpt_hva = hax_map_gpfn(vcpu->vm, pdpt_gpa >> 12);
pdpt_page_hva = hax_map_gpfn(vcpu->vm, pdpt_gpa >> 12);
#endif
#endif // CONFIG_HAX_EPT2
if (pdpt_hva == NULL) {
if (pdpt_page_hva == NULL) {
retval = TF_FAILED;
goto out;
}

// In PAE paging mode, pdpt_gpa is 32-byte aligned, not 4KB-aligned
pdpt_hva = pdpt_page_hva + (uint)(pdpt_gpa & (PAGE_SIZE_4K - 1));

pdpte_ptr = pw_retrieve_table_entry(vcpu, pdpt_hva, pdpte_index,
is_pae);
pw_read_entry_value(&pdpte_val, pdpte_ptr, is_pae);
Expand Down
19 changes: 13 additions & 6 deletions core/vcpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1859,6 +1859,7 @@ static int vcpu_prepare_pae_pdpt(struct vcpu_t *vcpu)
cr3, ret);
return ret < 0 ? ret : -EIO;
}
vcpu->pae_pdpt_dirty = 1;
return 0;
#else // !CONFIG_HAX_EPT2
uint64_t gpfn = (cr3 & 0xfffff000) >> PG_ORDER_4K;
Expand All @@ -1880,6 +1881,7 @@ static int vcpu_prepare_pae_pdpt(struct vcpu_t *vcpu)
#else // !HAX_ARCH_X86_64, i.e. HAX_ARCH_X86_32
hax_unmap_gpfn(vcpu->vm, buf, gpfn);
#endif // HAX_ARCH_X86_64
vcpu->pae_pdpt_dirty = 1;
return 0;
#endif // CONFIG_HAX_EPT2
}
Expand Down Expand Up @@ -1966,16 +1968,21 @@ static void vmwrite_cr(struct vcpu_t *vcpu)
// eptp);
vmwrite(vcpu, GUEST_CR3, state->_cr3);
scpu_ctls |= ENABLE_EPT;
// Set PDPTEs for vCPU if it's in or about to enter PAE paging mode
if ((state->_cr4 & CR4_PAE) && !(state->_efer & IA32_EFER_LME) &&
(state->_cr0 & CR0_PG)) {
// vcpu_prepare_pae_pdpt() has populated vcpu->pae_pdptes
// TODO: Enable CR3_LOAD_EXITING so as to update vcpu->pae_pdptes
// whenever guest writes to CR3 in EPT+PAE mode
if (vcpu->pae_pdpt_dirty) {
// vcpu_prepare_pae_pdpt() has updated vcpu->pae_pdptes
// Note that because we do not monitor guest writes to CR3, the only
// case where vcpu->pae_pdptes is newer than VMCS GUEST_PDPTE{0..3}
// is following a guest write to CR0 or CR4 that requires PDPTEs to
// be reloaded, i.e. the pae_pdpt_dirty case. When the guest is in
// PAE paging mode but !pae_pdpt_dirty, VMCS GUEST_PDPTE{0..3} are
// already up-to-date following each VM exit (see Intel SDM Vol. 3C
// 27.3.4), and we must not overwrite them with our cached values
// (vcpu->pae_pdptes), which may be outdated.
vmwrite(vcpu, GUEST_PDPTE0, vcpu->pae_pdptes[0]);
vmwrite(vcpu, GUEST_PDPTE1, vcpu->pae_pdptes[1]);
vmwrite(vcpu, GUEST_PDPTE2, vcpu->pae_pdptes[2]);
vmwrite(vcpu, GUEST_PDPTE3, vcpu->pae_pdptes[3]);
vcpu->pae_pdpt_dirty = 0;
}
vmwrite(vcpu, VMX_EPTP, eptp);
// pcpu_ctls |= RDTSC_EXITING;
Expand Down