aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/entry-header.S
diff options
context:
space:
mode:
authorJon Medhurst <tixy@yxit.co.uk>2011-03-18 13:32:44 -0400
committerTixy <tixy@medhuaa1.miniserver.com>2011-07-13 13:32:40 -0400
commit594810621d9605dd40b6ce42e2e188a7dd6ba27c (patch)
treeb44f46bf562bec026a2758ec6516fb22bfada28d /arch/arm/kernel/entry-header.S
parent620917de59eeb934b9f8cf35cc2d95c1ac8ed0fc (diff)
ARM: Thumb-2: Fix exception return sequence to restore stack correctly
The implementation of svc_exit didn't take into account any stack hole created by svc_entry; as happens with the undef handler when kprobes are configured. The fix is to read the saved value of SP rather than trying to calculate it. Signed-off-by: Jon Medhurst <tixy@yxit.co.uk> Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Diffstat (limited to 'arch/arm/kernel/entry-header.S')
-rw-r--r--arch/arm/kernel/entry-header.S12
1 files changed, 5 insertions, 7 deletions
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 051166c2a932..83e29adced6c 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -121,15 +121,13 @@
121 .endm 121 .endm
122#else /* CONFIG_THUMB2_KERNEL */ 122#else /* CONFIG_THUMB2_KERNEL */
123 .macro svc_exit, rpsr 123 .macro svc_exit, rpsr
124 ldr lr, [sp, #S_SP] @ top of the stack
125 ldrd r0, r1, [sp, #S_LR] @ calling lr and pc
124 clrex @ clear the exclusive monitor 126 clrex @ clear the exclusive monitor
125 ldr r0, [sp, #S_SP] @ top of the stack 127 stmdb lr!, {r0, r1, \rpsr} @ calling lr and rfe context
126 ldr r1, [sp, #S_PC] @ return address
127 tst r0, #4 @ orig stack 8-byte aligned?
128 stmdb r0, {r1, \rpsr} @ rfe context
129 ldmia sp, {r0 - r12} 128 ldmia sp, {r0 - r12}
130 ldr lr, [sp, #S_LR] 129 mov sp, lr
131 addeq sp, sp, #S_FRAME_SIZE - 8 @ aligned 130 ldr lr, [sp], #4
132 addne sp, sp, #S_FRAME_SIZE - 4 @ not aligned
133 rfeia sp! 131 rfeia sp!
134 .endm 132 .endm
135 133