in reverie-ptrace/src/validation.rs [384:430]
fn check_for_zen_speclockmap() -> Result<(), PmuValidationError> {
// When the SpecLockMap optimization is not disabled, rr will not work
// reliably (e.g. it would work fine on a single process with a single
// thread, but not more). When the optimization is disabled, the
// perf counter for retired lock instructions of type SpecLockMapCommit
// (on PMC 0x25) stays at 0.
// See more details at https://github.com/rr-debugger/rr/issues/2034.
// 0x25 == RETIRED_LOCK_INSTRUCTIONS - Counts the number of retired locked instructions
// + 0x08 == SPECLOCKMAPCOMMIT
let mut attr = init_perf_event_attr(perf::perf_type_id_PERF_TYPE_RAW, 0x510825, false);
let fd = start_counter(0, -1, &mut attr, None)?;
let val = 20_usize;
let to_add = 22_usize;
let count = read_counter(&fd)?;
// A lock add is known to increase the perf counter we're looking at.
#[cfg(not(feature = "llvm_asm"))]
unsafe {
let _prev: usize;
core::arch::asm!(
"lock",
"xadd [{}], {}",
in(reg) val,
inout(reg) to_add => _prev,
)
}
#[cfg(feature = "llvm_asm")]
#[allow(deprecated)]
unsafe {
let _prev: usize;
llvm_asm!("lock; xaddq $2, $1"
: "=r" (_prev), "+*m" (&val)
: "0" (to_add)
: "memory"
: "volatile");
}
if read_counter(&fd)? != count {
Err(PmuValidationError::AmdSpecLockMapShouldBeDisabled)
} else {
Ok(())
}
}