]>
Commit | Line | Data |
---|---|---|
321d628a FG |
1 | From a67ab82a8f60f725b002034dff10f28c7e2ac88e Mon Sep 17 00:00:00 2001 |
2 | From: Peter Zijlstra <peterz@infradead.org> | |
3 | Date: Tue, 5 Dec 2017 13:34:47 +0100 | |
633c5ed1 | 4 | Subject: [PATCH 182/242] x86/mm: Create asm/invpcid.h |
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 | Unclutter tlbflush.h a little. | |
12 | ||
13 | Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> | |
14 | Cc: Andy Lutomirski <luto@kernel.org> | |
15 | Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com> | |
16 | Cc: Borislav Petkov <bp@alien8.de> | |
17 | Cc: Brian Gerst <brgerst@gmail.com> | |
18 | Cc: Dave Hansen <dave.hansen@linux.intel.com> | |
19 | Cc: David Laight <David.Laight@aculab.com> | |
20 | Cc: Denys Vlasenko <dvlasenk@redhat.com> | |
21 | Cc: Eduardo Valentin <eduval@amazon.com> | |
22 | Cc: Greg KH <gregkh@linuxfoundation.org> | |
23 | Cc: H. Peter Anvin <hpa@zytor.com> | |
24 | Cc: Josh Poimboeuf <jpoimboe@redhat.com> | |
25 | Cc: Juergen Gross <jgross@suse.com> | |
26 | Cc: Linus Torvalds <torvalds@linux-foundation.org> | |
27 | Cc: Peter Zijlstra <peterz@infradead.org> | |
28 | Cc: Thomas Gleixner <tglx@linutronix.de> | |
29 | Cc: Will Deacon <will.deacon@arm.com> | |
30 | Cc: aliguori@amazon.com | |
31 | Cc: daniel.gruss@iaik.tugraz.at | |
32 | Cc: hughd@google.com | |
33 | Cc: keescook@google.com | |
34 | Cc: linux-mm@kvack.org | |
35 | Signed-off-by: Ingo Molnar <mingo@kernel.org> | |
36 | (cherry picked from commit 1a3b0caeb77edeac5ce5fa05e6a61c474c9a9745) | |
37 | Signed-off-by: Andy Whitcroft <apw@canonical.com> | |
38 | Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> | |
39 | (cherry picked from commit 5af02a8c43ce521f460891f6ba68af69428abe90) | |
40 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
41 | --- | |
42 | arch/x86/include/asm/invpcid.h | 53 +++++++++++++++++++++++++++++++++++++++++ | |
43 | arch/x86/include/asm/tlbflush.h | 49 +------------------------------------ | |
44 | 2 files changed, 54 insertions(+), 48 deletions(-) | |
45 | create mode 100644 arch/x86/include/asm/invpcid.h | |
46 | ||
47 | diff --git a/arch/x86/include/asm/invpcid.h b/arch/x86/include/asm/invpcid.h | |
48 | new file mode 100644 | |
49 | index 000000000000..989cfa86de85 | |
50 | --- /dev/null | |
51 | +++ b/arch/x86/include/asm/invpcid.h | |
52 | @@ -0,0 +1,53 @@ | |
53 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
54 | +#ifndef _ASM_X86_INVPCID | |
55 | +#define _ASM_X86_INVPCID | |
56 | + | |
57 | +static inline void __invpcid(unsigned long pcid, unsigned long addr, | |
58 | + unsigned long type) | |
59 | +{ | |
60 | + struct { u64 d[2]; } desc = { { pcid, addr } }; | |
61 | + | |
62 | + /* | |
63 | + * The memory clobber is because the whole point is to invalidate | |
64 | + * stale TLB entries and, especially if we're flushing global | |
65 | + * mappings, we don't want the compiler to reorder any subsequent | |
66 | + * memory accesses before the TLB flush. | |
67 | + * | |
68 | + * The hex opcode is invpcid (%ecx), %eax in 32-bit mode and | |
69 | + * invpcid (%rcx), %rax in long mode. | |
70 | + */ | |
71 | + asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01" | |
72 | + : : "m" (desc), "a" (type), "c" (&desc) : "memory"); | |
73 | +} | |
74 | + | |
75 | +#define INVPCID_TYPE_INDIV_ADDR 0 | |
76 | +#define INVPCID_TYPE_SINGLE_CTXT 1 | |
77 | +#define INVPCID_TYPE_ALL_INCL_GLOBAL 2 | |
78 | +#define INVPCID_TYPE_ALL_NON_GLOBAL 3 | |
79 | + | |
80 | +/* Flush all mappings for a given pcid and addr, not including globals. */ | |
81 | +static inline void invpcid_flush_one(unsigned long pcid, | |
82 | + unsigned long addr) | |
83 | +{ | |
84 | + __invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR); | |
85 | +} | |
86 | + | |
87 | +/* Flush all mappings for a given PCID, not including globals. */ | |
88 | +static inline void invpcid_flush_single_context(unsigned long pcid) | |
89 | +{ | |
90 | + __invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT); | |
91 | +} | |
92 | + | |
93 | +/* Flush all mappings, including globals, for all PCIDs. */ | |
94 | +static inline void invpcid_flush_all(void) | |
95 | +{ | |
96 | + __invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL); | |
97 | +} | |
98 | + | |
99 | +/* Flush all mappings for all PCIDs except globals. */ | |
100 | +static inline void invpcid_flush_all_nonglobals(void) | |
101 | +{ | |
102 | + __invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL); | |
103 | +} | |
104 | + | |
105 | +#endif /* _ASM_X86_INVPCID */ | |
106 | diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h | |
107 | index ecd634f87e4e..503f87c30c15 100644 | |
108 | --- a/arch/x86/include/asm/tlbflush.h | |
109 | +++ b/arch/x86/include/asm/tlbflush.h | |
110 | @@ -8,54 +8,7 @@ | |
111 | #include <asm/cpufeature.h> | |
112 | #include <asm/special_insns.h> | |
113 | #include <asm/smp.h> | |
114 | - | |
115 | -static inline void __invpcid(unsigned long pcid, unsigned long addr, | |
116 | - unsigned long type) | |
117 | -{ | |
118 | - struct { u64 d[2]; } desc = { { pcid, addr } }; | |
119 | - | |
120 | - /* | |
121 | - * The memory clobber is because the whole point is to invalidate | |
122 | - * stale TLB entries and, especially if we're flushing global | |
123 | - * mappings, we don't want the compiler to reorder any subsequent | |
124 | - * memory accesses before the TLB flush. | |
125 | - * | |
126 | - * The hex opcode is invpcid (%ecx), %eax in 32-bit mode and | |
127 | - * invpcid (%rcx), %rax in long mode. | |
128 | - */ | |
129 | - asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01" | |
130 | - : : "m" (desc), "a" (type), "c" (&desc) : "memory"); | |
131 | -} | |
132 | - | |
133 | -#define INVPCID_TYPE_INDIV_ADDR 0 | |
134 | -#define INVPCID_TYPE_SINGLE_CTXT 1 | |
135 | -#define INVPCID_TYPE_ALL_INCL_GLOBAL 2 | |
136 | -#define INVPCID_TYPE_ALL_NON_GLOBAL 3 | |
137 | - | |
138 | -/* Flush all mappings for a given pcid and addr, not including globals. */ | |
139 | -static inline void invpcid_flush_one(unsigned long pcid, | |
140 | - unsigned long addr) | |
141 | -{ | |
142 | - __invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR); | |
143 | -} | |
144 | - | |
145 | -/* Flush all mappings for a given PCID, not including globals. */ | |
146 | -static inline void invpcid_flush_single_context(unsigned long pcid) | |
147 | -{ | |
148 | - __invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT); | |
149 | -} | |
150 | - | |
151 | -/* Flush all mappings, including globals, for all PCIDs. */ | |
152 | -static inline void invpcid_flush_all(void) | |
153 | -{ | |
154 | - __invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL); | |
155 | -} | |
156 | - | |
157 | -/* Flush all mappings for all PCIDs except globals. */ | |
158 | -static inline void invpcid_flush_all_nonglobals(void) | |
159 | -{ | |
160 | - __invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL); | |
161 | -} | |
162 | +#include <asm/invpcid.h> | |
163 | ||
164 | static inline u64 inc_mm_tlb_gen(struct mm_struct *mm) | |
165 | { | |
166 | -- | |
167 | 2.14.2 | |
168 |