compat_13_machdep.c revision 1.22
11.22Snakayama/* $NetBSD: compat_13_machdep.c,v 1.22 2008/11/23 01:10:00 nakayama Exp $ */ 21.1Sthorpej 31.1Sthorpej/*- 41.1Sthorpej * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 51.1Sthorpej * All rights reserved. 61.1Sthorpej * 71.1Sthorpej * This code is derived from software contributed to The NetBSD Foundation 81.1Sthorpej * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 91.1Sthorpej * NASA Ames Research Center. 101.1Sthorpej * 111.1Sthorpej * Redistribution and use in source and binary forms, with or without 121.1Sthorpej * modification, are permitted provided that the following conditions 131.1Sthorpej * are met: 141.1Sthorpej * 1. Redistributions of source code must retain the above copyright 151.1Sthorpej * notice, this list of conditions and the following disclaimer. 161.1Sthorpej * 2. Redistributions in binary form must reproduce the above copyright 171.1Sthorpej * notice, this list of conditions and the following disclaimer in the 181.1Sthorpej * documentation and/or other materials provided with the distribution. 191.1Sthorpej * 201.1Sthorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 211.1Sthorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 221.1Sthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 231.1Sthorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 241.1Sthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 251.1Sthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 261.1Sthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 271.1Sthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 281.1Sthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 291.1Sthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 301.1Sthorpej * POSSIBILITY OF SUCH DAMAGE. 311.1Sthorpej */ 321.14Slukem 331.14Slukem#include <sys/cdefs.h> 341.22Snakayama__KERNEL_RCSID(0, "$NetBSD: compat_13_machdep.c,v 1.22 2008/11/23 01:10:00 nakayama Exp $"); 351.7Smrg 361.22Snakayama#ifdef _KERNEL_OPT 371.7Smrg#include "opt_ddb.h" 381.22Snakayama#endif 391.1Sthorpej 401.1Sthorpej#include <sys/param.h> 411.1Sthorpej#include <sys/systm.h> 421.1Sthorpej#include <sys/proc.h> 431.1Sthorpej#include <sys/user.h> 441.1Sthorpej#include <sys/kernel.h> 451.1Sthorpej#include <sys/mount.h> 461.1Sthorpej#include <sys/signal.h> 471.1Sthorpej#include <sys/signalvar.h> 481.1Sthorpej 491.1Sthorpej#include <sys/syscallargs.h> 501.5Seeh#include <sparc64/sparc64/sigdebug.h> 511.1Sthorpej 521.15Schristos#include <compat/sys/signal.h> 531.15Schristos#include <compat/sys/signalvar.h> 541.1Sthorpej/* 551.1Sthorpej * System call to cleanup state after a signal 561.1Sthorpej * has been taken. Reset signal mask and 571.1Sthorpej * stack state from context left by sendsig (above), 581.1Sthorpej * and return to the given trap frame (if there is one). 591.1Sthorpej * Check carefully to make sure that the user has not 601.1Sthorpej * modified the state to gain improper privileges or to cause 611.1Sthorpej * a machine fault. 621.1Sthorpej */ 631.1Sthorpej/* ARGSUSED */ 641.1Sthorpejint 651.19Sdslcompat_13_sys_sigreturn(struct lwp *l, const struct compat_13_sys_sigreturn_args *uap, register_t *retval) 661.1Sthorpej{ 671.19Sdsl /* { 681.1Sthorpej syscallarg(struct sigcontext13 *) sigcntxp; 691.19Sdsl } */ 701.1Sthorpej struct sigcontext13 sc, *scp; 711.13Sthorpej struct trapframe64 *tf; 721.17Sad struct proc *p = l->l_proc; 731.1Sthorpej sigset_t mask; 741.1Sthorpej 751.1Sthorpej /* First ensure consistent stack state (see sendsig). */ 761.1Sthorpej write_user_windows(); 771.13Sthorpej if (rwindow_save(l)) { 781.5Seeh#ifdef DEBUG 791.13Sthorpej printf("compat_13_sys_sigreturn: rwindow_save(%p) failed, sending SIGILL\n", l); 801.8Spk#ifdef DDB 811.5Seeh Debugger(); 821.5Seeh#endif 831.8Spk#endif 841.20Sad mutex_enter(p->p_lock); 851.13Sthorpej sigexit(l, SIGILL); 861.5Seeh } 871.5Seeh#ifdef DEBUG 881.5Seeh if (sigdebug & SDB_FOLLOW) { 891.5Seeh printf("compat_13_sys_sigreturn: %s[%d], sigcntxp %p\n", 901.5Seeh p->p_comm, p->p_pid, SCARG(uap, sigcntxp)); 911.8Spk#ifdef DDB 921.5Seeh if (sigdebug & SDB_DDB) Debugger(); 931.8Spk#endif 941.5Seeh } 951.5Seeh#endif 961.1Sthorpej 971.1Sthorpej scp = SCARG(uap, sigcntxp); 981.18Schristos if ((vaddr_t)scp & 3 || (copyin((void *)scp, &sc, sizeof sc) != 0)) 991.5Seeh#ifdef DEBUG 1001.5Seeh { 1011.5Seeh printf("compat_13_sys_sigreturn: copyin failed: scp=%p\n", scp); 1021.8Spk#ifdef DDB 1031.5Seeh Debugger(); 1041.8Spk#endif 1051.1Sthorpej return (EFAULT); 1061.5Seeh } 1071.5Seeh#else 1081.5Seeh return (EFAULT); 1091.5Seeh#endif 1101.5Seeh 1111.1Sthorpej scp = ≻ 1121.1Sthorpej 1131.13Sthorpej tf = l->l_md.md_tf; 1141.1Sthorpej /* 1151.1Sthorpej * Only the icc bits in the psr are used, so it need not be 1161.1Sthorpej * verified. pc and npc must be multiples of 4. This is all 1171.1Sthorpej * that is required; if it holds, just do it. 1181.1Sthorpej */ 1191.3Seeh if (((scp->sc_pc | scp->sc_npc) & 3) != 0 || scp->sc_pc == 0 || scp->sc_npc == 0) 1201.3Seeh#ifdef DEBUG 1211.3Seeh { 1221.12Seeh printf("compat_13_sys_sigreturn: pc %p or npc %p invalid\n", 1231.12Seeh (void *)scp->sc_pc, (void *)scp->sc_npc); 1241.8Spk#ifdef DDB 1251.3Seeh Debugger(); 1261.8Spk#endif 1271.3Seeh return (EINVAL); 1281.3Seeh } 1291.3Seeh#endif 1301.1Sthorpej return (EINVAL); 1311.1Sthorpej /* take only psr ICC field */ 1321.4Smrg#ifdef __arch64__ 1331.2Seeh tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) | scp->sc_tstate; 1341.2Seeh#else 1351.1Sthorpej tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) | PSRCC_TO_TSTATE(scp->sc_psr); 1361.2Seeh#endif 1371.1Sthorpej tf->tf_pc = scp->sc_pc; 1381.1Sthorpej tf->tf_npc = scp->sc_npc; 1391.1Sthorpej tf->tf_global[1] = scp->sc_g1; 1401.1Sthorpej tf->tf_out[0] = scp->sc_o0; 1411.1Sthorpej tf->tf_out[6] = scp->sc_sp; 1421.5Seeh#ifdef DEBUG 1431.5Seeh if (sigdebug & SDB_FOLLOW) { 1441.12Seeh printf("compat_13_sys_sigreturn: return trapframe pc=%llx sp=%llx tstate=%llx\n", 1451.12Seeh (long long)tf->tf_pc, (long long)tf->tf_out[6], 1461.12Seeh (long long)tf->tf_tstate); 1471.8Spk#ifdef DDB 1481.5Seeh if (sigdebug & SDB_DDB) Debugger(); 1491.8Spk#endif 1501.5Seeh } 1511.5Seeh#endif 1521.1Sthorpej 1531.20Sad mutex_enter(p->p_lock); 1541.1Sthorpej if (scp->sc_onstack & SS_ONSTACK) 1551.17Sad l->l_sigstk.ss_flags |= SS_ONSTACK; 1561.1Sthorpej else 1571.17Sad l->l_sigstk.ss_flags &= ~SS_ONSTACK; 1581.1Sthorpej 1591.1Sthorpej /* Restore signal mask */ 1601.1Sthorpej native_sigset13_to_sigset(&scp->sc_mask, &mask); 1611.17Sad (void) sigprocmask1(l, SIG_SETMASK, &mask, 0); 1621.20Sad mutex_exit(p->p_lock); 1631.1Sthorpej 1641.1Sthorpej return (EJUSTRETURN); 1651.1Sthorpej} 166