@@ -514,7 +514,12 @@ impl<A: ArchPagingMeta, P: PagingHandler + SelfMap> GenericPageTable<A, P, Pagin
514514
515515impl < A : ArchPagingMeta , P : PagingHandler , L : PagingLevel > GenericPageTable < A , P , L > {
516516 /// Allocate from level 3 (PML4E) down to the target level.
517- fn alloc_pte_lvl3 ( entry : & mut PTEntry < A > , vaddr : VirtAddr , size : PageSize ) -> Mapping < ' _ , A > {
517+ fn alloc_pte_lvl3 (
518+ entry : & mut PTEntry < A > ,
519+ vaddr : VirtAddr ,
520+ size : PageSize ,
521+ parent_flags : A :: PTFlags ,
522+ ) -> Mapping < ' _ , A > {
518523 if entry. flags ( ) . contains ( A :: PTFlags :: PRESENT ) {
519524 return Mapping :: new ( PageLevel :: Level3 , entry) ;
520525 }
@@ -523,14 +528,19 @@ impl<A: ArchPagingMeta, P: PagingHandler, L: PagingLevel> GenericPageTable<A, P,
523528 return Mapping :: new ( PageLevel :: Level3 , entry) ;
524529 } ;
525530
526- entry. set ( A :: make_private_address ( paddr) , A :: PTFlags :: parent_flags ( ) ) ;
531+ entry. set ( A :: make_private_address ( paddr) , parent_flags) ;
527532
528533 let idx = vaddr. to_pgtbl_idx :: < 2 > ( ) ;
529- Self :: alloc_pte_lvl2 ( & mut page[ idx] , vaddr, size)
534+ Self :: alloc_pte_lvl2 ( & mut page[ idx] , vaddr, size, parent_flags )
530535 }
531536
532537 /// Allocate from level 2 (PDPTE) down to the target level.
533- fn alloc_pte_lvl2 ( entry : & mut PTEntry < A > , vaddr : VirtAddr , size : PageSize ) -> Mapping < ' _ , A > {
538+ fn alloc_pte_lvl2 (
539+ entry : & mut PTEntry < A > ,
540+ vaddr : VirtAddr ,
541+ size : PageSize ,
542+ parent_flags : A :: PTFlags ,
543+ ) -> Mapping < ' _ , A > {
534544 if entry. flags ( ) . contains ( A :: PTFlags :: PRESENT ) {
535545 return Mapping :: new ( PageLevel :: Level2 , entry) ;
536546 }
@@ -539,15 +549,20 @@ impl<A: ArchPagingMeta, P: PagingHandler, L: PagingLevel> GenericPageTable<A, P,
539549 return Mapping :: new ( PageLevel :: Level2 , entry) ;
540550 } ;
541551
542- entry. set ( A :: make_private_address ( paddr) , A :: PTFlags :: parent_flags ( ) ) ;
552+ entry. set ( A :: make_private_address ( paddr) , parent_flags) ;
543553
544554 let idx = vaddr. to_pgtbl_idx :: < 1 > ( ) ;
545- Self :: alloc_pte_lvl1 ( & mut page[ idx] , vaddr, size)
555+ Self :: alloc_pte_lvl1 ( & mut page[ idx] , vaddr, size, parent_flags )
546556 }
547557
548558 /// Allocate from level 1 (PDE) down to level 0.
549559 /// Returns at level 1 if `size` is `Huge` (2 MiB page).
550- fn alloc_pte_lvl1 ( entry : & mut PTEntry < A > , vaddr : VirtAddr , size : PageSize ) -> Mapping < ' _ , A > {
560+ fn alloc_pte_lvl1 (
561+ entry : & mut PTEntry < A > ,
562+ vaddr : VirtAddr ,
563+ size : PageSize ,
564+ parent_flags : A :: PTFlags ,
565+ ) -> Mapping < ' _ , A > {
551566 let flags = entry. flags ( ) ;
552567 if size == PageSize :: Huge || flags. contains ( A :: PTFlags :: PRESENT ) {
553568 return Mapping :: new ( PageLevel :: Level1 , entry) ;
@@ -557,7 +572,7 @@ impl<A: ArchPagingMeta, P: PagingHandler, L: PagingLevel> GenericPageTable<A, P,
557572 return Mapping :: new ( PageLevel :: Level1 , entry) ;
558573 } ;
559574
560- entry. set ( A :: make_private_address ( paddr) , A :: PTFlags :: parent_flags ( ) ) ;
575+ entry. set ( A :: make_private_address ( paddr) , parent_flags) ;
561576
562577 let idx = vaddr. to_pgtbl_idx :: < 0 > ( ) ;
563578 Mapping :: new ( PageLevel :: Level0 , & mut page[ idx] )
@@ -567,30 +582,40 @@ impl<A: ArchPagingMeta, P: PagingHandler, L: PagingLevel> GenericPageTable<A, P,
567582 ///
568583 /// # Parameters
569584 /// - `vaddr`: The virtual address for which to allocate the PTE.
585+ /// - `parent_flags`: The flags to apply to the allocated page table entries.
586+ ///
570587 /// # Returns
571588 /// A `Mapping` representing the allocated or existing PTE for the address.
572- fn alloc_pte_4k ( & mut self , vaddr : VirtAddr ) -> Mapping < ' _ , A > {
589+ fn alloc_pte_4k ( & mut self , vaddr : VirtAddr , parent_flags : A :: PTFlags ) -> Mapping < ' _ , A > {
573590 let m = self . walk_addr ( vaddr) ;
574591 match m. level {
575592 PageLevel :: Level0 => m,
576- PageLevel :: Level1 => Self :: alloc_pte_lvl1 ( m. entry , vaddr, PageSize :: Regular ) ,
577- PageLevel :: Level2 => Self :: alloc_pte_lvl2 ( m. entry , vaddr, PageSize :: Regular ) ,
578- PageLevel :: Level3 => Self :: alloc_pte_lvl3 ( m. entry , vaddr, PageSize :: Regular ) ,
593+ PageLevel :: Level1 => {
594+ Self :: alloc_pte_lvl1 ( m. entry , vaddr, PageSize :: Regular , parent_flags)
595+ }
596+ PageLevel :: Level2 => {
597+ Self :: alloc_pte_lvl2 ( m. entry , vaddr, PageSize :: Regular , parent_flags)
598+ }
599+ PageLevel :: Level3 => {
600+ Self :: alloc_pte_lvl3 ( m. entry , vaddr, PageSize :: Regular , parent_flags)
601+ }
579602 }
580603 }
581604
582605 /// Allocates a 2MB page table entry for a given virtual address.
583606 ///
584607 /// # Parameters
585608 /// - `vaddr`: The virtual address for which to allocate the PTE.
609+ /// - `parent_flags`: The flags to apply to the allocated page table entries.
610+ ///
586611 /// # Returns
587612 /// A `Mapping` representing the allocated or existing PTE for the address.
588- fn alloc_pte_2m ( & mut self , vaddr : VirtAddr ) -> Mapping < ' _ , A > {
613+ fn alloc_pte_2m ( & mut self , vaddr : VirtAddr , parent_flags : A :: PTFlags ) -> Mapping < ' _ , A > {
589614 let m = self . walk_addr ( vaddr) ;
590615 match m. level {
591616 PageLevel :: Level0 | PageLevel :: Level1 => m,
592- PageLevel :: Level2 => Self :: alloc_pte_lvl2 ( m. entry , vaddr, PageSize :: Huge ) ,
593- PageLevel :: Level3 => Self :: alloc_pte_lvl3 ( m. entry , vaddr, PageSize :: Huge ) ,
617+ PageLevel :: Level2 => Self :: alloc_pte_lvl2 ( m. entry , vaddr, PageSize :: Huge , parent_flags ) ,
618+ PageLevel :: Level3 => Self :: alloc_pte_lvl3 ( m. entry , vaddr, PageSize :: Huge , parent_flags ) ,
594619 }
595620 }
596621
@@ -716,16 +741,17 @@ impl<A: ArchPagingMeta, P: PagingHandler, L: PagingLevel> GenericPageTable<A, P,
716741 ///
717742 /// # Panics
718743 /// Panics if either `vaddr` or `paddr` is not aligned to a 2MB boundary.
719- pub fn map_2m (
744+ pub fn map_2m_with_parent_flags (
720745 & mut self ,
721746 vaddr : VirtAddr ,
722747 paddr : PhysAddr ,
723748 flags : A :: PTFlags ,
724749 shared : bool ,
750+ parent_flags : A :: PTFlags ,
725751 ) -> Result < ( ) , PagingError > {
726752 assert ! ( vaddr. is_aligned( PAGE_SIZE_2M ) ) ;
727753 assert ! ( paddr. is_aligned( PAGE_SIZE_2M ) ) ;
728- let mapping = self . alloc_pte_2m ( vaddr) ;
754+ let mapping = self . alloc_pte_2m ( vaddr, parent_flags ) ;
729755 let addr = if !shared {
730756 A :: make_private_address ( paddr)
731757 } else {
@@ -744,6 +770,29 @@ impl<A: ArchPagingMeta, P: PagingHandler, L: PagingLevel> GenericPageTable<A, P,
744770 }
745771 }
746772
773+ /// Maps a 2MB page.
774+ ///
775+ /// # Parameters
776+ /// - `vaddr`: The virtual address to map.
777+ /// - `paddr`: The physical address to map to.
778+ /// - `flags`: The flags to apply to the mapping.
779+ /// - `shared`: Indicates whether the mapping is shared.
780+ ///
781+ /// # Returns
782+ /// A result indicating success or failure ([`PagingError`]).
783+ ///
784+ /// # Panics
785+ /// Panics if either `vaddr` or `paddr` is not aligned to a 2MB boundary.
786+ pub fn map_2m (
787+ & mut self ,
788+ vaddr : VirtAddr ,
789+ paddr : PhysAddr ,
790+ flags : A :: PTFlags ,
791+ shared : bool ,
792+ ) -> Result < ( ) , PagingError > {
793+ self . map_2m_with_parent_flags ( vaddr, paddr, flags, shared, A :: PTFlags :: parent_flags ( ) )
794+ }
795+
747796 /// Unmaps a 2MB page.
748797 ///
749798 /// # Parameters
@@ -777,16 +826,19 @@ impl<A: ArchPagingMeta, P: PagingHandler, L: PagingLevel> GenericPageTable<A, P,
777826 /// - `paddr`: The physical address to map to.
778827 /// - `flags`: The flags to apply to the mapping.
779828 /// - `shared`: Indicates whether the mapping is shared.
829+ /// - `parent_flags`: The flags to apply to the allocated parent page table entries.
830+ ///
780831 /// # Returns
781832 /// A result indicating success or failure ([`PagingError`]).
782- pub fn map_4k (
833+ pub fn map_4k_with_parent_flags (
783834 & mut self ,
784835 vaddr : VirtAddr ,
785836 paddr : PhysAddr ,
786837 flags : A :: PTFlags ,
787838 shared : bool ,
839+ parent_flags : A :: PTFlags ,
788840 ) -> Result < ( ) , PagingError > {
789- let mapping = self . alloc_pte_4k ( vaddr) ;
841+ let mapping = self . alloc_pte_4k ( vaddr, parent_flags ) ;
790842 let addr = if !shared {
791843 A :: make_private_address ( paddr)
792844 } else {
@@ -805,6 +857,26 @@ impl<A: ArchPagingMeta, P: PagingHandler, L: PagingLevel> GenericPageTable<A, P,
805857 }
806858 }
807859
860+ /// Maps a 4KB page.
861+ ///
862+ /// # Parameters
863+ /// - `vaddr`: The virtual address to map.
864+ /// - `paddr`: The physical address to map to.
865+ /// - `flags`: The flags to apply to the mapping.
866+ /// - `shared`: Indicates whether the mapping is shared.
867+ ///
868+ /// # Returns
869+ /// A result indicating success or failure ([`PagingError`]).
870+ pub fn map_4k (
871+ & mut self ,
872+ vaddr : VirtAddr ,
873+ paddr : PhysAddr ,
874+ flags : A :: PTFlags ,
875+ shared : bool ,
876+ ) -> Result < ( ) , PagingError > {
877+ self . map_4k_with_parent_flags ( vaddr, paddr, flags, shared, A :: PTFlags :: parent_flags ( ) )
878+ }
879+
808880 /// Unmaps a 4KB page.
809881 ///
810882 /// # Parameters
0 commit comments