Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd9e9a64

Browse files
hansendcIngo Molnar
authored and
Ingo Molnar
committed
x86/mm/pti: Allocate a separate user PGD
Kernel page table isolation requires to have two PGDs. One for the kernel,which contains the full kernel mapping plus the user space mapping and onefor user space which contains the user space mappings and the minimal setof kernel mappings which are required by the architecture to be able totransition from and to user space.Add the necessary preliminaries.[ tglx: Split out from the big kaiser dump. EFI fixup from Kirill ]Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>Signed-off-by: Thomas Gleixner <tglx@linutronix.de>Reviewed-by: Borislav Petkov <bp@suse.de>Cc: Andy Lutomirski <luto@kernel.org>Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>Cc: Borislav Petkov <bp@alien8.de>Cc: Brian Gerst <brgerst@gmail.com>Cc: David Laight <David.Laight@aculab.com>Cc: Denys Vlasenko <dvlasenk@redhat.com>Cc: Eduardo Valentin <eduval@amazon.com>Cc: Greg KH <gregkh@linuxfoundation.org>Cc: H. Peter Anvin <hpa@zytor.com>Cc: Josh Poimboeuf <jpoimboe@redhat.com>Cc: Juergen Gross <jgross@suse.com>Cc: Linus Torvalds <torvalds@linux-foundation.org>Cc: Peter Zijlstra <peterz@infradead.org>Cc: Will Deacon <will.deacon@arm.com>Cc: aliguori@amazon.comCc: daniel.gruss@iaik.tugraz.atCc: hughd@google.comCc: keescook@google.comSigned-off-by: Ingo Molnar <mingo@kernel.org>
1 parent1c4de1f commitd9e9a64

File tree

4 files changed

+45
-6
lines changed

4 files changed

+45
-6
lines changed

‎arch/x86/include/asm/pgalloc.h‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ static inline void paravirt_release_p4d(unsigned long pfn) {}
3030
*/
3131
externgfp_t__userpte_alloc_gfp;
3232

33+
#ifdefCONFIG_PAGE_TABLE_ISOLATION
34+
/*
35+
* Instead of one PGD, we acquire two PGDs. Being order-1, it is
36+
* both 8k in size and 8k-aligned. That lets us just flip bit 12
37+
* in a pointer to swap between the two 4k halves.
38+
*/
39+
#definePGD_ALLOCATION_ORDER 1
40+
#else
41+
#definePGD_ALLOCATION_ORDER 0
42+
#endif
43+
3344
/*
3445
* Allocate and free page tables.
3546
*/

‎arch/x86/kernel/head_64.S‎

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,27 @@ GLOBAL(early_recursion_flag)
341341
.balignPAGE_SIZE; \
342342
GLOBAL(name)
343343

344+
#ifdef CONFIG_PAGE_TABLE_ISOLATION
345+
/*
346+
* Each PGD needs to be 8k long and 8k aligned. We do not
347+
* ever go out to userspace with these, so we do not
348+
* strictly *need* the second page, but this allows us to
349+
* have a single set_pgd() implementation that does not
350+
* need to worry about whether it has 4k or 8k to work
351+
* with.
352+
*
353+
* This ensures PGDs are 8k long:
354+
*/
355+
#define PTI_USER_PGD_FILL512
356+
/* This ensures they are 8k-aligned: */
357+
#define NEXT_PGD_PAGE(name) \
358+
.balign2 * PAGE_SIZE; \
359+
GLOBAL(name)
360+
#else
361+
#define NEXT_PGD_PAGE(name) NEXT_PAGE(name)
362+
#define PTI_USER_PGD_FILL0
363+
#endif
364+
344365
/* Automate the creation of 1 to 1 mapping pmd entries */
345366
#define PMDS(START, PERM, COUNT)\
346367
i =0 ;\
@@ -350,27 +371,29 @@ GLOBAL(name)
350371
.endr
351372

352373
__INITDATA
353-
NEXT_PAGE(early_top_pgt)
374+
NEXT_PGD_PAGE(early_top_pgt)
354375
.fill511,8,0
355376
#ifdef CONFIG_X86_5LEVEL
356377
.quadlevel4_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC
357378
#else
358379
.quadlevel3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC
359380
#endif
381+
.fillPTI_USER_PGD_FILL,8,0
360382

361383
NEXT_PAGE(early_dynamic_pgts)
362384
.fill512*EARLY_DYNAMIC_PAGE_TABLES,8,0
363385

364386
.data
365387

366388
#if defined(CONFIG_XEN_PV) || defined(CONFIG_XEN_PVH)
367-
NEXT_PAGE(init_top_pgt)
389+
NEXT_PGD_PAGE(init_top_pgt)
368390
.quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC
369391
.org init_top_pgt + PGD_PAGE_OFFSET*8,0
370392
.quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC
371393
.org init_top_pgt + PGD_START_KERNEL*8,0
372394
/* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
373395
.quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC
396+
.fillPTI_USER_PGD_FILL,8,0
374397

375398
NEXT_PAGE(level3_ident_pgt)
376399
.quadlevel2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC
@@ -381,8 +404,9 @@ NEXT_PAGE(level2_ident_pgt)
381404
*/
382405
PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD)
383406
#else
384-
NEXT_PAGE(init_top_pgt)
407+
NEXT_PGD_PAGE(init_top_pgt)
385408
.fill512,8,0
409+
.fillPTI_USER_PGD_FILL,8,0
386410
#endif
387411

388412
#ifdef CONFIG_X86_5LEVEL

‎arch/x86/mm/pgtable.c‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,14 +355,15 @@ static inline void _pgd_free(pgd_t *pgd)
355355
kmem_cache_free(pgd_cache,pgd);
356356
}
357357
#else
358+
358359
staticinlinepgd_t*_pgd_alloc(void)
359360
{
360-
return (pgd_t*)__get_free_page(PGALLOC_GFP);
361+
return (pgd_t*)__get_free_pages(PGALLOC_GFP,PGD_ALLOCATION_ORDER);
361362
}
362363

363364
staticinlinevoid_pgd_free(pgd_t*pgd)
364365
{
365-
free_page((unsigned long)pgd);
366+
free_pages((unsigned long)pgd,PGD_ALLOCATION_ORDER);
366367
}
367368
#endif/* CONFIG_X86_PAE */
368369

‎arch/x86/platform/efi/efi_64.c‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ static pgd_t *efi_pgd;
195195
* because we want to avoid inserting EFI region mappings (EFI_VA_END
196196
* to EFI_VA_START) into the standard kernel page tables. Everything
197197
* else can be shared, see efi_sync_low_kernel_mappings().
198+
*
199+
* We don't want the pgd on the pgd_list and cannot use pgd_alloc() for the
200+
* allocation.
198201
*/
199202
int__initefi_alloc_page_tables(void)
200203
{
@@ -207,7 +210,7 @@ int __init efi_alloc_page_tables(void)
207210
return0;
208211

209212
gfp_mask=GFP_KERNEL |__GFP_NOTRACK |__GFP_ZERO;
210-
efi_pgd= (pgd_t*)__get_free_page(gfp_mask);
213+
efi_pgd= (pgd_t*)__get_free_pages(gfp_mask,PGD_ALLOCATION_ORDER);
211214
if (!efi_pgd)
212215
return-ENOMEM;
213216

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp