| From foo@baz Sun 27 Oct 2019 09:50:54 AM CET |
| From: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| Date: Thu, 24 Oct 2019 14:48:22 +0200 |
| Subject: arm64: add sysfs vulnerability show for meltdown |
| To: stable@vger.kernel.org |
| Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>, Will Deacon <will@kernel.org>, Catalin Marinas <catalin.marinas@arm.com>, Marc Zyngier <maz@kernel.org>, Mark Rutland <mark.rutland@arm.com>, Suzuki K Poulose <suzuki.poulose@arm.com>, Jeremy Linton <jeremy.linton@arm.com>, Andre Przywara <andre.przywara@arm.com>, Alexandru Elisei <alexandru.elisei@arm.com>, Stefan Wahren <stefan.wahren@i2se.com>, Will Deacon <will.deacon@arm.com> |
| Message-ID: <20191024124833.4158-38-ard.biesheuvel@linaro.org> |
| |
| From: Jeremy Linton <jeremy.linton@arm.com> |
| |
| [ Upstream commit 1b3ccf4be0e7be8c4bd8522066b6cbc92591e912 ] |
| |
| We implement page table isolation as a mitigation for meltdown. |
| Report this to userspace via sysfs. |
| |
| Signed-off-by: Jeremy Linton <jeremy.linton@arm.com> |
| Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> |
| Reviewed-by: Andre Przywara <andre.przywara@arm.com> |
| Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> |
| Tested-by: Stefan Wahren <stefan.wahren@i2se.com> |
| Signed-off-by: Will Deacon <will.deacon@arm.com> |
| Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/arm64/kernel/cpufeature.c | 58 +++++++++++++++++++++++++++++++---------- |
| 1 file changed, 44 insertions(+), 14 deletions(-) |
| |
| --- a/arch/arm64/kernel/cpufeature.c |
| +++ b/arch/arm64/kernel/cpufeature.c |
| @@ -824,7 +824,7 @@ static bool has_no_fpsimd(const struct a |
| ID_AA64PFR0_FP_SHIFT) < 0; |
| } |
| |
| -#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 |
| +static bool __meltdown_safe = true; |
| static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */ |
| |
| static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry, |
| @@ -842,6 +842,16 @@ static bool unmap_kernel_at_el0(const st |
| MIDR_ALL_VERSIONS(MIDR_CORTEX_A73), |
| }; |
| char const *str = "command line option"; |
| + bool meltdown_safe; |
| + |
| + meltdown_safe = is_midr_in_range_list(read_cpuid_id(), kpti_safe_list); |
| + |
| + /* Defer to CPU feature registers */ |
| + if (has_cpuid_feature(entry, scope)) |
| + meltdown_safe = true; |
| + |
| + if (!meltdown_safe) |
| + __meltdown_safe = false; |
| |
| /* |
| * For reasons that aren't entirely clear, enabling KPTI on Cavium |
| @@ -853,6 +863,19 @@ static bool unmap_kernel_at_el0(const st |
| __kpti_forced = -1; |
| } |
| |
| + /* Useful for KASLR robustness */ |
| + if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && kaslr_offset() > 0) { |
| + if (!__kpti_forced) { |
| + str = "KASLR"; |
| + __kpti_forced = 1; |
| + } |
| + } |
| + |
| + if (!IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0)) { |
| + pr_info_once("kernel page table isolation disabled by kernel configuration\n"); |
| + return false; |
| + } |
| + |
| /* Forced? */ |
| if (__kpti_forced) { |
| pr_info_once("kernel page table isolation forced %s by %s\n", |
| @@ -860,18 +883,10 @@ static bool unmap_kernel_at_el0(const st |
| return __kpti_forced > 0; |
| } |
| |
| - /* Useful for KASLR robustness */ |
| - if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) |
| - return true; |
| - |
| - /* Don't force KPTI for CPUs that are not vulnerable */ |
| - if (is_midr_in_range_list(read_cpuid_id(), kpti_safe_list)) |
| - return false; |
| - |
| - /* Defer to CPU feature registers */ |
| - return !has_cpuid_feature(entry, scope); |
| + return !meltdown_safe; |
| } |
| |
| +#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 |
| static void |
| kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused) |
| { |
| @@ -896,6 +911,12 @@ kpti_install_ng_mappings(const struct ar |
| |
| return; |
| } |
| +#else |
| +static void |
| +kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused) |
| +{ |
| +} |
| +#endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */ |
| |
| static int __init parse_kpti(char *str) |
| { |
| @@ -909,7 +930,6 @@ static int __init parse_kpti(char *str) |
| return 0; |
| } |
| early_param("kpti", parse_kpti); |
| -#endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */ |
| |
| static void cpu_copy_el2regs(const struct arm64_cpu_capabilities *__unused) |
| { |
| @@ -1056,7 +1076,6 @@ static const struct arm64_cpu_capabiliti |
| .type = ARM64_CPUCAP_SYSTEM_FEATURE, |
| .matches = hyp_offset_low, |
| }, |
| -#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 |
| { |
| .desc = "Kernel page table isolation (KPTI)", |
| .capability = ARM64_UNMAP_KERNEL_AT_EL0, |
| @@ -1072,7 +1091,6 @@ static const struct arm64_cpu_capabiliti |
| .matches = unmap_kernel_at_el0, |
| .cpu_enable = kpti_install_ng_mappings, |
| }, |
| -#endif |
| { |
| /* FP/SIMD is not implemented */ |
| .capability = ARM64_HAS_NO_FPSIMD, |
| @@ -1629,3 +1647,15 @@ static int __init enable_mrs_emulation(v |
| } |
| |
| core_initcall(enable_mrs_emulation); |
| + |
| +ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, |
| + char *buf) |
| +{ |
| + if (__meltdown_safe) |
| + return sprintf(buf, "Not affected\n"); |
| + |
| + if (arm64_kernel_unmapped_at_el0()) |
| + return sprintf(buf, "Mitigation: PTI\n"); |
| + |
| + return sprintf(buf, "Vulnerable\n"); |
| +} |