Skip to content

Commit

Permalink
add flux support crate and work on peeling back flux::ignores
Browse files Browse the repository at this point in the history
  • Loading branch information
enjhnsn2 committed Jul 22, 2024
1 parent cf097d0 commit 1b6579b
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 24 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ members = [
"libraries/riscv-csr",
"libraries/tock-cells",
"libraries/tock-register-interface",
"libraries/tickv",
"libraries/tickv", "flux_support",
]
exclude = ["tools/"]
resolver = "2"
Expand Down
1 change: 1 addition & 0 deletions arch/cortex-m/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ enabled = true

[dependencies]
kernel = { path = "../../kernel" }
flux_support = { path = "../../flux_support" }
11 changes: 9 additions & 2 deletions arch/cortex-m/src/mpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ use kernel::utilities::math;
use kernel::utilities::registers::interfaces::{Readable, Writeable};
use kernel::utilities::registers::{register_bitfields, FieldValue, ReadOnly, ReadWrite};
use kernel::utilities::StaticRef;
use flux_support::*;

/*
#[allow(dead_code)]
#[flux::sig(fn(x: bool[true]))]
fn assert(_x: bool) {}
Expand All @@ -26,6 +29,7 @@ pub fn assume(b: bool) {
panic!("assume fails")
}
}
*/

