path: root/arch/arm/kernel/entry-header.S
diff options
authorLinus Torvalds <torvalds@linux-foundation.org>2015-01-24 09:57:01 +1200
committerLinus Torvalds <torvalds@linux-foundation.org>2015-01-24 09:57:01 +1200
commit0ad4989d6270bec0a42598dd4d804569faedf228 (patch)
tree87fd4f7d1b15fa61d800c6b134abc370fddaf342 /arch/arm/kernel/entry-header.S
parent222713bb1e374dbec7d90abcfca3fe4535578885 (diff)
parent909ba297beb50981a9d12364688d3c5f3084c6eb (diff)
Merge branch 'fixes' of git://ftp.arm.linux.org.uk/~rmk/linux-arm
Pull ARM fixes from Russell King: "Another round of small ARM fixes. restore_user_regs early stack deallocation is buggy in the presence of FIQs which switch to SVC mode, and could lead to corrupted registers being returned to a user process given an inopportune FIQ event. Another bug was spotted in the ARM perf code where it could lose track of perf counter overflows, leading to incorrect perf results. Lastly, a bug in arm_add_memory() was spotted where the memory sizes aren't properly rounded. As most people pass properly rounded sizes, this hasn't been noticed" * 'fixes' of git://ftp.arm.linux.org.uk/~rmk/linux-arm: ARM: 8292/1: mm: fix size rounding-down of arm_add_memory() function ARM: 8255/1: perf: Prevent wraparound during overflow ARM: 8266/1: Remove early stack deallocation from restore_user_regs
Diffstat (limited to 'arch/arm/kernel/entry-header.S')
1 files changed, 7 insertions, 6 deletions
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 4176df721bf..1a0045abead 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -253,21 +253,22 @@
.macro restore_user_regs, fast = 0, offset = 0
- ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr
- ldr lr, [sp, #\offset + S_PC]! @ get pc
+ mov r2, sp
+ ldr r1, [r2, #\offset + S_PSR] @ get calling cpsr
+ ldr lr, [r2, #\offset + S_PC]! @ get pc
msr spsr_cxsf, r1 @ save in spsr_svc
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K)
@ We must avoid clrex due to Cortex-A15 erratum #830321
- strex r1, r2, [sp] @ clear the exclusive monitor
+ strex r1, r2, [r2] @ clear the exclusive monitor
.if \fast
- ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
+ ldmdb r2, {r1 - lr}^ @ get calling r1 - lr
- ldmdb sp, {r0 - lr}^ @ get calling r0 - lr
+ ldmdb r2, {r0 - lr}^ @ get calling r0 - lr
mov r0, r0 @ ARMv5T and earlier require a nop
@ after ldm {}^
- add sp, sp, #S_FRAME_SIZE - S_PC
+ add sp, sp, #\offset + S_FRAME_SIZE
movs pc, lr @ return & move spsr_svc into cpsr