Index: sys/amd64/amd64/trap.c =================================================================== --- sys/amd64/amd64/trap.c +++ sys/amd64/amd64/trap.c @@ -970,8 +970,8 @@ panic("double fault"); } -int -cpu_fetch_syscall_args(struct thread *td) +int __noinline +cpu_fetch_syscall_args_fallback(struct thread *td) { struct proc *p; struct trapframe *frame; @@ -1022,6 +1022,54 @@ return (error); } +int +cpu_fetch_syscall_args(struct thread *td) +{ + struct proc *p; + struct trapframe *frame; + register_t *argp; + struct syscall_args *sa; + int reg, regcnt; + + p = td->td_proc; + frame = td->td_frame; + sa = &td->td_sa; + reg = 0; + regcnt = 6; + + sa->code = frame->tf_rax; + + if (__predict_false(sa->code == SYS_syscall)) + goto fallback; + + if (__predict_false(sa->code == SYS___syscall)) + goto fallback; + + if (__predict_false(sa->code >= p->p_sysent->sv_size)) + goto fallback; + + sa->callp = &p->p_sysent->sv_table[sa->code]; + sa->narg = sa->callp->sy_narg; + KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]), + ("Too many syscall arguments!")); + + if (p->p_sysent->sv_mask) + sa->code &= p->p_sysent->sv_mask; + + if (__predict_false(sa->narg > regcnt)) + goto fallback; + + argp = &frame->tf_rdi; + memcpy(sa->args, argp, sizeof(sa->args[0]) * 6); + + td->td_retval[0] = 0; + td->td_retval[1] = frame->tf_rdx; + + return (0); +fallback: + return (cpu_fetch_syscall_args_fallback(td)); +} + #include "../../kern/subr_syscall.c" /*