1/* $OpenBSD: sig_machdep.c,v 1.9 2023/04/16 10:14:59 kettenis Exp $ */ 2 3/* 4 * Copyright (c) 1990 The Regents of the University of California. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * William Jolitz and Don Ahn. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 */ 39/* 40 * Copyright (c) 2001 Opsycon AB (www.opsycon.se) 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 52 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 53 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 55 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 * SUCH DAMAGE. 62 * 63 */ 64 65#include <sys/param.h> 66 67#include <sys/mount.h> /* XXX only needed by syscallargs.h */ 68#include <sys/proc.h> 69#include <sys/signal.h> 70#include <sys/signalvar.h> 71#include <sys/syscallargs.h> 72#include <sys/systm.h> 73#include <sys/user.h> 74 75#include <arm64/armreg.h> 76 77#include <machine/cpu.h> 78#include <machine/frame.h> 79#include <machine/pcb.h> 80 81#include <uvm/uvm_extern.h> 82 83static __inline struct trapframe * 84process_frame(struct proc *p) 85{ 86 return p->p_addr->u_pcb.pcb_tf; 87} 88 89/* 90 * Send an interrupt to process. 91 * 92 * Stack is set up to allow sigcode to call routine, followed by 93 * syscall to sigreturn routine below. After sigreturn resets the 94 * signal mask, the stack, and the frame pointer, it returns to the 95 * user specified pc. 96 */ 97int 98sendsig(sig_t catcher, int sig, sigset_t mask, const siginfo_t *ksip, 99 int info, int onstack) 100{ 101 struct proc *p = curproc; 102 struct trapframe *tf; 103 struct sigframe *fp, frame; 104 siginfo_t *sip = NULL; 105 int i; 106 107 tf = process_frame(p); 108 109 /* Allocate space for the signal handler context. */ 110 if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 && 111 !sigonstack(tf->tf_sp) && onstack) 112 fp = (struct sigframe *) 113 trunc_page((vaddr_t)p->p_sigstk.ss_sp + p->p_sigstk.ss_size); 114 else 115 fp = (struct sigframe *)tf->tf_sp; 116 117 /* make room on the stack */ 118 fp--; 119 120 /* make the stack aligned */ 121 fp = (struct sigframe *)STACKALIGN(fp); 122 123 /* Build stack frame for signal trampoline. */ 124 bzero(&frame, sizeof(frame)); 125 frame.sf_signum = sig; 126 127 /* Save register context. */ 128 for (i=0; i < 30; i++) 129 frame.sf_sc.sc_x[i] = tf->tf_x[i]; 130 frame.sf_sc.sc_sp = tf->tf_sp; 131 frame.sf_sc.sc_lr = tf->tf_lr; 132 frame.sf_sc.sc_elr = tf->tf_elr; 133 frame.sf_sc.sc_spsr = tf->tf_spsr; 134 135 /* Save signal mask. */ 136 frame.sf_sc.sc_mask = mask; 137 138 /* XXX Save floating point context */ 139 140 if (info) { 141 sip = &fp->sf_si; 142 frame.sf_si = *ksip; 143 } 144 145 frame.sf_sc.sc_cookie = (long)&fp->sf_sc ^ p->p_p->ps_sigcookie; 146 if (copyout(&frame, fp, sizeof(frame)) != 0) 147 return 1; 148 149 /* 150 * Build context to run handler in. We invoke the handler 151 * directly, only returning via the trampoline. 152 */ 153 tf->tf_x[0] = sig; 154 tf->tf_x[1] = (register_t)sip; 155 tf->tf_x[2] = (register_t)&fp->sf_sc; 156 tf->tf_lr = (register_t)catcher; 157 tf->tf_sp = (register_t)fp; 158 159 tf->tf_elr = p->p_p->ps_sigcode; 160 tf->tf_spsr &= ~PSR_BTYPE; 161 162 return 0; 163} 164 165/* 166 * System call to cleanup state after a signal 167 * has been taken. Reset signal mask and 168 * stack state from context left by sendsig (above). 169 * Return to previous pc and psl as specified by 170 * context left by sendsig. Check carefully to 171 * make sure that the user has not modified the 172 * psr to gain improper privileges or to cause 173 * a machine fault. 174 */ 175 176int 177sys_sigreturn(struct proc *p, void *v, register_t *retval) 178{ 179 struct sys_sigreturn_args /* { 180 syscallarg(struct sigcontext *) sigcntxp; 181 } */ *uap = v; 182 struct sigcontext ksc, *scp = SCARG(uap, sigcntxp); 183 struct trapframe *tf; 184 int i; 185 186 if (PROC_PC(p) != p->p_p->ps_sigcoderet) { 187 sigexit(p, SIGILL); 188 return (EPERM); 189 } 190 191 if (copyin(scp, &ksc, sizeof(*scp)) != 0) 192 return (EFAULT); 193 194 if (ksc.sc_cookie != ((long)scp ^ p->p_p->ps_sigcookie)) { 195 sigexit(p, SIGILL); 196 return (EFAULT); 197 } 198 199 /* Prevent reuse of the sigcontext cookie */ 200 ksc.sc_cookie = 0; 201 (void)copyout(&ksc.sc_cookie, (caddr_t)scp + 202 offsetof(struct sigcontext, sc_cookie), sizeof (ksc.sc_cookie)); 203 204 /* 205 * Make sure the processor mode has not been tampered with and 206 * interrupts have not been disabled. 207 */ 208 if ((ksc.sc_spsr & PSR_M_MASK) != PSR_M_EL0t || 209 (ksc.sc_spsr & (PSR_I | PSR_F)) != 0) 210 return (EINVAL); 211 212 /* XXX Restore floating point context */ 213 214 /* Restore register context. */ 215 tf = process_frame(p); 216 for (i=0; i < 30; i++) 217 tf->tf_x[i] = ksc.sc_x[i]; 218 tf->tf_sp = ksc.sc_sp; 219 tf->tf_lr = ksc.sc_lr; 220 tf->tf_elr = ksc.sc_elr; 221 tf->tf_spsr = ksc.sc_spsr; 222 223 /* Restore signal mask. */ 224 p->p_sigmask = ksc.sc_mask & ~sigcantmask; 225 226 return (EJUSTRETURN); 227} 228