diff --git a/reverie-ptrace/src/lib.rs b/reverie-ptrace/src/lib.rs index b45b72d..b6a2981 100644 --- a/reverie-ptrace/src/lib.rs +++ b/reverie-ptrace/src/lib.rs @@ -31,7 +31,6 @@ #![feature(async_closure)] #![feature(internal_output_capture)] #![feature(never_type)] -#![cfg_attr(feature = "llvm_asm", feature(llvm_asm))] #![feature(map_first_last)] #![feature(bench_black_box)] diff --git a/reverie-ptrace/src/perf.rs b/reverie-ptrace/src/perf.rs index 9efa4ce..6d78d81 100644 --- a/reverie-ptrace/src/perf.rs +++ b/reverie-ptrace/src/perf.rs @@ -571,7 +571,6 @@ macro_rules! ret_without_perf { /// Perform exactly `count+1` conditional branch instructions. Useful for /// testing timer-related code. #[cfg(target_arch = "x86_64")] -#[cfg(not(feature = "llvm_asm"))] #[inline(never)] pub fn do_branches(mut count: u64) { // Anything but assembly is unreliable between debug and release @@ -605,29 +604,6 @@ pub fn do_branches(mut count: u64) { assert_eq!(count, 0); } -/// Perform exactly `count+1` conditional branch instructions. Useful for -/// testing timer-related code. -#[cfg(target_arch = "x86_64")] -#[cfg(feature = "llvm_asm")] -#[inline(never)] -pub fn do_branches(count: u64) { - // Anything but assembly is unreliable between debug and release - #[allow(deprecated)] - unsafe { - // Loop until carry flag is set, indicating underflow - llvm_asm!(" - mov $0, %rax - perf_test_branch_loop: - subq $$1, %rax - jnc perf_test_branch_loop - " - : /* no output */ - : "r"(count) - : "cc", "rax" - ); - } -} - // NOTE: aarch64 doesn't work with // `Event::Hardware(HardwareEvent::BranchInstructions)`, so these tests are // disabled for that architecture. Most likely, we need to use `Event::Raw` diff --git a/reverie-ptrace/src/validation.rs b/reverie-ptrace/src/validation.rs index 7e6cbff..aea7965 100644 --- a/reverie-ptrace/src/validation.rs +++ b/reverie-ptrace/src/validation.rs @@ -72,10 +72,6 @@ pub(crate) enum PmuValidationError { #[cfg(target_arch = "x86_64")] #[error("Intel Kvm-In-Txcp bug found")] IntelKvmInTxcpBugDetected, - - #[cfg(feature = "llvm_asm")] - #[error("Overcount triggered by PMU interrupts detected due to Xen PMU virtualization bug")] - IntelXenPmiBugDetected, } fn init_perf_event_attr( @@ -377,8 +373,6 @@ fn check_for_arch_bugs(_precise_ip: bool) -> Result<(), PmuValidationError> { "AuthenticAMD" if is_amd_zen(feature_info) => check_for_zen_speclockmap(), "GenuineIntel" => { check_for_kvm_in_txcp_bug()?; - #[cfg(feature = "llvm_asm")] - check_for_xen_pmi_bug(_precise_ip)?; Ok(()) } s => panic!("Unknown CPU vendor: {}", s), @@ -411,7 +405,6 @@ fn check_for_zen_speclockmap() -> Result<(), PmuValidationError> { 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 mut _prev: *mut usize; core::arch::asm!( @@ -422,17 +415,6 @@ fn check_for_zen_speclockmap() -> Result<(), PmuValidationError> { ) } - #[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 { @@ -466,154 +448,6 @@ fn check_for_kvm_in_txcp_bug() -> Result<(), PmuValidationError> { } } -// FIXME: Convert this big block of llvm_asm over to the new asm syntax. -#[cfg(feature = "llvm_asm")] -fn check_for_xen_pmi_bug(precise_ip: bool) -> Result<(), PmuValidationError> { - #[allow(unused_assignments)] - let mut count: i32 = -1; - let mut attr = ticks_attr(precise_ip); - attr.__bindgen_anon_1.sample_period = NUM_BRANCHES - 1; - let fd = start_counter(0, -1, &mut attr, None)?; - - // The original C++ uses `rand()` to make sure this isn't optimized around. - // We will use black_box to do the same thing without introducing variability - - fn make_accumulator_seed() -> u32 { - 20764791 - } - - let mut accumulator = core::hint::black_box(make_accumulator_seed()); - let mut expected_accumulator = accumulator; - - // reproduce the assembly here to calculate what the final accumulator value should be - for _ in 0..(NUM_BRANCHES - 2) { - let temp_exp_accumulator = expected_accumulator.overflowing_shl(3).0; - expected_accumulator = temp_exp_accumulator - .overflowing_sub(expected_accumulator) - .0 - .overflowing_add(2) - .0 - & 0xffffff; - } - - let raw_fd = fd.0; - - #[allow(deprecated)] - unsafe { - // The following asm block does this: - // ``` - // let ret = syscall!(sys_ioctl, raw_fd, _PERF_EVENT_IOC_ENABLE, 0); - // if ret >= -4095 as u64 { return; } - // let ret = syscall!(SYS_ioctl, raw_fd, _PERF_EVENT_IOC_RESET, 0); - // // From this point on, all conditional branches count! - // if ret >= -4095 as u64 { return; } - // // Reset the counter period to the desired value. - // let ret = syscall!(SYS_ioctl, raw_fd, _PERF_EVENT_IOC_PERIOD, attr.sample_period); - // if ret >= -4095 as u64 { return; } - // let mut iterations = NUM_BRANCHES - 2; - // loop { - // iterations -= 1; - // accumulator *= 7; - // accumulator += 2; - // accumulator &= 0xffffff; - // if iterations == 0 { - // break; - // } - // } - // - // let ret = syscall!(SYS_ioctl, raw_fd, _PERF_EVENT_IOC_DISABLE, 0); - // if ret >= -4095 as u64 { return; } - // count = 0; - // ``` - llvm_asm!( - " - mov $2, %rax; - mov $9, %edi; - xor %rdx, %rdx; - mov $4, %rsi; - syscall; - cmp $$-4095, %rax; - jae 2f; - mov $2, %rax; - mov $6, %rsi; - syscall; - /* From this point on all conditional branches count! */ - cmp $$-4095, %rax; - jae 2f; - /* Reset the counter period to the desired value. */ - mov $2, %rax; - mov $5, %rsi; - mov $8, %rdx; - syscall; - cmp $$-4095, %rax; - jae 2f; - mov $7, %rax; - 1: dec %rax; - /* Multiply by 7. */ - mov $0, %edx; - shl $$3, $0; - sub %edx, $0; - /* Add 2. */ - add $$2, $0; - /* Mask off bits. */ - and $$0xffffff, $0; - /* And loop. */ - test %rax, %rax; - jnz 1b; - mov $3, %rsi; - mov $2, %rax; - xor %rdx, %rdx; - /* We didn't touch rdi. */ - syscall; - cmp $$-4095, %rax; - jae 2f; - movl $$0, $1; - 2: nop;" - : - "+r"(accumulator), - "=r"(count) - : - "i"(libc::SYS_ioctl) - , - "i"(perf::perf_event_ioctls_DISABLE), - "i"(perf::perf_event_ioctls_ENABLE), - "i"(perf::perf_event_ioctls_PERIOD), - "i"(perf::perf_event_ioctls_RESET), - // The check for the failure of some of our ioctls is in - // the measured region, so account for that when looping. - "i"(NUM_BRANCHES - 2), - "rm"(&attr.__bindgen_anon_1.sample_period), "rm"(raw_fd) - : - "rax", "rdx", "rdi", "rsi" - /* `syscall` clobbers rcx and r11. */ - , - "rcx", "r11" - : "volatile" - ); - } - - // If things worked above, `count` should have been set to 0. - if count == 0 { - count = read_counter(&fd)? as i32; - } - - // Use 'accumulator' so it can't be optimized out. - if accumulator != expected_accumulator { - return Err(PmuValidationError::UnexpectedTestingError(format!( - "Unexpected accumulator value in xen pmi bug check. Expected {}, but was {}", - expected_accumulator, accumulator - ))); - } - - let has_xen_pmi_bug = count as u64 > NUM_BRANCHES || count == -1; - - if has_xen_pmi_bug { - Err(PmuValidationError::IntelXenPmiBugDetected) - } else { - Ok(()) - } -} - #[cfg(test)] mod test { use super::*; diff --git a/tests/basics.rs b/tests/basics.rs index a2a3327..77320e8 100644 --- a/tests/basics.rs +++ b/tests/basics.rs @@ -6,8 +6,6 @@ * LICENSE file in the root directory of this source tree. */ -#![cfg_attr(feature = "llvm_asm", feature(llvm_asm))] - //! Basic tests that don't fall into some other category. #[allow(unused_imports)] diff --git a/tests/convert.rs b/tests/convert.rs index 114c4ff..cfd292b 100644 --- a/tests/convert.rs +++ b/tests/convert.rs @@ -6,7 +6,6 @@ * LICENSE file in the root directory of this source tree. */ -#![cfg_attr(feature = "llvm_asm", feature(llvm_asm))] // FIXME: This test does some very x86_64-specific things. #![cfg(target_arch = "x86_64")] @@ -68,7 +67,6 @@ mod tests { use super::*; #[cfg(target_arch = "x86_64")] - #[cfg(not(feature = "llvm_asm"))] #[allow(unused_mut)] unsafe fn open_syscall_sanity_check() -> i32 { let path = b"/dev/null\0".as_ptr() as usize; @@ -123,38 +121,6 @@ mod tests { ret as i32 } - #[cfg(target_arch = "x86_64")] - #[cfg(feature = "llvm_asm")] - #[allow(unused_mut)] - #[allow(deprecated)] - unsafe fn open_syscall_sanity_check() -> i32 { - let mut ret; - let path = b"/dev/null\0"; - llvm_asm!(r#"movq %rdi, %r8 - movq $$0x8000, %rsi # O_LARGEFILE - movq $$0x1a4, %rdx # 0644 - mov $$2, %eax - syscall - cmp $$0xfffffffffffff001,%rax - jae 1f - cmp %rdi, %r8 - jne 1f - cmp $$0x8000, %rsi - jne 1f - cmp $$0x1a4, %rdx - jne 1f - jmp 2f - 1:mov $$1, %rdi - mov $$231, %rax # call exit_group(1) - syscall - 2: - "# - :"={rax}"(ret) - :"{rdi}"(path.as_ptr() as u64) - :"rcx", "r11", "memory"); - ret - } - #[cfg(not(target_arch = "x86_64"))] unsafe fn open_syscall_sanity_check() -> i32 { unimplemented!()