All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/24] x86/mm: Add KAISER support
@ 2017-11-27 10:48 Ingo Molnar
  2017-11-27 10:49 ` [PATCH 01/24] x86/mm/kaiser: Disable global pages by default with KAISER Ingo Molnar
                   ` (25 more replies)
  0 siblings, 26 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

Sending this out for another round of review.

These are the main KAISER patches, on top of the preparatory series I just sent.
This includes KAISER support plus enhancements on top, all the latest code.

( All review feedback so far is incorporated - if anything is missing please
  let me know. )

Thanks,

     Ingo

=====================>
Dave Hansen (17):
  x86/mm/kaiser: Disable global pages by default with KAISER
  x86/mm/kaiser: Prepare the x86/entry assembly code for entry/exit CR3 switching
  x86/mm/kaiser: Introduce user-mapped per-CPU areas
  x86/mm/kaiser: Unmap kernel mappings from userspace page tables, core patch
  x86/mm/kaiser: Allow NX poison to be set in p4d/pgd
  x86/mm/kaiser: Make sure the static PGDs are 8k in size
  x86/mm/kaiser: Map the CPU entry area
  x86/mm/kaiser: Map the dynamically-allocated LDTs
  x86/mm/kaiser: Map the espfix structures
  x86/mm/kaiser: Map the entry stack variables
  x86/mm: Move the CR3 construction functions to tlbflush.h
  x86/mm: Remove hard-coded ASID limit checks
  x86/mm: Put MMU-to-h/w ASID translation in one place
  x86/mm: Allow flushing for future ASID switches
  x86/mm/kaiser: Use PCID feature to make user and kernel switches faster
  x86/mm/kaiser: Disable native VSYSCALL
  x86/mm/kaiser: Add Kconfig

Hugh Dickins (1):
  x86/mm/kaiser: Map virtually-addressed performance monitoring buffers

Peter Zijlstra (1):
  x86/mm/kaiser: Use the other page_table_lock pattern

Thomas Gleixner (5):
  x86/mm/kaiser: Respect disabled CPU features
  x86/mm/kaiser: Simplify disabling of global pages
  x86/mm/dump_pagetables: Check Kaiser shadow page table for WX pages
  x86/mm/debug_pagetables: Allow dumping current pagetables
  x86/mm/kaiser: Add boot time disable switch

 Documentation/x86/kaiser.txt                | 159 +++++++++
 arch/x86/Kconfig                            |   8 +
 arch/x86/entry/calling.h                    |  84 +++++
 arch/x86/entry/entry_64.S                   |  38 +-
 arch/x86/entry/entry_64_compat.S            |  24 +-
 arch/x86/events/intel/ds.c                  |  49 ++-
 arch/x86/include/asm/cpufeatures.h          |   1 +
 arch/x86/include/asm/kaiser.h               |  73 ++++
 arch/x86/include/asm/mmu_context.h          |  29 +-
 arch/x86/include/asm/pgtable.h              |  20 +-
 arch/x86/include/asm/pgtable_64.h           | 140 ++++++++
 arch/x86/include/asm/pgtable_types.h        |  14 +-
 arch/x86/include/asm/tlbflush.h             | 208 +++++++++--
 arch/x86/include/uapi/asm/processor-flags.h |   3 +-
 arch/x86/kernel/cpu/common.c                |   6 +-
 arch/x86/kernel/espfix_64.c                 |  28 +-
 arch/x86/kernel/head_64.S                   |  30 +-
 arch/x86/kernel/ldt.c                       |  25 +-
 arch/x86/kernel/process_64.c                |   2 +-
 arch/x86/kvm/x86.c                          |   3 +-
 arch/x86/mm/Makefile                        |   1 +
 arch/x86/mm/debug_pagetables.c              |  81 ++++-
 arch/x86/mm/dump_pagetables.c               |  32 +-
 arch/x86/mm/init.c                          |  89 +++--
 arch/x86/mm/kaiser.c                        | 521 ++++++++++++++++++++++++++++
 arch/x86/mm/pageattr.c                      |   2 +-
 arch/x86/mm/pgtable.c                       |  16 +-
 arch/x86/mm/tlb.c                           | 105 +++++-
 include/asm-generic/vmlinux.lds.h           |   7 +
 include/linux/kaiser.h                      |  32 ++
 include/linux/percpu-defs.h                 |  30 ++
 init/main.c                                 |   3 +
 kernel/fork.c                               |   1 +
 security/Kconfig                            |  10 +
 34 files changed, 1744 insertions(+), 130 deletions(-)
 create mode 100644 Documentation/x86/kaiser.txt
 create mode 100644 arch/x86/include/asm/kaiser.h
 create mode 100644 arch/x86/mm/kaiser.c
 create mode 100644 include/linux/kaiser.h

-- 
2.14.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 01/24] x86/mm/kaiser: Disable global pages by default with KAISER
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
@ 2017-11-27 10:49 ` 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
                   ` (24 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

Global pages stay in the TLB across context switches.  Since all contexts
share the same kernel mapping, these mappings are marked as global pages
so kernel entries in the TLB are not flushed out on a context switch.

But, even having these entries in the TLB opens up something that an
attacker can use, such as the double-page-fault attack:

   http://www.ieee-security.org/TC/SP2013/papers/4977a191.pdf

That means that even when KAISER switches page tables on return to user
space the global pages would stay in the TLB cache.

Disable global pages so that kernel TLB entries can be flushed before
returning to user space. This way, all accesses to kernel addresses from
userspace result in a TLB miss independent of the existence of a kernel
mapping.

Replace _PAGE_GLOBAL by __PAGE_KERNEL_GLOBAL and keep _PAGE_GLOBAL
available so that it can still be used for a few selected kernel mappings
which must be visible to userspace, when KAISER is enabled, like the
entry/exit code and data.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Rik van Riel <riel@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
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: https://lkml.kernel.org/r/20171123003441.63DDFC6F@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/pgtable_types.h | 17 ++++++++++++++++-
 arch/x86/mm/pageattr.c               | 16 ++++++++--------
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index 9e9b05fc4860..84fb12404618 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -180,8 +180,23 @@ enum page_cache_mode {
 #define PAGE_READONLY_EXEC	__pgprot(_PAGE_PRESENT | _PAGE_USER |	\
 					 _PAGE_ACCESSED)
 
+/*
+ * Disable global pages for anything using the default
+ * __PAGE_KERNEL* macros.
+ *
+ * PGE will still be enabled and _PAGE_GLOBAL may still be used carefully
+ * for a few selected kernel mappings which must be visible to userspace,
+ * when KAISER is enabled, like the entry/exit code and data.
+ */
+#ifdef CONFIG_KAISER
+#define __PAGE_KERNEL_GLOBAL	0
+#else
+#define __PAGE_KERNEL_GLOBAL	_PAGE_GLOBAL
+#endif
+
 #define __PAGE_KERNEL_EXEC						\
-	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
+	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED |	\
+	 __PAGE_KERNEL_GLOBAL)
 #define __PAGE_KERNEL		(__PAGE_KERNEL_EXEC | _PAGE_NX)
 
 #define __PAGE_KERNEL_RO		(__PAGE_KERNEL & ~_PAGE_RW)
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 3fe68483463c..ffe584fa1f5e 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -585,9 +585,9 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
 	 * for the ancient hardware that doesn't support it.
 	 */
 	if (pgprot_val(req_prot) & _PAGE_PRESENT)
-		pgprot_val(req_prot) |= _PAGE_PSE | _PAGE_GLOBAL;
+		pgprot_val(req_prot) |= _PAGE_PSE | __PAGE_KERNEL_GLOBAL;
 	else
-		pgprot_val(req_prot) &= ~(_PAGE_PSE | _PAGE_GLOBAL);
+		pgprot_val(req_prot) &= ~(_PAGE_PSE | __PAGE_KERNEL_GLOBAL);
 
 	req_prot = canon_pgprot(req_prot);
 
@@ -705,9 +705,9 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
 	 * for the ancient hardware that doesn't support it.
 	 */
 	if (pgprot_val(ref_prot) & _PAGE_PRESENT)
-		pgprot_val(ref_prot) |= _PAGE_GLOBAL;
+		pgprot_val(ref_prot) |= __PAGE_KERNEL_GLOBAL;
 	else
-		pgprot_val(ref_prot) &= ~_PAGE_GLOBAL;
+		pgprot_val(ref_prot) &= ~__PAGE_KERNEL_GLOBAL;
 
 	/*
 	 * Get the target pfn from the original entry:
@@ -938,9 +938,9 @@ static void populate_pte(struct cpa_data *cpa,
 	 * support it.
 	 */
 	if (pgprot_val(pgprot) & _PAGE_PRESENT)
-		pgprot_val(pgprot) |= _PAGE_GLOBAL;
+		pgprot_val(pgprot) |= __PAGE_KERNEL_GLOBAL;
 	else
-		pgprot_val(pgprot) &= ~_PAGE_GLOBAL;
+		pgprot_val(pgprot) &= ~__PAGE_KERNEL_GLOBAL;
 
 	pgprot = canon_pgprot(pgprot);
 
@@ -1242,9 +1242,9 @@ static int __change_page_attr(struct cpa_data *cpa, int primary)
 		 * support it.
 		 */
 		if (pgprot_val(new_prot) & _PAGE_PRESENT)
-			pgprot_val(new_prot) |= _PAGE_GLOBAL;
+			pgprot_val(new_prot) |= __PAGE_KERNEL_GLOBAL;
 		else
-			pgprot_val(new_prot) &= ~_PAGE_GLOBAL;
+			pgprot_val(new_prot) &= ~__PAGE_KERNEL_GLOBAL;
 
 		/*
 		 * We need to keep the pfn from the existing PTE,
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 02/24] x86/mm/kaiser: Prepare the x86/entry assembly code for entry/exit CR3 switching
  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 ` Ingo Molnar
  2017-11-27 17:31   ` Peter Zijlstra
  2017-11-27 10:49 ` [PATCH 03/24] x86/mm/kaiser: Introduce user-mapped per-CPU areas Ingo Molnar
                   ` (23 subsequent siblings)
  25 siblings, 1 reply; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

This is largely code from Andy Lutomirski.  I fixed a few bugs
in it, and added a few SWITCH_TO_* spots.

KAISER needs to switch to a different CR3 value when it enters
the kernel and switch back when it exits.  This essentially
needs to be done before leaving assembly code.

This is extra challenging because the switching context is
tricky: the registers that can be clobbered can vary.  It is also
hard to store things on the stack because there is an established
ABI (ptregs) or the stack is entirely unsafe to use.

This patch establishes a set of macros that allow changing to
the user and kernel CR3 values.

Interactions with SWAPGS: previous versions of the KAISER code
relied on having per-CPU scratch space to save/restore a register
that can be used for the CR3 MOV.  The %GS register is used to
index into our per-CPU space, so SWAPGS *had* to be done before
the CR3 switch.  That scratch space is gone now, but the semantic
that SWAPGS must be done before the CR3 MOV is retained.  This is
good to keep because it is not that hard to do and it allows us
to do things like add per-CPU debugging information to help us
figure out what goes wrong sometimes.

What this does in the NMI code is worth pointing out.  NMIs
can interrupt *any* context and they can also be nested with
NMIs interrupting other NMIs.  The comments below
".Lnmi_from_kernel" explain the format of the stack during this
situation.  Changing the format of this stack is not a fun
exercise: I tried.  Instead of storing the old CR3 value on the
stack, this patch depend on the *regular* register save/restore
mechanism and then uses %r14 to keep CR3 during the NMI.  It is
callee-saved and will not be clobbered by the C NMI handlers that
get called.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003442.2D047A7D@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/entry/calling.h         | 65 ++++++++++++++++++++++++++++++++++++++++
 arch/x86/entry/entry_64.S        | 38 +++++++++++++++++++++--
 arch/x86/entry/entry_64_compat.S | 24 ++++++++++++++-
 3 files changed, 123 insertions(+), 4 deletions(-)

diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index 3fd8bc560fae..e1650da01323 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #include <linux/jump_label.h>
 #include <asm/unwind_hints.h>
+#include <asm/cpufeatures.h>
 
 /*
 
@@ -187,6 +188,70 @@ For 32-bit we have the following conventions - kernel is built with
 #endif
 .endm
 
+#ifdef CONFIG_KAISER
+
+/* KAISER PGDs are 8k.  Flip bit 12 to switch between the two halves: */
+#define KAISER_SWITCH_MASK (1<<PAGE_SHIFT)
+
+.macro ADJUST_KERNEL_CR3 reg:req
+	/* Clear "KAISER bit", point CR3 at kernel pagetables: */
+	andq	$(~KAISER_SWITCH_MASK), \reg
+.endm
+
+.macro ADJUST_USER_CR3 reg:req
+	/* Move CR3 up a page to the user page tables: */
+	orq	$(KAISER_SWITCH_MASK), \reg
+.endm
+
+.macro SWITCH_TO_KERNEL_CR3 scratch_reg:req
+	mov	%cr3, \scratch_reg
+	ADJUST_KERNEL_CR3 \scratch_reg
+	mov	\scratch_reg, %cr3
+.endm
+
+.macro SWITCH_TO_USER_CR3 scratch_reg:req
+	mov	%cr3, \scratch_reg
+	ADJUST_USER_CR3 \scratch_reg
+	mov	\scratch_reg, %cr3
+.endm
+
+.macro SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg:req save_reg:req
+	movq	%cr3, %r\scratch_reg
+	movq	%r\scratch_reg, \save_reg
+	/*
+	 * Is the switch bit zero?  This means the address is
+	 * up in real KAISER patches in a moment.
+	 */
+	testq	$(KAISER_SWITCH_MASK), %r\scratch_reg
+	jz	.Ldone_\@
+
+	ADJUST_KERNEL_CR3 %r\scratch_reg
+	movq	%r\scratch_reg, %cr3
+
+.Ldone_\@:
+.endm
+
+.macro RESTORE_CR3 save_reg:req
+	/*
+	 * 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
+.endm
+
+#else /* CONFIG_KAISER=n: */
+
+.macro SWITCH_TO_KERNEL_CR3 scratch_reg:req
+.endm
+.macro SWITCH_TO_USER_CR3 scratch_reg:req
+.endm
+.macro SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg:req save_reg:req
+.endm
+.macro RESTORE_CR3 save_reg:req
+.endm
+
+#endif
+
 #endif /* CONFIG_X86_64 */
 
 /*
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index caf74a1bb3de..df0152bee8a8 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -168,6 +168,9 @@ ENTRY(entry_SYSCALL_64_trampoline)
 	/* Stash the user RSP. */
 	movq	%rsp, RSP_SCRATCH
 
+	/* Note: using %rsp as a scratch reg. */
+	SWITCH_TO_KERNEL_CR3 scratch_reg=%rsp
+
 	/* Load the top of the task stack into RSP */
 	movq	CPU_ENTRY_AREA_tss + TSS_sp1 + CPU_ENTRY_AREA, %rsp
 
@@ -198,6 +201,14 @@ ENTRY(entry_SYSCALL_64)
 
 	swapgs
 	movq	%rsp, PER_CPU_VAR(rsp_scratch)
+
+	/*
+	 * The kernel CR3 is needed to map the process stack, but we
+	 * need a scratch register to be able to load CR3.  %rsp is
+	 * clobberable right now, so use it as a scratch register.
+	 * %rsp will look crazy here for a couple instructions.
+	 */
+	SWITCH_TO_KERNEL_CR3 scratch_reg=%rsp
 	movq	PER_CPU_VAR(cpu_current_top_of_stack), %rsp
 
 	/* Construct struct pt_regs on stack */
@@ -393,6 +404,7 @@ GLOBAL(entry_SYSCALL_64_after_hwframe)
 	 * We are on the trampoline stack.  All regs except RDI are live.
 	 * We can do future final exit work right here.
 	 */
+	SWITCH_TO_USER_CR3 scratch_reg=%rdi
 
 	popq	%rdi
 	popq	%rsp
@@ -729,6 +741,8 @@ GLOBAL(swapgs_restore_regs_and_return_to_usermode)
 	 * We can do future final exit work right here.
 	 */
 
+	SWITCH_TO_USER_CR3 scratch_reg=%rdi
+
 	/* Restore RDI. */
 	popq	%rdi
 	SWAPGS
@@ -938,6 +952,8 @@ ENTRY(switch_to_thread_stack)
 	UNWIND_HINT_FUNC
 
 	pushq	%rdi
+	/* Need to switch before accessing the thread stack. */
+	SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
 	movq	%rsp, %rdi
 	movq	PER_CPU_VAR(cpu_current_top_of_stack), %rsp
 	UNWIND_HINT sp_offset=16 sp_reg=ORC_REG_DI
@@ -1239,7 +1255,11 @@ ENTRY(paranoid_entry)
 	js	1f				/* negative -> in kernel */
 	SWAPGS
 	xorl	%ebx, %ebx
-1:	ret
+
+1:
+	SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg=ax save_reg=%r14
+
+	ret
 END(paranoid_entry)
 
 /*
@@ -1261,6 +1281,7 @@ ENTRY(paranoid_exit)
 	testl	%ebx, %ebx			/* swapgs needed? */
 	jnz	.Lparanoid_exit_no_swapgs
 	TRACE_IRQS_IRETQ
+	RESTORE_CR3	save_reg=%r14
 	SWAPGS_UNSAFE_STACK
 	jmp	.Lparanoid_exit_restore
 .Lparanoid_exit_no_swapgs:
@@ -1288,6 +1309,8 @@ ENTRY(error_entry)
 	 * from user mode due to an IRET fault.
 	 */
 	SWAPGS
+	/* We have user CR3.  Change to kernel CR3. */
+	SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
 
 .Lerror_entry_from_usermode_after_swapgs:
 	/* Put us onto the real thread stack. */
@@ -1334,6 +1357,7 @@ ENTRY(error_entry)
 	 * .Lgs_change's error handler with kernel gsbase.
 	 */
 	SWAPGS
+	SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
 	jmp .Lerror_entry_done
 
 .Lbstep_iret:
@@ -1343,10 +1367,11 @@ ENTRY(error_entry)
 
 .Lerror_bad_iret:
 	/*
-	 * We came from an IRET to user mode, so we have user gsbase.
-	 * Switch to kernel gsbase:
+	 * We came from an IRET to user mode, so we have user
+	 * gsbase and CR3.  Switch to kernel gsbase and CR3:
 	 */
 	SWAPGS
+	SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
 
 	/*
 	 * Pretend that the exception came from user mode: set up pt_regs
@@ -1378,6 +1403,10 @@ END(error_exit)
 /*
  * Runs on exception stack.  Xen PV does not go through this path at all,
  * so we can use real assembly here.
+ *
+ * Registers:
+ *	%r14: Used to save/restore the CR3 of the interrupted context
+ *	      when KAISER is in use.  Do not clobber.
  */
 ENTRY(nmi)
 	UNWIND_HINT_IRET_REGS
@@ -1441,6 +1470,7 @@ ENTRY(nmi)
 
 	swapgs
 	cld
+	SWITCH_TO_KERNEL_CR3 scratch_reg=%rdx
 	movq	%rsp, %rdx
 	movq	PER_CPU_VAR(cpu_current_top_of_stack), %rsp
 	UNWIND_HINT_IRET_REGS base=%rdx offset=8
@@ -1693,6 +1723,8 @@ ENTRY(nmi)
 	movq	$-1, %rsi
 	call	do_nmi
 
+	RESTORE_CR3 save_reg=%r14
+
 	testl	%ebx, %ebx			/* swapgs needed? */
 	jnz	nmi_restore
 nmi_swapgs:
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
index 95ad40eb7eff..05238b29895e 100644
--- a/arch/x86/entry/entry_64_compat.S
+++ b/arch/x86/entry/entry_64_compat.S
@@ -49,6 +49,10 @@
 ENTRY(entry_SYSENTER_compat)
 	/* Interrupts are off on entry. */
 	SWAPGS
+
+	/* We are about to clobber %rsp anyway, clobbering here is OK */
+	SWITCH_TO_KERNEL_CR3 scratch_reg=%rsp
+
 	movq	PER_CPU_VAR(cpu_current_top_of_stack), %rsp
 
 	/*
@@ -215,6 +219,12 @@ GLOBAL(entry_SYSCALL_compat_after_hwframe)
 	pushq   $0			/* pt_regs->r14 = 0 */
 	pushq   $0			/* pt_regs->r15 = 0 */
 
+	/*
+	 * We just saved %rdi so it is safe to clobber.  It is not
+	 * preserved during the C calls inside TRACE_IRQS_OFF anyway.
+	 */
+	SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
+
 	/*
 	 * User mode is traced as though IRQs are on, and SYSENTER
 	 * turned them off.
@@ -256,10 +266,22 @@ GLOBAL(entry_SYSCALL_compat_after_hwframe)
 	 * when the system call started, which is already known to user
 	 * code.  We zero R8-R10 to avoid info leaks.
          */
+	movq	RSP-ORIG_RAX(%rsp), %rsp
+
+	/*
+	 * The original userspace %rsp (RSP-ORIG_RAX(%rsp)) is stored
+	 * on the process stack which is not mapped to userspace and
+	 * not readable after we SWITCH_TO_USER_CR3.  Delay the CR3
+	 * switch until after after the last reference to the process
+	 * stack.
+	 *
+	 * %r8 is zeroed before the sysret, thus safe to clobber.
+	 */
+	SWITCH_TO_USER_CR3 scratch_reg=%r8
+
 	xorq	%r8, %r8
 	xorq	%r9, %r9
 	xorq	%r10, %r10
-	movq	RSP-ORIG_RAX(%rsp), %rsp
 	swapgs
 	sysretl
 END(entry_SYSCALL_compat)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 03/24] x86/mm/kaiser: Introduce user-mapped per-CPU areas
  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 10:49 ` Ingo Molnar
  2017-11-27 10:49 ` [PATCH 04/24] x86/mm/kaiser: Unmap kernel mappings from userspace page tables, core patch Ingo Molnar
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

These patches are based on work from a team at Graz University of
Technology posted here:

   https://github.com/IAIK/KAISER

The KAISER approach keeps two copies of the page tables: one for running
in the kernel and one for running userspace.  But, there are a few
structures that are needed for switching in and out of the kernel and
a good subset of *those* are per-CPU data.

This patch creates a new kind of per-CPU data that is mapped and
can be used no matter which copy of the page tables is active.
Users of this new section will be forthcoming.

Thanks to Hugh Dickins for cleanups to this code.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003444.196CB6DB@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/asm-generic/vmlinux.lds.h |  7 +++++++
 include/linux/percpu-defs.h       | 30 ++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index bdcd1caae092..e12168936d3f 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -826,7 +826,14 @@
  */
 #define PERCPU_INPUT(cacheline)						\
 	VMLINUX_SYMBOL(__per_cpu_start) = .;				\
+	VMLINUX_SYMBOL(__per_cpu_user_mapped_start) = .;		\
 	*(.data..percpu..first)						\
+	. = ALIGN(cacheline);						\
+	*(.data..percpu..user_mapped)					\
+	*(.data..percpu..user_mapped..shared_aligned)			\
+	. = ALIGN(PAGE_SIZE);						\
+	*(.data..percpu..user_mapped..page_aligned)			\
+	VMLINUX_SYMBOL(__per_cpu_user_mapped_end) = .;			\
 	. = ALIGN(PAGE_SIZE);						\
 	*(.data..percpu..page_aligned)					\
 	. = ALIGN(cacheline);						\
diff --git a/include/linux/percpu-defs.h b/include/linux/percpu-defs.h
index 2d2096ba1cfe..752513674295 100644
--- a/include/linux/percpu-defs.h
+++ b/include/linux/percpu-defs.h
@@ -35,6 +35,12 @@
 
 #endif
 
