From b82fe778f899e5ba73ce9029159ac9cfce354748 Mon Sep 17 00:00:00 2001 From: Guillume DIDIER Date: Wed, 10 Nov 2021 15:12:01 +0100 Subject: [PATCH] Add the current experiments --- basic_timing_cache_channel/src/naive.rs | 17 ++++++++ prefetcher_reverse/run-msr-stream.sh | 8 ++++ prefetcher_reverse/run-msr-stride.sh | 8 ++++ prefetcher_reverse/setup.sh | 5 +++ prefetcher_reverse/src/bin/stream.rs | 34 +++++++++++++++ prefetcher_reverse/src/bin/strides.rs | 35 +++++++++++++++ prefetcher_reverse/src/lib.rs | 58 +++++++++++++++---------- 7 files changed, 141 insertions(+), 24 deletions(-) create mode 100755 prefetcher_reverse/run-msr-stream.sh create mode 100755 prefetcher_reverse/run-msr-stride.sh create mode 100755 prefetcher_reverse/setup.sh create mode 100644 prefetcher_reverse/src/bin/stream.rs create mode 100644 prefetcher_reverse/src/bin/strides.rs diff --git a/basic_timing_cache_channel/src/naive.rs b/basic_timing_cache_channel/src/naive.rs index c1e9ac8..922d7ad 100644 --- a/basic_timing_cache_channel/src/naive.rs +++ b/basic_timing_cache_channel/src/naive.rs @@ -165,6 +165,23 @@ impl NaiveTimingChannel { } Ok(()) } + + pub unsafe fn test_debug( + &self, + handle: &mut NaiveTimingChannelHandle, + reset: bool, + ) -> Result<(CacheStatus, u64), SideChannelError> { + // This should be handled in prepare / unprepare + let t = unsafe { self.channel_primitive.attack(handle.addr) }; + if T::NEED_RESET && reset { + unsafe { flush(handle.addr) }; + } + if self.threshold.is_hit(t) { + Ok((CacheStatus::Hit, t)) + } else { + Ok((CacheStatus::Miss, t)) + } + } } impl CoreSpec for NaiveTimingChannel { diff --git a/prefetcher_reverse/run-msr-stream.sh b/prefetcher_reverse/run-msr-stream.sh new file mode 100755 index 0000000..b46d286 --- /dev/null +++ b/prefetcher_reverse/run-msr-stream.sh @@ -0,0 +1,8 @@ +#!/bin/bash +PREFETCH_MSR=$1 +sudo wrmsr -a 0x1a4 $PREFETCH_MSR +sudo echo wrmsr -a 0x1a4 $PREFETCH_MSR +sudo rdmsr -a 0x1a4 +cargo run --release --bin stream > stream-with-${PREFETCH_MSR}-prefetcher.log +sudo rdmsr -a 0x1a4 + diff --git a/prefetcher_reverse/run-msr-stride.sh b/prefetcher_reverse/run-msr-stride.sh new file mode 100755 index 0000000..18a173a --- /dev/null +++ b/prefetcher_reverse/run-msr-stride.sh @@ -0,0 +1,8 @@ +#!/bin/bash +PREFETCH_MSR=$1 +sudo wrmsr -a 0x1a4 $PREFETCH_MSR +sudo echo wrmsr -a 0x1a4 $PREFETCH_MSR +sudo rdmsr -a 0x1a4 +cargo run --release --bin strides > strides-with-${PREFETCH_MSR}-prefetcher.log +sudo rdmsr -a 0x1a4 + diff --git a/prefetcher_reverse/setup.sh b/prefetcher_reverse/setup.sh new file mode 100755 index 0000000..e385301 --- /dev/null +++ b/prefetcher_reverse/setup.sh @@ -0,0 +1,5 @@ +# performance cpu frequency governor +cpupower frequency-set -g performance + +# No Turbo Boost +echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo diff --git a/prefetcher_reverse/src/bin/stream.rs b/prefetcher_reverse/src/bin/stream.rs new file mode 100644 index 0000000..75d944b --- /dev/null +++ b/prefetcher_reverse/src/bin/stream.rs @@ -0,0 +1,34 @@ +use prefetcher_reverse::{Prober, PAGE_CACHELINE_LEN}; + +pub const NUM_ITERATION: usize = 1 << 10; + +fn exp(stride: usize, num_steps: i32, delay: u64) { + let mut prober = Prober::<2>::new(63).unwrap(); + prober.set_delay(delay); + let limit = if num_steps < 0 { + PAGE_CACHELINE_LEN + stride + 2 + } else { + stride * num_steps as usize + }; + let pattern = (2usize..limit).step_by(stride).collect::>(); + let result = prober.full_page_probe(pattern, NUM_ITERATION as u32, 100); + println!("{}", result); +} + +fn main() { + for stride in [3, 4] { + for delay_shift in [5, 12] { + let limit = ((PAGE_CACHELINE_LEN + 32) / stride) as i32; + //for num_steps in -1..limit { + let num_steps = limit; + println!( + "Stride: {}, Limit: {}, Delay: {}", + stride, + num_steps, + 1 << delay_shift + ); + exp(stride, num_steps, 1 << delay_shift); + //} + } + } +} diff --git a/prefetcher_reverse/src/bin/strides.rs b/prefetcher_reverse/src/bin/strides.rs new file mode 100644 index 0000000..f2c6a49 --- /dev/null +++ b/prefetcher_reverse/src/bin/strides.rs @@ -0,0 +1,35 @@ +use prefetcher_reverse::{Prober, PAGE_CACHELINE_LEN}; + +pub const NUM_ITERATION: usize = 1 << 10; + +fn exp(stride: usize, num_steps: i32, delay: u64) { + let mut prober = Prober::<2>::new(63).unwrap(); + prober.set_delay(delay); + let limit = if num_steps < 0 { + PAGE_CACHELINE_LEN + stride + 2 + } else { + stride * num_steps as usize + }; + let pattern = (2usize..limit).step_by(stride).collect::>(); + let result = prober.full_page_probe(pattern, NUM_ITERATION as u32, 100); + println!("{}", result); +} + +fn main() { + for stride in [5, 7, 8] { + for delay_shift in [5, 12, 20] { + //let stride = 8; + let limit = (PAGE_CACHELINE_LEN / stride) as i32 + 2; + //for num_steps in -1..limit { + let num_steps = limit; + println!( + "Stride: {}, Limit: {}, Delay: {}", + stride, + num_steps, + 1 << delay_shift + ); + exp(stride, num_steps, 1 << delay_shift); + //} + } + } +} diff --git a/prefetcher_reverse/src/lib.rs b/prefetcher_reverse/src/lib.rs index d28bb85..1227345 100644 --- a/prefetcher_reverse/src/lib.rs +++ b/prefetcher_reverse/src/lib.rs @@ -13,6 +13,7 @@ use cache_side_channel::{ }; use cache_utils::calibration::{only_reload, Threshold, PAGE_LEN}; use cache_utils::mmap::MMappedMemory; +use cache_utils::rdtsc_nofence; use flush_flush::{FFHandle, FFPrimitives, FlushAndFlush}; use flush_reload::naive::{NFRHandle, NaiveFlushAndReload}; use flush_reload::{FRHandle, FRPrimitives, FlushAndReload}; @@ -34,12 +35,12 @@ pub const CALIBRATION_STRAT: CalibrationStrategy = CalibrationStrategy::ASVP; pub struct Prober { pages: Vec>, ff_handles: Vec>, - fr_handles: Vec>, - //fr_handles: Vec>, + //fr_handles: Vec>, + fr_handles: Vec>, page_indexes: Peekable>>, ff_channel: FlushAndFlush, - fr_channel: FlushAndReload, - //fr_channel: NaiveFlushAndReload, + //fr_channel: FlushAndReload, + fr_channel: NaiveFlushAndReload, delay: u64, } @@ -73,8 +74,8 @@ pub enum ProberError { /** Result of running a probe pattern num_iteration times, */ -pub type SinglePR = u32; -pub type FullPR = Vec; +pub type SinglePR = u64; +pub type FullPR = Vec; #[derive(Debug)] pub enum ProbeResult { @@ -86,13 +87,13 @@ pub enum ProbeResult { #[derive(Debug)] pub struct ProbePatternResult { pub num_iteration: u32, - pub pattern_result: Vec, + pub pattern_result: Vec, pub probe_result: ProbeResult, } #[derive(Debug)] pub struct DPRItem { - pub pattern_result: Vec, + pub pattern_result: Vec, pub probe_result: PR, } @@ -114,8 +115,8 @@ pub struct FullPageDualProbeResults { #[derive(Debug)] pub struct SingleProbeResult { pub probe_offset: usize, - pub pattern_result: Vec, - pub probe_result: u32, + pub pattern_result: Vec, + pub probe_result: u64, } #[derive(Debug)] @@ -126,6 +127,14 @@ pub struct FullPageSingleProbeResult { pub results: Vec, } +fn delay(d: u64) { + let mut t = unsafe { rdtsc_nofence() }; + let end = t + d; + while t < end { + t = unsafe { rdtsc_nofence() }; + } +} + // Helper function /** This function is a helper that determine what is the maximum stride for a pattern of len accesses @@ -160,16 +169,16 @@ impl Prober { Ok(old) => old, Err(nixerr) => return Err(ProberError::Nix(nixerr)), }; - /*let mut fr_channel = NaiveFlushAndReload::new(Threshold { - bucket_index: 250, + let mut fr_channel = NaiveFlushAndReload::new(Threshold { + bucket_index: 315, miss_faster_than_hit: false, - });*/ - let mut fr_channel = match FlushAndReload::new(core, core, CALIBRATION_STRAT) { + }); + /*let mut fr_channel = match FlushAndReload::new(core, core, CALIBRATION_STRAT) { Ok(res) => res, Err(err) => { return Err(ProberError::TopologyError(err)); } - }; + };*/ for i in 0..num_pages { let mut p = match MMappedMemory::::try_new(PAGE_LEN * GS, false, false, |j| { @@ -233,13 +242,14 @@ impl Prober { unsafe { self.ff_channel.prepare(&mut ff_handles) }; - let mut pattern_res = vec![CacheStatus::Miss; pattern.pattern.len()]; + let mut pattern_res = vec![0; pattern.pattern.len()]; for (i, offset) in pattern.pattern.iter().enumerate() { let h = &mut self.fr_handles[page_index][*offset]; - pattern_res[i] = unsafe { self.fr_channel.test_single(h, false) }.unwrap(); - if self.delay > 0 { + pattern_res[i] = unsafe { self.fr_channel.test_debug(h, false) }.unwrap().1; + delay(self.delay); + /*if self.delay > 0 { thread::sleep(time::Duration::from_nanos(self.delay)); // FIXME parameter magic - } + }*/ //pattern_res[i] = unsafe { self.fr_channel.test_single(h, false) }.unwrap() //pattern_res[i] = Miss; //unsafe { only_reload(h.to_const_u8_pointer()) }; @@ -286,9 +296,9 @@ impl Prober { } for (i, res) in pattern_res.into_iter().enumerate() { - if res == Hit { - result_ref.pattern_result[i] += 1 - } + //if res == Hit { + result_ref.pattern_result[i] += res; + //} } } } @@ -454,7 +464,7 @@ impl Display for FullPageDualProbeResults { ), Some(index) => { let pat = format!("{:3}", index); - let sf_ac: u32 = self + let sf_ac: u64 = self .single_probe_results .iter() .map(|d| d.flush.pattern_result[index]) @@ -462,7 +472,7 @@ impl Display for FullPageDualProbeResults { let sf_ac_h = format!("{:8}", sf_ac); let sf_ac_hr = format!("{:9.7}", sf_ac as f32 / divider); - let sr_ac: u32 = self + let sr_ac: u64 = self .single_probe_results .iter() .map(|d| d.load.pattern_result[index])