]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/arm/kernel/entry-armv.S
Merge branch 'ras-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-linux.git] / arch / arm / kernel / entry-armv.S
index cb4fb1e69778603d41356f3ed7a98695f4cc0cdb..3ce377f7251f3429668c2e2b563fcd8062c991ae 100644 (file)
@@ -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)
@@ -418,8 +427,7 @@ ENDPROC(__fiq_abt)
        .endm
 
        .macro  kuser_cmpxchg_check
-#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \
-    !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS)
 #ifndef CONFIG_MMU
 #warning "NPTL on non MMU needs fixing"
 #else
@@ -435,7 +443,7 @@ ENDPROC(__fiq_abt)
 
        .align  5
 __dabt_usr:
-       usr_entry
+       usr_entry uaccess=0
        kuser_cmpxchg_check
        mov     r2, sp
        dabt_helper
@@ -458,7 +466,7 @@ ENDPROC(__irq_usr)
 
        .align  5
 __und_usr:
-       usr_entry
+       usr_entry uaccess=0
 
        mov     r2, r4
        mov     r3, r5
@@ -484,6 +492,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 +528,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 +726,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
@@ -770,6 +783,8 @@ ENTRY(__switch_to)
        ldr     r4, [r2, #TI_TP_VALUE]
        ldr     r5, [r2, #TI_TP_VALUE + 4]
 #ifdef CONFIG_CPU_USE_DOMAINS
+       mrc     p15, 0, r6, c3, c0, 0           @ Get domain register
+       str     r6, [r1, #TI_CPU_DOMAIN]        @ Save old domain register
        ldr     r6, [r2, #TI_CPU_DOMAIN]
 #endif
        switch_tls r1, r4, r5, r3, r7
@@ -843,20 +858,7 @@ __kuser_helper_start:
 
 __kuser_cmpxchg64:                             @ 0xffff0f60
 
-#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
-
-       /*
-        * Poor you.  No fast solution possible...
-        * The kernel itself must perform the operation.
-        * A special ghost syscall is used for that (see traps.c).
-        */
-       stmfd   sp!, {r7, lr}
-       ldr     r7, 1f                  @ it's 20 bits
-       swi     __ARM_NR_cmpxchg64
-       ldmfd   sp!, {r7, pc}
-1:     .word   __ARM_NR_cmpxchg64
-
-#elif defined(CONFIG_CPU_32v6K)
+#if defined(CONFIG_CPU_32v6K)
 
        stmfd   sp!, {r4, r5, r6, r7}
        ldrd    r4, r5, [r0]                    @ load old val
@@ -932,20 +934,7 @@ __kuser_memory_barrier:                            @ 0xffff0fa0
 
 __kuser_cmpxchg:                               @ 0xffff0fc0
 
-#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
-
-       /*
-        * Poor you.  No fast solution possible...
-        * The kernel itself must perform the operation.
-        * A special ghost syscall is used for that (see traps.c).
-        */
-       stmfd   sp!, {r7, lr}
-       ldr     r7, 1f                  @ it's 20 bits
-       swi     __ARM_NR_cmpxchg
-       ldmfd   sp!, {r7, pc}
-1:     .word   __ARM_NR_cmpxchg
-
-#elif __LINUX_ARM_ARCH__ < 6
+#if __LINUX_ARM_ARCH__ < 6
 
 #ifdef CONFIG_MMU