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::realm::mm::rtt::RTT_PAGE_LEVEL;
use crate::realm::rd::Rd;
use crate::rmi::error::Error;
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
}
}