summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2011-10-04 13:14:24 +0000
committerkib <kib@FreeBSD.org>2011-10-04 13:14:24 +0000
commite851ae50456145fb8cc7ebe235ee33d2d25da7bc (patch)
tree3b21b5ee76d9cbf356e8bfb32183d225066a9bc7 /sys/arm
parent78eb31771dca6256fe67785a81c6853c6a49dba1 (diff)
downloadFreeBSD-src-e851ae50456145fb8cc7ebe235ee33d2d25da7bc.zip
FreeBSD-src-e851ae50456145fb8cc7ebe235ee33d2d25da7bc.tar.gz
Convert ARM to the syscallenter/syscallret system call sequence handlers.
Tested by: gber MFC after: 1 month
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/arm/elf_machdep.c2
-rw-r--r--sys/arm/arm/trap.c130
-rw-r--r--sys/arm/include/proc.h11
3 files changed, 62 insertions, 81 deletions
diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c
index 5ea5615..6aec18b 100644
--- a/sys/arm/arm/elf_machdep.c
+++ b/sys/arm/arm/elf_machdep.c
@@ -76,7 +76,7 @@ struct sysentvec elf32_freebsd_sysvec = {
.sv_maxssiz = NULL,
.sv_flags = SV_ABI_FREEBSD | SV_ILP32,
.sv_set_syscall_retval = cpu_set_syscall_retval,
- .sv_fetch_syscall_args = NULL, /* XXXKIB */
+ .sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
};
diff --git a/sys/arm/arm/trap.c b/sys/arm/arm/trap.c
index c7c84d0..e56f0ff 100644
--- a/sys/arm/arm/trap.c
+++ b/sys/arm/arm/trap.c
@@ -861,98 +861,68 @@ badaddr_read(void *addr, size_t size, void *rptr)
return (rv);
}
-#define MAXARGS 8
+int
+cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+{
+ struct proc *p;
+ register_t *ap;
+ int error;
+
+ sa->code = sa->insn & 0x000fffff;
+ ap = &td->td_frame->tf_r0;
+ if (sa->code == SYS_syscall) {
+ sa->code = *ap++;
+ sa->nap--;
+ } else if (sa->code == SYS___syscall) {
+ sa->code = ap[_QUAD_LOWWORD];
+ sa->nap -= 2;
+ ap += 2;
+ }
+ p = td->td_proc;
+ if (p->p_sysent->sv_mask)
+ sa->code &= p->p_sysent->sv_mask;
+ if (sa->code >= p->p_sysent->sv_size)
+ sa->callp = &p->p_sysent->sv_table[0];
+ else
+ sa->callp = &p->p_sysent->sv_table[sa->code];
+ sa->narg = sa->callp->sy_narg;
+ error = 0;
+ memcpy(sa->args, ap, sa->nap * sizeof(register_t));
+ if (sa->narg > sa->nap) {
+ error = copyin((void *)td->td_frame->tf_usr_sp, sa->args +
+ sa->nap, (sa->narg - sa->nap) * sizeof(register_t));
+ }
+ if (error == 0) {
+ td->td_retval[0] = 0;
+ td->td_retval[1] = 0;
+ }
+ return (error);
+}
+
+#include "../../kern/subr_syscall.c"
+
static void
syscall(struct thread *td, trapframe_t *frame, u_int32_t insn)
{
- struct proc *p = td->td_proc;
- int code, error;
- u_int nap, nargs;
- register_t *ap, *args, copyargs[MAXARGS];
- struct sysent *callp;
+ struct syscall_args sa;
+ int error;
- PCPU_INC(cnt.v_syscall);
- td->td_pticks = 0;
- if (td->td_ucred != td->td_proc->p_ucred)
- cred_update_thread(td);
+ td->td_frame = frame;
+ sa.insn = insn;
switch (insn & SWI_OS_MASK) {
case 0: /* XXX: we need our own one. */
- nap = 4;
+ sa.nap = 4;
break;
default:
call_trapsignal(td, SIGILL, 0);
userret(td, frame);
return;
}
- code = insn & 0x000fffff;
- td->td_pticks = 0;
- ap = &frame->tf_r0;
- if (code == SYS_syscall) {
- code = *ap++;
-
- nap--;
- } else if (code == SYS___syscall) {
- code = ap[_QUAD_LOWWORD];
- nap -= 2;
- ap += 2;
- }
- if (p->p_sysent->sv_mask)
- code &= p->p_sysent->sv_mask;
- if (code >= p->p_sysent->sv_size)
- callp = &p->p_sysent->sv_table[0];
- else
- callp = &p->p_sysent->sv_table[code];
- nargs = callp->sy_narg;
- memcpy(copyargs, ap, nap * sizeof(register_t));
- if (nargs > nap) {
- error = copyin((void *)frame->tf_usr_sp, copyargs + nap,
- (nargs - nap) * sizeof(register_t));
- if (error)
- goto bad;
- }
- args = copyargs;
- error = 0;
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_SYSCALL))
- ktrsyscall(code, nargs, args);
-#endif
-
- CTR4(KTR_SYSC, "syscall enter thread %p pid %d proc %s code %d", td,
- td->td_proc->p_pid, td->td_name, code);
- if (error == 0) {
- td->td_retval[0] = 0;
- td->td_retval[1] = 0;
- STOPEVENT(p, S_SCE, callp->sy_narg);
- PTRACESTOP_SC(p, td, S_PT_SCE);
- AUDIT_SYSCALL_ENTER(code, td);
- error = (*callp->sy_call)(td, args);
- AUDIT_SYSCALL_EXIT(error, td);
- KASSERT(td->td_ar == NULL,
- ("returning from syscall with td_ar set!"));
- }
-bad:
- cpu_set_syscall_retval(td, error);
-
- WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
- (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
- KASSERT(td->td_critnest == 0,
- ("System call %s returning in a critical section",
- (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"));
- KASSERT(td->td_locks == 0,
- ("System call %s returning with %d locks held",
- (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???",
- td->td_locks));
-
- userret(td, frame);
- CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
- td->td_proc->p_pid, td->td_name, code);
-
- STOPEVENT(p, S_SCX, code);
- PTRACESTOP_SC(p, td, S_PT_SCX);
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_SYSRET))
- ktrsysret(code, error, td->td_retval[0]);
-#endif
+
+ error = syscallenter(td, &sa);
+ KASSERT(error != 0 || td->td_ar == NULL,
+ ("returning from syscall with td_ar set!"));
+ syscallret(td, error, &sa);
}
void
diff --git a/sys/arm/include/proc.h b/sys/arm/include/proc.h
index 7032be5..cf74d36 100644
--- a/sys/arm/include/proc.h
+++ b/sys/arm/include/proc.h
@@ -62,4 +62,15 @@ struct mdproc {
#define KINFO_PROC_SIZE 792
+#define MAXARGS 8
+struct syscall_args {
+ u_int code;
+ struct sysent *callp;
+ register_t args[MAXARGS];
+ int narg;
+ u_int nap;
+ u_int32_t insn;
+};
+#define HAVE_SYSCALL_ARGS_DEF 1
+
#endif /* !_MACHINE_PROC_H_ */
OpenPOWER on IntegriCloud