Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+79 -91
+2 -91
arch/arm/kernel/entry-armv.S
··· 454 454 tst r5, #PSR_T_BIT @ Thumb mode? 455 455 mov r1, #2 @ set insn size to 2 for Thumb 456 456 bne 0f @ handle as Thumb undef exception 457 + #ifdef CONFIG_FPE_NWFPE 457 458 adr r9, ret_from_exception 458 459 bl call_fpe @ returns via R9 on success 460 + #endif 459 461 mov r1, #4 @ set insn size to 4 for ARM 460 462 0: mov r0, sp 461 463 uaccess_disable ip ··· 465 463 b ret_from_exception 466 464 UNWIND(.fnend) 467 465 ENDPROC(__und_usr) 468 - 469 - /* 470 - * The out of line fixup for the ldrt instruction below. 471 - */ 472 - .pushsection .text.fixup, "ax" 473 - .align 2 474 - 4: str r4, [sp, #S_PC] @ retry current instruction 475 - ret r9 476 - .popsection 477 - 478 - /* 479 - * Check whether the instruction is a co-processor instruction. 480 - * If yes, we need to call the relevant co-processor handler. 481 - * 482 - * Note that we don't do a full check here for the co-processor 483 - * instructions; all instructions with bit 27 set are well 484 - * defined. The only instructions that should fault are the 485 - * co-processor instructions. However, we have to watch out 486 - * for the ARM6/ARM7 SWI bug. 487 - * 488 - * Emulators may wish to make use of the following registers: 489 - * r4 = PC value to resume execution after successful emulation 490 - * r9 = normal "successful" return address 491 - * r10 = this threads thread_info structure 492 - * lr = unrecognised instruction return address 493 - * IRQs enabled, FIQs enabled. 494 - */ 495 - call_fpe: 496 - mov r2, r4 497 - sub r4, r4, #4 @ ARM instruction at user PC - 4 498 - USERL( 4b, ldrt r0, [r4]) @ load opcode from user space 499 - ARM_BE8(rev r0, r0) @ little endian instruction 500 - 501 - uaccess_disable ip 502 - 503 - get_thread_info r10 @ get current thread 504 - tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 505 - reteq lr 506 - and r8, r0, #0x00000f00 @ mask out CP number 507 - #ifdef CONFIG_IWMMXT 508 - @ Test if we need to give access to iWMMXt coprocessors 509 - ldr r5, [r10, #TI_FLAGS] 510 - rsbs r7, r8, #(1 << 8) @ CP 0 or 1 only 511 - movscs r7, r5, lsr #(TIF_USING_IWMMXT + 1) 512 - movcs r0, sp @ pass struct pt_regs 513 - bcs iwmmxt_task_enable 514 - #endif 515 - ARM( add pc, pc, r8, lsr #6 ) 516 - THUMB( lsr r8, r8, #6 ) 517 - THUMB( add pc, r8 ) 518 - nop 519 - 520 - ret.w lr @ CP#0 521 - W(b) do_fpe @ CP#1 (FPE) 522 - W(b) do_fpe @ CP#2 (FPE) 523 - ret.w lr @ CP#3 524 - ret.w lr @ CP#4 525 - ret.w lr @ CP#5 526 - ret.w lr @ CP#6 527 - ret.w lr @ CP#7 528 - ret.w lr @ CP#8 529 - ret.w lr @ CP#9 530 - ret.w lr @ CP#10 (VFP) 531 - ret.w lr @ CP#11 (VFP) 532 - ret.w lr @ CP#12 533 - ret.w lr @ CP#13 534 - ret.w lr @ CP#14 (Debug) 535 - ret.w lr @ CP#15 (Control) 536 - 537 - do_fpe: 538 - add r10, r10, #TI_FPSTATE @ r10 = workspace 539 - ldr_va pc, fp_enter, tmp=r4 @ Call FP module USR entry point 540 - 541 - /* 542 - * The FP module is called with these registers set: 543 - * r0 = instruction 544 - * r2 = PC+4 545 - * r9 = normal "successful" return address 546 - * r10 = FP workspace 547 - * lr = unrecognised FP instruction return address 548 - */ 549 - 550 - .pushsection .data 551 - .align 2 552 - ENTRY(fp_enter) 553 - .word no_fp 554 - .popsection 555 - 556 - ENTRY(no_fp) 557 - ret lr 558 - ENDPROC(no_fp) 559 466 560 467 .align 5 561 468 __pabt_usr:
+77
arch/arm/nwfpe/entry.S
··· 7 7 Direct questions, comments to Scott Bambrough <scottb@netwinder.org> 8 8 9 9 */ 10 + #include <linux/linkage.h> 10 11 #include <asm/assembler.h> 11 12 #include <asm/opcodes.h> 12 13 ··· 105 104 @ plain LDR instruction. Weird, but it seems harmless. 106 105 .pushsection .text.fixup,"ax" 107 106 .align 2 107 + .Lrep: str r4, [sp, #S_PC] @ retry current instruction 108 108 .Lfix: ret r9 @ let the user eat segfaults 109 109 .popsection 110 110 ··· 113 111 .align 3 114 112 .long .Lx1, .Lfix 115 113 .popsection 114 + 115 + @ 116 + @ Check whether the instruction is a co-processor instruction. 117 + @ If yes, we need to call the relevant co-processor handler. 118 + @ Only FPE instructions are dispatched here, everything else 119 + @ is handled by undef hooks. 120 + @ 121 + @ Emulators may wish to make use of the following registers: 122 + @ r4 = PC value to resume execution after successful emulation 123 + @ r9 = normal "successful" return address 124 + @ lr = unrecognised instruction return address 125 + @ IRQs enabled, FIQs enabled. 126 + @ 127 + ENTRY(call_fpe) 128 + mov r2, r4 129 + sub r4, r4, #4 @ ARM instruction at user PC - 4 130 + USERL( .Lrep, ldrt r0, [r4]) @ load opcode from user space 131 + ARM_BE8(rev r0, r0) @ little endian instruction 132 + 133 + uaccess_disable ip 134 + 135 + get_thread_info r10 @ get current thread 136 + tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 137 + reteq lr 138 + and r8, r0, #0x00000f00 @ mask out CP number 139 + #ifdef CONFIG_IWMMXT 140 + @ Test if we need to give access to iWMMXt coprocessors 141 + ldr r5, [r10, #TI_FLAGS] 142 + rsbs r7, r8, #(1 << 8) @ CP 0 or 1 only 143 + movscs r7, r5, lsr #(TIF_USING_IWMMXT + 1) 144 + movcs r0, sp @ pass struct pt_regs 145 + bcs iwmmxt_task_enable 146 + #endif 147 + add pc, pc, r8, lsr #6 148 + nop 149 + 150 + ret lr @ CP#0 151 + b do_fpe @ CP#1 (FPE) 152 + b do_fpe @ CP#2 (FPE) 153 + ret lr @ CP#3 154 + ret lr @ CP#4 155 + ret lr @ CP#5 156 + ret lr @ CP#6 157 + ret lr @ CP#7 158 + ret lr @ CP#8 159 + ret lr @ CP#9 160 + ret lr @ CP#10 (VFP) 161 + ret lr @ CP#11 (VFP) 162 + ret lr @ CP#12 163 + ret lr @ CP#13 164 + ret lr @ CP#14 (Debug) 165 + ret lr @ CP#15 (Control) 166 + 167 + do_fpe: 168 + add r10, r10, #TI_FPSTATE @ r10 = workspace 169 + ldr_va pc, fp_enter, tmp=r4 @ Call FP module USR entry point 170 + 171 + @ 172 + @ The FP module is called with these registers set: 173 + @ r0 = instruction 174 + @ r2 = PC+4 175 + @ r9 = normal "successful" return address 176 + @ r10 = FP workspace 177 + @ lr = unrecognised FP instruction return address 178 + @ 179 + 180 + .pushsection .data 181 + .align 2 182 + ENTRY(fp_enter) 183 + .word no_fp 184 + .popsection 185 + 186 + no_fp: 187 + ret lr 188 + ENDPROC(no_fp)