diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2010-05-06 21:33:52 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2010-05-06 21:33:52 +0000 |
commit | befa29e3d6d6a8d6fbef3c493cb1770e7eb535fd (patch) | |
tree | 993c636d4d6ec9c50cf38cc372bcd5c1b834e89b /sys/arch | |
parent | 16d3cb434647d5c256d6fdd0eea82ccfb81d1454 (diff) |
Change trap() and syscall() to accept a pointer rather than using call
by reference for the trap frame, the infrastructure in locore.S for this
was already present.
This prevents gcc4 from optimising away stores into the frame and allows
a gcc4-compiled kernel to boot.
ok kettenis robert guenther
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/amd64/amd64/syscall.c | 39 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/trap.c | 87 |
2 files changed, 62 insertions, 64 deletions
diff --git a/sys/arch/amd64/amd64/syscall.c b/sys/arch/amd64/amd64/syscall.c index 6e3d62cfe94..72eb9a22fcc 100644 --- a/sys/arch/amd64/amd64/syscall.c +++ b/sys/arch/amd64/amd64/syscall.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.c,v 1.13 2008/06/26 05:42:09 ray Exp $ */ +/* $OpenBSD: syscall.c,v 1.14 2010/05/06 21:33:51 nicm Exp $ */ /* $NetBSD: syscall.c,v 1.1 2003/04/26 18:39:32 fvdl Exp $ */ /*- @@ -50,15 +50,14 @@ #include <machine/psl.h> #include <machine/userret.h> -void syscall(struct trapframe); +void syscall(struct trapframe *); /* * syscall(frame): * System call request from POSIX system call gate interface to kernel. - * Like trap(), argument is call by reference. */ void -syscall(struct trapframe frame) +syscall(struct trapframe *frame) { caddr_t params; const struct sysent *callp; @@ -72,7 +71,7 @@ syscall(struct trapframe frame) uvmexp.syscalls++; p = curproc; - code = frame.tf_rax; + code = frame->tf_rax; callp = p->p_emul->e_sysent; nsys = p->p_emul->e_nsysent; argp = &args[0]; @@ -84,7 +83,7 @@ syscall(struct trapframe frame) /* * Code is first argument, followed by actual args. */ - code = frame.tf_rdi; + code = frame->tf_rdi; argp = &args[1]; argoff = 1; break; @@ -101,24 +100,24 @@ syscall(struct trapframe frame) if (argsize) { switch (MIN(argsize, 6)) { case 6: - args[5] = frame.tf_r9; + args[5] = frame->tf_r9; case 5: - args[4] = frame.tf_r8; + args[4] = frame->tf_r8; case 4: - args[3] = frame.tf_r10; + args[3] = frame->tf_r10; case 3: - args[2] = frame.tf_rdx; + args[2] = frame->tf_rdx; case 2: - args[1] = frame.tf_rsi; + args[1] = frame->tf_rsi; case 1: - args[0] = frame.tf_rdi; + args[0] = frame->tf_rdi; break; default: panic("impossible syscall argsize"); } if (argsize > 6) { argsize -= 6; - params = (caddr_t)frame.tf_rsp + sizeof(register_t); + params = (caddr_t)frame->tf_rsp + sizeof(register_t); error = copyin(params, (caddr_t)&args[6], argsize << 3); if (error != 0) @@ -141,7 +140,7 @@ syscall(struct trapframe frame) } #endif rval[0] = 0; - rval[1] = frame.tf_rdx; + rval[1] = frame->tf_rdx; #if NSYSTRACE > 0 if (ISSET(p->p_flag, P_SYSTRACE)) { KERNEL_PROC_LOCK(p); @@ -158,9 +157,9 @@ syscall(struct trapframe frame) } switch (error) { case 0: - frame.tf_rax = rval[0]; - frame.tf_rdx = rval[1]; - frame.tf_rflags &= ~PSL_C; /* carry bit */ + frame->tf_rax = rval[0]; + frame->tf_rdx = rval[1]; + frame->tf_rflags &= ~PSL_C; /* carry bit */ break; case ERESTART: /* @@ -168,15 +167,15 @@ syscall(struct trapframe frame) * the kernel through the trap or call gate. We pushed the * size of the instruction into tf_err on entry. */ - frame.tf_rip -= frame.tf_err; + frame->tf_rip -= frame->tf_err; break; case EJUSTRETURN: /* nothing to do */ break; default: bad: - frame.tf_rax = error; - frame.tf_rflags |= PSL_C; /* carry bit */ + frame->tf_rax = error; + frame->tf_rflags |= PSL_C; /* carry bit */ break; } diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c index ee4af801425..1dccaf218cf 100644 --- a/sys/arch/amd64/amd64/trap.c +++ b/sys/arch/amd64/amd64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.17 2009/06/06 18:57:31 art Exp $ */ +/* $OpenBSD: trap.c,v 1.18 2010/05/06 21:33:51 nicm Exp $ */ /* $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $ */ /*- @@ -99,7 +99,7 @@ #include <sys/kgdb.h> #endif -void trap(struct trapframe); +void trap(struct trapframe *); const char *trap_type[] = { "privileged instruction fault", /* 0 T_PRIVINFLT */ @@ -141,15 +141,14 @@ static void frame_dump(struct trapframe *); * Exception, fault, and trap interface to BSD kernel. This * common code is called from assembly language IDT gate entry * routines that prepare a suitable stack frame, and restore this - * frame after the exception has been processed. Note that the - * effect is as if the arguments were passed call by reference. + * frame after the exception has been processed. */ /*ARGSUSED*/ void -trap(struct trapframe frame) +trap(struct trapframe *frame) { struct proc *p = curproc; - int type = (int)frame.tf_trapno; + int type = (int)frame->tf_trapno; struct pcb *pcb; extern char resume_iret[], IDTVEC(oosyscall)[]; #if 0 @@ -170,17 +169,17 @@ trap(struct trapframe frame) if (trapdebug) { printf("trap %d code %lx eip %lx cs %lx rflags %lx cr2 %lx " "cpl %x\n", - type, frame.tf_err, frame.tf_rip, frame.tf_cs, - frame.tf_rflags, rcr2(), curcpu()->ci_ilevel); + type, frame->tf_err, frame->tf_rip, frame->tf_cs, + frame->tf_rflags, rcr2(), curcpu()->ci_ilevel); printf("curproc %p\n", curproc); if (curproc) printf("pid %d\n", p->p_pid); } #endif - if (!KERNELMODE(frame.tf_cs, frame.tf_rflags)) { + if (!KERNELMODE(frame->tf_cs, frame->tf_rflags)) { type |= T_USER; - p->p_md.md_regs = &frame; + p->p_md.md_regs = frame; } switch (type) { @@ -188,7 +187,7 @@ trap(struct trapframe frame) default: we_re_toast: #ifdef KGDB - if (kgdb_trap(type, &frame)) + if (kgdb_trap(type, frame)) return; else { /* @@ -202,18 +201,18 @@ trap(struct trapframe frame) } #endif #ifdef DDB - if (kdb_trap(type, 0, &frame)) + if (kdb_trap(type, 0, frame)) return; #endif - if (frame.tf_trapno < trap_types) - printf("fatal %s", trap_type[frame.tf_trapno]); + if (frame->tf_trapno < trap_types) + printf("fatal %s", trap_type[frame->tf_trapno]); else - printf("unknown trap %ld", (u_long)frame.tf_trapno); + printf("unknown trap %ld", (u_long)frame->tf_trapno); printf(" in %s mode\n", (type & T_USER) ? "user" : "supervisor"); printf("trap type %d code %lx rip %lx cs %lx rflags %lx cr2 " " %lx cpl %x rsp %lx\n", - type, frame.tf_err, (u_long)frame.tf_rip, frame.tf_cs, - frame.tf_rflags, rcr2(), curcpu()->ci_ilevel, frame.tf_rsp); + type, frame->tf_err, (u_long)frame->tf_rip, frame->tf_cs, + frame->tf_rflags, rcr2(), curcpu()->ci_ilevel, frame->tf_rsp); /* panic("trap"); */ boot(RB_HALT); @@ -229,8 +228,8 @@ trap(struct trapframe frame) if (pcb->pcb_onfault != 0) { error = EFAULT; copyfault: - frame.tf_rip = (u_int64_t)pcb->pcb_onfault; - frame.tf_rax = error; + frame->tf_rip = (u_int64_t)pcb->pcb_onfault; + frame->tf_rax = error; return; } @@ -251,9 +250,9 @@ copyfault: * at this point is the same as on exit from a `slow' * interrupt. */ - switch (*(u_char *)frame.tf_rip) { + switch (*(u_char *)frame->tf_rip) { case 0xcf: /* iret */ - vframe = (void *)((u_int64_t)&frame.tf_rsp - 44); + vframe = (void *)((u_int64_t)&frame->tf_rsp - 44); resume = resume_iret; break; default: @@ -262,7 +261,7 @@ copyfault: if (KERNELMODE(vframe->tf_cs, vframe->tf_rflags)) goto we_re_toast; - frame.tf_rip = (u_int64_t)resume; + frame->tf_rip = (u_int64_t)resume; return; case T_PROTFLT|T_USER: /* protection fault */ @@ -272,23 +271,23 @@ copyfault: case T_NMI|T_USER: #ifdef TRAP_SIGDEBUG printf("pid %d (%s): BUS at rip %lx addr %lx\n", - p->p_pid, p->p_comm, frame.tf_rip, rcr2()); - frame_dump(&frame); + p->p_pid, p->p_comm, frame->tf_rip, rcr2()); + frame_dump(frame); #endif - sv.sival_ptr = (void *)frame.tf_rip; + sv.sival_ptr = (void *)frame->tf_rip; KERNEL_PROC_LOCK(p); trapsignal(p, SIGBUS, type & ~T_USER, BUS_OBJERR, sv); KERNEL_PROC_UNLOCK(p); goto out; case T_ALIGNFLT|T_USER: - sv.sival_ptr = (void *)frame.tf_rip; + sv.sival_ptr = (void *)frame->tf_rip; KERNEL_PROC_LOCK(p); trapsignal(p, SIGBUS, type & ~T_USER, BUS_ADRALN, sv); KERNEL_PROC_UNLOCK(p); goto out; case T_PRIVINFLT|T_USER: /* privileged instruction fault */ - sv.sival_ptr = (void *)frame.tf_rip; + sv.sival_ptr = (void *)frame->tf_rip; KERNEL_PROC_LOCK(p); trapsignal(p, SIGILL, type & ~T_USER, ILL_PRVOPC, sv); KERNEL_PROC_UNLOCK(p); @@ -296,10 +295,10 @@ copyfault: case T_FPOPFLT|T_USER: /* coprocessor operand fault */ #ifdef TRAP_SIGDEBUG printf("pid %d (%s): ILL at rip %lx addr %lx\n", - p->p_pid, p->p_comm, frame.tf_rip, rcr2()); - frame_dump(&frame); + p->p_pid, p->p_comm, frame->tf_rip, rcr2()); + frame_dump(frame); #endif - sv.sival_ptr = (void *)frame.tf_rip; + sv.sival_ptr = (void *)frame->tf_rip; KERNEL_PROC_LOCK(p); trapsignal(p, SIGILL, type & ~T_USER, ILL_COPROC, sv); KERNEL_PROC_UNLOCK(p); @@ -318,19 +317,19 @@ copyfault: goto out; case T_BOUND|T_USER: - sv.sival_ptr = (void *)frame.tf_rip; + sv.sival_ptr = (void *)frame->tf_rip; KERNEL_PROC_LOCK(p); trapsignal(p, SIGFPE, type &~ T_USER, FPE_FLTSUB, sv); KERNEL_PROC_UNLOCK(p); goto out; case T_OFLOW|T_USER: - sv.sival_ptr = (void *)frame.tf_rip; + sv.sival_ptr = (void *)frame->tf_rip; KERNEL_PROC_LOCK(p); trapsignal(p, SIGFPE, type &~ T_USER, FPE_INTOVF, sv); KERNEL_PROC_UNLOCK(p); goto out; case T_DIVIDE|T_USER: - sv.sival_ptr = (void *)frame.tf_rip; + sv.sival_ptr = (void *)frame->tf_rip; KERNEL_PROC_LOCK(p); trapsignal(p, SIGFPE, type &~ T_USER, FPE_INTDIV, sv); KERNEL_PROC_UNLOCK(p); @@ -338,7 +337,7 @@ copyfault: case T_ARITHTRAP|T_USER: case T_XMM|T_USER: - fputrap(&frame); + fputrap(frame); goto out; case T_PAGEFLT: /* allow page faults in kernel mode */ @@ -375,9 +374,9 @@ faultcommon: map = kernel_map; else map = &vm->vm_map; - if (frame.tf_err & PGEX_W) + if (frame->tf_err & PGEX_W) ftype = VM_PROT_WRITE; - else if (frame.tf_err & PGEX_I) + else if (frame->tf_err & PGEX_I) ftype = VM_PROT_EXECUTE; else ftype = VM_PROT_READ; @@ -392,7 +391,7 @@ faultcommon: /* Fault the original page in. */ onfault = pcb->pcb_onfault; pcb->pcb_onfault = NULL; - error = uvm_fault(map, va, frame.tf_err & PGEX_P? + error = uvm_fault(map, va, frame->tf_err & PGEX_P? VM_FAULT_PROTECT : VM_FAULT_INVALID, ftype); pcb->pcb_onfault = onfault; if (error == 0) { @@ -429,8 +428,8 @@ faultcommon: } else { #ifdef TRAP_SIGDEBUG printf("pid %d (%s): SEGV at rip %lx addr %lx\n", - p->p_pid, p->p_comm, frame.tf_rip, va); - frame_dump(&frame); + p->p_pid, p->p_comm, frame->tf_rip, va); + frame_dump(frame); #endif sv.sival_ptr = (void *)fa; trapsignal(p, SIGSEGV, T_PAGEFLT, SEGV_MAPERR, sv); @@ -444,10 +443,10 @@ faultcommon: case T_TRCTRAP: /* Check whether they single-stepped into a lcall. */ - if (frame.tf_rip == (register_t)IDTVEC(oosyscall)) + if (frame->tf_rip == (register_t)IDTVEC(oosyscall)) return; - if (frame.tf_rip == (register_t)IDTVEC(oosyscall) + 1) { - frame.tf_rflags &= ~PSL_T; + if (frame->tf_rip == (register_t)IDTVEC(oosyscall) + 1) { + frame->tf_rflags &= ~PSL_T; return; } goto we_re_toast; @@ -469,11 +468,11 @@ faultcommon: printf ("NMI ... going to debugger\n"); #ifdef KGDB - if (kgdb_trap(type, &frame)) + if (kgdb_trap(type, frame)) return; #endif #ifdef DDB - if (kdb_trap(type, 0, &frame)) + if (kdb_trap(type, 0, frame)) return; #endif #endif /* KGDB || DDB */ |