Skip to content

Commit aa8c624

Browse files
KAGA-KOKOIngo Molnar
authored andcommitted
x86/mm/pti: Add infrastructure for page table isolation
Add the initial files for kernel page table isolation, with a minimal init function and the boot time detection for this misfeature. Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Borislav Petkov <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Boris Ostrovsky <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: Dave Hansen <[email protected]> Cc: David Laight <[email protected]> Cc: Denys Vlasenko <[email protected]> Cc: Eduardo Valentin <[email protected]> Cc: Greg KH <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Josh Poimboeuf <[email protected]> Cc: Juergen Gross <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Will Deacon <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 8a09317 commit aa8c624

File tree

9 files changed

+130
-3
lines changed

9 files changed

+130
-3
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2685,6 +2685,8 @@
26852685
steal time is computed, but won't influence scheduler
26862686
behaviour
26872687

2688+
nopti [X86-64] Disable kernel page table isolation
2689+
26882690
nolapic [X86-32,APIC] Do not enable or use the local APIC.
26892691

26902692
nolapic_timer [X86-32,APIC] Do not use the local APIC timer.

arch/x86/boot/compressed/pagetable.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
*/
2424
#undef CONFIG_AMD_MEM_ENCRYPT
2525

26+
/* No PAGE_TABLE_ISOLATION support needed either: */
27+
#undef CONFIG_PAGE_TABLE_ISOLATION
28+
2629
#include "misc.h"
2730

2831
/* These actually do the work of building the kernel identity maps. */

arch/x86/entry/calling.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,18 +205,23 @@ For 32-bit we have the following conventions - kernel is built with
205205
.endm
206206

207207
.macro SWITCH_TO_KERNEL_CR3 scratch_reg:req
208+
ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
208209
mov %cr3, \scratch_reg
209210
ADJUST_KERNEL_CR3 \scratch_reg
210211
mov \scratch_reg, %cr3
212+
.Lend_\@:
211213
.endm
212214

213215
.macro SWITCH_TO_USER_CR3 scratch_reg:req
216+
ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
214217
mov %cr3, \scratch_reg
215218
ADJUST_USER_CR3 \scratch_reg
216219
mov \scratch_reg, %cr3
220+
.Lend_\@:
217221
.endm
218222

219223
.macro SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg:req save_reg:req
224+
ALTERNATIVE "jmp .Ldone_\@", "", X86_FEATURE_PTI
220225
movq %cr3, \scratch_reg
221226
movq \scratch_reg, \save_reg
222227
/*
@@ -233,11 +238,13 @@ For 32-bit we have the following conventions - kernel is built with
233238
.endm
234239

235240
.macro RESTORE_CR3 save_reg:req
241+
ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
236242
/*
237243
* The CR3 write could be avoided when not changing its value,
238244
* but would require a CR3 read *and* a scratch register.
239245
*/
240246
movq \save_reg, %cr3
247+
.Lend_\@:
241248
.endm
242249

243250
#else /* CONFIG_PAGE_TABLE_ISOLATION=n: */

arch/x86/include/asm/pti.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#ifndef _ASM_X86_PTI_H
3+
#define _ASM_X86_PTI_H
4+
#ifndef __ASSEMBLY__
5+
6+
#ifdef CONFIG_PAGE_TABLE_ISOLATION
7+
extern void pti_init(void);
8+
extern void pti_check_boottime_disable(void);
9+
#else
10+
static inline void pti_check_boottime_disable(void) { }
11+
#endif
12+
13+
#endif /* __ASSEMBLY__ */
14+
#endif /* _ASM_X86_PTI_H */

arch/x86/mm/Makefile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ obj-$(CONFIG_AMD_NUMA) += amdtopology.o
4343
obj-$(CONFIG_ACPI_NUMA) += srat.o
4444
obj-$(CONFIG_NUMA_EMU) += numa_emulation.o
4545

46-
obj-$(CONFIG_X86_INTEL_MPX) += mpx.o
47-
obj-$(CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS) += pkeys.o
48-
obj-$(CONFIG_RANDOMIZE_MEMORY) += kaslr.o
46+
obj-$(CONFIG_X86_INTEL_MPX) += mpx.o
47+
obj-$(CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS) += pkeys.o
48+
obj-$(CONFIG_RANDOMIZE_MEMORY) += kaslr.o
49+
obj-$(CONFIG_PAGE_TABLE_ISOLATION) += pti.o
4950

5051
obj-$(CONFIG_AMD_MEM_ENCRYPT) += mem_encrypt.o
5152
obj-$(CONFIG_AMD_MEM_ENCRYPT) += mem_encrypt_boot.o

