Merge branch 'for-next/cpufeature' into for-next/core
* for-next/cpufeature: arm64/hwcap: Support FEAT_EBF16 arm64/cpufeature: Store elf_hwcaps as a bitmap rather than unsigned long arm64/hwcap: Document allocation of upper bits of AT_HWCAP arm64: trap implementation defined functionality in userspace
This commit is contained in:
commit
92867739e3
@ -301,6 +301,10 @@ HWCAP2_WFXT
|
||||
|
||||
Functionality implied by ID_AA64ISAR2_EL1.WFXT == 0b0010.
|
||||
|
||||
HWCAP2_EBF16
|
||||
|
||||
Functionality implied by ID_AA64ISAR1_EL1.BF16 == 0b0010.
|
||||
|
||||
4. Unused AT_HWCAP bits
|
||||
-----------------------
|
||||
|
||||
|
@ -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__
|
||||
|
@ -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)
|
||||
@ -118,6 +118,7 @@
|
||||
#define KERNEL_HWCAP_SME_F32F32 __khwcap2_feature(SME_F32F32)
|
||||
#define KERNEL_HWCAP_SME_FA64 __khwcap2_feature(SME_FA64)
|
||||
#define KERNEL_HWCAP_WFXT __khwcap2_feature(WFXT)
|
||||
#define KERNEL_HWCAP_EBF16 __khwcap2_feature(EBF16)
|
||||
|
||||
/*
|
||||
* This yields a mask that user programs can use to figure out what
|
||||
|
@ -788,6 +788,7 @@
|
||||
|
||||
/* id_aa64mmfr1 */
|
||||
#define ID_AA64MMFR1_ECBHB_SHIFT 60
|
||||
#define ID_AA64MMFR1_TIDCP1_SHIFT 52
|
||||
#define ID_AA64MMFR1_HCX_SHIFT 40
|
||||
#define ID_AA64MMFR1_AFP_SHIFT 44
|
||||
#define ID_AA64MMFR1_ETS_SHIFT 36
|
||||
@ -804,6 +805,9 @@
|
||||
#define ID_AA64MMFR1_VMIDBITS_8 0
|
||||
#define ID_AA64MMFR1_VMIDBITS_16 2
|
||||
|
||||
#define ID_AA64MMFR1_TIDCP1_NI 0
|
||||
#define ID_AA64MMFR1_TIDCP1_IMP 1
|
||||
|
||||
/* id_aa64mmfr2 */
|
||||
#define ID_AA64MMFR2_E0PD_SHIFT 60
|
||||
#define ID_AA64MMFR2_EVT_SHIFT 56
|
||||
|
@ -19,6 +19,9 @@
|
||||
|
||||
/*
|
||||
* HWCAP flags - for AT_HWCAP
|
||||
*
|
||||
* Bits 62 and 63 are reserved for use by libc.
|
||||
* Bits 32-61 are unallocated for potential use by libc.
|
||||
*/
|
||||
#define HWCAP_FP (1 << 0)
|
||||
#define HWCAP_ASIMD (1 << 1)
|
||||
@ -88,5 +91,6 @@
|
||||
#define HWCAP2_SME_F32F32 (1 << 29)
|
||||
#define HWCAP2_SME_FA64 (1 << 30)
|
||||
#define HWCAP2_WFXT (1UL << 31)
|
||||
#define HWCAP2_EBF16 (1UL << 32)
|
||||
|
||||
#endif /* _UAPI__ASM_HWCAP_H */
|
||||
|
@ -92,7 +92,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 \
|
||||
@ -362,6 +362,7 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
|
||||
};
|
||||
|
||||
static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_TIDCP1_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_AFP_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_ETS_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_TWED_SHIFT, 4, 0),
|
||||
@ -2035,6 +2036,11 @@ static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, in
|
||||
}
|
||||
#endif /* CONFIG_KVM */
|
||||
|
||||
static void cpu_trap_el0_impdef(const struct arm64_cpu_capabilities *__unused)
|
||||
{
|
||||
sysreg_clear_set(sctlr_el1, 0, SCTLR_EL1_TIDCP);
|
||||
}
|
||||
|
||||
/* Internal helper functions to match cpu capability type */
|
||||
static bool
|
||||
cpucap_late_cpu_optional(const struct arm64_cpu_capabilities *cap)
|
||||
@ -2578,6 +2584,18 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
|
||||
.matches = has_cpuid_feature,
|
||||
.min_field_value = ID_AA64ISAR2_EL1_WFxT_IMP,
|
||||
},
|
||||
{
|
||||
.desc = "Trap EL0 IMPLEMENTATION DEFINED functionality",
|
||||
.capability = ARM64_HAS_TIDCP1,
|
||||
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
|
||||
.sys_reg = SYS_ID_AA64MMFR1_EL1,
|
||||
.sign = FTR_UNSIGNED,
|
||||
.field_pos = ID_AA64MMFR1_TIDCP1_SHIFT,
|
||||
.field_width = 4,
|
||||
.min_field_value = ID_AA64MMFR1_TIDCP1_IMP,
|
||||
.matches = has_cpuid_feature,
|
||||
.cpu_enable = cpu_trap_el0_impdef,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
@ -2680,6 +2698,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
|
||||
HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_FRINTTS_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FRINT),
|
||||
HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_SB_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SB),
|
||||
HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_BF16_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_BF16),
|
||||
HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_BF16_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_EBF16),
|
||||
HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_DGH_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DGH),
|
||||
HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_I8MM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_I8MM),
|
||||
HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT),
|
||||
@ -3155,14 +3174,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);
|
||||
|
||||
@ -3173,12 +3190,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)
|
||||
|
@ -114,6 +114,7 @@ static const char *const hwcap_str[] = {
|
||||
[KERNEL_HWCAP_SME_F32F32] = "smef32f32",
|
||||
[KERNEL_HWCAP_SME_FA64] = "smefa64",
|
||||
[KERNEL_HWCAP_WFXT] = "wfxt",
|
||||
[KERNEL_HWCAP_EBF16] = "ebf16",
|
||||
};
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
@ -36,6 +36,7 @@ HAS_RNG
|
||||
HAS_SB
|
||||
HAS_STAGE2_FWB
|
||||
HAS_SYSREG_GIC_CPUIF
|
||||
HAS_TIDCP1
|
||||
HAS_TLB_RANGE
|
||||
HAS_VIRT_HOST_EXTN
|
||||
HAS_WFXT
|
||||
|
Loading…
Reference in New Issue
Block a user