aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2006-01-14 11:18:08 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-01-14 11:18:08 -0500
commit2dede2d8e925f4c2cb4e136b14df127685e15dd3 (patch)
tree271b3fb300c5ac143556295d10c6736430ebed85
parentda2b1cd61903c8e9796e76be2d606584f26a78e5 (diff)
[ARM] 3102/1: ARM EABI: stack pointer must be 64-bit aligned after a CPU exception
Patch from Nicolas Pitre The ARM EABI says that the stack pointer has to be 64-bit aligned for reasons already mentioned in patch #3101 when calling C functions. We therefore must verify and adjust sp accordingly when taking an exception from kernel mode since sp might not necessarily be 64-bit aligned if the exception occurs in the middle of a kernel function. If the exception occurs while in user mode then no sp fixup is needed as long as sizeof(struct pt_regs) as well as any additional syscall data stack space remain multiples of 8. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/kernel/entry-armv.S17
-rw-r--r--arch/arm/kernel/entry-header.S1
-rw-r--r--include/asm-arm/ptrace.h8
3 files changed, 23 insertions, 3 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index fb8e7f4c4b37..874e6bb79405 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -105,14 +105,24 @@ common_invalid:
105/* 105/*
106 * SVC mode handlers 106 * SVC mode handlers
107 */ 107 */
108
109#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
110#define SPFIX(code...) code
111#else
112#define SPFIX(code...)
113#endif
114
108 .macro svc_entry 115 .macro svc_entry
109 sub sp, sp, #S_FRAME_SIZE 116 sub sp, sp, #S_FRAME_SIZE
117 SPFIX( tst sp, #4 )
118 SPFIX( bicne sp, sp, #4 )
110 stmib sp, {r1 - r12} 119 stmib sp, {r1 - r12}
111 120
112 ldmia r0, {r1 - r3} 121 ldmia r0, {r1 - r3}
113 add r5, sp, #S_SP @ here for interlock avoidance 122 add r5, sp, #S_SP @ here for interlock avoidance
114 mov r4, #-1 @ "" "" "" "" 123 mov r4, #-1 @ "" "" "" ""
115 add r0, sp, #S_FRAME_SIZE @ "" "" "" "" 124 add r0, sp, #S_FRAME_SIZE @ "" "" "" ""
125 SPFIX( addne r0, r0, #4 )
116 str r1, [sp] @ save the "real" r0 copied 126 str r1, [sp] @ save the "real" r0 copied
117 @ from the exception stack 127 @ from the exception stack
118 128
@@ -303,7 +313,14 @@ __pabt_svc:
303 313
304/* 314/*
305 * User mode handlers 315 * User mode handlers
316 *
317 * EABI note: sp_svc is always 64-bit aligned here, so should S_FRAME_SIZE
306 */ 318 */
319
320#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) && (S_FRAME_SIZE & 7)
321#error "sizeof(struct pt_regs) must be a multiple of 8"
322#endif
323
307 .macro usr_entry 324 .macro usr_entry
308 sub sp, sp, #S_FRAME_SIZE 325 sub sp, sp, #S_FRAME_SIZE
309 stmib sp, {r1 - r12} 326 stmib sp, {r1 - r12}
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 648cfff93138..55c99cdab7d6 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -19,6 +19,7 @@
19@ 19@
20@ Most of the stack format comes from struct pt_regs, but with 20@ Most of the stack format comes from struct pt_regs, but with
21@ the addition of 8 bytes for storing syscall args 5 and 6. 21@ the addition of 8 bytes for storing syscall args 5 and 6.
22@ This _must_ remain a multiple of 8 for EABI.
22@ 23@
23#define S_OFF 8 24#define S_OFF 8
24 25
diff --git a/include/asm-arm/ptrace.h b/include/asm-arm/ptrace.h
index 4377e22b7e1a..f40948d54448 100644
--- a/include/asm-arm/ptrace.h
+++ b/include/asm-arm/ptrace.h
@@ -60,9 +60,11 @@
60 60
61#ifndef __ASSEMBLY__ 61#ifndef __ASSEMBLY__
62 62
63/* this struct defines the way the registers are stored on the 63/*
64 stack during a system call. */ 64 * This struct defines the way the registers are stored on the
65 65 * stack during a system call. Note that sizeof(struct pt_regs)
66 * has to be a multiple of 8.
67 */
66struct pt_regs { 68struct pt_regs {
67 long uregs[18]; 69 long uregs[18];
68}; 70};