arch/x86/mm/init.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <asm/kaslr.h>
2121
#include <asm/hypervisor.h>
2222
#include <asm/cpufeature.h>
23+
#include <asm/pti.h>
2324

2425
/*
2526
* We need to define the tracepoints somewhere, and tlb.c
@@ -630,6 +631,7 @@ void __init init_mem_mapping(void)
630631
{
631632
unsigned long end;
632633

634+
pti_check_boottime_disable();
633635
probe_page_size_mask();
634636
setup_pcid();
635637

arch/x86/mm/pti.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright(c) 2017 Intel Corporation. All rights reserved.
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of version 2 of the GNU General Public License as
6+
* published by the Free Software Foundation.
7+
*
8+
* This program is distributed in the hope that it will be useful, but
9+
* WITHOUT ANY WARRANTY; without even the implied warranty of
10+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+
* General Public License for more details.
12+
*
13+
* This code is based in part on work published here:
14+
*
15+
* https://github.com/IAIK/KAISER
16+
*
17+
* The original work was written by and and signed off by for the Linux
18+
* kernel by:
19+
*
20+
* Signed-off-by: Richard Fellner <[email protected]>
21+
* Signed-off-by: Moritz Lipp <[email protected]>
22+
* Signed-off-by: Daniel Gruss <[email protected]>
23+
* Signed-off-by: Michael Schwarz <[email protected]>
24+
*
25+
* Major changes to the original code by: Dave Hansen <[email protected]>
26+
* Mostly rewritten by Thomas Gleixner <[email protected]> and
27+
* Andy Lutomirsky <[email protected]>
28+
*/
29+
#include <linux/kernel.h>
30+
#include <linux/errno.h>
31+
#include <linux/string.h>
32+
#include <linux/types.h>
33+
#include <linux/bug.h>
34+
#include <linux/init.h>
35+
#include <linux/spinlock.h>
36+
#include <linux/mm.h>
37+
#include <linux/uaccess.h>
38+
39+
#include <asm/cpufeature.h>
40+
#include <asm/hypervisor.h>
41+
#include <asm/cmdline.h>
42+
#include <asm/pti.h>
43+
#include <asm/pgtable.h>
44+
#include <asm/pgalloc.h>
45+
#include <asm/tlbflush.h>
46+
#include <asm/desc.h>
47+
48+
#undef pr_fmt
49+
#define pr_fmt(fmt) "Kernel/User page tables isolation: " fmt
50+
51+
static void __init pti_print_if_insecure(const char *reason)
52+
{
53+
if (boot_cpu_has_bug(X86_BUG_CPU_INSECURE))
54+
pr_info("%s\n", reason);
55+
}
56+
57+
void __init pti_check_boottime_disable(void)
58+
{
59+
if (hypervisor_is_type(X86_HYPER_XEN_PV)) {
60+
pti_print_if_insecure("disabled on XEN PV.");
61+
return;
62+
}
63+
64+
if (cmdline_find_option_bool(boot_command_line, "nopti")) {
65+
pti_print_if_insecure("disabled on command line.");
66+
return;
67+
}
68+
69+
if (!boot_cpu_has_bug(X86_BUG_CPU_INSECURE))
70+
return;
71+
72+
setup_force_cpu_cap(X86_FEATURE_PTI);
73+
}
74+
75+
/*
76+
* Initialize kernel page table isolation
77+
*/
78+
void __init pti_init(void)
79+
{
80+
if (!static_cpu_has(X86_FEATURE_PTI))
81+
return;
82+
83+
pr_info("enabled\n");
84+
}

include/linux/pti.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#ifndef _INCLUDE_PTI_H
3+
#define _INCLUDE_PTI_H
4+
5+
#ifdef CONFIG_PAGE_TABLE_ISOLATION
6+
#include <asm/pti.h>
7+
#else
8+
static inline void pti_init(void) { }
9+
#endif
10+
11+
#endif

init/main.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
#include <linux/slab.h>
7676
#include <linux/perf_event.h>
7777
#include <linux/ptrace.h>
78+
#include <linux/pti.h>
7879
#include <linux/blkdev.h>
7980
#include <linux/elevator.h>
8081
#include <linux/sched_clock.h>
@@ -506,6 +507,8 @@ static void __init mm_init(void)
506507
ioremap_huge_init();
507508
/* Should be run before the first non-init thread is created */
508509
init_espfix_bsp();
510+
/* Should be run after espfix64 is set up. */
511+
pti_init();
509512
}
510513

511514
asmlinkage __visible void __init start_kernel(void)

0 commit comments

Comments
 (0)