arm64/cpufeature: Store elf_hwcaps as a bitmap rather than unsigned long
authorMark Brown <broonie@kernel.org>
Thu, 7 Jul 2022 10:36:31 +0000 (11:36 +0100)
committerWill Deacon <will@kernel.org>
Wed, 20 Jul 2022 10:18:11 +0000 (11:18 +0100)
When we added support for AT_HWCAP2 we took advantage of the fact that we
have limited hwcaps to the low 32 bits and stored it along with AT_HWCAP
in a single unsigned integer. Thanks to the ever expanding capabilities of
the architecture we have now allocated all 64 of the bits in an unsigned
long so in preparation for adding more hwcaps convert elf_hwcap to be a
bitmap instead, with 64 bits allocated to each AT_HWCAP.

There should be no functional change from this patch.

Signed-off-by: Mark Brown <broonie@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/r/20220707103632.12745-3-broonie@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/cpufeature.h
arch/arm64/include/asm/hwcap.h
arch/arm64/kernel/cpufeature.c

index 14a8f3d..7abd6c0 100644 (file)
@@ -11,7 +11,7 @@
 #include <asm/hwcap.h>
 #include <asm/sysreg.h>
 
-#define MAX_CPU_FEATURES       64
+#define MAX_CPU_FEATURES       128
 #define cpu_feature(x)         KERNEL_HWCAP_ ## x
 
 #ifndef __ASSEMBLY__
index aa443d8..9b5fdc1 100644 (file)
@@ -85,7 +85,7 @@
 #define KERNEL_HWCAP_PACA              __khwcap_feature(PACA)
 #define KERNEL_HWCAP_PACG              __khwcap_feature(PACG)
 
-#define __khwcap2_feature(x)           (const_ilog2(HWCAP2_ ## x) + 32)
+#define __khwcap2_feature(x)           (const_ilog2(HWCAP2_ ## x) + 64)
 #define KERNEL_HWCAP_DCPODP            __khwcap2_feature(DCPODP)
 #define KERNEL_HWCAP_SVE2              __khwcap2_feature(SVE2)
 #define KERNEL_HWCAP_SVEAES            __khwcap2_feature(SVEAES)
index 9daa38b..c7be49f 100644 (file)
@@ -91,7 +91,7 @@
 #include <asm/virt.h>
 
 /* Kernel representation of AT_HWCAP and AT_HWCAP2 */
-static unsigned long elf_hwcap __read_mostly;
+static DECLARE_BITMAP(elf_hwcap, MAX_CPU_FEATURES) __read_mostly;
 
 #ifdef CONFIG_COMPAT
 #define COMPAT_ELF_HWCAP_DEFAULT       \
@@ -3116,14 +3116,12 @@ static bool __maybe_unused __system_matches_cap(unsigned int n)
 
 void cpu_set_feature(unsigned int num)
 {
-       WARN_ON(num >= MAX_CPU_FEATURES);
-       elf_hwcap |= BIT(num);
+       set_bit(num, elf_hwcap);
 }
 
 bool cpu_have_feature(unsigned int num)
 {
-       WARN_ON(num >= MAX_CPU_FEATURES);
-       return elf_hwcap & BIT(num);
+       return test_bit(num, elf_hwcap);
 }
 EXPORT_SYMBOL_GPL(cpu_have_feature);
 
@@ -3134,12 +3132,12 @@ unsigned long cpu_get_elf_hwcap(void)
         * note that for userspace compatibility we guarantee that bits 62
         * and 63 will always be returned as 0.
         */
-       return lower_32_bits(elf_hwcap);
+       return elf_hwcap[0];
 }
 
 unsigned long cpu_get_elf_hwcap2(void)
 {
-       return upper_32_bits(elf_hwcap);
+       return elf_hwcap[1];
 }
 
 static void __init setup_system_capabilities(void)