Drink the swapgs kool-aid.

Enable the use of syscall/sysret as the default system cal entry
point.
This commit is contained in:
fvdl 2002-06-03 18:23:16 +00:00
parent 619aaa1337
commit 01fbe9c413
11 changed files with 93 additions and 108 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.3 2002/05/28 23:11:38 fvdl Exp $ */
/* $NetBSD: cpu.h,v 1.4 2002/06/03 18:23:16 fvdl Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@ -65,6 +65,7 @@ struct cpu_info {
u_long ci_spin_locks; /* # of spin locks held */
u_long ci_simple_locks; /* # of simple locks held */
#endif
u_int64_t ci_scratch;
};
#ifdef _KERNEL
@ -72,15 +73,6 @@ extern struct cpu_info cpu_info_store;
#define curcpu() (&cpu_info_store)
/*
* per-CPU private data. Present in kernel image, but remapped privately
* for non-boot CPUs.
*/
struct cpu_privdata {
struct trapframe cpriv_regs; /* scratch storage for registers */
};
extern struct cpu_privdata cpu_privata;
#endif
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: frameasm.h,v 1.2 2002/05/28 23:09:36 fvdl Exp $ */
/* $NetBSD: frameasm.h,v 1.3 2002/06/03 18:23:16 fvdl Exp $ */
#ifndef _X86_64_MACHINE_FRAMEASM_H
#define _X86_64_MACHINE_FRAMEASM_H
@ -11,8 +11,8 @@
/*
* These are used on interrupt or trap entry or exit.
*/
#define INTRENTRY \
pushq %rax ; \
#define INTR_SAVEARGS \
pushq %rax ; \
pushq %rcx ; \
pushq %rdx ; \
pushq %rbx ; \
@ -45,11 +45,18 @@
popq %rcx ; \
popq %rax
#define INTRFASTEXIT \
INTR_RESTOREARGS ; \
addq $16,%rsp ; \
iretq
#define INTRENTRY \
testq $SEL_UPL,24(%rsp) ; \
je 98f ; \
swapgs ; \
98: INTR_SAVEARGS
#define CPUPRIV(off) (cpu_private+CPRIV_/**/off)(%rip)
#define INTRFASTEXIT \
INTR_RESTOREARGS ; \
addq $16,%rsp ; \
testq $SEL_UPL,8(%rsp) ;\
je 99f ;\
swapgs ;\
99: iretq
#endif /* _X86_64_MACHINE_FRAMEASM_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: pcb.h,v 1.2 2002/05/26 12:08:49 fvdl Exp $ */
/* $NetBSD: pcb.h,v 1.3 2002/06/03 18:23:16 fvdl Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -103,6 +103,7 @@ struct pcb {
u_int64_t pcb_cr3;
u_int64_t pcb_rsp;
u_int64_t pcb_rbp;
u_int64_t pcb_usersp;
u_int64_t pcb_ldt_sel;
int pcb_cr0; /* saved image of CR0 */
struct fxsave64 pcb_savefpu; /* floating point state */

View File

