Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+41 -9
+4
Documentation/arm64/elf_hwcaps.rst
··· 301 301 302 302 Functionality implied by ID_AA64ISAR2_EL1.WFXT == 0b0010. 303 303 304 + HWCAP2_EBF16 305 + 306 + Functionality implied by ID_AA64ISAR1_EL1.BF16 == 0b0010. 307 + 304 308 4. Unused AT_HWCAP bits 305 309 ----------------------- 306 310
+1 -1
arch/arm64/include/asm/cpufeature.h
··· 11 11 #include <asm/hwcap.h> 12 12 #include <asm/sysreg.h> 13 13 14 - #define MAX_CPU_FEATURES 64 14 + #define MAX_CPU_FEATURES 128 15 15 #define cpu_feature(x) KERNEL_HWCAP_ ## x 16 16 17 17 #ifndef __ASSEMBLY__
+2 -1
arch/arm64/include/asm/hwcap.h
··· 85 85 #define KERNEL_HWCAP_PACA __khwcap_feature(PACA) 86 86 #define KERNEL_HWCAP_PACG __khwcap_feature(PACG) 87 87 88 - #define __khwcap2_feature(x) (const_ilog2(HWCAP2_ ## x) + 32) 88 + #define __khwcap2_feature(x) (const_ilog2(HWCAP2_ ## x) + 64) 89 89 #define KERNEL_HWCAP_DCPODP __khwcap2_feature(DCPODP) 90 90 #define KERNEL_HWCAP_SVE2 __khwcap2_feature(SVE2) 91 91 #define KERNEL_HWCAP_SVEAES __khwcap2_feature(SVEAES) ··· 118 118 #define KERNEL_HWCAP_SME_F32F32 __khwcap2_feature(SME_F32F32) 119 119 #define KERNEL_HWCAP_SME_FA64 __khwcap2_feature(SME_FA64) 120 120 #define KERNEL_HWCAP_WFXT __khwcap2_feature(WFXT) 121 + #define KERNEL_HWCAP_EBF16 __khwcap2_feature(EBF16) 121 122 122 123 /* 123 124 * This yields a mask that user programs can use to figure out what
+4
arch/arm64/include/asm/sysreg.h
··· 788 788 789 789 /* id_aa64mmfr1 */ 790 790 #define ID_AA64MMFR1_ECBHB_SHIFT 60 791 + #define ID_AA64MMFR1_TIDCP1_SHIFT 52 791 792 #define ID_AA64MMFR1_HCX_SHIFT 40 792 793 #define ID_AA64MMFR1_AFP_SHIFT 44 793 794 #define ID_AA64MMFR1_ETS_SHIFT 36 ··· 804 803 805 804 #define ID_AA64MMFR1_VMIDBITS_8 0 806 805 #define ID_AA64MMFR1_VMIDBITS_16 2 806 + 807 + #define ID_AA64MMFR1_TIDCP1_NI 0 808 + #define ID_AA64MMFR1_TIDCP1_IMP 1 807 809 808 810 /* id_aa64mmfr2 */ 809 811 #define ID_AA64MMFR2_E0PD_SHIFT 60
+4
arch/arm64/include/uapi/asm/hwcap.h
··· 19 19 20 20 /* 21 21 * HWCAP flags - for AT_HWCAP 22 + * 23 + * Bits 62 and 63 are reserved for use by libc. 24 + * Bits 32-61 are unallocated for potential use by libc. 22 25 */ 23 26 #define HWCAP_FP (1 << 0) 24 27 #define HWCAP_ASIMD (1 << 1) ··· 91 88 #define HWCAP2_SME_F32F32 (1 << 29) 92 89 #define HWCAP2_SME_FA64 (1 << 30) 93 90 #define HWCAP2_WFXT (1UL << 31) 91 + #define HWCAP2_EBF16 (1UL << 32) 94 92 95 93 #endif /* _UAPI__ASM_HWCAP_H */
+24 -7
arch/arm64/kernel/cpufeature.c
··· 92 92 #include <asm/virt.h> 93 93 94 94 /* Kernel representation of AT_HWCAP and AT_HWCAP2 */ 95 - static unsigned long elf_hwcap __read_mostly; 95 + static DECLARE_BITMAP(elf_hwcap, MAX_CPU_FEATURES) __read_mostly; 96 96 97 97 #ifdef CONFIG_COMPAT 98 98 #define COMPAT_ELF_HWCAP_DEFAULT \ ··· 362 362 }; 363 363 364 364 static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = { 365 + ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_TIDCP1_SHIFT, 4, 0), 365 366 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_AFP_SHIFT, 4, 0), 366 367 ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_ETS_SHIFT, 4, 0), 367 368 ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_TWED_SHIFT, 4, 0), ··· 2036 2035 } 2037 2036 #endif /* CONFIG_KVM */ 2038 2037 2038 + static void cpu_trap_el0_impdef(const struct arm64_cpu_capabilities *__unused) 2039 + { 2040 + sysreg_clear_set(sctlr_el1, 0, SCTLR_EL1_TIDCP); 2041 + } 2042 + 2039 2043 /* Internal helper functions to match cpu capability type */ 2040 2044 static bool 2041 2045 cpucap_late_cpu_optional(const struct arm64_cpu_capabilities *cap) ··· 2584 2578 .matches = has_cpuid_feature, 2585 2579 .min_field_value = ID_AA64ISAR2_EL1_WFxT_IMP, 2586 2580 }, 2581 + { 2582 + .desc = "Trap EL0 IMPLEMENTATION DEFINED functionality", 2583 + .capability = ARM64_HAS_TIDCP1, 2584 + .type = ARM64_CPUCAP_SYSTEM_FEATURE, 2585 + .sys_reg = SYS_ID_AA64MMFR1_EL1, 2586 + .sign = FTR_UNSIGNED, 2587 + .field_pos = ID_AA64MMFR1_TIDCP1_SHIFT, 2588 + .field_width = 4, 2589 + .min_field_value = ID_AA64MMFR1_TIDCP1_IMP, 2590 + .matches = has_cpuid_feature, 2591 + .cpu_enable = cpu_trap_el0_impdef, 2592 + }, 2587 2593 {}, 2588 2594 }; 2589 2595 ··· 2698 2680 HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_FRINTTS_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FRINT), 2699 2681 HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_SB_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SB), 2700 2682 HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_BF16_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_BF16), 2683 + HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_BF16_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_EBF16), 2701 2684 HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_DGH_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DGH), 2702 2685 HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_EL1_I8MM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_I8MM), 2703 2686 HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT), ··· 3174 3155 3175 3156 void cpu_set_feature(unsigned int num) 3176 3157 { 3177 - WARN_ON(num >= MAX_CPU_FEATURES); 3178 - elf_hwcap |= BIT(num); 3158 + set_bit(num, elf_hwcap); 3179 3159 } 3180 3160 3181 3161 bool cpu_have_feature(unsigned int num) 3182 3162 { 3183 - WARN_ON(num >= MAX_CPU_FEATURES); 3184 - return elf_hwcap & BIT(num); 3163 + return test_bit(num, elf_hwcap); 3185 3164 } 3186 3165 EXPORT_SYMBOL_GPL(cpu_have_feature); 3187 3166 ··· 3190 3173 * note that for userspace compatibility we guarantee that bits 62 3191 3174 * and 63 will always be returned as 0. 3192 3175 */ 3193 - return lower_32_bits(elf_hwcap); 3176 + return elf_hwcap[0]; 3194 3177 } 3195 3178 3196 3179 unsigned long cpu_get_elf_hwcap2(void) 3197 3180 { 3198 - return upper_32_bits(elf_hwcap); 3181 + return elf_hwcap[1]; 3199 3182 } 3200 3183 3201 3184 static void __init setup_system_capabilities(void)
+1
arch/arm64/kernel/cpuinfo.c
··· 114 114 [KERNEL_HWCAP_SME_F32F32] = "smef32f32", 115 115 [KERNEL_HWCAP_SME_FA64] = "smefa64", 116 116 [KERNEL_HWCAP_WFXT] = "wfxt", 117 + [KERNEL_HWCAP_EBF16] = "ebf16", 117 118 }; 118 119 119 120 #ifdef CONFIG_COMPAT
+1
arch/arm64/tools/cpucaps
··· 36 36 HAS_SB 37 37 HAS_STAGE2_FWB 38 38 HAS_SYSREG_GIC_CPUIF 39 + HAS_TIDCP1 39 40 HAS_TLB_RANGE 40 41 HAS_VIRT_HOST_EXTN 41 42 HAS_WFXT