xref: /titanic_41/usr/src/uts/intel/ia32/os/desctbls.c (revision 70025d765b044c6d8594bb965a2247a61e991a99)
1 /*
2  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 #pragma ident	"%Z%%M%	%I%	%E% SMI"
7 
8 /*
9  * Copyright (c) 1992 Terrence R. Lambert.
10  * Copyright (c) 1990 The Regents of the University of California.
11  * All rights reserved.
12  *
13  * This code is derived from software contributed to Berkeley by
14  * William Jolitz.
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
19  * 1. Redistributions of source code must retain the above copyright
20  *    notice, this list of conditions and the following disclaimer.
21  * 2. Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the
23  *    documentation and/or other materials provided with the distribution.
24  * 3. All advertising materials mentioning features or use of this software
25  *    must display the following acknowledgement:
26  *	This product includes software developed by the University of
27  *	California, Berkeley and its contributors.
28  * 4. Neither the name of the University nor the names of its contributors
29  *    may be used to endorse or promote products derived from this software
30  *    without specific prior written permission.
31  *
32  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
33  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
36  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42  * SUCH DAMAGE.
43  *
44  *	from: @(#)machdep.c	7.4 (Berkeley) 6/3/91
45  */
46 
47 #include <sys/types.h>
48 #include <sys/tss.h>
49 #include <sys/segments.h>
50 #include <sys/trap.h>
51 #include <sys/cpuvar.h>
52 #include <sys/x86_archext.h>
53 #include <sys/archsystm.h>
54 #include <sys/machsystm.h>
55 #include <sys/kobj.h>
56 #include <sys/cmn_err.h>
57 #include <sys/reboot.h>
58 #include <sys/kdi.h>
59 
60 extern void syscall_int(void);
61 
62 /*
63  * cpu0 and default tables and structures.
64  */
65 #pragma	align	16(gdt0)
66 user_desc_t	gdt0[NGDT];		/* global descriptor table */
67 desctbr_t	gdt0_default_r;
68 
69 #pragma	align	16(ldt0_default)
70 user_desc_t	ldt0_default[MINNLDT];	/* default local descriptor table */
71 system_desc_t	ldt0_default_desc;	/* seg descriptor for ldt0_default */
72 
73 #if defined(__amd64)
74 #pragma align	16(ltd0_default64)
75 user_desc_t	ldt0_default64[MINNLDT]; /* default LDT for 64-bit apps */
76 system_desc_t	ldt0_default64_desc;	/* seg descriptor for ldt0_default64 */
77 #endif	/* __amd64 */
78 
79 #pragma	align	16(idt0)
80 gate_desc_t	idt0[NIDT]; 		/* interrupt descriptor table */
81 desctbr_t	idt0_default_r;		/* describes idt0 in IDTR format */
82 
83 #pragma align	16(ktss0)
84 struct tss	ktss0;			/* kernel task state structure */
85 
86 #if defined(__i386)
87 #pragma align	16(dftss0)
88 struct tss	dftss0;			/* #DF double-fault exception */
89 #endif	/* __i386 */
90 
91 user_desc_t	zero_udesc;		/* base zero user desc native procs */
92 
93 #if defined(__amd64)
94 user_desc_t	zero_u32desc;		/* 32-bit compatibility procs */
95 #endif	/* __amd64 */
96 
97 #pragma	align	16(dblfault_stack0)
98 char		dblfault_stack0[DEFAULTSTKSZ];
99 
100 extern void	fast_null(void);
101 extern hrtime_t	get_hrtime(void);
102 extern hrtime_t	gethrvtime(void);
103 extern hrtime_t	get_hrestime(void);
104 extern uint64_t	getlgrp(void);
105 
106 void (*(fasttable[]))(void) = {
107 	fast_null,			/* T_FNULL routine */
108 	fast_null,			/* T_FGETFP routine (initially null) */
109 	fast_null,			/* T_FSETFP routine (initially null) */
110 	(void (*)())get_hrtime,		/* T_GETHRTIME */
111 	(void (*)())gethrvtime,		/* T_GETHRVTIME */
112 	(void (*)())get_hrestime,	/* T_GETHRESTIME */
113 	(void (*)())getlgrp		/* T_GETLGRP */
114 };
115 
116 /*
117  * software prototypes for default local descriptor table
118  */
119 
120 /*
121  * Routines for loading segment descriptors in format the hardware
122  * can understand.
123  */
124 
125 #if defined(__amd64)
126 
127 /*
128  * In long mode we have the new L or long mode attribute bit
129  * for code segments. Only the conforming bit in type is used along
130  * with descriptor priority and present bits. Default operand size must
131  * be zero when in long mode. In 32-bit compatibility mode all fields
132  * are treated as in legacy mode. For data segments while in long mode
133  * only the present bit is loaded.
134  */
135 void
136 set_usegd(user_desc_t *dp, uint_t lmode, void *base, size_t size,
137     uint_t type, uint_t dpl, uint_t gran, uint_t defopsz)
138 {
139 	ASSERT(lmode == SDP_SHORT || lmode == SDP_LONG);
140 
141 	/*
142 	 * 64-bit long mode.
143 	 */
144 	if (lmode == SDP_LONG)
145 		dp->usd_def32 = 0;		/* 32-bit operands only */
146 	else
147 		/*
148 		 * 32-bit compatibility mode.
149 		 */
150 		dp->usd_def32 = defopsz;	/* 0 = 16, 1 = 32-bit ops */
151 
152 	dp->usd_long = lmode;	/* 64-bit mode */
153 	dp->usd_type = type;
154 	dp->usd_dpl = dpl;
155 	dp->usd_p = 1;
156 	dp->usd_gran = gran;		/* 0 = bytes, 1 = pages */
157 
158 	dp->usd_lobase = (uintptr_t)base;
159 	dp->usd_midbase = (uintptr_t)base >> 16;
160 	dp->usd_hibase = (uintptr_t)base >> (16 + 8);
161 	dp->usd_lolimit = size;
162 	dp->usd_hilimit = (uintptr_t)size >> 16;
163 }
164 
165 #elif defined(__i386)
166 
167 /*
168  * Install user segment descriptor for code and data.
169  */
170 void
171 set_usegd(user_desc_t *dp, void *base, size_t size, uint_t type,
172     uint_t dpl, uint_t gran, uint_t defopsz)
173 {
174 	dp->usd_lolimit = size;
175 	dp->usd_hilimit = (uintptr_t)size >> 16;
176 
177 	dp->usd_lobase = (uintptr_t)base;
178 	dp->usd_midbase = (uintptr_t)base >> 16;
179 	dp->usd_hibase = (uintptr_t)base >> (16 + 8);
180 
181 	dp->usd_type = type;
182 	dp->usd_dpl = dpl;
183 	dp->usd_p = 1;
184 	dp->usd_def32 = defopsz;	/* 0 = 16, 1 = 32 bit operands */
185 	dp->usd_gran = gran;		/* 0 = bytes, 1 = pages */
186 }
187 
188 #endif	/* __i386 */
189 
190 /*
191  * Install system segment descriptor for LDT and TSS segments.
192  */
193 
194 #if defined(__amd64)
195 
196 void
197 set_syssegd(system_desc_t *dp, void *base, size_t size, uint_t type,
198     uint_t dpl)
199 {
200 	dp->ssd_lolimit = size;
201 	dp->ssd_hilimit = (uintptr_t)size >> 16;
202 
203 	dp->ssd_lobase = (uintptr_t)base;
204 	dp->ssd_midbase = (uintptr_t)base >> 16;
205 	dp->ssd_hibase = (uintptr_t)base >> (16 + 8);
206 	dp->ssd_hi64base = (uintptr_t)base >> (16 + 8 + 8);
207 
208 	dp->ssd_type = type;
209 	dp->ssd_zero1 = 0;	/* must be zero */
210 	dp->ssd_zero2 = 0;
211 	dp->ssd_dpl = dpl;
212 	dp->ssd_p = 1;
213 	dp->ssd_gran = 0;	/* force byte units */
214 }
215 
216 #elif defined(__i386)
217 
218 void
219 set_syssegd(system_desc_t *dp, void *base, size_t size, uint_t type,
220     uint_t dpl)
221 {
222 	dp->ssd_lolimit = size;
223 	dp->ssd_hilimit = (uintptr_t)size >> 16;
224 
225 	dp->ssd_lobase = (uintptr_t)base;
226 	dp->ssd_midbase = (uintptr_t)base >> 16;
227 	dp->ssd_hibase = (uintptr_t)base >> (16 + 8);
228 
229 	dp->ssd_type = type;
230 	dp->ssd_zero = 0;	/* must be zero */
231 	dp->ssd_dpl = dpl;
232 	dp->ssd_p = 1;
233 	dp->ssd_gran = 0;	/* force byte units */
234 }
235 
236 #endif	/* __i386 */
237 
238 /*
239  * Install gate segment descriptor for interrupt, trap, call and task gates.
240  */
241 
242 #if defined(__amd64)
243 
244 /*
245  * Note stkcpy is replaced with ist. Read the PRM for details on this.
246  */
247 void
248 set_gatesegd(gate_desc_t *dp, void (*func)(void), selector_t sel, uint_t ist,
249     uint_t type, uint_t dpl)
250 {
251 	dp->sgd_looffset = (uintptr_t)func;
252 	dp->sgd_hioffset = (uintptr_t)func >> 16;
253 	dp->sgd_hi64offset = (uintptr_t)func >> (16 + 16);
254 
255 	dp->sgd_selector =  (uint16_t)sel;
256 	dp->sgd_ist = ist;
257 	dp->sgd_type = type;
258 	dp->sgd_dpl = dpl;
259 	dp->sgd_p = 1;
260 }
261 
262 #elif defined(__i386)
263 
264 void
265 set_gatesegd(gate_desc_t *dp, void (*func)(void), selector_t sel,
266     uint_t wcount, uint_t type, uint_t dpl)
267 {
268 	dp->sgd_looffset = (uintptr_t)func;
269 	dp->sgd_hioffset = (uintptr_t)func >> 16;
270 
271 	dp->sgd_selector =  (uint16_t)sel;
272 	dp->sgd_stkcpy = wcount;
273 	dp->sgd_type = type;
274 	dp->sgd_dpl = dpl;
275 	dp->sgd_p = 1;
276 }
277 
278 #endif /* __i386 */
279 
280 /*
281  * Build kernel GDT.
282  */
283 
284 #if defined(__amd64)
285 
286 static void
287 init_gdt(void)
288 {
289 	desctbr_t	r_bgdt, r_gdt;
290 	user_desc_t	*bgdt;
291 	size_t		alen = 0xfffff;	/* entire 32-bit address space */
292 
293 	/*
294 	 * Copy in from boot's gdt to our gdt entries 1 - 4.
295 	 * Entry 0 is the null descriptor by definition.
296 	 */
297 	rd_gdtr(&r_bgdt);
298 	bgdt = (user_desc_t *)r_bgdt.dtr_base;
299 	if (bgdt == NULL)
300 		panic("null boot gdt");
301 
302 	gdt0[GDT_B32DATA] = bgdt[GDT_B32DATA];
303 	gdt0[GDT_B32CODE] = bgdt[GDT_B32CODE];
304 	gdt0[GDT_B64DATA] = bgdt[GDT_B64DATA];
305 	gdt0[GDT_B64CODE] = bgdt[GDT_B64CODE];
306 
307 	/*
308 	 * 64-bit kernel code segment.
309 	 */
310 	set_usegd(&gdt0[GDT_KCODE], SDP_LONG, NULL, 0, SDT_MEMERA, SEL_KPL,
311 	    SDP_PAGES, SDP_OP32);
312 
313 	/*
314 	 * 64-bit kernel data segment. The limit attribute is ignored in 64-bit
315 	 * mode, but we set it here to 0xFFFF so that we can use the SYSRET
316 	 * instruction to return from system calls back to 32-bit applications.
317 	 * SYSRET doesn't update the base, limit, or attributes of %ss or %ds
318 	 * descriptors. We therefore must ensure that the kernel uses something,
319 	 * though it will be ignored by hardware, that is compatible with 32-bit
320 	 * apps. For the same reason we must set the default op size of this
321 	 * descriptor to 32-bit operands.
322 	 */
323 	set_usegd(&gdt0[GDT_KDATA], SDP_LONG, NULL, alen, SDT_MEMRWA,
324 	    SEL_KPL, SDP_PAGES, SDP_OP32);
325 	gdt0[GDT_KDATA].usd_def32 = 1;
326 
327 	/*
328 	 * 64-bit user code segment.
329 	 */
330 	set_usegd(&gdt0[GDT_UCODE], SDP_LONG, NULL, 0, SDT_MEMERA, SEL_UPL,
331 	    SDP_PAGES, SDP_OP32);
332 
333 	/*
334 	 * 32-bit user code segment.
335 	 */
336 	set_usegd(&gdt0[GDT_U32CODE], SDP_SHORT, NULL, alen, SDT_MEMERA,
337 	    SEL_UPL, SDP_PAGES, SDP_OP32);
338 
339 	/*
340 	 * 32 and 64 bit data segments can actually share the same descriptor.
341 	 * In long mode only the present bit is checked but all other fields
342 	 * are loaded. But in compatibility mode all fields are interpreted
343 	 * as in legacy mode so they must be set correctly for a 32-bit data
344 	 * segment.
345 	 */
346 	set_usegd(&gdt0[GDT_UDATA], SDP_SHORT, NULL, alen, SDT_MEMRWA, SEL_UPL,
347 	    SDP_PAGES, SDP_OP32);
348 
349 	/*
350 	 * LDT descriptor for 64-bit processes
351 	 */
352 	set_syssegd((system_desc_t *)&gdt0[GDT_LDT], ldt0_default64,
353 	    sizeof (ldt0_default64) - 1, SDT_SYSLDT, SEL_KPL);
354 	ldt0_default64_desc = *((system_desc_t *)&gdt0[GDT_LDT]);
355 
356 	/*
357 	 * LDT descriptor for 32-bit processes
358 	 */
359 	set_syssegd((system_desc_t *)&gdt0[GDT_LDT], ldt0_default,
360 	    sizeof (ldt0_default) - 1, SDT_SYSLDT, SEL_KPL);
361 	ldt0_default_desc = *((system_desc_t *)&gdt0[GDT_LDT]);
362 
363 	/*
364 	 * Kernel TSS
365 	 */
366 	set_syssegd((system_desc_t *)&gdt0[GDT_KTSS], &ktss0,
367 	    sizeof (ktss0) - 1, SDT_SYSTSS, SEL_KPL);
368 
369 	/*
370 	 * Initialize fs and gs descriptors for 32 bit processes.
371 	 * Only attributes and limits are initialized, the effective
372 	 * base address is programmed via fsbase/gsbase.
373 	 */
374 	set_usegd(&gdt0[GDT_LWPFS], SDP_SHORT, NULL, alen, SDT_MEMRWA,
375 	    SEL_UPL, SDP_PAGES, SDP_OP32);
376 	set_usegd(&gdt0[GDT_LWPGS], SDP_SHORT, NULL, alen, SDT_MEMRWA,
377 	    SEL_UPL, SDP_PAGES, SDP_OP32);
378 
379 	/*
380 	 * Install our new GDT
381 	 */
382 	r_gdt.dtr_limit = sizeof (gdt0) - 1;
383 	r_gdt.dtr_base = (uintptr_t)gdt0;
384 	wr_gdtr(&r_gdt);
385 
386 	/*
387 	 * Initialize convenient zero base user descriptors for clearing
388 	 * lwp private %fs and %gs descriptors in GDT. See setregs() for
389 	 * an example.
390 	 */
391 	set_usegd(&zero_udesc, SDP_LONG, 0, 0, SDT_MEMRWA, SEL_UPL,
392 	    SDP_BYTES, SDP_OP32);
393 	set_usegd(&zero_u32desc, SDP_SHORT, 0, -1, SDT_MEMRWA, SEL_UPL,
394 	    SDP_PAGES, SDP_OP32);
395 }
396 
397 #elif defined(__i386)
398 
399 static void
400 init_gdt(void)
401 {
402 	desctbr_t	r_bgdt, r_gdt;
403 	user_desc_t	*bgdt;
404 
405 	/*
406 	 * Copy in from boot's gdt to our gdt entries 1 - 4.
407 	 * Entry 0 is null descriptor by definition.
408 	 */
409 	rd_gdtr(&r_bgdt);
410 	bgdt = (user_desc_t *)r_bgdt.dtr_base;
411 	if (bgdt == NULL)
412 		panic("null boot gdt");
413 
414 	gdt0[GDT_BOOTFLAT] = bgdt[GDT_BOOTFLAT];
415 	gdt0[GDT_BOOTCODE] = bgdt[GDT_BOOTCODE];
416 	gdt0[GDT_BOOTCODE16] = bgdt[GDT_BOOTCODE16];
417 	gdt0[GDT_BOOTDATA] = bgdt[GDT_BOOTDATA];
418 
419 	/*
420 	 * Text and data for both kernel and user span entire 32 bit
421 	 * address space.
422 	 */
423 
424 	/*
425 	 * kernel code segment.
426 	 */
427 	set_usegd(&gdt0[GDT_KCODE], NULL, -1, SDT_MEMERA, SEL_KPL, SDP_PAGES,
428 	    SDP_OP32);
429 
430 	/*
431 	 * kernel data segment.
432 	 */
433 	set_usegd(&gdt0[GDT_KDATA], NULL, -1, SDT_MEMRWA, SEL_KPL, SDP_PAGES,
434 	    SDP_OP32);
435 
436 	/*
437 	 * user code segment.
438 	 */
439 	set_usegd(&gdt0[GDT_UCODE], NULL, -1, SDT_MEMERA, SEL_UPL, SDP_PAGES,
440 	    SDP_OP32);
441 
442 	/*
443 	 * user data segment.
444 	 */
445 	set_usegd(&gdt0[GDT_UDATA], NULL, -1, SDT_MEMRWA, SEL_UPL, SDP_PAGES,
446 	    SDP_OP32);
447 
448 	/*
449 	 * LDT for current process
450 	 */
451 	set_syssegd((system_desc_t *)&gdt0[GDT_LDT], ldt0_default,
452 	    sizeof (ldt0_default) - 1, SDT_SYSLDT, SEL_KPL);
453 
454 	ldt0_default_desc = *((system_desc_t *)&gdt0[GDT_LDT]);
455 
456 	/*
457 	 * TSS for T_DBLFLT (double fault) handler
458 	 */
459 	set_syssegd((system_desc_t *)&gdt0[GDT_DBFLT], &dftss0,
460 	    sizeof (dftss0) - 1, SDT_SYSTSS, SEL_KPL);
461 
462 	/*
463 	 * TSS for kernel
464 	 */
465 	set_syssegd((system_desc_t *)&gdt0[GDT_KTSS], &ktss0,
466 	    sizeof (ktss0) - 1, SDT_SYSTSS, SEL_KPL);
467 
468 	/*
469 	 * %gs selector for kernel
470 	 */
471 	set_usegd(&gdt0[GDT_GS], &cpus[0], sizeof (struct cpu) -1, SDT_MEMRWA,
472 	    SEL_KPL, SDP_BYTES, SDP_OP32);
473 
474 	/*
475 	 * Initialize lwp private descriptors.
476 	 * Only attributes and limits are initialized, the effective
477 	 * base address is programmed via fsbase/gsbase.
478 	 */
479 	set_usegd(&gdt0[GDT_LWPFS], NULL, (size_t)-1, SDT_MEMRWA, SEL_UPL,
480 	    SDP_PAGES, SDP_OP32);
481 	set_usegd(&gdt0[GDT_LWPGS], NULL, (size_t)-1, SDT_MEMRWA, SEL_UPL,
482 	    SDP_PAGES, SDP_OP32);
483 
484 	/*
485 	 * Install our new GDT
486 	 */
487 	r_gdt.dtr_limit = sizeof (gdt0) - 1;
488 	r_gdt.dtr_base = (uintptr_t)gdt0;
489 	wr_gdtr(&r_gdt);
490 
491 	/*
492 	 * Initialize convenient zero base user descriptors for clearing
493 	 * lwp private %fs and %gs descriptors in GDT. See setregs() for
494 	 * an example.
495 	 */
496 	set_usegd(&zero_udesc, 0, -1, SDT_MEMRWA, SEL_UPL, SDP_PAGES, SDP_OP32);
497 }
498 
499 #endif	/* __i386 */
500 
501 #if defined(__amd64)
502 
503 /*
504  * Build kernel IDT.
505  *
506  * Note that we pretty much require every gate to be an interrupt gate;
507  * that's because of our dependency on using 'swapgs' every time we come
508  * into the kernel to find the cpu structure - if we get interrupted just
509  * before doing that, so that %cs is in kernel mode (so that the trap prolog
510  * doesn't do a swapgs), but %gsbase is really still pointing at something
511  * in userland, bad things ensue.
512  *
513  * Perhaps they should have invented a trap gate that does an atomic swapgs?
514  *
515  * XX64	We do need to think further about the follow-on impact of this.
516  *	Most of the kernel handlers re-enable interrupts as soon as they've
517  *	saved register state and done the swapgs, but there may be something
518  *	more subtle going on.
519  */
520 static void
521 init_idt(void)
522 {
523 	char	ivctname[80];
524 	void	(*ivctptr)(void);
525 	int	i;
526 
527 	/*
528 	 * Initialize entire table with 'reserved' trap and then overwrite
529 	 * specific entries. T_EXTOVRFLT (9) is unsupported and reserved
530 	 * since it can only be generated on a 386 processor. 15 is also
531 	 * unsupported and reserved.
532 	 */
533 	for (i = 0; i < NIDT; i++)
534 		set_gatesegd(&idt0[i], &resvtrap, KCS_SEL, 0, SDT_SYSIGT,
535 		    SEL_KPL);
536 
537 	set_gatesegd(&idt0[T_ZERODIV], &div0trap, KCS_SEL, 0, SDT_SYSIGT,
538 	    SEL_KPL);
539 	set_gatesegd(&idt0[T_SGLSTP], &dbgtrap, KCS_SEL, 0, SDT_SYSIGT,
540 	    SEL_KPL);
541 	set_gatesegd(&idt0[T_NMIFLT], &nmiint, KCS_SEL, 0, SDT_SYSIGT,
542 	    SEL_KPL);
543 	set_gatesegd(&idt0[T_BPTFLT], &brktrap, KCS_SEL, 0, SDT_SYSIGT,
544 	    SEL_UPL);
545 	set_gatesegd(&idt0[T_OVFLW], &ovflotrap, KCS_SEL, 0, SDT_SYSIGT,
546 	    SEL_UPL);
547 	set_gatesegd(&idt0[T_BOUNDFLT], &boundstrap, KCS_SEL, 0, SDT_SYSIGT,
548 	    SEL_KPL);
549 	set_gatesegd(&idt0[T_ILLINST], &invoptrap, KCS_SEL, 0, SDT_SYSIGT,
550 	    SEL_KPL);
551 	set_gatesegd(&idt0[T_NOEXTFLT], &ndptrap,  KCS_SEL, 0, SDT_SYSIGT,
552 	    SEL_KPL);
553 
554 	/*
555 	 * double fault handler.
556 	 */
557 	set_gatesegd(&idt0[T_DBLFLT], &syserrtrap, KCS_SEL, 1, SDT_SYSIGT,
558 	    SEL_KPL);
559 
560 	/*
561 	 * T_EXTOVRFLT coprocessor-segment-overrun not supported.
562 	 */
563 
564 	set_gatesegd(&idt0[T_TSSFLT], &invtsstrap, KCS_SEL, 0, SDT_SYSIGT,
565 	    SEL_KPL);
566 	set_gatesegd(&idt0[T_SEGFLT], &segnptrap, KCS_SEL, 0, SDT_SYSIGT,
567 	    SEL_KPL);
568 	set_gatesegd(&idt0[T_STKFLT], &stktrap, KCS_SEL, 0, SDT_SYSIGT,
569 	    SEL_KPL);
570 	set_gatesegd(&idt0[T_GPFLT], &gptrap, KCS_SEL, 0, SDT_SYSIGT,
571 	    SEL_KPL);
572 	set_gatesegd(&idt0[T_PGFLT], &pftrap, KCS_SEL, 0, SDT_SYSIGT,
573 	    SEL_KPL);
574 
575 	/*
576 	 * 15 reserved.
577 	 */
578 	set_gatesegd(&idt0[15], &resvtrap, KCS_SEL, 0, SDT_SYSIGT, SEL_KPL);
579 
580 	set_gatesegd(&idt0[T_EXTERRFLT], &ndperr, KCS_SEL, 0, SDT_SYSIGT,
581 	    SEL_KPL);
582 	set_gatesegd(&idt0[T_ALIGNMENT], &achktrap, KCS_SEL, 0, SDT_SYSIGT,
583 	    SEL_KPL);
584 	set_gatesegd(&idt0[T_MCE], &mcetrap, KCS_SEL, 0, SDT_SYSIGT,
585 	    SEL_KPL);
586 	set_gatesegd(&idt0[T_SIMDFPE], &xmtrap, KCS_SEL, 0, SDT_SYSIGT,
587 	    SEL_KPL);
588 
589 	/*
590 	 * 20-31 reserved
591 	 */
592 	for (i = 20; i < 32; i++)
593 		set_gatesegd(&idt0[i], &invaltrap, KCS_SEL, 0, SDT_SYSIGT,
594 		    SEL_KPL);
595 
596 	/*
597 	 * interrupts 32 - 255
598 	 */
599 	for (i = 32; i < 256; i++) {
600 		(void) snprintf(ivctname, sizeof (ivctname), "ivct%d", i);
601 		ivctptr = (void (*)(void))kobj_getsymvalue(ivctname, 0);
602 		if (ivctptr == NULL)
603 			panic("kobj_getsymvalue(%s) failed", ivctname);
604 
605 		set_gatesegd(&idt0[i], ivctptr, KCS_SEL, 0, SDT_SYSIGT,
606 		    SEL_KPL);
607 	}
608 
609 	/*
610 	 * install fast trap handler at 210.
611 	 */
612 	set_gatesegd(&idt0[T_FASTTRAP], &fasttrap, KCS_SEL, 0,
613 	    SDT_SYSIGT, SEL_UPL);
614 
615 	/*
616 	 * System call handler.
617 	 */
618 	set_gatesegd(&idt0[T_SYSCALLINT], &sys_syscall_int, KCS_SEL, 0,
619 	    SDT_SYSIGT, SEL_UPL);
620 
621 	/*
622 	 * Install the DTrace interrupt handlers for the fasttrap provider.
623 	 */
624 	set_gatesegd(&idt0[T_DTRACE_PROBE], &dtrace_fasttrap, KCS_SEL, 0,
625 	    SDT_SYSIGT, SEL_UPL);
626 	set_gatesegd(&idt0[T_DTRACE_RET], &dtrace_ret, KCS_SEL, 0,
627 	    SDT_SYSIGT, SEL_UPL);
628 
629 	if (boothowto & RB_DEBUG)
630 		kdi_dvec_idt_sync(idt0);
631 
632 	/*
633 	 * We must maintain a description of idt0 in convenient IDTR format
634 	 * for use by T_NMIFLT and T_PGFLT (nmiint() and pentium_pftrap())
635 	 * handlers.
636 	 */
637 	idt0_default_r.dtr_limit = sizeof (idt0) - 1;
638 	idt0_default_r.dtr_base = (uintptr_t)idt0;
639 	wr_idtr(&idt0_default_r);
640 }
641 
642 #elif defined(__i386)
643 
644 /*
645  * Build kernel IDT.
646  */
647 static void
648 init_idt(void)
649 {
650 	char	ivctname[80];
651 	void	(*ivctptr)(void);
652 	int	i;
653 
654 	/*
655 	 * Initialize entire table with 'reserved' trap and then overwrite
656 	 * specific entries. T_EXTOVRFLT (9) is unsupported and reserved
657 	 * since it can only be generated on a 386 processor. 15 is also
658 	 * unsupported and reserved.
659 	 */
660 	for (i = 0; i < NIDT; i++)
661 		set_gatesegd(&idt0[i], &resvtrap, KCS_SEL, 0, SDT_SYSTGT,
662 		    SEL_KPL);
663 
664 	set_gatesegd(&idt0[T_ZERODIV], &div0trap, KCS_SEL, 0, SDT_SYSTGT,
665 	    SEL_KPL);
666 	set_gatesegd(&idt0[T_SGLSTP], &dbgtrap, KCS_SEL, 0, SDT_SYSIGT,
667 	    SEL_KPL);
668 	set_gatesegd(&idt0[T_NMIFLT], &nmiint, KCS_SEL, 0, SDT_SYSIGT,
669 	    SEL_KPL);
670 	set_gatesegd(&idt0[T_BPTFLT], &brktrap, KCS_SEL, 0, SDT_SYSTGT,
671 	    SEL_UPL);
672 	set_gatesegd(&idt0[T_OVFLW], &ovflotrap, KCS_SEL, 0, SDT_SYSTGT,
673 	    SEL_UPL);
674 	set_gatesegd(&idt0[T_BOUNDFLT], &boundstrap, KCS_SEL, 0, SDT_SYSTGT,
675 	    SEL_KPL);
676 	set_gatesegd(&idt0[T_ILLINST], &invoptrap, KCS_SEL, 0, SDT_SYSIGT,
677 	    SEL_KPL);
678 	set_gatesegd(&idt0[T_NOEXTFLT], &ndptrap,  KCS_SEL, 0, SDT_SYSIGT,
679 	    SEL_KPL);
680 
681 	/*
682 	 * Install TSS for T_DBLFLT handler.
683 	 */
684 	set_gatesegd(&idt0[T_DBLFLT], NULL, DFTSS_SEL, 0, SDT_SYSTASKGT,
685 	    SEL_KPL);
686 
687 	/*
688 	 * T_EXTOVRFLT coprocessor-segment-overrun not supported.
689 	 */
690 
691 	set_gatesegd(&idt0[T_TSSFLT], &invtsstrap, KCS_SEL, 0, SDT_SYSTGT,
692 	    SEL_KPL);
693 	set_gatesegd(&idt0[T_SEGFLT], &segnptrap, KCS_SEL, 0, SDT_SYSTGT,
694 	    SEL_KPL);
695 	set_gatesegd(&idt0[T_STKFLT], &stktrap, KCS_SEL, 0, SDT_SYSTGT,
696 	    SEL_KPL);
697 	set_gatesegd(&idt0[T_GPFLT], &gptrap, KCS_SEL, 0, SDT_SYSTGT,
698 	    SEL_KPL);
699 	set_gatesegd(&idt0[T_PGFLT], &pftrap, KCS_SEL, 0, SDT_SYSIGT,
700 	    SEL_KPL);
701 
702 	/*
703 	 * 15 reserved.
704 	 */
705 	set_gatesegd(&idt0[15], &resvtrap, KCS_SEL, 0, SDT_SYSTGT, SEL_KPL);
706 
707 	set_gatesegd(&idt0[T_EXTERRFLT], &ndperr, KCS_SEL, 0, SDT_SYSIGT,
708 	    SEL_KPL);
709 	set_gatesegd(&idt0[T_ALIGNMENT], &achktrap, KCS_SEL, 0, SDT_SYSTGT,
710 	    SEL_KPL);
711 	set_gatesegd(&idt0[T_MCE], &mcetrap, KCS_SEL, 0, SDT_SYSIGT,
712 	    SEL_KPL);
713 	set_gatesegd(&idt0[T_SIMDFPE], &xmtrap, KCS_SEL, 0, SDT_SYSTGT,
714 	    SEL_KPL);
715 
716 	/*
717 	 * 20-31 reserved
718 	 */
719 	for (i = 20; i < 32; i++)
720 		set_gatesegd(&idt0[i], &invaltrap, KCS_SEL, 0, SDT_SYSTGT,
721 		    SEL_KPL);
722 
723 	/*
724 	 * interrupts 32 - 255
725 	 */
726 	for (i = 32; i < 256; i++) {
727 		(void) snprintf(ivctname, sizeof (ivctname), "ivct%d", i);
728 		ivctptr = (void (*)(void))kobj_getsymvalue(ivctname, 0);
729 		if (ivctptr == NULL)
730 			panic("kobj_getsymvalue(%s) failed", ivctname);
731 
732 		set_gatesegd(&idt0[i], ivctptr, KCS_SEL, 0, SDT_SYSIGT,
733 		    SEL_KPL);
734 	}
735 
736 	/*
737 	 * install fast trap handler at 210.
738 	 */
739 	set_gatesegd(&idt0[T_FASTTRAP], &fasttrap, KCS_SEL, 0,
740 	    SDT_SYSIGT, SEL_UPL);
741 
742 	/*
743 	 * System call handler. Note that we don't use the hardware's parameter
744 	 * copying mechanism here; see the comment above sys_call() for details.
745 	 */
746 	set_gatesegd(&idt0[T_SYSCALLINT], &sys_call, KCS_SEL, 0,
747 	    SDT_SYSIGT, SEL_UPL);
748 
749 	/*
750 	 * Install the DTrace interrupt handlers for the fasttrap provider.
751 	 */
752 	set_gatesegd(&idt0[T_DTRACE_PROBE], &dtrace_fasttrap, KCS_SEL, 0,
753 	    SDT_SYSIGT, SEL_UPL);
754 	set_gatesegd(&idt0[T_DTRACE_RET], &dtrace_ret, KCS_SEL, 0,
755 	    SDT_SYSIGT, SEL_UPL);
756 
757 	if (boothowto & RB_DEBUG)
758 		kdi_dvec_idt_sync(idt0);
759 
760 	/*
761 	 * We must maintain a description of idt0 in convenient IDTR format
762 	 * for use by T_NMIFLT and T_PGFLT (nmiint() and pentium_pftrap())
763 	 * handlers.
764 	 */
765 	idt0_default_r.dtr_limit = sizeof (idt0) - 1;
766 	idt0_default_r.dtr_base = (uintptr_t)idt0;
767 	wr_idtr(&idt0_default_r);
768 }
769 
770 #endif	/* __i386 */
771 
772 #if defined(__amd64)
773 
774 static void
775 init_ldt(void)
776 {
777 	/*
778 	 * System calls using call gates from libc.a and libc.so.1
779 	 * must cause a #NP fault and be processed in trap().
780 	 * Therefore clear the "present" bit in the gate descriptor.
781 	 */
782 
783 	/*
784 	 * call gate for libc.a (obsolete)
785 	 */
786 	set_gatesegd((gate_desc_t *)&ldt0_default[LDT_SYSCALL],
787 	    (void (*)(void))&sys_lcall32, KCS_SEL, 1, SDT_SYSCGT, SEL_UPL);
788 	((gate_desc_t *)&ldt0_default[LDT_SYSCALL])->sgd_p = 0;
789 
790 	/*
791 	 * i386 call gate for system calls from libc.
792 	 */
793 	set_gatesegd((gate_desc_t *)&ldt0_default[LDT_ALTSYSCALL],
794 	    (void (*)(void))&sys_lcall32, KCS_SEL, 1, SDT_SYSCGT, SEL_UPL);
795 	((gate_desc_t *)&ldt0_default[LDT_ALTSYSCALL])->sgd_p = 0;
796 
797 	wr_ldtr(ULDT_SEL);
798 }
799 
800 #elif defined(__i386)
801 
802 /*
803  * Note that the call gates for system calls ask the hardware to copy exactly
804  * one parameter onto the kernel stack for us; the parameter itself is not used.
805  * The real reason this is done is to make room for a snapshot of EFLAGS. See
806  * comment above sys_call() for details.
807  */
808 static void
809 init_ldt(void)
810 {
811 	/*
812 	 * call gate for libc.a (obsolete)
813 	 */
814 	set_gatesegd((gate_desc_t *)&ldt0_default[LDT_SYSCALL],
815 	    (void (*)(void))&sys_call, KCS_SEL, 1, SDT_SYSCGT, SEL_UPL);
816 
817 	/*
818 	 * i386 call gate for system calls from libc.
819 	 */
820 	set_gatesegd((gate_desc_t *)&ldt0_default[LDT_ALTSYSCALL],
821 	    (void (*)(void))&sys_call, KCS_SEL, 1, SDT_SYSCGT, SEL_UPL);
822 
823 	wr_ldtr(ULDT_SEL);
824 }
825 
826 #endif	/* __i386 */
827 
828 #if defined(__amd64)
829 
830 static void
831 init_tss(void)
832 {
833 	/*
834 	 * tss_rsp0 is dynamically filled in by resume() on each context switch.
835 	 * All exceptions but #DF will run on the thread stack.
836 	 * Set up the double fault stack here.
837 	 */
838 	ktss0.tss_ist1 =
839 	    (uint64_t)&dblfault_stack0[sizeof (dblfault_stack0)];
840 
841 	/*
842 	 * Set I/O bit map offset equal to size of TSS segment limit
843 	 * for no I/O permission map. This will force all user I/O
844 	 * instructions to generate #gp fault.
845 	 */
846 	ktss0.tss_bitmapbase = sizeof (ktss0);
847 
848 	/*
849 	 * Point %tr to descriptor for ktss0 in gdt.
850 	 */
851 	wr_tsr(KTSS_SEL);
852 }
853 
854 #elif defined(__i386)
855 
856 static void
857 init_tss(void)
858 {
859 	/*
860 	 * ktss0.tss_esp dynamically filled in by resume() on each
861 	 * context switch.
862 	 */
863 	ktss0.tss_ss0	= KDS_SEL;
864 	ktss0.tss_eip	= (uint32_t)_start;
865 	ktss0.tss_ds	= ktss0.tss_es = ktss0.tss_ss = KDS_SEL;
866 	ktss0.tss_cs	= KCS_SEL;
867 	ktss0.tss_fs	= KFS_SEL;
868 	ktss0.tss_gs	= KGS_SEL;
869 	ktss0.tss_ldt	= ULDT_SEL;
870 
871 	/*
872 	 * Initialize double fault tss.
873 	 */
874 	dftss0.tss_esp0	= (uint32_t)&dblfault_stack0[sizeof (dblfault_stack0)];
875 	dftss0.tss_ss0	= KDS_SEL;
876 
877 	/*
878 	 * tss_cr3 will get initialized in hat_kern_setup() once our page
879 	 * tables have been setup.
880 	 */
881 	dftss0.tss_eip	= (uint32_t)syserrtrap;
882 	dftss0.tss_esp	= (uint32_t)&dblfault_stack0[sizeof (dblfault_stack0)];
883 	dftss0.tss_cs	= KCS_SEL;
884 	dftss0.tss_ds	= KDS_SEL;
885 	dftss0.tss_es	= KDS_SEL;
886 	dftss0.tss_ss	= KDS_SEL;
887 	dftss0.tss_fs	= KFS_SEL;
888 	dftss0.tss_gs	= KGS_SEL;
889 
890 	/*
891 	 * Set I/O bit map offset equal to size of TSS segment limit
892 	 * for no I/O permission map. This will force all user I/O
893 	 * instructions to generate #gp fault.
894 	 */
895 	ktss0.tss_bitmapbase = sizeof (ktss0);
896 
897 	/*
898 	 * Point %tr to descriptor for ktss0 in gdt.
899 	 */
900 	wr_tsr(KTSS_SEL);
901 }
902 
903 #endif	/* __i386 */
904 
905 void
906 init_tables(void)
907 {
908 	init_gdt();
909 	init_tss();
910 	init_idt();
911 	init_ldt();
912 }
913