drm/panthor: Don't add write fences to the shared BOs
[drm/drm-misc.git] / arch / x86 / entry / entry_64_fred.S
bloba02bc6f3d2e6a43d4e00c4657986382029065aa0
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * The actual FRED entry points.
4  */
6 #include <linux/export.h>
8 #include <asm/asm.h>
9 #include <asm/fred.h>
10 #include <asm/segment.h>
12 #include "calling.h"
14         .code64
15         .section .noinstr.text, "ax"
17 .macro FRED_ENTER
18         UNWIND_HINT_END_OF_STACK
19         ENDBR
20         PUSH_AND_CLEAR_REGS
21         movq    %rsp, %rdi      /* %rdi -> pt_regs */
22 .endm
24 .macro FRED_EXIT
25         UNWIND_HINT_REGS
26         POP_REGS
27 .endm
30  * The new RIP value that FRED event delivery establishes is
31  * IA32_FRED_CONFIG & ~FFFH for events that occur in ring 3.
32  * Thus the FRED ring 3 entry point must be 4K page aligned.
33  */
34         .align 4096
36 SYM_CODE_START_NOALIGN(asm_fred_entrypoint_user)
37         FRED_ENTER
38         call    fred_entry_from_user
39 SYM_INNER_LABEL(asm_fred_exit_user, SYM_L_GLOBAL)
40         FRED_EXIT
41 1:      ERETU
43         _ASM_EXTABLE_TYPE(1b, asm_fred_entrypoint_user, EX_TYPE_ERETU)
44 SYM_CODE_END(asm_fred_entrypoint_user)
47  * The new RIP value that FRED event delivery establishes is
48  * (IA32_FRED_CONFIG & ~FFFH) + 256 for events that occur in
49  * ring 0, i.e., asm_fred_entrypoint_user + 256.
50  */
51         .org asm_fred_entrypoint_user + 256, 0xcc
52 SYM_CODE_START_NOALIGN(asm_fred_entrypoint_kernel)
53         FRED_ENTER
54         call    fred_entry_from_kernel
55         FRED_EXIT
56         ERETS
57 SYM_CODE_END(asm_fred_entrypoint_kernel)
59 #if IS_ENABLED(CONFIG_KVM_INTEL)
60 SYM_FUNC_START(asm_fred_entry_from_kvm)
61         push %rbp
62         mov %rsp, %rbp
64         UNWIND_HINT_SAVE
66         /*
67          * Both IRQ and NMI from VMX can be handled on current task stack
68          * because there is no need to protect from reentrancy and the call
69          * stack leading to this helper is effectively constant and shallow
70          * (relatively speaking). Do the same when FRED is active, i.e., no
71          * need to check current stack level for a stack switch.
72          *
73          * Emulate the FRED-defined redzone and stack alignment.
74          */
75         sub $(FRED_CONFIG_REDZONE_AMOUNT << 6), %rsp
76         and $FRED_STACK_FRAME_RSP_MASK, %rsp
78         /*
79          * Start to push a FRED stack frame, which is always 64 bytes:
80          *
81          * +--------+-----------------+
82          * | Bytes  | Usage           |
83          * +--------+-----------------+
84          * | 63:56  | Reserved        |
85          * | 55:48  | Event Data      |
86          * | 47:40  | SS + Event Info |
87          * | 39:32  | RSP             |
88          * | 31:24  | RFLAGS          |
89          * | 23:16  | CS + Aux Info   |
90          * |  15:8  | RIP             |
91          * |   7:0  | Error Code      |
92          * +--------+-----------------+
93          */
94         push $0                         /* Reserved, must be 0 */
95         push $0                         /* Event data, 0 for IRQ/NMI */
96         push %rdi                       /* fred_ss handed in by the caller */
97         push %rbp
98         pushf
99         mov $__KERNEL_CS, %rax
100         push %rax
102         /*
103          * Unlike the IDT event delivery, FRED _always_ pushes an error code
104          * after pushing the return RIP, thus the CALL instruction CANNOT be
105          * used here to push the return RIP, otherwise there is no chance to
106          * push an error code before invoking the IRQ/NMI handler.
107          *
108          * Use LEA to get the return RIP and push it, then push an error code.
109          */
110         lea 1f(%rip), %rax
111         push %rax                               /* Return RIP */
112         push $0                                 /* Error code, 0 for IRQ/NMI */
114         PUSH_AND_CLEAR_REGS clear_bp=0 unwind_hint=0
115         movq %rsp, %rdi                         /* %rdi -> pt_regs */
116         call __fred_entry_from_kvm              /* Call the C entry point */
117         POP_REGS
118         ERETS
120         /*
121          * Objtool doesn't understand what ERETS does, this hint tells it that
122          * yes, we'll reach here and with what stack state. A save/restore pair
123          * isn't strictly needed, but it's the simplest form.
124          */
125         UNWIND_HINT_RESTORE
126         pop %rbp
127         RET
129 SYM_FUNC_END(asm_fred_entry_from_kvm)
130 EXPORT_SYMBOL_GPL(asm_fred_entry_from_kvm);
131 #endif