aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Martin <Dave.Martin@arm.com>2017-10-31 11:51:10 -0400
committerWill Deacon <will.deacon@arm.com>2017-11-03 11:24:17 -0400
commit2e0f2478ea37eba945bee007884a2988b8f7d332 (patch)
treeeefdac015c0ee8702fefbdc99e3bf941d8456084
parent8f1eec57cdccd17faeaf7f593505124376340fd0 (diff)
arm64/sve: Probe SVE capabilities and usable vector lengths
This patch uses the cpufeatures framework to determine common SVE capabilities and vector lengths, and configures the runtime SVE support code appropriately. ZCR_ELx is not really a feature register, but it is convenient to use it as a template for recording the maximum vector length supported by a CPU, using the LEN field. This field is similar to a feature field in that it is a contiguous bitfield for which we want to determine the minimum system-wide value. This patch adds ZCR as a pseudo-register in cpuinfo/cpufeatures, with appropriate custom code to populate it. Finding the minimum supported value of the LEN field is left to the cpufeatures framework in the usual way. The meaning of ID_AA64ZFR0_EL1 is not architecturally defined yet, so for now we just require it to be zero. Note that much of this code is dormant and SVE still won't be used yet, since system_supports_sve() remains hardwired to false. Signed-off-by: Dave Martin <Dave.Martin@arm.com> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Cc: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--arch/arm64/include/asm/cpu.h4
-rw-r--r--arch/arm64/include/asm/cpufeature.h36
-rw-r--r--arch/arm64/include/asm/fpsimd.h14
-rw-r--r--arch/arm64/kernel/cpufeature.c52
-rw-r--r--arch/arm64/kernel/cpuinfo.c6
-rw-r--r--arch/arm64/kernel/fpsimd.c114
6 files changed, 223 insertions, 3 deletions
diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index 889226b4c6e1..88392272250e 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -41,6 +41,7 @@ struct cpuinfo_arm64 {
41 u64 reg_id_aa64mmfr2; 41 u64 reg_id_aa64mmfr2;
42 u64 reg_id_aa64pfr0; 42 u64 reg_id_aa64pfr0;
43 u64 reg_id_aa64pfr1; 43 u64 reg_id_aa64pfr1;
44 u64 reg_id_aa64zfr0;
44 45
45 u32 reg_id_dfr0; 46 u32 reg_id_dfr0;
46 u32 reg_id_isar0; 47 u32 reg_id_isar0;
@@ -59,6 +60,9 @@ struct cpuinfo_arm64 {
59 u32 reg_mvfr0; 60 u32 reg_mvfr0;
60 u32 reg_mvfr1; 61 u32 reg_mvfr1;
61 u32 reg_mvfr2; 62 u32 reg_mvfr2;
63
64 /* pseudo-ZCR for recording maximum ZCR_EL1 LEN value: */
65 u64 reg_zcr;
62}; 66};
63 67
64DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data); 68DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data);
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 4ea3441a8fa7..9b27e8c10086 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -10,7 +10,9 @@
10#define __ASM_CPUFEATURE_H 10#define __ASM_CPUFEATURE_H
11 11
12#include <asm/cpucaps.h> 12#include <asm/cpucaps.h>
13#include <asm/fpsimd.h>
13#include <asm/hwcap.h> 14#include <asm/hwcap.h>
15#include <asm/sigcontext.h>
14#include <asm/sysreg.h> 16#include <asm/sysreg.h>
15 17
16/* 18/*
@@ -223,6 +225,13 @@ static inline bool id_aa64pfr0_32bit_el0(u64 pfr0)
223 return val == ID_AA64PFR0_EL0_32BIT_64BIT; 225 return val == ID_AA64PFR0_EL0_32BIT_64BIT;
224} 226}
225 227
228static inline bool id_aa64pfr0_sve(u64 pfr0)
229{
230 u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_SVE_SHIFT);
231
232 return val > 0;
233}
234
226void __init setup_cpu_features(void); 235void __init setup_cpu_features(void);
227 236
228void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps, 237void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
@@ -267,6 +276,33 @@ static inline bool system_supports_sve(void)
267 return false; 276 return false;
268} 277}
269 278
279/*
280 * Read the pseudo-ZCR used by cpufeatures to identify the supported SVE
281 * vector length.
282 *
283 * Use only if SVE is present.
284 * This function clobbers the SVE vector length.
285 */
286static inline u64 read_zcr_features(void)
287{
288 u64 zcr;
289 unsigned int vq_max;
290
291 /*
292 * Set the maximum possible VL, and write zeroes to all other
293 * bits to see if they stick.
294 */
295 sve_kernel_enable(NULL);
296 write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL1);
297
298 zcr = read_sysreg_s(SYS_ZCR_EL1);
299 zcr &= ~(u64)ZCR_ELx_LEN_MASK; /* find sticky 1s outside LEN field */
300 vq_max = sve_vq_from_vl(sve_get_vl());
301 zcr |= vq_max - 1; /* set LEN field to maximum effective value */
302
303 return zcr;
304}
305
270#endif /* __ASSEMBLY__ */ 306#endif /* __ASSEMBLY__ */
271 307
272#endif 308#endif
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 86f550ce7b4d..d8e0dc9f65a1 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -78,6 +78,7 @@ extern void sve_save_state(void *state, u32 *pfpsr);
78extern void sve_load_state(void const *state, u32 const *pfpsr, 78extern void sve_load_state(void const *state, u32 const *pfpsr,
79 unsigned long vq_minus_1); 79 unsigned long vq_minus_1);
80extern unsigned int sve_get_vl(void); 80extern unsigned int sve_get_vl(void);
81extern int sve_kernel_enable(void *);
81 82
82extern int __ro_after_init sve_max_vl; 83extern int __ro_after_init sve_max_vl;
83 84
@@ -90,10 +91,23 @@ extern void fpsimd_release_task(struct task_struct *task);
90extern int sve_set_vector_length(struct task_struct *task, 91extern int sve_set_vector_length(struct task_struct *task,
91 unsigned long vl, unsigned long flags); 92 unsigned long vl, unsigned long flags);
92 93
94/*
95 * Probing and setup functions.
96 * Calls to these functions must be serialised with one another.
97 */
98extern void __init sve_init_vq_map(void);
99extern void sve_update_vq_map(void);
100extern int sve_verify_vq_map(void);
101extern void __init sve_setup(void);
102
93#else /* ! CONFIG_ARM64_SVE */ 103#else /* ! CONFIG_ARM64_SVE */
94 104
95static inline void sve_alloc(struct task_struct *task) { } 105static inline void sve_alloc(struct task_struct *task) { }
96static inline void fpsimd_release_task(struct task_struct *task) { } 106static inline void fpsimd_release_task(struct task_struct *task) { }
107static inline void sve_init_vq_map(void) { }
108static inline void sve_update_vq_map(void) { }
109static inline int sve_verify_vq_map(void) { return 0; }
110static inline void sve_setup(void) { }
97 111
98#endif /* ! CONFIG_ARM64_SVE */ 112#endif /* ! CONFIG_ARM64_SVE */
99 113
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 0e192cbe4149..036ad9d1b442 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -27,6 +27,7 @@
27#include <asm/cpu.h> 27#include <asm/cpu.h>
28#include <asm/cpufeature.h> 28#include <asm/cpufeature.h>
29#include <asm/cpu_ops.h> 29#include <asm/cpu_ops.h>
30#include <asm/fpsimd.h>
30#include <asm/mmu_context.h> 31#include <asm/mmu_context.h>
31#include <asm/processor.h> 32#include <asm/processor.h>
32#include <asm/sysreg.h> 33#include <asm/sysreg.h>
@@ -287,6 +288,12 @@ static const struct arm64_ftr_bits ftr_id_dfr0[] = {
287 ARM64_FTR_END, 288 ARM64_FTR_END,
288}; 289};
289 290
291static const struct arm64_ftr_bits ftr_zcr[] = {
292 ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE,
293 ZCR_ELx_LEN_SHIFT, ZCR_ELx_LEN_SIZE, 0), /* LEN */
294 ARM64_FTR_END,
295};
296
290/* 297/*
291 * Common ftr bits for a 32bit register with all hidden, strict 298 * Common ftr bits for a 32bit register with all hidden, strict
292 * attributes, with 4bit feature fields and a default safe value of 299 * attributes, with 4bit feature fields and a default safe value of
@@ -353,6 +360,7 @@ static const struct __ftr_reg_entry {
353 /* Op1 = 0, CRn = 0, CRm = 4 */ 360 /* Op1 = 0, CRn = 0, CRm = 4 */
354 ARM64_FTR_REG(SYS_ID_AA64PFR0_EL1, ftr_id_aa64pfr0), 361 ARM64_FTR_REG(SYS_ID_AA64PFR0_EL1, ftr_id_aa64pfr0),
355 ARM64_FTR_REG(SYS_ID_AA64PFR1_EL1, ftr_raz), 362 ARM64_FTR_REG(SYS_ID_AA64PFR1_EL1, ftr_raz),
363 ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_raz),
356 364
357 /* Op1 = 0, CRn = 0, CRm = 5 */ 365 /* Op1 = 0, CRn = 0, CRm = 5 */
358 ARM64_FTR_REG(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0), 366 ARM64_FTR_REG(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0),
@@ -367,6 +375,9 @@ static const struct __ftr_reg_entry {
367 ARM64_FTR_REG(SYS_ID_AA64MMFR1_EL1, ftr_id_aa64mmfr1), 375 ARM64_FTR_REG(SYS_ID_AA64MMFR1_EL1, ftr_id_aa64mmfr1),
368 ARM64_FTR_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2), 376 ARM64_FTR_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2),
369 377
378 /* Op1 = 0, CRn = 1, CRm = 2 */
379 ARM64_FTR_REG(SYS_ZCR_EL1, ftr_zcr),
380
370 /* Op1 = 3, CRn = 0, CRm = 0 */ 381 /* Op1 = 3, CRn = 0, CRm = 0 */
371 { SYS_CTR_EL0, &arm64_ftr_reg_ctrel0 }, 382 { SYS_CTR_EL0, &arm64_ftr_reg_ctrel0 },
372 ARM64_FTR_REG(SYS_DCZID_EL0, ftr_dczid), 383 ARM64_FTR_REG(SYS_DCZID_EL0, ftr_dczid),
@@ -504,6 +515,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
504 init_cpu_ftr_reg(SYS_ID_AA64MMFR2_EL1, info->reg_id_aa64mmfr2); 515 init_cpu_ftr_reg(SYS_ID_AA64MMFR2_EL1, info->reg_id_aa64mmfr2);
505 init_cpu_ftr_reg(SYS_ID_AA64PFR0_EL1, info->reg_id_aa64pfr0); 516 init_cpu_ftr_reg(SYS_ID_AA64PFR0_EL1, info->reg_id_aa64pfr0);
506 init_cpu_ftr_reg(SYS_ID_AA64PFR1_EL1, info->reg_id_aa64pfr1); 517 init_cpu_ftr_reg(SYS_ID_AA64PFR1_EL1, info->reg_id_aa64pfr1);
518 init_cpu_ftr_reg(SYS_ID_AA64ZFR0_EL1, info->reg_id_aa64zfr0);
507 519
508 if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) { 520 if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) {
509 init_cpu_ftr_reg(SYS_ID_DFR0_EL1, info->reg_id_dfr0); 521 init_cpu_ftr_reg(SYS_ID_DFR0_EL1, info->reg_id_dfr0);
@@ -524,6 +536,10 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
524 init_cpu_ftr_reg(SYS_MVFR2_EL1, info->reg_mvfr2); 536 init_cpu_ftr_reg(SYS_MVFR2_EL1, info->reg_mvfr2);
525 } 537 }
526 538
539 if (id_aa64pfr0_sve(info->reg_id_aa64pfr0)) {
540 init_cpu_ftr_reg(SYS_ZCR_EL1, info->reg_zcr);
541 sve_init_vq_map();
542 }
527} 543}
528 544
529static void update_cpu_ftr_reg(struct arm64_ftr_reg *reg, u64 new) 545static void update_cpu_ftr_reg(struct arm64_ftr_reg *reg, u64 new)
@@ -627,6 +643,9 @@ void update_cpu_features(int cpu,
627 taint |= check_update_ftr_reg(SYS_ID_AA64PFR1_EL1, cpu, 643 taint |= check_update_ftr_reg(SYS_ID_AA64PFR1_EL1, cpu,
628 info->reg_id_aa64pfr1, boot->reg_id_aa64pfr1); 644 info->reg_id_aa64pfr1, boot->reg_id_aa64pfr1);
629 645
646 taint |= check_update_ftr_reg(SYS_ID_AA64ZFR0_EL1, cpu,
647 info->reg_id_aa64zfr0, boot->reg_id_aa64zfr0);
648
630 /* 649 /*
631 * If we have AArch32, we care about 32-bit features for compat. 650 * If we have AArch32, we care about 32-bit features for compat.
632 * If the system doesn't support AArch32, don't update them. 651 * If the system doesn't support AArch32, don't update them.
@@ -674,6 +693,16 @@ void update_cpu_features(int cpu,
674 info->reg_mvfr2, boot->reg_mvfr2); 693 info->reg_mvfr2, boot->reg_mvfr2);
675 } 694 }
676 695
696 if (id_aa64pfr0_sve(info->reg_id_aa64pfr0)) {
697 taint |= check_update_ftr_reg(SYS_ZCR_EL1, cpu,
698 info->reg_zcr, boot->reg_zcr);
699
700 /* Probe vector lengths, unless we already gave up on SVE */
701 if (id_aa64pfr0_sve(read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1)) &&
702 !sys_caps_initialised)
703 sve_update_vq_map();
704 }
705
677 /* 706 /*
678 * Mismatched CPU features are a recipe for disaster. Don't even 707 * Mismatched CPU features are a recipe for disaster. Don't even
679 * pretend to support them. 708 * pretend to support them.
@@ -1106,6 +1135,23 @@ verify_local_cpu_features(const struct arm64_cpu_capabilities *caps)
1106 } 1135 }
1107} 1136}
1108 1137
1138static void verify_sve_features(void)
1139{
1140 u64 safe_zcr = read_sanitised_ftr_reg(SYS_ZCR_EL1);
1141 u64 zcr = read_zcr_features();
1142
1143 unsigned int safe_len = safe_zcr & ZCR_ELx_LEN_MASK;
1144 unsigned int len = zcr & ZCR_ELx_LEN_MASK;
1145
1146 if (len < safe_len || sve_verify_vq_map()) {
1147 pr_crit("CPU%d: SVE: required vector length(s) missing\n",
1148 smp_processor_id());
1149 cpu_die_early();
1150 }
1151
1152 /* Add checks on other ZCR bits here if necessary */
1153}
1154
1109/* 1155/*
1110 * Run through the enabled system capabilities and enable() it on this CPU. 1156 * Run through the enabled system capabilities and enable() it on this CPU.
1111 * The capabilities were decided based on the available CPUs at the boot time. 1157 * The capabilities were decided based on the available CPUs at the boot time.
@@ -1119,8 +1165,12 @@ static void verify_local_cpu_capabilities(void)
1119 verify_local_cpu_errata_workarounds(); 1165 verify_local_cpu_errata_workarounds();
1120 verify_local_cpu_features(arm64_features); 1166 verify_local_cpu_features(arm64_features);
1121 verify_local_elf_hwcaps(arm64_elf_hwcaps); 1167 verify_local_elf_hwcaps(arm64_elf_hwcaps);
1168
1122 if (system_supports_32bit_el0()) 1169 if (system_supports_32bit_el0())
1123 verify_local_elf_hwcaps(compat_elf_hwcaps); 1170 verify_local_elf_hwcaps(compat_elf_hwcaps);
1171
1172 if (system_supports_sve())
1173 verify_sve_features();
1124} 1174}
1125 1175
1126void check_local_cpu_capabilities(void) 1176void check_local_cpu_capabilities(void)
@@ -1198,6 +1248,8 @@ void __init setup_cpu_features(void)
1198 if (system_supports_32bit_el0()) 1248 if (system_supports_32bit_el0())
1199 setup_elf_hwcaps(compat_elf_hwcaps); 1249 setup_elf_hwcaps(compat_elf_hwcaps);
1200 1250
1251 sve_setup();
1252
1201 /* Advertise that we have computed the system capabilities */ 1253 /* Advertise that we have computed the system capabilities */
1202 set_sys_caps_initialised(); 1254 set_sys_caps_initialised();
1203 1255
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 1ff1c5a67081..58da504be36e 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -19,6 +19,7 @@
19#include <asm/cpu.h> 19#include <asm/cpu.h>
20#include <asm/cputype.h> 20#include <asm/cputype.h>
21#include <asm/cpufeature.h> 21#include <asm/cpufeature.h>
22#include <asm/fpsimd.h>
22 23
23#include <linux/bitops.h> 24#include <linux/bitops.h>
24#include <linux/bug.h> 25#include <linux/bug.h>
@@ -331,6 +332,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
331 info->reg_id_aa64mmfr2 = read_cpuid(ID_AA64MMFR2_EL1); 332 info->reg_id_aa64mmfr2 = read_cpuid(ID_AA64MMFR2_EL1);
332 info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1); 333 info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1);
333 info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1); 334 info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1);
335 info->reg_id_aa64zfr0 = read_cpuid(ID_AA64ZFR0_EL1);
334 336
335 /* Update the 32bit ID registers only if AArch32 is implemented */ 337 /* Update the 32bit ID registers only if AArch32 is implemented */
336 if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) { 338 if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) {
@@ -353,6 +355,10 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
353 info->reg_mvfr2 = read_cpuid(MVFR2_EL1); 355 info->reg_mvfr2 = read_cpuid(MVFR2_EL1);
354 } 356 }
355 357
358 if (IS_ENABLED(CONFIG_ARM64_SVE) &&
359 id_aa64pfr0_sve(info->reg_id_aa64pfr0))
360 info->reg_zcr = read_zcr_features();
361
356 cpuinfo_detect_icache_policy(info); 362 cpuinfo_detect_icache_policy(info);
357} 363}
358 364
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 667be3472114..715398e91d65 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -115,19 +115,19 @@
115static DEFINE_PER_CPU(struct fpsimd_state *, fpsimd_last_state); 115static DEFINE_PER_CPU(struct fpsimd_state *, fpsimd_last_state);
116 116
117/* Default VL for tasks that don't set it explicitly: */ 117/* Default VL for tasks that don't set it explicitly: */
118static int sve_default_vl = SVE_VL_MIN; 118static int sve_default_vl = -1;
119 119
120#ifdef CONFIG_ARM64_SVE 120#ifdef CONFIG_ARM64_SVE
121 121
122/* Maximum supported vector length across all CPUs (initially poisoned) */ 122/* Maximum supported vector length across all CPUs (initially poisoned) */
123int __ro_after_init sve_max_vl = -1; 123int __ro_after_init sve_max_vl = -1;
124/* Set of available vector lengths, as vq_to_bit(vq): */ 124/* Set of available vector lengths, as vq_to_bit(vq): */
125static DECLARE_BITMAP(sve_vq_map, SVE_VQ_MAX); 125static __ro_after_init DECLARE_BITMAP(sve_vq_map, SVE_VQ_MAX);
126 126
127#else /* ! CONFIG_ARM64_SVE */ 127#else /* ! CONFIG_ARM64_SVE */
128 128
129/* Dummy declaration for code that will be optimised out: */ 129/* Dummy declaration for code that will be optimised out: */
130extern DECLARE_BITMAP(sve_vq_map, SVE_VQ_MAX); 130extern __ro_after_init DECLARE_BITMAP(sve_vq_map, SVE_VQ_MAX);
131 131
132#endif /* ! CONFIG_ARM64_SVE */ 132#endif /* ! CONFIG_ARM64_SVE */
133 133
@@ -497,6 +497,111 @@ out:
497} 497}
498 498
499/* 499/*
500 * Bitmap for temporary storage of the per-CPU set of supported vector lengths
501 * during secondary boot.
502 */
503static DECLARE_BITMAP(sve_secondary_vq_map, SVE_VQ_MAX);
504
505static void sve_probe_vqs(DECLARE_BITMAP(map, SVE_VQ_MAX))
506{
507 unsigned int vq, vl;
508 unsigned long zcr;
509
510 bitmap_zero(map, SVE_VQ_MAX);
511
512 zcr = ZCR_ELx_LEN_MASK;
513 zcr = read_sysreg_s(SYS_ZCR_EL1) & ~zcr;
514
515 for (vq = SVE_VQ_MAX; vq >= SVE_VQ_MIN; --vq) {
516 write_sysreg_s(zcr | (vq - 1), SYS_ZCR_EL1); /* self-syncing */
517 vl = sve_get_vl();
518 vq = sve_vq_from_vl(vl); /* skip intervening lengths */
519 set_bit(vq_to_bit(vq), map);
520 }
521}
522
523void __init sve_init_vq_map(void)
524{
525 sve_probe_vqs(sve_vq_map);
526}
527
528/*
529 * If we haven't committed to the set of supported VQs yet, filter out
530 * those not supported by the current CPU.
531 */
532void sve_update_vq_map(void)
533{
534 sve_probe_vqs(sve_secondary_vq_map);
535 bitmap_and(sve_vq_map, sve_vq_map, sve_secondary_vq_map, SVE_VQ_MAX);
536}
537
538/* Check whether the current CPU supports all VQs in the committed set */
539int sve_verify_vq_map(void)
540{
541 int ret = 0;
542
543 sve_probe_vqs(sve_secondary_vq_map);
544 bitmap_andnot(sve_secondary_vq_map, sve_vq_map, sve_secondary_vq_map,
545 SVE_VQ_MAX);
546 if (!bitmap_empty(sve_secondary_vq_map, SVE_VQ_MAX)) {
547 pr_warn("SVE: cpu%d: Required vector length(s) missing\n",
548 smp_processor_id());
549 ret = -EINVAL;
550 }
551
552 return ret;
553}
554
555/*
556 * Enable SVE for EL1.
557 * Intended for use by the cpufeatures code during CPU boot.
558 */
559int sve_kernel_enable(void *__always_unused p)
560{
561 write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_ZEN_EL1EN, CPACR_EL1);
562 isb();
563
564 return 0;
565}
566
567void __init sve_setup(void)
568{
569 u64 zcr;
570
571 if (!system_supports_sve())
572 return;
573
574 /*
575 * The SVE architecture mandates support for 128-bit vectors,
576 * so sve_vq_map must have at least SVE_VQ_MIN set.
577 * If something went wrong, at least try to patch it up:
578 */
579 if (WARN_ON(!test_bit(vq_to_bit(SVE_VQ_MIN), sve_vq_map)))
580 set_bit(vq_to_bit(SVE_VQ_MIN), sve_vq_map);
581
582 zcr = read_sanitised_ftr_reg(SYS_ZCR_EL1);
583 sve_max_vl = sve_vl_from_vq((zcr & ZCR_ELx_LEN_MASK) + 1);
584
585 /*
586 * Sanity-check that the max VL we determined through CPU features
587 * corresponds properly to sve_vq_map. If not, do our best:
588 */
589 if (WARN_ON(sve_max_vl != find_supported_vector_length(sve_max_vl)))
590 sve_max_vl = find_supported_vector_length(sve_max_vl);
591
592 /*
593 * For the default VL, pick the maximum supported value <= 64.
594 * VL == 64 is guaranteed not to grow the signal frame.
595 */
596 sve_default_vl = find_supported_vector_length(64);
597
598 pr_info("SVE: maximum available vector length %u bytes per vector\n",
599 sve_max_vl);
600 pr_info("SVE: default vector length %u bytes per vector\n",
601 sve_default_vl);
602}
603
604/*
500 * Called from the put_task_struct() path, which cannot get here 605 * Called from the put_task_struct() path, which cannot get here
501 * unless dead_task is really dead and not schedulable. 606 * unless dead_task is really dead and not schedulable.
502 */ 607 */
@@ -631,6 +736,9 @@ void fpsimd_flush_thread(void)
631 * This is where we ensure that all user tasks have a valid 736 * This is where we ensure that all user tasks have a valid
632 * vector length configured: no kernel task can become a user 737 * vector length configured: no kernel task can become a user
633 * task without an exec and hence a call to this function. 738 * task without an exec and hence a call to this function.
739 * By the time the first call to this function is made, all
740 * early hardware probing is complete, so sve_default_vl
741 * should be valid.
634 * If a bug causes this to go wrong, we make some noise and 742 * If a bug causes this to go wrong, we make some noise and
635 * try to fudge thread.sve_vl to a safe value here. 743 * try to fudge thread.sve_vl to a safe value here.
636 */ 744 */