1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use crate::realm::mm::address::GuestPhysAddr;
use crate::rmi::error::Error;
use crate::rmi::realm::Rd;
use crate::rmi::rtt::RTT_PAGE_LEVEL;

use safe_abstraction::raw_ptr::assume_safe;

#[repr(C)]
pub struct RealmConfig {
    ipa_width: usize,
}

impl RealmConfig {
    // The below `init()` fills the object allocated in the Realm kernel with the proper
    // value (ipa_width), which helps to redirect the accesses to decrypted pages.
    //
    // For some reason, using 33 for ipa_width causes a problem (format string bug?)
    // in parsing the following kernel cmdline argument:
    // `console=ttyS0 root=/dev/vda rw  console=pl011,mmio,0x1c0a0000 console=ttyAMA0 printk.devkmsg=on`.
    // So, we get back to use the same kernel argument with TF-RMM's one (uart0 & uart3).
    pub fn init(config_addr: usize, ipa_width: usize) -> Result<(), Error> {
        Ok(assume_safe::<RealmConfig>(config_addr)
            .map(|mut realm_config| realm_config.ipa_width = ipa_width)?)
    }
}

pub fn realm_config(rd: &Rd, config_ipa: usize, ipa_bits: usize) -> Result<(), Error> {
    let res = rd
        .s2_table()
        .lock()
        .ipa_to_pa(GuestPhysAddr::from(config_ipa), RTT_PAGE_LEVEL);
    if let Some(pa) = res {
        RealmConfig::init(pa.into(), ipa_bits)
    } else {
        Err(Error::RmiErrorInput)
    }
}

impl safe_abstraction::raw_ptr::RawPtr for RealmConfig {}

impl safe_abstraction::raw_ptr::SafetyChecked for RealmConfig {}

impl safe_abstraction::raw_ptr::SafetyAssured for RealmConfig {
    fn is_initialized(&self) -> bool {
        // The initialization of this memory is guaranteed
        // according to the RMM Specification A2.2.4 Granule Wiping.
        // This instance belongs to a Data Granule and has been initialized.
        true
    }

    fn verify_ownership(&self) -> bool {
        // The instance's ownership is guaranteed while being processed by the RMM.
        // While the Realm holds RW permissions for the instance,
        // it cannot exercise these permissions from the moment an SMC request is made
        // until the request is completed. Even in multi-core environments,
        // the designated areas are protected by Stage 2 Table,
        // ensuring that there are no adverse effects on RMM's memory safety.
        true
    }
}