mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-08-01 05:47:18 +00:00
Merge "Add basic mailbox driver camkes component + a test script in DebugConsole."
GitOrigin-RevId: 687148fc664b922d3b04ba8a8397fa0f5ff79e29
This commit is contained in:
parent
8800dc4a96
commit
2b0dd2eb8b
@ -96,6 +96,17 @@ DeclareCAmkESComponent(TimerService
|
||||
INCLUDES interfaces
|
||||
)
|
||||
|
||||
RustAddLibrary(
|
||||
mailbox_driver
|
||||
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/components/MailboxDriver
|
||||
LIB_FILENAME libmailbox_driver.a
|
||||
)
|
||||
|
||||
DeclareCAmkESComponent(MailboxDriver
|
||||
LIBS mailbox_driver
|
||||
INCLUDES interfaces
|
||||
)
|
||||
|
||||
DeclareCAmkESComponent(LogFibonacci
|
||||
SOURCES
|
||||
components/LogFibonacci/src/main.c
|
||||
|
@ -13,6 +13,7 @@ sel4-config = { path = "../../kata-os-common/src/sel4-config" }
|
||||
[features]
|
||||
default = [
|
||||
"TEST_GLOBAL_ALLOCATOR",
|
||||
"TEST_MAILBOX",
|
||||
"TEST_MEMORY_MANAGER",
|
||||
"TEST_ML_COORDINATOR",
|
||||
"TEST_PANIC",
|
||||
@ -25,6 +26,7 @@ CONFIG_KERNEL_MCS = []
|
||||
FRINGE_CMDS = []
|
||||
# Runtime tests for various services (please keep sorted)
|
||||
TEST_GLOBAL_ALLOCATOR = []
|
||||
TEST_MAILBOX = []
|
||||
TEST_MEMORY_MANAGER = []
|
||||
TEST_ML_COORDINATOR = []
|
||||
TEST_PANIC = []
|
||||
|
@ -22,6 +22,7 @@ pub fn add_cmds(cmds: &mut HashMap::<&str, CmdFn>) {
|
||||
("delete_key", delete_key_command as CmdFn),
|
||||
("read_key", read_key_command as CmdFn),
|
||||
("write_key", write_key_command as CmdFn),
|
||||
("test_mailbox", test_mailbox_command as CmdFn),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -157,3 +158,20 @@ fn write_key_command(
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_mailbox_command(
|
||||
_args: &mut dyn Iterator<Item = &str>,
|
||||
_input: &mut dyn io::BufRead,
|
||||
output: &mut dyn io::Write,
|
||||
_builtin_cpio: &[u8],
|
||||
) -> Result<(), CommandError> {
|
||||
match kata_security_test_mailbox() {
|
||||
Ok(_) => {
|
||||
writeln!(output, "Test mailbox OK.")?;
|
||||
}
|
||||
Err(_status) => {
|
||||
writeln!(output, "Test mailbox failed.")?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
8
apps/system/components/MailboxDriver/Cargo.toml
Normal file
8
apps/system/components/MailboxDriver/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
||||
cargo-features = ["edition2021"]
|
||||
|
||||
[workspace]
|
||||
|
||||
members = [
|
||||
"mailbox-driver",
|
||||
]
|
||||
resolver = "2"
|
33
apps/system/components/MailboxDriver/MailboxDriver.camkes
Normal file
33
apps/system/components/MailboxDriver/MailboxDriver.camkes
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* CAmkES component for accessing Sparrow's SMC -> SEC mailbox.
|
||||
*
|
||||
* Copyright 2021, Google LLC
|
||||
* Apache License 2.0
|
||||
*/
|
||||
|
||||
import <MailboxInterface.camkes>;
|
||||
import <MemoryInterface.camkes>;
|
||||
import <LoggerInterface.camkes>;
|
||||
|
||||
component MailboxDriver {
|
||||
provides MailboxAPI api;
|
||||
|
||||
// Mailbox registers
|
||||
dataport Buf mailbox_mmio;
|
||||
|
||||
// Global mailbox lock
|
||||
has mutex api_mutex;
|
||||
|
||||
// Mailbox arrival semaphore
|
||||
has semaphore rx_semaphore;
|
||||
|
||||
// Mailbox interrupts
|
||||
consumes Interrupt wtirq;
|
||||
consumes Interrupt rtirq;
|
||||
consumes Interrupt eirq;
|
||||
|
||||
// Enable KataOS CAmkES support.
|
||||
attribute int kataos = true;
|
||||
|
||||
uses LoggerInterface logger;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
cargo-features = ["edition2021"]
|
||||
|
||||
[package]
|
||||
name = "mailbox-driver"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
[dependencies]
|
||||
kata-os-common = { path = "../../kata-os-common" }
|
||||
log = "0.4"
|
||||
cty = "0.2.1"
|
||||
kata-memory-interface = { path = "../../MemoryManager/kata-memory-interface" }
|
||||
|
||||
[lib]
|
||||
name = "mailbox_driver"
|
||||
path = "src/lib.rs"
|
||||
crate-type = ["staticlib"]
|
262
apps/system/components/MailboxDriver/mailbox-driver/src/lib.rs
Normal file
262
apps/system/components/MailboxDriver/mailbox-driver/src/lib.rs
Normal file
@ -0,0 +1,262 @@
|
||||
#![no_std]
|
||||
// We want to keep all mailbox constants here even if they're currently unused.
|
||||
#![allow(dead_code)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use kata_os_common::logger::KataLogger;
|
||||
use kata_os_common::sel4_sys::seL4_CPtr;
|
||||
use log::{error, trace};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// TODO(aappleby): Can we replace this with the register_struct! thing?
|
||||
|
||||
const REG_INTR_STATE: u32 = 0x000; // R/W1C
|
||||
const REG_INTR_ENABLE: u32 = 0x004; // R/W
|
||||
const REG_INTR_TEST: u32 = 0x008; // R/W
|
||||
const REG_MBOXW: u32 = 0x00C; // W
|
||||
const REG_MBOXR: u32 = 0x010; // R
|
||||
const REG_STATUS: u32 = 0x014; // R
|
||||
const REG_ERROR: u32 = 0x018; // R
|
||||
const REG_WIRQT: u32 = 0x01C; // R/W
|
||||
const REG_RIRQT: u32 = 0x020; // R/W
|
||||
const REG_CTRL: u32 = 0x024; // R/W
|
||||
|
||||
const INTR_STATE_BIT_WTIRQ: u32 = 0b001;
|
||||
const INTR_STATE_BIT_RTIRQ: u32 = 0b010;
|
||||
const INTR_STATE_BIT_EIRQ: u32 = 0b100;
|
||||
const INTR_STATE_MASK: u32 = 0b111;
|
||||
|
||||
const INTR_ENABLE_BIT_WTIRQ: u32 = 0b001;
|
||||
const INTR_ENABLE_BIT_RTIRQ: u32 = 0b010;
|
||||
const INTR_ENABLE_BIT_EIRQ: u32 = 0b100;
|
||||
const INTR_ENABLE_MASK: u32 = 0b111;
|
||||
|
||||
const INTR_TEST_BIT_WTIRQ: u32 = 0b001;
|
||||
const INTR_TEST_BIT_RTIRQ: u32 = 0b010;
|
||||
const INTR_TEST_BIT_EIRQ: u32 = 0b100;
|
||||
const INTR_TEST_MASK: u32 = 0b111;
|
||||
|
||||
const STATUS_BIT_EMPTY: u32 = 0b0001;
|
||||
const STATUS_BIT_FULL: u32 = 0b0010;
|
||||
const STATUS_BIT_WFIFOL: u32 = 0b0100;
|
||||
const STATUS_BIT_RFIFOL: u32 = 0b1000;
|
||||
const STATUS_MASK: u32 = 0b1111;
|
||||
|
||||
const ERROR_BIT_READ: u32 = 0b01;
|
||||
const ERROR_BIT_WRITE: u32 = 0b10;
|
||||
const ERROR_MASK: u32 = 0b11;
|
||||
|
||||
const FIFO_SIZE: u32 = 8;
|
||||
const FIFO_MASK: u32 = FIFO_SIZE - 1;
|
||||
const WIRQT_MASK: u32 = FIFO_MASK;
|
||||
const RIRQT_MASK: u32 = FIFO_MASK;
|
||||
|
||||
const CTRL_BIT_FLUSH_WFIFO: u32 = 0b01;
|
||||
const CTRL_BIT_FLUSH_RFIFO: u32 = 0b10;
|
||||
const CTRL_MASK: u32 = 0b11;
|
||||
|
||||
// The high bit of the message header is used to distinguish between "inline"
|
||||
// messages that fit in the mailbox and "long" messages that contain the
|
||||
// physical address of a memory page containing the message.
|
||||
const HEADER_FLAG_LONG_MESSAGE: u32 = 0x80000000;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
extern "C" {
|
||||
// Mailbox registers
|
||||
static mailbox_mmio: *mut u32;
|
||||
|
||||
// Global mailbox lock
|
||||
fn api_mutex_lock() -> u32;
|
||||
fn api_mutex_unlock() -> u32;
|
||||
|
||||
// Mailbox arrival semaphore
|
||||
fn rx_semaphore_wait() -> u32;
|
||||
fn rx_semaphore_post() -> u32;
|
||||
|
||||
// Mailbox interrupts
|
||||
fn wtirq_acknowledge() -> u32;
|
||||
fn rtirq_acknowledge() -> u32;
|
||||
fn eirq_acknowledge() -> u32;
|
||||
|
||||
// Enable KataOS CAmkES support.
|
||||
static SELF_CNODE: seL4_CPtr;
|
||||
static SELF_VSPACE_ROOT: seL4_CPtr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Directly manipulate the mailbox registers.
|
||||
|
||||
unsafe fn get_intr_state() -> u32 {
|
||||
mailbox_mmio.offset(0).read_volatile()
|
||||
}
|
||||
unsafe fn get_INTR_ENABLE() -> u32 {
|
||||
mailbox_mmio.offset(1).read_volatile()
|
||||
}
|
||||
unsafe fn get_INTR_TEST() -> u32 {
|
||||
mailbox_mmio.offset(2).read_volatile()
|
||||
}
|
||||
unsafe fn get_MBOXW() -> u32 {
|
||||
mailbox_mmio.offset(3).read_volatile()
|
||||
}
|
||||
unsafe fn get_MBOXR() -> u32 {
|
||||
mailbox_mmio.offset(4).read_volatile()
|
||||
}
|
||||
unsafe fn get_STATUS() -> u32 {
|
||||
mailbox_mmio.offset(5).read_volatile()
|
||||
}
|
||||
unsafe fn get_ERROR() -> u32 {
|
||||
mailbox_mmio.offset(6).read_volatile()
|
||||
}
|
||||
unsafe fn get_WIRQT() -> u32 {
|
||||
mailbox_mmio.offset(7).read_volatile()
|
||||
}
|
||||
unsafe fn get_RIRQT() -> u32 {
|
||||
mailbox_mmio.offset(8).read_volatile()
|
||||
}
|
||||
unsafe fn get_CTRL() -> u32 {
|
||||
mailbox_mmio.offset(9).read_volatile()
|
||||
}
|
||||
|
||||
unsafe fn set_INTR_STATE(x: u32) {
|
||||
mailbox_mmio.offset(0).write_volatile(x);
|
||||
}
|
||||
unsafe fn set_INTR_ENABLE(x: u32) {
|
||||
mailbox_mmio.offset(1).write_volatile(x);
|
||||
}
|
||||
unsafe fn set_INTR_TEST(x: u32) {
|
||||
mailbox_mmio.offset(2).write_volatile(x);
|
||||
}
|
||||
unsafe fn set_MBOXW(x: u32) {
|
||||
mailbox_mmio.offset(3).write_volatile(x);
|
||||
}
|
||||
unsafe fn set_MBOXR(x: u32) {
|
||||
mailbox_mmio.offset(4).write_volatile(x);
|
||||
}
|
||||
unsafe fn set_STATUS(x: u32) {
|
||||
mailbox_mmio.offset(5).write_volatile(x);
|
||||
}
|
||||
unsafe fn set_ERROR(x: u32) {
|
||||
mailbox_mmio.offset(6).write_volatile(x);
|
||||
}
|
||||
unsafe fn set_WIRQT(x: u32) {
|
||||
mailbox_mmio.offset(7).write_volatile(x);
|
||||
}
|
||||
unsafe fn set_RIRQT(x: u32) {
|
||||
mailbox_mmio.offset(8).write_volatile(x);
|
||||
}
|
||||
unsafe fn set_CTRL(x: u32) {
|
||||
mailbox_mmio.offset(9).write_volatile(x);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Directly manipulate the hardware FIFOs. Synchronous and busy-waits. Not
|
||||
// thread-safe, should only be used while holding the api_mutex lock.
|
||||
|
||||
fn enqueue_u32(x: u32) {
|
||||
unsafe {
|
||||
while (get_STATUS() & STATUS_BIT_FULL) == STATUS_BIT_FULL {}
|
||||
set_MBOXW(x);
|
||||
}
|
||||
}
|
||||
|
||||
fn dequeue_u32() -> u32 {
|
||||
unsafe {
|
||||
while (get_STATUS() & STATUS_BIT_EMPTY) == STATUS_BIT_EMPTY {}
|
||||
return get_MBOXR();
|
||||
}
|
||||
}
|
||||
|
||||
fn drain_read_fifo() {
|
||||
unsafe {
|
||||
while (get_STATUS() & STATUS_BIT_EMPTY) == 0 {
|
||||
let _ = get_MBOXR();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pre_init() {
|
||||
static KATA_LOGGER: KataLogger = KataLogger;
|
||||
log::set_logger(&KATA_LOGGER).unwrap();
|
||||
log::set_max_level(log::LevelFilter::Trace);
|
||||
|
||||
// We always want our receive interrupt to fire as soon as anything appears
|
||||
// in the mailbox, so set the threshold to 0.
|
||||
set_RIRQT(0);
|
||||
set_INTR_STATE(INTR_STATE_BIT_RTIRQ);
|
||||
set_INTR_ENABLE(INTR_ENABLE_BIT_RTIRQ);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// When outbox.count > write_threshold, this interrupt fires.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wtirq_handle() {
|
||||
trace!("wtirq_handle()");
|
||||
|
||||
// We don't have anything to do here yet, so just clear the interrupt.
|
||||
set_INTR_STATE(INTR_STATE_BIT_WTIRQ);
|
||||
wtirq_acknowledge();
|
||||
}
|
||||
|
||||
// When inbox.count > read_threshold, this interrupt fires.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn rtirq_handle() {
|
||||
trace!("rtirq_handle()");
|
||||
|
||||
// Unblock anyone waiting for a message. api_receive() below will clear
|
||||
// the interrupt once the message has been deliverd to the client.
|
||||
rx_semaphore_post();
|
||||
}
|
||||
|
||||
// When an error occurs, this interrupt fires. We don't handle errors yet.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn eirq_handle() {
|
||||
error!("eirq_handle() - error flag is 0x{:X}", get_ERROR());
|
||||
|
||||
// We don't have anything to do here yet, so just clear the interrupt.
|
||||
set_INTR_STATE(INTR_STATE_BIT_EIRQ);
|
||||
eirq_acknowledge();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Send a message to the security core. The message must be at a _physical_
|
||||
// address, as the security core knows nothing about seL4's virtual memory.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn api_send(request_paddr: u32, request_size: u32) {
|
||||
api_mutex_lock();
|
||||
|
||||
let request_header = request_size | HEADER_FLAG_LONG_MESSAGE;
|
||||
enqueue_u32(request_header);
|
||||
enqueue_u32(request_paddr);
|
||||
|
||||
api_mutex_unlock();
|
||||
}
|
||||
|
||||
// Receive a message from the security core. Blocks the calling thread until a
|
||||
// message arrives.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn api_receive(response_paddr: *mut u32, response_size: *mut u32) {
|
||||
api_mutex_lock();
|
||||
|
||||
// When a message arrives, the interrupt handler will raise the semaphore.
|
||||
rx_semaphore_wait();
|
||||
|
||||
// Message arrived, dequeue it.
|
||||
let message_header = dequeue_u32();
|
||||
let message_paddr = dequeue_u32();
|
||||
response_paddr.write(message_paddr);
|
||||
response_size.write(message_header & !HEADER_FLAG_LONG_MESSAGE);
|
||||
|
||||
// The interrupt that raised the semaphore has been handled, clear it.
|
||||
set_INTR_STATE(INTR_STATE_BIT_RTIRQ);
|
||||
rtirq_acknowledge();
|
||||
|
||||
api_mutex_unlock();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
@ -3,16 +3,21 @@
|
||||
import <LoggerInterface.camkes>;
|
||||
import <MemoryInterface.camkes>;
|
||||
import <SecurityCoordinatorInterface.camkes>;
|
||||
import <MailboxInterface.camkes>;
|
||||
|
||||
component SecurityCoordinator {
|
||||
provides SecurityCoordinatorInterface security;
|
||||
|
||||
uses LoggerInterface logger;
|
||||
uses MemoryInterface memory;
|
||||
uses MailboxAPI mailbox_api;
|
||||
|
||||
// Enable KataOS CAmkES support.
|
||||
attribute int kataos = true;
|
||||
|
||||
// Add free slots for processing requests.
|
||||
attribute int cnode_headroom = 32;
|
||||
|
||||
// For mailbox use. What should we call this?
|
||||
has copyregion COPYREGION;
|
||||
}
|
||||
|
@ -232,6 +232,12 @@ fn delete_key_request(
|
||||
unsafe { KATA_SECURITY.delete_key(request.bundle_id, request.key) }
|
||||
}
|
||||
|
||||
fn test_mailbox_request(
|
||||
) -> Result<(), SecurityRequestError> {
|
||||
trace!("TEST MAILBOX");
|
||||
unsafe { KATA_SECURITY.test_mailbox() }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn security_request(
|
||||
c_request: SecurityRequest,
|
||||
@ -263,5 +269,7 @@ pub unsafe extern "C" fn security_request(
|
||||
write_key_request(request_buffer, reply_buffer),
|
||||
SecurityRequest::SrDeleteKey =>
|
||||
delete_key_request(request_buffer, reply_buffer),
|
||||
SecurityRequest::SrTestMailbox =>
|
||||
test_mailbox_request(),
|
||||
}.map_or_else(|e| e, |_v| SecurityRequestError::SreSuccess)
|
||||
}
|
||||
|
@ -3,11 +3,13 @@
|
||||
extern crate alloc;
|
||||
use alloc::fmt;
|
||||
use alloc::string::{String, ToString};
|
||||
use core::mem::size_of;
|
||||
use hashbrown::HashMap;
|
||||
use kata_memory_interface::ObjDescBundle;
|
||||
use kata_memory_interface::kata_object_free_in_cnode;
|
||||
use kata_memory_interface::*;
|
||||
use kata_os_common::sel4_sys::*;
|
||||
use kata_security_interface::*;
|
||||
use kata_storage_interface::KeyValueData;
|
||||
use log::trace;
|
||||
|
||||
struct BundleData {
|
||||
pkg_contents: ObjDescBundle,
|
||||
@ -21,7 +23,8 @@ impl BundleData {
|
||||
BundleData {
|
||||
pkg_contents: pkg_contents.clone(),
|
||||
pkg_size: size_bytes,
|
||||
manifest: String::from(r##"
|
||||
manifest: String::from(
|
||||
r##"
|
||||
# Comments like this
|
||||
[Manifest]
|
||||
BundleId=com.google.cerebra.hw.HelloWorld
|
||||
@ -32,7 +35,8 @@ Model=NeuralNetworkName
|
||||
|
||||
[Storage]
|
||||
Required=1
|
||||
"##,),
|
||||
"##,
|
||||
),
|
||||
keys: HashMap::with_capacity(2),
|
||||
}
|
||||
}
|
||||
@ -84,7 +88,10 @@ impl SecurityCoordinatorInterface for FakeSecurityCoordinator {
|
||||
if self.bundles.contains_key(&bundle_id) {
|
||||
return Err(SecurityRequestError::SreDeleteFirst);
|
||||
}
|
||||
assert!(self.bundles.insert(bundle_id.clone(), BundleData::new(pkg_contents)).is_none());
|
||||
assert!(self
|
||||
.bundles
|
||||
.insert(bundle_id.clone(), BundleData::new(pkg_contents))
|
||||
.is_none());
|
||||
Ok(bundle_id)
|
||||
}
|
||||
fn uninstall(&mut self, bundle_id: &str) -> Result<(), SecurityRequestError> {
|
||||
@ -104,7 +111,11 @@ impl SecurityCoordinatorInterface for FakeSecurityCoordinator {
|
||||
// XXX just return the package for now
|
||||
Ok(bundle_data.pkg_contents.clone())
|
||||
}
|
||||
fn load_model(&self, bundle_id: &str, _model_id: &str) -> Result<ObjDescBundle, SecurityRequestError> {
|
||||
fn load_model(
|
||||
&self,
|
||||
bundle_id: &str,
|
||||
_model_id: &str,
|
||||
) -> Result<ObjDescBundle, SecurityRequestError> {
|
||||
let bundle_data = self.get_bundle(bundle_id)?;
|
||||
// TODO(sleffler): check model id
|
||||
// XXX just return the package for now
|
||||
@ -112,9 +123,17 @@ impl SecurityCoordinatorInterface for FakeSecurityCoordinator {
|
||||
}
|
||||
fn read_key(&self, bundle_id: &str, key: &str) -> Result<&KeyValueData, SecurityRequestError> {
|
||||
let bundle = self.get_bundle(bundle_id)?;
|
||||
bundle.keys.get(key).ok_or(SecurityRequestError::SreKeyNotFound)
|
||||
bundle
|
||||
.keys
|
||||
.get(key)
|
||||
.ok_or(SecurityRequestError::SreKeyNotFound)
|
||||
}
|
||||
fn write_key(&mut self, bundle_id: &str, key: &str, value: &KeyValueData) -> Result<(), SecurityRequestError> {
|
||||
fn write_key(
|
||||
&mut self,
|
||||
bundle_id: &str,
|
||||
key: &str,
|
||||
value: &KeyValueData,
|
||||
) -> Result<(), SecurityRequestError> {
|
||||
let bundle = self.get_bundle_mut(bundle_id)?;
|
||||
let _ = bundle.keys.insert(key.to_string(), *value);
|
||||
Ok(())
|
||||
@ -125,4 +144,98 @@ impl SecurityCoordinatorInterface for FakeSecurityCoordinator {
|
||||
let _ = bundle.keys.remove(key);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_mailbox(&mut self) -> Result<(), SecurityRequestError> {
|
||||
trace!("test_mailbox_command()");
|
||||
|
||||
const PAGE_SIZE: usize = 1 << seL4_PageBits;
|
||||
const MESSAGE_SIZE_DWORDS: usize = 17; // Just a random message size for testing.
|
||||
|
||||
extern "C" {
|
||||
fn mailbox_api_send(paddr: u32, size: u32);
|
||||
fn mailbox_api_receive(paddr: *mut u32, size: *mut u32);
|
||||
static SELF_VSPACE_ROOT: seL4_CPtr;
|
||||
|
||||
// This is not actually a block of memory, it's a reserved range in
|
||||
// the virtual address space that we can map physical memory into.
|
||||
static mut COPYREGION: [u32; 1024];
|
||||
}
|
||||
|
||||
// Allocate a 4k page to serve as our message buffer.
|
||||
let frame_bundle =
|
||||
kata_frame_alloc(PAGE_SIZE).map_err(|_| SecurityRequestError::SreTestFailed)?;
|
||||
trace!("test_mailbox: Frame {:?}", frame_bundle);
|
||||
|
||||
unsafe {
|
||||
// Map the message buffer into our copyregion so we can access it.
|
||||
// FIXME(aappleby): We need a drop() impl here somewhere so this
|
||||
// doesn't leak if something fails.
|
||||
let message_ptr = core::ptr::addr_of_mut!(COPYREGION[0]);
|
||||
seL4_Page_Map(
|
||||
/*sel4_page=*/ frame_bundle.objs[0].cptr,
|
||||
/*seL4_pd=*/ SELF_VSPACE_ROOT,
|
||||
/*vaddr=*/ message_ptr as usize,
|
||||
seL4_CapRights::new(
|
||||
// NB: RW 'cuz W-only silently gets upgraded by kernel
|
||||
/*grant_reply=*/
|
||||
0, /*grant=*/ 0, /*read=1*/ 1, /*write=*/ 1,
|
||||
),
|
||||
seL4_Default_VMAttributes,
|
||||
)
|
||||
.map_err(|_| SecurityRequestError::SreTestFailed)?;
|
||||
|
||||
// Write to the message buffer through the copyregion.
|
||||
let offset_a = 0 as isize;
|
||||
let offset_b = (MESSAGE_SIZE_DWORDS - 1) as isize;
|
||||
message_ptr.offset(offset_a).write(0xDEADBEEF);
|
||||
message_ptr.offset(offset_b).write(0xF00DCAFE);
|
||||
trace!(
|
||||
"test_mailbox: old buf contents 0x{:X} 0x{:X}",
|
||||
message_ptr.offset(offset_a).read(),
|
||||
message_ptr.offset(offset_b).read()
|
||||
);
|
||||
|
||||
// Send the _physical_ address of the message buffer to the security
|
||||
// core.
|
||||
let paddr = seL4_Page_GetAddress(frame_bundle.objs[0].cptr);
|
||||
mailbox_api_send(
|
||||
paddr.paddr as u32,
|
||||
(MESSAGE_SIZE_DWORDS * size_of::<u32>()) as u32,
|
||||
);
|
||||
|
||||
// Wait for the response to arrive.
|
||||
let mut response_paddr: u32 = 0;
|
||||
let mut response_size: u32 = 0;
|
||||
mailbox_api_receive(
|
||||
&mut response_paddr as *mut u32,
|
||||
&mut response_size as *mut u32,
|
||||
);
|
||||
|
||||
// The security core should have replaced the first and last dwords
|
||||
// with 0x12345678 and 0x87654321.
|
||||
trace!("test_mailbox: expected contents 0x12345678 0x87654321");
|
||||
trace!(
|
||||
"test_mailbox: new buf contents 0x{:X} 0x{:X}",
|
||||
message_ptr.offset(offset_a).read(),
|
||||
message_ptr.offset(offset_b).read()
|
||||
);
|
||||
|
||||
let dword_a = message_ptr.offset(offset_a).read();
|
||||
let dword_b = message_ptr.offset(offset_b).read();
|
||||
|
||||
seL4_Page_Unmap(frame_bundle.objs[0].cptr)
|
||||
.map_err(|_| SecurityRequestError::SreTestFailed)?;
|
||||
|
||||
// Done, free the message buffer.
|
||||
kata_object_free_toplevel(&frame_bundle)
|
||||
.map_err(|_| SecurityRequestError::SreTestFailed)?;
|
||||
|
||||
if dword_a != 0x12345678 || dword_b != 0x87654321 {
|
||||
return Err(SecurityRequestError::SreTestFailed);
|
||||
}
|
||||
}
|
||||
|
||||
trace!("test_mailbox_command() done");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -84,8 +84,9 @@ impl SecurityCoordinatorInterface for SeL4SecurityCoordinator {
|
||||
Err(SreGetManifestFailed)
|
||||
}
|
||||
SecurityRequest::SrLoadApplication => {
|
||||
let mut request = postcard::from_bytes::<LoadApplicationRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
let mut request =
|
||||
postcard::from_bytes::<LoadApplicationRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
request.set_container_cap(unsafe { SECURITY_RECV_SLOT });
|
||||
trace!(
|
||||
"LOAD APPLICATION bundle_id {} app_binary {:?}",
|
||||
|
@ -57,16 +57,34 @@ impl SecurityCoordinatorInterface for KataSecurityCoordinator {
|
||||
fn load_application(&self, bundle_id: &str) -> Result<ObjDescBundle, SecurityRequestError> {
|
||||
self.manager.as_ref().unwrap().load_application(bundle_id)
|
||||
}
|
||||
fn load_model(&self, bundle_id: &str, model_id: &str) -> Result<ObjDescBundle, SecurityRequestError> {
|
||||
self.manager.as_ref().unwrap().load_model(bundle_id, model_id)
|
||||
fn load_model(
|
||||
&self,
|
||||
bundle_id: &str,
|
||||
model_id: &str,
|
||||
) -> Result<ObjDescBundle, SecurityRequestError> {
|
||||
self.manager
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.load_model(bundle_id, model_id)
|
||||
}
|
||||
fn read_key(&self, bundle_id: &str, key: &str) -> Result<&KeyValueData, SecurityRequestError> {
|
||||
self.manager.as_ref().unwrap().read_key(bundle_id, key)
|
||||
}
|
||||
fn write_key(&mut self, bundle_id: &str, key: &str, value: &KeyValueData) -> Result<(), SecurityRequestError> {
|
||||
self.manager.as_mut().unwrap().write_key(bundle_id, key, value)
|
||||
fn write_key(
|
||||
&mut self,
|
||||
bundle_id: &str,
|
||||
key: &str,
|
||||
value: &KeyValueData,
|
||||
) -> Result<(), SecurityRequestError> {
|
||||
self.manager
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.write_key(bundle_id, key, value)
|
||||
}
|
||||
fn delete_key(&mut self, bundle_id: &str, key: &str) -> Result<(), SecurityRequestError> {
|
||||
self.manager.as_mut().unwrap().delete_key(bundle_id, key)
|
||||
}
|
||||
fn test_mailbox(&mut self) -> Result<(), SecurityRequestError> {
|
||||
self.manager.as_mut().unwrap().test_mailbox()
|
||||
}
|
||||
}
|
||||
|
@ -166,6 +166,12 @@ pub struct DeleteKeyRequest<'a> {
|
||||
}
|
||||
impl<'a> SecurityCapability for DeleteKeyRequest<'a> {}
|
||||
|
||||
// SecurityRequestTestMailbox
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct TestMailboxRequest {
|
||||
}
|
||||
impl SecurityCapability for TestMailboxRequest {}
|
||||
|
||||
// NB: this is the union of InstallInterface & StorageInterface because
|
||||
// the camkes-generated interface code uses basic C which does not
|
||||
// tolerate overlapping member names.
|
||||
@ -197,6 +203,7 @@ pub enum SecurityRequestError {
|
||||
SreReadFailed,
|
||||
SreWriteFailed,
|
||||
SreDeleteFailed,
|
||||
SreTestFailed,
|
||||
}
|
||||
|
||||
impl From<SecurityRequestError> for StorageError {
|
||||
@ -232,6 +239,8 @@ pub enum SecurityRequest {
|
||||
SrReadKey, // Read key value [bundle_id, key] -> value
|
||||
SrWriteKey, // Write key value [bundle_id, key, value]
|
||||
SrDeleteKey, // Delete key [bundle_id, key]
|
||||
|
||||
SrTestMailbox, // Run mailbox tests
|
||||
}
|
||||
|
||||
// Interface to underlying facilities; also used to inject fakes for unit tests.
|
||||
@ -245,6 +254,7 @@ pub trait SecurityCoordinatorInterface {
|
||||
fn read_key(&self, bundle_id: &str, key: &str) -> Result<&KeyValueData, SecurityRequestError>;
|
||||
fn write_key(&mut self, bundle_id: &str, key: &str, value: &KeyValueData) -> Result<(), SecurityRequestError>;
|
||||
fn delete_key(&mut self, bundle_id: &str, key: &str) -> Result<(), SecurityRequestError>;
|
||||
fn test_mailbox(&mut self) -> Result<(), SecurityRequestError>;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -462,3 +472,13 @@ pub fn kata_security_delete_key(
|
||||
&mut [0u8; SECURITY_REPLY_DATA_SIZE],
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn kata_security_test_mailbox() -> Result<(), SecurityRequestError> {
|
||||
kata_security_request(
|
||||
SecurityRequest::SrTestMailbox,
|
||||
&TestMailboxRequest {},
|
||||
&mut [0u8; SECURITY_REPLY_DATA_SIZE],
|
||||
)
|
||||
}
|
||||
|
4
apps/system/interfaces/MailboxInterface.camkes
Normal file
4
apps/system/interfaces/MailboxInterface.camkes
Normal file
@ -0,0 +1,4 @@
|
||||
procedure MailboxAPI {
|
||||
void send(in uint32_t request_paddr, in uint32_t request_size);
|
||||
void receive(out uint32_t response_paddr, out uint32_t response_size);
|
||||
};
|
@ -21,6 +21,7 @@ import "components/MemoryManager/MemoryManager.camkes";
|
||||
import "components/StorageManager/StorageManager.camkes";
|
||||
import "components/SecurityCoordinator/SecurityCoordinator.camkes";
|
||||
import "components/TimerService/TimerService.camkes";
|
||||
import "components/MailboxDriver/MailboxDriver.camkes";
|
||||
|
||||
component OpenTitanUART {
|
||||
hardware;
|
||||
@ -55,6 +56,14 @@ component BuiltinCpioArchive {
|
||||
dataport Buf(0x1000000) cpio;
|
||||
}
|
||||
|
||||
component MailboxHardware {
|
||||
hardware;
|
||||
dataport Buf mmio;
|
||||
emits Interrupt wtirq;
|
||||
emits Interrupt rtirq;
|
||||
emits Interrupt eirq;
|
||||
}
|
||||
|
||||
assembly {
|
||||
composition {
|
||||
component VectorCoreHw vctop;
|
||||
@ -76,6 +85,20 @@ assembly {
|
||||
connection seL4HardwareMMIO cpio_archive(from debug_console.cpio_archive,
|
||||
to cpio.cpio);
|
||||
|
||||
// MailboxDriver
|
||||
component MailboxHardware mailbox_hardware;
|
||||
component MailboxDriver mailbox_driver;
|
||||
connection seL4HardwareMMIO mailbox_driver_mmio(
|
||||
from mailbox_driver.mailbox_mmio, to mailbox_hardware.mmio);
|
||||
connection seL4HardwareInterrupt mailbox_driver_wtirq(
|
||||
from mailbox_hardware.wtirq, to mailbox_driver.wtirq);
|
||||
connection seL4HardwareInterrupt mailbox_driver_rtirq(
|
||||
from mailbox_hardware.rtirq, to mailbox_driver.rtirq);
|
||||
connection seL4HardwareInterrupt mailbox_driver_eirq(
|
||||
from mailbox_hardware.eirq, to mailbox_driver.eirq);
|
||||
connection seL4RPCCall security_coordinator_to_mailbox_api(
|
||||
from security_coordinator.mailbox_api, to mailbox_driver.api);
|
||||
|
||||
// OpenTitanUARTDriver
|
||||
connection seL4HardwareMMIO uart_mem(from uart_driver.mmio_region,
|
||||
to uart.mmio_region);
|
||||
@ -165,6 +188,7 @@ assembly {
|
||||
from security_coordinator.logger,
|
||||
from storage_manager.logger,
|
||||
from timer_service.logger,
|
||||
from mailbox_driver.logger,
|
||||
to debug_console.logger);
|
||||
}
|
||||
|
||||
@ -172,6 +196,14 @@ assembly {
|
||||
cpio.cpio_paddr = 0x46000000;
|
||||
cpio.cpio_size = 0x1000000;
|
||||
|
||||
mailbox_hardware.mmio_paddr = 0x540F1000;
|
||||
mailbox_hardware.mmio_size = 0x00001000;
|
||||
mailbox_hardware.wtirq_irq_number = 10; // kTopMatchaPlicIrqIdMailboxSmcWtirq
|
||||
mailbox_hardware.rtirq_irq_number = 11; // kTopMatchaPlicIrqIdMailboxSmcRtirq
|
||||
mailbox_hardware.eirq_irq_number = 12; // kTopMatchaPlicIrqIdMailboxSmcEirq
|
||||
|
||||
mailbox_driver.rx_semaphore_value = 0;
|
||||
|
||||
uart.mmio_region_paddr = 0x50000000;
|
||||
uart.mmio_region_size = 0x1000;
|
||||
uart.tx_watermark_irq_number = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user