+#ifdef CONFIG_KAISER
+#define USER_MAPPED_SECTION "..user_mapped"
+#else
+#define USER_MAPPED_SECTION ""
+#endif
+
 /*
  * Base implementations of per-CPU variable declarations and definitions, where
  * the section in which the variable is to be placed is provided by the
@@ -115,6 +121,12 @@
 #define DEFINE_PER_CPU(type, name)					\
 	DEFINE_PER_CPU_SECTION(type, name, "")
 
+#define DECLARE_PER_CPU_USER_MAPPED(type, name)				\
+	DECLARE_PER_CPU_SECTION(type, name, USER_MAPPED_SECTION)
+
+#define DEFINE_PER_CPU_USER_MAPPED(type, name)				\
+	DEFINE_PER_CPU_SECTION(type, name, USER_MAPPED_SECTION)
+
 /*
  * Declaration/definition used for per-CPU variables that must come first in
  * the set of variables.
@@ -144,6 +156,14 @@
 	DEFINE_PER_CPU_SECTION(type, name, PER_CPU_SHARED_ALIGNED_SECTION) \
 	____cacheline_aligned_in_smp
 
+#define DECLARE_PER_CPU_SHARED_ALIGNED_USER_MAPPED(type, name)		\
+	DECLARE_PER_CPU_SECTION(type, name, USER_MAPPED_SECTION PER_CPU_SHARED_ALIGNED_SECTION) \
+	____cacheline_aligned_in_smp
+
+#define DEFINE_PER_CPU_SHARED_ALIGNED_USER_MAPPED(type, name)		\
+	DEFINE_PER_CPU_SECTION(type, name, USER_MAPPED_SECTION PER_CPU_SHARED_ALIGNED_SECTION) \
+	____cacheline_aligned_in_smp
+
 #define DECLARE_PER_CPU_ALIGNED(type, name)				\
 	DECLARE_PER_CPU_SECTION(type, name, PER_CPU_ALIGNED_SECTION)	\
 	____cacheline_aligned
@@ -162,6 +182,16 @@
 #define DEFINE_PER_CPU_PAGE_ALIGNED(type, name)				\
 	DEFINE_PER_CPU_SECTION(type, name, "..page_aligned")		\
 	__aligned(PAGE_SIZE)
+/*
+ * Declaration/definition used for per-CPU variables that must be page aligned and need to be mapped in user mode.
+ */
+#define DECLARE_PER_CPU_PAGE_ALIGNED_USER_MAPPED(type, name)		\
+	DECLARE_PER_CPU_SECTION(type, name, USER_MAPPED_SECTION"..page_aligned") \
+	__aligned(PAGE_SIZE)
+
+#define DEFINE_PER_CPU_PAGE_ALIGNED_USER_MAPPED(type, name)		\
+	DEFINE_PER_CPU_SECTION(type, name, USER_MAPPED_SECTION"..page_aligned") \
+	__aligned(PAGE_SIZE)
 
 /*
  * Declaration/definition used for per-CPU variables that must be read mostly.
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 04/24] x86/mm/kaiser: Unmap kernel mappings from userspace page tables, core patch
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (2 preceding siblings ...)
  2017-11-27 10:49 ` [PATCH 03/24] x86/mm/kaiser: Introduce user-mapped per-CPU areas Ingo Molnar
@ 2017-11-27 10:49 ` Ingo Molnar
  2017-11-27 15:39   ` Peter Zijlstra
  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
                   ` (21 subsequent siblings)
  25 siblings, 2 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

These patches are based on work from a team at the Graz University of
Technology:

   https://github.com/IAIK/KAISER

Signed off by the following gentlemen:

  *   Signed-off-by: Richard Fellner <richard.fellner@student.tugraz.at>
  *   Signed-off-by: Moritz Lipp     <moritz.lipp@iaik.tugraz.at>
  *   Signed-off-by: Daniel Gruss    <daniel.gruss@iaik.tugraz.at>
  *   Signed-off-by: Michael Schwarz <michael.schwarz@iaik.tugraz.at>

This work would not have been possible without their work as a starting point.

To credit the original work we kept the 'KAISER' name, and added the
Signed-off-by tags to the KAISER source code file itself. This patch
also carries their 'Originally-by' tags to show credit. (We could not
keep the original Signed-off-by tags for the patch itself, as it was
changed significantly.)

KAISER is a countermeasure against side channel attacks against kernel
virtual memory.  It leaves the existing page tables largely alone and
refers to them as the "kernel page tables.  It adds a "shadow" PGD for
every process which is intended for use when running userspace.  The
shadow PGD maps all the same user memory as the "kernel" copy, but
only maps a minimal set of kernel memory.

Whenever entering the kernel (syscalls, interrupts, exceptions), the
PGD is switched to the "kernel" copy.  When switching back to user
mode, the shadow PGD is used.

The minimalistic kernel page tables try to map only what is needed to
enter/exit the kernel such as the entry/exit functions themselves and
the interrupt descriptors (IDT).

=== Page Table Poisoning ===

KAISER has two copies of the page tables: one for the kernel and
one for when running in userspace.  There is also a kernel
portion of each of the page tables: the part that *maps* the
kernel.

The kernel portion is relatively static and uses pre-populated
PGDs.  Nobody ever calls set_pgd() on the kernel portion during
normal operation.

The userspace portion of the page tables is updated frequently as
userspace pages are mapped and page table pages are allocated.
These updates of the userspace *portion* of the tables need to be
reflected into both the kernel and user/shadow copies.

The original KAISER patches did this by effectively looking at the
address that is being updated.  If it is <PAGE_OFFSET, it is
considered to be doing an update for the userspace portion of the page
tables and must make an entry in the shadow.

However, this has a wrinkle: there are a few places where low
addresses are used in supervisor (kernel) mode.  When EFI calls
are made, they use what are traditionally user addresses in
supervisor mode and trip over these checks.  The trampoline code
that used for booting secondary CPUs has a similar issue.

Remember, there are two things that KAISER needs performed on a
userspace PGD:

 1. Populate the shadow itself
 2. Poison the kernel PGD so it can not be used by userspace.

Only perform these actions when dealing with a user address *and* the
PGD has _PAGE_USER set.  That way, in-kernel users of low addresses
typically used by userspace are not accidentally poisoned.

Here an (incomplete) list of changes from original KAISER patch:

 * Gobs of coding style cleanups

 * The original patch tried to allocate an order-2 page, then
   8k-align the result.  That's silly since order-2 is already
   guaranteed to be 16k-aligned.  Removed that gunk and just
   allocate an order-1 page.

 * Handle (or at least detect and warn on) allocation failures

 * Use _KERNPG_TABLE, not _PAGE_TABLE when creating mappings for
   the kernel in the shadow (user) page tables.

 * BUG_ON() for !pte_none() case was totally insane: it checked
   the physical address of the 'struct page' against the physical
   address of the page being mapped.

 * Added 5-level page table support

 * Never free KAISER page tables.  We don't have the locking to
   keep them from getting referenced during the freeing process.

 * Use a totally different scheme in the entry code.  The
   original code just fell apart in horrific ways in debug faults,
   NMIs, or when iret faults.  Big thanks to Andy Lutomirski for
   reducing the number of places that needed to be patched.  He
   made the code a ton simpler.

 * Use new entry trampoline instead of mapping process stacks.

Originally-by: Richard Fellner <richard.fellner@student.tugraz.at>
Originally-by: Moritz Lipp <moritz.lipp@iaik.tugraz.at>
Originally-by: Daniel Gruss <daniel.gruss@iaik.tugraz.at>
Originally-by: Michael Schwarz <michael.schwarz@iaik.tugraz.at>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003447.1DB395E3@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 Documentation/x86/kaiser.txt      | 159 ++++++++++++++
 arch/x86/entry/calling.h          |   1 +
 arch/x86/include/asm/kaiser.h     |  57 +++++
 arch/x86/include/asm/pgtable.h    |   5 +
 arch/x86/include/asm/pgtable_64.h | 133 ++++++++++++
 arch/x86/kernel/espfix_64.c       |  18 ++
 arch/x86/kernel/head_64.S         |  14 +-
 arch/x86/mm/Makefile              |   1 +
 arch/x86/mm/kaiser.c              | 444 ++++++++++++++++++++++++++++++++++++++
 arch/x86/mm/pageattr.c            |   2 +-
 arch/x86/mm/pgtable.c             |  16 +-
 include/linux/kaiser.h            |  29 +++
 init/main.c                       |   3 +
 kernel/fork.c                     |   1 +
 14 files changed, 877 insertions(+), 6 deletions(-)

diff --git a/Documentation/x86/kaiser.txt b/Documentation/x86/kaiser.txt
new file mode 100644
index 000000000000..f2df0441f6ea
--- /dev/null
+++ b/Documentation/x86/kaiser.txt
@@ -0,0 +1,159 @@
+Overview
+========
+
+KAISER is a countermeasure against attacks on kernel address
+information.  There are at least three existing, published,
+approaches using the shared user/kernel mapping and hardware features
+to defeat KASLR.  One approach referenced in the paper
+(https://gruss.cc/files/kaiser.pdf) locates the kernel by
+observing differences in page fault timing between
+present-but-inaccessible kernel pages and non-present pages.
+
+When the kernel is entered via syscalls, interrupts or exceptions,
+page tables are switched to the full "kernel" copy.  When the
+system switches back to user mode, the user/shadow copy is used.
+
+The minimalistic kernel portion of the user page tables try to
+map only what is needed to enter/exit the kernel such as the
+entry/exit functions themselves and the interrupt descriptor
+table (IDT).
+
+This helps to ensure that side-channel attacks that leverage the
+paging structures do not function when KAISER is enabled, by setting
+CONFIG_KAISER=y.
+
+Page Table Management
+=====================
+
+When KAISER is enabled, the kernel manages two sets of page
+tables.  The first copy is very similar to what would be present
+for a kernel without KAISER.  It includes a complete mapping of
+userspace that the kernel needs for things like copy_*_user().
+
+The second (shadow) is used when running userspace and mirrors the
+mapping of userspace present in the kernel copy.  It maps only
+the kernel data needed to enter and exit the kernel.
+
+The shadow is populated by the kaiser_add_*() functions.  Only
+kernel data which has been explicitly mapped will appear in the
+shadow copy. These calls are rare at runtime.
+
+For a new userspace mapping, the kernel makes the entries in its
+page tables like normal.  The only difference is when the kernel
+makes entries in the top (PGD) level.  In addition to setting the
+entry in the main kernel PGD, a copy of the entry is made in the
+shadow PGD.
+
+For user space mappings the kernel creates an entry in the kernel
+PGD and the same entry in the shadow PGD, so the underlying page
+table to which the PGD entry points to, is shared down to the PTE
+level.  This leaves a single, shared set of userspace page tables
+to manage.  One PTE to lock, one set of accessed, dirty bits, etc...
+
+Overhead
+========
+
+Protection against side-channel attacks is important.  But,
+this protection comes at a cost:
+
+1. Increased Memory Use
+  a. Each process now needs an order-1 PGD instead of order-0.
+     (Consumes 4k per process).
+  b. The pre-allocated second-level (p4d or pud) kernel page
+     table pages cost ~1MB of additional memory at boot.  This
+     is not totally wasted because some of these pages would
+     have been needed eventually for normal kernel page tables
+     and things in the vmalloc() area like vmemmap[].
+  c. Statically-allocated structures and entry/exit text must
+     be padded out to 4k (or 8k for PGDs) so they can be mapped
+     into the user page tables.  This bloats the kernel image
+     by ~20-30k.
+  d. The shadow page tables eventually grow to map all of used
+     vmalloc() space.  They can have roughly the same memory
+     consumption as the vmalloc() page tables.
+
+2. Runtime Cost
+  a. CR3 manipulation to switch between the page table copies
+     must be done at interrupt, syscall, and exception entry
+     and exit (it can be skipped when the kernel is interrupted,
+     though.)  CR3 modifications are in the order of a hundred
+     cycles, and are required at every entry and exit.
+  b. Task stacks must be mapped/unmapped.  We need to walk
+     and modify the shadow page tables at fork() and exit().
+  c. Global pages are disabled.  This feature of the MMU
+     allows different processes to share TLB entries mapping
+     the kernel.  Losing the feature means potentially more
+     TLB misses after a context switch.
+  d. Process Context IDentifiers (PCID) is a CPU feature that
+     allows us to skip flushing the entire TLB when switching
+     page tables.  This makes switching the page tables (at
+     context switch, or kernel entry/exit) cheaper.  But, on
+     systems with PCID support, the context switch code must flush
+     both the user and kernel entries out of the TLB, with an
+     INVPCID in addition to the CR3 write.  This INVPCID is
+     generally slower than a CR3 write, but still in the order of
+     a hundred cycles.
+  e. The shadow page tables must be populated for each new
+     process.  Even without KAISER, the shared kernel mappings
+     are created by copying top-level (PGD) entries into each
+     new process.  But, with KAISER, there are now *two* kernel
+     mappings: one in the kernel page tables that maps everything
+     and one in the user/shadow page tables mapping the "minimal"
+     kernel.  At fork(), a copy of the portion of the shadow PGD
+     that maps the minimal kernel structures is needed in
+     addition to the normal kernel PGD.
+  f. In addition to the fork()-time copying, there must also
+     be an update to the shadow PGD any time a set_pgd() is done
+     on a PGD used to map userspace.  This ensures that the kernel
+     and user/shadow copies always map the same userspace
+     memory.
+  g. On systems without PCID support, each CR3 write flushes
+     the entire TLB.  That means that each syscall, interrupt
+     or exception flushes the TLB.
+
+Possible Future Work:
+1. We can be more careful about not actually writing to CR3
+   unless its value is actually changed.
+2. Compress the user/shadow-mapped data to be mapped together
+   underneath a single PGD entry.
+3. Re-enable global pages, but use them for mappings in the
+   user/shadow page tables.  This would allow the kernel to
+   take advantage of TLB entries that were established from
+   the user page tables.  This might speed up the entry/exit
+   code or userspace since it will not have to reload all of
+   its TLB entries.  However, its upside is limited by PCID
+   being used.
+4. Allow KAISER to be enabled/disabled at runtime so folks can
+   run a single kernel image.
+
+Debugging:
+
+Bugs in KAISER cause a few different signatures of crashes
+that are worth noting here.
+
+ * Crashes in early boot, especially around CPU bringup.  Bugs
+   in the trampoline code or mappings cause these.
+ * Crashes at the first interrupt.  Caused by bugs in entry_64.S,
+   like screwing up a page table switch.  Also caused by
+   incorrectly mapping the IRQ handler entry code.
+ * Crashes at the first NMI.  The NMI code is separate from main
+   interrupt handlers and can have bugs that do not affect
+   normal interrupts.  Also caused by incorrectly mapping NMI
+   code.  NMIs that interrupt the entry code must be very
+   careful and can be the cause of crashes that show up when
+   running perf.
+ * Kernel crashes at the first exit to userspace.  entry_64.S
+   bugs, or failing to map some of the exit code.
+ * Crashes at the first interrupt that interrupts userspace. The paths
+   in entry_64.S that return to userspace are sometimes separate
+   from the ones that return to the kernel.
+ * Double faults: overflowing the kernel stack because of page
+   faults upon page faults.  Caused by touching non-kaiser-mapped
+   data in the entry code, or forgetting to switch to kernel
+   CR3 before calling into C functions which are not kaiser-mapped.
+ * Failures of the selftests/x86 code.  Usually a bug in one of the
+   more obscure corners of entry_64.S
+ * Userspace segfaults early in boot, sometimes manifesting
+   as mount(8) failing to mount the rootfs.  These have
+   tended to be TLB invalidation issues.  Usually invalidating
+   the wrong PCID, or otherwise missing an invalidation.
diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index e1650da01323..d087c3aa0514 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -2,6 +2,7 @@
 #include <linux/jump_label.h>
 #include <asm/unwind_hints.h>
 #include <asm/cpufeatures.h>
+#include <asm/page_types.h>
 
 /*
 
diff --git a/arch/x86/include/asm/kaiser.h b/arch/x86/include/asm/kaiser.h
new file mode 100644
index 000000000000..3c2cc71b4058
--- /dev/null
+++ b/arch/x86/include/asm/kaiser.h
@@ -0,0 +1,57 @@
+#ifndef _ASM_X86_KAISER_H
+#define _ASM_X86_KAISER_H
+/*
+ * Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * Based on work published here: https://github.com/IAIK/KAISER
+ * Modified by Dave Hansen <dave.hansen@intel.com to actually work.
+ */
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_KAISER
+/**
+ *  kaiser_add_mapping - map a kernel range into the user page tables
+ *  @addr: the start address of the range
+ *  @size: the size of the range
+ *  @flags: The mapping flags of the pages
+ *
+ *  Use this on all data and code that need to be mapped into both
+ *  copies of the page tables.  This includes the code that switches
+ *  to/from userspace and all of the hardware structures that are
+ *  virtually-addressed and needed in userspace like the interrupt
+ *  table.
+ */
+extern int kaiser_add_mapping(unsigned long addr, unsigned long size,
+			      unsigned long flags);
+
+/**
+ *  kaiser_remove_mapping - remove a kernel mapping from the userpage tables
+ *  @addr: the start address of the range
+ *  @size: the size of the range
+ */
+extern void kaiser_remove_mapping(unsigned long start, unsigned long size);
+
+/**
+ *  kaiser_init - Initialize the shadow mapping
+ *
+ *  Most parts of the shadow mapping can be mapped upon boot
+ *  time.  Only per-process things like the thread stacks
+ *  or a new LDT have to be mapped at runtime.  These boot-
+ *  time mappings are permanent and never unmapped.
+ */
+extern void kaiser_init(void);
+
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_X86_KAISER_H */
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index f735c3016325..d3901124143f 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -1106,6 +1106,11 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm,
 static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
 {
        memcpy(dst, src, count * sizeof(pgd_t));
+#ifdef CONFIG_KAISER
+	/* Clone the shadow pgd part as well */
+	memcpy(kernel_to_shadow_pgdp(dst), kernel_to_shadow_pgdp(src),
+	       count * sizeof(pgd_t));
+#endif
 }
 
 #define PTE_SHIFT ilog2(PTRS_PER_PTE)
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index e9f05331e732..0c6e14f1e274 100644
--- a/arch/x86/include/asm/pgtable_64.h
+++ b/arch/x86/include/asm/pgtable_64.h
@@ -131,9 +131,138 @@ static inline pud_t native_pudp_get_and_clear(pud_t *xp)
 #endif
 }
 
+#ifdef CONFIG_KAISER
+/*
+ * All top-level KAISER page tables are order-1 pages (8k-aligned
+ * and 8k in size).  The kernel one is at the beginning 4k and
+ * the user (shadow) one is in the last 4k.  To switch between
+ * them, you just need to flip the 12th bit in their addresses.
+ */
+#define KAISER_PGTABLE_SWITCH_BIT	PAGE_SHIFT
+
+/*
+ * This generates better code than the inline assembly in
+ * __set_bit().
+ */
+static inline void *ptr_set_bit(void *ptr, int bit)
+{
+	unsigned long __ptr = (unsigned long)ptr;
+
+	__ptr |= BIT(bit);
+	return (void *)__ptr;
+}
+static inline void *ptr_clear_bit(void *ptr, int bit)
+{
+	unsigned long __ptr = (unsigned long)ptr;
+
+	__ptr &= ~BIT(bit);
+	return (void *)__ptr;
+}
+
+static inline pgd_t *kernel_to_shadow_pgdp(pgd_t *pgdp)
+{
+	return ptr_set_bit(pgdp, KAISER_PGTABLE_SWITCH_BIT);
+}
+static inline pgd_t *shadow_to_kernel_pgdp(pgd_t *pgdp)
+{
+	return ptr_clear_bit(pgdp, KAISER_PGTABLE_SWITCH_BIT);
+}
+static inline p4d_t *kernel_to_shadow_p4dp(p4d_t *p4dp)
+{
+	return ptr_set_bit(p4dp, KAISER_PGTABLE_SWITCH_BIT);
+}
+static inline p4d_t *shadow_to_kernel_p4dp(p4d_t *p4dp)
+{
+	return ptr_clear_bit(p4dp, KAISER_PGTABLE_SWITCH_BIT);
+}
+#endif /* CONFIG_KAISER */
+
+/*
+ * Page table pages are page-aligned.  The lower half of the top
+ * level is used for userspace and the top half for the kernel.
+ *
+ * Returns true for parts of the PGD that map userspace and
+ * false for the parts that map the kernel.
+ */
+static inline bool pgdp_maps_userspace(void *__ptr)
+{
+	unsigned long ptr = (unsigned long)__ptr;
+
+	return (ptr & ~PAGE_MASK) < (PAGE_SIZE / 2);
+}
+
+/*
+ * Does this PGD allow access from userspace?
+ */
+static inline bool pgd_userspace_access(pgd_t pgd)
+{
+	return pgd.pgd & _PAGE_USER;
+}
+
+/*
+ * Take a PGD location (pgdp) and a pgd value that needs
+ * to be set there.  Populates the shadow and returns
+ * the resulting PGD that must be set in the kernel copy
+ * of the page tables.
+ */
+static inline pgd_t kaiser_set_shadow_pgd(pgd_t *pgdp, pgd_t pgd)
+{
+#ifdef CONFIG_KAISER
+	if (pgd_userspace_access(pgd)) {
+		if (pgdp_maps_userspace(pgdp)) {
+			/*
+			 * The user/shadow page tables get the full
+			 * PGD, accessible from userspace:
+			 */
+			kernel_to_shadow_pgdp(pgdp)->pgd = pgd.pgd;
+			/*
+			 * For the copy of the pgd that the kernel
+			 * uses, make it unusable to userspace.  This
+			 * ensures if we get out to userspace with the
+			 * wrong CR3 value, userspace will crash
+			 * instead of running.
+			 */
+			pgd.pgd |= _PAGE_NX;
+		}
+	} else if (pgd_userspace_access(*pgdp)) {
+		/*
+		 * We are clearing a _PAGE_USER PGD for which we
+		 * presumably populated the shadow.  We must now
+		 * clear the shadow PGD entry.
+		 */
+		if (pgdp_maps_userspace(pgdp)) {
+			kernel_to_shadow_pgdp(pgdp)->pgd = pgd.pgd;
+		} else {
+			/*
+			 * Attempted to clear a _PAGE_USER PGD which
+			 * is in the kernel porttion of the address
+			 * space.  PGDs are pre-populated and we
+			 * never clear them.
+			 */
+			WARN_ON_ONCE(1);
+		}
+	} else {
+		/*
+		 * _PAGE_USER was not set in either the PGD being set
+		 * or cleared.  All kernel PGDs should be
+		 * pre-populated so this should never happen after
+		 * boot.
+		 */
+		WARN_ON_ONCE(system_state == SYSTEM_RUNNING);
+	}
+#endif
+	/* return the copy of the PGD we want the kernel to use: */
+	return pgd;
+}
+
+
 static inline void native_set_p4d(p4d_t *p4dp, p4d_t p4d)
 {
+#if defined(CONFIG_KAISER) && !defined(CONFIG_X86_5LEVEL)
+	p4dp->pgd = kaiser_set_shadow_pgd(&p4dp->pgd, p4d.pgd);
+#else
 	*p4dp = p4d;
+#endif
 }
 
 static inline void native_p4d_clear(p4d_t *p4d)
@@ -147,7 +276,11 @@ static inline void native_p4d_clear(p4d_t *p4d)
 
 static inline void native_set_pgd(pgd_t *pgdp, pgd_t pgd)
 {
+#ifdef CONFIG_KAISER
+	*pgdp = kaiser_set_shadow_pgd(pgdp, pgd);
+#else
 	*pgdp = pgd;
+#endif
 }
 
 static inline void native_pgd_clear(pgd_t *pgd)
diff --git a/arch/x86/kernel/espfix_64.c b/arch/x86/kernel/espfix_64.c
index 7d7715dde901..7b95cb47a3cf 100644
--- a/arch/x86/kernel/espfix_64.c
+++ b/arch/x86/kernel/espfix_64.c
@@ -41,6 +41,7 @@
 #include <asm/pgalloc.h>
 #include <asm/setup.h>
 #include <asm/espfix.h>
+#include <asm/kaiser.h>
 
 /*
  * Note: we only need 6*8 = 48 bytes for the espfix stack, but round
@@ -129,6 +130,23 @@ void __init init_espfix_bsp(void)
 	p4d = p4d_alloc(&init_mm, pgd, ESPFIX_BASE_ADDR);
 	p4d_populate(&init_mm, p4d, espfix_pud_page);
 
+	/*
+	 * Just copy the top-level PGD that is mapping the espfix
+	 * area to ensure it is mapped into the shadow user page
+	 * tables.
+	 *
+	 * For 5-level paging, the espfix pgd was populated when
+	 * kaiser_init() pre-populated all the pgd entries.  The above
+	 * p4d_alloc() would never do anything and the p4d_populate()
+	 * would be done to a p4d already mapped in the userspace pgd.
+	 */
+#ifdef CONFIG_KAISER
+	if (CONFIG_PGTABLE_LEVELS <= 4) {
+		set_pgd(kernel_to_shadow_pgdp(pgd),
+			__pgd(_KERNPG_TABLE | (p4d_pfn(*p4d) << PAGE_SHIFT)));
+	}
+#endif
+
 	/* Randomize the locations */
 	init_espfix_random();
 
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 7dca675fe78d..43d1cffd1fcf 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -341,6 +341,14 @@ GLOBAL(early_recursion_flag)
 	.balign	PAGE_SIZE; \
 GLOBAL(name)
 
+#ifdef CONFIG_KAISER
+#define NEXT_PGD_PAGE(name) \
+	.balign 2 * PAGE_SIZE; \
+GLOBAL(name)
+#else
+#define NEXT_PGD_PAGE(name) NEXT_PAGE(name)
+#endif
+
 /* Automate the creation of 1 to 1 mapping pmd entries */
 #define PMDS(START, PERM, COUNT)			\
 	i = 0 ;						\
@@ -350,7 +358,7 @@ GLOBAL(name)
 	.endr
 
 	__INITDATA
-NEXT_PAGE(early_top_pgt)
+NEXT_PGD_PAGE(early_top_pgt)
 	.fill	511,8,0
 #ifdef CONFIG_X86_5LEVEL
 	.quad	level4_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC
@@ -364,7 +372,7 @@ NEXT_PAGE(early_dynamic_pgts)
 	.data
 
 #if defined(CONFIG_XEN_PV) || defined(CONFIG_XEN_PVH)
-NEXT_PAGE(init_top_pgt)
+NEXT_PGD_PAGE(init_top_pgt)
 	.quad   level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC
 	.org    init_top_pgt + PGD_PAGE_OFFSET*8, 0
 	.quad   level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC
@@ -381,7 +389,7 @@ NEXT_PAGE(level2_ident_pgt)
 	 */
 	PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD)
 #else
-NEXT_PAGE(init_top_pgt)
+NEXT_PGD_PAGE(init_top_pgt)
 	.fill	512,8,0
 #endif
 
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 7ba7f3d7f477..1684e8891165 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_NUMA_EMU)		+= numa_emulation.o
 obj-$(CONFIG_X86_INTEL_MPX)	+= mpx.o
 obj-$(CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS) += pkeys.o
 obj-$(CONFIG_RANDOMIZE_MEMORY) += kaslr.o
+obj-$(CONFIG_KAISER)		+= kaiser.o
 
 obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= mem_encrypt.o
 obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= mem_encrypt_boot.o
diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c
new file mode 100644
index 000000000000..72dc15364390
--- /dev/null
+++ b/arch/x86/mm/kaiser.c
@@ -0,0 +1,444 @@
+/*
+ * Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * This code is based in part on work published here:
+ *
+ *	https://github.com/IAIK/KAISER
+ *
+ * The original work was written by and and signed off by for the Linux
+ * kernel by:
+ *
+ *   Signed-off-by: Richard Fellner <richard.fellner@student.tugraz.at>
+ *   Signed-off-by: Moritz Lipp <moritz.lipp@iaik.tugraz.at>
+ *   Signed-off-by: Daniel Gruss <daniel.gruss@iaik.tugraz.at>
+ *   Signed-off-by: Michael Schwarz <michael.schwarz@iaik.tugraz.at>
+ *
+ * Major changes to the original code by: Dave Hansen <dave.hansen@intel.com>
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/bug.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/uaccess.h>
+
+#include <asm/kaiser.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+#include <asm/desc.h>
+
+#define KAISER_WALK_ATOMIC  0x1
+
+/*
+ * At runtime, the only things we map are some things for CPU
+ * hotplug, and stacks for new processes.  No two CPUs will ever
+ * be populating the same addresses, so we only need to ensure
+ * that we protect between two CPUs trying to allocate and
+ * populate the same page table page.
+ *
+ * Only take this lock when doing a set_p[4um]d(), but it is not
+ * needed for doing a set_pte().  We assume that only the *owner*
+ * of a given allocation will be doing this for _their_
+ * allocation.
+ *
+ * This ensures that once a system has been running for a while
+ * and there have been stacks all over and these page tables
+ * are fully populated, there will be no further acquisitions of
+ * this lock.
+ */
+static DEFINE_SPINLOCK(shadow_table_allocation_lock);
+
+/*
+ * This is only for walking kernel addresses.  We use it to help
+ * recreate the "shadow" page tables which are used while we are in
+ * userspace.
+ *
+ * This can be called on any kernel memory addresses and will work
+ * with any page sizes and any types: normal linear map memory,
+ * vmalloc(), even kmap().
+ *
+ * Note: this is only used when mapping new *kernel* entries into
+ * the user/shadow page tables.  It is never used for userspace
+ * addresses.
+ *
+ * Returns -1 on error.
+ */
+static inline unsigned long get_pa_from_kernel_map(unsigned long vaddr)
+{
+	pgd_t *pgd;
+	p4d_t *p4d;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+
+	/* We should only be asked to walk kernel addresses */
+	if (vaddr < PAGE_OFFSET) {
+		WARN_ON_ONCE(1);
+		return -1;
+	}
+
+	pgd = pgd_offset_k(vaddr);
+	/*
+	 * We made all the kernel PGDs present in kaiser_init().
+	 * We expect them to stay that way.
+	 */
+	if (pgd_none(*pgd)) {
+		WARN_ON_ONCE(1);
+		return -1;
+	}
+	/*
+	 * PGDs are either 512GB or 128TB on all x86_64
+	 * configurations.  We don't handle these.
+	 */
+	BUILD_BUG_ON(pgd_large(*pgd) != 0);
+
+	p4d = p4d_offset(pgd, vaddr);
+	if (p4d_none(*p4d)) {
+		WARN_ON_ONCE(1);
+		return -1;
+	}
+
+	pud = pud_offset(p4d, vaddr);
+	if (pud_none(*pud)) {
+		WARN_ON_ONCE(1);
+		return -1;
+	}
+
+	if (pud_large(*pud))
+		return (pud_pfn(*pud) << PAGE_SHIFT) | (vaddr & ~PUD_PAGE_MASK);
+
+	pmd = pmd_offset(pud, vaddr);
+	if (pmd_none(*pmd)) {
+		WARN_ON_ONCE(1);
+		return -1;
+	}
+
+	if (pmd_large(*pmd))
+		return (pmd_pfn(*pmd) << PAGE_SHIFT) | (vaddr & ~PMD_PAGE_MASK);
+
+	pte = pte_offset_kernel(pmd, vaddr);
+	if (pte_none(*pte)) {
+		WARN_ON_ONCE(1);
+		return -1;
+	}
+
+	return (pte_pfn(*pte) << PAGE_SHIFT) | (vaddr & ~PAGE_MASK);
+}
+
+/*
+ * Walk the shadow copy of the page tables (optionally) trying to
+ * allocate page table pages on the way down.  Does not support
+ * large pages since the data we are mapping is (generally) not
+ * large enough or aligned to 2MB.
+ *
+ * Note: this is only used when mapping *new* kernel data into the
+ * user/shadow page tables.  It is never used for userspace data.
+ *
+ * Returns a pointer to a PTE on success, or NULL on failure.
+ */
+static pte_t *kaiser_shadow_pagetable_walk(unsigned long address,
+					   unsigned long flags)
+{
+	pte_t *pte;
+	pmd_t *pmd;
+	pud_t *pud;
+	p4d_t *p4d;
+	pgd_t *pgd = kernel_to_shadow_pgdp(pgd_offset_k(address));
+	gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO);
+
+	if (flags & KAISER_WALK_ATOMIC) {
+		gfp &= ~GFP_KERNEL;
+		gfp |= __GFP_HIGH | __GFP_ATOMIC;
+	}
+
+	if (address < PAGE_OFFSET) {
+		WARN_ONCE(1, "attempt to walk user address\n");
+		return NULL;
+	}
+
+	if (pgd_none(*pgd)) {
+		WARN_ONCE(1, "All shadow pgds should have been populated\n");
+		return NULL;
+	}
+	BUILD_BUG_ON(pgd_large(*pgd) != 0);
+
+	p4d = p4d_offset(pgd, address);
+	BUILD_BUG_ON(p4d_large(*p4d) != 0);
+	if (p4d_none(*p4d)) {
+		unsigned long new_pud_page = __get_free_page(gfp);
+		if (!new_pud_page)
+			return NULL;
+
+		spin_lock(&shadow_table_allocation_lock);
+		if (p4d_none(*p4d))
+			set_p4d(p4d, __p4d(_KERNPG_TABLE | __pa(new_pud_page)));
+		else
+			free_page(new_pud_page);
+		spin_unlock(&shadow_table_allocation_lock);
+	}
+
+	pud = pud_offset(p4d, address);
+	/* The shadow page tables do not use large mappings: */
+	if (pud_large(*pud)) {
+		WARN_ON(1);
+		return NULL;
+	}
+	if (pud_none(*pud)) {
+		unsigned long new_pmd_page = __get_free_page(gfp);
+		if (!new_pmd_page)
+			return NULL;
+
+		spin_lock(&shadow_table_allocation_lock);
+		if (pud_none(*pud))
+			set_pud(pud, __pud(_KERNPG_TABLE | __pa(new_pmd_page)));
+		else
+			free_page(new_pmd_page);
+		spin_unlock(&shadow_table_allocation_lock);
+	}
+
+	pmd = pmd_offset(pud, address);
+	/* The shadow page tables do not use large mappings: */
+	if (pmd_large(*pmd)) {
+		WARN_ON(1);
+		return NULL;
+	}
+	if (pmd_none(*pmd)) {
+		unsigned long new_pte_page = __get_free_page(gfp);
+		if (!new_pte_page)
+			return NULL;
+
+		spin_lock(&shadow_table_allocation_lock);
+		if (pmd_none(*pmd))
+			set_pmd(pmd, __pmd(_KERNPG_TABLE  | __pa(new_pte_page)));
+		else
+			free_page(new_pte_page);
+		spin_unlock(&shadow_table_allocation_lock);
+	}
+
+	pte = pte_offset_kernel(pmd, address);
+	if (pte_flags(*pte) & _PAGE_USER) {
+		WARN_ONCE(1, "attempt to walk to user pte\n");
+		return NULL;
+	}
+	return pte;
+}
+
+/*
+ * Given a kernel address, @__start_addr, copy that mapping into
+ * the user (shadow) page tables.  This may need to allocate page
+ * table pages.
+ */
+int kaiser_add_user_map(const void *__start_addr, unsigned long size,
+			unsigned long flags)
+{
+	pte_t *pte;
+	unsigned long start_addr = (unsigned long)__start_addr;
+	unsigned long address = start_addr & PAGE_MASK;
+	unsigned long end_addr = PAGE_ALIGN(start_addr + size);
+	unsigned long target_address;
+
+	for (; address < end_addr; address += PAGE_SIZE) {
+		target_address = get_pa_from_kernel_map(address);
+		if (target_address == -1)
+			return -EIO;
+
+		pte = kaiser_shadow_pagetable_walk(address, false);
+		/*
+		 * Errors come from either -ENOMEM for a page
+		 * table page, or something screwy that did a
+		 * WARN_ON().  Just return -ENOMEM.
+		 */
+		if (!pte)
+			return -ENOMEM;
+		if (pte_none(*pte)) {
+			set_pte(pte, __pte(flags | target_address));
+		} else {
+			pte_t tmp;
+			/*
+			 * Make a fake, temporary PTE that mimics the
+			 * one we would have created.
+			 */
+			set_pte(&tmp, __pte(flags | target_address));
+			/*
+			 * Warn if the pte that would have been
+			 * created is different from the one that
+			 * was there previously.  In other words,
+			 * we allow the same PTE value to be set,
+			 * but not changed.
+			 */
+			WARN_ON_ONCE(!pte_same(*pte, tmp));
+		}
+	}
+	return 0;
+}
+
+int kaiser_add_user_map_ptrs(const void *__start_addr,
+			     const void *__end_addr,
+			     unsigned long flags)
+{
+	return kaiser_add_user_map(__start_addr,
+				   __end_addr - __start_addr,
+				   flags);
+}
+
+/*
+ * Ensure that the top level of the (shadow) page tables are
+ * entirely populated.  This ensures that all processes that get
+ * forked have the same entries.  This way, we do not have to
+ * ever go set up new entries in older processes.
+ *
+ * Note: we never free these, so there are no updates to them
+ * after this.
+ */
+static void __init kaiser_init_all_pgds(void)
+{
+	pgd_t *pgd;
+	int i;
+
+	pgd = kernel_to_shadow_pgdp(pgd_offset_k(0UL));
+	for (i = PTRS_PER_PGD / 2; i < PTRS_PER_PGD; i++) {
+		/*
+		 * Each PGD entry moves up PGDIR_SIZE bytes through
+		 * the address space, so get the first virtual
+		 * address mapped by PGD #i:
+		 */
+		unsigned long addr = i * PGDIR_SIZE;
+#if CONFIG_PGTABLE_LEVELS > 4
+		p4d_t *p4d = p4d_alloc_one(&init_mm, addr);
+		if (!p4d) {
+			WARN_ON(1);
+			break;
+		}
+		set_pgd(pgd + i, __pgd(_KERNPG_TABLE | __pa(p4d)));
+#else /* CONFIG_PGTABLE_LEVELS <= 4 */
+		pud_t *pud = pud_alloc_one(&init_mm, addr);
+		if (!pud) {
+			WARN_ON(1);
+			break;
+		}
+		set_pgd(pgd + i, __pgd(_KERNPG_TABLE | __pa(pud)));
+#endif /* CONFIG_PGTABLE_LEVELS */
+	}
+}
+
+/*
+ * Page table allocations called by kaiser_add_user_map() can
+ * theoretically fail, but are very unlikely to fail in early boot.
+ * This would at least output a warning before crashing.
+ *
+ * Do the checking and warning in a macro to make it more readable and
+ * preserve line numbers in the warning message that you would not get
+ * with an inline.
+ */
+#define kaiser_add_user_map_early(start, size, flags) do {	\
+	int __ret = kaiser_add_user_map(start, size, flags);	\
+	WARN_ON(__ret);						\
+} while (0)
+
+#define kaiser_add_user_map_ptrs_early(start, end, flags) do {		\
+	int __ret = kaiser_add_user_map_ptrs(start, end, flags);	\
+	WARN_ON(__ret);							\
+} while (0)
+
+extern char __per_cpu_user_mapped_start[], __per_cpu_user_mapped_end[];
+/*
+ * If anything in here fails, we will likely die on one of the
+ * first kernel->user transitions and init will die.  But, we
+ * will have most of the kernel up by then and should be able to
+ * get a clean warning out of it.  If we BUG_ON() here, we run
+ * the risk of being before we have good console output.
+ *
+ * When KAISER is enabled, we remove _PAGE_GLOBAL from all of the
+ * kernel PTE permissions.  This ensures that the TLB entries for
+ * the kernel are not available when in userspace.  However, for
+ * the pages that are available to userspace *anyway*, we might as
+ * well continue to map them _PAGE_GLOBAL and enjoy the potential
+ * performance advantages.
+ */
+void __init kaiser_init(void)
+{
+	int cpu;
+
+	kaiser_init_all_pgds();
+
+	for_each_possible_cpu(cpu) {
+		void *percpu_vaddr = __per_cpu_user_mapped_start +
+				     per_cpu_offset(cpu);
+		unsigned long percpu_sz = __per_cpu_user_mapped_end -
+					  __per_cpu_user_mapped_start;
+		kaiser_add_user_map_early(percpu_vaddr, percpu_sz,
+					  __PAGE_KERNEL | _PAGE_GLOBAL);
+	}
+
+	kaiser_add_user_map_ptrs_early(__entry_text_start, __entry_text_end,
+				       __PAGE_KERNEL_RX | _PAGE_GLOBAL);
+
+	kaiser_add_user_map_ptrs_early(__irqentry_text_start, __irqentry_text_end,
+				       __PAGE_KERNEL_RX | _PAGE_GLOBAL);
+
+	/* the fixed map address of the idt_table */
+	kaiser_add_user_map_early((void *)idt_descr.address,
+				  sizeof(gate_desc) * NR_VECTORS,
+				  __PAGE_KERNEL_RO | _PAGE_GLOBAL);
+}
+
+int kaiser_add_mapping(unsigned long addr, unsigned long size,
+		       unsigned long flags)
+{
+	return kaiser_add_user_map((const void *)addr, size, flags);
+}
+
+void kaiser_remove_mapping(unsigned long start, unsigned long size)
+{
+	unsigned long addr;
+
+	/* The shadow page tables always use small pages: */
+	for (addr = start; addr < start + size; addr += PAGE_SIZE) {
+		/*
+		 * Do an "atomic" walk in case this got called from an atomic
+		 * context.  This should not do any allocations because we
+		 * should only be walking things that are known to be mapped.
+		 */
+		pte_t *pte = kaiser_shadow_pagetable_walk(addr, KAISER_WALK_ATOMIC);
+
+		/*
+		 * We are removing a mapping that should
+		 * exist.  WARN if it was not there:
+		 */
+		if (!pte) {
+			WARN_ON_ONCE(1);
+			continue;
+		}
+
+		pte_clear(&init_mm, addr, pte);
+	}
+	/*
+	 * This ensures that the TLB entries used to map this data are
+	 * no longer usable on *this* CPU.  We theoretically want to
+	 * flush the entries on all CPUs here, but that's too
+	 * expensive right now: this is called to unmap process
+	 * stacks in the exit() path.
+	 *
+	 * This can change if we get to the point where this is not
+	 * in a remotely hot path, like only called via write_ldt().
+	 *
+	 * Note: we could probably also just invalidate the individual
+	 * addresses to take care of *this* PCID and then do a
+	 * tlb_flush_shared_nonglobals() to ensure that all other
+	 * PCIDs get flushed before being used again.
+	 */
+	__native_flush_tlb_global();
+}
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index ffe584fa1f5e..1b3dbf3b3846 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -859,7 +859,7 @@ static void unmap_pmd_range(pud_t *pud, unsigned long start, unsigned long end)
 			pud_clear(pud);
 }
 
-static void unmap_pud_range(p4d_t *p4d, unsigned long start, unsigned long end)
+void unmap_pud_range(p4d_t *p4d, unsigned long start, unsigned long end)
 {
 	pud_t *pud = pud_offset(p4d, start);
 
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 17ebc5a978cc..1e47ce734404 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -355,14 +355,26 @@ static inline void _pgd_free(pgd_t *pgd)
 		kmem_cache_free(pgd_cache, pgd);
 }
 #else
+
+#ifdef CONFIG_KAISER
+/*
+ * Instead of one pgd, we aquire two pgds.  Being order-1, it is
+ * both 8k in size and 8k-aligned.  That lets us just flip bit 12
+ * in a pointer to swap between the two 4k halves.
+ */
+#define PGD_ALLOCATION_ORDER 1
+#else
+#define PGD_ALLOCATION_ORDER 0
+#endif
+
 static inline pgd_t *_pgd_alloc(void)
 {
-	return (pgd_t *)__get_free_page(PGALLOC_GFP);
+	return (pgd_t *)__get_free_pages(PGALLOC_GFP, PGD_ALLOCATION_ORDER);
 }
 
 static inline void _pgd_free(pgd_t *pgd)
 {
-	free_page((unsigned long)pgd);
+	free_pages((unsigned long)pgd, PGD_ALLOCATION_ORDER);
 }
 #endif /* CONFIG_X86_PAE */
 
diff --git a/include/linux/kaiser.h b/include/linux/kaiser.h
new file mode 100644
index 000000000000..0fd800efa95c
--- /dev/null
+++ b/include/linux/kaiser.h
@@ -0,0 +1,29 @@
+#ifndef _INCLUDE_KAISER_H
+#define _INCLUDE_KAISER_H
+
+#ifdef CONFIG_KAISER
+#include <asm/kaiser.h>
+#else
+
+/*
+ * These stubs are used whenever CONFIG_KAISER is off, which
+ * includes architectures that support KAISER, but have it
+ * disabled.
+ */
+
+static inline void kaiser_init(void)
+{
+}
+
+static inline void kaiser_remove_mapping(unsigned long start, unsigned long size)
+{
+}
+
+static inline int kaiser_add_mapping(unsigned long addr, unsigned long size,
+				     unsigned long flags)
+{
+	return 0;
+}
+
+#endif /* !CONFIG_KAISER */
+#endif /* _INCLUDE_KAISER_H */
diff --git a/init/main.c b/init/main.c
index 3bdd8da90f69..559bc0a6e9ad 100644
--- a/init/main.c
+++ b/init/main.c
@@ -76,6 +76,7 @@
 #include <linux/slab.h>
 #include <linux/perf_event.h>
 #include <linux/ptrace.h>
+#include <linux/kaiser.h>
 #include <linux/blkdev.h>
 #include <linux/elevator.h>
 #include <linux/sched_clock.h>
@@ -505,6 +506,8 @@ static void __init mm_init(void)
 	pgtable_init();
 	vmalloc_init();
 	ioremap_huge_init();
+	/* This just needs to be done before we first run userspace: */
+	kaiser_init();
 }
 
 asmlinkage __visible void __init start_kernel(void)
diff --git a/kernel/fork.c b/kernel/fork.c
index 07cc743698d3..685202058d65 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -70,6 +70,7 @@
 #include <linux/tsacct_kern.h>
 #include <linux/cn_proc.h>
 #include <linux/freezer.h>
+#include <linux/kaiser.h>
 #include <linux/delayacct.h>
 #include <linux/taskstats_kern.h>
 #include <linux/random.h>
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 05/24] x86/mm/kaiser: Allow NX poison to be set in p4d/pgd
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (3 preceding siblings ...)
  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 10:49 ` Ingo Molnar
  2017-11-27 10:49 ` [PATCH 06/24] x86/mm/kaiser: Make sure the static PGDs are 8k in size Ingo Molnar
                   ` (20 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

The user portion of the kernel page tables use the NX bit to
poison them for userspace.  But, that trips the p4d/pgd_bad()
checks.  Make sure it does not do that.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003448.C6AB3575@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/pgtable.h | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index d3901124143f..9cceaf6c0405 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -846,7 +846,12 @@ static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address)
 
 static inline int p4d_bad(p4d_t p4d)
 {
-	return (p4d_flags(p4d) & ~(_KERNPG_TABLE | _PAGE_USER)) != 0;
+	unsigned long ignore_flags = _KERNPG_TABLE | _PAGE_USER;
+
+	if (IS_ENABLED(CONFIG_KAISER))
+		ignore_flags |= _PAGE_NX;
+
+	return (p4d_flags(p4d) & ~ignore_flags) != 0;
 }
 #endif  /* CONFIG_PGTABLE_LEVELS > 3 */
 
@@ -880,7 +885,12 @@ static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address)
 
 static inline int pgd_bad(pgd_t pgd)
 {
-	return (pgd_flags(pgd) & ~_PAGE_USER) != _KERNPG_TABLE;
+	unsigned long ignore_flags = _PAGE_USER;
+
+	if (IS_ENABLED(CONFIG_KAISER))
+		ignore_flags |= _PAGE_NX;
+
+	return (pgd_flags(pgd) & ~ignore_flags) != _KERNPG_TABLE;
 }
 
 static inline int pgd_none(pgd_t pgd)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 06/24] x86/mm/kaiser: Make sure the static PGDs are 8k in size
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (4 preceding siblings ...)
  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 ` Ingo Molnar
  2017-11-27 10:49 ` [PATCH 07/24] x86/mm/kaiser: Map the CPU entry area Ingo Molnar
                   ` (19 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

A few PGDs come out of the kernel binary instead of being
allocated dynamically.  Before this patch, they are all
8k-aligned, but they must also be 8k in *size*.

The original KAISER patch did not do this.  It probably just
lucked out that it did not trample over data after the last PGD.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003450.76492124@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/head_64.S | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 43d1cffd1fcf..58087ab1782e 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -342,11 +342,24 @@ GLOBAL(early_recursion_flag)
 GLOBAL(name)
 
 #ifdef CONFIG_KAISER
+/*
+ * Each PGD needs to be 8k long and 8k aligned.  We do not
+ * ever go out to userspace with these, so we do not
+ * strictly *need* the second page, but this allows us to
+ * have a single set_pgd() implementation that does not
+ * need to worry about whether it has 4k or 8k to work
+ * with.
+ *
+ * This ensures PGDs are 8k long:
+ */
+#define KAISER_USER_PGD_FILL	512
+/* This ensures they are 8k-aligned: */
 #define NEXT_PGD_PAGE(name) \
 	.balign 2 * PAGE_SIZE; \
 GLOBAL(name)
 #else
 #define NEXT_PGD_PAGE(name) NEXT_PAGE(name)
+#define KAISER_USER_PGD_FILL	0
 #endif
 
 /* Automate the creation of 1 to 1 mapping pmd entries */
@@ -365,6 +378,7 @@ NEXT_PGD_PAGE(early_top_pgt)
 #else
 	.quad	level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC
 #endif
+	.fill	KAISER_USER_PGD_FILL,8,0
 
 NEXT_PAGE(early_dynamic_pgts)
 	.fill	512*EARLY_DYNAMIC_PAGE_TABLES,8,0
@@ -379,6 +393,7 @@ NEXT_PGD_PAGE(init_top_pgt)
 	.org    init_top_pgt + PGD_START_KERNEL*8, 0
 	/* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
 	.quad   level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC
+	.fill	KAISER_USER_PGD_FILL,8,0
 
 NEXT_PAGE(level3_ident_pgt)
 	.quad	level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC
@@ -391,6 +406,7 @@ NEXT_PAGE(level2_ident_pgt)
 #else
 NEXT_PGD_PAGE(init_top_pgt)
 	.fill	512,8,0
+	.fill	KAISER_USER_PGD_FILL,8,0
 #endif
 
 #ifdef CONFIG_X86_5LEVEL
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 07/24] x86/mm/kaiser: Map the CPU entry area
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (5 preceding siblings ...)
  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 ` Ingo Molnar
  2017-11-27 10:49 ` [PATCH 08/24] x86/mm/kaiser: Map the dynamically-allocated LDTs Ingo Molnar
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

There is now a special 'struct cpu_entry_area' that contains all
of the data needed to enter the kernel.  It's mapped in the fixmap
area and contains:

 * The GDT (hardware segment descriptor)

 * The TSS (thread information structure that points the hardware
   to the various stacks, and contains the entry stack).

 * The entry trampoline code itself

 * The exception stacks (aka IRQ stacks)

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003453.D4CB33A9@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/kaiser.h |  6 ++++++
 arch/x86/kernel/cpu/common.c  |  4 ++++
 arch/x86/mm/kaiser.c          | 31 +++++++++++++++++++++++++++++++
 include/linux/kaiser.h        |  3 +++
 4 files changed, 44 insertions(+)

diff --git a/arch/x86/include/asm/kaiser.h b/arch/x86/include/asm/kaiser.h
index 3c2cc71b4058..040cb096d29d 100644
--- a/arch/x86/include/asm/kaiser.h
+++ b/arch/x86/include/asm/kaiser.h
@@ -33,6 +33,12 @@
 extern int kaiser_add_mapping(unsigned long addr, unsigned long size,
 			      unsigned long flags);
 
+/**
+ *  kaiser_add_mapping_cpu_entry - map the cpu entry area
+ *  @cpu: the CPU for which the entry area is being mapped
+ */
+extern void kaiser_add_mapping_cpu_entry(int cpu);
+
 /**
  *  kaiser_remove_mapping - remove a kernel mapping from the userpage tables
  *  @addr: the start address of the range
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 1509f09abf5e..7b348cc33e2d 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -4,6 +4,7 @@
 #include <linux/kernel.h>
 #include <linux/export.h>
 #include <linux/percpu.h>
+#include <linux/kaiser.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <linux/delay.h>
@@ -584,6 +585,9 @@ static inline void setup_cpu_entry_area(int cpu)
 	__set_fixmap(get_cpu_entry_area_index(cpu, entry_trampoline),
 		     __pa_symbol(_entry_trampoline), PAGE_KERNEL_RX);
 #endif
+ 	/* CPU 0's mapping is done in kaiser_init() */
+	if (cpu)
+		kaiser_add_mapping_cpu_entry(cpu);
 }
 
 /* Load the original GDT from the per-cpu structure */
diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c
index 72dc15364390..10c0e9e6bf6b 100644
--- a/arch/x86/mm/kaiser.c
+++ b/arch/x86/mm/kaiser.c
@@ -353,6 +353,26 @@ static void __init kaiser_init_all_pgds(void)
 	WARN_ON(__ret);							\
 } while (0)
 
+void kaiser_add_mapping_cpu_entry(int cpu)
+{
+	kaiser_add_user_map_early(get_cpu_gdt_ro(cpu), PAGE_SIZE,
+				  __PAGE_KERNEL_RO);
+
+	/* includes the entry stack */
+	kaiser_add_user_map_early(&get_cpu_entry_area(cpu)->tss,
+				  sizeof(get_cpu_entry_area(cpu)->tss),
+				  __PAGE_KERNEL | _PAGE_GLOBAL);
+
+	/* Entry code, so needs to be EXEC */
+	kaiser_add_user_map_early(&get_cpu_entry_area(cpu)->entry_trampoline,
+				  sizeof(get_cpu_entry_area(cpu)->entry_trampoline),
+				  __PAGE_KERNEL_RX | _PAGE_GLOBAL);
+
+	kaiser_add_user_map_early(&get_cpu_entry_area(cpu)->exception_stacks,
+				 sizeof(get_cpu_entry_area(cpu)->exception_stacks),
+				 __PAGE_KERNEL | _PAGE_GLOBAL);
+}
+
 extern char __per_cpu_user_mapped_start[], __per_cpu_user_mapped_end[];
 /*
  * If anything in here fails, we will likely die on one of the
@@ -393,6 +413,17 @@ void __init kaiser_init(void)
 	kaiser_add_user_map_early((void *)idt_descr.address,
 				  sizeof(gate_desc) * NR_VECTORS,
 				  __PAGE_KERNEL_RO | _PAGE_GLOBAL);
+
+	/*
+	 * We delay CPU 0's mappings because these structures are
+	 * created before the page allocator is up.  Deferring it
+	 * until here lets us use the plain page allocator
+	 * unconditionally in the page table code above.
+	 *
+	 * This is OK because kaiser_init() is called long before
+	 * we ever run userspace and need the KAISER mappings.
+	 */
+	kaiser_add_mapping_cpu_entry(0);
 }
 
 int kaiser_add_mapping(unsigned long addr, unsigned long size,
diff --git a/include/linux/kaiser.h b/include/linux/kaiser.h
index 0fd800efa95c..77db4230a0dd 100644
--- a/include/linux/kaiser.h
+++ b/include/linux/kaiser.h
@@ -25,5 +25,8 @@ static inline int kaiser_add_mapping(unsigned long addr, unsigned long size,
 	return 0;
 }
 
+static inline void kaiser_add_mapping_cpu_entry(int cpu)
+{
+}
 #endif /* !CONFIG_KAISER */
 #endif /* _INCLUDE_KAISER_H */
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 08/24] x86/mm/kaiser: Map the dynamically-allocated LDTs
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (6 preceding siblings ...)
  2017-11-27 10:49 ` [PATCH 07/24] x86/mm/kaiser: Map the CPU entry area Ingo Molnar
@ 2017-11-27 10:49 ` 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
                   ` (17 subsequent siblings)
  25 siblings, 1 reply; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

Normally, a process has a NULL mm->context.ldt.  But, there is a
syscall for a process to set a new one.  If a process does that,
the LDT be mapped into the user page tables, just like the
default copy.

The original KAISER patch missed this case.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003455.275397F7@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/ldt.c | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
index 1c1eae961340..d6ab1144fdbf 100644
--- a/arch/x86/kernel/ldt.c
+++ b/arch/x86/kernel/ldt.c
@@ -11,6 +11,7 @@
 #include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/string.h>
+#include <linux/kaiser.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
 #include <linux/syscalls.h>
@@ -57,11 +58,21 @@ static void flush_ldt(void *__mm)
 	refresh_ldt_segments();
 }
 
+static void __free_ldt_struct(struct ldt_struct *ldt)
+{
+	if (ldt->nr_entries * LDT_ENTRY_SIZE > PAGE_SIZE)
+		vfree_atomic(ldt->entries);
+	else
+		free_page((unsigned long)ldt->entries);
+	kfree(ldt);
+}
+
 /* The caller must call finalize_ldt_struct on the result. LDT starts zeroed. */
 static struct ldt_struct *alloc_ldt_struct(unsigned int num_entries)
 {
 	struct ldt_struct *new_ldt;
 	unsigned int alloc_size;
+	int ret;
 
 	if (num_entries > LDT_ENTRIES)
 		return NULL;
@@ -89,6 +100,12 @@ static struct ldt_struct *alloc_ldt_struct(unsigned int num_entries)
 		return NULL;
 	}
 
+	ret = kaiser_add_mapping((unsigned long)new_ldt->entries, alloc_size,
+				 __PAGE_KERNEL | _PAGE_GLOBAL);
+	if (ret) {
+		__free_ldt_struct(new_ldt);
+		return NULL;
+	}
 	new_ldt->nr_entries = num_entries;
 	return new_ldt;
 }
@@ -115,12 +132,10 @@ static void free_ldt_struct(struct ldt_struct *ldt)
 	if (likely(!ldt))
 		return;
 
+	kaiser_remove_mapping((unsigned long)ldt->entries,
+			      ldt->nr_entries * LDT_ENTRY_SIZE);
 	paravirt_free_ldt(ldt->entries, ldt->nr_entries);
-	if (ldt->nr_entries * LDT_ENTRY_SIZE > PAGE_SIZE)
-		vfree_atomic(ldt->entries);
-	else
-		free_page((unsigned long)ldt->entries);
-	kfree(ldt);
+	__free_ldt_struct(ldt);
 }
 
 /*
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 09/24] x86/mm/kaiser: Map the espfix structures
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (7 preceding siblings ...)
  2017-11-27 10:49 ` [PATCH 08/24] x86/mm/kaiser: Map the dynamically-allocated LDTs Ingo Molnar
@ 2017-11-27 10:49 ` Ingo Molnar
  2017-11-27 10:49 ` [PATCH 10/24] x86/mm/kaiser: Map the entry stack variables Ingo Molnar
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

There is some rather arcane code to help when an IRET returns
to 16-bit segments.  It is referred to as the "espfix" code.
This consists of a few per-CPU variables:

	espfix_stack: tells us where the stack is allocated (the bottom)

	espfix_waddr: tells us to where %rsp may be pointed (the top)

These are in addition to the stack itself.  All three things must
be mapped for the espfix code to function.

Note: the espfix code runs with a kernel GSBASE, but user
(shadow) page tables.  A switch to the kernel page tables could
be performed instead of mapping these structures, but mapping
them is simpler and less likely to break the assembly.  To switch
over to the kernel copy, additional temporary storage would be
required which is in short supply in this context.

The original KAISER patch missed this case.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003457.EB854D0D@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/espfix_64.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/espfix_64.c b/arch/x86/kernel/espfix_64.c
index 7b95cb47a3cf..319033f5bbd9 100644
--- a/arch/x86/kernel/espfix_64.c
+++ b/arch/x86/kernel/espfix_64.c
@@ -33,6 +33,7 @@
 
 #include <linux/init.h>
 #include <linux/init_task.h>
+#include <linux/kaiser.h>
 #include <linux/kernel.h>
 #include <linux/percpu.h>
 #include <linux/gfp.h>
@@ -41,7 +42,6 @@
 #include <asm/pgalloc.h>
 #include <asm/setup.h>
 #include <asm/espfix.h>
-#include <asm/kaiser.h>
 
 /*
  * Note: we only need 6*8 = 48 bytes for the espfix stack, but round
@@ -61,8 +61,8 @@
 #define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO)
 
 /* This contains the *bottom* address of the espfix stack */
-DEFINE_PER_CPU_READ_MOSTLY(unsigned long, espfix_stack);
-DEFINE_PER_CPU_READ_MOSTLY(unsigned long, espfix_waddr);
+DEFINE_PER_CPU_USER_MAPPED(unsigned long, espfix_stack);
+DEFINE_PER_CPU_USER_MAPPED(unsigned long, espfix_waddr);
 
 /* Initialization mutex - should this be a spinlock? */
 static DEFINE_MUTEX(espfix_init_mutex);
@@ -226,4 +226,10 @@ void init_espfix_ap(int cpu)
 	per_cpu(espfix_stack, cpu) = addr;
 	per_cpu(espfix_waddr, cpu) = (unsigned long)stack_page
 				      + (addr & ~PAGE_MASK);
+	/*
+	 * _PAGE_GLOBAL is not really required.  This is not a hot
+	 * path, but we do it here for consistency.
+	 */
+	kaiser_add_mapping((unsigned long)stack_page, PAGE_SIZE,
+			__PAGE_KERNEL | _PAGE_GLOBAL);
 }
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 10/24] x86/mm/kaiser: Map the entry stack variables
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (8 preceding siblings ...)
  2017-11-27 10:49 ` [PATCH 09/24] x86/mm/kaiser: Map the espfix structures Ingo Molnar
@ 2017-11-27 10:49 ` Ingo Molnar
  2017-11-27 17:22   ` Peter Zijlstra
  2017-11-27 17:29   ` Peter Zijlstra
  2017-11-27 10:49 ` [PATCH 11/24] x86/mm/kaiser: Map virtually-addressed performance monitoring buffers Ingo Molnar
                   ` (15 subsequent siblings)
  25 siblings, 2 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

There are times where the kernel is entered but there is not a
safe stack, like at SYSCALL entry.  To obtain a safe stack, the
per-CPU variables 'rsp_scratch' and 'cpu_current_top_of_stack'
are used to save the old %rsp value and to find where the kernel
stack should start.

You can not directly manipulate the CR3 register.  You can only
'MOV' to it from another register, which means a register must be
clobbered in order to do any CR3 manipulation.  User-mapping
these variables allows us to obtain a safe stack and use it for
temporary storage *before* CR3 is switched.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003459.C0FF167A@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/cpu/common.c | 2 +-
 arch/x86/kernel/process_64.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 7b348cc33e2d..f4f4ab8525bd 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1515,7 +1515,7 @@ EXPORT_PER_CPU_SYMBOL(__preempt_count);
  * the top of the kernel stack.  Use an extra percpu variable to track the
  * top of the kernel stack directly.
  */
-DEFINE_PER_CPU(unsigned long, cpu_current_top_of_stack) =
+DEFINE_PER_CPU_USER_MAPPED(unsigned long, cpu_current_top_of_stack) =
 	(unsigned long)&init_thread_union + THREAD_SIZE;
 EXPORT_PER_CPU_SYMBOL(cpu_current_top_of_stack);
 
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 157f81816915..631e229ab428 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -59,7 +59,7 @@
 #include <asm/unistd_32_ia32.h>
 #endif
 
