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

[Xen-changelog] [IA64] VTI: Optimize thash vtlb algorithm



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 166073f830a3ca3ba4495f33e1beed99f09a0e99
# Parent  18b087bafac6197716b7b2290ddb1c7e656916fe
[IA64] VTI: Optimize thash vtlb algorithm

Signed-off-by: Anthony Xu <anthony.xu@xxxxxxxxx>
---
 xen/arch/ia64/vmx/vmmu.c          |   32 +
 xen/arch/ia64/vmx/vmx_interrupt.c |   11 
 xen/arch/ia64/vmx/vmx_ivt.S       |  222 +++++-------
 xen/arch/ia64/vmx/vmx_process.c   |   57 +--
 xen/arch/ia64/vmx/vtlb.c          |  679 ++++++++++++++------------------------
 xen/include/asm-ia64/vmmu.h       |  111 +-----
 xen/include/asm-ia64/vmx_vcpu.h   |    1 
 7 files changed, 428 insertions(+), 685 deletions(-)

diff -r 18b087bafac6 -r 166073f830a3 xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c  Tue May 30 08:46:21 2006 -0600
+++ b/xen/arch/ia64/vmx/vmmu.c  Tue May 30 10:28:59 2006 -0600
@@ -338,6 +338,7 @@ fetch_code(VCPU *vcpu, u64 gip, u64 *cod
 
 IA64FAULT vmx_vcpu_itc_i(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa)
 {
+#ifdef VTLB_DEBUG
     int slot;
     u64 ps, va;
     ps = itir_ps(itir);
@@ -348,14 +349,16 @@ IA64FAULT vmx_vcpu_itc_i(VCPU *vcpu, UIN
         panic_domain(vcpu_regs(vcpu),"Tlb conflict!!");
         return IA64_FAULT;
     }
+#endif //VTLB_DEBUG    
     thash_purge_and_insert(vcpu, pte, itir, ifa);
     return IA64_NO_FAULT;
 }
 
 IA64FAULT vmx_vcpu_itc_d(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa)
 {
+#ifdef VTLB_DEBUG    
     int slot;
-    u64 ps, va, gpfn;
+    u64 ps, va;
     ps = itir_ps(itir);
     va = PAGEALIGN(ifa, ps);
     slot = vtr_find_overlap(vcpu, va, ps, DSIDE_TLB);
@@ -364,9 +367,7 @@ IA64FAULT vmx_vcpu_itc_d(VCPU *vcpu, UIN
         panic_domain(vcpu_regs(vcpu),"Tlb conflict!!");
         return IA64_FAULT;
     }
-    gpfn = (pte & _PAGE_PPN_MASK)>> PAGE_SHIFT;
-    if(VMX_DOMAIN(vcpu) && __gpfn_is_io(vcpu->domain,gpfn))
-        pte |= VTLB_PTE_IO;
+#endif //VTLB_DEBUG
     thash_purge_and_insert(vcpu, pte, itir, ifa);
     return IA64_NO_FAULT;
 
@@ -377,11 +378,14 @@ IA64FAULT vmx_vcpu_itc_d(VCPU *vcpu, UIN
 
 IA64FAULT vmx_vcpu_itr_i(VCPU *vcpu, u64 slot, u64 pte, u64 itir, u64 ifa)
 {
+#ifdef VTLB_DEBUG
     int index;
+#endif    
     u64 ps, va, rid;
-
+    thash_data_t * p_itr;
     ps = itir_ps(itir);
     va = PAGEALIGN(ifa, ps);
+#ifdef VTLB_DEBUG    
     index = vtr_find_overlap(vcpu, va, ps, ISIDE_TLB);
     if (index >=0) {
         // generate MCA.
@@ -389,9 +393,11 @@ IA64FAULT vmx_vcpu_itr_i(VCPU *vcpu, u64
         return IA64_FAULT;
     }
     thash_purge_entries(vcpu, va, ps);
+#endif    
     vcpu_get_rr(vcpu, va, &rid);
     rid = rid& RR_RID_MASK;
-    vmx_vcpu_set_tr((thash_data_t *)&vcpu->arch.itrs[slot], pte, itir, va, 
rid);
+    p_itr = (thash_data_t *)&vcpu->arch.itrs[slot];
+    vmx_vcpu_set_tr(p_itr, pte, itir, va, rid);
     vcpu_quick_region_set(PSCBX(vcpu,itr_regions),va);
     return IA64_NO_FAULT;
 }
@@ -399,11 +405,15 @@ IA64FAULT vmx_vcpu_itr_i(VCPU *vcpu, u64
 
 IA64FAULT vmx_vcpu_itr_d(VCPU *vcpu, u64 slot, u64 pte, u64 itir, u64 ifa)
 {
+#ifdef VTLB_DEBUG
     int index;
-    u64 ps, va, gpfn, rid;
-
+    u64 gpfn;
+#endif    
+    u64 ps, va, rid;
+    thash_data_t * p_dtr;
     ps = itir_ps(itir);
     va = PAGEALIGN(ifa, ps);
+#ifdef VTLB_DEBUG    
     index = vtr_find_overlap(vcpu, va, ps, DSIDE_TLB);
     if (index>=0) {
         // generate MCA.
@@ -412,10 +422,12 @@ IA64FAULT vmx_vcpu_itr_d(VCPU *vcpu, u64
     }
     thash_purge_entries(vcpu, va, ps);
     gpfn = (pte & _PAGE_PPN_MASK)>> PAGE_SHIFT;
-    if(__gpfn_is_io(vcpu->domain,gpfn))
+    if(VMX_DOMAIN(vcpu) && _gpfn_is_io(vcpu->domain,gpfn))
         pte |= VTLB_PTE_IO;
+#endif    
     vcpu_get_rr(vcpu, va, &rid);
     rid = rid& RR_RID_MASK;
+    p_dtr = (thash_data_t *)&vcpu->arch.dtrs[slot];
     vmx_vcpu_set_tr((thash_data_t *)&vcpu->arch.dtrs[slot], pte, itir, va, 
rid);
     vcpu_quick_region_set(PSCBX(vcpu,dtr_regions),va);
     return IA64_NO_FAULT;
@@ -432,7 +444,6 @@ IA64FAULT vmx_vcpu_ptr_d(VCPU *vcpu,UINT
     index = vtr_find_overlap(vcpu, va, ps, DSIDE_TLB);
     if (index>=0) {
         vcpu->arch.dtrs[index].pte.p=0;
-        index = vtr_find_overlap(vcpu, va, ps, DSIDE_TLB);
     }
     thash_purge_entries(vcpu, va, ps);
     return IA64_NO_FAULT;
@@ -447,7 +458,6 @@ IA64FAULT vmx_vcpu_ptr_i(VCPU *vcpu,UINT
     index = vtr_find_overlap(vcpu, va, ps, ISIDE_TLB);
     if (index>=0) {
         vcpu->arch.itrs[index].pte.p=0;
-        index = vtr_find_overlap(vcpu, va, ps, ISIDE_TLB);
     }
     thash_purge_entries(vcpu, va, ps);
     return IA64_NO_FAULT;
diff -r 18b087bafac6 -r 166073f830a3 xen/arch/ia64/vmx/vmx_interrupt.c
--- a/xen/arch/ia64/vmx/vmx_interrupt.c Tue May 30 08:46:21 2006 -0600
+++ b/xen/arch/ia64/vmx/vmx_interrupt.c Tue May 30 10:28:59 2006 -0600
@@ -390,3 +390,14 @@ page_not_present(VCPU *vcpu, u64 vadr)
     inject_guest_interruption(vcpu, IA64_PAGE_NOT_PRESENT_VECTOR);
 }
 
+/* Deal with
+ *  Data access rights vector
+ */
+void
+data_access_rights(VCPU *vcpu, u64 vadr)
+{
+    /* If vPSR.ic, IFA, ITIR */
+    set_ifa_itir_iha (vcpu, vadr, 1, 1, 0);
+    inject_guest_interruption(vcpu, IA64_DATA_ACCESS_RIGHTS_VECTOR);
+}
+
diff -r 18b087bafac6 -r 166073f830a3 xen/arch/ia64/vmx/vmx_ivt.S
--- a/xen/arch/ia64/vmx/vmx_ivt.S       Tue May 30 08:46:21 2006 -0600
+++ b/xen/arch/ia64/vmx/vmx_ivt.S       Tue May 30 10:28:59 2006 -0600
@@ -141,9 +141,13 @@ ENTRY(vmx_itlb_miss)
     mov r16 = cr.ifa
     ;;
     thash r17 = r16
-    ;;
     ttag r20 = r16
-    mov r18 = r17      
+    ;;
+    mov r18 = r17
+    adds r28 = VLE_TITAG_OFFSET,r17
+    adds r19 = VLE_CCHAIN_OFFSET, r17
+    ;;
+    ld8 r17 = [r19]
     ;;
 vmx_itlb_loop:
     cmp.eq p6,p0 = r0, r17
@@ -161,43 +165,21 @@ vmx_itlb_loop:
 (p7)mov r17 = r23;
 (p7)br.sptk vmx_itlb_loop
     ;;
-    adds r23 = VLE_PGFLAGS_OFFSET, r17
-    adds r24 = VLE_ITIR_OFFSET, r17
-    ;;
-    ld8 r25 = [r23]
-    ld8 r26 = [r24]
-    ;;
-    cmp.eq p6,p7=r18,r17
-(p6) br vmx_itlb_loop1
-    ;;
+    ld8 r25 = [r17]
     ld8 r27 = [r18]
-    ;;
-    extr.u r19 = r27, 56, 8
-    extr.u r20 = r25, 56, 8
-    ;;
-    dep r27 = r20, r27, 56, 8
-    dep r25 = r19, r25, 56, 8
-    ;;
-    st8 [r18] = r25,8
-    st8 [r23] = r27
-    ;;
-    ld8 r28 = [r18]
-    ;;
-    st8 [r18] = r26,8
-    st8 [r24] = r28
-    ;;
-    ld8 r30 = [r18]
-    ;;
-    st8 [r18] = r22
-    st8 [r16] = r30 
-    ;;
-vmx_itlb_loop1:
-    mov cr.itir = r26
+    ld8 r29 = [r28]
+    ;;
+    st8 [r16] = r29
+    st8 [r28] = r22
+    extr.u r19 = r27, 56, 4
+    ;;
+    dep r27 = r0, r27, 56, 4
+    dep r25 = r19, r25, 56, 4
+    ;;
+    st8 [r18] = r25
+    st8 [r17] = r27
     ;;
     itc.i r25
-    ;;
-    srlz.i
-    ;;
     mov r17=cr.isr
     mov r23=r31
     mov r22=b0
@@ -219,7 +201,7 @@ vmx_itlb_out:
     VMX_FAULT(1);
 END(vmx_itlb_miss)
 
-       .org vmx_ia64_ivt+0x0800
+    .org vmx_ia64_ivt+0x0800
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x0800 Entry 2 (size 64 bundles) DTLB (9,48)
 ENTRY(vmx_dtlb_miss)
@@ -232,9 +214,13 @@ ENTRY(vmx_dtlb_miss)
     mov r16 = cr.ifa
     ;;
     thash r17 = r16
-    ;;
     ttag r20 = r16
-    mov r18 = r17      
+    ;;
+    mov r18 = r17
+    adds r28 = VLE_TITAG_OFFSET,r17
+    adds r19 = VLE_CCHAIN_OFFSET, r17
+    ;;
+    ld8 r17 = [r19]
     ;;
 vmx_dtlb_loop:
     cmp.eq p6,p0 = r0, r17
@@ -252,43 +238,21 @@ vmx_dtlb_loop:
 (p7)mov r17 = r23;
 (p7)br.sptk vmx_dtlb_loop
     ;;
-    adds r23 = VLE_PGFLAGS_OFFSET, r17
-    adds r24 = VLE_ITIR_OFFSET, r17
-    ;;
-    ld8 r25 = [r23]
-    ld8 r26 = [r24]
-    ;;
-    cmp.eq p6,p7=r18,r17
-(p6) br vmx_dtlb_loop1
-    ;;
+    ld8 r25 = [r17]
     ld8 r27 = [r18]
-    ;;
-    extr.u r19 = r27, 56, 8
-    extr.u r20 = r25, 56, 8
-    ;;
-    dep r27 = r20, r27, 56, 8
-    dep r25 = r19, r25, 56, 8
-    ;;
-    st8 [r18] = r25,8
-    st8 [r23] = r27
-    ;;
-    ld8 r28 = [r18]
-    ;;
-    st8 [r18] = r26,8
-    st8 [r24] = r28
-    ;;
-    ld8 r30 = [r18]
-    ;;
-    st8 [r18] = r22
-    st8 [r16] = r30 
-    ;;
-vmx_dtlb_loop1:
-    mov cr.itir = r26
-    ;;
+    ld8 r29 = [r28]
+    ;;
+    st8 [r16] = r29
+    st8 [r28] = r22
+    extr.u r19 = r27, 56, 4
+    ;;
+    dep r27 = r0, r27, 56, 4
+    dep r25 = r19, r25, 56, 4
+    ;;
+    st8 [r18] = r25
+    st8 [r17] = r27
+    ;;    
     itc.d r25
-    ;;
-    srlz.d;
-    ;;
     mov r17=cr.isr
     mov r23=r31
     mov r22=b0
@@ -310,7 +274,7 @@ vmx_dtlb_out:
     VMX_FAULT(2);
 END(vmx_dtlb_miss)
 
-       .org vmx_ia64_ivt+0x0c00
+    .org vmx_ia64_ivt+0x0c00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
 ENTRY(vmx_alt_itlb_miss)
@@ -321,88 +285,84 @@ ENTRY(vmx_alt_itlb_miss)
     tbit.z p6,p7=r29,IA64_PSR_VM_BIT;
 (p7)br.spnt vmx_fault_3
 vmx_alt_itlb_miss_1:
-       mov r16=cr.ifa          // get address that caused the TLB miss
+    mov r16=cr.ifa    // get address that caused the TLB miss
     ;;
     tbit.z p6,p7=r16,63
 (p6)br.spnt vmx_fault_3
     ;;
-       movl r17=PAGE_KERNEL
-       mov r24=cr.ipsr
-       movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
-       ;;
-       and r19=r19,r16         // clear ed, reserved bits, and PTE control bits
-       shr.u r18=r16,55        // move address bit 59 to bit 4
-       ;;
-       and r18=0x10,r18        // bit 4=address-bit(61)
-       or r19=r17,r19          // insert PTE control bits into r19
-       ;;
-       movl r20=IA64_GRANULE_SHIFT<<2
-       or r19=r19,r18          // set bit 4 (uncached) if the access was to 
region 6
-       ;;
-       mov cr.itir=r20
-       ;;
-       srlz.i
-       ;;
-       itc.i r19               // insert the TLB entry
-       mov pr=r31,-1
-       rfi
+    movl r17=PAGE_KERNEL
+    mov r24=cr.ipsr
+    movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
+    ;;
+    and r19=r19,r16     // clear ed, reserved bits, and PTE control bits
+    shr.u r18=r16,55    // move address bit 59 to bit 4
+    ;;
+    and r18=0x10,r18    // bit 4=address-bit(61)
+    or r19=r17,r19      // insert PTE control bits into r19
+    ;;
+    movl r20=IA64_GRANULE_SHIFT<<2
+    or r19=r19,r18     // set bit 4 (uncached) if the access was to region 6
+    ;;
+    mov cr.itir=r20
+    ;;
+    itc.i r19          // insert the TLB entry
+    mov pr=r31,-1
+    rfi
     VMX_FAULT(3);
 END(vmx_alt_itlb_miss)
 
 
-       .org vmx_ia64_ivt+0x1000
+    .org vmx_ia64_ivt+0x1000
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
 ENTRY(vmx_alt_dtlb_miss)
     VMX_DBG_FAULT(4)
-       mov r31=pr
+    mov r31=pr
     mov r29=cr.ipsr;
     ;;
     tbit.z p6,p7=r29,IA64_PSR_VM_BIT;
 (p7)br.spnt vmx_fault_4
 vmx_alt_dtlb_miss_1:
-       mov r16=cr.ifa          // get address that caused the TLB miss
+    mov r16=cr.ifa             // get address that caused the TLB miss
     ;;
 #ifdef CONFIG_VIRTUAL_FRAME_TABLE
-       // Test for the address of virtual frame_table
-       shr r22=r16,56;;
-       cmp.eq p8,p0=((VIRT_FRAME_TABLE_ADDR>>56)&0xff)-0x100,r22
-(p8)   br.cond.sptk frametable_miss ;;
+    // Test for the address of virtual frame_table
+    shr r22=r16,56;;
+    cmp.eq p8,p0=((VIRT_FRAME_TABLE_ADDR>>56)&0xff)-0x100,r22
+(p8)br.cond.sptk frametable_miss ;;
 #endif
     tbit.z p6,p7=r16,63
 (p6)br.spnt vmx_fault_4
     ;;
-       movl r17=PAGE_KERNEL
-       mov r20=cr.isr
-       movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
-       mov r24=cr.ipsr
-       ;;
-       and r22=IA64_ISR_CODE_MASK,r20          // get the isr.code field
-       tbit.nz p6,p7=r20,IA64_ISR_SP_BIT       // is speculation bit on?
-       shr.u r18=r16,55                        // move address bit 59 to bit 4
-       and r19=r19,r16                         // clear ed, reserved bits, and 
PTE control bits
-       tbit.nz p9,p0=r20,IA64_ISR_NA_BIT       // is non-access bit on?
-       ;;
-       and r18=0x10,r18        // bit 4=address-bit(61)
-(p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22    // check isr.code field
-       dep r24=-1,r24,IA64_PSR_ED_BIT,1
-       or r19=r19,r17          // insert PTE control bits into r19
-       ;;
-       or r19=r19,r18          // set bit 4 (uncached) if the access was to 
region 6
-(p6) mov cr.ipsr=r24
-       movl r20=IA64_GRANULE_SHIFT<<2
-       ;;
-       mov cr.itir=r20
-       ;;
-       srlz.i
-       ;;
-(p7) itc.d r19         // insert the TLB entry
-       mov pr=r31,-1
-       rfi
+    movl r17=PAGE_KERNEL
+    mov r20=cr.isr
+    movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
+    mov r24=cr.ipsr
+    ;;
+    and r22=IA64_ISR_CODE_MASK,r20             // get the isr.code field
+    tbit.nz p6,p7=r20,IA64_ISR_SP_BIT          // is speculation bit on?
+    shr.u r18=r16,55                           // move address bit 59 to bit 4
+    and r19=r19,r16                            // clear ed, reserved bits, and 
PTE control bits
+    tbit.nz p9,p0=r20,IA64_ISR_NA_BIT          // is non-access bit on?
+    ;;
+    and r18=0x10,r18                           // bit 4=address-bit(61)
+(p9)cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22     // check isr.code field
+    dep r24=-1,r24,IA64_PSR_ED_BIT,1
+    or r19=r19,r17                             // insert PTE control bits into 
r19
+    ;;
+    or r19=r19,r18                             // set bit 4 (uncached) if the 
access was to region 6
+(p6)mov cr.ipsr=r24
+    movl r20=IA64_GRANULE_SHIFT<<2
+    ;;
+    mov cr.itir=r20
+    ;;
+(p7)itc.d r19          // insert the TLB entry
+    mov pr=r31,-1
+    rfi
     VMX_FAULT(4);
 END(vmx_alt_dtlb_miss)
 
-       .org vmx_ia64_ivt+0x1400
+    .org vmx_ia64_ivt+0x1400
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45)
 ENTRY(vmx_nested_dtlb_miss)
diff -r 18b087bafac6 -r 166073f830a3 xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c   Tue May 30 08:46:21 2006 -0600
+++ b/xen/arch/ia64/vmx/vmx_process.c   Tue May 30 10:28:59 2006 -0600
@@ -302,7 +302,7 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r
 {
     IA64_PSR vpsr;
     int type=ISIDE_TLB;
-    u64 vhpt_adr, gppa;
+    u64 vhpt_adr, gppa, pteval, rr, itir;
     ISR misr;
 //    REGS *regs;
     thash_data_t *data;
@@ -314,18 +314,6 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r
     vpsr.val = vmx_vcpu_get_psr(v);
     misr.val=VMX(v,cr_isr);
 
-/*  TODO
-    if(v->domain->id && vec == 2 &&
-       vpsr.dt == 0 && is_gpa_io(MASK_PMA(vaddr))){
-        emulate_ins(&v);
-        return;
-    }
-*/
-/*    if(vadr == 0x1ea18c00 ){
-        ia64_clear_ic();
-        while(1);
-    }
- */
     if(is_physical_mode(v)&&(!(vadr<<1>>62))){
         if(vec==2){
             
if(v->domain!=dom0&&__gpfn_is_io(v->domain,(vadr<<1)>>(PAGE_SHIFT+1))){
@@ -338,31 +326,24 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r
     }
     if(vec == 1) type = ISIDE_TLB;
     else if(vec == 2) type = DSIDE_TLB;
-    else panic_domain(regs,"wrong vec:%0xlx\n",vec);
+    else panic_domain(regs,"wrong vec:%lx\n",vec);
 
 //    prepare_if_physical_mode(v);
 
     if((data=vtlb_lookup(v, vadr,type))!=0){
-//     gppa = (vadr&((1UL<<data->ps)-1))+(data->ppn>>(data->ps-12)<<data->ps);
-//        if(v->domain!=dom0&&type==DSIDE_TLB && 
__gpfn_is_io(v->domain,gppa>>PAGE_SHIFT)){
+//       gppa = 
(vadr&((1UL<<data->ps)-1))+(data->ppn>>(data->ps-12)<<data->ps);
+//       if(v->domain!=dom0&&type==DSIDE_TLB && 
__gpfn_is_io(v->domain,gppa>>PAGE_SHIFT)){
         if(v->domain!=dom0 && data->io && type==DSIDE_TLB ){
-               gppa = 
(vadr&((1UL<<data->ps)-1))+(data->ppn>>(data->ps-12)<<data->ps);
-            emulate_io_inst(v, gppa, data->ma);
+            if(data->pl >= ((regs->cr_ipsr>>IA64_PSR_CPL0_BIT)&3)){
+                gppa = 
(vadr&((1UL<<data->ps)-1))+(data->ppn>>(data->ps-12)<<data->ps);
+                emulate_io_inst(v, gppa, data->ma);
+            }else{
+                data_access_rights(v, vadr);
+            }
             return IA64_FAULT;
         }
 
-//     if ( data->ps != vrr.ps ) {
-//             machine_tlb_insert(v, data);
-//     }
-//     else {
-/*        if ( data->contiguous&&(!data->tc)){
-               machine_tlb_insert(v, data);
-        }
-        else{
- */
-            thash_vhpt_insert(&v->arch.vhpt,data->page_flags, data->itir 
,vadr);
-//        }
-//         }
+        thash_vhpt_insert(v,data->page_flags, data->itir ,vadr);
     }else if(type == DSIDE_TLB){
         if(!vhpt_enabled(v, vadr, misr.rs?RSE_REF:DATA_REF)){
             if(vpsr.ic){
@@ -381,7 +362,13 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r
             }
         } else{
             vmx_vcpu_thash(v, vadr, &vhpt_adr);
-            if(vhpt_lookup(vhpt_adr) ||  vtlb_lookup(v, vhpt_adr, DSIDE_TLB)){
+            if(!guest_vhpt_lookup(vhpt_adr, &pteval)){
+                if (pteval & _PAGE_P){
+                    vcpu_get_rr(v, vadr, &rr);
+                    itir = rr&(RR_RID_MASK | RR_PS_MASK);
+                    thash_purge_and_insert(v, pteval, itir , vadr);
+                    return IA64_NO_FAULT;
+                }
                 if(vpsr.ic){
                     vcpu_set_isr(v, misr.val);
                     dtlb_fault(v, vadr);
@@ -423,7 +410,13 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r
             return IA64_FAULT;
         } else{
             vmx_vcpu_thash(v, vadr, &vhpt_adr);
-            if(vhpt_lookup(vhpt_adr) || vtlb_lookup(v, vhpt_adr, DSIDE_TLB)){
+            if(!guest_vhpt_lookup(vhpt_adr, &pteval)){
+                if (pteval & _PAGE_P){
+                    vcpu_get_rr(v, vadr, &rr);
+                    itir = rr&(RR_RID_MASK | RR_PS_MASK);
+                    thash_purge_and_insert(v, pteval, itir , vadr);
+                    return IA64_NO_FAULT;
+                }
                 if(!vpsr.ic){
                     misr.ni=1;
                 }
diff -r 18b087bafac6 -r 166073f830a3 xen/arch/ia64/vmx/vtlb.c
--- a/xen/arch/ia64/vmx/vtlb.c  Tue May 30 08:46:21 2006 -0600
+++ b/xen/arch/ia64/vmx/vtlb.c  Tue May 30 10:28:59 2006 -0600
@@ -36,27 +36,26 @@ thash_data_t *__alloc_chain(thash_cb_t *
 
 static void cch_mem_init(thash_cb_t *hcb)
 {
-    thash_data_t *p, *q;
+    int num;
+    thash_data_t *p;
 
     hcb->cch_freelist = p = hcb->cch_buf;
-
-    for ( q=p+1; (u64)(q + 1) <= (u64)hcb->cch_buf + hcb->cch_sz;
-        p++, q++ ) {
-        p->next = q;
-    }
+    num = (hcb->cch_sz/sizeof(thash_data_t))-1;
+    do{
+        p->next =p+1;
+        p++;
+        num--;
+    }while(num);
     p->next = NULL;
 }
 
 static thash_data_t *cch_alloc(thash_cb_t *hcb)
 {
     thash_data_t *p;
-
     if ( (p = hcb->cch_freelist) != NULL ) {
         hcb->cch_freelist = p->next;
-        return p;
-    }else{
-        return NULL;
-    }
+    }
+    return p;
 }
 
 static void cch_free(thash_cb_t *hcb, thash_data_t *cch)
@@ -101,17 +100,13 @@ static void __rem_hash_head(thash_cb_t *
 static void __rem_hash_head(thash_cb_t *hcb, thash_data_t *hash)
 {
     thash_data_t *next=hash->next;
-
-/*    if ( hcb->remove_notifier ) {
-        (hcb->remove_notifier)(hcb,hash);
-    } */
-    if ( next != NULL ) {
+    if ( next) {
         next->len=hash->len-1;
         *hash = *next;
         cch_free (hcb, next);
     }
     else {
-        INVALIDATE_HASH_HEADER(hcb, hash);
+        hash->ti=1;
     }
 }
 
@@ -145,125 +140,109 @@ thash_data_t *__vtr_lookup(VCPU *vcpu, u
 }
 
 
-/*
- * Get the machine format of VHPT entry.
- *    PARAS:
- *  1: tlb: means the tlb format hash entry converting to VHPT.
- *  2: va means the guest virtual address that must be coverd by
- *     the translated machine VHPT.
- *  3: vhpt: means the machine format VHPT converting from tlb.
- *    NOTES:
- *  1: In case of the machine address is discontiguous,
- *     "tlb" needs to be covered by several machine VHPT. va
- *     is used to choice one of them.
- *  2: Foreign map is supported in this API.
- *    RETURN:
- *  0/1: means successful or fail.
- *
- */
-int __tlb_to_vhpt(thash_cb_t *hcb, thash_data_t *vhpt, u64 va)
-{
-    u64 padr,pte;
-    ASSERT ( hcb->ht == THASH_VHPT );
-    padr = vhpt->ppn >>(vhpt->ps-ARCH_PAGE_SHIFT)<<vhpt->ps;
-    padr += va&((1UL<<vhpt->ps)-1);
-    pte=lookup_domain_mpa(current->domain,padr);
-    if((pte>>56))
-        return 0;
-    vhpt->etag = ia64_ttag(va);
-    vhpt->ps = PAGE_SHIFT;
-    vhpt->ppn = 
(pte&((1UL<<IA64_MAX_PHYS_BITS)-(1UL<<PAGE_SHIFT)))>>ARCH_PAGE_SHIFT;
-    vhpt->next = 0;
-    return 1;
-}
-
-static void thash_remove_cch(thash_cb_t *hcb, thash_data_t *hash)
+static void thash_recycle_cch(thash_cb_t *hcb, thash_data_t *hash)
 {
     thash_data_t *p;
-    if(hash->next){
-        p=hash->next;
-        while(p->next)
-            p=p->next;
-        p->next=hcb->cch_freelist;
-        hcb->cch_freelist=hash->next;
-        hash->next=0;
+    int i=0;
+    
+    p=hash;
+    for(i=0; i < MAX_CCN_DEPTH; i++){
+        p=p->next;
+    }
+    p->next=hcb->cch_freelist;
+    hcb->cch_freelist=hash->next;
+    hash->len=0;
+    hash->next=0;
+}
+
+
+
+
+static void vmx_vhpt_insert(thash_cb_t *hcb, u64 pte, u64 itir, u64 ifa)
+{
+    u64 tag;
+    thash_data_t *head, *cch;
+    pte = pte & ~PAGE_FLAGS_RV_MASK;
+
+    head = (thash_data_t *)ia64_thash(ifa);
+    tag = ia64_ttag(ifa);
+    if( INVALID_VHPT(head) ) {
+        head->page_flags = pte;
+        head->etag = tag;
+        return;
+    }
+
+    if(head->len>=MAX_CCN_DEPTH){
+        thash_recycle_cch(hcb, head);
+        cch = cch_alloc(hcb);
+    }
+    else{
+        cch = __alloc_chain(hcb);
+    }
+    cch->page_flags=head->page_flags;
+    cch->etag=head->etag;
+    cch->next=head->next;
+    head->page_flags=pte;
+    head->etag=tag;
+    head->next = cch;
+    head->len = cch->len+1;
+    cch->len = 0;
+    return;
+}
+
+void thash_vhpt_insert(VCPU *v, u64 pte, u64 itir, u64 va)
+{
+    u64 phy_pte;
+    phy_pte=translate_phy_pte(v, &pte, itir, va);
+    vmx_vhpt_insert(vcpu_get_vhpt(v), phy_pte, itir, va);
+}
+/*
+ *   vhpt lookup
+ */
+
+thash_data_t * vhpt_lookup(u64 va)
+{
+    thash_data_t *hash, *head;
+    u64 tag, pte;
+    head = (thash_data_t *)ia64_thash(va);
+    hash=head;
+    tag = ia64_ttag(va);
+    do{
+        if(hash->etag == tag)
+            break;
+        hash=hash->next;
+    }while(hash);
+    if(hash && hash!=head){
+        pte = hash->page_flags;
+        hash->page_flags = head->page_flags;
+        head->page_flags = pte;
+        tag = hash->etag;
+        hash->etag = head->etag;
+        head->etag = tag;
+        head->len = hash->len;
         hash->len=0;
-    }
-}
-
-/*  vhpt only has entries with PAGE_SIZE page size */
-
-void thash_vhpt_insert(thash_cb_t *hcb, u64 pte, u64 itir, u64 ifa)
-{
-    thash_data_t   vhpt_entry, *hash_table, *cch;
-    vhpt_entry.page_flags = pte & ~PAGE_FLAGS_RV_MASK;
-    vhpt_entry.itir=itir;
-
-    if ( !__tlb_to_vhpt(hcb, &vhpt_entry, ifa) ) {
-        return;
-    //panic("Can't convert to machine VHPT entry\n");
-    }
-
-    hash_table = (thash_data_t *)ia64_thash(ifa);
-    if( INVALID_VHPT(hash_table) ) {
-        *hash_table = vhpt_entry;
-        hash_table->next = 0;
-       return;
-    }
-
-    cch = hash_table;
-    while(cch){
-        if(cch->etag == vhpt_entry.etag){
-            if(cch->ppn == vhpt_entry.ppn)
-                return;
-            else
-                while(1);
-        }
-        cch = cch->next;
-    }
-
-    if(hash_table->len>=MAX_CCN_DEPTH){
-       thash_remove_cch(hcb, hash_table);
-       cch = cch_alloc(hcb);
-       *cch = *hash_table;
-        *hash_table = vhpt_entry;
-       hash_table->len = 1;
-        hash_table->next = cch;
-       return;
-    }
-
-    // TODO: Add collision chain length limitation.
-     cch = __alloc_chain(hcb);
-     if(cch == NULL){
-           *hash_table = vhpt_entry;
-            hash_table->next = 0;
-     }else{
-            *cch = *hash_table;
-            *hash_table = vhpt_entry;
-            hash_table->next = cch;
-           hash_table->len = cch->len + 1;
-           cch->len = 0;
-
-    }
-    return /*hash_table*/;
-}
-
-/*
- *   vhpt lookup
- */
-
-thash_data_t * vhpt_lookup(u64 va)
-{
-    thash_data_t *hash;
-    u64 tag;
-    hash = (thash_data_t *)ia64_thash(va);
-    tag = ia64_ttag(va);
-    while(hash){
-       if(hash->etag == tag)
-               return hash;
-        hash=hash->next;
-    }
-    return NULL;
+        return head;
+    }
+    return hash;
+}
+
+u64 guest_vhpt_lookup(u64 iha, u64 *pte)
+{
+    u64 ret;
+    vhpt_lookup(iha);
+    asm volatile ("rsm psr.ic|psr.i;;"
+                  "srlz.d;;"
+                  "ld8.s r9=[%1];;"
+                  "tnat.nz p6,p7=r9;;"
+                  "(p6) mov %0=1;"
+                  "(p6) mov r9=r0;"
+                  "(p7) mov %0=r0;"
+                  "(p7) st8 [%2]=r9;;"
+                  "ssm psr.ic;;"
+                  "srlz.d;;"
+                  "ssm psr.i;;"
+             : "=r"(ret) : "r"(iha), "r"(pte):"memory");
+    return ret;
 }
 
 
@@ -310,7 +289,6 @@ static void vtlb_purge(thash_cb_t *hcb, 
 /*
  *  purge VHPT and machine TLB
  */
-
 static void vhpt_purge(thash_cb_t *hcb, u64 va, u64 ps)
 {
     thash_data_t *hash_table, *prev, *next;
@@ -332,7 +310,7 @@ static void vhpt_purge(thash_cb_t *hcb, 
                     prev->next=next->next;
                     cch_free(hcb,next);
                     hash_table->len--;
-                    break;
+                    break; 
                 }
                 prev=next;
                 next=next->next;
@@ -347,16 +325,21 @@ static void vhpt_purge(thash_cb_t *hcb, 
  * Recycle all collisions chain in VTLB or VHPT.
  *
  */
-
-void thash_recycle_cch(thash_cb_t *hcb)
-{
-    thash_data_t    *hash_table;
-
-    hash_table = (thash_data_t*)((u64)hcb->hash + hcb->hash_sz);
-    for (--hash_table;(u64)hash_table >= (u64)hcb->hash;hash_table--) {
-        thash_remove_cch(hcb,hash_table);
-    }
-}
+void thash_recycle_cch_all(thash_cb_t *hcb)
+{
+    int num;
+    thash_data_t *head;
+    head=hcb->hash;
+    num = (hcb->hash_sz/sizeof(thash_data_t));
+    do{
+        head->len = 0;
+        head->next = 0;
+        head++;
+        num--;
+    }while(num);
+    cch_mem_init(hcb);
+}
+
 
 thash_data_t *__alloc_chain(thash_cb_t *hcb)
 {
@@ -364,7 +347,7 @@ thash_data_t *__alloc_chain(thash_cb_t *
 
     cch = cch_alloc(hcb);
     if(cch == NULL){
-        thash_recycle_cch(hcb);
+        thash_recycle_cch_all(hcb);
         cch = cch_alloc(hcb);
     }
     return cch;
@@ -385,51 +368,38 @@ void vtlb_insert(thash_cb_t *hcb, u64 pt
     /* int flag; */
     ia64_rr vrr;
     /* u64 gppn, ppns, ppne; */
-    u64 tag, ps;
-    ps = itir_ps(itir);
+    u64 tag;
     vcpu_get_rr(current, va, &vrr.rrval);
-    if (vrr.ps != ps) {
+#ifdef VTLB_DEBUG    
+    if (vrr.ps != itir_ps(itir)) {
 //        machine_tlb_insert(hcb->vcpu, entry);
         panic_domain(NULL, "not preferred ps with va: 0x%lx vrr.ps=%d 
ps=%ld\n",
-                     va, vrr.ps, ps);
+             va, vrr.ps, itir_ps(itir));
         return;
     }
+#endif
     hash_table = vsa_thash(hcb->pta, va, vrr.rrval, &tag);
     if( INVALID_TLB(hash_table) ) {
         hash_table->page_flags = pte;
         hash_table->itir=itir;
         hash_table->etag=tag;
         hash_table->next = 0;
-    }
-    else if (hash_table->len>=MAX_CCN_DEPTH){
-        thash_remove_cch(hcb, hash_table);
+        return;
+    }
+    if (hash_table->len>=MAX_CCN_DEPTH){
+        thash_recycle_cch(hcb, hash_table);
         cch = cch_alloc(hcb);
-        *cch = *hash_table;
-        hash_table->page_flags = pte;
-        hash_table->itir=itir;
-        hash_table->etag=tag;
-        hash_table->len = 1;
-        hash_table->next = cch;
-    }
-
+    }
     else {
-        // TODO: Add collision chain length limitation.
         cch = __alloc_chain(hcb);
-        if(cch == NULL){
-            hash_table->page_flags = pte;
-            hash_table->itir=itir;
-            hash_table->etag=tag;
-            hash_table->next = 0;
-        }else{
-            *cch = *hash_table;
-            hash_table->page_flags = pte;
-            hash_table->itir=itir;
-            hash_table->etag=tag;
-            hash_table->next = cch;
-            hash_table->len = cch->len + 1;
-            cch->len = 0;
-        }
-    }
+    }
+    *cch = *hash_table;
+    hash_table->page_flags = pte;
+    hash_table->itir=itir;
+    hash_table->etag=tag;
+    hash_table->next = cch;
+    hash_table->len = cch->len + 1;
+    cch->len = 0;
     return ;
 }
 
@@ -473,6 +443,23 @@ void thash_purge_entries(VCPU *v, u64 va
     vhpt_purge(&v->arch.vhpt, va, ps);
 }
 
+u64 translate_phy_pte(VCPU *v, u64 *pte, u64 itir, u64 va)
+{
+    u64 ps, addr;
+    union pte_flags phy_pte;
+    ps = itir_ps(itir);
+    phy_pte.val = *pte;
+    addr = *pte;
+    addr = ((addr & _PAGE_PPN_MASK)>>ps<<ps)|(va&((1UL<<ps)-1));
+    addr = lookup_domain_mpa(v->domain, addr);
+    if(addr & GPFN_IO_MASK){
+        *pte |= VTLB_PTE_IO;
+        return -1;
+    }
+    phy_pte.ppn = addr >> ARCH_PAGE_SHIFT;
+    return phy_pte.val;
+}
+
 
 /*
  * Purge overlap TCs and then insert the new entry to emulate itc ops.
@@ -480,59 +467,79 @@ void thash_purge_entries(VCPU *v, u64 va
  */
 void thash_purge_and_insert(VCPU *v, u64 pte, u64 itir, u64 ifa)
 {
-    u64 ps, va;
+    u64 ps;//, va;
+    u64 phy_pte;
     ps = itir_ps(itir);
-    va = PAGEALIGN(ifa,ps);
-    if(vcpu_quick_region_check(v->arch.tc_regions,va))
-        vtlb_purge(&v->arch.vtlb, va, ps);
-    vhpt_purge(&v->arch.vhpt, va, ps);
-    if((ps!=PAGE_SHIFT)||(pte&VTLB_PTE_IO)){
-        vtlb_insert(&v->arch.vtlb, pte, itir, va);
-       vcpu_quick_region_set(PSCBX(v,tc_regions),va);
-    }  
-    if(!(pte&VTLB_PTE_IO)){
-        va = PAGEALIGN(ifa,PAGE_SHIFT);
-        thash_vhpt_insert(&v->arch.vhpt, pte, itir, va);
-    }
-}
-
-
+
+    if(VMX_DOMAIN(v)){
+        phy_pte = translate_phy_pte(v, &pte, itir, ifa);
+        if(ps==PAGE_SHIFT){
+            if(!(pte&VTLB_PTE_IO)){
+                vhpt_purge(&v->arch.vhpt, ifa, ps);
+                vmx_vhpt_insert(&v->arch.vhpt, phy_pte, itir, ifa);
+            }
+            else{
+                vhpt_purge(&v->arch.vhpt, ifa, ps);
+                vtlb_insert(&v->arch.vtlb, pte, itir, ifa);
+                vcpu_quick_region_set(PSCBX(v,tc_regions),ifa);
+            }
+        }
+        else{
+            vhpt_purge(&v->arch.vhpt, ifa, ps);
+            vtlb_insert(&v->arch.vtlb, pte, itir, ifa);
+            vcpu_quick_region_set(PSCBX(v,tc_regions),ifa);
+            if(!(pte&VTLB_PTE_IO)){
+                vmx_vhpt_insert(&v->arch.vhpt, phy_pte, itir, ifa);
+            }
+        }
+    }
+    else{
+        phy_pte = translate_phy_pte(v, &pte, itir, ifa);
+        if(ps!=PAGE_SHIFT){
+            vtlb_insert(&v->arch.vtlb, pte, itir, ifa);
+            vcpu_quick_region_set(PSCBX(v,tc_regions),ifa);
+        }
+        machine_tlb_purge(ifa, ps);
+        vmx_vhpt_insert(&v->arch.vhpt, phy_pte, itir, ifa);
+    }
+}
 
 /*
  * Purge all TCs or VHPT entries including those in Hash table.
  *
  */
 
-// TODO: add sections.
+//TODO: add sections.
 void thash_purge_all(VCPU *v)
 {
-    thash_data_t    *hash_table;
-    /* thash_data_t    *entry; */
-    thash_cb_t  *hcb,*vhpt;
-    /* u64 i, start, end; */
-    hcb =&v->arch.vtlb;
+    int num;
+    thash_data_t *head;
+    thash_cb_t  *vtlb,*vhpt;
+    vtlb =&v->arch.vtlb;
     vhpt =&v->arch.vhpt;
-#ifdef  VTLB_DEBUG
-       extern u64  sanity_check;
-    static u64 statistics_before_purge_all=0;
-    if ( statistics_before_purge_all ) {
-       sanity_check = 1;
-        check_vtlb_sanity(hcb);
-    }
-#endif
-    ASSERT ( hcb->ht == THASH_TLB );
-
-    hash_table = (thash_data_t*)((u64)hcb->hash + hcb->hash_sz);
-    for (--hash_table;(u64)hash_table >= (u64)hcb->hash;hash_table--) {
-        INVALIDATE_TLB_HEADER(hash_table);
-    }
-    cch_mem_init (hcb);
-
-    hash_table = (thash_data_t*)((u64)vhpt->hash + vhpt->hash_sz);
-    for (--hash_table;(u64)hash_table >= (u64)vhpt->hash;hash_table--) {
-        INVALIDATE_VHPT_HEADER(hash_table);
-    }
-    cch_mem_init (vhpt);
+
+    head=vtlb->hash;
+    num = (vtlb->hash_sz/sizeof(thash_data_t));
+    do{
+        head->page_flags = 0;
+        head->etag = 1UL<<63;
+        head->next = 0;
+        head++;
+        num--;
+    }while(num);
+    cch_mem_init(vtlb);
+    
+    head=vhpt->hash;
+    num = (vhpt->hash_sz/sizeof(thash_data_t));
+    do{
+        head->page_flags = 0;
+        head->etag = 1UL<<63;
+        head->next = 0;
+        head++;
+        num--;
+    }while(num);
+    cch_mem_init(vhpt);
+
     local_flush_tlb_all();
 }
 
@@ -547,7 +554,7 @@ void thash_purge_all(VCPU *v)
 
 thash_data_t *vtlb_lookup(VCPU *v, u64 va,int is_data)
 {
-    thash_data_t    *hash_table, *cch;
+    thash_data_t  *cch;
     u64     tag;
     ia64_rr vrr;
     thash_cb_t * hcb= &v->arch.vtlb;
@@ -559,18 +566,14 @@ thash_data_t *vtlb_lookup(VCPU *v, u64 v
     if(vcpu_quick_region_check(v->arch.tc_regions,va)==0)
         return NULL;
     
-
     vcpu_get_rr(v,va,&vrr.rrval);
-    hash_table = vsa_thash( hcb->pta, va, vrr.rrval, &tag);
-
-    if ( INVALID_ENTRY(hcb, hash_table ) )
-        return NULL;
-
-
-    for (cch=hash_table; cch; cch = cch->next) {
+    cch = vsa_thash( hcb->pta, va, vrr.rrval, &tag);
+
+    do{
         if(cch->etag == tag)
             return cch;
-    }
+        cch = cch->next;
+    }while(cch);
     return NULL;
 }
 
@@ -580,198 +583,32 @@ thash_data_t *vtlb_lookup(VCPU *v, u64 v
  */
 void thash_init(thash_cb_t *hcb, u64 sz)
 {
-    thash_data_t    *hash_table;
-
-    cch_mem_init (hcb);
+    int num;
+    thash_data_t *head, *p;
+
     hcb->pta.val = (unsigned long)hcb->hash;
     hcb->pta.vf = 1;
     hcb->pta.ve = 1;
     hcb->pta.size = sz;
-//    hcb->get_rr_fn = vmmu_get_rr;
-    ASSERT ( hcb->hash_sz % sizeof(thash_data_t) == 0 );
-    hash_table = (thash_data_t*)((u64)hcb->hash + hcb->hash_sz);
-
-    for (--hash_table;(u64)hash_table >= (u64)hcb->hash;hash_table--) {
-        INVALIDATE_HASH_HEADER(hcb,hash_table);
-    }
-}
-
-#ifdef  VTLB_DEBUG
-/*
-static  u64 cch_length_statistics[MAX_CCH_LENGTH+1];
-u64  sanity_check=0;
-u64 vtlb_chain_sanity(thash_cb_t *vtlb, thash_cb_t *vhpt, thash_data_t *hash)
-{
-    thash_data_t *cch;
-    thash_data_t    *ovl;
-    search_section_t s_sect;
-    u64     num=0;
-
-    s_sect.v = 0;
-    for (cch=hash; cch; cch=cch->next) {
-        ovl = thash_find_overlap(vhpt, cch, s_sect);
-        while ( ovl != NULL ) {
-            ovl->checked = 1;
-            ovl = (vhpt->next_overlap)(vhpt);
-        };
-        num ++;
-    }
-    if ( num >= MAX_CCH_LENGTH ) {
-       cch_length_statistics[MAX_CCH_LENGTH] ++;
-    }
-    else {
-       cch_length_statistics[num] ++;
-    }
-    return num;
-}
-
-void check_vtlb_sanity(thash_cb_t *vtlb)
-{
-//    struct page_info *page;
-    u64  hash_num, i, psr;
-    static u64 check_ok_num, check_fail_num,check_invalid;
-//  void *vb1, *vb2;
-    thash_data_t  *hash, *cch;
-    thash_data_t    *ovl;
-    search_section_t s_sect;
-    thash_cb_t *vhpt = vtlb->vhpt;
-    u64   invalid_ratio;
- 
-    if ( sanity_check == 0 ) return;
-    sanity_check --;
-    s_sect.v = 0;
-//    page = alloc_domheap_pages (NULL, VCPU_TLB_ORDER, 0);
-//    if ( page == NULL ) {
-//        panic("No enough contiguous memory for init_domain_mm\n");
-//    };
-//    vb1 = page_to_virt(page);
-//    printf("Allocated page=%lp vbase=%lp\n", page, vb1);
-//    vb2 = vb1 + vtlb->hash_sz;
-    hash_num = vhpt->hash_sz / sizeof(thash_data_t);
-//    printf("vb2=%lp, size=%lx hash_num=%lx\n", vb2, vhpt->hash_sz, hash_num);
-    printf("vtlb=%p, hash=%p size=0x%lx; vhpt=%p, hash=%p size=0x%lx\n", 
-                vtlb, vtlb->hash,vtlb->hash_sz,
-                vhpt, vhpt->hash, vhpt->hash_sz);
-    //memcpy(vb1, vtlb->hash, vtlb->hash_sz);
-    //memcpy(vb2, vhpt->hash, vhpt->hash_sz);
-    for ( i=0; i < 
sizeof(cch_length_statistics)/sizeof(cch_length_statistics[0]); i++ ) {
-       cch_length_statistics[i] = 0;
-    }
-
-    local_irq_save(psr);
-
-    hash = vhpt->hash;
-    for (i=0; i < hash_num; i++) {
-        if ( !INVALID_ENTRY(vhpt, hash) ) {
-            for ( cch= hash; cch; cch=cch->next) {
-                cch->checked = 0;
-            }
-        }
-        hash ++;
-    }
-    printf("Done vhpt clear checked flag, hash_num=0x%lx\n", hash_num);
-    check_invalid = 0;
-    check_ok_num=0;
-    hash = vtlb->hash;
-    for ( i=0; i< hash_num; i++ ) {
-        if ( !INVALID_ENTRY(vtlb, hash) ) {
-            check_ok_num += vtlb_chain_sanity(vtlb, vhpt, hash);
-        }
-        else {
-            check_invalid++;
-        }
-        hash ++;
-    }
-    printf("Done vtlb entry check, hash=%p\n", hash);
-    printf("check_ok_num = 0x%lx check_invalid=0x%lx\n", 
check_ok_num,check_invalid);
-    invalid_ratio = 1000*check_invalid / hash_num;
-    printf("%02ld.%01ld%% entries are invalid\n", 
-               invalid_ratio/10, invalid_ratio % 10 );
-    for (i=0; i<NDTRS; i++) {
-        ovl = thash_find_overlap(vhpt, &vtlb->ts->dtr[i], s_sect);
-        while ( ovl != NULL ) {
-            ovl->checked = 1;
-            ovl = (vhpt->next_overlap)(vhpt);
-        };
-    }
-    printf("Done dTR\n");
-    for (i=0; i<NITRS; i++) {
-        ovl = thash_find_overlap(vhpt, &vtlb->ts->itr[i], s_sect);
-        while ( ovl != NULL ) {
-            ovl->checked = 1;
-            ovl = (vhpt->next_overlap)(vhpt);
-        };
-    }
-    printf("Done iTR\n");
-    check_fail_num = 0;
-    check_invalid = 0;
-    check_ok_num=0;
-    hash = vhpt->hash;
-    for (i=0; i < hash_num; i++) {
-        if ( !INVALID_ENTRY(vhpt, hash) ) {
-            for ( cch= hash; cch; cch=cch->next) {
-                if ( !cch->checked ) {
-                    printf ("!!!Hash=%p cch=%p not within vtlb\n", hash, cch);
-                    check_fail_num ++;
-                }
-                else {
-                    check_ok_num++;
-                }
-            }
-        }
-        else {
-            check_invalid ++;
-        }
-        hash ++;
-    }
-    local_irq_restore(psr);
-    printf("check_ok_num=0x%lx check_fail_num=0x%lx check_invalid=0x%lx\n", 
-            check_ok_num, check_fail_num, check_invalid);
-    //memcpy(vtlb->hash, vb1, vtlb->hash_sz);
-    //memcpy(vhpt->hash, vb2, vhpt->hash_sz);
-    printf("The statistics of collision chain length is listed\n");
-    for ( i=0; i < 
sizeof(cch_length_statistics)/sizeof(cch_length_statistics[0]); i++ ) {
-       printf("CCH length=%02ld, chain number=%ld\n", i, 
cch_length_statistics[i]);
-    }
-//    free_domheap_pages(page, VCPU_TLB_ORDER);
-    printf("Done check_vtlb\n");
-}
-
-void dump_vtlb(thash_cb_t *vtlb)
-{
-    static u64  dump_vtlb=0;
-    thash_data_t  *hash, *cch, *tr;
-    u64     hash_num,i;
-
-    if ( dump_vtlb == 0 ) return;
-    dump_vtlb --;
-    hash_num = vtlb->hash_sz / sizeof(thash_data_t);
-    hash = vtlb->hash;
-
-    printf("Dump vTC\n");
-    for ( i = 0; i < hash_num; i++ ) {
-        if ( !INVALID_ENTRY(vtlb, hash) ) {
-            printf("VTLB at hash=%p\n", hash);
-            for (cch=hash; cch; cch=cch->next) {
-                printf("Entry %p va=%lx ps=%d rid=%d\n",
-                    cch, cch->vadr, cch->ps, cch->rid);
-            }
-        }
-        hash ++;
-    }
-    printf("Dump vDTR\n");
-    for (i=0; i<NDTRS; i++) {
-        tr = &DTR(vtlb,i);
-        printf("Entry %p va=%lx ps=%d rid=%d\n",
-                    tr, tr->vadr, tr->ps, tr->rid);
-    }
-    printf("Dump vITR\n");
-    for (i=0; i<NITRS; i++) {
-        tr = &ITR(vtlb,i);
-        printf("Entry %p va=%lx ps=%d rid=%d\n",
-                    tr, tr->vadr, tr->ps, tr->rid);
-    }
-    printf("End of vTLB dump\n");
-}
-*/
-#endif
+    hcb->cch_rec_head = hcb->hash;
+    
+    head=hcb->hash;
+    num = (hcb->hash_sz/sizeof(thash_data_t));
+    do{
+        head->itir = PAGE_SHIFT<<2;
+        head->next = 0;
+        head++;
+        num--;
+    }while(num);
+    
+    hcb->cch_freelist = p = hcb->cch_buf;
+    num = (hcb->cch_sz/sizeof(thash_data_t))-1;
+    do{
+        p->itir = PAGE_SHIFT<<2;
+        p->next =p+1;
+        p++;
+        num--;
+    }while(num);
+    p->itir = PAGE_SHIFT<<2;
+    p->next = NULL;
+}
diff -r 18b087bafac6 -r 166073f830a3 xen/include/asm-ia64/vmmu.h
--- a/xen/include/asm-ia64/vmmu.h       Tue May 30 08:46:21 2006 -0600
+++ b/xen/include/asm-ia64/vmmu.h       Tue May 30 10:28:59 2006 -0600
@@ -137,21 +137,19 @@ typedef struct thash_data {
 } thash_data_t;
 
 #define INVALIDATE_VHPT_HEADER(hdata)   \
-{      ((hdata)->page_flags)=0;        \
-       ((hdata)->ti)=1;        \
-       ((hdata)->next)=0; }
-
-#define INVALIDATE_TLB_HEADER(hdata)   \
-{      ((hdata)->page_flags)=0;        \
-       ((hdata)->ti)=1;                \
-       ((hdata)->next)=0; }
+{   ((hdata)->page_flags)=0;            \
+    ((hdata)->itir)=PAGE_SHIFT<<2;      \
+    ((hdata)->etag)=1UL<<63;            \
+    ((hdata)->next)=0;}
+
+#define INVALIDATE_TLB_HEADER(hash)   INVALIDATE_VHPT_HEADER(hash)
+
+#define INVALIDATE_HASH_HEADER(hcb,hash)    INVALIDATE_VHPT_HEADER(hash)
 
 #define INVALID_VHPT(hdata)     ((hdata)->ti)
 #define INVALID_TLB(hdata)      ((hdata)->ti)
 #define INVALID_TR(hdata)      (!(hdata)->p)
 #define INVALID_ENTRY(hcb, hdata)       INVALID_VHPT(hdata)
-
-/*        ((hcb)->ht==THASH_TLB ? INVALID_TLB(hdata) : INVALID_VHPT(hdata)) */
 
 
 /*
@@ -189,80 +187,17 @@ typedef void (REM_THASH_FN)(struct thash
 typedef void (REM_THASH_FN)(struct thash_cb *hcb, thash_data_t *entry);
 typedef void (INS_THASH_FN)(struct thash_cb *hcb, thash_data_t *entry, u64 va);
 
-//typedef struct tlb_special {
-//        thash_data_t     itr[NITRS];
-//        thash_data_t     dtr[NDTRS];
-//        struct thash_cb  *vhpt;
-//} tlb_special_t;
-
-//typedef struct vhpt_cb {
-        //u64     pta;    // pta value.
-//        GET_MFN_FN      *get_mfn;
-//        TTAG_FN         *tag_func;
-//} vhpt_special;
-/*
-typedef struct thash_internal {
-        thash_data_t *hash_base;
-        thash_data_t *cur_cch;  // head of overlap search
-        int     rid;
-        int     ps;
-        union {
-            u64  tag;           // for VHPT
-            struct {            // for TLB
-                char    _tr_idx;        // -1: means done of TR search
-                char    cl;
-                search_section_t s_sect;   // search section combinations
-            };
-        };
-        u64     _curva;         // current address to search
-        u64     _eva;
-} thash_internal_t;
- */
-//#define  THASH_CB_MAGIC         0x55aa00aa55aa55aaUL
+
 typedef struct thash_cb {
-        /* THASH base information */
-//        THASH_TYPE      ht;     // For TLB or VHPT
-//        u64             magic;
-        thash_data_t    *hash; // hash table pointer, aligned at thash_sz.
-        u64     hash_sz;        // size of above data.
-        void    *cch_buf;       // base address of collision chain.
-        u64     cch_sz;         // size of above data.
-//        THASH_FN        *hash_func;
-//        GET_RR_FN       *get_rr_fn;
-//        RECYCLE_FN      *recycle_notifier;
-        thash_data_t *cch_freelist;
-//        struct vcpu *vcpu;
-        PTA     pta;
-//        struct thash_cb *vhpt;
-        /* VTLB/VHPT common information */
-//        FIND_OVERLAP_FN *find_overlap;
-//        FIND_NEXT_OVL_FN *next_overlap;
-//        REM_THASH_FN    *rem_hash; // remove hash entry.
-//        INS_THASH_FN    *ins_hash; // insert hash entry.
-//        REM_NOTIFIER_FN *remove_notifier;
-        /* private information */
-//        thash_internal_t  priv;
-//        union {
-//                tlb_special_t  *ts;
-//                vhpt_special   *vs;
-//        };
-        // Internal positon information, buffer and storage etc. TBD
+    /* THASH base information */
+    thash_data_t    *hash; // hash table pointer, aligned at thash_sz.
+    u64     hash_sz;        // size of above data.
+    void    *cch_buf;       // base address of collision chain.
+    u64     cch_sz;         // size of above data.
+    thash_data_t *cch_freelist;
+    thash_data_t *cch_rec_head;  // cch recycle header
+    PTA     pta;
 } thash_cb_t;
-
-//#define ITR(hcb,id)             ((hcb)->ts->itr[id])
-//#define DTR(hcb,id)             ((hcb)->ts->dtr[id])
-#define INVALIDATE_HASH_HEADER(hcb,hash)    INVALIDATE_TLB_HEADER(hash)
-/*              \
-{           if ((hcb)->ht==THASH_TLB){            \
-            INVALIDATE_TLB_HEADER(hash);             \
-           }else{                                 \
-             INVALIDATE_VHPT_HEADER(hash);            \
-            }                                       \
-}
- */
-#define PURGABLE_ENTRY(hcb,en)  1
-//             ((hcb)->ht == THASH_VHPT || ( (en)->tc && !(en->locked)) )
-
 
 /*
  * Initialize internal control data before service.
@@ -281,7 +216,6 @@ extern void thash_init(thash_cb_t *hcb, 
  *      4: Return the entry in hash table or collision chain.
  *
  */
-extern void thash_vhpt_insert(thash_cb_t *hcb, u64 pte, u64 itir, u64 ifa);
 //extern void thash_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va);
 //extern void thash_tr_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va, 
int idx);
 extern int vtr_find_overlap(struct vcpu *vcpu, u64 va, u64 ps, int is_data);
@@ -368,6 +302,10 @@ extern int fetch_code(struct vcpu *vcpu,
 extern int fetch_code(struct vcpu *vcpu, u64 gip, u64 *code1, u64 *code2);
 extern void emulate_io_inst(struct vcpu *vcpu, u64 padr, u64 ma);
 extern int vhpt_enabled(struct vcpu *vcpu, uint64_t vadr, vhpt_ref_t ref);
+extern void  vtlb_insert(thash_cb_t *hcb, u64 pte, u64 itir, u64 va);
+extern u64 translate_phy_pte(struct vcpu *v, u64 *pte, u64 itir, u64 va);
+extern void thash_vhpt_insert(struct vcpu *v, u64 pte, u64 itir, u64 ifa);
+extern u64 guest_vhpt_lookup(u64 iha, u64 *pte);
 
 static inline void vmx_vcpu_set_tr (thash_data_t *trp, u64 pte, u64 itir, u64 
va, u64 rid)
 {
@@ -377,13 +315,6 @@ static inline void vmx_vcpu_set_tr (thas
     trp->rid = rid;
 }
 
-
-//#define   VTLB_DEBUG
-#ifdef   VTLB_DEBUG
-extern void check_vtlb_sanity(thash_cb_t *vtlb);
-extern void dump_vtlb(thash_cb_t *vtlb);
-#endif
-
 #endif  /* __ASSEMBLY__ */
 
 #endif  /* XEN_TLBthash_H */
diff -r 18b087bafac6 -r 166073f830a3 xen/include/asm-ia64/vmx_vcpu.h
--- a/xen/include/asm-ia64/vmx_vcpu.h   Tue May 30 08:46:21 2006 -0600
+++ b/xen/include/asm-ia64/vmx_vcpu.h   Tue May 30 10:28:59 2006 -0600
@@ -121,6 +121,7 @@ extern void dvhpt_fault (VCPU *vcpu, u64
 extern void dvhpt_fault (VCPU *vcpu, u64 vadr);
 extern void dnat_page_consumption (VCPU *vcpu, uint64_t vadr);
 extern void page_not_present(VCPU *vcpu, u64 vadr);
+extern void data_access_rights(VCPU *vcpu, u64 vadr);
 
 /**************************************************************************
  VCPU control register access routines

_______________________________________________
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®.