summaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2006-01-14 16:18:09 +0000
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-01-14 16:18:09 +0000
commit499b2ea11ff00c624d63af23516404fa2156639a (patch)
tree7c63e058acd8f6c6a59b08cc64febf9def142852 /arch/arm
parent2dede2d8e925f4c2cb4e136b14df127685e15dd3 (diff)
[ARM] 3103/1: ARM EABI: stack pointer must be 64-bit aligned (part 2)
Patch from Nicolas Pitre We must make sure that assembly code that modifies the stack pointer before calling a C function does it so it remains 64-bit aligned. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/kernel/semaphore.c17
-rw-r--r--arch/arm/lib/lib1funcs.S4
2 files changed, 11 insertions, 10 deletions
diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c
index 4c31f292305..981fe5c6ccb 100644
--- a/arch/arm/kernel/semaphore.c
+++ b/arch/arm/kernel/semaphore.c
@@ -177,41 +177,42 @@ int __down_trylock(struct semaphore * sem)
* ip contains the semaphore pointer on entry. Save the C-clobbered
* registers (r0 to r3 and lr), but not ip, as we use it as a return
* value in some cases..
+ * To remain AAPCS compliant (64-bit stack align) we save r4 as well.
*/
asm(" .section .sched.text,\"ax\",%progbits \n\
.align 5 \n\
.globl __down_failed \n\
__down_failed: \n\
- stmfd sp!, {r0 - r3, lr} \n\
+ stmfd sp!, {r0 - r4, lr} \n\
mov r0, ip \n\
bl __down \n\
- ldmfd sp!, {r0 - r3, pc} \n\
+ ldmfd sp!, {r0 - r4, pc} \n\
\n\
.align 5 \n\
.globl __down_interruptible_failed \n\
__down_interruptible_failed: \n\
- stmfd sp!, {r0 - r3, lr} \n\
+ stmfd sp!, {r0 - r4, lr} \n\
mov r0, ip \n\
bl __down_interruptible \n\
mov ip, r0 \n\
- ldmfd sp!, {r0 - r3, pc} \n\
+ ldmfd sp!, {r0 - r4, pc} \n\
\n\
.align 5 \n\
.globl __down_trylock_failed \n\
__down_trylock_failed: \n\
- stmfd sp!, {r0 - r3, lr} \n\
+ stmfd sp!, {r0 - r4, lr} \n\
mov r0, ip \n\
bl __down_trylock \n\
mov ip, r0 \n\
- ldmfd sp!, {r0 - r3, pc} \n\
+ ldmfd sp!, {r0 - r4, pc} \n\
\n\
.align 5 \n\
.globl __up_wakeup \n\
__up_wakeup: \n\
- stmfd sp!, {r0 - r3, lr} \n\
+ stmfd sp!, {r0 - r4, lr} \n\
mov r0, ip \n\
bl __up \n\
- ldmfd sp!, {r0 - r3, pc} \n\
+ ldmfd sp!, {r0 - r4, pc} \n\
");
EXPORT_SYMBOL(__down_failed);
diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S
index 59026029d01..4964e5bafa0 100644
--- a/arch/arm/lib/lib1funcs.S
+++ b/arch/arm/lib/lib1funcs.S
@@ -306,9 +306,9 @@ ENTRY(__modsi3)
Ldiv0:
- str lr, [sp, #-4]!
+ str lr, [sp, #-8]!
bl __div0
mov r0, #0 @ About as wrong as it could be.
- ldr pc, [sp], #4
+ ldr pc, [sp], #8