|
@@ -149,10 +149,10 @@ ENDPROC(__und_invalid)
|
|
|
#define SPFIX(code...)
|
|
|
#endif
|
|
|
|
|
|
- .macro svc_entry, stack_hole=0, trace=1
|
|
|
+ .macro svc_entry, stack_hole=0, trace=1, uaccess=1
|
|
|
UNWIND(.fnstart )
|
|
|
UNWIND(.save {r0 - pc} )
|
|
|
- sub sp, sp, #(S_FRAME_SIZE + \stack_hole - 4)
|
|
|
+ sub sp, sp, #(S_FRAME_SIZE + 8 + \stack_hole - 4)
|
|
|
#ifdef CONFIG_THUMB2_KERNEL
|
|
|
SPFIX( str r0, [sp] ) @ temporarily saved
|
|
|
SPFIX( mov r0, sp )
|
|
@@ -167,7 +167,7 @@ ENDPROC(__und_invalid)
|
|
|
ldmia r0, {r3 - r5}
|
|
|
add r7, sp, #S_SP - 4 @ here for interlock avoidance
|
|
|
mov r6, #-1 @ "" "" "" ""
|
|
|
- add r2, sp, #(S_FRAME_SIZE + \stack_hole - 4)
|
|
|
+ add r2, sp, #(S_FRAME_SIZE + 8 + \stack_hole - 4)
|
|
|
SPFIX( addeq r2, r2, #4 )
|
|
|
str r3, [sp, #-4]! @ save the "real" r0 copied
|
|
|
@ from the exception stack
|
|
@@ -185,6 +185,11 @@ ENDPROC(__und_invalid)
|
|
|
@
|
|
|
stmia r7, {r2 - r6}
|
|
|
|
|
|
+ uaccess_save r0
|
|
|
+ .if \uaccess
|
|
|
+ uaccess_disable r0
|
|
|
+ .endif
|
|
|
+
|
|
|
.if \trace
|
|
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
|
|
bl trace_hardirqs_off
|
|
@@ -194,7 +199,7 @@ ENDPROC(__und_invalid)
|
|
|
|
|
|
.align 5
|
|
|
__dabt_svc:
|
|
|
- svc_entry
|
|
|
+ svc_entry uaccess=0
|
|
|
mov r2, sp
|
|
|
dabt_helper
|
|
|
THUMB( ldr r5, [sp, #S_PSR] ) @ potentially updated CPSR
|
|
@@ -368,7 +373,7 @@ ENDPROC(__fiq_abt)
|
|
|
#error "sizeof(struct pt_regs) must be a multiple of 8"
|
|
|
#endif
|
|
|
|
|
|
- .macro usr_entry, trace=1
|
|
|
+ .macro usr_entry, trace=1, uaccess=1
|
|
|
UNWIND(.fnstart )
|
|
|
UNWIND(.cantunwind ) @ don't unwind the user space
|
|
|
sub sp, sp, #S_FRAME_SIZE
|
|
@@ -400,6 +405,10 @@ ENDPROC(__fiq_abt)
|
|
|
ARM( stmdb r0, {sp, lr}^ )
|
|
|
THUMB( store_user_sp_lr r0, r1, S_SP - S_PC )
|
|
|
|
|
|
+ .if \uaccess
|
|
|
+ uaccess_disable ip
|
|
|
+ .endif
|
|
|
+
|
|
|
@ Enable the alignment trap while in kernel mode
|
|
|
ATRAP( teq r8, r7)
|
|
|
ATRAP( mcrne p15, 0, r8, c1, c0, 0)
|
|
@@ -435,7 +444,7 @@ ENDPROC(__fiq_abt)
|
|
|
|
|
|
.align 5
|
|
|
__dabt_usr:
|
|
|
- usr_entry
|
|
|
+ usr_entry uaccess=0
|
|
|
kuser_cmpxchg_check
|
|
|
mov r2, sp
|
|
|
dabt_helper
|
|
@@ -458,7 +467,7 @@ ENDPROC(__irq_usr)
|
|
|
|
|
|
.align 5
|
|
|
__und_usr:
|
|
|
- usr_entry
|
|
|
+ usr_entry uaccess=0
|
|
|
|
|
|
mov r2, r4
|
|
|
mov r3, r5
|
|
@@ -484,6 +493,8 @@ __und_usr:
|
|
|
1: ldrt r0, [r4]
|
|
|
ARM_BE8(rev r0, r0) @ little endian instruction
|
|
|
|
|
|
+ uaccess_disable ip
|
|
|
+
|
|
|
@ r0 = 32-bit ARM instruction which caused the exception
|
|
|
@ r2 = PC value for the following instruction (:= regs->ARM_pc)
|
|
|
@ r4 = PC value for the faulting instruction
|
|
@@ -518,9 +529,10 @@ __und_usr_thumb:
|
|
|
2: ldrht r5, [r4]
|
|
|
ARM_BE8(rev16 r5, r5) @ little endian instruction
|
|
|
cmp r5, #0xe800 @ 32bit instruction if xx != 0
|
|
|
- blo __und_usr_fault_16 @ 16bit undefined instruction
|
|
|
+ blo __und_usr_fault_16_pan @ 16bit undefined instruction
|
|
|
3: ldrht r0, [r2]
|
|
|
ARM_BE8(rev16 r0, r0) @ little endian instruction
|
|
|
+ uaccess_disable ip
|
|
|
add r2, r2, #2 @ r2 is PC + 2, make it PC + 4
|
|
|
str r2, [sp, #S_PC] @ it's a 2x16bit instr, update
|
|
|
orr r0, r0, r5, lsl #16
|
|
@@ -715,6 +727,8 @@ ENDPROC(no_fp)
|
|
|
__und_usr_fault_32:
|
|
|
mov r1, #4
|
|
|
b 1f
|
|
|
+__und_usr_fault_16_pan:
|
|
|
+ uaccess_disable ip
|
|
|
__und_usr_fault_16:
|
|
|
mov r1, #2
|
|
|
1: mov r0, sp
|