-__visible DEFINE_PER_CPU(unsigned long, rsp_scratch);
+__visible DEFINE_PER_CPU_USER_MAPPED(unsigned long, rsp_scratch);
 
 /* Prints also some state that isn't saved in the pt_regs */
 void __show_regs(struct pt_regs *regs, int all)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 11/24] x86/mm/kaiser: Map virtually-addressed performance monitoring buffers
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (9 preceding siblings ...)
  2017-11-27 10:49 ` [PATCH 10/24] x86/mm/kaiser: Map the entry stack variables Ingo Molnar
@ 2017-11-27 10:49 ` Ingo Molnar
  2017-11-27 10:49 ` [PATCH 12/24] x86/mm: Move the CR3 construction functions to tlbflush.h Ingo Molnar
                   ` (14 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Hugh Dickins <hughd@google.com>

The BTS and PEBS buffers both have their virtual addresses
programmed into the hardware.  This means that any access to them
is performed via the page tables.  The times that the hardware
accesses these are entirely dependent on how the performance
monitoring hardware events are set up.  In other words, there is
no way for the kernel to tell when the hardware might access
these buffers.

To avoid perf crashes, place 'debug_store' in the user-mapped
per-CPU area instead of dynamically allocating.  Also use the
page allocator plus kaiser_add_mapping() to keep the BTS and PEBS
buffers user-mapped (that is, present in the user mapping, though
visible only to kernel and hardware).  The PEBS fixup buffer does
not need this treatment.

The need for a user-mapped struct debug_store showed up before doing
any conscious perf testing: in a couple of kernel paging oopses on
Westmere, implicating the debug_store offset of the per-CPU area.

[Dave] Added explicit _PAGE_GLOBAL
[Dave] Removed KAISER #ifdefs by moving kmalloc() to plain page allocator
[Dave] Reworded the commit message a bit to be consistent with other patches

Signed-off-by: Hugh Dickins <hughd@google.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: 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: https://lkml.kernel.org/r/20171123003500.7EC0DB4E@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/events/intel/ds.c | 49 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 37 insertions(+), 12 deletions(-)

diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index 3674a4b6f8bd..b5cf473e443a 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/bitops.h>
 #include <linux/types.h>
+#include <linux/kaiser.h>
 #include <linux/slab.h>
 
 #include <asm/perf_event.h>
@@ -8,6 +9,9 @@
 
 #include "../perf_event.h"
 
+static
+DEFINE_PER_CPU_SHARED_ALIGNED_USER_MAPPED(struct debug_store, cpu_debug_store);
+
 /* The size of a BTS record in bytes: */
 #define BTS_RECORD_SIZE		24
 
@@ -279,6 +283,31 @@ void fini_debug_store_on_cpu(int cpu)
 
 static DEFINE_PER_CPU(void *, insn_buffer);
 
+static void *dsalloc(size_t size, gfp_t flags, int node)
+{
+	unsigned int order = get_order(size);
+	struct page *page;
+	unsigned long addr;
+
+	page = __alloc_pages_node(node, flags | __GFP_ZERO, order);
+	if (!page)
+		return NULL;
+	addr = (unsigned long)page_address(page);
+	if (kaiser_add_mapping(addr, size, __PAGE_KERNEL | _PAGE_GLOBAL) < 0) {
+		__free_pages(page, order);
+		addr = 0;
+	}
+	return (void *)addr;
+}
+
+static void dsfree(const void *buffer, size_t size)
+{
+	if (!buffer)
+		return;
+	kaiser_remove_mapping((unsigned long)buffer, size);
+	free_pages((unsigned long)buffer, get_order(size));
+}
+
 static int alloc_pebs_buffer(int cpu)
 {
 	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
@@ -289,7 +318,7 @@ static int alloc_pebs_buffer(int cpu)
 	if (!x86_pmu.pebs)
 		return 0;
 
-	buffer = kzalloc_node(x86_pmu.pebs_buffer_size, GFP_KERNEL, node);
+	buffer = dsalloc(x86_pmu.pebs_buffer_size, GFP_KERNEL, node);
 	if (unlikely(!buffer))
 		return -ENOMEM;
 
@@ -300,7 +329,7 @@ static int alloc_pebs_buffer(int cpu)
 	if (x86_pmu.intel_cap.pebs_format < 2) {
 		ibuffer = kzalloc_node(PEBS_FIXUP_SIZE, GFP_KERNEL, node);
 		if (!ibuffer) {
-			kfree(buffer);
+			dsfree(buffer, x86_pmu.pebs_buffer_size);
 			return -ENOMEM;
 		}
 		per_cpu(insn_buffer, cpu) = ibuffer;
@@ -326,7 +355,8 @@ static void release_pebs_buffer(int cpu)
 	kfree(per_cpu(insn_buffer, cpu));
 	per_cpu(insn_buffer, cpu) = NULL;
 
-	kfree((void *)(unsigned long)ds->pebs_buffer_base);
+	dsfree((void *)(unsigned long)ds->pebs_buffer_base,
+			x86_pmu.pebs_buffer_size);
 	ds->pebs_buffer_base = 0;
 }
 
@@ -340,7 +370,7 @@ static int alloc_bts_buffer(int cpu)
 	if (!x86_pmu.bts)
 		return 0;
 
-	buffer = kzalloc_node(BTS_BUFFER_SIZE, GFP_KERNEL | __GFP_NOWARN, node);
+	buffer = dsalloc(BTS_BUFFER_SIZE, GFP_KERNEL | __GFP_NOWARN, node);
 	if (unlikely(!buffer)) {
 		WARN_ONCE(1, "%s: BTS buffer allocation failure\n", __func__);
 		return -ENOMEM;
@@ -366,19 +396,15 @@ static void release_bts_buffer(int cpu)
 	if (!ds || !x86_pmu.bts)
 		return;
 
-	kfree((void *)(unsigned long)ds->bts_buffer_base);
+	dsfree((void *)(unsigned long)ds->bts_buffer_base, BTS_BUFFER_SIZE);
 	ds->bts_buffer_base = 0;
 }
 
 static int alloc_ds_buffer(int cpu)
 {
-	int node = cpu_to_node(cpu);
-	struct debug_store *ds;
-
-	ds = kzalloc_node(sizeof(*ds), GFP_KERNEL, node);
-	if (unlikely(!ds))
-		return -ENOMEM;
+	struct debug_store *ds = per_cpu_ptr(&cpu_debug_store, cpu);
 
+	memset(ds, 0, sizeof(*ds));
 	per_cpu(cpu_hw_events, cpu).ds = ds;
 
 	return 0;
@@ -392,7 +418,6 @@ static void release_ds_buffer(int cpu)
 		return;
 
 	per_cpu(cpu_hw_events, cpu).ds = NULL;
-	kfree(ds);
 }
 
 void release_ds_buffers(void)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 12/24] x86/mm: Move the CR3 construction functions to tlbflush.h
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (10 preceding siblings ...)
  2017-11-27 10:49 ` [PATCH 11/24] x86/mm/kaiser: Map virtually-addressed performance monitoring buffers Ingo Molnar
@ 2017-11-27 10:49 ` Ingo Molnar
  2017-11-27 10:49 ` [PATCH 13/24] x86/mm: Remove hard-coded ASID limit checks Ingo Molnar
                   ` (13 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

For flushing the TLB, the ASID which has been programmed into the
hardware must be known.  That differs from what is in 'cpu_tlbstate'.

Add functions to transform the 'cpu_tlbstate' values into to the one
programmed into the hardware (CR3).

It's not easy to include mmu_context.h into tlbflush.h, so just move
the CR3 building over to tlbflush.h.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003502.CC87BF47@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/mmu_context.h | 29 +----------------------------
 arch/x86/include/asm/tlbflush.h    | 27 +++++++++++++++++++++++++++
 arch/x86/mm/tlb.c                  |  8 ++++----
 3 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
index 6d16d15d09a0..5e1a1ecb65c6 100644
--- a/arch/x86/include/asm/mmu_context.h
+++ b/arch/x86/include/asm/mmu_context.h
@@ -281,33 +281,6 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,
 	return __pkru_allows_pkey(vma_pkey(vma), write);
 }
 
-/*
- * If PCID is on, ASID-aware code paths put the ASID+1 into the PCID
- * bits.  This serves two purposes.  It prevents a nasty situation in
- * which PCID-unaware code saves CR3, loads some other value (with PCID
- * == 0), and then restores CR3, thus corrupting the TLB for ASID 0 if
- * the saved ASID was nonzero.  It also means that any bugs involving
- * loading a PCID-enabled CR3 with CR4.PCIDE off will trigger
- * deterministically.
- */
-
-static inline unsigned long build_cr3(struct mm_struct *mm, u16 asid)
-{
-	if (static_cpu_has(X86_FEATURE_PCID)) {
-		VM_WARN_ON_ONCE(asid > 4094);
-		return __sme_pa(mm->pgd) | (asid + 1);
-	} else {
-		VM_WARN_ON_ONCE(asid != 0);
-		return __sme_pa(mm->pgd);
-	}
-}
-
-static inline unsigned long build_cr3_noflush(struct mm_struct *mm, u16 asid)
-{
-	VM_WARN_ON_ONCE(asid > 4094);
-	return __sme_pa(mm->pgd) | (asid + 1) | CR3_NOFLUSH;
-}
-
 /*
  * This can be used from process context to figure out what the value of
  * CR3 is without needing to do a (slow) __read_cr3().
@@ -317,7 +290,7 @@ static inline unsigned long build_cr3_noflush(struct mm_struct *mm, u16 asid)
  */
 static inline unsigned long __get_current_cr3_fast(void)
 {
-	unsigned long cr3 = build_cr3(this_cpu_read(cpu_tlbstate.loaded_mm),
+	unsigned long cr3 = build_cr3(this_cpu_read(cpu_tlbstate.loaded_mm)->pgd,
 		this_cpu_read(cpu_tlbstate.loaded_mm_asid));
 
 	/* For now, be very restrictive about when this can be called. */
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 877b5c1a1b12..cb65bddca360 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -75,6 +75,33 @@ static inline u64 inc_mm_tlb_gen(struct mm_struct *mm)
 	return new_tlb_gen;
 }
 
+/*
+ * If PCID is on, ASID-aware code paths put the ASID+1 into the PCID
+ * bits.  This serves two purposes.  It prevents a nasty situation in
+ * which PCID-unaware code saves CR3, loads some other value (with PCID
+ * == 0), and then restores CR3, thus corrupting the TLB for ASID 0 if
+ * the saved ASID was nonzero.  It also means that any bugs involving
+ * loading a PCID-enabled CR3 with CR4.PCIDE off will trigger
+ * deterministically.
+ */
+struct pgd_t;
+static inline unsigned long build_cr3(pgd_t *pgd, u16 asid)
+{
+	if (static_cpu_has(X86_FEATURE_PCID)) {
+		VM_WARN_ON_ONCE(asid > 4094);
+		return __sme_pa(pgd) | (asid + 1);
+	} else {
+		VM_WARN_ON_ONCE(asid != 0);
+		return __sme_pa(pgd);
+	}
+}
+
+static inline unsigned long build_cr3_noflush(pgd_t *pgd, u16 asid)
+{
+	VM_WARN_ON_ONCE(asid > 4094);
+	return __sme_pa(pgd) | (asid + 1) | CR3_NOFLUSH;
+}
+
 #ifdef CONFIG_PARAVIRT
 #include <asm/paravirt.h>
 #else
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 3118392cdf75..e629dbda01a0 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -128,7 +128,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
 	 * isn't free.
 	 */
 #ifdef CONFIG_DEBUG_VM
-	if (WARN_ON_ONCE(__read_cr3() != build_cr3(real_prev, prev_asid))) {
+	if (WARN_ON_ONCE(__read_cr3() != build_cr3(real_prev->pgd, prev_asid))) {
 		/*
 		 * If we were to BUG here, we'd be very likely to kill
 		 * the system so hard that we don't see the call trace.
@@ -195,7 +195,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
 		if (need_flush) {
 			this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id);
 			this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen);
-			write_cr3(build_cr3(next, new_asid));
+			write_cr3(build_cr3(next->pgd, new_asid));
 
 			/*
 			 * NB: This gets called via leave_mm() in the idle path
@@ -208,7 +208,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
 			trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
 		} else {
 			/* The new ASID is already up to date. */
-			write_cr3(build_cr3_noflush(next, new_asid));
+			write_cr3(build_cr3_noflush(next->pgd, new_asid));
 
 			/* See above wrt _rcuidle. */
 			trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, 0);
@@ -288,7 +288,7 @@ void initialize_tlbstate_and_flush(void)
 		!(cr4_read_shadow() & X86_CR4_PCIDE));
 
 	/* Force ASID 0 and force a TLB flush. */
-	write_cr3(build_cr3(mm, 0));
+	write_cr3(build_cr3(mm->pgd, 0));
 
 	/* Reinitialize tlbstate. */
 	this_cpu_write(cpu_tlbstate.loaded_mm_asid, 0);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 13/24] x86/mm: Remove hard-coded ASID limit checks
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (11 preceding siblings ...)
  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 ` Ingo Molnar
  2017-11-27 10:49 ` [PATCH 14/24] x86/mm: Put MMU-to-h/w ASID translation in one place Ingo Molnar
                   ` (12 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

First, it's nice to remove the magic numbers.

Second, KAISER is going to consume half of the available ASID
space.  The space is currently unused, but add a comment to spell
out this new restriction.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003504.57EDB845@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/tlbflush.h | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index cb65bddca360..d35776d9580b 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -75,6 +75,19 @@ static inline u64 inc_mm_tlb_gen(struct mm_struct *mm)
 	return new_tlb_gen;
 }
 
+/* There are 12 bits of space for ASIDS in CR3 */
+#define CR3_HW_ASID_BITS 12
+/* When enabled, KAISER consumes a single bit for user/kernel switches */
+#define KAISER_CONSUMED_ASID_BITS 0
+
+#define CR3_AVAIL_ASID_BITS (CR3_HW_ASID_BITS - KAISER_CONSUMED_ASID_BITS)
+/*
+ * ASIDs are zero-based: 0->MAX_AVAIL_ASID are valid.  -1 below
+ * to account for them being zero-based.  Another -1 is because ASID 0
+ * is reserved for use by non-PCID-aware users.
+ */
+#define MAX_ASID_AVAILABLE ((1<<CR3_AVAIL_ASID_BITS) - 2)
+
 /*
  * If PCID is on, ASID-aware code paths put the ASID+1 into the PCID
  * bits.  This serves two purposes.  It prevents a nasty situation in
@@ -88,7 +101,7 @@ struct pgd_t;
 static inline unsigned long build_cr3(pgd_t *pgd, u16 asid)
 {
 	if (static_cpu_has(X86_FEATURE_PCID)) {
-		VM_WARN_ON_ONCE(asid > 4094);
+		VM_WARN_ON_ONCE(asid > MAX_ASID_AVAILABLE);
 		return __sme_pa(pgd) | (asid + 1);
 	} else {
 		VM_WARN_ON_ONCE(asid != 0);
@@ -98,7 +111,7 @@ static inline unsigned long build_cr3(pgd_t *pgd, u16 asid)
 
 static inline unsigned long build_cr3_noflush(pgd_t *pgd, u16 asid)
 {
-	VM_WARN_ON_ONCE(asid > 4094);
+	VM_WARN_ON_ONCE(asid > MAX_ASID_AVAILABLE);
 	return __sme_pa(pgd) | (asid + 1) | CR3_NOFLUSH;
 }
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 14/24] x86/mm: Put MMU-to-h/w ASID translation in one place
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (12 preceding siblings ...)
  2017-11-27 10:49 ` [PATCH 13/24] x86/mm: Remove hard-coded ASID limit checks Ingo Molnar
@ 2017-11-27 10:49 ` Ingo Molnar
  2017-11-27 10:49 ` [PATCH 15/24] x86/mm: Allow flushing for future ASID switches Ingo Molnar
                   ` (11 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

There are effectively two ASID types:

 1. The one stored in the mmu_context that goes from 0..5
 2. The one programmed into the hardware that goes from 1..6

This consolidates the locations where converting beween the two
(by doing +1) to a single place which gives us a nice place to
comment.  KAISER will also need to, given an ASID, know which
hardware ASID to flush for the userspace mapping.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003506.67E81D7F@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/tlbflush.h | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index d35776d9580b..3732b75c248a 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -88,21 +88,26 @@ static inline u64 inc_mm_tlb_gen(struct mm_struct *mm)
  */
 #define MAX_ASID_AVAILABLE ((1<<CR3_AVAIL_ASID_BITS) - 2)
 
-/*
- * If PCID is on, ASID-aware code paths put the ASID+1 into the PCID
- * bits.  This serves two purposes.  It prevents a nasty situation in
- * which PCID-unaware code saves CR3, loads some other value (with PCID
- * == 0), and then restores CR3, thus corrupting the TLB for ASID 0 if
- * the saved ASID was nonzero.  It also means that any bugs involving
- * loading a PCID-enabled CR3 with CR4.PCIDE off will trigger
- * deterministically.
- */
+static inline u16 kern_asid(u16 asid)
+{
+	VM_WARN_ON_ONCE(asid > MAX_ASID_AVAILABLE);
+	/*
+	 * If PCID is on, ASID-aware code paths put the ASID+1 into the PCID
+	 * bits.  This serves two purposes.  It prevents a nasty situation in
+	 * which PCID-unaware code saves CR3, loads some other value (with PCID
+	 * == 0), and then restores CR3, thus corrupting the TLB for ASID 0 if
+	 * the saved ASID was nonzero.  It also means that any bugs involving
+	 * loading a PCID-enabled CR3 with CR4.PCIDE off will trigger
+	 * deterministically.
+	 */
+	return asid + 1;
+}
+
 struct pgd_t;
 static inline unsigned long build_cr3(pgd_t *pgd, u16 asid)
 {
 	if (static_cpu_has(X86_FEATURE_PCID)) {
-		VM_WARN_ON_ONCE(asid > MAX_ASID_AVAILABLE);
-		return __sme_pa(pgd) | (asid + 1);
+		return __sme_pa(pgd) | kern_asid(asid);
 	} else {
 		VM_WARN_ON_ONCE(asid != 0);
 		return __sme_pa(pgd);
@@ -112,7 +117,8 @@ static inline unsigned long build_cr3(pgd_t *pgd, u16 asid)
 static inline unsigned long build_cr3_noflush(pgd_t *pgd, u16 asid)
 {
 	VM_WARN_ON_ONCE(asid > MAX_ASID_AVAILABLE);
-	return __sme_pa(pgd) | (asid + 1) | CR3_NOFLUSH;
+	VM_WARN_ON_ONCE(!this_cpu_has(X86_FEATURE_PCID));
+	return __sme_pa(pgd) | kern_asid(asid) | CR3_NOFLUSH;
 }
 
 #ifdef CONFIG_PARAVIRT
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (13 preceding siblings ...)
  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 ` Ingo Molnar
  2017-11-28  5:16   ` Andy Lutomirski
  2017-11-30 15:44   ` 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
                   ` (10 subsequent siblings)
  25 siblings, 2 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

If changing the page tables in such a way that an invalidation of
all contexts (aka. PCIDs / ASIDs) is required, they can be
actively invalidated by:

 1. INVPCID for each PCID (works for single pages too).

 2. Load CR3 with each PCID without the NOFLUSH bit set

 3. Load CR3 with the NOFLUSH bit set for each and do INVLPG for each address.

But, none of these are really feasible since there are ~6 ASIDs (12 with
KAISER) at the time that invalidation is required.  Instead of
actively invalidating them, invalidate the *current* context and
also mark the cpu_tlbstate _quickly_ to indicate future invalidation
to be required.

At the next context-switch, look for this indicator
('all_other_ctxs_invalid' being set) invalidate all of the
cpu_tlbstate.ctxs[] entries.

This ensures that any future context switches will do a full flush
of the TLB, picking up the previous changes.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003507.E8C327F5@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/tlbflush.h | 47 ++++++++++++++++++++++++++++++++---------
 arch/x86/mm/tlb.c               | 35 ++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 3732b75c248a..446a4a2d4457 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -184,6 +184,17 @@ struct tlb_state {
 	 */
 	bool is_lazy;
 
+	/*
+	 * If set we changed the page tables in such a way that we
+	 * needed an invalidation of all contexts (aka. PCIDs / ASIDs).
+	 * This tells us to go invalidate all the non-loaded ctxs[]
+	 * on the next context switch.
+	 *
+	 * The current ctx was kept up-to-date as it ran and does not
+	 * need to be invalidated.
+	 */
+	bool all_other_ctxs_invalid;
+
 	/*
 	 * Access to this CR4 shadow and to H/W CR4 is protected by
 	 * disabling interrupts when modifying either one.
@@ -264,6 +275,19 @@ static inline unsigned long cr4_read_shadow(void)
 	return this_cpu_read(cpu_tlbstate.cr4);
 }
 
+static inline void tlb_flush_shared_nonglobals(void)
+{
+	/*
+	 * With global pages, all of the shared kenel page tables
+	 * are set as _PAGE_GLOBAL.  We have no shared nonglobals
+	 * and nothing to do here.
+	 */
+	if (IS_ENABLED(CONFIG_X86_GLOBAL_PAGES))
+		return;
+
+	this_cpu_write(cpu_tlbstate.all_other_ctxs_invalid, true);
+}
+
 /*
  * Save some of cr4 feature set we're using (e.g.  Pentium 4MB
  * enable and PPro Global page enable), so that any CPU's that boot
@@ -293,6 +317,10 @@ static inline void __native_flush_tlb(void)
 	preempt_disable();
 	native_write_cr3(__native_read_cr3());
 	preempt_enable();
+	/*
+	 * Does not need tlb_flush_shared_nonglobals() since the CR3 write
+	 * without PCIDs flushes all non-globals.
+	 */
 }
 
 static inline void __native_flush_tlb_global_irq_disabled(void)
@@ -338,24 +366,23 @@ static inline void __native_flush_tlb_single(unsigned long addr)
 
 static inline void __flush_tlb_all(void)
 {
-	if (boot_cpu_has(X86_FEATURE_PGE))
+	if (boot_cpu_has(X86_FEATURE_PGE)) {
 		__flush_tlb_global();
-	else
+	} else {
 		__flush_tlb();
-
-	/*
-	 * Note: if we somehow had PCID but not PGE, then this wouldn't work --
-	 * we'd end up flushing kernel translations for the current ASID but
-	 * we might fail to flush kernel translations for other cached ASIDs.
-	 *
-	 * To avoid this issue, we force PCID off if PGE is off.
-	 */
+		tlb_flush_shared_nonglobals();
+	}
 }
 
 static inline void __flush_tlb_one(unsigned long addr)
 {
 	count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ONE);
 	__flush_tlb_single(addr);
+	/*
+	 * Invalidate other address spaces inaccessible to single-page
+	 * invalidation:
+	 */
+	tlb_flush_shared_nonglobals();
 }
 
 #define TLB_FLUSH_ALL	-1UL
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index e629dbda01a0..81941f1690fa 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -28,6 +28,38 @@
  *	Implement flush IPI by CALL_FUNCTION_VECTOR, Alex Shi
  */
 
+/*
+ * We get here when we do something requiring a TLB invalidation
+ * but could not go invalidate all of the contexts.  We do the
+ * necessary invalidation by clearing out the 'ctx_id' which
+ * forces a TLB flush when the context is loaded.
+ */
+void clear_non_loaded_ctxs(void)
+{
+	u16 asid;
+
+	/*
+	 * This is only expected to be set if we have disabled
+	 * kernel _PAGE_GLOBAL pages.
+	 */
+	if (IS_ENABLED(CONFIG_X86_GLOBAL_PAGES)) {
+		WARN_ON_ONCE(1);
+		return;
+	}
+
+	for (asid = 0; asid < TLB_NR_DYN_ASIDS; asid++) {
+		/* Do not need to flush the current asid */
+		if (asid == this_cpu_read(cpu_tlbstate.loaded_mm_asid))
+			continue;
+		/*
+		 * Make sure the next time we go to switch to
+		 * this asid, we do a flush:
+		 */
+		this_cpu_write(cpu_tlbstate.ctxs[asid].ctx_id, 0);
+	}
+	this_cpu_write(cpu_tlbstate.all_other_ctxs_invalid, false);
+}
+
 atomic64_t last_mm_ctx_id = ATOMIC64_INIT(1);
 
 
@@ -42,6 +74,9 @@ static void choose_new_asid(struct mm_struct *next, u64 next_tlb_gen,
 		return;
 	}
 
+	if (this_cpu_read(cpu_tlbstate.all_other_ctxs_invalid))
+		clear_non_loaded_ctxs();
+
 	for (asid = 0; asid < TLB_NR_DYN_ASIDS; asid++) {
 		if (this_cpu_read(cpu_tlbstate.ctxs[asid].ctx_id) !=
 		    next->context.ctx_id)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 16/24] x86/mm/kaiser: Use PCID feature to make user and kernel switches faster
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (14 preceding siblings ...)
  2017-11-27 10:49 ` [PATCH 15/24] x86/mm: Allow flushing for future ASID switches Ingo Molnar
@ 2017-11-27 10:49 ` Ingo Molnar
  2017-11-28  5:22   ` Andy Lutomirski
  2017-11-27 10:49 ` [PATCH 17/24] x86/mm/kaiser: Disable native VSYSCALL Ingo Molnar
                   ` (9 subsequent siblings)
  25 siblings, 1 reply; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

Short summary: Use x86 PCID feature to avoid flushing the TLB at all
interrupts and syscalls.  Speed them up.  Makes context switches
and TLB flushing slower.

Background:

KAISER keeps two copies of the page tables.  Switches between the
copies are performed by writing to the CR3 register.  But, CR3
was really designed for context switches and writes to it also
flush the entire TLB (modulo global pages).  This TLB flush
increases the cost of interrupts and context switches.  For
syscall-heavy microbenchmarks it can cut the rate of syscalls by 2/3.

The kernel recently gained support for and Intel CPU feature
called Process Context IDentifiers (PCID) thanks to Andy
Lutomirski.  This feature is intended to allow you to switch
between contexts without flushing the TLB.

Implementation:

PCIDs can be used to avoid flushing the TLB at kernel entry/exit.
This is speeds up both interrupts and syscalls.

First, the kernel and userspace must be assigned different ASIDs.
On entry from userspace, move over to the kernel page tables
*and* ASID.  On exit, restore the user page tables and ASID.
Fortunately, the ASID is programmed via CR3, which is already
being used to switch between the user and kernel page tables.
This gives us convenient, one-stop shopping.

The CR3 write which is used to switch between processes provides
all the TLB flushing normally required at context switch time.
But, with KAISER, that CR3 write only flushes the current
(kernel) ASID.  An extra TLB flush operation is now required in
order to flush the user ASID.  This new instruction (INVPCID) is
probably ~100 cycles, but this is done with the assumption that
the time lost in context switches is more than made up for by
lower cost of interrupts and syscalls.

Support:

PCIDs are generally available on Sandybridge and newer CPUs.  However,
the accompanying INVPCID instruction did not become available until
Haswell (the ones with "v4", or called fourth-generation Core).  This
instruction allows non-current-PCID TLB entries to be flushed without
switching CR3 and global pages to be flushed without a double
MOV-to-CR4.

Without INVPCID, PCIDs are much harder to use.  TLB invalidation gets
much more onerous:

1. Every kernel TLB flush (even for a single page) requires an
   interrupts-off MOV-to-CR4 which is very expensive.  This is because
   there is no way to flush a kernel address that might be loaded
   in *EVERY* PCID.  Right now, there are "only" ~12 of these per-CPU,
   but that's too painful to use the MOV-to-CR3 to flush them.  That
   leaves only the MOV-to-CR4.

2. Every userspace flush (even for a single page requires one of the
   following:
   a. A pair of flushing (bit 63 clear) CR3 writes: one for
      the kernel ASID and another for userspace.
   b. A pair of non-flushing CR3 writes (bit 63 set) with the
      flush done for each.  For instance, what is currently a
      single instruction without KAISER:

		invpcid_flush_one(current_pcid, addr);

      becomes this with KAISER:

		invpcid_flush_one(current_kern_pcid, addr);
		invpcid_flush_one(current_user_pcid, addr);

      and this without INVPCID:

		__native_flush_tlb_single(addr);
		write_cr3(mm->pgd | current_user_pcid | NOFLUSH);
		__native_flush_tlb_single(addr);
		write_cr3(mm->pgd | current_kern_pcid | NOFLUSH);

So, for now, fully disable PCIDs with KAISER when INVPCID is not
available.  This is fixable, but it's an optimization that can be
performed later.

Hugh Dickins also points out that PCIDs really have two distinct
use-cases in the context of KAISER.  The first way they can be used
is as "TLB preservation across context-switch", which is what
Andy Lutomirksi's 4.14 PCID code does.  They can also be used as
a "KAISER syscall/interrupt accelerator".  If we just use them to
speed up syscall/interrupts (and ignore the context-switch TLB
preservation), then the deficiency of not having INVPCID
becomes much less onerous.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003509.EC42DD15@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/entry/calling.h                    |  25 +++--
 arch/x86/include/asm/cpufeatures.h          |   1 +
 arch/x86/include/asm/pgtable_types.h        |  11 +++
 arch/x86/include/asm/tlbflush.h             | 137 +++++++++++++++++++++++-----
 arch/x86/include/uapi/asm/processor-flags.h |   3 +-
 arch/x86/kvm/x86.c                          |   3 +-
 arch/x86/mm/init.c                          |  75 ++++++++++-----
 arch/x86/mm/tlb.c                           |  66 +++++++++++++-
 8 files changed, 261 insertions(+), 60 deletions(-)

diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index d087c3aa0514..66af80514197 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -3,6 +3,7 @@
 #include <asm/unwind_hints.h>
 #include <asm/cpufeatures.h>
 #include <asm/page_types.h>
+#include <asm/pgtable_types.h>
 
 /*
 
@@ -192,16 +193,20 @@ For 32-bit we have the following conventions - kernel is built with
 #ifdef CONFIG_KAISER
 
 /* KAISER PGDs are 8k.  Flip bit 12 to switch between the two halves: */
-#define KAISER_SWITCH_MASK (1<<PAGE_SHIFT)
+#define KAISER_SWITCH_PGTABLES_MASK (1<<PAGE_SHIFT)
+#define KAISER_SWITCH_MASK     (KAISER_SWITCH_PGTABLES_MASK|\
+				(1<<X86_CR3_KAISER_SWITCH_BIT))
 
 .macro ADJUST_KERNEL_CR3 reg:req
-	/* Clear "KAISER bit", point CR3 at kernel pagetables: */
-	andq	$(~KAISER_SWITCH_MASK), \reg
+	ALTERNATIVE "", "bts $63, \reg", X86_FEATURE_PCID
+	/* Clear PCID and "KAISER bit", point CR3 at kernel pagetables: */
+	andq    $(~KAISER_SWITCH_MASK), \reg
 .endm
 
 .macro ADJUST_USER_CR3 reg:req
-	/* Move CR3 up a page to the user page tables: */
-	orq	$(KAISER_SWITCH_MASK), \reg
+	ALTERNATIVE "", "bts $63, \reg", X86_FEATURE_PCID
+	/* Set user PCID bit, and move CR3 up a page to the user page tables: */
+	orq     $(KAISER_SWITCH_MASK), \reg
 .endm
 
 .macro SWITCH_TO_KERNEL_CR3 scratch_reg:req
@@ -220,8 +225,14 @@ For 32-bit we have the following conventions - kernel is built with
 	movq	%cr3, %r\scratch_reg
 	movq	%r\scratch_reg, \save_reg
 	/*
-	 * Is the switch bit zero?  This means the address is
-	 * up in real KAISER patches in a moment.
+	 * Is the "switch mask" all zero?  That means that both of
+	 * these are zero:
+	 *
+	 *	1. The user/kernel PCID bit, and
+	 *	2. The user/kernel "bit" that points CR3 to the
+	 *	   bottom half of the 8k PGD
+	 *
+	 * That indicates a kernel CR3 value, not user/shadow.
 	 */
 	testq	$(KAISER_SWITCH_MASK), %r\scratch_reg
 	jz	.Ldone_\@
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index c0b0e9e8aa66..ea51d4a28d96 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -197,6 +197,7 @@
 #define X86_FEATURE_CAT_L3		( 7*32+ 4) /* Cache Allocation Technology L3 */
 #define X86_FEATURE_CAT_L2		( 7*32+ 5) /* Cache Allocation Technology L2 */
 #define X86_FEATURE_CDP_L3		( 7*32+ 6) /* Code and Data Prioritization L3 */
+#define X86_FEATURE_INVPCID_SINGLE ( 7*32+ 7) /* Effectively INVPCID && CR4.PCIDE=1 */
 
 #define X86_FEATURE_HW_PSTATE		( 7*32+ 8) /* AMD HW-PState */
 #define X86_FEATURE_PROC_FEEDBACK	( 7*32+ 9) /* AMD ProcFeedbackInterface */
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index 84fb12404618..503bb6999a75 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -140,6 +140,17 @@
 			 _PAGE_SOFT_DIRTY)
 #define _HPAGE_CHG_MASK (_PAGE_CHG_MASK | _PAGE_PSE)
 
+/* The ASID is the lower 12 bits of CR3 */
+#define X86_CR3_PCID_ASID_MASK  (_AC((1<<12)-1, UL))
+
+/* Mask for all the PCID-related bits in CR3: */
+#define X86_CR3_PCID_MASK       (X86_CR3_PCID_NOFLUSH | X86_CR3_PCID_ASID_MASK)
+
+/* Make sure this is only usable in KAISER #ifdef'd code: */
+#ifdef CONFIG_KAISER
+#define X86_CR3_KAISER_SWITCH_BIT 11
+#endif
+
 /*
  * The cache modes defined here are used to translate between pure SW usage
  * and the HW defined cache mode bits and/or PAT entries.
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 446a4a2d4457..27eb7e8c5e84 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -78,7 +78,12 @@ static inline u64 inc_mm_tlb_gen(struct mm_struct *mm)
 /* There are 12 bits of space for ASIDS in CR3 */
 #define CR3_HW_ASID_BITS 12
 /* When enabled, KAISER consumes a single bit for user/kernel switches */
+#ifdef CONFIG_KAISER
+#define X86_CR3_KAISER_SWITCH_BIT 11
+#define KAISER_CONSUMED_ASID_BITS 1
+#else
 #define KAISER_CONSUMED_ASID_BITS 0
+#endif
 
 #define CR3_AVAIL_ASID_BITS (CR3_HW_ASID_BITS - KAISER_CONSUMED_ASID_BITS)
 /*
@@ -88,21 +93,62 @@ static inline u64 inc_mm_tlb_gen(struct mm_struct *mm)
  */
 #define MAX_ASID_AVAILABLE ((1<<CR3_AVAIL_ASID_BITS) - 2)
 
+/*
+ * 6 because 6 should be plenty and struct tlb_state will fit in
+ * two cache lines.
+ */
+#define TLB_NR_DYN_ASIDS 6
+
 static inline u16 kern_asid(u16 asid)
 {
 	VM_WARN_ON_ONCE(asid > MAX_ASID_AVAILABLE);
+
+#ifdef CONFIG_KAISER
+	/*
+	 * Make sure that the dynamic ASID space does not confict
+	 * with the bit we are using to switch between user and
+	 * kernel ASIDs.
+	 */
+	BUILD_BUG_ON(TLB_NR_DYN_ASIDS >= (1<<X86_CR3_KAISER_SWITCH_BIT));
+
 	/*
-	 * If PCID is on, ASID-aware code paths put the ASID+1 into the PCID
-	 * bits.  This serves two purposes.  It prevents a nasty situation in
-	 * which PCID-unaware code saves CR3, loads some other value (with PCID
-	 * == 0), and then restores CR3, thus corrupting the TLB for ASID 0 if
-	 * the saved ASID was nonzero.  It also means that any bugs involving
-	 * loading a PCID-enabled CR3 with CR4.PCIDE off will trigger
-	 * deterministically.
+	 * The ASID being passed in here should have respected
+	 * the MAX_ASID_AVAILABLE and thus never have the switch
+	 * bit set.
+	 */
+	VM_WARN_ON_ONCE(asid & (1<<X86_CR3_KAISER_SWITCH_BIT));
+#endif
+	/*
+	 * The dynamically-assigned ASIDs that get passed in  are
+	 * small (<TLB_NR_DYN_ASIDS).  They never have the high
+	 * switch bit set, so do not bother to clear it.
+	 */
+
+	/*
+	 * If PCID is on, ASID-aware code paths put the ASID+1
+	 * into the PCID bits.  This serves two purposes.  It
+	 * prevents a nasty situation in which PCID-unaware code
+	 * saves CR3, loads some other value (with PCID == 0),
+	 * and then restores CR3, thus corrupting the TLB for
+	 * ASID 0 if the saved ASID was nonzero.  It also means
+	 * that any bugs involving loading a PCID-enabled CR3
+	 * with CR4.PCIDE off will trigger deterministically.
 	 */
 	return asid + 1;
 }
 
+/*
+ * The user ASID is just the kernel one, plus the "switch bit".
+ */
+static inline u16 user_asid(u16 asid)
+{
+	u16 ret = kern_asid(asid);
+#ifdef CONFIG_KAISER
+	ret |= 1<<X86_CR3_KAISER_SWITCH_BIT;
+#endif
+	return ret;
+}
+
 struct pgd_t;
 static inline unsigned long build_cr3(pgd_t *pgd, u16 asid)
 {
@@ -145,12 +191,6 @@ static inline bool tlb_defer_switch_to_init_mm(void)
 	return !static_cpu_has(X86_FEATURE_PCID);
 }
 
