1293b5c22SAndrew Turner /* $NetBSD: fault.c,v 1.45 2003/11/20 14:44:36 scw Exp $ */ 2293b5c22SAndrew Turner 3293b5c22SAndrew Turner /*- 4293b5c22SAndrew Turner * Copyright 2004 Olivier Houchard 5293b5c22SAndrew Turner * Copyright 2003 Wasabi Systems, Inc. 6293b5c22SAndrew Turner * All rights reserved. 7293b5c22SAndrew Turner * 8293b5c22SAndrew Turner * Written by Steve C. Woodford for Wasabi Systems, Inc. 9293b5c22SAndrew Turner * 10293b5c22SAndrew Turner * Redistribution and use in source and binary forms, with or without 11293b5c22SAndrew Turner * modification, are permitted provided that the following conditions 12293b5c22SAndrew Turner * are met: 13293b5c22SAndrew Turner * 1. Redistributions of source code must retain the above copyright 14293b5c22SAndrew Turner * notice, this list of conditions and the following disclaimer. 15293b5c22SAndrew Turner * 2. Redistributions in binary form must reproduce the above copyright 16293b5c22SAndrew Turner * notice, this list of conditions and the following disclaimer in the 17293b5c22SAndrew Turner * documentation and/or other materials provided with the distribution. 18293b5c22SAndrew Turner * 3. All advertising materials mentioning features or use of this software 19293b5c22SAndrew Turner * must display the following acknowledgement: 20293b5c22SAndrew Turner * This product includes software developed for the NetBSD Project by 21293b5c22SAndrew Turner * Wasabi Systems, Inc. 22293b5c22SAndrew Turner * 4. The name of Wasabi Systems, Inc. may not be used to endorse 23293b5c22SAndrew Turner * or promote products derived from this software without specific prior 24293b5c22SAndrew Turner * written permission. 25293b5c22SAndrew Turner * 26293b5c22SAndrew Turner * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 27293b5c22SAndrew Turner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28293b5c22SAndrew Turner * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29293b5c22SAndrew Turner * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 30293b5c22SAndrew Turner * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31293b5c22SAndrew Turner * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32293b5c22SAndrew Turner * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33293b5c22SAndrew Turner * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34293b5c22SAndrew Turner * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35293b5c22SAndrew Turner * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36293b5c22SAndrew Turner * POSSIBILITY OF SUCH DAMAGE. 37293b5c22SAndrew Turner */ 38293b5c22SAndrew Turner /*- 39293b5c22SAndrew Turner * Copyright (c) 1994-1997 Mark Brinicombe. 40293b5c22SAndrew Turner * Copyright (c) 1994 Brini. 41293b5c22SAndrew Turner * All rights reserved. 42293b5c22SAndrew Turner * 43293b5c22SAndrew Turner * This code is derived from software written for Brini by Mark Brinicombe 44293b5c22SAndrew Turner * 45293b5c22SAndrew Turner * Redistribution and use in source and binary forms, with or without 46293b5c22SAndrew Turner * modification, are permitted provided that the following conditions 47293b5c22SAndrew Turner * are met: 48293b5c22SAndrew Turner * 1. Redistributions of source code must retain the above copyright 49293b5c22SAndrew Turner * notice, this list of conditions and the following disclaimer. 50293b5c22SAndrew Turner * 2. Redistributions in binary form must reproduce the above copyright 51293b5c22SAndrew Turner * notice, this list of conditions and the following disclaimer in the 52293b5c22SAndrew Turner * documentation and/or other materials provided with the distribution. 53293b5c22SAndrew Turner * 3. All advertising materials mentioning features or use of this software 54293b5c22SAndrew Turner * must display the following acknowledgement: 55293b5c22SAndrew Turner * This product includes software developed by Brini. 56293b5c22SAndrew Turner * 4. The name of the company nor the name of the author may be used to 57293b5c22SAndrew Turner * endorse or promote products derived from this software without specific 58293b5c22SAndrew Turner * prior written permission. 59293b5c22SAndrew Turner * 60293b5c22SAndrew Turner * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED 61293b5c22SAndrew Turner * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 62293b5c22SAndrew Turner * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 63293b5c22SAndrew Turner * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 64293b5c22SAndrew Turner * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 65293b5c22SAndrew Turner * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 66293b5c22SAndrew Turner * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 67293b5c22SAndrew Turner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 68293b5c22SAndrew Turner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 69293b5c22SAndrew Turner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 70293b5c22SAndrew Turner * SUCH DAMAGE. 71293b5c22SAndrew Turner * 72293b5c22SAndrew Turner * RiscBSD kernel project 73293b5c22SAndrew Turner * 74293b5c22SAndrew Turner * fault.c 75293b5c22SAndrew Turner * 76293b5c22SAndrew Turner * Fault handlers 77293b5c22SAndrew Turner * 78293b5c22SAndrew Turner * Created : 28/11/94 79293b5c22SAndrew Turner */ 80293b5c22SAndrew Turner 81293b5c22SAndrew Turner 82293b5c22SAndrew Turner #include <sys/cdefs.h> 83293b5c22SAndrew Turner __FBSDID("$FreeBSD$"); 84293b5c22SAndrew Turner 85293b5c22SAndrew Turner #include <sys/param.h> 86293b5c22SAndrew Turner #include <sys/systm.h> 87*95d7f8aaSAndrew Turner #include <sys/kernel.h> 88293b5c22SAndrew Turner #include <sys/proc.h> 89293b5c22SAndrew Turner #include <sys/lock.h> 90293b5c22SAndrew Turner #include <sys/mutex.h> 91293b5c22SAndrew Turner #include <sys/syscall.h> 92293b5c22SAndrew Turner #include <sys/sysent.h> 93293b5c22SAndrew Turner #include <sys/signalvar.h> 94293b5c22SAndrew Turner #include <sys/ptrace.h> 95293b5c22SAndrew Turner #include <sys/pioctl.h> 96293b5c22SAndrew Turner 97293b5c22SAndrew Turner #include <machine/frame.h> 98293b5c22SAndrew Turner 99293b5c22SAndrew Turner void swi_handler(struct trapframe *); 100293b5c22SAndrew Turner 101293b5c22SAndrew Turner static __inline void 102293b5c22SAndrew Turner call_trapsignal(struct thread *td, int sig, u_long code) 103293b5c22SAndrew Turner { 104293b5c22SAndrew Turner ksiginfo_t ksi; 105293b5c22SAndrew Turner 106293b5c22SAndrew Turner ksiginfo_init_trap(&ksi); 107293b5c22SAndrew Turner ksi.ksi_signo = sig; 108293b5c22SAndrew Turner ksi.ksi_code = (int)code; 109293b5c22SAndrew Turner trapsignal(td, &ksi); 110293b5c22SAndrew Turner } 111293b5c22SAndrew Turner 112293b5c22SAndrew Turner int 113293b5c22SAndrew Turner cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa) 114293b5c22SAndrew Turner { 115293b5c22SAndrew Turner struct proc *p; 116293b5c22SAndrew Turner register_t *ap; 117293b5c22SAndrew Turner int error; 118293b5c22SAndrew Turner 119293b5c22SAndrew Turner sa->code = td->td_frame->tf_r7; 120293b5c22SAndrew Turner ap = &td->td_frame->tf_r0; 121293b5c22SAndrew Turner if (sa->code == SYS_syscall) { 122293b5c22SAndrew Turner sa->code = *ap++; 123293b5c22SAndrew Turner sa->nap--; 124293b5c22SAndrew Turner } else if (sa->code == SYS___syscall) { 125293b5c22SAndrew Turner sa->code = ap[_QUAD_LOWWORD]; 126293b5c22SAndrew Turner sa->nap -= 2; 127293b5c22SAndrew Turner ap += 2; 128293b5c22SAndrew Turner } 129293b5c22SAndrew Turner p = td->td_proc; 130293b5c22SAndrew Turner if (p->p_sysent->sv_mask) 131293b5c22SAndrew Turner sa->code &= p->p_sysent->sv_mask; 132293b5c22SAndrew Turner if (sa->code >= p->p_sysent->sv_size) 133293b5c22SAndrew Turner sa->callp = &p->p_sysent->sv_table[0]; 134293b5c22SAndrew Turner else 135293b5c22SAndrew Turner sa->callp = &p->p_sysent->sv_table[sa->code]; 136293b5c22SAndrew Turner sa->narg = sa->callp->sy_narg; 137293b5c22SAndrew Turner error = 0; 138293b5c22SAndrew Turner memcpy(sa->args, ap, sa->nap * sizeof(register_t)); 139293b5c22SAndrew Turner if (sa->narg > sa->nap) { 140293b5c22SAndrew Turner error = copyin((void *)td->td_frame->tf_usr_sp, sa->args + 141293b5c22SAndrew Turner sa->nap, (sa->narg - sa->nap) * sizeof(register_t)); 142293b5c22SAndrew Turner } 143293b5c22SAndrew Turner if (error == 0) { 144293b5c22SAndrew Turner td->td_retval[0] = 0; 145293b5c22SAndrew Turner td->td_retval[1] = 0; 146293b5c22SAndrew Turner } 147293b5c22SAndrew Turner return (error); 148293b5c22SAndrew Turner } 149293b5c22SAndrew Turner 150293b5c22SAndrew Turner #include "../../kern/subr_syscall.c" 151293b5c22SAndrew Turner 152293b5c22SAndrew Turner static void 153293b5c22SAndrew Turner syscall(struct thread *td, struct trapframe *frame) 154293b5c22SAndrew Turner { 155293b5c22SAndrew Turner struct syscall_args sa; 156293b5c22SAndrew Turner int error; 157293b5c22SAndrew Turner 158293b5c22SAndrew Turner sa.nap = 4; 159293b5c22SAndrew Turner 160293b5c22SAndrew Turner error = syscallenter(td, &sa); 161293b5c22SAndrew Turner KASSERT(error != 0 || td->td_ar == NULL, 162293b5c22SAndrew Turner ("returning from syscall with td_ar set!")); 163293b5c22SAndrew Turner syscallret(td, error, &sa); 164293b5c22SAndrew Turner } 165293b5c22SAndrew Turner 166293b5c22SAndrew Turner void 167293b5c22SAndrew Turner swi_handler(struct trapframe *frame) 168293b5c22SAndrew Turner { 169293b5c22SAndrew Turner struct thread *td = curthread; 170293b5c22SAndrew Turner 171293b5c22SAndrew Turner td->td_frame = frame; 172293b5c22SAndrew Turner 173293b5c22SAndrew Turner td->td_pticks = 0; 174293b5c22SAndrew Turner /* 175293b5c22SAndrew Turner * Make sure the program counter is correctly aligned so we 176293b5c22SAndrew Turner * don't take an alignment fault trying to read the opcode. 177293b5c22SAndrew Turner * XXX: Fix for Thumb mode 178293b5c22SAndrew Turner */ 179293b5c22SAndrew Turner if (__predict_false(((frame->tf_pc - INSN_SIZE) & 3) != 0)) { 180293b5c22SAndrew Turner call_trapsignal(td, SIGILL, 0); 181293b5c22SAndrew Turner userret(td, frame); 182293b5c22SAndrew Turner return; 183293b5c22SAndrew Turner } 184293b5c22SAndrew Turner /* 185293b5c22SAndrew Turner * Enable interrupts if they were enabled before the exception. 186293b5c22SAndrew Turner * Since all syscalls *should* come from user mode it will always 187293b5c22SAndrew Turner * be safe to enable them, but check anyway. 188293b5c22SAndrew Turner */ 189293b5c22SAndrew Turner if (td->td_md.md_spinlock_count == 0) { 190293b5c22SAndrew Turner if (__predict_true(frame->tf_spsr & PSR_I) == 0) 191293b5c22SAndrew Turner enable_interrupts(PSR_I); 192293b5c22SAndrew Turner if (__predict_true(frame->tf_spsr & PSR_F) == 0) 193293b5c22SAndrew Turner enable_interrupts(PSR_F); 194293b5c22SAndrew Turner } 195293b5c22SAndrew Turner 196293b5c22SAndrew Turner syscall(td, frame); 197293b5c22SAndrew Turner } 198