linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/9] Clarify/cleanup/fix tlbflush API/usage
@ 2017-12-05 12:34 Peter Zijlstra
  2017-12-05 12:34 ` [PATCH 1/9] x86/mm: Remove superfluous barriers Peter Zijlstra
                   ` (8 more replies)
  0 siblings, 9 replies; 13+ messages in thread
From: Peter Zijlstra @ 2017-12-05 12:34 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Linus Torvalds, Andy Lutomirsky, Peter Zijlstra,
	Dave Hansen, Borislav Petkov, Greg KH, keescook, hughd,
	Brian Gerst, Josh Poimboeuf, Denys Vlasenko, Rik van Riel,
	Boris Ostrovsky, Juergen Gross, David Laight, Eduardo Valentin,
	aliguori, Will Deacon, daniel.gruss, Dave Hansen, Ingo Molnar,
	moritz.lipp, linux-mm, Borislav Petkov, michael.schwarz,
	richard.fellner

By popular request, here be some patches (against tip/WIP.x86/kpti) that
clarify/cleanup/fix the x86 tlbflush API and usage.


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 1/9] x86/mm: Remove superfluous barriers
  2017-12-05 12:34 [PATCH 0/9] Clarify/cleanup/fix tlbflush API/usage Peter Zijlstra
@ 2017-12-05 12:34 ` Peter Zijlstra
  2017-12-05 12:34 ` [PATCH 2/9] x86/mm: Create asm/invpcid.h Peter Zijlstra
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2017-12-05 12:34 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Linus Torvalds, Andy Lutomirsky, Peter Zijlstra,
	Dave Hansen, Borislav Petkov, Greg KH, keescook, hughd,
	Brian Gerst, Josh Poimboeuf, Denys Vlasenko, Rik van Riel,
	Boris Ostrovsky, Juergen Gross, David Laight, Eduardo Valentin,
	aliguori, Will Deacon, daniel.gruss, Dave Hansen, Ingo Molnar,
	moritz.lipp, linux-mm, Borislav Petkov, michael.schwarz,
	richard.fellner

