From e11227c8daa169eabf61c6f02a463ca2f730f0ae Mon Sep 17 00:00:00 2001 From: Zhe Tang Date: Thu, 31 Jul 2025 12:55:52 +0000 Subject: [PATCH] Move the `AVAIL1` flag from `PageFlags` to `PrivilegedPageFlags` in `PageProperty` --- ostd/src/arch/loongarch/mm/mod.rs | 15 +++++++++------ ostd/src/arch/riscv/mm/mod.rs | 10 +++++++--- ostd/src/arch/x86/mm/mod.rs | 8 ++++---- ostd/src/mm/kspace/mod.rs | 10 +++++----- ostd/src/mm/page_prop.rs | 7 +++++-- ostd/src/mm/page_table/boot_pt.rs | 10 +++++----- 6 files changed, 35 insertions(+), 25 deletions(-) diff --git a/ostd/src/arch/loongarch/mm/mod.rs b/ostd/src/arch/loongarch/mm/mod.rs index aaaad726c..92a2d4558 100644 --- a/ostd/src/arch/loongarch/mm/mod.rs +++ b/ostd/src/arch/loongarch/mm/mod.rs @@ -205,14 +205,13 @@ impl PageTableEntryTrait for PageTableEntry { // TODO: How to get the accessed bit in loongarch? | (parse_flags!(self.0, PageTableFlags::PRESENT, PageFlags::ACCESSED)) | (parse_flags!(self.0, PageTableFlags::DIRTY, PageFlags::DIRTY)) - | (parse_flags!(self.0, PageTableFlags::RSV1, PageFlags::AVAIL1)) | (parse_flags!(self.0, PageTableFlags::RSV2, PageFlags::AVAIL2)); - let mut priv_flags = PrivFlags::empty().bits(); + let mut priv_flags = parse_flags!(self.0, PageTableFlags::RSV1, PrivFlags::AVAIL1); if self.is_user() { - priv_flags |= PrivFlags::USER.bits(); + priv_flags |= PrivFlags::USER.bits() as usize; } if self.is_global() { - priv_flags |= PrivFlags::GLOBAL.bits(); + priv_flags |= PrivFlags::GLOBAL.bits() as usize; } let cache = if self.0 & PageTableFlags::MATL.bits() != 0 { @@ -226,7 +225,7 @@ impl PageTableEntryTrait for PageTableEntry { PageProperty { flags: PageFlags::from_bits(flags as u8).unwrap(), cache, - priv_flags: PrivFlags::from_bits(priv_flags).unwrap(), + priv_flags: PrivFlags::from_bits(priv_flags as u8).unwrap(), } } @@ -250,8 +249,12 @@ impl PageTableEntryTrait for PageTableEntry { | parse_flags!(prop.flags.bits(), PageFlags::DIRTY, PageTableFlags::DIRTY) // TODO: How to get the accessed bit in loongarch? | parse_flags!(prop.flags.bits(), PageFlags::ACCESSED, PageTableFlags::PRESENT) - | parse_flags!(prop.flags.bits(), PageFlags::AVAIL1, PageTableFlags::RSV1) | parse_flags!(prop.flags.bits(), PageFlags::AVAIL2, PageTableFlags::RSV2); + flags |= parse_flags!( + prop.priv_flags.bits(), + PrivFlags::AVAIL1, + PageTableFlags::RSV1 + ); if prop.priv_flags.contains(PrivFlags::USER) { flags |= PageTableFlags::PLVL.bits(); flags |= PageTableFlags::PLVH.bits(); diff --git a/ostd/src/arch/riscv/mm/mod.rs b/ostd/src/arch/riscv/mm/mod.rs index 07b607d0f..7768f3fed 100644 --- a/ostd/src/arch/riscv/mm/mod.rs +++ b/ostd/src/arch/riscv/mm/mod.rs @@ -157,10 +157,10 @@ impl PageTableEntryTrait for PageTableEntry { | (parse_flags!(self.0, PageTableFlags::EXECUTABLE, PageFlags::X)) | (parse_flags!(self.0, PageTableFlags::ACCESSED, PageFlags::ACCESSED)) | (parse_flags!(self.0, PageTableFlags::DIRTY, PageFlags::DIRTY)) - | (parse_flags!(self.0, PageTableFlags::RSV1, PageFlags::AVAIL1)) | (parse_flags!(self.0, PageTableFlags::RSV2, PageFlags::AVAIL2)); let priv_flags = (parse_flags!(self.0, PageTableFlags::USER, PrivFlags::USER)) - | (parse_flags!(self.0, PageTableFlags::GLOBAL, PrivFlags::GLOBAL)); + | (parse_flags!(self.0, PageTableFlags::GLOBAL, PrivFlags::GLOBAL)) + | (parse_flags!(self.0, PageTableFlags::RSV1, PrivFlags::AVAIL1)); let cache = if self.0 & PageTableFlags::PBMT_IO.bits() != 0 { CachePolicy::Uncacheable @@ -191,7 +191,11 @@ impl PageTableEntryTrait for PageTableEntry { PrivFlags::GLOBAL, PageTableFlags::GLOBAL ) - | parse_flags!(prop.flags.bits(), PageFlags::AVAIL1, PageTableFlags::RSV1) + | parse_flags!( + prop.priv_flags.bits(), + PrivFlags::AVAIL1, + PageTableFlags::RSV1 + ) | parse_flags!(prop.flags.bits(), PageFlags::AVAIL2, PageTableFlags::RSV2); match prop.cache { diff --git a/ostd/src/arch/x86/mm/mod.rs b/ostd/src/arch/x86/mm/mod.rs index bab3243c0..07b0f353e 100644 --- a/ostd/src/arch/x86/mm/mod.rs +++ b/ostd/src/arch/x86/mm/mod.rs @@ -201,10 +201,10 @@ impl PageTableEntryTrait for PageTableEntry { | (parse_flags!(!self.0, PageTableFlags::NO_EXECUTE, PageFlags::X)) | (parse_flags!(self.0, PageTableFlags::ACCESSED, PageFlags::ACCESSED)) | (parse_flags!(self.0, PageTableFlags::DIRTY, PageFlags::DIRTY)) - | (parse_flags!(self.0, PageTableFlags::HIGH_IGN1, PageFlags::AVAIL1)) | (parse_flags!(self.0, PageTableFlags::HIGH_IGN2, PageFlags::AVAIL2)); let priv_flags = (parse_flags!(self.0, PageTableFlags::USER, PrivFlags::USER)) - | (parse_flags!(self.0, PageTableFlags::GLOBAL, PrivFlags::GLOBAL)); + | (parse_flags!(self.0, PageTableFlags::GLOBAL, PrivFlags::GLOBAL)) + | (parse_flags!(self.0, PageTableFlags::HIGH_IGN1, PrivFlags::AVAIL1)); #[cfg(feature = "cvm_guest")] let priv_flags = priv_flags | (parse_flags!(self.0, PageTableFlags::SHARED, PrivFlags::SHARED)); @@ -237,8 +237,8 @@ impl PageTableEntryTrait for PageTableEntry { )) | (parse_flags!(prop.flags.bits(), PageFlags::DIRTY, PageTableFlags::DIRTY)) | (parse_flags!( - prop.flags.bits(), - PageFlags::AVAIL1, + prop.priv_flags.bits(), + PrivFlags::AVAIL1, PageTableFlags::HIGH_IGN1 )) | (parse_flags!( diff --git a/ostd/src/mm/kspace/mod.rs b/ostd/src/mm/kspace/mod.rs index fc207f72d..a32b99819 100644 --- a/ostd/src/mm/kspace/mod.rs +++ b/ostd/src/mm/kspace/mod.rs @@ -136,22 +136,22 @@ unsafe impl PageTableConfig for KernelPtConfig { fn item_into_raw(item: Self::Item) -> (Paddr, PagingLevel, PageProperty) { match item { MappedItem::Tracked(frame, mut prop) => { - debug_assert!(!prop.flags.contains(PageFlags::AVAIL1)); - prop.flags |= PageFlags::AVAIL1; + debug_assert!(!prop.priv_flags.contains(PrivilegedPageFlags::AVAIL1)); + prop.priv_flags |= PrivilegedPageFlags::AVAIL1; let level = frame.map_level(); let paddr = frame.into_raw(); (paddr, level, prop) } MappedItem::Untracked(pa, level, mut prop) => { - debug_assert!(!prop.flags.contains(PageFlags::AVAIL1)); - prop.flags -= PageFlags::AVAIL1; + debug_assert!(!prop.priv_flags.contains(PrivilegedPageFlags::AVAIL1)); + prop.priv_flags -= PrivilegedPageFlags::AVAIL1; (pa, level, prop) } } } unsafe fn item_from_raw(paddr: Paddr, level: PagingLevel, prop: PageProperty) -> Self::Item { - if prop.flags.contains(PageFlags::AVAIL1) { + if prop.priv_flags.contains(PrivilegedPageFlags::AVAIL1) { debug_assert_eq!(level, 1); // SAFETY: The caller ensures safety. let frame = unsafe { Frame::::from_raw(paddr) }; diff --git a/ostd/src/mm/page_prop.rs b/ostd/src/mm/page_prop.rs index 069b2d4ff..b158cc998 100644 --- a/ostd/src/mm/page_prop.rs +++ b/ostd/src/mm/page_prop.rs @@ -117,8 +117,6 @@ bitflags! { /// Has the memory page been written. const DIRTY = 0b00010000; - /// The first bit available for software use. - const AVAIL1 = 0b01000000; /// The second bit available for software use. const AVAIL2 = 0b10000000; } @@ -132,6 +130,11 @@ bitflags! { /// Global page that won't be evicted from TLB with normal TLB flush. const GLOBAL = 0b00000010; + /// The first bit available for software use. + /// This flag is reserved for OSTD to distinguish between tracked + /// mappings and untracked mappings in the page table. + const AVAIL1 = 0b01000000; + /// (TEE only) If the page is shared with the host. /// Otherwise the page is ensured confidential and not visible outside the guest. #[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))] diff --git a/ostd/src/mm/page_table/boot_pt.rs b/ostd/src/mm/page_table/boot_pt.rs index bad279fd1..7c3c51b56 100644 --- a/ostd/src/mm/page_table/boot_pt.rs +++ b/ostd/src/mm/page_table/boot_pt.rs @@ -20,8 +20,8 @@ use crate::{ self, allocator::{self, EarlyAllocatedFrameMeta}, }, - nr_subpage_per_huge, paddr_to_vaddr, Frame, FrameAllocOptions, Paddr, PageFlags, - PageProperty, PagingConstsTrait, PagingLevel, Vaddr, PAGE_SIZE, + nr_subpage_per_huge, paddr_to_vaddr, Frame, FrameAllocOptions, Paddr, PageProperty, + PagingConstsTrait, PagingLevel, PrivilegedPageFlags, Vaddr, PAGE_SIZE, }, sync::SpinLock, }; @@ -79,7 +79,7 @@ pub(crate) unsafe fn dismiss() { boot_pt.root_pt, PagingConsts::NR_LEVELS, &mut |pte| { - if !pte.prop().flags.contains(PTE_POINTS_TO_FIRMWARE_PT) { + if !pte.prop().priv_flags.contains(PTE_POINTS_TO_FIRMWARE_PT) { // SAFETY: The pointed frame is allocated and forgotten with `into_raw`. drop(unsafe { Frame::::from_raw(pte.paddr()) }) } @@ -121,7 +121,7 @@ pub(crate) struct BootPageTable< // The first available bit is used to differentiate firmware page tables from // the page tables allocated here. The second is for identifying double-visits // when walking the page tables since the PT can be a DAG. -const PTE_POINTS_TO_FIRMWARE_PT: PageFlags = PageFlags::AVAIL1; +const PTE_POINTS_TO_FIRMWARE_PT: PrivilegedPageFlags = PrivilegedPageFlags::AVAIL1; impl BootPageTable { /// Creates a new boot page table from the current page table root @@ -137,7 +137,7 @@ impl BootPageTable { // Make sure the 2 available bits are not set for firmware page tables. dfs_walk_on_leave::(root_pt, C::NR_LEVELS, &mut |pte: &mut E| { let mut prop = pte.prop(); - prop.flags |= PTE_POINTS_TO_FIRMWARE_PT; + prop.priv_flags |= PTE_POINTS_TO_FIRMWARE_PT; pte.set_prop(prop); }); Self {