Skip to content

Commit

Permalink
ARM: entry: rejig register allocation in exception entry handlers
Browse files Browse the repository at this point in the history
This allows us to avoid moving registers twice to work around the
clobbered registers when we add calls to trace_hardirqs_{on,off}.

Ensure that all SVC handlers return with SPSR in r5 for consistency.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Russell King committed Jun 30, 2011
1 parent fbab1c8 commit b059bdc
Showing 1 changed file with 43 additions and 38 deletions.
81 changes: 43 additions & 38 deletions arch/arm/kernel/entry-armv.S
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
.endm

.macro pabt_helper
mov r0, r2 @ pass address of aborted instruction.
mov r0, r4 @ pass address of aborted instruction.
#ifdef MULTI_PABORT
ldr ip, .LCprocfns
mov lr, pc
Expand All @@ -56,6 +56,8 @@
.endm

.macro dabt_helper
mov r2, r4
mov r3, r5

@
@ Call the processor-specific abort handler:
Expand Down Expand Up @@ -157,26 +159,26 @@ ENDPROC(__und_invalid)
SPFIX( subeq sp, sp, #4 )
stmia sp, {r1 - r12}

ldmia r0, {r1 - r3}
add r5, sp, #S_SP - 4 @ here for interlock avoidance
mov r4, #-1 @ "" "" "" ""
add r0, sp, #(S_FRAME_SIZE + \stack_hole - 4)
SPFIX( addeq r0, r0, #4 )
str r1, [sp, #-4]! @ save the "real" r0 copied
ldmia r0, {r3 - r5}
add r7, sp, #S_SP - 4 @ here for interlock avoidance
mov r6, #-1 @ "" "" "" ""
add r2, sp, #(S_FRAME_SIZE + \stack_hole - 4)
SPFIX( addeq r2, r2, #4 )
str r3, [sp, #-4]! @ save the "real" r0 copied
@ from the exception stack

mov r1, lr
mov r3, lr

@
@ We are now ready to fill in the remaining blanks on the stack:
@
@ r0 - sp_svc
@ r1 - lr_svc
@ r2 - lr_<exception>, already fixed up for correct return/restart
@ r3 - spsr_<exception>
@ r4 - orig_r0 (see pt_regs definition in ptrace.h)
@ r2 - sp_svc
@ r3 - lr_svc
@ r4 - lr_<exception>, already fixed up for correct return/restart
@ r5 - spsr_<exception>
@ r6 - orig_r0 (see pt_regs definition in ptrace.h)
@
stmia r5, {r0 - r4}
stmia r7, {r2 - r6}
.endm

.align 5
Expand All @@ -187,7 +189,7 @@ __dabt_svc:
@ get ready to re-enable interrupts if appropriate
@
mrs r9, cpsr
tst r3, #PSR_I_BIT
tst r5, #PSR_I_BIT
biceq r9, r9, #PSR_I_BIT

dabt_helper
Expand All @@ -208,8 +210,8 @@ __dabt_svc:
@
@ restore SPSR and restart the instruction
@
ldr r2, [sp, #S_PSR]
svc_exit r2 @ return from exception
ldr r5, [sp, #S_PSR]
svc_exit r5 @ return from exception
UNWIND(.fnend )
ENDPROC(__dabt_svc)

Expand All @@ -232,13 +234,13 @@ __irq_svc:
tst r0, #_TIF_NEED_RESCHED
blne svc_preempt
#endif
ldr r4, [sp, #S_PSR] @ irqs are already disabled
ldr r5, [sp, #S_PSR]
#ifdef CONFIG_TRACE_IRQFLAGS
@ The parent context IRQs must have been enabled to get here in
@ the first place, so there's no point checking the PSR I bit.
bl trace_hardirqs_on
#endif
svc_exit r4 @ return from exception
svc_exit r5 @ return from exception
UNWIND(.fnend )
ENDPROC(__irq_svc)

Expand Down Expand Up @@ -273,15 +275,16 @@ __und_svc:
@ r0 - instruction
@
#ifndef CONFIG_THUMB2_KERNEL
ldr r0, [r2, #-4]
ldr r0, [r4, #-4]
#else
ldrh r0, [r2, #-2] @ Thumb instruction at LR - 2
ldrh r0, [r4, #-2] @ Thumb instruction at LR - 2
and r9, r0, #0xf800
cmp r9, #0xe800 @ 32-bit instruction if xx >= 0
ldrhhs r9, [r2] @ bottom 16 bits
ldrhhs r9, [r4] @ bottom 16 bits
orrhs r0, r9, r0, lsl #16
#endif
adr r9, BSYM(1f)
mov r2, r4
bl call_fpe

mov r0, sp @ struct pt_regs *regs
Expand All @@ -295,8 +298,8 @@ __und_svc:
@
@ restore SPSR and restart the instruction
@
ldr r2, [sp, #S_PSR] @ Get SVC cpsr
svc_exit r2 @ return from exception
ldr r5, [sp, #S_PSR] @ Get SVC cpsr
svc_exit r5 @ return from exception
UNWIND(.fnend )
ENDPROC(__und_svc)

Expand All @@ -308,7 +311,7 @@ __pabt_svc:
@ re-enable interrupts if appropriate
@
mrs r9, cpsr
tst r3, #PSR_I_BIT
tst r5, #PSR_I_BIT
biceq r9, r9, #PSR_I_BIT

pabt_helper
Expand All @@ -325,8 +328,8 @@ __pabt_svc:
@
@ restore SPSR and restart the instruction
@
ldr r2, [sp, #S_PSR]
svc_exit r2 @ return from exception
ldr r5, [sp, #S_PSR]
svc_exit r5 @ return from exception
UNWIND(.fnend )
ENDPROC(__pabt_svc)

Expand Down Expand Up @@ -357,23 +360,23 @@ ENDPROC(__pabt_svc)
ARM( stmib sp, {r1 - r12} )
THUMB( stmia sp, {r0 - r12} )

ldmia r0, {r1 - r3}
ldmia r0, {r3 - r5}
add r0, sp, #S_PC @ here for interlock avoidance
mov r4, #-1 @ "" "" "" ""
mov r6, #-1 @ "" "" "" ""

str r1, [sp] @ save the "real" r0 copied
str r3, [sp] @ save the "real" r0 copied
@ from the exception stack

@
@ We are now ready to fill in the remaining blanks on the stack:
@
@ r2 - lr_<exception>, already fixed up for correct return/restart
@ r3 - spsr_<exception>
@ r4 - orig_r0 (see pt_regs definition in ptrace.h)
@ r4 - lr_<exception>, already fixed up for correct return/restart
@ r5 - spsr_<exception>
@ r6 - orig_r0 (see pt_regs definition in ptrace.h)
@
@ Also, separately save sp_usr and lr_usr
@
stmia r0, {r2 - r4}
stmia r0, {r4 - r6}
ARM( stmdb r0, {sp, lr}^ )
THUMB( store_user_sp_lr r0, r1, S_SP - S_PC )

Expand All @@ -397,7 +400,7 @@ ENDPROC(__pabt_svc)
@ if it was interrupted in a critical region. Here we
@ perform a quick test inline since it should be false
@ 99.9999% of the time. The rest is done out of line.
cmp r2, #TASK_SIZE
cmp r4, #TASK_SIZE
blhs kuser_cmpxchg_fixup
#endif
#endif
Expand Down Expand Up @@ -441,6 +444,8 @@ ENDPROC(__irq_usr)
.align 5
__und_usr:
usr_entry
mov r2, r4
mov r3, r5

@
@ fall through to the emulation code, which returns using r9 if
Expand Down Expand Up @@ -894,13 +899,13 @@ __kuser_cmpxchg: @ 0xffff0fc0
.text
kuser_cmpxchg_fixup:
@ Called from kuser_cmpxchg_check macro.
@ r2 = address of interrupted insn (must be preserved).
@ r4 = address of interrupted insn (must be preserved).
@ sp = saved regs. r7 and r8 are clobbered.
@ 1b = first critical insn, 2b = last critical insn.
@ If r2 >= 1b and r2 <= 2b then saved pc_usr is set to 1b.
@ If r4 >= 1b and r4 <= 2b then saved pc_usr is set to 1b.
mov r7, #0xffff0fff
sub r7, r7, #(0xffff0fff - (0xffff0fc0 + (1b - __kuser_cmpxchg)))
subs r8, r2, r7
subs r8, r4, r7
rsbcss r8, r8, #(2b - 1b)
strcs r7, [sp, #S_PC]
mov pc, lr
Expand Down

0 comments on commit b059bdc

Please sign in to comment.