diff --git a/Cargo.lock b/Cargo.lock index 8599a7fd..256cf7a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -551,6 +551,7 @@ dependencies = [ name = "tracing_firmware" version = "0.1.0" dependencies = [ + "config_helpers", "miralis_abi", ] diff --git a/config/test/spike-latency-benchmark-protect-payload.toml b/config/test/spike-latency-benchmark-protect-payload.toml new file mode 100644 index 00000000..c55152d4 --- /dev/null +++ b/config/test/spike-latency-benchmark-protect-payload.toml @@ -0,0 +1,23 @@ +# A simple configuration to run on the Spike platform + +[log] +level = "info" +color = true + +[vcpu] +max_pmp = 8 +delegate_perf_counters=true + +[platform] +name = "spike" + +[target.miralis] +# Build profile for Miralis (dev profile is set by default) +profile = "release" + +[target.firmware] +# Build profile for the firmware (dev profile is set by default) +profile = "release" + +[policy] +name = "protect_payload" diff --git a/firmware/tracing_firmware/Cargo.toml b/firmware/tracing_firmware/Cargo.toml index 661b8f61..92987b4c 100644 --- a/firmware/tracing_firmware/Cargo.toml +++ b/firmware/tracing_firmware/Cargo.toml @@ -11,3 +11,4 @@ path = "main.rs" [dependencies] miralis_abi = { path = "../../crates/abi" } +config_helpers = { path = "../../crates/config_helpers" } \ No newline at end of file diff --git a/firmware/tracing_firmware/main.rs b/firmware/tracing_firmware/main.rs index 32e9bdc0..4befeaa1 100644 --- a/firmware/tracing_firmware/main.rs +++ b/firmware/tracing_firmware/main.rs @@ -9,10 +9,15 @@ use core::arch::{asm, global_asm}; +use config_helpers::parse_str_or; use miralis_abi::{failure, log, setup_binary, success}; setup_binary!(main); +const POLICY_NAME: &str = parse_str_or(option_env!("MIRALIS_POLICY_NAME"), "default_policy"); + +const PROTECT_PAYLOAD_POLICY: &str = "protect_payload"; + fn enable_mcycle_in_smode() { unsafe { // This allows to read cycle in S-mode - for the payload @@ -122,6 +127,11 @@ fn operating_system() { } measure(false); + + if POLICY_NAME == PROTECT_PAYLOAD_POLICY { + measure_misaligned(); + } + success(); } @@ -136,14 +146,29 @@ fn measure(is_firmware: bool) { let average_measure = trigger_ctx_switch_to_firmware_batched(); if is_firmware { - log::info!("Firmware cost : {}", average_measure); + log::info!("Firmware cost {} : {}", POLICY_NAME, average_measure); } else { - log::info!("Payload cost : {}", average_measure); + log::info!("Payload cost {} : {}", POLICY_NAME, average_measure); } print_statistics(stats); } +fn measure_misaligned() { + let mut values: [usize; NB_REPEATS] = [0; NB_REPEATS]; + + for i in 0..NB_REPEATS { + values[i] = trigger_misaligned_op() + } + + let stats = get_statistics(values); + let average_measure = trigger_ctx_switch_to_firmware_batched(); + + log::info!("Misaligned cost {} : {}", POLICY_NAME, average_measure); + + print_statistics(stats); +} + fn trigger_ctx_switch_to_firmware() -> usize { let begin: u64; let end: u64; @@ -179,6 +204,53 @@ fn trigger_ctx_switch_to_firmware_batched() -> usize { (end - begin) as usize / NB_REPEATS } +pub fn trigger_misaligned_op() -> usize { + let begin: u64; + let end: u64; + + let misaligned_address_8_bytes: usize = 0x80600301; + + unsafe { + // Read the `mcycle` register (assuming 64-bit RISC-V) + asm!("csrr {}, cycle", out(reg) begin); + // We trigger a misaligned operation + asm!( + "ld {r}, 0({addr})", + addr = in(reg) misaligned_address_8_bytes, + r = out(reg) _, + ); + // Read the `mcycle` register (assuming 64-bit RISC-V) + asm!("csrr {}, cycle", out(reg) end); + } + + (end - begin) as usize +} + +pub fn trigger_misaligned_op_batched() -> usize { + let begin: u64; + let end: u64; + + let misaligned_address_8_bytes: usize = 0x80600301; + + unsafe { + // Read the `mcycle` register (assuming 64-bit RISC-V) + asm!("csrr {}, cycle", out(reg) begin); + + for _ in 0..NB_REPEATS { + // We trigger a misaligned operation + asm!( + "ld {r}, 0({addr})", + addr = in(reg) misaligned_address_8_bytes, + r = out(reg) _, + ); + } + // Read the `mcycle` register (assuming 64-bit RISC-V) + asm!("csrr {}, cycle", out(reg) end); + } + + (end - begin) as usize / NB_REPEATS +} + #[derive(Debug)] pub struct Statistics { mean: usize, diff --git a/miralis.toml b/miralis.toml index 41b010ac..519014c5 100644 --- a/miralis.toml +++ b/miralis.toml @@ -32,6 +32,9 @@ path = "config/test/spike-protect-payload.toml" [config.spike-benchmark] path = "./config/test/spike-latency-benchmark.toml" +[config.spike-benchmark-protect-payload] +path = "./config/test/spike-latency-benchmark-protect-payload.toml" + ## ——————————————————————————— Integration Tests ———————————————————————————— ## [test.ecall] @@ -226,3 +229,8 @@ description = "The most basic test, which directly exit with an ecall to Miralis firmware = "tracing_firmware" config = "spike-benchmark" description = "The firmware and configuration we use to measure cycles in the CI" + +[test.spike-benchmark-protect-payload] +firmware = "tracing_firmware" +config = "spike-benchmark-protect-payload" +description = "The firmware and configuration we use to measure cycles in the CI using the protect payload policy" diff --git a/misc/push_stats.sh b/misc/push_stats.sh index 3314cc40..ae77a6a1 100755 --- a/misc/push_stats.sh +++ b/misc/push_stats.sh @@ -49,8 +49,11 @@ file="cycles.txt" cargo run -- run --firmware tracing_firmware --config ./config/test/spike-latency-benchmark.toml > $file # Extract the number after "firmware cost:" -firmware_cost=$(grep -i "Firmware cost :" "$file" | sed -E 's/.*Firmware cost : ([0-9]+).*/\1/') -payload_cost=$(grep -i "Payload cost :" "$file" | sed -E 's/.*Payload cost : ([0-9]+).*/\1/') +firmware_cost=$(grep -i "Firmware cost default_policy :" "$file" | sed -E 's/.*Firmware cost default_policy : ([0-9]+).*/\1/') +payload_cost=$(grep -i "Payload cost default_policy :" "$file" | sed -E 's/.*Payload cost default_policy : ([0-9]+).*/\1/') +firmware_cost_protect=$(grep -i "Firmware cost protect_payload:" "$file" | sed -E 's/.*Firmware cost protect_payload : ([0-9]+).*/\1/') +payload_cost_protect=$(grep -i "Payload cost protect_payload :" "$file" | sed -E 's/.*Payload cost protect_payload : ([0-9]+).*/\1/') +misaligned_cost_protect=$(grep -i "Misaligned cost protect_payload :" "$file" | sed -E 's/.*Misaligned cost protect_payload : ([0-9]+).*/\1/') # Check if a number was found if [ -n "$firmware_cost" ]; then @@ -66,17 +69,42 @@ else echo "No firmware cost found in the file." fi +# Check if a number was found +if [ -n "$firmware_cost_protect" ]; then + echo "Firmware cost: $firmware_cost_protect" +else + echo "No firmware cost found in the file." +fi + +# Check if a number was found +if [ -n "$payload_cost_protect" ]; then + echo "Payload cost: $payload_cost_protect" +else + echo "No firmware cost found in the file." +fi + +# Check if a number was found +if [ -n "$misaligned_cost_protect" ]; then + echo "Payload cost: $misaligned_cost_protect" +else + echo "No firmware cost found in the file." +fi + + # ———————————————————————————————— Push stats ———————————————————————————————— # echo "Commit: $git_commit" echo "Current date: $current_date" echo "Miralis size: $miralis_size bytes" echo "Build time: $build_time" -echo "Miralis <--> Firmware latency in cycles: " firmware_cost +echo "Miralis <--> Firmware latency in cycles: " $firmware_cost echo "Payload <--> Firmware latency in cycles: " $payload_cost +echo "[PROTECT PAYLOAD] Miralis <--> Firmware latency in cycles: " $firmware_cost_protect +echo "[PROTECT PAYLOAD] Payload <--> Firmware latency in cycles: " $payload_cost_protect +echo "[PROTECT PAYLOAD] Cost of a misaligned emulation: " $misaligned_cost_protect if [ "$1" = "--commit" ]; then - csv_entry="$git_commit, $current_date, $miralis_size, $build_time, $firmware_cost, $payload_cost" + csv_entry="$git_commit, $current_date, $miralis_size, $build_time, $firmware_cost, $payload_cost,$firmware_cost_protect,$payload_cost_protect,$misaligned_cost_protect" echo $csv_entry >> "$miralis_stats_csv_path" echo "Added CSV entry to $miralis_stats_csv_path" fi diff --git a/runner/src/artifacts.rs b/runner/src/artifacts.rs index 122bef0a..71fbe6d7 100644 --- a/runner/src/artifacts.rs +++ b/runner/src/artifacts.rs @@ -347,7 +347,7 @@ pub fn build_target(target: Target, cfg: &Config) -> PathBuf { let linker_args = format!("-C link-arg=-Tmisc/linker-script.x -C link-arg=--defsym=_start_address={firmware_address}"); build_cmd.env("RUSTFLAGS", linker_args); build_cmd.env("IS_TARGET_FIRMWARE", "true"); - build_cmd.envs(cfg.benchmark.build_envs()); + build_cmd.envs(cfg.build_envs()); build_cmd.arg("--package").arg(firmware); if firmware == "miralis" { @@ -365,7 +365,7 @@ pub fn build_target(target: Target, cfg: &Config) -> PathBuf { let linker_args = format!("-C link-arg=-Tmisc/linker-script.x -C link-arg=--defsym=_start_address={payload_address}"); build_cmd.env("RUSTFLAGS", linker_args); build_cmd.env("IS_TARGET_FIRMWARE", "false"); - build_cmd.envs(cfg.benchmark.build_envs()); + build_cmd.envs(cfg.build_envs()); build_cmd.arg("--package").arg(payload_name); } }