fn can_map_as_huge_page(
        &mut self,
        pml4_entry: PML4Entry,
        pbase: PAddr,
        psize: usize,
        vbase: VAddr,
        _rights: MapAction,
    ) -> bool {
        let pml4_idx = pml4_index(vbase);
        let pdpt_idx = pdpt_index(vbase);
        let pdpt_entry = {
            let pdpt = self.get_pdpt(pml4_entry);
            pdpt[pdpt_idx]
        };

        // The virtual address corresponding to the current position within the page-table
        let vaddr_pos: VAddr = VAddr::from(PML4_SLOT_SIZE * pml4_idx + HUGE_PAGE_SIZE * pdpt_idx);

        let want_to_map_here = vbase == vaddr_pos;
        let physical_frame_is_aligned = pbase.is_huge_page_aligned();
        let want_to_map_at_least_1gib = psize >= HUGE_PAGE_SIZE;

        if !want_to_map_here || !physical_frame_is_aligned || !want_to_map_at_least_1gib {
            return false;
        }

        let no_underlying_2mib_mappings = if !pdpt_entry.is_present() {
            true
        } else {
            // We go and check if the underlying page-table is emtpy
            // (previous mappings could've left a PD here which since has been emptied)
            // TODO(efficiency): If we had 4 KiB mappings (that are empty below the PD) we
            // don't currently detect that.
            let mut all_entries_empty: bool = true;
            let pd = self.get_pd(pdpt_entry);
            for i in 0..pd.len() {
                all_entries_empty &= !pd[i].is_present();
            }

            if all_entries_empty {
                // Reclaim PD page back to pager
                // warn!("TODO: pager.release_base_page()");
                let pdpt = self.get_pdpt_mut(pml4_entry);
                pdpt[pdpt_idx] = PDPTEntry::new(PAddr::from(0x0), PDPTFlags::empty());
            }

            all_entries_empty
        };

        no_underlying_2mib_mappings
    }
/// Check if we can just insert a huge page for the current mapping
Check if we can just insert a huge page for the current mapping
Check if we can just insert a huge page for the current mapping
fn can_map_as_huge_page(
        &mut self,
        pml4_entry: PML4Entry,
        pbase: PAddr,
        psize: usize,
        vbase: VAddr,
        _rights: MapAction,
    ) -> bool {
        let pml4_idx = pml4_index(vbase);
        let pdpt_idx = pdpt_index(vbase);
        let pdpt_entry = {
            let pdpt = self.get_pdpt(pml4_entry);
            pdpt[pdpt_idx]
        };
        // The virtual address corresponding to the current position within the page-table
        let vaddr_pos: VAddr = VAddr::from(PML4_SLOT_SIZE * pml4_idx + HUGE_PAGE_SIZE * pdpt_idx);
        let want_to_map_here = vbase == vaddr_pos;
        let physical_frame_is_aligned = pbase.is_huge_page_aligned();
        let want_to_map_at_least_1gib = psize >= HUGE_PAGE_SIZE;
        if !want_to_map_here || !physical_frame_is_aligned || !want_to_map_at_least_1gib {
            return false;
        }
        let no_underlying_2mib_mappings = if !pdpt_entry.is_present() {
            true
        } else {
            // We go and check if the underlying page-table is emtpy
            // (previous mappings could've left a PD here which since has been emptied)
            // TODO(efficiency): If we had 4 KiB mappings (that are empty below the PD) we
            // don't currently detect that.
            let mut all_entries_empty: bool = true;
            let pd = self.get_pd(pdpt_entry);
            for i in 0..pd.len() {
                all_entries_empty &= !pd[i].is_present();
            }
            if all_entries_empty {
                // Reclaim PD page back to pager
                // warn!("TODO: pager.release_base_page()");
                let pdpt = self.get_pdpt_mut(pml4_entry);
                pdpt[pdpt_idx] = PDPTEntry::new(PAddr::from(0x0), PDPTFlags::empty());
            }
            all_entries_empty
        };
        no_underlying_2mib_mappings
    }
fn can_map_as_huge_page ( & mut self , pml4_entry : PML4Entry , pbase : PAddr , psize : usize , vbase : VAddr , _rights : MapAction , ) -> bool { let pml4_idx = pml4_index ( vbase ) ; let pdpt_idx = pdpt_index ( vbase ) ; let pdpt_entry = { let pdpt = self . get_pdpt ( pml4_entry ) ; pdpt [ pdpt_idx ] } ; // The virtual address corresponding to the current position within the page-table let vaddr_pos : VAddr = VAddr :: from ( PML4_SLOT_SIZE * pml4_idx + HUGE_PAGE_SIZE * pdpt_idx ) ; let want_to_map_here = vbase == vaddr_pos ; let physical_frame_is_aligned = pbase . is_huge_page_aligned ( ) ; let want_to_map_at_least_1gib = psize >= HUGE_PAGE_SIZE ; if ! want_to_map_here || ! physical_frame_is_aligned || ! want_to_map_at_least_1gib { return false ; } let no_underlying_2mib_mappings = if ! pdpt_entry . is_present ( ) { true } else { // We go and check if the underlying page-table is emtpy // (previous mappings could've left a PD here which since has been emptied) // TODO(efficiency): If we had 4 KiB mappings (that are empty below the PD) we // don't currently detect that. let mut all_entries_empty : bool = true ; let pd = self . get_pd ( pdpt_entry ) ; for i in 0 .. pd . len ( ) { all_entries_empty &= ! pd [ i ] . is_present ( ) ; } if all_entries_empty { // Reclaim PD page back to pager // warn!("TODO: pager.release_base_page()"); let pdpt = self . get_pdpt_mut ( pml4_entry ) ; pdpt [ pdpt_idx ] = PDPTEntry :: new ( PAddr :: from ( 0x0 ) , PDPTFlags :: empty ( ) ) ; } all_entries_empty } ; no_underlying_2mib_mappings }
Check if we can just insert a huge page for the current mapping
Check if we can just insert a huge page for the current mapping
&mut self
pml4_entry
PML4Entry
pbase
PAddr
psize
usize
vbase
VAddr
_rights
MapAction
&mut self
pml4_entry
PML4Entry
pbase
PAddr
psize
usize
vbase
VAddr
_rights
MapAction