Subject: Re: Kernel
To: Colin Wood <cwood@ichips.intel.com>
From: Chas Williams <chas@cmf.nrl.navy.mil>
List: port-mac68k
Date: 09/24/1998 17:31:12
In message <199809242050.NAA24934@pdxcs204.pdx.intel.com>,Colin Wood writes:
>The problem is that the libc signal stuff broke shortly before this was
>fixed, so we haven't had a working snapshot built in a couple of weeks :-(

i took a look at this yesterday and today and i have a diff that will 
produce a running kernel with current sources (as of yesterday).

it runs fine for 99% of things, the only exception being using 'suspend'
with su. (this leads me to suspect an error in my compat_13_sys_sigreturn()
not restoring the signal mask correctly)

i wont have any more time over the next couple days, i thought
someone else might take a look and see what i missed.

here are the diffs (apply in /usr/src/sys/arch):

diff -r -u mac68k.orig/mac68k/locore.s mac68k/mac68k/locore.s
--- mac68k.orig/mac68k/locore.s	Wed Sep  9 04:19:43 1998
+++ mac68k/mac68k/locore.s	Thu Sep 24 13:16:05 1998
@@ -80,6 +80,7 @@
 #include "opt_ddb.h"
 #include "opt_uvm.h"
 #include "assym.h"
+#include <sys/syscall.h>
 #include <machine/asm.h>
 #include <machine/trap.h>
 
diff -r -u mac68k.orig/mac68k/trap.c mac68k/mac68k/trap.c
--- mac68k.orig/mac68k/trap.c	Sun Jul  5 04:10:09 1998
+++ mac68k/mac68k/trap.c	Thu Sep 24 14:28:49 1998
@@ -428,11 +428,13 @@
 		printf("pid %d: kernel %s exception\n", p->p_pid,
 		    type==T_COPERR ? "coprocessor" : "format");
 		type |= T_USER;
+#ifdef notdef
 		p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL;
 		i = sigmask(SIGILL);
 		p->p_sigignore &= ~i;
 		p->p_sigcatch &= ~i;
 		p->p_sigmask &= ~i;
+#endif
 		i = SIGILL;
 		ucode = frame.f_format;	/* XXX was ILL_RESAD_FAULT */
 		break;
@@ -1074,7 +1076,7 @@
 		 * that is only done if entered via the sigreturn
 		 * trap.  Cannot allow here, so make sure we fail.
 		 */
-		if (code == SYS_sigreturn)
+		if (code == SYS___sigreturn14)
 			code = nsys;
 		break;
 	case SYS___syscall:
diff -P -r -u m68k.orig/conf/files.m68k m68k/conf/files.m68k
--- m68k.orig/conf/files.m68k	Mon May 25 04:13:25 1998
+++ m68k/conf/files.m68k	Thu Sep 24 08:37:55 1998
@@ -15,5 +15,6 @@
 file	arch/m68k/m68k/process_machdep.c
 file	arch/m68k/m68k/regdump.c
 file	arch/m68k/m68k/sig_machdep.c
+file	arch/m68k/m68k/compat_13_machdep.c
 
 include "../../../compat/m68k4k/files.m68k4k"
