#endif
        .endm
 
+       .macro  uaccess_disable, tmp, isb=1
+       .endm
+
+       .macro  uaccess_enable, tmp, isb=1
+       .endm
+
+       .macro  uaccess_save, tmp
+       .endm
+
+       .macro  uaccess_restore
+       .endm
+
+       .macro  uaccess_save_and_disable, tmp
+       uaccess_save \tmp
+       uaccess_disable \tmp
+       .endm
+
        .irp    c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo
        .macro  ret\c, reg
 #if __LINUX_ARM_ARCH__ < 6
 
 #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          )
        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
        @
        stmia   r7, {r2 - r6}
 
+       uaccess_save r0
+       .if \uaccess
+       uaccess_disable r0
+       .endif
+
        .if \trace
 #ifdef CONFIG_TRACE_IRQFLAGS
        bl      trace_hardirqs_off
 
        .align  5
 __dabt_svc:
-       svc_entry
+       svc_entry uaccess=0
        mov     r2, sp
        dabt_helper
  THUMB(        ldr     r5, [sp, #S_PSR]        )       @ potentially updated CPSR
 #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
  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)
 
        .align  5
 __dabt_usr:
-       usr_entry
+       usr_entry uaccess=0
        kuser_cmpxchg_check
        mov     r2, sp
        dabt_helper
 
        .align  5
 __und_usr:
-       usr_entry
+       usr_entry uaccess=0
 
        mov     r2, r4
        mov     r3, r5
 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
 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
 __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
 
  USER( ldr     scno, [lr, #-4]         )       @ get SWI instruction
 #endif
 
+       uaccess_disable tbl
+
        adr     tbl, sys_call_table             @ load syscall table pointer
 
 #if defined(CONFIG_OABI_COMPAT)
 
        blne    trace_hardirqs_off
 #endif
        .endif
+       uaccess_restore
 
 #ifndef CONFIG_THUMB2_KERNEL
        @ ARM mode SVC restore
        @ on the stack remains correct).
        @
        .macro  svc_exit_via_fiq
+       uaccess_restore
 #ifndef CONFIG_THUMB2_KERNEL
        @ ARM mode restore
        mov     r0, sp
 
 
        .macro  restore_user_regs, fast = 0, offset = 0
+       uaccess_enable r1, isb=0
 #ifndef CONFIG_THUMB2_KERNEL
        @ ARM mode restore
        mov     r2, sp
 
        mrc     p15, 0, r1, c5, c0, 0           @ get FSR
        mrc     p15, 0, r0, c6, c0, 0           @ get FAR
        ldr     r3, [r4]                        @ read aborted ARM instruction
+       uaccess_disable ip                      @ disable userspace access
        bic     r1, r1, #1 << 11 | 1 << 10      @ clear bits 11 and 10 of FSR
        tst     r3, #1 << 20                    @ L = 1 -> write?
        orreq   r1, r1, #1 << 11                @ yes.
 
        mrc     p15, 0, r0, c6, c0, 0           @ get FAR
        do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3
        ldreq   r3, [r4]                        @ read aborted ARM instruction
+       uaccess_disable ip                      @ disable user access
        bic     r1, r1, #1 << 11                @ clear bits 11 of FSR
        teq_ldrd tmp=ip, insn=r3                @ insn was LDRD?
        beq     do_DataAbort                    @ yes
 
        bne     do_DataAbort
        do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3
        ldreq   r3, [r4]                        @ read aborted ARM instruction
+       uaccess_disable ip                      @ disable userspace access
        teq_ldrd tmp=ip, insn=r3                @ insn was LDRD?
        beq     do_DataAbort                    @ yes
        tst     r3, #1 << 20                    @ L = 0 -> write
 
        ldr     ip, =0x4107b36
        mrc     p15, 0, r3, c0, c0, 0           @ get processor id
        teq     ip, r3, lsr #4                  @ r0 ARM1136?
-       bne     do_DataAbort
+       bne     1f
        tst     r5, #PSR_J_BIT                  @ Java?
        tsteq   r5, #PSR_T_BIT                  @ Thumb?
-       bne     do_DataAbort
+       bne     1f
        bic     r1, r1, #1 << 11                @ clear bit 11 of FSR
        ldr     r3, [r4]                        @ read aborted ARM instruction
  ARM_BE8(rev   r3, r3)
 
        teq_ldrd tmp=ip, insn=r3                @ insn was LDRD?
-       beq     do_DataAbort                    @ yes
+       beq     1f                              @ yes
        tst     r3, #1 << 20                    @ L = 0 -> write
        orreq   r1, r1, #1 << 11                @ yes.
 #endif
+1:     uaccess_disable ip                      @ disable userspace access
        b       do_DataAbort
 
 ENTRY(v7_early_abort)
        mrc     p15, 0, r1, c5, c0, 0           @ get FSR
        mrc     p15, 0, r0, c6, c0, 0           @ get FAR
+       uaccess_disable ip                      @ disable userspace access
 
        /*
         * V6 code adjusts the returned DFSR.
 
 #endif
        bne     .data_thumb_abort
        ldr     r8, [r4]                        @ read arm instruction
+       uaccess_disable ip                      @ disable userspace access
        tst     r8, #1 << 20                    @ L = 1 -> write?
        orreq   r1, r1, #1 << 11                @ yes.
        and     r7, r8, #15 << 24
 
 .data_thumb_abort:
        ldrh    r8, [r4]                        @ read instruction
+       uaccess_disable ip                      @ disable userspace access
        tst     r8, #1 << 11                    @ L = 1 -> write?
        orreq   r1, r1, #1 << 8                 @ yes
        and     r7, r8, #15 << 12
 
        tst     \psr, #PSR_T_BIT
        beq     not_thumb
        ldrh    \tmp, [\pc]                     @ Read aborted Thumb instruction
+       uaccess_disable ip                      @ disable userspace access
        and     \tmp, \tmp, # 0xfe00            @ Mask opcode field
        cmp     \tmp, # 0x5600                  @ Is it ldrsb?
        orreq   \tmp, \tmp, #1 << 11            @ Set L-bit if yes