464 lines
20 KiB
Diff
464 lines
20 KiB
Diff
From a97497b283894653e53f7eb83b5825f5564d1614 Mon Sep 17 00:00:00 2001
|
|
From: Andrew Murray <andrew.murray@arm.com>
|
|
Date: Tue, 9 Apr 2019 10:52:40 +0100
|
|
Subject: [PATCH openEuler-20.03-LTS-SP4 1/4] arm64: HWCAP: add support for
|
|
AT_HWCAP2
|
|
|
|
mainline inclusion
|
|
from mainline-v5.2-rc1
|
|
commit 06a916feca2b262ab0c1a2aeb68882f4b1108a07
|
|
category: feature
|
|
bugzilla: https://gitee.com/openeuler/kernel/issues/I8B82O
|
|
CVE: NA
|
|
|
|
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=06a916feca2b262ab0c1a2aeb68882f4b1108a07
|
|
|
|
--------------------------------
|
|
|
|
As we will exhaust the first 32 bits of AT_HWCAP let's start
|
|
exposing AT_HWCAP2 to userspace to give us up to 64 caps.
|
|
|
|
Whilst it's possible to use the remaining 32 bits of AT_HWCAP, we
|
|
prefer to expand into AT_HWCAP2 in order to provide a consistent
|
|
view to userspace between ILP32 and LP64. However internal to the
|
|
kernel we prefer to continue to use the full space of elf_hwcap.
|
|
|
|
To reduce complexity and allow for future expansion, we now
|
|
represent hwcaps in the kernel as ordinals and use a
|
|
KERNEL_HWCAP_ prefix. This allows us to support automatic feature
|
|
based module loading for all our hwcaps.
|
|
|
|
We introduce cpu_set_feature to set hwcaps which complements the
|
|
existing cpu_have_feature helper. These helpers allow us to clean
|
|
up existing direct uses of elf_hwcap and reduce any future effort
|
|
required to move beyond 64 caps.
|
|
|
|
For convenience we also introduce cpu_{have,set}_named_feature which
|
|
makes use of the cpu_feature macro to allow providing a hwcap name
|
|
without a {KERNEL_}HWCAP_ prefix.
|
|
|
|
Signed-off-by: Andrew Murray <andrew.murray@arm.com>
|
|
[will: use const_ilog2() and tweak documentation]
|
|
Signed-off-by: Will Deacon <will.deacon@arm.com>
|
|
|
|
Conflicts:
|
|
Documentation/arm64/elf_hwcaps.txt
|
|
arch/arm64/crypto/chacha-neon-glue.c
|
|
arch/arm64/crypto/crct10dif-ce-glue.c
|
|
arch/arm64/crypto/ghash-ce-glue.c
|
|
arch/arm64/crypto/nhpoly1305-neon-glue.c
|
|
arch/arm64/kernel/cpufeature.c
|
|
drivers/clocksource/arm_arch_timer.c
|
|
|
|
Signed-off-by: Yu Liao <liaoyu15@huawei.com>
|
|
---
|
|
Documentation/arm64/elf_hwcaps.txt | 13 ++++--
|
|
arch/arm64/crypto/aes-ce-ccm-glue.c | 2 +-
|
|
arch/arm64/crypto/aes-neonbs-glue.c | 2 +-
|
|
arch/arm64/crypto/chacha20-neon-glue.c | 2 +-
|
|
arch/arm64/crypto/ghash-ce-glue.c | 6 +--
|
|
arch/arm64/crypto/sha256-glue.c | 4 +-
|
|
arch/arm64/include/asm/cpufeature.h | 22 +++++-----
|
|
arch/arm64/include/asm/hwcap.h | 49 ++++++++++++++++++++-
|
|
arch/arm64/include/uapi/asm/hwcap.h | 2 +-
|
|
arch/arm64/kernel/cpufeature.c | 60 +++++++++++++-------------
|
|
arch/arm64/kernel/cpuinfo.c | 2 +-
|
|
arch/arm64/kernel/fpsimd.c | 4 +-
|
|
drivers/clocksource/arm_arch_timer.c | 8 ++++
|
|
13 files changed, 120 insertions(+), 56 deletions(-)
|
|
|
|
diff --git a/Documentation/arm64/elf_hwcaps.txt b/Documentation/arm64/elf_hwcaps.txt
|
|
index 6feaffe90e22..186feb16e2f2 100644
|
|
--- a/Documentation/arm64/elf_hwcaps.txt
|
|
+++ b/Documentation/arm64/elf_hwcaps.txt
|
|
@@ -13,9 +13,9 @@ architected discovery mechanism available to userspace code at EL0. The
|
|
kernel exposes the presence of these features to userspace through a set
|
|
of flags called hwcaps, exposed in the auxilliary vector.
|
|
|
|
-Userspace software can test for features by acquiring the AT_HWCAP entry
|
|
-of the auxilliary vector, and testing whether the relevant flags are
|
|
-set, e.g.
|
|
+Userspace software can test for features by acquiring the AT_HWCAP or
|
|
+AT_HWCAP2 entry of the auxiliary vector, and testing whether the relevant
|
|
+flags are set, e.g.
|
|
|
|
bool floating_point_is_present(void)
|
|
{
|
|
@@ -182,3 +182,10 @@ HWCAP_FLAGM
|
|
HWCAP_SSBS
|
|
|
|
Functionality implied by ID_AA64PFR1_EL1.SSBS == 0b0010.
|
|
+
|
|
+
|
|
+4. Unused AT_HWCAP bits
|
|
+-----------------------
|
|
+
|
|
+For interoperation with userspace, the kernel guarantees that bits 62
|
|
+and 63 of AT_HWCAP will always be returned as 0.
|
|
diff --git a/arch/arm64/crypto/aes-ce-ccm-glue.c b/arch/arm64/crypto/aes-ce-ccm-glue.c
|
|
index 5fc6f51908fd..036ea77f83bc 100644
|
|
--- a/arch/arm64/crypto/aes-ce-ccm-glue.c
|
|
+++ b/arch/arm64/crypto/aes-ce-ccm-glue.c
|
|
@@ -372,7 +372,7 @@ static struct aead_alg ccm_aes_alg = {
|
|
|
|
static int __init aes_mod_init(void)
|
|
{
|
|
- if (!(elf_hwcap & HWCAP_AES))
|
|
+ if (!cpu_have_named_feature(AES))
|
|
return -ENODEV;
|
|
return crypto_register_aead(&ccm_aes_alg);
|
|
}
|
|
diff --git a/arch/arm64/crypto/aes-neonbs-glue.c b/arch/arm64/crypto/aes-neonbs-glue.c
|
|
index 5cc248967387..742359801559 100644
|
|
--- a/arch/arm64/crypto/aes-neonbs-glue.c
|
|
+++ b/arch/arm64/crypto/aes-neonbs-glue.c
|
|
@@ -442,7 +442,7 @@ static int __init aes_init(void)
|
|
int err;
|
|
int i;
|
|
|
|
- if (!(elf_hwcap & HWCAP_ASIMD))
|
|
+ if (!cpu_have_named_feature(ASIMD))
|
|
return -ENODEV;
|
|
|
|
err = crypto_register_skciphers(aes_algs, ARRAY_SIZE(aes_algs));
|
|
diff --git a/arch/arm64/crypto/chacha20-neon-glue.c b/arch/arm64/crypto/chacha20-neon-glue.c
|
|
index 727579c93ded..bb3314905bee 100644
|
|
--- a/arch/arm64/crypto/chacha20-neon-glue.c
|
|
+++ b/arch/arm64/crypto/chacha20-neon-glue.c
|
|
@@ -114,7 +114,7 @@ static struct skcipher_alg alg = {
|
|
|
|
static int __init chacha20_simd_mod_init(void)
|
|
{
|
|
- if (!(elf_hwcap & HWCAP_ASIMD))
|
|
+ if (!cpu_have_named_feature(ASIMD))
|
|
return -ENODEV;
|
|
|
|
return crypto_register_skcipher(&alg);
|
|
diff --git a/arch/arm64/crypto/ghash-ce-glue.c b/arch/arm64/crypto/ghash-ce-glue.c
|
|
index 1ed227bf6106..cd9d743cb40f 100644
|
|
--- a/arch/arm64/crypto/ghash-ce-glue.c
|
|
+++ b/arch/arm64/crypto/ghash-ce-glue.c
|
|
@@ -648,10 +648,10 @@ static int __init ghash_ce_mod_init(void)
|
|
{
|
|
int ret;
|
|
|
|
- if (!(elf_hwcap & HWCAP_ASIMD))
|
|
+ if (!cpu_have_named_feature(ASIMD))
|
|
return -ENODEV;
|
|
|
|
- if (elf_hwcap & HWCAP_PMULL)
|
|
+ if (cpu_have_named_feature(PMULL))
|
|
pmull_ghash_update = pmull_ghash_update_p64;
|
|
|
|
else
|
|
@@ -661,7 +661,7 @@ static int __init ghash_ce_mod_init(void)
|
|
if (ret)
|
|
return ret;
|
|
|
|
- if (elf_hwcap & HWCAP_PMULL) {
|
|
+ if (cpu_have_named_feature(PMULL)) {
|
|
ret = crypto_register_aead(&gcm_aes_alg);
|
|
if (ret)
|
|
crypto_unregister_shash(&ghash_alg);
|
|
diff --git a/arch/arm64/crypto/sha256-glue.c b/arch/arm64/crypto/sha256-glue.c
|
|
index 4aedeaefd61f..0cccdb9cc2c0 100644
|
|
--- a/arch/arm64/crypto/sha256-glue.c
|
|
+++ b/arch/arm64/crypto/sha256-glue.c
|
|
@@ -173,7 +173,7 @@ static int __init sha256_mod_init(void)
|
|
if (ret)
|
|
return ret;
|
|
|
|
- if (elf_hwcap & HWCAP_ASIMD) {
|
|
+ if (cpu_have_named_feature(ASIMD)) {
|
|
ret = crypto_register_shashes(neon_algs, ARRAY_SIZE(neon_algs));
|
|
if (ret)
|
|
crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
|
|
@@ -183,7 +183,7 @@ static int __init sha256_mod_init(void)
|
|
|
|
static void __exit sha256_mod_fini(void)
|
|
{
|
|
- if (elf_hwcap & HWCAP_ASIMD)
|
|
+ if (cpu_have_named_feature(ASIMD))
|
|
crypto_unregister_shashes(neon_algs, ARRAY_SIZE(neon_algs));
|
|
crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
|
|
}
|
|
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
|
|
index ffb0a1ec0088..eef5a9c9b823 100644
|
|
--- a/arch/arm64/include/asm/cpufeature.h
|
|
+++ b/arch/arm64/include/asm/cpufeature.h
|
|
@@ -14,15 +14,8 @@
|
|
#include <asm/hwcap.h>
|
|
#include <asm/sysreg.h>
|
|
|
|
-/*
|
|
- * In the arm64 world (as in the ARM world), elf_hwcap is used both internally
|
|
- * in the kernel and for user space to keep track of which optional features
|
|
- * are supported by the current system. So let's map feature 'x' to HWCAP_x.
|
|
- * Note that HWCAP_x constants are bit fields so we need to take the log.
|
|
- */
|
|
-
|
|
-#define MAX_CPU_FEATURES (8 * sizeof(elf_hwcap))
|
|
-#define cpu_feature(x) ilog2(HWCAP_ ## x)
|
|
+#define MAX_CPU_FEATURES 64
|
|
+#define cpu_feature(x) KERNEL_HWCAP_ ## x
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
@@ -372,10 +365,19 @@ extern bool set_cap_spectre_bhb;
|
|
|
|
bool this_cpu_has_cap(unsigned int cap);
|
|
|
|
+static inline void cpu_set_feature(unsigned int num)
|
|
+{
|
|
+ WARN_ON(num >= MAX_CPU_FEATURES);
|
|
+ elf_hwcap |= BIT(num);
|
|
+}
|
|
+#define cpu_set_named_feature(name) cpu_set_feature(cpu_feature(name))
|
|
+
|
|
static inline bool cpu_have_feature(unsigned int num)
|
|
{
|
|
- return elf_hwcap & (1UL << num);
|
|
+ WARN_ON(num >= MAX_CPU_FEATURES);
|
|
+ return elf_hwcap & BIT(num);
|
|
}
|
|
+#define cpu_have_named_feature(name) cpu_have_feature(cpu_feature(name))
|
|
|
|
/* System capability check for constant caps */
|
|
static __always_inline bool __cpus_have_const_cap(int num)
|
|
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
|
|
index 428b745b5386..458ff2d7ece3 100644
|
|
--- a/arch/arm64/include/asm/hwcap.h
|
|
+++ b/arch/arm64/include/asm/hwcap.h
|
|
@@ -40,11 +40,58 @@
|
|
#define COMPAT_HWCAP2_CRC32 (1 << 4)
|
|
|
|
#ifndef __ASSEMBLY__
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/log2.h>
|
|
+
|
|
+/*
|
|
+ * For userspace we represent hwcaps as a collection of HWCAP{,2}_x bitfields
|
|
+ * as described in uapi/asm/hwcap.h. For the kernel we represent hwcaps as
|
|
+ * natural numbers (in a single range of size MAX_CPU_FEATURES) defined here
|
|
+ * with prefix KERNEL_HWCAP_ mapped to their HWCAP{,2}_x counterpart.
|
|
+ *
|
|
+ * Hwcaps should be set and tested within the kernel via the
|
|
+ * cpu_{set,have}_named_feature(feature) where feature is the unique suffix
|
|
+ * of KERNEL_HWCAP_{feature}.
|
|
+ */
|
|
+#define __khwcap_feature(x) const_ilog2(HWCAP_ ## x)
|
|
+#define KERNEL_HWCAP_FP __khwcap_feature(FP)
|
|
+#define KERNEL_HWCAP_ASIMD __khwcap_feature(ASIMD)
|
|
+#define KERNEL_HWCAP_EVTSTRM __khwcap_feature(EVTSTRM)
|
|
+#define KERNEL_HWCAP_AES __khwcap_feature(AES)
|
|
+#define KERNEL_HWCAP_PMULL __khwcap_feature(PMULL)
|
|
+#define KERNEL_HWCAP_SHA1 __khwcap_feature(SHA1)
|
|
+#define KERNEL_HWCAP_SHA2 __khwcap_feature(SHA2)
|
|
+#define KERNEL_HWCAP_CRC32 __khwcap_feature(CRC32)
|
|
+#define KERNEL_HWCAP_ATOMICS __khwcap_feature(ATOMICS)
|
|
+#define KERNEL_HWCAP_FPHP __khwcap_feature(FPHP)
|
|
+#define KERNEL_HWCAP_ASIMDHP __khwcap_feature(ASIMDHP)
|
|
+#define KERNEL_HWCAP_CPUID __khwcap_feature(CPUID)
|
|
+#define KERNEL_HWCAP_ASIMDRDM __khwcap_feature(ASIMDRDM)
|
|
+#define KERNEL_HWCAP_JSCVT __khwcap_feature(JSCVT)
|
|
+#define KERNEL_HWCAP_FCMA __khwcap_feature(FCMA)
|
|
+#define KERNEL_HWCAP_LRCPC __khwcap_feature(LRCPC)
|
|
+#define KERNEL_HWCAP_DCPOP __khwcap_feature(DCPOP)
|
|
+#define KERNEL_HWCAP_SHA3 __khwcap_feature(SHA3)
|
|
+#define KERNEL_HWCAP_SM3 __khwcap_feature(SM3)
|
|
+#define KERNEL_HWCAP_SM4 __khwcap_feature(SM4)
|
|
+#define KERNEL_HWCAP_ASIMDDP __khwcap_feature(ASIMDDP)
|
|
+#define KERNEL_HWCAP_SHA512 __khwcap_feature(SHA512)
|
|
+#define KERNEL_HWCAP_SVE __khwcap_feature(SVE)
|
|
+#define KERNEL_HWCAP_ASIMDFHM __khwcap_feature(ASIMDFHM)
|
|
+#define KERNEL_HWCAP_DIT __khwcap_feature(DIT)
|
|
+#define KERNEL_HWCAP_USCAT __khwcap_feature(USCAT)
|
|
+#define KERNEL_HWCAP_ILRCPC __khwcap_feature(ILRCPC)
|
|
+#define KERNEL_HWCAP_FLAGM __khwcap_feature(FLAGM)
|
|
+#define KERNEL_HWCAP_SSBS __khwcap_feature(SSBS)
|
|
+
|
|
+#define __khwcap2_feature(x) (const_ilog2(HWCAP2_ ## x) + 32)
|
|
+
|
|
/*
|
|
* This yields a mask that user programs can use to figure out what
|
|
* instruction set this cpu supports.
|
|
*/
|
|
-#define ELF_HWCAP (elf_hwcap)
|
|
+#define ELF_HWCAP lower_32_bits(elf_hwcap)
|
|
+#define ELF_HWCAP2 upper_32_bits(elf_hwcap)
|
|
|
|
#ifdef CONFIG_AARCH32_EL0
|
|
extern unsigned int a32_elf_hwcap, a32_elf_hwcap2;
|
|
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
|
|
index 2bcd6e4f3474..602158a55554 100644
|
|
--- a/arch/arm64/include/uapi/asm/hwcap.h
|
|
+++ b/arch/arm64/include/uapi/asm/hwcap.h
|
|
@@ -18,7 +18,7 @@
|
|
#define _UAPI__ASM_HWCAP_H
|
|
|
|
/*
|
|
- * HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
|
|
+ * HWCAP flags - for AT_HWCAP
|
|
*/
|
|
#define HWCAP_FP (1 << 0)
|
|
#define HWCAP_ASIMD (1 << 1)
|
|
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
|
|
index 1c93cc3f7692..3a0e7e10f2d7 100644
|
|
--- a/arch/arm64/kernel/cpufeature.c
|
|
+++ b/arch/arm64/kernel/cpufeature.c
|
|
@@ -1553,35 +1553,35 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
|
|
}
|
|
|
|
static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, HWCAP_PMULL),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_AES),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_SHA1),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_SHA2),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, HWCAP_SHA512),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_CRC32_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_CRC32),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_ATOMICS_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, HWCAP_ATOMICS),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RDM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_ASIMDRDM),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA3_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_SHA3),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM3_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_SM3),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM4_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_SM4),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_DP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_ASIMDDP),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_FHM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_ASIMDFHM),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_FLAGM),
|
|
- HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, HWCAP_FP),
|
|
- HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, HWCAP_FPHP),
|
|
- HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, HWCAP_ASIMD),
|
|
- HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, HWCAP_ASIMDHP),
|
|
- HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_DIT_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, HWCAP_DIT),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_DCPOP),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_JSCVT),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_FCMA),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_LRCPC),
|
|
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, HWCAP_ILRCPC),
|
|
- HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_USCAT),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_PMULL),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AES),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA1),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA2),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_SHA512),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_CRC32_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_CRC32),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_ATOMICS_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ATOMICS),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RDM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDRDM),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA3_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA3),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM3_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM3),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM4_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM4),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_DP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDDP),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_FHM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDFHM),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FLAGM),
|
|
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_FP),
|
|
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FPHP),
|
|
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_ASIMD),
|
|
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDHP),
|
|
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_DIT_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DIT),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DCPOP),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_JSCVT),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FCMA),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_LRCPC),
|
|
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ILRCPC),
|
|
+ HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT),
|
|
#ifdef CONFIG_ARM64_SVE
|
|
- HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, HWCAP_SVE),
|
|
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, KERNEL_HWCAP_SVE),
|
|
#endif
|
|
- HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, HWCAP_SSBS),
|
|
+ HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, KERNEL_HWCAP_SSBS),
|
|
{},
|
|
};
|
|
|
|
@@ -1627,7 +1627,7 @@ static void __init cap_set_elf_hwcap(const struct arm64_cpu_capabilities *cap)
|
|
{
|
|
switch (cap->hwcap_type) {
|
|
case CAP_HWCAP:
|
|
- elf_hwcap |= cap->hwcap;
|
|
+ cpu_set_feature(cap->hwcap);
|
|
break;
|
|
#ifdef CONFIG_AARCH32_EL0
|
|
case CAP_COMPAT_HWCAP:
|
|
@@ -1650,7 +1650,7 @@ static bool cpus_have_elf_hwcap(const struct arm64_cpu_capabilities *cap)
|
|
|
|
switch (cap->hwcap_type) {
|
|
case CAP_HWCAP:
|
|
- rc = (elf_hwcap & cap->hwcap) != 0;
|
|
+ rc = cpu_have_feature(cap->hwcap);
|
|
break;
|
|
#ifdef CONFIG_AARCH32_EL0
|
|
case CAP_COMPAT_HWCAP:
|
|
@@ -1671,7 +1671,7 @@ static bool cpus_have_elf_hwcap(const struct arm64_cpu_capabilities *cap)
|
|
static void __init setup_elf_hwcaps(const struct arm64_cpu_capabilities *hwcaps)
|
|
{
|
|
/* We support emulation of accesses to CPU ID feature registers */
|
|
- elf_hwcap |= HWCAP_CPUID;
|
|
+ cpu_set_named_feature(CPUID);
|
|
for (; hwcaps->matches; hwcaps++)
|
|
if (hwcaps->matches(hwcaps, cpucap_default_scope(hwcaps)))
|
|
cap_set_elf_hwcap(hwcaps);
|
|
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
|
|
index 005d88db1082..bfe3bb8f05fe 100644
|
|
--- a/arch/arm64/kernel/cpuinfo.c
|
|
+++ b/arch/arm64/kernel/cpuinfo.c
|
|
@@ -164,7 +164,7 @@ static int c_show(struct seq_file *m, void *v)
|
|
#endif /* CONFIG_AARCH32_EL0 */
|
|
} else {
|
|
for (j = 0; hwcap_str[j]; j++)
|
|
- if (elf_hwcap & (1 << j))
|
|
+ if (cpu_have_feature(j))
|
|
seq_printf(m, " %s", hwcap_str[j]);
|
|
}
|
|
seq_puts(m, "\n");
|
|
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
|
|
index bb048144c3bd..6972de5681ec 100644
|
|
--- a/arch/arm64/kernel/fpsimd.c
|
|
+++ b/arch/arm64/kernel/fpsimd.c
|
|
@@ -1302,14 +1302,14 @@ static inline void fpsimd_hotplug_init(void) { }
|
|
*/
|
|
static int __init fpsimd_init(void)
|
|
{
|
|
- if (elf_hwcap & HWCAP_FP) {
|
|
+ if (cpu_have_named_feature(FP)) {
|
|
fpsimd_pm_init();
|
|
fpsimd_hotplug_init();
|
|
} else {
|
|
pr_notice("Floating-point is not implemented\n");
|
|
}
|
|
|
|
- if (!(elf_hwcap & HWCAP_ASIMD))
|
|
+ if (!cpu_have_named_feature(ASIMD))
|
|
pr_notice("Advanced SIMD is not implemented\n");
|
|
|
|
return sve_sysctl_init();
|
|
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
|
|
index 58863fd9c91b..fbfc81932dea 100644
|
|
--- a/drivers/clocksource/arm_arch_timer.c
|
|
+++ b/drivers/clocksource/arm_arch_timer.c
|
|
@@ -825,7 +825,11 @@ static void arch_timer_evtstrm_enable(int divider)
|
|
cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
|
|
| ARCH_TIMER_VIRT_EVT_EN;
|
|
arch_timer_set_cntkctl(cntkctl);
|
|
+#ifdef CONFIG_ARM64
|
|
+ cpu_set_named_feature(EVTSTRM);
|
|
+#else
|
|
elf_hwcap |= HWCAP_EVTSTRM;
|
|
+#endif
|
|
#ifdef CONFIG_AARCH32_EL0
|
|
a32_elf_hwcap |= COMPAT_HWCAP_EVTSTRM;
|
|
#endif
|
|
@@ -1059,7 +1063,11 @@ static int arch_timer_cpu_pm_notify(struct notifier_block *self,
|
|
} else if (action == CPU_PM_ENTER_FAILED || action == CPU_PM_EXIT) {
|
|
arch_timer_set_cntkctl(__this_cpu_read(saved_cntkctl));
|
|
|
|
+#ifdef CONFIG_ARM64
|
|
+ if (cpu_have_named_feature(EVTSTRM))
|
|
+#else
|
|
if (elf_hwcap & HWCAP_EVTSTRM)
|
|
+#endif
|
|
cpumask_set_cpu(smp_processor_id(), &evtstrm_available);
|
|
}
|
|
return NOTIFY_OK;
|
|
--
|
|
2.25.1
|
|
|