Skip to content

Commit 63a2d92

Browse files
mrutland-armwilldeacon
authored andcommitted
arm64: Cleanup system cpucap handling
Recent changes to remove cpus_have_const_cap() introduced new users of cpus_have_cap() in the period between detecting system cpucaps and patching alternatives. It would be preferable to defer these until after the relevant cpucaps have been patched so that these can use the usual feature check helper functions, which is clearer and has less risk of accidental usage of code relying upon an alternative which has not yet been patched. This patch reworks the system-wide cpucap detection and patching to minimize this transient period: * The detection, enablement, and patching of system cpucaps is moved into a new setup_system_capabilities() function so that these can be grouped together more clearly, with no other functions called in the period between detection and patching. This is called from setup_system_features() before the subsequent checks that depend on the cpucaps. The logging of TTBR0 PAN and cpucaps with a mask is also moved here to keep these as close as possible to update_cpu_capabilities(). At the same time, comments are corrected and improved to make the intent clearer. * As hyp_mode_check() only tests system register values (not hwcaps) and must be called prior to patching, the call to hyp_mode_check() is moved before the call to setup_system_features(). * In setup_system_features(), the use of system_uses_ttbr0_pan() is restored, now that this occurs after alternatives are patched. This is a partial revert of commit: 53d62e9 ("arm64: Avoid cpus_have_const_cap() for ARM64_HAS_PAN") * In sve_setup() and sme_setup(), the use of system_supports_sve() and system_supports_sme() respectively are restored, now that these occur after alternatives are patched. This is a partial revert of commit: a76521d ("arm64: Avoid cpus_have_const_cap() for ARM64_{SVE,SME,SME2,FA64}") Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: Ard Biesheuvel <ardb@kernel.org> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will@kernel.org> Link: https://lore.kernel.org/r/20231212170910.3745497-2-mark.rutland@arm.com Signed-off-by: Will Deacon <will@kernel.org>
1 parent 7540f70 commit 63a2d92

3 files changed

Lines changed: 30 additions & 23 deletions

File tree

arch/arm64/kernel/cpufeature.c

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3318,23 +3318,40 @@ unsigned long cpu_get_elf_hwcap2(void)
33183318
return elf_hwcap[1];
33193319
}
33203320

3321-
void __init setup_system_features(void)
3321+
static void __init setup_system_capabilities(void)
33223322
{
3323-
int i;
33243323
/*
3325-
* The system-wide safe feature feature register values have been
3326-
* finalized. Finalize and log the available system capabilities.
3324+
* The system-wide safe feature register values have been finalized.
3325+
* Detect, enable, and patch alternatives for the available system
3326+
* cpucaps.
33273327
*/
33283328
update_cpu_capabilities(SCOPE_SYSTEM);
3329-
if (IS_ENABLED(CONFIG_ARM64_SW_TTBR0_PAN) &&
3330-
!cpus_have_cap(ARM64_HAS_PAN))
3331-
pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n");
3329+
enable_cpu_capabilities(SCOPE_ALL & ~SCOPE_BOOT_CPU);
3330+
apply_alternatives_all();
33323331

33333332
/*
3334-
* Enable all the available capabilities which have not been enabled
3335-
* already.
3333+
* Log any cpucaps with a cpumask as these aren't logged by
3334+
* update_cpu_capabilities().
33363335
*/
3337-
enable_cpu_capabilities(SCOPE_ALL & ~SCOPE_BOOT_CPU);
3336+
for (int i = 0; i < ARM64_NCAPS; i++) {
3337+
const struct arm64_cpu_capabilities *caps = cpucap_ptrs[i];
3338+
3339+
if (caps && caps->cpus && caps->desc &&
3340+
cpumask_any(caps->cpus) < nr_cpu_ids)
3341+
pr_info("detected: %s on CPU%*pbl\n",
3342+
caps->desc, cpumask_pr_args(caps->cpus));
3343+
}
3344+
3345+
/*
3346+
* TTBR0 PAN doesn't have its own cpucap, so log it manually.
3347+
*/
3348+
if (system_uses_ttbr0_pan())
3349+
pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n");
3350+
}
3351+
3352+
void __init setup_system_features(void)
3353+
{
3354+
setup_system_capabilities();
33383355

33393356
kpti_install_ng_mappings();
33403357

@@ -3347,15 +3364,6 @@ void __init setup_system_features(void)
33473364
if (!cache_type_cwg())
33483365
pr_warn("No Cache Writeback Granule information, assuming %d\n",
33493366
ARCH_DMA_MINALIGN);
3350-
3351-
for (i = 0; i < ARM64_NCAPS; i++) {
3352-
const struct arm64_cpu_capabilities *caps = cpucap_ptrs[i];
3353-
3354-
if (caps && caps->cpus && caps->desc &&
3355-
cpumask_any(caps->cpus) < nr_cpu_ids)
3356-
pr_info("detected: %s on CPU%*pbl\n",
3357-
caps->desc, cpumask_pr_args(caps->cpus));
3358-
}
33593367
}
33603368

33613369
void __init setup_user_features(void)

arch/arm64/kernel/fpsimd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,7 +1171,7 @@ void __init sve_setup(void)
11711171
unsigned long b;
11721172
int max_bit;
11731173

1174-
if (!cpus_have_cap(ARM64_SVE))
1174+
if (!system_supports_sve())
11751175
return;
11761176

11771177
/*
@@ -1301,7 +1301,7 @@ void __init sme_setup(void)
13011301
struct vl_info *info = &vl_info[ARM64_VEC_SME];
13021302
int min_bit, max_bit;
13031303

1304-
if (!cpus_have_cap(ARM64_SME))
1304+
if (!system_supports_sme())
13051305
return;
13061306

13071307
/*

arch/arm64/kernel/smp.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -439,9 +439,8 @@ static void __init hyp_mode_check(void)
439439
void __init smp_cpus_done(unsigned int max_cpus)
440440
{
441441
pr_info("SMP: Total of %d processors activated.\n", num_online_cpus());
442-
setup_system_features();
443442
hyp_mode_check();
444-
apply_alternatives_all();
443+
setup_system_features();
445444
setup_user_features();
446445
mark_linear_text_alias_ro();
447446
}

0 commit comments

Comments
 (0)