Skip to main content

islet_rmm/realm/
config.rs

1use crate::realm::mm::address::GuestPhysAddr;
2use crate::realm::mm::rtt::RTT_PAGE_LEVEL;
3use crate::realm::rd::{Rd, RPV_SIZE};
4use crate::rmi::error::Error;
5
6use autopadding::*;
7use safe_abstraction::raw_ptr::assume_safe;
8
9pad_struct_and_impl_default!(
10pub struct RealmConfig {
11    0x0    ipa_width: usize,    // Offset 0x0
12    0x8    hash_algo: u8,       // Offset 0x8
13    0x200  rpv: [u8; RPV_SIZE], // Offset 0x200
14    0x1000 => @END,             // The width of the RealmConfig structure is 4096 (0x1000) bytes.
15}
16);
17
18impl RealmConfig {
19    // The below `init()` fills the object allocated in the Realm kernel with the proper
20    // value (ipa_width), which helps to redirect the accesses to decrypted pages.
21    //
22    // For some reason, using 33 for ipa_width causes a problem (format string bug?)
23    // in parsing the following kernel cmdline argument:
24    // `console=ttyS0 root=/dev/vda rw  console=pl011,mmio,0x1c0a0000 console=ttyAMA0 printk.devkmsg=on`.
25    // So, we get back to use the same kernel argument with TF-RMM's one (uart0 & uart3).
26    pub fn init(
27        config_addr: usize,
28        ipa_width: usize,
29        hash_algo: u8,
30        rpv: &[u8],
31    ) -> Result<(), Error> {
32        Ok(assume_safe::<RealmConfig>(config_addr)
33            .map(|mut realm_config| realm_config.init_inner(ipa_width, hash_algo, rpv))?)
34    }
35
36    fn init_inner(&mut self, ipa_width: usize, hash_algo: u8, rpv: &[u8]) {
37        self.ipa_width = ipa_width;
38        self.hash_algo = hash_algo;
39        self.rpv.copy_from_slice(rpv);
40    }
41}
42
43pub fn realm_config(rd: &Rd, config_ipa: usize, ipa_bits: usize) -> Result<(), Error> {
44    let res = rd
45        .s2_table()
46        .lock()
47        .ipa_to_pa(GuestPhysAddr::from(config_ipa), RTT_PAGE_LEVEL);
48    let hash_algo = rd.hash_algo();
49    let rpv = rd.personalization_value();
50    if let Some(pa) = res {
51        RealmConfig::init(pa.into(), ipa_bits, hash_algo, rpv)
52    } else {
53        Err(Error::RmiErrorInput)
54    }
55}
56
57impl safe_abstraction::raw_ptr::RawPtr for RealmConfig {}
58
59impl safe_abstraction::raw_ptr::SafetyChecked for RealmConfig {}
60
61impl safe_abstraction::raw_ptr::SafetyAssured for RealmConfig {
62    fn is_initialized(&self) -> bool {
63        // The initialization of this memory is guaranteed
64        // according to the RMM Specification A2.2.4 Granule Wiping.
65        // This instance belongs to a Data Granule and has been initialized.
66        true
67    }
68
69    fn verify_ownership(&self) -> bool {
70        // The instance's ownership is guaranteed while being processed by the RMM.
71        // While the Realm holds RW permissions for the instance,
72        // it cannot exercise these permissions from the moment an SMC request is made
73        // until the request is completed. Even in multi-core environments,
74        // the designated areas are protected by Stage 2 Table,
75        // ensuring that there are no adverse effects on RMM's memory safety.
76        true
77    }
78}