All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@kernel.org>
To: linux-kernel@vger.kernel.org
Cc: Dave Hansen <dave.hansen@linux.intel.com>,
	Andy Lutomirski <luto@amacapital.net>,
	Thomas Gleixner <tglx@linutronix.de>,
	"H . Peter Anvin" <hpa@zytor.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Borislav Petkov <bp@alien8.de>,
	Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH 23/24] x86/mm/kaiser: Add boot time disable switch
Date: Mon, 27 Nov 2017 11:49:22 +0100	[thread overview]
Message-ID: <20171127104923.14378-24-mingo@kernel.org> (raw)
In-Reply-To: <20171127104923.14378-1-mingo@kernel.org>

From: Thomas Gleixner <tglx@linutronix.de>

Kaiser comes with overhead. The most expensive part is the CR3 switching in
the entry code.

Add a command line parameter which allows to disable Kaiser at boot time.

Most code paths simply check a variable, but the entry code uses a static
branch. The other code paths cannot use a static branch because they are
used before jump label patching is possible. Not an issue as the code
paths are not so performance sensitive as the entry/exit code.

This makes Kaiser depend on JUMP_LABEL and on a GCC which supports
it, but that's a resonable requirement.

The PGD allocation is still 8k when CONFIG_KAISER is enabled. This can be
addressed on top of this.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rik van Riel <riel@redhat.com>
Cc: daniel.gruss@iaik.tugraz.at
Cc: hughd@google.com
Cc: keescook@google.com
Cc: linux-mm@kvack.org
Cc: michael.schwarz@iaik.tugraz.at
Cc: moritz.lipp@iaik.tugraz.at
Cc: richard.fellner@student.tugraz.at
Link: http://lkml.kernel.org/r/20171126232414.645128754@linutronix.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/entry/calling.h          |  7 +++++++
 arch/x86/include/asm/kaiser.h     | 10 ++++++++++
 arch/x86/include/asm/pgtable_64.h |  6 ++++++
 arch/x86/mm/dump_pagetables.c     |  5 ++++-
 arch/x86/mm/init.c                |  7 ++++---
 arch/x86/mm/kaiser.c              | 30 ++++++++++++++++++++++++++++++
 security/Kconfig                  |  2 +-
 7 files changed, 62 insertions(+), 5 deletions(-)

diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index 66af80514197..07fa7fdd7b68 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -210,18 +210,23 @@ For 32-bit we have the following conventions - kernel is built with
 .endm
 
 .macro SWITCH_TO_KERNEL_CR3 scratch_reg:req
+	STATIC_JUMP_IF_FALSE .Lend_\@, kaiser_enabled_key, def=1
 	mov	%cr3, \scratch_reg
 	ADJUST_KERNEL_CR3 \scratch_reg
 	mov	\scratch_reg, %cr3
+.Lend_\@:
 .endm
 
 .macro SWITCH_TO_USER_CR3 scratch_reg:req
+	STATIC_JUMP_IF_FALSE .Lend_\@, kaiser_enabled_key, def=1
 	mov	%cr3, \scratch_reg
 	ADJUST_USER_CR3 \scratch_reg
 	mov	\scratch_reg, %cr3
+.Lend_\@:
 .endm
 
 .macro SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg:req save_reg:req
+	STATIC_JUMP_IF_FALSE .Ldone_\@, kaiser_enabled_key, def=1
 	movq	%cr3, %r\scratch_reg
 	movq	%r\scratch_reg, \save_reg
 	/*
@@ -244,11 +249,13 @@ For 32-bit we have the following conventions - kernel is built with
 .endm
 
 .macro RESTORE_CR3 save_reg:req
+	STATIC_JUMP_IF_FALSE .Lend_\@, kaiser_enabled_key, def=1
 	/*
 	 * The CR3 write could be avoided when not changing its value,
 	 * but would require a CR3 read *and* a scratch register.
 	 */
 	movq	\save_reg, %cr3
+.Lend_\@:
 .endm
 
 #else /* CONFIG_KAISER=n: */
diff --git a/arch/x86/include/asm/kaiser.h b/arch/x86/include/asm/kaiser.h
index 040cb096d29d..7c636cd25d65 100644
--- a/arch/x86/include/asm/kaiser.h
+++ b/arch/x86/include/asm/kaiser.h
@@ -56,6 +56,16 @@ extern void kaiser_remove_mapping(unsigned long start, unsigned long size);
  */
 extern void kaiser_init(void);
 
