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}