Commit f036d9f3 authored by David S. Miller's avatar David S. Miller

sparc: Align clone and signal stacks to 16 bytes.

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: default avatarDavid S. Miller <davem@davemloft.net>
parent 6abce771
...@@ -526,7 +526,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, ...@@ -526,7 +526,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
* Set some valid stack frames to give to the child. * Set some valid stack frames to give to the child.
*/ */
childstack = (struct sparc_stackf __user *) childstack = (struct sparc_stackf __user *)
(sp & ~0x7UL); (sp & ~0x15UL);
parentstack = (struct sparc_stackf __user *) parentstack = (struct sparc_stackf __user *)
regs->u_regs[UREG_FP]; regs->u_regs[UREG_FP];
......
...@@ -406,11 +406,11 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) ...@@ -406,11 +406,11 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp)
} else } else
__get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6]));
/* Now 8-byte align the stack as this is mandatory in the /* Now align the stack as this is mandatory in the Sparc ABI
* Sparc ABI due to how register windows work. This hides * due to how register windows work. This hides the
* the restriction from thread libraries etc. -DaveM * restriction from thread libraries etc.
*/ */
csp &= ~7UL; csp &= ~15UL;
distance = fp - psp; distance = fp - psp;
rval = (csp - distance); rval = (csp - distance);
......
...@@ -120,8 +120,8 @@ struct rt_signal_frame32 { ...@@ -120,8 +120,8 @@ struct rt_signal_frame32 {
}; };
/* Align macros */ /* Align macros */
#define SF_ALIGNEDSZ (((sizeof(struct signal_frame32) + 7) & (~7))) #define SF_ALIGNEDSZ (((sizeof(struct signal_frame32) + 15) & (~15)))
#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 7) & (~7))) #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 15) & (~15)))
int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) 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 ...@@ -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 = current->sas_ss_sp + current->sas_ss_size;
} }
sp -= framesize;
/* Always align the stack frame. This handles two cases. First, /* Always align the stack frame. This handles two cases. First,
* sigaltstack need not be mindful of platform specific stack * sigaltstack need not be mindful of platform specific stack
* alignment. Second, if we took this signal because the stack * alignment. Second, if we took this signal because the stack
* is not aligned properly, we'd like to take the signal cleanly * is not aligned properly, we'd like to take the signal cleanly
* and report that. * 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) static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
......
...@@ -267,15 +267,17 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re ...@@ -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 = current->sas_ss_sp + current->sas_ss_size;
} }
sp -= framesize;
/* Always align the stack frame. This handles two cases. First, /* Always align the stack frame. This handles two cases. First,
* sigaltstack need not be mindful of platform specific stack * sigaltstack need not be mindful of platform specific stack
* alignment. Second, if we took this signal because the stack * alignment. Second, if we took this signal because the stack
* is not aligned properly, we'd like to take the signal cleanly * is not aligned properly, we'd like to take the signal cleanly
* and report that. * and report that.
*/ */
sp &= ~7UL; sp &= ~15UL;
return (void __user *)(sp - framesize); return (void __user *) sp;
} }
static inline int static inline int
......
...@@ -353,7 +353,7 @@ segv: ...@@ -353,7 +353,7 @@ segv:
/* Checks if the fp is valid */ /* Checks if the fp is valid */
static int invalid_frame_pointer(void __user *fp, int fplen) static int invalid_frame_pointer(void __user *fp, int fplen)
{ {
if (((unsigned long) fp) & 7) if (((unsigned long) fp) & 15)
return 1; return 1;
return 0; return 0;
} }
...@@ -396,15 +396,17 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs * ...@@ -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 = current->sas_ss_sp + current->sas_ss_size;
} }
sp -= framesize;
/* Always align the stack frame. This handles two cases. First, /* Always align the stack frame. This handles two cases. First,
* sigaltstack need not be mindful of platform specific stack * sigaltstack need not be mindful of platform specific stack
* alignment. Second, if we took this signal because the stack * alignment. Second, if we took this signal because the stack
* is not aligned properly, we'd like to take the signal cleanly * is not aligned properly, we'd like to take the signal cleanly
* and report that. * and report that.
*/ */
sp &= ~7UL; sp &= ~15UL;
return (void __user *)(sp - framesize); return (void __user *) sp;
} }
static inline void static inline void
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment