X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fia64%2Fkernel%2Fivt.S;h=b3ed949a4f8609e516093687c1d52a48643deba8;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=c65b6bfb29beb67304e42df39e2fd97357f5c660;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index c65b6bfb2..b3ed949a4 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -51,6 +51,7 @@ #include #include #include +#include #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