[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [IA64] update xenivt.S and xenentry.S



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID ea181d8577124856ce003b80fedc310532082b34
# Parent  00141f6d15e005969b14776eb87f5e217b5eb851
[IA64] update xenivt.S and xenentry.S

Update xenentry.S and xenivt.S for linux 2.6.16.13.

Signed-off-by: Tristan Gingold <tristan.gingold@xxxxxxxx>
---
 linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S |  198 ++++----
 linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S   |  586 +++++++++++++++-----------
 2 files changed, 447 insertions(+), 337 deletions(-)

diff -r 00141f6d15e0 -r ea181d857712 
linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S
--- a/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S     Wed May 10 15:58:36 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S     Wed May 10 17:07:06 
2006 -0600
@@ -83,11 +83,7 @@ GLOBAL_ENTRY(ia64_switch_to)
        mov r8=1
        ;;
        st4 [r27]=r8                    // psr.ic back on
-       ;;
-#else
-(p6)   ssm psr.ic                      // if we had to map, reenable the 
psr.ic bit FIRST!!!
-       ;;
-(p6)   srlz.d
+#else
        ld8 sp=[r21]                    // load kernel stack pointer of new task
        mov IA64_KR(CURRENT)=in0        // update "current" application register
 #endif
@@ -136,6 +132,11 @@ GLOBAL_ENTRY(ia64_switch_to)
 #endif
        ;;
        itr.d dtr[r25]=r23              // wire in new mapping...
+#ifndef CONFIG_XEN
+       ssm psr.ic                      // reenable the psr.ic bit
+       ;;
+       srlz.d
+#endif
        br.cond.sptk .done
 #ifdef CONFIG_XEN
 END(xen_switch_to)
@@ -216,7 +217,9 @@ GLOBAL_ENTRY(ia64_trace_syscall)
 .mem.offset 0,0; st8.spill [r2]=r8             // store return value in slot 
for r8
 .mem.offset 8,0; st8.spill [r3]=r10            // clear error indication in 
slot for r10
        br.call.sptk.many rp=syscall_trace_leave // give parent a chance to 
catch return value
-.ret3: br.cond.sptk .work_pending_syscall_end
+.ret3:
+(pUStk)        cmp.eq.unc p6,p0=r0,r0                  // p6 <- pUStk
+       br.cond.sptk .work_pending_syscall_end
 
 strace_error:
        ld8 r3=[r2]                             // load pt_regs.r8
@@ -246,7 +249,7 @@ END(ia64_trace_syscall)
  *           r8-r11: restored (syscall return value(s))
  *              r12: restored (user-level stack pointer)
  *              r13: restored (user-level thread pointer)
- *              r14: cleared
+ *              r14: set to __kernel_syscall_via_epc
  *              r15: restored (syscall #)
  *          r16-r17: cleared
  *              r18: user-level b6
@@ -267,7 +270,7 @@ END(ia64_trace_syscall)
  *               pr: restored (user-level pr)
  *               b0: restored (user-level rp)
  *               b6: restored
- *               b7: cleared
+ *               b7: set to __kernel_syscall_via_epc
  *          ar.unat: restored (user-level ar.unat)
  *           ar.pfs: restored (user-level ar.pfs)
  *           ar.rsc: restored (user-level ar.rsc)
@@ -331,20 +334,20 @@ ENTRY(ia64_leave_syscall)
        ;;
 (p6)   ld4 r31=[r18]                           // load 
current_thread_info()->flags
        ld8 r19=[r2],PT(B6)-PT(LOADRS)          // load ar.rsc value for 
"loadrs"
-       mov b7=r0               // clear b7
-       ;;
-       ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE)    // load ar.bspstore (may be 
garbage)
+       nop.i 0
+       ;;
+       mov r16=ar.bsp                          // M2  get existing backing 
store pointer
        ld8 r18=[r2],PT(R9)-PT(B6)              // load b6
 (p6)   and r15=TIF_WORK_MASK,r31               // any work other than 
TIF_SYSCALL_TRACE?
        ;;
-       mov r16=ar.bsp                          // M2  get existing backing 
store pointer
+       ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE)    // load ar.bspstore (may be 
garbage)
 (p6)   cmp4.ne.unc p6,p0=r15, r0               // any special work pending?
 (p6)   br.cond.spnt .work_pending_syscall
        ;;
        // start restoring the state saved on the kernel stack (struct pt_regs):
        ld8 r9=[r2],PT(CR_IPSR)-PT(R9)
        ld8 r11=[r3],PT(CR_IIP)-PT(R11)
-       mov f6=f0               // clear f6
+(pNonSys) break 0              //      bug check: we shouldn't be here if 
pNonSys is TRUE!
        ;;
        invala                  // M0|1 invalidate ALAT
 #ifdef CONFIG_XEN
@@ -358,57 +361,68 @@ ENTRY(ia64_leave_syscall)
        st4     [r29]=r0        // note: clears both vpsr.i and vpsr.ic!
        ;;
 #else
-       rsm psr.i | psr.ic      // M2 initiate turning off of interrupt and 
interruption collection
-#endif
-       mov f9=f0               // clear f9
-
-       ld8 r29=[r2],16         // load cr.ipsr
-       ld8 r28=[r3],16                 // load cr.iip
-       mov f8=f0               // clear f8
+       rsm psr.i | psr.ic      // M2   turn off interrupts and interruption 
collection
+#endif
+       cmp.eq p9,p0=r0,r0      // A    set p9 to indicate that we should 
restore cr.ifs
+
+       ld8 r29=[r2],16         // M0|1 load cr.ipsr
+       ld8 r28=[r3],16         // M0|1 load cr.iip
+       mov r22=r0              // A    clear r22
        ;;
        ld8 r30=[r2],16         // M0|1 load cr.ifs
-       mov.m ar.ssd=r0         // M2 clear ar.ssd
-       cmp.eq p9,p0=r0,r0      // set p9 to indicate that we should restore 
cr.ifs
-       ;;
        ld8 r25=[r3],16         // M0|1 load ar.unat
-       mov.m ar.csd=r0         // M2 clear ar.csd
-       mov r22=r0              // clear r22
+(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
        ;;
        ld8 r26=[r2],PT(B0)-PT(AR_PFS)  // M0|1 load ar.pfs
-(pKStk)        mov r22=psr             // M2 read PSR now that interrupts are 
disabled
-       mov f10=f0              // clear f10
-       ;;
-       ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0
-       ld8 r27=[r3],PT(PR)-PT(AR_RSC)  // load ar.rsc
-       mov f11=f0              // clear f11
-       ;;
-       ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT)    // load ar.rnat (may be garbage)
-       ld8 r31=[r3],PT(R1)-PT(PR)              // load predicates
-(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
-       ;;
-       ld8 r20=[r2],PT(R12)-PT(AR_FPSR)        // load ar.fpsr
-       ld8.fill r1=[r3],16     // load r1
-(pUStk) mov r17=1
-       ;;
-       srlz.d                  // M0  ensure interruption collection is off
-       ld8.fill r13=[r3],16
-       mov f7=f0               // clear f7
-       ;;
-       ld8.fill r12=[r2]       // restore r12 (sp)
-       ld8.fill r15=[r3]       // restore r15
-       addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0
-       ;;
-(pUStk)        ld4 r3=[r3]             // r3 = cpu_data->phys_stacked_size_p8
-(pUStk) st1 [r14]=r17
-       mov b6=r18              // I0  restore b6
-       ;;
-       mov r14=r0              // clear r14
-       shr.u r18=r19,16        // I0|1 get byte size of existing "dirty" 
partition
-(pKStk) br.cond.dpnt.many skip_rbs_switch
-
-       mov.m ar.ccv=r0         // clear ar.ccv
-(pNonSys) br.cond.dpnt.many dont_preserve_current_frame
-       br.cond.sptk.many rbs_switch
+(pKStk)        mov r22=psr                     // M2   read PSR now that 
interrupts are disabled
+       nop 0
+       ;;
+       ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0
+       ld8 r27=[r3],PT(PR)-PT(AR_RSC)  // M0|1 load ar.rsc
+       mov f6=f0                       // F    clear f6
+       ;;
+       ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT)    // M0|1 load ar.rnat (may be 
garbage)
+       ld8 r31=[r3],PT(R1)-PT(PR)              // M0|1 load predicates
+       mov f7=f0                               // F    clear f7
+       ;;
+       ld8 r20=[r2],PT(R12)-PT(AR_FPSR)        // M0|1 load ar.fpsr
+       ld8.fill r1=[r3],16                     // M0|1 load r1
+(pUStk) mov r17=1                              // A
+       ;;
+(pUStk) st1 [r14]=r17                          // M2|3
+       ld8.fill r13=[r3],16                    // M0|1
+       mov f8=f0                               // F    clear f8
+       ;;
+       ld8.fill r12=[r2]                       // M0|1 restore r12 (sp)
+       ld8.fill r15=[r3]                       // M0|1 restore r15
+       mov b6=r18                              // I0   restore b6
+
+       addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A
+       mov f9=f0                                       // F    clear f9
+(pKStk) br.cond.dpnt.many skip_rbs_switch              // B
+
+       srlz.d                          // M0   ensure interruption collection 
is off (for cover)
+       shr.u r18=r19,16                // I0|1 get byte size of existing 
"dirty" partition
+#ifdef CONFIG_XEN
+       XEN_HYPER_COVER;
+#else
+       cover                           // B    add current frame into dirty 
partition & set cr.ifs
+#endif
+       ;;
+(pUStk) ld4 r17=[r17]                  // M0|1 r17 = 
cpu_data->phys_stacked_size_p8
+       mov r19=ar.bsp                  // M2   get new backing store pointer
+       mov f10=f0                      // F    clear f10
+
+       nop.m 0
+       movl r14=__kernel_syscall_via_epc // X
+       ;;
+       mov.m ar.csd=r0                 // M2   clear ar.csd
+       mov.m ar.ccv=r0                 // M2   clear ar.ccv
+       mov b7=r14                      // I0   clear b7 (hint with 
__kernel_syscall_via_epc)
+
+       mov.m ar.ssd=r0                 // M2   clear ar.ssd
+       mov f11=f0                      // F    clear f11
+       br.cond.sptk.many rbs_switch    // B
 #ifdef CONFIG_XEN
 END(xen_leave_syscall)
 #else
@@ -546,7 +560,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
        ldf.fill f7=[r2],PT(F11)-PT(F7)
        ldf.fill f8=[r3],32
        ;;
-       srlz.i                  // ensure interruption collection is off
+       srlz.d  // ensure that inter. collection is off (VHPT is don't care, 
since text is pinned)
        mov ar.ccv=r15
        ;;
        ldf.fill f11=[r2]
@@ -556,29 +570,29 @@ GLOBAL_ENTRY(ia64_leave_kernel)
        movl r2=XSI_BANK1_R16
        movl r3=XSI_BANK1_R16+8
        ;;
-       st8.spill [r2]=r16,16
-       st8.spill [r3]=r17,16
-       ;;
-       st8.spill [r2]=r18,16
-       st8.spill [r3]=r19,16
-       ;;
-       st8.spill [r2]=r20,16
-       st8.spill [r3]=r21,16
-       ;;
-       st8.spill [r2]=r22,16
-       st8.spill [r3]=r23,16
-       ;;
-       st8.spill [r2]=r24,16
-       st8.spill [r3]=r25,16
-       ;;
-       st8.spill [r2]=r26,16
-       st8.spill [r3]=r27,16
-       ;;
-       st8.spill [r2]=r28,16
-       st8.spill [r3]=r29,16
-       ;;
-       st8.spill [r2]=r30,16
-       st8.spill [r3]=r31,16
+.mem.offset 0,0; st8.spill [r2]=r16,16
+.mem.offset 8,0; st8.spill [r3]=r17,16
+       ;;
+.mem.offset 0,0; st8.spill [r2]=r18,16
+.mem.offset 8,0; st8.spill [r3]=r19,16
+       ;;
+.mem.offset 0,0; st8.spill [r2]=r20,16
+.mem.offset 8,0; st8.spill [r3]=r21,16
+       ;;
+.mem.offset 0,0; st8.spill [r2]=r22,16
+.mem.offset 8,0; st8.spill [r3]=r23,16
+       ;;
+.mem.offset 0,0; st8.spill [r2]=r24,16
+.mem.offset 8,0; st8.spill [r3]=r25,16
+       ;;
+.mem.offset 0,0; st8.spill [r2]=r26,16
+.mem.offset 8,0; st8.spill [r3]=r27,16
+       ;;
+.mem.offset 0,0; st8.spill [r2]=r28,16
+.mem.offset 8,0; st8.spill [r3]=r29,16
+       ;;
+.mem.offset 0,0; st8.spill [r2]=r30,16
+.mem.offset 8,0; st8.spill [r3]=r31,16
        ;;
        movl r2=XSI_BANKNUM;;
        st4 [r2]=r0;
@@ -641,14 +655,14 @@ GLOBAL_ENTRY(ia64_leave_kernel)
         */
 (pNonSys) br.cond.dpnt dont_preserve_current_frame
 
+#ifdef CONFIG_XEN
+       XEN_HYPER_COVER;
+#else
+       cover                           // add current frame into dirty 
partition and set cr.ifs
+#endif
+       ;;
+       mov r19=ar.bsp                  // get new backing store pointer
 rbs_switch:
-#ifdef CONFIG_XEN
-       XEN_HYPER_COVER;
-#else
-       cover                           // add current frame into dirty 
partition and set cr.ifs
-#endif
-       ;;
-       mov r19=ar.bsp                  // get new backing store pointer
        sub r16=r16,r18                 // krbs = old bsp - size of dirty 
partition
        cmp.ne p9,p0=r0,r0              // clear p9 to skip restore of cr.ifs
        ;;
@@ -723,14 +737,14 @@ rse_clear_invalid:
        mov loc5=0
        mov loc6=0
        mov loc7=0
-(pRecurse) br.call.sptk.few b0=rse_clear_invalid
+(pRecurse) br.call.dptk.few b0=rse_clear_invalid
        ;;
        mov loc8=0
        mov loc9=0
        cmp.ne pReturn,p0=r0,in1        // if recursion count != 0, we need to 
