Re: alt signal stack fixes

2012-11-29 Thread Philip Guenther
On Fri, Nov 16, 2012 at 11:45 AM, Philip Guenther guent...@gmail.com wrote:
 The diff below changes the alt sig stack logic to dynamically determine
 whether the thread is currently on the alt stack, 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/
...

Ping?  Hello, anyone?

I've gotten no test reports on this, not even didn't break anything reports.

No one cares about sigaltstack()?


Philip Guenther



alt signal stack fixes

2012-11-16 Thread Philip Guenther
The diff below changes the alt sig stack logic to dynamically determine 
whether the thread is currently on the alt stack, 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 changed: the logic on vax for deciding whether to switch stacks was 
completely broken, such that it would never switch.  This updates it to 
match the other platforms, which should make it happier.

Tested on amd64, sparc64, and i386; needs testing on the other platforms 
at the least.


I'm not sure if the PROC_STACK() macro is the best API.  In particular, my 
current implementation on alpha will only work on curproc, which is all 
that it's currently needed for.  The obvious change to make it just always 
operate on curproc is less than idea, as curproc isn't cheap on all 
platforms and the caller in this case at least will always have it 
handy...


Philip Guenther

Index: sys/arch/alpha/alpha/machdep.c
===
RCS file: /cvs/src/sys/arch/alpha/alpha/machdep.c,v
retrieving revision 1.139
diff -u -p -r1.139 machdep.c
--- sys/arch/alpha/alpha/machdep.c  1 Nov 2012 21:09:17 -   1.139
+++ sys/arch/alpha/alpha/machdep.c  16 Nov 2012 17:58:58 -
@@ -1431,11 +1431,12 @@ sendsig(catcher, sig, mask, code, type, 
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, 
 * 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, 
/* 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;
Index: sys/arch/alpha/include/cpu.h
===
RCS file: /cvs/src/sys/arch/alpha/include/cpu.h,v
retrieving revision 1.45
diff -u -p -r1.45 cpu.h
--- sys/arch/alpha/include/cpu.h1 Nov 2012 21:09:17 -   1.45
+++ sys/arch/alpha/include/cpu.h16 Nov 2012 17:58:58 -
@@ -275,6 +275,7 @@ struct clockframe {
  * This is used during profiling to integrate system time.
  */
 #definePROC_PC(p)  ((p)-p_md.md_tf-tf_regs[FRAME_PC])
+#definePROC_STACK(p)   (alpha_pal_rdusp()) /*XXX only works for 
curproc */
 
 /*
  * Preempt the current process if in interrupt from user mode,
Index: sys/arch/alpha/include/signal.h
===
RCS file: /cvs/src/sys/arch/alpha/include/signal.h,v
retrieving revision 1.7
diff -u -p -r1.7 signal.h
--- sys/arch/alpha/include/signal.h 23 Mar