summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus F.X.J. Oberhumer <markus@oberhumer.com>2005-10-09 18:54:23 +0200
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-10 17:45:06 +0200
commitd347f372273c2b3d86a66e2e1c94c790c208e166 (patch)
tree2015798f0acdc66866765438343f992326db51ad
parent[PATCH] ide: Workaround PM problem (diff)
downloadlinux-d347f372273c2b3d86a66e2e1c94c790c208e166.tar.xz
linux-d347f372273c2b3d86a66e2e1c94c790c208e166.zip
[PATCH] i386: fix stack alignment for signal handlers
This fixes the setup of the alignment of the signal frame, so that all signal handlers are run with a properly aligned stack frame. The current code "over-aligns" the stack pointer so that the stack frame is effectively always mis-aligned by 4 bytes. But what we really want is that on function entry ((sp + 4) & 15) == 0, which matches what would happen if the stack were aligned before a "call" instruction. Signed-off-by: Markus F.X.J. Oberhumer <markus@oberhumer.com> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/i386/kernel/signal.c6
-rw-r--r--arch/x86_64/ia32/ia32_signal.c6
2 files changed, 10 insertions, 2 deletions
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index 61eb0c8a6e47..adcd069db91e 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -338,7 +338,11 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
esp = (unsigned long) ka->sa.sa_restorer;
}
- return (void __user *)((esp - frame_size) & -8ul);
+ esp -= frame_size;
+ /* Align the stack pointer according to the i386 ABI,
+ * i.e. so that on function entry ((sp + 4) & 15) == 0. */
+ esp = ((esp + 4) & -16ul) - 4;
+ return (void __user *) esp;
}
/* These symbols are defined with the addresses in the vsyscall page.
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
index 66e2821533db..0903cc1faef2 100644
--- a/arch/x86_64/ia32/ia32_signal.c
+++ b/arch/x86_64/ia32/ia32_signal.c
@@ -425,7 +425,11 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
rsp = (unsigned long) ka->sa.sa_restorer;
}
- return (void __user *)((rsp - frame_size) & -8UL);
+ rsp -= frame_size;
+ /* Align the stack pointer according to the i386 ABI,
+ * i.e. so that on function entry ((sp + 4) & 15) == 0. */
+ rsp = ((rsp + 4) & -16ul) - 4;
+ return (void __user *) rsp;
}
int ia32_setup_frame(int sig, struct k_sigaction *ka,