WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [IA64] update xenivt.S and xenentry.S, Xen patchbot-unstable <=