From 19df2c6f7457c62884fe087f08f913443acf0267 Mon Sep 17 00:00:00 2001 From: Greg V Date: Sun, 25 Aug 2019 16:54:24 +0300 Subject: [PATCH 1/2] Fix build on aarch64 on arbitrary OS (without a feature detection method) I agree to license my contributions to each file under the terms given at the top of each file I changed. --- src/cpu.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git cargo-crates/ring-0.14.6/src/cpu.rs cargo-crates/ring-0.14.6/src/cpu.rs index 822aae4e3..bfd87c8de 100644 --- cargo-crates/ring-0.14.6/src/cpu.rs +++ cargo-crates/ring-0.14.6/src/cpu.rs @@ -170,10 +170,10 @@ pub(crate) mod arm { pub(crate) struct Feature { #[cfg_attr( - any( - target_os = "ios", - not(any(target_arch = "arm", target_arch = "aarch64")) - ), + not(all( + any(target_os = "android", target_os = "linux", target_os = "fuchsia"), + any(target_arch = "arm", target_arch = "aarch64") + )), allow(dead_code) )] mask: u32, @@ -198,7 +198,10 @@ pub(crate) mod arm { return self.mask == self.mask & unsafe { GFp_armcap_P }; } - #[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))] + #[cfg(not(all( + any(target_os = "android", target_os = "ios", target_os = "linux", target_os = "fuchsia"), + any(target_arch = "arm", target_arch = "aarch64") + )))] { return false; } @@ -206,7 +209,10 @@ pub(crate) mod arm { } // Keep in sync with `ARMV7_NEON`. - #[cfg(any(target_arch = "aarch64", target_arch = "arm"))] + #[cfg(all( + any(target_os = "android", target_os = "ios", target_os = "linux", target_os = "fuchsia"), + any(target_arch = "arm", target_arch = "aarch64") + ))] pub(crate) const NEON: Feature = Feature { mask: 1 << 0, ios: true, From 300516a643a1019e5bb99663ab76acc0fb05e7ae Mon Sep 17 00:00:00 2001 From: Greg V Date: Sun, 25 Aug 2019 17:52:18 +0300 Subject: [PATCH 2/2] Add CPU feature detection for FreeBSD/aarch64 I agree to license my contributions to each file under the terms given at the top of each file I changed. --- build.rs | 1 + crypto/cpu-aarch64.c | 32 ++++++++++++++++++++++++++++++++ src/cpu.rs | 40 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 crypto/cpu-aarch64.c diff --git cargo-crates/ring-0.14.6/build.rs cargo-crates/ring-0.14.6/build.rs index c6cb3a700..62b150170 100644 --- cargo-crates/ring-0.14.6/build.rs +++ cargo-crates/ring-0.14.6/build.rs @@ -65,6 +65,7 @@ const RING_SRCS: &[(&[&str], &str)] = &[ (&[], "third_party/fiat/curve25519.c"), (&[X86_64, X86], "crypto/cpu-intel.c"), + (&[AARCH64], "crypto/cpu-aarch64.c"), (&[X86], "crypto/fipsmodule/aes/asm/aes-586.pl"), (&[X86], "crypto/fipsmodule/aes/asm/aesni-x86.pl"), diff --git cargo-crates/ring-0.14.6/crypto/cpu-aarch64.c cargo-crates/ring-0.14.6/crypto/cpu-aarch64.c new file mode 100644 index 000000000..8bb537b78 --- /dev/null +++ cargo-crates/ring-0.14.6/crypto/cpu-aarch64.c @@ -0,0 +1,32 @@ +// Copyright 2019 Greg V +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +// Run-time feature detection for aarch64 on any OS that emulates the mrs instruction. +// +// On FreeBSD >= 12.0, Linux >= 4.11 and other operating systems, it is possible to use +// privileged system registers from userspace to check CPU feature support. +// +// For proper support of SoCs where different cores have different capabilities +// the OS has to always report only the features supported by all cores, like FreeBSD does. +// +// Only FreeBSD uses this right now. + +#include + +uint64_t GFp_aarch64_read_isar0(void) { + uint64_t val; + __asm __volatile("mrs %0, ID_AA64ISAR0_EL1" : "=&r" (val)); + return val; +} diff --git cargo-crates/ring-0.14.6/src/cpu.rs cargo-crates/ring-0.14.6/src/cpu.rs index bfd87c8de..d65d36a6a 100644 --- cargo-crates/ring-0.14.6/src/cpu.rs +++ cargo-crates/ring-0.14.6/src/cpu.rs @@ -60,6 +60,11 @@ pub(crate) fn features() -> Features { { arm::fuchsia_setup(); } + + #[cfg(all(any(target_os = "freebsd"), target_arch = "aarch64"))] + { + arm::aarch64_mrs_setup(); + } }); } @@ -168,10 +173,37 @@ pub(crate) mod arm { } } + #[cfg(all(any(target_os = "freebsd"), target_arch = "aarch64"))] + pub fn aarch64_mrs_setup() { + extern "C" { + fn GFp_aarch64_read_isar0() -> u64; + } + + #[inline] + fn bits_shift(x: u64, high: usize, low: usize) -> u64 { + (x >> low) & ((1 << (high - low + 1)) - 1) + } + + let mut features = 0; + let aa64isar0 = unsafe { GFp_aarch64_read_isar0() }; + + if bits_shift(aa64isar0, 7, 4) >= 1 { + features |= AES.mask; + } + if bits_shift(aa64isar0, 7, 4) >= 2 { + features |= PMULL.mask; + } + if bits_shift(aa64isar0, 15, 12) >= 1 { + features |= 1 << 4; + } + + unsafe { GFp_armcap_P = features }; + } + pub(crate) struct Feature { #[cfg_attr( not(all( - any(target_os = "android", target_os = "linux", target_os = "fuchsia"), + any(target_os = "android", all(target_os = "freebsd", target_arch = "aarch64"), target_os = "linux", target_os = "fuchsia"), any(target_arch = "arm", target_arch = "aarch64") )), allow(dead_code) @@ -191,7 +223,7 @@ pub(crate) mod arm { } #[cfg(all( - any(target_os = "android", target_os = "linux", target_os = "fuchsia"), + any(target_os = "android", all(target_os = "freebsd", target_arch = "aarch64"), target_os = "linux", target_os = "fuchsia"), any(target_arch = "arm", target_arch = "aarch64") ))] { @@ -199,7 +231,7 @@ pub(crate) mod arm { } #[cfg(not(all( - any(target_os = "android", target_os = "ios", target_os = "linux", target_os = "fuchsia"), + any(target_os = "android", all(target_os = "freebsd", target_arch = "aarch64"), target_os = "ios", target_os = "linux", target_os = "fuchsia"), any(target_arch = "arm", target_arch = "aarch64") )))] { @@ -231,7 +263,7 @@ pub(crate) mod arm { }; #[cfg(all( - any(target_os = "android", target_os = "linux", target_os = "fuchsia"), + any(target_os = "android", all(target_os = "freebsd", target_arch = "aarch64"), target_os = "linux", target_os = "fuchsia"), any(target_arch = "arm", target_arch = "aarch64") ))] extern "C" {