Compare commits

...

2 Commits

3 changed files with 46 additions and 15 deletions

View File

@ -1,3 +1,4 @@
use std::arch::asm;
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
unsafe extern "C" { unsafe extern "C" {
@ -24,11 +25,18 @@ fn hypercall(hypercall: NyxHypercall, argument: u32) {
} }
} }
fn ptwrite(val: u32) {
unsafe {
asm!("ptwrite {0:e}", in(reg) val);
}
}
fn main() { fn main() {
hprint(c"Acuiring again!\n"); hprint(c"Acuiring again!\n");
hypercall(NyxHypercall::Acquire, 100); hypercall(NyxHypercall::Acquire, 100);
let start = std::time::Instant::now(); let start = std::time::Instant::now();
let mut last_time = std::time::Duration::ZERO; let mut last_time = std::time::Duration::ZERO;
ptwrite(42);
loop { loop {
let elapsed = start.elapsed(); let elapsed = start.elapsed();
if elapsed.as_secs() >= 2 { if elapsed.as_secs() >= 2 {
@ -42,5 +50,6 @@ fn main() {
} }
last_time = elapsed; last_time = elapsed;
} }
ptwrite(43);
hprint(c"Done\n"); hprint(c"Done\n");
} }

View File

@ -14,6 +14,13 @@ pub struct AnalyzeData {
pub time_outside_hypervisor: Duration, pub time_outside_hypervisor: Duration,
} }
#[derive(Debug)]
enum Scope {
Main,
PreRun,
PostRun,
}
pub fn analyze_dump(path: impl AsRef<Path>) -> Result<AnalyzeData, Box<dyn Error>> { pub fn analyze_dump(path: impl AsRef<Path>) -> Result<AnalyzeData, Box<dyn Error>> {
let trace_file = File::open(path)?; let trace_file = File::open(path)?;
let mmap = unsafe { Mmap::map(&trace_file)? }; let mmap = unsafe { Mmap::map(&trace_file)? };
@ -26,34 +33,45 @@ pub fn analyze_dump(path: impl AsRef<Path>) -> Result<AnalyzeData, Box<dyn Error
// Required before it can be used // Required before it can be used
decoder.sync_forward()?; decoder.sync_forward()?;
let mut segments = vec![(Scope::PreRun, 0u64)];
let mut total = 0u64; let mut total = 0u64;
let mut cycles = 0u64;
let mut cycles_in_vmcs = 0u64;
let mut last_packet_vmcs = false;
for packet in decoder { for packet in decoder {
total += 1; total += 1;
match packet { match packet {
Ok(Packet::Cyc(cyc)) => { Ok(Packet::Cyc(cyc)) => {
cycles += cyc.value(); segments.last_mut().unwrap().1 += cyc.value();
if last_packet_vmcs {
cycles_in_vmcs += cyc.value();
last_packet_vmcs = false;
}
} }
Ok(Packet::Vmcs(_)) => { Ok(Packet::Vmcs(_)) => {
last_packet_vmcs = true; // last_packet_vmcs = true;
}
Ok(Packet::Ptw(ptwrite)) => {
if ptwrite.payload() == 42 {
// Main enter
segments.push((Scope::Main, 0));
} else if ptwrite.payload() == 43 {
// Main exit
segments.push((Scope::PostRun, 0));
} else {
println!("GOT PTWRITE!!!!!: {ptwrite:?}");
}
} }
Ok(_) => {} Ok(_) => {}
Err(error) => println!("Got error: {error:?}"), Err(error) => println!("Got error: {error:?}"),
} }
} }
let cycles_outside_hypervisor = cycles - cycles_in_vmcs; // dbg!(&segments);
let total_seconds = cycles as f64 / 2_700_000_000.0; let cycles_main: u64 = segments
let total_seconds_no_hypervisor = cycles_outside_hypervisor as f64 / 2_700_000_000.0; .iter()
.filter(|(scope, _)| matches!(scope, Scope::Main))
.map(|(_, cycles)| cycles)
.sum();
let cycles_total = segments.iter().map(|(_, cycles)| cycles).sum();
let total_seconds = cycles_total as f64 / 2_700_000_000.0;
let total_seconds_no_hypervisor = cycles_main as f64 / 2_700_000_000.0;
Ok(AnalyzeData { Ok(AnalyzeData {
packets: total, packets: total,
cycles, cycles: cycles_total,
time: Duration::from_secs_f64(total_seconds), time: Duration::from_secs_f64(total_seconds),
time_outside_hypervisor: Duration::from_secs_f64(total_seconds_no_hypervisor), time_outside_hypervisor: Duration::from_secs_f64(total_seconds_no_hypervisor),
}) })

View File

@ -2,8 +2,8 @@
use libnyx::ffi::nyx_print_aux_buffer; use libnyx::ffi::nyx_print_aux_buffer;
use libnyx::{NyxConfig, NyxProcess, NyxProcessRole, NyxReturnValue}; use libnyx::{NyxConfig, NyxProcess, NyxProcessRole, NyxReturnValue};
use std::error::Error;
use pt_dump_decoder::analyze_dump; use pt_dump_decoder::analyze_dump;
use std::error::Error;
const WORKDIR_PATH: &str = "/tmp/wdir"; const WORKDIR_PATH: &str = "/tmp/wdir";
// The sharedir path gets set by the build script // The sharedir path gets set by the build script
@ -12,6 +12,7 @@ const SHAREDIR_PATH: &str = env!("NYX_SHAREDIR");
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
let _ = std::fs::remove_dir_all(WORKDIR_PATH); let _ = std::fs::remove_dir_all(WORKDIR_PATH);
run_client()?; run_client()?;
println!("Analyzing pt data...");
let dump_path = format!("{WORKDIR_PATH}/pt_trace_dump_0"); let dump_path = format!("{WORKDIR_PATH}/pt_trace_dump_0");
let result = analyze_dump(dump_path)?; let result = analyze_dump(dump_path)?;
@ -35,7 +36,10 @@ fn run_client() -> Result<(), Box<dyn Error>> {
nyx_runner.option_apply(); nyx_runner.option_apply();
let result = nyx_runner.exec(); let result = nyx_runner.exec();
assert!(matches!(result, NyxReturnValue::Normal), "Unexpected return value {result:?}"); assert!(
matches!(result, NyxReturnValue::Normal),
"Unexpected return value {result:?}"
);
nyx_print_aux_buffer(&mut nyx_runner as *mut _); nyx_print_aux_buffer(&mut nyx_runner as *mut _);
nyx_runner.shutdown(); nyx_runner.shutdown();