Home | History | Annotate | Line # | Download | only in mips
      1 /*	$NetBSD: compat_13_machdep.c,v 1.23 2025/04/24 12:54:43 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 1996 The Board of Trustees of The Leland Stanford
      5  * Junior University. All Rights Reserved.
      6  *
      7  * Permission to use, copy, modify, and distribute this
      8  * software and its documentation for any purpose and without
      9  * fee is hereby granted, provided that the above copyright
     10  * notice appear in all copies.  Stanford University
     11  * makes no representations about the suitability of this
     12  * software for any purpose.  It is provided "as is" without
     13  * express or implied warranty.
     14  */
     15 
     16 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
     17 
     18 __KERNEL_RCSID(0, "$NetBSD: compat_13_machdep.c,v 1.23 2025/04/24 12:54:43 riastradh Exp $");
     19 
     20 #include <sys/param.h>
     21 #include <sys/systm.h>
     22 #include <sys/signalvar.h>
     23 #include <sys/kernel.h>
     24 #include <sys/proc.h>
     25 #include <sys/mount.h>
     26 #include <sys/syscallargs.h>
     27 
     28 #include <compat/sys/signal.h>
     29 #include <compat/sys/signalvar.h>
     30 
     31 #include <mips/regnum.h>
     32 #include <mips/locore.h>
     33 #include <mips/pcb.h>
     34 
     35 #ifdef DEBUG
     36 extern int sigdebug;
     37 /* XXX defined in mips_machdep.c */
     38 #define SDB_FOLLOW	0x01
     39 #define SDB_KSTACK	0x02
     40 #define SDB_FPSTATE	0x04
     41 #endif
     42 
     43 #if !defined(__mips_o32)
     44 #define	fpreg		fpreg_oabi
     45 #endif
     46 
     47 int
     48 compat_13_sys_sigreturn(struct lwp *l, const struct compat_13_sys_sigreturn_args *uap, register_t *retval)
     49 {
     50 	/* {
     51 		syscallarg(struct sigcontext13 *) sigcntxp;
     52 	} */
     53 	struct sigcontext13 *scp, ksc;
     54 	struct proc *p = l->l_proc;
     55 	int error;
     56 	struct trapframe *tf = l->l_md.md_utf;
     57 	sigset_t mask;
     58 
     59 #if !defined(__mips_o32)
     60 	if (p->p_md.md_abi != _MIPS_BSD_API_O32)
     61 		return ENOSYS;
     62 #endif
     63 
     64 	/*
     65 	 * The trampoline code hands us the context.
     66 	 * It is unsafe to keep track of it ourselves, in the event that a
     67 	 * program jumps out of a signal handler.
     68 	 */
     69 	scp = SCARG(uap, sigcntxp);
     70 #ifdef DEBUG
     71 	if (sigdebug & SDB_FOLLOW)
     72 		printf("sigreturn13: pid %d, scp %p\n", p->p_pid, scp);
     73 #endif
     74 	if ((error = copyin(scp, &ksc, sizeof(ksc))) != 0)
     75 		return (error);
     76 
     77 	if ((uint32_t)ksc.sc_regs[_R_ZERO] != 0xacedbadeU)/* magic number */
     78 		return (EINVAL);
     79 
     80 	/* Restore the register context. */
     81 	tf->tf_regs[_R_PC] = ksc.sc_pc;
     82 	tf->tf_regs[_R_MULLO] = ksc.mullo;
     83 	tf->tf_regs[_R_MULHI] = ksc.mulhi;
     84 #if defined(__mips_o32)
     85 	memcpy(&tf->tf_regs[1], &scp->sc_regs[1],
     86 	    sizeof(scp->sc_regs) - sizeof(scp->sc_regs[0]));
     87 #else
     88 	for (size_t i = 1; i < __arraycount(scp->sc_regs); i++)
     89 		tf->tf_regs[i] = scp->sc_regs[i];
     90 #endif
     91 	if (scp->sc_fpused) {
     92 		struct pcb * const pcb = lwp_getpcb(l);
     93 		*(struct fpreg *)&pcb->pcb_fpregs = *(struct fpreg *)scp->sc_fpregs;
     94 	}
     95 
     96 	mutex_enter(p->p_lock);
     97 
     98 	/* Restore signal stack. */
     99 	if (ksc.sc_onstack & SS_ONSTACK)
    100 		l->l_sigstk.ss_flags |= SS_ONSTACK;
    101 	else
    102 		l->l_sigstk.ss_flags &= ~SS_ONSTACK;
    103 
    104 	/* Restore signal mask. */
    105 	native_sigset13_to_sigset(&ksc.sc_mask, &mask);
    106 	(void) sigprocmask1(l, SIG_SETMASK, &mask, 0);
    107 
    108 	mutex_exit(p->p_lock);
    109 
    110 	return (EJUSTRETURN);
    111 }
    112