| From: Borislav Petkov <bp@suse.de> |
| Date: Tue, 2 Jan 2018 14:19:48 +0100 |
| Subject: x86/kaiser: Check boottime cmdline params |
| |
| AMD (and possibly other vendors) are not affected by the leak |
| KAISER is protecting against. |
| |
| Keep the "nopti" for traditional reasons and add pti=<on|off|auto> |
| like upstream. |
| |
| Signed-off-by: Borislav Petkov <bp@suse.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| Documentation/kernel-parameters.txt | 6 ++++ |
| arch/x86/mm/kaiser.c | 56 +++++++++++++++++++++++++------------ |
| 2 files changed, 44 insertions(+), 18 deletions(-) |
| |
| diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt |
| index 56b678603531..ccaf4be39d17 100644 |
| --- a/Documentation/kernel-parameters.txt |
| +++ b/Documentation/kernel-parameters.txt |
| @@ -2245,6 +2245,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. |
| pt. [PARIDE] |
| See Documentation/blockdev/paride.txt. |
| |
| + pti= [X86_64] |
| + Control KAISER user/kernel address space isolation: |
| + on - enable |
| + off - disable |
| + auto - default setting |
| + |
| pty.legacy_count= |
| [KNL] Number of legacy pty's. Overwrites compiled-in |
| default number. |
| diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c |
| index 5d0be21c32a6..9684ebb5a902 100644 |
| --- a/arch/x86/mm/kaiser.c |
| +++ b/arch/x86/mm/kaiser.c |
| @@ -20,6 +20,7 @@ extern struct mm_struct init_mm; |
| #include <asm/pgtable.h> |
| #include <asm/pgalloc.h> |
| #include <asm/desc.h> |
| +#include <asm/cmdline.h> |
| |
| int kaiser_enabled __read_mostly = 1; |
| EXPORT_SYMBOL(kaiser_enabled); /* for inlined TLB flush functions */ |
| @@ -264,6 +265,43 @@ static void __init kaiser_init_all_pgds(void) |
| WARN_ON(__ret); \ |
| } while (0) |
| |
| +void __init kaiser_check_boottime_disable(void) |
| +{ |
| + bool enable = true; |
| + char arg[5]; |
| + int ret; |
| + |
| + ret = cmdline_find_option(boot_command_line, "pti", arg, sizeof(arg)); |
| + if (ret > 0) { |
| + if (!strncmp(arg, "on", 2)) |
| + goto enable; |
| + |
| + if (!strncmp(arg, "off", 3)) |
| + goto disable; |
| + |
| + if (!strncmp(arg, "auto", 4)) |
| + goto skip; |
| + } |
| + |
| + if (cmdline_find_option_bool(boot_command_line, "nopti")) |
| + goto disable; |
| + |
| +skip: |
| + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) |
| + goto disable; |
| + |
| +enable: |
| + if (enable) |
| + setup_force_cpu_cap(X86_FEATURE_KAISER); |
| + |
| + return; |
| + |
| +disable: |
| + pr_info("Kernel/User page tables isolation: disabled\n"); |
| + kaiser_enabled = 0; |
| + setup_clear_cpu_cap(X86_FEATURE_KAISER); |
| +} |
| + |
| /* |
| * If anything in here fails, we will likely die on one of the |
| * first kernel->user transitions and init will die. But, we |
| @@ -275,12 +310,10 @@ void __init kaiser_init(void) |
| { |
| int cpu; |
| |
| - if (!kaiser_enabled) { |
| - setup_clear_cpu_cap(X86_FEATURE_KAISER); |
| - return; |
| - } |
| + kaiser_check_boottime_disable(); |
| |
| - setup_force_cpu_cap(X86_FEATURE_KAISER); |
| + if (!kaiser_enabled) |
| + return; |
| |
| kaiser_init_all_pgds(); |
| |
| @@ -413,16 +446,3 @@ void kaiser_flush_tlb_on_return_to_user(void) |
| X86_CR3_PCID_USER_FLUSH | KAISER_SHADOW_PGD_OFFSET); |
| } |
| EXPORT_SYMBOL(kaiser_flush_tlb_on_return_to_user); |
| - |
| -static int __init x86_nokaiser_setup(char *s) |
| -{ |
| - /* nopti doesn't accept parameters */ |
| - if (s) |
| - return -EINVAL; |
| - |
| - kaiser_enabled = 0; |
| - pr_info("Kernel/User page tables isolation: disabled\n"); |
| - |
| - return 0; |
| -} |
| -early_param("nopti", x86_nokaiser_setup); |
| |