Start working on cache detection using Clementine Maurice's performance counter approach.

Add a new crate for that, getting out of cache_utils no_std / use_std mess.
This commit is contained in:
Guillaume DIDIER 2024-06-24 09:40:43 +02:00
parent a20210e5d7
commit f9217b00c4
6 changed files with 95 additions and 2 deletions

4
Cargo.lock generated
View File

@ -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"

View File

@ -15,5 +15,6 @@ members = [
"basic_timing_cache_channel",
"turn_lock",
"CacheObserver",
"dendrobates-t-azureus"
]
"dendrobates-t-azureus",
"cache_slice",
]

6
cache_slice/Cargo.toml Normal file
View File

@ -0,0 +1,6 @@
[package]
name = "cache_slice"
version = "0.1.0"
edition = "2021"
[dependencies]

View File

@ -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::<u32>() {
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);
}
}
}
}

16
cache_slice/src/lib.rs Normal file
View File

@ -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);
}
}

42
cache_slice/src/msr.rs Normal file
View File

@ -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::<u64>() {
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<u64> {
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::<u64>()];
match file.read_at(&mut read_data, msr as u64) {
Ok(size) => {
if size == size_of::<u64>() {
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 ?
}