do a br.ret
        mov loc10=0
        mov loc11=0
-(pReturn) br.ret.sptk.many b0
+(pReturn) br.ret.dptk.many b0
 #endif /* !CONFIG_ITANIUM */
 #      undef pRecurse
 #      undef pReturn
diff -r 00141f6d15e0 -r ea181d857712 linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S
--- a/linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S       Wed May 10 15:58:36 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S       Wed May 10 17:07:06 
2006 -0600
@@ -87,16 +87,17 @@ ENTRY(vhpt_miss)
         * (the "original") TLB miss, which may either be caused by an 
instruction
         * fetch or a data access (or non-access).
         *
-        * What we do here is normal TLB miss handing for the _original_ miss, 
followed
-        * by inserting the TLB entry for the virtual page table page that the 
VHPT
-        * walker was attempting to access.  The latter gets inserted as long
-        * as both L1 and L2 have valid mappings for the faulting address.
-        * The TLB entry for the original miss gets inserted only if
-        * the L3 entry indicates that the page is present.
+        * What we do here is normal TLB miss handing for the _original_ miss,
+        * followed by inserting the TLB entry for the virtual page table page
+        * that the VHPT walker was attempting to access.  The latter gets
+        * inserted as long as page table entry above pte level have valid
+        * mappings for the faulting address.  The TLB entry for the original
+        * miss gets inserted only if the pte entry indicates that the page is
+        * present.
         *
         * do_page_fault gets invoked in the following cases:
         *      - the faulting virtual address uses unimplemented address bits
-        *      - the faulting virtual address has no L1, L2, or L3 mapping
+        *      - the faulting virtual address has no valid page table mapping
         */
 #ifdef CONFIG_XEN
        movl r16=XSI_IFA
@@ -127,7 +128,7 @@ ENTRY(vhpt_miss)
        shl r21=r16,3                           // shift bit 60 into sign bit
        shr.u r17=r16,61                        // get the region number into 
r17
        ;;
-       shr r22=r21,3
+       shr.u r22=r21,3
 #ifdef CONFIG_HUGETLB_PAGE
        extr.u r26=r25,2,6
        ;;
@@ -139,7 +140,7 @@ ENTRY(vhpt_miss)
 #endif
        ;;
        cmp.eq p6,p7=5,r17                      // is IFA pointing into to 
region 5?
-       shr.u r18=r22,PGDIR_SHIFT               // get bits 33-63 of the 
faulting address
+       shr.u r18=r22,PGDIR_SHIFT               // get bottom portion of pgd 
index bit
        ;;
 (p7)   dep r17=r17,r19,(PAGE_SHIFT-3),3        // put region number bits in 
place
 
@@ -150,41 +151,54 @@ ENTRY(vhpt_miss)
 (p6)   shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
 (p7)   shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
        ;;
-(p6)   dep r17=r18,r19,3,(PAGE_SHIFT-3)        // r17=PTA + IFA(33,42)*8
-(p7)   dep r17=r18,r17,3,(PAGE_SHIFT-6)        // r17=PTA + (((IFA(61,63) << 
7) | IFA(33,39))*8)
+(p6)   dep r17=r18,r19,3,(PAGE_SHIFT-3)        // r17=pgd_offset for region 5
+(p7)   dep r17=r18,r17,3,(PAGE_SHIFT-6)        // r17=pgd_offset for 
region[0-4]
        cmp.eq p7,p6=0,r21                      // unused address bits all 
zeroes?
-       shr.u r18=r22,PMD_SHIFT                 // shift L2 index into position
-       ;;
-       ld8 r17=[r17]                           // fetch the L1 entry (may be 0)
-       ;;
-(p7)   cmp.eq p6,p7=r17,r0                     // was L1 entry NULL?
-       dep r17=r18,r17,3,(PAGE_SHIFT-3)        // compute address of L2 page 
table entry
-       ;;
-(p7)   ld8 r20=[r17]                           // fetch the L2 entry (may be 0)
-       shr.u r19=r22,PAGE_SHIFT                // shift L3 index into position
-       ;;
-(p7)   cmp.eq.or.andcm p6,p7=r20,r0            // was L2 entry NULL?
-       dep r21=r19,r20,3,(PAGE_SHIFT-3)        // compute address of L3 page 
table entry
-       ;;
-#ifdef CONFIG_XEN
-(p7)   ld8 r18=[r21]                           // read the L3 PTE
+#ifdef CONFIG_PGTABLE_4
+       shr.u r28=r22,PUD_SHIFT                 // shift pud index into position
+#else
+       shr.u r18=r22,PMD_SHIFT                 // shift pmd index into position
+#endif
+       ;;
+       ld8 r17=[r17]                           // get *pgd (may be 0)
+       ;;
+(p7)   cmp.eq p6,p7=r17,r0                     // was pgd_present(*pgd) == 
NULL?
+#ifdef CONFIG_PGTABLE_4
+       dep r28=r28,r17,3,(PAGE_SHIFT-3)        // r28=pud_offset(pgd,addr)
+       ;;
+       shr.u r18=r22,PMD_SHIFT                 // shift pmd index into position
+(p7)   ld8 r29=[r28]                           // get *pud (may be 0)
+       ;;
+(p7)   cmp.eq.or.andcm p6,p7=r29,r0            // was pud_present(*pud) == 
NULL?
+       dep r17=r18,r29,3,(PAGE_SHIFT-3)        // r17=pmd_offset(pud,addr)
+#else
+       dep r17=r18,r17,3,(PAGE_SHIFT-3)        // r17=pmd_offset(pgd,addr)
+#endif
+       ;;
+(p7)   ld8 r20=[r17]                           // get *pmd (may be 0)
+       shr.u r19=r22,PAGE_SHIFT                // shift pte index into position
+       ;;
+(p7)   cmp.eq.or.andcm p6,p7=r20,r0            // was pmd_present(*pmd) == 
NULL?
+       dep r21=r19,r20,3,(PAGE_SHIFT-3)        // r21=pte_offset(pmd,addr)
+       ;;
+(p7)   ld8 r18=[r21]                           // read *pte
+#ifdef CONFIG_XEN
        movl r19=XSI_ISR
        ;;
        ld8 r19=[r19]
+#else
+       mov r19=cr.isr                          // cr.isr bit 32 tells us if 
this is an insn miss
+#endif
        ;;
 (p7)   tbit.z p6,p7=r18,_PAGE_P_BIT            // page present bit cleared?
+#ifdef CONFIG_XEN
        movl r22=XSI_IHA
        ;;
        ld8 r22=[r22]
-       ;;
-#else
-(p7)   ld8 r18=[r21]                           // read the L3 PTE
-       mov r19=cr.isr                          // cr.isr bit 0 tells us if 
this is an insn miss
-       ;;
-(p7)   tbit.z p6,p7=r18,_PAGE_P_BIT            // page present bit cleared?
+#else
        mov r22=cr.iha                          // get the VHPT address that 
caused the TLB miss
+#endif
        ;;                                      // avoid RAW on p7
-#endif
 (p7)   tbit.nz.unc p10,p11=r19,32              // is it an instruction TLB 