+/* True if kaiser is enabled at boot time */
+extern struct static_key_true kaiser_enabled_key;
+extern bool kaiser_enabled;
+extern void kaiser_check_cmdline(void);
+
+#else /* CONFIG_KAISER */
+
+#define kaiser_enabled		(false)
+static inline void kaiser_check_cmdline(void) { }
+
 #endif
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index 1c9f1f803ad8..8d725fcb921b 100644
--- a/arch/x86/include/asm/pgtable_64.h
+++ b/arch/x86/include/asm/pgtable_64.h
@@ -175,6 +175,9 @@ static inline p4d_t *shadow_to_kernel_p4dp(p4d_t *p4dp)
 {
 	return ptr_clear_bit(p4dp, KAISER_PGTABLE_SWITCH_BIT);
 }
+
+extern bool kaiser_enabled;
+
 #endif /* CONFIG_KAISER */
 
 /*
@@ -208,6 +211,9 @@ static inline bool pgd_userspace_access(pgd_t pgd)
 static inline pgd_t kaiser_set_shadow_pgd(pgd_t *pgdp, pgd_t pgd)
 {
 #ifdef CONFIG_KAISER
+	if (!kaiser_enabled)
+		return pgd;
+
 	if (pgd_userspace_access(pgd)) {
 		if (pgdp_maps_userspace(pgdp)) {
 			/*
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index 6560b932dd02..65bf3a902400 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -20,6 +20,7 @@
 #include <linux/seq_file.h>
 
 #include <asm/pgtable.h>
+#include <asm/kaiser.h>
 
 /*
  * The dumper groups pagetable entries of the same type into one, and for
@@ -503,7 +504,7 @@ void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 
 void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd, bool shadow)
 {
-	if (shadow)
+	if (shadow && kaiser_enabled)
 		pgd += PTRS_PER_PGD;
 	ptdump_walk_pgd_level_core(m, pgd, false, false);
 }
@@ -514,6 +515,8 @@ void ptdump_walk_shadow_pgd_level_checkwx(void)
 #ifdef CONFIG_KAISER
 	pgd_t *pgd = (pgd_t *) &init_top_pgt;
 
+	if (!kaiser_enabled)
+		return;
 	pr_info("x86/mm: Checking shadow page tables\n");
 	pgd += PTRS_PER_PGD;
 	ptdump_walk_pgd_level_core(NULL, pgd, true, false);
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 7c0126835f22..a3846669fe3a 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -20,6 +20,7 @@
 #include <asm/kaslr.h>
 #include <asm/hypervisor.h>
 #include <asm/cpufeature.h>
+#include <asm/kaiser.h>
 
 /*
  * We need to define the tracepoints somewhere, and tlb.c
@@ -163,9 +164,8 @@ static int page_size_mask;
 
 static void enable_global_pages(void)
 {
-#ifndef CONFIG_KAISER
-	__supported_pte_mask |= _PAGE_GLOBAL;
-#endif
+	if (!kaiser_enabled)
+		__supported_pte_mask |= _PAGE_GLOBAL;
 }
 
 static void __init probe_page_size_mask(void)
@@ -656,6 +656,7 @@ void __init init_mem_mapping(void)
 {
 	unsigned long end;
 
+	kaiser_check_cmdline();
 	probe_page_size_mask();
 	setup_pcid();
 
diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c
index 6e3c5da5f7e8..0282169ede18 100644
--- a/arch/x86/mm/kaiser.c
+++ b/arch/x86/mm/kaiser.c
@@ -34,6 +34,7 @@
 #include <linux/mm.h>
 #include <linux/uaccess.h>
 
+#include <asm/cmdline.h>
 #include <asm/kaiser.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -44,6 +45,16 @@
 
 static pteval_t kaiser_pte_mask __ro_after_init = ~(_PAGE_NX | _PAGE_GLOBAL);
 
+/* Global flag for boot time kaiser enable/disable */
+bool kaiser_enabled __ro_after_init = true;
+DEFINE_STATIC_KEY_TRUE(kaiser_enabled_key);
+
+void __init kaiser_check_cmdline(void)
+{
+	if (cmdline_find_option_bool(boot_command_line, "nokaiser"))
+		kaiser_enabled = false;
+}
+
 /*
  * At runtime, the only things we map are some things for CPU
  * hotplug, and stacks for new processes.  No two CPUs will ever
@@ -252,6 +263,9 @@ int kaiser_add_user_map(const void *__start_addr, unsigned long size,
 	unsigned long target_address;
 	pte_t *pte;
 
+	if (!kaiser_enabled)
+		return 0;
+
 	/* Clear not supported bits */
 	flags &= kaiser_pte_mask;
 