-/*
- * 6 because 6 should be plenty and struct tlb_state will fit in
- * two cache lines.
- */
-#define TLB_NR_DYN_ASIDS 6
-
 struct tlb_context {
 	u64 ctx_id;
 	u64 tlb_gen;
@@ -309,18 +349,42 @@ extern void initialize_tlbstate_and_flush(void);
 
 static inline void __native_flush_tlb(void)
 {
+	if (!cpu_feature_enabled(X86_FEATURE_INVPCID)) {
+		/*
+		 * native_write_cr3() only clears the current PCID if
+		 * CR4 has X86_CR4_PCIDE set.  In other words, this does
+		 * not fully flush the TLB if PCIDs are in use.
+		 *
+		 * With KAISER and PCIDs, the means that we did not
+		 * flush the user PCID.  Warn if it gets called.
+		 */
+		if (IS_ENABLED(CONFIG_KAISER))
+			WARN_ON_ONCE(this_cpu_read(cpu_tlbstate.cr4) &
+				     X86_CR4_PCIDE);
+		/*
+		 * If current->mm == NULL then we borrow a mm
+		 * which may change during a task switch and
+		 * therefore we must not be preempted while we
+		 * write CR3 back:
+		 */
+		preempt_disable();
+		native_write_cr3(__native_read_cr3());
+		preempt_enable();
+		/*
+		 * Does not need tlb_flush_shared_nonglobals()
+		 * since the CR3 write without PCIDs flushes all
+		 * non-globals.
+		 */
+		return;
+	}
 	/*
-	 * If current->mm == NULL then we borrow a mm which may change during a
-	 * task switch and therefore we must not be preempted while we write CR3
-	 * back:
-	 */
-	preempt_disable();
-	native_write_cr3(__native_read_cr3());
-	preempt_enable();
-	/*
-	 * Does not need tlb_flush_shared_nonglobals() since the CR3 write
-	 * without PCIDs flushes all non-globals.
+	 * We are no longer using globals with KAISER, so a
+	 * "nonglobals" flush would work too. But, this is more
+	 * conservative.
+	 *
+	 * Note, this works with CR4.PCIDE=0 or 1.
 	 */
+	invpcid_flush_all();
 }
 
 static inline void __native_flush_tlb_global_irq_disabled(void)
@@ -342,6 +406,8 @@ static inline void __native_flush_tlb_global(void)
 		/*
 		 * Using INVPCID is considerably faster than a pair of writes
 		 * to CR4 sandwiched inside an IRQ flag save/restore.
+		 *
+		 * Note, this works with CR4.PCIDE=0 or 1.
 		 */
 		invpcid_flush_all();
 		return;
@@ -361,7 +427,30 @@ static inline void __native_flush_tlb_global(void)
 
 static inline void __native_flush_tlb_single(unsigned long addr)
 {
-	asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
+	u32 loaded_mm_asid = this_cpu_read(cpu_tlbstate.loaded_mm_asid);
+
+	/*
+	 * Some platforms #GP if we call invpcid(type=1/2) before
+	 * CR4.PCIDE=1.  Just call invpcid in the case we are called
+	 * early.
+	 */
+	if (!this_cpu_has(X86_FEATURE_INVPCID_SINGLE)) {
+		asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
+		return;
+	}
+	/* Flush the address out of both PCIDs. */
+	/*
+	 * An optimization here might be to determine addresses
+	 * that are only kernel-mapped and only flush the kernel
+	 * ASID.  But, userspace flushes are probably much more
+	 * important performance-wise.
+	 *
+	 * Make sure to do only a single invpcid when KAISER is
+	 * disabled and we have only a single ASID.
+	 */
+	if (kern_asid(loaded_mm_asid) != user_asid(loaded_mm_asid))
+		invpcid_flush_one(user_asid(loaded_mm_asid), addr);
+	invpcid_flush_one(kern_asid(loaded_mm_asid), addr);
 }
 
 static inline void __flush_tlb_all(void)
diff --git a/arch/x86/include/uapi/asm/processor-flags.h b/arch/x86/include/uapi/asm/processor-flags.h
index 7e1e730396ae..7ef94b64dbb4 100644
--- a/arch/x86/include/uapi/asm/processor-flags.h
+++ b/arch/x86/include/uapi/asm/processor-flags.h
@@ -78,7 +78,8 @@
 #define X86_CR3_PWT		_BITUL(X86_CR3_PWT_BIT)
 #define X86_CR3_PCD_BIT		4 /* Page Cache Disable */
 #define X86_CR3_PCD		_BITUL(X86_CR3_PCD_BIT)
-#define X86_CR3_PCID_MASK	_AC(0x00000fff,UL) /* PCID Mask */
+#define X86_CR3_PCID_NOFLUSH_BIT 63 /* Preserve old PCID */
+#define X86_CR3_PCID_NOFLUSH    _BITULL(X86_CR3_PCID_NOFLUSH_BIT)
 
 /*
  * Intel CPU features in CR4
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 03869eb7fcd6..cd7ed7a874d1 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -805,7 +805,8 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
 			return 1;
 
 		/* PCID can not be enabled when cr3[11:0]!=000H or EFER.LMA=0 */
-		if ((kvm_read_cr3(vcpu) & X86_CR3_PCID_MASK) || !is_long_mode(vcpu))
+		if ((kvm_read_cr3(vcpu) & X86_CR3_PCID_ASID_MASK) ||
+		    !is_long_mode(vcpu))
 			return 1;
 	}
 
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index a22c2b95e513..9618e57d46cf 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -196,34 +196,59 @@ static void __init probe_page_size_mask(void)
 
 static void setup_pcid(void)
 {
-#ifdef CONFIG_X86_64
-	if (boot_cpu_has(X86_FEATURE_PCID)) {
-		if (boot_cpu_has(X86_FEATURE_PGE)) {
-			/*
-			 * This can't be cr4_set_bits_and_update_boot() --
-			 * the trampoline code can't handle CR4.PCIDE and
-			 * it wouldn't do any good anyway.  Despite the name,
-			 * cr4_set_bits_and_update_boot() doesn't actually
-			 * cause the bits in question to remain set all the
-			 * way through the secondary boot asm.
-			 *
-			 * Instead, we brute-force it and set CR4.PCIDE
-			 * manually in start_secondary().
-			 */
-			cr4_set_bits(X86_CR4_PCIDE);
-		} else {
-			/*
-			 * flush_tlb_all(), as currently implemented, won't
-			 * work if PCID is on but PGE is not.  Since that
-			 * combination doesn't exist on real hardware, there's
-			 * no reason to try to fully support it, but it's
-			 * polite to avoid corrupting data if we're on
-			 * an improperly configured VM.
-			 */
+	if (!IS_ENABLED(CONFIG_X86_64))
+		return;
+
+	if (!boot_cpu_has(X86_FEATURE_PCID))
+		return;
+
+	if (boot_cpu_has(X86_FEATURE_PGE)) {
+		/*
+		 * KAISER uses a PCID for the kernel and another
+		 * for userspace.  Both PCIDs need to be flushed
+		 * when the TLB flush functions are called.  But,
+		 * flushing *another* PCID is insane without
+		 * INVPCID.  Just avoid using PCIDs at all if we
+		 * have KAISER and do not have INVPCID.
+		 */
+		if (!IS_ENABLED(CONFIG_X86_GLOBAL_PAGES) &&
+		    !boot_cpu_has(X86_FEATURE_INVPCID)) {
 			setup_clear_cpu_cap(X86_FEATURE_PCID);
+			return;
 		}
+		/*
+		 * This can't be cr4_set_bits_and_update_boot() --
+		 * the trampoline code can't handle CR4.PCIDE and
+		 * it wouldn't do any good anyway.  Despite the name,
+		 * cr4_set_bits_and_update_boot() doesn't actually
+		 * cause the bits in question to remain set all the
+		 * way through the secondary boot asm.
+		 *
+		 * Instead, we brute-force it and set CR4.PCIDE
+		 * manually in start_secondary().
+		 */
+		cr4_set_bits(X86_CR4_PCIDE);
+
+		/*
+		 * INVPCID's single-context modes (2/3) only work
+		 * if we set X86_CR4_PCIDE, *and* we INVPCID
+		 * support.  It's unusable on systems that have
+		 * X86_CR4_PCIDE clear, or that have no INVPCID
+		 * support at all.
+		 */
+		if (boot_cpu_has(X86_FEATURE_INVPCID))
+			setup_force_cpu_cap(X86_FEATURE_INVPCID_SINGLE);
+	} else {
+		/*
+		 * flush_tlb_all(), as currently implemented, won't
+		 * work if PCID is on but PGE is not.  Since that
+		 * combination doesn't exist on real hardware, there's
+		 * no reason to try to fully support it, but it's
+		 * polite to avoid corrupting data if we're on
+		 * an improperly configured VM.
+		 */
+		setup_clear_cpu_cap(X86_FEATURE_PCID);
 	}
-#endif
 }
 
 #ifdef CONFIG_X86_32
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 81941f1690fa..f75b6eb47a6d 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -100,6 +100,68 @@ static void choose_new_asid(struct mm_struct *next, u64 next_tlb_gen,
 	*need_flush = true;
 }
 
+/*
+ * Given a kernel asid, flush the corresponding KAISER
+ * user ASID.
+ */
+static void flush_user_asid(pgd_t *pgd, u16 kern_asid)
+{
+	/* There is no user ASID if KAISER is off */
+	if (!IS_ENABLED(CONFIG_KAISER))
+		return;
+	/*
+	 * We only have a single ASID if PCID is off and the CR3
+	 * write will have flushed it.
+	 */
+	if (!cpu_feature_enabled(X86_FEATURE_PCID))
+		return;
+	/*
+	 * With PCIDs enabled, write_cr3() only flushes TLB
+	 * entries for the current (kernel) ASID.  This leaves
+	 * old TLB entries for the user ASID in place and we must
+	 * flush that context separately.  We can theoretically
+	 * delay doing this until we actually load up the
+	 * userspace CR3, but do it here for simplicity.
+	 */
+	if (cpu_feature_enabled(X86_FEATURE_INVPCID)) {
+		invpcid_flush_single_context(user_asid(kern_asid));
+	} else {
+		/*
+		 * On systems with PCIDs, but no INVPCID, the only
+		 * way to flush a PCID is a CR3 write.  Note that
+		 * we use the kernel page tables with the *user*
+		 * ASID here.
+		 */
+		unsigned long user_asid_flush_cr3;
+		user_asid_flush_cr3 = build_cr3(pgd, user_asid(kern_asid));
+		write_cr3(user_asid_flush_cr3);
+		/*
+		 * We do not use PCIDs with KAISER unless we also
+		 * have INVPCID.  Getting here is unexpected.
+		 */
+		WARN_ON_ONCE(1);
+	}
+}
+
+static void load_new_mm_cr3(pgd_t *pgdir, u16 new_asid, bool need_flush)
+{
+	unsigned long new_mm_cr3;
+
+	if (need_flush) {
+		flush_user_asid(pgdir, new_asid);
+		new_mm_cr3 = build_cr3(pgdir, new_asid);
+	} else {
+		new_mm_cr3 = build_cr3_noflush(pgdir, new_asid);
+	}
+
+	/*
+	 * Caution: many callers of this function expect
+	 * that load_cr3() is serializing and orders TLB
+	 * fills with respect to the mm_cpumask writes.
+	 */
+	write_cr3(new_mm_cr3);
+}
+
 void leave_mm(int cpu)
 {
 	struct mm_struct *loaded_mm = this_cpu_read(cpu_tlbstate.loaded_mm);
@@ -230,7 +292,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
 		if (need_flush) {
 			this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id);
 			this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen);
-			write_cr3(build_cr3(next->pgd, new_asid));
+			load_new_mm_cr3(next->pgd, new_asid, true);
 
 			/*
 			 * NB: This gets called via leave_mm() in the idle path
@@ -243,7 +305,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
 			trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
 		} else {
 			/* The new ASID is already up to date. */
-			write_cr3(build_cr3_noflush(next->pgd, new_asid));
+			load_new_mm_cr3(next->pgd, new_asid, false);
 
 			/* See above wrt _rcuidle. */
 			trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, 0);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 17/24] x86/mm/kaiser: Disable native VSYSCALL
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (15 preceding siblings ...)
  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-27 10:49 ` Ingo Molnar
  2017-11-27 10:49 ` [PATCH 18/24] x86/mm/kaiser: Add Kconfig Ingo Molnar
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

The KAISER code attempts to "poison" the user portion of the kernel page
tables. It detects entries that it wants that it wants to poison in two
ways:

 * Looking for addresses >= PAGE_OFFSET

 * Looking for entries without _PAGE_USER set

But, to allow the _PAGE_USER check to work, it must never be set on
init_mm entries, and an earlier patch in this series ensured that it
will never be set.

The VDSO is at a address >= PAGE_OFFSET and it is also mapped by init_mm.
Because of the earlier, KAISER-enforced restriction, _PAGE_USER is never
set which makes the VDSO unreadable to userspace.

This makes the "NATIVE" case totally unusable since userspace can not
even see the memory any more.  Disable it whenever KAISER is enabled.

Also add some help text about how KAISER might affect the emulation
case as well.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003513.10CAD896@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/Kconfig | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 09dcc94c4484..d23cd2902b10 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2249,6 +2249,9 @@ choice
 
 	config LEGACY_VSYSCALL_NATIVE
 		bool "Native"
+		# The VSYSCALL page comes from the kernel page tables
+		# and is not available when KAISER is enabled.
+		depends on ! KAISER
 		help
 		  Actual executable code is located in the fixed vsyscall
 		  address mapping, implementing time() efficiently. Since
@@ -2266,6 +2269,11 @@ choice
 		  exploits. This configuration is recommended when userspace
 		  still uses the vsyscall area.
 
+		  When KAISER is enabled, the vsyscall area will become
+		  unreadable.  This emulation option still works, but KAISER
+		  will make it harder to do things like trace code using the
+		  emulation.
+
 	config LEGACY_VSYSCALL_NONE
 		bool "None"
 		help
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 18/24] x86/mm/kaiser: Add Kconfig
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (16 preceding siblings ...)
  2017-11-27 10:49 ` [PATCH 17/24] x86/mm/kaiser: Disable native VSYSCALL Ingo Molnar
@ 2017-11-27 10:49 ` Ingo Molnar
  2017-11-27 10:49 ` [PATCH 19/24] x86/mm/kaiser: Respect disabled CPU features Ingo Molnar
                   ` (7 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Dave Hansen <dave.hansen@linux.intel.com>

Finally allow CONFIG_KAISER to be enabled.

PARAVIRT generally requires that the kernel not manage its own page
tables.  It also means that the hypervisor and kernel must agree
wholeheartedly about what format the page tables are in and what
they contain.  KAISER, unfortunately, changes the rules and they
can not be used together.

I've seen conflicting feedback from maintainers lately about whether
they want the Kconfig magic to go first or last in a patch series.
It's going last here because the partially-applied series leads to
kernels that can not boot in a bunch of cases.  I did a run through
the entire series with CONFIG_KAISER=y to look for build errors,
though.

Note from Hugh Dickins on why it depends on SMP:

	It is absurd that KAISER should depend on SMP, but
	apparently nobody has tried a UP build before: which
	breaks on implicit declaration of function
	'per_cpu_offset' in arch/x86/mm/kaiser.c.

	Now, you would expect that to be trivially fixed up; but
	looking at the System.map when that block is #ifdef'ed
	out of kaiser_init(), I see that in a UP build
	__per_cpu_user_mapped_end is precisely at
	__per_cpu_user_mapped_start, and the items carefully
	gathered into that section for user-mapping on SMP,
	dispersed elsewhere on UP.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
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: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003524.88C90659@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 security/Kconfig | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/security/Kconfig b/security/Kconfig
index e8e449444e65..99b530d0dd9e 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -54,6 +54,16 @@ config SECURITY_NETWORK
 	  implement socket and networking access controls.
 	  If you are unsure how to answer this question, answer N.
 
+config KAISER
+	bool "Remove the kernel mapping in user mode"
+	depends on X86_64 && SMP && !PARAVIRT
+	help
+	  This feature reduces the number of hardware side channels by
+	  ensuring that the majority of kernel addresses are not mapped
+	  into userspace.
+
+	  See Documentation/x86/kaiser.txt for more details.
+
 config SECURITY_INFINIBAND
 	bool "Infiniband Security Hooks"
 	depends on SECURITY && INFINIBAND
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 19/24] x86/mm/kaiser: Respect disabled CPU features
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (17 preceding siblings ...)
  2017-11-27 10:49 ` [PATCH 18/24] x86/mm/kaiser: Add Kconfig Ingo Molnar
@ 2017-11-27 10:49 ` Ingo Molnar
  2017-11-27 10:49 ` [PATCH 20/24] x86/mm/kaiser: Simplify disabling of global pages Ingo Molnar
                   ` (6 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Thomas Gleixner <tglx@linutronix.de>

PAGE_NX and PAGE_GLOBAL might not be supported, or migth be disabled
on the command line, but Kaiser sets them unconditionally.

Add proper protection against that.

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.313869499@linutronix.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/pgtable_64.h |  3 ++-
 arch/x86/mm/kaiser.c              | 12 +++++++++++-
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index 0c6e14f1e274..1c9f1f803ad8 100644
--- a/arch/x86/include/asm/pgtable_64.h
+++ b/arch/x86/include/asm/pgtable_64.h
@@ -222,7 +222,8 @@ static inline pgd_t kaiser_set_shadow_pgd(pgd_t *pgdp, pgd_t pgd)
 			 * wrong CR3 value, userspace will crash
 			 * instead of running.
 			 */
-			pgd.pgd |= _PAGE_NX;
+			if (__supported_pte_mask & _PAGE_NX)
+				pgd.pgd |= _PAGE_NX;
 		}
 	} else if (pgd_userspace_access(*pgdp)) {
 		/*
diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c
index 10c0e9e6bf6b..6e3c5da5f7e8 100644
--- a/arch/x86/mm/kaiser.c
+++ b/arch/x86/mm/kaiser.c
@@ -42,6 +42,8 @@
 
 #define KAISER_WALK_ATOMIC  0x1
 
+static pteval_t kaiser_pte_mask __ro_after_init = ~(_PAGE_NX | _PAGE_GLOBAL);
+
 /*
  * At runtime, the only things we map are some things for CPU
  * hotplug, and stacks for new processes.  No two CPUs will ever
@@ -244,11 +246,14 @@ static pte_t *kaiser_shadow_pagetable_walk(unsigned long address,
 int kaiser_add_user_map(const void *__start_addr, unsigned long size,
 			unsigned long flags)
 {
-	pte_t *pte;
 	unsigned long start_addr = (unsigned long)__start_addr;
 	unsigned long address = start_addr & PAGE_MASK;
 	unsigned long end_addr = PAGE_ALIGN(start_addr + size);
 	unsigned long target_address;
+	pte_t *pte;
+
+	/* Clear not supported bits */
+	flags &= kaiser_pte_mask;
 
 	for (; address < end_addr; address += PAGE_SIZE) {
 		target_address = get_pa_from_kernel_map(address);
@@ -308,6 +313,11 @@ static void __init kaiser_init_all_pgds(void)
 	pgd_t *pgd;
 	int i;
 
+	if (__supported_pte_mask & _PAGE_NX)
+		kaiser_pte_mask |= _PAGE_NX;
+	if (boot_cpu_has(X86_FEATURE_PGE))
+		kaiser_pte_mask |= _PAGE_GLOBAL;
+
 	pgd = kernel_to_shadow_pgdp(pgd_offset_k(0UL));
 	for (i = PTRS_PER_PGD / 2; i < PTRS_PER_PGD; i++) {
 		/*
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 20/24] x86/mm/kaiser: Simplify disabling of global pages
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (18 preceding siblings ...)
  2017-11-27 10:49 ` [PATCH 19/24] x86/mm/kaiser: Respect disabled CPU features Ingo Molnar
@ 2017-11-27 10:49 ` Ingo Molnar
  2017-11-27 10:49 ` [PATCH 21/24] x86/mm/dump_pagetables: Check Kaiser shadow page table for WX pages Ingo Molnar
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Thomas Gleixner <tglx@linutronix.de>

The current way of disabling global pages at compile time prevents boot
time disabling of Kaiser and creates unnecessary indirections.

Global pages can be supressed by __supported_pte_mask as well. The shadow
mappings set PAGE_GLOBAL for the minimal kernel mappings which are required
for entry/exit. These mappings are set up manually so the filtering does not
take place.

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.393912629@linutronix.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/pgtable_types.h | 16 +---------------
 arch/x86/mm/init.c                   | 13 ++++++++++---
 arch/x86/mm/pageattr.c               | 16 ++++++++--------
 3 files changed, 19 insertions(+), 26 deletions(-)

diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index 503bb6999a75..289dde8a9eb3 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -191,23 +191,9 @@ enum page_cache_mode {
 #define PAGE_READONLY_EXEC	__pgprot(_PAGE_PRESENT | _PAGE_USER |	\
 					 _PAGE_ACCESSED)
 
-/*
- * Disable global pages for anything using the default
- * __PAGE_KERNEL* macros.
- *
- * PGE will still be enabled and _PAGE_GLOBAL may still be used carefully
- * for a few selected kernel mappings which must be visible to userspace,
- * when KAISER is enabled, like the entry/exit code and data.
- */
-#ifdef CONFIG_KAISER
-#define __PAGE_KERNEL_GLOBAL	0
-#else
-#define __PAGE_KERNEL_GLOBAL	_PAGE_GLOBAL
-#endif
-
 #define __PAGE_KERNEL_EXEC						\
 	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED |	\
-	 __PAGE_KERNEL_GLOBAL)
+	 _PAGE_GLOBAL)
 #define __PAGE_KERNEL		(__PAGE_KERNEL_EXEC | _PAGE_NX)
 
 #define __PAGE_KERNEL_RO		(__PAGE_KERNEL & ~_PAGE_RW)
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 9618e57d46cf..7c0126835f22 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -161,6 +161,13 @@ struct map_range {
 
 static int page_size_mask;
 
+static void enable_global_pages(void)
+{
+#ifndef CONFIG_KAISER
+	__supported_pte_mask |= _PAGE_GLOBAL;
+#endif
+}
+
 static void __init probe_page_size_mask(void)
 {
 	/*
@@ -179,11 +186,11 @@ static void __init probe_page_size_mask(void)
 		cr4_set_bits_and_update_boot(X86_CR4_PSE);
 
 	/* Enable PGE if available */
+	__supported_pte_mask |= _PAGE_GLOBAL;
 	if (boot_cpu_has(X86_FEATURE_PGE)) {
 		cr4_set_bits_and_update_boot(X86_CR4_PGE);
-		__supported_pte_mask |= _PAGE_GLOBAL;
-	} else
-		__supported_pte_mask &= ~_PAGE_GLOBAL;
+		enable_global_pages();
+	}
 
 	/* Enable 1 GB linear kernel mappings if available: */
 	if (direct_gbpages && boot_cpu_has(X86_FEATURE_GBPAGES)) {
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 1b3dbf3b3846..f09d8b362194 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -585,9 +585,9 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
 	 * for the ancient hardware that doesn't support it.
 	 */
 	if (pgprot_val(req_prot) & _PAGE_PRESENT)
-		pgprot_val(req_prot) |= _PAGE_PSE | __PAGE_KERNEL_GLOBAL;
+		pgprot_val(req_prot) |= _PAGE_PSE | _PAGE_GLOBAL;
 	else
-		pgprot_val(req_prot) &= ~(_PAGE_PSE | __PAGE_KERNEL_GLOBAL);
+		pgprot_val(req_prot) &= ~(_PAGE_PSE | _PAGE_GLOBAL);
 
 	req_prot = canon_pgprot(req_prot);
 
@@ -705,9 +705,9 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
 	 * for the ancient hardware that doesn't support it.
 	 */
 	if (pgprot_val(ref_prot) & _PAGE_PRESENT)
-		pgprot_val(ref_prot) |= __PAGE_KERNEL_GLOBAL;
+		pgprot_val(ref_prot) |= _PAGE_GLOBAL;
 	else
-		pgprot_val(ref_prot) &= ~__PAGE_KERNEL_GLOBAL;
+		pgprot_val(ref_prot) &= ~_PAGE_GLOBAL;
 
 	/*
 	 * Get the target pfn from the original entry:
@@ -938,9 +938,9 @@ static void populate_pte(struct cpa_data *cpa,
 	 * support it.
 	 */
 	if (pgprot_val(pgprot) & _PAGE_PRESENT)
-		pgprot_val(pgprot) |= __PAGE_KERNEL_GLOBAL;
+		pgprot_val(pgprot) |= _PAGE_GLOBAL;
 	else
-		pgprot_val(pgprot) &= ~__PAGE_KERNEL_GLOBAL;
+		pgprot_val(pgprot) &= ~_PAGE_GLOBAL;
 
 	pgprot = canon_pgprot(pgprot);
 
@@ -1242,9 +1242,9 @@ static int __change_page_attr(struct cpa_data *cpa, int primary)
 		 * support it.
 		 */
 		if (pgprot_val(new_prot) & _PAGE_PRESENT)
-			pgprot_val(new_prot) |= __PAGE_KERNEL_GLOBAL;
+			pgprot_val(new_prot) |= _PAGE_GLOBAL;
 		else
-			pgprot_val(new_prot) &= ~__PAGE_KERNEL_GLOBAL;
+			pgprot_val(new_prot) &= ~_PAGE_GLOBAL;
 
 		/*
 		 * We need to keep the pfn from the existing PTE,
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 21/24] x86/mm/dump_pagetables: Check Kaiser shadow page table for WX pages
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (19 preceding siblings ...)
  2017-11-27 10:49 ` [PATCH 20/24] x86/mm/kaiser: Simplify disabling of global pages Ingo Molnar
@ 2017-11-27 10:49 ` Ingo Molnar
  2017-11-27 10:49 ` [PATCH 22/24] x86/mm/debug_pagetables: Allow dumping current pagetables Ingo Molnar
                   ` (4 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Thomas Gleixner <tglx@linutronix.de>

ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the Kaiser shadow page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL.
Add the check for the shadow page table.

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.481903103@linutronix.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/pgtable.h |  1 +
 arch/x86/mm/debug_pagetables.c |  2 +-
 arch/x86/mm/dump_pagetables.c  | 27 ++++++++++++++++++++++-----
 3 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 9cceaf6c0405..75d1dc090072 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD];
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 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);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
diff --git a/arch/x86/mm/debug_pagetables.c b/arch/x86/mm/debug_pagetables.c
index bfcffdf6c577..9b627b7eabd4 100644
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-	ptdump_walk_pgd_level(m, NULL);
+	ptdump_walk_pgd_level_debugfs(m, NULL);
 	return 0;
 }
 
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index 5e3ac6fe6c9e..535ed1fe4897 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -447,7 +447,7 @@ static inline bool is_hypervisor_range(int idx)
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-				       bool checkwx)
+				       bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
 	pgd_t *start = (pgd_t *) &init_top_pgt;
@@ -460,7 +460,7 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
 
 	if (pgd) {
 		start = pgd;
-		st.to_dmesg = true;
+		st.to_dmesg = dmesg;
 	}
 
 	st.check_wx = checkwx;
@@ -498,13 +498,30 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-	ptdump_walk_pgd_level_core(m, pgd, false);
+	ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+	ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+void ptdump_walk_shadow_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_KAISER
+	pgd_t *pgd = (pgd_t *) &init_top_pgt;
+
+	pr_info("x86/mm: Checking shadow page tables\n");
+	pgd += PTRS_PER_PGD;
+	ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-	ptdump_walk_pgd_level_core(NULL, NULL, true);
+	ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+	ptdump_walk_shadow_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 22/24] x86/mm/debug_pagetables: Allow dumping current pagetables
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (20 preceding siblings ...)
  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 ` Ingo Molnar
  2017-11-27 10:49 ` [PATCH 23/24] x86/mm/kaiser: Add boot time disable switch Ingo Molnar
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Thomas Gleixner <tglx@linutronix.de>

Add two debugfs files which allow to dump the pagetable of the current task.

current_page_tables_knl dumps the regular page table. This is the page
table which is normally shared between kernel and user space. If Kaiser is
enabled this is the kernel space mapping.

If Kaiser is enabled the second file, current_page_tables_usr, dumps the
user space page table.

These files allow to verify the resulting page tables for Kaiser, but even
in the non Kaiser case its useful to be able to inspect user space page
tables of current for debugging purposes.

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.563046145@linutronix.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/pgtable.h |  2 +-
 arch/x86/mm/debug_pagetables.c | 81 ++++++++++++++++++++++++++++++++++++++----
 arch/x86/mm/dump_pagetables.c  |  4 ++-
 3 files changed, 79 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 75d1dc090072..6a05e23ea1a9 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,7 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD];
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 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);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd, bool shadow);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
diff --git a/arch/x86/mm/debug_pagetables.c b/arch/x86/mm/debug_pagetables.c
index 9b627b7eabd4..ec0d8930fab3 100644
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-	ptdump_walk_pgd_level_debugfs(m, NULL);
+	ptdump_walk_pgd_level_debugfs(m, NULL, false);
 	return 0;
 }
 
@@ -22,21 +22,90 @@ static const struct file_operations ptdump_fops = {
 	.release	= single_release,
 };
 
-static struct dentry *pe;
+static int ptdump_show_curknl(struct seq_file *m, void *v)
+{
+	if (current->mm->pgd) {
+		down_read(&current->mm->mmap_sem);
+		ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, false);
+		up_read(&current->mm->mmap_sem);
+	}
+	return 0;
+}
+
+static int ptdump_open_curknl(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, ptdump_show_curknl, NULL);
+}
+
+static const struct file_operations ptdump_curknl_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ptdump_open_curknl,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+#ifdef CONFIG_KAISER
+static int ptdump_show_curusr(struct seq_file *m, void *v)
+{
+	if (current->mm->pgd) {
+		down_read(&current->mm->mmap_sem);
+		ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, true);
+		up_read(&current->mm->mmap_sem);
+	}
+	return 0;
+}
+
+static int ptdump_open_curusr(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, ptdump_show_curusr, NULL);
+}
+
+static const struct file_operations ptdump_curusr_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ptdump_open_curusr,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+#endif
+
+static struct dentry *pe_knl, *pe_curknl, *pe_curusr;
+
+static void pt_dump_debug_remove_files(void)
+{
+	debugfs_remove_recursive(pe_knl);
+	debugfs_remove_recursive(pe_curknl);
+	debugfs_remove_recursive(pe_curusr);
+}
 
 static int __init pt_dump_debug_init(void)
 {
-	pe = debugfs_create_file("kernel_page_tables", S_IRUSR, NULL, NULL,
-				 &ptdump_fops);
-	if (!pe)
+	pe_knl = debugfs_create_file("kernel_page_tables", S_IRUSR, NULL, NULL,
+				     &ptdump_fops);
+	if (!pe_knl)
 		return -ENOMEM;
 
+	pe_curknl = debugfs_create_file("current_page_tables_knl", S_IRUSR,
+					NULL, NULL, &ptdump_curknl_fops);
+	if (!pe_curknl)
+		goto err;
+
+#ifdef CONFIG_KAISER
+	pe_curusr = debugfs_create_file("current_page_tables_usr", S_IRUSR,
+					NULL, NULL, &ptdump_curusr_fops);
+	if (!pe_curusr)
+		goto err;
+#endif
 	return 0;
+err:
+	pt_dump_debug_remove_files();
+	return -ENOMEM;
 }
 
 static void __exit pt_dump_debug_exit(void)
 {
-	debugfs_remove_recursive(pe);
+	pt_dump_debug_remove_files();
 }
 
 module_init(pt_dump_debug_init);
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index 535ed1fe4897..6560b932dd02 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -501,8 +501,10 @@ void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 	ptdump_walk_pgd_level_core(m, pgd, false, true);
 }
 
-void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd, bool shadow)
 {
+	if (shadow)
+		pgd += PTRS_PER_PGD;
 	ptdump_walk_pgd_level_core(m, pgd, false, false);
 }
 EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 23/24] x86/mm/kaiser: Add boot time disable switch
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (21 preceding siblings ...)
  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
  2017-11-27 10:49 ` [PATCH 24/24] x86/mm/kaiser: Use the other page_table_lock pattern Ingo Molnar
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

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

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 24/24] x86/mm/kaiser: Use the other page_table_lock pattern
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (22 preceding siblings ...)
  2017-11-27 10:49 ` [PATCH 23/24] x86/mm/kaiser: Add boot time disable switch Ingo Molnar
@ 2017-11-27 10:49 ` Ingo Molnar
  2017-11-27 13:51 ` [PATCH 00/24] x86/mm: Add KAISER support Borislav Petkov
  2017-11-27 19:43 ` Linus Torvalds
  25 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 10:49 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

From: Peter Zijlstra <peterz@infradead.org>

Use the other page_table_lock pattern; this removes the free from
under the lock, reducing worst case hold times and makes it a leaf
lock.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20171127085906.uth5hldrtbbqsnkr@hirez.programming.kicks-ass.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/mm/kaiser.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c
index 0282169ede18..0ff502fa655b 100644
--- a/arch/x86/mm/kaiser.c
+++ b/arch/x86/mm/kaiser.c
@@ -196,11 +196,13 @@ static pte_t *kaiser_shadow_pagetable_walk(unsigned long address,
 			return NULL;
 
 		spin_lock(&shadow_table_allocation_lock);
-		if (p4d_none(*p4d))
+		if (p4d_none(*p4d)) {
 			set_p4d(p4d, __p4d(_KERNPG_TABLE | __pa(new_pud_page)));
-		else
-			free_page(new_pud_page);
+			new_pud_page = 0;
+		}
 		spin_unlock(&shadow_table_allocation_lock);
+		if (new_pud_page)
+			free_page(new_pud_page);
 	}
 
 	pud = pud_offset(p4d, address);
@@ -215,11 +217,13 @@ static pte_t *kaiser_shadow_pagetable_walk(unsigned long address,
 			return NULL;
 
 		spin_lock(&shadow_table_allocation_lock);
-		if (pud_none(*pud))
+		if (pud_none(*pud)) {
 			set_pud(pud, __pud(_KERNPG_TABLE | __pa(new_pmd_page)));
-		else
-			free_page(new_pmd_page);
+			new_pmd_page = 0;
+		}
 		spin_unlock(&shadow_table_allocation_lock);
+		if (new_pmd_page)
+			free_page(new_pmd_page);
 	}
 
 	pmd = pmd_offset(pud, address);
@@ -234,11 +238,13 @@ static pte_t *kaiser_shadow_pagetable_walk(unsigned long address,
 			return NULL;
 
 		spin_lock(&shadow_table_allocation_lock);
-		if (pmd_none(*pmd))
+		if (pmd_none(*pmd)) {
 			set_pmd(pmd, __pmd(_KERNPG_TABLE  | __pa(new_pte_page)));
-		else
-			free_page(new_pte_page);
+			new_pte_page = 0;
+		}
 		spin_unlock(&shadow_table_allocation_lock);
+		if (new_pte_page)
+			free_page(new_pte_page);
 	}
 
 	pte = pte_offset_kernel(pmd, address);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/24] x86/mm: Add KAISER support
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (23 preceding siblings ...)
  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 ` Borislav Petkov
  2017-11-27 13:57   ` Thomas Gleixner
  2017-11-27 19:43 ` Linus Torvalds
  25 siblings, 1 reply; 70+ messages in thread
From: Borislav Petkov @ 2017-11-27 13:51 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Dave Hansen, Andy Lutomirski, Thomas Gleixner,
	H . Peter Anvin, Peter Zijlstra, Linus Torvalds

[-- Attachment #1: Type: text/plain, Size: 1046 bytes --]

On Mon, Nov 27, 2017 at 11:48:59AM +0100, Ingo Molnar wrote:
> Sending this out for another round of review.
> 
> These are the main KAISER patches, on top of the preparatory series I just sent.
> This includes KAISER support plus enhancements on top, all the latest code.
> 
> ( All review feedback so far is incorporated - if anything is missing please
>   let me know. )

Something's missing:

arch/x86/boot/compressed/pagetable.o: In function `kernel_ident_mapping_init':
pagetable.c:(.text+0x3cc): undefined reference to `kaiser_enabled'
pagetable.c:(.text+0x400): undefined reference to `__supported_pte_mask'
pagetable.c:(.text+0x473): undefined reference to `system_state'
make[2]: *** [arch/x86/boot/compressed/vmlinux] Error 1
make[1]: *** [arch/x86/boot/compressed/vmlinux] Error 2
make: *** [bzImage] Error 2
make: *** Waiting for unfinished jobs....

I suspect it is that core patch but need to stare at it more. .config
attached.

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 47160 bytes --]

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/24] x86/mm: Add KAISER support
  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
  0 siblings, 1 reply; 70+ messages in thread
From: Thomas Gleixner @ 2017-11-27 13:57 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Ingo Molnar, linux-kernel, Dave Hansen, Andy Lutomirski,
	H . Peter Anvin, Peter Zijlstra, Linus Torvalds

On Mon, 27 Nov 2017, Borislav Petkov wrote:
> On Mon, Nov 27, 2017 at 11:48:59AM +0100, Ingo Molnar wrote:
> > Sending this out for another round of review.
> > 
> > These are the main KAISER patches, on top of the preparatory series I just sent.
> > This includes KAISER support plus enhancements on top, all the latest code.
> > 
> > ( All review feedback so far is incorporated - if anything is missing please
> >   let me know. )
> 
> Something's missing:
> 
> arch/x86/boot/compressed/pagetable.o: In function `kernel_ident_mapping_init':
> pagetable.c:(.text+0x3cc): undefined reference to `kaiser_enabled'
> pagetable.c:(.text+0x400): undefined reference to `__supported_pte_mask'
> pagetable.c:(.text+0x473): undefined reference to `system_state'
> make[2]: *** [arch/x86/boot/compressed/vmlinux] Error 1
> make[1]: *** [arch/x86/boot/compressed/vmlinux] Error 2
> make: *** [bzImage] Error 2
> make: *** Waiting for unfinished jobs....
> 
> I suspect it is that core patch but need to stare at it more. .config
> attached.

That's the core patch plus the run time enablement I did.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/24] x86/mm: Add KAISER support
  2017-11-27 13:57   ` Thomas Gleixner
@ 2017-11-27 13:59     ` Borislav Petkov
  2017-11-27 14:03       ` Ingo Molnar
  0 siblings, 1 reply; 70+ messages in thread
From: Borislav Petkov @ 2017-11-27 13:59 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Ingo Molnar, linux-kernel, Dave Hansen, Andy Lutomirski,
	H . Peter Anvin, Peter Zijlstra, Linus Torvalds

On Mon, Nov 27, 2017 at 02:57:17PM +0100, Thomas Gleixner wrote:
> On Mon, 27 Nov 2017, Borislav Petkov wrote:
> > On Mon, Nov 27, 2017 at 11:48:59AM +0100, Ingo Molnar wrote:
> > > Sending this out for another round of review.
> > > 
> > > These are the main KAISER patches, on top of the preparatory series I just sent.
> > > This includes KAISER support plus enhancements on top, all the latest code.
> > > 
> > > ( All review feedback so far is incorporated - if anything is missing please
> > >   let me know. )
> > 
> > Something's missing:
> > 
> > arch/x86/boot/compressed/pagetable.o: In function `kernel_ident_mapping_init':
> > pagetable.c:(.text+0x3cc): undefined reference to `kaiser_enabled'
> > pagetable.c:(.text+0x400): undefined reference to `__supported_pte_mask'
> > pagetable.c:(.text+0x473): undefined reference to `system_state'
> > make[2]: *** [arch/x86/boot/compressed/vmlinux] Error 1
> > make[1]: *** [arch/x86/boot/compressed/vmlinux] Error 2
> > make: *** [bzImage] Error 2
> > make: *** Waiting for unfinished jobs....
> > 
> > I suspect it is that core patch but need to stare at it more. .config
> > attached.
> 
> That's the core patch plus the run time enablement I did.

Right, and I think the fix is as simple as this because we don't care
about kaiser in the bootstrap kernel:

---
diff --git a/arch/x86/boot/compressed/pagetable.c b/arch/x86/boot/compressed/pagetable.c
index d5364ca2e3f9..63eaa71ad9f1 100644
--- a/arch/x86/boot/compressed/pagetable.c
+++ b/arch/x86/boot/compressed/pagetable.c
@@ -22,6 +22,7 @@
  * the SME support to avoid any compile and link errors.
  */
 #undef CONFIG_AMD_MEM_ENCRYPT
+#undef CONFIG_KAISER
 
 #include "misc.h"
 


-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/24] x86/mm: Add KAISER support
  2017-11-27 13:59     ` Borislav Petkov
@ 2017-11-27 14:03       ` Ingo Molnar
  2017-11-27 14:08         ` Ingo Molnar
  0 siblings, 1 reply; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 14:03 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Thomas Gleixner, linux-kernel, Dave Hansen, Andy Lutomirski,
	H . Peter Anvin, Peter Zijlstra, Linus Torvalds


* Borislav Petkov <bp@alien8.de> wrote:

> On Mon, Nov 27, 2017 at 02:57:17PM +0100, Thomas Gleixner wrote:
> > On Mon, 27 Nov 2017, Borislav Petkov wrote:
> > > On Mon, Nov 27, 2017 at 11:48:59AM +0100, Ingo Molnar wrote:
> > > > Sending this out for another round of review.
> > > > 
> > > > These are the main KAISER patches, on top of the preparatory series I just sent.
> > > > This includes KAISER support plus enhancements on top, all the latest code.
> > > > 
> > > > ( All review feedback so far is incorporated - if anything is missing please
> > > >   let me know. )
> > > 
> > > Something's missing:
> > > 
> > > arch/x86/boot/compressed/pagetable.o: In function `kernel_ident_mapping_init':
> > > pagetable.c:(.text+0x3cc): undefined reference to `kaiser_enabled'
> > > pagetable.c:(.text+0x400): undefined reference to `__supported_pte_mask'
> > > pagetable.c:(.text+0x473): undefined reference to `system_state'
> > > make[2]: *** [arch/x86/boot/compressed/vmlinux] Error 1
> > > make[1]: *** [arch/x86/boot/compressed/vmlinux] Error 2
> > > make: *** [bzImage] Error 2
> > > make: *** Waiting for unfinished jobs....
> > > 
> > > I suspect it is that core patch but need to stare at it more. .config
> > > attached.
> > 
> > That's the core patch plus the run time enablement I did.
> 
> Right, and I think the fix is as simple as this because we don't care
> about kaiser in the bootstrap kernel:
> 
> ---
> diff --git a/arch/x86/boot/compressed/pagetable.c b/arch/x86/boot/compressed/pagetable.c
> index d5364ca2e3f9..63eaa71ad9f1 100644
> --- a/arch/x86/boot/compressed/pagetable.c
> +++ b/arch/x86/boot/compressed/pagetable.c
> @@ -22,6 +22,7 @@
>   * the SME support to avoid any compile and link errors.
>   */
>  #undef CONFIG_AMD_MEM_ENCRYPT
> +#undef CONFIG_KAISER
>  
>  #include "misc.h"

Yeah - will use one with a bit more explanation:

 arch/x86/boot/compressed/pagetable.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/x86/boot/compressed/pagetable.c b/arch/x86/boot/compressed/pagetable.c
index d5364ca2e3f9..6bd51de4475c 100644
--- a/arch/x86/boot/compressed/pagetable.c
+++ b/arch/x86/boot/compressed/pagetable.c
@@ -23,6 +23,11 @@
  */
 #undef CONFIG_AMD_MEM_ENCRYPT
 
+/*
+ * No KAISER support needed either:
+ */
+#undef CONFIG_KAISER
+
 #include "misc.h"
 
 /* These actually do the work of building the kernel identity maps. */

Thanks,

	Ingo

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/24] x86/mm: Add KAISER support
  2017-11-27 14:03       ` Ingo Molnar
@ 2017-11-27 14:08         ` Ingo Molnar
  0 siblings, 0 replies; 70+ messages in thread
From: Ingo Molnar @ 2017-11-27 14:08 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Thomas Gleixner, linux-kernel, Dave Hansen, Andy Lutomirski,
	H . Peter Anvin, Peter Zijlstra, Linus Torvalds


* Ingo Molnar <mingo@kernel.org> wrote:

> > diff --git a/arch/x86/boot/compressed/pagetable.c b/arch/x86/boot/compressed/pagetable.c
> > index d5364ca2e3f9..63eaa71ad9f1 100644
> > --- a/arch/x86/boot/compressed/pagetable.c
> > +++ b/arch/x86/boot/compressed/pagetable.c
> > @@ -22,6 +22,7 @@
> >   * the SME support to avoid any compile and link errors.
> >   */
> >  #undef CONFIG_AMD_MEM_ENCRYPT
> > +#undef CONFIG_KAISER
> >  
> >  #include "misc.h"
> 
> Yeah - will use one with a bit more explanation:
> 
>  arch/x86/boot/compressed/pagetable.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/arch/x86/boot/compressed/pagetable.c b/arch/x86/boot/compressed/pagetable.c
> index d5364ca2e3f9..6bd51de4475c 100644
> --- a/arch/x86/boot/compressed/pagetable.c
> +++ b/arch/x86/boot/compressed/pagetable.c
> @@ -23,6 +23,11 @@
>   */
>  #undef CONFIG_AMD_MEM_ENCRYPT
>  
> +/*
> + * No KAISER support needed either:
> + */
> +#undef CONFIG_KAISER
> +
>  #include "misc.h"
>  
>  /* These actually do the work of building the kernel identity maps. */

Ok, have refreshed the -tip branches with this fix as well.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 04/24] x86/mm/kaiser: Unmap kernel mappings from userspace page tables, core patch
  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
  1 sibling, 2 replies; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-27 15:39 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Dave Hansen, Andy Lutomirski, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds


So I had the problem that I could not tell if my shiny new kernel had
this brand spanking awesome feature enabled or not.

Do we want something like so?

---
 arch/x86/mm/kaiser.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c
index 0ff502fa655b..655349e0b5fb 100644
--- a/arch/x86/mm/kaiser.c
+++ b/arch/x86/mm/kaiser.c
@@ -425,6 +425,8 @@ void __init kaiser_init(void)
 	if (!kaiser_enabled)
 		return;
 
+	pr_info("All your KAISER are belong to us.\n");
+
 	kaiser_init_all_pgds();
 
 	for_each_possible_cpu(cpu) {

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH 04/24] x86/mm/kaiser: Unmap kernel mappings from userspace page tables, core patch
  2017-11-27 15:39   ` Peter Zijlstra
@ 2017-11-27 17:04     ` Borislav Petkov
  2017-11-27 19:17     ` Dave Hansen
  1 sibling, 0 replies; 70+ messages in thread
From: Borislav Petkov @ 2017-11-27 17:04 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, linux-kernel, Dave Hansen, Andy Lutomirski,
	Thomas Gleixner, H . Peter Anvin, Linus Torvalds

On Mon, Nov 27, 2017 at 04:39:07PM +0100, Peter Zijlstra wrote:
> 
> So I had the problem that I could not tell if my shiny new kernel had
> this brand spanking awesome feature enabled or not.
> 
> Do we want something like so?
> 
> ---
>  arch/x86/mm/kaiser.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c
> index 0ff502fa655b..655349e0b5fb 100644
> --- a/arch/x86/mm/kaiser.c
> +++ b/arch/x86/mm/kaiser.c
> @@ -425,6 +425,8 @@ void __init kaiser_init(void)
>  	if (!kaiser_enabled)
>  		return;
>  
> +	pr_info("All your KAISER are belong to us.\n");
> +
>  	kaiser_init_all_pgds();
>  
>  	for_each_possible_cpu(cpu) {

Acked-by: Borislav Petkov <bp@suse.de>

And yes, the whimsical formulation is a nice touch among all those
serious dmesg spews.

:-)

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/24] x86/mm/kaiser: Map the entry stack variables
  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 17:29   ` Peter Zijlstra
  1 sibling, 1 reply; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-27 17:22 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Dave Hansen, Andy Lutomirski, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Mon, Nov 27, 2017 at 11:49:09AM +0100, Ingo Molnar wrote:
> diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
> index 157f81816915..631e229ab428 100644
> --- a/arch/x86/kernel/process_64.c
> +++ b/arch/x86/kernel/process_64.c
> @@ -59,7 +59,7 @@
>  #include <asm/unistd_32_ia32.h>
>  #endif
>  
> -__visible DEFINE_PER_CPU(unsigned long, rsp_scratch);
> +__visible DEFINE_PER_CPU_USER_MAPPED(unsigned long, rsp_scratch);
>  
>  /* Prints also some state that isn't saved in the pt_regs */
>  void __show_regs(struct pt_regs *regs, int all)

Do we still need this one? It appears to me we'll never actually execute
that part of entry_SYSCALL_64 anymore, due to
entry_SYSCALL_64_trampoline.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/24] x86/mm/kaiser: Map the entry stack variables
  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:29   ` Peter Zijlstra
  2017-11-27 17:32     ` Thomas Gleixner
  1 sibling, 1 reply; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-27 17:29 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Dave Hansen, Andy Lutomirski, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Mon, Nov 27, 2017 at 11:49:09AM +0100, Ingo Molnar wrote:
> diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
> index 7b348cc33e2d..f4f4ab8525bd 100644
> --- a/arch/x86/kernel/cpu/common.c
> +++ b/arch/x86/kernel/cpu/common.c
> @@ -1515,7 +1515,7 @@ EXPORT_PER_CPU_SYMBOL(__preempt_count);
>   * the top of the kernel stack.  Use an extra percpu variable to track the
>   * top of the kernel stack directly.
>   */
> -DEFINE_PER_CPU(unsigned long, cpu_current_top_of_stack) =
> +DEFINE_PER_CPU_USER_MAPPED(unsigned long, cpu_current_top_of_stack) =
>  	(unsigned long)&init_thread_union + THREAD_SIZE;
>  EXPORT_PER_CPU_SYMBOL(cpu_current_top_of_stack);

I can't find where we would access this one without already having
switched to kernel CR3.

A kernel with this entire patch reverted seems to boot for me.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 02/24] x86/mm/kaiser: Prepare the x86/entry assembly code for entry/exit CR3 switching
  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
  0 siblings, 1 reply; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-27 17:31 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Dave Hansen, Andy Lutomirski, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Mon, Nov 27, 2017 at 11:49:01AM +0100, Ingo Molnar wrote:
> diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
> index caf74a1bb3de..df0152bee8a8 100644

> @@ -198,6 +201,14 @@ ENTRY(entry_SYSCALL_64)
>  
>  	swapgs
>  	movq	%rsp, PER_CPU_VAR(rsp_scratch)
> +
> +	/*
> +	 * The kernel CR3 is needed to map the process stack, but we
> +	 * need a scratch register to be able to load CR3.  %rsp is
> +	 * clobberable right now, so use it as a scratch register.
> +	 * %rsp will look crazy here for a couple instructions.
> +	 */
> +	SWITCH_TO_KERNEL_CR3 scratch_reg=%rsp
>  	movq	PER_CPU_VAR(cpu_current_top_of_stack), %rsp
>  
>  	/* Construct struct pt_regs on stack */

I think we can do away with this one, on account of never getting here
because of entry_SYSCALL_64_trampoline.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/24] x86/mm/kaiser: Map the entry stack variables
  2017-11-27 17:22   ` Peter Zijlstra
@ 2017-11-27 17:32     ` Thomas Gleixner
  2017-11-27 21:00       ` Peter Zijlstra
  0 siblings, 1 reply; 70+ messages in thread
From: Thomas Gleixner @ 2017-11-27 17:32 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, linux-kernel, Dave Hansen, Andy Lutomirski,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Mon, 27 Nov 2017, Peter Zijlstra wrote:

> On Mon, Nov 27, 2017 at 11:49:09AM +0100, Ingo Molnar wrote:
> > diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
> > index 157f81816915..631e229ab428 100644
> > --- a/arch/x86/kernel/process_64.c
> > +++ b/arch/x86/kernel/process_64.c
> > @@ -59,7 +59,7 @@
> >  #include <asm/unistd_32_ia32.h>
> >  #endif
> >  
> > -__visible DEFINE_PER_CPU(unsigned long, rsp_scratch);
> > +__visible DEFINE_PER_CPU_USER_MAPPED(unsigned long, rsp_scratch);
> >  
> >  /* Prints also some state that isn't saved in the pt_regs */
> >  void __show_regs(struct pt_regs *regs, int all)
> 
> Do we still need this one? It appears to me we'll never actually execute
> that part of entry_SYSCALL_64 anymore, due to
> entry_SYSCALL_64_trampoline.

Unless we use entry_SYSCALL_64 when kaiser is disabled at boottime

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/24] x86/mm/kaiser: Map the entry stack variables
  2017-11-27 17:29   ` Peter Zijlstra
@ 2017-11-27 17:32     ` Thomas Gleixner
  0 siblings, 0 replies; 70+ messages in thread
From: Thomas Gleixner @ 2017-11-27 17:32 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, linux-kernel, Dave Hansen, Andy Lutomirski,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Mon, 27 Nov 2017, Peter Zijlstra wrote:

> On Mon, Nov 27, 2017 at 11:49:09AM +0100, Ingo Molnar wrote:
> > diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
> > index 7b348cc33e2d..f4f4ab8525bd 100644
> > --- a/arch/x86/kernel/cpu/common.c
> > +++ b/arch/x86/kernel/cpu/common.c
> > @@ -1515,7 +1515,7 @@ EXPORT_PER_CPU_SYMBOL(__preempt_count);
> >   * the top of the kernel stack.  Use an extra percpu variable to track the
> >   * top of the kernel stack directly.
> >   */
> > -DEFINE_PER_CPU(unsigned long, cpu_current_top_of_stack) =
> > +DEFINE_PER_CPU_USER_MAPPED(unsigned long, cpu_current_top_of_stack) =
> >  	(unsigned long)&init_thread_union + THREAD_SIZE;
> >  EXPORT_PER_CPU_SYMBOL(cpu_current_top_of_stack);
> 
> I can't find where we would access this one without already having
> switched to kernel CR3.
> 
> A kernel with this entire patch reverted seems to boot for me.

Yes, it's not longer required.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 02/24] x86/mm/kaiser: Prepare the x86/entry assembly code for entry/exit CR3 switching
  2017-11-27 17:31   ` Peter Zijlstra
@ 2017-11-27 17:33     ` Thomas Gleixner
  2017-11-27 21:00       ` Peter Zijlstra
  0 siblings, 1 reply; 70+ messages in thread
From: Thomas Gleixner @ 2017-11-27 17:33 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, linux-kernel, Dave Hansen, Andy Lutomirski,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Mon, 27 Nov 2017, Peter Zijlstra wrote:
> On Mon, Nov 27, 2017 at 11:49:01AM +0100, Ingo Molnar wrote:
> > diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
> > index caf74a1bb3de..df0152bee8a8 100644
> 
> > @@ -198,6 +201,14 @@ ENTRY(entry_SYSCALL_64)
> >  
> >  	swapgs
> >  	movq	%rsp, PER_CPU_VAR(rsp_scratch)
> > +
> > +	/*
> > +	 * The kernel CR3 is needed to map the process stack, but we
> > +	 * need a scratch register to be able to load CR3.  %rsp is
> > +	 * clobberable right now, so use it as a scratch register.
> > +	 * %rsp will look crazy here for a couple instructions.
> > +	 */
> > +	SWITCH_TO_KERNEL_CR3 scratch_reg=%rsp
> >  	movq	PER_CPU_VAR(cpu_current_top_of_stack), %rsp
> >  
> >  	/* Construct struct pt_regs on stack */
> 
> I think we can do away with this one, on account of never getting here
> because of entry_SYSCALL_64_trampoline.

It's on my list already. About 5 people noticed :)

Still trying to decode that paravirt fail.....

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 04/24] x86/mm/kaiser: Unmap kernel mappings from userspace page tables, core patch
  2017-11-27 15:39   ` Peter Zijlstra
  2017-11-27 17:04     ` Borislav Petkov
@ 2017-11-27 19:17     ` Dave Hansen
  1 sibling, 0 replies; 70+ messages in thread
From: Dave Hansen @ 2017-11-27 19:17 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar
  Cc: linux-kernel, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Borislav Petkov, Linus Torvalds

On 11/27/2017 07:39 AM, Peter Zijlstra wrote:
> So I had the problem that I could not tell if my shiny new kernel had
> this brand spanking awesome feature enabled or not.
> 
> Do we want something like so?

I eventually shoved one of these in the (buggy) runtime enable/disable
patch.  But, yeah, we do.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/24] x86/mm: Add KAISER support
  2017-11-27 10:48 [PATCH 00/24] x86/mm: Add KAISER support Ingo Molnar
                   ` (24 preceding siblings ...)
  2017-11-27 13:51 ` [PATCH 00/24] x86/mm: Add KAISER support Borislav Petkov
@ 2017-11-27 19:43 ` Linus Torvalds
  2017-11-27 20:01   ` Linus Torvalds
  25 siblings, 1 reply; 70+ messages in thread
From: Linus Torvalds @ 2017-11-27 19:43 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Linux Kernel Mailing List, Dave Hansen, Andy Lutomirski,
	Thomas Gleixner, H . Peter Anvin, Peter Zijlstra,
	Borislav Petkov

On Mon, Nov 27, 2017 at 2:48 AM, Ingo Molnar <mingo@kernel.org> wrote:
> Sending this out for another round of review.

Ok, I have tried to go through the patches, and I don't see anything
horrible, but honestly, at this point I'd rather leave it for 4.16.

We're presumably going to have to back-port these things anyway for
the LTS releases, and they're still getting comments and small fixes
after the merge window is over. I'd rather have people feel like they
can take the time to just get it all clean and finished (and as much
testing as possible) than start merging things aggressively.

I'll happily take some of the cleanup and prep patches if people want
those to go in separately. The unwinder and stack overflow patches
seem to be entirely unrelated to the actual changes that are
introduced, for example, and came out of debugging them. And the
sysenter stack patch seems a nice cleanup that actually removes
special cases.

Comments?

                  Linus

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/24] x86/mm: Add KAISER support
  2017-11-27 19:43 ` Linus Torvalds
@ 2017-11-27 20:01   ` Linus Torvalds
  0 siblings, 0 replies; 70+ messages in thread
From: Linus Torvalds @ 2017-11-27 20:01 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Linux Kernel Mailing List, Dave Hansen, Andy Lutomirski,
	Thomas Gleixner, H . Peter Anvin, Peter Zijlstra,
	Borislav Petkov

On Mon, Nov 27, 2017 at 11:43 AM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> I'll happily take some of the cleanup and prep patches if people want
> those to go in separately.

Actually, perhaps we should not strive to do that.

Because particularly if we expect that this will want to be
back-ported into at least 4.14, maybe the right thing to do is to make
_that_ as easy as possible, and make the whole series be based on 4.14
(so that back-porting is literally just "merge the branch").

If I start taking this piece-meal, it is just going to make the
back-porting messier.

              Linus

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/24] x86/mm/kaiser: Map the entry stack variables
  2017-11-27 17:32     ` Thomas Gleixner
@ 2017-11-27 21:00       ` Peter Zijlstra
  0 siblings, 0 replies; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-27 21:00 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Ingo Molnar, linux-kernel, Dave Hansen, Andy Lutomirski,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Mon, Nov 27, 2017 at 06:32:11PM +0100, Thomas Gleixner wrote:
> On Mon, 27 Nov 2017, Peter Zijlstra wrote:
> 
> > On Mon, Nov 27, 2017 at 11:49:09AM +0100, Ingo Molnar wrote:
> > > diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
> > > index 157f81816915..631e229ab428 100644
> > > --- a/arch/x86/kernel/process_64.c
> > > +++ b/arch/x86/kernel/process_64.c
> > > @@ -59,7 +59,7 @@
> > >  #include <asm/unistd_32_ia32.h>
> > >  #endif
> > >  
> > > -__visible DEFINE_PER_CPU(unsigned long, rsp_scratch);
> > > +__visible DEFINE_PER_CPU_USER_MAPPED(unsigned long, rsp_scratch);
> > >  
> > >  /* Prints also some state that isn't saved in the pt_regs */
> > >  void __show_regs(struct pt_regs *regs, int all)
> > 
> > Do we still need this one? It appears to me we'll never actually execute
> > that part of entry_SYSCALL_64 anymore, due to
> > entry_SYSCALL_64_trampoline.
> 
> Unless we use entry_SYSCALL_64 when kaiser is disabled at boottime

Right for which you need that patchlet I send earlier today. The patches
as they are will never ever reach that code.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 02/24] x86/mm/kaiser: Prepare the x86/entry assembly code for entry/exit CR3 switching
  2017-11-27 17:33     ` Thomas Gleixner
@ 2017-11-27 21:00       ` Peter Zijlstra
  0 siblings, 0 replies; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-27 21:00 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Ingo Molnar, linux-kernel, Dave Hansen, Andy Lutomirski,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Mon, Nov 27, 2017 at 06:33:39PM +0100, Thomas Gleixner wrote:
> On Mon, 27 Nov 2017, Peter Zijlstra wrote:
> > On Mon, Nov 27, 2017 at 11:49:01AM +0100, Ingo Molnar wrote:
> > > diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
> > > index caf74a1bb3de..df0152bee8a8 100644
> > 
> > > @@ -198,6 +201,14 @@ ENTRY(entry_SYSCALL_64)
> > >  
> > >  	swapgs
> > >  	movq	%rsp, PER_CPU_VAR(rsp_scratch)
> > > +
> > > +	/*
> > > +	 * The kernel CR3 is needed to map the process stack, but we
> > > +	 * need a scratch register to be able to load CR3.  %rsp is
> > > +	 * clobberable right now, so use it as a scratch register.
> > > +	 * %rsp will look crazy here for a couple instructions.
> > > +	 */
> > > +	SWITCH_TO_KERNEL_CR3 scratch_reg=%rsp
> > >  	movq	PER_CPU_VAR(cpu_current_top_of_stack), %rsp
> > >  
> > >  	/* Construct struct pt_regs on stack */
> > 
> > I think we can do away with this one, on account of never getting here
> > because of entry_SYSCALL_64_trampoline.
> 
> It's on my list already. About 5 people noticed :)

Hey, at least we all agree ;-)

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  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
                       ` (2 more replies)
  2017-11-30 15:44   ` Peter Zijlstra
  1 sibling, 3 replies; 70+ messages in thread
From: Andy Lutomirski @ 2017-11-28  5:16 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Dave Hansen, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

On Mon, Nov 27, 2017 at 2:49 AM, Ingo Molnar <mingo@kernel.org> wrote:
> From: Dave Hansen <dave.hansen@linux.intel.com>
>
> If changing the page tables in such a way that an invalidation of
> all contexts (aka. PCIDs / ASIDs) is required, they can be
> actively invalidated by:
>
>  1. INVPCID for each PCID (works for single pages too).
>
>  2. Load CR3 with each PCID without the NOFLUSH bit set
>
>  3. Load CR3 with the NOFLUSH bit set for each and do INVLPG for each address.
>
> But, none of these are really feasible since there are ~6 ASIDs (12 with
> KAISER) at the time that invalidation is required.  Instead of
> actively invalidating them, invalidate the *current* context and
> also mark the cpu_tlbstate _quickly_ to indicate future invalidation
> to be required.
>
> At the next context-switch, look for this indicator
> ('all_other_ctxs_invalid' being set) invalidate all of the
> cpu_tlbstate.ctxs[] entries.
>
> This ensures that any future context switches will do a full flush
> of the TLB, picking up the previous changes.

NAK.

We need to split up __flush_tlb_one() into __flush_tlb_one() and
__flush_tlb_one_kernel().  We've gotten away with having a single
function for both this long because we've never had PCID on and
nonglobal kernel mappings around.  So we're busted starting with
"x86/mm/kaiser: Disable global pages by default with KAISER", which
means that we have a potential corruption issue affecting anyone who
tries to bisect the series.

Then we need to make the kernel variant do something sane (presumably
just call __flush_tlb_all if we have PCID && !PGE).  And, for the user
variant, we need a straightforward, clean, efficient way to mark a
given address space on a given CPU as needing a usermode PCID flush
when its usermode tables are next loaded.  This patch isn't it.

--Andy

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 16/24] x86/mm/kaiser: Use PCID feature to make user and kernel switches faster
  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
  0 siblings, 1 reply; 70+ messages in thread
From: Andy Lutomirski @ 2017-11-28  5:22 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Dave Hansen, Thomas Gleixner, H . Peter Anvin,
	Peter Zijlstra, Borislav Petkov, Linus Torvalds

