4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 /*
29 * Companion to kdi_idt.c - the implementation of the trap and interrupt
30 * handlers. For the most part, these handlers do the same thing - they
31 * push a trap number onto the stack, followed by a jump to kdi_cmnint.
32 * Each trap and interrupt has its own handler because each one pushes a
33 * different number.
34 */
35
36 #include <sys/asm_linkage.h>
37 #include <sys/kdi_regs.h>
38
39 /* Nothing in this file is of interest to lint. */
40 #if !defined(__lint)
41
42 /*
43 * The default ASM_ENTRY_ALIGN (16) wastes far too much space. Pay no
44 * attention to the fleet of nop's we're adding to each handler.
45 */
46 #undef ASM_ENTRY_ALIGN
47 #define ASM_ENTRY_ALIGN 8
48
49 /*
50 * We need the .align in ENTRY_NP (defined to be ASM_ENTRY_ALIGN) to match our
51 * manual .align (KDI_MSR_PATCHOFF) in order to ensure that the space reserved
52 * at the beginning of the handler for code is exactly KDI_MSR_PATCHOFF bytes
53 * long. Note that the #error below isn't supported by the preprocessor invoked
54 * by as(1), and won't stop the build, but it'll emit a noticeable error message
55 * which won't escape the filters.
56 */
57 #if ASM_ENTRY_ALIGN != KDI_MSR_PATCHOFF
58 #error "ASM_ENTRY_ALIGN != KDI_MSR_PATCHOFF"
59 this won't assemble
60 #endif
61
62 /*
63 * kdi_idt_patch will, on certain processors, replace the patch points below
64 * with MSR-clearing code. kdi_id_patch has intimate knowledge of the size of
65 * the nop hole, as well as the structure of the handlers. Do not change
66 * anything here without also changing kdi_idt_patch.
67 */
68
69 /*
70 * Generic trap and interrupt handlers.
71 */
72
73 #if defined(__xpv) && defined(__amd64)
74
75 /*
76 * The hypervisor places r11 and rcx on the stack.
77 */
78
79 #define TRAP_NOERR(trapno) \
80 popq %rcx; \
81 popq %r11; \
82 pushq $trapno
83
84 #define TRAP_ERR(trapno) \
85 popq %rcx; \
86 popq %r11; \
87 pushq $0; \
88 pushq $trapno
89
90 #else
91
92 #define TRAP_NOERR(trapno) \
93 push $trapno
94
95 #define TRAP_ERR(trapno) \
96 push $0; \
97 push $trapno
98
99 #endif /* __xpv && __amd64 */
100
101
102 #define MKIVCT(n) \
103 ENTRY_NP(kdi_ivct/**/n/**/); \
104 TRAP_ERR(n); \
105 .align KDI_MSR_PATCHOFF; \
106 KDI_MSR_PATCH; \
107 jmp kdi_cmnint; \
108 SET_SIZE(kdi_ivct/**/n/**/)
109
110 #define MKTRAPHDLR(n) \
111 ENTRY_NP(kdi_trap/**/n); \
112 TRAP_ERR(n); \
113 .align KDI_MSR_PATCHOFF; \
114 KDI_MSR_PATCH; \
115 jmp kdi_cmnint; \
116 SET_SIZE(kdi_trap/**/n/**/)
117
118 #define MKTRAPERRHDLR(n) \
119 ENTRY_NP(kdi_traperr/**/n); \
120 TRAP_NOERR(n); \
121 .align KDI_MSR_PATCHOFF; \
122 KDI_MSR_PATCH; \
123 jmp kdi_cmnint; \
124 SET_SIZE(kdi_traperr/**/n)
125
126 #define MKNMIHDLR \
127 ENTRY_NP(kdi_int2); \
128 TRAP_NOERR(2); \
129 .align KDI_MSR_PATCHOFF; \
130 KDI_MSR_PATCH; \
131 jmp kdi_nmiint; \
132 SET_SIZE(kdi_int2)
133
134 #define MKINVALHDLR \
135 ENTRY_NP(kdi_invaltrap); \
136 TRAP_NOERR(255); \
137 .align KDI_MSR_PATCHOFF; \
138 KDI_MSR_PATCH; \
139 jmp kdi_cmnint; \
140 SET_SIZE(kdi_invaltrap)
141
142 /*
143 * The handlers themselves
144 */
145
146 MKINVALHDLR
147 MKTRAPHDLR(0)
148 MKTRAPHDLR(1)
149 MKNMIHDLR/*2*/
150 MKTRAPHDLR(3)
151 MKTRAPHDLR(4)
152 MKTRAPHDLR(5)
153 MKTRAPHDLR(6)
154 MKTRAPHDLR(7)
155 MKTRAPHDLR(9)
156 MKTRAPHDLR(15)
157 MKTRAPHDLR(16)
158 MKTRAPHDLR(17)
159 MKTRAPHDLR(18)
160 MKTRAPHDLR(19)
161 MKTRAPHDLR(20)
162
163 MKTRAPERRHDLR(8)
164 MKTRAPERRHDLR(10)
165 MKTRAPERRHDLR(11)
166 MKTRAPERRHDLR(12)
167 MKTRAPERRHDLR(13)
168 MKTRAPERRHDLR(14)
169
170 .globl kdi_ivct_size
171 kdi_ivct_size:
172 .NWORD [kdi_ivct33-kdi_ivct32]
173
174 /* 10 billion and one interrupt handlers */
175 kdi_ivct_base:
176 MKIVCT(32); MKIVCT(33); MKIVCT(34); MKIVCT(35);
177 MKIVCT(36); MKIVCT(37); MKIVCT(38); MKIVCT(39);
178 MKIVCT(40); MKIVCT(41); MKIVCT(42); MKIVCT(43);
179 MKIVCT(44); MKIVCT(45); MKIVCT(46); MKIVCT(47);
180 MKIVCT(48); MKIVCT(49); MKIVCT(50); MKIVCT(51);
181 MKIVCT(52); MKIVCT(53); MKIVCT(54); MKIVCT(55);
182 MKIVCT(56); MKIVCT(57); MKIVCT(58); MKIVCT(59);
183 MKIVCT(60); MKIVCT(61); MKIVCT(62); MKIVCT(63);
184 MKIVCT(64); MKIVCT(65); MKIVCT(66); MKIVCT(67);
185 MKIVCT(68); MKIVCT(69); MKIVCT(70); MKIVCT(71);
186 MKIVCT(72); MKIVCT(73); MKIVCT(74); MKIVCT(75);
187 MKIVCT(76); MKIVCT(77); MKIVCT(78); MKIVCT(79);
188 MKIVCT(80); MKIVCT(81); MKIVCT(82); MKIVCT(83);
213 MKIVCT(180); MKIVCT(181); MKIVCT(182); MKIVCT(183);
214 MKIVCT(184); MKIVCT(185); MKIVCT(186); MKIVCT(187);
215 MKIVCT(188); MKIVCT(189); MKIVCT(190); MKIVCT(191);
216 MKIVCT(192); MKIVCT(193); MKIVCT(194); MKIVCT(195);
217 MKIVCT(196); MKIVCT(197); MKIVCT(198); MKIVCT(199);
218 MKIVCT(200); MKIVCT(201); MKIVCT(202); MKIVCT(203);
219 MKIVCT(204); MKIVCT(205); MKIVCT(206); MKIVCT(207);
220 MKIVCT(208); MKIVCT(209); MKIVCT(210); MKIVCT(211);
221 MKIVCT(212); MKIVCT(213); MKIVCT(214); MKIVCT(215);
222 MKIVCT(216); MKIVCT(217); MKIVCT(218); MKIVCT(219);
223 MKIVCT(220); MKIVCT(221); MKIVCT(222); MKIVCT(223);
224 MKIVCT(224); MKIVCT(225); MKIVCT(226); MKIVCT(227);
225 MKIVCT(228); MKIVCT(229); MKIVCT(230); MKIVCT(231);
226 MKIVCT(232); MKIVCT(233); MKIVCT(234); MKIVCT(235);
227 MKIVCT(236); MKIVCT(237); MKIVCT(238); MKIVCT(239);
228 MKIVCT(240); MKIVCT(241); MKIVCT(242); MKIVCT(243);
229 MKIVCT(244); MKIVCT(245); MKIVCT(246); MKIVCT(247);
230 MKIVCT(248); MKIVCT(249); MKIVCT(250); MKIVCT(251);
231 MKIVCT(252); MKIVCT(253); MKIVCT(254); MKIVCT(255);
232
233 #endif
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 *
25 * Copyright 2018 Joyent, Inc.
26 */
27
28 /*
29 * Companion to kdi_asm.s - the implementation of the trap and interrupt
30 * handlers. For the most part, these handlers do the same thing - they
31 * push a trap number onto the stack, followed by a jump to kdi_cmnint.
32 * Each trap and interrupt has its own handler because each one pushes a
33 * different number.
34 */
35
36 #if defined(__lint)
37 #include <sys/types.h>
38 #else
39
40 #include <sys/asm_linkage.h>
41 #include <sys/asm_misc.h>
42 #include <sys/machprivregs.h>
43 #include <sys/privregs.h>
44 #include <sys/kdi_regs.h>
45 #include <sys/trap.h>
46 #include <sys/param.h>
47
48 #include <kdi_assym.h>
49 #include <assym.h>
50
51 /*
52 * The default ASM_ENTRY_ALIGN (16) wastes far too much space.
53 */
54 #undef ASM_ENTRY_ALIGN
55 #define ASM_ENTRY_ALIGN 8
56
57 /*
58 * Generic trap and interrupt handlers.
59 */
60
61 #if defined(__xpv)
62
63 #define INTERRUPT_TRAMPOLINE
64
65 #else
66
67 /*
68 * If we're !xpv, then we will need to support KPTI (kernel page table
69 * isolation), where we have separate page tables for user and kernel modes.
70 * There's more detail about this in kpti_trampolines.s and hat_i86.c
71 */
72
73 #define INTERRUPT_TRAMPOLINE \
74 pushq %r13; \
75 pushq %r14; \
76 subq $KPTI_R14, %rsp; \
77 /* Check for clobbering */ \
78 cmp $0, KPTI_FLAG(%rsp); \
79 je 1f; \
80 /* Don't worry, this totally works */ \
81 int $8; \
82 1: \
83 movq $1, KPTI_FLAG(%rsp); \
84 /* Save current %cr3. */ \
85 mov %cr3, %r14; \
86 mov %r14, KPTI_TR_CR3(%rsp); \
87 /* Switch to paranoid %cr3. */ \
88 mov kpti_safe_cr3, %r14; \
89 mov %r14, %cr3; \
90 \
91 cmpw $KCS_SEL, KPTI_CS(%rsp); \
92 je 3f; \
93 2: \
94 /* Get our cpu_t in %r13 */ \
95 mov %rsp, %r13; \
96 and $(~(MMU_PAGESIZE - 1)), %r13; \
97 subq $CPU_KPTI_START, %r13; \
98 /* Use top of the kthread stk */ \
99 mov CPU_THREAD(%r13), %r14; \
100 mov T_STACK(%r14), %r14; \
101 addq $REGSIZE+MINFRAME, %r14; \
102 jmp 5f; \
103 3: \
104 /* Check the %rsp in the frame. */ \
105 /* Is it above kernel base? */ \
106 mov kpti_kbase, %r14; \
107 cmp %r14, KPTI_RSP(%rsp); \
108 jb 2b; \
109 /* Is it within the kpti_frame page? */ \
110 mov %rsp, %r13; \
111 and $(~(MMU_PAGESIZE - 1)), %r13; \
112 mov KPTI_RSP(%rsp), %r14; \
113 and $(~(MMU_PAGESIZE - 1)), %r14; \
114 cmp %r13, %r14; \
115 je 2b; \
116 /* Use the %rsp from the trap frame. */ \
117 /* We already did %cr3. */ \
118 mov KPTI_RSP(%rsp), %r14; \
119 and $(~0xf), %r14; \
120 5: \
121 mov %rsp, %r13; \
122 /* %r14 contains our destination stk */ \
123 mov %r14, %rsp; \
124 pushq KPTI_SS(%r13); \
125 pushq KPTI_RSP(%r13); \
126 pushq KPTI_RFLAGS(%r13); \
127 pushq KPTI_CS(%r13); \
128 pushq KPTI_RIP(%r13); \
129 pushq KPTI_ERR(%r13); \
130 mov KPTI_R14(%r13), %r14; \
131 movq $0, KPTI_FLAG(%r13); \
132 mov KPTI_R13(%r13), %r13
133
134 #endif /* !__xpv */
135
136
137 #define MKIVCT(n) \
138 ENTRY_NP(kdi_ivct/**/n/**/); \
139 XPV_TRAP_POP; \
140 push $0; /* err */ \
141 INTERRUPT_TRAMPOLINE; \
142 push $n; \
143 jmp kdi_cmnint; \
144 SET_SIZE(kdi_ivct/**/n/**/)
145
146 #define MKTRAPHDLR(n) \
147 ENTRY_NP(kdi_trap/**/n); \
148 XPV_TRAP_POP; \
149 push $0; /* err */ \
150 INTERRUPT_TRAMPOLINE; \
151 push $n; \
152 jmp kdi_cmnint; \
153 SET_SIZE(kdi_trap/**/n/**/)
154
155 #define MKTRAPERRHDLR(n) \
156 ENTRY_NP(kdi_traperr/**/n); \
157 XPV_TRAP_POP; \
158 INTERRUPT_TRAMPOLINE; \
159 push $n; \
160 jmp kdi_cmnint; \
161 SET_SIZE(kdi_traperr/**/n)
162
163 #if !defined(__xpv)
164 #define MKNMIHDLR \
165 ENTRY_NP(kdi_int2); \
166 push $0; \
167 push $2; \
168 pushq %r13; \
169 mov kpti_safe_cr3, %r13; \
170 mov %r13, %cr3; \
171 popq %r13; \
172 jmp kdi_nmiint; \
173 SET_SIZE(kdi_int2)
174
175 #define MKMCEHDLR \
176 ENTRY_NP(kdi_trap18); \
177 push $0; \
178 push $18; \
179 pushq %r13; \
180 mov kpti_safe_cr3, %r13; \
181 mov %r13, %cr3; \
182 popq %r13; \
183 jmp kdi_cmnint; \
184 SET_SIZE(kdi_trap18)
185 #else
186 #define MKNMIHDLR \
187 ENTRY_NP(kdi_int2); \
188 push $0; \
189 push $2; \
190 jmp kdi_nmiint; \
191 SET_SIZE(kdi_int2)
192
193 #define MKMCEHDLR \
194 ENTRY_NP(kdi_trap18); \
195 push $0; \
196 push $18; \
197 jmp kdi_cmnint; \
198 SET_SIZE(kdi_trap18)
199 #endif
200
201 /*
202 * The only way we should reach here is by an explicit "int 0x.." which is
203 * defined not to push an error code.
204 */
205 #define MKINVALHDLR \
206 ENTRY_NP(kdi_invaltrap); \
207 XPV_TRAP_POP; \
208 push $0; /* err */ \
209 INTERRUPT_TRAMPOLINE; \
210 push $255; \
211 jmp kdi_cmnint; \
212 SET_SIZE(kdi_invaltrap)
213
214 .data
215 DGDEF3(kdi_idt, 16 * NIDT, MMU_PAGESIZE)
216 .fill MMU_PAGESIZE, 1, 0
217
218 #if !defined(__xpv)
219 .section ".text"
220 .align MMU_PAGESIZE
221 .global kdi_isr_start
222 kdi_isr_start:
223 nop
224
225 .global kpti_safe_cr3
226 .global kpti_kbase
227 #endif
228
229 /*
230 * The handlers themselves
231 */
232
233 MKINVALHDLR
234 MKTRAPHDLR(0)
235 MKTRAPHDLR(1)
236 MKNMIHDLR/*2*/
237 MKTRAPHDLR(3)
238 MKTRAPHDLR(4)
239 MKTRAPHDLR(5)
240 MKTRAPHDLR(6)
241 MKTRAPHDLR(7)
242 MKTRAPHDLR(9)
243 MKTRAPHDLR(15)
244 MKTRAPHDLR(16)
245 MKMCEHDLR/*18*/
246 MKTRAPHDLR(19)
247 MKTRAPHDLR(20)
248
249 MKTRAPERRHDLR(8)
250 MKTRAPERRHDLR(10)
251 MKTRAPERRHDLR(11)
252 MKTRAPERRHDLR(12)
253 MKTRAPERRHDLR(13)
254 MKTRAPERRHDLR(14)
255 MKTRAPERRHDLR(17)
256
257 .globl kdi_ivct_size
258 kdi_ivct_size:
259 .NWORD [kdi_ivct33-kdi_ivct32]
260
261 /* 10 billion and one interrupt handlers */
262 kdi_ivct_base:
263 MKIVCT(32); MKIVCT(33); MKIVCT(34); MKIVCT(35);
264 MKIVCT(36); MKIVCT(37); MKIVCT(38); MKIVCT(39);
265 MKIVCT(40); MKIVCT(41); MKIVCT(42); MKIVCT(43);
266 MKIVCT(44); MKIVCT(45); MKIVCT(46); MKIVCT(47);
267 MKIVCT(48); MKIVCT(49); MKIVCT(50); MKIVCT(51);
268 MKIVCT(52); MKIVCT(53); MKIVCT(54); MKIVCT(55);
269 MKIVCT(56); MKIVCT(57); MKIVCT(58); MKIVCT(59);
270 MKIVCT(60); MKIVCT(61); MKIVCT(62); MKIVCT(63);
271 MKIVCT(64); MKIVCT(65); MKIVCT(66); MKIVCT(67);
272 MKIVCT(68); MKIVCT(69); MKIVCT(70); MKIVCT(71);
273 MKIVCT(72); MKIVCT(73); MKIVCT(74); MKIVCT(75);
274 MKIVCT(76); MKIVCT(77); MKIVCT(78); MKIVCT(79);
275 MKIVCT(80); MKIVCT(81); MKIVCT(82); MKIVCT(83);
300 MKIVCT(180); MKIVCT(181); MKIVCT(182); MKIVCT(183);
301 MKIVCT(184); MKIVCT(185); MKIVCT(186); MKIVCT(187);
302 MKIVCT(188); MKIVCT(189); MKIVCT(190); MKIVCT(191);
303 MKIVCT(192); MKIVCT(193); MKIVCT(194); MKIVCT(195);
304 MKIVCT(196); MKIVCT(197); MKIVCT(198); MKIVCT(199);
305 MKIVCT(200); MKIVCT(201); MKIVCT(202); MKIVCT(203);
306 MKIVCT(204); MKIVCT(205); MKIVCT(206); MKIVCT(207);
307 MKIVCT(208); MKIVCT(209); MKIVCT(210); MKIVCT(211);
308 MKIVCT(212); MKIVCT(213); MKIVCT(214); MKIVCT(215);
309 MKIVCT(216); MKIVCT(217); MKIVCT(218); MKIVCT(219);
310 MKIVCT(220); MKIVCT(221); MKIVCT(222); MKIVCT(223);
311 MKIVCT(224); MKIVCT(225); MKIVCT(226); MKIVCT(227);
312 MKIVCT(228); MKIVCT(229); MKIVCT(230); MKIVCT(231);
313 MKIVCT(232); MKIVCT(233); MKIVCT(234); MKIVCT(235);
314 MKIVCT(236); MKIVCT(237); MKIVCT(238); MKIVCT(239);
315 MKIVCT(240); MKIVCT(241); MKIVCT(242); MKIVCT(243);
316 MKIVCT(244); MKIVCT(245); MKIVCT(246); MKIVCT(247);
317 MKIVCT(248); MKIVCT(249); MKIVCT(250); MKIVCT(251);
318 MKIVCT(252); MKIVCT(253); MKIVCT(254); MKIVCT(255);
319
320 #if !defined(__xpv)
321 .section ".text"
322 .align MMU_PAGESIZE
323 .global kdi_isr_end
324 kdi_isr_end:
325 nop
326 #endif
327
328 #endif /* !__lint */
|