diff options
| author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2007-01-06 17:53:48 -0500 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2007-01-06 17:53:48 -0500 |
| commit | db6ccbb61c1291c8aaefadcc8304444f27eeb88d (patch) | |
| tree | 196718a54ccd89fe12c48383a15e0639f8ddf939 | |
| parent | 4ac941d2d04ef26a91adf677f3a371818596305d (diff) | |
[ARM] Fix kernel-mode undefined instruction aborts
If the kernel attempts to execute a CP1 or CP2 instruction and it
aborts, and a FP emulator is not loaded, we try to return as if to
a user context, instead of the proper kernel context. Since the
fault came from kernel mode, we must use the kernel return paths.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
| -rw-r--r-- | arch/arm/kernel/entry-armv.S | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 2db42b18f53f..8517c3c3eb33 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
| @@ -436,7 +436,7 @@ __und_usr: | |||
| 436 | usr_entry | 436 | usr_entry |
| 437 | 437 | ||
| 438 | tst r3, #PSR_T_BIT @ Thumb mode? | 438 | tst r3, #PSR_T_BIT @ Thumb mode? |
| 439 | bne fpundefinstr @ ignore FP | 439 | bne __und_usr_unknown @ ignore FP |
| 440 | sub r4, r2, #4 | 440 | sub r4, r2, #4 |
| 441 | 441 | ||
| 442 | @ | 442 | @ |
| @@ -448,7 +448,7 @@ __und_usr: | |||
| 448 | @ | 448 | @ |
| 449 | 1: ldrt r0, [r4] | 449 | 1: ldrt r0, [r4] |
| 450 | adr r9, ret_from_exception | 450 | adr r9, ret_from_exception |
| 451 | adr lr, fpundefinstr | 451 | adr lr, __und_usr_unknown |
| 452 | @ | 452 | @ |
| 453 | @ fallthrough to call_fpe | 453 | @ fallthrough to call_fpe |
| 454 | @ | 454 | @ |
| @@ -476,7 +476,9 @@ __und_usr: | |||
| 476 | * Emulators may wish to make use of the following registers: | 476 | * Emulators may wish to make use of the following registers: |
| 477 | * r0 = instruction opcode. | 477 | * r0 = instruction opcode. |
| 478 | * r2 = PC+4 | 478 | * r2 = PC+4 |
| 479 | * r9 = normal "successful" return address | ||
| 479 | * r10 = this threads thread_info structure. | 480 | * r10 = this threads thread_info structure. |
| 481 | * lr = unrecognised instruction return address | ||
| 480 | */ | 482 | */ |
| 481 | call_fpe: | 483 | call_fpe: |
| 482 | tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 | 484 | tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 |
| @@ -545,10 +547,12 @@ do_fpe: | |||
| 545 | 547 | ||
| 546 | .data | 548 | .data |
| 547 | ENTRY(fp_enter) | 549 | ENTRY(fp_enter) |
| 548 | .word fpundefinstr | 550 | .word no_fp |
| 549 | .text | 551 | .text |
| 550 | 552 | ||
| 551 | fpundefinstr: | 553 | no_fp: mov pc, lr |
| 554 | |||
| 555 | __und_usr_unknown: | ||
| 552 | mov r0, sp | 556 | mov r0, sp |
| 553 | adr lr, ret_from_exception | 557 | adr lr, ret_from_exception |
| 554 | b do_undefinstr | 558 | b do_undefinstr |