diff -P -r -u m68k.orig/conf/mfi m68k/conf/mfi
--- m68k.orig/conf/mfi	Wed Dec 31 16:00:00 1969
+++ m68k/conf/mfi	Thu Sep 24 08:37:24 1998
@@ -0,0 +1,19 @@
+#       $NetBSD: files.m68k,v 1.22 1998/05/24 19:32:42 is Exp $
+#
+file	arch/m68k/m68k/bcopy.s
+file	arch/m68k/m68k/copy.s
+file	arch/m68k/m68k/copypage.s
+file	arch/m68k/m68k/db_disasm.c		ddb
+file	arch/m68k/m68k/db_interface.c		ddb
+file	arch/m68k/m68k/db_trace.c		ddb
+file	arch/m68k/m68k/in_cksum.c		inet
+file	arch/m68k/m68k/kgdb_m68k.c		kgdb
+file	arch/m68k/m68k/m68k_machdep.c
+file	arch/m68k/m68k/mappedcopy.c		mappedcopy
+file	arch/m68k/m68k/ns_cksum.c		ns
+file	arch/m68k/m68k/oc_cksum.s		inet
+file	arch/m68k/m68k/process_machdep.c
+file	arch/m68k/m68k/regdump.c
+file	arch/m68k/m68k/sig_machdep.c
+
+include "../../../compat/m68k4k/files.m68k4k"
diff -P -r -u m68k.orig/m68k/compat_13_machdep.c m68k/m68k/compat_13_machdep.c
--- m68k.orig/m68k/compat_13_machdep.c	Wed Dec 31 16:00:00 1969
+++ m68k/m68k/compat_13_machdep.c	Thu Sep 24 13:42:42 1998
@@ -0,0 +1,249 @@
+/*	$NetBSD: sig_machdep.c,v 1.4.2.1 1998/02/07 01:02:15 mellon Exp $	*/
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1986, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: Utah Hdr: machdep.c 1.74 92/12/20
+ *	from: @(#)machdep.c	8.10 (Berkeley) 4/20/94
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/exec.h>
+#include <sys/ioctl.h>
+#include <sys/mount.h>
+#include <sys/signal.h>
+#include <sys/signalvar.h>
+#include <sys/malloc.h>
+#include <sys/buf.h>
+
+#include <vm/vm.h>
+
+#include <sys/syscallargs.h>
+
+#include <machine/cpu.h>
+#include <machine/reg.h>
+
+extern int fputype;
+extern short exframesize[];
+void	m68881_save __P((struct fpframe *));
+void	m68881_restore __P((struct fpframe *));
+
+#define SS_RTEFRAME	1
+#define SS_FPSTATE	2
+#define SS_USERREGS	4
+
+struct sigstate {
+	int	ss_flags;		/* which of the following are valid */
+	struct	frame ss_frame;		/* original exception frame */
+	struct	fpframe ss_fpstate;	/* 68881/68882 state info */
+};
+
+/*
+ * WARNING: code in locore.s assumes the layout shown for sf_signum
+ * thru sf_handler so... don't screw with them!
+ */
+struct sigframe {
+	int	sf_signum;		/* signo for handler */
+	int	sf_code;		/* additional info for handler */
+	struct	sigcontext *sf_scp;	/* context ptr for handler */
+	sig_t	sf_handler;		/* handler addr for u_sigc */
+	struct	sigstate sf_state;	/* state of the hardware */
+	struct	sigcontext sf_sc;	/* actual context */
+};
+
+#ifdef DEBUG
+int sigdebug = 0;
+int sigpid = 0;
+#define SDB_FOLLOW	0x01
+#define SDB_KSTACK	0x02
+#define SDB_FPSTATE	0x04
+#endif
+
+
+/*
+ * System call to cleanup state after a signal
+ * has been taken.  Reset signal mask and
+ * stack state from context left by sendsig (above).
+ * Return to previous pc and psl as specified by
+ * context left by sendsig. Check carefully to
+ * make sure that the user has not modified the
+ * psl to gain improper priviledges or to cause
+ * a machine fault.
+ */
+int
+compat_13_sys_sigreturn(p, v, retval)
+	struct proc *p;
+	void *v;
+	register_t *retval;
+{
+	struct compat_13_sys_sigreturn_args /* {
+		syscallarg(struct sigcontext *) sigcntxp;
+	} */ *uap = v;
+	struct sigcontext13 *scp, context;
+	struct frame *frame;
+	register int rf;
+	struct sigstate tstate;
+	int flags;
+	sigset_t mask;
+
+	scp = SCARG(uap, sigcntxp);
+
+#ifdef DEBUG
+	if (sigdebug & SDB_FOLLOW)
+		printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
+#endif
+	if ((int)scp & 1)
+		return (EINVAL);
+
+	/*
+	 * Test and fetch the context structure.
+	 * We grab it all at once for speed.
+	 */
+	if (copyin((caddr_t)scp, (caddr_t)&context, sizeof(*scp)) != 0)
+		return (EFAULT);
+
+	scp = &context;
+	if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0)
+		return (EINVAL);
+
+	/*
+	 * We'll restore infomation in this structure.
+	 */
+	frame = (struct frame *) p->p_md.md_regs;
+
+	/*
+	 * Grab pointer to hardware state information.
+	 * If zero, the user is probably doing a longjmp.
+	 */
+	if ((rf = scp->sc_ap) == 0)
+		goto restore;
+	/*
+	 * See if there is anything to do before we go to the
+	 * expense of copying in close to 1/2K of data
+	 */
+	flags = fuword((caddr_t)rf);
+#ifdef DEBUG
+	if (sigdebug & SDB_FOLLOW)
+		printf("sigreturn(%d): sc_ap %x flags %x\n",
+		       p->p_pid, rf, flags);
+#endif
+	/*
+	 * fuword failed (bogus sc_ap value).
+	 */
+	if (flags == -1)
+		return (EINVAL);
+	if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate))
+		goto restore;
+#ifdef DEBUG
+	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
+		printf("sigreturn(%d): ssp %p usp %x scp %p ft %d\n",
+		       p->p_pid, &flags, scp->sc_sp, SCARG(uap, sigcntxp),
+		       (flags&SS_RTEFRAME) ? tstate.ss_frame.f_format : -1);
+#endif
+	/*
+	 * Restore long stack frames.  Note that we do not copy
+	 * back the saved SR or PC, they were picked up above from
+	 * the sigcontext structure.
+	 */
+	if (flags & SS_RTEFRAME) {
+		register int sz;
+
+		/* grab frame type and validate */
+		sz = tstate.ss_frame.f_format;
+		if (sz > 15 || (sz = exframesize[sz]) < 0
+				|| frame->f_stackadj < sz)
+			return (EINVAL);
+		frame->f_stackadj -= sz;
+		frame->f_format = tstate.ss_frame.f_format;
+		frame->f_vector = tstate.ss_frame.f_vector;
+		bcopy((caddr_t)&tstate.ss_frame.F_u, (caddr_t)&frame->F_u, sz);
+#ifdef DEBUG
+		if (sigdebug & SDB_FOLLOW)
+			printf("sigreturn(%d): copy in %d of frame type %d\n",
+			       p->p_pid, sz, tstate.ss_frame.f_format);
+#endif
+	}
+
+	/*
+	 * Restore most of the users registers except for A6 and SP
+	 * which will be handled below.
+	 */
+	if (flags & SS_USERREGS)
+		bcopy((caddr_t)tstate.ss_frame.f_regs,
+		      (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW);
+	/*
+	 * Restore the original FP context
+	 */
+	if (fputype && (flags & SS_FPSTATE))
+		m68881_restore(&tstate.ss_fpstate);
+
+	/*
+	 * Restore the user supplied information.
+	 * This should be at the last so that the error (EINVAL)
+	 * is reported to the sigreturn caller, not to the
+	 * jump destination.
+	 */
+restore:
+	frame->f_regs[SP] = scp->sc_sp;
+	frame->f_regs[A6] = scp->sc_fp;
+	frame->f_pc = scp->sc_pc;
+	frame->f_sr = scp->sc_ps;
+
+	if (scp->sc_onstack & SS_ONSTACK)
+		p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
+	else
+		p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
+
+	/* Restore signal mask. */
+	native_sigset13_to_sigset(&scp->sc_mask, &mask);
+	(void) sigprocmask1(p, SIG_SETMASK, &mask, 0);
+
+#ifdef DEBUG
+	if ((sigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate)
+		printf("sigreturn(%d): copied in FP state (%x) at %p\n",
+		       p->p_pid, *(u_int *)&tstate.ss_fpstate,
+		       &tstate.ss_fpstate);
+	if ((sigdebug & SDB_FOLLOW) ||
+	    ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid))
+		printf("sigreturn(%d): returns\n", p->p_pid);
+#endif
+	return (EJUSTRETURN);
+}
diff -P -r -u m68k.orig/m68k/sig_machdep.c m68k/m68k/sig_machdep.c
--- m68k.orig/m68k/sig_machdep.c	Sat May  9 04:14:58 1998
+++ m68k/m68k/sig_machdep.c	Thu Sep 24 14:22:20 1998
@@ -1,4 +1,4 @@
-/*	$NetBSD: sig_machdep.c,v 1.8 1998/05/08 16:55:16 kleink Exp $	*/
+/*	$NetBSD: sig_machdep.c,v 1.4.2.1 1998/02/07 01:02:15 mellon Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -41,8 +41,6 @@
  *	from: @(#)machdep.c	8.10 (Berkeley) 4/20/94
  */
 
