]>
Commit | Line | Data |
---|---|---|
59d5af67 | 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
321d628a FG |
2 | From: Peter Zijlstra <peterz@infradead.org> |
3 | Date: Tue, 5 Dec 2017 13:34:53 +0100 | |
59d5af67 | 4 | Subject: [PATCH] x86/mm: Clarify the whole ASID/kernel PCID/user PCID naming |
321d628a FG |
5 | MIME-Version: 1.0 |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | CVE-2017-5754 | |
10 | ||
11 | Ideally we'd also use sparse to enforce this separation so it becomes much | |
12 | more difficult to mess up. | |
13 | ||
14 | Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> | |
15 | Signed-off-by: Thomas Gleixner <tglx@linutronix.de> | |
16 | Cc: Andy Lutomirski <luto@kernel.org> | |
17 | Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com> | |
18 | Cc: Borislav Petkov <bp@alien8.de> | |
19 | Cc: Brian Gerst <brgerst@gmail.com> | |
20 | Cc: Dave Hansen <dave.hansen@linux.intel.com> | |
21 | Cc: David Laight <David.Laight@aculab.com> | |
22 | Cc: Denys Vlasenko <dvlasenk@redhat.com> | |
23 | Cc: Eduardo Valentin <eduval@amazon.com> | |
24 | Cc: Greg KH <gregkh@linuxfoundation.org> | |
25 | Cc: H. Peter Anvin <hpa@zytor.com> | |
26 | Cc: Josh Poimboeuf <jpoimboe@redhat.com> | |
27 | Cc: Juergen Gross <jgross@suse.com> | |
28 | Cc: Linus Torvalds <torvalds@linux-foundation.org> | |
29 | Cc: Peter Zijlstra <peterz@infradead.org> | |
30 | Cc: Will Deacon <will.deacon@arm.com> | |
31 | Cc: aliguori@amazon.com | |
32 | Cc: daniel.gruss@iaik.tugraz.at | |
33 | Cc: hughd@google.com | |
34 | Cc: keescook@google.com | |
35 | Cc: linux-mm@kvack.org | |
36 | Signed-off-by: Ingo Molnar <mingo@kernel.org> | |
37 | (cherry picked from commit 0a126abd576ebc6403f063dbe20cf7416c9d9393) | |
38 | Signed-off-by: Andy Whitcroft <apw@canonical.com> | |
39 | Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> | |
40 | (cherry picked from commit 2ee6efc0f708e21cfd08471132ac2255fac54553) | |
41 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
42 | --- | |
43 | arch/x86/include/asm/tlbflush.h | 55 ++++++++++++++++++++++++++++++++--------- | |
44 | 1 file changed, 43 insertions(+), 12 deletions(-) | |
45 | ||
46 | diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h | |
47 | index 979e590648a5..7a04a1f1ca11 100644 | |
48 | --- a/arch/x86/include/asm/tlbflush.h | |
49 | +++ b/arch/x86/include/asm/tlbflush.h | |
50 | @@ -12,16 +12,33 @@ | |
51 | #include <asm/pti.h> | |
52 | #include <asm/processor-flags.h> | |
53 | ||
54 | -static inline u64 inc_mm_tlb_gen(struct mm_struct *mm) | |
55 | -{ | |
56 | - /* | |
57 | - * Bump the generation count. This also serves as a full barrier | |
58 | - * that synchronizes with switch_mm(): callers are required to order | |
59 | - * their read of mm_cpumask after their writes to the paging | |
60 | - * structures. | |
61 | - */ | |
62 | - return atomic64_inc_return(&mm->context.tlb_gen); | |
63 | -} | |
64 | +/* | |
65 | + * The x86 feature is called PCID (Process Context IDentifier). It is similar | |
66 | + * to what is traditionally called ASID on the RISC processors. | |
67 | + * | |
68 | + * We don't use the traditional ASID implementation, where each process/mm gets | |
69 | + * its own ASID and flush/restart when we run out of ASID space. | |
70 | + * | |
71 | + * Instead we have a small per-cpu array of ASIDs and cache the last few mm's | |
72 | + * that came by on this CPU, allowing cheaper switch_mm between processes on | |
73 | + * this CPU. | |
74 | + * | |
75 | + * We end up with different spaces for different things. To avoid confusion we | |
76 | + * use different names for each of them: | |
77 | + * | |
78 | + * ASID - [0, TLB_NR_DYN_ASIDS-1] | |
79 | + * the canonical identifier for an mm | |
80 | + * | |
81 | + * kPCID - [1, TLB_NR_DYN_ASIDS] | |
82 | + * the value we write into the PCID part of CR3; corresponds to the | |
83 | + * ASID+1, because PCID 0 is special. | |
84 | + * | |
85 | + * uPCID - [2048 + 1, 2048 + TLB_NR_DYN_ASIDS] | |
86 | + * for KPTI each mm has two address spaces and thus needs two | |
87 | + * PCID values, but we can still do with a single ASID denomination | |
88 | + * for each mm. Corresponds to kPCID + 2048. | |
89 | + * | |
90 | + */ | |
91 | ||
92 | /* There are 12 bits of space for ASIDS in CR3 */ | |
93 | #define CR3_HW_ASID_BITS 12 | |
94 | @@ -40,7 +57,7 @@ static inline u64 inc_mm_tlb_gen(struct mm_struct *mm) | |
95 | ||
96 | /* | |
97 | * ASIDs are zero-based: 0->MAX_AVAIL_ASID are valid. -1 below to account | |
98 | - * for them being zero-based. Another -1 is because ASID 0 is reserved for | |
99 | + * for them being zero-based. Another -1 is because PCID 0 is reserved for | |
100 | * use by non-PCID-aware users. | |
101 | */ | |
102 | #define MAX_ASID_AVAILABLE ((1 << CR3_AVAIL_PCID_BITS) - 2) | |
103 | @@ -51,6 +68,9 @@ static inline u64 inc_mm_tlb_gen(struct mm_struct *mm) | |
104 | */ | |
105 | #define TLB_NR_DYN_ASIDS 6 | |
106 | ||
107 | +/* | |
108 | + * Given @asid, compute kPCID | |
109 | + */ | |
110 | static inline u16 kern_pcid(u16 asid) | |
111 | { | |
112 | VM_WARN_ON_ONCE(asid > MAX_ASID_AVAILABLE); | |
113 | @@ -85,7 +105,7 @@ static inline u16 kern_pcid(u16 asid) | |
114 | } | |
115 | ||
116 | /* | |
117 | - * The user PCID is just the kernel one, plus the "switch bit". | |
118 | + * Given @asid, compute uPCID | |
119 | */ | |
120 | static inline u16 user_pcid(u16 asid) | |
121 | { | |
122 | @@ -473,6 +493,17 @@ static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long a) | |
123 | void native_flush_tlb_others(const struct cpumask *cpumask, | |
124 | const struct flush_tlb_info *info); | |
125 | ||
126 | +static inline u64 inc_mm_tlb_gen(struct mm_struct *mm) | |
127 | +{ | |
128 | + /* | |
129 | + * Bump the generation count. This also serves as a full barrier | |
130 | + * that synchronizes with switch_mm(): callers are required to order | |
131 | + * their read of mm_cpumask after their writes to the paging | |
132 | + * structures. | |
133 | + */ | |
134 | + return atomic64_inc_return(&mm->context.tlb_gen); | |
135 | +} | |
136 | + | |
137 | static inline void arch_tlbbatch_add_mm(struct arch_tlbflush_unmap_batch *batch, | |
138 | struct mm_struct *mm) | |
139 | { | |
140 | -- | |
141 | 2.14.2 | |
142 |