diff --git a/src/arch/aarch64/mod.rs b/src/arch/aarch64/mod.rs index 02c4db8d..4768d789 100644 --- a/src/arch/aarch64/mod.rs +++ b/src/arch/aarch64/mod.rs @@ -3,6 +3,7 @@ use core::marker::PhantomData; use typenum::*; use crate::cap::{page_state, Page, PageTable, PhantomCap}; +use crate::error::{ErrorExt, SeL4Error}; use crate::vspace::{PagingRec, PagingTop}; pub mod cap; @@ -145,3 +146,11 @@ pub mod vm_attributes { pub const PROGRAM_DATA: VMAttributes = PAGE_CACHEABLE | PARITY_ENABLED | EXECUTE_NEVER; } + +pub(crate) unsafe fn flush_page(cptr: usize) -> Result<(), SeL4Error> { + selfe_sys::seL4_ARM_Page_CleanInvalidate_Data(cptr, 0x0000, PageBytes::USIZE) + .as_result() + .map_err(|e| SeL4Error::PageCleanInvalidateData(e))?; + + Ok(()) +} diff --git a/src/arch/arm/mod.rs b/src/arch/arm/mod.rs index c88f04e3..2689d773 100644 --- a/src/arch/arm/mod.rs +++ b/src/arch/arm/mod.rs @@ -1,3 +1,4 @@ +use crate::error::{ErrorExt, SeL4Error}; use typenum::*; pub mod cap; @@ -135,3 +136,11 @@ pub mod vm_attributes { pub const PROGRAM_DATA: VMAttributes = PAGE_CACHEABLE | PARITY_ENABLED | EXECUTE_NEVER; } + +pub(crate) unsafe fn flush_page(cptr: usize) -> Result<(), SeL4Error> { + selfe_sys::seL4_ARM_Page_CleanInvalidate_Data(cptr, 0x0000, PageBytes::USIZE) + .as_result() + .map_err(|e| SeL4Error::PageCleanInvalidateData(e))?; + + Ok(()) +} diff --git a/src/cap/mod.rs b/src/cap/mod.rs index 18b50745..b03bd4b9 100644 --- a/src/cap/mod.rs +++ b/src/cap/mod.rs @@ -148,6 +148,19 @@ impl CapRange { } } + pub(crate) fn for_each) -> ()>(&self, f: F) + where + CT: CapRangeDataReconstruction, + { + for index in (0..self.len()) { + f(&Cap { + cptr: self.start_cptr + index, + _role: PhantomData, + cap_data: CT::reconstruct(index, &self.start_cap_data), + }) + } + } + pub(crate) fn into_iter(self) -> impl Iterator> where CT: CapRangeDataReconstruction, diff --git a/src/userland/process/self_hosted.rs b/src/userland/process/self_hosted.rs index a7194d83..f36dc303 100644 --- a/src/userland/process/self_hosted.rs +++ b/src/userland/process/self_hosted.rs @@ -109,7 +109,7 @@ impl SelfHostedProcess { // Map the stack to the target address space let stack_top = parent_mapped_region.vaddr() + parent_mapped_region.size_bytes(); - let (unmapped_stack_pages, _) = + let (unmapped_stack_pages, local_stack_pages) = parent_mapped_region.share(stack_slots, parent_cnode, CapRights::RW)?; let mapped_stack_pages = vspace.map_shared_region_and_consume( unmapped_stack_pages, @@ -150,6 +150,8 @@ impl SelfHostedProcess { let stack_pointer = mapped_stack_pages.vaddr() + mapped_stack_pages.size_bytes() - param_size_on_stack; + local_stack_pages.flush()?; + registers.sp = stack_pointer; registers.pc = self_hosted_run:: as usize; diff --git a/src/userland/process/standard.rs b/src/userland/process/standard.rs index e6deec9f..27ae7fe2 100644 --- a/src/userland/process/standard.rs +++ b/src/userland/process/standard.rs @@ -100,7 +100,7 @@ impl StandardProcess { // Map the stack to the target address space let stack_top = parent_mapped_region.vaddr() + parent_mapped_region.size_bytes(); - let (unmapped_stack_pages, _): (UnmappedMemoryRegion, _) = + let (unmapped_stack_pages, local_stack_pages): (UnmappedMemoryRegion, _) = parent_mapped_region.share(stack_slots, parent_cnode, CapRights::RW)?; let mapped_stack_pages = vspace.map_shared_region_and_consume( unmapped_stack_pages, @@ -119,6 +119,8 @@ impl StandardProcess { ) }; + local_stack_pages.flush()?; + let stack_pointer = mapped_stack_pages.vaddr() + mapped_stack_pages.size_bytes() - param_size_on_stack; diff --git a/src/vspace/region.rs b/src/vspace/region.rs index 3d1078e9..7daab8c8 100644 --- a/src/vspace/region.rs +++ b/src/vspace/region.rs @@ -4,7 +4,7 @@ use core::ops::Sub; use typenum::*; use super::{KernelRetypeFanOutLimit, NumPages, VSpaceError}; -use crate::arch::PageBits; +use crate::arch::{self, PageBits}; use crate::cap::{ memory_kind, page_state, role, CNode, CNodeRole, CNodeSlots, Cap, CapRange, InternalASID, LocalCNodeSlots, LocalCap, MemoryKind, Page, PageState, RetypeError, Untyped, WCNodeSlots, @@ -270,6 +270,14 @@ where unsafe { core::slice::from_raw_parts_mut(self.vaddr() as *mut u8, self.size_bytes()) } } + pub fn flush(&self) -> Result<(), SeL4Error> { + self.caps.for_each(|cap| { + unsafe { arch::flush_page(cap.cptr) }.unwrap(); + }); + + Ok(()) + } + #[cfg(feature = "test_support")] /// Super dangerous copy-aliasing pub(crate) unsafe fn dangerous_internal_alias(&mut self) -> Self {