summaryrefslogtreecommitdiffstats
path: root/arch/arm64/include/asm/cpufeature.h
diff options
context:
space:
mode:
authorWill Deacon <will@kernel.org>2021-06-08 20:02:55 +0200
committerWill Deacon <will@kernel.org>2021-06-11 14:25:40 +0200
commit2122a833316f2f3f6ddc78429fa67ef6d3c86636 (patch)
treea95ac214b398b4dd7f46e1f8aca026e84056a233 /arch/arm64/include/asm/cpufeature.h
parentarm64: cpuinfo: Split AArch32 registers out into a separate struct (diff)
downloadlinux-2122a833316f2f3f6ddc78429fa67ef6d3c86636.tar.xz
linux-2122a833316f2f3f6ddc78429fa67ef6d3c86636.zip
arm64: Allow mismatched 32-bit EL0 support
When confronted with a mixture of CPUs, some of which support 32-bit applications and others which don't, we quite sensibly treat the system as 64-bit only for userspace and prevent execve() of 32-bit binaries. Unfortunately, some crazy folks have decided to build systems like this with the intention of running 32-bit applications, so relax our sanitisation logic to continue to advertise 32-bit support to userspace on these systems and track the real 32-bit capable cores in a cpumask instead. For now, the default behaviour remains but will be tied to a command-line option in a later patch. Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Link: https://lore.kernel.org/r/20210608180313.11502-3-will@kernel.org Signed-off-by: Will Deacon <will@kernel.org>
Diffstat (limited to 'arch/arm64/include/asm/cpufeature.h')
-rw-r--r--arch/arm64/include/asm/cpufeature.h8
1 files changed, 7 insertions, 1 deletions
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 650de920e067..9bb9d11750d7 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -637,9 +637,15 @@ static inline bool cpu_supports_mixed_endian_el0(void)
return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
}
+const struct cpumask *system_32bit_el0_cpumask(void);
+DECLARE_STATIC_KEY_FALSE(arm64_mismatched_32bit_el0);
+
static inline bool system_supports_32bit_el0(void)
{
- return cpus_have_const_cap(ARM64_HAS_32BIT_EL0);
+ u64 pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+
+ return static_branch_unlikely(&arm64_mismatched_32bit_el0) ||
+ id_aa64pfr0_32bit_el0(pfr0);
}
static inline bool system_supports_4kb_granule(void)