@ -1,4 +1,4 @@
# $NetBSD: genassym.cf,v 1.4 2002/05/28 23:11:39 fvdl Exp $
# $NetBSD: genassym.cf,v 1.5 2002/06/03 18:23:17 fvdl Exp $
#
# Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -94,6 +94,7 @@ include <uvm/uvm.h>
include <machine/trap.h>
include <machine/pmap.h>
include <machine/vmparam.h>
include <machine/cpu.h>
if defined(COMPAT_NETBSD32)
include <machine/netbsd32_machdep.h>
@ -131,7 +132,7 @@ define P_MD_SYSCALL offsetof(struct proc, p_md.md_syscall)
define P_MD_FLAGS offsetof(struct proc, p_md.md_flags)
define P_SYSTEM P_SYSTEM
define MDP_SYSCALL MDP_SYSCALL
define P_32 P_32
define M_DATA offsetof(struct mbuf, m_data)
define M_LEN offsetof(struct mbuf, m_len)
@ -146,6 +147,7 @@ define V_INTR offsetof(struct uvmexp, intrs)
define PCB_CR3 offsetof(struct pcb, pcb_cr3)
define PCB_RBP offsetof(struct pcb, pcb_rbp)
define PCB_RSP offsetof(struct pcb, pcb_rsp)
define PCB_USERSP offsetof(struct pcb, pcb_usersp)
define PCB_RSP0 offsetof(struct pcb, pcb_tss.tss_rsp0)
define PCB_CR0 offsetof(struct pcb, pcb_cr0)
define PCB_LDT_SEL offsetof(struct pcb, pcb_ldt_sel)
@ -153,6 +155,8 @@ define PCB_ONFAULT offsetof(struct pcb, pcb_onfault)
define TF_CS offsetof(struct trapframe, tf_cs)
define TF_RIP offsetof(struct trapframe, tf_rip)
define TF_RSP offsetof(struct trapframe, tf_rsp)
define TF_SS offsetof(struct trapframe, tf_ss)
define TF_ERR offsetof(struct trapframe, tf_err)
define TF_TRAPNO offsetof(struct trapframe, tf_trapno)
define TF_RFLAGS offsetof(struct trapframe, tf_rflags)
@ -168,13 +172,13 @@ define SC_FS offsetof(struct sigcontext, sc_fs)
define SC_GS offsetof(struct sigcontext, sc_gs)
define SC_RFLAGS offsetof(struct sigcontext, sc_rflags)
define CPU_INFO_SCRATCH offsetof(struct cpu_info, ci_scratch)
define IH_FUN offsetof(struct intrhand, ih_fun)
define IH_ARG offsetof(struct intrhand, ih_arg)
define IH_COUNT offsetof(struct intrhand, ih_count)
define IH_NEXT offsetof(struct intrhand, ih_next)
define CPRIV_SCRATCH_R15 offsetof(struct cpu_privdata, cpriv_regs.tf_r15)
ifdef COMPAT_NETBSD32
define SIGF_HANDLER32 offsetof(struct netbsd32_sigframe, sf_handler)
define SIGF_SC32 offsetof(struct netbsd32_sigframe, sf_sc)

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.S,v 1.4 2002/05/28 23:11:39 fvdl Exp $ */
/* $NetBSD: locore.S,v 1.5 2002/06/03 18:23:17 fvdl Exp $ */
/*
* Copyright-o-rama!
@ -646,18 +646,14 @@ longmode_hi:
movq %rsi,PCB_CR3(%rax) # pcb->pcb_cr3
xorq %rbp,%rbp # mark end of frames
xorw %ax,%ax
movw %ax,%gs
movw %ax,%fs
/* XXX merge these */
movq $VM_MIN_KERNEL_ADDRESS,%rdi
call _C_LABEL(init_x86_64)
/* Clear segment registers; always null in proc0. */
xorq %rax,%rax
movq $MSR_FSBASE,%rcx
wrmsr
movq $MSR_GSBASE,%rcx
wrmsr
movq $MSR_KERNELGSBASE,%rcx
wrmsr
call _C_LABEL(main)
/*****************************************************************************/
@ -680,9 +676,9 @@ NENTRY(sigcode)
movq %rax,%rdi
pushq %rax
movq $SYS___sigreturn14,%rax
int $0x80
syscall
movq $SYS_exit,%rax
int $0x80
syscall
.globl _C_LABEL(esigcode)
_C_LABEL(esigcode):
@ -1122,10 +1118,11 @@ ENTRY(switch_exit)
/* We're always in the kernel, so we don't need the LDT. */
/* Clear segment registers; always null in proc0. */
xorl %ecx,%ecx
#if 0
movl $GSEL(GUDATA_SEL,SEL_KPL),%ecx
movl %ecx,%fs
movl %ecx,%gs
#endif
/* Restore cr0 (including FPU state). */
movl PCB_CR0(%rsi),%ecx

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.7 2002/05/28 23:11:39 fvdl Exp $ */
/* $NetBSD: machdep.c,v 1.8 2002/06/03 18:23:17 fvdl Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 2000 The NetBSD Foundation, Inc.
@ -558,9 +558,9 @@ sendsig(catcher, sig, mask, code)
/*
* Build context to run handler in.
*/
#if 0
__asm("movl %0,%%gs" : : "r" (GSEL(GUDATA_SEL, SEL_UPL)));
__asm("movl %0,%%fs" : : "r" (GSEL(GUDATA_SEL, SEL_UPL)));
#if 0
tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
#endif
@ -985,9 +985,9 @@ setregs(p, pack, stack)
pcb->pcb_savefpu.fx_fcw = __NetBSD_NPXCW__;
tf = p->p_md.md_regs;
#if 0
__asm("movl %0,%%gs" : : "r" (LSEL(LUDATA_SEL, SEL_UPL)));
__asm("movl %0,%%fs" : : "r" (LSEL(LUDATA_SEL, SEL_UPL)));
#if 0
tf->tf_es = LSEL(LUDATA_SEL, SEL_UPL);
tf->tf_ds = LSEL(LUDATA_SEL, SEL_UPL);
#endif
@ -1087,6 +1087,7 @@ set_sys_segment(sd, base, limit, type, dpl, gran)
#define IDTVEC(name) __CONCAT(X, name)
typedef void (vector) __P((void));
extern vector IDTVEC(syscall);
extern vector IDTVEC(syscall32);
extern vector IDTVEC(osyscall);
extern vector IDTVEC(oosyscall);
extern vector *IDTVEC(exceptions)[];
@ -1527,7 +1528,12 @@ init_x86_64(first_avail)
((uint64_t)GSEL(GCODE_SEL, SEL_KPL) << 32) |
((uint64_t)LSEL(LSYSRETBASE_SEL, SEL_UPL) << 48));
wrmsr(MSR_LSTAR, (uint64_t)IDTVEC(syscall));
wrmsr(MSR_SFMASK, PSL_NT|PSL_T|PSL_I);
wrmsr(MSR_CSTAR, (uint64_t)IDTVEC(syscall32));
wrmsr(MSR_SFMASK, PSL_NT|PSL_T|PSL_I|PSL_C);
wrmsr(MSR_FSBASE, 0);
wrmsr(MSR_GSBASE, (u_int64_t)&cpu_info_store);
wrmsr(MSR_KERNELGSBASE, 0);
setregion(&region, gdtstore, DYNSEL_START - 1);
lgdt(&region);

View File

@ -1,4 +1,4 @@
/* $NetBSD: netbsd32_machdep.c,v 1.3 2002/05/28 23:11:39 fvdl Exp $ */
/* $NetBSD: netbsd32_machdep.c,v 1.4 2002/06/03 18:23:17 fvdl Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -83,8 +83,10 @@ netbsd32_setregs(struct proc *p, struct exec_package *pack, u_long stack)
p->p_flag |= P_32;
tf = p->p_md.md_regs;
#if 0
__asm("movl %0,%%gs" : : "r" (LSEL(LUDATA32_SEL, SEL_UPL)));
__asm("movl %0,%%fs" : : "r" (LSEL(LUDATA32_SEL, SEL_UPL)));
#endif
/*
* XXXfvdl needs to be revisited
@ -189,8 +191,10 @@ netbsd32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/*
* Build context to run handler in.
*/
#if 0
__asm("movl %0,%%gs" : : "r" (GSEL(GUDATA32_SEL, SEL_UPL)));
__asm("movl %0,%%fs" : : "r" (GSEL(GUDATA32_SEL, SEL_UPL)));
#endif
#if 1
/* XXXX */
__asm("movl %0,%%es" : : "r" (GSEL(GUDATA32_SEL, SEL_UPL)));

View File

@ -1,4 +1,4 @@
/* $NetBSD: syscall.c,v 1.2 2002/05/28 23:11:40 fvdl Exp $ */
/* $NetBSD: syscall.c,v 1.3 2002/06/03 18:23:17 fvdl Exp $ */
/*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@ -121,10 +121,7 @@ syscall_plain(frame)
case 5:
args[4] = frame.tf_r8;
case 4:
if (p->p_md.md_flags & MDP_SYSCALL)
args[3] = frame.tf_r10;
else
args[3] = frame.tf_rcx;
args[3] = frame.tf_r10;
case 3:
args[2] = frame.tf_rdx;
case 2:
@ -225,10 +222,7 @@ syscall_fancy(frame)
case 5:
args[4] = frame.tf_r8;
case 4:
if (p->p_md.md_flags & MDP_SYSCALL)
args[3] = frame.tf_r10;
else
args[3] = frame.tf_rcx;
args[3] = frame.tf_r10;
case 3:
args[2] = frame.tf_rdx;
case 2:

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.5 2002/05/28 23:11:40 fvdl Exp $ */
/* $NetBSD: trap.c,v 1.6 2002/06/03 18:23:17 fvdl Exp $ */
/*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@ -421,8 +421,13 @@ copyfault:
p->p_cred && p->p_ucred ?
p->p_ucred->cr_uid : -1);
trapsignal(p, SIGKILL, T_PAGEFLT);
} else
} else {
#ifdef fvdl_debug
printf("pid %d (%s): SEGV at rip %lx addr %lx\n",
p->p_pid, p->p_comm, frame.tf_rip, va);
#endif
trapsignal(p, SIGSEGV, T_PAGEFLT);
}
break;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: vector.S,v 1.3 2002/05/28 23:11:40 fvdl Exp $ */
/* $NetBSD: vector.S,v 1.4 2002/06/03 18:23:17 fvdl Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -92,6 +92,8 @@
#define BPTTRAP(a) ZTRAP(a)
#define CPUVAR(off) %gs:CPU_INFO_/**/off
.text
IDTVEC(trap00)
ZTRAP(T_DIVIDE)
@ -229,52 +231,40 @@ calltrap:
4: .asciz "WARNING: SPL NOT LOWERED ON TRAP EXIT\n"
#endif /* DIAGNOSTIC */
IDTVEC(syscall32)
sysret /* go away please */
/*
* syscall insn entry. This currently isn't much faster, but
* it can be made faster in the future.
*/
IDTVEC(syscall)
/*
* We're out of spare registers in the ABI. I don't want
* to go the swapgs route, so use temp storage in
* per-CPU private data. XXX
*/
movq %r15,CPUPRIV(SCRATCH_R15)
movq _C_LABEL(curpcb)(%rip), %r15
swapgs
movq %r15,CPUVAR(SCRATCH)
movq _C_LABEL(curpcb)(%rip),%r15
movq PCB_RSP0(%r15),%r15
xchgq %rsp,%r15
xchgq %r15,%rsp
sti
/*
* XXX don't need this whole frame, split of the
* syscall frame and trapframe is needed.
* First, leave some room for the trapno, error,
* ss:rsp, etc, so that all GP registers can be
* saved. Then, fill in the rest.
*/
pushq $(LSEL(LUDATA_SEL, SEL_UPL))
pushq %r15
pushq %r11 /* old rflags */
pushq $(LSEL(LUCODE_SEL, SEL_UPL))
pushq %rcx /* old rip */
pushq $0
pushq $T_ASTFLT
pushq %rax
pushq %rcx
pushq %rdx
pushq %rbx
pushq %rbp
pushq %rsi
pushq %rdi
pushq %r8
pushq %r9
pushq %r10
pushq %r11
pushq %r12
pushq %r13
pushq %r14
movq CPUPRIV(SCRATCH_R15),%r15
pushq %r15
subq $(TF_RSP-TF_TRAPNO),%rsp
movq CPUVAR(SCRATCH),%r15
INTR_SAVEARGS
movq %r11, TF_RFLAGS(%rsp) /* old rflags from syscall insn */
movq $(LSEL(LUCODE_SEL, SEL_UPL)), TF_CS(%rsp)
movq %rcx,TF_RIP(%rsp)
movq $0,TF_ERR(%rsp)
movq $T_ASTFLT, TF_TRAPNO(%rsp)
movq _C_LABEL(curproc)(%rip),%r15 # get pointer to curproc
orl $MDP_SYSCALL,P_MD_FLAGS(%r15)
movq _C_LABEL(curproc)(%rip),%r15
movq %rsp,P_MD_REGS(%r15) # save pointer to frame
call *P_MD_SYSCALL(%r15)
1: /* Check for ASTs on exit to user mode. */
@ -289,27 +279,13 @@ IDTVEC(syscall)
jmp 1b
2:
sti
andl $~MDP_SYSCALL,P_MD_FLAGS(%r15)
syscall_return:
popq %r15
popq %r14
popq %r13
popq %r12
popq %r11
popq %r10
popq %r9
popq %r8
popq %rdi
popq %rsi
popq %rbp
popq %rbx
popq %rdx
popq %rcx
popq %rax
INTR_RESTOREARGS
addq $16,%rsp
popq %rcx /* return rip */
addq $8,%rsp
popq %r11 /* flags as set by sysret insn */
swapgs
cli
movq (%rsp),%rsp
sysretq
@ -323,9 +299,7 @@ NENTRY(proc_trampoline)
NENTRY(child_trampoline)
movq %r13,%rdi
call *%r12
btrl $MDP_SYSCALL,P_MD_FLAGS(%r13)
jc syscall_return
INTRFASTEXIT
jmp syscall_return
/*
* Old call gate entry for syscall. XXXfvdl: only needed if we're
@ -341,8 +315,7 @@ IDTVEC(oosyscall)
/*
* Trap gate entry for int $80 syscall
* XXX convert to using syscall/sysret.
* XXXfvdl Pushing all of the intr frame is overkill.
* XXX should only be used for 32bit binaries, check for this.
*/
IDTVEC(osyscall)
pushq $2 # size of instruction for restart
@ -350,6 +323,8 @@ osyscall1:
pushq $T_ASTFLT # trap # for doing ASTs
INTRENTRY
movq _C_LABEL(curproc)(%rip),%rdx # get pointer to curproc
testl $P_32,P_FLAG(%rdx)
je 1f # not a 32bit process, go away please
#ifdef DIAGNOSTIC
movl _C_LABEL(cpl)(%rip),%ebx
#endif /* DIAGNOSTIC */

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.5 2002/05/28 23:11:40 fvdl Exp $ */
/* $NetBSD: vm_machdep.c,v 1.6 2002/06/03 18:23:17 fvdl Exp $ */
/*-
* Copyright (c) 1995 Charles M. Hannum. All rights reserved.
@ -152,7 +152,7 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
sf->sf_ppl = 0;
sf->sf_r12 = (u_int64_t)func;
sf->sf_r13 = (u_int64_t)arg;
if (func == child_return && (p1->p_md.md_flags & MDP_SYSCALL))
if (func == child_return)
sf->sf_rip = (u_int64_t)child_trampoline;
else
sf->sf_rip = (u_int64_t)proc_trampoline;