summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2010-11-13 04:16:43 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2010-11-13 04:16:43 +0000
commit184db9656b99370319619f1ff8225c9a5367859e (patch)
tree32d7865766c63c379f9a3ae16fd037c0e72e2dc9 /sys/arch
parenta4b25181b366373237fce8135d5a46f63251346e (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.c4
-rw-r--r--sys/arch/amd64/amd64/cpu.c5
-rw-r--r--sys/arch/amd64/amd64/gdt.c206
-rw-r--r--sys/arch/amd64/amd64/genassym.cf20
-rw-r--r--sys/arch/amd64/amd64/ipifuncs.c6
-rw-r--r--sys/arch/amd64/amd64/locore.S52
-rw-r--r--sys/arch/amd64/amd64/machdep.c59
-rw-r--r--sys/arch/amd64/amd64/mptramp.S5
-rw-r--r--sys/arch/amd64/amd64/pmap.c4
-rw-r--r--sys/arch/amd64/amd64/vm_machdep.c11
-rw-r--r--sys/arch/amd64/conf/files.amd644
-rw-r--r--sys/arch/amd64/include/cpu.h11
-rw-r--r--sys/arch/amd64/include/gdt.h26
-rw-r--r--sys/arch/amd64/include/intrdefs.h10
-rw-r--r--sys/arch/amd64/include/pcb.h29
-rw-r--r--sys/arch/amd64/include/proc.h3
-rw-r--r--sys/arch/amd64/include/segments.h13
-rw-r--r--sys/arch/amd64/include/tss.h4
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(&region, ci->ci_gdt, (u_int16_t)(MAXGDTSIZ - 1));
- lgdt(&region);
-}
-
-#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(&region, ci->ci_gdt, MAXGDTSIZ - 1);
+ setregion(&region, ci->ci_gdt, GDT_SIZE - 1);
lgdt(&region);
+ 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(&region, gdtstore, DYNSEL_START - 1);
+ setregion(&region, gdtstore, GDT_SIZE - 1);
lgdt(&region);
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];