Skip to main content

islet_rmm/
host.rs

1#[cfg(feature = "gst_page_table")]
2use crate::granule::{is_not_in_realm, GRANULE_SIZE};
3#[cfg(not(feature = "gst_page_table"))]
4use crate::granule::{GranuleState, GRANULE_SIZE};
5#[cfg(not(feature = "gst_page_table"))]
6use crate::{get_granule, get_granule_if};
7
8use safe_abstraction::raw_ptr::{assume_safe, SafetyAssured, SafetyChecked};
9use vmsa::guard::Content;
10
11pub fn copy_from<T: SafetyChecked + SafetyAssured + Copy>(addr: usize) -> Option<T> {
12    #[cfg(feature = "gst_page_table")]
13    if !is_not_in_realm(addr) {
14        return None;
15    }
16    #[cfg(not(feature = "gst_page_table"))]
17    if get_granule_if!(addr, GranuleState::Undelegated).is_err() {
18        return None;
19    }
20
21    let ret = assume_safe::<T>(addr).map(|safety_assumed| *safety_assumed);
22    match ret {
23        Ok(obj) => Some(obj),
24        Err(err) => {
25            error!("Failed to convert a raw pointer to the struct. {:?}", err);
26            None
27        }
28    }
29}
30
31pub fn copy_to_obj<T: SafetyChecked + SafetyAssured + Copy>(src: usize, dst: &mut T) -> Option<()> {
32    #[cfg(feature = "gst_page_table")]
33    if !is_not_in_realm(src) {
34        return None;
35    }
36    #[cfg(not(feature = "gst_page_table"))]
37    if get_granule_if!(src, GranuleState::Undelegated).is_err() {
38        return None;
39    }
40
41    let ret = assume_safe::<T>(src).map(|safety_assumed| *dst = *safety_assumed);
42    match ret {
43        Ok(_) => Some(()),
44        Err(err) => {
45            error!("Failed to convert a raw pointer to the struct. {:?}", err);
46            None
47        }
48    }
49}
50
51pub fn copy_to_ptr<T: SafetyChecked + SafetyAssured + Copy>(src: &T, dst: usize) -> Option<()> {
52    #[cfg(feature = "gst_page_table")]
53    if !is_not_in_realm(dst) {
54        return None;
55    }
56    #[cfg(not(feature = "gst_page_table"))]
57    if get_granule_if!(dst, GranuleState::Undelegated).is_err() {
58        return None;
59    }
60
61    let ret = assume_safe::<T>(dst).map(|mut safety_assumed| *safety_assumed = *src);
62    match ret {
63        Ok(_) => Some(()),
64        Err(err) => {
65            error!("Failed to convert a raw pointer to the struct. {:?}", err);
66            None
67        }
68    }
69}
70
71/// DataPage is used to convey realm data from host to realm.
72#[repr(C)]
73#[derive(Copy, Clone)]
74pub struct DataPage([u8; GRANULE_SIZE]);
75
76impl DataPage {
77    pub fn as_slice(&self) -> &[u8] {
78        self.0.as_slice()
79    }
80}
81
82impl Default for DataPage {
83    fn default() -> Self {
84        Self([0; GRANULE_SIZE])
85    }
86}
87
88impl Content for DataPage {}
89
90impl safe_abstraction::raw_ptr::RawPtr for DataPage {}
91
92impl safe_abstraction::raw_ptr::SafetyChecked for DataPage {}
93
94impl safe_abstraction::raw_ptr::SafetyAssured for DataPage {
95    fn is_initialized(&self) -> bool {
96        // Given the fact that this memory is initialized by the Host,
97        // it's not possible to unequivocally guarantee
98        // that the values have been initialized from the perspective of the RMM.
99        // However, any values, whether correctly initialized or not, will undergo
100        // verification during the Measurement phase.
101        // Consequently, this function returns `true`.
102        true
103    }
104
105    fn verify_ownership(&self) -> bool {
106        // This memory has permissions from the Host's perspective,
107        // which inherently implies that exclusive ownership cannot be guaranteed by the RMM alone.
108        // However, since the RMM only performs read operations and any incorrect values will be
109        // verified during the Measurement phase.
110        // Consequently, this function returns `true`.
111        true
112    }
113}