vserver 1.9.5.x5
[linux-2.6.git] / arch / ia64 / kernel / ivt.S
index c65b6bf..b3ed949 100644 (file)
@@ -51,6 +51,7 @@
 #include <asm/system.h>
 #include <asm/thread_info.h>
 #include <asm/unistd.h>
+#include <asm/errno.h>
 
 #if 1
 # define PSR_DEFAULT_BITS      psr.ac
@@ -181,6 +182,12 @@ ENTRY(vhpt_miss)
 (p7)   itc.d r24
        ;;
 #ifdef CONFIG_SMP
+       /*
+        * Tell the assemblers dependency-violation checker that the above "itc" instructions
+        * cannot possibly affect the following loads:
+        */
+       dv_serialize_data
+
        /*
         * Re-check L2 and L3 pagetable.  If they changed, we may have received a ptc.g
         * between reading the pagetable and the "itc".  If so, flush the entry we
@@ -229,6 +236,12 @@ ENTRY(itlb_miss)
        itc.i r18
        ;;
 #ifdef CONFIG_SMP
+       /*
+        * Tell the assemblers dependency-violation checker that the above "itc" instructions
+        * cannot possibly affect the following loads:
+        */
+       dv_serialize_data
+
        ld8 r19=[r17]                           // read L3 PTE again and see if same
        mov r20=PAGE_SHIFT<<2                   // setup page size for purge
        ;;
@@ -267,6 +280,12 @@ dtlb_fault:
        itc.d r18
        ;;
 #ifdef CONFIG_SMP
+       /*
+        * Tell the assemblers dependency-violation checker that the above "itc" instructions
+        * cannot possibly affect the following loads:
+        */
+       dv_serialize_data
+
        ld8 r19=[r17]                           // read L3 PTE again and see if same
        mov r20=PAGE_SHIFT<<2                   // setup page size for purge
        ;;
@@ -504,6 +523,12 @@ ENTRY(dirty_bit)
        ;;
 (p6)   itc.d r25                               // install updated PTE
        ;;
+       /*
+        * Tell the assemblers dependency-violation checker that the above "itc" instructions
+        * cannot possibly affect the following loads:
+        */
+       dv_serialize_data
+
        ld8 r18=[r17]                           // read PTE again
        ;;
        cmp.eq p6,p7=r18,r25                    // is it same as the newly installed
@@ -523,7 +548,7 @@ ENTRY(dirty_bit)
 #endif
        mov pr=r31,-1                           // restore pr
        rfi
-END(idirty_bit)
+END(dirty_bit)
 
        .org ia64_ivt+0x2400
 /////////////////////////////////////////////////////////////////////////////////////////
@@ -563,6 +588,12 @@ ENTRY(iaccess_bit)
        ;;
 (p6)   itc.i r25                               // install updated PTE
        ;;
+       /*
+        * Tell the assemblers dependency-violation checker that the above "itc" instructions
+        * cannot possibly affect the following loads:
+        */
+       dv_serialize_data
+
        ld8 r18=[r17]                           // read PTE again
        ;;
        cmp.eq p6,p7=r18,r25                    // is it same as the newly installed
@@ -610,6 +641,11 @@ ENTRY(daccess_bit)
        cmp.eq p6,p7=r26,r18
        ;;
 (p6)   itc.d r25                               // install updated PTE
+       /*
+        * Tell the assemblers dependency-violation checker that the above "itc" instructions
+        * cannot possibly affect the following loads:
+        */
+       dv_serialize_data
        ;;
        ld8 r18=[r17]                           // read PTE again
        ;;
@@ -697,10 +733,12 @@ ENTRY(break_fault)
        ssm psr.ic | PSR_DEFAULT_BITS
        ;;
        srlz.i                                  // guarantee that interruption collection is on
+       mov r3=NR_syscalls - 1
        ;;
 (p15)  ssm psr.i                               // restore psr.i
+       // p10==true means out registers are more than 8 or r15's Nat is true
+(p10)  br.cond.spnt.many ia64_ret_from_syscall
        ;;
-       mov r3=NR_syscalls - 1
        movl r16=sys_call_table
 
        adds r15=-1024,r15                      // r15 contains the syscall number---subtract 1024
@@ -717,7 +755,9 @@ ENTRY(break_fault)
        ;;
        ld4 r2=[r2]                             // r2 = current_thread_info()->flags
        ;;
-       tbit.z p8,p0=r2,TIF_SYSCALL_TRACE
+       and r2=_TIF_SYSCALL_TRACEAUDIT,r2       // mask trace or audit
+       ;;
+       cmp.eq p8,p0=r2,r0
        mov b6=r20
        ;;
 (p8)   br.call.sptk.many b6=b6                 // ignore this return addr
@@ -799,8 +839,11 @@ END(interrupt)
         * On exit:
         *      - executing on bank 1 registers
         *      - psr.ic enabled, interrupts restored
+        *      -  p10: TRUE if syscall is invoked with more than 8 out
+        *              registers or r15's Nat is true
         *      -  r1: kernel's gp
         *      -  r3: preserved (same as on entry)
+        *      -  r8: -EINVAL if p10 is true
         *      - r12: points to kernel stack
         *      - r13: points to current task
         *      - p15: TRUE if interrupts need to be re-enabled
