Commit ddadbcda authored by Mark Brown's avatar Mark Brown Committed by Catalin Marinas
Browse files

arm64: Support AT_HWCAP3



We have filled all 64 bits of AT_HWCAP2 so in order to support discovery of
further features provide the framework to use the already defined AT_HWCAP3
for further CPU features.

Signed-off-by: default avatarMark Brown <broonie@kernel.org>
Reviewed-by: default avatarAnshuman Khandual <anshuman.khandual@arm.com>
Link: https://lore.kernel.org/r/20241004-arm64-elf-hwcap3-v2-2-799d1daad8b0@kernel.org


Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 4e6e8c2b
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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 auxiliary 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)
	{
+2 −1
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@
#include <asm/hwcap.h>
#include <asm/sysreg.h>

#define MAX_CPU_FEATURES	128
#define MAX_CPU_FEATURES	192
#define cpu_feature(x)		KERNEL_HWCAP_ ## x

#define ARM64_SW_FEATURE_OVERRIDE_NOKASLR	0
@@ -438,6 +438,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))
+5 −1
Original line number Diff line number Diff line
@@ -159,17 +159,21 @@
#define KERNEL_HWCAP_SME_SF8DP2		__khwcap2_feature(SME_SF8DP2)
#define KERNEL_HWCAP_POE		__khwcap2_feature(POE)

#define __khwcap3_feature(x)		(const_ilog2(HWCAP3_ ## x) + 128)

/*
 * 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)
#define COMPAT_ELF_HWCAP2	(compat_elf_hwcap2)
extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
#define COMPAT_ELF_HWCAP3	(compat_elf_hwcap3)
extern unsigned int compat_elf_hwcap, compat_elf_hwcap2, compat_elf_hwcap3;
#endif

enum {
+4 −0
Original line number Diff line number Diff line
@@ -124,4 +124,8 @@
#define HWCAP2_SME_SF8DP2	(1UL << 62)
#define HWCAP2_POE		(1UL << 63)

/*
 * HWCAP3 flags - for AT_HWCAP3
 */

#endif /* _UAPI__ASM_HWCAP_H */
+6 −0
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ static DECLARE_BITMAP(elf_hwcap, MAX_CPU_FEATURES) __read_mostly;
				 COMPAT_HWCAP_LPAE)
unsigned int compat_elf_hwcap __read_mostly = COMPAT_ELF_HWCAP_DEFAULT;
unsigned int compat_elf_hwcap2 __read_mostly;
unsigned int compat_elf_hwcap3 __read_mostly;
#endif

DECLARE_BITMAP(system_cpucaps, ARM64_NCAPS);
@@ -3499,6 +3500,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_boot_cpu_capabilities(void)
{
	/*