diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2009-09-23 17:27:58 +0100 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2009-09-23 17:28:48 +0100 |
commit | b86e123e48f09dfcdca0d144938a52dc861c4770 (patch) | |
tree | ca698fb1b84b6d01c2f5b5397a9f94b7f334c7c4 /arch/arm/kernel | |
parent | 30bb6551675d2dfddeb3f7fda0f3af3aa753df12 (diff) |
Thumb-2: Correct "mov.w pc, lr" instruction which is unpredictable
The 32-bit wide variant of "mov pc, reg" in Thumb-2 is unpredictable
causing improper handling of the undefined instructions not caught by
the kernel. This patch adds a movw_pc macro for such situations
(currently only used in call_fpe).
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 28 | ||||
-rw-r--r-- | arch/arm/kernel/entry-header.S | 15 |
2 files changed, 29 insertions, 14 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 49b95b3ac2b5..b778ca82d921 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -635,33 +635,33 @@ call_fpe: THUMB( add pc, r8 ) nop - W(mov) pc, lr @ CP#0 + movw_pc lr @ CP#0 W(b) do_fpe @ CP#1 (FPE) W(b) do_fpe @ CP#2 (FPE) - W(mov) pc, lr @ CP#3 + movw_pc lr @ CP#3 #ifdef CONFIG_CRUNCH b crunch_task_enable @ CP#4 (MaverickCrunch) b crunch_task_enable @ CP#5 (MaverickCrunch) b crunch_task_enable @ CP#6 (MaverickCrunch) #else - W(mov) pc, lr @ CP#4 - W(mov) pc, lr @ CP#5 - W(mov) pc, lr @ CP#6 + movw_pc lr @ CP#4 + movw_pc lr @ CP#5 + movw_pc lr @ CP#6 #endif - W(mov) pc, lr @ CP#7 - W(mov) pc, lr @ CP#8 - W(mov) pc, lr @ CP#9 + movw_pc lr @ CP#7 + movw_pc lr @ CP#8 + movw_pc lr @ CP#9 #ifdef CONFIG_VFP W(b) do_vfp @ CP#10 (VFP) W(b) do_vfp @ CP#11 (VFP) #else - W(mov) pc, lr @ CP#10 (VFP) - W(mov) pc, lr @ CP#11 (VFP) + movw_pc lr @ CP#10 (VFP) + movw_pc lr @ CP#11 (VFP) #endif - W(mov) pc, lr @ CP#12 - W(mov) pc, lr @ CP#13 - W(mov) pc, lr @ CP#14 (Debug) - W(mov) pc, lr @ CP#15 (Control) + movw_pc lr @ CP#12 + movw_pc lr @ CP#13 + movw_pc lr @ CP#14 (Debug) + movw_pc lr @ CP#15 (Control) #ifdef CONFIG_NEON .align 6 diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index 38e202d194f8..5a44d3f0dc02 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S @@ -194,6 +194,13 @@ mov \rd, sp, lsr #13 mov \rd, \rd, lsl #13 .endm + + @ + @ 32-bit wide "mov pc, reg" + @ + .macro movw_pc, reg + mov pc, \reg + .endm #else /* CONFIG_THUMB2_KERNEL */ .macro svc_exit, rpsr clrex @ clear the exclusive monitor @@ -240,6 +247,14 @@ lsr \rd, \rd, #13 mov \rd, \rd, lsl #13 .endm + + @ + @ 32-bit wide "mov pc, reg" + @ + .macro movw_pc, reg + mov pc, \reg + nop + .endm #endif /* CONFIG_THUMB2_KERNEL */ /* |