kernel/arch/x86_64/mm/vmm/paging/
unmap.rs1use super::helpers::{advance_current_pagetable, is_huge_page, is_present};
7use crate::lib::addr::VirtAddr;
8use crate::mm::vmm::{VmmError, VmmResult};
9use x86_64::instructions::tlb;
10use x86_64::structures::paging::page_table::PageTableEntry;
11use x86_64::structures::paging::PageTable;
12
13pub unsafe fn unmap_page(
14 page_ptr: VirtAddr,
15 virt: VirtAddr
16) -> VmmResult {
17 #[cfg(feature = "debug-checks")]
18 {
19 use crate::mm::pmm::FRAME_SIZE;
20 use super::super::page_type::PageType;
21 use super::helpers::misaligned_address_panic;
22
23 if virt.as_u64() % FRAME_SIZE != 0 {
24 misaligned_address_panic(PageType::Normal);
25 }
26 }
27
28 let mut current_pagetable = page_ptr.as_mut_ptr::<PageTable>();
29
30 let entry = unsafe { &mut current_pagetable.as_mut().unwrap()[virt.p4_index()] };
36 if !is_present(entry) { return Err(VmmError::InvalidUnmap) };
37 current_pagetable = advance_current_pagetable(entry);
38
39 let entry = unsafe { &mut current_pagetable.as_mut().unwrap()[virt.p3_index()] };
45 if !is_present(entry) { return Err(VmmError::InvalidUnmap) };
46 if is_huge_page(entry) {
47 clear_and_flush(entry, virt);
48 debug_log(virt);
49 return Ok(());
50 }
51 current_pagetable = advance_current_pagetable(entry);
52
53 let entry = unsafe { &mut current_pagetable.as_mut().unwrap()[virt.p2_index()] };
59 if !is_present(entry) { return Err(VmmError::InvalidUnmap) };
60 if is_huge_page(entry) {
61 clear_and_flush(entry, virt);
62 debug_log(virt);
63 return Ok(());
64 }
65 current_pagetable = advance_current_pagetable(entry);
66
67 let entry = unsafe { &mut current_pagetable.as_mut().unwrap()[virt.p1_index()] };
73 if !is_present(entry) { return Err(VmmError::InvalidUnmap) };
74 clear_and_flush(entry, virt);
75 debug_log(virt);
76
77 Ok(())
78}
79
80fn clear_and_flush(entry: &mut PageTableEntry, virt: VirtAddr) {
82 entry.set_unused();
83 tlb::flush(virt.as_x86_64());
84}
85
86#[allow(unused_variables)]
88fn debug_log(virt: VirtAddr) {
89 #[cfg(feature = "vmm-debug-logging")]
90 crate::kdebug!("[VMM] unmap page at virt {virt:#x}");
91}