@@ -402,6 +416,9 @@ void __init kaiser_init(void)
 {
 	int cpu;
 
+	if (!kaiser_enabled)
+		return;
+
 	kaiser_init_all_pgds();
 
 	for_each_possible_cpu(cpu) {
@@ -436,6 +453,16 @@ void __init kaiser_init(void)
 	kaiser_add_mapping_cpu_entry(0);
 }
 
+static int __init kaiser_boottime_control(void)
+{
+	if (!kaiser_enabled) {
+		static_branch_disable(&kaiser_enabled_key);
+		pr_info("kaiser: Disabled on command line\n");
+	}
+	return 0;
+}
+subsys_initcall(kaiser_boottime_control);
+
 int kaiser_add_mapping(unsigned long addr, unsigned long size,
 		       unsigned long flags)
 {
@@ -446,6 +473,9 @@ void kaiser_remove_mapping(unsigned long start, unsigned long size)
 {
 	unsigned long addr;
 
+	if (!kaiser_enabled)
+		return;
+
 	/* The shadow page tables always use small pages: */
 	for (addr = start; addr < start + size; addr += PAGE_SIZE) {
 		/*
diff --git a/security/Kconfig b/security/Kconfig
index 99b530d0dd9e..75bb023d49b7 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -56,7 +56,7 @@ config SECURITY_NETWORK
 
 config KAISER
 	bool "Remove the kernel mapping in user mode"
-	depends on X86_64 && SMP && !PARAVIRT
+	depends on X86_64 && SMP && !PARAVIRT && JUMP_LABEL
 	help
 	  This feature reduces the number of hardware side channels by
 	  ensuring that the majority of kernel addresses are not mapped
-- 
2.14.1

  parent reply	other threads:[~2017-11-27 10:52 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
2017-11-27 10:49 ` [PATCH 01/24] x86/mm/kaiser: Disable global pages by default with KAISER Ingo Molnar
2017-11-27 10:49 ` [PATCH 02/24] x86/mm/kaiser: Prepare the x86/entry assembly code for entry/exit CR3 switching Ingo Molnar
2017-11-27 17:31   ` Peter Zijlstra
2017-11-27 17:33     ` Thomas Gleixner
2017-11-27 21:00       ` Peter Zijlstra
2017-11-27 10:49 ` [PATCH 03/24] x86/mm/kaiser: Introduce user-mapped per-CPU areas Ingo Molnar
2017-11-27 10:49 ` [PATCH 04/24] x86/mm/kaiser: Unmap kernel mappings from userspace page tables, core patch Ingo Molnar
2017-11-27 15:39   ` Peter Zijlstra
2017-11-27 17:04     ` Borislav Petkov
2017-11-27 19:17     ` Dave Hansen
2017-11-28 10:34   ` Peter Zijlstra
2017-11-27 10:49 ` [PATCH 05/24] x86/mm/kaiser: Allow NX poison to be set in p4d/pgd Ingo Molnar
2017-11-27 10:49 ` [PATCH 06/24] x86/mm/kaiser: Make sure the static PGDs are 8k in size Ingo Molnar
2017-11-27 10:49 ` [PATCH 07/24] x86/mm/kaiser: Map the CPU entry area Ingo Molnar
2017-11-27 10:49 ` [PATCH 08/24] x86/mm/kaiser: Map the dynamically-allocated LDTs Ingo Molnar
2017-11-29 22:03   ` [08/24] " Guenter Roeck
2017-11-27 10:49 ` [PATCH 09/24] x86/mm/kaiser: Map the espfix structures Ingo Molnar
2017-11-27 10:49 ` [PATCH 10/24] x86/mm/kaiser: Map the entry stack variables Ingo Molnar
2017-11-27 17:22   ` Peter Zijlstra
2017-11-27 17:32     ` Thomas Gleixner
2017-11-27 21:00       ` Peter Zijlstra
2017-11-27 17:29   ` Peter Zijlstra
2017-11-27 17:32     ` Thomas Gleixner
2017-11-27 10:49 ` [PATCH 11/24] x86/mm/kaiser: Map virtually-addressed performance monitoring buffers Ingo Molnar
2017-11-27 10:49 ` [PATCH 12/24] x86/mm: Move the CR3 construction functions to tlbflush.h Ingo Molnar
2017-11-27 10:49 ` [PATCH 13/24] x86/mm: Remove hard-coded ASID limit checks Ingo Molnar
2017-11-27 10:49 ` [PATCH 14/24] x86/mm: Put MMU-to-h/w ASID translation in one place Ingo Molnar
2017-11-27 10:49 ` [PATCH 15/24] x86/mm: Allow flushing for future ASID switches Ingo Molnar
2017-11-28  5:16   ` Andy Lutomirski
2017-11-28  7:32     ` Dave Hansen
2017-11-28 16:39     ` Peter Zijlstra
2017-11-28 16:48       ` Peter Zijlstra
2017-11-28 18:13       ` Dave Hansen
2017-11-28 19:05         ` Peter Zijlstra
2017-11-28 19:36           ` Peter Zijlstra
2017-11-28 20:34           ` Andy Lutomirski
2017-11-28 20:39             ` Peter Zijlstra
2017-11-28 20:45             ` Peter Zijlstra
2017-11-30 15:40     ` Peter Zijlstra
2017-11-30 15:42       ` Andy Lutomirski
2017-11-30 15:44   ` Peter Zijlstra
2017-11-30 15:51     ` Dave Hansen
2017-11-30 16:18       ` Peter Zijlstra
2017-11-30 18:44         ` Dave Hansen
2017-11-30 18:48           ` Andy Lutomirski
2017-11-30 18:53             ` Dave Hansen
2017-11-30 20:01             ` Peter Zijlstra
2017-11-30 21:51               ` Andy Lutomirski
2017-11-30 18:55           ` Peter Zijlstra
2017-11-30 19:00             ` Dave Hansen
2017-11-30 19:20               ` Peter Zijlstra
2017-11-27 10:49 ` [PATCH 16/24] x86/mm/kaiser: Use PCID feature to make user and kernel switches faster Ingo Molnar
2017-11-28  5:22   ` Andy Lutomirski
2017-11-28  7:52     ` Dave Hansen
2017-11-27 10:49 ` [PATCH 17/24] x86/mm/kaiser: Disable native VSYSCALL Ingo Molnar
2017-11-27 10:49 ` [PATCH 18/24] x86/mm/kaiser: Add Kconfig Ingo Molnar
2017-11-27 10:49 ` [PATCH 19/24] x86/mm/kaiser: Respect disabled CPU features Ingo Molnar
2017-11-27 10:49 ` [PATCH 20/24] x86/mm/kaiser: Simplify disabling of global pages Ingo Molnar
2017-11-27 10:49 ` [PATCH 21/24] x86/mm/dump_pagetables: Check Kaiser shadow page table for WX pages Ingo Molnar
2017-11-27 10:49 ` [PATCH 22/24] x86/mm/debug_pagetables: Allow dumping current pagetables Ingo Molnar
2017-11-27 10:49 ` Ingo Molnar [this message]
2017-11-27 10:49 ` [PATCH 24/24] x86/mm/kaiser: Use the other page_table_lock pattern Ingo Molnar
2017-11-27 13:51 ` [PATCH 00/24] x86/mm: Add KAISER support Borislav Petkov
2017-11-27 13:57   ` Thomas Gleixner
2017-11-27 13:59     ` Borislav Petkov
2017-11-27 14:03       ` Ingo Molnar
2017-11-27 14:08         ` Ingo Molnar
2017-11-27 19:43 ` Linus Torvalds
2017-11-27 20:01   ` Linus Torvalds

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171127104923.14378-24-mingo@kernel.org \
    --to=mingo@kernel.org \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.