]>
Commit | Line | Data |
---|---|---|
53aaf262 TG |
1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _ASM_X86_IDTENTRY_H | |
3 | #define _ASM_X86_IDTENTRY_H | |
4 | ||
5 | /* Interrupts/Exceptions */ | |
6 | #include <asm/trapnr.h> | |
7 | ||
8 | #ifndef __ASSEMBLY__ | |
6368558c TG |
9 | #include <linux/hardirq.h> |
10 | ||
11 | #include <asm/irq_stack.h> | |
53aaf262 | 12 | |
9f9781b6 TG |
13 | void idtentry_enter_user(struct pt_regs *regs); |
14 | void idtentry_exit_user(struct pt_regs *regs); | |
15 | ||
9ee01e0f | 16 | bool idtentry_enter_cond_rcu(struct pt_regs *regs); |
3eeec385 TG |
17 | void idtentry_exit_cond_rcu(struct pt_regs *regs, bool rcu_exit); |
18 | ||
53aaf262 TG |
19 | /** |
20 | * DECLARE_IDTENTRY - Declare functions for simple IDT entry points | |
21 | * No error code pushed by hardware | |
22 | * @vector: Vector number (ignored for C) | |
23 | * @func: Function name of the entry point | |
24 | * | |
25 | * Declares three functions: | |
26 | * - The ASM entry point: asm_##func | |
27 | * - The XEN PV trap entry point: xen_##func (maybe unused) | |
28 | * - The C handler called from the ASM entry point | |
29 | * | |
30 | * Note: This is the C variant of DECLARE_IDTENTRY(). As the name says it | |
31 | * declares the entry points for usage in C code. There is an ASM variant | |
32 | * as well which is used to emit the entry stubs in entry_32/64.S. | |
33 | */ | |
34 | #define DECLARE_IDTENTRY(vector, func) \ | |
35 | asmlinkage void asm_##func(void); \ | |
36 | asmlinkage void xen_asm_##func(void); \ | |
37 | __visible void func(struct pt_regs *regs) | |
38 | ||
39 | /** | |
40 | * DEFINE_IDTENTRY - Emit code for simple IDT entry points | |
41 | * @func: Function name of the entry point | |
42 | * | |
43 | * @func is called from ASM entry code with interrupts disabled. | |
44 | * | |
45 | * The macro is written so it acts as function definition. Append the | |
46 | * body with a pair of curly brackets. | |
47 | * | |
48 | * idtentry_enter() contains common code which has to be invoked before | |
49 | * arbitrary code in the body. idtentry_exit() contains common code | |
50 | * which has to run before returning to the low level assembly code. | |
51 | */ | |
52 | #define DEFINE_IDTENTRY(func) \ | |
53 | static __always_inline void __##func(struct pt_regs *regs); \ | |
54 | \ | |
55 | __visible noinstr void func(struct pt_regs *regs) \ | |
56 | { \ | |
fa95d7dc TG |
57 | bool rcu_exit = idtentry_enter_cond_rcu(regs); \ |
58 | \ | |
53aaf262 TG |
59 | instrumentation_begin(); \ |
60 | __##func (regs); \ | |
61 | instrumentation_end(); \ | |
fa95d7dc | 62 | idtentry_exit_cond_rcu(regs, rcu_exit); \ |
53aaf262 TG |
63 | } \ |
64 | \ | |
65 | static __always_inline void __##func(struct pt_regs *regs) | |
66 | ||
d7729050 TG |
67 | /* Special case for 32bit IRET 'trap' */ |
68 | #define DECLARE_IDTENTRY_SW DECLARE_IDTENTRY | |
69 | #define DEFINE_IDTENTRY_SW DEFINE_IDTENTRY | |
70 | ||
aabfe538 TG |
71 | /** |
72 | * DECLARE_IDTENTRY_ERRORCODE - Declare functions for simple IDT entry points | |
73 | * Error code pushed by hardware | |
74 | * @vector: Vector number (ignored for C) | |
75 | * @func: Function name of the entry point | |
76 | * | |
77 | * Declares three functions: | |
78 | * - The ASM entry point: asm_##func | |
79 | * - The XEN PV trap entry point: xen_##func (maybe unused) | |
80 | * - The C handler called from the ASM entry point | |
81 | * | |
82 | * Same as DECLARE_IDTENTRY, but has an extra error_code argument for the | |
83 | * C-handler. | |
84 | */ | |
85 | #define DECLARE_IDTENTRY_ERRORCODE(vector, func) \ | |
86 | asmlinkage void asm_##func(void); \ | |
87 | asmlinkage void xen_asm_##func(void); \ | |
88 | __visible void func(struct pt_regs *regs, unsigned long error_code) | |
89 | ||
90 | /** | |
91 | * DEFINE_IDTENTRY_ERRORCODE - Emit code for simple IDT entry points | |
92 | * Error code pushed by hardware | |
93 | * @func: Function name of the entry point | |
94 | * | |
95 | * Same as DEFINE_IDTENTRY, but has an extra error_code argument | |
96 | */ | |
97 | #define DEFINE_IDTENTRY_ERRORCODE(func) \ | |
98 | static __always_inline void __##func(struct pt_regs *regs, \ | |
99 | unsigned long error_code); \ | |
100 | \ | |
101 | __visible noinstr void func(struct pt_regs *regs, \ | |
102 | unsigned long error_code) \ | |
103 | { \ | |
fa95d7dc TG |
104 | bool rcu_exit = idtentry_enter_cond_rcu(regs); \ |
105 | \ | |
aabfe538 TG |
106 | instrumentation_begin(); \ |
107 | __##func (regs, error_code); \ | |
108 | instrumentation_end(); \ | |
fa95d7dc | 109 | idtentry_exit_cond_rcu(regs, rcu_exit); \ |
aabfe538 TG |
110 | } \ |
111 | \ | |
112 | static __always_inline void __##func(struct pt_regs *regs, \ | |
113 | unsigned long error_code) | |
114 | ||
0dc6cdc2 TG |
115 | /** |
116 | * DECLARE_IDTENTRY_RAW - Declare functions for raw IDT entry points | |
117 | * No error code pushed by hardware | |
118 | * @vector: Vector number (ignored for C) | |
119 | * @func: Function name of the entry point | |
120 | * | |
121 | * Maps to DECLARE_IDTENTRY(). | |
122 | */ | |
123 | #define DECLARE_IDTENTRY_RAW(vector, func) \ | |
124 | DECLARE_IDTENTRY(vector, func) | |
125 | ||
126 | /** | |
127 | * DEFINE_IDTENTRY_RAW - Emit code for raw IDT entry points | |
128 | * @func: Function name of the entry point | |
129 | * | |
130 | * @func is called from ASM entry code with interrupts disabled. | |
131 | * | |
132 | * The macro is written so it acts as function definition. Append the | |
133 | * body with a pair of curly brackets. | |
134 | * | |
135 | * Contrary to DEFINE_IDTENTRY() this does not invoke the | |
136 | * idtentry_enter/exit() helpers before and after the body invocation. This | |
137 | * needs to be done in the body itself if applicable. Use if extra work | |
138 | * is required before the enter/exit() helpers are invoked. | |
139 | */ | |
140 | #define DEFINE_IDTENTRY_RAW(func) \ | |
141 | __visible noinstr void func(struct pt_regs *regs) | |
142 | ||
6a8dfa8e TG |
143 | /** |
144 | * DECLARE_IDTENTRY_RAW_ERRORCODE - Declare functions for raw IDT entry points | |
145 | * Error code pushed by hardware | |
146 | * @vector: Vector number (ignored for C) | |
147 | * @func: Function name of the entry point | |
148 | * | |
149 | * Maps to DECLARE_IDTENTRY_ERRORCODE() | |
150 | */ | |
151 | #define DECLARE_IDTENTRY_RAW_ERRORCODE(vector, func) \ | |
152 | DECLARE_IDTENTRY_ERRORCODE(vector, func) | |
153 | ||
154 | /** | |
155 | * DEFINE_IDTENTRY_RAW_ERRORCODE - Emit code for raw IDT entry points | |
156 | * @func: Function name of the entry point | |
157 | * | |
158 | * @func is called from ASM entry code with interrupts disabled. | |
159 | * | |
160 | * The macro is written so it acts as function definition. Append the | |
161 | * body with a pair of curly brackets. | |
162 | * | |
163 | * Contrary to DEFINE_IDTENTRY_ERRORCODE() this does not invoke the | |
164 | * idtentry_enter/exit() helpers before and after the body invocation. This | |
165 | * needs to be done in the body itself if applicable. Use if extra work | |
166 | * is required before the enter/exit() helpers are invoked. | |
167 | */ | |
168 | #define DEFINE_IDTENTRY_RAW_ERRORCODE(func) \ | |
169 | __visible noinstr void func(struct pt_regs *regs, unsigned long error_code) | |
170 | ||
0bf7c314 TG |
171 | /** |
172 | * DECLARE_IDTENTRY_IRQ - Declare functions for device interrupt IDT entry | |
173 | * points (common/spurious) | |
174 | * @vector: Vector number (ignored for C) | |
175 | * @func: Function name of the entry point | |
176 | * | |
177 | * Maps to DECLARE_IDTENTRY_ERRORCODE() | |
178 | */ | |
179 | #define DECLARE_IDTENTRY_IRQ(vector, func) \ | |
180 | DECLARE_IDTENTRY_ERRORCODE(vector, func) | |
181 | ||
182 | /** | |
183 | * DEFINE_IDTENTRY_IRQ - Emit code for device interrupt IDT entry points | |
184 | * @func: Function name of the entry point | |
185 | * | |
186 | * The vector number is pushed by the low level entry stub and handed | |
187 | * to the function as error_code argument which needs to be truncated | |
188 | * to an u8 because the push is sign extending. | |
189 | * | |
190 | * On 64-bit idtentry_enter/exit() are invoked in the ASM entry code before | |
191 | * and after switching to the interrupt stack. On 32-bit this happens in C. | |
192 | * | |
193 | * irq_enter/exit_rcu() are invoked before the function body and the | |
194 | * KVM L1D flush request is set. | |
195 | */ | |
196 | #define DEFINE_IDTENTRY_IRQ(func) \ | |
197 | static __always_inline void __##func(struct pt_regs *regs, u8 vector); \ | |
198 | \ | |
199 | __visible noinstr void func(struct pt_regs *regs, \ | |
200 | unsigned long error_code) \ | |
201 | { \ | |
202 | bool rcu_exit = idtentry_enter_cond_rcu(regs); \ | |
203 | \ | |
204 | instrumentation_begin(); \ | |
205 | irq_enter_rcu(); \ | |
206 | kvm_set_cpu_l1tf_flush_l1d(); \ | |
207 | __##func (regs, (u8)error_code); \ | |
208 | irq_exit_rcu(); \ | |
0bf7c314 TG |
209 | instrumentation_end(); \ |
210 | idtentry_exit_cond_rcu(regs, rcu_exit); \ | |
211 | } \ | |
212 | \ | |
213 | static __always_inline void __##func(struct pt_regs *regs, u8 vector) | |
214 | ||
6368558c TG |
215 | /** |
216 | * DECLARE_IDTENTRY_SYSVEC - Declare functions for system vector entry points | |
217 | * @vector: Vector number (ignored for C) | |
218 | * @func: Function name of the entry point | |
219 | * | |
220 | * Declares three functions: | |
221 | * - The ASM entry point: asm_##func | |
222 | * - The XEN PV trap entry point: xen_##func (maybe unused) | |
223 | * - The C handler called from the ASM entry point | |
224 | * | |
225 | * Maps to DECLARE_IDTENTRY(). | |
226 | */ | |
227 | #define DECLARE_IDTENTRY_SYSVEC(vector, func) \ | |
228 | DECLARE_IDTENTRY(vector, func) | |
229 | ||
230 | /** | |
231 | * DEFINE_IDTENTRY_SYSVEC - Emit code for system vector IDT entry points | |
232 | * @func: Function name of the entry point | |
233 | * | |
234 | * idtentry_enter/exit() and irq_enter/exit_rcu() are invoked before the | |
235 | * function body. KVM L1D flush request is set. | |
236 | * | |
237 | * Runs the function on the interrupt stack if the entry hit kernel mode | |
238 | */ | |
239 | #define DEFINE_IDTENTRY_SYSVEC(func) \ | |
240 | static void __##func(struct pt_regs *regs); \ | |
241 | \ | |
242 | __visible noinstr void func(struct pt_regs *regs) \ | |
243 | { \ | |
244 | bool rcu_exit = idtentry_enter_cond_rcu(regs); \ | |
245 | \ | |
246 | instrumentation_begin(); \ | |
247 | irq_enter_rcu(); \ | |
248 | kvm_set_cpu_l1tf_flush_l1d(); \ | |
249 | run_on_irqstack_cond(__##func, regs, regs); \ | |
250 | irq_exit_rcu(); \ | |
6368558c TG |
251 | instrumentation_end(); \ |
252 | idtentry_exit_cond_rcu(regs, rcu_exit); \ | |
253 | } \ | |
254 | \ | |
255 | static noinline void __##func(struct pt_regs *regs) | |
256 | ||
257 | /** | |
258 | * DEFINE_IDTENTRY_SYSVEC_SIMPLE - Emit code for simple system vector IDT | |
259 | * entry points | |
260 | * @func: Function name of the entry point | |
261 | * | |
262 | * Runs the function on the interrupted stack. No switch to IRQ stack and | |
263 | * only the minimal __irq_enter/exit() handling. | |
264 | * | |
265 | * Only use for 'empty' vectors like reschedule IPI and KVM posted | |
266 | * interrupt vectors. | |
267 | */ | |
268 | #define DEFINE_IDTENTRY_SYSVEC_SIMPLE(func) \ | |
269 | static __always_inline void __##func(struct pt_regs *regs); \ | |
270 | \ | |
271 | __visible noinstr void func(struct pt_regs *regs) \ | |
272 | { \ | |
273 | bool rcu_exit = idtentry_enter_cond_rcu(regs); \ | |
274 | \ | |
275 | instrumentation_begin(); \ | |
276 | __irq_enter_raw(); \ | |
277 | kvm_set_cpu_l1tf_flush_l1d(); \ | |
278 | __##func (regs); \ | |
279 | __irq_exit_raw(); \ | |
280 | instrumentation_end(); \ | |
281 | idtentry_exit_cond_rcu(regs, rcu_exit); \ | |
282 | } \ | |
283 | \ | |
284 | static __always_inline void __##func(struct pt_regs *regs) | |
285 | ||
2f6474e4 TG |
286 | /** |
287 | * DECLARE_IDTENTRY_XENCB - Declare functions for XEN HV callback entry point | |
288 | * @vector: Vector number (ignored for C) | |
289 | * @func: Function name of the entry point | |
290 | * | |
291 | * Declares three functions: | |
292 | * - The ASM entry point: asm_##func | |
293 | * - The XEN PV trap entry point: xen_##func (maybe unused) | |
294 | * - The C handler called from the ASM entry point | |
295 | * | |
296 | * Maps to DECLARE_IDTENTRY(). Distinct entry point to handle the 32/64-bit | |
297 | * difference | |
298 | */ | |
299 | #define DECLARE_IDTENTRY_XENCB(vector, func) \ | |
300 | DECLARE_IDTENTRY(vector, func) | |
6a8dfa8e | 301 | |
2c058b03 TG |
302 | #ifdef CONFIG_X86_64 |
303 | /** | |
304 | * DECLARE_IDTENTRY_IST - Declare functions for IST handling IDT entry points | |
305 | * @vector: Vector number (ignored for C) | |
306 | * @func: Function name of the entry point | |
307 | * | |
f08e32ec TG |
308 | * Maps to DECLARE_IDTENTRY_RAW, but declares also the NOIST C handler |
309 | * which is called from the ASM entry point on user mode entry | |
2c058b03 TG |
310 | */ |
311 | #define DECLARE_IDTENTRY_IST(vector, func) \ | |
f08e32ec TG |
312 | DECLARE_IDTENTRY_RAW(vector, func); \ |
313 | __visible void noist_##func(struct pt_regs *regs) | |
2c058b03 TG |
314 | |
315 | /** | |
316 | * DEFINE_IDTENTRY_IST - Emit code for IST entry points | |
317 | * @func: Function name of the entry point | |
318 | * | |
319 | * Maps to DEFINE_IDTENTRY_RAW | |
320 | */ | |
321 | #define DEFINE_IDTENTRY_IST(func) \ | |
322 | DEFINE_IDTENTRY_RAW(func) | |
323 | ||
f08e32ec TG |
324 | /** |
325 | * DEFINE_IDTENTRY_NOIST - Emit code for NOIST entry points which | |
326 | * belong to a IST entry point (MCE, DB) | |
327 | * @func: Function name of the entry point. Must be the same as | |
328 | * the function name of the corresponding IST variant | |
329 | * | |
330 | * Maps to DEFINE_IDTENTRY_RAW(). | |
331 | */ | |
332 | #define DEFINE_IDTENTRY_NOIST(func) \ | |
333 | DEFINE_IDTENTRY_RAW(noist_##func) | |
334 | ||
6a8dfa8e TG |
335 | /** |
336 | * DECLARE_IDTENTRY_DF - Declare functions for double fault | |
337 | * @vector: Vector number (ignored for C) | |
338 | * @func: Function name of the entry point | |
339 | * | |
340 | * Maps to DECLARE_IDTENTRY_RAW_ERRORCODE | |
341 | */ | |
342 | #define DECLARE_IDTENTRY_DF(vector, func) \ | |
343 | DECLARE_IDTENTRY_RAW_ERRORCODE(vector, func) | |
344 | ||
345 | /** | |
346 | * DEFINE_IDTENTRY_DF - Emit code for double fault | |
347 | * @func: Function name of the entry point | |
348 | * | |
349 | * Maps to DEFINE_IDTENTRY_RAW_ERRORCODE | |
350 | */ | |
351 | #define DEFINE_IDTENTRY_DF(func) \ | |
352 | DEFINE_IDTENTRY_RAW_ERRORCODE(func) | |
353 | ||
2c058b03 | 354 | #else /* CONFIG_X86_64 */ |
6a8dfa8e | 355 | |
2c058b03 TG |
356 | /* Maps to a regular IDTENTRY on 32bit for now */ |
357 | # define DECLARE_IDTENTRY_IST DECLARE_IDTENTRY | |
358 | # define DEFINE_IDTENTRY_IST DEFINE_IDTENTRY | |
6a8dfa8e TG |
359 | |
360 | /** | |
361 | * DECLARE_IDTENTRY_DF - Declare functions for double fault 32bit variant | |
362 | * @vector: Vector number (ignored for C) | |
363 | * @func: Function name of the entry point | |
364 | * | |
365 | * Declares two functions: | |
366 | * - The ASM entry point: asm_##func | |
367 | * - The C handler called from the C shim | |
368 | */ | |
369 | #define DECLARE_IDTENTRY_DF(vector, func) \ | |
370 | asmlinkage void asm_##func(void); \ | |
371 | __visible void func(struct pt_regs *regs, \ | |
372 | unsigned long error_code, \ | |
373 | unsigned long address) | |
374 | ||
375 | /** | |
376 | * DEFINE_IDTENTRY_DF - Emit code for double fault on 32bit | |
377 | * @func: Function name of the entry point | |
378 | * | |
379 | * This is called through the doublefault shim which already provides | |
380 | * cr2 in the address argument. | |
381 | */ | |
382 | #define DEFINE_IDTENTRY_DF(func) \ | |
383 | __visible noinstr void func(struct pt_regs *regs, \ | |
384 | unsigned long error_code, \ | |
385 | unsigned long address) | |
386 | ||
2c058b03 TG |
387 | #endif /* !CONFIG_X86_64 */ |
388 | ||
389 | /* C-Code mapping */ | |
390 | #define DECLARE_IDTENTRY_MCE DECLARE_IDTENTRY_IST | |
391 | #define DEFINE_IDTENTRY_MCE DEFINE_IDTENTRY_IST | |
f08e32ec | 392 | #define DEFINE_IDTENTRY_MCE_USER DEFINE_IDTENTRY_NOIST |
2c058b03 | 393 | |
71ed49d8 TG |
394 | #define DECLARE_IDTENTRY_NMI DECLARE_IDTENTRY_RAW |
395 | #define DEFINE_IDTENTRY_NMI DEFINE_IDTENTRY_RAW | |
2c058b03 TG |
396 | |
397 | #define DECLARE_IDTENTRY_DEBUG DECLARE_IDTENTRY_IST | |
398 | #define DEFINE_IDTENTRY_DEBUG DEFINE_IDTENTRY_IST | |
f08e32ec | 399 | #define DEFINE_IDTENTRY_DEBUG_USER DEFINE_IDTENTRY_NOIST |
2c058b03 | 400 | |
53aaf262 TG |
401 | #else /* !__ASSEMBLY__ */ |
402 | ||
403 | /* | |
404 | * The ASM variants for DECLARE_IDTENTRY*() which emit the ASM entry stubs. | |
405 | */ | |
406 | #define DECLARE_IDTENTRY(vector, func) \ | |
e2dcb5f1 | 407 | idtentry vector asm_##func func has_error_code=0 |
53aaf262 | 408 | |
aabfe538 | 409 | #define DECLARE_IDTENTRY_ERRORCODE(vector, func) \ |
e2dcb5f1 | 410 | idtentry vector asm_##func func has_error_code=1 |
aabfe538 | 411 | |
d7729050 TG |
412 | /* Special case for 32bit IRET 'trap'. Do not emit ASM code */ |
413 | #define DECLARE_IDTENTRY_SW(vector, func) | |
414 | ||
0dc6cdc2 TG |
415 | #define DECLARE_IDTENTRY_RAW(vector, func) \ |
416 | DECLARE_IDTENTRY(vector, func) | |
417 | ||
6a8dfa8e TG |
418 | #define DECLARE_IDTENTRY_RAW_ERRORCODE(vector, func) \ |
419 | DECLARE_IDTENTRY_ERRORCODE(vector, func) | |
420 | ||
0bf7c314 TG |
421 | /* Entries for common/spurious (device) interrupts */ |
422 | #define DECLARE_IDTENTRY_IRQ(vector, func) \ | |
423 | idtentry_irq vector func | |
424 | ||
6368558c TG |
425 | /* System vector entries */ |
426 | #define DECLARE_IDTENTRY_SYSVEC(vector, func) \ | |
427 | idtentry_sysvec vector func | |
428 | ||
2c058b03 TG |
429 | #ifdef CONFIG_X86_64 |
430 | # define DECLARE_IDTENTRY_MCE(vector, func) \ | |
431 | idtentry_mce_db vector asm_##func func | |
432 | ||
433 | # define DECLARE_IDTENTRY_DEBUG(vector, func) \ | |
434 | idtentry_mce_db vector asm_##func func | |
435 | ||
6a8dfa8e TG |
436 | # define DECLARE_IDTENTRY_DF(vector, func) \ |
437 | idtentry_df vector asm_##func func | |
438 | ||
2f6474e4 TG |
439 | # define DECLARE_IDTENTRY_XENCB(vector, func) \ |
440 | DECLARE_IDTENTRY(vector, func) | |
441 | ||
2c058b03 TG |
442 | #else |
443 | # define DECLARE_IDTENTRY_MCE(vector, func) \ | |
444 | DECLARE_IDTENTRY(vector, func) | |
445 | ||
446 | # define DECLARE_IDTENTRY_DEBUG(vector, func) \ | |
447 | DECLARE_IDTENTRY(vector, func) | |
6a8dfa8e TG |
448 | |
449 | /* No ASM emitted for DF as this goes through a C shim */ | |
450 | # define DECLARE_IDTENTRY_DF(vector, func) | |
451 | ||
2f6474e4 TG |
452 | /* No ASM emitted for XEN hypervisor callback */ |
453 | # define DECLARE_IDTENTRY_XENCB(vector, func) | |
454 | ||
2c058b03 TG |
455 | #endif |
456 | ||
457 | /* No ASM code emitted for NMI */ | |
458 | #define DECLARE_IDTENTRY_NMI(vector, func) | |
459 | ||
633260fa TG |
460 | /* |
461 | * ASM code to emit the common vector entry stubs where each stub is | |
462 | * packed into 8 bytes. | |
463 | * | |
464 | * Note, that the 'pushq imm8' is emitted via '.byte 0x6a, vector' because | |
465 | * GCC treats the local vector variable as unsigned int and would expand | |
466 | * all vectors above 0x7F to a 5 byte push. The original code did an | |
467 | * adjustment of the vector number to be in the signed byte range to avoid | |
468 | * this. While clever it's mindboggling counterintuitive and requires the | |
469 | * odd conversion back to a real vector number in the C entry points. Using | |
470 | * .byte achieves the same thing and the only fixup needed in the C entry | |
471 | * point is to mask off the bits above bit 7 because the push is sign | |
472 | * extending. | |
473 | */ | |
474 | .align 8 | |
475 | SYM_CODE_START(irq_entries_start) | |
476 | vector=FIRST_EXTERNAL_VECTOR | |
477 | pos = . | |
478 | .rept (FIRST_SYSTEM_VECTOR - FIRST_EXTERNAL_VECTOR) | |
479 | UNWIND_HINT_IRET_REGS | |
480 | .byte 0x6a, vector | |
fa5e5c40 | 481 | jmp asm_common_interrupt |
633260fa TG |
482 | nop |
483 | /* Ensure that the above is 8 bytes max */ | |
484 | . = pos + 8 | |
485 | pos=pos+8 | |
486 | vector=vector+1 | |
487 | .endr | |
488 | SYM_CODE_END(irq_entries_start) | |
489 | ||
490 | #ifdef CONFIG_X86_LOCAL_APIC | |
491 | .align 8 | |
492 | SYM_CODE_START(spurious_entries_start) | |
493 | vector=FIRST_SYSTEM_VECTOR | |
494 | pos = . | |
495 | .rept (NR_VECTORS - FIRST_SYSTEM_VECTOR) | |
496 | UNWIND_HINT_IRET_REGS | |
497 | .byte 0x6a, vector | |
fa5e5c40 | 498 | jmp asm_spurious_interrupt |
633260fa TG |
499 | nop |
500 | /* Ensure that the above is 8 bytes max */ | |
501 | . = pos + 8 | |
502 | pos=pos+8 | |
503 | vector=vector+1 | |
504 | .endr | |
505 | SYM_CODE_END(spurious_entries_start) | |
506 | #endif | |
507 | ||
53aaf262 TG |
508 | #endif /* __ASSEMBLY__ */ |
509 | ||
9d06c402 TG |
510 | /* |
511 | * The actual entry points. Note that DECLARE_IDTENTRY*() serves two | |
512 | * purposes: | |
513 | * - provide the function declarations when included from C-Code | |
514 | * - emit the ASM stubs when included from entry_32/64.S | |
515 | * | |
516 | * This avoids duplicate defines and ensures that everything is consistent. | |
517 | */ | |
518 | ||
2f6474e4 TG |
519 | /* |
520 | * Dummy trap number so the low level ASM macro vector number checks do not | |
521 | * match which results in emitting plain IDTENTRY stubs without bells and | |
522 | * whistels. | |
523 | */ | |
524 | #define X86_TRAP_OTHER 0xFFFF | |
525 | ||
9d06c402 TG |
526 | /* Simple exception entry points. No hardware error code */ |
527 | DECLARE_IDTENTRY(X86_TRAP_DE, exc_divide_error); | |
4b6b9111 | 528 | DECLARE_IDTENTRY(X86_TRAP_OF, exc_overflow); |
58d9c81f | 529 | DECLARE_IDTENTRY(X86_TRAP_BR, exc_bounds); |
866ae2cc | 530 | DECLARE_IDTENTRY(X86_TRAP_NM, exc_device_not_available); |
f95658fd | 531 | DECLARE_IDTENTRY(X86_TRAP_OLD_MF, exc_coproc_segment_overrun); |
dad7106f | 532 | DECLARE_IDTENTRY(X86_TRAP_SPURIOUS, exc_spurious_interrupt_bug); |
14a8bd2a | 533 | DECLARE_IDTENTRY(X86_TRAP_MF, exc_coprocessor_error); |
48227e21 | 534 | DECLARE_IDTENTRY(X86_TRAP_XF, exc_simd_coprocessor_error); |
9d06c402 | 535 | |
d7729050 TG |
536 | /* 32bit software IRET trap. Do not emit ASM code */ |
537 | DECLARE_IDTENTRY_SW(X86_TRAP_IRET, iret_error); | |
538 | ||
97b3d290 TG |
539 | /* Simple exception entries with error code pushed by hardware */ |
540 | DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_TS, exc_invalid_tss); | |
99a3fb8d | 541 | DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_NP, exc_segment_not_present); |
fd9689bf | 542 | DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_SS, exc_stack_segment); |
be4c11af | 543 | DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_GP, exc_general_protection); |
436608bb | 544 | DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_AC, exc_alignment_check); |
97b3d290 | 545 | |
8edd7e37 | 546 | /* Raw exception entries which need extra work */ |
15a416e8 | 547 | DECLARE_IDTENTRY_RAW(X86_TRAP_UD, exc_invalid_op); |
91eeafea TG |
548 | DECLARE_IDTENTRY_RAW(X86_TRAP_BP, exc_int3); |
549 | DECLARE_IDTENTRY_RAW_ERRORCODE(X86_TRAP_PF, exc_page_fault); | |
8edd7e37 | 550 | |
8cd501c1 TG |
551 | #ifdef CONFIG_X86_MCE |
552 | DECLARE_IDTENTRY_MCE(X86_TRAP_MC, exc_machine_check); | |
553 | #endif | |
554 | ||
6271fef0 TG |
555 | /* NMI */ |
556 | DECLARE_IDTENTRY_NMI(X86_TRAP_NMI, exc_nmi); | |
f41f0824 AL |
557 | #ifdef CONFIG_XEN_PV |
558 | DECLARE_IDTENTRY_RAW(X86_TRAP_NMI, xenpv_exc_nmi); | |
559 | #endif | |
6271fef0 | 560 | |
2bbc68f8 TG |
561 | /* #DB */ |
562 | DECLARE_IDTENTRY_DEBUG(X86_TRAP_DB, exc_debug); | |
f41f0824 AL |
563 | #ifdef CONFIG_XEN_PV |
564 | DECLARE_IDTENTRY_RAW(X86_TRAP_DB, xenpv_exc_debug); | |
565 | #endif | |
2bbc68f8 | 566 | |
c29c775a TG |
567 | /* #DF */ |
568 | DECLARE_IDTENTRY_DF(X86_TRAP_DF, exc_double_fault); | |
569 | ||
2f6474e4 TG |
570 | #ifdef CONFIG_XEN_PV |
571 | DECLARE_IDTENTRY_XENCB(X86_TRAP_OTHER, exc_xen_hypervisor_callback); | |
572 | #endif | |
573 | ||
fa5e5c40 TG |
574 | /* Device interrupts common/spurious */ |
575 | DECLARE_IDTENTRY_IRQ(X86_TRAP_OTHER, common_interrupt); | |
576 | #ifdef CONFIG_X86_LOCAL_APIC | |
577 | DECLARE_IDTENTRY_IRQ(X86_TRAP_OTHER, spurious_interrupt); | |
578 | #endif | |
579 | ||
db0338ee TG |
580 | /* System vector entry points */ |
581 | #ifdef CONFIG_X86_LOCAL_APIC | |
582 | DECLARE_IDTENTRY_SYSVEC(ERROR_APIC_VECTOR, sysvec_error_interrupt); | |
583 | DECLARE_IDTENTRY_SYSVEC(SPURIOUS_APIC_VECTOR, sysvec_spurious_apic_interrupt); | |
584 | DECLARE_IDTENTRY_SYSVEC(LOCAL_TIMER_VECTOR, sysvec_apic_timer_interrupt); | |
585 | DECLARE_IDTENTRY_SYSVEC(X86_PLATFORM_IPI_VECTOR, sysvec_x86_platform_ipi); | |
586 | #endif | |
587 | ||
582f9191 | 588 | #ifdef CONFIG_SMP |
13cad985 | 589 | DECLARE_IDTENTRY(RESCHEDULE_VECTOR, sysvec_reschedule_ipi); |
582f9191 TG |
590 | DECLARE_IDTENTRY_SYSVEC(IRQ_MOVE_CLEANUP_VECTOR, sysvec_irq_move_cleanup); |
591 | DECLARE_IDTENTRY_SYSVEC(REBOOT_VECTOR, sysvec_reboot); | |
592 | DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_SINGLE_VECTOR, sysvec_call_function_single); | |
593 | DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_VECTOR, sysvec_call_function); | |
594 | #endif | |
595 | ||
720909a7 TG |
596 | #ifdef CONFIG_X86_LOCAL_APIC |
597 | # ifdef CONFIG_X86_UV | |
598 | DECLARE_IDTENTRY_SYSVEC(UV_BAU_MESSAGE, sysvec_uv_bau_message); | |
599 | # endif | |
600 | ||
601 | # ifdef CONFIG_X86_MCE_THRESHOLD | |
602 | DECLARE_IDTENTRY_SYSVEC(THRESHOLD_APIC_VECTOR, sysvec_threshold); | |
603 | # endif | |
604 | ||
605 | # ifdef CONFIG_X86_MCE_AMD | |
606 | DECLARE_IDTENTRY_SYSVEC(DEFERRED_ERROR_VECTOR, sysvec_deferred_error); | |
607 | # endif | |
608 | ||
609 | # ifdef CONFIG_X86_THERMAL_VECTOR | |
610 | DECLARE_IDTENTRY_SYSVEC(THERMAL_APIC_VECTOR, sysvec_thermal); | |
611 | # endif | |
612 | ||
613 | # ifdef CONFIG_IRQ_WORK | |
614 | DECLARE_IDTENTRY_SYSVEC(IRQ_WORK_VECTOR, sysvec_irq_work); | |
615 | # endif | |
616 | #endif | |
617 | ||
9c3b1f49 TG |
618 | #ifdef CONFIG_HAVE_KVM |
619 | DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_VECTOR, sysvec_kvm_posted_intr_ipi); | |
620 | DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_WAKEUP_VECTOR, sysvec_kvm_posted_intr_wakeup_ipi); | |
621 | DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_NESTED_VECTOR, sysvec_kvm_posted_intr_nested_ipi); | |
622 | #endif | |
623 | ||
a16be368 TG |
624 | #if IS_ENABLED(CONFIG_HYPERV) |
625 | DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR, sysvec_hyperv_callback); | |
626 | DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_REENLIGHTENMENT_VECTOR, sysvec_hyperv_reenlightenment); | |
627 | DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_STIMER0_VECTOR, sysvec_hyperv_stimer0); | |
628 | #endif | |
629 | ||
630 | #if IS_ENABLED(CONFIG_ACRN_GUEST) | |
631 | DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR, sysvec_acrn_hv_callback); | |
632 | #endif | |
633 | ||
cb09ea29 TG |
634 | #ifdef CONFIG_XEN_PVHVM |
635 | DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR, sysvec_xen_hvm_callback); | |
636 | #endif | |
637 | ||
2f6474e4 TG |
638 | #undef X86_TRAP_OTHER |
639 | ||
53aaf262 | 640 | #endif |