Subject: Re: per-cpu TSS
To: None <port-i386@netbsd.org>
From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
List: port-i386
Date: 11/12/2003 23:12:46
--NextPart-20031112231206-0293300
Content-Type: Text/Plain; charset=us-ascii

> attached diff is to use per-cpu tss rather than per-process tss.

forgot to attach..

YAMAMOTO Takashi

--NextPart-20031112231206-0293300
Content-Type: Text/Plain; charset=us-ascii
Content-Disposition: attachment; filename="i386.cputss2.diff"

Index: include/gdt.h
===================================================================
--- include/gdt.h	(revision 374)
+++ include/gdt.h	(working copy)
@@ -45,7 +45,7 @@ void gdt_init(void);
 void gdt_init_cpu(struct cpu_info *);
 void gdt_reload_cpu(struct cpu_info *);
 void gdt_alloc_cpu(struct cpu_info *);
-int tss_alloc(struct pcb *);
+int tss_alloc(const struct i386tss *);
 void tss_free(int);
 void ldt_alloc(struct pmap *, union descriptor *, size_t);
 void ldt_free(struct pmap *);
Index: include/pcb.h
===================================================================
--- include/pcb.h	(revision 413)
+++ include/pcb.h	(working copy)
@@ -88,17 +88,16 @@
 #include <machine/npx.h>
 #include <machine/sysarch.h>
 
-#define	NIOPORTS	1024		/* # of ports we allow to be mapped */
-
 struct pcb {
-	struct	i386tss pcb_tss;
-#define	pcb_cr3	pcb_tss.tss_cr3
-#define	pcb_esp	pcb_tss.tss_esp
-#define	pcb_ebp	pcb_tss.tss_ebp
-#define	pcb_cs	pcb_tss.__tss_cs
-#define	pcb_ldt_sel	pcb_tss.tss_ldt
+	int	pcb_esp0;		/* ring0 esp */
+	int	pcb_esp;		/* kernel esp */
+	int	pcb_ebp;		/* kernel ebp */
+	int	pcb_ldt_sel;
 	int	pcb_cr0;		/* saved image of CR0 */
 	int	pcb_cr2;		/* page fault address (CR2) */
+	int	pcb_cr3;		/* page directory pointer */
+	int	__dummy;		/* pcb_savefpu need to be
+					   16-bytes aligned */
 	union	savefpu pcb_savefpu;	/* floating point state for FPU */
 	struct	emcsts pcb_saveemc;	/* Cyrix EMC state */
 /*
@@ -110,7 +109,7 @@ struct pcb {
 	void	*vm86_userp;		/* XXX performance hack */
 	struct pmap *pcb_pmap;		/* back pointer to our pmap */
 	struct cpu_info *pcb_fpcpu;	/* cpu holding our fp state. */
-	u_long	pcb_iomap[NIOPORTS/32];	/* I/O bitmap */
+	char	*pcb_iomap;		/* I/O permission bitmap */
 };
 
 /*    
Index: include/types.h
===================================================================
--- include/types.h	(revision 343)
+++ include/types.h	(working copy)
@@ -72,6 +72,5 @@ typedef	__volatile int		__cpu_simple_loc
 #define	__HAVE_OLD_DISKLABEL
 #define	__HAVE_GENERIC_SOFT_INTERRUPTS
 #define __HAVE_RAS
-#define	__HAVE_CPU_MAXPROC
 
 #endif	/* _MACHTYPES_H_ */
Index: include/segments.h
===================================================================
--- include/segments.h	(revision 374)
+++ include/segments.h	(working copy)
@@ -169,9 +169,9 @@ extern struct gate_descriptor *idt;
 
 void setgate(struct gate_descriptor *, void *, int, int, int, int);
 void setregion(struct region_descriptor *, void *, size_t);
-void setsegment(struct segment_descriptor *, void *, size_t, int, int,
+void setsegment(struct segment_descriptor *, const void *, size_t, int, int,
     int, int);
-void setgdt(int, void *, size_t, int, int, int, int);
+void setgdt(int, const void *, size_t, int, int, int, int);
 void unsetgate(struct gate_descriptor *);
 void cpu_init_idt(void);
 
Index: include/cpu.h
===================================================================
--- include/cpu.h	(revision 374)
+++ include/cpu.h	(working copy)
@@ -62,6 +62,15 @@
 
 struct intrsource;
 
+#define	NIOPORTS	1024		/* # of ports we allow to be mapped */
+#define	IOMAPSIZE	(NIOPORTS / 8)	/* I/O bitmap size in bytes */
+
+/*
+ * I/O bitmap offset beyond TSS's segment limit means no bitmaps.
+ * (i.e. any I/O attempt generates an exception.)
+ */
+#define	IOMAP_INVALOFF	0xffff
+
 /*
  * a bunch of this belongs in cpuvar.h; move it later..
  */
@@ -94,7 +103,6 @@ struct cpu_info {
 
 	struct pcb *ci_curpcb;		/* VA of current HW PCB */
 	struct pcb *ci_idle_pcb;	/* VA of current PCB */
-	int ci_idle_tss_sel;		/* TSS selector of idle PCB */
 
 	struct intrsource *ci_isources[MAX_INTR_SOURCES];
 	u_int32_t	ci_ipending;
@@ -129,6 +137,13 @@ struct cpu_info {
 	u_int ci_cflush_lsize;	/* CFLUSH insn line size */
 	struct x86_cache_info ci_cinfo[CAI_COUNT];
 
+	struct i386tss ci_tss;		/* Per-cpu TSS; shared among processes*/
+	char		ci_iomap[IOMAPSIZE];	/* I/O Bitmap */
+	int ci_tss_sel;			/* TSS selector of this cpu */
+#define	ci_esp0		ci_tss.tss_esp0
+#define	ci_ss0		ci_tss.tss_ss0
+#define	ci_ioopt	ci_tss.tss_ioopt
+
 	/*
 	 * Variables used by cc_microtime().
 	 */
@@ -347,9 +362,9 @@ extern int i386_has_sse2;
 
 /* machdep.c */
 void	dumpconf(void);
-int	cpu_maxproc(void);
 void	cpu_reset(void);
-void	i386_init_pcb_tss_ldt(struct cpu_info *);
+void	i386_init_idle_pcb(struct cpu_info *);
+void	i386_init_tss(struct cpu_info *);
 void	i386_proc0_tss_ldt_init(void);
 void	i386_bufinit(void);
 
Index: include/proc.h
===================================================================
--- include/proc.h	(revision 374)
+++ include/proc.h	(working copy)
@@ -46,7 +46,6 @@
 struct mdlwp {
 	struct	trapframe *md_regs;	/* registers on current frame */
 	int	md_flags;		/* machine-dependent flags */
-	int	md_tss_sel;		/* TSS selector */
 };
 
 /* md_flags */
Index: i386/vm_machdep.c
===================================================================
--- i386/vm_machdep.c	(revision 374)
+++ i386/vm_machdep.c	(working copy)
@@ -172,24 +172,14 @@ cpu_lwp_fork(l1, l2, stack, stacksize, f
 	*pcb = l1->l_addr->u_pcb;
 
 	/*
-	 * Preset these so that gdt_compact() doesn't get confused if called
-	 * during the allocations below.
-	 *
-	 * Note: pcb_ldt_sel is handled in the pmap_activate() call when
-	 * we run the new process.
+	 * Fix up the ring0 esp.
 	 */
-	l2->l_md.md_tss_sel = GSEL(GNULL_SEL, SEL_KPL);
-
-	/* Fix up the TSS. */
-	pcb->pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
-	pcb->pcb_tss.tss_esp0 = (int)l2->l_addr + USPACE - 16;
-
-	l2->l_md.md_tss_sel = tss_alloc(pcb);
+	pcb->pcb_esp0 = (int)l2->l_addr + USPACE - 16;
 
 	/*
 	 * Copy the trapframe.
 	 */
-	l2->l_md.md_regs = tf = (struct trapframe *)pcb->pcb_tss.tss_esp0 - 1;
+	l2->l_md.md_regs = tf = (struct trapframe *)pcb->pcb_esp0 - 1;
 	*tf = *l1->l_md.md_regs;
 
 #ifndef NOREDZONE
@@ -207,6 +197,7 @@ cpu_lwp_fork(l1, l2, stack, stacksize, f
 	sf->sf_eip = (int)proc_trampoline;
 	pcb->pcb_esp = (int)sf;
 	pcb->pcb_ebp = 0;
+	pcb->pcb_iomap = NULL;
 }
 
 void
@@ -300,9 +291,10 @@ void
 cpu_wait(l)
 	struct lwp *l;
 {
+	struct pcb *pcb = &l->l_addr->u_pcb;
 
-	/* Nuke the TSS. */
-	tss_free(l->l_md.md_tss_sel);
+	if (pcb->pcb_iomap)
+		free(pcb->pcb_iomap, M_DEVBUF);
 }
 
 /*
Index: i386/gdt.c
===================================================================
--- i386/gdt.c	(revision 182)
+++ i386/gdt.c	(working copy)
@@ -89,7 +89,7 @@ gdt_unlock()
 }
 
 void
-setgdt(int sel, void *base, size_t limit,
+setgdt(int sel, const void *base, size_t limit,
     int type, int dpl, int def32, int gran)
 {
 	struct segment_descriptor *sd = &gdt[sel].sd;
@@ -274,12 +274,12 @@ gdt_put_slot(int slot)
 }
 
 int
-tss_alloc(struct pcb *pcb)
+tss_alloc(const struct i386tss *tss)
 {
 	int slot;
 
 	slot = gdt_get_slot();
-	setgdt(slot, &pcb->pcb_tss, sizeof(struct pcb) - 1,
+	setgdt(slot, tss, sizeof(struct i386tss) + IOMAPSIZE - 1,
 	    SDT_SYS386TSS, SEL_KPL, 0, 0);
 	return GSEL(slot, SEL_KPL);
 }
Index: i386/cpu.c
===================================================================
--- i386/cpu.c	(revision 374)
+++ i386/cpu.c	(working copy)
@@ -309,16 +309,9 @@ cpu_attach(parent, self, aux)
 	pcb = ci->ci_idle_pcb = (struct pcb *) kstack;
 	memset(pcb, 0, USPACE);
 
-	pcb->pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
-	pcb->pcb_tss.tss_esp0 =
-	    kstack + USPACE - 16 - sizeof (struct trapframe);
-	pcb->pcb_tss.tss_esp =
-	    kstack + USPACE - 16 - sizeof (struct trapframe);
 	pcb->pcb_pmap = pmap_kernel();
-	pcb->pcb_cr0 = rcr0();
-	pcb->pcb_cr3 = pcb->pcb_pmap->pm_pdirpa;
+	i386_init_idle_pcb(ci);
 #endif
-
 	/* further PCB init done later. */
 
 	printf(": ");
@@ -495,6 +488,9 @@ cpu_boot_secondary_processors()
 	}
 }
 
+/*
+ * called by BP.
+ */
 void
 cpu_init_idle_pcbs()
 {
@@ -509,7 +505,8 @@ cpu_init_idle_pcbs()
 			continue;
 		if ((ci->ci_flags & CPUF_PRESENT) == 0)
 			continue;
-		i386_init_pcb_tss_ldt(ci);
+		i386_init_idle_pcb(ci);
+		i386_init_tss(ci);
 	}
 }
 
@@ -608,8 +605,7 @@ cpu_hatch(void *v)
 	lapic_set_lvt();
 	gdt_init_cpu(ci);
 	npxinit(ci);
-
-	lldt(GSEL(GLDT_SEL, SEL_KPL));
+	ltr(ci->ci_tss_sel);
 
 	cpu_init(ci);
 
Index: i386/pmap.c
===================================================================
--- i386/pmap.c	(revision 413)
+++ i386/pmap.c	(working copy)
@@ -738,9 +738,8 @@ pmap_exec_account(struct pmap *pm, vaddr
 
 	if ((opte & PG_X) && (npte & PG_X) == 0 && va == pm->pm_hiexec) {
 		struct trapframe *tf = curlwp->l_md.md_regs;
-		struct pcb *pcb = &curlwp->l_addr->u_pcb;
 
-		pcb->pcb_cs = tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
+		tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
 		pm->pm_hiexec = I386_MAX_EXE_ADDR;
 	}
 }
@@ -774,9 +773,9 @@ pmap_exec_fixup(struct vm_map *map, stru
 
 	pm->pm_hiexec = va;
 	if (pm->pm_hiexec > I386_MAX_EXE_ADDR) {
-		pcb->pcb_cs = tf->tf_cs = GSEL(GUCODEBIG_SEL, SEL_UPL);
+		tf->tf_cs = GSEL(GUCODEBIG_SEL, SEL_UPL);
 	} else {
-		pcb->pcb_cs = tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
+		tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
 	}
 	return (1);
 }
Index: i386/sys_machdep.c
===================================================================
--- i386/sys_machdep.c	(revision 374)
+++ i386/sys_machdep.c	(working copy)
@@ -378,11 +378,16 @@ i386_get_ioperm(l, args, retval)
 	int error;
 	struct pcb *pcb = &l->l_addr->u_pcb;
 	struct i386_get_ioperm_args ua;
+	char dummymap[IOMAPSIZE];
 
 	if ((error = copyin(args, &ua, sizeof(ua))) != 0)
 		return (error);
 
-	return copyout(pcb->pcb_iomap, ua.iomap, sizeof(pcb->pcb_iomap));
+	if (pcb->pcb_iomap)
+		return copyout(pcb->pcb_iomap, ua.iomap, IOMAPSIZE);
+
+	memset(dummymap, 0xff, sizeof(dummymap));
+	return copyout(dummymap, ua.iomap, sizeof(dummymap));
 }
 
 int
@@ -395,6 +400,7 @@ i386_set_ioperm(l, args, retval)
 	struct proc *p = l->l_proc;
 	struct pcb *pcb = &l->l_addr->u_pcb;
 	struct i386_set_ioperm_args ua;
+	struct cpu_info *ci;
 
 	if (securelevel > 1)
 		return EPERM;
@@ -403,9 +409,26 @@ i386_set_ioperm(l, args, retval)
 		return error;
 
 	if ((error = copyin(args, &ua, sizeof(ua))) != 0)
-		return (error);
+		return error;
 
-	return copyin(ua.iomap, pcb->pcb_iomap, sizeof(pcb->pcb_iomap));
+	if (pcb->pcb_iomap == NULL)
+		pcb->pcb_iomap = malloc(IOMAPSIZE, M_DEVBUF, M_WAITOK);
+
+	if ((error = copyin(ua.iomap, pcb->pcb_iomap, IOMAPSIZE)) != 0)
+		goto fail;
+
+	/*
+	 * make it effective immediately.
+	 */
+	ci = curcpu();
+	memcpy(ci->ci_iomap, pcb->pcb_iomap, sizeof(ci->ci_iomap));
+	ci->ci_ioopt = ((caddr_t)ci->ci_iomap - (caddr_t)&ci->ci_tss) << 16;
+
+	return 0;
+fail:
+	free(pcb->pcb_iomap, M_DEVBUF);
+	pcb->pcb_iomap = NULL;
+	return error;
 }
 
 #ifdef MTRR
Index: i386/machdep.c
===================================================================
--- i386/machdep.c	(revision 390)
+++ i386/machdep.c	(working copy)
@@ -396,49 +396,60 @@ void
 i386_proc0_tss_ldt_init()
 {
 	struct pcb *pcb;
-	int x;
 
 	gdt_init();
 
 	cpu_info_primary.ci_curpcb = pcb = &lwp0.l_addr->u_pcb;
 
-	pcb->pcb_tss.tss_ioopt =
-	    ((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss) << 16;
-
-	for (x = 0; x < sizeof(pcb->pcb_iomap) / 4; x++)
-		pcb->pcb_iomap[x] = 0xffffffff;
-
 	pcb->pcb_ldt_sel = pmap_kernel()->pm_ldt_sel = GSEL(GLDT_SEL, SEL_KPL);
 	pcb->pcb_cr0 = rcr0();
-	pcb->pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
-	pcb->pcb_tss.tss_esp0 = (int)lwp0.l_addr + USPACE - 16;
-	lwp0.l_md.md_regs = (struct trapframe *)pcb->pcb_tss.tss_esp0 - 1;
-	lwp0.l_md.md_tss_sel = tss_alloc(pcb);
+	pcb->pcb_esp0 = (int)lwp0.l_addr + USPACE - 16;
+	pcb->pcb_iomap = NULL;
+	lwp0.l_md.md_regs = (struct trapframe *)pcb->pcb_esp0 - 1;
 
-	ltr(lwp0.l_md.md_tss_sel);
 	lldt(pcb->pcb_ldt_sel);
 }
 
+#ifdef MULTIPROCESSOR
 /*
- * Set up TSS and LDT for a new PCB.
+ * Set up cpu's idle pcb.
+ *
+ * XXX this is called twice,
+ * once from cpu_attach and once from cpu_init_idle_pcbs.
  */
 
 void
-i386_init_pcb_tss_ldt(ci)
+i386_init_idle_pcb(ci)
 	struct cpu_info *ci;
 {
-	int x;
 	struct pcb *pcb = ci->ci_idle_pcb;
 
-	pcb->pcb_tss.tss_ioopt =
-	    ((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss) << 16;
-	for (x = 0; x < sizeof(pcb->pcb_iomap) / 4; x++)
-		pcb->pcb_iomap[x] = 0xffffffff;
-
-	pcb->pcb_ldt_sel = pmap_kernel()->pm_ldt_sel = GSEL(GLDT_SEL, SEL_KPL);
+	/* Set up idle PCB */
+	pcb->pcb_ldt_sel = -1;
+	pcb->pcb_iomap = NULL;
 	pcb->pcb_cr0 = rcr0();
+	pcb->pcb_cr3 = pcb->pcb_pmap->pm_pdirpa;
+	/* mptramp needs esp */
+	pcb->pcb_esp = (int)pcb + USPACE - 16 - sizeof(struct trapframe);
+}
+#endif /* MULTIPROCESSOR */
+
+/*
+ * Set up cpu's TSS.
+ */
+
+void
+i386_init_tss(ci)
+	struct cpu_info *ci;
+{
+	struct i386tss *tss = &ci->ci_tss;
 
-	ci->ci_idle_tss_sel = tss_alloc(pcb);
+	/*
+	 * Set up shared TSS and I/O bitmap
+	 */
+	tss->tss_ioopt = IOMAP_INVALOFF << 16;
+	tss->tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
+	ci->ci_tss_sel = tss_alloc(tss);
 }
 
 /*
@@ -1213,7 +1224,7 @@ setregion(rd, base, limit)
 void
 setsegment(sd, base, limit, type, dpl, def32, gran)
 	struct segment_descriptor *sd;
-	void *base;
+	const void *base;
 	size_t limit;
 	int type, dpl, def32, gran;
 {
@@ -2365,16 +2376,3 @@ idt_vec_free(vec)
 	idt_allocmap[vec] = 0;
 	simple_unlock(&idt_lock);
 }
-
-/*
- * Number of processes is limited by number of available GDT slots.
- */
-int
-cpu_maxproc(void)
-{
-#ifdef USER_LDT
-	return ((MAXGDTSIZ - NGDT) / 2);
-#else
-	return (MAXGDTSIZ - NGDT);
-#endif
-}
Index: i386/locore.S
===================================================================
--- i386/locore.S	(revision 413)
+++ i386/locore.S	(working copy)
@@ -1736,10 +1736,8 @@ ENTRY(cpu_switch)
 #ifndef MULTIPROCESSOR
 	movl	$_C_LABEL(lwp0),%ebx
 	movl	L_ADDR(%ebx),%edi
-	movl	L_MD_TSS_SEL(%ebx),%edx
 #else
 	movl	CPUVAR(IDLE_PCB),%edi
-	movl	CPUVAR(IDLE_TSS_SEL),%edx
 #endif
 	movl	$0,CPUVAR(CURLWP)		/* In case we fault... */
 
@@ -1750,21 +1748,15 @@ ENTRY(cpu_switch)
 	movl	PCB_ESP(%edi),%esp
 	movl	PCB_EBP(%edi),%ebp
 
-
 	/* Switch address space. */
 	movl	PCB_CR3(%edi),%ecx
 	movl	%ecx,%cr3
 
-	/* Switch TSS. Reset "task busy" flag before loading. */
-#ifdef MULTIPROCESSOR
-	movl	CPUVAR(GDT),%eax
-#else
-	movl	_C_LABEL(gdt),%eax
-#endif
-	andl	$~0x0200,4-SEL_KPL(%eax,%edx,1)
-	ltr	%dx
-
-	/* We're always in the kernel, so we don't need the LDT. */
+	/*
+	 * We're always in the kernel, so
+	 *  - we don't need the LDT.
+	 *  - we don't need to update TSS.
+	 */
 
 	/* Restore cr0 (including FPU state). */
 	movl	PCB_CR0(%edi),%ecx
@@ -1892,9 +1884,42 @@ switch_exited:
 	 *   %edi - new lwp
 	 */
 
+	movl	L_ADDR(%edi),%esi
+
+	/*
+	 * Switch I/O bitmap.
+	 *
+	 */
+	movl	PCB_IOMAP(%esi),%eax
+	orl	%eax,%eax
+	jnz	switch_hasiomap
+
+	/*
+	 * no I/O bitmap.
+	 * just use invalid offset.
+	 */
+	movl	$(IOMAP_INVALOFF << 16),CPUVAR(IOOPT)
+	jmp	switch_iomap_restored
+
+switch_hasiomap:
+	/*
+	 * XXX copying bitmap here might be slow.
+	 */
+	movl	$(IOMAPSIZE/4),%ecx
+	pushl	%esi
+	pushl	%edi
+	movl	%eax,%esi		/* pcb_iomap */
+	movl	CPUVAR(SELF),%edi
+	leal	CPU_INFO_IOMAP(%edi),%edi
+	rep
+	movsl
+	popl	%edi
+	popl	%esi
+	movl	$((CPU_INFO_IOMAP - CPU_INFO_TSS) << 16),CPUVAR(IOOPT)
+
+switch_iomap_restored:
 	/* No interrupts while loading new state. */
 	cli
-	movl	L_ADDR(%edi),%esi
 
 	/* Restore stack pointers. */
 	movl	PCB_ESP(%esi),%esp
@@ -1906,17 +1931,9 @@ switch_exited:
 	jnz	switch_restored
 #endif
 
-#ifdef MULTIPROCESSOR
-	movl	CPUVAR(GDT),%eax
-#else	
-	/* Load TSS info. */
-	movl	_C_LABEL(gdt),%eax
-#endif
-	movl	L_MD_TSS_SEL(%edi),%edx
-
-	/* Switch TSS. Reset "task busy" flag before loading. */
-	andl	$~0x0200,4(%eax,%edx, 1)
-	ltr	%dx
+	/* Switch ring0 esp in shared TSS */
+	movl	PCB_ESP0(%esi),%eax
+	movl	%eax,CPUVAR(ESP0)
 
 	pushl	%edi
 	call	_C_LABEL(pmap_activate)		# pmap_activate(p)
@@ -2045,10 +2062,8 @@ ENTRY(switch_exit)
 #ifndef MULTIPROCESSOR
 	movl	$_C_LABEL(lwp0),%ebx
 	movl	L_ADDR(%ebx),%esi
-	movl	L_MD_TSS_SEL(%ebx),%edx
 #else
 	movl	CPUVAR(IDLE_PCB),%esi
-	movl	CPUVAR(IDLE_TSS_SEL),%edx
 #endif
 	/* In case we fault... */
 	movl	$0,CPUVAR(CURLWP)
@@ -2063,23 +2078,15 @@ ENTRY(switch_exit)
 	/* Save exit func. */
 	pushl	%eax
 
-	/* Load TSS info. */
-#ifdef MULTIPROCESSOR
-	movl	CPUVAR(GDT),%eax
-#else	
-	/* Load TSS info. */
-	movl	_C_LABEL(gdt),%eax
-#endif
-
 	/* Switch address space. */
 	movl	PCB_CR3(%esi),%ecx
 	movl	%ecx,%cr3
 
-	/* Switch TSS. */
-	andl	$~0x0200,4-SEL_KPL(%eax,%edx,1)
-	ltr	%dx
-
-	/* We're always in the kernel, so we don't need the LDT. */
+	/*
+	 * We're always in the kernel, so
+	 *  - we don't need the LDT.
+	 *  - we don't need to update TSS.
+	 */
 
 	/* Restore cr0 (including FPU state). */
 	movl	PCB_CR0(%esi),%ecx
Index: i386/autoconf.c
===================================================================
--- i386/autoconf.c	(revision 374)
+++ i386/autoconf.c	(working copy)
@@ -145,12 +145,17 @@ cpu_configure(void)
 #endif
 	/* resync cr0 after FPU configuration */
 	lwp0.l_addr->u_pcb.pcb_cr0 = rcr0();
+
 #ifdef MULTIPROCESSOR
 	/* propagate this to the idle pcb's. */
 	cpu_init_idle_pcbs();
-#endif
+#else /* MULTIPROCESSOR */
+	i386_init_tss(&cpu_info_primary);
+#endif /* MULTIPROCESSOR */
 
 	spl0();
+
+	ltr(cpu_info_primary.ci_tss_sel);
 #if NLAPIC > 0
 	lapic_tpr = 0;
 #endif
Index: i386/genassym.cf
===================================================================
--- i386/genassym.cf	(revision 413)
+++ i386/genassym.cf	(working copy)
@@ -152,6 +152,8 @@ define	PDSLOT_KERN		PDSLOT_KERN
 define	NKPTP_MIN		NKPTP_MIN
 define	NKPTP_MAX		NKPTP_MAX
 
+define	IOMAPSIZE		IOMAPSIZE
+
 define	VM_MAXUSER_ADDRESS	(int)VM_MAXUSER_ADDRESS
 
 define	UVM_PAGE_IDLE_ZERO	offsetof(struct uvm, page_idle_zero)
@@ -163,7 +165,6 @@ define	L_PRIORITY		offsetof(struct lwp, 
 define	L_STAT			offsetof(struct lwp, l_stat)
 define	L_WCHAN			offsetof(struct lwp, l_wchan)
 define	L_PROC			offsetof(struct lwp, l_proc)
-define	L_MD_TSS_SEL		offsetof(struct lwp, l_md.md_tss_sel)
 define	L_MD_REGS		offsetof(struct lwp, l_md.md_regs)
 define	L_CPU			offsetof(struct lwp, l_cpu)
 define	P_FLAG			offsetof(struct proc, p_flag)
@@ -189,10 +190,12 @@ define	V_INTR			offsetof(struct uvmexp, 
 define	PCB_CR3			offsetof(struct pcb, pcb_cr3)
 define	PCB_EBP			offsetof(struct pcb, pcb_ebp)
 define	PCB_ESP			offsetof(struct pcb, pcb_esp)
+define	PCB_ESP0		offsetof(struct pcb, pcb_esp0)
 define	PCB_CR0			offsetof(struct pcb, pcb_cr0)
 define	PCB_LDT_SEL		offsetof(struct pcb, pcb_ldt_sel)
 define	PCB_ONFAULT		offsetof(struct pcb, pcb_onfault)
 define	PCB_FPCPU		offsetof(struct pcb, pcb_fpcpu)
+define	PCB_IOMAP		offsetof(struct pcb, pcb_iomap)
 
 define	TF_CS			offsetof(struct trapframe, tf_cs)
 define	TF_EIP			offsetof(struct trapframe, tf_eip)
@@ -261,8 +264,12 @@ define	CPU_INFO_RESCHED	offsetof(struct 
 define	CPU_INFO_CURLWP		offsetof(struct cpu_info, ci_curlwp)
 define	CPU_INFO_CURPCB		offsetof(struct cpu_info, ci_curpcb)
 define	CPU_INFO_IDLE_PCB	offsetof(struct cpu_info, ci_idle_pcb)
-define  CPU_INFO_IDLE_TSS_SEL	offsetof(struct cpu_info, ci_idle_tss_sel)
 define	CPU_INFO_ASTPENDING	offsetof(struct cpu_info, ci_astpending)
+define	CPU_INFO_ESP0		offsetof(struct cpu_info, ci_esp0)
+define	CPU_INFO_TSS		offsetof(struct cpu_info, ci_tss)
+define	CPU_INFO_IOMAP		offsetof(struct cpu_info, ci_iomap)
+define	CPU_INFO_IOOPT		offsetof(struct cpu_info, ci_ioopt)
+define	IOMAP_INVALOFF		IOMAP_INVALOFF
 
 define	CPU_INFO_LEVEL		offsetof(struct cpu_info, ci_cpuid_level)
 define	CPU_INFO_VENDOR		offsetof(struct cpu_info, ci_vendor[0])

--NextPart-20031112231206-0293300--