aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/ldt.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/ldt.c')
-rw-r--r--arch/x86/kernel/ldt.c59
1 files changed, 38 insertions, 21 deletions
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
index ab18e0884dc6..6135ae8ce036 100644
--- a/arch/x86/kernel/ldt.c
+++ b/arch/x86/kernel/ldt.c
@@ -199,14 +199,6 @@ static void sanity_check_ldt_mapping(struct mm_struct *mm)
199/* 199/*
200 * If PTI is enabled, this maps the LDT into the kernelmode and 200 * If PTI is enabled, this maps the LDT into the kernelmode and
201 * usermode tables for the given mm. 201 * usermode tables for the given mm.
202 *
203 * There is no corresponding unmap function. Even if the LDT is freed, we
204 * leave the PTEs around until the slot is reused or the mm is destroyed.
205 * This is harmless: the LDT is always in ordinary memory, and no one will
206 * access the freed slot.
207 *
208 * If we wanted to unmap freed LDTs, we'd also need to do a flush to make
209 * it useful, and the flush would slow down modify_ldt().
210 */ 202 */
211static int 203static int
212map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot) 204map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
@@ -214,8 +206,7 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
214 unsigned long va; 206 unsigned long va;
215 bool is_vmalloc; 207 bool is_vmalloc;
216 spinlock_t *ptl; 208 spinlock_t *ptl;
217 pgd_t *pgd; 209 int i, nr_pages;
218 int i;
219 210
220 if (!static_cpu_has(X86_FEATURE_PTI)) 211 if (!static_cpu_has(X86_FEATURE_PTI))
221 return 0; 212 return 0;
@@ -229,16 +220,11 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
229 /* Check if the current mappings are sane */ 220 /* Check if the current mappings are sane */
230 sanity_check_ldt_mapping(mm); 221 sanity_check_ldt_mapping(mm);
231 222
232 /*
233 * Did we already have the top level entry allocated? We can't
234 * use pgd_none() for this because it doens't do anything on
235 * 4-level page table kernels.
236 */
237 pgd = pgd_offset(mm, LDT_BASE_ADDR);
238
239 is_vmalloc = is_vmalloc_addr(ldt->entries); 223 is_vmalloc = is_vmalloc_addr(ldt->entries);
240 224
241 for (i = 0; i * PAGE_SIZE < ldt->nr_entries * LDT_ENTRY_SIZE; i++) { 225 nr_pages = DIV_ROUND_UP(ldt->nr_entries * LDT_ENTRY_SIZE, PAGE_SIZE);
226
227 for (i = 0; i < nr_pages; i++) {
242 unsigned long offset = i << PAGE_SHIFT; 228 unsigned long offset = i << PAGE_SHIFT;
243 const void *src = (char *)ldt->entries + offset; 229 const void *src = (char *)ldt->entries + offset;
244 unsigned long pfn; 230 unsigned long pfn;
@@ -272,13 +258,39 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
272 /* Propagate LDT mapping to the user page-table */ 258 /* Propagate LDT mapping to the user page-table */
273 map_ldt_struct_to_user(mm); 259 map_ldt_struct_to_user(mm);
274 260
275 va = (unsigned long)ldt_slot_va(slot);
276 flush_tlb_mm_range(mm, va, va + LDT_SLOT_STRIDE, PAGE_SHIFT, false);
277
278 ldt->slot = slot; 261 ldt->slot = slot;
279 return 0; 262 return 0;
280} 263}
281 264
265static void unmap_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt)
266{
267 unsigned long va;
268 int i, nr_pages;
269
270 if (!ldt)
271 return;
272
273 /* LDT map/unmap is only required for PTI */
274 if (!static_cpu_has(X86_FEATURE_PTI))
275 return;
276
277 nr_pages = DIV_ROUND_UP(ldt->nr_entries * LDT_ENTRY_SIZE, PAGE_SIZE);
278
279 for (i = 0; i < nr_pages; i++) {
280 unsigned long offset = i << PAGE_SHIFT;
281 spinlock_t *ptl;
282 pte_t *ptep;
283
284 va = (unsigned long)ldt_slot_va(ldt->slot) + offset;
285 ptep = get_locked_pte(mm, va, &ptl);
286 pte_clear(mm, va, ptep);
287 pte_unmap_unlock(ptep, ptl);
288 }
289
290 va = (unsigned long)ldt_slot_va(ldt->slot);
291 flush_tlb_mm_range(mm, va, va + nr_pages * PAGE_SIZE, PAGE_SHIFT, false);
292}
293
282#else /* !CONFIG_PAGE_TABLE_ISOLATION */ 294#else /* !CONFIG_PAGE_TABLE_ISOLATION */
283 295
284static int 296static int
@@ -286,6 +298,10 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
286{ 298{
287 return 0; 299 return 0;
288} 300}
301
302static void unmap_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt)
303{
304}
289#endif /* CONFIG_PAGE_TABLE_ISOLATION */ 305#endif /* CONFIG_PAGE_TABLE_ISOLATION */
290 306
291static void free_ldt_pgtables(struct mm_struct *mm) 307static void free_ldt_pgtables(struct mm_struct *mm)
@@ -524,6 +540,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
524 } 540 }
525 541
526 install_ldt(mm, new_ldt); 542 install_ldt(mm, new_ldt);
543 unmap_ldt_struct(mm, old_ldt);
527 free_ldt_struct(old_ldt); 544 free_ldt_struct(old_ldt);
528 error = 0; 545 error = 0;
529 546