Skip to content
This repository has been archived by the owner on Jul 11, 2024. It is now read-only.

Commit

Permalink
Changed create_eptp_with_wb_and_4lvl_walk to be called from self.
Browse files Browse the repository at this point in the history
  • Loading branch information
memN0ps committed Dec 21, 2023
1 parent ce4f4d6 commit bd36fed
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 10 deletions.
21 changes: 13 additions & 8 deletions hypervisor/src/intel/ept/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,24 +127,29 @@ impl Ept {
/// It encodes the provided physical base address of the EPT PML4 table into the EPTP format, setting
/// the memory type to Write-Back and indicating a 4-level page walk.
///
/// # Arguments
/// * `ept_pml4_base_addr` - The physical base address of the EPT PML4 table. This address must be 4KB aligned.
///
/// # Returns
/// A `Result<u64, HypervisorError>` containing the configured EPTP value. Returns an error if
/// the base address is not properly aligned.
///
/// Reference: Intel® 64 and IA-32 Architectures Software Developer's Manual: 25.6.11 Extended-Page-Table Pointer (EPTP)
pub fn create_eptp_with_wb_and_4lvl_walk(
ept_pml4_base_addr: u64,
) -> Result<u64, HypervisorError> {
/// Reference: Intel® 64 and IA-32 Architectures Software Developer's Manual: 28.2.6 EPT Paging-Structure Entries
pub fn create_eptp_with_wb_and_4lvl_walk(&self) -> Result<u64, HypervisorError> {
// Get the virtual address of the PML4 table for EPT.
let addr = addr_of!(self.pml4) as u64;

// Get the physical address of the PML4 table for EPT.
let ept_pml4_base_addr = PhysicalAddress::pa_from_va(addr);

// Represents the EPT page walk length for Intel VT-x, specifically for a 4-level page walk.
// The value is 3 (encoded as '3 << 3' in EPTP) because the EPTP encoding requires "number of levels minus one".
const EPT_PAGE_WALK_LENGTH_4: u64 = 3 << 3;

// Represents the memory type setting for Write-Back (WB) in the EPTP.
const EPT_MEMORY_TYPE_WB: u64 = Mtrr::WriteBack as u64;

// Check if the base address is 4KB aligned (the lower 12 bits should be zero).
if ept_pml4_base_addr.trailing_zeros() >= 12 {
Ok(ept_pml4_base_addr | EPT_PAGE_WALK_LENGTH_4 | Mtrr::WriteBack as u64)
// Construct the EPTP with the page walk length and memory type for WB.
Ok(ept_pml4_base_addr | EPT_PAGE_WALK_LENGTH_4 | EPT_MEMORY_TYPE_WB)
} else {
Err(HypervisorError::InvalidEptPml4BaseAddress)
}
Expand Down
8 changes: 6 additions & 2 deletions hypervisor/src/intel/vmcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,10 @@ impl Vmcs {
#[rustfmt::skip]
pub fn setup_host_registers_state(context: &CONTEXT, host_descriptor_table: &Box<DescriptorTables, KernelAlloc>, host_paging: &Box<PageTables, PhysicalAllocator>) -> Result<(), HypervisorError> {
unsafe { vmwrite(vmcs::host::CR0, controlregs::cr0().bits() as u64) };
vmwrite(vmcs::host::CR3, host_paging.get_pml4_pa()?);

let pml4_pa = host_paging.get_pml4_pa()?;
vmwrite(vmcs::host::CR3, pml4_pa);

unsafe { vmwrite(vmcs::host::CR4, controlregs::cr4().bits() as u64) };

// The RIP/RSP registers are set within `launch_vm`.
Expand Down Expand Up @@ -280,7 +283,8 @@ impl Vmcs {

vmwrite(vmcs::control::MSR_BITMAPS_ADDR_FULL, PhysicalAddress::pa_from_va(msr_bitmap.as_ref() as *const _ as _));

let eptp = Ept::create_eptp_with_wb_and_4lvl_walk(PhysicalAddress::pa_from_va(ept.as_ref() as *const _ as _))?;
let eptp = ept.create_eptp_with_wb_and_4lvl_walk()?;

vmwrite(vmcs::control::EPTP_FULL, eptp);
vmwrite(vmcs::control::VPID, VPID_TAG);

Expand Down

0 comments on commit bd36fed

Please sign in to comment.