diff --git a/Cargo.lock b/Cargo.lock index 3460145..fcc36ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -115,6 +115,7 @@ dependencies = [ "covert_channels_evaluation", "flush_flush", "flush_reload", + "nix", ] [[package]] diff --git a/covert_channels_benchmark/Cargo.toml b/covert_channels_benchmark/Cargo.toml index 0249f0c..7ce0f33 100644 --- a/covert_channels_benchmark/Cargo.toml +++ b/covert_channels_benchmark/Cargo.toml @@ -10,3 +10,6 @@ edition = "2018" covert_channels_evaluation = { path = "../covert_channels_evaluation" } flush_flush = { path = "../flush_flush" } flush_reload = { path = "../flush_reload" } +nix = "0.18.0" + + diff --git a/covert_channels_benchmark/src/bin/main-naive.rs b/covert_channels_benchmark/src/bin/main-naive.rs new file mode 100644 index 0000000..ca58cbf --- /dev/null +++ b/covert_channels_benchmark/src/bin/main-naive.rs @@ -0,0 +1,124 @@ +#![feature(unsafe_block_in_unsafe_fn)] +#![deny(unsafe_op_in_unsafe_fn)] + +use std::io::{stdout, Write}; + +use covert_channels_evaluation::{benchmark_channel, CovertChannel, CovertChannelBenchmarkResult}; +use flush_flush::naive::NaiveFlushAndFlush; +use flush_flush::{FlushAndFlush, SingleFlushAndFlush}; +use flush_reload::naive::NaiveFlushAndReload; +use nix::sched::{sched_getaffinity, CpuSet}; +use nix::unistd::Pid; + +const NUM_BYTES: usize = 1 << 14; //20 + +const NUM_PAGES: usize = 1; + +const NUM_PAGES_2: usize = 4; + +const NUM_PAGE_MAX: usize = 32; + +const NUM_ITER: usize = 32; + +struct BenchmarkStats { + raw_res: Vec, + average_p: f64, + var_p: f64, + average_C: f64, + var_C: f64, + average_T: f64, + var_T: f64, +} + +fn run_benchmark( + name: &str, + constructor: impl Fn(usize, usize) -> T, + num_iter: usize, + num_pages: usize, +) -> BenchmarkStats { + let mut results = Vec::new(); + print!("Benchmarking {} with {} pages", name, num_pages); + let old = sched_getaffinity(Pid::from_raw(0)).unwrap(); + for i in 0..CpuSet::count() { + for j in 0..CpuSet::count() { + for _ in 0..num_iter { + print!("."); + stdout().flush().expect("Failed to flush"); + let channel = constructor(i, j); + let r = benchmark_channel(channel, num_pages, NUM_BYTES); + results.push(r); + } + } + } + println!(); + let mut average_p = 0.0; + let mut average_C = 0.0; + let mut average_T = 0.0; + for result in results.iter() { + println!("{:?}", result); + println!("C: {}, T: {}", result.capacity(), result.true_capacity()); + average_p += result.error_rate; + average_C += result.capacity(); + average_T += result.true_capacity() + } + average_p /= num_iter as f64; + average_C /= num_iter as f64; + average_T /= num_iter as f64; + println!( + "{} - {} Average p: {} C: {}, T: {}", + name, num_pages, average_p, average_C, average_T + ); + let mut var_p = 0.0; + let mut var_C = 0.0; + let mut var_T = 0.0; + for result in results.iter() { + let p = result.error_rate - average_p; + var_p += p * p; + let C = result.capacity() - average_C; + var_C += C * C; + let T = result.true_capacity() - average_T; + var_T += T * T; + } + var_p /= num_iter as f64; + var_C /= num_iter as f64; + var_T /= num_iter as f64; + println!( + "{} - {} Variance of p: {}, C: {}, T:{}", + name, num_pages, var_p, var_C, var_T + ); + BenchmarkStats { + raw_res: results, + average_p, + var_p, + average_C, + var_C, + average_T, + var_T, + } +} + +fn main() { + for num_pages in 1..=32 { + let naive_ff = run_benchmark( + "Naive F+F", + |i, j| { + let mut r = NaiveFlushAndFlush::from_threshold(202); + r.set_cores(i, j); + r + }, + NUM_ITER, + num_pages, + ); + + let fr = run_benchmark( + "F+R", + |i, j| { + let mut r = NaiveFlushAndReload::from_threshold(250); + r.set_cores(i, j); + r + }, + NUM_ITER, + num_pages, + ); + } +} diff --git a/flush_flush/src/naive.rs b/flush_flush/src/naive.rs index 6f76c70..b491fca 100644 --- a/flush_flush/src/naive.rs +++ b/flush_flush/src/naive.rs @@ -13,6 +13,8 @@ use std::thread::current; pub struct NaiveFlushAndFlush { pub threshold: u64, current: HashMap, + main_core: CpuSet, + helper_core: CpuSet, } impl NaiveFlushAndFlush { @@ -20,6 +22,8 @@ impl NaiveFlushAndFlush { NaiveFlushAndFlush { threshold, current: Default::default(), + main_core: sched_getaffinity(Pid::from_raw(0)).unwrap(), + helper_core: sched_getaffinity(Pid::from_raw(0)).unwrap(), } } unsafe fn test_impl(&self, addr: *const u8) -> Result { @@ -34,6 +38,14 @@ impl NaiveFlushAndFlush { Ok(CacheStatus::Hit) } } + + pub fn set_cores(&mut self, main_core: usize, helper_core: usize) { + self.main_core = CpuSet::new(); + self.main_core.set(main_core).unwrap(); + + self.helper_core = CpuSet::new(); + self.helper_core.set(helper_core).unwrap(); + } } impl SingleAddrCacheSideChannel for NaiveFlushAndFlush { @@ -74,11 +86,11 @@ unsafe impl Sync for NaiveFlushAndFlush {} impl CoreSpec for NaiveFlushAndFlush { fn main_core(&self) -> CpuSet { - sched_getaffinity(Pid::from_raw(0)).unwrap() + self.main_core } fn helper_core(&self) -> CpuSet { - sched_getaffinity(Pid::from_raw(0)).unwrap() + self.helper_core } } diff --git a/flush_reload/src/naive.rs b/flush_reload/src/naive.rs index deb6f17..e1c0ef9 100644 --- a/flush_reload/src/naive.rs +++ b/flush_reload/src/naive.rs @@ -13,6 +13,8 @@ use std::thread::current; pub struct NaiveFlushAndReload { pub threshold: u64, current: HashMap, + main_core: CpuSet, + helper_core: CpuSet, } impl NaiveFlushAndReload { @@ -20,6 +22,8 @@ impl NaiveFlushAndReload { NaiveFlushAndReload { threshold, current: Default::default(), + main_core: sched_getaffinity(Pid::from_raw(0)).unwrap(), + helper_core: sched_getaffinity(Pid::from_raw(0)).unwrap(), } } unsafe fn test_impl(&self, addr: *const u8) -> Result { @@ -35,6 +39,14 @@ impl NaiveFlushAndReload { Ok(CacheStatus::Hit) } } + + pub fn set_cores(&mut self, main_core: usize, helper_core: usize) { + self.main_core = CpuSet::new(); + self.main_core.set(main_core).unwrap(); + + self.helper_core = CpuSet::new(); + self.helper_core.set(helper_core).unwrap(); + } } impl SingleAddrCacheSideChannel for NaiveFlushAndReload { @@ -75,11 +87,11 @@ unsafe impl Sync for NaiveFlushAndReload {} impl CoreSpec for NaiveFlushAndReload { fn main_core(&self) -> CpuSet { - sched_getaffinity(Pid::from_raw(0)).unwrap() + self.main_core } fn helper_core(&self) -> CpuSet { - sched_getaffinity(Pid::from_raw(0)).unwrap() + self.helper_core } }