Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 23 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions cpufeatures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ readme = "README.md"
edition = "2024"
rust-version = "1.85"

[dependencies]
cfg-if = "1"

[target.'cfg(all(target_arch = "aarch64", target_vendor = "apple"))'.dependencies]
libc = { version = "0.2.155", default-features = false }

Expand Down
169 changes: 0 additions & 169 deletions cpufeatures/src/aarch64.rs

This file was deleted.

84 changes: 84 additions & 0 deletions cpufeatures/src/aarch64_apple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//! ARM64 CPU feature detection support.
//!
//! Unfortunately ARM instructions to detect CPU features cannot be called from
//! unprivileged userspace code, so this implementation relies on OS-specific
//! APIs for feature detection.

use core::ffi::CStr;

// Evaluate the given `$body` expression any of the supplied target features
// are not enabled. Otherwise returns true.
#[macro_export]
#[doc(hidden)]
macro_rules! __can_detect {
($($tf:tt),+) => {
true
};
}

// Apple platform's runtime detection of target CPU features using `sysctlbyname`.
#[macro_export]
#[doc(hidden)]
macro_rules! __detect {
($($tf:tt),+) => {{
$($crate::check!($tf) & )+ true
}};
}

// Apple OS (macOS, iOS, watchOS, and tvOS) `check!` macro.
//
// NOTE: several of these instructions (e.g. `aes`, `sha2`) can be assumed to
// be present on all Apple ARM64 hardware.
//
// Newer CPU instructions now have nodes within sysctl's `hw.optional`
// namespace, however the ones that do not can safely be assumed to be
// present on all Apple ARM64 devices, now and for the foreseeable future.
//
// See discussion on this issue for more information:
// <https://github.com/RustCrypto/utils/issues/378>
#[macro_export]
#[doc(hidden)]
macro_rules! check {
("aes") => {
true
};
("dit") => {
// https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Enable-DIT-for-constant-time-cryptographic-operations
unsafe {
$crate::aarch64_apple::sysctlbyname(c"hw.optional.arm.FEAT_DIT")
}
};
("sha2") => {
true
};
("sha3") => {
unsafe {
// `sha3` target feature implies SHA-512 as well
$crate::aarch64_apple::sysctlbyname(c"hw.optional.armv8_2_sha512")
&& $crate::aarch64_apple::sysctlbyname(c"hw.optional.armv8_2_sha3")
}
};
("sm4") => {
false
};
}

/// Apple helper function for calling `sysctlbyname`.
pub unsafe fn sysctlbyname(name: &CStr) -> bool {
let mut value: u32 = 0;
let mut size = core::mem::size_of::<u32>();

let rc = unsafe {
libc::sysctlbyname(
name.as_ptr(),
&mut value as *mut _ as *mut libc::c_void,
&mut size,
core::ptr::null_mut(),
0,
)
};

assert_eq!(size, 4, "unexpected sysctlbyname(3) result size");
assert_eq!(rc, 0, "sysctlbyname returned error code: {}", rc);
value != 0
}
Loading
Loading