From 73599c263efc74248686c043a93067d8c1a66b6c Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 17 May 2021 11:48:05 +0100 Subject: [PATCH] ANDROID: Fix compat hwcap reporting on asymmetric 32-bit SoCs When support for asymmetric 32-bit SoCs is enabled on the kernel command-line, system_supports_32bit_el0() will always return true since a late-onlined CPU could introduce the need for 32-bit support. In order to avoid checking for the presence of compat hwcaps on 64-bit-only CPUs, adjust the verification of compat hwcaps for late-onlined CPUs so that it is only performed for CPUs which actually have 32-bit support. This allows late CPU hotplug of 64-bit-only CPUs on a mismatched system. When mismatched support is not enabled, incompatible CPUs are preventing from coming online by the CPU capability. Bug: 186482502 Change-Id: I22c285a54dbf9abb1a35e2bb608e5a41517f0ad0 Signed-off-by: Will Deacon --- arch/arm64/kernel/cpufeature.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 7c49b938fe7b..c9711b504e8f 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -2685,7 +2685,7 @@ static void check_early_cpu_features(void) } static void -verify_local_elf_hwcaps(const struct arm64_cpu_capabilities *caps) +__verify_local_elf_hwcaps(const struct arm64_cpu_capabilities *caps) { for (; caps->matches; caps++) @@ -2696,6 +2696,14 @@ verify_local_elf_hwcaps(const struct arm64_cpu_capabilities *caps) } } +static void verify_local_elf_hwcaps(void) +{ + __verify_local_elf_hwcaps(arm64_elf_hwcaps); + + if (id_aa64pfr0_32bit_el0(read_cpuid(ID_AA64PFR0_EL1))) + __verify_local_elf_hwcaps(compat_elf_hwcaps); +} + static void verify_sve_features(void) { u64 safe_zcr = read_sanitised_ftr_reg(SYS_ZCR_EL1); @@ -2760,11 +2768,7 @@ static void verify_local_cpu_capabilities(void) * on all secondary CPUs. */ verify_local_cpu_caps(SCOPE_ALL & ~SCOPE_BOOT_CPU); - - verify_local_elf_hwcaps(arm64_elf_hwcaps); - - if (system_supports_32bit_el0()) - verify_local_elf_hwcaps(compat_elf_hwcaps); + verify_local_elf_hwcaps(); if (system_supports_sve()) verify_sve_features();