On Mon, Nov 27, 2017 at 2:49 AM, Ingo Molnar <mingo@kernel.org> wrote:
> From: Dave Hansen <dave.hansen@linux.intel.com>
>
> Short summary: Use x86 PCID feature to avoid flushing the TLB at all
> interrupts and syscalls.  Speed them up.  Makes context switches
> and TLB flushing slower.

I suspect that, if we actually did it right (by doing a deferred
usermode flush when we switch CR3), it wouldn't make context switches
or TLB flushing slower.

> +               /*
> +                * On systems with PCIDs, but no INVPCID, the only
> +                * way to flush a PCID is a CR3 write.  Note that
> +                * we use the kernel page tables with the *user*
> +                * ASID here.
> +                */
> +               unsigned long user_asid_flush_cr3;
> +               user_asid_flush_cr3 = build_cr3(pgd, user_asid(kern_asid));
> +               write_cr3(user_asid_flush_cr3);

This is wrong.  If we could atomically switch CR3 and switch it back
without any speculative fills in the mean time, we might be okay, but
that's not what's happening.  We could be filling the TLB with
usermode-tagged kernel entries, which is a big no-no.

(And I'm ignoring the fact that this code seems to have forgotten the
"switch back" part.)

> +               /*
> +                * We do not use PCIDs with KAISER unless we also
> +                * have INVPCID.  Getting here is unexpected.
> +                */
> +               WARN_ON_ONCE(1);

Well that's a bummer.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  2017-11-28  5:16   ` Andy Lutomirski
@ 2017-11-28  7:32     ` Dave Hansen
  2017-11-28 16:39     ` Peter Zijlstra
  2017-11-30 15:40     ` Peter Zijlstra
  2 siblings, 0 replies; 70+ messages in thread
From: Dave Hansen @ 2017-11-28  7:32 UTC (permalink / raw)
  To: Andy Lutomirski, Ingo Molnar
  Cc: linux-kernel, Thomas Gleixner, H . Peter Anvin, Peter Zijlstra,
	Borislav Petkov, Linus Torvalds

On 11/27/2017 09:16 PM, Andy Lutomirski wrote:
> We need to split up __flush_tlb_one() into __flush_tlb_one() and
> __flush_tlb_one_kernel().  We've gotten away with having a single
> function for both this long because we've never had PCID on and
> nonglobal kernel mappings around.  So we're busted starting with
> "x86/mm/kaiser: Disable global pages by default with KAISER", which
> means that we have a potential corruption issue affecting anyone who
> tries to bisect the series.

There's no way this thing works with CONFIG_KAISER=y in the middle of
the series, that's why the Kconfig patch was stuck at the end.  Is there
breaking without the Kconfig option enabled?

> Then we need to make the kernel variant do something sane (presumably
> just call __flush_tlb_all if we have PCID && !PGE).

Yes, auditing all the callers and figuring out what they're flushing is
a good exercise.

BTW, one reason I've avoided falling back to __flush_tlb_all() in the
"single" invalidate cases is that it hides bugs.  TLB invalidation bugs
are hard enough to find as it stands, but silently turning every "little
hammer" single flush into an implicit "big hammer" full flush shouldn't
be something that we do lightly.

> and, for the user
> variant, we need a straightforward, clean, efficient way to mark a
> given address space on a given CPU as needing a usermode PCID flush
> when its usermode tables are next loaded.  This patch isn't it.

Right now, the kernel and user ASIDs are pretty joined at the hip.  We
always flush them together.  We don't _need_ a mechanism to specifically
mark a user ASID because it doesn't get managed separately.

I assume you want to go this route so that we can eventually separate
out the user and kernel flushing because we can get the kernel flushing
for "free" at context switch time and then the user flushing for "free"
at the return to userspace.

That's all fine and good, but it *is* more complicated than what's there
right now.  Is there something that I'm missing here that it simplifies?

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 16/24] x86/mm/kaiser: Use PCID feature to make user and kernel switches faster
  2017-11-28  5:22   ` Andy Lutomirski
@ 2017-11-28  7:52     ` Dave Hansen
  0 siblings, 0 replies; 70+ messages in thread
From: Dave Hansen @ 2017-11-28  7:52 UTC (permalink / raw)
  To: Andy Lutomirski, Ingo Molnar
  Cc: linux-kernel, Thomas Gleixner, H . Peter Anvin, Peter Zijlstra,
	Borislav Petkov, Linus Torvalds

On 11/27/2017 09:22 PM, Andy Lutomirski wrote:
> On Mon, Nov 27, 2017 at 2:49 AM, Ingo Molnar <mingo@kernel.org> wrote:
>> From: Dave Hansen <dave.hansen@linux.intel.com>
>>
>> Short summary: Use x86 PCID feature to avoid flushing the TLB at all
>> interrupts and syscalls.  Speed them up.  Makes context switches
>> and TLB flushing slower.
> 
> I suspect that, if we actually did it right (by doing a deferred
> usermode flush when we switch CR3), it wouldn't make context switches
> or TLB flushing slower.

Totally agree.

>> +               /*
>> +                * On systems with PCIDs, but no INVPCID, the only
>> +                * way to flush a PCID is a CR3 write.  Note that
>> +                * we use the kernel page tables with the *user*
>> +                * ASID here.
>> +                */
>> +               unsigned long user_asid_flush_cr3;
>> +               user_asid_flush_cr3 = build_cr3(pgd, user_asid(kern_asid));
>> +               write_cr3(user_asid_flush_cr3);
> 
> This is wrong.  If we could atomically switch CR3 and switch it back
> without any speculative fills in the mean time, we might be okay, but
> that's not what's happening.  We could be filling the TLB with
> usermode-tagged kernel entries, which is a big no-no.

This hunk should disappear.  It was an attempt to support PCIDs without
INVPCID.  But, as you point out, that needs even more infrastructure to
support perfectly.   It's yet another reason not to support that
configuration for now.

Just to make sure I understand your concern (because I'm sure we'll get
back to this soon): this code is functionally correct: it will ensure
that TLB entries in the user ASID _are_ flushed.

But, I think what you're saying is that any TLB fills between this and
the reload of the kernel ASID might fill parts of the kernel page tables
into the TLB (with the user ASID), and _those_ could be used to weaken
KASLR.  I agree, that's theoretically problematic.

Am I missing anything?

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 04/24] x86/mm/kaiser: Unmap kernel mappings from userspace page tables, core patch
  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-28 10:34   ` Peter Zijlstra
  1 sibling, 0 replies; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-28 10:34 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Dave Hansen, Andy Lutomirski, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Mon, Nov 27, 2017 at 11:49:03AM +0100, Ingo Molnar wrote:
> +/*
> + * Given a kernel address, @__start_addr, copy that mapping into
> + * the user (shadow) page tables.  This may need to allocate page
> + * table pages.
> + */
> +int kaiser_add_user_map(const void *__start_addr, unsigned long size,
> +			unsigned long flags)
> +{
> +}
> +
> +int kaiser_add_user_map_ptrs(const void *__start_addr,
> +			     const void *__end_addr,
> +			     unsigned long flags)
> +{
> +}

AFAICT these here can be static..


diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c
index 0ff502fa655b..f2bf074b08e5 100644
--- a/arch/x86/mm/kaiser.c
+++ b/arch/x86/mm/kaiser.c
@@ -260,8 +260,8 @@ static pte_t *kaiser_shadow_pagetable_walk(unsigned long address,
  * the user (shadow) page tables.  This may need to allocate page
  * table pages.
  */
-int kaiser_add_user_map(const void *__start_addr, unsigned long size,
-			unsigned long flags)
+static int kaiser_add_user_map(const void *__start_addr, unsigned long size,
+			       unsigned long flags)
 {
 	unsigned long start_addr = (unsigned long)__start_addr;
 	unsigned long address = start_addr & PAGE_MASK;
@@ -310,9 +310,9 @@ int kaiser_add_user_map(const void *__start_addr, unsigned long size,
 	return 0;
 }
 
-int kaiser_add_user_map_ptrs(const void *__start_addr,
-			     const void *__end_addr,
-			     unsigned long flags)
+static int kaiser_add_user_map_ptrs(const void *__start_addr,
+				    const void *__end_addr,
+				    unsigned long flags)
 {
 	return kaiser_add_user_map(__start_addr,
 				   __end_addr - __start_addr,

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  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-30 15:40     ` Peter Zijlstra
  2 siblings, 2 replies; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-28 16:39 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Ingo Molnar, linux-kernel, Dave Hansen, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Mon, Nov 27, 2017 at 09:16:19PM -0800, Andy Lutomirski wrote:
> We need to split up __flush_tlb_one() into __flush_tlb_one() and
> __flush_tlb_one_kernel().  We've gotten away with having a single
> function for both this long because we've never had PCID on and
> nonglobal kernel mappings around.  So we're busted starting with
> "x86/mm/kaiser: Disable global pages by default with KAISER", which
> means that we have a potential corruption issue affecting anyone who
> tries to bisect the series.

Didn't do that..

> Then we need to make the kernel variant do something sane (presumably
> just call __flush_tlb_all if we have PCID && !PGE).  And, for the user
> variant, we need a straightforward, clean, efficient way to mark a
> given address space on a given CPU as needing a usermode PCID flush
> when its usermode tables are next loaded.  This patch isn't it.

Did give this a try, mostly also to get PCID + !INVPCID working for my
IVB.

The below is fairly ugly but it does boot and build a kernel so its not
immensely broken.

---
diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index 07fa7fdd7b68..d7f1be6ccc97 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -4,6 +4,7 @@
 #include <asm/cpufeatures.h>
 #include <asm/page_types.h>
 #include <asm/pgtable_types.h>
+#include <asm/percpu.h>
 
 /*
 
@@ -220,7 +221,21 @@ For 32-bit we have the following conventions - kernel is built with
 .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
+	push	\scratch_reg
+	andq	$(0x7FF), \scratch_reg
+	bt	\scratch_reg, PER_CPU_VAR(__asid_flush)
+	jnc	.Lnoflush_\@
+
+	btr	\scratch_reg, PER_CPU_VAR(__asid_flush)
+	pop	\scratch_reg
+	jmp	.Ldo_\@
+
+.Lnoflush_\@:
+	pop	\scratch_reg
+	ALTERNATIVE "", "bts $63, \scratch_reg", X86_FEATURE_PCID
+
+.Ldo_\@:
+	orq     $(KAISER_SWITCH_MASK), \scratch_reg
 	mov	\scratch_reg, %cr3
 .Lend_\@:
 .endm
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 27eb7e8c5e84..1fb137da4c9f 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -9,6 +9,7 @@
 #include <asm/cpufeature.h>
 #include <asm/special_insns.h>
 #include <asm/smp.h>
+#include <asm/kaiser.h>
 
 static inline void __invpcid(unsigned long pcid, unsigned long addr,
 			     unsigned long type)
@@ -347,9 +348,33 @@ static inline void cr4_set_bits_and_update_boot(unsigned long mask)
 
 extern void initialize_tlbstate_and_flush(void);
 
+DECLARE_PER_CPU(unsigned long, __asid_flush);
+
+/*
+ * Given an asid, flush the corresponding KAISER user ASID.
+ */
+static inline void flush_user_asid(u16 asid)
+{
+	/* There is no user ASID if KAISER is off */
+	if (!IS_ENABLED(CONFIG_KAISER))
+		return;
+	/*
+	 * We only have a single ASID if PCID is off and the CR3
+	 * write will have flushed it.
+	 */
+	if (!cpu_feature_enabled(X86_FEATURE_PCID))
+		return;
+
+	if (!kaiser_enabled)
+		return;
+
+	__set_bit(kern_asid(asid), this_cpu_ptr(&__asid_flush));
+}
+
 static inline void __native_flush_tlb(void)
 {
 	if (!cpu_feature_enabled(X86_FEATURE_INVPCID)) {
+#if 0
 		/*
 		 * native_write_cr3() only clears the current PCID if
 		 * CR4 has X86_CR4_PCIDE set.  In other words, this does
@@ -358,9 +383,10 @@ static inline void __native_flush_tlb(void)
 		 * With KAISER and PCIDs, the means that we did not
 		 * flush the user PCID.  Warn if it gets called.
 		 */
-		if (IS_ENABLED(CONFIG_KAISER))
-			WARN_ON_ONCE(this_cpu_read(cpu_tlbstate.cr4) &
-				     X86_CR4_PCIDE);
+		if (IS_ENABLED(CONFIG_KAISER) && kaiser_enabled)
+			WARN_ON_ONCE(this_cpu_read(cpu_tlbstate.cr4) & X86_CR4_PCIDE);
+#endif
+		flush_user_asid(this_cpu_read(cpu_tlbstate.loaded_mm_asid));
 		/*
 		 * If current->mm == NULL then we borrow a mm
 		 * which may change during a task switch and
@@ -435,6 +461,8 @@ static inline void __native_flush_tlb_single(unsigned long addr)
 	 * early.
 	 */
 	if (!this_cpu_has(X86_FEATURE_INVPCID_SINGLE)) {
+		flush_user_asid(loaded_mm_asid);
+
 		asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
 		return;
 	}
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 72f115178d14..2dcd01615772 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -218,11 +218,13 @@ static void setup_pcid(void)
 		 * INVPCID.  Just avoid using PCIDs at all if we
 		 * have KAISER and do not have INVPCID.
 		 */
+#if 0
 		if (!IS_ENABLED(CONFIG_X86_GLOBAL_PAGES) &&
-		    !boot_cpu_has(X86_FEATURE_INVPCID)) {
+		    kaiser_enabled && !boot_cpu_has(X86_FEATURE_INVPCID)) {
 			setup_clear_cpu_cap(X86_FEATURE_PCID);
 			return;
 		}
+#endif
 		/*
 		 * This can't be cr4_set_bits_and_update_boot() --
 		 * the trampoline code can't handle CR4.PCIDE and
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index f75b6eb47a6d..4ed1d0dfd54f 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -100,55 +100,14 @@ static void choose_new_asid(struct mm_struct *next, u64 next_tlb_gen,
 	*need_flush = true;
 }
 
-/*
- * Given a kernel asid, flush the corresponding KAISER
- * user ASID.
- */
-static void flush_user_asid(pgd_t *pgd, u16 kern_asid)
-{
-	/* There is no user ASID if KAISER is off */
-	if (!IS_ENABLED(CONFIG_KAISER))
-		return;
-	/*
-	 * We only have a single ASID if PCID is off and the CR3
-	 * write will have flushed it.
-	 */
-	if (!cpu_feature_enabled(X86_FEATURE_PCID))
-		return;
-	/*
-	 * With PCIDs enabled, write_cr3() only flushes TLB
-	 * entries for the current (kernel) ASID.  This leaves
-	 * old TLB entries for the user ASID in place and we must
-	 * flush that context separately.  We can theoretically
-	 * delay doing this until we actually load up the
-	 * userspace CR3, but do it here for simplicity.
-	 */
-	if (cpu_feature_enabled(X86_FEATURE_INVPCID)) {
-		invpcid_flush_single_context(user_asid(kern_asid));
-	} else {
-		/*
-		 * On systems with PCIDs, but no INVPCID, the only
-		 * way to flush a PCID is a CR3 write.  Note that
-		 * we use the kernel page tables with the *user*
-		 * ASID here.
-		 */
-		unsigned long user_asid_flush_cr3;
-		user_asid_flush_cr3 = build_cr3(pgd, user_asid(kern_asid));
-		write_cr3(user_asid_flush_cr3);
-		/*
-		 * We do not use PCIDs with KAISER unless we also
-		 * have INVPCID.  Getting here is unexpected.
-		 */
-		WARN_ON_ONCE(1);
-	}
-}
+__visible DEFINE_PER_CPU(unsigned long, __asid_flush);
 
 static void load_new_mm_cr3(pgd_t *pgdir, u16 new_asid, bool need_flush)
 {
 	unsigned long new_mm_cr3;
 
 	if (need_flush) {
-		flush_user_asid(pgdir, new_asid);
+		flush_user_asid(new_asid);
 		new_mm_cr3 = build_cr3(pgdir, new_asid);
 	} else {
 		new_mm_cr3 = build_cr3_noflush(pgdir, new_asid);

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  2017-11-28 16:39     ` Peter Zijlstra
@ 2017-11-28 16:48       ` Peter Zijlstra
  2017-11-28 18:13       ` Dave Hansen
  1 sibling, 0 replies; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-28 16:48 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Ingo Molnar, linux-kernel, Dave Hansen, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Tue, Nov 28, 2017 at 05:39:08PM +0100, Peter Zijlstra wrote:

> @@ -220,7 +221,21 @@ For 32-bit we have the following conventions - kernel is built with
>  .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
> +	push	\scratch_reg
> +	andq	$(0x7FF), \scratch_reg
> +	bt	\scratch_reg, PER_CPU_VAR(__asid_flush)
> +	jnc	.Lnoflush_\@
> +
> +	btr	\scratch_reg, PER_CPU_VAR(__asid_flush)
> +	pop	\scratch_reg
> +	jmp	.Ldo_\@
> +
> +.Lnoflush_\@:
> +	pop	\scratch_reg
> +	ALTERNATIVE "", "bts $63, \scratch_reg", X86_FEATURE_PCID
> +
> +.Ldo_\@:
> +	orq     $(KAISER_SWITCH_MASK), \scratch_reg
>  	mov	\scratch_reg, %cr3
>  .Lend_\@:
>  .endm

Ah, I suppose I should also deal with RESTORE_CR3...

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  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
  1 sibling, 1 reply; 70+ messages in thread
From: Dave Hansen @ 2017-11-28 18:13 UTC (permalink / raw)
  To: Peter Zijlstra, Andy Lutomirski
  Cc: Ingo Molnar, linux-kernel, Thomas Gleixner, H . Peter Anvin,
	Borislav Petkov, Linus Torvalds

Thanks for looking at this, Peter.  I've been resisting doing this for a
bit and it's an embarrassingly small amount of code.

On 11/28/2017 08:39 AM, Peter Zijlstra wrote:
> @@ -220,7 +221,21 @@ For 32-bit we have the following conventions - kernel is built with
>  .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
> +	push	\scratch_reg

Do we have a good stack in all the spots that we need to do this?  It
may have changed with the trampoline stack, but I'm 100% sure that it
wasn't so in the recent past.

Let me see if I'm reading the assembly right.

Load the kernel's ASID from CR3 into \scratch_reg:

> +	andq	$(0x7FF), \scratch_reg

See if that ASID needs a flush by checking its bit in __asid_flush.
Store value of the bit in CF:

> +	bt	\scratch_reg, PER_CPU_VAR(__asid_flush)

Jump if CF bit is clear:

> +	jnc	.Lnoflush_\@

Clear the ASID bit from __asid_flush since we are about to do the flush:

> +	btr	\scratch_reg, PER_CPU_VAR(__asid_flush)

Restore CR3 back to what it was:

> +	pop	\scratch_reg

Jump past the code that sets the no-flush bit (63), forcing a flush:

> +	jmp	.Ldo_\@
> +
> +.Lnoflush_\@:
> +	pop	\scratch_reg
> +	ALTERNATIVE "", "bts $63, \scratch_reg", X86_FEATURE_PCID
> +
> +.Ldo_\@:
> +	orq     $(KAISER_SWITCH_MASK), \scratch_reg
>  	mov	\scratch_reg, %cr3
>  .Lend_\@:
>  .endm



> diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
> index 27eb7e8c5e84..1fb137da4c9f 100644
> --- a/arch/x86/include/asm/tlbflush.h
> +++ b/arch/x86/include/asm/tlbflush.h
> @@ -9,6 +9,7 @@
>  #include <asm/cpufeature.h>
>  #include <asm/special_insns.h>
>  #include <asm/smp.h>
> +#include <asm/kaiser.h>
>  
>  static inline void __invpcid(unsigned long pcid, unsigned long addr,
>  			     unsigned long type)
> @@ -347,9 +348,33 @@ static inline void cr4_set_bits_and_update_boot(unsigned long mask)
>  
>  extern void initialize_tlbstate_and_flush(void);
>  
> +DECLARE_PER_CPU(unsigned long, __asid_flush);

Could we spare enough space to make this something like
user_asid_flush_pending_mask?

It took me a minute to realize that it was a mask.  Also, since we only
have 6 asids, should we bit a bit more stingy with the type?

> +/*
> + * Given an asid, flush the corresponding KAISER user ASID.
> + */
> +static inline void flush_user_asid(u16 asid)
> +{
> +	/* There is no user ASID if KAISER is off */
> +	if (!IS_ENABLED(CONFIG_KAISER))
> +		return;
> +	/*
> +	 * We only have a single ASID if PCID is off and the CR3
> +	 * write will have flushed it.
> +	 */
> +	if (!cpu_feature_enabled(X86_FEATURE_PCID))
> +		return;
> +
> +	if (!kaiser_enabled)
> +		return;
> +
> +	__set_bit(kern_asid(asid), this_cpu_ptr(&__asid_flush));
> +}

We flush_user_asid() and thus set bits in __asid_flush in two cases:

1. When we flush the TLB explicitly
2. When we re-use an ASID for a new mm

It took me a minute to realize that mixing these is still OK, even if
the mm associated with the ASID changes.  It's because once the ASID is
stale, it doesn't matter *why* it is stale.  Just that the next guy who
*uses* it needs to do the flush.  You can do 1,000 tlb flushes, a
context switch, a tlb flush and another context switch, but if you only
go out to userspace once, you only need 1 ASID flush.  That fits
perfectly with this bit that gets set a bunch of times and only cleared
once at exit to userspace.

IOW, this all seems sane, but it took me a few minutes of staring at it
to come to that conclusion.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  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
  0 siblings, 2 replies; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-28 19:05 UTC (permalink / raw)
  To: Dave Hansen
  Cc: Andy Lutomirski, Ingo Molnar, linux-kernel, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Tue, Nov 28, 2017 at 10:13:30AM -0800, Dave Hansen wrote:
> Thanks for looking at this, Peter.  I've been resisting doing this for a
> bit and it's an embarrassingly small amount of code.

Right, well, its not complete yet, and it might be complete crap :-)

> On 11/28/2017 08:39 AM, Peter Zijlstra wrote:
> > @@ -220,7 +221,21 @@ For 32-bit we have the following conventions - kernel is built with
> >  .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
> > +	push	\scratch_reg
> 
> Do we have a good stack in all the spots that we need to do this?  It
> may have changed with the trampoline stack, but I'm 100% sure that it
> wasn't so in the recent past.

Dunno really. I figured I'd give it a go and see what happens. So far
the machine still works. But I was hoping Andy would have an opinion on
this.

> Let me see if I'm reading the assembly right.

Yep, seems you can read asm :-)


> > +DECLARE_PER_CPU(unsigned long, __asid_flush);
> 
> Could we spare enough space to make this something like
> user_asid_flush_pending_mask?

Yeah, if I can get it all working we'll bikeshed on a name ;-)

> It took me a minute to realize that it was a mask.  Also, since we only
> have 6 asids, should we bit a bit more stingy with the type?

I picked unsigned long because our bitops (__set_bit in this case, use
it), and I know we're LE and could simply use a shorter type, but meh.

> It took me a minute to realize that mixing these is still OK, even if
> the mm associated with the ASID changes.  It's because once the ASID is
> stale, it doesn't matter *why* it is stale.  Just that the next guy who
> *uses* it needs to do the flush.  You can do 1,000 tlb flushes, a
> context switch, a tlb flush and another context switch, but if you only
> go out to userspace once, you only need 1 ASID flush.  That fits
> perfectly with this bit that gets set a bunch of times and only cleared
> once at exit to userspace.

Just so.

I'm now staring at the RESTORE_CR3 stuff, and that appears to be called
in the NMI handling where the stack is not to be used (if I read it
right), so that's going to be a little more tricky.

Let me prod at that..

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  2017-11-28 19:05         ` Peter Zijlstra
@ 2017-11-28 19:36           ` Peter Zijlstra
  2017-11-28 20:34           ` Andy Lutomirski
  1 sibling, 0 replies; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-28 19:36 UTC (permalink / raw)
  To: Dave Hansen
  Cc: Andy Lutomirski, Ingo Molnar, linux-kernel, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Tue, Nov 28, 2017 at 08:05:05PM +0100, Peter Zijlstra wrote:
> I'm now staring at the RESTORE_CR3 stuff, and that appears to be called
> in the NMI handling where the stack is not to be used (if I read it
> right), so that's going to be a little more tricky.

As I just mentioned on IRC; I just realized that RESTORE_CR3 is always
flushing. So what I just wrote is effectively an optimization that
allows a nonflush.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  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
  1 sibling, 2 replies; 70+ messages in thread
From: Andy Lutomirski @ 2017-11-28 20:34 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Dave Hansen, Ingo Molnar, linux-kernel, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Tue, Nov 28, 2017 at 11:05 AM, Peter Zijlstra <peterz@infradead.org> wrote:
> On Tue, Nov 28, 2017 at 10:13:30AM -0800, Dave Hansen wrote:
>> Thanks for looking at this, Peter.  I've been resisting doing this for a
>> bit and it's an embarrassingly small amount of code.
>
> Right, well, its not complete yet, and it might be complete crap :-)
>
>> On 11/28/2017 08:39 AM, Peter Zijlstra wrote:
>> > @@ -220,7 +221,21 @@ For 32-bit we have the following conventions - kernel is built with
>> >  .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
>> > +   push    \scratch_reg
>>
>> Do we have a good stack in all the spots that we need to do this?  It
>> may have changed with the trampoline stack, but I'm 100% sure that it
>> wasn't so in the recent past.
>
> Dunno really. I figured I'd give it a go and see what happens. So far
> the machine still works. But I was hoping Andy would have an opinion on
> this.

I thought we had a stack in all these places even before the
trampoline.  There was an issue with *entry*, but I think exit has
always been okay.

>
>> Let me see if I'm reading the assembly right.
>
> Yep, seems you can read asm :-)
>
>
>> > +DECLARE_PER_CPU(unsigned long, __asid_flush);
>>
>> Could we spare enough space to make this something like
>> user_asid_flush_pending_mask?
>
> Yeah, if I can get it all working we'll bikeshed on a name ;-)
>
>> It took me a minute to realize that it was a mask.  Also, since we only
>> have 6 asids, should we bit a bit more stingy with the type?
>
> I picked unsigned long because our bitops (__set_bit in this case, use
> it), and I know we're LE and could simply use a shorter type, but meh.
>
>> It took me a minute to realize that mixing these is still OK, even if
>> the mm associated with the ASID changes.  It's because once the ASID is
>> stale, it doesn't matter *why* it is stale.  Just that the next guy who
>> *uses* it needs to do the flush.  You can do 1,000 tlb flushes, a
>> context switch, a tlb flush and another context switch, but if you only
>> go out to userspace once, you only need 1 ASID flush.  That fits
>> perfectly with this bit that gets set a bunch of times and only cleared
>> once at exit to userspace.
>
> Just so.
>
> I'm now staring at the RESTORE_CR3 stuff, and that appears to be called
> in the NMI handling where the stack is not to be used (if I read it
> right), so that's going to be a little more tricky.

I think it should be fine.  A very old version of the patches had that
problem, but, in -tip, the nmi RESTORE_CR3 is in the fancy
recursion-protected region, and the stack is okay.  The idea is that
we're already on the old (possibly user) CR3 before we do the crazy
recursion-checking bits.  But that's fine, since all that's accessed
there is the IST stack, and that's in the cpu_entry_area and thus safe
regardless of CR3.

Side question: on extremely quick read, you're doing bt then btr.  Why
not just do a single btr and be done with it?  Are you trying to avoid
getting exclusive access to the cacheline when not needed?

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  2017-11-28 20:34           ` Andy Lutomirski
@ 2017-11-28 20:39             ` Peter Zijlstra
  2017-11-28 20:45             ` Peter Zijlstra
  1 sibling, 0 replies; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-28 20:39 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Dave Hansen, Ingo Molnar, linux-kernel, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Tue, Nov 28, 2017 at 12:34:17PM -0800, Andy Lutomirski wrote:
> Side question: on extremely quick read, you're doing bt then btr.  Why
> not just do a single btr and be done with it?  Are you trying to avoid
> getting exclusive access to the cacheline when not needed?

Yes, avoids the M in the common !flush case.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  2017-11-28 20:34           ` Andy Lutomirski
  2017-11-28 20:39             ` Peter Zijlstra
@ 2017-11-28 20:45             ` Peter Zijlstra
  1 sibling, 0 replies; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-28 20:45 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Dave Hansen, Ingo Molnar, linux-kernel, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Tue, Nov 28, 2017 at 12:34:17PM -0800, Andy Lutomirski wrote:
> I think it should be fine.  A very old version of the patches had that
> problem, but, in -tip, the nmi RESTORE_CR3 is in the fancy
> recursion-protected region, and the stack is okay.  The idea is that
> we're already on the old (possibly user) CR3 before we do the crazy
> recursion-checking bits.  But that's fine, since all that's accessed
> there is the IST stack, and that's in the cpu_entry_area and thus safe
> regardless of CR3.

Turns out there's a gob of spare registers to be had on RESTORE_CR3, we
do POP_EXTRA_REGS right after both call-sites. So I just picked
something from there.


diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index 07fa7fdd7b68..9617b7c642db 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -4,6 +4,7 @@
 #include <asm/cpufeatures.h>
 #include <asm/page_types.h>
 #include <asm/pgtable_types.h>
+#include <asm/percpu.h>
 
 /*
 
@@ -220,15 +221,29 @@ For 32-bit we have the following conventions - kernel is built with
 .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
+	push	\scratch_reg
+	andq	$(0x7FF), \scratch_reg
+	bt	\scratch_reg, PER_CPU_VAR(__asid_flush)
+	jnc	.Lnoflush_\@
+
+	btr	\scratch_reg, PER_CPU_VAR(__asid_flush)
+	pop	\scratch_reg
+	jmp	.Ldo_\@
+
+.Lnoflush_\@:
+	pop	\scratch_reg
+	ALTERNATIVE "", "bts $63, \scratch_reg", X86_FEATURE_PCID
+
+.Ldo_\@:
+	orq     $(KAISER_SWITCH_MASK), \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
+	movq	%cr3, \scratch_reg
+	movq	\scratch_reg, \save_reg
 	/*
 	 * Is the "switch mask" all zero?  That means that both of
 	 * these are zero:
@@ -239,17 +254,42 @@ For 32-bit we have the following conventions - kernel is built with
 	 *
 	 * That indicates a kernel CR3 value, not user/shadow.
 	 */
-	testq	$(KAISER_SWITCH_MASK), %r\scratch_reg
+	testq	$(KAISER_SWITCH_MASK), \scratch_reg
 	jz	.Ldone_\@
 
-	ADJUST_KERNEL_CR3 %r\scratch_reg
-	movq	%r\scratch_reg, %cr3
+	ADJUST_KERNEL_CR3 \scratch_reg
+	movq	\scratch_reg, %cr3
 
 .Ldone_\@:
 .endm
 
-.macro RESTORE_CR3 save_reg:req
+.macro RESTORE_CR3 scratch_reg:req save_reg:req
 	STATIC_JUMP_IF_FALSE .Lend_\@, kaiser_enabled_key, def=1
+
+	/* ASID bit 11 is for USER */
+	bt	$11, \save_reg
+	/*
+	 * KERNEL pages can always resume with NOFLUSH as we do
+	 * explicit flushes.
+	 */
+	jnc	.Lnoflush_\@
+
+	/*
+	 * Check if there's a pending flush for the USER ASID we're
+	 * about to set.
+	 */
+	movq	\save_reg, \scratch_reg
+	andq	$(0x7FF), \scratch_reg
+	bt	\scratch_reg, PER_CPU_VAR(__asid_flush)
+	jnc	.Lnoflush_\@
+
+	btr	\scratch_reg, PER_CPU_VAR(__asid_flush)
+	jmp	.Ldo_\@
+
+.Lnoflush_\@:
+	ALTERNATIVE "", "bts $63, \save_reg", X86_FEATURE_PCID
+
+.Ldo_\@:
 	/*
 	 * The CR3 write could be avoided when not changing its value,
 	 * but would require a CR3 read *and* a scratch register.
@@ -266,7 +306,7 @@ For 32-bit we have the following conventions - kernel is built with
 .endm
 .macro SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg:req save_reg:req
 .endm
-.macro RESTORE_CR3 save_reg:req
+.macro RESTORE_CR3 scratch_reg:req save_reg:req
 .endm
 
 #endif
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index df0152bee8a8..39233c58f14a 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1257,7 +1254,7 @@ ENTRY(paranoid_entry)
 	xorl	%ebx, %ebx
 
 1:
-	SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg=ax save_reg=%r14
+	SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg=%rax save_reg=%r14
 
 	ret
 END(paranoid_entry)
@@ -1281,7 +1278,7 @@ ENTRY(paranoid_exit)
 	testl	%ebx, %ebx			/* swapgs needed? */
 	jnz	.Lparanoid_exit_no_swapgs
 	TRACE_IRQS_IRETQ
-	RESTORE_CR3	save_reg=%r14
+	RESTORE_CR3	scratch_reg=%rbx save_reg=%r14
 	SWAPGS_UNSAFE_STACK
 	jmp	.Lparanoid_exit_restore
 .Lparanoid_exit_no_swapgs:
@@ -1723,7 +1720,7 @@ end_repeat_nmi:
 	movq	$-1, %rsi
 	call	do_nmi
 
-	RESTORE_CR3 save_reg=%r14
+	RESTORE_CR3 scratch_reg=%r15 save_reg=%r14
 
 	testl	%ebx, %ebx			/* swapgs needed? */
 	jnz	nmi_restore
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 27eb7e8c5e84..1fb137da4c9f 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -9,6 +9,7 @@
 #include <asm/cpufeature.h>
 #include <asm/special_insns.h>
 #include <asm/smp.h>
+#include <asm/kaiser.h>
 
 static inline void __invpcid(unsigned long pcid, unsigned long addr,
 			     unsigned long type)
@@ -347,9 +348,33 @@ static inline void cr4_set_bits_and_update_boot(unsigned long mask)
 
 extern void initialize_tlbstate_and_flush(void);
 
+DECLARE_PER_CPU(unsigned long, __asid_flush);
+
+/*
+ * Given an asid, flush the corresponding KAISER user ASID.
+ */
+static inline void flush_user_asid(u16 asid)
+{
+	/* There is no user ASID if KAISER is off */
+	if (!IS_ENABLED(CONFIG_KAISER))
+		return;
+	/*
+	 * We only have a single ASID if PCID is off and the CR3
+	 * write will have flushed it.
+	 */
+	if (!cpu_feature_enabled(X86_FEATURE_PCID))
+		return;
+
+	if (!kaiser_enabled)
+		return;
+
+	__set_bit(kern_asid(asid), this_cpu_ptr(&__asid_flush));
+}
+
 static inline void __native_flush_tlb(void)
 {
 	if (!cpu_feature_enabled(X86_FEATURE_INVPCID)) {
+#if 0
 		/*
 		 * native_write_cr3() only clears the current PCID if
 		 * CR4 has X86_CR4_PCIDE set.  In other words, this does
@@ -358,9 +383,10 @@ static inline void __native_flush_tlb(void)
 		 * With KAISER and PCIDs, the means that we did not
 		 * flush the user PCID.  Warn if it gets called.
 		 */
-		if (IS_ENABLED(CONFIG_KAISER))
-			WARN_ON_ONCE(this_cpu_read(cpu_tlbstate.cr4) &
-				     X86_CR4_PCIDE);
+		if (IS_ENABLED(CONFIG_KAISER) && kaiser_enabled)
+			WARN_ON_ONCE(this_cpu_read(cpu_tlbstate.cr4) & X86_CR4_PCIDE);
+#endif
+		flush_user_asid(this_cpu_read(cpu_tlbstate.loaded_mm_asid));
 		/*
 		 * If current->mm == NULL then we borrow a mm
 		 * which may change during a task switch and
@@ -435,6 +461,8 @@ static inline void __native_flush_tlb_single(unsigned long addr)
 	 * early.
 	 */
 	if (!this_cpu_has(X86_FEATURE_INVPCID_SINGLE)) {
+		flush_user_asid(loaded_mm_asid);
+
 		asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
 		return;
 	}
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 72f115178d14..2dcd01615772 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -218,11 +218,13 @@ static void setup_pcid(void)
 		 * INVPCID.  Just avoid using PCIDs at all if we
 		 * have KAISER and do not have INVPCID.
 		 */
+#if 0
 		if (!IS_ENABLED(CONFIG_X86_GLOBAL_PAGES) &&
-		    !boot_cpu_has(X86_FEATURE_INVPCID)) {
+		    kaiser_enabled && !boot_cpu_has(X86_FEATURE_INVPCID)) {
 			setup_clear_cpu_cap(X86_FEATURE_PCID);
 			return;
 		}
+#endif
 		/*
 		 * This can't be cr4_set_bits_and_update_boot() --
 		 * the trampoline code can't handle CR4.PCIDE and
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index f75b6eb47a6d..4ed1d0dfd54f 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -100,55 +100,14 @@ static void choose_new_asid(struct mm_struct *next, u64 next_tlb_gen,
 	*need_flush = true;
 }
 
-/*
- * Given a kernel asid, flush the corresponding KAISER
- * user ASID.
- */
-static void flush_user_asid(pgd_t *pgd, u16 kern_asid)
-{
-	/* There is no user ASID if KAISER is off */
-	if (!IS_ENABLED(CONFIG_KAISER))
-		return;
-	/*
-	 * We only have a single ASID if PCID is off and the CR3
-	 * write will have flushed it.
-	 */
-	if (!cpu_feature_enabled(X86_FEATURE_PCID))
-		return;
-	/*
-	 * With PCIDs enabled, write_cr3() only flushes TLB
-	 * entries for the current (kernel) ASID.  This leaves
-	 * old TLB entries for the user ASID in place and we must
-	 * flush that context separately.  We can theoretically
-	 * delay doing this until we actually load up the
-	 * userspace CR3, but do it here for simplicity.
-	 */
-	if (cpu_feature_enabled(X86_FEATURE_INVPCID)) {
-		invpcid_flush_single_context(user_asid(kern_asid));
-	} else {
-		/*
-		 * On systems with PCIDs, but no INVPCID, the only
-		 * way to flush a PCID is a CR3 write.  Note that
-		 * we use the kernel page tables with the *user*
-		 * ASID here.
-		 */
-		unsigned long user_asid_flush_cr3;
-		user_asid_flush_cr3 = build_cr3(pgd, user_asid(kern_asid));
-		write_cr3(user_asid_flush_cr3);
-		/*
-		 * We do not use PCIDs with KAISER unless we also
-		 * have INVPCID.  Getting here is unexpected.
-		 */
-		WARN_ON_ONCE(1);
-	}
-}
+__visible DEFINE_PER_CPU(unsigned long, __asid_flush);
 
 static void load_new_mm_cr3(pgd_t *pgdir, u16 new_asid, bool need_flush)
 {
 	unsigned long new_mm_cr3;
 
 	if (need_flush) {
-		flush_user_asid(pgdir, new_asid);
+		flush_user_asid(new_asid);
 		new_mm_cr3 = build_cr3(pgdir, new_asid);
 	} else {
 		new_mm_cr3 = build_cr3_noflush(pgdir, new_asid);

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [08/24] x86/mm/kaiser: Map the dynamically-allocated LDTs
  2017-11-27 10:49 ` [PATCH 08/24] x86/mm/kaiser: Map the dynamically-allocated LDTs Ingo Molnar
@ 2017-11-29 22:03   ` Guenter Roeck
  0 siblings, 0 replies; 70+ messages in thread
From: Guenter Roeck @ 2017-11-29 22:03 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Dave Hansen, Andy Lutomirski, Thomas Gleixner,
	H . Peter Anvin, Peter Zijlstra, Borislav Petkov, Linus Torvalds

On Mon, Nov 27, 2017 at 11:49:07AM +0100, Ingo Molnar wrote:
> From: Dave Hansen <dave.hansen@linux.intel.com>
> 
> Normally, a process has a NULL mm->context.ldt.  But, there is a
> syscall for a process to set a new one.  If a process does that,
> the LDT be mapped into the user page tables, just like the
> default copy.
> 
> The original KAISER patch missed this case.
> 
> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
> 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: Denys Vlasenko <dvlasenk@redhat.com>
> Cc: H. Peter Anvin <hpa@zytor.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: https://lkml.kernel.org/r/20171123003455.275397F7@viggo.jf.intel.com
> Signed-off-by: Ingo Molnar <mingo@kernel.org>
> ---
>  arch/x86/kernel/ldt.c | 25 ++++++++++++++++++++-----
>  1 file changed, 20 insertions(+), 5 deletions(-)
> 
... 
> +
>  /* The caller must call finalize_ldt_struct on the result. LDT starts zeroed. */
>  static struct ldt_struct *alloc_ldt_struct(unsigned int num_entries)
>  {
>  	struct ldt_struct *new_ldt;
>  	unsigned int alloc_size;
> +	int ret;
>  
>  	if (num_entries > LDT_ENTRIES)
>  		return NULL;
> @@ -89,6 +100,12 @@ static struct ldt_struct *alloc_ldt_struct(unsigned int num_entries)
>  		return NULL;
>  	}
>  
> +	ret = kaiser_add_mapping((unsigned long)new_ldt->entries, alloc_size,
> +				 __PAGE_KERNEL | _PAGE_GLOBAL);

This results in:

arch/x86/kernel/ldt.c: In function ‘alloc_ldt_struct’:
arch/x86/kernel/ldt.c:104:6: warning: large integer implicitly truncated to
unsigned type [-Woverflow]
      __PAGE_KERNEL | _PAGE_GLOBAL);
            ^

in ARCH=i386 builds with CONFIG_X86_PAE enabled. See
https://groups.google.com/forum/#!topic/cros-kernel-buildreports/8R41aX07daU

Guenter

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  2017-11-28  5:16   ` Andy Lutomirski
  2017-11-28  7:32     ` Dave Hansen
  2017-11-28 16:39     ` Peter Zijlstra
@ 2017-11-30 15:40     ` Peter Zijlstra
  2017-11-30 15:42       ` Andy Lutomirski
  2 siblings, 1 reply; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-30 15:40 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Ingo Molnar, linux-kernel, Dave Hansen, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Mon, Nov 27, 2017 at 09:16:19PM -0800, Andy Lutomirski wrote:
> On Mon, Nov 27, 2017 at 2:49 AM, Ingo Molnar <mingo@kernel.org> wrote:
> > From: Dave Hansen <dave.hansen@linux.intel.com>
> >
> > If changing the page tables in such a way that an invalidation of
> > all contexts (aka. PCIDs / ASIDs) is required, they can be
> > actively invalidated by:
> >
> >  1. INVPCID for each PCID (works for single pages too).
> >
> >  2. Load CR3 with each PCID without the NOFLUSH bit set
> >
> >  3. Load CR3 with the NOFLUSH bit set for each and do INVLPG for each address.
> >
> > But, none of these are really feasible since there are ~6 ASIDs (12 with
> > KAISER) at the time that invalidation is required.  Instead of
> > actively invalidating them, invalidate the *current* context and
> > also mark the cpu_tlbstate _quickly_ to indicate future invalidation
> > to be required.
> >
> > At the next context-switch, look for this indicator
> > ('all_other_ctxs_invalid' being set) invalidate all of the
> > cpu_tlbstate.ctxs[] entries.
> >
> > This ensures that any future context switches will do a full flush
> > of the TLB, picking up the previous changes.
> 
> NAK.

So I can't say I'm a fan of this patch either, but I tried really hard
to get rid of it, I can't really come up with anything better, see
below.

> We need to split up __flush_tlb_one() into __flush_tlb_one() and
> __flush_tlb_one_kernel().

I prefer __flush_tlb_kernel_one() -- given we already
flush_tlb_kernel_range().

So both __set_pte_vaddr() and __early_set_fixmap() are about setting up
fixmap and would need to flush world. But this seems to be mostly __init
code.

The kmmio one confuses me, I don't see how that is correct to just flush
the local CPU map.

tlb_uv appears to be about user mappings.

The rest is about pure kernel maps afaict.

> We've gotten away with having a single
> function for both this long because we've never had PCID on and
> nonglobal kernel mappings around.  So we're busted starting with
> "x86/mm/kaiser: Disable global pages by default with KAISER", which
> means that we have a potential corruption issue affecting anyone who
> tries to bisect the series.
> 
> Then we need to make the kernel variant do something sane (presumably
> just call __flush_tlb_all if we have PCID && !PGE).

(We don't support PCID && !PGE)

__flush_tlb_all() if PCID, because it needs to flush the thing from all
kernel ASIDs, which this patch -- however nasty -- achieves best.




---
diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h
index e67c0620aec2..a8e90f545495 100644
--- a/arch/x86/include/asm/pgtable_32.h
+++ b/arch/x86/include/asm/pgtable_32.h
@@ -61,7 +61,7 @@ void paging_init(void);
 #define kpte_clear_flush(ptep, vaddr)		\
 do {						\
 	pte_clear(&init_mm, (vaddr), (ptep));	\
-	__flush_tlb_one((vaddr));		\
+	__flush_tlb_kernel_one((vaddr));	\
 } while (0)
 
 #endif /* !__ASSEMBLY__ */
diff --git a/arch/x86/kernel/acpi/apei.c b/arch/x86/kernel/acpi/apei.c
index ea3046e0b0cf..0e430d5758ea 100644
--- a/arch/x86/kernel/acpi/apei.c
+++ b/arch/x86/kernel/acpi/apei.c
@@ -55,5 +55,5 @@ void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
 
 void arch_apei_flush_tlb_one(unsigned long addr)
 {
-	__flush_tlb_one(addr);
+	__flush_tlb_kernel_one(addr);
 }
diff --git a/arch/x86/mm/kmemcheck/kmemcheck.c b/arch/x86/mm/kmemcheck/kmemcheck.c
index 4515bae36bbe..202106fc0a64 100644
--- a/arch/x86/mm/kmemcheck/kmemcheck.c
+++ b/arch/x86/mm/kmemcheck/kmemcheck.c
@@ -101,7 +101,7 @@ int kmemcheck_show_addr(unsigned long address)
 		return 0;
 
 	set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT));
-	__flush_tlb_one(address);
+	__flush_tlb_kernel_one(address);
 	return 1;
 }
 
