[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |