blob: 3edd6d011ecd5959ce257066908619fdafb1dff0 [file] [log] [blame]
Thomas Gleixner53aaf262020-02-25 23:16:12 +01001/* 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__
9
Thomas Gleixner0ba50e82020-03-26 16:28:52 +010010void idtentry_enter(struct pt_regs *regs);
11void idtentry_exit(struct pt_regs *regs);
12
Thomas Gleixner53aaf262020-02-25 23:16:12 +010013/**
14 * DECLARE_IDTENTRY - Declare functions for simple IDT entry points
15 * No error code pushed by hardware
16 * @vector: Vector number (ignored for C)
17 * @func: Function name of the entry point
18 *
19 * Declares three functions:
20 * - The ASM entry point: asm_##func
21 * - The XEN PV trap entry point: xen_##func (maybe unused)
22 * - The C handler called from the ASM entry point
23 *
24 * Note: This is the C variant of DECLARE_IDTENTRY(). As the name says it
25 * declares the entry points for usage in C code. There is an ASM variant
26 * as well which is used to emit the entry stubs in entry_32/64.S.
27 */
28#define DECLARE_IDTENTRY(vector, func) \
29 asmlinkage void asm_##func(void); \
30 asmlinkage void xen_asm_##func(void); \
31 __visible void func(struct pt_regs *regs)
32
33/**
34 * DEFINE_IDTENTRY - Emit code for simple IDT entry points
35 * @func: Function name of the entry point
36 *
37 * @func is called from ASM entry code with interrupts disabled.
38 *
39 * The macro is written so it acts as function definition. Append the
40 * body with a pair of curly brackets.
41 *
42 * idtentry_enter() contains common code which has to be invoked before
43 * arbitrary code in the body. idtentry_exit() contains common code
44 * which has to run before returning to the low level assembly code.
45 */
46#define DEFINE_IDTENTRY(func) \
47static __always_inline void __##func(struct pt_regs *regs); \
48 \
49__visible noinstr void func(struct pt_regs *regs) \
50{ \
51 idtentry_enter(regs); \
52 instrumentation_begin(); \
53 __##func (regs); \
54 instrumentation_end(); \
55 idtentry_exit(regs); \
56} \
57 \
58static __always_inline void __##func(struct pt_regs *regs)
59
Thomas Gleixnerd7729052020-02-25 23:16:30 +010060/* Special case for 32bit IRET 'trap' */
61#define DECLARE_IDTENTRY_SW DECLARE_IDTENTRY
62#define DEFINE_IDTENTRY_SW DEFINE_IDTENTRY
63
Thomas Gleixneraabfe532020-02-25 23:16:21 +010064/**
65 * DECLARE_IDTENTRY_ERRORCODE - Declare functions for simple IDT entry points
66 * Error code pushed by hardware
67 * @vector: Vector number (ignored for C)
68 * @func: Function name of the entry point
69 *
70 * Declares three functions:
71 * - The ASM entry point: asm_##func
72 * - The XEN PV trap entry point: xen_##func (maybe unused)
73 * - The C handler called from the ASM entry point
74 *
75 * Same as DECLARE_IDTENTRY, but has an extra error_code argument for the
76 * C-handler.
77 */
78#define DECLARE_IDTENTRY_ERRORCODE(vector, func) \
79 asmlinkage void asm_##func(void); \
80 asmlinkage void xen_asm_##func(void); \
81 __visible void func(struct pt_regs *regs, unsigned long error_code)
82
83/**
84 * DEFINE_IDTENTRY_ERRORCODE - Emit code for simple IDT entry points
85 * Error code pushed by hardware
86 * @func: Function name of the entry point
87 *
88 * Same as DEFINE_IDTENTRY, but has an extra error_code argument
89 */
90#define DEFINE_IDTENTRY_ERRORCODE(func) \
91static __always_inline void __##func(struct pt_regs *regs, \
92 unsigned long error_code); \
93 \
94__visible noinstr void func(struct pt_regs *regs, \
95 unsigned long error_code) \
96{ \
97 idtentry_enter(regs); \
98 instrumentation_begin(); \
99 __##func (regs, error_code); \
100 instrumentation_end(); \
101 idtentry_exit(regs); \
102} \
103 \
104static __always_inline void __##func(struct pt_regs *regs, \
105 unsigned long error_code)
106
Thomas Gleixner0dc6cdc2020-03-04 15:22:09 +0100107/**
108 * DECLARE_IDTENTRY_RAW - Declare functions for raw IDT entry points
109 * No error code pushed by hardware
110 * @vector: Vector number (ignored for C)
111 * @func: Function name of the entry point
112 *
113 * Maps to DECLARE_IDTENTRY().
114 */
115#define DECLARE_IDTENTRY_RAW(vector, func) \
116 DECLARE_IDTENTRY(vector, func)
117
118/**
119 * DEFINE_IDTENTRY_RAW - Emit code for raw IDT entry points
120 * @func: Function name of the entry point
121 *
122 * @func is called from ASM entry code with interrupts disabled.
123 *
124 * The macro is written so it acts as function definition. Append the
125 * body with a pair of curly brackets.
126 *
127 * Contrary to DEFINE_IDTENTRY() this does not invoke the
128 * idtentry_enter/exit() helpers before and after the body invocation. This
129 * needs to be done in the body itself if applicable. Use if extra work
130 * is required before the enter/exit() helpers are invoked.
131 */
132#define DEFINE_IDTENTRY_RAW(func) \
133__visible noinstr void func(struct pt_regs *regs)
134
Thomas Gleixner2c058b02020-02-25 23:33:22 +0100135#ifdef CONFIG_X86_64
136/**
137 * DECLARE_IDTENTRY_IST - Declare functions for IST handling IDT entry points
138 * @vector: Vector number (ignored for C)
139 * @func: Function name of the entry point
140 *
141 * Maps to DECLARE_IDTENTRY_RAW
142 */
143#define DECLARE_IDTENTRY_IST(vector, func) \
144 DECLARE_IDTENTRY_RAW(vector, func)
145
146/**
147 * DEFINE_IDTENTRY_IST - Emit code for IST entry points
148 * @func: Function name of the entry point
149 *
150 * Maps to DEFINE_IDTENTRY_RAW
151 */
152#define DEFINE_IDTENTRY_IST(func) \
153 DEFINE_IDTENTRY_RAW(func)
154
155#else /* CONFIG_X86_64 */
156/* Maps to a regular IDTENTRY on 32bit for now */
157# define DECLARE_IDTENTRY_IST DECLARE_IDTENTRY
158# define DEFINE_IDTENTRY_IST DEFINE_IDTENTRY
159#endif /* !CONFIG_X86_64 */
160
161/* C-Code mapping */
162#define DECLARE_IDTENTRY_MCE DECLARE_IDTENTRY_IST
163#define DEFINE_IDTENTRY_MCE DEFINE_IDTENTRY_IST
164
165#define DECLARE_IDTENTRY_NMI DECLARE_IDTENTRY_IST
166#define DEFINE_IDTENTRY_NMI DEFINE_IDTENTRY_IST
167
168#define DECLARE_IDTENTRY_DEBUG DECLARE_IDTENTRY_IST
169#define DEFINE_IDTENTRY_DEBUG DEFINE_IDTENTRY_IST
170
Thomas Gleixner53aaf262020-02-25 23:16:12 +0100171#else /* !__ASSEMBLY__ */
172
173/*
174 * The ASM variants for DECLARE_IDTENTRY*() which emit the ASM entry stubs.
175 */
176#define DECLARE_IDTENTRY(vector, func) \
177 idtentry vector asm_##func func has_error_code=0 sane=1
178
Thomas Gleixneraabfe532020-02-25 23:16:21 +0100179#define DECLARE_IDTENTRY_ERRORCODE(vector, func) \
180 idtentry vector asm_##func func has_error_code=1 sane=1
181
Thomas Gleixnerd7729052020-02-25 23:16:30 +0100182/* Special case for 32bit IRET 'trap'. Do not emit ASM code */
183#define DECLARE_IDTENTRY_SW(vector, func)
184
Thomas Gleixner0dc6cdc2020-03-04 15:22:09 +0100185#define DECLARE_IDTENTRY_RAW(vector, func) \
186 DECLARE_IDTENTRY(vector, func)
187
Thomas Gleixner2c058b02020-02-25 23:33:22 +0100188#ifdef CONFIG_X86_64
189# define DECLARE_IDTENTRY_MCE(vector, func) \
190 idtentry_mce_db vector asm_##func func
191
192# define DECLARE_IDTENTRY_DEBUG(vector, func) \
193 idtentry_mce_db vector asm_##func func
194
195#else
196# define DECLARE_IDTENTRY_MCE(vector, func) \
197 DECLARE_IDTENTRY(vector, func)
198
199# define DECLARE_IDTENTRY_DEBUG(vector, func) \
200 DECLARE_IDTENTRY(vector, func)
201#endif
202
203/* No ASM code emitted for NMI */
204#define DECLARE_IDTENTRY_NMI(vector, func)
205
Thomas Gleixner53aaf262020-02-25 23:16:12 +0100206#endif /* __ASSEMBLY__ */
207
Thomas Gleixner9d06c402020-02-25 23:16:14 +0100208/*
209 * The actual entry points. Note that DECLARE_IDTENTRY*() serves two
210 * purposes:
211 * - provide the function declarations when included from C-Code
212 * - emit the ASM stubs when included from entry_32/64.S
213 *
214 * This avoids duplicate defines and ensures that everything is consistent.
215 */
216
217/* Simple exception entry points. No hardware error code */
218DECLARE_IDTENTRY(X86_TRAP_DE, exc_divide_error);
Thomas Gleixner4b6b9112020-02-25 23:16:15 +0100219DECLARE_IDTENTRY(X86_TRAP_OF, exc_overflow);
Thomas Gleixner58d9c812020-02-25 23:16:17 +0100220DECLARE_IDTENTRY(X86_TRAP_BR, exc_bounds);
Thomas Gleixner49893c52020-02-25 23:16:18 +0100221DECLARE_IDTENTRY(X86_TRAP_UD, exc_invalid_op);
Thomas Gleixner866ae2c2020-02-25 23:16:19 +0100222DECLARE_IDTENTRY(X86_TRAP_NM, exc_device_not_available);
Thomas Gleixnerf95658f2020-02-25 23:16:20 +0100223DECLARE_IDTENTRY(X86_TRAP_OLD_MF, exc_coproc_segment_overrun);
Thomas Gleixnerdad71062020-02-25 23:16:26 +0100224DECLARE_IDTENTRY(X86_TRAP_SPURIOUS, exc_spurious_interrupt_bug);
Thomas Gleixner14a8bd22020-02-25 23:16:27 +0100225DECLARE_IDTENTRY(X86_TRAP_MF, exc_coprocessor_error);
Thomas Gleixner48227e22020-02-25 23:16:29 +0100226DECLARE_IDTENTRY(X86_TRAP_XF, exc_simd_coprocessor_error);
Thomas Gleixner9d06c402020-02-25 23:16:14 +0100227
Thomas Gleixnerd7729052020-02-25 23:16:30 +0100228/* 32bit software IRET trap. Do not emit ASM code */
229DECLARE_IDTENTRY_SW(X86_TRAP_IRET, iret_error);
230
Thomas Gleixner97b3d292020-02-25 23:16:22 +0100231/* Simple exception entries with error code pushed by hardware */
232DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_TS, exc_invalid_tss);
Thomas Gleixner99a3fb82020-02-25 23:16:23 +0100233DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_NP, exc_segment_not_present);
Thomas Gleixnerfd9689b2020-02-25 23:16:24 +0100234DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_SS, exc_stack_segment);
Thomas Gleixnerbe4c11a2020-02-25 23:16:25 +0100235DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_GP, exc_general_protection);
Thomas Gleixner436608b2020-02-25 23:16:28 +0100236DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_AC, exc_alignment_check);
Thomas Gleixner97b3d292020-02-25 23:16:22 +0100237
Thomas Gleixner8edd7e32020-02-25 23:16:16 +0100238/* Raw exception entries which need extra work */
239DECLARE_IDTENTRY_RAW(X86_TRAP_BP, exc_int3);
240
Thomas Gleixner53aaf262020-02-25 23:16:12 +0100241#endif