Skip to content

Commit

Permalink
Manually flush stack pages after populating them
Browse files Browse the repository at this point in the history
We'd prefer to unmap the pages, but we can't (See #53). Instead directly flush
them, to be sure the stack is visible in the target process.
  • Loading branch information
mullr committed Aug 14, 2019
1 parent eeddd7f commit f33e339
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 3 deletions.
9 changes: 9 additions & 0 deletions src/arch/aarch64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(())
}
9 changes: 9 additions & 0 deletions src/arch/arm/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::error::{ErrorExt, SeL4Error};
use typenum::*;

pub mod cap;
Expand Down Expand Up @@ -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(())
}
13 changes: 13 additions & 0 deletions src/cap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,19 @@ impl<CT: CapType, Role: CNodeRole, Slots: Unsigned> CapRange<CT, Role, Slots> {
}
}

pub(crate) fn for_each<F: Fn(&Cap<CT, Role>) -> ()>(&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<Item = Cap<CT, Role>>
where
CT: CapRangeDataReconstruction,
Expand Down
4 changes: 3 additions & 1 deletion src/userland/process/self_hosted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl<StackBitSize: Unsigned> SelfHostedProcess<StackBitSize> {

// 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,
Expand Down Expand Up @@ -150,6 +150,8 @@ impl<StackBitSize: Unsigned> SelfHostedProcess<StackBitSize> {
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::<T> as usize;

Expand Down
4 changes: 3 additions & 1 deletion src/userland/process/standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl<StackBitSize: Unsigned> StandardProcess<StackBitSize> {

// 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<StackBitSize, _>, _) =
let (unmapped_stack_pages, local_stack_pages): (UnmappedMemoryRegion<StackBitSize, _>, _) =
parent_mapped_region.share(stack_slots, parent_cnode, CapRights::RW)?;
let mapped_stack_pages = vspace.map_shared_region_and_consume(
unmapped_stack_pages,
Expand All @@ -119,6 +119,8 @@ impl<StackBitSize: Unsigned> StandardProcess<StackBitSize> {
)
};

local_stack_pages.flush()?;

let stack_pointer =
mapped_stack_pages.vaddr() + mapped_stack_pages.size_bytes() - param_size_on_stack;

Expand Down
10 changes: 9 additions & 1 deletion src/vspace/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit f33e339

Please sign in to comment.