Skip to content

Commit 47ba5f3

Browse files
committed
ARM: entry: Make asm coproc dispatch code NWFPE only
Now that we can dispatch all VFP and iWMMXT related undef exceptions using undef hooks implemented in C code, we no longer need the asm entry code that takes care of this unless we are using FPE, so we can move it into the FPE entry code. As this means it is ARM only, we can remove the Thumb2 specific decorations as well. It also means the non-standard, asm-only calling convention where returning via LR means failure and returning via R9 means success is now only used on legacy platforms that lack any kind of function return prediction, avoiding the associated performance impact. Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
1 parent 303d6da commit 47ba5f3

File tree

2 files changed

+79
-91
lines changed

2 files changed

+79
-91
lines changed

arch/arm/kernel/entry-armv.S

Lines changed: 2 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -454,8 +454,10 @@ __und_usr:
454454
tst r5, #PSR_T_BIT @ Thumb mode?
455455
mov r1, #2 @ set insn size to 2 for Thumb
456456
bne 0f @ handle as Thumb undef exception
457+
#ifdef CONFIG_FPE_NWFPE
457458
adr r9, ret_from_exception
458459
bl call_fpe @ returns via R9 on success
460+
#endif
459461
mov r1, #4 @ set insn size to 4 for ARM
460462
0: mov r0, sp
461463
uaccess_disable ip
@@ -464,97 +466,6 @@ __und_usr:
464466
UNWIND(.fnend)
465467
ENDPROC(__und_usr)
466468

467-
/*
468-
* The out of line fixup for the ldrt instruction below.
469-
*/
470-
.pushsection .text.fixup, "ax"
471-
.align 2
472-
4: str r4, [sp, #S_PC] @ retry current instruction
473-
ret r9
474-
.popsection
475-
476-
/*
477-
* Check whether the instruction is a co-processor instruction.
478-
* If yes, we need to call the relevant co-processor handler.
479-
*
480-
* Note that we don't do a full check here for the co-processor
481-
* instructions; all instructions with bit 27 set are well
482-
* defined. The only instructions that should fault are the
483-
* co-processor instructions. However, we have to watch out
484-
* for the ARM6/ARM7 SWI bug.
485-
*
486-
* Emulators may wish to make use of the following registers:
487-
* r4 = PC value to resume execution after successful emulation
488-
* r9 = normal "successful" return address
489-
* r10 = this threads thread_info structure
490-
* lr = unrecognised instruction return address
491-
* IRQs enabled, FIQs enabled.
492-
*/
493-
call_fpe:
494-
mov r2, r4
495-
sub r4, r4, #4 @ ARM instruction at user PC - 4
496-
USERL( 4b, ldrt r0, [r4]) @ load opcode from user space
497-
ARM_BE8(rev r0, r0) @ little endian instruction
498-
499-
uaccess_disable ip
500-
501-
get_thread_info r10 @ get current thread
502-
tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27
503-
reteq lr
504-
and r8, r0, #0x00000f00 @ mask out CP number
505-
#ifdef CONFIG_IWMMXT
506-
@ Test if we need to give access to iWMMXt coprocessors
507-
ldr r5, [r10, #TI_FLAGS]
508-
rsbs r7, r8, #(1 << 8) @ CP 0 or 1 only
509-
movscs r7, r5, lsr #(TIF_USING_IWMMXT + 1)
510-
movcs r0, sp @ pass struct pt_regs
511-
bcs iwmmxt_task_enable
512-
#endif
513-
ARM( add pc, pc, r8, lsr #6 )
514-
THUMB( lsr r8, r8, #6 )
515-
THUMB( add pc, r8 )
516-
nop
517-
518-
ret.w lr @ CP#0
519-
W(b) do_fpe @ CP#1 (FPE)
520-
W(b) do_fpe @ CP#2 (FPE)
521-
ret.w lr @ CP#3
522-
ret.w lr @ CP#4
523-
ret.w lr @ CP#5
524-
ret.w lr @ CP#6
525-
ret.w lr @ CP#7
526-
ret.w lr @ CP#8
527-
ret.w lr @ CP#9
528-
ret.w lr @ CP#10 (VFP)
529-
ret.w lr @ CP#11 (VFP)
530-
ret.w lr @ CP#12
531-
ret.w lr @ CP#13
532-
ret.w lr @ CP#14 (Debug)
533-
ret.w lr @ CP#15 (Control)
534-
535-
do_fpe:
536-
add r10, r10, #TI_FPSTATE @ r10 = workspace
537-
ldr_va pc, fp_enter, tmp=r4 @ Call FP module USR entry point
538-
539-
/*
540-
* The FP module is called with these registers set:
541-
* r0 = instruction
542-
* r2 = PC+4
543-
* r9 = normal "successful" return address
544-
* r10 = FP workspace
545-
* lr = unrecognised FP instruction return address
546-
*/
547-
548-
.pushsection .data
549-
.align 2
550-
ENTRY(fp_enter)
551-
.word no_fp
552-
.popsection
553-
554-
ENTRY(no_fp)
555-
ret lr
556-
ENDPROC(no_fp)
557-
558469
.align 5
559470
__pabt_usr:
560471
usr_entry

arch/arm/nwfpe/entry.S

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
88

99
*/
10+
#include <linux/linkage.h>
1011
#include <asm/assembler.h>
1112
#include <asm/opcodes.h>
1213

@@ -104,10 +105,86 @@ next:
104105
@ plain LDR instruction. Weird, but it seems harmless.
105106
.pushsection .text.fixup,"ax"
106107
.align 2
108+
.Lrep: str r4, [sp, #S_PC] @ retry current instruction
107109
.Lfix: ret r9 @ let the user eat segfaults
108110
.popsection
109111

110112
.pushsection __ex_table,"a"
111113
.align 3
112114
.long .Lx1, .Lfix
113115
.popsection
116+
117+
@
118+
@ Check whether the instruction is a co-processor instruction.
119+
@ If yes, we need to call the relevant co-processor handler.
120+
@ Only FPE instructions are dispatched here, everything else
121+
@ is handled by undef hooks.
122+
@
123+
@ Emulators may wish to make use of the following registers:
124+
@ r4 = PC value to resume execution after successful emulation
125+
@ r9 = normal "successful" return address
126+
@ lr = unrecognised instruction return address
127+
@ IRQs enabled, FIQs enabled.
128+
@
129+
ENTRY(call_fpe)
130+
mov r2, r4
131+
sub r4, r4, #4 @ ARM instruction at user PC - 4
132+
USERL( .Lrep, ldrt r0, [r4]) @ load opcode from user space
133+
ARM_BE8(rev r0, r0) @ little endian instruction
134+
135+
uaccess_disable ip
136+
137+
get_thread_info r10 @ get current thread
138+
tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27
139+
reteq lr
140+
and r8, r0, #0x00000f00 @ mask out CP number
141+
#ifdef CONFIG_IWMMXT
142+
@ Test if we need to give access to iWMMXt coprocessors
143+
ldr r5, [r10, #TI_FLAGS]
144+
rsbs r7, r8, #(1 << 8) @ CP 0 or 1 only
145+
movscs r7, r5, lsr #(TIF_USING_IWMMXT + 1)
146+
movcs r0, sp @ pass struct pt_regs
147+
bcs iwmmxt_task_enable
148+
#endif
149+
add pc, pc, r8, lsr #6
150+
nop
151+
152+
ret lr @ CP#0
153+
b do_fpe @ CP#1 (FPE)
154+
b do_fpe @ CP#2 (FPE)
155+
ret lr @ CP#3
156+
ret lr @ CP#4
157+
ret lr @ CP#5
158+
ret lr @ CP#6
159+
ret lr @ CP#7
160+
ret lr @ CP#8
161+
ret lr @ CP#9
162+
ret lr @ CP#10 (VFP)
163+
ret lr @ CP#11 (VFP)
164+
ret lr @ CP#12
165+
ret lr @ CP#13
166+
ret lr @ CP#14 (Debug)
167+
ret lr @ CP#15 (Control)
168+
169+
do_fpe:
170+
add r10, r10, #TI_FPSTATE @ r10 = workspace
171+
ldr_va pc, fp_enter, tmp=r4 @ Call FP module USR entry point
172+
173+
@
174+
@ The FP module is called with these registers set:
175+
@ r0 = instruction
176+
@ r2 = PC+4
177+
@ r9 = normal "successful" return address
178+
@ r10 = FP workspace
179+
@ lr = unrecognised FP instruction return address
180+
@
181+
182+
.pushsection .data
183+
.align 2
184+
ENTRY(fp_enter)
185+
.word no_fp
186+
.popsection
187+
188+
no_fp:
189+
ret lr
190+
ENDPROC(no_fp)

0 commit comments

Comments
 (0)