[-- Attachment #1: peterz-tlb-remove-barriers.patch --]
[-- Type: text/plain, Size: 1149 bytes --]

atomic64_inc_return() already implies smp_mb() before and after.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/tlbflush.h |    8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -62,19 +62,13 @@ static inline void invpcid_flush_all_non
 
 static inline u64 inc_mm_tlb_gen(struct mm_struct *mm)
 {
-	u64 new_tlb_gen;
-
 	/*
 	 * Bump the generation count.  This also serves as a full barrier
 	 * that synchronizes with switch_mm(): callers are required to order
 	 * their read of mm_cpumask after their writes to the paging
 	 * structures.
 	 */
-	smp_mb__before_atomic();
-	new_tlb_gen = atomic64_inc_return(&mm->context.tlb_gen);
-	smp_mb__after_atomic();
-
-	return new_tlb_gen;
+	return atomic64_inc_return(&mm->context.tlb_gen);
 }
 
 /* There are 12 bits of space for ASIDS in CR3 */


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 2/9] x86/mm: Create asm/invpcid.h
  2017-12-05 12:34 [PATCH 0/9] Clarify/cleanup/fix tlbflush API/usage Peter Zijlstra
  2017-12-05 12:34 ` [PATCH 1/9] x86/mm: Remove superfluous barriers Peter Zijlstra
@ 2017-12-05 12:34 ` Peter Zijlstra
  2017-12-05 12:34 ` [PATCH 3/9] x86/mm: Address feedback Peter Zijlstra
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2017-12-05 12:34 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Linus Torvalds, Andy Lutomirsky, Peter Zijlstra,
	Dave Hansen, Borislav Petkov, Greg KH, keescook, hughd,
	Brian Gerst, Josh Poimboeuf, Denys Vlasenko, Rik van Riel,
	Boris Ostrovsky, Juergen Gross, David Laight, Eduardo Valentin,
	aliguori, Will Deacon, daniel.gruss, Dave Hansen, Ingo Molnar,
	moritz.lipp, linux-mm, Borislav Petkov, michael.schwarz,
	richard.fellner

[-- Attachment #1: peterz-move-invpcid.patch --]
[-- Type: text/plain, Size: 4053 bytes --]

Unclutter tlbflush.h a little.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/invpcid.h  |   53 ++++++++++++++++++++++++++++++++++++++++
 arch/x86/include/asm/tlbflush.h |   49 ------------------------------------
 2 files changed, 54 insertions(+), 48 deletions(-)

--- /dev/null
+++ b/arch/x86/include/asm/invpcid.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_INVPCID
+#define _ASM_X86_INVPCID
+
+static inline void __invpcid(unsigned long pcid, unsigned long addr,
+			     unsigned long type)
+{
+	struct { u64 d[2]; } desc = { { pcid, addr } };
+
+	/*
+	 * The memory clobber is because the whole point is to invalidate
+	 * stale TLB entries and, especially if we're flushing global
+	 * mappings, we don't want the compiler to reorder any subsequent
+	 * memory accesses before the TLB flush.
+	 *
+	 * The hex opcode is invpcid (%ecx), %eax in 32-bit mode and
+	 * invpcid (%rcx), %rax in long mode.
+	 */
+	asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01"
+		      : : "m" (desc), "a" (type), "c" (&desc) : "memory");
+}
+
+#define INVPCID_TYPE_INDIV_ADDR		0
+#define INVPCID_TYPE_SINGLE_CTXT	1
+#define INVPCID_TYPE_ALL_INCL_GLOBAL	2
+#define INVPCID_TYPE_ALL_NON_GLOBAL	3
+
+/* Flush all mappings for a given pcid and addr, not including globals. */
+static inline void invpcid_flush_one(unsigned long pcid,
+				     unsigned long addr)
+{
+	__invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR);
+}
+
+/* Flush all mappings for a given PCID, not including globals. */
+static inline void invpcid_flush_single_context(unsigned long pcid)
+{
+	__invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT);
+}
+
+/* Flush all mappings, including globals, for all PCIDs. */
+static inline void invpcid_flush_all(void)
+{
+	__invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL);
+}
+
+/* Flush all mappings for all PCIDs except globals. */
+static inline void invpcid_flush_all_nonglobals(void)
+{
+	__invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL);
+}
+
+#endif /* _ASM_X86_INVPCID */
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -11,54 +11,7 @@
 #include <asm/smp.h>
 #include <asm/kpti.h>
 #include <asm/processor-flags.h>
-
-static inline void __invpcid(unsigned long pcid, unsigned long addr,
-			     unsigned long type)
-{
-	struct { u64 d[2]; } desc = { { pcid, addr } };
-
-	/*
-	 * The memory clobber is because the whole point is to invalidate
-	 * stale TLB entries and, especially if we're flushing global
-	 * mappings, we don't want the compiler to reorder any subsequent
-	 * memory accesses before the TLB flush.
-	 *
-	 * The hex opcode is invpcid (%ecx), %eax in 32-bit mode and
-	 * invpcid (%rcx), %rax in long mode.
-	 */
-	asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01"
-		      : : "m" (desc), "a" (type), "c" (&desc) : "memory");
-}
-
-#define INVPCID_TYPE_INDIV_ADDR		0
-#define INVPCID_TYPE_SINGLE_CTXT	1
-#define INVPCID_TYPE_ALL_INCL_GLOBAL	2
-#define INVPCID_TYPE_ALL_NON_GLOBAL	3
-
-/* Flush all mappings for a given pcid and addr, not including globals. */
-static inline void invpcid_flush_one(unsigned long pcid,
-				     unsigned long addr)
-{
-	__invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR);
-}
-
-/* Flush all mappings for a given PCID, not including globals. */
-static inline void invpcid_flush_single_context(unsigned long pcid)
-{
-	__invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT);
-}
-
-/* Flush all mappings, including globals, for all PCIDs. */
-static inline void invpcid_flush_all(void)
-{
-	__invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL);
-}
-
-/* Flush all mappings for all PCIDs except globals. */
-static inline void invpcid_flush_all_nonglobals(void)
-{
-	__invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL);
-}
+#include <asm/invpcid.h>
 
 static inline u64 inc_mm_tlb_gen(struct mm_struct *mm)
 {


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 3/9] x86/mm: Address feedback
  2017-12-05 12:34 [PATCH 0/9] Clarify/cleanup/fix tlbflush API/usage Peter Zijlstra
  2017-12-05 12:34 ` [PATCH 1/9] x86/mm: Remove superfluous barriers Peter Zijlstra
  2017-12-05 12:34 ` [PATCH 2/9] x86/mm: Create asm/invpcid.h Peter Zijlstra
@ 2017-12-05 12:34 ` Peter Zijlstra
  2017-12-05 12:34 ` [PATCH 4/9] x86/mm: Use __flush_tlb_one() for kernel memory Peter Zijlstra
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2017-12-05 12:34 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Linus Torvalds, Andy Lutomirsky, Peter Zijlstra,
	Dave Hansen, Borislav Petkov, Greg KH, keescook, hughd,
	Brian Gerst, Josh Poimboeuf, Denys Vlasenko, Rik van Riel,
	Boris Ostrovsky, Juergen Gross, David Laight, Eduardo Valentin,
	aliguori, Will Deacon, daniel.gruss, Dave Hansen, Ingo Molnar,
	moritz.lipp, linux-mm, Borislav Petkov, michael.schwarz,
	richard.fellner

[-- Attachment #1: peterz-tlb-invalidate-other-fix.patch --]
[-- Type: text/plain, Size: 2007 bytes --]

fold into: ("x86/mm: Allow flushing for future ASID switches")

Andy asked for the KPTI check to be pulled out of the API such that
the function always does as advertised.

Rename to: invalidate_other_asid() because the pcid name is actually
wrong if we consider our ASID to represend two PCID values (as it does
with KPTI). In specific, it will not flush the user PCID of the
current ASID.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/tlbflush.h |   24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -270,16 +270,11 @@ static inline unsigned long cr4_read_sha
 	return this_cpu_read(cpu_tlbstate.cr4);
 }
 
-static inline void invalidate_pcid_other(void)
+/*
+ * Mark all other ASIDs as invalid, preserves the current.
+ */
+static inline void invalidate_other_asid(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 (!static_cpu_has_bug(X86_BUG_CPU_SECURE_MODE_KPTI))
-		return;
-
 	this_cpu_write(cpu_tlbstate.invalidate_other, true);
 }
 
@@ -411,11 +406,16 @@ static inline void __flush_tlb_one(unsig
 {
 	count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ONE);
 	__flush_tlb_single(addr);
+
+	if (!static_cpu_has_bug(X86_BUG_CPU_SECURE_MODE_KPTI))
+		return;
+
 	/*
-	 * Invalidate other address spaces inaccessible to single-page
-	 * invalidation:
+	 * __flush_tlb_single() will have cleared the TLB entry for this ASID,
+	 * but since kernel space is replicated across all, we must also
+	 * invalidate all others.
 	 */
-	invalidate_pcid_other();
+	invalidate_other_asid();
 }
 
 #define TLB_FLUSH_ALL	-1UL


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 4/9] x86/mm: Use __flush_tlb_one() for kernel memory
  2017-12-05 12:34 [PATCH 0/9] Clarify/cleanup/fix tlbflush API/usage Peter Zijlstra
                   ` (2 preceding siblings ...)
  2017-12-05 12:34 ` [PATCH 3/9] x86/mm: Address feedback Peter Zijlstra
@ 2017-12-05 12:34 ` Peter Zijlstra
  2017-12-05 12:34 ` [PATCH 5/9] x86/uv: Use the right tlbflush API Peter Zijlstra
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2017-12-05 12:34 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Linus Torvalds, Andy Lutomirsky, Peter Zijlstra,
	Dave Hansen, Borislav Petkov, Greg KH, keescook, hughd,
	Brian Gerst, Josh Poimboeuf, Denys Vlasenko, Rik van Riel,
	Boris Ostrovsky, Juergen Gross, David Laight, Eduardo Valentin,
	aliguori, Will Deacon, daniel.gruss, Dave Hansen, Ingo Molnar,
	moritz.lipp, linux-mm, Borislav Petkov, michael.schwarz,
	richard.fellner

[-- Attachment #1: peterz-tlb-flush_kernel_range.patch --]
[-- Type: text/plain, Size: 825 bytes --]

__flush_tlb_single() is for user mappings, __flush_tlb_one() for
kernel mappings.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/mm/tlb.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -605,9 +605,7 @@ static void do_kernel_range_flush(void *
 
 	/* flush range by one by one 'invlpg' */
 	for (addr = f->start; addr < f->end; addr += PAGE_SIZE)
-		__flush_tlb_single(addr);
-
-	invalidate_pcid_other();
+		__flush_tlb_one(addr);
 }
 
 void flush_tlb_kernel_range(unsigned long start, unsigned long end)


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 5/9] x86/uv: Use the right tlbflush API
  2017-12-05 12:34 [PATCH 0/9] Clarify/cleanup/fix tlbflush API/usage Peter Zijlstra
                   ` (3 preceding siblings ...)
  2017-12-05 12:34 ` [PATCH 4/9] x86/mm: Use __flush_tlb_one() for kernel memory Peter Zijlstra
@ 2017-12-05 12:34 ` Peter Zijlstra
  2017-12-05 21:09   ` Andrew Banman
  2017-12-05 12:34 ` [PATCH 6/9] x86/microcode: Dont abuse the tlbflush interface Peter Zijlstra
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 13+ messages in thread
From: Peter Zijlstra @ 2017-12-05 12:34 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Linus Torvalds, Andy Lutomirsky, Peter Zijlstra,
	Dave Hansen, Borislav Petkov, Greg KH, keescook, hughd,
	Brian Gerst, Josh Poimboeuf, Denys Vlasenko, Rik van Riel,
	Boris Ostrovsky, Juergen Gross, David Laight, Eduardo Valentin,
	aliguori, Will Deacon, daniel.gruss, Dave Hansen, Ingo Molnar,
	moritz.lipp, linux-mm, Borislav Petkov, michael.schwarz,
	richard.fellner, Andrew Banman, Mike Travis

