6624280 GDT, LDT, IDT and TSS should not share pages with other things
authorjosephb
Mon, 12 Nov 2007 10:17:46 -0800
changeset 5460 265cc42b6f62
parent 5459 47c7b3aa8805
child 5461 12a11f16263a
6624280 GDT, LDT, IDT and TSS should not share pages with other things
usr/src/uts/common/vm/seg_kmem.c
usr/src/uts/i86pc/boot/boot_gdt.s
usr/src/uts/i86pc/dboot/dboot_grub.s
usr/src/uts/i86pc/os/fakebop.c
usr/src/uts/i86pc/os/mp_pc.c
usr/src/uts/i86pc/os/mp_startup.c
usr/src/uts/i86pc/os/startup.c
usr/src/uts/i86pc/sys/machparam.h
usr/src/uts/i86pc/vm/i86_mmu.c
usr/src/uts/intel/ia32/os/desctbls.c
usr/src/uts/intel/kdi/kdi_idt.c
usr/src/uts/intel/sys/segments.h
--- a/usr/src/uts/common/vm/seg_kmem.c	Mon Nov 12 10:03:36 2007 -0800
+++ b/usr/src/uts/common/vm/seg_kmem.c	Mon Nov 12 10:17:46 2007 -0800
@@ -354,6 +354,8 @@
 
 	for (eaddr = addr + size; addr < eaddr; addr += PAGESIZE) {
 		pfnum = va_to_pfn(addr);
+		if (pfnum == PFN_INVALID)
+			continue;
 		if ((pp = page_numtopp_nolock(pfnum)) == NULL)
 			panic("boot_mapin(): No pp for pfnum = %lx", pfnum);
 
--- a/usr/src/uts/i86pc/boot/boot_gdt.s	Mon Nov 12 10:03:36 2007 -0800
+++ b/usr/src/uts/i86pc/boot/boot_gdt.s	Mon Nov 12 10:17:46 2007 -0800
@@ -27,8 +27,20 @@
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #if defined(__lint)
-
-int global_descriptor_table[0x10];
+#pragma pack(1)
+struct {
+	uint16_t limit_low;
+	uint16_t base_low;
+	uint8_t base_middle;
+	uint8_t attr;
+	uint8_t attr_and_limit;
+	uint8_t base_high;
+} global_descriptor_table[8];
+struct {
+	uint16_t limit;	/* sizeof (global_descriptor_table) - 1 */
+	void     *base;	/* &global_descriptor_table */
+} gdt_info;
+#pragma pack()
 
 #else	/* __lint */
 
--- a/usr/src/uts/i86pc/dboot/dboot_grub.s	Mon Nov 12 10:03:36 2007 -0800
+++ b/usr/src/uts/i86pc/dboot/dboot_grub.s	Mon Nov 12 10:17:46 2007 -0800
@@ -245,6 +245,13 @@
 	ret
 	SET_SIZE(have_cpuid)
 
+	/*
+	 * We want the GDT to be on its own page for better performance
+	 * running under hypervisors.
+	 */
+	.skip 4096
 #include "../boot/boot_gdt.s"
+	.skip 4096
+	.long	0
 
 #endif /* __lint */
--- a/usr/src/uts/i86pc/os/fakebop.c	Mon Nov 12 10:03:36 2007 -0800
+++ b/usr/src/uts/i86pc/os/fakebop.c	Mon Nov 12 10:17:46 2007 -0800
@@ -1489,7 +1489,7 @@
 
 extern void bop_trap_handler(void);
 
-static gate_desc_t bop_idt[NIDT];
+static gate_desc_t *bop_idt;
 
 static desctbr_t bop_idt_info;
 
@@ -1498,16 +1498,18 @@
 {
 	int t;
 
-	bzero(&bop_idt, sizeof (bop_idt));
+	bop_idt = (gate_desc_t *)
+	    do_bsys_alloc(NULL, NULL, MMU_PAGESIZE, MMU_PAGESIZE);
+	bzero(bop_idt, MMU_PAGESIZE);
 	for (t = 0; t < NIDT; ++t) {
 		set_gatesegd(&bop_idt[t], &bop_trap_handler, bcode_sel,
 		    SDT_SYSIGT, TRP_KPL);
 	}
-	bop_idt_info.dtr_limit = sizeof (bop_idt) - 1;
-	bop_idt_info.dtr_base = (uintptr_t)&bop_idt;
+	bop_idt_info.dtr_limit = (NIDT * sizeof (gate_desc_t)) - 1;
+	bop_idt_info.dtr_base = (uintptr_t)bop_idt;
 	wr_idtr(&bop_idt_info);
 }
-#endif
+#endif	/* !defined(__xpv) */
 
 /*
  * This is where we enter the kernel. It dummies up the boot_ops and
@@ -1540,14 +1542,6 @@
 	DBG_MSG((char *)xbootp->bi_cmdline);
 	DBG_MSG("\n\n\n");
 
-#ifndef __xpv
-	/*
-	 * Install an IDT to catch early pagefaults (shouldn't have any).
-	 * Also needed for kmdb.
-	 */
-	bop_idt_init();
-#endif
-
 	/*
 	 * physavail is no longer used by startup
 	 */
@@ -1605,8 +1599,16 @@
 		relocate_boot_archive();
 #endif
 
+#ifndef __xpv
 	/*
-	 *
+	 * Install an IDT to catch early pagefaults (shouldn't have any).
+	 * Also needed for kmdb.
+	 */
+	bop_idt_init();
+#endif
+
+	/*
+	 * Start building the boot properties from the command line
 	 */
 	DBG_MSG("Initializing boot properties:\n");
 	build_boot_properties();
--- a/usr/src/uts/i86pc/os/mp_pc.c	Mon Nov 12 10:03:36 2007 -0800
+++ b/usr/src/uts/i86pc/os/mp_pc.c	Mon Nov 12 10:17:46 2007 -0800
@@ -105,11 +105,12 @@
 	struct tss *ntss;
 
 	/*
-	 * Allocate space for page directory, stack, tss, gdt and idt.
-	 * The page directory has to be page aligned
+	 * Allocate space for stack, tss, gdt and idt. We round the size
+	 * alloated for cpu_tables up, so that the TSS is on a unique page.
+	 * This is more efficient when running in virtual machines.
 	 */
-	ct = kmem_zalloc(sizeof (*ct), KM_SLEEP);
-	if ((uintptr_t)ct & ~MMU_STD_PAGEMASK)
+	ct = kmem_zalloc(P2ROUNDUP(sizeof (*ct), PAGESIZE), KM_SLEEP);
+	if ((uintptr_t)ct & PAGEOFFSET)
 		panic("mp_startup_init: cpu%d misaligned tables", cp->cpu_id);
 
 	ntss = cp->cpu_tss = &ct->ct_tss;
@@ -148,7 +149,7 @@
 	 * Setup kernel tss.
 	 */
 	set_syssegd((system_desc_t *)&cp->cpu_gdt[GDT_KTSS], cp->cpu_tss,
-	    sizeof (*cp->cpu_tss) -1, SDT_SYSTSS, SEL_KPL);
+	    sizeof (*cp->cpu_tss) - 1, SDT_SYSTSS, SEL_KPL);
 
 	/*
 	 * Now copy all that we've set up onto the real mode platter
@@ -156,9 +157,9 @@
 	 */
 
 	rm->rm_idt_base = cp->cpu_idt;
