diff --git a/rmm/armv9a/src/rmm/page_table/attr.rs b/rmm/armv9a/src/rmm/page_table/attr.rs index dea671178e301..ba3e5662ebfae 100644 --- a/rmm/armv9a/src/rmm/page_table/attr.rs +++ b/rmm/armv9a/src/rmm/page_table/attr.rs @@ -17,4 +17,5 @@ pub mod page_type { pub mod mair_idx { pub const RMM_MEM: u64 = 0b0; pub const DEVICE_MEM: u64 = 0b1; + pub const RW_DATA: u64 = 0b0; } diff --git a/rmm/armv9a/src/rmm/translation.rs b/rmm/armv9a/src/rmm/translation.rs index 409f44339a1ad..48927813bf147 100644 --- a/rmm/armv9a/src/rmm/translation.rs +++ b/rmm/armv9a/src/rmm/translation.rs @@ -65,7 +65,7 @@ impl<'a> RmmPageTable<'a> { let ro_flags = helper::bits_in_reg(PTDesc::AP, attr::permission::RO); let rw_flags = helper::bits_in_reg(PTDesc::AP, attr::permission::RW); - let rmm_flags = helper::bits_in_reg(PTDesc::INDX, attr::mair_idx::RMM_MEM); + let rmm_flags = helper::bits_in_reg(PTDesc::INDX, attr::mair_idx::RW_DATA); unsafe { let base_address = &__RMM_BASE__ as *const u64 as u64; @@ -172,14 +172,20 @@ pub fn set_register_mm() { pub fn set_pages_for_rmi(addr: usize, secure: bool) { let rw_flags = helper::bits_in_reg(PTDesc::AP, attr::permission::RW); - let device_flags = helper::bits_in_reg(PTDesc::INDX, attr::mair_idx::DEVICE_MEM); + let memattr_flags = helper::bits_in_reg(PTDesc::INDX, attr::mair_idx::RMM_MEM); + let sh_flags = helper::bits_in_reg(PTDesc::SH, attr::shareable::INNER); let secure_flags = helper::bits_in_reg(PTDesc::NS, !secure as u64); let va = VirtAddr::from(addr); let phys = PhysAddr::from(addr); let mut page_table = RMM_PAGE_TABLE.lock(); - page_table.set_pages(va, phys, PAGE_SIZE, rw_flags | device_flags | secure_flags); + page_table.set_pages( + va, + phys, + PAGE_SIZE, + rw_flags | memattr_flags | secure_flags | sh_flags, + ); } pub fn unset_page_for_rmi(addr: usize) { diff --git a/rmm/monitor/src/event/mainloop.rs b/rmm/monitor/src/event/mainloop.rs index 3ecb4a89a380e..dbb7a3f49de52 100644 --- a/rmm/monitor/src/event/mainloop.rs +++ b/rmm/monitor/src/event/mainloop.rs @@ -55,7 +55,10 @@ impl Mainloop { ctx.resize_ret(ret_num); self.queue.lock().push_back(ctx); }, - || {}, + || { + let ctx = Context::new(rmi::NOT_SUPPORTED_YET); + self.queue.lock().push_back(ctx); + }, ); } diff --git a/rmm/monitor/src/rmi/gpt.rs b/rmm/monitor/src/rmi/gpt.rs index e046ac1eb4601..af70dec67ca93 100644 --- a/rmm/monitor/src/rmi/gpt.rs +++ b/rmm/monitor/src/rmi/gpt.rs @@ -1,11 +1,13 @@ use crate::event::Mainloop; use crate::listen; +use crate::mm::error::Error as MmError; use crate::rmi; use crate::rmi::error::Error; use crate::rmm::granule::{set_granule, GranuleState}; use crate::rmm::PageMap; use crate::smc; -use crate::{get_granule, get_granule_if, get_granule_not_if, set_state_and_get_granule}; +use crate::{get_granule, get_granule_if, set_state_and_get_granule}; + extern crate alloc; pub fn set_event_handler(mainloop: &mut Mainloop) { @@ -18,22 +20,11 @@ pub fn set_event_handler(mainloop: &mut Mainloop) { }); } -fn check_state_not_if(addr: usize, state: u64) -> Result<(), Error> { - get_granule_not_if!(addr, state)?; - Ok(()) -} - -fn check_state_if(addr: usize, state: u64) -> Result<(), Error> { - get_granule_if!(addr, state)?; - Ok(()) -} - -pub fn mark_realm(smc: smc::SecureMonitorCall, mm: PageMap, addr: usize) -> Result<(), Error> { - if check_state_not_if(addr, GranuleState::Undelegated).is_ok() { - // returns error if this is not in the state of Undelegated. - return Err(Error::RmiErrorInput); - } - let mut granule = set_state_and_get_granule!(addr, GranuleState::Undelegated)?; +fn mark_realm(smc: smc::SecureMonitorCall, mm: PageMap, addr: usize) -> Result<(), Error> { + let mut granule = match get_granule_if!(addr, GranuleState::Undelegated) { + Err(MmError::MmNoEntry) => set_state_and_get_granule!(addr, GranuleState::Undelegated), + other => other, + }?; let cmd = smc.convert(smc::Code::MarkRealm); if smc.call(cmd, &[addr])[0] != smc::SMC_SUCCESS { @@ -49,10 +40,7 @@ pub fn mark_realm(smc: smc::SecureMonitorCall, mm: PageMap, addr: usize) -> Resu Ok(()) } -pub fn mark_ns(smc: smc::SecureMonitorCall, mm: PageMap, addr: usize) -> Result<(), Error> { - if check_state_if(addr, GranuleState::Undelegated).is_ok() { - return Ok(()); - } +fn mark_ns(smc: smc::SecureMonitorCall, mm: PageMap, addr: usize) -> Result<(), Error> { let mut granule = get_granule_if!(addr, GranuleState::Delegated)?; let cmd = smc.convert(smc::Code::MarkNonSecure); diff --git a/rmm/monitor/src/rmi/mod.rs b/rmm/monitor/src/rmi/mod.rs index a1f7d745b9575..430c1e6795eed 100644 --- a/rmm/monitor/src/rmi/mod.rs +++ b/rmm/monitor/src/rmi/mod.rs @@ -39,6 +39,8 @@ pub const REQ_COMPLETE: usize = 0xc400_018f; pub const BOOT_COMPLETE: usize = 0xC400_01CF; pub const BOOT_SUCCESS: usize = 0x0; +pub const NOT_SUPPORTED_YET: usize = 0xFFFF_EEEE; + pub const ABI_MAJOR_VERSION: usize = 1; pub const ABI_MINOR_VERSION: usize = 0; diff --git a/rmm/monitor/src/rmi/realm/mod.rs b/rmm/monitor/src/rmi/realm/mod.rs index cdf52942e3c44..49d346f4d5ae1 100644 --- a/rmm/monitor/src/rmi/realm/mod.rs +++ b/rmm/monitor/src/rmi/realm/mod.rs @@ -23,8 +23,8 @@ pub fn set_event_handler(mainloop: &mut Mainloop) { let mm = rmm.mm; // get the lock for granule. - let mut granule = get_granule_if!(arg[0], GranuleState::Delegated)?; - let rd = granule.content_mut::(); + let mut rd_granule = get_granule_if!(arg[0], GranuleState::Delegated)?; + let rd = rd_granule.content_mut::(); mm.map(arg[0], true); // read params @@ -36,17 +36,17 @@ pub fn set_event_handler(mainloop: &mut Mainloop) { // Keep params in Realm // revisit rmi.create_realm() (is it necessary?) - let res = rmi.create_realm(); - match res { - Ok(id) => { - rd.init(id); - ret[1] = id; - } - Err(val) => return Err(val), - } + rmi.create_realm().map(|id| { + rd.init(id, params.rtt_base as usize); + ret[1] = id; + })?; + + let mut rtt_granule = get_granule_if!(rd.rtt_base(), GranuleState::Delegated)?; + set_granule(&mut rtt_granule, GranuleState::RTT)?; // set Rd state only when everything goes well. - set_granule(&mut granule, GranuleState::RD)?; + set_granule(&mut rd_granule, GranuleState::RD)?; + Ok(()) }); @@ -61,16 +61,15 @@ pub fn set_event_handler(mainloop: &mut Mainloop) { // get the lock for Rd let mut rd_granule = get_granule_if!(arg[0], GranuleState::RD)?; let rd = rd_granule.content::(); - let res = rmi.remove(rd.id()); + rmi.remove(rd.id())?; - match res { - Ok(_) => {} - Err(val) => return Err(val), - } + let mut rtt_granule = get_granule_if!(rd.rtt_base(), GranuleState::RTT)?; + set_granule(&mut rtt_granule, GranuleState::Delegated)?; // change state when everything goes fine. set_granule(&mut rd_granule, GranuleState::Delegated)?; rmm.mm.unmap(arg[0]); + Ok(()) }); } diff --git a/rmm/monitor/src/rmi/realm/rd.rs b/rmm/monitor/src/rmi/realm/rd.rs index 62ed97294c962..cc051b2699d73 100644 --- a/rmm/monitor/src/rmi/realm/rd.rs +++ b/rmm/monitor/src/rmi/realm/rd.rs @@ -1,15 +1,18 @@ use crate::mm::guard::Content; use crate::rmm::granule::GranuleState; +// TODO: Integrate with our `struct Realm` pub struct Rd { realm_id: usize, state: State, + rtt_base: usize, } impl Rd { - pub fn init(&mut self, id: usize) { + pub fn init(&mut self, id: usize, rtt_base: usize) { self.realm_id = id; self.state = State::New; + self.rtt_base = rtt_base } pub fn init_with_state(&mut self, id: usize, state: State) { @@ -28,6 +31,10 @@ impl Rd { pub fn at_state(&self, compared: State) -> bool { self.state == compared } + + pub fn rtt_base(&self) -> usize { + self.rtt_base + } } impl Content for Rd { diff --git a/rmm/monitor/src/rmi/rtt.rs b/rmm/monitor/src/rmi/rtt.rs index a0074d0b051f9..60fa4c966fb53 100644 --- a/rmm/monitor/src/rmi/rtt.rs +++ b/rmm/monitor/src/rmi/rtt.rs @@ -150,7 +150,7 @@ pub fn set_event_handler(mainloop: &mut Mainloop) { listen!(mainloop, rmi::DATA_DESTORY, |arg, _ret, rmm| { // rd granule lock - let rd_granule = get_granule_if!(arg[1], GranuleState::RD)?; + let rd_granule = get_granule_if!(arg[0], GranuleState::RD)?; let rd = rd_granule.content::(); let realm_id = rd.id(); let ipa = arg[1]; diff --git a/rmm/monitor/src/rmm/granule/entry.rs b/rmm/monitor/src/rmm/granule/entry.rs index c8c880ebf99f4..25fda08718d00 100644 --- a/rmm/monitor/src/rmm/granule/entry.rs +++ b/rmm/monitor/src/rmm/granule/entry.rs @@ -44,6 +44,10 @@ impl Granule { _ => state == GranuleState::Delegated, }; if !valid { + error!( + "Granule state transition failed: prev[{:?}] -> next[{:?}]", + prev, state + ); return Err(Error::MmStateError); } diff --git a/rmm/monitor/src/rmm/granule/mod.rs b/rmm/monitor/src/rmm/granule/mod.rs index c36d6266dfbd5..2744908e0f3aa 100644 --- a/rmm/monitor/src/rmm/granule/mod.rs +++ b/rmm/monitor/src/rmm/granule/mod.rs @@ -128,28 +128,14 @@ macro_rules! get_granule { #[macro_export] macro_rules! get_granule_if { ($addr:expr, $state:expr) => {{ - let guard = get_granule!($addr)?; - if guard.state() != $state { - use crate::mm::error::Error as MmError; - Err(MmError::MmStateError) - } else { - Ok(guard) - } - }}; -} - -/// get_granule_not_if!(addr: a physical address, state: a granule state you don't expect it to be) -/// - when success, returns `EntryGuard` allowing an access to "Granule". -#[macro_export] -macro_rules! get_granule_not_if { - ($addr:expr, $state:expr) => {{ - let guard = get_granule!($addr)?; - if guard.state() == $state { - use crate::mm::error::Error as MmError; - Err(MmError::MmStateError) - } else { - Ok(guard) - } + get_granule!($addr).and_then(|guard| { + if guard.state() != $state { + use crate::mm::error::Error as MmError; + Err(MmError::MmStateError) + } else { + Ok(guard) + } + }) }}; } @@ -160,12 +146,7 @@ macro_rules! set_state_and_get_granule { ($addr:expr, $state:expr) => {{ { use crate::rmm::granule::set_granule_raw; - - set_granule_raw($addr, $state)?; - match get_granule!($addr) { - Ok(g) => Ok(g), - Err(e) => Err(e), - } + set_granule_raw($addr, $state).and_then(|_| get_granule!($addr)) } }}; }