ostd/mm/
page_prop.rs

1// SPDX-License-Identifier: MPL-2.0
2
3//! Definitions of page mapping properties.
4
5use core::fmt::Debug;
6
7use bitflags::bitflags;
8
9/// The property of a mapped virtual memory page.
10#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11pub struct PageProperty {
12    /// The flags associated with the page,
13    pub flags: PageFlags,
14    /// The cache policy for the page.
15    pub cache: CachePolicy,
16    pub(crate) priv_flags: PrivilegedPageFlags,
17}
18
19impl PageProperty {
20    /// Creates a new `PageProperty` with the given flags and cache policy for the user.
21    pub fn new_user(flags: PageFlags, cache: CachePolicy) -> Self {
22        Self {
23            flags,
24            cache,
25            priv_flags: PrivilegedPageFlags::USER,
26        }
27    }
28}
29
30// TODO: Make it more abstract when supporting other architectures.
31/// A type to control the cacheability of the main memory.
32///
33/// The type currently follows the definition as defined by the AMD64 manual.
34#[derive(Clone, Copy, Debug, PartialEq, Eq)]
35pub enum CachePolicy {
36    /// Uncacheable (UC).
37    ///
38    /// Reads from, and writes to, UC memory are not cacheable.
39    /// Reads from UC memory cannot be speculative.
40    /// Write-combining to UC memory is not allowed.
41    /// Reads from or writes to UC memory cause the write buffers to be written to memory
42    /// and be invalidated prior to the access to UC memory.
43    ///
44    /// The UC memory type is useful for memory-mapped I/O devices
45    /// where strict ordering of reads and writes is important.
46    Uncacheable,
47    /// Write-Combining (WC).
48    ///
49    /// Reads from, and writes to, WC memory are not cacheable.
50    /// Reads from WC memory can be speculative.
51    ///
52    /// Writes to this memory type can be combined internally by the processor
53    /// and written to memory as a single write operation to reduce memory accesses.
54    ///
55    /// The WC memory type is useful for graphics-display memory buffers
56    /// where the order of writes is not important.
57    WriteCombining,
58    /// Write-Protect (WP).
59    ///
60    /// Reads from WP memory are cacheable and allocate cache lines on a read miss.
61    /// Reads from WP memory can be speculative.
62    ///
63    /// Writes to WP memory that hit in the cache do not update the cache.
64    /// Instead, all writes update memory (write to memory),
65    /// and writes that hit in the cache invalidate the cache line.
66    /// Write buffering of WP memory is allowed.
67    ///
68    /// The WP memory type is useful for shadowed-ROM memory
69    /// where updates must be immediately visible to all devices that read the shadow locations.
70    WriteProtected,
71    /// Writethrough (WT).
72    ///
73    /// Reads from WT memory are cacheable and allocate cache lines on a read miss.
74    /// Reads from WT memory can be speculative.
75    ///
76    /// All writes to WT memory update main memory,
77    /// and writes that hit in the cache update the cache line.
78    /// Writes that miss the cache do not allocate a cache line.
79    /// Write buffering of WT memory is allowed.
80    Writethrough,
81    /// Writeback (WB).
82    ///
83    /// The WB memory is the "normal" memory. See detailed descriptions in the manual.
84    ///
85    /// This type of memory provides the highest-possible performance
86    /// and is useful for most software and data stored in system memory (DRAM).
87    Writeback,
88}
89
90bitflags! {
91    /// Page protection permissions and access status.
92    pub struct PageFlags: u8 {
93        /// Readable.
94        const R = 0b00000001;
95        /// Writable.
96        const W = 0b00000010;
97        /// Executable.
98        const X = 0b00000100;
99        /// Readable + writable.
100        const RW = Self::R.bits | Self::W.bits;
101        /// Readable + executable.
102        const RX = Self::R.bits | Self::X.bits;
103        /// Readable + writable + executable.
104        const RWX = Self::R.bits | Self::W.bits | Self::X.bits;
105
106        /// Has the memory page been read or written.
107        const ACCESSED  = 0b00001000;
108        /// Has the memory page been written.
109        const DIRTY     = 0b00010000;
110
111        /// The second bit available for software use.
112        const AVAIL2    = 0b10000000;
113    }
114}
115
116bitflags! {
117    /// Page property that are only accessible in OSTD.
118    pub(crate) struct PrivilegedPageFlags: u8 {
119        /// Accessible from user mode.
120        const USER      = 0b00000001;
121        /// Global page that won't be evicted from TLB with normal TLB flush.
122        const GLOBAL    = 0b00000010;
123
124        /// The first bit available for software use.
125        /// This flag is reserved for OSTD to distinguish between tracked
126        /// mappings and untracked mappings in the page table.
127        const AVAIL1    = 0b01000000;
128
129        /// (TEE only) If the page is shared with the host.
130        /// Otherwise the page is ensured confidential and not visible outside the guest.
131        #[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))]
132        const SHARED    = 0b10000000;
133    }
134}