# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID cfe20f41f043a4c9d4166f117fd3f17adf706224
# Parent e58ff5fd3550dc48bcaeb7b36bbb5579983e7e55
[IA64] VTI: updated vtlb, support_non_contiguous memory on vtidomain
Previously VTI-domain only supported contiguous memory,
this patch is intended to make VTI-domain support non-contiguous memory.
Signed-off-by: Anthony Xu <anthony.xu@xxxxxxxxx>
diff -r e58ff5fd3550 -r cfe20f41f043 xen/arch/ia64/vmx/mm.c
--- a/xen/arch/ia64/vmx/mm.c Tue Feb 28 20:18:08 2006
+++ b/xen/arch/ia64/vmx/mm.c Wed Mar 1 15:29:00 2006
@@ -117,6 +117,7 @@
copy_from_user(&req, ureqs, sizeof(req));
cmd = req.ptr&3;
req.ptr &= ~3;
+/*
if(cmd ==MMU_NORMAL_PT_UPDATE){
entry.page_flags = req.val;
entry.locked = 1;
@@ -135,8 +136,10 @@
panic("Tlb conflict!!");
return -1;
}
- thash_purge_and_insert(hcb, &entry);
- }else if(cmd == MMU_MACHPHYS_UPDATE){
+ thash_purge_and_insert(hcb, &entry, req.ptr);
+ }else
+ */
+ if(cmd == MMU_MACHPHYS_UPDATE){
mfn = req.ptr >>PAGE_SHIFT;
gpfn = req.val;
set_machinetophys(mfn,gpfn);
diff -r e58ff5fd3550 -r cfe20f41f043 xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c Tue Feb 28 20:18:08 2006
+++ b/xen/arch/ia64/vmx/vmmu.c Wed Mar 1 15:29:00 2006
@@ -34,37 +34,23 @@
#include <xen/irq.h>
/*
- * Architecture ppn is in 4KB unit while XEN
- * page may be different(1<<PAGE_SHIFT).
- */
-static inline u64 arch_ppn_to_xen_ppn(u64 appn)
-{
- return (appn << ARCH_PAGE_SHIFT) >> PAGE_SHIFT;
-}
-
-static inline u64 xen_ppn_to_arch_ppn(u64 xppn)
-{
- return (xppn << PAGE_SHIFT) >> ARCH_PAGE_SHIFT;
-}
-
-
-/*
* Get the machine page frame number in 16KB unit
* Input:
* d:
*/
-u64 get_mfn(domid_t domid, u64 gpfn, u64 pages)
-{
- struct domain *d;
+u64 get_mfn(struct domain *d, u64 gpfn)
+{
+// struct domain *d;
u64 xen_gppn, xen_mppn, mpfn;
-
+/*
if ( domid == DOMID_SELF ) {
d = current->domain;
}
else {
d = find_domain_by_id(domid);
}
- xen_gppn = arch_ppn_to_xen_ppn(gpfn);
+ */
+ xen_gppn = arch_to_xen_ppn(gpfn);
xen_mppn = gmfn_to_mfn(d, xen_gppn);
/*
for (i=0; i<pages; i++) {
@@ -73,8 +59,8 @@
}
}
*/
- mpfn= xen_ppn_to_arch_ppn(xen_mppn);
- mpfn = mpfn | (((1UL <<(PAGE_SHIFT-12))-1)&gpfn);
+ mpfn= xen_to_arch_ppn(xen_mppn);
+ mpfn = mpfn | (((1UL <<(PAGE_SHIFT-ARCH_PAGE_SHIFT))-1)&gpfn);
return mpfn;
}
@@ -142,66 +128,67 @@
#endif
}
-static thash_cb_t *init_domain_vhpt(struct vcpu *d)
-{
- struct page_info *page;
- void *vbase,*vcur;
- vhpt_special *vs;
+static thash_cb_t *init_domain_vhpt(struct vcpu *d, void *vbase, void *vcur)
+{
+// struct page_info *page;
thash_cb_t *vhpt;
PTA pta_value;
-
- page = alloc_domheap_pages (NULL, VCPU_TLB_ORDER, 0);
+/*
+ page = alloc_domheap_pages (NULL, VCPU_VHPT_ORDER, 0);
if ( page == NULL ) {
panic("No enough contiguous memory for init_domain_mm\n");
}
vbase = page_to_virt(page);
printk("Allocate domain vhpt at 0x%lx\n", (u64)vbase);
- memset(vbase, 0, VCPU_TLB_SIZE);
- vcur = (void*)((u64)vbase + VCPU_TLB_SIZE);
+ memset(vbase, 0, VCPU_VHPT_SIZE);
+ */
+// vcur = (void*)((u64)vbase + VCPU_VHPT_SIZE);
vcur -= sizeof (thash_cb_t);
vhpt = vcur;
vhpt->ht = THASH_VHPT;
vhpt->vcpu = d;
- vhpt->hash_func = machine_thash;
- vcur -= sizeof (vhpt_special);
- vs = vcur;
+// vhpt->hash_func = machine_thash;
+// vcur -= sizeof (vhpt_special);
+// vs = vcur;
/* Setup guest pta */
pta_value.val = 0;
pta_value.ve = 1;
pta_value.vf = 1;
- pta_value.size = VCPU_TLB_SHIFT - 1; /* 2M */
+ pta_value.size = VCPU_VHPT_SHIFT - 1; /* 16M*/
pta_value.base = ((u64)vbase) >> PTA_BASE_SHIFT;
d->arch.arch_vmx.mpta = pta_value.val;
-
- vhpt->vs = vs;
- vhpt->vs->get_mfn = get_mfn;
- vhpt->vs->tag_func = machine_ttag;
+
+// vhpt->vs = vs;
+// vhpt->vs->get_mfn = __gpfn_to_mfn_foreign;
+// vhpt->vs->tag_func = machine_ttag;
vhpt->hash = vbase;
- vhpt->hash_sz = VCPU_TLB_SIZE/2;
+ vhpt->hash_sz = VCPU_VHPT_SIZE/2;
vhpt->cch_buf = (void *)(vbase + vhpt->hash_sz);
vhpt->cch_sz = (u64)vcur - (u64)vhpt->cch_buf;
- vhpt->recycle_notifier = recycle_message;
- thash_init(vhpt,VCPU_TLB_SHIFT-1);
+// vhpt->recycle_notifier = recycle_message;
+ thash_init(vhpt,VCPU_VHPT_SHIFT-1);
return vhpt;
}
+
thash_cb_t *init_domain_tlb(struct vcpu *d)
{
struct page_info *page;
- void *vbase,*vcur;
+ void *vbase, *vhptbase, *vcur;
tlb_special_t *ts;
thash_cb_t *tlb;
- page = alloc_domheap_pages (NULL, VCPU_TLB_ORDER, 0);
+ page = alloc_domheap_pages (NULL, VCPU_VHPT_ORDER, 0);
if ( page == NULL ) {
panic("No enough contiguous memory for init_domain_mm\n");
}
- vbase = page_to_virt(page);
- printk("Allocate domain tlb at 0x%lx\n", (u64)vbase);
- memset(vbase, 0, VCPU_TLB_SIZE);
- vcur = (void*)((u64)vbase + VCPU_TLB_SIZE);
+ vhptbase = page_to_virt(page);
+ memset(vhptbase, 0, VCPU_VHPT_SIZE);
+ printk("Allocate domain tlb&vhpt at 0x%lx\n", (u64)vhptbase);
+ vbase =vhptbase + VCPU_VHPT_SIZE - VCPU_VTLB_SIZE;
+ vcur = (void*)((u64)vbase + VCPU_VTLB_SIZE);
vcur -= sizeof (thash_cb_t);
tlb = vcur;
tlb->ht = THASH_TLB;
@@ -209,14 +196,14 @@
vcur -= sizeof (tlb_special_t);
ts = vcur;
tlb->ts = ts;
- tlb->ts->vhpt = init_domain_vhpt(d);
- tlb->hash_func = machine_thash;
+ tlb->ts->vhpt = init_domain_vhpt(d,vhptbase,vbase);
+// tlb->hash_func = machine_thash;
tlb->hash = vbase;
- tlb->hash_sz = VCPU_TLB_SIZE/2;
- tlb->cch_buf = (void *)((u64)vbase + tlb->hash_sz);
+ tlb->hash_sz = VCPU_VTLB_SIZE/2;
+ tlb->cch_buf = (void *)(vbase + tlb->hash_sz);
tlb->cch_sz = (u64)vcur - (u64)tlb->cch_buf;
- tlb->recycle_notifier = recycle_message;
- thash_init(tlb,VCPU_TLB_SHIFT-1);
+// tlb->recycle_notifier = recycle_message;
+ thash_init(tlb,VCPU_VTLB_SHIFT-1);
return tlb;
}
@@ -250,12 +237,12 @@
u64 psr;
thash_data_t mtlb;
unsigned int cl = tlb->cl;
- unsigned long mtlb_ppn;
+ unsigned long mtlb_ppn;
mtlb.ifa = tlb->vadr;
mtlb.itir = tlb->itir & ~ITIR_RV_MASK;
//vmx_vcpu_get_rr(d, mtlb.ifa, &vrr.value);
mtlb.page_flags = tlb->page_flags & ~PAGE_FLAGS_RV_MASK;
- mtlb.ppn = (unsigned long)get_mfn(DOMID_SELF,tlb->ppn, 1);
+ mtlb.ppn = get_mfn(d->domain,tlb->ppn);
mtlb_ppn=mtlb.ppn;
if (mtlb_ppn == INVALID_MFN)
panic("Machine tlb insert with invalid mfn number.\n");
@@ -289,42 +276,33 @@
// ia64_srlz_i();
// return;
}
-
-u64 machine_thash(PTA pta, u64 va)
-{
- u64 saved_pta;
- u64 hash_addr;
- unsigned long psr;
-
- saved_pta = ia64_getreg(_IA64_REG_CR_PTA);
- psr = ia64_clear_ic();
- ia64_setreg(_IA64_REG_CR_PTA, pta.val);
- hash_addr = ia64_thash(va);
- ia64_setreg(_IA64_REG_CR_PTA, saved_pta);
- ia64_set_psr(psr);
- ia64_srlz_i();
- return hash_addr;
-}
-
-u64 machine_ttag(PTA pta, u64 va)
-{
-// u64 saved_pta;
-// u64 hash_addr, tag;
-// u64 psr;
-// struct vcpu *v = current;
-
-// saved_pta = ia64_getreg(_IA64_REG_CR_PTA);
-// psr = ia64_clear_ic();
-// ia64_setreg(_IA64_REG_CR_PTA, pta.val);
-// tag = ia64_ttag(va);
+/*
+u64 machine_thash(u64 va)
+{
+ return ia64_thash(va);
+}
+
+u64 machine_ttag(u64 va)
+{
return ia64_ttag(va);
-// ia64_setreg(_IA64_REG_CR_PTA, saved_pta);
-// ia64_set_psr(psr);
-// ia64_srlz_i();
-// return tag;
-}
-
-
+}
+*/
+thash_data_t * vsa_thash(PTA vpta, u64 va, u64 vrr, u64 *tag)
+{
+ u64 index,pfn,rid,pfn_bits;
+ pfn_bits = vpta.size-5-8;
+ pfn = REGION_OFFSET(va)>>_REGION_PAGE_SIZE(vrr);
+ rid = _REGION_ID(vrr);
+ index = ((rid&0xff)<<pfn_bits)|(pfn&((1UL<<pfn_bits)-1));
+ *tag = ((rid>>8)&0xffff) | ((pfn >>pfn_bits)<<16);
+ return (thash_data_t *)((vpta.base<<PTA_BASE_SHIFT)+(index<<5));
+// return ia64_call_vsa(PAL_VPS_THASH,va,vrr,vpta,0,0,0,0);
+}
+
+//u64 vsa_ttag(u64 va, u64 vrr)
+//{
+// return ia64_call_vsa(PAL_VPS_TTAG,va,vrr,0,0,0,0,0);
+//}
int vhpt_enabled(VCPU *vcpu, uint64_t vadr, vhpt_ref_t ref)
{
@@ -371,11 +349,12 @@
* num: number of dword (8byts) to read.
*/
int
-fetch_code(VCPU *vcpu, u64 gip, u64 *code)
-{
- u64 gpip; // guest physical IP
- u64 mpa;
+fetch_code(VCPU *vcpu, u64 gip, u64 *code1, u64 *code2)
+{
+ u64 gpip=0; // guest physical IP
+ u64 *vpa;
thash_data_t *tlb;
+ thash_cb_t *hcb;
ia64_rr vrr;
u64 mfn;
@@ -384,19 +363,26 @@
}
else {
vmx_vcpu_get_rr(vcpu, gip, &vrr.rrval);
- tlb = vtlb_lookup_ex (vmx_vcpu_get_vtlb(vcpu),
- vrr.rid, gip, ISIDE_TLB );
+ hcb = vmx_vcpu_get_vtlb(vcpu);
+ tlb = vtlb_lookup_ex (hcb, vrr.rid, gip, ISIDE_TLB );
if( tlb == NULL )
- tlb = vtlb_lookup_ex (vmx_vcpu_get_vtlb(vcpu),
+ tlb = vtlb_lookup_ex (hcb,
vrr.rid, gip, DSIDE_TLB );
- if ( tlb == NULL ) panic("No entry found in ITLB and DTLB\n");
- gpip = (tlb->ppn << 12) | ( gip & (PSIZE(tlb->ps)-1) );
- }
- mfn = gmfn_to_mfn(vcpu->domain, gpip >>PAGE_SHIFT);
- if ( mfn == INVALID_MFN ) return 0;
-
- mpa = (gpip & (PAGE_SIZE-1)) | (mfn<<PAGE_SHIFT);
- *code = *(u64*)__va(mpa);
+ if (tlb)
+ gpip = (tlb->ppn << 12) | ( gip & (PSIZE(tlb->ps)-1) );
+ }
+ if( gpip){
+ mfn = gmfn_to_mfn(vcpu->domain, gpip >>PAGE_SHIFT);
+ if( mfn == INVALID_MFN ) panic("fetch_code: invalid memory\n");
+ vpa =(u64 *)__va( (gip & (PAGE_SIZE-1)) | (mfn<<PAGE_SHIFT));
+ }else{
+ tlb = vhpt_lookup(gip);
+ if( tlb == NULL)
+ panic("No entry found in ITLB and DTLB\n");
+ vpa =(u64
*)__va((tlb->ppn>>(PAGE_SHIFT-ARCH_PAGE_SHIFT)<<PAGE_SHIFT)|(gip&(PAGE_SIZE-1)));
+ }
+ *code1 = *vpa++;
+ *code2 = *vpa;
return 1;
}
@@ -420,13 +406,13 @@
sections.tr = 1;
sections.tc = 0;
- ovl = thash_find_overlap(hcb, &data, sections);
+ ovl = vtr_find_overlap(hcb, &data, ISIDE_TLB);
while (ovl) {
// generate MCA.
panic("Tlb conflict!!");
return IA64_FAULT;
}
- thash_purge_and_insert(hcb, &data);
+ thash_purge_and_insert(hcb, &data, ifa);
return IA64_NO_FAULT;
}
@@ -447,24 +433,26 @@
data.vadr=PAGEALIGN(ifa,data.ps);
data.tc = 1;
data.cl=DSIDE_TLB;
- vmx_vcpu_get_rr(vcpu, ifa, (UINT64 *)&vrr);
+ vmx_vcpu_get_rr(vcpu, ifa,(UINT64 *)&vrr);
data.rid = vrr.rid;
sections.tr = 1;
sections.tc = 0;
- ovl = thash_find_overlap(hcb, &data, sections);
+ ovl = vtr_find_overlap(hcb, &data, DSIDE_TLB);
if (ovl) {
// generate MCA.
panic("Tlb conflict!!");
return IA64_FAULT;
}
- thash_purge_and_insert(hcb, &data);
+ thash_purge_and_insert(hcb, &data, ifa);
return IA64_NO_FAULT;
}
/*
* Return TRUE/FALSE for success of lock operation
*/
+
+/*
int vmx_lock_guest_dtc (VCPU *vcpu, UINT64 va, int lock)
{
@@ -472,12 +460,15 @@
ia64_rr vrr;
u64 preferred_size;
- vmx_vcpu_get_rr(vcpu, va, (UINT64 *)&vrr);
+ vmx_vcpu_get_rr(vcpu, va, &vrr);
hcb = vmx_vcpu_get_vtlb(vcpu);
va = PAGEALIGN(va,vrr.ps);
preferred_size = PSIZE(vrr.ps);
return thash_lock_tc(hcb, va, preferred_size, vrr.rid, DSIDE_TLB, lock);
}
+ */
+
+
IA64FAULT vmx_vcpu_itr_i(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa,
UINT64 idx)
{
@@ -486,6 +477,7 @@
thash_cb_t *hcb;
search_section_t sections;
ia64_rr vrr;
+ u64 mfn,psr;
hcb = vmx_vcpu_get_vtlb(vcpu);
data.page_flags=pte & ~PAGE_FLAGS_RV_MASK;
@@ -498,7 +490,8 @@
sections.tr = 1;
sections.tc = 0;
- ovl = thash_find_overlap(hcb, &data, sections);
+
+ ovl = vtr_find_overlap(hcb, &data, ISIDE_TLB);
if (ovl) {
// generate MCA.
panic("Tlb conflict!!");
@@ -507,7 +500,23 @@
sections.tr = 0;
sections.tc = 1;
thash_purge_entries(hcb, &data, sections);
+/* if((idx==IA64_TR_KERNEL)&&(data.ps == KERNEL_TR_PAGE_SHIFT)){
+ data.contiguous=1;
+ }
+ */
thash_tr_insert(hcb, &data, ifa, idx);
+/*
+ if((idx==IA64_TR_KERNEL)&&(data.ps == KERNEL_TR_PAGE_SHIFT)){
+ mfn = __gpfn_to_mfn_foreign(vcpu->domain,arch_to_xen_ppn(data.ppn));
+ data.page_flags=pte&~PAGE_FLAGS_RV_MASK;
+ data.ppn = xen_to_arch_ppn(mfn);
+ psr = ia64_clear_ic();
+ ia64_itr(0x1, IA64_ITR_GUEST_KERNEL, data.vadr, data.page_flags,
data.ps);
+ ia64_set_psr(psr); // restore psr
+ ia64_srlz_i();
+// return IA64_NO_FAULT;
+ }
+*/
return IA64_NO_FAULT;
}
@@ -518,7 +527,7 @@
thash_cb_t *hcb;
search_section_t sections;
ia64_rr vrr;
-
+ u64 mfn,psr;
hcb = vmx_vcpu_get_vtlb(vcpu);
data.page_flags=pte & ~PAGE_FLAGS_RV_MASK;
@@ -526,12 +535,12 @@
data.vadr=PAGEALIGN(ifa,data.ps);
data.tc = 0;
data.cl=DSIDE_TLB;
- vmx_vcpu_get_rr(vcpu, ifa, (UINT64 *)&vrr);
+ vmx_vcpu_get_rr(vcpu, ifa,(UINT64 *)&vrr);
data.rid = vrr.rid;
sections.tr = 1;
sections.tc = 0;
- ovl = thash_find_overlap(hcb, &data, sections);
+ ovl = vtr_find_overlap(hcb, &data, DSIDE_TLB);
while (ovl) {
// generate MCA.
panic("Tlb conflict!!");
@@ -540,7 +549,25 @@
sections.tr = 0;
sections.tc = 1;
thash_purge_entries(hcb, &data, sections);
+/*
+ if((idx==IA64_TR_KERNEL)&&(data.ps == KERNEL_TR_PAGE_SHIFT)){
+ data.contiguous=1;
+ }
+ */
thash_tr_insert(hcb, &data, ifa, idx);
+/*
+ if((idx==IA64_TR_KERNEL)&&(data.ps == KERNEL_TR_PAGE_SHIFT)){
+ mfn = __gpfn_to_mfn_foreign(vcpu->domain,arch_to_xen_ppn(data.ppn));
+ data.page_flags=pte&~PAGE_FLAGS_RV_MASK;
+ data.ppn = xen_to_arch_ppn(mfn);
+ psr = ia64_clear_ic();
+ ia64_itr(0x2,IA64_DTR_GUEST_KERNEL , data.vadr, data.page_flags,
data.ps);
+ ia64_set_psr(psr); // restore psr
+ ia64_srlz_i();
+// return IA64_NO_FAULT;
+ }
+*/
+
return IA64_NO_FAULT;
}
@@ -685,7 +712,25 @@
*padr = (data->ppn<<12) | (vadr&(PSIZE(data->ps)-1));
return IA64_NO_FAULT;
}
- }else{
+ }
+ data = vhpt_lookup(vadr);
+ if(data){
+ if(data->p==0){
+ visr.na=1;
+ vcpu_set_isr(vcpu,visr.val);
+ page_not_present(vcpu, vadr);
+ return IA64_FAULT;
+ }else if(data->ma == VA_MATTR_NATPAGE){
+ visr.na = 1;
+ vcpu_set_isr(vcpu, visr.val);
+ dnat_page_consumption(vcpu, vadr);
+ return IA64_FAULT;
+ }else{
+ *padr = ((*(mpt_table+arch_to_xen_ppn(data->ppn)))<<PAGE_SHIFT) |
(vadr&(PAGE_SIZE-1));
+ return IA64_NO_FAULT;
+ }
+ }
+ else{
if(!vhpt_enabled(vcpu, vadr, NA_REF)){
if(vpsr.ic){
vcpu_set_isr(vcpu, visr.val);
diff -r e58ff5fd3550 -r cfe20f41f043 xen/arch/ia64/vmx/vmx_entry.S
--- a/xen/arch/ia64/vmx/vmx_entry.S Tue Feb 28 20:18:08 2006
+++ b/xen/arch/ia64/vmx/vmx_entry.S Wed Mar 1 15:29:00 2006
@@ -34,6 +34,7 @@
#include <asm/thread_info.h>
#include <asm/unistd.h>
#include <asm/vhpt.h>
+#include <asm/vmmu.h>
#include "vmx_minstate.h"
/*
@@ -696,7 +697,7 @@
movl r25=PAGE_KERNEL
;;
or loc5 = r25,loc5 // construct PA | page properties
- mov r23 = IA64_GRANULE_SHIFT <<2
+ mov r23 = VCPU_VHPT_SHIFT <<2
;;
ptr.d in3,r23
;;
diff -r e58ff5fd3550 -r cfe20f41f043 xen/arch/ia64/vmx/vmx_hypercall.c
--- a/xen/arch/ia64/vmx/vmx_hypercall.c Tue Feb 28 20:18:08 2006
+++ b/xen/arch/ia64/vmx/vmx_hypercall.c Wed Mar 1 15:29:00 2006
@@ -178,6 +178,8 @@
* Lock guest page in vTLB, so that it's not relinquished by recycle
* session when HV is servicing that hypercall.
*/
+
+/*
void hyper_lock_page(void)
{
//TODO:
@@ -190,6 +192,7 @@
vmx_vcpu_increment_iip(vcpu);
}
+ */
static int do_set_shared_page(VCPU *vcpu, u64 gpa)
{
diff -r e58ff5fd3550 -r cfe20f41f043 xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c Tue Feb 28 20:18:08 2006
+++ b/xen/arch/ia64/vmx/vmx_init.c Wed Mar 1 15:29:00 2006
@@ -172,7 +172,15 @@
cpuid3.number = 4; /* 5 - 1 */
vpd->vcpuid[3] = cpuid3.value;
+ vpd->vac.a_from_int_cr = 1;
+ vpd->vac.a_to_int_cr = 1;
+ vpd->vac.a_from_psr = 1;
+ vpd->vac.a_from_cpuid = 1;
+ vpd->vac.a_cover = 1;
+ vpd->vac.a_bsw = 1;
+
vpd->vdc.d_vmsw = 1;
+
return vpd;
}
@@ -300,7 +308,7 @@
int vmx_alloc_contig_pages(struct domain *d)
{
unsigned int order;
- unsigned long i, j, start, end, pgnr, conf_nr;
+ unsigned long i, j, start,tmp, end, pgnr, conf_nr;
struct page_info *page;
struct vcpu *v = d->vcpu[0];
@@ -315,52 +323,100 @@
}
conf_nr = VMX_CONFIG_PAGES(d);
+ if((conf_nr<<PAGE_SHIFT)<(1UL<<(_PAGE_SIZE_64M+1)))
+ panic("vti domain needs 128M memory at least\n");
+/*
order = get_order_from_pages(conf_nr);
if (unlikely((page = alloc_domheap_pages(d, order, 0)) == NULL)) {
printk("Could not allocate order=%d pages for vmx contig alloc\n",
order);
return -1;
}
+*/
+
+/* reserve contiguous 64M for linux kernel */
+
+ if (unlikely((page =
alloc_domheap_pages(d,(KERNEL_TR_PAGE_SHIFT-PAGE_SHIFT), 0)) == NULL)) {
+ printk("No enough memory for vti domain!!!\n");
+ return -1;
+ }
+ pgnr = page_to_mfn(page);
+ for
(i=(1UL<<KERNEL_TR_PAGE_SHIFT);i<(1UL<<(KERNEL_TR_PAGE_SHIFT+1));i+=PAGE_SIZE,pgnr++){
+ assign_domain_page(d, i, pgnr << PAGE_SHIFT);
+ }
+
+ for (i = 0; i < (1UL<<KERNEL_TR_PAGE_SHIFT) ; i += PAGE_SIZE){
+ if (unlikely((page = alloc_domheap_pages(d, 0, 0)) == NULL)) {
+ printk("No enough memory for vti domain!!!\n");
+ return -1;
+ }
+ pgnr = page_to_mfn(page);
+ assign_domain_page(d, i, pgnr << PAGE_SHIFT);
+ }
/* Map normal memory below 3G */
- pgnr = page_to_mfn(page);
end = conf_nr << PAGE_SHIFT;
- for (i = 0;
- i < (end < MMIO_START ? end : MMIO_START);
- i += PAGE_SIZE, pgnr++)
+ tmp = end < MMIO_START ? end : MMIO_START;
+ for (i = (1UL<<(KERNEL_TR_PAGE_SHIFT+1)); i < tmp; i += PAGE_SIZE){
+ if (unlikely((page = alloc_domheap_pages(d, 0, 0)) == NULL)) {
+ printk("No enough memory for vti domain!!!\n");
+ return -1;
+ }
+ pgnr = page_to_mfn(page);
assign_domain_page(d, i, pgnr << PAGE_SHIFT);
-
+ }
/* Map normal memory beyond 4G */
if (unlikely(end > MMIO_START)) {
start = 4 * MEM_G;
end = start + (end - 3 * MEM_G);
- for (i = start; i < end; i += PAGE_SIZE, pgnr++)
- assign_domain_page(d, i, pgnr << PAGE_SHIFT);
+ for (i = start; i < end; i += PAGE_SIZE){
+ if (unlikely((page = alloc_domheap_pages(d, 0, 0)) == NULL)) {
+ printk("No enough memory for vti domain!!!\n");
+ return -1;
+ }
+ pgnr = page_to_mfn(page);
+ assign_domain_page(d, i, pgnr << PAGE_SHIFT);
+ }
}
d->arch.max_pfn = end >> PAGE_SHIFT;
-
+/*
order = get_order_from_pages(GFW_SIZE >> PAGE_SHIFT);
if (unlikely((page = alloc_domheap_pages(d, order, 0)) == NULL)) {
printk("Could not allocate order=%d pages for vmx contig alloc\n",
- order);
+ order);`
return -1;
}
-
+*/
/* Map guest firmware */
- pgnr = page_to_mfn(page);
- for (i = GFW_START; i < GFW_START + GFW_SIZE; i += PAGE_SIZE, pgnr++)
+ for (i = GFW_START; i < GFW_START + GFW_SIZE; i += PAGE_SIZE, pgnr++){
+ if (unlikely((page = alloc_domheap_pages(d, 0, 0)) == NULL)) {
+ printk("No enough memory for vti domain!!!\n");
+ return -1;
+ }
+ pgnr = page_to_mfn(page);
assign_domain_page(d, i, pgnr << PAGE_SHIFT);
-
+ }
+
+/*
if (unlikely((page = alloc_domheap_pages(d, 1, 0)) == NULL)) {
printk("Could not allocate order=1 pages for vmx contig alloc\n");
return -1;
}
-
+*/
/* Map for shared I/O page and xenstore */
+ if (unlikely((page = alloc_domheap_pages(d, 0, 0)) == NULL)) {
+ printk("No enough memory for vti domain!!!\n");
+ return -1;
+ }
pgnr = page_to_mfn(page);
assign_domain_page(d, IO_PAGE_START, pgnr << PAGE_SHIFT);
- pgnr++;
+
+ if (unlikely((page = alloc_domheap_pages(d, 0, 0)) == NULL)) {
+ printk("No enough memory for vti domain!!!\n");
+ return -1;
+ }
+ pgnr = page_to_mfn(page);
assign_domain_page(d, STORE_PAGE_START, pgnr << PAGE_SHIFT);
set_bit(ARCH_VMX_CONTIG_MEM, &v->arch.arch_vmx.flags);
diff -r e58ff5fd3550 -r cfe20f41f043 xen/arch/ia64/vmx/vmx_ivt.S
--- a/xen/arch/ia64/vmx/vmx_ivt.S Tue Feb 28 20:18:08 2006
+++ b/xen/arch/ia64/vmx/vmx_ivt.S Wed Mar 1 15:29:00 2006
@@ -269,6 +269,10 @@
(p7)br.sptk vmx_fault_3
vmx_alt_itlb_miss_1:
mov r16=cr.ifa // get address that caused the TLB miss
+ ;;
+ tbit.z p6,p7=r16,63
+(p6)br.sptk vmx_fault_3
+ ;;
movl r17=PAGE_KERNEL
mov r24=cr.ipsr
movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
@@ -300,6 +304,10 @@
(p7)br.sptk vmx_fault_4
vmx_alt_dtlb_miss_1:
mov r16=cr.ifa // get address that caused the TLB miss
+ ;;
+ tbit.z p6,p7=r16,63
+(p6)br.sptk vmx_fault_4
+ ;;
movl r17=PAGE_KERNEL
mov r20=cr.isr
movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
@@ -397,7 +405,7 @@
/////////////////////////////////////////////////////////////////////////////////////////
// 0x3000 Entry 12 (size 64 bundles) External Interrupt (4)
ENTRY(vmx_interrupt)
- VMX_DBG_FAULT(12)
+// VMX_DBG_FAULT(12)
mov r31=pr // prepare to save predicates
mov r19=12
mov r29=cr.ipsr
@@ -734,7 +742,7 @@
/////////////////////////////////////////////////////////////////////////////////////////
// 0x6100 Entry 37 (size 16 bundles) Virtualization Fault
ENTRY(vmx_virtualization_fault)
- VMX_DBG_FAULT(37)
+// VMX_DBG_FAULT(37)
mov r31=pr
mov r19=37
adds r16 = IA64_VCPU_CAUSE_OFFSET,r21
@@ -1138,5 +1146,5 @@
data8 hyper_not_support //hyper_boot_vcpu
data8 hyper_not_support //hyper_ni_hypercall /* 25 */
data8 hyper_not_support //hyper_mmuext_op
- data8 hyper_lock_page
+ data8 hyper_not_support //tata8 hyper_lock_page
data8 hyper_set_shared_page
diff -r e58ff5fd3550 -r cfe20f41f043 xen/arch/ia64/vmx/vmx_phy_mode.c
--- a/xen/arch/ia64/vmx/vmx_phy_mode.c Tue Feb 28 20:18:08 2006
+++ b/xen/arch/ia64/vmx/vmx_phy_mode.c Wed Mar 1 15:29:00 2006
@@ -27,7 +27,7 @@
#include <asm/vmx_phy_mode.h>
#include <xen/sched.h>
#include <asm/pgtable.h>
-
+#include <asm/vmmu.h>
int valid_mm_mode[8] = {
GUEST_PHYS, /* (it, dt, rt) -> (0, 0, 0) */
INV_MODE,
@@ -94,7 +94,7 @@
* (1,1,1)->(1,0,0)
*/
- {SW_V2P, 0, 0, 0, SW_V2P, SW_V2P, 0, SW_SELF}
+ {SW_V2P, 0, 0, 0, SW_V2P, SW_V2P, 0, SW_SELF},
};
void
@@ -104,9 +104,8 @@
vcpu->arch.mode_flags = GUEST_IN_PHY;
}
-extern u64 get_mfn(domid_t domid, u64 gpfn, u64 pages);
+extern u64 get_mfn(struct domain *d, u64 gpfn);
extern void vmx_switch_rr7(unsigned long ,shared_info_t*,void *,void *,void *);
-
void
physical_itlb_miss_dom0(VCPU *vcpu, u64 vadr)
{
@@ -115,7 +114,7 @@
u64 mppn,gppn;
vpsr.val=vmx_vcpu_get_psr(vcpu);
gppn=(vadr<<1)>>13;
- mppn = get_mfn(DOMID_SELF,gppn,1);
+ mppn = get_mfn(vcpu->domain,gppn);
mppn=(mppn<<12)|(vpsr.cpl<<7);
// if(vadr>>63)
// mppn |= PHY_PAGE_UC;
@@ -147,7 +146,7 @@
// panic("dom n physical dtlb miss happen\n");
vpsr.val=vmx_vcpu_get_psr(vcpu);
gppn=(vadr<<1)>>13;
- mppn = get_mfn(DOMID_SELF,gppn,1);
+ mppn = get_mfn(vcpu->domain, gppn);
mppn=(mppn<<12)|(vpsr.cpl<<7);
if(vadr>>63)
mppn |= PHY_PAGE_UC;
diff -r e58ff5fd3550 -r cfe20f41f043 xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c Tue Feb 28 20:18:08 2006
+++ b/xen/arch/ia64/vmx/vmx_process.c Wed Mar 1 15:29:00 2006
@@ -47,6 +47,7 @@
#include <asm/vmx_vcpu.h>
#include <asm/kregs.h>
#include <asm/vmx.h>
+#include <asm/vmmu.h>
#include <asm/vmx_mm_def.h>
#include <asm/vmx_phy_mode.h>
#include <xen/mm.h>
@@ -314,6 +315,10 @@
return;
}
*/
+ if(vadr == 0x1ea18c00 ){
+ ia64_clear_ic();
+ while(1);
+ }
if(is_physical_mode(v)&&(!(vadr<<1>>62))){
if(vec==1){
physical_itlb_miss(v, vadr);
@@ -342,12 +347,18 @@
return IA64_FAULT;
}
- if ( data->ps != vrr.ps ) {
+// if ( data->ps != vrr.ps ) {
+// machine_tlb_insert(v, data);
+// }
+// else {
+/* if ( data->contiguous&&(!data->tc)){
machine_tlb_insert(v, data);
- }
- else {
- thash_insert(vtlb->ts->vhpt,data,vadr);
- }
+ }
+ else{
+ */
+ thash_vhpt_insert(vtlb->ts->vhpt,data,vadr);
+// }
+// }
}else if(type == DSIDE_TLB){
if(!vhpt_enabled(v, vadr, misr.rs?RSE_REF:DATA_REF)){
if(vpsr.ic){
@@ -367,8 +378,7 @@
} else{
vmx_vcpu_thash(v, vadr, &vhpt_adr);
vrr=vmx_vcpu_rr(v,vhpt_adr);
- data = vtlb_lookup_ex(vtlb, vrr.rid, vhpt_adr, DSIDE_TLB);
- if(data){
+ if(vhpt_lookup(vhpt_adr) || vtlb_lookup_ex(vtlb, vrr.rid,
vhpt_adr, DSIDE_TLB)){
if(vpsr.ic){
vcpu_set_isr(v, misr.val);
dtlb_fault(v, vadr);
@@ -411,8 +421,7 @@
} else{
vmx_vcpu_thash(v, vadr, &vhpt_adr);
vrr=vmx_vcpu_rr(v,vhpt_adr);
- data = vtlb_lookup_ex(vtlb, vrr.rid, vhpt_adr, DSIDE_TLB);
- if(data){
+ if(vhpt_lookup(vhpt_adr) || vtlb_lookup_ex(vtlb, vrr.rid,
vhpt_adr, DSIDE_TLB)){
if(!vpsr.ic){
misr.ni=1;
}
diff -r e58ff5fd3550 -r cfe20f41f043 xen/arch/ia64/vmx/vmx_virt.c
--- a/xen/arch/ia64/vmx/vmx_virt.c Tue Feb 28 20:18:08 2006
+++ b/xen/arch/ia64/vmx/vmx_virt.c Wed Mar 1 15:29:00 2006
@@ -1300,9 +1300,7 @@
IA64_BUNDLE __vmx_get_domain_bundle(u64 iip)
{
IA64_BUNDLE bundle;
-
- fetch_code( current,iip, &bundle.i64[0]);
- fetch_code( current,iip+8, &bundle.i64[1]);
+ fetch_code( current, iip, &bundle.i64[0], &bundle.i64[1]);
return bundle;
}
diff -r e58ff5fd3550 -r cfe20f41f043 xen/arch/ia64/vmx/vtlb.c
--- a/xen/arch/ia64/vmx/vtlb.c Tue Feb 28 20:18:08 2006
+++ b/xen/arch/ia64/vmx/vtlb.c Wed Mar 1 15:29:00 2006
@@ -28,8 +28,10 @@
#include <asm/gcc_intrin.h>
#include <linux/interrupt.h>
#include <asm/vmx_vcpu.h>
+#include <asm/vmmu.h>
#define MAX_CCH_LENGTH 40
+thash_data_t *__alloc_chain(thash_cb_t *, thash_data_t *);
static void cch_mem_init(thash_cb_t *hcb)
{
@@ -50,8 +52,10 @@
if ( (p = hcb->cch_freelist) != NULL ) {
hcb->cch_freelist = p->next;
- }
- return &(p->data);
+ return p;
+ }else{
+ return NULL;
+ }
}
static void cch_free(thash_cb_t *hcb, thash_data_t *cch)
@@ -65,36 +69,38 @@
/*
* Check to see if the address rid:va is translated by the TLB
*/
-static int __is_translated(thash_data_t *tlb, u64 rid, u64 va, CACHE_LINE_TYPE
cl)
-{
- u64 size1,sa1,ea1;
- if ( tlb->rid != rid ||(!tlb->tc && tlb->cl != cl) )
- return 0;
- size1 = PSIZE(tlb->ps);
- sa1 = tlb->vadr & ~(size1-1); // mask the low address bits
- ea1 = sa1 + size1;
-
- if ( va >= sa1 && (va < ea1 || ea1 == 0) )
+
+static int __is_tr_translated(thash_data_t *tlb, u64 rid, u64 va,
CACHE_LINE_TYPE cl)
+{
+ u64 size;
+ size = PSIZE(tlb->ps);
+ if(tlb->vadr&(size-1))
+ while(1);
+ if ((tlb->rid == rid) && ((va-tlb->vadr)<size))
return 1;
else
return 0;
}
/*
- * Only for TLB format.
+ * Only for GUEST TR format.
*/
static int
-__is_tlb_overlap(thash_cb_t *hcb,thash_data_t *entry,int rid, char cl, u64
sva, u64 eva)
-{
- uint64_t size1,sa1,ea1;
-
- if ( entry->invalid || entry->rid != rid || (!entry->tc && entry->cl != cl
) ) {
+__is_tr_overlap(thash_cb_t *hcb,thash_data_t *entry,int rid, char cl, u64 sva,
u64 eva)
+{
+ uint64_t size, sa1, ea1;
+
+// if ( entry->invalid || entry->rid != rid || (entry->cl != cl ) ) {
+ if ( entry->invalid || entry->rid != rid ) {
return 0;
}
- size1=PSIZE(entry->ps);
- sa1 = entry->vadr & ~(size1-1); // mask the low address bits
- ea1 = sa1 + size1;
- if ( (sva >= ea1 && ea1 != 0) || (eva <= sa1 && eva != 0) )
+ size = PSIZE(entry->ps);
+ sa1 = entry->vadr;
+ ea1 = sa1 + size -1;
+ eva -= 1;
+ if(sa1&(size-1))
+ while(1);
+ if ( (sva>ea1) || (sa1>eva) )
return 0;
else
return 1;
@@ -103,9 +109,11 @@
static void __rem_tr (thash_cb_t *hcb, thash_data_t *tr)
{
+/*
if ( hcb->remove_notifier ) {
(hcb->remove_notifier)(hcb,tr);
}
+*/
tr->invalid = 1;
}
@@ -142,7 +150,7 @@
else {
tr = &DTR(hcb,idx);
}
- if ( !INVALID_TLB(tr) ) {
+ if ( !INVALID_TR(tr) ) {
__rem_tr(hcb, tr);
}
__set_tr (tr, insert, idx);
@@ -151,6 +159,7 @@
/*
* remove TR entry.
*/
+/*
static void rem_tr(thash_cb_t *hcb,CACHE_LINE_TYPE cl, int idx)
{
thash_data_t *tr;
@@ -161,17 +170,18 @@
else {
tr = &DTR(hcb,idx);
}
- if ( !INVALID_TLB(tr) ) {
+ if ( !INVALID_TR(tr) ) {
__rem_tr(hcb, tr);
}
}
-
+ */
/*
* Delete an thash entry in collision chain.
* prev: the previous entry.
* rem: the removed entry.
*/
-static void __rem_chain(thash_cb_t *hcb/*, thash_data_t *prev*/, thash_data_t
*rem)
+/*
+static void __rem_chain(thash_cb_t *hcb, thash_data_t *prev, thash_data_t *rem)
{
//prev->next = rem->next;
if ( hcb->remove_notifier ) {
@@ -179,6 +189,7 @@
}
cch_free (hcb, rem);
}
+ */
/*
* Delete an thash entry leading collision chain.
@@ -187,15 +198,16 @@
{
thash_data_t *next=hash->next;
- if ( hcb->remove_notifier ) {
+/* if ( hcb->remove_notifier ) {
(hcb->remove_notifier)(hcb,hash);
- }
+ } */
if ( next != NULL ) {
+ next->len=hash->len-1;
*hash = *next;
cch_free (hcb, next);
}
else {
- INVALIDATE_HASH(hcb, hash);
+ INVALIDATE_HASH_HEADER(hcb, hash);
}
}
@@ -215,8 +227,8 @@
num = NDTRS;
}
for ( i=0; i<num; i++ ) {
- if ( !INVALID_ENTRY(hcb,&tr[i]) &&
- __is_translated(&tr[i], rid, va, cl) )
+ if ( !INVALID_TR(&tr[i]) &&
+ __is_tr_translated(&tr[i], rid, va, cl) )
return &tr[i];
}
return NULL;
@@ -227,6 +239,7 @@
* Find overlap VHPT entry within current collision chain
* base on internal priv info.
*/
+/*
static inline thash_data_t* _vhpt_next_overlap_in_chain(thash_cb_t *hcb)
{
thash_data_t *cch;
@@ -240,26 +253,27 @@
}
return NULL;
}
-
+*/
/*
* Find overlap TLB/VHPT entry within current collision chain
* base on internal priv info.
*/
+/*
static thash_data_t *_vtlb_next_overlap_in_chain(thash_cb_t *hcb)
{
thash_data_t *cch;
thash_internal_t *priv = &hcb->priv;
- /* Find overlap TLB entry */
+ // Find overlap TLB entry
for (cch=priv->cur_cch; cch; cch = cch->next) {
if ( ( cch->tc ? priv->s_sect.tc : priv->s_sect.tr ) &&
- __is_tlb_overlap(hcb, cch, priv->rid, priv->cl,
- priv->_curva, priv->_eva) ) {
+ __is_translated( cch, priv->rid, priv->_curva, priv->cl)) {
return cch;
}
}
return NULL;
}
+ */
/*
* Get the machine format of VHPT entry.
@@ -281,26 +295,190 @@
thash_data_t *tlb, u64 va,
thash_data_t *vhpt)
{
- u64 pages,mfn;
- ia64_rr vrr;
-
+ u64 pages,mfn,padr,pte;
+// ia64_rr vrr;
ASSERT ( hcb->ht == THASH_VHPT );
- vrr = (hcb->get_rr_fn)(hcb->vcpu,va);
- pages = PSIZE(vrr.ps) >> PAGE_SHIFT;
- mfn = (unsigned long)(hcb->vs->get_mfn)(DOMID_SELF,tlb->ppn, pages);
- if ( mfn == INVALID_MFN ) return 0;
-
+// vrr = (hcb->get_rr_fn)(hcb->vcpu,va);
+ padr = tlb->ppn >>(tlb->ps-ARCH_PAGE_SHIFT)<<tlb->ps;
+ padr += va&((1UL<<tlb->ps)-1);
+ pte=lookup_domain_mpa(current->domain,padr);
+ if((pte>>56))
+ return 0;
// TODO with machine discontinuous address space issue.
- vhpt->etag =(unsigned long) (hcb->vs->tag_func)( hcb->pta, tlb->vadr);
+ vhpt->etag = ia64_ttag(va);
//vhpt->ti = 0;
vhpt->itir = tlb->itir & ~ITIR_RV_MASK;
vhpt->page_flags = tlb->page_flags & ~PAGE_FLAGS_RV_MASK;
- vhpt->ppn = mfn;
+ 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)
+{
+ thash_data_t *prev, *next;
+ prev = hash; next= hash->next;
+ while(next){
+ prev=next;
+ next=prev->next;
+ cch_free(hcb, prev);
+ }
+ hash->next = NULL;
+ hash->len = 0;
+}
+
+/* vhpt only has entries with PAGE_SIZE page size */
+
+void thash_vhpt_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va)
+{
+ thash_data_t vhpt_entry, *hash_table, *cch;
+// ia64_rr vrr;
+
+ if ( !__tlb_to_vhpt(hcb, entry, va, &vhpt_entry) ) {
+ return;
+ //panic("Can't convert to machine VHPT entry\n");
+ }
+
+ hash_table = ia64_thash(va);
+ 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,entry);
+ 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;
+// if(hash_table->tag==hash_table->next->tag)
+// while(1);
+
+ }
+ return /*hash_table*/;
+}
+
+/*
+ * vhpt lookup
+ */
+
+thash_data_t * vhpt_lookup(u64 va)
+{
+ thash_data_t *hash;
+ u64 tag;
+ hash = ia64_thash(va);
+ tag = ia64_ttag(va);
+ while(hash){
+ if(hash->etag == tag)
+ return hash;
+ hash=hash->next;
+ }
+ return NULL;
+}
+
+
+/*
+ * purge software guest tlb
+ */
+
+static void vtlb_purge(thash_cb_t *hcb, u64 va, u64 ps)
+{
+ thash_data_t *hash_table, *prev, *next;
+ u64 start, end, size, tag, rid;
+ ia64_rr vrr;
+ vrr=vmx_vcpu_rr(current, va);
+ rid = vrr.rid;
+ size = PSIZE(ps);
+ start = va & (-size);
+ end = start + size;
+ while(start < end){
+ hash_table = vsa_thash(hcb->pta, start, vrr.rrval, &tag);
+// tag = ia64_ttag(start);
+ if(!INVALID_TLB(hash_table)){
+ if(hash_table->etag == tag){
+ __rem_hash_head(hcb, hash_table);
+ }
+ else{
+ prev=hash_table;
+ next=prev->next;
+ while(next){
+ if(next->etag == tag){
+ prev->next=next->next;
+ cch_free(hcb,next);
+ hash_table->len--;
+ break;
+ }
+ prev=next;
+ next=next->next;
+ }
+ }
+ }
+ start += PAGE_SIZE;
+ }
+// machine_tlb_purge(va, ps);
+}
+/*
+ * purge VHPT and machine TLB
+ */
+
+static void vhpt_purge(thash_cb_t *hcb, u64 va, u64 ps)
+{
+ thash_data_t *hash_table, *prev, *next;
+ u64 start, end, size, tag;
+ size = PSIZE(ps);
+ start = va & (-size);
+ end = start + size;
+ while(start < end){
+ hash_table = ia64_thash(start);
+ tag = ia64_ttag(start);
+ if(hash_table->etag == tag ){
+ __rem_hash_head(hcb, hash_table);
+ }
+ else{
+ prev=hash_table;
+ next=prev->next;
+ while(next){
+ if(next->etag == tag){
+ prev->next=next->next;
+ cch_free(hcb,next);
+ hash_table->len--;
+ break;
+ }
+ prev=next;
+ next=next->next;
+ }
+ }
+ start += PAGE_SIZE;
+ }
+ machine_tlb_purge(va, ps);
+}
/*
* Insert an entry to hash table.
* NOTES:
@@ -327,43 +505,62 @@
entry->vadr = PAGEALIGN(entry->vadr,entry->ps);
entry->ppn = PAGEALIGN(entry->ppn, entry->ps-12);
rep_tr(hcb, entry, idx);
+// thash_vhpt_insert(hcb->ts->vhpt, entry, va);
return ;
}
+
+
+/*
+ * 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);
+ }
+}
+/*
thash_data_t *vtlb_alloc_chain(thash_cb_t *hcb,thash_data_t *entry)
{
thash_data_t *cch;
-
+
cch = cch_alloc(hcb);
if(cch == NULL){
- thash_purge_all(hcb);
+ thash_recycle_cch(hcb);
+ cch = cch_alloc(hcb);
}
return cch;
}
-
+*/
thash_data_t *__alloc_chain(thash_cb_t *hcb,thash_data_t *entry)
{
thash_data_t *cch;
-
+
cch = cch_alloc(hcb);
if(cch == NULL){
// recycle
- if ( hcb->recycle_notifier ) {
- hcb->recycle_notifier(hcb,(u64)entry);
- }
- thash_purge_all(hcb);
-// cch = cch_alloc(hcb);
+// if ( hcb->recycle_notifier ) {
+// hcb->recycle_notifier(hcb,(u64)entry);
+// }
+ thash_recycle_cch(hcb);
+ cch = cch_alloc(hcb);
}
return cch;
}
-
+
/*
* Insert an entry into hash TLB or VHPT.
* NOTES:
* 1: When inserting VHPT to thash, "va" is a must covered
* address by the inserted machine VHPT entry.
* 2: The format of entry is always in TLB.
- * 3: The caller need to make sure the new entry will not overlap
+ * 3: The caller need to make sure the new entry will not overlap
* with any existed entry.
*/
void vtlb_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va)
@@ -372,16 +569,32 @@
int flag;
ia64_rr vrr;
u64 gppn;
- u64 ppns, ppne;
-
- hash_table = (thash_data_t *)(hcb->hash_func)(hcb->pta, va);
- if( INVALID_ENTRY(hcb, hash_table) ) {
+ u64 ppns, ppne, tag;
+ vrr=vmx_vcpu_rr(current, va);
+ if (vrr.ps != entry->ps) {
+// machine_tlb_insert(hcb->vcpu, entry);
+ panic("not preferred ps with va: 0x%lx\n", va);
+ return;
+ }
+ entry->vadr = PAGEALIGN(entry->vadr,entry->ps);
+ entry->ppn = PAGEALIGN(entry->ppn, entry->ps-12);
+ hash_table = vsa_thash(hcb->pta, va, vrr.rrval, &tag);
+ entry->etag = tag;
+ if( INVALID_TLB(hash_table) ) {
*hash_table = *entry;
hash_table->next = 0;
}
+ else if (hash_table->len>=MAX_CCN_DEPTH){
+ thash_remove_cch(hcb, hash_table);
+ cch = cch_alloc(hcb);
+ *cch = *hash_table;
+ *hash_table = *entry;
+ hash_table->len = 1;
+ hash_table->next = cch;
+ }
else {
// TODO: Add collision chain length limitation.
- cch = vtlb_alloc_chain(hcb,entry);
+ cch = __alloc_chain(hcb,entry);
if(cch == NULL){
*hash_table = *entry;
hash_table->next = 0;
@@ -389,22 +602,17 @@
*cch = *hash_table;
*hash_table = *entry;
hash_table->next = cch;
- }
- }
+ hash_table->len = cch->len + 1;
+ cch->len = 0;
+ }
+ }
+#if 0
if(hcb->vcpu->domain->domain_id==0){
thash_insert(hcb->ts->vhpt, entry, va);
return;
}
-
-#if 1
- vrr=vmx_vcpu_rr(current, va);
- if (vrr.ps != entry->ps) {
- machine_tlb_insert(hcb->vcpu, entry);
- printk("not preferred ps with va: 0x%lx\n", va);
- return;
- }
-#endif
-
+#endif
+/*
flag = 1;
gppn =
(POFFSET(va,entry->ps)|PAGEALIGN((entry->ppn<<12),entry->ps))>>PAGE_SHIFT;
ppns = PAGEALIGN((entry->ppn<<12),entry->ps);
@@ -413,46 +621,18 @@
flag = 0;
if((__gpfn_is_mem(hcb->vcpu->domain, gppn)&&flag))
thash_insert(hcb->ts->vhpt, entry, va);
+*/
return ;
}
-static void vhpt_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va)
-{
- thash_data_t vhpt_entry, *hash_table, *cch;
-
- if ( !__tlb_to_vhpt(hcb, entry, va, &vhpt_entry) ) {
- panic("Can't convert to machine VHPT entry\n");
- }
- hash_table = (thash_data_t *)(hcb->hash_func)(hcb->pta, va);
- if( INVALID_ENTRY(hcb, hash_table) ) {
- *hash_table = vhpt_entry;
- hash_table->next = 0;
- }
- else {
- // TODO: Add collision chain length limitation.
- cch = __alloc_chain(hcb,entry);
- if(cch == NULL){
- *hash_table = vhpt_entry;
- hash_table->next = 0;
- }else{
- *cch = *hash_table;
- *hash_table = vhpt_entry;
- hash_table->next = cch;
- if(hash_table->tag==hash_table->next->tag)
- while(1);
-
- }
-
- }
- return /*hash_table*/;
-}
-
+
+/*
void thash_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va)
{
- //thash_data_t *hash_table;
+ thash_data_t *hash_table;
ia64_rr vrr;
- vrr = (hcb->get_rr_fn)(hcb->vcpu,entry->vadr);
+ vrr = vmx_vcpu_rr(hcb->vcpu,entry->vadr);
if ( entry->ps != vrr.ps && entry->tc ) {
panic("Not support for multiple page size now\n");
}
@@ -461,11 +641,13 @@
(hcb->ins_hash)(hcb, entry, va);
}
-
+*/
+/*
static void rem_thash(thash_cb_t *hcb, thash_data_t *entry)
{
thash_data_t *hash_table, *p, *q;
thash_internal_t *priv = &hcb->priv;
+ int idx;
hash_table = priv->hash_base;
if ( hash_table == entry ) {
@@ -481,6 +663,7 @@
// if ( PURGABLE_ENTRY(hcb,q ) ) {
p->next = q->next;
__rem_chain(hcb, entry);
+ hash_table->len--;
// }
return ;
}
@@ -488,16 +671,20 @@
}
panic("Entry not existed or bad sequence\n");
}
-
+*/
+/*
static void rem_vtlb(thash_cb_t *hcb, thash_data_t *entry)
{
+ thash_data_t *hash_table, *p, *q;
+ thash_internal_t *priv = &hcb->priv;
+ int idx;
if ( !entry->tc ) {
return rem_tr(hcb, entry->cl, entry->tr_idx);
}
rem_thash(hcb, entry);
}
-
+*/
int cch_depth=0;
/*
* Purge the collision chain starting from cch.
@@ -505,6 +692,7 @@
* For those UN-Purgable entries(FM), this function will return
* the head of left collision chain.
*/
+/*
static thash_data_t *thash_rem_cch(thash_cb_t *hcb, thash_data_t *cch)
{
thash_data_t *next;
@@ -536,10 +724,11 @@
* hash: The head of collision chain (hash table)
*
*/
+/*
static void thash_rem_line(thash_cb_t *hcb, thash_data_t *hash)
{
if ( INVALID_ENTRY(hcb, hash) ) return;
-
+
if ( hash->next ) {
cch_depth = 0;
hash->next = thash_rem_cch(hcb, hash->next);
@@ -549,6 +738,7 @@
__rem_hash_head(hcb, hash);
}
}
+ */
/*
* Find an overlap entry in hash table and its collision chain.
@@ -563,26 +753,31 @@
* NOTES:
*
*/
-thash_data_t *thash_find_overlap(thash_cb_t *hcb,
+
+/*
+thash_data_t *thash_find_overlap(thash_cb_t *hcb,
thash_data_t *in, search_section_t s_sect)
{
- return (hcb->find_overlap)(hcb, in->vadr,
+ return (hcb->find_overlap)(hcb, in->vadr,
PSIZE(in->ps), in->rid, in->cl, s_sect);
}
-
-static thash_data_t *vtlb_find_overlap(thash_cb_t *hcb,
+*/
+
+/*
+static thash_data_t *vtlb_find_overlap(thash_cb_t *hcb,
u64 va, u64 size, int rid, char cl, search_section_t s_sect)
{
thash_data_t *hash_table;
thash_internal_t *priv = &hcb->priv;
+ u64 tag;
ia64_rr vrr;
priv->_curva = va & ~(size-1);
priv->_eva = priv->_curva + size;
priv->rid = rid;
- vrr = (hcb->get_rr_fn)(hcb->vcpu,va);
+ vrr = vmx_vcpu_rr(hcb->vcpu,va);
priv->ps = vrr.ps;
- hash_table =(thash_data_t *)(hcb->hash_func)(hcb->pta, priv->_curva);
+ hash_table = vsa_thash(hcb->pta, priv->_curva, vrr.rrval, &tag);
priv->s_sect = s_sect;
priv->cl = cl;
priv->_tr_idx = 0;
@@ -590,8 +785,10 @@
priv->cur_cch = hash_table;
return (hcb->next_overlap)(hcb);
}
-
-static thash_data_t *vhpt_find_overlap(thash_cb_t *hcb,
+*/
+
+/*
+static thash_data_t *vhpt_find_overlap(thash_cb_t *hcb,
u64 va, u64 size, int rid, char cl, search_section_t s_sect)
{
thash_data_t *hash_table;
@@ -602,17 +799,43 @@
priv->_curva = va & ~(size-1);
priv->_eva = priv->_curva + size;
priv->rid = rid;
- vrr = (hcb->get_rr_fn)(hcb->vcpu,va);
+ vrr = vmx_vcpu_rr(hcb->vcpu,va);
priv->ps = vrr.ps;
- hash_table = (thash_data_t *)(hcb->hash_func)( hcb->pta, priv->_curva);
- tag = (unsigned long)(hcb->vs->tag_func)( hcb->pta, priv->_curva);
+ hash_table = ia64_thash(priv->_curva);
+ tag = ia64_ttag(priv->_curva);
priv->tag = tag;
priv->hash_base = hash_table;
priv->cur_cch = hash_table;
return (hcb->next_overlap)(hcb);
}
-
-
+*/
+
+
+thash_data_t *vtr_find_overlap(thash_cb_t *hcb, thash_data_t *data, char cl)
+{
+ thash_data_t *tr;
+ int i,num;
+ u64 end;
+
+ if (cl == ISIDE_TLB ) {
+ num = NITRS;
+ tr = &ITR(hcb,0);
+ }
+ else {
+ num = NDTRS;
+ tr = &DTR(hcb,0);
+ }
+ end=data->vadr + PSIZE(data->ps);
+ for (i=0; i<num; i++ ) {
+ if ( __is_tr_overlap(hcb, &tr[i], data->rid, cl, data->vadr, end )) {
+ return &tr[i];
+ }
+ }
+ return NULL;
+}
+
+
+/*
static thash_data_t *vtr_find_next_overlap(thash_cb_t *hcb)
{
thash_data_t *tr;
@@ -628,25 +851,27 @@
tr = &DTR(hcb,0);
}
for (; priv->_tr_idx < num; priv->_tr_idx ++ ) {
- if ( __is_tlb_overlap(hcb, &tr[(unsigned)priv->_tr_idx],
+ if ( __is_tr_overlap(hcb, &tr[priv->_tr_idx],
priv->rid, priv->cl,
priv->_curva, priv->_eva) ) {
- return &tr[(unsigned)priv->_tr_idx++];
+ return &tr[priv->_tr_idx++];
}
}
return NULL;
}
+*/
/*
* Similar with vtlb_next_overlap but find next entry.
* NOTES:
* Intermediate position information is stored in hcb->priv.
*/
+/*
static thash_data_t *vtlb_next_overlap(thash_cb_t *hcb)
{
thash_data_t *ovl;
thash_internal_t *priv = &hcb->priv;
- u64 rr_psize;
+ u64 addr,rr_psize,tag;
ia64_rr vrr;
if ( priv->s_sect.tr ) {
@@ -655,7 +880,7 @@
priv->s_sect.tr = 0;
}
if ( priv->s_sect.v == 0 ) return NULL;
- vrr = (hcb->get_rr_fn)(hcb->vcpu,priv->_curva);
+ vrr = vmx_vcpu_rr(hcb->vcpu,priv->_curva);
rr_psize = PSIZE(vrr.ps);
while ( priv->_curva < priv->_eva ) {
@@ -667,20 +892,23 @@
}
}
priv->_curva += rr_psize;
- priv->hash_base = (thash_data_t *)(hcb->hash_func)( hcb->pta,
priv->_curva);
+ priv->hash_base = vsa_thash( hcb->pta, priv->_curva, vrr.rrval, &tag);
priv->cur_cch = priv->hash_base;
}
return NULL;
}
-
+ */
+
+
+/*
static thash_data_t *vhpt_next_overlap(thash_cb_t *hcb)
{
thash_data_t *ovl;
thash_internal_t *priv = &hcb->priv;
- u64 rr_psize;
+ u64 addr,rr_psize;
ia64_rr vrr;
- vrr = (hcb->get_rr_fn)(hcb->vcpu,priv->_curva);
+ vrr = vmx_vcpu_rr(hcb->vcpu,priv->_curva);
rr_psize = PSIZE(vrr.ps);
while ( priv->_curva < priv->_eva ) {
@@ -692,13 +920,13 @@
}
}
priv->_curva += rr_psize;
- priv->hash_base =(thash_data_t *)(hcb->hash_func)( hcb->pta,
priv->_curva);
- priv->tag = (unsigned long)(hcb->vs->tag_func)( hcb->pta,
priv->_curva);
+ priv->hash_base = ia64_thash(priv->_curva);
+ priv->tag = ia64_ttag(priv->_curva);
priv->cur_cch = priv->hash_base;
}
return NULL;
}
-
+*/
/*
* Find and purge overlap entries in hash table and its collision chain.
@@ -710,7 +938,7 @@
* NOTES:
*
*/
-void thash_purge_entries(thash_cb_t *hcb,
+void thash_purge_entries(thash_cb_t *hcb,
thash_data_t *in, search_section_t p_sect)
{
return thash_purge_entries_ex(hcb, in->rid, in->vadr,
@@ -718,30 +946,33 @@
}
void thash_purge_entries_ex(thash_cb_t *hcb,
- u64 rid, u64 va, u64 ps,
- search_section_t p_sect,
+ u64 rid, u64 va, u64 ps,
+ search_section_t p_sect,
CACHE_LINE_TYPE cl)
{
thash_data_t *ovl;
- ovl = (hcb->find_overlap)(hcb, va, PSIZE(ps), rid, cl, p_sect);
+/* ovl = (hcb->find_overlap)(hcb, va, PSIZE(ps), rid, cl, p_sect);
while ( ovl != NULL ) {
(hcb->rem_hash)(hcb, ovl);
ovl = (hcb->next_overlap)(hcb);
};
+ */
+ vtlb_purge(hcb, va, ps);
+ vhpt_purge(hcb->ts->vhpt, va, ps);
}
/*
* Purge overlap TCs and then insert the new entry to emulate itc ops.
* Notes: Only TC entry can purge and insert.
*/
-void thash_purge_and_insert(thash_cb_t *hcb, thash_data_t *in)
+void thash_purge_and_insert(thash_cb_t *hcb, thash_data_t *in, u64 va)
{
thash_data_t *ovl;
search_section_t sections;
#ifdef XEN_DEBUGGER
- vrr = (hcb->get_rr_fn)(hcb->vcpu,in->vadr);
+ vrr = vmx_vcpu_rr(hcb->vcpu,in->vadr);
if ( in->ps != vrr.ps || hcb->ht != THASH_TLB || !in->tc ) {
panic ("Oops, wrong call for purge_and_insert\n");
return;
@@ -751,10 +982,14 @@
in->ppn = PAGEALIGN(in->ppn, in->ps-12);
sections.tr = 0;
sections.tc = 1;
+/*
ovl = (hcb->find_overlap)(hcb, in->vadr, PSIZE(in->ps),
in->rid, in->cl, sections);
if(ovl)
(hcb->rem_hash)(hcb, ovl);
+ */
+ vtlb_purge(hcb, va, in->ps);
+ vhpt_purge(hcb->ts->vhpt, va, in->ps);
#ifdef XEN_DEBUGGER
ovl = (hcb->next_overlap)(hcb);
if ( ovl ) {
@@ -762,7 +997,9 @@
return;
}
#endif
- (hcb->ins_hash)(hcb, in, in->vadr);
+ if(in->ps!=PAGE_SHIFT)
+ vtlb_insert(hcb, in, va);
+ thash_vhpt_insert(hcb->ts->vhpt, in, va);
}
/*
* Purge one hash line (include the entry in hash table).
@@ -771,6 +1008,7 @@
* hash: The head of collision chain (hash table)
*
*/
+/*
static void thash_purge_line(thash_cb_t *hcb, thash_data_t *hash)
{
if ( INVALID_ENTRY(hcb, hash) ) return;
@@ -784,6 +1022,16 @@
// Then hash table itself.
INVALIDATE_HASH(hcb, hash);
}
+*/
+
+
+
+
+
+
+
+
+
/*
* Purge all TCs or VHPT entries including those in Hash table.
*
@@ -792,8 +1040,10 @@
// TODO: add sections.
void thash_purge_all(thash_cb_t *hcb)
{
- thash_data_t *hash_table;
-
+ thash_data_t *hash_table, *entry;
+ thash_cb_t *vhpt;
+ u64 i, start, end;
+
#ifdef VTLB_DEBUG
extern u64 sanity_check;
static u64 statistics_before_purge_all=0;
@@ -802,18 +1052,35 @@
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--) {
- thash_purge_line(hcb, hash_table);
- }
- if(hcb->ht== THASH_TLB) {
- hcb = hcb->ts->vhpt;
- hash_table = (thash_data_t*)((u64)hcb->hash + hcb->hash_sz);
- for (--hash_table;(u64)hash_table >= (u64)hcb->hash;hash_table--) {
- thash_purge_line(hcb, hash_table);
- }
- }
+ INVALIDATE_TLB_HEADER(hash_table);
+ }
+ cch_mem_init (hcb);
+
+ vhpt = hcb->ts->vhpt;
+ 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);
+
+/*
+ entry = &hcb->ts->itr[0];
+ for(i=0; i< (NITRS+NDTRS); i++){
+ if(!INVALID_TLB(entry)){
+ start=entry->vadr & (-PSIZE(entry->ps));
+ end = start + PSIZE(entry->ps);
+ while(start<end){
+ thash_vhpt_insert(vhpt, entry, start);
+ start += PAGE_SIZE;
+ }
+ }
+ entry++;
+ }
+*/
local_flush_tlb_all();
}
@@ -836,22 +1103,24 @@
CACHE_LINE_TYPE cl)
{
thash_data_t *hash_table, *cch;
+ u64 tag;
ia64_rr vrr;
- ASSERT ( hcb->ht == THASH_VTLB );
+ ASSERT ( hcb->ht == THASH_TLB );
cch = __vtr_lookup(hcb, rid, va, cl);;
if ( cch ) return cch;
- vrr = (hcb->get_rr_fn)(hcb->vcpu,va);
- hash_table = (thash_data_t *)(hcb->hash_func)( hcb->pta, va);
+ vrr = vmx_vcpu_rr(hcb->vcpu,va);
+ 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) {
- if ( __is_translated(cch, rid, va, cl) )
+// if ( __is_translated(cch, rid, va, cl) )
+ if(cch->etag == tag)
return cch;
}
return NULL;
@@ -864,6 +1133,7 @@
* 1: failure
* 0: success
*/
+/*
int thash_lock_tc(thash_cb_t *hcb, u64 va, u64 size, int rid, char cl, int
lock)
{
thash_data_t *ovl;
@@ -893,6 +1163,7 @@
}
return 1;
}
+*/
/*
* Notifier when TLB is deleted from hash table and its collision chain.
@@ -904,16 +1175,17 @@
* 2: The format of entry is always in TLB.
*
*/
-void tlb_remove_notifier(thash_cb_t *hcb, thash_data_t *entry)
-{
+//void tlb_remove_notifier(thash_cb_t *hcb, thash_data_t *entry)
+//{
+// vhpt_purge(hcb->ts->vhpt,entry->vadr,entry->ps);
// thash_cb_t *vhpt;
- search_section_t s_sect;
- s_sect.v = 0;
- thash_purge_entries(hcb->ts->vhpt, entry, s_sect);
- machine_tlb_purge(entry->vadr, entry->ps);
- return;
-}
+// search_section_t s_sect;
+
+// s_sect.v = 0;
+// thash_purge_entries(hcb->ts->vhpt, entry, s_sect);
+// machine_tlb_purge(entry->vadr, entry->ps);
+//}
/*
* Initialize internal control data before service.
@@ -928,30 +1200,29 @@
hcb->pta.vf = 1;
hcb->pta.ve = 1;
hcb->pta.size = sz;
- hcb->get_rr_fn = vmmu_get_rr;
+// hcb->get_rr_fn = vmmu_get_rr;
ASSERT ( hcb->hash_sz % sizeof(thash_data_t) == 0 );
if ( hcb->ht == THASH_TLB ) {
- hcb->remove_notifier = tlb_remove_notifier;
- hcb->find_overlap = vtlb_find_overlap;
- hcb->next_overlap = vtlb_next_overlap;
- hcb->rem_hash = rem_vtlb;
- hcb->ins_hash = vtlb_insert;
+// hcb->remove_notifier = NULL; //tlb_remove_notifier;
+// hcb->find_overlap = vtlb_find_overlap;
+// hcb->next_overlap = vtlb_next_overlap;
+// hcb->rem_hash = rem_vtlb;
+// hcb->ins_hash = vtlb_insert;
__init_tr(hcb);
}
else {
- hcb->remove_notifier = NULL;
- hcb->find_overlap = vhpt_find_overlap;
- hcb->next_overlap = vhpt_next_overlap;
- hcb->rem_hash = rem_thash;
- hcb->ins_hash = vhpt_insert;
+// hcb->remove_notifier = NULL;
+// hcb->find_overlap = vhpt_find_overlap;
+// hcb->next_overlap = vhpt_next_overlap;
+// hcb->rem_hash = rem_thash;
+// hcb->ins_hash = thash_vhpt_insert;
}
hash_table = (thash_data_t*)((u64)hcb->hash + hcb->hash_sz);
-
+
for (--hash_table;(u64)hash_table >= (u64)hcb->hash;hash_table--) {
- INVALIDATE_HASH(hcb,hash_table);
- }
-}
-#define VTLB_DEBUG
+ INVALIDATE_HASH_HEADER(hcb,hash_table);
+ }
+}
#ifdef VTLB_DEBUG
static u64 cch_length_statistics[MAX_CCH_LENGTH+1];
u64 sanity_check=0;
@@ -961,7 +1232,7 @@
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);
@@ -991,7 +1262,7 @@
search_section_t s_sect;
thash_cb_t *vhpt = vtlb->ts->vhpt;
u64 invalid_ratio;
-
+
if ( sanity_check == 0 ) return;
sanity_check --;
s_sect.v = 0;
@@ -1012,9 +1283,9 @@
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) ) {
@@ -1097,12 +1368,12 @@
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) ) {
diff -r e58ff5fd3550 -r cfe20f41f043 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c Tue Feb 28 20:18:08 2006
+++ b/xen/arch/ia64/xen/domain.c Wed Mar 1 15:29:00 2006
@@ -484,6 +484,9 @@
__pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
}
else printk("assign_domain_page: mpaddr %lx already mapped!\n",mpaddr);
+ if((physaddr>>PAGE_SHIFT)<max_page){
+ *(mpt_table + (physaddr>>PAGE_SHIFT))=(mpaddr>>PAGE_SHIFT);
+ }
}
#if 0
/* map a physical address with specified I/O flag */
diff -r e58ff5fd3550 -r cfe20f41f043 xen/include/asm-ia64/config.h
--- a/xen/include/asm-ia64/config.h Tue Feb 28 20:18:08 2006
+++ b/xen/include/asm-ia64/config.h Wed Mar 1 15:29:00 2006
@@ -67,7 +67,7 @@
extern unsigned long xenheap_phys_end;
extern unsigned long xen_pstart;
extern unsigned long xenheap_size;
-extern struct domain *dom0;
+//extern struct domain *dom0;
extern unsigned long dom0_start;
extern unsigned long dom0_size;
diff -r e58ff5fd3550 -r cfe20f41f043 xen/include/asm-ia64/mm.h
--- a/xen/include/asm-ia64/mm.h Tue Feb 28 20:18:08 2006
+++ b/xen/include/asm-ia64/mm.h Wed Mar 1 15:29:00 2006
@@ -133,6 +133,8 @@
extern void __init init_frametable(void);
#endif
void add_to_domain_alloc_list(unsigned long ps, unsigned long pe);
+
+extern unsigned long gmfn_to_mfn_foreign(struct domain *d, unsigned long gpfn);
static inline void put_page(struct page_info *page)
{
@@ -215,8 +217,8 @@
#endif
// prototype of misc memory stuff
-unsigned long __get_free_pages(unsigned int mask, unsigned int order);
-void __free_pages(struct page *page, unsigned int order);
+//unsigned long __get_free_pages(unsigned int mask, unsigned int order);
+//void __free_pages(struct page *page, unsigned int order);
void *pgtable_quicklist_alloc(void);
void pgtable_quicklist_free(void *pgtable_entry);
@@ -436,12 +438,22 @@
/* Return I/O type if trye */
#define __gpfn_is_io(_d, gpfn) \
- (__gmfn_valid(_d, gpfn) ? \
- (lookup_domain_mpa((_d), ((gpfn)<<PAGE_SHIFT)) & GPFN_IO_MASK) : 0)
+({ \
+ u64 pte, ret=0; \
+ pte=lookup_domain_mpa((_d), ((gpfn)<<PAGE_SHIFT)); \
+ if(!(pte&GPFN_INV_MASK)) \
+ ret = pte & GPFN_IO_MASK; \
+ ret; \
+})
#define __gpfn_is_mem(_d, gpfn) \
- (__gmfn_valid(_d, gpfn) ? \
- ((lookup_domain_mpa((_d), ((gpfn)<<PAGE_SHIFT)) & GPFN_IO_MASK) ==
GPFN_MEM) : 0)
+({ \
+ u64 pte, ret=0; \
+ pte=lookup_domain_mpa((_d), ((gpfn)<<PAGE_SHIFT)); \
+ if((!(pte&GPFN_INV_MASK))&&((pte & GPFN_IO_MASK)==GPFN_MEM)) \
+ ret = 1; \
+ ret; \
+})
#define __gpa_to_mpa(_d, gpa) \
diff -r e58ff5fd3550 -r cfe20f41f043 xen/include/asm-ia64/vcpu.h
--- a/xen/include/asm-ia64/vcpu.h Tue Feb 28 20:18:08 2006
+++ b/xen/include/asm-ia64/vcpu.h Wed Mar 1 15:29:00 2006
@@ -104,7 +104,6 @@
extern IA64FAULT vcpu_set_pmv(VCPU *vcpu, UINT64 val);
extern IA64FAULT vcpu_set_cmcv(VCPU *vcpu, UINT64 val);
/* interval timer registers */
-extern IA64FAULT vcpu_set_itm(VCPU *vcpu,UINT64 val);
extern IA64FAULT vcpu_set_itc(VCPU *vcpu,UINT64 val);
extern UINT64 vcpu_timer_pending_early(VCPU *vcpu);
/* debug breakpoint registers */
diff -r e58ff5fd3550 -r cfe20f41f043 xen/include/asm-ia64/vmmu.h
--- a/xen/include/asm-ia64/vmmu.h Tue Feb 28 20:18:08 2006
+++ b/xen/include/asm-ia64/vmmu.h Wed Mar 1 15:29:00 2006
@@ -22,13 +22,27 @@
#ifndef XEN_TLBthash_H
#define XEN_TLBthash_H
+
+#define MAX_CCN_DEPTH 15 // collision chain depth
+#define VCPU_VTLB_SHIFT (20) // 1M for VTLB
+#define VCPU_VTLB_SIZE (1UL<<VCPU_VTLB_SHIFT)
+#define VCPU_VTLB_ORDER (VCPU_VTLB_SHIFT - PAGE_SHIFT)
+#define VCPU_VHPT_SHIFT (24) // 16M for VTLB
+#define VCPU_VHPT_SIZE (1UL<<VCPU_VHPT_SHIFT)
+#define VCPU_VHPT_ORDER (VCPU_VHPT_SHIFT - PAGE_SHIFT)
+
+#define PTA_BASE_SHIFT (15)
+
+
+
+#ifndef __ASSEMBLY__
#include <xen/config.h>
#include <xen/types.h>
#include <public/xen.h>
#include <asm/tlb.h>
#include <asm/regionreg.h>
-
+#include <asm/vmx_mm_def.h>
//#define THASH_TLB_TR 0
//#define THASH_TLB_TC 1
@@ -39,7 +53,15 @@
/*
* Next bit definition must be same with THASH_TLB_XX
- */
+#define PTA_BASE_SHIFT (15)
+ */
+
+
+
+
+#define HIGH_32BITS(x) bits(x,32,63)
+#define LOW_32BITS(x) bits(x,0,31)
+
typedef union search_section {
struct {
u32 tr : 1;
@@ -49,15 +71,6 @@
u32 v;
} search_section_t;
-#define MAX_CCN_DEPTH 4 // collision chain depth
-#define VCPU_TLB_SHIFT (22)
-#define VCPU_TLB_SIZE (1UL<<VCPU_TLB_SHIFT)
-#define VCPU_TLB_ORDER VCPU_TLB_SHIFT - PAGE_SHIFT
-#define PTA_BASE_SHIFT (15)
-
-#ifndef __ASSEMBLY__
-#define HIGH_32BITS(x) bits(x,32,63)
-#define LOW_32BITS(x) bits(x,0,31)
typedef enum {
ISIDE_TLB=0,
@@ -77,18 +90,21 @@
u64 ppn : 38; // 12-49
u64 rv2 : 2; // 50-51
u64 ed : 1; // 52
- u64 ig1 : 11; //53-63
+ u64 ig1 : 3; // 53-55
+ u64 len : 4; // 56-59
+ u64 ig2 : 3; // 60-63
};
struct {
u64 __rv1 : 53; // 0-52
+ u64 contiguous : 1; //53
+ u64 tc : 1; // 54 TR or TC
+ CACHE_LINE_TYPE cl : 1; // 55 I side or D side cache line
// next extension to ig1, only for TLB instance
- u64 tc : 1; // 53 TR or TC
- u64 locked : 1; // 54 entry locked or not
- CACHE_LINE_TYPE cl : 1; // I side or D side cache line
- u64 nomap : 1; // entry cann't be inserted into machine TLB.
- u64 __ig1 : 5; // 56-61
- u64 checked : 1; // for VTLB/VHPT sanity check
- u64 invalid : 1; // invalid entry
+ u64 __ig1 : 4; // 56-59
+ u64 locked : 1; // 60 entry locked or not
+ u64 nomap : 1; // 61 entry cann't be inserted into machine TLB.
+ u64 checked : 1; // 62 for VTLB/VHPT sanity check
+ u64 invalid : 1; // 63 invalid entry
};
u64 page_flags;
}; // same for VHPT and TLB
@@ -128,10 +144,37 @@
};
} 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; }
+
#define INVALID_VHPT(hdata) ((hdata)->ti)
-#define INVALID_TLB(hdata) ((hdata)->invalid)
-#define INVALID_ENTRY(hcb, hdata) \
- ((hcb)->ht==THASH_TLB ? INVALID_TLB(hdata) : INVALID_VHPT(hdata))
+#define INVALID_TLB(hdata) ((hdata)->ti)
+#define INVALID_TR(hdata) ((hdata)->invalid)
+#define INVALID_ENTRY(hcb, hdata) INVALID_VHPT(hdata)
+
+/* ((hcb)->ht==THASH_TLB ? INVALID_TLB(hdata) : INVALID_VHPT(hdata)) */
+
+
+/*
+ * Architecture ppn is in 4KB unit while XEN
+ * page may be different(1<<PAGE_SHIFT).
+ */
+static inline u64 arch_to_xen_ppn(u64 appn)
+{
+ return (appn >>(PAGE_SHIFT-ARCH_PAGE_SHIFT));
+}
+
+static inline u64 xen_to_arch_ppn(u64 xppn)
+{
+ return (xppn <<(PAGE_SHIFT- ARCH_PAGE_SHIFT));
+}
typedef enum {
THASH_TLB=0,
@@ -166,11 +209,11 @@
struct thash_cb *vhpt;
} tlb_special_t;
-typedef struct vhpt_cb {
+//typedef struct vhpt_cb {
//u64 pta; // pta value.
- GET_MFN_FN *get_mfn;
- TTAG_FN *tag_func;
-} vhpt_special;
+// GET_MFN_FN *get_mfn;
+// TTAG_FN *tag_func;
+//} vhpt_special;
typedef struct thash_internal {
thash_data_t *hash_base;
@@ -198,36 +241,38 @@
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_FN *hash_func;
+// GET_RR_FN *get_rr_fn;
+// RECYCLE_FN *recycle_notifier;
thash_cch_mem_t *cch_freelist;
struct vcpu *vcpu;
PTA pta;
/* 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;
+// 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;
+// thash_internal_t priv;
union {
tlb_special_t *ts;
- vhpt_special *vs;
+// vhpt_special *vs;
};
// Internal positon information, buffer and storage etc. TBD
} thash_cb_t;
#define ITR(hcb,id) ((hcb)->ts->itr[id])
#define DTR(hcb,id) ((hcb)->ts->dtr[id])
-#define INVALIDATE_HASH(hcb,hash) { \
- if ((hcb)->ht==THASH_TLB) \
- INVALID_TLB(hash) = 1; \
- else \
- INVALID_VHPT(hash) = 1; \
- hash->next = NULL; }
-
+#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)) )
@@ -242,18 +287,20 @@
* NOTES:
* 1: TLB entry may be TR, TC or Foreign Map. For TR entry,
* itr[]/dtr[] need to be updated too.
- * 2: Inserting to collision chain may trigger recycling if
+ * 2: Inserting to collision chain may trigger recycling if
* the buffer for collision chain is empty.
* 3: The new entry is inserted at the hash table.
* (I.e. head of the collision chain)
* 4: Return the entry in hash table or collision chain.
*
*/
-extern void thash_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va);
+extern void thash_vhpt_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va);
+//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);
-
-/*
- * Force to delete a found entry no matter TR or foreign map for TLB.
+extern thash_data_t *vtr_find_overlap(thash_cb_t *hcb, thash_data_t *data,
char cl);
+extern u64 get_mfn(struct domain *d, u64 gpfn);
+/*
+ * Force to delete a found entry no matter TR or foreign map for TLB.
* NOTES:
* 1: TLB entry may be TR, TC or Foreign Map. For TR entry,
* itr[]/dtr[] need to be updated too.
@@ -307,7 +354,7 @@
u64 rid, u64 va, u64 sz,
search_section_t p_sect,
CACHE_LINE_TYPE cl);
-extern void thash_purge_and_insert(thash_cb_t *hcb, thash_data_t *in);
+extern void thash_purge_and_insert(thash_cb_t *hcb, thash_data_t *in, u64 va);
/*
* Purge all TCs or VHPT entries including those in Hash table.
@@ -335,8 +382,10 @@
extern void machine_tlb_insert(struct vcpu *d, thash_data_t *tlb);
extern ia64_rr vmmu_get_rr(struct vcpu *vcpu, u64 va);
extern thash_cb_t *init_domain_tlb(struct vcpu *d);
-
-#define VTLB_DEBUG
+extern thash_data_t * vsa_thash(PTA vpta, u64 va, u64 vrr, u64 *tag);
+extern thash_data_t * vhpt_lookup(u64 va);
+
+//#define VTLB_DEBUG
#ifdef VTLB_DEBUG
extern void check_vtlb_sanity(thash_cb_t *vtlb);
extern void dump_vtlb(thash_cb_t *vtlb);
diff -r e58ff5fd3550 -r cfe20f41f043 xen/include/asm-ia64/vmx_mm_def.h
--- a/xen/include/asm-ia64/vmx_mm_def.h Tue Feb 28 20:18:08 2006
+++ b/xen/include/asm-ia64/vmx_mm_def.h Wed Mar 1 15:29:00 2006
@@ -34,7 +34,7 @@
#define POFFSET(vaddr, ps) ((vaddr) & (PSIZE(ps) - 1))
#define PPN_2_PA(ppn) ((ppn)<<12)
#define CLEARLSB(ppn, nbits) ((((uint64_t)ppn) >> (nbits)) << (nbits))
-#define PAGEALIGN(va, ps) (va & ~(PSIZE(ps)-1))
+#define PAGEALIGN(va, ps) CLEARLSB(va, ps)
#define TLB_AR_R 0
#define TLB_AR_RX 1
@@ -104,6 +104,7 @@
#define VRN_MASK 0xe000000000000000L
#define PTA_BASE_MASK 0x3fffffffffffL
+#define PTA_BASE_SHIFT 15
#define VHPT_OFFSET_MASK 0x7fff
#define BITS_SHIFT_256MB 28
diff -r e58ff5fd3550 -r cfe20f41f043 xen/include/asm-ia64/vmx_platform.h
--- a/xen/include/asm-ia64/vmx_platform.h Tue Feb 28 20:18:08 2006
+++ b/xen/include/asm-ia64/vmx_platform.h Wed Mar 1 15:29:00 2006
@@ -54,7 +54,7 @@
#define VCPU(_v,_x) _v->arch.privregs->_x
#define VLAPIC_ID(l) (uint16_t)(VCPU((l)->vcpu, lid) >> 16)
#define VLAPIC_IRR(l) VCPU((l)->vcpu, irr[0])
-
+struct vlapic* apic_round_robin(struct domain *d, uint8_t dest_mode, uint8_t
vector, uint32_t bitmap);
extern int vmx_vcpu_pend_interrupt(struct vcpu *vcpu, uint8_t vector);
static inline int vlapic_set_irq(struct vlapic *t, uint8_t vec, uint8_t trig)
{
diff -r e58ff5fd3550 -r cfe20f41f043 xen/include/asm-ia64/vmx_vcpu.h
--- a/xen/include/asm-ia64/vmx_vcpu.h Tue Feb 28 20:18:08 2006
+++ b/xen/include/asm-ia64/vmx_vcpu.h Wed Mar 1 15:29:00 2006
@@ -464,6 +464,7 @@
rr.rrval=val;
rr.rid = rr.rid + v->arch.starting_rid;
+ rr.ps = PAGE_SHIFT;
rr.ve = 1;
return vmMangleRID(rr.rrval);
/* Disable this rid allocation algorithm for now */
diff -r e58ff5fd3550 -r cfe20f41f043 xen/include/asm-ia64/xenkregs.h
--- a/xen/include/asm-ia64/xenkregs.h Tue Feb 28 20:18:08 2006
+++ b/xen/include/asm-ia64/xenkregs.h Wed Mar 1 15:29:00 2006
@@ -8,7 +8,8 @@
#define IA64_TR_VHPT 4 /* dtr4: vhpt */
#define IA64_TR_ARCH_INFO 5
#define IA64_TR_PERVP_VHPT 6
-
+#define IA64_DTR_GUEST_KERNEL 7
+#define IA64_ITR_GUEST_KERNEL 2
/* Processor status register bits: */
#define IA64_PSR_VM_BIT 46
#define IA64_PSR_VM (__IA64_UL(1) << IA64_PSR_VM_BIT)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|