xref: /illumos-gate/usr/src/uts/intel/kdi/kdi_idthdl.S (revision e3ae4b35c024af1196582063ecee3ab79367227d)
1/*
2 * CDDL HEADER START
3 *
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 * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
27 */
28
29/*
30 * Companion to kdi_asm.s - the implementation of the trap and interrupt
31 * handlers.  For the most part, these handlers do the same thing - they
32 * push a trap number onto the stack, followed by a jump to kdi_cmnint.
33 * Each trap and interrupt has its own handler because each one pushes a
34 * different number.
35 */
36
37#include <sys/asm_linkage.h>
38#include <sys/asm_misc.h>
39#include <sys/machprivregs.h>
40#include <sys/privregs.h>
41#include <sys/kdi_regs.h>
42#include <sys/trap.h>
43#include <sys/param.h>
44
45#include <kdi_assym.h>
46#include <assym.h>
47
48/*
49 * The default ASM_ENTRY_ALIGN (16) wastes far too much space.
50 */
51#undef	ASM_ENTRY_ALIGN
52#define	ASM_ENTRY_ALIGN	8
53
54/*
55 * Generic trap and interrupt handlers.
56 */
57
58#if defined(__xpv)
59
60#define	INTERRUPT_TRAMPOLINE
61
62#else
63
64/*
65 * If we're !xpv, then we will need to support KPTI (kernel page table
66 * isolation), where we have separate page tables for user and kernel modes.
67 * There's more detail about this in kpti_trampolines.s and hat_i86.c
68 */
69
70#define	INTERRUPT_TRAMPOLINE			\
71	pushq	%r13;				\
72	pushq	%r14;				\
73	subq	$KPTI_R14, %rsp;		\
74	/* Check for clobbering */		\
75	cmpq	$0, KPTI_FLAG(%rsp);		\
76	je	1f;				\
77	/* Don't worry, this totally works */	\
78	int	$8;				\
791:						\
80	movq	$1, KPTI_FLAG(%rsp);		\
81	/* Save current %cr3. */		\
82	mov	%cr3, %r14;			\
83	mov	%r14, KPTI_TR_CR3(%rsp);	\
84	/* Switch to paranoid %cr3. */		\
85	mov	kpti_safe_cr3, %r14;		\
86	mov	%r14, %cr3;			\
87						\
88	cmpw	$KCS_SEL, KPTI_CS(%rsp);	\
89	je	3f;				\
902:						\
91	/* Get our cpu_t in %r13 */		\
92	mov	%rsp, %r13;			\
93	and	$(~(MMU_PAGESIZE - 1)), %r13;	\
94	subq	$CPU_KPTI_START, %r13;		\
95	/* Use top of the kthread stk */	\
96	mov	CPU_THREAD(%r13), %r14;		\
97	mov	T_STACK(%r14), %r14;		\
98	addq	$REGSIZE+MINFRAME, %r14;	\
99	jmp	5f;				\
1003:						\
101	/* Check the %rsp in the frame. */	\
102	/* Is it above kernel base? */		\
103	mov	kpti_kbase, %r14;		\
104	cmp	%r14, KPTI_RSP(%rsp);		\
105	jb	2b;				\
106	/* Is it within the kpti_frame page? */	\
107	mov	%rsp, %r13;			\
108	and	$(~(MMU_PAGESIZE - 1)), %r13;	\
109	mov	KPTI_RSP(%rsp), %r14;		\
110	and	$(~(MMU_PAGESIZE - 1)), %r14;	\
111	cmp	%r13, %r14;			\
112	je	2b;				\
113	/* Use the %rsp from the trap frame. */	\
114	/* We already did %cr3. */		\
115	mov	KPTI_RSP(%rsp), %r14;		\
116	and	$(~0xf), %r14;			\
1175:						\
118	mov	%rsp, %r13;			\
119	/* %r14 contains our destination stk */	\
120	mov	%r14, %rsp;			\
121	pushq	KPTI_SS(%r13);			\
122	pushq	KPTI_RSP(%r13);			\
123	pushq	KPTI_RFLAGS(%r13);		\
124	pushq	KPTI_CS(%r13);			\
125	pushq	KPTI_RIP(%r13);			\
126	pushq	KPTI_ERR(%r13);			\
127	mov	KPTI_R14(%r13), %r14;		\
128	movq	$0, KPTI_FLAG(%r13);		\
129	mov	KPTI_R13(%r13), %r13
130
131#endif	/* !__xpv */
132
133
134#define	MKIVCT(n) \
135	ENTRY_NP(kdi_ivct##n);		\
136	XPV_TRAP_POP;			\
137	push	$0; /* err */		\
138	INTERRUPT_TRAMPOLINE;		\
139	push	$n;			\
140	jmp	kdi_cmnint;		\
141	SET_SIZE(kdi_ivct##n)
142
143#define	MKTRAPHDLR(n) \
144	ENTRY_NP(kdi_trap##n);		\
145	XPV_TRAP_POP;			\
146	push	$0; /* err */		\
147	INTERRUPT_TRAMPOLINE;		\
148	push	$n;			\
149	jmp	kdi_cmnint;		\
150	SET_SIZE(kdi_trap##n)
151
152#define	MKTRAPERRHDLR(n) \
153	ENTRY_NP(kdi_traperr##n);	\
154	XPV_TRAP_POP;			\
155	INTERRUPT_TRAMPOLINE;		\
156	push	$n;			\
157	jmp	kdi_cmnint;		\
158	SET_SIZE(kdi_traperr##n)
159
160#if !defined(__xpv)
161#define	MKNMIHDLR \
162	ENTRY_NP(kdi_int2);		\
163	push	$0;			\
164	push	$2;			\
165	pushq	%r13;			\
166	mov	kpti_safe_cr3, %r13;	\
167	mov	%r13, %cr3;		\
168	popq	%r13;			\
169	jmp	kdi_nmiint;		\
170	SET_SIZE(kdi_int2)
171
172#define	MKMCEHDLR \
173	ENTRY_NP(kdi_trap18);		\
174	push	$0;			\
175	push	$18;			\
176	pushq	%r13;			\
177	mov	kpti_safe_cr3, %r13;	\
178	mov	%r13, %cr3;		\
179	popq	%r13;			\
180	jmp	kdi_cmnint;		\
181	SET_SIZE(kdi_trap18)
182#else
183#define	MKNMIHDLR \
184	ENTRY_NP(kdi_int2);		\
185	push	$0;			\
186	push	$2;			\
187	jmp	kdi_nmiint;		\
188	SET_SIZE(kdi_int2)
189
190#define	MKMCEHDLR \
191	ENTRY_NP(kdi_trap18);		\
192	push	$0;			\
193	push	$18;			\
194	jmp	kdi_cmnint;		\
195	SET_SIZE(kdi_trap18)
196#endif
197
198/*
199 * The only way we should reach here is by an explicit "int 0x.." which is
200 * defined not to push an error code.
201 */
202#define	MKINVALHDLR \
203	ENTRY_NP(kdi_invaltrap);	\
204	XPV_TRAP_POP;			\
205	push	$0; /* err */		\
206	INTERRUPT_TRAMPOLINE;		\
207	push	$255;			\
208	jmp	kdi_cmnint;		\
209	SET_SIZE(kdi_invaltrap)
210
211	.data
212	DGDEF3(kdi_idt, 16 * NIDT, MMU_PAGESIZE)
213	.fill	MMU_PAGESIZE, 1, 0
214
215#if !defined(__xpv)
216.section ".text"
217.align MMU_PAGESIZE
218.global kdi_isr_start
219kdi_isr_start:
220	nop
221
222.global kpti_safe_cr3
223.global kpti_kbase
224#endif
225
226/*
227 * The handlers themselves
228 */
229
230	MKINVALHDLR
231	MKTRAPHDLR(0)
232	MKTRAPHDLR(1)
233	MKNMIHDLR/*2*/
234	MKTRAPHDLR(3)
235	MKTRAPHDLR(4)
236	MKTRAPHDLR(5)
237	MKTRAPHDLR(6)
238	MKTRAPHDLR(7)
239	MKTRAPHDLR(9)
240	MKTRAPHDLR(15)
241	MKTRAPHDLR(16)
242	MKMCEHDLR/*18*/
243	MKTRAPHDLR(19)
244	MKTRAPHDLR(20)
245
246	MKTRAPERRHDLR(8)
247	MKTRAPERRHDLR(10)
248	MKTRAPERRHDLR(11)
249	MKTRAPERRHDLR(12)
250	MKTRAPERRHDLR(13)
251	MKTRAPERRHDLR(14)
252	MKTRAPERRHDLR(17)
253
254	.globl	kdi_ivct_size
255kdi_ivct_size:
256	.NWORD [kdi_ivct33-kdi_ivct32]
257
258	/* 10 billion and one interrupt handlers */
259kdi_ivct_base:
260	MKIVCT(32);	MKIVCT(33);	MKIVCT(34);	MKIVCT(35);
261	MKIVCT(36);	MKIVCT(37);	MKIVCT(38);	MKIVCT(39);
262	MKIVCT(40);	MKIVCT(41);	MKIVCT(42);	MKIVCT(43);
263	MKIVCT(44);	MKIVCT(45);	MKIVCT(46);	MKIVCT(47);
264	MKIVCT(48);	MKIVCT(49);	MKIVCT(50);	MKIVCT(51);
265	MKIVCT(52);	MKIVCT(53);	MKIVCT(54);	MKIVCT(55);
266	MKIVCT(56);	MKIVCT(57);	MKIVCT(58);	MKIVCT(59);
267	MKIVCT(60);	MKIVCT(61);	MKIVCT(62);	MKIVCT(63);
268	MKIVCT(64);	MKIVCT(65);	MKIVCT(66);	MKIVCT(67);
269	MKIVCT(68);	MKIVCT(69);	MKIVCT(70);	MKIVCT(71);
270	MKIVCT(72);	MKIVCT(73);	MKIVCT(74);	MKIVCT(75);
271	MKIVCT(76);	MKIVCT(77);	MKIVCT(78);	MKIVCT(79);
272	MKIVCT(80);	MKIVCT(81);	MKIVCT(82);	MKIVCT(83);
273	MKIVCT(84);	MKIVCT(85);	MKIVCT(86);	MKIVCT(87);
274	MKIVCT(88);	MKIVCT(89);	MKIVCT(90);	MKIVCT(91);
275	MKIVCT(92);	MKIVCT(93);	MKIVCT(94);	MKIVCT(95);
276	MKIVCT(96);	MKIVCT(97);	MKIVCT(98);	MKIVCT(99);
277	MKIVCT(100);	MKIVCT(101);	MKIVCT(102);	MKIVCT(103);
278	MKIVCT(104);	MKIVCT(105);	MKIVCT(106);	MKIVCT(107);
279	MKIVCT(108);	MKIVCT(109);	MKIVCT(110);	MKIVCT(111);
280	MKIVCT(112);	MKIVCT(113);	MKIVCT(114);	MKIVCT(115);
281	MKIVCT(116);	MKIVCT(117);	MKIVCT(118);	MKIVCT(119);
282	MKIVCT(120);	MKIVCT(121);	MKIVCT(122);	MKIVCT(123);
283	MKIVCT(124);	MKIVCT(125);	MKIVCT(126);	MKIVCT(127);
284	MKIVCT(128);	MKIVCT(129);	MKIVCT(130);	MKIVCT(131);
285	MKIVCT(132);	MKIVCT(133);	MKIVCT(134);	MKIVCT(135);
286	MKIVCT(136);	MKIVCT(137);	MKIVCT(138);	MKIVCT(139);
287	MKIVCT(140);	MKIVCT(141);	MKIVCT(142);	MKIVCT(143);
288	MKIVCT(144);	MKIVCT(145);	MKIVCT(146);	MKIVCT(147);
289	MKIVCT(148);	MKIVCT(149);	MKIVCT(150);	MKIVCT(151);
290	MKIVCT(152);	MKIVCT(153);	MKIVCT(154);	MKIVCT(155);
291	MKIVCT(156);	MKIVCT(157);	MKIVCT(158);	MKIVCT(159);
292	MKIVCT(160);	MKIVCT(161);	MKIVCT(162);	MKIVCT(163);
293	MKIVCT(164);	MKIVCT(165);	MKIVCT(166);	MKIVCT(167);
294	MKIVCT(168);	MKIVCT(169);	MKIVCT(170);	MKIVCT(171);
295	MKIVCT(172);	MKIVCT(173);	MKIVCT(174);	MKIVCT(175);
296	MKIVCT(176);	MKIVCT(177);	MKIVCT(178);	MKIVCT(179);
297	MKIVCT(180);	MKIVCT(181);	MKIVCT(182);	MKIVCT(183);
298	MKIVCT(184);	MKIVCT(185);	MKIVCT(186);	MKIVCT(187);
299	MKIVCT(188);	MKIVCT(189);	MKIVCT(190);	MKIVCT(191);
300	MKIVCT(192);	MKIVCT(193);	MKIVCT(194);	MKIVCT(195);
301	MKIVCT(196);	MKIVCT(197);	MKIVCT(198);	MKIVCT(199);
302	MKIVCT(200);	MKIVCT(201);	MKIVCT(202);	MKIVCT(203);
303	MKIVCT(204);	MKIVCT(205);	MKIVCT(206);	MKIVCT(207);
304	MKIVCT(208);	MKIVCT(209);	MKIVCT(210);	MKIVCT(211);
305	MKIVCT(212);	MKIVCT(213);	MKIVCT(214);	MKIVCT(215);
306	MKIVCT(216);	MKIVCT(217);	MKIVCT(218);	MKIVCT(219);
307	MKIVCT(220);	MKIVCT(221);	MKIVCT(222);	MKIVCT(223);
308	MKIVCT(224);	MKIVCT(225);	MKIVCT(226);	MKIVCT(227);
309	MKIVCT(228);	MKIVCT(229);	MKIVCT(230);	MKIVCT(231);
310	MKIVCT(232);	MKIVCT(233);	MKIVCT(234);	MKIVCT(235);
311	MKIVCT(236);	MKIVCT(237);	MKIVCT(238);	MKIVCT(239);
312	MKIVCT(240);	MKIVCT(241);	MKIVCT(242);	MKIVCT(243);
313	MKIVCT(244);	MKIVCT(245);	MKIVCT(246);	MKIVCT(247);
314	MKIVCT(248);	MKIVCT(249);	MKIVCT(250);	MKIVCT(251);
315	MKIVCT(252);	MKIVCT(253);	MKIVCT(254);	MKIVCT(255);
316
317#if !defined(__xpv)
318.section ".text"
319.align MMU_PAGESIZE
320.global kdi_isr_end
321kdi_isr_end:
322	nop
323#endif
324