@@ -815,7 +858,7 @@ GLOBAL_ENTRY(ia64_syscall_setup)
        add r17=PT(R11),r1                      // initialize second base pointer
        ;;
        alloc r19=ar.pfs,8,0,0,0                // ensure in0-in7 are writable
-       st8 [r16]=r29,PT(CR_IFS)-PT(CR_IPSR)    // save cr.ipsr
+       st8 [r16]=r29,PT(AR_PFS)-PT(CR_IPSR)    // save cr.ipsr
        tnat.nz p8,p0=in0
 
        st8.spill [r17]=r11,PT(CR_IIP)-PT(R11)  // save r11
@@ -823,31 +866,36 @@ GLOBAL_ENTRY(ia64_syscall_setup)
 (pKStk)        mov r18=r0                              // make sure r18 isn't NaT
        ;;
 
+       st8 [r16]=r26,PT(CR_IFS)-PT(AR_PFS)     // save ar.pfs
        st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP)    // save cr.iip
        mov r28=b0                              // save b0 (2 cyc)
-(p8)   mov in0=-1
        ;;
 
-       st8 [r16]=r0,PT(AR_PFS)-PT(CR_IFS)      // clear cr.ifs
        st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT)    // save ar.unat
-(p9)   mov in1=-1
+       dep r19=0,r19,38,26                     // clear all bits but 0..37 [I0]
+(p8)   mov in0=-1
        ;;
 
-       st8 [r16]=r26,PT(AR_RNAT)-PT(AR_PFS)    // save ar.pfs
+       st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS)    // store ar.pfs.pfm in cr.ifs
+       extr.u r11=r19,7,7      // I0           // get sol of ar.pfs
+       and r8=0x7f,r19         // A            // get sof of ar.pfs
+
        st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
-       tnat.nz p10,p0=in2
+       tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0
+(p9)   mov in1=-1
+       ;;
 
 (pUStk) sub r18=r18,r22                                // r18=RSE.ndirty*8
-       tbit.nz p15,p0=r29,IA64_PSR_I_BIT
-       tnat.nz p11,p0=in3
+       tnat.nz p10,p0=in2
+       add r11=8,r11
        ;;
 (pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16                // skip over ar_rnat field
 (pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17    // skip over ar_bspstore field
+       tnat.nz p11,p0=in3
+       ;;
 (p10)  mov in2=-1
-
+       tnat.nz p12,p0=in4                              // [I0]
 (p11)  mov in3=-1
-       tnat.nz p12,p0=in4
-       tnat.nz p13,p0=in5
        ;;
 (pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT)       // save ar.rnat
 (pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE)   // save ar.bspstore
@@ -855,36 +903,41 @@ GLOBAL_ENTRY(ia64_syscall_setup)
        ;;
        st8 [r16]=r31,PT(LOADRS)-PT(PR)         // save predicates
        st8 [r17]=r28,PT(R1)-PT(B0)             // save b0
-(p12)  mov in4=-1
+       tnat.nz p13,p0=in5                              // [I0]
        ;;
        st8 [r16]=r18,PT(R12)-PT(LOADRS)        // save ar.rsc value for "loadrs"
        st8.spill [r17]=r20,PT(R13)-PT(R1)      // save original r1
-(p13)  mov in5=-1
+(p12)  mov in4=-1
        ;;
 
 .mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12)       // save r12
 .mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13)           // save r13
-       tnat.nz p14,p0=in6
+(p13)  mov in5=-1
        ;;
        st8 [r16]=r21,PT(R8)-PT(AR_FPSR)        // save ar.fpsr
-       st8.spill [r17]=r15                     // save r15
-       tnat.nz p8,p0=in7
+       tnat.nz p14,p0=in6
+       cmp.lt p10,p9=r11,r8    // frame size can't be more than local+8
        ;;
        stf8 [r16]=f1           // ensure pt_regs.r8 != 0 (see handle_syscall_error)
+(p9)   tnat.nz p10,p0=r15
        adds r12=-16,r1         // switch to kernel memory stack (with 16 bytes of scratch)
-(p14)  mov in6=-1
+
+       st8.spill [r17]=r15                     // save r15
+       tnat.nz p8,p0=in7
+       nop.i 0
 
        mov r13=r2                              // establish `current'
        movl r1=__gp                            // establish kernel global pointer
        ;;
+(p14)  mov in6=-1
 (p8)   mov in7=-1
-       tnat.nz p9,p0=r15
+       nop.i 0
 
        cmp.eq pSys,pNonSys=r0,r0               // set pSys=1, pNonSys=0
        movl r17=FPSR_DEFAULT
        ;;
        mov.m ar.fpsr=r17                       // set ar.fpsr to kernel default value
-(p9)   mov r15=-1
+(p10)  mov r8=-EINVAL
        br.ret.sptk.many b7
 END(ia64_syscall_setup)
 
@@ -1538,10 +1591,11 @@ ENTRY(dispatch_to_ia32_handler)
        ld4 r2=[r2]             // r2 = current_thread_info()->flags
        ;;
        ld8 r16=[r16]
-       tbit.z p8,p0=r2,TIF_SYSCALL_TRACE
+       and r2=_TIF_SYSCALL_TRACEAUDIT,r2       // mask trace or audit
        ;;
        mov b6=r16
        movl r15=ia32_ret_from_syscall
+       cmp.eq p8,p0=r2,r0
        ;;
        mov rp=r15
 (p8)   br.call.sptk.many b6=b6