-#include "opt_uvm.h"
-
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
@@ -58,10 +56,6 @@
 
 #include <vm/vm.h>
 
-#if defined(UVM)
-#include <uvm/uvm_extern.h>
-#endif
-
 #include <sys/syscallargs.h>
 
 #include <machine/cpu.h>
@@ -109,20 +103,33 @@
 void
 sendsig(catcher, sig, mask, code)
 	sig_t catcher;
-	int sig, mask;
+	int sig;
+	sigset_t *mask;
 	u_long code;
 {
-	register struct proc *p = curproc;
-	register struct sigframe *fp, *kfp;
-	register struct frame *frame;
-	register struct sigacts *psp = p->p_sigacts;
-	register short ft;
-	int oonstack, fsize;
+	struct proc *p = curproc;
+	struct frame *tf;
+	struct sigframe *fp, frame;
+	struct sigacts *psp = p->p_sigacts;
+	int onstack;
+	short ft;
 	extern char sigcode[], esigcode[];
 
-	frame = (struct frame *)p->p_md.md_regs;
-	ft = frame->f_format;
-	oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
+	tf = (struct frame *)p->p_md.md_regs;
+	ft = tf->f_format;
+
+	/* Do we need to jump onto the signal stack? */
+        onstack =
+	    (psp->ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
+	    (psp->ps_sigact[sig].sa_flags & SA_ONSTACK) != 0;
+
+	/* Do we need to jump onto the signal stack? */
+        if (onstack)
+		fp = (struct sigframe *)(psp->ps_sigstk.ss_sp +
+					 psp->ps_sigstk.ss_size);
+        else
+		fp = (struct sigframe *)(tf->f_regs[SP]);
+	fp--;
 
 	/*
 	 * Allocate and validate space for the signal handler
@@ -131,53 +138,40 @@
 	 * will fail if the process has not already allocated
 	 * the space with a `brk'.
 	 */
-	fsize = sizeof(struct sigframe);
-	if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
-	    (psp->ps_sigonstack & sigmask(sig))) {
-		fp = (struct sigframe *)((caddr_t)psp->ps_sigstk.ss_sp +
-		    psp->ps_sigstk.ss_size - fsize);
-		psp->ps_sigstk.ss_flags |= SS_ONSTACK;
-	} else
-		fp = (struct sigframe *)(frame->f_regs[SP] - fsize);
-#if defined(UVM)
-	if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
-		(void)uvm_grow(p, (unsigned)fp);
-#else
-	if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
-		(void)grow(p, (unsigned)fp);
-#endif
+	/* if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
+		(void)grow(p, (unsigned)fp); 	XXX -- grow() still needed? */
 #ifdef DEBUG
 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
 		printf("sendsig(%d): sig %d ssp %p usp %p scp %p ft %d\n",
-		       p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft);
+		       p->p_pid, sig, &onstack, fp, &fp->sf_sc, ft);
 #endif
-	kfp = (struct sigframe *)malloc((u_long)fsize, M_TEMP, M_WAITOK);
 	/*
 	 * Build the argument list for the signal handler.
 	 */
-	kfp->sf_signum = sig;
-	kfp->sf_code = code;
-	kfp->sf_scp = &fp->sf_sc;
-	kfp->sf_handler = catcher;
+	frame.sf_signum = sig;
+	frame.sf_code = code;
+	frame.sf_scp = &fp->sf_sc;
+	frame.sf_handler = catcher;
+
 	/*
 	 * Save necessary hardware state.  Currently this includes:
 	 *	- general registers
 	 *	- original exception frame (if not a "normal" frame)
 	 *	- FP coprocessor state
 	 */
-	kfp->sf_state.ss_flags = SS_USERREGS;
-	bcopy((caddr_t)frame->f_regs,
-	      (caddr_t)kfp->sf_state.ss_frame.f_regs, sizeof frame->f_regs);
+	frame.sf_state.ss_flags = SS_USERREGS;
+	bcopy((caddr_t)tf->f_regs,
+	      (caddr_t)&frame.sf_state.ss_frame.f_regs, sizeof tf->f_regs);
 	if (ft >= FMT4) {
 #ifdef DEBUG
 		if (ft > 15 || exframesize[ft] < 0)
 			panic("sendsig: bogus frame type");
 #endif
-		kfp->sf_state.ss_flags |= SS_RTEFRAME;
-		kfp->sf_state.ss_frame.f_format = frame->f_format;
-		kfp->sf_state.ss_frame.f_vector = frame->f_vector;
-		bcopy((caddr_t)&frame->F_u,
-		      (caddr_t)&kfp->sf_state.ss_frame.F_u,
+		frame.sf_state.ss_flags |= SS_RTEFRAME;
+		frame.sf_state.ss_frame.f_format = tf->f_format;
+		frame.sf_state.ss_frame.f_vector = tf->f_vector;
+		bcopy((caddr_t)&tf->F_u,
+		      (caddr_t)&frame.sf_state.ss_frame.F_u,
 			  (size_t) exframesize[ft]);
 		/*
 		 * Leave an indicator that we need to clean up the kernel
@@ -189,8 +183,8 @@
 		 * case we are called from syscall when processing a
 		 * sigreturn.  In that case, f_stackadj may be non-zero.
 		 */
-		frame->f_stackadj += exframesize[ft];
-		frame->f_format = frame->f_vector = 0;
+		tf->f_stackadj += exframesize[ft];
+		tf->f_format = tf->f_vector = 0;
 #ifdef DEBUG
 		if (sigdebug & SDB_FOLLOW)
 			printf("sendsig(%d): copy out %d of frame %d\n",
@@ -199,28 +193,39 @@
 	}
 
 	if (fputype) {
-		kfp->sf_state.ss_flags |= SS_FPSTATE;
-		m68881_save(&kfp->sf_state.ss_fpstate);
+		frame.sf_state.ss_flags |= SS_FPSTATE;
+		m68881_save(&frame.sf_state.ss_fpstate);
 	}
 #ifdef DEBUG
-	if ((sigdebug & SDB_FPSTATE) && *(char *)&kfp->sf_state.ss_fpstate)
+	if ((sigdebug & SDB_FPSTATE) && *(char *)&frame.sf_state.ss_fpstate)
 		printf("sendsig(%d): copy out FP state (%x) to %p\n",
-		       p->p_pid, *(u_int *)&kfp->sf_state.ss_fpstate,
-		       &kfp->sf_state.ss_fpstate);
+		       p->p_pid, *(u_int *)&frame.sf_state.ss_fpstate,
+		       &frame.sf_state.ss_fpstate);
 #endif
 
-	/*
-	 * Build the signal context to be used by sigreturn.
-	 */
-	kfp->sf_sc.sc_onstack = oonstack;
-	kfp->sf_sc.sc_mask = mask;
-	kfp->sf_sc.sc_sp = frame->f_regs[SP];
-	kfp->sf_sc.sc_fp = frame->f_regs[A6];
-	kfp->sf_sc.sc_ap = (int)&fp->sf_state;
-	kfp->sf_sc.sc_pc = frame->f_pc;
-	kfp->sf_sc.sc_ps = frame->f_sr;
-	if (copyout((caddr_t)kfp, (caddr_t)fp, fsize)) {
-		free((caddr_t)kfp, M_TEMP);
+	frame.sf_sc.sc_sp = tf->f_regs[SP];
+	frame.sf_sc.sc_fp = tf->f_regs[A6];
+	frame.sf_sc.sc_ap = (int)&fp->sf_state;
+	frame.sf_sc.sc_pc = tf->f_pc;
+	frame.sf_sc.sc_ps = tf->f_sr;
+
+	/* Save signal stack. */
+	frame.sf_sc.sc_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
+
+	/* Save signal mask. */
+	frame.sf_sc.sc_mask = *mask;
+
+#ifdef COMPAT_13
+        /*
+         * XXX We always have to save an old style signal mask because
+         * XXX we might be delivering a signal to a process which will
+         * XXX escape from the signal in a non-standard way and invoke
+         * XXX sigreturn() directly.
+         */
+        native_sigset_to_sigset13(mask, &frame.sf_sc.__sc_mask13);
+#endif
+
+	if (copyout(&frame, fp, sizeof(frame)) != 0) {
 #ifdef DEBUG
 		if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
 			printf("sendsig(%d): copyout failed on sig %d\n",
@@ -233,23 +238,26 @@
 		sigexit(p, SIGILL);
 		/* NOTREACHED */
 	}
-	frame->f_regs[SP] = (int)fp;
+	tf->f_regs[SP] = (int)fp;
 #ifdef DEBUG
 	if (sigdebug & SDB_FOLLOW)
 		printf("sendsig(%d): sig %d scp %p fp %p sc_sp %x sc_ap %x\n",
-		       p->p_pid, sig, kfp->sf_scp, fp,
-		       kfp->sf_sc.sc_sp, kfp->sf_sc.sc_ap);
+		       p->p_pid, sig, frame.sf_scp, fp,
+		       frame.sf_sc.sc_sp, frame.sf_sc.sc_ap);
 #endif
 	/*
 	 * Signal trampoline code is at base of user stack.
 	 */
-	frame->f_pc = (int)PS_STRINGS - (esigcode - sigcode);
+	tf->f_pc = (int)PS_STRINGS - (esigcode - sigcode);
+
+	if (onstack)
+		psp->ps_sigstk.ss_flags |= SS_ONSTACK;
+
 #ifdef DEBUG
 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
 		printf("sendsig(%d): sig %d returns\n",
 		       p->p_pid, sig);
 #endif
-	free((caddr_t)kfp, M_TEMP);
 }
 
 /*
@@ -263,20 +271,22 @@
  * a machine fault.
  */
 int
-sys_sigreturn(p, v, retval)
+sys___sigreturn14(p, v, retval)
 	struct proc *p;
 	void *v;
 	register_t *retval;
 {
-	struct sys_sigreturn_args *uap = v;
-	register struct sigcontext *scp;
-	register struct frame *frame;
+	struct sys___sigreturn14_args /* {
+		syscallarg(struct sigcontext *) sigcntxp;
+	} */ *uap = v;
+	struct sigcontext *scp, context;
+	struct frame *tf;
 	register int rf;
-	struct sigcontext tsigc;
 	struct sigstate tstate;
 	int flags;
 
 	scp = SCARG(uap, sigcntxp);
+
 #ifdef DEBUG
 	if (sigdebug & SDB_FOLLOW)
 		printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
@@ -288,16 +298,17 @@
 	 * Test and fetch the context structure.
 	 * We grab it all at once for speed.
 	 */
-	if (copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc))
-		return (EINVAL);
-	scp = &tsigc;
+	if (copyin((caddr_t)scp, (caddr_t)&context, sizeof *scp))
+		return (EFAULT);
+
+	scp = &context;
 	if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0)
 		return (EINVAL);
 
 	/*
 	 * We'll restore infomation in this structure.
 	 */