-	rm->rm_idt_lim = sizeof (idt0) - 1;
+	rm->rm_idt_lim = sizeof (*cp->cpu_idt) * NIDT - 1;
 	rm->rm_gdt_base = cp->cpu_gdt;
-	rm->rm_gdt_lim = ((sizeof (*cp->cpu_gdt) * NGDT)) -1;
+	rm->rm_gdt_lim = sizeof (*cp->cpu_gdt) * NGDT - 1;
 
 	rm->rm_pdbr = getcr3();
 	rm->rm_cpu = cp->cpu_id;
@@ -209,7 +210,6 @@
 	rm->rm_longmode64_addr = rm_platter_pa +
 	    ((uint32_t)long_mode_64 - (uint32_t)real_mode_start);
 #endif	/* __amd64 */
-
 }
 
 /*ARGSUSED*/
@@ -234,7 +234,7 @@
 		/*
 		 * Some other, passive, error occurred.
 		 */
-		kmem_free(ct, sizeof (*ct));
+		kmem_free(ct, P2ROUNDUP(sizeof (*ct), PAGESIZE));
 		cp->cpu_tss = NULL;
 		break;
 	}
--- a/usr/src/uts/i86pc/os/mp_startup.c	Mon Nov 12 10:03:36 2007 -0800
+++ b/usr/src/uts/i86pc/os/mp_startup.c	Mon Nov 12 10:17:46 2007 -0800
@@ -352,9 +352,8 @@
 #if !defined(__lint)
 	ASSERT((sizeof (*cp->cpu_gdt) * NGDT) <= PAGESIZE);
 #endif
-	cp->cpu_m.mcpu_gdt = kmem_zalloc(PAGESIZE, KM_SLEEP);
-	bcopy(CPU->cpu_m.mcpu_gdt, cp->cpu_m.mcpu_gdt,
-	    (sizeof (*cp->cpu_m.mcpu_gdt) * NGDT));
+	cp->cpu_gdt = kmem_zalloc(PAGESIZE, KM_SLEEP);
+	bcopy(CPU->cpu_gdt, cp->cpu_gdt, (sizeof (*cp->cpu_gdt) * NGDT));
 
 #if defined(__i386)
 	/*
@@ -371,12 +370,13 @@
 	 * cmpxchgl register bug
 	 */
 	if (system_hardware.hd_nodes && x86_type != X86_TYPE_P5) {
-		struct machcpu *mcpu = &cp->cpu_m;
-
-		mcpu->mcpu_idt = kmem_alloc(sizeof (idt0), KM_SLEEP);
-		bcopy(idt0, mcpu->mcpu_idt, sizeof (idt0));
+#if !defined(__lint)
+		ASSERT((sizeof (*CPU->cpu_idt) * NIDT) <= PAGESIZE);
+#endif
+		cp->cpu_idt = kmem_zalloc(PAGESIZE, KM_SLEEP);
+		bcopy(CPU->cpu_idt, cp->cpu_idt, PAGESIZE);
 	} else {
-		cp->cpu_m.mcpu_idt = CPU->cpu_m.mcpu_idt;
+		cp->cpu_idt = CPU->cpu_idt;
 	}
 
 	/*
@@ -489,12 +489,12 @@
 	ucode_free_space(cp);
 #endif
 
-	if (cp->cpu_m.mcpu_idt != CPU->cpu_m.mcpu_idt)
-		kmem_free(cp->cpu_m.mcpu_idt, sizeof (idt0));
-	cp->cpu_m.mcpu_idt = NULL;
+	if (cp->cpu_idt != CPU->cpu_idt)
+		kmem_free(cp->cpu_idt, PAGESIZE);
+	cp->cpu_idt = NULL;
 
-	kmem_free(cp->cpu_m.mcpu_gdt, PAGESIZE);
-	cp->cpu_m.mcpu_gdt = NULL;
+	kmem_free(cp->cpu_gdt, PAGESIZE);
+	cp->cpu_gdt = NULL;
 
 	teardown_vaddr_for_ppcopy(cp);
 
--- a/usr/src/uts/i86pc/os/startup.c	Mon Nov 12 10:03:36 2007 -0800
+++ b/usr/src/uts/i86pc/os/startup.c	Mon Nov 12 10:17:46 2007 -0800
@@ -1160,8 +1160,7 @@
 	 * initial allocation pages from the kernel free page lists.
 	 */
 	boot_mapin((caddr_t)valloc_base, valloc_sz);
-	boot_mapin((caddr_t)GDT_VA, MMU_PAGESIZE);
-	boot_mapin((caddr_t)DEBUG_INFO_VA, MMU_PAGESIZE);
+	boot_mapin((caddr_t)MISC_VA_BASE, MISC_VA_SIZE);
 	PRM_POINT("startup_memlist() done");
 
 	PRM_DEBUG(valloc_sz);
@@ -1788,21 +1787,20 @@
 	if (x86_type == X86_TYPE_P5) {
 		desctbr_t idtr;
 		gate_desc_t *newidt;
-		struct machcpu *mcpu = &CPU->cpu_m;
 
 		if ((newidt = kmem_zalloc(MMU_PAGESIZE, KM_NOSLEEP)) == NULL)
 			panic("failed to install pentium_pftrap");
 
-		bcopy(idt0, newidt, sizeof (idt0));
+		bcopy(idt0, newidt, NIDT * sizeof (*idt0));
 		set_gatesegd(&newidt[T_PGFLT], &pentium_pftrap,
 		    KCS_SEL, SDT_SYSIGT, TRP_KPL);
 
 		(void) as_setprot(&kas, (caddr_t)newidt, MMU_PAGESIZE,
-		    PROT_READ|PROT_EXEC);
+		    PROT_READ | PROT_EXEC);
 
-		mcpu->mcpu_idt = newidt;
-		idtr.dtr_base = (uintptr_t)mcpu->mcpu_idt;
-		idtr.dtr_limit = sizeof (idt0) - 1;
+		CPU->cpu_idt = newidt;
+		idtr.dtr_base = (uintptr_t)CPU->cpu_idt;
+		idtr.dtr_limit = (NIDT * sizeof (*idt0)) - 1;
 		wr_idtr(&idtr);
 	}
 #endif	/* !__amd64 */
--- a/usr/src/uts/i86pc/sys/machparam.h	Mon Nov 12 10:03:36 2007 -0800
+++ b/usr/src/uts/i86pc/sys/machparam.h	Mon Nov 12 10:17:46 2007 -0800
@@ -286,12 +286,16 @@
 #endif	/* __i386 */
 
 /*
- * Reserve two pages just below KERNEL_TEXT for the GDT and debug info page.
+ * Reserve pages just below KERNEL_TEXT for the GDT, IDT, TSS and debug info.
  */
 #if !defined(_ASM)
-#define	MISC_VA_BASE (KERNEL_TEXT - MMU_PAGESIZE * 2)
-#define	GDT_VA	(MISC_VA_BASE)
-#define	DEBUG_INFO_VA (MISC_VA_BASE + MMU_PAGESIZE)
+#define	GDT_VA		(KERNEL_TEXT - MMU_PAGESIZE)
+#define	IDT_VA		(GDT_VA - MMU_PAGESIZE)
+#define	KTSS_VA		(IDT_VA - MMU_PAGESIZE)
+#define	DFTSS_VA	(KTSS_VA - MMU_PAGESIZE)
+#define	DEBUG_INFO_VA	(DFTSS_VA - MMU_PAGESIZE)
+#define	MISC_VA_BASE	(DEBUG_INFO_VA)
+#define	MISC_VA_SIZE	(KERNEL_TEXT - MISC_VA_BASE)
 #endif /* !_ASM */
 
 #if !defined(_ASM) && !defined(_KMDB)
--- a/usr/src/uts/i86pc/vm/i86_mmu.c	Mon Nov 12 10:03:36 2007 -0800
+++ b/usr/src/uts/i86pc/vm/i86_mmu.c	Mon Nov 12 10:17:46 2007 -0800
@@ -500,7 +500,7 @@
 	/* END CSTYLED */
 
 #if defined(__i386) && !defined(__xpv)
-	CPU->cpu_tss->tss_cr3 = dftss0.tss_cr3 = getcr3();
+	CPU->cpu_tss->tss_cr3 = dftss0->tss_cr3 = getcr3();
 #endif /* __i386 */
 
 #if defined(__xpv) && defined(__amd64)
--- a/usr/src/uts/intel/ia32/os/desctbls.c	Mon Nov 12 10:03:36 2007 -0800
+++ b/usr/src/uts/intel/ia32/os/desctbls.c	Mon Nov 12 10:17:46 2007 -0800
@@ -101,18 +101,15 @@
 desctbr_t	gdt0_default_r;
 #endif
 
-#pragma	align	16(idt0)
-gate_desc_t	idt0[NIDT]; 		/* interrupt descriptor table */
+gate_desc_t	*idt0; 		/* interrupt descriptor table */
 #if defined(__i386)
 desctbr_t	idt0_default_r;		/* describes idt0 in IDTR format */
 #endif
 
-#pragma align	16(ktss0)
-struct tss	ktss0;			/* kernel task state structure */
+struct tss	*ktss0;			/* kernel task state structure */
 
 #if defined(__i386)
-#pragma align	16(dftss0)
-struct tss	dftss0;			/* #DF double-fault exception */
+struct tss	*dftss0;		/* #DF double-fault exception */
 #endif	/* __i386 */
 
 user_desc_t	zero_udesc;		/* base zero user desc native procs */
@@ -537,8 +534,8 @@
 	/*
 	 * Kernel TSS
 	 */
-	set_syssegd((system_desc_t *)&gdt[GDT_KTSS], &ktss0,
-	    sizeof (ktss0) - 1, SDT_SYSTSS, SEL_KPL);
+	set_syssegd((system_desc_t *)&gdt[GDT_KTSS], ktss0,
+	    sizeof (*ktss0) - 1, SDT_SYSTSS, SEL_KPL);
 
 #endif	/* !__xpv */
 
@@ -588,8 +585,6 @@
 #endif
 	gdt0 = (user_desc_t *)BOP_ALLOC(bootops, (caddr_t)GDT_VA,
 	    PAGESIZE, PAGESIZE);
-	if (gdt0 == NULL)
-		panic("init_gdt: BOP_ALLOC failed");
 	bzero(gdt0, PAGESIZE);
 
 	init_gdt_common(gdt0);
@@ -660,8 +655,6 @@
 #endif
 	gdt0 = (user_desc_t *)BOP_ALLOC(bootops, (caddr_t)GDT_VA,
 	    PAGESIZE, PAGESIZE);
-	if (gdt0 == NULL)
-		panic("init_gdt: BOP_ALLOC failed");
 	bzero(gdt0, PAGESIZE);
 
 	init_gdt_common(gdt0);
@@ -756,14 +749,14 @@
 	/*
 	 * TSS for T_DBLFLT (double fault) handler
 	 */
-	set_syssegd((system_desc_t *)&gdt[GDT_DBFLT], &dftss0,
-	    sizeof (dftss0) - 1, SDT_SYSTSS, SEL_KPL);
+	set_syssegd((system_desc_t *)&gdt[GDT_DBFLT], dftss0,
+	    sizeof (*dftss0) - 1, SDT_SYSTSS, SEL_KPL);
 
 	/*
 	 * TSS for kernel
 	 */
-	set_syssegd((system_desc_t *)&gdt[GDT_KTSS], &ktss0,
-	    sizeof (ktss0) - 1, SDT_SYSTSS, SEL_KPL);
+	set_syssegd((system_desc_t *)&gdt[GDT_KTSS], ktss0,
+	    sizeof (*ktss0) - 1, SDT_SYSTSS, SEL_KPL);
 
 #endif	/* !__xpv */
 
@@ -815,8 +808,6 @@
 #endif
 	gdt0 = (user_desc_t *)BOP_ALLOC(bootops, (caddr_t)GDT_VA,
 	    PAGESIZE, PAGESIZE);
-	if (gdt0 == NULL)
-		panic("init_gdt: BOP_ALLOC failed");
 	bzero(gdt0, PAGESIZE);
 
 	init_gdt_common(gdt0);
@@ -869,8 +860,6 @@
 	 */
 	gdt0 = (user_desc_t *)BOP_ALLOC(bootops, (caddr_t)GDT_VA,
 	    PAGESIZE, PAGESIZE);
-	if (gdt0 == NULL)
-		panic("init_gdt: BOP_ALLOC failed");
 	bzero(gdt0, PAGESIZE);
 
 	init_gdt_common(gdt0);
@@ -1107,7 +1096,7 @@
 	 * All exceptions but #DF will run on the thread stack.
 	 * Set up the double fault stack here.
 	 */
-	ktss0.tss_ist1 =
+	ktss0->tss_ist1 =
 	    (uint64_t)&dblfault_stack0[sizeof (dblfault_stack0)];
 
 	/*
@@ -1115,7 +1104,7 @@
 	 * for no I/O permission map. This will force all user I/O
 	 * instructions to generate #gp fault.
 	 */
-	ktss0.tss_bitmapbase = sizeof (ktss0);
+	ktss0->tss_bitmapbase = sizeof (*ktss0);
 
 	/*
 	 * Point %tr to descriptor for ktss0 in gdt.
@@ -1129,42 +1118,42 @@
 init_tss(void)
 {
 	/*
-	 * ktss0.tss_esp dynamically filled in by resume() on each
+	 * ktss0->tss_esp dynamically filled in by resume() on each
 	 * context switch.
 	 */
-	ktss0.tss_ss0	= KDS_SEL;
-	ktss0.tss_eip	= (uint32_t)_start;
-	ktss0.tss_ds	= ktss0.tss_es = ktss0.tss_ss = KDS_SEL;
-	ktss0.tss_cs	= KCS_SEL;
-	ktss0.tss_fs	= KFS_SEL;
-	ktss0.tss_gs	= KGS_SEL;
-	ktss0.tss_ldt	= ULDT_SEL;
+	ktss0->tss_ss0	= KDS_SEL;
+	ktss0->tss_eip	= (uint32_t)_start;
+	ktss0->tss_ds	= ktss0->tss_es = ktss0->tss_ss = KDS_SEL;
+	ktss0->tss_cs	= KCS_SEL;
+	ktss0->tss_fs	= KFS_SEL;
+	ktss0->tss_gs	= KGS_SEL;
+	ktss0->tss_ldt	= ULDT_SEL;
 
 	/*
 	 * Initialize double fault tss.
 	 */
-	dftss0.tss_esp0	= (uint32_t)&dblfault_stack0[sizeof (dblfault_stack0)];
-	dftss0.tss_ss0	= KDS_SEL;
+	dftss0->tss_esp0 = (uint32_t)&dblfault_stack0[sizeof (dblfault_stack0)];
+	dftss0->tss_ss0	= KDS_SEL;
 
 	/*
 	 * tss_cr3 will get initialized in hat_kern_setup() once our page
 	 * tables have been setup.
 	 */
-	dftss0.tss_eip	= (uint32_t)syserrtrap;
-	dftss0.tss_esp	= (uint32_t)&dblfault_stack0[sizeof (dblfault_stack0)];
-	dftss0.tss_cs	= KCS_SEL;
-	dftss0.tss_ds	= KDS_SEL;
-	dftss0.tss_es	= KDS_SEL;
-	dftss0.tss_ss	= KDS_SEL;
-	dftss0.tss_fs	= KFS_SEL;
-	dftss0.tss_gs	= KGS_SEL;
+	dftss0->tss_eip	= (uint32_t)syserrtrap;
+	dftss0->tss_esp	= (uint32_t)&dblfault_stack0[sizeof (dblfault_stack0)];
+	dftss0->tss_cs	= KCS_SEL;
+	dftss0->tss_ds	= KDS_SEL;
+	dftss0->tss_es	= KDS_SEL;
+	dftss0->tss_ss	= KDS_SEL;
+	dftss0->tss_fs	= KFS_SEL;
+	dftss0->tss_gs	= KGS_SEL;
 
 	/*
 	 * Set I/O bit map offset equal to size of TSS segment limit
 	 * for no I/O permission map. This will force all user I/O
 	 * instructions to generate #gp fault.
 	 */
-	ktss0.tss_bitmapbase = sizeof (ktss0);
+	ktss0->tss_bitmapbase = sizeof (*ktss0);
 
 	/*
 	 * Point %tr to descriptor for ktss0 in gdt.
@@ -1193,17 +1182,22 @@
 	 * on lwp context switches.
 	 */
 	ASSERT(IS_P2ALIGNED((uintptr_t)gdt, PAGESIZE));
-	CPU->cpu_m.mcpu_gdt = gdt;
+	CPU->cpu_gdt = gdt;
 	CPU->cpu_m.mcpu_gdtpa = pfn_to_pa(va_to_pfn(gdt));
 
 	/*
 	 * Setup and install our IDT.
 	 */
-	init_idt(&idt0[0]);
+#if !defined(__lint)
+	ASSERT(NIDT * sizeof (*idt0) <= PAGESIZE);
+#endif
+	idt0 = (gate_desc_t *)BOP_ALLOC(bootops, (caddr_t)IDT_VA,
+	    PAGESIZE, PAGESIZE);
+	init_idt(idt0);
 	for (vec = 0; vec < NIDT; vec++)
 		xen_idt_write(&idt0[vec], vec);
 
-	CPU->cpu_m.mcpu_idt = idt0;
+	CPU->cpu_idt = idt0;
 
 	/*
 	 * set default kernel stack
@@ -1225,21 +1219,44 @@
 	desctbr_t idtr;
 
 	/*
+	 * Allocate IDT and TSS structures on unique pages for better
+	 * performance in virtual machines.
+	 */
+#if !defined(__lint)
+	ASSERT(NIDT * sizeof (*idt0) <= PAGESIZE);
+#endif
+	idt0 = (gate_desc_t *)BOP_ALLOC(bootops, (caddr_t)IDT_VA,
+	    PAGESIZE, PAGESIZE);
+#if !defined(__lint)
+	ASSERT(sizeof (*ktss0) <= PAGESIZE);
+#endif
+	ktss0 = (struct tss *)BOP_ALLOC(bootops, (caddr_t)KTSS_VA,
+	    PAGESIZE, PAGESIZE);
+
+#if defined(__i386)
+#if !defined(__lint)
+	ASSERT(sizeof (*dftss0) <= PAGESIZE);
+#endif
+	dftss0 = (struct tss *)BOP_ALLOC(bootops, (caddr_t)DFTSS_VA,
+	    PAGESIZE, PAGESIZE);
+#endif
+
+	/*
 	 * Setup and install our GDT.
 	 */
 	gdt = init_gdt();
 	ASSERT(IS_P2ALIGNED((uintptr_t)gdt, PAGESIZE));
-	CPU->cpu_m.mcpu_gdt = gdt;
+	CPU->cpu_gdt = gdt;
 
 	/*
 	 * Setup and install our IDT.
 	 */
-	init_idt(&idt0[0]);
+	init_idt(idt0);
 
 	idtr.dtr_base = (uintptr_t)idt0;
-	idtr.dtr_limit = sizeof (idt0) - 1;
+	idtr.dtr_limit = (NIDT * sizeof (*idt0)) - 1;
 	wr_idtr(&idtr);
-	CPU->cpu_m.mcpu_idt = idt0;
+	CPU->cpu_idt = idt0;
 
 #if defined(__i386)
 	/*
@@ -1250,7 +1267,7 @@
 #endif	/* __i386 */
 
 	init_tss();
-	CPU->cpu_tss = &ktss0;
+	CPU->cpu_tss = ktss0;
 	init_ldt();
 }
 
--- a/usr/src/uts/intel/kdi/kdi_idt.c	Mon Nov 12 10:03:36 2007 -0800
+++ b/usr/src/uts/intel/kdi/kdi_idt.c	Mon Nov 12 10:17:46 2007 -0800
@@ -377,7 +377,7 @@
 	if (cpusave == NULL)
 		kdi_idtr_set(kdi_idt, sizeof (kdi_idt) - 1);
 	else
-		kdi_idtr_set(cpusave->krs_idt, sizeof (idt0) - 1);
+		kdi_idtr_set(cpusave->krs_idt, (sizeof (*idt0) * NIDT) - 1);
 }
 
 /*
--- a/usr/src/uts/intel/sys/segments.h	Mon Nov 12 10:03:36 2007 -0800
+++ b/usr/src/uts/intel/sys/segments.h	Mon Nov 12 10:17:46 2007 -0800
@@ -647,8 +647,7 @@
 
 #ifndef	_ASM
 
-#pragma	align	16(idt0)
-extern	gate_desc_t	idt0[NIDT];
+extern	gate_desc_t	*idt0;
 extern	desctbr_t	idt0_default_reg;
 extern	user_desc_t	*gdt0;
 
@@ -666,11 +665,10 @@
 extern user_desc_t	ucs32_off;
 #endif  /* __amd64 */
 
-#pragma	align	16(ktss0)
-extern struct tss ktss0;
+extern struct tss *ktss0;
 
 #if defined(__i386)
-extern struct tss dftss0;
+extern struct tss *dftss0;
 #endif	/* __i386 */
 
 extern void div0trap(), dbgtrap(), nmiint(), brktrap(), ovflotrap();