Skip to content

Commit

Permalink
sparc: Align clone and signal stacks to 16 bytes.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
David S. Miller committed Feb 10, 2010
1 parent 6abce77 commit f036d9f
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 14 deletions.
2 changes: 1 addition & 1 deletion arch/sparc/kernel/process_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down
8 changes: 4 additions & 4 deletions arch/sparc/kernel/process_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
10 changes: 6 additions & 4 deletions arch/sparc/kernel/signal32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 4 additions & 2 deletions arch/sparc/kernel/signal_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 5 additions & 3 deletions arch/sparc/kernel/signal_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ void do_rt_sigreturn(struct pt_regs *regs)
/* 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;
}
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit f036d9f

Please sign in to comment.