Skip to content

Commit d5ba0c9

Browse files
Ivan Kokshayskyjfvogel
Ivan Kokshaysky
authored andcommitted
alpha: make stack 16-byte aligned (most cases)
commit 0a0f7362b0367634a2d5cb7c96226afc116f19c9 upstream. The problem is that GCC expects 16-byte alignment of the incoming stack since early 2004, as Maciej found out [1]: Having actually dug speculatively I can see that the psABI was changed in GCC 3.5 with commit e5e10fb4a350 ("re PR target/14539 (128-bit long double improperly aligned)") back in Mar 2004, when the stack pointer alignment was increased from 8 bytes to 16 bytes, and arch/alpha/kernel/entry.S has various suspicious stack pointer adjustments, starting with SP_OFF which is not a whole multiple of 16. Also, as Magnus noted, "ALPHA Calling Standard" [2] required the same: D.3.1 Stack Alignment This standard requires that stacks be octaword aligned at the time a new procedure is invoked. However: - the "normal" kernel stack is always misaligned by 8 bytes, thanks to the odd number of 64-bit words in 'struct pt_regs', which is the very first thing pushed onto the kernel thread stack; - syscall, fault, interrupt etc. handlers may, or may not, receive aligned stack depending on numerous factors. Somehow we got away with it until recently, when we ended up with a stack corruption in kernel/smp.c:smp_call_function_single() due to its use of 32-byte aligned local data and the compiler doing clever things allocating it on the stack. This adds padding between the PAL-saved and kernel-saved registers so that 'struct pt_regs' have an even number of 64-bit words. This makes the stack properly aligned for most of the kernel code, except two handlers which need special threatment. Note: struct pt_regs doesn't belong in uapi/asm; this should be fixed, but let's put this off until later. Link: https://lore.kernel.org/rcu/[email protected]/ [1] Link: https://bitsavers.org/pdf/dec/alpha/Alpha_Calling_Standard_Rev_2.0_19900427.pdf [2] Cc: [email protected] Tested-by: Maciej W. Rozycki <[email protected]> Tested-by: Magnus Lindholm <[email protected]> Tested-by: Matt Turner <[email protected]> Reviewed-by: Maciej W. Rozycki <[email protected]> Signed-off-by: Ivan Kokshaysky <[email protected]> Signed-off-by: Matt Turner <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> (cherry picked from commit 2c637b4aa50ff3bfc57b6e28413f9e2c0f823990) Signed-off-by: Jack Vogel <[email protected]>
1 parent da798db commit d5ba0c9

File tree

1 file changed

+2
-0
lines changed

1 file changed

+2
-0
lines changed

arch/alpha/include/uapi/asm/ptrace.h

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ struct pt_regs {
4242
unsigned long trap_a0;
4343
unsigned long trap_a1;
4444
unsigned long trap_a2;
45+
/* This makes the stack 16-byte aligned as GCC expects */
46+
unsigned long __pad0;
4547
/* These are saved by PAL-code: */
4648
unsigned long ps;
4749
unsigned long pc;

0 commit comments

Comments
 (0)