mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
Merge branch 'for-next/cpufeature' into for-next/core
* for-next/cpufeature: kselftest/arm64: Add SVE 2.1 to hwcap test arm64/hwcap: Add support for SVE 2.1 kselftest/arm64: Add FEAT_RPRFM to the hwcap test arm64/hwcap: Add support for FEAT_RPRFM kselftest/arm64: Add FEAT_CSSC to the hwcap selftest arm64/hwcap: Add support for FEAT_CSSC arm64: Enable data independent timing (DIT) in the kernel
This commit is contained in:
commit
9f930478c6
12 changed files with 98 additions and 5 deletions
|
|
@ -275,6 +275,15 @@ HWCAP2_EBF16
|
|||
HWCAP2_SVE_EBF16
|
||||
Functionality implied by ID_AA64ZFR0_EL1.BF16 == 0b0010.
|
||||
|
||||
HWCAP2_CSSC
|
||||
Functionality implied by ID_AA64ISAR2_EL1.CSSC == 0b0001.
|
||||
|
||||
HWCAP2_RPRFM
|
||||
Functionality implied by ID_AA64ISAR2_EL1.RPRFM == 0b0001.
|
||||
|
||||
HWCAP2_SVE2P1
|
||||
Functionality implied by ID_AA64ZFR0_EL1.SVEver == 0b0010.
|
||||
|
||||
4. Unused AT_HWCAP bits
|
||||
-----------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ model features for SVE is included in Appendix A.
|
|||
HWCAP2_SVEBITPERM
|
||||
HWCAP2_SVESHA3
|
||||
HWCAP2_SVESM4
|
||||
HWCAP2_SVE2P1
|
||||
|
||||
This list may be extended over time as the SVE architecture evolves.
|
||||
|
||||
|
|
|
|||
|
|
@ -120,6 +120,9 @@
|
|||
#define KERNEL_HWCAP_WFXT __khwcap2_feature(WFXT)
|
||||
#define KERNEL_HWCAP_EBF16 __khwcap2_feature(EBF16)
|
||||
#define KERNEL_HWCAP_SVE_EBF16 __khwcap2_feature(SVE_EBF16)
|
||||
#define KERNEL_HWCAP_CSSC __khwcap2_feature(CSSC)
|
||||
#define KERNEL_HWCAP_RPRFM __khwcap2_feature(RPRFM)
|
||||
#define KERNEL_HWCAP_SVE2P1 __khwcap2_feature(SVE2P1)
|
||||
|
||||
/*
|
||||
* This yields a mask that user programs can use to figure out what
|
||||
|
|
|
|||
|
|
@ -90,20 +90,24 @@
|
|||
*/
|
||||
#define pstate_field(op1, op2) ((op1) << Op1_shift | (op2) << Op2_shift)
|
||||
#define PSTATE_Imm_shift CRm_shift
|
||||
#define SET_PSTATE(x, r) __emit_inst(0xd500401f | PSTATE_ ## r | ((!!x) << PSTATE_Imm_shift))
|
||||
|
||||
#define PSTATE_PAN pstate_field(0, 4)
|
||||
#define PSTATE_UAO pstate_field(0, 3)
|
||||
#define PSTATE_SSBS pstate_field(3, 1)
|
||||
#define PSTATE_DIT pstate_field(3, 2)
|
||||
#define PSTATE_TCO pstate_field(3, 4)
|
||||
|
||||
#define SET_PSTATE_PAN(x) __emit_inst(0xd500401f | PSTATE_PAN | ((!!x) << PSTATE_Imm_shift))
|
||||
#define SET_PSTATE_UAO(x) __emit_inst(0xd500401f | PSTATE_UAO | ((!!x) << PSTATE_Imm_shift))
|
||||
#define SET_PSTATE_SSBS(x) __emit_inst(0xd500401f | PSTATE_SSBS | ((!!x) << PSTATE_Imm_shift))
|
||||
#define SET_PSTATE_TCO(x) __emit_inst(0xd500401f | PSTATE_TCO | ((!!x) << PSTATE_Imm_shift))
|
||||
#define SET_PSTATE_PAN(x) SET_PSTATE((x), PAN)
|
||||
#define SET_PSTATE_UAO(x) SET_PSTATE((x), UAO)
|
||||
#define SET_PSTATE_SSBS(x) SET_PSTATE((x), SSBS)
|
||||
#define SET_PSTATE_DIT(x) SET_PSTATE((x), DIT)
|
||||
#define SET_PSTATE_TCO(x) SET_PSTATE((x), TCO)
|
||||
|
||||
#define set_pstate_pan(x) asm volatile(SET_PSTATE_PAN(x))
|
||||
#define set_pstate_uao(x) asm volatile(SET_PSTATE_UAO(x))
|
||||
#define set_pstate_ssbs(x) asm volatile(SET_PSTATE_SSBS(x))
|
||||
#define set_pstate_dit(x) asm volatile(SET_PSTATE_DIT(x))
|
||||
|
||||
#define __SYS_BARRIER_INSN(CRm, op2, Rt) \
|
||||
__emit_inst(0xd5000000 | sys_insn(0, 3, 3, (CRm), (op2)) | ((Rt) & 0x1f))
|
||||
|
|
|
|||
|
|
@ -93,5 +93,8 @@
|
|||
#define HWCAP2_WFXT (1UL << 31)
|
||||
#define HWCAP2_EBF16 (1UL << 32)
|
||||
#define HWCAP2_SVE_EBF16 (1UL << 33)
|
||||
#define HWCAP2_CSSC (1UL << 34)
|
||||
#define HWCAP2_RPRFM (1UL << 35)
|
||||
#define HWCAP2_SVE2P1 (1UL << 36)
|
||||
|
||||
#endif /* _UAPI__ASM_HWCAP_H */
|
||||
|
|
|
|||
|
|
@ -212,6 +212,8 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
|
|||
};
|
||||
|
||||
static const struct arm64_ftr_bits ftr_id_aa64isar2[] = {
|
||||
ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CSSC_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_RPRFM_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH),
|
||||
FTR_STRICT, FTR_EXACT, ID_AA64ISAR2_EL1_APA3_SHIFT, 4, 0),
|
||||
|
|
@ -2101,6 +2103,11 @@ static void cpu_trap_el0_impdef(const struct arm64_cpu_capabilities *__unused)
|
|||
sysreg_clear_set(sctlr_el1, 0, SCTLR_EL1_TIDCP);
|
||||
}
|
||||
|
||||
static void cpu_enable_dit(const struct arm64_cpu_capabilities *__unused)
|
||||
{
|
||||
set_pstate_dit(1);
|
||||
}
|
||||
|
||||
/* Internal helper functions to match cpu capability type */
|
||||
static bool
|
||||
cpucap_late_cpu_optional(const struct arm64_cpu_capabilities *cap)
|
||||
|
|
@ -2664,6 +2671,18 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
|
|||
.matches = has_cpuid_feature,
|
||||
.cpu_enable = cpu_trap_el0_impdef,
|
||||
},
|
||||
{
|
||||
.desc = "Data independent timing control (DIT)",
|
||||
.capability = ARM64_HAS_DIT,
|
||||
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
|
||||
.sys_reg = SYS_ID_AA64PFR0_EL1,
|
||||
.sign = FTR_UNSIGNED,
|
||||
.field_pos = ID_AA64PFR0_EL1_DIT_SHIFT,
|
||||
.field_width = 4,
|
||||
.min_field_value = ID_AA64PFR0_EL1_DIT_IMP,
|
||||
.matches = has_cpuid_feature,
|
||||
.cpu_enable = cpu_enable_dit,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
|
@ -2772,6 +2791,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
|
|||
HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_EL1_AT_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT),
|
||||
#ifdef CONFIG_ARM64_SVE
|
||||
HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_EL1_SVE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR0_EL1_SVE_IMP, CAP_HWCAP, KERNEL_HWCAP_SVE),
|
||||
HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_SVEver_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_SVEver_SVE2p1, CAP_HWCAP, KERNEL_HWCAP_SVE2P1),
|
||||
HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_SVEver_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_SVEver_SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
|
||||
HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_AES_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_AES_IMP, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
|
||||
HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_EL1_AES_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_EL1_AES_PMULL128, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
|
||||
|
|
@ -2798,6 +2818,8 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
|
|||
#endif /* CONFIG_ARM64_MTE */
|
||||
HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_EL1_ECV_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
|
||||
HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_EL1_AFP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
|
||||
HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_EL1_CSSC_SHIFT, 4, FTR_UNSIGNED, ID_AA64ISAR2_EL1_CSSC_IMP, CAP_HWCAP, KERNEL_HWCAP_CSSC),
|
||||
HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_EL1_RPRFM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ISAR2_EL1_RPRFM_IMP, CAP_HWCAP, KERNEL_HWCAP_RPRFM),
|
||||
HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_EL1_RPRES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES),
|
||||
HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_EL1_WFxT_SHIFT, 4, FTR_UNSIGNED, ID_AA64ISAR2_EL1_WFxT_IMP, CAP_HWCAP, KERNEL_HWCAP_WFXT),
|
||||
#ifdef CONFIG_ARM64_SME
|
||||
|
|
|
|||
|
|
@ -116,6 +116,9 @@ static const char *const hwcap_str[] = {
|
|||
[KERNEL_HWCAP_WFXT] = "wfxt",
|
||||
[KERNEL_HWCAP_EBF16] = "ebf16",
|
||||
[KERNEL_HWCAP_SVE_EBF16] = "sveebf16",
|
||||
[KERNEL_HWCAP_CSSC] = "cssc",
|
||||
[KERNEL_HWCAP_RPRFM] = "rprfm",
|
||||
[KERNEL_HWCAP_SVE2P1] = "sve2p1",
|
||||
};
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
|
|
|||
|
|
@ -197,6 +197,9 @@ alternative_cb_end
|
|||
.endm
|
||||
|
||||
.macro kernel_entry, el, regsize = 64
|
||||
.if \el == 0
|
||||
alternative_insn nop, SET_PSTATE_DIT(1), ARM64_HAS_DIT
|
||||
.endif
|
||||
.if \regsize == 32
|
||||
mov w0, w0 // zero upper 32 bits of x0
|
||||
.endif
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ void notrace __cpu_suspend_exit(void)
|
|||
* PSTATE was not saved over suspend/resume, re-enable any detected
|
||||
* features that might not have been set correctly.
|
||||
*/
|
||||
if (cpus_have_const_cap(ARM64_HAS_DIT))
|
||||
set_pstate_dit(1);
|
||||
__uaccess_enable_hw_pan();
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ HAS_CNP
|
|||
HAS_CRC32
|
||||
HAS_DCPODP
|
||||
HAS_DCPOP
|
||||
HAS_DIT
|
||||
HAS_E0PD
|
||||
HAS_ECV
|
||||
HAS_EPAN
|
||||
|
|
|
|||
|
|
@ -210,6 +210,7 @@ EndEnum
|
|||
Enum 3:0 SVEver
|
||||
0b0000 IMP
|
||||
0b0001 SVE2
|
||||
0b0010 SVE2p1
|
||||
EndEnum
|
||||
EndSysreg
|
||||
|
||||
|
|
@ -484,7 +485,16 @@ EndEnum
|
|||
EndSysreg
|
||||
|
||||
Sysreg ID_AA64ISAR2_EL1 3 0 0 6 2
|
||||
Res0 63:28
|
||||
Res0 63:56
|
||||
Enum 55:52 CSSC
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
EndEnum
|
||||
Enum 51:48 RPRFM
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
EndEnum
|
||||
Res0 47:28
|
||||
Enum 27:24 PAC_frac
|
||||
0b0000 NI
|
||||
0b0001 IMP
|
||||
|
|
|
|||
|
|
@ -33,6 +33,12 @@
|
|||
*/
|
||||
typedef void (*sigill_fn)(void);
|
||||
|
||||
static void cssc_sigill(void)
|
||||
{
|
||||
/* CNT x0, x0 */
|
||||
asm volatile(".inst 0xdac01c00" : : : "x0");
|
||||
}
|
||||
|
||||
static void rng_sigill(void)
|
||||
{
|
||||
asm volatile("mrs x0, S3_3_C2_C4_0" : : : "x0");
|
||||
|
|
@ -56,6 +62,12 @@ static void sve2_sigill(void)
|
|||
asm volatile(".inst 0x4408A000" : : : "z0");
|
||||
}
|
||||
|
||||
static void sve2p1_sigill(void)
|
||||
{
|
||||
/* BFADD Z0.H, Z0.H, Z0.H */
|
||||
asm volatile(".inst 0x65000000" : : : "z0");
|
||||
}
|
||||
|
||||
static void sveaes_sigill(void)
|
||||
{
|
||||
/* AESD z0.b, z0.b, z0.b */
|
||||
|
|
@ -118,6 +130,13 @@ static const struct hwcap_data {
|
|||
sigill_fn sigill_fn;
|
||||
bool sigill_reliable;
|
||||
} hwcaps[] = {
|
||||
{
|
||||
.name = "CSSC",
|
||||
.at_hwcap = AT_HWCAP2,
|
||||
.hwcap_bit = HWCAP2_CSSC,
|
||||
.cpuinfo = "cssc",
|
||||
.sigill_fn = cssc_sigill,
|
||||
},
|
||||
{
|
||||
.name = "RNG",
|
||||
.at_hwcap = AT_HWCAP2,
|
||||
|
|
@ -125,6 +144,12 @@ static const struct hwcap_data {
|
|||
.cpuinfo = "rng",
|
||||
.sigill_fn = rng_sigill,
|
||||
},
|
||||
{
|
||||
.name = "RPRFM",
|
||||
.at_hwcap = AT_HWCAP2,
|
||||
.hwcap_bit = HWCAP2_RPRFM,
|
||||
.cpuinfo = "rprfm",
|
||||
},
|
||||
{
|
||||
.name = "SME",
|
||||
.at_hwcap = AT_HWCAP2,
|
||||
|
|
@ -148,6 +173,13 @@ static const struct hwcap_data {
|
|||
.cpuinfo = "sve2",
|
||||
.sigill_fn = sve2_sigill,
|
||||
},
|
||||
{
|
||||
.name = "SVE 2.1",
|
||||
.at_hwcap = AT_HWCAP2,
|
||||
.hwcap_bit = HWCAP2_SVE2P1,
|
||||
.cpuinfo = "sve2p1",
|
||||
.sigill_fn = sve2p1_sigill,
|
||||
},
|
||||
{
|
||||
.name = "SVE AES",
|
||||
.at_hwcap = AT_HWCAP2,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue