diff options
author | Philip Guenthe <guenther@cvs.openbsd.org> | 2010-11-13 04:16:43 +0000 |
---|---|---|
committer | Philip Guenthe <guenther@cvs.openbsd.org> | 2010-11-13 04:16:43 +0000 |
commit | 184db9656b99370319619f1ff8225c9a5367859e (patch) | |
tree | 32d7865766c63c379f9a3ae16fd037c0e72e2dc9 /sys/arch | |
parent | a4b25181b366373237fce8135d5a46f63251346e (diff) |
Switch from TSS-per-process to TSS-per-CPU, placing the TSS right
next to the cpu's GDT, also making the double-fault stack per-CPU,
leaving it at the top of the page of the CPU's idle process. Inline
pmap_activate() and pmap_deactivate() into the asm cpu_switchto
routine, adding a check for the new pmap already being marked as
active on the CPU. Garbage collect the hasn't-been-used-in-years
GDT update IPI.
Tested by many; ok mikeb@, kettenis@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/amd64/amd64/acpi_machdep.c | 4 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/cpu.c | 5 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/gdt.c | 206 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/genassym.cf | 20 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/ipifuncs.c | 6 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/locore.S | 52 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/machdep.c | 59 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/mptramp.S | 5 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/pmap.c | 4 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/vm_machdep.c | 11 | ||||
-rw-r--r-- | sys/arch/amd64/conf/files.amd64 | 4 | ||||
-rw-r--r-- | sys/arch/amd64/include/cpu.h | 11 | ||||
-rw-r--r-- | sys/arch/amd64/include/gdt.h | 26 | ||||
-rw-r--r-- | sys/arch/amd64/include/intrdefs.h | 10 | ||||
-rw-r--r-- | sys/arch/amd64/include/pcb.h | 29 | ||||
-rw-r--r-- | sys/arch/amd64/include/proc.h | 3 | ||||
-rw-r--r-- | sys/arch/amd64/include/segments.h | 13 | ||||
-rw-r--r-- | sys/arch/amd64/include/tss.h | 4 |
18 files changed, 121 insertions, 351 deletions
diff --git a/sys/arch/amd64/amd64/acpi_machdep.c b/sys/arch/amd64/amd64/acpi_machdep.c index 1d6a29833c3..b521cf00ade 100644 --- a/sys/arch/amd64/amd64/acpi_machdep.c +++ b/sys/arch/amd64/amd64/acpi_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi_machdep.c,v 1.46 2010/10/06 16:37:29 deraadt Exp $ */ +/* $OpenBSD: acpi_machdep.c,v 1.47 2010/11/13 04:16:42 guenther Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * @@ -303,7 +303,7 @@ acpi_resume_machdep(void) p = ci->ci_schedstate.spc_idleproc; pcb = &p->p_addr->u_pcb; - tf = (struct trapframe *)pcb->pcb_tss.tss_rsp0 - 1; + tf = (struct trapframe *)pcb->pcb_kstack - 1; sf = (struct switchframe *)tf - 1; sf->sf_r12 = (u_int64_t)sched_idle; sf->sf_r13 = (u_int64_t)ci; diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c index 6219a90cdea..0a29134d946 100644 --- a/sys/arch/amd64/amd64/cpu.c +++ b/sys/arch/amd64/amd64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.37 2010/10/26 05:49:10 guenther Exp $ */ +/* $OpenBSD: cpu.c,v 1.38 2010/11/13 04:16:42 guenther Exp $ */ /* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */ /*- @@ -280,9 +280,8 @@ cpu_attach(struct device *parent, struct device *self, void *aux) pcb = ci->ci_idle_pcb = (struct pcb *) kstack; memset(pcb, 0, USPACE); - pcb->pcb_tss.tss_rsp0 = kstack + USPACE - 16; + pcb->pcb_kstack = kstack + USPACE - 16; pcb->pcb_rbp = pcb->pcb_rsp = kstack + USPACE - 16; - pcb->pcb_tss.tss_ist[0] = kstack + PAGE_SIZE - 16; pcb->pcb_pmap = pmap_kernel(); pcb->pcb_cr0 = rcr0(); pcb->pcb_cr3 = pcb->pcb_pmap->pm_pdirpa; diff --git a/sys/arch/amd64/amd64/gdt.c b/sys/arch/amd64/amd64/gdt.c index aec3012d6dc..df975b5758a 100644 --- a/sys/arch/amd64/amd64/gdt.c +++ b/sys/arch/amd64/amd64/gdt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gdt.c,v 1.17 2010/10/26 05:49:10 guenther Exp $ */ +/* $OpenBSD: gdt.c,v 1.18 2010/11/13 04:16:42 guenther Exp $ */ /* $NetBSD: gdt.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */ /*- @@ -33,8 +33,6 @@ /* * Modified to deal with variable-length entries for amd64 by * fvdl@wasabisystems.com, may 2001 - * XXX this file should be shared with the i386 code, the difference - * can be hidden in macros. */ #include <sys/param.h> @@ -45,90 +43,9 @@ #include <uvm/uvm.h> #include <machine/gdt.h> +#include <machine/tss.h> #include <machine/pcb.h> -int gdt_next; /* next available slot for sweeping */ -int gdt_free; /* next free slot; terminated with GNULL_SEL */ - -struct mutex gdt_lock_store = MUTEX_INITIALIZER(IPL_HIGH); - -void gdt_init(void); -int gdt_get_slot(void); -void gdt_put_slot(int); - -/* - * Lock and unlock the GDT. - */ -#define gdt_lock() (mtx_enter(&gdt_lock_store)) -#define gdt_unlock() (mtx_leave(&gdt_lock_store)) - -void -set_mem_gdt(struct mem_segment_descriptor *sd, void *base, size_t limit, - int type, int dpl, int gran, int def32, int is64) -{ - CPU_INFO_ITERATOR cii; - struct cpu_info *ci; - int off; - - set_mem_segment(sd, base, limit, type, dpl, gran, def32, is64); - off = (char *)sd - gdtstore; - CPU_INFO_FOREACH(cii, ci) { - if (ci->ci_gdt != NULL) - *(struct mem_segment_descriptor *)(ci->ci_gdt + off) = - *sd; - } -} - -void -set_sys_gdt(struct sys_segment_descriptor *sd, void *base, size_t limit, - int type, int dpl, int gran) -{ - CPU_INFO_ITERATOR cii; - struct cpu_info *ci; - int off; - - set_sys_segment(sd, base, limit, type, dpl, gran); - off = (char *)sd - gdtstore; - CPU_INFO_FOREACH(cii, ci) { - if (ci->ci_gdt != NULL) - *(struct sys_segment_descriptor *)(ci->ci_gdt + off) = - *sd; - } -} - - -/* - * Initialize the GDT. - */ -void -gdt_init(void) -{ - char *old_gdt; - struct vm_page *pg; - vaddr_t va; - struct cpu_info *ci = &cpu_info_primary; - - gdt_next = 0; - gdt_free = GNULL_SEL; - - old_gdt = gdtstore; - gdtstore = (char *)uvm_km_valloc(kernel_map, MAXGDTSIZ); - for (va = (vaddr_t)gdtstore; va < (vaddr_t)gdtstore + MAXGDTSIZ; - va += PAGE_SIZE) { - pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO); - if (pg == NULL) { - panic("gdt_init: no pages"); - } - pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg), - VM_PROT_READ | VM_PROT_WRITE); - } - bcopy(old_gdt, gdtstore, DYNSEL_START); - ci->ci_gdt = gdtstore; - - gdt_init_cpu(ci); -} - -#ifdef MULTIPROCESSOR /* * Allocate shadow GDT for a slave cpu. */ @@ -138,10 +55,13 @@ gdt_alloc_cpu(struct cpu_info *ci) struct vm_page *pg; vaddr_t va; - ci->ci_gdt = (char *)uvm_km_valloc(kernel_map, MAXGDTSIZ); + ci->ci_gdt = (char *)uvm_km_valloc(kernel_map, + GDT_SIZE + sizeof(*ci->ci_tss)); + ci->ci_tss = (void *)(ci->ci_gdt + GDT_SIZE); uvm_map_pageable(kernel_map, (vaddr_t)ci->ci_gdt, - (vaddr_t)ci->ci_gdt + MAXGDTSIZ, FALSE, FALSE); - for (va = (vaddr_t)ci->ci_gdt; va < (vaddr_t)ci->ci_gdt + MAXGDTSIZ; + (vaddr_t)ci->ci_gdt + GDT_SIZE, FALSE, FALSE); + for (va = (vaddr_t)ci->ci_gdt; + va < (vaddr_t)ci->ci_gdt + GDT_SIZE + sizeof(*ci->ci_tss); va += PAGE_SIZE) { pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO); if (pg == NULL) @@ -149,10 +69,9 @@ gdt_alloc_cpu(struct cpu_info *ci) pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg), VM_PROT_READ | VM_PROT_WRITE); } - bzero(ci->ci_gdt, MAXGDTSIZ); - bcopy(gdtstore, ci->ci_gdt, MAXGDTSIZ); + bcopy(gdtstore, ci->ci_gdt, GDT_SIZE); + bzero(ci->ci_tss, sizeof(*ci->ci_tss)); } -#endif /* MULTIPROCESSOR */ /* @@ -164,107 +83,10 @@ gdt_init_cpu(struct cpu_info *ci) { struct region_descriptor region; - setregion(®ion, ci->ci_gdt, (u_int16_t)(MAXGDTSIZ - 1)); - lgdt(®ion); -} - -#ifdef MULTIPROCESSOR - -void -gdt_reload_cpu(struct cpu_info *ci) -{ - struct region_descriptor region; + set_sys_segment(GDT_ADDR_SYS(ci->ci_gdt, GPROC0_SEL), ci->ci_tss, + sizeof (struct x86_64_tss)-1, SDT_SYS386TSS, SEL_KPL, 0); - setregion(®ion, ci->ci_gdt, MAXGDTSIZ - 1); + setregion(®ion, ci->ci_gdt, GDT_SIZE - 1); lgdt(®ion); + ltr(GSYSSEL(GPROC0_SEL, SEL_KPL)); } -#endif - -/* - * Allocate a GDT slot as follows: - * 1) If there are entries on the free list, use those. - * 2) If there are fewer than MAXGDTSIZ entries in use, there are free slots - * near the end that we can sweep through. - */ -int -gdt_get_slot(void) -{ - int slot; - struct sys_segment_descriptor *gdt; - - gdt = (struct sys_segment_descriptor *)&gdtstore[DYNSEL_START]; - - gdt_lock(); - - if (gdt_free != GNULL_SEL) { - slot = gdt_free; - gdt_free = gdt[slot].sd_xx3; /* XXXfvdl res. field abuse */ - } else { - if (gdt_next >= MAXGDTSIZ) - panic("gdt_get_slot: out of GDT descriptors"); - slot = gdt_next++; - } - - gdt_unlock(); - return (slot); -} - -/* - * Deallocate a GDT slot, putting it on the free list. - */ -void -gdt_put_slot(int slot) -{ - struct sys_segment_descriptor *gdt; - - gdt = (struct sys_segment_descriptor *)&gdtstore[DYNSEL_START]; - - gdt_lock(); - - gdt[slot].sd_type = SDT_SYSNULL; - gdt[slot].sd_xx3 = gdt_free; - gdt_free = slot; - - gdt_unlock(); -} - -int -tss_alloc(struct pcb *pcb) -{ - int slot; - struct sys_segment_descriptor *gdt; - - gdt = (struct sys_segment_descriptor *)&gdtstore[DYNSEL_START]; - - slot = gdt_get_slot(); -#if 0 - printf("tss_alloc: slot %d addr %p\n", slot, &gdt[slot]); -#endif - set_sys_gdt(&gdt[slot], &pcb->pcb_tss, sizeof (struct x86_64_tss)-1, - SDT_SYS386TSS, SEL_KPL, 0); -#if 0 - printf("lolimit %lx lobase %lx type %lx dpl %lx p %lx hilimit %lx\n" - "xx1 %lx gran %lx hibase %lx xx2 %lx zero %lx xx3 %lx pad %lx\n", - (unsigned long)gdt[slot].sd_lolimit, - (unsigned long)gdt[slot].sd_lobase, - (unsigned long)gdt[slot].sd_type, - (unsigned long)gdt[slot].sd_dpl, - (unsigned long)gdt[slot].sd_p, - (unsigned long)gdt[slot].sd_hilimit, - (unsigned long)gdt[slot].sd_xx1, - (unsigned long)gdt[slot].sd_gran, - (unsigned long)gdt[slot].sd_hibase, - (unsigned long)gdt[slot].sd_xx2, - (unsigned long)gdt[slot].sd_zero, - (unsigned long)gdt[slot].sd_xx3); -#endif - return GDYNSEL(slot, SEL_KPL); -} - -void -tss_free(int sel) -{ - - gdt_put_slot(IDXDYNSEL(sel)); -} - diff --git a/sys/arch/amd64/amd64/genassym.cf b/sys/arch/amd64/amd64/genassym.cf index f82dabe9c33..b882b230349 100644 --- a/sys/arch/amd64/amd64/genassym.cf +++ b/sys/arch/amd64/amd64/genassym.cf @@ -1,4 +1,4 @@ -# $OpenBSD: genassym.cf,v 1.24 2010/10/26 05:49:10 guenther Exp $ +# $OpenBSD: genassym.cf,v 1.25 2010/11/13 04:16:42 guenther Exp $ # Written by Artur Grabowski art@openbsd.org, Public Domain include <sys/param.h> @@ -15,6 +15,7 @@ include <machine/pte.h> include <machine/vmparam.h> include <machine/intr.h> include <machine/pic.h> +include <machine/tss.h> include <machine/i82093var.h> include <machine/mutex.h> @@ -36,7 +37,6 @@ member p_addr member p_priority member p_stat member p_wchan -member P_MD_TSS_SEL p_md.md_tss_sel member P_MD_REGS p_md.md_regs member P_MD_FLAGS p_md.md_flags member P_MD_ASTPENDING p_md.md_astpending @@ -82,22 +82,29 @@ define FRAMESIZE sizeof(struct trapframe) struct pcb member pcb_cr3 -member pcb_rbp member pcb_rsp -member PCB_RSP0 pcb_tss.tss_rsp0 -member pcb_cr0 +member pcb_rbp +member pcb_kstack member pcb_onfault member pcb_fpcpu +member pcb_pmap +member pcb_cr0 + +struct pmap +member pm_cpus + +struct x86_64_tss +member tss_rsp0 struct cpu_info member CPU_INFO_SCRATCH ci_scratch member CPU_INFO_SELF ci_self +member CPU_INFO_CPUID ci_cpuid member CPU_INFO_APICID ci_apicid member CPU_INFO_RESCHED ci_want_resched member CPU_INFO_CURPROC ci_curproc member CPU_INFO_CURPCB ci_curpcb member CPU_INFO_IDLE_PCB ci_idle_pcb -member CPU_INFO_IDLE_TSS_SEL ci_idle_tss_sel member CPU_INFO_ILEVEL ci_ilevel member CPU_INFO_IDEPTH ci_idepth member CPU_INFO_ISOURCES ci_isources @@ -107,6 +114,7 @@ ifdef DIAGNOSTIC member CPU_INFO_MUTEX_LEVEL ci_mutex_level endif member CPU_INFO_GDT ci_gdt +member CPU_INFO_TSS ci_tss struct intrsource member is_recurse diff --git a/sys/arch/amd64/amd64/ipifuncs.c b/sys/arch/amd64/amd64/ipifuncs.c index fdf6373cc9f..6ab5a412390 100644 --- a/sys/arch/amd64/amd64/ipifuncs.c +++ b/sys/arch/amd64/amd64/ipifuncs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipifuncs.c,v 1.14 2010/10/02 23:14:32 deraadt Exp $ */ +/* $OpenBSD: ipifuncs.c,v 1.15 2010/11/13 04:16:42 guenther Exp $ */ /* $NetBSD: ipifuncs.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */ /*- @@ -54,7 +54,6 @@ #include <machine/i82489reg.h> #include <machine/i82489var.h> #include <machine/mtrr.h> -#include <machine/gdt.h> #include <machine/fpu.h> #include <ddb/db_output.h> @@ -80,13 +79,12 @@ void (*ipifunc[X86_NIPI])(struct cpu_info *) = x86_64_ipi_synch_fpu, NULL, x86_64_ipi_reload_mtrr, - gdt_reload_cpu, + x86_setperf_ipi, #ifdef DDB x86_ipi_db, #else NULL, #endif - x86_setperf_ipi, }; void diff --git a/sys/arch/amd64/amd64/locore.S b/sys/arch/amd64/amd64/locore.S index e5270186815..556b51a35a9 100644 --- a/sys/arch/amd64/amd64/locore.S +++ b/sys/arch/amd64/amd64/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.42 2010/10/26 05:49:10 guenther Exp $ */ +/* $OpenBSD: locore.S,v 1.43 2010/11/13 04:16:42 guenther Exp $ */ /* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */ /* @@ -741,6 +741,8 @@ ENTRY(cpu_switchto) movb $SONPROC,P_STAT(%r12) # p->p_stat = SONPROC SET_CURPROC(%r12,%rcx) + movl CPUVAR(CPUID),%edi + /* If old proc exited, don't bother. */ testq %r13,%r13 jz switch_exited @@ -752,13 +754,16 @@ ENTRY(cpu_switchto) * %rax, %rcx - scratch * %r13 - old proc, then old pcb * %r12 - new proc + * %edi - cpuid */ - movq %r13,%rdi - call pmap_deactivate - movq P_ADDR(%r13),%r13 + /* clear the old pmap's bit for the cpu */ + movq PCB_PMAP(%r13),%rcx + lock + btrl %edi,PM_CPUS(%rcx) + /* Save stack pointers. */ movq %rsp,PCB_RSP(%r13) movq %rbp,PCB_RBP(%r13) @@ -781,30 +786,28 @@ switch_exited: movq PCB_RSP(%r13),%rsp movq PCB_RBP(%r13),%rbp -#if 0 + movq CPUVAR(TSS),%rcx + movq PCB_KSTACK(%r13),%rdx + movq %rdx,TSS_RSP0(%rcx) + + movq PCB_CR3(%r13),%rax + movq %rax,%cr3 + /* Don't bother with the rest if switching to a system process. */ testl $P_SYSTEM,P_FLAG(%r12) jnz switch_restored -#endif - /* Load TSS info. */ -#ifdef MULTIPROCESSOR - movq CPUVAR(GDT),%rax -#else - movq _C_LABEL(gdtstore)(%rip),%rax + /* set the new pmap's bit for the cpu */ + movl CPUVAR(CPUID),%edi + movq PCB_PMAP(%r13),%rcx + movl PM_CPUS(%rcx),%eax + lock + btsl %edi,PM_CPUS(%rcx) +#ifdef DIAGNOSTIC + jc _C_LABEL(switch_pmcpu_set) #endif - movl P_MD_TSS_SEL(%r12),%edx - - /* Switch TSS. Reset "task busy" flag before */ - andl $~0x0200,4(%rax,%rdx, 1) - ltr %dx - - movq %r12,%rdi - call _C_LABEL(pmap_activate) -#if 0 switch_restored: -#endif /* Restore cr0 (including FPU state). */ movl PCB_CR0(%r13),%ecx #ifdef MULTIPROCESSOR @@ -876,6 +879,11 @@ NENTRY(switch_error3) call _C_LABEL(panic) /* NOTREACHED */ 1: .asciz "cpu_switch 3" +NENTRY(switch_pmcpu_set) + movabsq $1f,%rdi + call _C_LABEL(panic) + /* NOTREACHED */ +1: .asciz "activate already active pmap" #endif /* DIAGNOSTIC */ /* @@ -900,7 +908,7 @@ IDTVEC(syscall) swapgs movq %r15,CPUVAR(SCRATCH) movq CPUVAR(CURPCB),%r15 - movq PCB_RSP0(%r15),%r15 + movq PCB_KSTACK(%r15),%r15 xchgq %r15,%rsp sti diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index 0572a2b3cae..b5eaae0e9b7 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.126 2010/10/26 05:49:10 guenther Exp $ */ +/* $OpenBSD: machdep.c,v 1.127 2010/11/13 04:16:42 guenther Exp $ */ /* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */ /*- @@ -111,6 +111,7 @@ #include <machine/mpbiosvar.h> #include <machine/reg.h> #include <machine/kcore.h> +#include <machine/tss.h> #include <dev/isa/isareg.h> #include <machine/isa_machdep.h> @@ -360,30 +361,25 @@ cpu_startup(void) } /* - * Set up proc0's TSS + * Set up proc0's PCB and the cpu's TSS. */ void x86_64_proc0_tss_ldt_init(void) { struct pcb *pcb; - int x; - - gdt_init(); cpu_info_primary.ci_curpcb = pcb = &proc0.p_addr->u_pcb; - - pcb->pcb_tss.tss_iobase = - (u_int16_t)((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss); - for (x = 0; x < sizeof(pcb->pcb_iomap) / 4; x++) - pcb->pcb_iomap[x] = 0xffffffff; - pcb->pcb_cr0 = rcr0(); - pcb->pcb_tss.tss_rsp0 = (u_int64_t)proc0.p_addr + USPACE - 16; - pcb->pcb_tss.tss_ist[0] = (u_int64_t)proc0.p_addr + PAGE_SIZE; - proc0.p_md.md_regs = (struct trapframe *)pcb->pcb_tss.tss_rsp0 - 1; - proc0.p_md.md_tss_sel = tss_alloc(pcb); + pcb->pcb_kstack = (u_int64_t)proc0.p_addr + USPACE - 16; + proc0.p_md.md_regs = (struct trapframe *)pcb->pcb_kstack - 1; - ltr(proc0.p_md.md_tss_sel); + /* an empty iomap, by setting its offset to the TSS limit */ + cpu_info_primary.ci_tss->tss_iobase = sizeof(struct x86_64_tss); + cpu_info_primary.ci_tss->tss_rsp0 = pcb->pcb_kstack; + cpu_info_primary.ci_tss->tss_ist[0] = + (u_int64_t)proc0.p_addr + PAGE_SIZE - 16; + + ltr(GSYSSEL(GPROC0_SEL, SEL_KPL)); lldt(0); } @@ -395,17 +391,13 @@ x86_64_proc0_tss_ldt_init(void) void x86_64_init_pcb_tss_ldt(struct cpu_info *ci) { - int x; struct pcb *pcb = ci->ci_idle_pcb; - pcb->pcb_tss.tss_iobase = - (u_int16_t)((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss); - for (x = 0; x < sizeof(pcb->pcb_iomap) / 4; x++) - pcb->pcb_iomap[x] = 0xffffffff; + ci->ci_tss->tss_iobase = sizeof(*ci->ci_tss); + ci->ci_tss->tss_rsp0 = pcb->pcb_kstack; + ci->ci_tss->tss_ist[0] = pcb->pcb_kstack - USPACE + PAGE_SIZE; pcb->pcb_cr0 = rcr0(); - - ci->ci_idle_tss_sel = tss_alloc(pcb); } #endif /* MULTIPROCESSOR */ @@ -1471,7 +1463,8 @@ init_x86_64(paddr_t first_avail) #endif idt = (struct gate_descriptor *)idt_vaddr; - gdtstore = (char *)(idt + NIDT); + cpu_info_primary.ci_tss = (void *)(idt + NIDT); + gdtstore = (void *)(cpu_info_primary.ci_tss + 1); /* make gdt gates and memory segments */ set_mem_segment(GDT_ADDR_MEM(gdtstore, GCODE_SEL), 0, @@ -1489,6 +1482,10 @@ init_x86_64(paddr_t first_avail) set_mem_segment(GDT_ADDR_MEM(gdtstore, GUCODE_SEL), 0, atop(VM_MAXUSER_ADDRESS) - 1, SDT_MEMERA, SEL_UPL, 1, 0, 1); + set_sys_segment(GDT_ADDR_SYS(gdtstore, GPROC0_SEL), + cpu_info_primary.ci_tss, sizeof (struct x86_64_tss)-1, + SDT_SYS386TSS, SEL_KPL, 0); + /* exceptions */ for (x = 0; x < 32; x++) { ist = (x == 8) ? 1 : 0; @@ -1503,7 +1500,7 @@ init_x86_64(paddr_t first_avail) GSEL(GCODE_SEL, SEL_KPL)); idt_allocmap[128] = 1; - setregion(®ion, gdtstore, DYNSEL_START - 1); + setregion(®ion, gdtstore, GDT_SIZE - 1); lgdt(®ion); cpu_init_idt(); @@ -1528,9 +1525,6 @@ init_x86_64(paddr_t first_avail) } #endif - /* Make sure maxproc is sane */ - if (maxproc > cpu_maxproc()) - maxproc = cpu_maxproc(); } #ifdef KGDB @@ -1704,15 +1698,6 @@ idt_vec_free(int vec) simple_unlock(&idt_lock); } -/* - * Number of processes is limited by number of available GDT slots. - */ -int -cpu_maxproc(void) -{ - return (MAXGDTSIZ - DYNSEL_START) / 16; -} - #ifdef DIAGNOSTIC void splassert_check(int wantipl, const char *func) diff --git a/sys/arch/amd64/amd64/mptramp.S b/sys/arch/amd64/amd64/mptramp.S index 98d9f861f2d..aece9c33443 100644 --- a/sys/arch/amd64/amd64/mptramp.S +++ b/sys/arch/amd64/amd64/mptramp.S @@ -1,4 +1,4 @@ -/* $OpenBSD: mptramp.S,v 1.6 2010/04/01 19:47:59 kettenis Exp $ */ +/* $OpenBSD: mptramp.S,v 1.7 2010/11/13 04:16:42 guenther Exp $ */ /* $NetBSD: mptramp.S,v 1.1 2003/04/26 18:39:30 fvdl Exp $ */ /*- @@ -83,7 +83,6 @@ #include <machine/segments.h> #include <machine/mpbiosvar.h> #include <machine/i82489reg.h> -#include <machine/gdt.h> #define _RELOC(x) ((x) - KERNBASE) #define RELOC(x) _RELOC(_C_LABEL(x)) @@ -224,7 +223,7 @@ _C_LABEL(cpu_spinup_trampoline_end): #end of code copied to MP_TRAMPOLINE movq PCB_RBP(%rsi),%rbp movq CPU_INFO_GDT(%rdi),%rax - movw $(MAXGDTSIZ-1),-10(%rsp) + movw $(GDT_SIZE-1),-10(%rsp) movq %rax,-8(%rsp) lgdt -10(%rsp) diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c index a49ca83dc68..8a754946bc3 100644 --- a/sys/arch/amd64/amd64/pmap.c +++ b/sys/arch/amd64/amd64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.57 2010/10/26 05:49:10 guenther Exp $ */ +/* $OpenBSD: pmap.c,v 1.58 2010/11/13 04:16:42 guenther Exp $ */ /* $NetBSD: pmap.c,v 1.3 2003/05/08 18:13:13 thorpej Exp $ */ /* @@ -1118,7 +1118,7 @@ pmap_reference(struct pmap *pmap) /* * pmap_activate: activate a process' pmap (fill in %cr3) * - * => called from cpu_switch() + * => called from cpu_fork() and when switching pmaps during exec * => if p is the curproc, then load it into the MMU */ diff --git a/sys/arch/amd64/amd64/vm_machdep.c b/sys/arch/amd64/amd64/vm_machdep.c index 6237a0e9080..19a669d5514 100644 --- a/sys/arch/amd64/amd64/vm_machdep.c +++ b/sys/arch/amd64/amd64/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.23 2010/10/26 05:49:10 guenther Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.24 2010/11/13 04:16:42 guenther Exp $ */ /* $NetBSD: vm_machdep.c,v 1.1 2003/04/26 18:39:33 fvdl Exp $ */ /*- @@ -111,15 +111,13 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, */ pmap_activate(p2); - /* Fix up the TSS. */ - pcb->pcb_tss.tss_rsp0 = (u_int64_t)p2->p_addr + USPACE - 16; - pcb->pcb_tss.tss_ist[0] = (u_int64_t)p2->p_addr + PAGE_SIZE - 16; - p2->p_md.md_tss_sel = tss_alloc(pcb); + /* Record where this process's kernel stack is */ + pcb->pcb_kstack = (u_int64_t)p2->p_addr + USPACE - 16; /* * Copy the trapframe. */ - p2->p_md.md_regs = tf = (struct trapframe *)pcb->pcb_tss.tss_rsp0 - 1; + p2->p_md.md_regs = tf = (struct trapframe *)pcb->pcb_kstack - 1; *tf = *p1->p_md.md_regs; setredzone(p2); @@ -160,7 +158,6 @@ cpu_exit(struct proc *p) mtrr_clean(p); pmap_deactivate(p); - tss_free(p->p_md.md_tss_sel); sched_exit(p); } diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64 index 519b24be01e..5d5931aa8c2 100644 --- a/sys/arch/amd64/conf/files.amd64 +++ b/sys/arch/amd64/conf/files.amd64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.amd64,v 1.58 2010/09/07 16:22:48 mikeb Exp $ +# $OpenBSD: files.amd64,v 1.59 2010/11/13 04:16:42 guenther Exp $ maxpartitions 16 maxusers 2 16 128 @@ -6,7 +6,7 @@ maxusers 2 16 128 file arch/amd64/amd64/autoconf.c file arch/amd64/amd64/conf.c file arch/amd64/amd64/disksubr.c disk -file arch/amd64/amd64/gdt.c +file arch/amd64/amd64/gdt.c multiprocessor file arch/amd64/amd64/machdep.c file arch/amd64/amd64/identcpu.c file arch/amd64/amd64/via.c diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index b2a1ab3cd7d..ad8df981d52 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.58 2010/10/02 23:13:27 deraadt Exp $ */ +/* $OpenBSD: cpu.h,v 1.59 2010/11/13 04:16:42 guenther Exp $ */ /* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */ /*- @@ -43,7 +43,6 @@ */ #include <machine/frame.h> #include <machine/segments.h> -#include <machine/tss.h> #include <machine/intrdefs.h> #include <machine/cacheinfo.h> @@ -59,6 +58,7 @@ #ifdef _KERNEL +struct x86_64_tss; struct cpu_info { struct device *ci_dev; struct cpu_info *ci_self; @@ -79,7 +79,6 @@ struct cpu_info { struct pcb *ci_curpcb; struct pcb *ci_idle_pcb; - int ci_idle_tss_sel; struct intrsource *ci_isources[MAX_INTR_SOURCES]; u_int32_t ci_ipending; @@ -110,6 +109,7 @@ struct cpu_info { struct x86_cache_info ci_cinfo[CAI_COUNT]; + struct x86_64_tss *ci_tss; char *ci_gdt; volatile int ci_ddb_paused; @@ -125,10 +125,6 @@ struct cpu_info { #define CI_SETPERF_INTRANSIT 2 #define CI_SETPERF_DONE 3 - struct x86_64_tss ci_doubleflt_tss; - - char *ci_doubleflt_stack; - struct ksensordev ci_sensordev; struct ksensor ci_sensor; }; @@ -272,7 +268,6 @@ void cpu_probe_features(struct cpu_info *); /* machdep.c */ void dumpconf(void); -int cpu_maxproc(void); void cpu_reset(void); void x86_64_proc0_tss_ldt_init(void); void x86_64_bufinit(void); diff --git a/sys/arch/amd64/include/gdt.h b/sys/arch/amd64/include/gdt.h index b52bc98e3eb..65a116e8bc1 100644 --- a/sys/arch/amd64/include/gdt.h +++ b/sys/arch/amd64/include/gdt.h @@ -1,4 +1,4 @@ -/* $OpenBSD: gdt.h,v 1.4 2009/02/03 11:24:19 mikeb Exp $ */ +/* $OpenBSD: gdt.h,v 1.5 2010/11/13 04:16:42 guenther Exp $ */ /* $NetBSD: gdt.h,v 1.1 2003/04/26 18:39:40 fvdl Exp $ */ /*- @@ -30,29 +30,5 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _LOCORE -struct proc; -struct pmap; - -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 *); -void tss_free(int); - -void ldt_alloc(struct pmap *, char *, size_t); -void ldt_free(struct pmap *); - -void set_mem_gdt(struct mem_segment_descriptor *, void *, size_t, - int, int, int, int, int); -void set_sys_gdt(struct sys_segment_descriptor *, void *, size_t, int, int, - int); -#endif - -/* - * Maximum GDT size. It cannot exceed 65536 since the selector field of - * a descriptor is just 16 bits, and used as free list link. - */ -#define MAXGDTSIZ 65536 diff --git a/sys/arch/amd64/include/intrdefs.h b/sys/arch/amd64/include/intrdefs.h index c61cc1f1c45..96a196ff7cd 100644 --- a/sys/arch/amd64/include/intrdefs.h +++ b/sys/arch/amd64/include/intrdefs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intrdefs.h,v 1.7 2010/05/22 21:31:05 deraadt Exp $ */ +/* $OpenBSD: intrdefs.h,v 1.8 2010/11/13 04:16:42 guenther Exp $ */ /* $NetBSD: intrdefs.h,v 1.2 2003/05/04 22:01:56 fvdl Exp $ */ #ifndef _AMD64_INTRDEFS_H @@ -75,16 +75,14 @@ #define X86_IPI_SYNCH_FPU 0x00000008 #define X86_IPI_TLB 0x00000010 #define X86_IPI_MTRR 0x00000020 -#define X86_IPI_GDT 0x00000040 +#define X86_IPI_SETPERF 0x00000040 #define X86_IPI_DDB 0x00000080 -#define X86_IPI_SETPERF 0x00000100 -#define X86_NIPI 9 +#define X86_NIPI 8 #define X86_IPI_NAMES { "halt IPI", "nop IPI", "FPU flush IPI", \ "FPU synch IPI", "TLB shootdown IPI", \ - "MTRR update IPI", "GDT update IPI", "ddb IPI", \ - "setperf IPI"} + "MTRR update IPI", "setperf IPI", "ddb IPI" } #define IREENT_MAGIC 0x18041969 diff --git a/sys/arch/amd64/include/pcb.h b/sys/arch/amd64/include/pcb.h index db8b0cab91a..8151dc666d4 100644 --- a/sys/arch/amd64/include/pcb.h +++ b/sys/arch/amd64/include/pcb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pcb.h,v 1.6 2010/10/26 05:49:10 guenther Exp $ */ +/* $OpenBSD: pcb.h,v 1.7 2010/11/13 04:16:42 guenther Exp $ */ /* $NetBSD: pcb.h,v 1.1 2003/04/26 18:39:45 fvdl Exp $ */ /*- @@ -73,36 +73,23 @@ #include <sys/signal.h> -#include <machine/segments.h> #include <machine/tss.h> #include <machine/fpu.h> -#include <machine/sysarch.h> - -#define NIOPORTS 1024 /* # of ports we allow to be mapped */ /* * Please note that the pcb_savefpu field in struct below must be * on a 16-byte boundary. */ struct pcb { - /* - * XXXfvdl - * It's overkill to have a TSS here, as it's only needed - * for compatibility processes who use an I/O permission map. - * The pcb fields below are not in the TSS anymore (and there's - * not enough room in the TSS to store them all) - * Should just make this a pointer and allocate. - */ - struct x86_64_tss pcb_tss; - u_int64_t pcb_cr3; - u_int64_t pcb_rsp; - u_int64_t pcb_rbp; struct savefpu pcb_savefpu; /* floating point state */ - int pcb_cr0; /* saved image of CR0 */ + u_int64_t pcb_cr3; + u_int64_t pcb_rsp; + u_int64_t pcb_rbp; + u_int64_t pcb_kstack; /* kernel stack address */ caddr_t pcb_onfault; /* copyin/out fault recovery */ - struct cpu_info *pcb_fpcpu; /* cpu holding our fp state. */ - unsigned pcb_iomap[NIOPORTS/32]; /* I/O bitmap */ - struct pmap *pcb_pmap; /* back pointer to our pmap */ + struct cpu_info *pcb_fpcpu; /* cpu holding our fp state. */ + struct pmap *pcb_pmap; /* back pointer to our pmap */ + int pcb_cr0; /* saved image of CR0 */ }; /* diff --git a/sys/arch/amd64/include/proc.h b/sys/arch/amd64/include/proc.h index fb662a6ecd7..46ca006f6b4 100644 --- a/sys/arch/amd64/include/proc.h +++ b/sys/arch/amd64/include/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.3 2005/12/13 00:18:19 jsg Exp $ */ +/* $OpenBSD: proc.h,v 1.4 2010/11/13 04:16:42 guenther Exp $ */ /* $NetBSD: proc.h,v 1.1 2003/04/26 18:39:46 fvdl Exp $ */ /* @@ -42,7 +42,6 @@ */ struct mdproc { struct trapframe *md_regs; /* registers on current frame */ - int md_tss_sel; /* TSS selector */ int md_flags; __volatile int md_astpending; }; diff --git a/sys/arch/amd64/include/segments.h b/sys/arch/amd64/include/segments.h index 79f36ed301f..87650c8388a 100644 --- a/sys/arch/amd64/include/segments.h +++ b/sys/arch/amd64/include/segments.h @@ -1,4 +1,4 @@ -/* $OpenBSD: segments.h,v 1.7 2010/10/26 05:49:10 guenther Exp $ */ +/* $OpenBSD: segments.h,v 1.8 2010/11/13 04:16:42 guenther Exp $ */ /* $NetBSD: segments.h,v 1.1 2003/04/26 18:39:47 fvdl Exp $ */ /*- @@ -61,16 +61,14 @@ #define ISLDT(s) ((s) & SEL_LDT) /* is it local or global */ #define SEL_LDT 4 /* local descriptor table */ -/* Dynamically allocated TSSs start (byte offset) */ #define SYSSEL_START (NGDT_MEM << 3) -#define DYNSEL_START (SYSSEL_START + (NGDT_SYS << 4)) +#define GDT_SIZE (SYSSEL_START + (NGDT_SYS << 4)) /* * These define the index not from the start of the GDT, but from * the part of the GDT that they're allocated from. * First NGDT_MEM entries are 8-byte descriptors for CS and DS. - * - * The rest is 16-byte descriptors for TSSs + * Next NGDT_SYS entries are 16-byte descriptors defining TSSs. */ #define IDXSEL(s) (((s) >> 3) & 0x1fff) @@ -249,7 +247,7 @@ void cpu_init_idt(void); * The code and data descriptors must come first. There * are NGDT_MEM of them. * - * Then come the predefined LDT (and possibly TSS) descriptors. + * Then comes the predefined TSS descriptor. * There are NGDT_SYS of them. * * The particular order of the UCODE32, UDATA, and UCODE descriptors is @@ -263,7 +261,8 @@ void cpu_init_idt(void); #define GUCODE_SEL 5 /* User code descriptor */ #define NGDT_MEM 6 -#define NGDT_SYS 0 +#define GPROC0_SEL 0 /* common TSS */ +#define NGDT_SYS 1 #define GDT_SYS_OFFSET (NGDT_MEM << 3) diff --git a/sys/arch/amd64/include/tss.h b/sys/arch/amd64/include/tss.h index c674e0952dd..22b44bca8b2 100644 --- a/sys/arch/amd64/include/tss.h +++ b/sys/arch/amd64/include/tss.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tss.h,v 1.1 2004/01/28 01:39:39 mickey Exp $ */ +/* $OpenBSD: tss.h,v 1.2 2010/11/13 04:16:42 guenther Exp $ */ /* $NetBSD: tss.h,v 1.1 2003/04/26 18:39:49 fvdl Exp $ */ /* @@ -49,7 +49,7 @@ struct x86_64_tss { u_int32_t tss_reserved1; u_int64_t tss_rsp0; u_int64_t tss_rsp1; - u_int64_t tss_rsp3; + u_int64_t tss_rsp2; u_int32_t tss_reserved2; u_int32_t tss_reserved3; u_int64_t tss_ist[7]; |