miss?
        dep r23=0,r20,0,PAGE_SHIFT              // clear low bits to get page 
address
        ;;
@@ -198,16 +212,17 @@ ENTRY(vhpt_miss)
        ;;
        mov r8=r24
        ;;
-(p6)   br.cond.spnt.many page_fault            // handle bad address/page not 
present (page fault)
-       ;;
-       movl r24=XSI_IFA
-       ;;
-       st8 [r24]=r22
-       ;;
 #else
 (p10)  itc.i r18                               // insert the instruction TLB 
entry
 (p11)  itc.d r18                               // insert the data TLB entry
+#endif
 (p6)   br.cond.spnt.many page_fault            // handle bad address/page not 
present (page fault)
+#ifdef CONFIG_XEN
+       movl r24=XSI_IFA
+       ;;
+       st8 [r24]=r22
+       ;;
+#else
        mov cr.ifa=r22
 #endif
 
@@ -242,25 +257,41 @@ ENTRY(vhpt_miss)
        dv_serialize_data
 
        /*
-        * Re-check L2 and L3 pagetable.  If they changed, we may have received 
a ptc.g
+        * Re-check pagetable entry.  If they changed, we may have received a 
ptc.g
         * between reading the pagetable and the "itc".  If so, flush the entry 
we
-        * inserted and retry.
-        */
-       ld8 r25=[r21]                           // read L3 PTE again
-       ld8 r26=[r17]                           // read L2 entry again
-       ;;
-       cmp.ne p6,p7=r26,r20                    // did L2 entry change
+        * inserted and retry.  At this point, we have:
+        *
+        * r28 = equivalent of pud_offset(pgd, ifa)
+        * r17 = equivalent of pmd_offset(pud, ifa)
+        * r21 = equivalent of pte_offset(pmd, ifa)
+        *
+        * r29 = *pud
+        * r20 = *pmd
+        * r18 = *pte
+        */
+       ld8 r25=[r21]                           // read *pte again
+       ld8 r26=[r17]                           // read *pmd again
+#ifdef CONFIG_PGTABLE_4
+       ld8 r19=[r28]                           // read *pud again
+#endif
+       cmp.ne p6,p7=r0,r0
+       ;;
+       cmp.ne.or.andcm p6,p7=r26,r20           // did *pmd change
+#ifdef CONFIG_PGTABLE_4
+       cmp.ne.or.andcm p6,p7=r19,r29           // did *pud change
+#endif
        mov r27=PAGE_SHIFT<<2
        ;;
 (p6)   ptc.l r22,r27                           // purge PTE page translation
-(p7)   cmp.ne.or.andcm p6,p7=r25,r18           // did L3 PTE change
+(p7)   cmp.ne.or.andcm p6,p7=r25,r18           // did *pte change
        ;;
 (p6)   ptc.l r16,r27                           // purge translation
 #endif
 
        mov pr=r31,-1                           // restore predicate registers
 #ifdef CONFIG_XEN
-       XEN_HYPER_RFI;
+       XEN_HYPER_RFI
+       dv_serialize_data
 #else
        rfi
 #endif
@@ -272,10 +303,10 @@ ENTRY(itlb_miss)
 ENTRY(itlb_miss)
        DBG_FAULT(1)
        /*
-        * The ITLB handler accesses the L3 PTE via the virtually mapped linear
+        * The ITLB handler accesses the PTE via the virtually mapped linear
         * page table.  If a nested TLB miss occurs, we switch into physical
-        * mode, walk the page table, and then re-execute the L3 PTE read
-        * and go on normally after that.
+        * mode, walk the page table, and then re-execute the PTE read and
+        * go on normally after that.
         */
 #ifdef CONFIG_XEN
        movl r16=XSI_IFA
@@ -292,11 +323,11 @@ ENTRY(itlb_miss)
        ;;
        ld8 r17=[r17]                           // get virtual address of L3 PTE
 #else
-       mov r17=cr.iha                          // get virtual address of L3 PTE
+       mov r17=cr.iha                          // get virtual address of PTE
 #endif
        movl r30=1f                             // load nested fault 
continuation point
        ;;
-1:     ld8 r18=[r17]                           // read L3 PTE
+1:     ld8 r18=[r17]                           // read *pte
        ;;
        mov b0=r29
        tbit.z p6,p0=r18,_PAGE_P_BIT            // page present bit cleared?
@@ -320,7 +351,7 @@ 1:  ld8 r18=[r17]                           // read L3 PTE
         */
        dv_serialize_data
 
-       ld8 r19=[r17]                           // read L3 PTE again and see if 
same
+       ld8 r19=[r17]                           // read *pte again and see if 
same
        mov r20=PAGE_SHIFT<<2                   // setup page size for purge
        ;;
        cmp.ne p7,p0=r18,r19
@@ -329,7 +360,8 @@ 1:  ld8 r18=[r17]                           // read L3 PTE
 #endif
        mov pr=r31,-1
 #ifdef CONFIG_XEN
-       XEN_HYPER_RFI;
+       XEN_HYPER_RFI
+       dv_serialize_data
 #else
        rfi
 #endif
@@ -341,10 +373,10 @@ ENTRY(dtlb_miss)
 ENTRY(dtlb_miss)
        DBG_FAULT(2)
        /*
-        * The DTLB handler accesses the L3 PTE via the virtually mapped linear
+        * The DTLB handler accesses the PTE via the virtually mapped linear
         * page table.  If a nested TLB miss occurs, we switch into physical
-        * mode, walk the page table, and then re-execute the L3 PTE read
-        * and go on normally after that.
+        * mode, walk the page table, and then re-execute the PTE read and
+        * go on normally after that.
         */
 #ifdef CONFIG_XEN
        movl r16=XSI_IFA
@@ -361,11 +393,11 @@ dtlb_fault:
        ;;
        ld8 r17=[r17]                           // get virtual address of L3 PTE
 #else
-       mov r17=cr.iha                          // get virtual address of L3 PTE
+       mov r17=cr.iha                          // get virtual address of PTE
 #endif
        movl r30=1f                             // load nested fault 
continuation point
        ;;
-1:     ld8 r18=[r17]                           // read L3 PTE
+1:     ld8 r18=[r17]                           // read *pte
        ;;
        mov b0=r29
        tbit.z p6,p0=r18,_PAGE_P_BIT            // page present bit cleared?
@@ -390,7 +422,7 @@ 1:  ld8 r18=[r17]                           // read L3 PTE
         */
        dv_serialize_data
 
-       ld8 r19=[r17]                           // read L3 PTE again and see if 
same
+       ld8 r19=[r17]                           // read *pte again and see if 
same
        mov r20=PAGE_SHIFT<<2                   // setup page size for purge
        ;;
        cmp.ne p7,p0=r18,r19
@@ -399,7 +431,8 @@ 1:  ld8 r18=[r17]                           // read L3 PTE
 #endif
        mov pr=r31,-1
 #ifdef CONFIG_XEN
-       XEN_HYPER_RFI;
+       XEN_HYPER_RFI
+       dv_serialize_data
 #else
        rfi
 #endif
