Move the `AVAIL1` flag from `PageFlags` to `PrivilegedPageFlags` in `PageProperty`

This commit is contained in:
Zhe Tang 2025-07-31 12:55:52 +00:00 committed by Tate, Hongliang Tian
parent 3b606f5b6c
commit e11227c8da
6 changed files with 35 additions and 25 deletions

View File

@ -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();

View File

@ -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 {

View File

@ -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!(

View File

@ -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::<dyn AnyFrameMeta>::from_raw(paddr) };

View File

@ -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"))]

View File

@ -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::<EarlyAllocatedFrameMeta>::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<E: PageTableEntryTrait, C: PagingConstsTrait> BootPageTable<E, C> {
/// Creates a new boot page table from the current page table root
@ -137,7 +137,7 @@ impl<E: PageTableEntryTrait, C: PagingConstsTrait> BootPageTable<E, C> {
// Make sure the 2 available bits are not set for firmware page tables.
dfs_walk_on_leave::<E, C>(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 {