hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/x86/entry/entry_64_compat.S
....@@ -4,7 +4,6 @@
44 *
55 * Copyright 2000-2002 Andi Kleen, SuSE Labs.
66 */
7
-#include "calling.h"
87 #include <asm/asm-offsets.h>
98 #include <asm/current.h>
109 #include <asm/errno.h>
....@@ -14,8 +13,11 @@
1413 #include <asm/irqflags.h>
1514 #include <asm/asm.h>
1615 #include <asm/smap.h>
16
+#include <asm/nospec-branch.h>
1717 #include <linux/linkage.h>
1818 #include <linux/err.h>
19
+
20
+#include "calling.h"
1921
2022 .section .entry.text, "ax"
2123
....@@ -46,14 +48,31 @@
4648 * ebp user stack
4749 * 0(%ebp) arg6
4850 */
49
-ENTRY(entry_SYSENTER_compat)
51
+SYM_CODE_START(entry_SYSENTER_compat)
52
+ UNWIND_HINT_ENTRY
5053 /* Interrupts are off on entry. */
5154 SWAPGS
5255
53
- /* We are about to clobber %rsp anyway, clobbering here is OK */
54
- SWITCH_TO_KERNEL_CR3 scratch_reg=%rsp
56
+ pushq %rax
57
+ SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
58
+ popq %rax
5559
5660 movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
61
+
62
+ /* Construct struct pt_regs on stack */
63
+ pushq $__USER32_DS /* pt_regs->ss */
64
+ pushq $0 /* pt_regs->sp = 0 (placeholder) */
65
+
66
+ /*
67
+ * Push flags. This is nasty. First, interrupts are currently
68
+ * off, but we need pt_regs->flags to have IF set. Second, if TS
69
+ * was set in usermode, it's still set, and we're singlestepping
70
+ * through this code. do_SYSENTER_32() will fix up IF.
71
+ */
72
+ pushfq /* pt_regs->flags (except IF = 0) */
73
+ pushq $__USER32_CS /* pt_regs->cs */
74
+ pushq $0 /* pt_regs->ip = 0 (placeholder) */
75
+SYM_INNER_LABEL(entry_SYSENTER_compat_after_hwframe, SYM_L_GLOBAL)
5776
5877 /*
5978 * User tracing code (ptrace or signal handlers) might assume that
....@@ -64,20 +83,6 @@
6483 */
6584 movl %eax, %eax
6685
67
- /* Construct struct pt_regs on stack */
68
- pushq $__USER32_DS /* pt_regs->ss */
69
- pushq %rbp /* pt_regs->sp (stashed in bp) */
70
-
71
- /*
72
- * Push flags. This is nasty. First, interrupts are currently
73
- * off, but we need pt_regs->flags to have IF set. Second, even
74
- * if TF was set when SYSENTER started, it's clear by now. We fix
75
- * that later using TIF_SINGLESTEP.
76
- */
77
- pushfq /* pt_regs->flags (except IF = 0) */
78
- orl $X86_EFLAGS_IF, (%rsp) /* Fix saved flags */
79
- pushq $__USER32_CS /* pt_regs->cs */
80
- pushq $0 /* pt_regs->ip = 0 (placeholder) */
8186 pushq %rax /* pt_regs->orig_ax */
8287 pushq %rdi /* pt_regs->di */
8388 pushq %rsi /* pt_regs->si */
....@@ -104,7 +109,13 @@
104109 xorl %r14d, %r14d /* nospec r14 */
105110 pushq $0 /* pt_regs->r15 = 0 */
106111 xorl %r15d, %r15d /* nospec r15 */
112
+
113
+ UNWIND_HINT_REGS
114
+
107115 cld
116
+
117
+ IBRS_ENTER
118
+ UNTRAIN_RET
108119
109120 /*
110121 * SYSENTER doesn't filter flags, so we need to clear NT and AC
....@@ -129,25 +140,19 @@
129140 jnz .Lsysenter_fix_flags
130141 .Lsysenter_flags_fixed:
131142
132
- /*
133
- * User mode is traced as though IRQs are on, and SYSENTER
134
- * turned them off.
135
- */
136
- TRACE_IRQS_OFF
137
-
138143 movq %rsp, %rdi
139
- call do_fast_syscall_32
144
+ call do_SYSENTER_32
140145 /* XEN PV guests always use IRET path */
141
- ALTERNATIVE "testl %eax, %eax; jz .Lsyscall_32_done", \
142
- "jmp .Lsyscall_32_done", X86_FEATURE_XENPV
146
+ ALTERNATIVE "testl %eax, %eax; jz swapgs_restore_regs_and_return_to_usermode", \
147
+ "jmp swapgs_restore_regs_and_return_to_usermode", X86_FEATURE_XENPV
143148 jmp sysret32_from_system_call
144149
145150 .Lsysenter_fix_flags:
146151 pushq $X86_EFLAGS_FIXED
147152 popfq
148153 jmp .Lsysenter_flags_fixed
149
-GLOBAL(__end_entry_SYSENTER_compat)
150
-ENDPROC(entry_SYSENTER_compat)
154
+SYM_INNER_LABEL(__end_entry_SYSENTER_compat, SYM_L_GLOBAL)
155
+SYM_CODE_END(entry_SYSENTER_compat)
151156
152157 /*
153158 * 32-bit SYSCALL entry.
....@@ -196,7 +201,8 @@
196201 * esp user stack
197202 * 0(%esp) arg6
198203 */
199
-ENTRY(entry_SYSCALL_compat)
204
+SYM_CODE_START(entry_SYSCALL_compat)
205
+ UNWIND_HINT_ENTRY
200206 /* Interrupts are off on entry. */
201207 swapgs
202208
....@@ -209,13 +215,15 @@
209215 /* Switch to the kernel stack */
210216 movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
211217
218
+SYM_INNER_LABEL(entry_SYSCALL_compat_safe_stack, SYM_L_GLOBAL)
219
+
212220 /* Construct struct pt_regs on stack */
213221 pushq $__USER32_DS /* pt_regs->ss */
214222 pushq %r8 /* pt_regs->sp */
215223 pushq %r11 /* pt_regs->flags */
216224 pushq $__USER32_CS /* pt_regs->cs */
217225 pushq %rcx /* pt_regs->ip */
218
-GLOBAL(entry_SYSCALL_compat_after_hwframe)
226
+SYM_INNER_LABEL(entry_SYSCALL_compat_after_hwframe, SYM_L_GLOBAL)
219227 movl %eax, %eax /* discard orig_ax high bits */
220228 pushq %rax /* pt_regs->orig_ax */
221229 pushq %rdi /* pt_regs->di */
....@@ -247,21 +255,27 @@
247255 pushq $0 /* pt_regs->r15 = 0 */
248256 xorl %r15d, %r15d /* nospec r15 */
249257
250
- /*
251
- * User mode is traced as though IRQs are on, and SYSENTER
252
- * turned them off.
253
- */
254
- TRACE_IRQS_OFF
258
+ UNWIND_HINT_REGS
259
+
260
+ IBRS_ENTER
261
+ UNTRAIN_RET
255262
256263 movq %rsp, %rdi
257264 call do_fast_syscall_32
258265 /* XEN PV guests always use IRET path */
259
- ALTERNATIVE "testl %eax, %eax; jz .Lsyscall_32_done", \
260
- "jmp .Lsyscall_32_done", X86_FEATURE_XENPV
266
+ ALTERNATIVE "testl %eax, %eax; jz swapgs_restore_regs_and_return_to_usermode", \
267
+ "jmp swapgs_restore_regs_and_return_to_usermode", X86_FEATURE_XENPV
261268
262269 /* Opportunistic SYSRET */
263270 sysret32_from_system_call:
264
- TRACE_IRQS_ON /* User mode traces as IRQs on. */
271
+ /*
272
+ * We are not going to return to userspace from the trampoline
273
+ * stack. So let's erase the thread stack right now.
274
+ */
275
+ STACKLEAK_ERASE
276
+
277
+ IBRS_EXIT
278
+
265279 movq RBX(%rsp), %rbx /* pt_regs->rbx */
266280 movq RBP(%rsp), %rbp /* pt_regs->rbp */
267281 movq EFLAGS(%rsp), %r11 /* pt_regs->flags (in r11) */
....@@ -306,7 +320,7 @@
306320 xorl %r10d, %r10d
307321 swapgs
308322 sysretl
309
-END(entry_SYSCALL_compat)
323
+SYM_CODE_END(entry_SYSCALL_compat)
310324
311325 /*
312326 * 32-bit legacy system call entry.
....@@ -334,7 +348,8 @@
334348 * edi arg5
335349 * ebp arg6
336350 */
337
-ENTRY(entry_INT80_compat)
351
+SYM_CODE_START(entry_INT80_compat)
352
+ UNWIND_HINT_ENTRY
338353 /*
339354 * Interrupts are off on entry.
340355 */
....@@ -356,8 +371,11 @@
356371
357372 /* Need to switch before accessing the thread stack. */
358373 SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
374
+
359375 /* In the Xen PV case we already run on the thread stack. */
360
- ALTERNATIVE "movq %rsp, %rdi", "jmp .Lint80_keep_stack", X86_FEATURE_XENPV
376
+ ALTERNATIVE "", "jmp .Lint80_keep_stack", X86_FEATURE_XENPV
377
+
378
+ movq %rsp, %rdi
361379 movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
362380
363381 pushq 6*8(%rdi) /* regs->ss */
....@@ -396,19 +414,15 @@
396414 xorl %r14d, %r14d /* nospec r14 */
397415 pushq %r15 /* pt_regs->r15 */
398416 xorl %r15d, %r15d /* nospec r15 */
417
+
418
+ UNWIND_HINT_REGS
419
+
399420 cld
400421
401
- /*
402
- * User mode is traced as though IRQs are on, and the interrupt
403
- * gate turned them off.
404
- */
405
- TRACE_IRQS_OFF
422
+ IBRS_ENTER
423
+ UNTRAIN_RET
406424
407425 movq %rsp, %rdi
408426 call do_int80_syscall_32
409
-.Lsyscall_32_done:
410
-
411
- /* Go back to user mode. */
412
- TRACE_IRQS_ON
413427 jmp swapgs_restore_regs_and_return_to_usermode
414
-END(entry_INT80_compat)
428
+SYM_CODE_END(entry_INT80_compat)