summaryrefslogtreecommitdiff
path: root/sys/arch/amd64
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2010-10-14 04:38:25 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2010-10-14 04:38:25 +0000
commit4b789166b617211d8b7224aac4b6d89dd84c12dd (patch)
tree11aef126d9042761f7a1bd134760028a90431001 /sys/arch/amd64
parent24d2c93045be0a7889a3e5f63b65eb03c32b083f (diff)
Clean up segment handling: switch user-space to using code and data
segments in the GDT instead of the LDT and eliminate the GDT slots that we don't actually use. tested on both amd and intel by several not really the right person, but ok: kettenis@
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r--sys/arch/amd64/amd64/cpu.c4
-rw-r--r--sys/arch/amd64/amd64/locore.S10
-rw-r--r--sys/arch/amd64/amd64/machdep.c43
-rw-r--r--sys/arch/amd64/include/segments.h22
4 files changed, 32 insertions, 47 deletions
diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c
index a42691a6363..5661b800203 100644
--- a/sys/arch/amd64/amd64/cpu.c
+++ b/sys/arch/amd64/amd64/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.35 2010/07/25 21:43:38 deraadt Exp $ */
+/* $OpenBSD: cpu.c,v 1.36 2010/10/14 04:38:24 guenther Exp $ */
/* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */
/*-
@@ -654,7 +654,7 @@ cpu_init_msrs(struct cpu_info *ci)
{
wrmsr(MSR_STAR,
((uint64_t)GSEL(GCODE_SEL, SEL_KPL) << 32) |
- ((uint64_t)LSEL(LSYSRETBASE_SEL, SEL_UPL) << 48));
+ ((uint64_t)GSEL(GUCODE32_SEL, SEL_UPL) << 48));
wrmsr(MSR_LSTAR, (uint64_t)Xsyscall);
wrmsr(MSR_CSTAR, (uint64_t)Xsyscall32);
wrmsr(MSR_SFMASK, PSL_NT|PSL_T|PSL_I|PSL_C);
diff --git a/sys/arch/amd64/amd64/locore.S b/sys/arch/amd64/amd64/locore.S
index 8d4459f86c9..2b47a252132 100644
--- a/sys/arch/amd64/amd64/locore.S
+++ b/sys/arch/amd64/amd64/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.40 2010/09/28 03:53:14 guenther Exp $ */
+/* $OpenBSD: locore.S,v 1.41 2010/10/14 04:38:24 guenther Exp $ */
/* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */
/*
@@ -911,7 +911,7 @@ IDTVEC(syscall)
* ss:rsp, etc, so that all GP registers can be
* saved. Then, fill in the rest.
*/
- pushq $(LSEL(LUDATA_SEL, SEL_UPL))
+ pushq $(GSEL(GUDATA_SEL, SEL_UPL))
pushq %r15
subq $(TF_RSP-TF_TRAPNO),%rsp
movq CPUVAR(SCRATCH),%r15
@@ -920,9 +920,9 @@ IDTVEC(syscall)
movw %fs,TF_FS(%rsp)
movw %gs,TF_GS(%rsp)
movw %es,TF_ES(%rsp)
- movw $(LSEL(LUDATA_SEL, SEL_UPL)),TF_DS(%rsp)
+ movw $(GSEL(GUDATA_SEL, SEL_UPL)),TF_DS(%rsp)
movq %r11, TF_RFLAGS(%rsp) /* old rflags from syscall insn */
- movq $(LSEL(LUCODE_SEL, SEL_UPL)), TF_CS(%rsp)
+ movq $(GSEL(GUCODE_SEL, SEL_UPL)), TF_CS(%rsp)
movq %rcx,TF_RIP(%rsp)
movq $2,TF_ERR(%rsp)
movq $T_ASTFLT, TF_TRAPNO(%rsp)
@@ -961,7 +961,7 @@ syscall_return:
movw TF_FS(%rsp),%fs
movw TF_GS(%rsp),%gs
INTR_RESTORE_GPRS
- movw $(LSEL(LUDATA_SEL, SEL_UPL)),%r11
+ movw $(GSEL(GUDATA_SEL, SEL_UPL)),%r11
movw %r11,%ds
addq $48,%rsp
popq %rcx /* return rip */
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index 46d8724262b..a666456e78d 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.124 2010/10/02 23:31:33 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.125 2010/10/14 04:38:24 guenther Exp $ */
/* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */
/*-
@@ -612,10 +612,10 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
/*
* Build context to run handler in.
*/
- tf->tf_ds = LSEL(LUDATA_SEL, SEL_UPL);
- tf->tf_es = LSEL(LUDATA_SEL, SEL_UPL);
- tf->tf_fs = LSEL(LUDATA_SEL, SEL_UPL);
- tf->tf_gs = LSEL(LUDATA_SEL, SEL_UPL);
+ tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
+ tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
+ tf->tf_fs = GSEL(GUDATA_SEL, SEL_UPL);
+ tf->tf_gs = GSEL(GUDATA_SEL, SEL_UPL);
tf->tf_rax = (u_int64_t)catcher;
tf->tf_rdi = sig;
@@ -623,10 +623,10 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
tf->tf_rdx = scp;
tf->tf_rip = (u_int64_t)p->p_sigcode;
- tf->tf_cs = LSEL(LUCODE_SEL, SEL_UPL);
+ tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
tf->tf_rflags &= ~(PSL_T|PSL_D|PSL_VM|PSL_AC);
tf->tf_rsp = scp;
- tf->tf_ss = LSEL(LUDATA_SEL, SEL_UPL);
+ tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
#ifdef DEBUG
if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
@@ -1018,10 +1018,10 @@ setregs(struct proc *p, struct exec_package *pack, u_long stack,
pcb->pcb_flags = 0;
tf = p->p_md.md_regs;
- tf->tf_ds = LSEL(LUDATA_SEL, SEL_UPL);
- tf->tf_es = LSEL(LUDATA_SEL, SEL_UPL);
- tf->tf_fs = LSEL(LUDATA_SEL, SEL_UPL);
- tf->tf_gs = LSEL(LUDATA_SEL, SEL_UPL);
+ tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
+ tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
+ tf->tf_fs = GSEL(GUDATA_SEL, SEL_UPL);
+ tf->tf_gs = GSEL(GUDATA_SEL, SEL_UPL);
tf->tf_rdi = 0;
tf->tf_rsi = 0;
tf->tf_rbp = 0;
@@ -1038,10 +1038,10 @@ setregs(struct proc *p, struct exec_package *pack, u_long stack,
tf->tf_r14 = 0;
tf->tf_r15 = 0;
tf->tf_rip = pack->ep_entry;
- tf->tf_cs = LSEL(LUCODE_SEL, SEL_UPL);
+ tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
tf->tf_rflags = PSL_USERSET;
tf->tf_rsp = stack;
- tf->tf_ss = LSEL(LUDATA_SEL, SEL_UPL);
+ tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
retval[1] = 0;
}
@@ -1498,12 +1498,15 @@ init_x86_64(paddr_t first_avail)
set_sys_segment(GDT_ADDR_SYS(gdtstore, GLDT_SEL), ldtstore, LDT_SIZE - 1,
SDT_SYSLDT, SEL_KPL, 0);
- set_mem_segment(GDT_ADDR_MEM(gdtstore, GUCODE_SEL), 0,
- atop(VM_MAXUSER_ADDRESS) - 1, SDT_MEMERA, SEL_UPL, 1, 0, 1);
+ set_mem_segment(GDT_ADDR_MEM(gdtstore, GUCODE32_SEL), 0,
+ atop(VM_MAXUSER_ADDRESS) - 1, SDT_MEMERA, SEL_UPL, 1, 1, 0);
set_mem_segment(GDT_ADDR_MEM(gdtstore, GUDATA_SEL), 0,
atop(VM_MAXUSER_ADDRESS) - 1, SDT_MEMRWA, SEL_UPL, 1, 0, 1);
+ set_mem_segment(GDT_ADDR_MEM(gdtstore, GUCODE_SEL), 0,
+ atop(VM_MAXUSER_ADDRESS) - 1, SDT_MEMERA, SEL_UPL, 1, 0, 1);
+
/* make ldt gates and memory segments */
setgate((struct gate_descriptor *)(ldtstore + LSYS5CALLS_SEL),
&IDTVEC(oosyscall), 0, SDT_SYS386CGT, SEL_UPL,
@@ -1515,16 +1518,6 @@ init_x86_64(paddr_t first_avail)
*GDT_ADDR_MEM(gdtstore, GUDATA_SEL);
/*
- * 32 bit GDT entries.
- */
-
- set_mem_segment(GDT_ADDR_MEM(gdtstore, GUCODE32_SEL), 0,
- atop(VM_MAXUSER_ADDRESS) - 1, SDT_MEMERA, SEL_UPL, 1, 1, 0);
-
- set_mem_segment(GDT_ADDR_MEM(gdtstore, GUDATA32_SEL), 0,
- atop(VM_MAXUSER_ADDRESS) - 1, SDT_MEMRWA, SEL_UPL, 1, 1, 0);
-
- /*
* 32 bit LDT entries.
*/
ldt_segp = (struct mem_segment_descriptor *)(ldtstore + LUCODE32_SEL);
diff --git a/sys/arch/amd64/include/segments.h b/sys/arch/amd64/include/segments.h
index 5e9fbd6b2bc..87acb9c7c4b 100644
--- a/sys/arch/amd64/include/segments.h
+++ b/sys/arch/amd64/include/segments.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: segments.h,v 1.5 2008/05/23 15:39:43 jasper Exp $ */
+/* $OpenBSD: segments.h,v 1.6 2010/10/14 04:38:24 guenther Exp $ */
/* $NetBSD: segments.h,v 1.1 2003/04/26 18:39:47 fvdl Exp $ */
/*-
@@ -253,24 +253,17 @@ void cpu_init_idt(void);
*
* Then come the predefined LDT (and possibly TSS) descriptors.
* There are NGDT_SYS of them.
+ *
+ * The particular order of the UCODE32, UDATA, and UCODE descriptors is
+ * required by the syscall/sysret instructions.
*/
#define GNULL_SEL 0 /* Null descriptor */
#define GCODE_SEL 1 /* Kernel code descriptor */
#define GDATA_SEL 2 /* Kernel data descriptor */
-#define GUCODE_SEL 3 /* User code descriptor */
+#define GUCODE32_SEL 3 /* User 32bit code descriptor (unused) */
#define GUDATA_SEL 4 /* User data descriptor */
-#define GAPM32CODE_SEL 5
-#define GAPM16CODE_SEL 6
-#define GAPMDATA_SEL 7
-#define GBIOSCODE_SEL 8
-#define GBIOSDATA_SEL 9
-#define GPNPBIOSCODE_SEL 10
-#define GPNPBIOSDATA_SEL 11
-#define GPNPBIOSSCRATCH_SEL 12
-#define GPNPBIOSTRAMP_SEL 13
-#define GUCODE32_SEL 14
-#define GUDATA32_SEL 15
-#define NGDT_MEM 16
+#define GUCODE_SEL 5 /* User code descriptor */
+#define NGDT_MEM 6
#define GLDT_SEL 0 /* Default LDT descriptor */
#define NGDT_SYS 1
@@ -296,7 +289,6 @@ void cpu_init_idt(void);
#define LDT_SIZE 144
-#define LSYSRETBASE_SEL LUCODE32_SEL
/*
* Checks for valid user selectors.