hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/arch/x86/include/asm/cpu_entry_area.h
....@@ -1,4 +1,4 @@
1
-// SPDX-License-Identifier: GPL-2.0
1
+/* SPDX-License-Identifier: GPL-2.0 */
22
33 #ifndef _ASM_X86_CPU_ENTRY_AREA_H
44 #define _ASM_X86_CPU_ENTRY_AREA_H
....@@ -6,6 +6,78 @@
66 #include <linux/percpu-defs.h>
77 #include <asm/processor.h>
88 #include <asm/intel_ds.h>
9
+#include <asm/pgtable_areas.h>
10
+
11
+#ifdef CONFIG_X86_64
12
+
13
+#ifdef CONFIG_AMD_MEM_ENCRYPT
14
+#define VC_EXCEPTION_STKSZ EXCEPTION_STKSZ
15
+#else
16
+#define VC_EXCEPTION_STKSZ 0
17
+#endif
18
+
19
+/* Macro to enforce the same ordering and stack sizes */
20
+#define ESTACKS_MEMBERS(guardsize, optional_stack_size) \
21
+ char DF_stack_guard[guardsize]; \
22
+ char DF_stack[EXCEPTION_STKSZ]; \
23
+ char NMI_stack_guard[guardsize]; \
24
+ char NMI_stack[EXCEPTION_STKSZ]; \
25
+ char DB_stack_guard[guardsize]; \
26
+ char DB_stack[EXCEPTION_STKSZ]; \
27
+ char MCE_stack_guard[guardsize]; \
28
+ char MCE_stack[EXCEPTION_STKSZ]; \
29
+ char VC_stack_guard[guardsize]; \
30
+ char VC_stack[optional_stack_size]; \
31
+ char VC2_stack_guard[guardsize]; \
32
+ char VC2_stack[optional_stack_size]; \
33
+ char IST_top_guard[guardsize]; \
34
+
35
+/* The exception stacks' physical storage. No guard pages required */
36
+struct exception_stacks {
37
+ ESTACKS_MEMBERS(0, VC_EXCEPTION_STKSZ)
38
+};
39
+
40
+/* The effective cpu entry area mapping with guard pages. */
41
+struct cea_exception_stacks {
42
+ ESTACKS_MEMBERS(PAGE_SIZE, EXCEPTION_STKSZ)
43
+};
44
+
45
+/*
46
+ * The exception stack ordering in [cea_]exception_stacks
47
+ */
48
+enum exception_stack_ordering {
49
+ ESTACK_DF,
50
+ ESTACK_NMI,
51
+ ESTACK_DB,
52
+ ESTACK_MCE,
53
+ ESTACK_VC,
54
+ ESTACK_VC2,
55
+ N_EXCEPTION_STACKS
56
+};
57
+
58
+#define CEA_ESTACK_SIZE(st) \
59
+ sizeof(((struct cea_exception_stacks *)0)->st## _stack)
60
+
61
+#define CEA_ESTACK_BOT(ceastp, st) \
62
+ ((unsigned long)&(ceastp)->st## _stack)
63
+
64
+#define CEA_ESTACK_TOP(ceastp, st) \
65
+ (CEA_ESTACK_BOT(ceastp, st) + CEA_ESTACK_SIZE(st))
66
+
67
+#define CEA_ESTACK_OFFS(st) \
68
+ offsetof(struct cea_exception_stacks, st## _stack)
69
+
70
+#define CEA_ESTACK_PAGES \
71
+ (sizeof(struct cea_exception_stacks) / PAGE_SIZE)
72
+
73
+#endif
74
+
75
+#ifdef CONFIG_X86_32
76
+struct doublefault_stack {
77
+ unsigned long stack[(PAGE_SIZE - sizeof(struct x86_hw_tss)) / sizeof(unsigned long)];
78
+ struct x86_hw_tss tss;
79
+} __aligned(PAGE_SIZE);
80
+#endif
981
1082 /*
1183 * cpu_entry_area is a percpu region that contains things needed by the CPU
....@@ -20,9 +92,18 @@
2092
2193 /*
2294 * The GDT is just below entry_stack and thus serves (on x86_64) as
23
- * a a read-only guard page.
95
+ * a read-only guard page. On 32-bit the GDT must be writeable, so
96
+ * it needs an extra guard page.
2497 */
98
+#ifdef CONFIG_X86_32
99
+ char guard_entry_stack[PAGE_SIZE];
100
+#endif
25101 struct entry_stack_page entry_stack_page;
102
+
103
+#ifdef CONFIG_X86_32
104
+ char guard_doublefault_stack[PAGE_SIZE];
105
+ struct doublefault_stack doublefault_stack;
106
+#endif
26107
27108 /*
28109 * On x86_64, the TSS is mapped RO. On x86_32, it's mapped RW because
....@@ -30,18 +111,12 @@
30111 */
31112 struct tss_struct tss;
32113
33
- char entry_trampoline[PAGE_SIZE];
34
-
35114 #ifdef CONFIG_X86_64
36115 /*
37
- * Exception stacks used for IST entries.
38
- *
39
- * In the future, this should have a separate slot for each stack
40
- * with guard pages between them.
116
+ * Exception stacks used for IST entries with guard pages.
41117 */
42
- char exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ];
118
+ struct cea_exception_stacks estacks;
43119 #endif
44
-#ifdef CONFIG_CPU_SUP_INTEL
45120 /*
46121 * Per CPU debug store for Intel performance monitoring. Wastes a
47122 * full page at the moment.
....@@ -52,24 +127,19 @@
52127 * Reserve enough fixmap PTEs.
53128 */
54129 struct debug_store_buffers cpu_debug_buffers;
55
-#endif
56130 };
57131
58
-#define CPU_ENTRY_AREA_SIZE (sizeof(struct cpu_entry_area))
59
-#define CPU_ENTRY_AREA_TOT_SIZE (CPU_ENTRY_AREA_SIZE * NR_CPUS)
132
+#define CPU_ENTRY_AREA_SIZE (sizeof(struct cpu_entry_area))
133
+#define CPU_ENTRY_AREA_ARRAY_SIZE (CPU_ENTRY_AREA_SIZE * NR_CPUS)
134
+
135
+/* Total size includes the readonly IDT mapping page as well: */
136
+#define CPU_ENTRY_AREA_TOTAL_SIZE (CPU_ENTRY_AREA_ARRAY_SIZE + PAGE_SIZE)
60137
61138 DECLARE_PER_CPU(struct cpu_entry_area *, cpu_entry_area);
139
+DECLARE_PER_CPU(struct cea_exception_stacks *, cea_exception_stacks);
62140
63141 extern void setup_cpu_entry_areas(void);
64142 extern void cea_set_pte(void *cea_vaddr, phys_addr_t pa, pgprot_t flags);
65
-
66
-#define CPU_ENTRY_AREA_RO_IDT CPU_ENTRY_AREA_BASE
67
-#define CPU_ENTRY_AREA_PER_CPU (CPU_ENTRY_AREA_RO_IDT + PAGE_SIZE)
68
-
69
-#define CPU_ENTRY_AREA_RO_IDT_VADDR ((void *)CPU_ENTRY_AREA_RO_IDT)
70
-
71
-#define CPU_ENTRY_AREA_MAP_SIZE \
72
- (CPU_ENTRY_AREA_PER_CPU + CPU_ENTRY_AREA_TOT_SIZE - CPU_ENTRY_AREA_BASE)
73143
74144 extern struct cpu_entry_area *get_cpu_entry_area(int cpu);
75145
....@@ -78,4 +148,10 @@
78148 return &get_cpu_entry_area(cpu)->entry_stack_page.stack;
79149 }
80150
151
+#define __this_cpu_ist_top_va(name) \
152
+ CEA_ESTACK_TOP(__this_cpu_read(cea_exception_stacks), name)
153
+
154
+#define __this_cpu_ist_bottom_va(name) \
155
+ CEA_ESTACK_BOT(__this_cpu_read(cea_exception_stacks), name)
156
+
81157 #endif