Commit cf20d1ea authored by David Mosberger-Tang's avatar David Mosberger-Tang Committed by Tony Luck

[IA64] align signal-frame even when not using alternate signal-stack

At the moment, attempting to invoke a signal-handler on the normal
stack is guaranteed to fail if the stack-pointer happens not to be
16-byte aligned.  This is because the signal-trampoline will attempt
to store fp-regs with stf.spill instructions, which will trap for
misaligned addresses.  This isn't terribly useful behavior.  It's
better to just always align the signal frame to the next lower 16-byte
boundary.
Signed-off-by: default avatarDavid Mosberger-Tang <David.Mosberger@acm.org>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent f093182d
...@@ -387,15 +387,14 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, ...@@ -387,15 +387,14 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
struct sigscratch *scr) struct sigscratch *scr)
{ {
extern char __kernel_sigtramp[]; extern char __kernel_sigtramp[];
unsigned long tramp_addr, new_rbs = 0; unsigned long tramp_addr, new_rbs = 0, new_sp;
struct sigframe __user *frame; struct sigframe __user *frame;
long err; long err;
frame = (void __user *) scr->pt.r12; new_sp = scr->pt.r12;
tramp_addr = (unsigned long) __kernel_sigtramp; tramp_addr = (unsigned long) __kernel_sigtramp;
if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags((unsigned long) frame) == 0) { if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(new_sp) == 0) {
frame = (void __user *) ((current->sas_ss_sp + current->sas_ss_size) new_sp = current->sas_ss_sp + current->sas_ss_size;
& ~(STACK_ALIGN - 1));
/* /*
* We need to check for the register stack being on the signal stack * We need to check for the register stack being on the signal stack
* separately, because it's switched separately (memory stack is switched * separately, because it's switched separately (memory stack is switched
...@@ -404,7 +403,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, ...@@ -404,7 +403,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
if (!rbs_on_sig_stack(scr->pt.ar_bspstore)) if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1); new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1);
} }
frame = (void __user *) frame - ((sizeof(*frame) + STACK_ALIGN - 1) & ~(STACK_ALIGN - 1)); frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN);
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
return force_sigsegv_info(sig, frame); return force_sigsegv_info(sig, frame);
......
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