Correct various issues in scan, and set core affinity properly.

This commit is contained in:
Guillaume DIDIER 2024-06-24 16:58:32 +02:00
parent ba87550b65
commit f6494a82b2
4 changed files with 50 additions and 19 deletions

View File

@ -5,4 +5,4 @@ edition = "2021"
[dependencies]
raw-cpuid = "11.0.2"
nix = "0.29.0"
nix = { version = "0.29.0", features = ["sched"] }

View File

@ -1,20 +1,21 @@
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>() {
match arg.parse::<u64>() {
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);

View File

@ -1,6 +1,7 @@
use cache_slice::monitor_address;
use cache_slice::utils::core_per_package;
use nix::sched::{sched_getaffinity, CpuSet};
use nix::sched::{sched_getaffinity, sched_setaffinity, CpuSet};
use nix::unistd::Pid;
pub fn main() {
@ -8,10 +9,23 @@ pub fn main() {
println!("Found {} cores", nb_cores);
let target = vec![0x0123456789abcdefu64, 64];
for core in 0..CpuSet::count() {
let old = sched_getaffinity(Pid::from_raw(0)).unwrap();
let mut core_set = Vec::new();
for i in 0..CpuSet::count() {
if old.is_set(i).unwrap() {
core_set.push(i);
}
}
for core in core_set {
let mut cpu_set = CpuSet::new();
cpu_set.set(core).unwrap();
sched_setaffinity(Pid::this(), &cpu_set).unwrap();
for addr in target.iter() {
let res = unsafe { monitor_address(addr as *const u64 as *const u8, core as u8, nb_cores) };
let slice = res.iter().enumerate().max_by_key(|(i, val)| { val });
let res = unsafe { monitor_address(addr as *const u64 as *const u8, core as u8, nb_cores) }.unwrap();
let slice = res.iter().enumerate().max_by_key(|(_i, val)| { **val });
match slice {
Some((slice, _)) => {
println!("({:2}) Slice for addr {:x}: {}", core, addr as *const u64 as usize, slice)
@ -22,8 +36,8 @@ pub fn main() {
}
}
for addr in target.iter() {
let res = unsafe { monitor_address(addr as *const u64 as *const u8, 0, nb_cores) };
let slice = res.iter().enumerate().max_by_key(|(i, val)| { val });
let res = unsafe { monitor_address(addr as *const u64 as *const u8, 0, nb_cores) }.unwrap();
let slice = res.iter().enumerate().max_by_key(|(_i, val)| { **val });
match slice {
Some((slice, _)) => {
println!("({:2}) Slice for addr {:x}: {}", 0, addr as *const u64 as usize, slice)
@ -33,5 +47,6 @@ pub fn main() {
}
}
}
sched_setaffinity(Pid::this(), &old).unwrap();
}
}

View File

@ -2,7 +2,7 @@
use std::arch::x86_64::_mm_clflush;
use crate::arch::CpuClass::{IntelCore, IntelXeon, IntelXeonSP};
use crate::arch::get_performance_counters_xeon;
use crate::arch::{get_performance_counters_core, get_performance_counters_xeon};
use crate::Error::UnsupportedCPU;
use crate::msr::{read_msr_on_cpu, write_msr_on_cpu};
@ -10,6 +10,7 @@ pub mod msr;
pub mod utils;
mod arch;
#[derive(Debug)]
pub enum Error {
UnsupportedCPU,
InvalidParameter,
@ -30,7 +31,7 @@ unsafe fn poke(addr: *const u8) {
}
}
unsafe fn monitor_xeon(addr: *const u8, cpu: u8, max_cbox: usize) -> Result<Vec<u32>, Error> {
unsafe fn monitor_xeon(addr: *const u8, cpu: u8, max_cbox: usize) -> Result<Vec<u64>, Error> {
let performance_counters = if let Some(p) = get_performance_counters_xeon() {
p
} else {
@ -75,24 +76,38 @@ unsafe fn monitor_xeon(addr: *const u8, cpu: u8, max_cbox: usize) -> Result<Vec<
}
// Read counters
let mut result = Vec::new();
let mut results = Vec::new();
for i in 0..max_cbox {
let result = read_msr_on_cpu(performance_counters.msr_pmon_ctr0[i], cpu)?;
result.push(result)
results.push(result)
}
Ok(result)
Ok(results)
}
fn monitor_core(addr: *const u8, cpu: u8, max_core: u8) -> Result<Vec<u32>, Error> {
fn monitor_core(addr: *const u8, cpu: u8, max_cbox: usize) -> Result<Vec<u64>, Error> {
// Note, we need to add the workaround for one missing perf counter here.
let performance_counters = if let Some(p) = get_performance_counters_core() {
p
} else {
return Err(UnsupportedCPU);
};
let workaround = if (performance_counters.max_slice as usize) + 1 == max_cbox {
true
} else if (performance_counters.max_slice as usize) >= max_cbox {
false
} else {
return Err(Error::InvalidParameter);
};
unimplemented!()
}
pub unsafe fn monitor_address(addr: *const u8, cpu: u8, max_cbox: u16) -> Result<Vec<u32>, Error> {
pub unsafe fn monitor_address(addr: *const u8, cpu: u8, max_cbox: u16) -> Result<Vec<u64>, Error> {
match arch::determine_cpu_class() {
Some(IntelCore) => {
unimplemented!()
unsafe { monitor_core(addr, cpu, max_cbox as usize) }
}
Some(IntelXeon) => {
unsafe { monitor_xeon(addr, cpu, max_cbox as usize) }