@@ -416,19 +449,15 @@ ENTRY(alt_itlb_miss)
        ld8 r21=[r31],XSI_IFA-XSI_IPSR  // get ipsr, point to ifa
        movl r17=PAGE_KERNEL
        ;;
-       movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
-       ;;
        ld8 r16=[r31]           // get ifa
-       mov r31=pr
-       ;;
 #else
        mov r16=cr.ifa          // get address that caused the TLB miss
        movl r17=PAGE_KERNEL
        mov r21=cr.ipsr
+#endif
        movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
        mov r31=pr
        ;;
-#endif
 #ifdef CONFIG_DISABLE_VHPT
        shr.u r22=r16,61                        // get the region number into 
r21
        ;;
@@ -486,17 +515,15 @@ ENTRY(alt_dtlb_miss)
        movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
        ;;
        ld8 r16=[r31]           // get ifa
-       mov r31=pr
-       ;;
 #else
        mov r16=cr.ifa          // get address that caused the TLB miss
        movl r17=PAGE_KERNEL
        mov r20=cr.isr
        movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
        mov r21=cr.ipsr
+#endif
        mov r31=pr
        ;;
-#endif
 #ifdef CONFIG_DISABLE_VHPT
        shr.u r22=r16,61                        // get the region number into 
r21
        ;;
@@ -565,12 +592,12 @@ ENTRY(nested_dtlb_miss)
         *              r30:    continuation address
         *              r31:    saved pr
         *
-        * Output:      r17:    physical address of L3 PTE of faulting address
+        * Output:      r17:    physical address of PTE of faulting address
         *              r29:    saved b0
         *              r30:    continuation address
         *              r31:    saved pr
         *
-        * Clobbered:   b0, r18, r19, r21, psr.dt (cleared)
+        * Clobbered:   b0, r18, r19, r21, r22, psr.dt (cleared)
         */
 #ifdef CONFIG_XEN
        XEN_HYPER_RSM_PSR_DT;
@@ -579,12 +606,23 @@ ENTRY(nested_dtlb_miss)
 #endif
        mov r19=IA64_KR(PT_BASE)                // get the page table base 
address
        shl r21=r16,3                           // shift bit 60 into sign bit
+#ifdef CONFIG_XEN
+       movl r18=XSI_ITIR
+       ;;
+       ld8 r18=[r18]
+#else
+       mov r18=cr.itir
+#endif
        ;;
        shr.u r17=r16,61                        // get the region number into 
r17
+       extr.u r18=r18,2,6                      // get the faulting page size
        ;;
        cmp.eq p6,p7=5,r17                      // is faulting address in 
region 5?
-       shr.u r18=r16,PGDIR_SHIFT               // get bits 33-63 of faulting 
address
-       ;;
+       add r22=-PAGE_SHIFT,r18                 // adjustment for hugetlb 
address
+       add r18=PGDIR_SHIFT-PAGE_SHIFT,r18
+       ;;
+       shr.u r22=r16,r22
+       shr.u r18=r16,r18
 (p7)   dep r17=r17,r19,(PAGE_SHIFT-3),3        // put region number bits in 
place
 
        srlz.d
@@ -594,21 +632,33 @@ ENTRY(nested_dtlb_miss)
 (p6)   shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
 (p7)   shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
        ;;
-(p6)   dep r17=r18,r19,3,(PAGE_SHIFT-3)        // r17=PTA + IFA(33,42)*8
-(p7)   dep r17=r18,r17,3,(PAGE_SHIFT-6)        // r17=PTA + (((IFA(61,63) << 
7) | IFA(33,39))*8)
+(p6)   dep r17=r18,r19,3,(PAGE_SHIFT-3)        // r17=pgd_offset for region 5
+(p7)   dep r17=r18,r17,3,(PAGE_SHIFT-6)        // r17=pgd_offset for 
region[0-4]
        cmp.eq p7,p6=0,r21                      // unused address bits all 
zeroes?
-       shr.u r18=r16,PMD_SHIFT                 // shift L2 index into position
-       ;;
-       ld8 r17=[r17]                           // fetch the L1 entry (may be 0)
-       ;;
-(p7)   cmp.eq p6,p7=r17,r0                     // was L1 entry NULL?
-       dep r17=r18,r17,3,(PAGE_SHIFT-3)        // compute address of L2 page 
table entry
-       ;;
-(p7)   ld8 r17=[r17]                           // fetch the L2 entry (may be 0)
-       shr.u r19=r16,PAGE_SHIFT                // shift L3 index into position
-       ;;
-(p7)   cmp.eq.or.andcm p6,p7=r17,r0            // was L2 entry NULL?
-       dep r17=r19,r17,3,(PAGE_SHIFT-3)        // compute address of L3 page 
table entry
+#ifdef CONFIG_PGTABLE_4
+       shr.u r18=r22,PUD_SHIFT                 // shift pud index into position
+#else
+       shr.u r18=r22,PMD_SHIFT                 // shift pmd index into position
+#endif
+       ;;
+       ld8 r17=[r17]                           // get *pgd (may be 0)
+       ;;
+(p7)   cmp.eq p6,p7=r17,r0                     // was pgd_present(*pgd) == 
NULL?
+       dep r17=r18,r17,3,(PAGE_SHIFT-3)        // r17=p[u|m]d_offset(pgd,addr)
+       ;;
+#ifdef CONFIG_PGTABLE_4
+(p7)   ld8 r17=[r17]                           // get *pud (may be 0)
+       shr.u r18=r22,PMD_SHIFT                 // shift pmd index into position
+       ;;
+(p7)   cmp.eq.or.andcm p6,p7=r17,r0            // was pud_present(*pud) == 
NULL?
+       dep r17=r18,r17,3,(PAGE_SHIFT-3)        // r17=pmd_offset(pud,addr)
+       ;;
+#endif
+(p7)   ld8 r17=[r17]                           // get *pmd (may be 0)
+       shr.u r19=r22,PAGE_SHIFT                // shift pte index into position
+       ;;
+(p7)   cmp.eq.or.andcm p6,p7=r17,r0            // was pmd_present(*pmd) == 
NULL?
+       dep r17=r19,r17,3,(PAGE_SHIFT-3)        // r17=pte_offset(pmd,addr);
 (p6)   br.cond.spnt page_fault
        mov b0=r30
        br.sptk.many b0                         // return to continuation point
@@ -626,7 +676,7 @@ END(ikey_miss)
        // call do_page_fault (predicates are in r31, psr.dt may be off, r16 is 
faulting address)
 ENTRY(page_fault)
 #ifdef CONFIG_XEN
-       XEN_HYPER_SSM_PSR_DT;
+       XEN_HYPER_SSM_PSR_DT
 #else
        ssm psr.dt
        ;;
@@ -742,11 +792,12 @@ 1:        ld8 r18=[r17]
        ;;                                      // avoid RAW on r18
        mov ar.ccv=r18                          // set compare value for cmpxchg
        or r25=_PAGE_D|_PAGE_A,r18              // set the dirty and accessed 
bits
-       ;;
-       cmpxchg8.acq r26=[r17],r25,ar.ccv
+       tbit.z p7,p6 = r18,_PAGE_P_BIT          // Check present bit
+       ;;
+(p6)   cmpxchg8.acq r26=[r17],r25,ar.ccv       // Only update if page is 
present
        mov r24=PAGE_SHIFT<<2
        ;;
-       cmp.eq p6,p7=r26,r18
+(p6)   cmp.eq p6,p7=r26,r18                    // Only compare if page is 
present
        ;;
 (p6)   itc.d r25                               // install updated PTE
        ;;
@@ -775,7 +826,8 @@ 1:  ld8 r18=[r17]
 #endif
        mov pr=r31,-1                           // restore pr
 #ifdef CONFIG_XEN
-       XEN_HYPER_RFI;
+       XEN_HYPER_RFI
+       dv_serialize_data
 #else
        rfi
 #endif
@@ -826,11 +878,12 @@ 1:        ld8 r18=[r17]
        ;;
        mov ar.ccv=r18                          // set compare value for cmpxchg
        or r25=_PAGE_A,r18                      // set the accessed bit
-       ;;
-       cmpxchg8.acq r26=[r17],r25,ar.ccv
+       tbit.z p7,p6 = r18,_PAGE_P_BIT          // Check present bit
+       ;;
+(p6)   cmpxchg8.acq r26=[r17],r25,ar.ccv       // Only if page present
        mov r24=PAGE_SHIFT<<2
        ;;
-       cmp.eq p6,p7=r26,r18
+(p6)   cmp.eq p6,p7=r26,r18                    // Only if page present
        ;;
 #ifdef CONFIG_XEN
        mov r26=r8
@@ -869,7 +922,8 @@ 1:  ld8 r18=[r17]
 #endif /* !CONFIG_SMP */
        mov pr=r31,-1
 #ifdef CONFIG_XEN
-       XEN_HYPER_RFI;
+       XEN_HYPER_RFI
+       dv_serialize_data
 #else
        rfi
 #endif
@@ -892,11 +946,13 @@ ENTRY(daccess_bit)
        movl r30=1f                             // load continuation point in 
case of nested fault
        ;;
 #ifdef CONFIG_XEN
-       mov r18=r8;
-       mov r8=r16;
-       XEN_HYPER_THASH;;
-       mov r17=r8;
-       mov r8=r18;;
+       mov r18=r8
+       mov r8=r16
+       XEN_HYPER_THASH
+       ;;
+       mov r17=r8
+       mov r8=r18
+       ;;
 #else
        thash r17=r16                           // compute virtual address of 
L3 PTE
 #endif
@@ -909,11 +965,12 @@ 1:        ld8 r18=[r17]
        ;;                                      // avoid RAW on r18
        mov ar.ccv=r18                          // set compare value for cmpxchg
        or r25=_PAGE_A,r18                      // set the dirty bit
-       ;;
-       cmpxchg8.acq r26=[r17],r25,ar.ccv
+       tbit.z p7,p6 = r18,_PAGE_P_BIT          // Check present bit
+       ;;
+(p6)   cmpxchg8.acq r26=[r17],r25,ar.ccv       // Only if page is present
        mov r24=PAGE_SHIFT<<2
        ;;
-       cmp.eq p6,p7=r26,r18
+(p6)   cmp.eq p6,p7=r26,r18                    // Only if page is present
        ;;
 #ifdef CONFIG_XEN
        mov r26=r8
@@ -950,7 +1007,8 @@ 1: ld8 r18=[r17]
        mov b0=r29                              // restore b0
        mov pr=r31,-1
 #ifdef CONFIG_XEN
-       XEN_HYPER_RFI;
+       XEN_HYPER_RFI
+       dv_serialize_data
 #else
        rfi
 #endif
@@ -976,143 +1034,157 @@ ENTRY(break_fault)
         * to prevent leaking bits from kernel to user level.
         */
        DBG_FAULT(11)
-       mov r16=IA64_KR(CURRENT)                // r16 = current task; 12 cycle 
read lat.
-#ifdef CONFIG_XEN
-       movl r31=XSI_IPSR
-       ;;
-       ld8 r29=[r31],XSI_IIP-XSI_IPSR          // get ipsr, point to iip
-       mov r18=__IA64_BREAK_SYSCALL
-       mov r21=ar.fpsr
-       ;;
-       ld8 r28=[r31],XSI_IIM-XSI_IIP           // get iip, point to iim
-       mov r19=b6
-       mov r25=ar.unat
-       ;;
-       ld8 r17=[r31]                           // get iim
-       mov r27=ar.rsc
-       mov r26=ar.pfs
-       ;;
-#else
-       mov r17=cr.iim
-       mov r18=__IA64_BREAK_SYSCALL
-       mov r21=ar.fpsr
-       mov r29=cr.ipsr
-       mov r19=b6
-       mov r25=ar.unat
-       mov r27=ar.rsc
-       mov r26=ar.pfs
-       mov r28=cr.iip
-#endif
-       mov r31=pr                              // prepare to save predicates
-       mov r20=r1
-       ;;
+       mov.m r16=IA64_KR(CURRENT)              // M2 r16 <- current task (12 
cyc)
+#ifdef CONFIG_XEN
+       movl r22=XSI_IPSR
+       ;;
+       ld8 r29=[r22],XSI_IIM-XSI_IPSR          // get ipsr, point to iip
+#else
+       mov r29=cr.ipsr                         // M2 (12 cyc)
+#endif
+       mov r31=pr                              // I0 (2 cyc)
+
+#ifdef CONFIG_XEN
+       ;;
+       ld8 r17=[r22],XSI_IIP-XSI_IIM
+#else
+       mov r17=cr.iim                          // M2 (2 cyc)
+#endif
+       mov.m r27=ar.rsc                        // M2 (12 cyc)
+       mov r18=__IA64_BREAK_SYSCALL            // A
+
+       mov.m ar.rsc=0                          // M2
+       mov.m r21=ar.fpsr                       // M2 (12 cyc)
+       mov r19=b6                              // I0 (2 cyc)
+       ;;
+       mov.m r23=ar.bspstore                   // M2 (12 cyc)
+       mov.m r24=ar.rnat                       // M2 (5 cyc)
+       mov.i r26=ar.pfs                        // I0 (2 cyc)
+
+       invala                                  // M0|1
+       nop.m 0                                 // M
+       mov r20=r1                              // A                    save r1
+
+       nop.m 0
+       movl r30=sys_call_table                 // X
+
+#ifdef CONFIG_XEN
+       ld8 r28=[r22]
+#else
+       mov r28=cr.iip                          // M2 (2 cyc)
+#endif
+       cmp.eq p0,p7=r18,r17                    // I0 is this a system call?
+(p7)   br.cond.spnt non_syscall                // B  no ->
+       //
+       // From this point on, we are definitely on the syscall-path
+       // and we can use (non-banked) scratch registers.
+       //
+///////////////////////////////////////////////////////////////////////
+       mov r1=r16                              // A    move task-pointer to 
"addl"-addressable reg
+       mov r2=r16                              // A    setup r2 for 
ia64_syscall_setup
+       add r9=TI_FLAGS+IA64_TASK_SIZE,r16      // A    r9 = 
&current_thread_info()->flags
+
        adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
-       cmp.eq p0,p7=r18,r17                    // is this a system call? (p7 
<- false, if so)
-(p7)   br.cond.spnt non_syscall
-       ;;
-       ld1 r17=[r16]                           // load 
current->thread.on_ustack flag
-       st1 [r16]=r0                            // clear 
current->thread.on_ustack flag
-       add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16   // set r1 for 
MINSTATE_START_SAVE_MIN_VIRT
-       ;;
-       invala
-
-       /* adjust return address so we skip over the break instruction: */
-
-       extr.u r8=r29,41,2                      // extract ei field from cr.ipsr
-       ;;
-       cmp.eq p6,p7=2,r8                       // isr.ei==2?
-       mov r2=r1                               // setup r2 for 
ia64_syscall_setup
-       ;;
-(p6)   mov r8=0                                // clear ei to 0
-(p6)   adds r28=16,r28                         // switch cr.iip to next bundle 
cr.ipsr.ei wrapped
-(p7)   adds r8=1,r8                            // increment ei to next slot
-       ;;
-       cmp.eq pKStk,pUStk=r0,r17               // are we in kernel mode 
already?
-       dep r29=r8,r29,41,2                     // insert new ei into cr.ipsr
-       ;;
-
-       // switch from user to kernel RBS:
-       MINSTATE_START_SAVE_MIN_VIRT
-       br.call.sptk.many b7=ia64_syscall_setup
-       ;;
+       adds r15=-1024,r15                      // A    subtract 1024 from 
syscall number
+       mov r3=NR_syscalls - 1
+       ;;
+       ld1.bias r17=[r16]                      // M0|1 r17 = 
current->thread.on_ustack flag
+       ld4 r9=[r9]                             // M0|1 r9 = 
current_thread_info()->flags
+       extr.u r8=r29,41,2                      // I0   extract ei field from 
cr.ipsr
+
+       shladd r30=r15,3,r30                    // A    r30 = sys_call_table + 
8*(syscall-1024)
+       addl r22=IA64_RBS_OFFSET,r1             // A    compute base of RBS
+       cmp.leu p6,p7=r15,r3                    // A    syscall number in range?
+       ;;
+
+       lfetch.fault.excl.nt1 [r22]             // M0|1 prefetch RBS
+(p6)   ld8 r30=[r30]                           // M0|1 load address of syscall 
entry point
+       tnat.nz.or p7,p0=r15                    // I0   is syscall nr a NaT?
+
+       mov.m ar.bspstore=r22                   // M2   switch to kernel RBS
+       cmp.eq p8,p9=2,r8                       // A    isr.ei==2?
+       ;;
+
+(p8)   mov r8=0                                // A    clear ei to 0
+(p7)   movl r30=sys_ni_syscall                 // X
+
+(p8)   adds r28=16,r28                         // A    switch cr.iip to next 
bundle
+(p9)   adds r8=1,r8                            // A    increment ei to next 
slot
+       nop.i 0
+       ;;
+
+       mov.m r25=ar.unat                       // M2 (5 cyc)
+       dep r29=r8,r29,41,2                     // I0   insert new ei into 
cr.ipsr
+       adds r15=1024,r15                       // A    restore original 
syscall number
+       //
+       // If any of the above loads miss in L1D, we'll stall here until
+       // the data arrives.
+       //
+///////////////////////////////////////////////////////////////////////
+       st1 [r16]=r0                            // M2|3 clear 
current->thread.on_ustack flag
+       mov b6=r30                              // I0   setup syscall handler 
branch reg early
+       cmp.eq pKStk,pUStk=r0,r17               // A    were we on kernel 
stacks already?
+
+       and r9=_TIF_SYSCALL_TRACEAUDIT,r9       // A    mask trace or audit
+       mov r18=ar.bsp                          // M2 (12 cyc)
+(pKStk)        br.cond.spnt .break_fixup               // B    we're already 
in kernel-mode -- fix up RBS
+       ;;
+.back_from_break_fixup:
+(pUStk)        addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A    compute 
base of memory stack
+       cmp.eq p14,p0=r9,r0                     // A    are syscalls being 
traced/audited?
+       br.call.sptk.many b7=ia64_syscall_setup // B
+1:
+       mov ar.rsc=0x3                          // M2   set eager mode, pl 0, 
LE, loadrs=0
+       nop 0
 #ifdef CONFIG_XEN
        mov r2=b0; br.call.sptk b0=xen_bsw1;; mov b0=r2;;
 #else
-       MINSTATE_END_SAVE_MIN_VIRT              // switch to bank 1
-#endif
-#ifdef CONFIG_XEN
-       movl r3=XSI_PSR_IC
-       mov r16=1
-       ;;
-#if 1
-       st4 [r3]=r16,XSI_PSR_I_ADDR-XSI_PSR_IC  // vpsr.ic = 1
-       ;;
-(p15)  ld8 r3=[r3]
-       ;;
-(p15)  st1 [r3]=r0,XSI_PEND-XSI_PSR_I_ADDR     // if (p15) vpsr.i = 1
-       mov r16=r0
-       ;;
-(p15)  ld4 r16=[r3]                            // if (pending_interrupts)
-       ;;
-       cmp.ne  p6,p0=r16,r0
+       bsw.1                                   // B (6 cyc) regs are saved, 
switch to bank 1
+#endif
+       ;;
+
+#ifdef CONFIG_XEN
+       movl r16=XSI_PSR_IC
+       mov r3=1
+       ;;
+       st4 [r16]=r3,XSI_PSR_I_ADDR-XSI_PSR_IC  // vpsr.ic = 1
+#else
+       ssm psr.ic | PSR_DEFAULT_BITS           // M2   now it's safe to 
re-enable intr.-collection
+#endif
+       movl r3=ia64_ret_from_syscall           // X
+       ;;
+
+       srlz.i                                  // M0   ensure interruption 
collection is on
+       mov rp=r3                               // I0   set the real return addr
+(p10)  br.cond.spnt.many ia64_ret_from_syscall // B    return if bad 
call-frame or r15 is a NaT
+
+#ifdef CONFIG_XEN
+(p15)  ld8 r16=[r16]                           // vpsr.i
+       ;;
+(p15)  st1 [r16]=r0,XSI_PEND-XSI_PSR_I_ADDR    // if (p15) vpsr.i = 1
+       mov r2=r0
+       ;;
+(p15)  ld4 r2=[r16]                            // if (pending_interrupts)
+       ;;
+       cmp.ne  p6,p0=r2,r0
        ;;
 (p6)   ssm     psr.i                           //   do a real ssm psr.i
-       ;;
-#else
-//     st4 [r3]=r16,XSI_PSR_I_ADDR-XSI_PSR_IC  // vpsr.ic = 1
-       adds r3=XSI_PSR_I_ADDR-XSI_PSR_IC,r3    // SKIP vpsr.ic = 1
-       ;;
-(p15)  ld8 r3=[r3]
-       ;;
-(p15)  st1 [r3]=r0,XSI_PEND-XSI_PSR_I_ADDR     // if (p15) vpsr.i = 1
-       mov r16=r0
-       ;;
-(p15)  ld4 r16=[r3]                            // if (pending_interrupts)
-       ;;
-       cmp.ne  p6,p0=r16,r0
-       ;;
-//(p6) ssm     psr.i                           //   do a real ssm psr.i
-//(p6) XEN_HYPER_SSM_I;
-(p6)   break 0x7;
-       ;;
-#endif
-       mov r3=NR_syscalls - 1
-       ;;
-#else
-       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
-#endif
-       // p10==true means out registers are more than 8 or r15's Nat is true
-(p10)  br.cond.spnt.many ia64_ret_from_syscall
-       ;;
-       movl r16=sys_call_table
-
-       adds r15=-1024,r15                      // r15 contains the syscall 
number---subtract 1024
-       movl r2=ia64_ret_from_syscall
-       ;;
-       shladd r20=r15,3,r16                    // r20 = sys_call_table + 
8*(syscall-1024)
-       cmp.leu p6,p7=r15,r3                    // (syscall > 0 && syscall < 
1024 + NR_syscalls) ?
-       mov rp=r2                               // set the real return addr
-       ;;
-(p6)   ld8 r20=[r20]                           // load address of syscall 
entry point
-(p7)   movl r20=sys_ni_syscall
-
-       add r2=TI_FLAGS+IA64_TASK_SIZE,r13
-       ;;
-       ld4 r2=[r2]                             // r2 = 
current_thread_info()->flags
-       ;;
-       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
-       br.cond.sptk ia64_trace_syscall
+#else
+(p15)  ssm psr.i                               // M2   restore psr.i
+#endif
+(p14)  br.call.sptk.many b6=b6                 // B    invoke syscall-handker 
(ignore return addr)
+       br.cond.spnt.many ia64_trace_syscall    // B    do syscall-tracing 
thingamagic
        // NOT REACHED
+///////////////////////////////////////////////////////////////////////
+       // On entry, we optimistically assumed that we're coming from 
user-space.
+       // For the rare cases where a system-call is done from within the 
kernel,
+       // we fix things up at this point:
+.break_fixup:
+       add r1=-IA64_PT_REGS_SIZE,sp            // A    allocate space for 
pt_regs structure
+       mov ar.rnat=r24                         // M2   restore kernel's AR.RNAT
+       ;;
+       mov ar.bspstore=r23                     // M2   restore kernel's 
AR.BSPSTORE
+       br.cond.sptk .back_from_break_fixup
 END(break_fault)
 
        .org ia64_ivt+0x3000
@@ -1201,8 +1273,6 @@ END(interrupt)
         *      - r31: saved pr
         *      -  b0: original contents (to be saved)
         * 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
@@ -1210,8 +1280,11 @@ END(interrupt)
         *      -  r8: -EINVAL if p10 is true
         *      - r12: points to kernel stack
         *      - r13: points to current task
+        *      - r14: preserved (same as on entry)
+        *      - p13: preserved
         *      - p15: TRUE if interrupts need to be re-enabled
         *      - ar.fpsr: set to kernel settings
+        *      -  b6: preserved (same as on entry)
         */
 #ifndef CONFIG_XEN
 GLOBAL_ENTRY(ia64_syscall_setup)
@@ -1280,10 +1353,10 @@ GLOBAL_ENTRY(ia64_syscall_setup)
 (p13)  mov in5=-1
        ;;
        st8 [r16]=r21,PT(R8)-PT(AR_FPSR)        // save ar.fpsr
-       tnat.nz p14,p0=in6
+       tnat.nz p13,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)
+       mov r8=1
 (p9)   tnat.nz p10,p0=r15
        adds r12=-16,r1         // switch to kernel memory stack (with 16 bytes 
of scratch)
 
@@ -1294,9 +1367,9 @@ GLOBAL_ENTRY(ia64_syscall_setup)
        mov r13=r2                              // establish `current'
        movl r1=__gp                            // establish kernel global 
pointer
        ;;
-(p14)  mov in6=-1
+       st8 [r16]=r8            // ensure pt_regs.r8 != 0 (see 
handle_syscall_error)
+(p13)  mov in6=-1
 (p8)   mov in7=-1
-       nop.i 0
 
        cmp.eq pSys,pNonSys=r0,r0               // set pSys=1, pNonSys=0
        movl r17=FPSR_DEFAULT
@@ -1323,6 +1396,8 @@ END(ia64_syscall_setup)
         * element, followed by the arguments.
         */
 ENTRY(dispatch_illegal_op_fault)
+       .prologue
+       .body
        SAVE_MIN_WITH_COVER
        ssm psr.ic | PSR_DEFAULT_BITS
        ;;
@@ -1335,6 +1410,7 @@ ENTRY(dispatch_illegal_op_fault)
        mov out0=ar.ec
        ;;
        SAVE_REST
+       PT_REGS_UNWIND_INFO(0)
        ;;
        br.call.sptk.many rp=ia64_illegal_op_fault
 .ret0: ;;
@@ -1365,6 +1441,8 @@ END(dispatch_illegal_op_fault)
        FAULT(17)
 
 ENTRY(non_syscall)
+       mov ar.rsc=r27                  // restore ar.rsc before 
SAVE_MIN_WITH_COVER
+       ;;
        SAVE_MIN_WITH_COVER
 
        // There is no particular reason for this code to be here, other than 
that
@@ -1540,7 +1618,7 @@ ENTRY(daccess_rights)
        ;;
        ld8 r16=[r16]
        ;;
-       XEN_HYPER_RSM_PSR_DT;
+       XEN_HYPER_RSM_PSR_DT
 #else
        mov r16=cr.ifa
        rsm psr.dt
@@ -1584,6 +1662,25 @@ END(disabled_fp_reg)
 // 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50)
 ENTRY(nat_consumption)
        DBG_FAULT(26)
+
+       mov r16=cr.ipsr
+       mov r17=cr.isr
+       mov r31=pr                              // save PR
+       ;;
+       and r18=0xf,r17                         // r18 = cr.ipsr.code{3:0}
+       tbit.z p6,p0=r17,IA64_ISR_NA_BIT
+       ;;
+       cmp.ne.or p6,p0=IA64_ISR_CODE_LFETCH,r18
+       dep r16=-1,r16,IA64_PSR_ED_BIT,1
+(p6)   br.cond.spnt 1f         // branch if (cr.ispr.na == 0 || 
cr.ipsr.code{3:0} != LFETCH)
+       ;;
+       mov cr.ipsr=r16         // set cr.ipsr.na
+       mov pr=r31,-1
+       ;;
+       rfi
+
+1:     mov pr=r31,-1
+       ;;
        FAULT(26)
 END(nat_consumption)
 
@@ -1624,7 +1721,7 @@ ENTRY(speculation_vector)
 #ifdef CONFIG_XEN
        XEN_HYPER_RFI;
 #else
-       rfi
+       rfi                             // and go back
 #endif
 END(speculation_vector)
 
@@ -1647,7 +1744,6 @@ END(debug_vector)
 // 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57)
 ENTRY(unaligned_access)
        DBG_FAULT(30)
-       mov r16=cr.ipsr
        mov r31=pr              // prepare to save predicates
        ;;
        br.sptk.many dispatch_unaligned_handler

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.