diff --git a/Cargo.lock b/Cargo.lock index f441343..b390e94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,6 +112,10 @@ dependencies = [ "nix 0.28.0", ] +[[package]] +name = "cache_slice" +version = "0.1.0" + [[package]] name = "cache_utils" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 2008c78..876b5ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,5 +15,6 @@ members = [ "basic_timing_cache_channel", "turn_lock", "CacheObserver", - "dendrobates-t-azureus" -] \ No newline at end of file + "dendrobates-t-azureus", + "cache_slice", +] diff --git a/cache_slice/Cargo.toml b/cache_slice/Cargo.toml new file mode 100644 index 0000000..eeafc02 --- /dev/null +++ b/cache_slice/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cache_slice" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/cache_slice/src/bin/rdmsr.rs b/cache_slice/src/bin/rdmsr.rs new file mode 100644 index 0000000..15ce6d0 --- /dev/null +++ b/cache_slice/src/bin/rdmsr.rs @@ -0,0 +1,24 @@ +use cache_slice::msr; +use std::env; +fn main() { + let mut args = env::args().into_iter(); + args.next(); + for arg in args { + match arg.parse::() { + Ok(msr) => { + match msr::read_msr_on_cpu(msr, 0) { + Ok(result) => { + println!("MSR {}: {:x}", msr, result); + }, + Err(e) => { + eprintln!("Error, failed to read MSR {}: {}", msr, e); + } + } + }, + Err(e) => { + eprintln!("Error: {}", e); + eprintln!("{} is not a valid MSR number", arg); + } + } + } +} \ No newline at end of file diff --git a/cache_slice/src/lib.rs b/cache_slice/src/lib.rs new file mode 100644 index 0000000..89e7ac1 --- /dev/null +++ b/cache_slice/src/lib.rs @@ -0,0 +1,16 @@ +pub mod msr; + +pub fn add(left: u64, right: u64) -> u64 { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/cache_slice/src/msr.rs b/cache_slice/src/msr.rs new file mode 100644 index 0000000..9b6ee29 --- /dev/null +++ b/cache_slice/src/msr.rs @@ -0,0 +1,42 @@ +use core::mem::size_of; +use std::format; +use std::fs::{File, OpenOptions}; +use std::os::unix::fs::FileExt; +use std::io::{Result, Error, ErrorKind}; + +pub fn write_msr_on_cpu(msr: u32, cpu: u8, value: u64) -> Result<()> { + let path = format!("/dev/cpu/{}/msr", cpu); + let file : File = OpenOptions::new().write(true).open(path).expect("Failed to open MSR, are you running as root ?"); + match file.write_at(&value.to_ne_bytes(), msr as u64) { + Ok(size) => { + if size == size_of::() { + Ok(()) + } else { + Err(Error::other("Failed to write complete value")) + } + }, + Err(e) => Err(e) + } +} + +pub fn read_msr_on_cpu(msr: u32, cpu: u8) -> Result { + let path = format!("/dev/cpu/{}/msr", cpu); + let file : File = OpenOptions::new().read(true).open(path).expect("Failed to open MSR, are you running as root ?"); + let mut read_data = [0u8; size_of::()]; + match file.read_at(&mut read_data, msr as u64) { + Ok(size) => { + if size == size_of::() { + Ok(u64::from_ne_bytes(read_data)) + } else { + Err(Error::other("Failed to write complete value")) + } + }, + Err(e) => Err(e) + } +} + +#[cfg(test)] +mod tests { + use super::*; + // TODO how can we test model specific register read / write ? +}