mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-07-15 06:51:49 +00:00
kata-os-common: add CopyRegion support.
Move the CopyRegion support to kata-os-common. CopyRegion wraps a CAmkES copyregion virtual memory window to support virtual access to physical page frames. There is RAII cleanup to clear any virtual mapping. Embedding a CopyRegion in struct that may be cloned is not recommeded (at least for now). Change-Id: I7fd465fafa4a5d1de9a7e565ecb62c38a3b7e81a GitOrigin-RevId: f58e973b1c47ec05e48bfedcb9cd5e75b71c212a
This commit is contained in:
parent
f70a9af73f
commit
acf7c28eba
@ -5,8 +5,8 @@
|
||||
use core::mem::size_of;
|
||||
use core::ptr;
|
||||
use crate::sel4bundle::arch;
|
||||
use crate::sel4bundle::CopyRegion;
|
||||
use crate::sel4bundle::seL4BundleImpl;
|
||||
use super::CopyRegion;
|
||||
use super::sel4_sys;
|
||||
|
||||
use arch::PAGE_SIZE;
|
||||
@ -64,8 +64,10 @@ impl seL4BundleImpl {
|
||||
// be on a page boundary.
|
||||
let frame_obj = self.get_stack_frame_obj(sp - size_of::<seL4_Word>());
|
||||
|
||||
let mut copy_region =
|
||||
CopyRegion::new(unsafe { ptr::addr_of_mut!(LOAD_APPLICATION[0])});
|
||||
let mut copy_region = CopyRegion::new(
|
||||
unsafe { ptr::addr_of_mut!(LOAD_APPLICATION[0])},
|
||||
PAGE_SIZE
|
||||
);
|
||||
copy_region.map(frame_obj.cptr)?;
|
||||
|
||||
// Write spillover arguments to the TCB's stack.
|
||||
|
@ -16,6 +16,7 @@ use kata_memory_interface::kata_object_free;
|
||||
use kata_memory_interface::kata_object_free_in_cnode;
|
||||
use kata_memory_interface::ObjDesc;
|
||||
use kata_memory_interface::ObjDescBundle;
|
||||
use kata_os_common::copyregion::CopyRegion;
|
||||
use kata_os_common::cspace_slot::CSpaceSlot;
|
||||
use kata_os_common::sel4_sys;
|
||||
use kata_proc_interface::Bundle;
|
||||
@ -36,9 +37,7 @@ use sel4_sys::seL4_DomainSet_Set;
|
||||
use sel4_sys::seL4_EndpointObject;
|
||||
use sel4_sys::seL4_Error;
|
||||
use sel4_sys::seL4_MinSchedContextBits;
|
||||
use sel4_sys::seL4_Page_Map;
|
||||
use sel4_sys::seL4_PageTableObject;
|
||||
use sel4_sys::seL4_Page_Unmap;
|
||||
use sel4_sys::seL4_ReplyObject;
|
||||
use sel4_sys::seL4_Result;
|
||||
use sel4_sys::seL4_SchedContextObject;
|
||||
@ -64,8 +63,6 @@ extern "C" {
|
||||
// Our thread's TCB; used in setting up scheduling of new TCB's.
|
||||
static SELF_TCB_PROCESS_MANAGER_PROC_CTRL_0000: seL4_CPtr;
|
||||
|
||||
static SELF_VSPACE_ROOT: seL4_CPtr;
|
||||
|
||||
// Region for mapping data when loading the contents of a BundleImage.
|
||||
static mut LOAD_APPLICATION: [seL4_Word; PAGE_SIZE / size_of::<seL4_Word>()];
|
||||
}
|
||||
@ -136,78 +133,6 @@ fn check_bundle(bundle: &ObjDescBundle) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(sleffler): move to kata-os-common
|
||||
pub struct CopyRegion {
|
||||
region: *mut seL4_Word,
|
||||
cur_frame: Option<seL4_CPtr>,
|
||||
}
|
||||
impl CopyRegion {
|
||||
pub fn new(region: *mut seL4_Word) -> Self {
|
||||
CopyRegion {
|
||||
region,
|
||||
cur_frame: None,
|
||||
}
|
||||
}
|
||||
// Returns the region size in bytes.
|
||||
pub fn size(&self) -> usize { PAGE_SIZE }
|
||||
|
||||
// Returns a mutable [u8] ref to the mapped region.
|
||||
pub fn as_mut(&mut self) -> &mut [u8] {
|
||||
assert!(self.cur_frame.is_some());
|
||||
unsafe {
|
||||
core::slice::from_raw_parts_mut(
|
||||
self.region as _, PAGE_SIZE
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a mutable [seL4_Word] ref to the mapped region.
|
||||
pub fn as_word_mut(&mut self) -> &mut [seL4_Word] {
|
||||
assert!(self.cur_frame.is_some());
|
||||
unsafe {
|
||||
core::slice::from_raw_parts_mut(
|
||||
self.region, PAGE_SIZE / size_of::<seL4_Word>(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Maps the |frame| in the SELF_VSPACE_ROOT for r/w.
|
||||
pub fn map(&mut self, frame: seL4_CPtr) -> seL4_Result {
|
||||
let attribs = seL4_Default_VMAttributes;
|
||||
unsafe {
|
||||
seL4_Page_Map(
|
||||
frame,
|
||||
SELF_VSPACE_ROOT,
|
||||
self.region as usize,
|
||||
// seL4_ReadWrite
|
||||
seL4_CapRights::new(
|
||||
/*grant_reply=*/ 0, /*grant=*/ 0, /*read=*/ 1, /*write=*/ 1,
|
||||
),
|
||||
attribs,
|
||||
)
|
||||
}?;
|
||||
self.cur_frame = Some(frame);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Unmaps the current frame, if any.
|
||||
pub fn unmap(&mut self) -> seL4_Result {
|
||||
if let Some(cptr) = self.cur_frame {
|
||||
#[cfg(target_arch = "arm")]
|
||||
unsafe { seL4_ARM_Page_Unify_Instruction(cptr, 0, self.size()) }?;
|
||||
|
||||
unsafe { seL4_Page_Unmap(cptr) }?;
|
||||
self.cur_frame = None;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Drop for CopyRegion {
|
||||
fn drop(&mut self) {
|
||||
self.unmap().expect("CopyRegion");
|
||||
}
|
||||
}
|
||||
|
||||
const NOCAP: seL4_CPtr = 0;
|
||||
|
||||
// Layout of the CNode holding dynamic_objs. All entries are singletons
|
||||
@ -427,10 +352,10 @@ impl seL4BundleImpl {
|
||||
// to fill from the |bundle_frames| and/or zero-fill.
|
||||
let mut image = BundleImage::new(bundle_frames);
|
||||
|
||||
let mut copy_region =
|
||||
CopyRegion::new(unsafe { ptr::addr_of_mut!(LOAD_APPLICATION[0])});
|
||||
// Many places assume the copy region is PAGE_SIZE
|
||||
assert_eq!(copy_region.size(), PAGE_SIZE);
|
||||
let mut copy_region = CopyRegion::new(
|
||||
unsafe { ptr::addr_of_mut!(LOAD_APPLICATION[0])},
|
||||
PAGE_SIZE
|
||||
);
|
||||
|
||||
let mut vaddr_top = 0;
|
||||
while let Some(section) = image.next_section() {
|
||||
|
@ -13,6 +13,7 @@ camkes_support = []
|
||||
allocator = { path = "src/allocator" }
|
||||
camkes = { path = "src/camkes" }
|
||||
capdl = { path = "src/capdl" }
|
||||
copyregion = { path = "src/copyregion" }
|
||||
cspace-slot = { path = "src/cspace-slot" }
|
||||
logger = { path = "src/logger" }
|
||||
model = { path = "src/model" }
|
||||
|
@ -0,0 +1,11 @@
|
||||
cargo-features = ["edition2021"]
|
||||
|
||||
[package]
|
||||
name = "copyregion"
|
||||
version = "0.1.0"
|
||||
authors = ["Sam Leffler <sleffler@google.com>"]
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
sel4-sys = { path = "../sel4-sys" }
|
141
apps/system/components/kata-os-common/src/copyregion/src/lib.rs
Normal file
141
apps/system/components/kata-os-common/src/copyregion/src/lib.rs
Normal file
@ -0,0 +1,141 @@
|
||||
//! RAII wrapper for using a KataOS copyregion object.
|
||||
|
||||
#![no_std]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use core::mem::size_of;
|
||||
|
||||
use sel4_sys::seL4_CapRights;
|
||||
use sel4_sys::seL4_CPtr;
|
||||
use sel4_sys::seL4_Default_VMAttributes;
|
||||
use sel4_sys::seL4_Page_Map;
|
||||
use sel4_sys::seL4_Page_Unmap;
|
||||
use sel4_sys::seL4_Result;
|
||||
use sel4_sys::seL4_Word;
|
||||
|
||||
extern "C" {
|
||||
static SELF_VSPACE_ROOT: seL4_CPtr;
|
||||
}
|
||||
|
||||
// Sample usage:
|
||||
// let mut copy_region = CopyRegion::new(unsafe { ptr::addr_of_mut!(LOAD_APPLICATION[0])}, PAGE_SIZE);
|
||||
// copy_region.map(frame.cptr)?;
|
||||
// copy_region.as_mut()[..].fill(0);
|
||||
// let start = if index > 0 { 0 } else { vaddr - data_range.start };
|
||||
// let end = cmp::min(data_range.end - vaddr, copy_region.size());
|
||||
// image.read_exact(&mut copy_region.as_mut()[start..end])
|
||||
// .map_err(|_| seL4_Error::seL4_NoError)?; // XXX
|
||||
// copy_region.unmap()?;
|
||||
|
||||
// TODO(sleffler): do we need to parameterize VM_Attributes & CapRights?
|
||||
// TODO(sleffler): Mutex-wrapped & maybe RefCell-wrapped versions?
|
||||
|
||||
// Fn from the criterion crate that convinces the optimizer
|
||||
// a value is used in order to defeat premature optimization.
|
||||
fn black_box<T>(dummy: T) -> T {
|
||||
unsafe {
|
||||
let ret = core::ptr::read_volatile(&dummy);
|
||||
core::mem::forget(dummy);
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CopyRegion {
|
||||
region: *mut seL4_Word,
|
||||
size: usize,
|
||||
cur_frame: Option<seL4_CPtr>,
|
||||
}
|
||||
impl CopyRegion {
|
||||
pub fn new(region: *mut seL4_Word, size: usize) -> Self {
|
||||
CopyRegion {
|
||||
region,
|
||||
size,
|
||||
cur_frame: None,
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the region size in bytes.
|
||||
pub fn size(&self) -> usize { self.size }
|
||||
|
||||
// Returns the region size if mapped, otherwise 0.
|
||||
pub fn mapped_bytes(&self) -> usize {
|
||||
if self.cur_frame.is_some() { self.size } else { 0 }
|
||||
}
|
||||
|
||||
// Returns an immutable [u8] ref to the mapped region.
|
||||
pub fn as_ref(&mut self) -> &[u8] {
|
||||
assert!(self.cur_frame.is_some());
|
||||
unsafe {
|
||||
core::slice::from_raw_parts(
|
||||
self.region as _, self.size
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a mutable [u8] ref to the mapped region.
|
||||
pub fn as_mut(&mut self) -> &mut [u8] {
|
||||
assert!(self.cur_frame.is_some());
|
||||
unsafe {
|
||||
core::slice::from_raw_parts_mut(
|
||||
self.region as _, self.size
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns an immutable [seL4_Word] ref to the mapped region.
|
||||
pub fn as_word_ref(&mut self) -> &[seL4_Word] {
|
||||
assert!(self.cur_frame.is_some());
|
||||
unsafe {
|
||||
core::slice::from_raw_parts(
|
||||
self.region, self.size / size_of::<seL4_Word>(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a mutable [seL4_Word] ref to the mapped region.
|
||||
pub fn as_word_mut(&mut self) -> &mut [seL4_Word] {
|
||||
assert!(self.cur_frame.is_some());
|
||||
unsafe {
|
||||
core::slice::from_raw_parts_mut(
|
||||
self.region, self.size / size_of::<seL4_Word>(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Maps the |frame| in the SELF_VSPACE_ROOT for r/w.
|
||||
// XXX need rights + attribs?
|
||||
pub fn map(&mut self, frame: seL4_CPtr) -> seL4_Result {
|
||||
black_box(frame); // NB: compiler WAR for frame clobber
|
||||
unsafe {
|
||||
seL4_Page_Map(
|
||||
frame,
|
||||
SELF_VSPACE_ROOT,
|
||||
self.region as seL4_Word,
|
||||
// seL4_ReadWrite
|
||||
seL4_CapRights::new(
|
||||
/*grant_reply=*/ 0, /*grant=*/ 0, /*read=*/ 1, /*write=*/ 1,
|
||||
),
|
||||
seL4_Default_VMAttributes,
|
||||
)
|
||||
}?;
|
||||
self.cur_frame = Some(frame);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Unmaps the current frame, if any.
|
||||
pub fn unmap(&mut self) -> seL4_Result {
|
||||
if let Some(cptr) = self.cur_frame {
|
||||
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
|
||||
unsafe { seL4_ARM_Page_Unify_Instruction(cptr, 0, self.size()) }?;
|
||||
|
||||
unsafe { seL4_Page_Unmap(cptr) }?;
|
||||
self.cur_frame = None;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Drop for CopyRegion {
|
||||
fn drop(&mut self) {
|
||||
self.unmap().expect("CopyRegion");
|
||||
}
|
||||
}
|
@ -5,6 +5,8 @@ pub extern crate allocator;
|
||||
pub extern crate camkes;
|
||||
pub extern crate capdl;
|
||||
#[cfg(feature = "camkes_support")]
|
||||
pub extern crate copyregion;
|
||||
#[cfg(feature = "camkes_support")]
|
||||
pub extern crate cspace_slot;
|
||||
pub extern crate logger;
|
||||
pub extern crate model;
|
||||
|
Loading…
Reference in New Issue
Block a user