// VTOCK-TODO: supplementary proof?
#[flux::sig(fn(n: u32{n < 32}) -> usize {r: r > 0 })]
Expand Down Expand Up @@ -651,9 +655,8 @@ impl<const MIN_REGION_SIZE: usize> mpu::MPU for MPU<MIN_REGION_SIZE> {
// Region size is the actual size the MPU region will be set to, and is
// half of the total power of two size we are allocating to the app.

//assume(memory_size_po2 > 1);
let mut region_size = memory_size_po2 / 2;
//assume(region_size > 0);

// The region should start as close as possible to the start of the
// unallocated memory.
let mut region_start = unallocated_memory_start as usize;
Expand Down Expand Up @@ -760,6 +763,9 @@ impl<const MIN_REGION_SIZE: usize> mpu::MPU for MPU<MIN_REGION_SIZE> {
let app_memory_break = app_memory_break as usize;
let kernel_memory_break = kernel_memory_break as usize;

assume(app_memory_break > region_start);
assume(region_size > 7);

// Out of memory
if app_memory_break > kernel_memory_break {
return Err(());
Expand All @@ -785,6 +791,7 @@ impl<const MIN_REGION_SIZE: usize> mpu::MPU for MPU<MIN_REGION_SIZE> {

// Get the number of subregions enabled in each of the two MPU regions.
let num_enabled_subregions0 = cmp::min(num_enabled_subregions, 8);
assume(num_enabled_subregions0 >= 8);
let num_enabled_subregions1 = num_enabled_subregions.saturating_sub(8);

let region0 = CortexMRegion::new(
Expand Down
1 change: 1 addition & 0 deletions kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ enabled = true
tock-registers = { path = "../libraries/tock-register-interface" }
tock-cells = { path = "../libraries/tock-cells" }
tock-tbf = { path = "../libraries/tock-tbf" }
flux_support = { path = "../flux_support" }

# In general, Tock discourages the use of cargo features. However for certain
# kernel crate configuration, we have not found reasonable alternatives to
Expand Down
3 changes: 3 additions & 0 deletions kernel/src/memop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use crate::process::TockProc;
use crate::syscall::SyscallReturn;
use crate::ErrorCode;
use flux_support::*;

/// Handle the `memop` syscall.
///
Expand Down Expand Up @@ -80,6 +81,7 @@ pub(crate) fn memop(process: &TockProc<'_>, op_type: usize, r1: usize) -> Syscal
if size == 0 {
SyscallReturn::Failure(ErrorCode::FAIL)
} else {
assume(flash_start < u32::MAX / 2 && offset < u32::MAX / 4);
SyscallReturn::SuccessU32(flash_start + offset)
}
}
Expand All @@ -93,6 +95,7 @@ pub(crate) fn memop(process: &TockProc<'_>, op_type: usize, r1: usize) -> Syscal
if size == 0 {
SyscallReturn::Failure(ErrorCode::FAIL)
} else {
assume(flash_start < u32::MAX / 2 && offset < u32::MAX / 4 && size < u32::MAX / 4);
SyscallReturn::SuccessU32(flash_start + offset + size)
}
}
Expand Down
3 changes: 3 additions & 0 deletions kernel/src/platform/mpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use core::cmp;
use core::fmt::{self, Display};
use flux_support::*;

/// User mode access permissions.
#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -312,6 +313,8 @@ impl MPU for () {
_permissions: Permissions,
_config: &mut Self::MpuConfig,
) -> Option<(*const u8, usize)> {
assume(initial_app_memory_size < usize::MAX / 2);
assume(initial_kernel_memory_size < usize::MAX / 2);
let memory_size = cmp::max(
min_memory_size,
initial_app_memory_size + initial_kernel_memory_size,
Expand Down
31 changes: 31 additions & 0 deletions kernel/src/process_checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,37 @@ impl Compress for () {
pub trait AppIdPolicy: AppUniqueness + Compress {}
impl<T: AppUniqueness + Compress> AppIdPolicy for T {}

#[allow(dead_code, unused_variables)]
#[flux::opaque]
#[flux::trusted]
pub struct AppIdPolicyProxy<'a> {
_inner: &'a dyn AppIdPolicy,
}

impl<'a> AppIdPolicyProxy<'a> {
pub fn to_short_id(&self, _process: &ProcessBinary) -> ShortId { unimplemented!() }
pub fn different_identifier(&self, _process_a: &ProcessBinary, _process_b: &ProcessBinary) -> bool {
unimplemented!()
}

pub fn different_identifier_process(
&self,
_process_a: &ProcessBinary,
_process_b: &TockProc<'_>,
) -> bool {
unimplemented!()
}

pub fn different_identifier_processes(
&self,
_process_a: &TockProc<'_>,
_process_b: &TockProc<'_>,
) -> bool {
unimplemented!()
}
}


/// Client interface for the outcome of a process credential check.
pub trait ProcessCheckerMachineClient {
/// Check is finished, and the check result is in `result`.0
Expand Down
48 changes: 31 additions & 17 deletions kernel/src/process_loading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@
use core::cell::Cell;
use core::fmt;

use crate::capabilities::ProcessManagementCapability;
use crate::capabilities::ProcessManagementCap;
use crate::config;
use crate::debug;
use crate::deferred_call::{DeferredCall, DeferredCallClient};
use crate::kernel::Kernel;
use crate::platform::chip::Chip;
use crate::process::{ShortId, TockProc};
use crate::process_binary::{ProcessBinary, ProcessBinaryError};
use crate::process_checker::{AppIdPolicy, ProcessCheckError, ProcessCheckerMachine};
use crate::process_policies::ProcessFaultPolicy;
use crate::process_checker::{AppIdPolicyProxy, ProcessCheckError, ProcessCheckerMachine};
use crate::process_policies::ProcessFaultPolicyProxy;
use crate::process_standard::ProcessStandard;
use crate::utilities::cells::{MapCell, OptionalCell};

Expand Down Expand Up @@ -137,8 +137,8 @@ pub fn load_processes<C: Chip>(
app_flash: &'static [u8],
app_memory: &'static mut [u8],
mut procs: &'static mut [Option<TockProc<'_>>],
fault_policy: &'static dyn ProcessFaultPolicy,
_capability_management: &dyn ProcessManagementCapability,
fault_policy: &'static ProcessFaultPolicyProxy,
_capability_management: &ProcessManagementCap,
) -> Result<(), ProcessLoadError> {
load_processes_from_flash(
kernel,
Expand Down Expand Up @@ -187,7 +187,7 @@ fn load_processes_from_flash<C: Chip>(
app_flash: &'static [u8],
app_memory: &'static mut [u8],
procs: &mut &'static mut [Option<TockProc<'_>>],
fault_policy: &'static dyn ProcessFaultPolicy,
fault_policy: &'static ProcessFaultPolicyProxy,
) -> Result<(), ProcessLoadError> {
if config::CONFIG.debug_load_processes {
debug!(
Expand Down Expand Up @@ -348,7 +348,7 @@ fn load_process<C: Chip>(
app_memory: &'static mut [u8],
app_id: ShortId,
index: usize,
fault_policy: &'static dyn ProcessFaultPolicy,
fault_policy: &'static ProcessFaultPolicyProxy,
) -> Result<(&'static mut [u8], Option<TockProc<'static>>), (&'static mut [u8], ProcessLoadError)> {
if config::CONFIG.debug_load_processes {
debug!(
Expand Down Expand Up @@ -418,6 +418,20 @@ pub trait ProcessLoadingAsyncClient {
fn process_loading_finished(&self);
}

#[allow(dead_code, unused_variables)]
#[flux::opaque]
#[flux::trusted]
pub struct ProcessLoadingAsyncClientProxy<'a> {
_inner: &'a dyn ProcessLoadingAsyncClient,
}

impl<'a> ProcessLoadingAsyncClientProxy<'a> {
fn process_loaded(&self, _result: Result<(), ProcessLoadError>) {unimplemented!()}

fn process_loading_finished(&self) {unimplemented!()}
}


/// Asynchronous process loading.
///
/// Machines which implement this trait perform asynchronous process loading and
Expand All @@ -428,10 +442,10 @@ pub trait ProcessLoadingAsyncClient {
pub trait ProcessLoadingAsync<'a> {
/// Set the client to receive callbacks about process loading and when
/// process loading has finished.
fn set_client(&self, client: &'a dyn ProcessLoadingAsyncClient);
fn set_client(&self, client: &'a ProcessLoadingAsyncClientProxy<'a>);

/// Set the credential checking policy for the loader.
fn set_policy(&self, policy: &'a dyn AppIdPolicy);
fn set_policy(&self, policy: &'a AppIdPolicyProxy);

/// Start the process loading operation.
fn start(&self);
Expand All @@ -454,7 +468,7 @@ enum SequentialProcessLoaderMachineState {
/// the checker to decide whether the process has sufficient credentials to run.
pub struct SequentialProcessLoaderMachine<'a, C: Chip + 'static> {
/// Client to notify as processes are loaded and process loading finishes.
client: OptionalCell<&'a dyn ProcessLoadingAsyncClient>,
client: OptionalCell<&'a ProcessLoadingAsyncClientProxy<'a>>,
/// Machine to use to check process credentials.
checker: &'static ProcessCheckerMachine,
/// Array of stored process references for loaded processes.
Expand All @@ -472,9 +486,9 @@ pub struct SequentialProcessLoaderMachine<'a, C: Chip + 'static> {
/// Reference to the Chip object for creating Processes.
chip: &'static C,
/// The policy to use when determining ShortIds and process uniqueness.
policy: OptionalCell<&'a dyn AppIdPolicy>,
policy: OptionalCell<&'a AppIdPolicyProxy<'a>>,
/// The fault policy to assign to each created Process.
fault_policy: &'static dyn ProcessFaultPolicy,
fault_policy: &'static ProcessFaultPolicyProxy<'static>,
/// Current mode of the loading machine.
state: OptionalCell<SequentialProcessLoaderMachineState>,
}
Expand All @@ -492,9 +506,9 @@ impl<'a, C: Chip> SequentialProcessLoaderMachine<'a, C> {
chip: &'static C,
flash: &'static [u8],
app_memory: &'static mut [u8],
fault_policy: &'static dyn ProcessFaultPolicy,
policy: &'static dyn AppIdPolicy,
_capability_management: &dyn ProcessManagementCapability,
fault_policy: &'static ProcessFaultPolicyProxy<'static>,
policy: &'static AppIdPolicyProxy,
_capability_management: &ProcessManagementCap,
) -> Self {
Self {
deferred_call: DeferredCall::new(),
Expand Down Expand Up @@ -855,11 +869,11 @@ impl<'a, C: Chip> SequentialProcessLoaderMachine<'a, C> {
}

impl<'a, C: Chip> ProcessLoadingAsync<'a> for SequentialProcessLoaderMachine<'a, C> {
fn set_client(&self, client: &'a dyn ProcessLoadingAsyncClient) {
fn set_client(&self, client: &'a ProcessLoadingAsyncClientProxy<'a>) {
self.client.set(client);
}

fn set_policy(&self, policy: &'a dyn AppIdPolicy) {
fn set_policy(&self, policy: &'a AppIdPolicyProxy) {
self.policy.replace(policy);
}

Expand Down
12 changes: 12 additions & 0 deletions kernel/src/process_policies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ pub trait ProcessFaultPolicy {
fn action(&self, process: &TockProc<'_>) -> process::FaultAction;
}

#[allow(dead_code, unused_variables)]
#[flux::opaque]
#[flux::trusted]
pub struct ProcessFaultPolicyProxy<'a> {
_inner: &'a dyn ProcessFaultPolicy,
}

impl<'a> ProcessFaultPolicyProxy<'a> {
pub fn action(&self, _process: &TockProc<'_>) -> process::FaultAction {unimplemented!()}
}


/// Simply panic the entire board if a process faults.
pub struct PanicFaultPolicy {}

Expand Down
9 changes: 5 additions & 4 deletions kernel/src/process_standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ use crate::process::{Error, FunctionCall, FunctionCallSource, Process, State, Ta
use crate::process::{FaultAction, ProcessCustomGrantIdentifier, ProcessId};
use crate::process::{ProcessAddresses, ProcessSizes, ShortId};
use crate::process_loading::ProcessLoadError;
use crate::process_policies::ProcessFaultPolicy;
use crate::processbuffer::{ReadOnlyProcessBuffer, ReadWriteProcessBuffer};
use crate::storage_permissions;
use crate::syscall::{self, Syscall, SyscallReturn, UserspaceKernelBoundary};
use crate::upcall::UpcallId;
use crate::utilities::cells::{MapCell, NumericCellExt, OptionalCell};
use crate::process_policies::ProcessFaultPolicyProxy;


use tock_tbf::types::CommandPermissions;

Expand Down Expand Up @@ -203,7 +204,7 @@ pub struct ProcessStandard<'a, C: 'static + Chip> {
state: Cell<State>,

/// How to respond if this process faults.
fault_policy: &'a dyn ProcessFaultPolicy,
fault_policy: &'a ProcessFaultPolicyProxy<'a>,

/// Configuration data for the MPU
mpu_config: MapCell<<<C as Chip>::MPU as MPU>::MpuConfig>,
Expand Down Expand Up @@ -1162,7 +1163,7 @@ impl<C: Chip> Process for ProcessStandard<'_, C> {
process_control_block: Self::PROCESS_STRUCT_OFFSET,
}
}

#[flux::ignore]
fn print_full_process(&self, writer: &mut dyn Write) {
if !config::CONFIG.debug_panics {
return;
Expand Down Expand Up @@ -1281,7 +1282,7 @@ impl<C: 'static + Chip> ProcessStandard<'_, C> {
chip: &'static C,
pb: ProcessBinary,
remaining_memory: &'a mut [u8],
fault_policy: &'static dyn ProcessFaultPolicy,
fault_policy: &'static ProcessFaultPolicyProxy,
app_id: ShortId,
index: usize,
) -> Result<(Option<TockProc<'static>>, &'a mut [u8]), (ProcessLoadError, &'a mut [u8])> {
Expand Down
4 changes: 4 additions & 0 deletions kernel/src/utilities/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ pub fn log_base_two_u64(num: u64) -> u32 {
const EXPONENT_MASK: u32 = 0b01111111_10000000_00000000_00000000;
const EXPONENT_BIAS: u32 = 127;

#[flux::ignore]
pub fn abs(n: f32) -> f32 {
f32::from_bits(n.to_bits() & 0x7FFF_FFFF)
}
Expand All @@ -124,10 +125,12 @@ fn extract_exponent_bits(x: f32) -> u32 {
(x.to_bits() & EXPONENT_MASK).overflowing_shr(23).0
}

#[flux::ignore]
fn extract_exponent_value(x: f32) -> i32 {
(extract_exponent_bits(x) as i32) - EXPONENT_BIAS as i32
}

#[flux::ignore]
fn ln_1to2_series_approximation(x: f32) -> f32 {
// idea from https://stackoverflow.com/a/44232045/
// modified to not be restricted to int range and only values of x above 1.0.
Expand Down Expand Up @@ -165,6 +168,7 @@ fn ln_1to2_series_approximation(x: f32) -> f32 {
}
}

#[flux::ignore]
pub fn log10(x: f32) -> f32 {
//using change of base log10(x) = ln(x)/ln(10)
let ln10_recip = f32::consts::LOG10_E;
Expand Down

0 comments on commit 1b6579b

Please sign in to comment.