]>
Commit | Line | Data |
---|---|---|
59d5af67 | 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
321d628a FG |
2 | From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> |
3 | Date: Fri, 29 Sep 2017 17:08:20 +0300 | |
59d5af67 FG |
4 | Subject: [PATCH] x86/xen: Drop 5-level paging support code from the XEN_PV |
5 | code | |
321d628a FG |
6 | MIME-Version: 1.0 |
7 | Content-Type: text/plain; charset=UTF-8 | |
8 | Content-Transfer-Encoding: 8bit | |
9 | ||
10 | CVE-2017-5754 | |
11 | ||
12 | It was decided 5-level paging is not going to be supported in XEN_PV. | |
13 | ||
14 | Let's drop the dead code from the XEN_PV code. | |
15 | ||
16 | Tested-by: Juergen Gross <jgross@suse.com> | |
17 | Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> | |
18 | Reviewed-by: Juergen Gross <jgross@suse.com> | |
19 | Cc: Andrew Morton <akpm@linux-foundation.org> | |
20 | Cc: Andy Lutomirski <luto@amacapital.net> | |
21 | Cc: Borislav Petkov <bp@suse.de> | |
22 | Cc: Cyrill Gorcunov <gorcunov@openvz.org> | |
23 | Cc: Linus Torvalds <torvalds@linux-foundation.org> | |
24 | Cc: Peter Zijlstra <peterz@infradead.org> | |
25 | Cc: Thomas Gleixner <tglx@linutronix.de> | |
26 | Cc: linux-mm@kvack.org | |
27 | Link: http://lkml.kernel.org/r/20170929140821.37654-6-kirill.shutemov@linux.intel.com | |
28 | Signed-off-by: Ingo Molnar <mingo@kernel.org> | |
29 | (cherry picked from commit 773dd2fca581b0a80e5a33332cc8ee67e5a79cba) | |
30 | Signed-off-by: Andy Whitcroft <apw@canonical.com> | |
31 | Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> | |
32 | (cherry picked from commit 3fd0b7ef0094fd8bb3c8172d9b137ebe0d81ecbc) | |
33 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
34 | --- | |
35 | arch/x86/xen/mmu_pv.c | 159 +++++++++++++++++++------------------------------- | |
36 | 1 file changed, 60 insertions(+), 99 deletions(-) | |
37 | ||
38 | diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c | |
39 | index ba76f3ce997f..45bb2d462e44 100644 | |
40 | --- a/arch/x86/xen/mmu_pv.c | |
41 | +++ b/arch/x86/xen/mmu_pv.c | |
42 | @@ -469,7 +469,7 @@ __visible pmd_t xen_make_pmd(pmdval_t pmd) | |
43 | } | |
44 | PV_CALLEE_SAVE_REGS_THUNK(xen_make_pmd); | |
45 | ||
46 | -#if CONFIG_PGTABLE_LEVELS == 4 | |
47 | +#ifdef CONFIG_X86_64 | |
48 | __visible pudval_t xen_pud_val(pud_t pud) | |
49 | { | |
50 | return pte_mfn_to_pfn(pud.pud); | |
51 | @@ -558,7 +558,7 @@ static void xen_set_p4d(p4d_t *ptr, p4d_t val) | |
52 | ||
53 | xen_mc_issue(PARAVIRT_LAZY_MMU); | |
54 | } | |
55 | -#endif /* CONFIG_PGTABLE_LEVELS == 4 */ | |
56 | +#endif /* CONFIG_X86_64 */ | |
57 | ||
58 | static int xen_pmd_walk(struct mm_struct *mm, pmd_t *pmd, | |
59 | int (*func)(struct mm_struct *mm, struct page *, enum pt_level), | |
60 | @@ -600,21 +600,17 @@ static int xen_p4d_walk(struct mm_struct *mm, p4d_t *p4d, | |
61 | int (*func)(struct mm_struct *mm, struct page *, enum pt_level), | |
62 | bool last, unsigned long limit) | |
63 | { | |
64 | - int i, nr, flush = 0; | |
65 | + int flush = 0; | |
66 | + pud_t *pud; | |
67 | ||
68 | - nr = last ? p4d_index(limit) + 1 : PTRS_PER_P4D; | |
69 | - for (i = 0; i < nr; i++) { | |
70 | - pud_t *pud; | |
71 | ||
72 | - if (p4d_none(p4d[i])) | |
73 | - continue; | |
74 | + if (p4d_none(*p4d)) | |
75 | + return flush; | |
76 | ||
77 | - pud = pud_offset(&p4d[i], 0); | |
78 | - if (PTRS_PER_PUD > 1) | |
79 | - flush |= (*func)(mm, virt_to_page(pud), PT_PUD); | |
80 | - flush |= xen_pud_walk(mm, pud, func, | |
81 | - last && i == nr - 1, limit); | |
82 | - } | |
83 | + pud = pud_offset(p4d, 0); | |
84 | + if (PTRS_PER_PUD > 1) | |
85 | + flush |= (*func)(mm, virt_to_page(pud), PT_PUD); | |
86 | + flush |= xen_pud_walk(mm, pud, func, last, limit); | |
87 | return flush; | |
88 | } | |
89 | ||
90 | @@ -664,8 +660,6 @@ static int __xen_pgd_walk(struct mm_struct *mm, pgd_t *pgd, | |
91 | continue; | |
92 | ||
93 | p4d = p4d_offset(&pgd[i], 0); | |
94 | - if (PTRS_PER_P4D > 1) | |
95 | - flush |= (*func)(mm, virt_to_page(p4d), PT_P4D); | |
96 | flush |= xen_p4d_walk(mm, p4d, func, i == nr - 1, limit); | |
97 | } | |
98 | ||
99 | @@ -1196,22 +1190,14 @@ static void __init xen_cleanmfnmap(unsigned long vaddr) | |
100 | { | |
101 | pgd_t *pgd; | |
102 | p4d_t *p4d; | |
103 | - unsigned int i; | |
104 | bool unpin; | |
105 | ||
106 | unpin = (vaddr == 2 * PGDIR_SIZE); | |
107 | vaddr &= PMD_MASK; | |
108 | pgd = pgd_offset_k(vaddr); | |
109 | p4d = p4d_offset(pgd, 0); | |
110 | - for (i = 0; i < PTRS_PER_P4D; i++) { | |
111 | - if (p4d_none(p4d[i])) | |
112 | - continue; | |
113 | - xen_cleanmfnmap_p4d(p4d + i, unpin); | |
114 | - } | |
115 | - if (IS_ENABLED(CONFIG_X86_5LEVEL)) { | |
116 | - set_pgd(pgd, __pgd(0)); | |
117 | - xen_cleanmfnmap_free_pgtbl(p4d, unpin); | |
118 | - } | |
119 | + if (!p4d_none(*p4d)) | |
120 | + xen_cleanmfnmap_p4d(p4d, unpin); | |
121 | } | |
122 | ||
123 | static void __init xen_pagetable_p2m_free(void) | |
124 | @@ -1717,7 +1703,7 @@ static void xen_release_pmd(unsigned long pfn) | |
125 | xen_release_ptpage(pfn, PT_PMD); | |
126 | } | |
127 | ||
128 | -#if CONFIG_PGTABLE_LEVELS >= 4 | |
129 | +#ifdef CONFIG_X86_64 | |
130 | static void xen_alloc_pud(struct mm_struct *mm, unsigned long pfn) | |
131 | { | |
132 | xen_alloc_ptpage(mm, pfn, PT_PUD); | |
133 | @@ -2054,13 +2040,12 @@ static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr) | |
134 | */ | |
135 | void __init xen_relocate_p2m(void) | |
136 | { | |
137 | - phys_addr_t size, new_area, pt_phys, pmd_phys, pud_phys, p4d_phys; | |
138 | + phys_addr_t size, new_area, pt_phys, pmd_phys, pud_phys; | |
139 | unsigned long p2m_pfn, p2m_pfn_end, n_frames, pfn, pfn_end; | |
140 | - int n_pte, n_pt, n_pmd, n_pud, n_p4d, idx_pte, idx_pt, idx_pmd, idx_pud, idx_p4d; | |
141 | + int n_pte, n_pt, n_pmd, n_pud, idx_pte, idx_pt, idx_pmd, idx_pud; | |
142 | pte_t *pt; | |
143 | pmd_t *pmd; | |
144 | pud_t *pud; | |
145 | - p4d_t *p4d = NULL; | |
146 | pgd_t *pgd; | |
147 | unsigned long *new_p2m; | |
148 | int save_pud; | |
149 | @@ -2070,11 +2055,7 @@ void __init xen_relocate_p2m(void) | |
150 | n_pt = roundup(size, PMD_SIZE) >> PMD_SHIFT; | |
151 | n_pmd = roundup(size, PUD_SIZE) >> PUD_SHIFT; | |
152 | n_pud = roundup(size, P4D_SIZE) >> P4D_SHIFT; | |
153 | - if (PTRS_PER_P4D > 1) | |
154 | - n_p4d = roundup(size, PGDIR_SIZE) >> PGDIR_SHIFT; | |
155 | - else | |
156 | - n_p4d = 0; | |
157 | - n_frames = n_pte + n_pt + n_pmd + n_pud + n_p4d; | |
158 | + n_frames = n_pte + n_pt + n_pmd + n_pud; | |
159 | ||
160 | new_area = xen_find_free_area(PFN_PHYS(n_frames)); | |
161 | if (!new_area) { | |
162 | @@ -2090,76 +2071,56 @@ void __init xen_relocate_p2m(void) | |
163 | * To avoid any possible virtual address collision, just use | |
164 | * 2 * PUD_SIZE for the new area. | |
165 | */ | |
166 | - p4d_phys = new_area; | |
167 | - pud_phys = p4d_phys + PFN_PHYS(n_p4d); | |
168 | + pud_phys = new_area; | |
169 | pmd_phys = pud_phys + PFN_PHYS(n_pud); | |
170 | pt_phys = pmd_phys + PFN_PHYS(n_pmd); | |
171 | p2m_pfn = PFN_DOWN(pt_phys) + n_pt; | |
172 | ||
173 | pgd = __va(read_cr3_pa()); | |
174 | new_p2m = (unsigned long *)(2 * PGDIR_SIZE); | |
175 | - idx_p4d = 0; | |
176 | save_pud = n_pud; | |
177 | - do { | |
178 | - if (n_p4d > 0) { | |
179 | - p4d = early_memremap(p4d_phys, PAGE_SIZE); | |
180 | - clear_page(p4d); | |
181 | - n_pud = min(save_pud, PTRS_PER_P4D); | |
182 | - } | |
183 | - for (idx_pud = 0; idx_pud < n_pud; idx_pud++) { | |
184 | - pud = early_memremap(pud_phys, PAGE_SIZE); | |
185 | - clear_page(pud); | |
186 | - for (idx_pmd = 0; idx_pmd < min(n_pmd, PTRS_PER_PUD); | |
187 | - idx_pmd++) { | |
188 | - pmd = early_memremap(pmd_phys, PAGE_SIZE); | |
189 | - clear_page(pmd); | |
190 | - for (idx_pt = 0; idx_pt < min(n_pt, PTRS_PER_PMD); | |
191 | - idx_pt++) { | |
192 | - pt = early_memremap(pt_phys, PAGE_SIZE); | |
193 | - clear_page(pt); | |
194 | - for (idx_pte = 0; | |
195 | - idx_pte < min(n_pte, PTRS_PER_PTE); | |
196 | - idx_pte++) { | |
197 | - set_pte(pt + idx_pte, | |
198 | - pfn_pte(p2m_pfn, PAGE_KERNEL)); | |
199 | - p2m_pfn++; | |
200 | - } | |
201 | - n_pte -= PTRS_PER_PTE; | |
202 | - early_memunmap(pt, PAGE_SIZE); | |
203 | - make_lowmem_page_readonly(__va(pt_phys)); | |
204 | - pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, | |
205 | - PFN_DOWN(pt_phys)); | |
206 | - set_pmd(pmd + idx_pt, | |
207 | - __pmd(_PAGE_TABLE | pt_phys)); | |
208 | - pt_phys += PAGE_SIZE; | |
209 | + for (idx_pud = 0; idx_pud < n_pud; idx_pud++) { | |
210 | + pud = early_memremap(pud_phys, PAGE_SIZE); | |
211 | + clear_page(pud); | |
212 | + for (idx_pmd = 0; idx_pmd < min(n_pmd, PTRS_PER_PUD); | |
213 | + idx_pmd++) { | |
214 | + pmd = early_memremap(pmd_phys, PAGE_SIZE); | |
215 | + clear_page(pmd); | |
216 | + for (idx_pt = 0; idx_pt < min(n_pt, PTRS_PER_PMD); | |
217 | + idx_pt++) { | |
218 | + pt = early_memremap(pt_phys, PAGE_SIZE); | |
219 | + clear_page(pt); | |
220 | + for (idx_pte = 0; | |
221 | + idx_pte < min(n_pte, PTRS_PER_PTE); | |
222 | + idx_pte++) { | |
223 | + set_pte(pt + idx_pte, | |
224 | + pfn_pte(p2m_pfn, PAGE_KERNEL)); | |
225 | + p2m_pfn++; | |
226 | } | |
227 | - n_pt -= PTRS_PER_PMD; | |
228 | - early_memunmap(pmd, PAGE_SIZE); | |
229 | - make_lowmem_page_readonly(__va(pmd_phys)); | |
230 | - pin_pagetable_pfn(MMUEXT_PIN_L2_TABLE, | |
231 | - PFN_DOWN(pmd_phys)); | |
232 | - set_pud(pud + idx_pmd, __pud(_PAGE_TABLE | pmd_phys)); | |
233 | - pmd_phys += PAGE_SIZE; | |
234 | + n_pte -= PTRS_PER_PTE; | |
235 | + early_memunmap(pt, PAGE_SIZE); | |
236 | + make_lowmem_page_readonly(__va(pt_phys)); | |
237 | + pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, | |
238 | + PFN_DOWN(pt_phys)); | |
239 | + set_pmd(pmd + idx_pt, | |
240 | + __pmd(_PAGE_TABLE | pt_phys)); | |
241 | + pt_phys += PAGE_SIZE; | |
242 | } | |
243 | - n_pmd -= PTRS_PER_PUD; | |
244 | - early_memunmap(pud, PAGE_SIZE); | |
245 | - make_lowmem_page_readonly(__va(pud_phys)); | |
246 | - pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(pud_phys)); | |
247 | - if (n_p4d > 0) | |
248 | - set_p4d(p4d + idx_pud, __p4d(_PAGE_TABLE | pud_phys)); | |
249 | - else | |
250 | - set_pgd(pgd + 2 + idx_pud, __pgd(_PAGE_TABLE | pud_phys)); | |
251 | - pud_phys += PAGE_SIZE; | |
252 | - } | |
253 | - if (n_p4d > 0) { | |
254 | - save_pud -= PTRS_PER_P4D; | |
255 | - early_memunmap(p4d, PAGE_SIZE); | |
256 | - make_lowmem_page_readonly(__va(p4d_phys)); | |
257 | - pin_pagetable_pfn(MMUEXT_PIN_L4_TABLE, PFN_DOWN(p4d_phys)); | |
258 | - set_pgd(pgd + 2 + idx_p4d, __pgd(_PAGE_TABLE | p4d_phys)); | |
259 | - p4d_phys += PAGE_SIZE; | |
260 | + n_pt -= PTRS_PER_PMD; | |
261 | + early_memunmap(pmd, PAGE_SIZE); | |
262 | + make_lowmem_page_readonly(__va(pmd_phys)); | |
263 | + pin_pagetable_pfn(MMUEXT_PIN_L2_TABLE, | |
264 | + PFN_DOWN(pmd_phys)); | |
265 | + set_pud(pud + idx_pmd, __pud(_PAGE_TABLE | pmd_phys)); | |
266 | + pmd_phys += PAGE_SIZE; | |
267 | } | |
268 | - } while (++idx_p4d < n_p4d); | |
269 | + n_pmd -= PTRS_PER_PUD; | |
270 | + early_memunmap(pud, PAGE_SIZE); | |
271 | + make_lowmem_page_readonly(__va(pud_phys)); | |
272 | + pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(pud_phys)); | |
273 | + set_pgd(pgd + 2 + idx_pud, __pgd(_PAGE_TABLE | pud_phys)); | |
274 | + pud_phys += PAGE_SIZE; | |
275 | + } | |
276 | ||
277 | /* Now copy the old p2m info to the new area. */ | |
278 | memcpy(new_p2m, xen_p2m_addr, size); | |
279 | @@ -2386,7 +2347,7 @@ static void __init xen_post_allocator_init(void) | |
280 | pv_mmu_ops.set_pte = xen_set_pte; | |
281 | pv_mmu_ops.set_pmd = xen_set_pmd; | |
282 | pv_mmu_ops.set_pud = xen_set_pud; | |
283 | -#if CONFIG_PGTABLE_LEVELS >= 4 | |
284 | +#ifdef CONFIG_X86_64 | |
285 | pv_mmu_ops.set_p4d = xen_set_p4d; | |
286 | #endif | |
287 | ||
288 | @@ -2396,7 +2357,7 @@ static void __init xen_post_allocator_init(void) | |
289 | pv_mmu_ops.alloc_pmd = xen_alloc_pmd; | |
290 | pv_mmu_ops.release_pte = xen_release_pte; | |
291 | pv_mmu_ops.release_pmd = xen_release_pmd; | |
292 | -#if CONFIG_PGTABLE_LEVELS >= 4 | |
293 | +#ifdef CONFIG_X86_64 | |
294 | pv_mmu_ops.alloc_pud = xen_alloc_pud; | |
295 | pv_mmu_ops.release_pud = xen_release_pud; | |
296 | #endif | |
297 | @@ -2460,14 +2421,14 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = { | |
298 | .make_pmd = PV_CALLEE_SAVE(xen_make_pmd), | |
299 | .pmd_val = PV_CALLEE_SAVE(xen_pmd_val), | |
300 | ||
301 | -#if CONFIG_PGTABLE_LEVELS >= 4 | |
302 | +#ifdef CONFIG_X86_64 | |
303 | .pud_val = PV_CALLEE_SAVE(xen_pud_val), | |
304 | .make_pud = PV_CALLEE_SAVE(xen_make_pud), | |
305 | .set_p4d = xen_set_p4d_hyper, | |
306 | ||
307 | .alloc_pud = xen_alloc_pmd_init, | |
308 | .release_pud = xen_release_pmd_init, | |
309 | -#endif /* CONFIG_PGTABLE_LEVELS == 4 */ | |
310 | +#endif /* CONFIG_X86_64 */ | |
311 | ||
312 | .activate_mm = xen_activate_mm, | |
313 | .dup_mmap = xen_dup_mmap, | |
314 | -- | |
315 | 2.14.2 | |
316 |