@@ -114,7 +114,7 @@ int kmemcheck_hide_addr(unsigned long address)
 		return 0;
 
 	set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT));
-	__flush_tlb_one(address);
+	__flush_tlb_kernel_one(address);
 	return 1;
 }
 
@@ -277,7 +277,7 @@ void kmemcheck_show_pages(struct page *p, unsigned int n)
 
 		set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT));
 		set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_HIDDEN));
-		__flush_tlb_one(address);
+		__flush_tlb_kernel_one(address);
 	}
 }
 
@@ -303,7 +303,7 @@ void kmemcheck_hide_pages(struct page *p, unsigned int n)
 
 		set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT));
 		set_pte(pte, __pte(pte_val(*pte) | _PAGE_HIDDEN));
-		__flush_tlb_one(address);
+		__flush_tlb_kernel_one(address);
 	}
 }
 

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  2017-11-30 15:40     ` Peter Zijlstra
@ 2017-11-30 15:42       ` Andy Lutomirski
  0 siblings, 0 replies; 70+ messages in thread
From: Andy Lutomirski @ 2017-11-30 15:42 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, linux-kernel, Dave Hansen, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Thu, Nov 30, 2017 at 7:40 AM, Peter Zijlstra <peterz@infradead.org> wrote:
> On Mon, Nov 27, 2017 at 09:16:19PM -0800, Andy Lutomirski wrote:
>> We've gotten away with having a single
>> function for both this long because we've never had PCID on and
>> nonglobal kernel mappings around.  So we're busted starting with
>> "x86/mm/kaiser: Disable global pages by default with KAISER", which
>> means that we have a potential corruption issue affecting anyone who
>> tries to bisect the series.
>>
>> Then we need to make the kernel variant do something sane (presumably
>> just call __flush_tlb_all if we have PCID && !PGE).
>
> (We don't support PCID && !PGE)
>
> __flush_tlb_all() if PCID, because it needs to flush the thing from all
> kernel ASIDs, which this patch -- however nasty -- achieves best.
>
>

Brain fart there.  What I meant was: the old code was wrong if PCID
was on and the page being flushed wasn't GLOBAL.  Which is what KAISER
dies.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  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-30 15:44   ` Peter Zijlstra
  2017-11-30 15:51     ` Dave Hansen
  1 sibling, 1 reply; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-30 15:44 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Dave Hansen, Andy Lutomirski, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Mon, Nov 27, 2017 at 11:49:14AM +0100, Ingo Molnar wrote:
> @@ -338,24 +366,23 @@ static inline void __native_flush_tlb_single(unsigned long addr)
>  
>  static inline void __flush_tlb_all(void)
>  {
> +	if (boot_cpu_has(X86_FEATURE_PGE)) {
>  		__flush_tlb_global();
> +	} else {
>  		__flush_tlb();
> +		tlb_flush_shared_nonglobals();

I do however think this one is superfluous; if we do not have PGE we
also do not have PCID and every CR3 switch flushes everything.

> +	}
>  }

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  2017-11-30 15:44   ` Peter Zijlstra
@ 2017-11-30 15:51     ` Dave Hansen
  2017-11-30 16:18       ` Peter Zijlstra
  0 siblings, 1 reply; 70+ messages in thread
From: Dave Hansen @ 2017-11-30 15:51 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar
  Cc: linux-kernel, Andy Lutomirski, Thomas Gleixner, H . Peter Anvin,
	Borislav Petkov, Linus Torvalds

On 11/30/2017 07:44 AM, Peter Zijlstra wrote:
> On Mon, Nov 27, 2017 at 11:49:14AM +0100, Ingo Molnar wrote:
>> @@ -338,24 +366,23 @@ static inline void __native_flush_tlb_single(unsigned long addr)
>>  
>>  static inline void __flush_tlb_all(void)
>>  {
>> +	if (boot_cpu_has(X86_FEATURE_PGE)) {
>>  		__flush_tlb_global();
>> +	} else {
>>  		__flush_tlb();
>> +		tlb_flush_shared_nonglobals();
> I do however think this one is superfluous; if we do not have PGE we
> also do not have PCID and every CR3 switch flushes everything.

I tried to sprinkle these around at all the sites that did non-global
kernel flushes.  In the case that it's superfluous !KAISER, it's a noop
anyway.  In the (currently unsupported) case that we *do* need it, well,
we need it.

It also makes it a bit more self-documenting that __flush_tlb() does not
flush shared non-globals.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  2017-11-30 15:51     ` Dave Hansen
@ 2017-11-30 16:18       ` Peter Zijlstra
  2017-11-30 18:44         ` Dave Hansen
  0 siblings, 1 reply; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-30 16:18 UTC (permalink / raw)
  To: Dave Hansen
  Cc: Ingo Molnar, linux-kernel, Andy Lutomirski, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Thu, Nov 30, 2017 at 07:51:17AM -0800, Dave Hansen wrote:
> On 11/30/2017 07:44 AM, Peter Zijlstra wrote:
> > On Mon, Nov 27, 2017 at 11:49:14AM +0100, Ingo Molnar wrote:
> >> @@ -338,24 +366,23 @@ static inline void __native_flush_tlb_single(unsigned long addr)
> >>  
> >>  static inline void __flush_tlb_all(void)
> >>  {
> >> +	if (boot_cpu_has(X86_FEATURE_PGE)) {
> >>  		__flush_tlb_global();
> >> +	} else {
> >>  		__flush_tlb();
> >> +		tlb_flush_shared_nonglobals();
> > I do however think this one is superfluous; if we do not have PGE we
> > also do not have PCID and every CR3 switch flushes everything.
> 
> I tried to sprinkle these around at all the sites that did non-global
> kernel flushes.  In the case that it's superfluous !KAISER, it's a noop
> anyway.  In the (currently unsupported) case that we *do* need it, well,
> we need it.

I'm confused. When would we need it there?

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  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:55           ` Peter Zijlstra
  0 siblings, 2 replies; 70+ messages in thread
From: Dave Hansen @ 2017-11-30 18:44 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, linux-kernel, Andy Lutomirski, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On 11/30/2017 08:18 AM, Peter Zijlstra wrote:
> On Thu, Nov 30, 2017 at 07:51:17AM -0800, Dave Hansen wrote:
>> On 11/30/2017 07:44 AM, Peter Zijlstra wrote:
>>> On Mon, Nov 27, 2017 at 11:49:14AM +0100, Ingo Molnar wrote:
>>>> @@ -338,24 +366,23 @@ static inline void __native_flush_tlb_single(unsigned long addr)
>>>>  
>>>>  static inline void __flush_tlb_all(void)
>>>>  {
>>>> +	if (boot_cpu_has(X86_FEATURE_PGE)) {
>>>>  		__flush_tlb_global();
>>>> +	} else {
>>>>  		__flush_tlb();
>>>> +		tlb_flush_shared_nonglobals();
>>> I do however think this one is superfluous; if we do not have PGE we
>>> also do not have PCID and every CR3 switch flushes everything.
>>
>> I tried to sprinkle these around at all the sites that did non-global
>> kernel flushes.  In the case that it's superfluous !KAISER, it's a noop
>> anyway.  In the (currently unsupported) case that we *do* need it, well,
>> we need it.
> 
> I'm confused. When would we need it there?

__flush_tlb() does a flushing CR3 write that flushes the current PCID.
If we need other PCIDs flushed, we have to do it via the
tlb_flush_shared_nonglobals() mechanism.

Does it matter today in practice?  Nope, we never have that situation.
But, it also doesn't _hurt_ to have that line there in any way.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  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 18:55           ` Peter Zijlstra
  1 sibling, 2 replies; 70+ messages in thread
From: Andy Lutomirski @ 2017-11-30 18:48 UTC (permalink / raw)
  To: Dave Hansen
  Cc: Peter Zijlstra, Ingo Molnar, linux-kernel, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Thu, Nov 30, 2017 at 10:44 AM, Dave Hansen
<dave.hansen@linux.intel.com> wrote:
> On 11/30/2017 08:18 AM, Peter Zijlstra wrote:
>> On Thu, Nov 30, 2017 at 07:51:17AM -0800, Dave Hansen wrote:
>>> On 11/30/2017 07:44 AM, Peter Zijlstra wrote:
>>>> On Mon, Nov 27, 2017 at 11:49:14AM +0100, Ingo Molnar wrote:
>>>>> @@ -338,24 +366,23 @@ static inline void __native_flush_tlb_single(unsigned long addr)
>>>>>
>>>>>  static inline void __flush_tlb_all(void)
>>>>>  {
>>>>> +  if (boot_cpu_has(X86_FEATURE_PGE)) {
>>>>>            __flush_tlb_global();
>>>>> +  } else {
>>>>>            __flush_tlb();
>>>>> +          tlb_flush_shared_nonglobals();
>>>> I do however think this one is superfluous; if we do not have PGE we
>>>> also do not have PCID and every CR3 switch flushes everything.
>>>
>>> I tried to sprinkle these around at all the sites that did non-global
>>> kernel flushes.  In the case that it's superfluous !KAISER, it's a noop
>>> anyway.  In the (currently unsupported) case that we *do* need it, well,
>>> we need it.
>>
>> I'm confused. When would we need it there?
>
> __flush_tlb() does a flushing CR3 write that flushes the current PCID.
> If we need other PCIDs flushed, we have to do it via the
> tlb_flush_shared_nonglobals() mechanism.
>
> Does it matter today in practice?  Nope, we never have that situation.
> But, it also doesn't _hurt_ to have that line there in any way.

Should it be tlb_flush_shared_nonglobals_if_kernel_and_user_pagetables_are_separate()?

The whole idea that we can get away with ambiguous functions like
__flush_tlb() seems to be much less true with KAISER.  I think we
should maybe start getting rid of overly vague functions like this.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  2017-11-30 18:48           ` Andy Lutomirski
@ 2017-11-30 18:53             ` Dave Hansen
  2017-11-30 20:01             ` Peter Zijlstra
  1 sibling, 0 replies; 70+ messages in thread
From: Dave Hansen @ 2017-11-30 18:53 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Peter Zijlstra, Ingo Molnar, linux-kernel, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On 11/30/2017 10:48 AM, Andy Lutomirski wrote:
>> __flush_tlb() does a flushing CR3 write that flushes the current PCID.
>> If we need other PCIDs flushed, we have to do it via the
>> tlb_flush_shared_nonglobals() mechanism.
>>
>> Does it matter today in practice?  Nope, we never have that situation.
>> But, it also doesn't _hurt_ to have that line there in any way.
> Should it be tlb_flush_shared_nonglobals_if_kernel_and_user_pagetables_are_separate()?

The separate page tables doesn't play into it as far as I can tell.  the
important thing is that you have "stuff" in some other *kernel* address
space that you didn't flush.

> The whole idea that we can get away with ambiguous functions like
> __flush_tlb() seems to be much less true with KAISER.  I think we
> should maybe start getting rid of overly vague functions like this.

Yeah, making the intent more explicit would be highly welcome.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  2017-11-30 18:44         ` Dave Hansen
  2017-11-30 18:48           ` Andy Lutomirski
@ 2017-11-30 18:55           ` Peter Zijlstra
  2017-11-30 19:00             ` Dave Hansen
  1 sibling, 1 reply; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-30 18:55 UTC (permalink / raw)
  To: Dave Hansen
  Cc: Ingo Molnar, linux-kernel, Andy Lutomirski, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Thu, Nov 30, 2017 at 10:44:40AM -0800, Dave Hansen wrote:
> On 11/30/2017 08:18 AM, Peter Zijlstra wrote:
> > On Thu, Nov 30, 2017 at 07:51:17AM -0800, Dave Hansen wrote:
> >> On 11/30/2017 07:44 AM, Peter Zijlstra wrote:
> >>> On Mon, Nov 27, 2017 at 11:49:14AM +0100, Ingo Molnar wrote:
> >>>> @@ -338,24 +366,23 @@ static inline void __native_flush_tlb_single(unsigned long addr)
> >>>>  
> >>>>  static inline void __flush_tlb_all(void)
> >>>>  {
> >>>> +	if (boot_cpu_has(X86_FEATURE_PGE)) {
> >>>>  		__flush_tlb_global();
> >>>> +	} else {
> >>>>  		__flush_tlb();
> >>>> +		tlb_flush_shared_nonglobals();
> >>> I do however think this one is superfluous; if we do not have PGE we
> >>> also do not have PCID and every CR3 switch flushes everything.
> >>
> >> I tried to sprinkle these around at all the sites that did non-global
> >> kernel flushes.  In the case that it's superfluous !KAISER, it's a noop
> >> anyway.  In the (currently unsupported) case that we *do* need it, well,
> >> we need it.
> > 
> > I'm confused. When would we need it there?
> 
> __flush_tlb() does a flushing CR3 write that flushes the current PCID.
> If we need other PCIDs flushed, we have to do it via the
> tlb_flush_shared_nonglobals() mechanism.

But the thing is, you _cannot_ have PCID enabled in that branch.

> Does it matter today in practice?  Nope, we never have that situation.
> But, it also doesn't _hurt_ to have that line there in any way.

Well, it confused the heck out of me.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  2017-11-30 18:55           ` Peter Zijlstra
@ 2017-11-30 19:00             ` Dave Hansen
  2017-11-30 19:20               ` Peter Zijlstra
  0 siblings, 1 reply; 70+ messages in thread
From: Dave Hansen @ 2017-11-30 19:00 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, linux-kernel, Andy Lutomirski, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On 11/30/2017 10:55 AM, Peter Zijlstra wrote:
>> __flush_tlb() does a flushing CR3 write that flushes the current PCID.
>> If we need other PCIDs flushed, we have to do it via the
>> tlb_flush_shared_nonglobals() mechanism.
> But the thing is, you _cannot_ have PCID enabled in that branch.

Is there some hardware limitation that I'm missing?

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  2017-11-30 19:00             ` Dave Hansen
@ 2017-11-30 19:20               ` Peter Zijlstra
  0 siblings, 0 replies; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-30 19:20 UTC (permalink / raw)
  To: Dave Hansen
  Cc: Ingo Molnar, linux-kernel, Andy Lutomirski, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Thu, Nov 30, 2017 at 11:00:06AM -0800, Dave Hansen wrote:
> On 11/30/2017 10:55 AM, Peter Zijlstra wrote:
> >> __flush_tlb() does a flushing CR3 write that flushes the current PCID.
> >> If we need other PCIDs flushed, we have to do it via the
> >> tlb_flush_shared_nonglobals() mechanism.
> > But the thing is, you _cannot_ have PCID enabled in that branch.
> 
> Is there some hardware limitation that I'm missing?

No, but in setup_pcid() we explicit clear PCID if !PGE.

And as you said, there isn't actually any real hardware that has this
combination, so who cares.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  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
  1 sibling, 1 reply; 70+ messages in thread
From: Peter Zijlstra @ 2017-11-30 20:01 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Dave Hansen, Ingo Molnar, linux-kernel, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Thu, Nov 30, 2017 at 10:48:56AM -0800, Andy Lutomirski wrote:
> Should it be tlb_flush_shared_nonglobals_if_kernel_and_user_pagetables_are_separate()?

Its effectively invpcid_flush_all_other() or something like that. Of
course, its not invpcid based, so we should not name it such.

flush_asid_other() ?

> The whole idea that we can get away with ambiguous functions like
> __flush_tlb() seems to be much less true with KAISER.  I think we
> should maybe start getting rid of overly vague functions like this.

There is a lot of cleanup to be done for sure. I had to actually draw
pictures to untangle this stuff.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/24] x86/mm: Allow flushing for future ASID switches
  2017-11-30 20:01             ` Peter Zijlstra
@ 2017-11-30 21:51               ` Andy Lutomirski
  0 siblings, 0 replies; 70+ messages in thread
From: Andy Lutomirski @ 2017-11-30 21:51 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Dave Hansen, Ingo Molnar, linux-kernel, Thomas Gleixner,
	H . Peter Anvin, Borislav Petkov, Linus Torvalds

On Thu, Nov 30, 2017 at 12:01 PM, Peter Zijlstra <peterz@infradead.org> wrote:
> On Thu, Nov 30, 2017 at 10:48:56AM -0800, Andy Lutomirski wrote:
>> Should it be tlb_flush_shared_nonglobals_if_kernel_and_user_pagetables_are_separate()?
>
> Its effectively invpcid_flush_all_other() or something like that. Of
> course, its not invpcid based, so we should not name it such.
>
> flush_asid_other() ?

How about mark_other_asids_invalid()?  It doesn't actually flush
anything.  And the caller could be:

if (!kernel_ptes_are_global()) {
  /* nothing to do.  INVLPG flushes global mappings for all ASIDs. */
} else {
  /* There is no efficient way to invalidate a given VA for all ASIDs
simultaneously. */
  mark_other_asids_invalid();
}

^ permalink raw reply	[flat|nested] 70+ messages in thread

end of thread, other threads:[~2017-11-30 21:51 UTC | newest]

Thread overview: 70+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 23/24] x86/mm/kaiser: Add boot time disable switch Ingo Molnar
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

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.