[-- Attachment #1: peterz-tlb-uv.patch --]
[-- Type: text/plain, Size: 938 bytes --]

Since uv_flush_tlb_others() implements flush_tlb_others() which is
about flushing user mappings, we should use __flush_tlb_single(),
which too is about flushing user mappings.

Cc: Andrew Banman <abanman@hpe.com>
Cc: Mike Travis <mike.travis@hpe.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/platform/uv/tlb_uv.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/x86/platform/uv/tlb_uv.c
+++ b/arch/x86/platform/uv/tlb_uv.c
@@ -299,7 +299,7 @@ static void bau_process_message(struct m
 		local_flush_tlb();
 		stat->d_alltlb++;
 	} else {
-		__flush_tlb_one(msg->address);
+		__flush_tlb_single(msg->address);
 		stat->d_onetlb++;
 	}
 	stat->d_requestee++;


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 6/9] x86/microcode: Dont abuse the tlbflush interface
  2017-12-05 12:34 [PATCH 0/9] Clarify/cleanup/fix tlbflush API/usage Peter Zijlstra
                   ` (4 preceding siblings ...)
  2017-12-05 12:34 ` [PATCH 5/9] x86/uv: Use the right tlbflush API Peter Zijlstra
@ 2017-12-05 12:34 ` Peter Zijlstra
  2017-12-05 12:34 ` [PATCH 7/9] x86/mm: Clarify which functions are supposed to flush what Peter Zijlstra
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2017-12-05 12:34 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Linus Torvalds, Andy Lutomirsky, Peter Zijlstra,
	Dave Hansen, Borislav Petkov, Greg KH, keescook, hughd,
	Brian Gerst, Josh Poimboeuf, Denys Vlasenko, Rik van Riel,
	Boris Ostrovsky, Juergen Gross, David Laight, Eduardo Valentin,
	aliguori, Will Deacon, daniel.gruss, Dave Hansen, Ingo Molnar,
	moritz.lipp, linux-mm, Borislav Petkov, michael.schwarz,
	richard.fellner, hpa, fenghua.yu

