summaryrefslogtreecommitdiff
path: root/sys/arch/alpha
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2012-12-02 07:03:33 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2012-12-02 07:03:33 +0000
commit15c7623306062239f832ef81bd0bdfc804b4d186 (patch)
treed4c341f7fa4f162d4c4cd1ede1db5c9089f0afb6 /sys/arch/alpha
parentb02dfe0ab7aae6700f0c15419373891118eab134 (diff)
Determine whether we're currently on the alternative signal stack
dynamically, by comparing the stack pointer against the altstack base and size, so that you get the correct answer if you longjmp out of the signal handler, as tested by regress/sys/kern/stackjmp/. Also, fix alt stack handling on vax, where it was completely broken. Testing and corrections by miod@, krw@, tobiasu@, pirofti@
Diffstat (limited to 'sys/arch/alpha')
-rw-r--r--sys/arch/alpha/alpha/machdep.c26
-rw-r--r--sys/arch/alpha/include/cpu.h3
-rw-r--r--sys/arch/alpha/include/signal.h4
3 files changed, 15 insertions, 18 deletions
diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c
index 264180a6993..a66a81c01d0 100644
--- a/sys/arch/alpha/alpha/machdep.c
+++ b/sys/arch/alpha/alpha/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.139 2012/11/01 21:09:17 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.140 2012/12/02 07:03:30 guenther Exp $ */
/* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */
/*-
@@ -1431,11 +1431,12 @@ sendsig(catcher, sig, mask, code, type, val)
struct fpreg *fpregs = (struct fpreg *)&ksc.sc_fpregs;
struct trapframe *frame;
struct sigacts *psp = p->p_sigacts;
- int oonstack, fsize, rndfsize, kscsize;
+ unsigned long oldsp;
+ int fsize, rndfsize, kscsize;
siginfo_t *sip, ksi;
+ oldsp = alpha_pal_rdusp();
frame = p->p_md.md_tf;
- oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
fsize = sizeof ksc;
rndfsize = ((fsize + 15) / 16) * 16;
kscsize = rndfsize;
@@ -1451,25 +1452,24 @@ sendsig(catcher, sig, mask, code, type, val)
* will fail if the process has not already allocated
* the space with a `brk'.
*/
- if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 && !oonstack &&
- (psp->ps_sigonstack & sigmask(sig))) {
+ if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
+ !sigonstack(oldsp) && (psp->ps_sigonstack & sigmask(sig)))
scp = (struct sigcontext *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - rndfsize);
- p->p_sigstk.ss_flags |= SS_ONSTACK;
- } else
- scp = (struct sigcontext *)(alpha_pal_rdusp() - rndfsize);
+ else
+ scp = (struct sigcontext *)(oldsp - rndfsize);
if ((u_long)scp <= USRSTACK - ptoa(p->p_vmspace->vm_ssize))
(void)uvm_grow(p, (u_long)scp);
#ifdef DEBUG
if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
printf("sendsig(%d): sig %d ssp %p usp %p\n", p->p_pid,
- sig, &oonstack, scp);
+ sig, &ksc, scp);
#endif
/*
* Build the signal context to be used by sigreturn.
*/
- ksc.sc_onstack = oonstack;
+ bzero(&ksc, sizeof(ksc));
ksc.sc_mask = mask;
ksc.sc_pc = frame->tf_regs[FRAME_PC];
ksc.sc_ps = frame->tf_regs[FRAME_PS];
@@ -1477,7 +1477,7 @@ sendsig(catcher, sig, mask, code, type, val)
/* copy the registers. */
frametoreg(frame, (struct reg *)ksc.sc_regs);
ksc.sc_regs[R_ZERO] = 0xACEDBADE; /* magic number */
- ksc.sc_regs[R_SP] = alpha_pal_rdusp();
+ ksc.sc_regs[R_SP] = oldsp;
/* save the floating-point state, if necessary, then copy it. */
if (p->p_addr->u_pcb.pcb_fpcpu != NULL)
@@ -1588,10 +1588,6 @@ sys_sigreturn(p, v, retval)
/*
* Restore the user-supplied information
*/
- if (ksc.sc_onstack)
- p->p_sigstk.ss_flags |= SS_ONSTACK;
- else
- p->p_sigstk.ss_flags &= ~SS_ONSTACK;
p->p_sigmask = ksc.sc_mask &~ sigcantmask;
p->p_md.md_tf->tf_regs[FRAME_PC] = ksc.sc_pc;
diff --git a/sys/arch/alpha/include/cpu.h b/sys/arch/alpha/include/cpu.h
index 24c3f2c755f..689df5d258a 100644
--- a/sys/arch/alpha/include/cpu.h
+++ b/sys/arch/alpha/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.45 2012/11/01 21:09:17 miod Exp $ */
+/* $OpenBSD: cpu.h,v 1.46 2012/12/02 07:03:30 guenther Exp $ */
/* $NetBSD: cpu.h,v 1.45 2000/08/21 02:03:12 thorpej Exp $ */
/*-
@@ -275,6 +275,7 @@ struct clockframe {
* This is used during profiling to integrate system time.
*/
#define PROC_PC(p) ((p)->p_md.md_tf->tf_regs[FRAME_PC])
+#define PROC_STACK(p) (alpha_pal_rdusp()) /*XXX only works for curproc */
/*
* Preempt the current process if in interrupt from user mode,
diff --git a/sys/arch/alpha/include/signal.h b/sys/arch/alpha/include/signal.h
index 1f446e22e1b..a5bf019502b 100644
--- a/sys/arch/alpha/include/signal.h
+++ b/sys/arch/alpha/include/signal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: signal.h,v 1.7 2011/03/23 16:54:34 pirofti Exp $ */
+/* $OpenBSD: signal.h,v 1.8 2012/12/02 07:03:31 guenther Exp $ */
/* $NetBSD: signal.h,v 1.2 1995/02/16 03:08:08 cgd Exp $ */
/*
@@ -47,7 +47,7 @@ typedef int sig_atomic_t;
* representations of 'struct reg' and 'struct fpreg', respectively.
*/
struct sigcontext {
- long sc_onstack; /* sigstack state to restore */
+ long __sc_ununsed;
long sc_mask; /* signal mask to restore */
long sc_pc; /* pc to restore */
long sc_ps; /* ps to restore */