[PATCH v1 3/4] arm64/cpufeature: Support AT_HWCAP3

Mark Brown broonie at kernel.org
Thu Jun 16 04:18:17 PDT 2022


We have filled the low 32 bits of both AT_HWCAP and AT_HWCAP2 so in order
to support further architecture features we must either start allocating
from the upper 32 bits or add a new AT_HWCAP3. Feedback from the glibc
developers was that AT_HWCAP3 would be cleaner so go with that.

This patch merely adds the glue required for AT_HWCAP3, meaning that we
start providing AT_HWCAP3 for ELF executables but no bits will be set in
it.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/arm64/elf_hwcaps.rst  |  6 +++---
 arch/arm64/include/asm/cpufeature.h |  3 ++-
 arch/arm64/include/asm/hwcap.h      | 12 ++++++++----
 arch/arm64/include/uapi/asm/hwcap.h |  4 ++++
 arch/arm64/kernel/cpufeature.c      |  5 +++++
 5 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/Documentation/arm64/elf_hwcaps.rst b/Documentation/arm64/elf_hwcaps.rst
index 3d116fb536c5..5f4d89c4afe2 100644
--- a/Documentation/arm64/elf_hwcaps.rst
+++ b/Documentation/arm64/elf_hwcaps.rst
@@ -16,9 +16,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 or
-AT_HWCAP2 entry of the auxiliary vector, and testing whether the relevant
-flags are set, e.g.::
+Userspace software can test for features by acquiring the AT_HWCAP,
+AT_HWCAP2 or AT_HWCAP3 entry of the auxiliary vector, and testing
+whether the relevant flags are set, e.g.::
 
 	bool floating_point_is_present(void)
 	{
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 84756c660b5e..901cf318a556 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -13,7 +13,7 @@
 
 /* Note that bits 62 and 63 of each AT_HWCAP are reserved */
 #define CPU_FEATURES_PER_HWCAP	32
-#define MAX_CPU_FEATURES	64
+#define MAX_CPU_FEATURES	96
 #define cpu_feature(x)		KERNEL_HWCAP_ ## x
 
 #ifndef __ASSEMBLY__
@@ -436,6 +436,7 @@ void cpu_set_feature(unsigned int num);
 bool cpu_have_feature(unsigned int num);
 unsigned long cpu_get_elf_hwcap(void);
 unsigned long cpu_get_elf_hwcap2(void);
+unsigned long cpu_get_elf_hwcap3(void);
 
 #define cpu_set_named_feature(name) cpu_set_feature(cpu_feature(name))
 #define cpu_have_named_feature(name) cpu_have_feature(cpu_feature(name))
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index e0054c7b3a98..1ef208ab6895 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -44,10 +44,11 @@
 #define KHWCAP_OFFSET(n)		((n - 1) * CPU_FEATURES_PER_HWCAP)
 
 /*
- * 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.
+ * For userspace we represent hwcaps as a collection of HWCAP{,[23]}_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
@@ -121,12 +122,15 @@
 #define KERNEL_HWCAP_SME_FA64		__khwcap2_feature(SME_FA64)
 #define KERNEL_HWCAP_WFXT		__khwcap2_feature(WFXT)
 
+#define __khwcap3_feature(x)		(const_ilog2(HWCAP3_ ## x) + KHWCAP_OFFSET(3))
+
 /*
  * This yields a mask that user programs can use to figure out what
  * instruction set this cpu supports.
  */
 #define ELF_HWCAP		cpu_get_elf_hwcap()
 #define ELF_HWCAP2		cpu_get_elf_hwcap2()
+#define ELF_HWCAP3		cpu_get_elf_hwcap3()
 
 #ifdef CONFIG_COMPAT
 #define COMPAT_ELF_HWCAP	(compat_elf_hwcap)
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
index 4bb2cc8ac446..7b818f8fc01b 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -89,4 +89,8 @@
 #define HWCAP2_SME_FA64		(1 << 30)
 #define HWCAP2_WFXT		(1UL << 31)
 
+/*
+ * HWCAP3 flags - for AT_HWCAP3
+ */
+
 #endif /* _UAPI__ASM_HWCAP_H */
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 3ae8eb4a9446..1b1ef0178e7e 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -3141,6 +3141,11 @@ unsigned long cpu_get_elf_hwcap2(void)
 	return elf_hwcap[1];
 }
 
+unsigned long cpu_get_elf_hwcap3(void)
+{
+	return elf_hwcap[2];
+}
+
 static void __init setup_system_capabilities(void)
 {
 	/*
-- 
2.30.2




More information about the linux-arm-kernel mailing list