[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>
This commit is contained in:
committed by
Russell King
parent
4ac941d2d0
commit
db6ccbb61c
@@ -436,7 +436,7 @@ __und_usr:
|
|||||||
usr_entry
|
usr_entry
|
||||||
|
|
||||||
tst r3, #PSR_T_BIT @ Thumb mode?
|
tst r3, #PSR_T_BIT @ Thumb mode?
|
||||||
bne fpundefinstr @ ignore FP
|
bne __und_usr_unknown @ ignore FP
|
||||||
sub r4, r2, #4
|
sub r4, r2, #4
|
||||||
|
|
||||||
@
|
@
|
||||||
@@ -448,7 +448,7 @@ __und_usr:
|
|||||||
@
|
@
|
||||||
1: ldrt r0, [r4]
|
1: ldrt r0, [r4]
|
||||||
adr r9, ret_from_exception
|
adr r9, ret_from_exception
|
||||||
adr lr, fpundefinstr
|
adr lr, __und_usr_unknown
|
||||||
@
|
@
|
||||||
@ fallthrough to call_fpe
|
@ fallthrough to call_fpe
|
||||||
@
|
@
|
||||||
@@ -476,7 +476,9 @@ __und_usr:
|
|||||||
* Emulators may wish to make use of the following registers:
|
* Emulators may wish to make use of the following registers:
|
||||||
* r0 = instruction opcode.
|
* r0 = instruction opcode.
|
||||||
* r2 = PC+4
|
* r2 = PC+4
|
||||||
|
* r9 = normal "successful" return address
|
||||||
* r10 = this threads thread_info structure.
|
* r10 = this threads thread_info structure.
|
||||||
|
* lr = unrecognised instruction return address
|
||||||
*/
|
*/
|
||||||
call_fpe:
|
call_fpe:
|
||||||
tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27
|
tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27
|
||||||
@@ -545,10 +547,12 @@ do_fpe:
|
|||||||
|
|
||||||
.data
|
.data
|
||||||
ENTRY(fp_enter)
|
ENTRY(fp_enter)
|
||||||
.word fpundefinstr
|
.word no_fp
|
||||||
.text
|
.text
|
||||||
|
|
||||||
fpundefinstr:
|
no_fp: mov pc, lr
|
||||||
|
|
||||||
|
__und_usr_unknown:
|
||||||
mov r0, sp
|
mov r0, sp
|
||||||
adr lr, ret_from_exception
|
adr lr, ret_from_exception
|
||||||
b do_undefinstr
|
b do_undefinstr
|
||||||
|
Reference in New Issue
Block a user