hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/x86/mm/pti.c
....@@ -1,14 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * 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.
124 *
135 * This code is based in part on work published here:
146 *
....@@ -42,11 +34,10 @@
4234 #include <asm/vsyscall.h>
4335 #include <asm/cmdline.h>
4436 #include <asm/pti.h>
45
-#include <asm/pgtable.h>
46
-#include <asm/pgalloc.h>
4737 #include <asm/tlbflush.h>
4838 #include <asm/desc.h>
4939 #include <asm/sections.h>
40
+#include <asm/set_memory.h>
5041
5142 #undef pr_fmt
5243 #define pr_fmt(fmt) "Kernel/User page tables isolation: " fmt
....@@ -78,7 +69,7 @@
7869 pr_info("%s\n", reason);
7970 }
8071
81
-enum pti_mode {
72
+static enum pti_mode {
8273 PTI_AUTO = 0,
8374 PTI_FORCE_OFF,
8475 PTI_FORCE_ON
....@@ -438,11 +429,36 @@
438429 }
439430
440431 /*
441
- * Clone the CPU_ENTRY_AREA into the user space visible page table.
432
+ * Clone the CPU_ENTRY_AREA and associated data into the user space visible
433
+ * page table.
442434 */
443435 static void __init pti_clone_user_shared(void)
444436 {
437
+ unsigned int cpu;
438
+
445439 pti_clone_p4d(CPU_ENTRY_AREA_BASE);
440
+
441
+ for_each_possible_cpu(cpu) {
442
+ /*
443
+ * The SYSCALL64 entry code needs to be able to find the
444
+ * thread stack and needs one word of scratch space in which
445
+ * to spill a register. All of this lives in the TSS, in
446
+ * the sp1 and sp2 slots.
447
+ *
448
+ * This is done for all possible CPUs during boot to ensure
449
+ * that it's propagated to all mms.
450
+ */
451
+
452
+ unsigned long va = (unsigned long)&per_cpu(cpu_tss_rw, cpu);
453
+ phys_addr_t pa = per_cpu_ptr_to_phys((void *)va);
454
+ pte_t *target_pte;
455
+
456
+ target_pte = pti_user_pagetable_walk_pte(va);
457
+ if (WARN_ON(!target_pte))
458
+ return;
459
+
460
+ *target_pte = pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL);
461
+ }
446462 }
447463
448464 #else /* CONFIG_X86_64 */
....@@ -475,12 +491,12 @@
475491 }
476492
477493 /*
478
- * Clone the populated PMDs of the entry and irqentry text and force it RO.
494
+ * Clone the populated PMDs of the entry text and force it RO.
479495 */
480496 static void pti_clone_entry_text(void)
481497 {
482498 pti_clone_pgtable((unsigned long) __entry_text_start,
483
- (unsigned long) __irqentry_text_end,
499
+ (unsigned long) __entry_text_end,
484500 PTI_CLONE_PMD);
485501
486502 /*
....@@ -541,13 +557,6 @@
541557 }
542558
543559 /*
544
- * This is the only user for these and it is not arch-generic
545
- * like the other set_memory.h functions. Just extern them.
546
- */
547
-extern int set_memory_nonglobal(unsigned long addr, int numpages);
548
-extern int set_memory_global(unsigned long addr, int numpages);
549
-
550
-/*
551560 * For some configurations, map all of kernel text into the user page
552561 * tables. This reduces TLB misses, especially on non-PCID systems.
553562 */
....@@ -584,7 +593,7 @@
584593 set_memory_global(start, (end_global - start) >> PAGE_SHIFT);
585594 }
586595
587
-void pti_set_kernel_image_nonglobal(void)
596
+static void pti_set_kernel_image_nonglobal(void)
588597 {
589598 /*
590599 * The identity map is created with PMDs, regardless of the
....@@ -608,7 +617,7 @@
608617 */
609618 void __init pti_init(void)
610619 {
611
- if (!static_cpu_has(X86_FEATURE_PTI))
620
+ if (!boot_cpu_has(X86_FEATURE_PTI))
612621 return;
613622
614623 pr_info("enabled\n");