Skip to content

Commit 303d6da

Browse files
committed
ARM: iwmmxt: Use undef hook to enable coprocessor for task
Define a undef hook to deal with undef exceptions triggered by iwmmxt instructions that were issued with the coprocessor disabled. This removes the dependency on the coprocessor dispatch code in entry-armv.S, which will be made NWFPE-only in a subsequent patch. Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
1 parent 8bcba70 commit 303d6da

File tree

5 files changed

+33
-4
lines changed

5 files changed

+33
-4
lines changed

arch/arm/include/asm/thread_info.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ struct task_struct;
4040
DECLARE_PER_CPU(struct task_struct *, __entry_task);
4141

4242
#include <asm/types.h>
43+
#include <asm/traps.h>
4344

4445
struct cpu_context_save {
4546
__u32 r4;
@@ -104,6 +105,21 @@ extern void iwmmxt_task_restore(struct thread_info *, void *);
104105
extern void iwmmxt_task_release(struct thread_info *);
105106
extern void iwmmxt_task_switch(struct thread_info *);
106107

108+
extern int iwmmxt_undef_handler(struct pt_regs *, u32);
109+
110+
static inline void register_iwmmxt_undef_handler(void)
111+
{
112+
static struct undef_hook iwmmxt_undef_hook = {
113+
.instr_mask = 0x0c000e00,
114+
.instr_val = 0x0c000000,
115+
.cpsr_mask = MODE_MASK | PSR_T_BIT,
116+
.cpsr_val = USR_MODE,
117+
.fn = iwmmxt_undef_handler,
118+
};
119+
120+
register_undef_hook(&iwmmxt_undef_hook);
121+
}
122+
107123
extern void vfp_sync_hwstate(struct thread_info *);
108124
extern void vfp_flush_hwstate(struct thread_info *);
109125

arch/arm/kernel/entry-armv.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,7 @@ ARM_BE8(rev r0, r0) @ little endian instruction
507507
ldr r5, [r10, #TI_FLAGS]
508508
rsbs r7, r8, #(1 << 8) @ CP 0 or 1 only
509509
movscs r7, r5, lsr #(TIF_USING_IWMMXT + 1)
510+
movcs r0, sp @ pass struct pt_regs
510511
bcs iwmmxt_task_enable
511512
#endif
512513
ARM( add pc, pc, r8, lsr #6 )

arch/arm/kernel/iwmmxt.S

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,19 @@
5858
.text
5959
.arm
6060

61+
ENTRY(iwmmxt_undef_handler)
62+
push {r9, r10, lr}
63+
get_thread_info r10
64+
mov r9, pc
65+
b iwmmxt_task_enable
66+
mov r0, #0
67+
pop {r9, r10, pc}
68+
ENDPROC(iwmmxt_undef_handler)
69+
6170
/*
6271
* Lazy switching of Concan coprocessor context
6372
*
73+
* r0 = struct pt_regs pointer
6474
* r10 = struct thread_info pointer
6575
* r9 = ret_from_exception
6676
* lr = undefined instr exit
@@ -84,12 +94,12 @@ ENTRY(iwmmxt_task_enable)
8494
PJ4(mcr p15, 0, r2, c1, c0, 2)
8595

8696
ldr r3, =concan_owner
87-
add r0, r10, #TI_IWMMXT_STATE @ get task Concan save area
88-
ldr r2, [sp, #60] @ current task pc value
97+
ldr r2, [r0, #S_PC] @ current task pc value
8998
ldr r1, [r3] @ get current Concan owner
90-
str r0, [r3] @ this task now owns Concan regs
9199
sub r2, r2, #4 @ adjust pc back
92-
str r2, [sp, #60]
100+
str r2, [r0, #S_PC]
101+
add r0, r10, #TI_IWMMXT_STATE @ get task Concan save area
102+
str r0, [r3] @ this task now owns Concan regs
93103

94104
mrc p15, 0, r2, c2, c0, 0
95105
mov r2, r2 @ cpwait

arch/arm/kernel/pj4-cp0.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ static int __init pj4_cp0_init(void)
126126
pr_info("PJ4 iWMMXt v%d coprocessor enabled.\n", vers);
127127
elf_hwcap |= HWCAP_IWMMXT;
128128
thread_register_notifier(&iwmmxt_notifier_block);
129+
register_iwmmxt_undef_handler();
129130
#endif
130131

131132
return 0;

arch/arm/kernel/xscale-cp0.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ static int __init xscale_cp0_init(void)
166166
pr_info("XScale iWMMXt coprocessor detected.\n");
167167
elf_hwcap |= HWCAP_IWMMXT;
168168
thread_register_notifier(&iwmmxt_notifier_block);
169+
register_iwmmxt_undef_handler();
169170
#endif
170171
} else {
171172
pr_info("XScale DSP coprocessor detected.\n");

0 commit comments

Comments
 (0)