From 7e71616723c6f9b891707f7a09ed060e5c9feff1 Mon Sep 17 00:00:00 2001 From: Greg V Date: Tue, 14 Jan 2020 16:25:56 +0000 Subject: [PATCH] Bug 1575843 - Detect AArch64 CPU features on FreeBSD r=jcj Environment checks are reogranized to be separate from platform code to make it impossible to forget to check disable_FEATURE on one platform but not the other. Differential Revision: https://phabricator.services.mozilla.com/D55386 --HG-- extra : moz-landing-system : lando --- lib/freebl/blinit.c | 48 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/lib/freebl/blinit.c b/lib/freebl/blinit.c index 050b32113e..4723d3bb16 100644 --- a/lib/freebl/blinit.c +++ b/lib/freebl/blinit.c @@ -133,6 +133,8 @@ static unsigned long (*getauxval)(unsigned long) = NULL; /* clang-format on */ #if defined(__aarch64__) + +#if defined(__linux__) // Defines from hwcap.h in Linux kernel - ARM64 #ifndef HWCAP_AES #define HWCAP_AES (1 << 3) @@ -146,30 +148,54 @@ static unsigned long (*getauxval)(unsigned long) = NULL; #ifndef HWCAP_SHA2 #define HWCAP_SHA2 (1 << 6) #endif +#endif /* defined(__linux__) */ + +#if defined(__FreeBSD__) +#include +#include +// Support for older version of armreg.h +#ifndef ID_AA64ISAR0_AES_VAL +#define ID_AA64ISAR0_AES_VAL ID_AA64ISAR0_AES +#endif +#ifndef ID_AA64ISAR0_SHA1_VAL +#define ID_AA64ISAR0_SHA1_VAL ID_AA64ISAR0_SHA1 +#endif +#ifndef ID_AA64ISAR0_SHA2_VAL +#define ID_AA64ISAR0_SHA2_VAL ID_AA64ISAR0_SHA2 +#endif +#endif /* defined(__FreeBSD__) */ void CheckARMSupport() { - char *disable_arm_neon = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON"); - char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES"); - char *disable_pmull = PR_GetEnvSecure("NSS_DISABLE_PMULL"); #if defined(_WIN64) BOOL arm_crypto_support = IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE); - arm_aes_support_ = arm_crypto_support && disable_hw_aes == NULL; - arm_pmull_support_ = arm_crypto_support && disable_pmull == NULL; + arm_aes_support_ = arm_crypto_support; + arm_pmull_support_ = arm_crypto_support; arm_sha1_support_ = arm_crypto_support; arm_sha2_support_ = arm_crypto_support; -#else +#elif defined(__linux__) if (getauxval) { long hwcaps = getauxval(AT_HWCAP); - arm_aes_support_ = hwcaps & HWCAP_AES && disable_hw_aes == NULL; - arm_pmull_support_ = hwcaps & HWCAP_PMULL && disable_pmull == NULL; - arm_sha1_support_ = hwcaps & HWCAP_SHA1; - arm_sha2_support_ = hwcaps & HWCAP_SHA2; + arm_aes_support_ = (hwcaps & HWCAP_AES) == HWCAP_AES; + arm_pmull_support_ = (hwcaps & HWCAP_PMULL) == HWCAP_PMULL; + arm_sha1_support_ = (hwcaps & HWCAP_SHA1) == HWCAP_SHA1; + arm_sha2_support_ = (hwcaps & HWCAP_SHA2) == HWCAP_SHA2; + } +#elif defined(__FreeBSD__) + /* qemu-user does not support register access from userspace */ + if (PR_GetEnvSecure("QEMU_EMULATING") == NULL) { + uint64_t isar0 = READ_SPECIALREG(id_aa64isar0_el1); + arm_aes_support_ = ID_AA64ISAR0_AES_VAL(isar0) >= ID_AA64ISAR0_AES_BASE; + arm_pmull_support_ = ID_AA64ISAR0_AES_VAL(isar0) >= ID_AA64ISAR0_AES_PMULL; + arm_sha1_support_ = ID_AA64ISAR0_SHA1_VAL(isar0) >= ID_AA64ISAR0_SHA1_BASE; + arm_sha2_support_ = ID_AA64ISAR0_SHA2_VAL(isar0) >= ID_AA64ISAR0_SHA2_BASE; } #endif /* aarch64 must support NEON. */ - arm_neon_support_ = disable_arm_neon == NULL; + arm_neon_support_ = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON") == NULL; + arm_aes_support_ &= PR_GetEnvSecure("NSS_DISABLE_HW_AES") == NULL; + arm_pmull_support_ &= PR_GetEnvSecure("NSS_DISABLE_PMULL") == NULL; } #endif /* defined(__aarch64__) */