compat_13_machdep.c revision 1.22
1/* $NetBSD: compat_13_machdep.c,v 1.22 2008/11/23 01:10:00 nakayama Exp $ */ 2 3/*- 4 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> 34__KERNEL_RCSID(0, "$NetBSD: compat_13_machdep.c,v 1.22 2008/11/23 01:10:00 nakayama Exp $"); 35 36#ifdef _KERNEL_OPT 37#include "opt_ddb.h" 38#endif 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/proc.h> 43#include <sys/user.h> 44#include <sys/kernel.h> 45#include <sys/mount.h> 46#include <sys/signal.h> 47#include <sys/signalvar.h> 48 49#include <sys/syscallargs.h> 50#include <sparc64/sparc64/sigdebug.h> 51 52#include <compat/sys/signal.h> 53#include <compat/sys/signalvar.h> 54/* 55 * System call to cleanup state after a signal 56 * has been taken. Reset signal mask and 57 * stack state from context left by sendsig (above), 58 * and return to the given trap frame (if there is one). 59 * Check carefully to make sure that the user has not 60 * modified the state to gain improper privileges or to cause 61 * a machine fault. 62 */ 63/* ARGSUSED */ 64int 65compat_13_sys_sigreturn(struct lwp *l, const struct compat_13_sys_sigreturn_args *uap, register_t *retval) 66{ 67 /* { 68 syscallarg(struct sigcontext13 *) sigcntxp; 69 } */ 70 struct sigcontext13 sc, *scp; 71 struct trapframe64 *tf; 72 struct proc *p = l->l_proc; 73 sigset_t mask; 74 75 /* First ensure consistent stack state (see sendsig). */ 76 write_user_windows(); 77 if (rwindow_save(l)) { 78#ifdef DEBUG 79 printf("compat_13_sys_sigreturn: rwindow_save(%p) failed, sending SIGILL\n", l); 80#ifdef DDB 81 Debugger(); 82#endif 83#endif 84 mutex_enter(p->p_lock); 85 sigexit(l, SIGILL); 86 } 87#ifdef DEBUG 88 if (sigdebug & SDB_FOLLOW) { 89 printf("compat_13_sys_sigreturn: %s[%d], sigcntxp %p\n", 90 p->p_comm, p->p_pid, SCARG(uap, sigcntxp)); 91#ifdef DDB 92 if (sigdebug & SDB_DDB) Debugger(); 93#endif 94 } 95#endif 96 97 scp = SCARG(uap, sigcntxp); 98 if ((vaddr_t)scp & 3 || (copyin((void *)scp, &sc, sizeof sc) != 0)) 99#ifdef DEBUG 100 { 101 printf("compat_13_sys_sigreturn: copyin failed: scp=%p\n", scp); 102#ifdef DDB 103 Debugger(); 104#endif 105 return (EFAULT); 106 } 107#else 108 return (EFAULT); 109#endif 110 111 scp = ≻ 112 113 tf = l->l_md.md_tf; 114 /* 115 * Only the icc bits in the psr are used, so it need not be 116 * verified. pc and npc must be multiples of 4. This is all 117 * that is required; if it holds, just do it. 118 */ 119 if (((scp->sc_pc | scp->sc_npc) & 3) != 0 || scp->sc_pc == 0 || scp->sc_npc == 0) 120#ifdef DEBUG 121 { 122 printf("compat_13_sys_sigreturn: pc %p or npc %p invalid\n", 123 (void *)scp->sc_pc, (void *)scp->sc_npc); 124#ifdef DDB 125 Debugger(); 126#endif 127 return (EINVAL); 128 } 129#endif 130 return (EINVAL); 131 /* take only psr ICC field */ 132#ifdef __arch64__ 133 tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) | scp->sc_tstate; 134#else 135 tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) | PSRCC_TO_TSTATE(scp->sc_psr); 136#endif 137 tf->tf_pc = scp->sc_pc; 138 tf->tf_npc = scp->sc_npc; 139 tf->tf_global[1] = scp->sc_g1; 140 tf->tf_out[0] = scp->sc_o0; 141 tf->tf_out[6] = scp->sc_sp; 142#ifdef DEBUG 143 if (sigdebug & SDB_FOLLOW) { 144 printf("compat_13_sys_sigreturn: return trapframe pc=%llx sp=%llx tstate=%llx\n", 145 (long long)tf->tf_pc, (long long)tf->tf_out[6], 146 (long long)tf->tf_tstate); 147#ifdef DDB 148 if (sigdebug & SDB_DDB) Debugger(); 149#endif 150 } 151#endif 152 153 mutex_enter(p->p_lock); 154 if (scp->sc_onstack & SS_ONSTACK) 155 l->l_sigstk.ss_flags |= SS_ONSTACK; 156 else 157 l->l_sigstk.ss_flags &= ~SS_ONSTACK; 158 159 /* Restore signal mask */ 160 native_sigset13_to_sigset(&scp->sc_mask, &mask); 161 (void) sigprocmask1(l, SIG_SETMASK, &mask, 0); 162 mutex_exit(p->p_lock); 163 164 return (EJUSTRETURN); 165} 166