[-- Attachment #1: peterz-tlb-cleanup.patch --]
[-- Type: text/plain, Size: 2432 bytes --]

Commit ec400ddeff20 ("x86/microcode_intel_early.c: Early update ucode
on Intel's CPU") grubbed into tlbflush internals without coherent
explanation.

Since it says its precaution and the SDM doesn't mention anything like
this, take it out back.

Cc: hpa@zytor.com
Cc: fenghua.yu@intel.com
Cc: bp@alien8.de
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/tlbflush.h       |   19 ++++++-------------
 arch/x86/kernel/cpu/microcode/intel.c |   13 -------------
 2 files changed, 6 insertions(+), 26 deletions(-)

--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -394,20 +394,9 @@ static inline void __native_flush_tlb(vo
 	preempt_enable();
 }
 
-static inline void __native_flush_tlb_global_irq_disabled(void)
-{
-	unsigned long cr4;
-
-	cr4 = this_cpu_read(cpu_tlbstate.cr4);
-	/* clear PGE */
-	native_write_cr4(cr4 & ~X86_CR4_PGE);
-	/* write old PGE again and flush TLBs */
-	native_write_cr4(cr4);
-}
-
 static inline void __native_flush_tlb_global(void)
 {
-	unsigned long flags;
+	unsigned long cr4, flags;
 
 	if (static_cpu_has(X86_FEATURE_INVPCID)) {
 		/*
@@ -427,7 +416,11 @@ static inline void __native_flush_tlb_gl
 	 */
 	raw_local_irq_save(flags);
 
-	__native_flush_tlb_global_irq_disabled();
+	cr4 = this_cpu_read(cpu_tlbstate.cr4);
+	/* toggle PGE */
+	native_write_cr4(cr4 ^ X86_CR4_PGE);
+	/* write old PGE again and flush TLBs */
+	native_write_cr4(cr4);
 
 	raw_local_irq_restore(flags);
 }
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -565,15 +565,6 @@ static void print_ucode(struct ucode_cpu
 }
 #else
 
-/*
- * Flush global tlb. We only do this in x86_64 where paging has been enabled
- * already and PGE should be enabled as well.
- */
-static inline void flush_tlb_early(void)
-{
-	__native_flush_tlb_global_irq_disabled();
-}
-
 static inline void print_ucode(struct ucode_cpu_info *uci)
 {
 	struct microcode_intel *mc;
@@ -602,10 +593,6 @@ static int apply_microcode_early(struct
 	if (rev != mc->hdr.rev)
 		return -1;
 
-#ifdef CONFIG_X86_64
-	/* Flush global tlb. This is precaution. */
-	flush_tlb_early();
-#endif
 	uci->cpu_sig.rev = rev;
 
 	if (early)


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 7/9] x86/mm: Clarify which functions are supposed to flush what
  2017-12-05 12:34 [PATCH 0/9] Clarify/cleanup/fix tlbflush API/usage Peter Zijlstra
                   ` (5 preceding siblings ...)
  2017-12-05 12:34 ` [PATCH 6/9] x86/microcode: Dont abuse the tlbflush interface Peter Zijlstra
@ 2017-12-05 12:34 ` Peter Zijlstra
  2017-12-05 12:34 ` [PATCH 8/9] x86/mm: Clarify the whole ASID/kernel PCID/user PCID naming Peter Zijlstra
  2017-12-05 12:34 ` [PATCH 9/9] x86/doc: Remove obvious weirdness Peter Zijlstra
  8 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2017-12-05 12:34 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Linus Torvalds, Andy Lutomirsky, Peter Zijlstra,
	Dave Hansen, Borislav Petkov, Greg KH, keescook, hughd,
	Brian Gerst, Josh Poimboeuf, Denys Vlasenko, Rik van Riel,
	Boris Ostrovsky, Juergen Gross, David Laight, Eduardo Valentin,
	aliguori, Will Deacon, daniel.gruss, Dave Hansen, Ingo Molnar,
	moritz.lipp, linux-mm, Borislav Petkov, michael.schwarz,
	richard.fellner

[-- Attachment #1: peterz-tlb-comment.patch --]
[-- Type: text/plain, Size: 1803 bytes --]

Per popular request..

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/tlbflush.h |   18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -376,6 +376,9 @@ static inline void invalidate_user_asid(
 		  (unsigned long *)this_cpu_ptr(&cpu_tlbstate.user_pcid_flush_mask));
 }
 
+/*
+ * flush the entire current user mapping
+ */
 static inline void __native_flush_tlb(void)
 {
 	invalidate_user_asid(this_cpu_read(cpu_tlbstate.loaded_mm_asid));
@@ -389,6 +392,9 @@ static inline void __native_flush_tlb(vo
 	preempt_enable();
 }
 
+/*
+ * flush everything
+ */
 static inline void __native_flush_tlb_global(void)
 {
 	unsigned long cr4, flags;
@@ -420,6 +426,9 @@ static inline void __native_flush_tlb_gl
 	raw_local_irq_restore(flags);
 }
 
+/*
+ * flush one page in the user mapping
+ */
 static inline void __native_flush_tlb_single(unsigned long addr)
 {
 	u32 loaded_mm_asid = this_cpu_read(cpu_tlbstate.loaded_mm_asid);
@@ -439,15 +448,24 @@ static inline void __native_flush_tlb_si
 		invpcid_flush_one(user_pcid(loaded_mm_asid), addr);
 }
 
+/*
+ * flush everything
+ */
 static inline void __flush_tlb_all(void)
 {
 	if (boot_cpu_has(X86_FEATURE_PGE)) {
 		__flush_tlb_global();
 	} else {
+		/*
+		 * !PGE -> !PCID (setup_pcid()), thus every flush is total.
+		 */
 		__flush_tlb();
 	}
 }
 
+/*
+ * flush one page in the kernel mapping
+ */
 static inline void __flush_tlb_one(unsigned long addr)
 {
 	count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ONE);


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 8/9] x86/mm: Clarify the whole ASID/kernel PCID/user PCID naming
  2017-12-05 12:34 [PATCH 0/9] Clarify/cleanup/fix tlbflush API/usage Peter Zijlstra
                   ` (6 preceding siblings ...)
  2017-12-05 12:34 ` [PATCH 7/9] x86/mm: Clarify which functions are supposed to flush what Peter Zijlstra
@ 2017-12-05 12:34 ` Peter Zijlstra
  2017-12-05 12:34 ` [PATCH 9/9] x86/doc: Remove obvious weirdness Peter Zijlstra
  8 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2017-12-05 12:34 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Linus Torvalds, Andy Lutomirsky, Peter Zijlstra,
	Dave Hansen, Borislav Petkov, Greg KH, keescook, hughd,
	Brian Gerst, Josh Poimboeuf, Denys Vlasenko, Rik van Riel,
	Boris Ostrovsky, Juergen Gross, David Laight, Eduardo Valentin,
	aliguori, Will Deacon, daniel.gruss, Dave Hansen, Ingo Molnar,
	moritz.lipp, linux-mm, Borislav Petkov, michael.schwarz,
	richard.fellner

[-- Attachment #1: peterz-tlb-comment-asid.patch --]
[-- Type: text/plain, Size: 3676 bytes --]

Ideally we'd also use sparse to enforce this sparation so it becomes
much more difficult to mess up.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/tlbflush.h |   55 +++++++++++++++++++++++++++++++---------
 1 file changed, 43 insertions(+), 12 deletions(-)

--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -13,16 +13,33 @@
 #include <asm/processor-flags.h>
 #include <asm/invpcid.h>
 
-static inline u64 inc_mm_tlb_gen(struct mm_struct *mm)
-{
-	/*
-	 * Bump the generation count.  This also serves as a full barrier
-	 * that synchronizes with switch_mm(): callers are required to order
-	 * their read of mm_cpumask after their writes to the paging
-	 * structures.
-	 */
-	return atomic64_inc_return(&mm->context.tlb_gen);
-}
+/*
+ * The x86 feature is called PCID (Process Context IDentifier). It is similar
+ * to what is traditionally called ASID on the RISC processors.
+ *
+ * We don't use the traditional ASID implementation, where each process/mm gets
+ * its own ASID and flush/restart when we run out of ASID space.
+ *
+ * Instead we have a small per-cpu array of ASIDs and cache the last few mm's
+ * that came by on this CPU, allowing cheaper switch_mm between processes on
+ * this CPU.
+ *
+ * We end up with different spaces for different things. To avoid confusion we
+ * use different names for each of them:
+ *
+ * ASID  - [0, TLB_NR_DYN_ASIDS-1]
+ *         the canonical identifier for an mm
+ *
+ * kPCID - [1, TLB_NR_DYN_ASIDS]
+ *         the value we write into the PCID part of CR3; corresponds to the
+ *         ASID+1, because PCID 0 is special.
+ *
+ * uPCID - [2048 + 1, 2048 + TLB_NR_DYN_ASIDS]
+ *         for KPTI each mm has two address spaces and thus needs two
+ *         PCID values, but we can still do with a single ASID denomination
+ *         for each mm. Corresponds to kPCID + 2048.
+ *
+ */
 
 /* There are 12 bits of space for ASIDS in CR3 */
 #define CR3_HW_ASID_BITS		12
@@ -41,7 +58,7 @@ static inline u64 inc_mm_tlb_gen(struct
 
 /*
  * 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
+ * for them being zero-based.  Another -1 is because PCID 0 is reserved for
  * use by non-PCID-aware users.
  */
 #define MAX_ASID_AVAILABLE ((1 << CR3_AVAIL_PCID_BITS) - 2)
@@ -52,6 +69,9 @@ static inline u64 inc_mm_tlb_gen(struct
  */
 #define TLB_NR_DYN_ASIDS	6
 
+/*
+ * Given @asid, compute kPCID
+ */
 static inline u16 kern_pcid(u16 asid)
 {
 	VM_WARN_ON_ONCE(asid > MAX_ASID_AVAILABLE);
@@ -86,7 +106,7 @@ static inline u16 kern_pcid(u16 asid)
 }
 
 /*
- * The user PCID is just the kernel one, plus the "switch bit".
+ * Given @asid, compute uPCID
  */
 static inline u16 user_pcid(u16 asid)
 {
@@ -487,6 +507,17 @@ static inline void flush_tlb_page(struct
 void native_flush_tlb_others(const struct cpumask *cpumask,
 			     const struct flush_tlb_info *info);
 
+static inline u64 inc_mm_tlb_gen(struct mm_struct *mm)
+{
+	/*
+	 * Bump the generation count.  This also serves as a full barrier
+	 * that synchronizes with switch_mm(): callers are required to order
+	 * their read of mm_cpumask after their writes to the paging
+	 * structures.
+	 */
+	return atomic64_inc_return(&mm->context.tlb_gen);
+}
+
 static inline void arch_tlbbatch_add_mm(struct arch_tlbflush_unmap_batch *batch,
 					struct mm_struct *mm)
 {


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 9/9] x86/doc: Remove obvious weirdness
  2017-12-05 12:34 [PATCH 0/9] Clarify/cleanup/fix tlbflush API/usage Peter Zijlstra
                   ` (7 preceding siblings ...)
  2017-12-05 12:34 ` [PATCH 8/9] x86/mm: Clarify the whole ASID/kernel PCID/user PCID naming Peter Zijlstra
@ 2017-12-05 12:34 ` Peter Zijlstra
  8 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2017-12-05 12:34 UTC (permalink / raw)
  To: linux-kernel
  Cc: x86, Linus Torvalds, Andy Lutomirsky, Peter Zijlstra,
	Dave Hansen, Borislav Petkov, Greg KH, keescook, hughd,
	Brian Gerst, Josh Poimboeuf, Denys Vlasenko, Rik van Riel,
	Boris Ostrovsky, Juergen Gross, David Laight, Eduardo Valentin,
	aliguori, Will Deacon, daniel.gruss, Dave Hansen, Ingo Molnar,
	moritz.lipp, linux-mm, Borislav Petkov, michael.schwarz,
	richard.fellner

[-- Attachment #1: peterz-mm-doc.patch --]
[-- Type: text/plain, Size: 2144 bytes --]


Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 Documentation/x86/x86_64/mm.txt |   12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

--- a/Documentation/x86/x86_64/mm.txt
+++ b/Documentation/x86/x86_64/mm.txt
@@ -1,6 +1,4 @@
 
-<previous description obsolete, deleted>
-
 Virtual memory map with 4 level page tables:
 
 0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm
@@ -47,8 +45,9 @@ ffffffffffe00000 - ffffffffffffffff (=2
 
 Architecture defines a 64-bit virtual address. Implementations can support
 less. Currently supported are 48- and 57-bit virtual addresses. Bits 63
-through to the most-significant implemented bit are set to either all ones
-or all zero. This causes hole between user space and kernel addresses.
+through to the most-significant implemented bit are sign extended.
+This causes hole between user space and kernel addresses if you interpret them
+as unsigned.
 
 The direct mapping covers all memory in the system up to the highest
 memory address (this means in some cases it can also include PCI memory
@@ -58,9 +57,6 @@ vmalloc space is lazily synchronized int
 the processes using the page fault handler, with init_top_pgt as
 reference.
 
-Current X86-64 implementations support up to 46 bits of address space (64 TB),
-which is our current limit. This expands into MBZ space in the page tables.
-
 We map EFI runtime services in the 'efi_pgd' PGD in a 64Gb large virtual
 memory window (this size is arbitrary, it can be raised later if needed).
 The mappings are not part of any other kernel PGD and are only available
@@ -72,5 +68,3 @@ following fixmap section.
 Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
 physical memory, vmalloc/ioremap space and virtual memory map are randomized.
 Their order is preserved but their base will be offset early at boot time.
-
--Andi Kleen, Jul 2004


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 5/9] x86/uv: Use the right tlbflush API
  2017-12-05 12:34 ` [PATCH 5/9] x86/uv: Use the right tlbflush API Peter Zijlstra
@ 2017-12-05 21:09   ` Andrew Banman
  2017-12-05 21:27     ` Peter Zijlstra
  0 siblings, 1 reply; 13+ messages in thread
From: Andrew Banman @ 2017-12-05 21:09 UTC (permalink / raw)
  To: Peter Zijlstra, linux-kernel
  Cc: x86, Linus Torvalds, Andy Lutomirsky, Dave Hansen,
	Borislav Petkov, Greg KH, keescook, hughd, Brian Gerst,
	Josh Poimboeuf, Denys Vlasenko, Rik van Riel, Boris Ostrovsky,
	Juergen Gross, David Laight, Eduardo Valentin, aliguori,
	Will Deacon, daniel.gruss, Dave Hansen, Ingo Molnar, moritz.lipp,
	linux-mm, Borislav Petkov, michael.schwarz, richard.fellner,
	Mike Travis

On 12/5/17 6:34 AM, Peter Zijlstra wrote:
> Since uv_flush_tlb_others() implements flush_tlb_others() which is
> about flushing user mappings, we should use __flush_tlb_single(),
> which too is about flushing user mappings.
> 
> Cc: Andrew Banman<abanman@hpe.com>
> Cc: Mike Travis<mike.travis@hpe.com>
> Signed-off-by: Peter Zijlstra (Intel)<peterz@infradead.org>
> ---
>   arch/x86/platform/uv/tlb_uv.c |    2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> --- a/arch/x86/platform/uv/tlb_uv.c
> +++ b/arch/x86/platform/uv/tlb_uv.c
> @@ -299,7 +299,7 @@ static void bau_process_message(struct m
>   		local_flush_tlb();
>   		stat->d_alltlb++;
>   	} else {
> -		__flush_tlb_one(msg->address);
> +		__flush_tlb_single(msg->address);
>   		stat->d_onetlb++;
>   	}
>   	stat->d_requestee++;

This looks like the right thing to do. We'll be testing it and complain later if
we find any problems, but I'm not expecting any since this patch looks to
maintain our status quo.

Best,

Andrew

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 5/9] x86/uv: Use the right tlbflush API
  2017-12-05 21:09   ` Andrew Banman
@ 2017-12-05 21:27     ` Peter Zijlstra
  2017-12-05 23:04       ` Andrew Banman
  0 siblings, 1 reply; 13+ messages in thread
From: Peter Zijlstra @ 2017-12-05 21:27 UTC (permalink / raw)
  To: Andrew Banman
  Cc: linux-kernel, x86, Linus Torvalds, Andy Lutomirsky, Dave Hansen,
	Borislav Petkov, Greg KH, keescook, hughd, Brian Gerst,
	Josh Poimboeuf, Denys Vlasenko, Rik van Riel, Boris Ostrovsky,
	Juergen Gross, David Laight, Eduardo Valentin, aliguori,
	Will Deacon, daniel.gruss, Dave Hansen, Ingo Molnar, moritz.lipp,
	linux-mm, Borislav Petkov, michael.schwarz, richard.fellner,
	Mike Travis

On Tue, Dec 05, 2017 at 03:09:48PM -0600, Andrew Banman wrote:
> On 12/5/17 6:34 AM, Peter Zijlstra wrote:
> >Since uv_flush_tlb_others() implements flush_tlb_others() which is
> >about flushing user mappings, we should use __flush_tlb_single(),
> >which too is about flushing user mappings.
> >
> >Cc: Andrew Banman<abanman@hpe.com>
> >Cc: Mike Travis<mike.travis@hpe.com>
> >Signed-off-by: Peter Zijlstra (Intel)<peterz@infradead.org>
> >---
> >  arch/x86/platform/uv/tlb_uv.c |    2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> >--- a/arch/x86/platform/uv/tlb_uv.c
> >+++ b/arch/x86/platform/uv/tlb_uv.c
> >@@ -299,7 +299,7 @@ static void bau_process_message(struct m
> >  		local_flush_tlb();
> >  		stat->d_alltlb++;
> >  	} else {
> >-		__flush_tlb_one(msg->address);
> >+		__flush_tlb_single(msg->address);
> >  		stat->d_onetlb++;
> >  	}
> >  	stat->d_requestee++;
> 
> This looks like the right thing to do. We'll be testing it and complain later if
> we find any problems, but I'm not expecting any since this patch looks to
> maintain our status quo.

Well, with KPTI (the-patch-set-formerly-known-as-kaiser), there will be
a distinct difference between the two.

With KPTI __flush_tlb_one() would end up invalidating all kernel
mappings while __flush_tlb_single() will end up only invalidating the
user mappings of the current mm.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 5/9] x86/uv: Use the right tlbflush API
  2017-12-05 21:27     ` Peter Zijlstra
@ 2017-12-05 23:04       ` Andrew Banman
  0 siblings, 0 replies; 13+ messages in thread
From: Andrew Banman @ 2017-12-05 23:04 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: linux-kernel, x86, Linus Torvalds, Andy Lutomirsky, Dave Hansen,
	Borislav Petkov, Greg KH, keescook, hughd, Brian Gerst,
	Josh Poimboeuf, Denys Vlasenko, Rik van Riel, Boris Ostrovsky,
	Juergen Gross, David Laight, Eduardo Valentin, aliguori,
	Will Deacon, daniel.gruss, Dave Hansen, Ingo Molnar, moritz.lipp,
	linux-mm, Borislav Petkov, michael.schwarz, richard.fellner,
	Mike Travis



On 12/5/17 3:27 PM, Peter Zijlstra wrote:
> On Tue, Dec 05, 2017 at 03:09:48PM -0600, Andrew Banman wrote:
>> On 12/5/17 6:34 AM, Peter Zijlstra wrote:
>>> Since uv_flush_tlb_others() implements flush_tlb_others() which is
>>> about flushing user mappings, we should use __flush_tlb_single(),
>>> which too is about flushing user mappings.
>>>
>>> Cc: Andrew Banman<abanman@hpe.com>
>>> Cc: Mike Travis<mike.travis@hpe.com>
>>> Signed-off-by: Peter Zijlstra (Intel)<peterz@infradead.org>
>>> ---
>>>   arch/x86/platform/uv/tlb_uv.c |    2 +-
>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> --- a/arch/x86/platform/uv/tlb_uv.c
>>> +++ b/arch/x86/platform/uv/tlb_uv.c
>>> @@ -299,7 +299,7 @@ static void bau_process_message(struct m
>>>   		local_flush_tlb();
>>>   		stat->d_alltlb++;
>>>   	} else {
>>> -		__flush_tlb_one(msg->address);
>>> +		__flush_tlb_single(msg->address);
>>>   		stat->d_onetlb++;
>>>   	}
>>>   	stat->d_requestee++;
>>
>> This looks like the right thing to do. We'll be testing it and complain later if
>> we find any problems, but I'm not expecting any since this patch looks to
>> maintain our status quo.
> 
> Well, with KPTI (the-patch-set-formerly-known-as-kaiser), there will be
> a distinct difference between the two.
> 
> With KPTI __flush_tlb_one() would end up invalidating all kernel
> mappings while __flush_tlb_single() will end up only invalidating the
> user mappings of the current mm.
> 

Right! Now the KPTI __flush_tlb_single() equals the old
__flush_tlb_one(), less the call to count_vm_tlb_event().

ACK

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

end of thread, other threads:[~2017-12-05 23:04 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-05 12:34 [PATCH 0/9] Clarify/cleanup/fix tlbflush API/usage Peter Zijlstra
2017-12-05 12:34 ` [PATCH 1/9] x86/mm: Remove superfluous barriers Peter Zijlstra
2017-12-05 12:34 ` [PATCH 2/9] x86/mm: Create asm/invpcid.h Peter Zijlstra
2017-12-05 12:34 ` [PATCH 3/9] x86/mm: Address feedback Peter Zijlstra
2017-12-05 12:34 ` [PATCH 4/9] x86/mm: Use __flush_tlb_one() for kernel memory Peter Zijlstra
2017-12-05 12:34 ` [PATCH 5/9] x86/uv: Use the right tlbflush API Peter Zijlstra
2017-12-05 21:09   ` Andrew Banman
2017-12-05 21:27     ` Peter Zijlstra
2017-12-05 23:04       ` Andrew Banman
2017-12-05 12:34 ` [PATCH 6/9] x86/microcode: Dont abuse the tlbflush interface Peter Zijlstra
2017-12-05 12:34 ` [PATCH 7/9] x86/mm: Clarify which functions are supposed to flush what Peter Zijlstra
2017-12-05 12:34 ` [PATCH 8/9] x86/mm: Clarify the whole ASID/kernel PCID/user PCID naming Peter Zijlstra
2017-12-05 12:34 ` [PATCH 9/9] x86/doc: Remove obvious weirdness Peter Zijlstra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).