This is a note to let you know that I've just added the patch titled
arm64: entry: Add fake CPU feature for unmapping the kernel at EL0
to the 4.9-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git%3Ba=su...
The filename of the patch is: arm64-entry-add-fake-cpu-feature-for-unmapping-the-kernel-at-el0.patch and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let stable@vger.kernel.org know about it.
From foo@baz Thu Apr 5 21:39:28 CEST 2018
From: Mark Rutland mark.rutland@arm.com Date: Tue, 3 Apr 2018 12:09:09 +0100 Subject: arm64: entry: Add fake CPU feature for unmapping the kernel at EL0 To: stable@vger.kernel.org Cc: mark.brown@linaro.org, ard.biesheuvel@linaro.org, marc.zyngier@arm.com, will.deacon@arm.com Message-ID: 20180403110923.43575-14-mark.rutland@arm.com
From: Will Deacon will.deacon@arm.com
commit ea1e3de85e94 upstream.
Allow explicit disabling of the entry trampoline on the kernel command line (kpti=off) by adding a fake CPU feature (ARM64_UNMAP_KERNEL_AT_EL0) that can be used to toggle the alternative sequences in our entry code and avoid use of the trampoline altogether if desired. This also allows us to make use of a static key in arm64_kernel_unmapped_at_el0().
Reviewed-by: Mark Rutland mark.rutland@arm.com Tested-by: Laura Abbott labbott@redhat.com Tested-by: Shanker Donthineni shankerd@codeaurora.org Signed-off-by: Will Deacon will.deacon@arm.com [Alex: use first free cpucap number, use cpus_have_cap] Signed-off-by: Alex Shi alex.shi@linaro.org [v4.9 backport] Signed-off-by: Mark Rutland mark.rutland@arm.com [v4.9 backport] Tested-by: Will Deacon will.deacon@arm.com Tested-by: Greg Hackmann ghackmann@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/include/asm/cpucaps.h | 3 +- arch/arm64/include/asm/mmu.h | 3 +- arch/arm64/kernel/cpufeature.c | 41 +++++++++++++++++++++++++++++++++++++++ arch/arm64/kernel/entry.S | 9 ++++---- 4 files changed, 50 insertions(+), 6 deletions(-)
--- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -34,7 +34,8 @@ #define ARM64_HAS_32BIT_EL0 13 #define ARM64_HYP_OFFSET_LOW 14 #define ARM64_MISMATCHED_CACHE_LINE_SIZE 15 +#define ARM64_UNMAP_KERNEL_AT_EL0 16
-#define ARM64_NCAPS 16 +#define ARM64_NCAPS 17
#endif /* __ASM_CPUCAPS_H */ --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -34,7 +34,8 @@ typedef struct {
static inline bool arm64_kernel_unmapped_at_el0(void) { - return IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0); + return IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0) && + cpus_have_cap(ARM64_UNMAP_KERNEL_AT_EL0); }
extern void paging_init(void); --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -746,6 +746,40 @@ static bool hyp_offset_low(const struct return idmap_addr > GENMASK(VA_BITS - 2, 0) && !is_kernel_in_hyp_mode(); }
+#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 +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, + int __unused) +{ + /* Forced on command line? */ + if (__kpti_forced) { + pr_info_once("kernel page table isolation forced %s by command line option\n", + __kpti_forced > 0 ? "ON" : "OFF"); + return __kpti_forced > 0; + } + + /* Useful for KASLR robustness */ + if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) + return true; + + return false; +} + +static int __init parse_kpti(char *str) +{ + bool enabled; + int ret = strtobool(str, &enabled); + + if (ret) + return ret; + + __kpti_forced = enabled ? 1 : -1; + return 0; +} +__setup("kpti=", parse_kpti); +#endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */ + static const struct arm64_cpu_capabilities arm64_features[] = { { .desc = "GIC system register CPU interface", @@ -829,6 +863,13 @@ static const struct arm64_cpu_capabiliti .def_scope = SCOPE_SYSTEM, .matches = hyp_offset_low, }, +#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 + { + .capability = ARM64_UNMAP_KERNEL_AT_EL0, + .def_scope = SCOPE_SYSTEM, + .matches = unmap_kernel_at_el0, + }, +#endif {}, };
--- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -73,6 +73,7 @@ .macro kernel_ventry, el, label, regsize = 64 .align 7 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 +alternative_if ARM64_UNMAP_KERNEL_AT_EL0 .if \el == 0 .if \regsize == 64 mrs x30, tpidrro_el0 @@ -81,6 +82,7 @@ mov x30, xzr .endif .endif +alternative_else_nop_endif #endif
sub sp, sp, #S_FRAME_SIZE @@ -208,10 +210,9 @@ alternative_else_nop_endif ldr lr, [sp, #S_LR] add sp, sp, #S_FRAME_SIZE // restore sp
-#ifndef CONFIG_UNMAP_KERNEL_AT_EL0 - eret -#else .if \el == 0 +alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0 +#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 bne 4f msr far_el1, x30 tramp_alias x30, tramp_exit_native @@ -219,10 +220,10 @@ alternative_else_nop_endif 4: tramp_alias x30, tramp_exit_compat br x30 +#endif .else eret .endif -#endif .endm
.macro get_thread_info, rd
Patches currently in stable-queue which might be from mark.rutland@arm.com are
queue-4.9/arm64-mm-add-arm64_kernel_unmapped_at_el0-helper.patch queue-4.9/arm64-entry-reword-comment-about-post_ttbr_update_workaround.patch queue-4.9/arm64-kaslr-put-kernel-vectors-address-in-separate-data-page.patch queue-4.9/arm64-turn-on-kpti-only-on-cpus-that-need-it.patch queue-4.9/arm64-force-kpti-to-be-disabled-on-cavium-thunderx.patch queue-4.9/arm64-mm-allocate-asids-in-pairs.patch queue-4.9/arm64-tls-avoid-unconditional-zeroing-of-tpidrro_el0-for-native-tasks.patch queue-4.9/arm64-use-ret-instruction-for-exiting-the-trampoline.patch queue-4.9/arm64-entry-explicitly-pass-exception-level-to-kernel_ventry-macro.patch queue-4.9/arm64-kpti-make-use-of-ng-dependent-on-arm64_kernel_unmapped_at_el0.patch queue-4.9/arm64-mm-use-non-global-mappings-for-kernel-space.patch queue-4.9/arm64-capabilities-handle-duplicate-entries-for-a-capability.patch queue-4.9/arm64-entry-hook-up-entry-trampoline-to-exception-vectors.patch queue-4.9/arm64-mm-invalidate-both-kernel-and-user-asids-when-performing-tlbi.patch queue-4.9/arm64-mm-map-entry-trampoline-into-trampoline-and-kernel-page-tables.patch queue-4.9/module-extend-rodata-off-boot-cmdline-parameter-to-module-mappings.patch queue-4.9/arm64-kconfig-reword-unmap_kernel_at_el0-kconfig-entry.patch queue-4.9/arm64-mm-move-asid-from-ttbr0-to-ttbr1.patch queue-4.9/arm64-allow-checking-of-a-cpu-local-erratum.patch queue-4.9/arm64-take-into-account-id_aa64pfr0_el1.csv3.patch queue-4.9/arm64-kconfig-add-config_unmap_kernel_at_el0.patch queue-4.9/arm64-idmap-use-awx-flags-for-.idmap.text-.pushsection-directives.patch queue-4.9/arm64-factor-out-entry-stack-manipulation.patch queue-4.9/arm64-entry-add-exception-trampoline-page-for-exceptions-from-el0.patch queue-4.9/arm64-kpti-add-enable-callback-to-remap-swapper-using-ng-mappings.patch queue-4.9/arm64-entry-add-fake-cpu-feature-for-unmapping-the-kernel-at-el0.patch queue-4.9/arm64-cputype-add-midr-values-for-cavium-thunderx2-cpus.patch