Skip to content

Commit 3912084

Browse files
brooniectmarinas
authored andcommitted
arm64/sve: Remove SMCR pseudo register from cpufeature code
For reasons that are not currently apparent during cpufeature enumeration we maintain a pseudo register for SMCR which records the maximum supported vector length using the value that would be written to SMCR_EL1.LEN to configure it. This is not exposed to userspace and is not sufficient for detecting unsupportable configurations, we need the more detailed checks in vec_update_vq_map() for that since we can't cope with missing vector lengths on late CPUs and KVM requires an exactly matching set of supported vector lengths as EL1 can enumerate VLs directly with the hardware. Remove the code, replacing the usage in sme_setup() with a query of the vq_map. Signed-off-by: Mark Brown <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent abef069 commit 3912084

File tree

3 files changed

+10
-61
lines changed

3 files changed

+10
-61
lines changed

arch/arm64/include/asm/cpu.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@ struct cpuinfo_arm64 {
6363
u64 reg_id_aa64smfr0;
6464

6565
struct cpuinfo_32bit aarch32;
66-
67-
/* pseudo-SMCR for recording maximum SMCR_EL1 LEN value: */
68-
u64 reg_smcr;
6966
};
7067

7168
DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data);

arch/arm64/kernel/cpufeature.c

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -611,12 +611,6 @@ static const struct arm64_ftr_bits ftr_id_dfr1[] = {
611611
ARM64_FTR_END,
612612
};
613613

614-
static const struct arm64_ftr_bits ftr_smcr[] = {
615-
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE,
616-
SMCR_ELx_LEN_SHIFT, SMCR_ELx_LEN_WIDTH, 0), /* LEN */
617-
ARM64_FTR_END,
618-
};
619-
620614
/*
621615
* Common ftr bits for a 32bit register with all hidden, strict
622616
* attributes, with 4bit feature fields and a default safe value of
@@ -729,9 +723,6 @@ static const struct __ftr_reg_entry {
729723
ARM64_FTR_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2),
730724
ARM64_FTR_REG(SYS_ID_AA64MMFR3_EL1, ftr_id_aa64mmfr3),
731725

732-
/* Op1 = 0, CRn = 1, CRm = 2 */
733-
ARM64_FTR_REG(SYS_SMCR_EL1, ftr_smcr),
734-
735726
/* Op1 = 1, CRn = 0, CRm = 0 */
736727
ARM64_FTR_REG(SYS_GMID_EL1, ftr_gmid),
737728

@@ -1039,14 +1030,14 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
10391030

10401031
if (IS_ENABLED(CONFIG_ARM64_SME) &&
10411032
id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
1042-
info->reg_smcr = read_smcr_features();
1033+
sme_kernel_enable(NULL);
1034+
10431035
/*
10441036
* We mask out SMPS since even if the hardware
10451037
* supports priorities the kernel does not at present
10461038
* and we block access to them.
10471039
*/
10481040
info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
1049-
init_cpu_ftr_reg(SYS_SMCR_EL1, info->reg_smcr);
10501041
vec_init_vq_map(ARM64_VEC_SME);
10511042
}
10521043

@@ -1292,15 +1283,14 @@ void update_cpu_features(int cpu,
12921283

12931284
if (IS_ENABLED(CONFIG_ARM64_SME) &&
12941285
id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
1295-
info->reg_smcr = read_smcr_features();
1286+
sme_kernel_enable(NULL);
1287+
12961288
/*
12971289
* We mask out SMPS since even if the hardware
12981290
* supports priorities the kernel does not at present
12991291
* and we block access to them.
13001292
*/
13011293
info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
1302-
taint |= check_update_ftr_reg(SYS_SMCR_EL1, cpu,
1303-
info->reg_smcr, boot->reg_smcr);
13041294

13051295
/* Probe vector lengths */
13061296
if (!system_capabilities_finalized())
@@ -3152,19 +3142,11 @@ static void verify_sve_features(void)
31523142

31533143
static void verify_sme_features(void)
31543144
{
3155-
u64 safe_smcr = read_sanitised_ftr_reg(SYS_SMCR_EL1);
3156-
u64 smcr = read_smcr_features();
3157-
3158-
unsigned int safe_len = safe_smcr & SMCR_ELx_LEN_MASK;
3159-
unsigned int len = smcr & SMCR_ELx_LEN_MASK;
3160-
3161-
if (len < safe_len || vec_verify_vq_map(ARM64_VEC_SME)) {
3145+
if (vec_verify_vq_map(ARM64_VEC_SME)) {
31623146
pr_crit("CPU%d: SME: vector length support mismatch\n",
31633147
smp_processor_id());
31643148
cpu_die_early();
31653149
}
3166-
3167-
/* Add checks on other SMCR bits here if necessary */
31683150
}
31693151

31703152
static void verify_hyp_capabilities(void)

arch/arm64/kernel/fpsimd.c

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,32 +1304,10 @@ void fa64_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
13041304
SYS_SMCR_EL1);
13051305
}
13061306

1307-
/*
1308-
* Read the pseudo-SMCR used by cpufeatures to identify the supported
1309-
* vector length.
1310-
*
1311-
* Use only if SME is present.
1312-
* This function clobbers the SME vector length.
1313-
*/
1314-
u64 read_smcr_features(void)
1315-
{
1316-
sme_kernel_enable(NULL);
1317-
1318-
/*
1319-
* Set the maximum possible VL.
1320-
*/
1321-
write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_LEN_MASK,
1322-
SYS_SMCR_EL1);
1323-
1324-
/* Return LEN value that would be written to get the maximum VL */
1325-
return sve_vq_from_vl(sme_get_vl()) - 1;
1326-
}
1327-
13281307
void __init sme_setup(void)
13291308
{
13301309
struct vl_info *info = &vl_info[ARM64_VEC_SME];
1331-
u64 smcr;
1332-
int min_bit;
1310+
int min_bit, max_bit;
13331311

13341312
if (!system_supports_sme())
13351313
return;
@@ -1338,24 +1316,16 @@ void __init sme_setup(void)
13381316
* SME doesn't require any particular vector length be
13391317
* supported but it does require at least one. We should have
13401318
* disabled the feature entirely while bringing up CPUs but
1341-
* let's double check here.
1319+
* let's double check here. The bitmap is SVE_VQ_MAP sized for
1320+
* sharing with SVE.
13421321
*/
13431322
WARN_ON(bitmap_empty(info->vq_map, SVE_VQ_MAX));
13441323

13451324
min_bit = find_last_bit(info->vq_map, SVE_VQ_MAX);
13461325
info->min_vl = sve_vl_from_vq(__bit_to_vq(min_bit));
13471326

1348-
smcr = read_sanitised_ftr_reg(SYS_SMCR_EL1);
1349-
info->max_vl = sve_vl_from_vq((smcr & SMCR_ELx_LEN_MASK) + 1);
1350-
1351-
/*
1352-
* Sanity-check that the max VL we determined through CPU features
1353-
* corresponds properly to sme_vq_map. If not, do our best:
1354-
*/
1355-
if (WARN_ON(info->max_vl != find_supported_vector_length(ARM64_VEC_SME,
1356-
info->max_vl)))
1357-
info->max_vl = find_supported_vector_length(ARM64_VEC_SME,
1358-
info->max_vl);
1327+
max_bit = find_first_bit(info->vq_map, SVE_VQ_MAX);
1328+
info->max_vl = sve_vl_from_vq(__bit_to_vq(max_bit));
13591329

13601330
WARN_ON(info->min_vl > info->max_vl);
13611331

0 commit comments

Comments
 (0)