-	frame = (struct frame *) p->p_md.md_regs;
+	tf = (struct frame *) p->p_md.md_regs;
 
 	/*
 	 * Grab pointer to hardware state information.
@@ -339,12 +350,12 @@
 		/* grab frame type and validate */
 		sz = tstate.ss_frame.f_format;
 		if (sz > 15 || (sz = exframesize[sz]) < 0
-				|| frame->f_stackadj < sz)
+				|| tf->f_stackadj < sz)
 			return (EINVAL);
-		frame->f_stackadj -= sz;
-		frame->f_format = tstate.ss_frame.f_format;
-		frame->f_vector = tstate.ss_frame.f_vector;
-		bcopy((caddr_t)&tstate.ss_frame.F_u, (caddr_t)&frame->F_u, sz);
+		tf->f_stackadj -= sz;
+		tf->f_format = tstate.ss_frame.f_format;
+		tf->f_vector = tstate.ss_frame.f_vector;
+		bcopy((caddr_t)&tstate.ss_frame.F_u, (caddr_t)&tf->F_u, sz);
 #ifdef DEBUG
 		if (sigdebug & SDB_FOLLOW)
 			printf("sigreturn(%d): copy in %d of frame type %d\n",
@@ -358,7 +369,7 @@
 	 */
 	if (flags & SS_USERREGS)
 		bcopy((caddr_t)tstate.ss_frame.f_regs,
-		      (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW);
+		      (caddr_t)tf->f_regs, sizeof(tf->f_regs)-2*NBPW);
 	/*
 	 * Restore the original FP context
 	 */
@@ -372,15 +383,18 @@
 	 * jump destination.
 	 */
 restore:
-	if (scp->sc_onstack & 01)
+	tf->f_regs[SP] = scp->sc_sp;
+	tf->f_regs[A6] = scp->sc_fp;
+	tf->f_pc = scp->sc_pc;
+	tf->f_sr = scp->sc_ps;
+
+	if (scp->sc_onstack & SS_ONSTACK)
 		p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
 	else
 		p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
-	p->p_sigmask = scp->sc_mask &~ sigcantmask;
-	frame->f_regs[SP] = scp->sc_sp;
-	frame->f_regs[A6] = scp->sc_fp;
-	frame->f_pc = scp->sc_pc;
-	frame->f_sr = scp->sc_ps;
+
+	/* Restore signal mask. */
+	(void) sigprocmask1(p, SIG_SETMASK, &scp->sc_mask, 0);
 
 #ifdef DEBUG
 	if ((sigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate)
diff -P -r -u m68k.orig/m68k/sigreturn.s m68k/m68k/sigreturn.s
--- m68k.orig/m68k/sigreturn.s	Fri Apr 25 04:18:51 1997
+++ m68k/m68k/sigreturn.s	Thu Sep 24 08:25:57 1998
@@ -62,7 +62,7 @@
 	moveml	#0xFFFF,sp@-		| save user registers
 	movl	usp,a0			| save the user SP
 	movl	a0,sp@(FR_SP)		|   in the savearea
-	movl	#SYS_sigreturn,sp@-	| push syscall number
+	movl	#SYS___sigreturn14,sp@-	| push syscall number
 	jbsr	_C_LABEL(syscall)	| handle it
 	addql	#4,sp			| pop syscall#
 	movl	sp@(FR_SP),a0		| grab and restore