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

Commit

Permalink
Added functions to unmap guest and large pages (unhook)
Browse files Browse the repository at this point in the history
  • Loading branch information
memN0ps committed Jul 30, 2024
1 parent aed592d commit ccc2452
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 0 deletions.
6 changes: 6 additions & 0 deletions hypervisor/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,4 +238,10 @@ pub enum HypervisorError {

#[error("EPT misconfiguration error")]
EptMisconfiguration,

#[error("Large page table unmapping error")]
LargePageUnmapError,

#[error("Guest page table unmapping error")]
GuestPageUnmapError,
}
4 changes: 4 additions & 0 deletions hypervisor/src/intel/hooks/hook_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,10 @@ impl HookManager {
vm.primary_ept
.swap_page(guest_page_pa.as_u64(), guest_page_pa.as_u64(), AccessType::READ_WRITE_EXECUTE, pre_alloc_pt)?;

// Update the memory manager to indicate that the guest page is no longer processed (unmapped/unhooked).
// This will allow the page to be reprocessed/remapped/rehooked if needed.
self.memory_manager.unmap_guest_from_shadow_page(guest_page_pa.as_u64())?;

Ok(())
}

Expand Down
40 changes: 40 additions & 0 deletions hypervisor/src/intel/hooks/memory_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,46 @@ impl MemoryManager {
Ok(())
}

/// Unmaps a shadow page from a guest physical address, removing the associated hooks.
///
/// # Arguments
/// * `guest_page_pa` - The guest physical address to unmap.
///
/// # Returns
/// `Ok(())` if successful, or an error if the page was not mapped.
pub fn unmap_guest_from_shadow_page(&mut self, guest_page_pa: u64) -> Result<(), HypervisorError> {
trace!("Unmapping guest page and shadow page for PA: {:#x}", guest_page_pa);

// Remove the mapping if it exists
if self.guest_page_mappings.remove(&guest_page_pa).is_some() {
trace!("Guest page unmapped from shadow page successfully");
Ok(())
} else {
trace!("Guest page PA: {:#x} was not mapped", guest_page_pa);
Err(HypervisorError::GuestPageUnmapError)
}
}

/// Unmaps a page table from a large guest physical address.
///
/// # Arguments
/// * `guest_large_page_pa` - The large guest physical address to unmap.
///
/// # Returns
/// `Ok(())` if successful, or an error if the page table was not mapped.
pub fn unmap_large_page_from_pt(&mut self, guest_large_page_pa: u64) -> Result<(), HypervisorError> {
trace!("Unmapping large page and page table for PA: {:#x}", guest_large_page_pa);

// Remove the mapping if it exists
if self.large_page_table_mappings.remove(&guest_large_page_pa).is_some() {
trace!("Large page unmapped from page table successfully");
Ok(())
} else {
trace!("Large page PA: {:#x} was not mapped", guest_large_page_pa);
Err(HypervisorError::LargePageUnmapError)
}
}

/// Retrieves a mutable reference to the page table associated with a large guest physical address.
///
/// # Arguments
Expand Down

0 comments on commit ccc2452

Please sign in to comment.