sparc: Align clone and signal stacks to 16 bytes.
authorDavid S. Miller <davem@davemloft.net>
Wed, 10 Feb 2010 00:18:40 +0000 (16:18 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 10 Feb 2010 00:18:40 +0000 (16:18 -0800)
This is mandatory for 64-bit processes, and doing it also for 32-bit
processes saves a conditional in the compat case.

This fixes the glibc/nptl/tst-stdio1 test case, as well
as many others, on 64-bit.

Signed-off-by: David S. Miller <davem@davemloft.net>
arch/sparc/kernel/process_32.c
arch/sparc/kernel/process_64.c
arch/sparc/kernel/signal32.c
arch/sparc/kernel/signal_32.c
arch/sparc/kernel/signal_64.c

index 2830b41..f23c8fd 100644 (file)
@@ -526,7 +526,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
                         * Set some valid stack frames to give to the child.
                         */
                        childstack = (struct sparc_stackf __user *)
-                               (sp & ~0x7UL);
+                               (sp & ~0x15UL);
                        parentstack = (struct sparc_stackf __user *)
                                regs->u_regs[UREG_FP];
 
index 18d6785..6679eeb 100644 (file)
@@ -406,11 +406,11 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp)
        } else
                __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6]));
 
-       /* Now 8-byte align the stack as this is mandatory in the
-        * Sparc ABI due to how register windows work.  This hides
-        * the restriction from thread libraries etc.  -DaveM
+       /* Now align the stack as this is mandatory in the Sparc ABI
+        * due to how register windows work.  This hides the
+        * restriction from thread libraries etc.
         */
-       csp &= ~7UL;
+       csp &= ~15UL;
 
        distance = fp - psp;
        rval = (csp - distance);
index ba5b09a..ea22cd3 100644 (file)
@@ -120,8 +120,8 @@ struct rt_signal_frame32 {
 };
 
 /* Align macros */
-#define SF_ALIGNEDSZ  (((sizeof(struct signal_frame32) + 7) & (~7)))
-#define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame32) + 7) & (~7)))
+#define SF_ALIGNEDSZ  (((sizeof(struct signal_frame32) + 15) & (~15)))
+#define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame32) + 15) & (~15)))
 
 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 {
@@ -420,15 +420,17 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns
                        sp = current->sas_ss_sp + current->sas_ss_size;
        }
 
+       sp -= framesize;
+
        /* Always align the stack frame.  This handles two cases.  First,
         * sigaltstack need not be mindful of platform specific stack
         * alignment.  Second, if we took this signal because the stack
         * is not aligned properly, we'd like to take the signal cleanly
         * and report that.
         */
-       sp &= ~7UL;
+       sp &= ~15UL;
 
-       return (void __user *)(sp - framesize);
+       return (void __user *) sp;
 }
 
 static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
index 7ce1a10..9882df9 100644 (file)
@@ -267,15 +267,17 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re
                        sp = current->sas_ss_sp + current->sas_ss_size;
        }
 
+       sp -= framesize;
+
        /* Always align the stack frame.  This handles two cases.  First,
         * sigaltstack need not be mindful of platform specific stack
         * alignment.  Second, if we took this signal because the stack
         * is not aligned properly, we'd like to take the signal cleanly
         * and report that.
         */
-       sp &= ~7UL;
+       sp &= ~15UL;
 
-       return (void __user *)(sp - framesize);
+       return (void __user *) sp;
 }
 
 static inline int
index 647afbd..9fa48c3 100644 (file)
@@ -353,7 +353,7 @@ segv:
 /* Checks if the fp is valid */
 static int invalid_frame_pointer(void __user *fp, int fplen)
 {
-       if (((unsigned long) fp) & 7)
+       if (((unsigned long) fp) & 15)
                return 1;
        return 0;
 }
@@ -396,15 +396,17 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *
                        sp = current->sas_ss_sp + current->sas_ss_size;
        }
 
+       sp -= framesize;
+
        /* Always align the stack frame.  This handles two cases.  First,
         * sigaltstack need not be mindful of platform specific stack
         * alignment.  Second, if we took this signal because the stack
         * is not aligned properly, we'd like to take the signal cleanly
         * and report that.
         */
-       sp &= ~7UL;
+       sp &= ~15UL;
 
-       return (void __user *)(sp - framesize);
+       return (void __user *) sp;
 }
 
 static inline void