5
5
#include <linux/context_tracking.h>
6
6
#include <asm/ftrace.h>
7
7
8
+ struct interrupt_state {
9
+ };
10
+
11
+ static inline void interrupt_enter_prepare (struct pt_regs * regs , struct interrupt_state * state )
12
+ {
13
+ }
14
+
15
+ /*
16
+ * Care should be taken to note that interrupt_exit_prepare and
17
+ * interrupt_async_exit_prepare do not necessarily return immediately to
18
+ * regs context (e.g., if regs is usermode, we don't necessarily return to
19
+ * user mode). Other interrupts might be taken between here and return,
20
+ * context switch / preemption may occur in the exit path after this, or a
21
+ * signal may be delivered, etc.
22
+ *
23
+ * The real interrupt exit code is platform specific, e.g.,
24
+ * interrupt_exit_user_prepare / interrupt_exit_kernel_prepare for 64s.
25
+ *
26
+ * However interrupt_nmi_exit_prepare does return directly to regs, because
27
+ * NMIs do not do "exit work" or replay soft-masked interrupts.
28
+ */
29
+ static inline void interrupt_exit_prepare (struct pt_regs * regs , struct interrupt_state * state )
30
+ {
31
+ }
32
+
33
+ static inline void interrupt_async_enter_prepare (struct pt_regs * regs , struct interrupt_state * state )
34
+ {
35
+ }
36
+
37
+ static inline void interrupt_async_exit_prepare (struct pt_regs * regs , struct interrupt_state * state )
38
+ {
39
+ }
40
+
41
+ struct interrupt_nmi_state {
42
+ };
43
+
44
+ static inline void interrupt_nmi_enter_prepare (struct pt_regs * regs , struct interrupt_nmi_state * state )
45
+ {
46
+ }
47
+
48
+ static inline void interrupt_nmi_exit_prepare (struct pt_regs * regs , struct interrupt_nmi_state * state )
49
+ {
50
+ }
51
+
8
52
/**
9
53
* DECLARE_INTERRUPT_HANDLER_RAW - Declare raw interrupt handler function
10
54
* @func: Function name of the entry point
@@ -71,7 +115,13 @@ static __always_inline void ____##func(struct pt_regs *regs); \
71
115
\
72
116
__visible noinstr void func(struct pt_regs *regs) \
73
117
{ \
118
+ struct interrupt_state state; \
119
+ \
120
+ interrupt_enter_prepare(regs, &state); \
121
+ \
74
122
____##func (regs); \
123
+ \
124
+ interrupt_exit_prepare(regs, &state); \
75
125
} \
76
126
\
77
127
static __always_inline void ____##func(struct pt_regs *regs)
@@ -99,10 +149,15 @@ static __always_inline long ____##func(struct pt_regs *regs); \
99
149
\
100
150
__visible noinstr long func(struct pt_regs *regs) \
101
151
{ \
152
+ struct interrupt_state state; \
102
153
long ret; \
103
154
\
155
+ interrupt_enter_prepare(regs, &state); \
156
+ \
104
157
ret = ____##func (regs); \
105
158
\
159
+ interrupt_exit_prepare(regs, &state); \
160
+ \
106
161
return ret; \
107
162
} \
108
163
\
@@ -129,7 +184,13 @@ static __always_inline void ____##func(struct pt_regs *regs); \
129
184
\
130
185
__visible noinstr void func(struct pt_regs *regs) \
131
186
{ \
187
+ struct interrupt_state state; \
188
+ \
189
+ interrupt_async_enter_prepare(regs, &state); \
190
+ \
132
191
____##func (regs); \
192
+ \
193
+ interrupt_async_exit_prepare(regs, &state); \
133
194
} \
134
195
\
135
196
static __always_inline void ____##func(struct pt_regs *regs)
@@ -157,10 +218,15 @@ static __always_inline long ____##func(struct pt_regs *regs); \
157
218
\
158
219
__visible noinstr long func(struct pt_regs *regs) \
159
220
{ \
221
+ struct interrupt_nmi_state state; \
160
222
long ret; \
161
223
\
224
+ interrupt_nmi_enter_prepare(regs, &state); \
225
+ \
162
226
ret = ____##func (regs); \
163
227
\
228
+ interrupt_nmi_exit_prepare(regs, &state); \
229
+ \
164
230
return ret; \
165
231
} \
166
232
\
0 commit comments