efi: libstub: check Shim mode using MokSBStateRT
[platform/kernel/linux-rpi.git] / arch / x86 / include / asm / irq_stack.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_X86_IRQ_STACK_H
3 #define _ASM_X86_IRQ_STACK_H
4
5 #include <linux/ptrace.h>
6 #include <linux/objtool.h>
7
8 #include <asm/processor.h>
9
10 #ifdef CONFIG_X86_64
11
12 /*
13  * Macro to inline switching to an interrupt stack and invoking function
14  * calls from there. The following rules apply:
15  *
16  * - Ordering:
17  *
18  *   1. Write the stack pointer into the top most place of the irq
19  *      stack. This ensures that the various unwinders can link back to the
20  *      original stack.
21  *
22  *   2. Switch the stack pointer to the top of the irq stack.
23  *
24  *   3. Invoke whatever needs to be done (@asm_call argument)
25  *
26  *   4. Pop the original stack pointer from the top of the irq stack
27  *      which brings it back to the original stack where it left off.
28  *
29  * - Function invocation:
30  *
31  *   To allow flexible usage of the macro, the actual function code including
32  *   the store of the arguments in the call ABI registers is handed in via
33  *   the @asm_call argument.
34  *
35  * - Local variables:
36  *
37  *   @tos:
38  *      The @tos variable holds a pointer to the top of the irq stack and
39  *      _must_ be allocated in a non-callee saved register as this is a
40  *      restriction coming from objtool.
41  *
42  *      Note, that (tos) is both in input and output constraints to ensure
43  *      that the compiler does not assume that R11 is left untouched in
44  *      case this macro is used in some place where the per cpu interrupt
45  *      stack pointer is used again afterwards
46  *
47  * - Function arguments:
48  *      The function argument(s), if any, have to be defined in register
49  *      variables at the place where this is invoked. Storing the
50  *      argument(s) in the proper register(s) is part of the @asm_call
51  *
52  * - Constraints:
53  *
54  *   The constraints have to be done very carefully because the compiler
55  *   does not know about the assembly call.
56  *
57  *   output:
58  *     As documented already above the @tos variable is required to be in
59  *     the output constraints to make the compiler aware that R11 cannot be
60  *     reused after the asm() statement.
61  *
62  *     For builds with CONFIG_UNWINDER_FRAME_POINTER, ASM_CALL_CONSTRAINT is
63  *     required as well as this prevents certain creative GCC variants from
64  *     misplacing the ASM code.
65  *
66  *  input:
67  *    - func:
68  *        Immediate, which tells the compiler that the function is referenced.
69  *
70  *    - tos:
71  *        Register. The actual register is defined by the variable declaration.
72  *
73  *    - function arguments:
74  *        The constraints are handed in via the 'argconstr' argument list. They
75  *        describe the register arguments which are used in @asm_call.
76  *
77  *  clobbers:
78  *     Function calls can clobber anything except the callee-saved
79  *     registers. Tell the compiler.
80  */
81 #define call_on_stack(stack, func, asm_call, argconstr...)              \
82 {                                                                       \
83         register void *tos asm("r11");                                  \
84                                                                         \
85         tos = ((void *)(stack));                                        \
86                                                                         \
87         asm_inline volatile(                                            \
88         "movq   %%rsp, (%[tos])                         \n"             \
89         "movq   %[tos], %%rsp                           \n"             \
90                                                                         \
91         asm_call                                                        \
92                                                                         \
93         "popq   %%rsp                                   \n"             \
94                                                                         \
95         : "+r" (tos), ASM_CALL_CONSTRAINT                               \
96         : [__func] "i" (func), [tos] "r" (tos) argconstr                \
97         : "cc", "rax", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10",   \
98           "memory"                                                      \
99         );                                                              \
100 }
101
102 #define ASM_CALL_ARG0                                                   \
103         "call %P[__func]                                \n"             \
104         ASM_REACHABLE
105
106 #define ASM_CALL_ARG1                                                   \
107         "movq   %[arg1], %%rdi                          \n"             \
108         ASM_CALL_ARG0
109
110 #define ASM_CALL_ARG2                                                   \
111         "movq   %[arg2], %%rsi                          \n"             \
112         ASM_CALL_ARG1
113
114 #define ASM_CALL_ARG3                                                   \
115         "movq   %[arg3], %%rdx                          \n"             \
116         ASM_CALL_ARG2
117
118 #define call_on_irqstack(func, asm_call, argconstr...)                  \
119         call_on_stack(__this_cpu_read(hardirq_stack_ptr),               \
120                       func, asm_call, argconstr)
121
122 /* Macros to assert type correctness for run_*_on_irqstack macros */
123 #define assert_function_type(func, proto)                               \
124         static_assert(__builtin_types_compatible_p(typeof(&func), proto))
125
126 #define assert_arg_type(arg, proto)                                     \
127         static_assert(__builtin_types_compatible_p(typeof(arg), proto))
128
129 /*
130  * Macro to invoke system vector and device interrupt C handlers.
131  */
132 #define call_on_irqstack_cond(func, regs, asm_call, constr, c_args...)  \
133 {                                                                       \
134         /*                                                              \
135          * User mode entry and interrupt on the irq stack do not        \
136          * switch stacks. If from user mode the task stack is empty.    \
137          */                                                             \
138         if (user_mode(regs) || __this_cpu_read(hardirq_stack_inuse)) {  \
139                 irq_enter_rcu();                                        \
140                 func(c_args);                                           \
141                 irq_exit_rcu();                                         \
142         } else {                                                        \
143                 /*                                                      \
144                  * Mark the irq stack inuse _before_ and unmark _after_ \
145                  * switching stacks. Interrupts are disabled in both    \
146                  * places. Invoke the stack switch macro with the call  \
147                  * sequence which matches the above direct invocation.  \
148                  */                                                     \
149                 __this_cpu_write(hardirq_stack_inuse, true);            \
150                 call_on_irqstack(func, asm_call, constr);               \
151                 __this_cpu_write(hardirq_stack_inuse, false);           \
152         }                                                               \
153 }
154
155 /*
156  * Function call sequence for __call_on_irqstack() for system vectors.
157  *
158  * Note that irq_enter_rcu() and irq_exit_rcu() do not use the input
159  * mechanism because these functions are global and cannot be optimized out
160  * when compiling a particular source file which uses one of these macros.
161  *
162  * The argument (regs) does not need to be pushed or stashed in a callee
163  * saved register to be safe vs. the irq_enter_rcu() call because the
164  * clobbers already prevent the compiler from storing it in a callee
165  * clobbered register. As the compiler has to preserve @regs for the final
166  * call to idtentry_exit() anyway, it's likely that it does not cause extra
167  * effort for this asm magic.
168  */
169 #define ASM_CALL_SYSVEC                                                 \
170         "call irq_enter_rcu                             \n"             \
171         ASM_CALL_ARG1                                                   \
172         "call irq_exit_rcu                              \n"
173
174 #define SYSVEC_CONSTRAINTS      , [arg1] "r" (regs)
175
176 #define run_sysvec_on_irqstack_cond(func, regs)                         \
177 {                                                                       \
178         assert_function_type(func, void (*)(struct pt_regs *));         \
179         assert_arg_type(regs, struct pt_regs *);                        \
180                                                                         \
181         call_on_irqstack_cond(func, regs, ASM_CALL_SYSVEC,              \
182                               SYSVEC_CONSTRAINTS, regs);                \
183 }
184
185 /*
186  * As in ASM_CALL_SYSVEC above the clobbers force the compiler to store
187  * @regs and @vector in callee saved registers.
188  */
189 #define ASM_CALL_IRQ                                                    \
190         "call irq_enter_rcu                             \n"             \
191         ASM_CALL_ARG2                                                   \
192         "call irq_exit_rcu                              \n"
193
194 #define IRQ_CONSTRAINTS , [arg1] "r" (regs), [arg2] "r" ((unsigned long)vector)
195
196 #define run_irq_on_irqstack_cond(func, regs, vector)                    \
197 {                                                                       \
198         assert_function_type(func, void (*)(struct pt_regs *, u32));    \
199         assert_arg_type(regs, struct pt_regs *);                        \
200         assert_arg_type(vector, u32);                                   \
201                                                                         \
202         call_on_irqstack_cond(func, regs, ASM_CALL_IRQ,                 \
203                               IRQ_CONSTRAINTS, regs, vector);           \
204 }
205
206 #ifndef CONFIG_PREEMPT_RT
207 /*
208  * Macro to invoke __do_softirq on the irq stack. This is only called from
209  * task context when bottom halves are about to be reenabled and soft
210  * interrupts are pending to be processed. The interrupt stack cannot be in
211  * use here.
212  */
213 #define do_softirq_own_stack()                                          \
214 {                                                                       \
215         __this_cpu_write(hardirq_stack_inuse, true);                    \
216         call_on_irqstack(__do_softirq, ASM_CALL_ARG0);                  \
217         __this_cpu_write(hardirq_stack_inuse, false);                   \
218 }
219
220 #endif
221
222 #else /* CONFIG_X86_64 */
223 /* System vector handlers always run on the stack they interrupted. */
224 #define run_sysvec_on_irqstack_cond(func, regs)                         \
225 {                                                                       \
226         irq_enter_rcu();                                                \
227         func(regs);                                                     \
228         irq_exit_rcu();                                                 \
229 }
230
231 /* Switches to the irq stack within func() */
232 #define run_irq_on_irqstack_cond(func, regs, vector)                    \
233 {                                                                       \
234         irq_enter_rcu();                                                \
235         func(regs, vector);                                             \
236         irq_exit_rcu();                                                 \
237 }
238
239 #endif /* !CONFIG_X86_64 */
240
241 #endif