WARNING - OLD ARCHIVES

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

xen-changelog

[Xen-changelog] Fix itir bugs in vcpu_transalte and do some cleanup

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Fix itir bugs in vcpu_transalte and do some cleanup
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 29 Oct 2005 09:58:09 +0000
Delivery-date: Sat, 29 Oct 2005 09:56:06 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User djm@xxxxxxxxxxxxxxx
# Node ID 70de2b71f43923f7fc2698956204cf475e5950be
# Parent  c03dc328bf3a5fcb5a8ab33f957ac3cd47ec2861
Fix itir bugs in vcpu_transalte and do some cleanup
to avoid a gazillion unnecessary function calls.
Signed-off-by: Dan Magenheimer <dan.magenheimer@xxxxxx>

diff -r c03dc328bf3a -r 70de2b71f439 xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c  Thu Oct 13 22:02:35 2005
+++ b/xen/arch/ia64/xen/vcpu.c  Fri Oct 14 17:56:18 2005
@@ -66,8 +66,16 @@
 unsigned long vcpu_verbose = 0;
 #define verbose(a...) do {if (vcpu_verbose) printf(a);} while(0)
 
-extern TR_ENTRY *match_tr(VCPU *vcpu, unsigned long ifa);
-extern TR_ENTRY *match_dtlb(VCPU *vcpu, unsigned long ifa);
+//#define vcpu_quick_region_check(_tr_regions,_ifa)    1
+#define vcpu_quick_region_check(_tr_regions,_ifa)                      \
+       (_tr_regions & (1 << ((unsigned long)_ifa >> 61)))
+#define vcpu_quick_region_set(_tr_regions,_ifa)                                
\
+       do {_tr_regions |= (1 << ((unsigned long)_ifa >> 61)); } while (0)
+
+// FIXME: also need to check && (!trp->key || vcpu_pkr_match(trp->key))
+#define vcpu_match_tr_entry(_trp,_ifa,_rid)                            \
+       ((_trp->p && (_trp->rid==_rid) && (_ifa >= _trp->vadr) &&       \
+       (_ifa < (_trp->vadr + (1L<< _trp->ps)) - 1)))
 
 /**************************************************************************
  VCPU general register access routines
@@ -620,7 +628,7 @@
                return;
        }
     if ( VMX_DOMAIN(vcpu) ) {
-           set_bit(vector,VCPU(vcpu,irr));
+           set_bit(vector,VCPU(vcpu,irr));
     } else
     {
        /* if (!test_bit(vector,PSCB(vcpu,delivery_mask))) return; */
@@ -630,16 +638,6 @@
        set_bit(vector,PSCBX(vcpu,irr));
        PSCB(vcpu,pending_interruption) = 1;
     }
-
-#if 0
-    /* Keir: I think you should unblock when an interrupt is pending. */
-    {
-        int running = test_bit(_VCPUF_running, &vcpu->vcpu_flags);
-        vcpu_unblock(vcpu);
-        if ( running )
-            smp_send_event_check_cpu(vcpu->processor);
-    }
-#endif
 }
 
 void early_tick(VCPU *vcpu)
@@ -710,14 +708,6 @@
        }
 
 //printf("returned to caller\n");
-#if 0
-if (vector == (PSCB(vcpu,itv) & 0xff)) {
-       UINT64 now = ia64_get_itc();
-       UINT64 itm = PSCBX(vcpu,domain_itm);
-       if (now < itm) early_tick(vcpu);
-
-}
-#endif
        return vector;
 }
 
@@ -1070,23 +1060,6 @@
        /* gloss over the wraparound problem for now... we know it exists
         * but it doesn't matter right now */
 
-#if 0
-       /* ensure at least next SP tick is in the future */
-       if (!interval) PSCBX(vcpu,xen_itm) = now +
-#if 0
-               (running_on_sim() ? SIM_DEFAULT_CLOCK_RATE :
-                                       DEFAULT_CLOCK_RATE);
-#else
-       3000000;
-//printf("vcpu_set_next_timer: HACK!\n");
-#endif
-#if 0
-       if (PSCBX(vcpu,xen_itm) < now)
-               while (PSCBX(vcpu,xen_itm) < now + (interval>>1))
-                       PSCBX(vcpu,xen_itm) += interval;
-#endif
-#endif
-
        if (is_idle_task(vcpu->domain)) {
 //             printf("****** vcpu_set_next_timer called during idle!!\n");
                vcpu_safe_set_itm(s);
@@ -1177,14 +1150,6 @@
                // don't deliver another
                return;
        }
-#if 0
-       // attempt to flag "timer tick before its due" source
-       {
-       UINT64 itm = PSCBX(vcpu,domain_itm);
-       UINT64 now = ia64_get_itc();
-       if (now < itm) printf("******* vcpu_pend_timer: pending before due!\n");
-       }
-#endif
        vcpu_pend_interrupt(vcpu, itv);
 }
 
@@ -1198,33 +1163,6 @@
        if (!itm) return 0;
        return (vcpu_deliverable_timer(vcpu) && (now < itm));
 }
-
-//FIXME: This is a hack because everything dies if a timer tick is lost
-void vcpu_poke_timer(VCPU *vcpu)
-{
-       UINT64 itv = PSCB(vcpu,itv) & 0xff;
-       UINT64 now = ia64_get_itc();
-       UINT64 itm = PSCBX(vcpu,domain_itm);
-       UINT64 irr;
-
-       if (vcpu_timer_disabled(vcpu)) return;
-       if (!itm) return;
-       if (itv != 0xefL) {
-               printf("vcpu_poke_timer: unimplemented itv=%lx!\n",itv);
-               while(1);
-       }
-       // using 0xef instead of itv so can get real irr
-       if (now > itm && !test_bit(0xefL, PSCBX(vcpu,insvc))) {
-               if (!test_bit(0xefL,PSCBX(vcpu,irr))) {
-                       irr = ia64_getreg(_IA64_REG_CR_IRR3);
-                       if (irr & (1L<<(0xef-0xc0))) return;
-if (now-itm>0x800000)
-printf("*** poking timer: 
now=%lx,vitm=%lx,xitm=%lx,itm=%lx\n",now,itm,local_cpu_data->itm_next,ia64_get_itm());
-                       vcpu_pend_timer(vcpu);
-               }
-       }
-}
-
 
 /**************************************************************************
 Privileged operation emulation routines
@@ -1318,13 +1256,6 @@
        UINT64 VHPT_addr = VHPT_addr1 | ((VHPT_addr2a | VHPT_addr2b) << 15) |
                        VHPT_addr3;
 
-#if 0
-       if (VHPT_addr1 == 0xe000000000000000L) {
-           printf("vcpu_thash: thash unsupported with rr7 @%lx\n",
-               PSCB(vcpu,iip));
-           return (IA64_ILLOP_FAULT);
-       }
-#endif
 //verbose("vcpu_thash: vadr=%p, VHPT_addr=%p\n",vadr,VHPT_addr);
        *pval = VHPT_addr;
        return (IA64_NO_FAULT);
@@ -1343,8 +1274,10 @@
 
 IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 
*pteval, UINT64 *itir, UINT64 *iha)
 {
-       unsigned long pta, pta_mask, pte, ps;
+       unsigned long pta, pta_mask, pte, ps, rid, itir_addr;
+       int i;
        TR_ENTRY *trp;
+       IA64FAULT fault;
        ia64_rr rr;
 
        if (!(address >> 61)) {
@@ -1362,68 +1295,83 @@
                phys_translate_count++;
                return IA64_NO_FAULT;
        }
-
-       /* check translation registers */
-       if ((trp = match_tr(vcpu,address))) {
-                       tr_translate_count++;
-               *pteval = trp->page_flags;
-               *itir = trp->itir;
-               return IA64_NO_FAULT;
+       rid = virtualize_rid(vcpu,get_rr(address) & RR_RID_MASK);
+       if (is_data) {
+               if (vcpu_quick_region_check(vcpu->arch.dtr_regions,address)) {
+                       for (trp = vcpu->arch.dtrs, i = NDTRS; i; i--, trp++) {
+                               if (vcpu_match_tr_entry(trp,address,rid)) {
+                                       *pteval = trp->page_flags;
+                                       *itir = trp->itir;
+                                       tr_translate_count++;
+                                       return IA64_NO_FAULT;
+                               }
+                       }
+               }
+       }
+       // FIXME?: check itr's for data accesses too, else bad things happen?
+       /* else */ {
+               if (vcpu_quick_region_check(vcpu->arch.itr_regions,address)) {
+                       for (trp = vcpu->arch.itrs, i = NITRS; i; i--, trp++) {
+                               if (vcpu_match_tr_entry(trp,address,rid)) {
+                                       *pteval = trp->page_flags;
+                                       *itir = trp->itir;
+                                       tr_translate_count++;
+                                       return IA64_NO_FAULT;
+                               }
+                       }
+               }
        }
 
        /* check 1-entry TLB */
-       if ((trp = match_dtlb(vcpu,address))) {
-               dtlb_translate_count++;
+       // FIXME?: check dtlb for inst accesses too, else bad things happen?
+       trp = &vcpu->arch.dtlb;
+       if (/* is_data && */ vcpu_match_tr_entry(trp,address,rid)) {
                if (vcpu->domain==dom0 && !in_tpa) *pteval = trp->page_flags;
                else *pteval = vcpu->arch.dtlb_pte;
-//             printf("DTLB MATCH... NEW, DOM%s, %s\n", vcpu->domain==dom0?
-//                     "0":"U", in_tpa?"vcpu_tpa":"ia64_do_page_fault");
                *itir = trp->itir;
+               dtlb_translate_count++;
                return IA64_NO_FAULT;
        }
 
        /* check guest VHPT */
        pta = PSCB(vcpu,pta);
-       rr.rrval = PSCB(vcpu,rrs)[address>>61];
-       if (!rr.ve || !(pta & IA64_PTA_VE)) {
-// FIXME? does iha get set for alt faults? does xenlinux depend on it?
-               vcpu_thash(vcpu, address, iha);
-// FIXME?: does itir get set for alt faults?
-               *itir = vcpu_get_itir_on_fault(vcpu,address);
-               return (is_data ? IA64_ALT_DATA_TLB_VECTOR :
-                               IA64_ALT_INST_TLB_VECTOR);
-       }
        if (pta & IA64_PTA_VF) { /* long format VHPT - not implemented */
-               // thash won't work right?
                panic_domain(vcpu_regs(vcpu),"can't do long format VHPT\n");
                //return (is_data ? IA64_DATA_TLB_VECTOR:IA64_INST_TLB_VECTOR);
        }
 
+       vcpu_thash(vcpu, address, iha);
+       rr.rrval = PSCB(vcpu,rrs)[address>>61];
+       fault = is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR;
+       if (!rr.ve || !(pta & IA64_PTA_VE)) {
+       // architecturally, iha is optionally set for alt faults but xenlinux
+       // depends on it so should document it as part of PV interface
+               fault += IA64_ALT_INST_TLB_VECTOR - IA64_INST_TLB_VECTOR;
+       }
+
        /* avoid recursively walking (short format) VHPT */
-       pta_mask = (itir_mask(pta) << 3) >> 3;
-       if (((address ^ pta) & pta_mask) == 0)
-               return (is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR);
-
-       vcpu_thash(vcpu, address, iha);
-       if (__copy_from_user(&pte, (void *)(*iha), sizeof(pte)) != 0) {
-// FIXME?: does itir get set for vhpt faults?
-               *itir = vcpu_get_itir_on_fault(vcpu,*iha);
-               return IA64_VHPT_FAULT;
-       }
-
-       /*
-        * Optimisation: this VHPT walker aborts on not-present pages
-        * instead of inserting a not-present translation, this allows
-        * vectoring directly to the miss handler.
-        */
-       if (pte & _PAGE_P) {
-               *pteval = pte;
-               *itir = vcpu_get_itir_on_fault(vcpu,address);
-               vhpt_translate_count++;
-               return IA64_NO_FAULT;
-       }
-       *itir = vcpu_get_itir_on_fault(vcpu,address);
-       return (is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR);
+       else if (((address ^ pta) & ((itir_mask(pta) << 3) >> 3)) != 0) {
+
+               if (__copy_from_user(&pte, (void *)(*iha), sizeof(pte)) != 0)
+                       // virtual VHPT walker "missed" in TLB
+                       fault = IA64_VHPT_FAULT;
+
+               /*
+               * Optimisation: this VHPT walker aborts on not-present pages
+               * instead of inserting a not-present translation, this allows
+               * vectoring directly to the miss handler.
+               */
+               else if (pte & _PAGE_P) {
+                       *pteval = pte;
+                       vhpt_translate_count++;
+                       return IA64_NO_FAULT;
+               }
+       }
+
+       // for VHPT fault, use itir based on iha, not on fault address
+       itir_addr = (fault == IA64_VHPT_FAULT) ? *iha : address;
+       *itir = vcpu_get_itir_on_fault(vcpu,itir_addr);
+       return fault;
 }
 
 IA64FAULT vcpu_tpa(VCPU *vcpu, UINT64 vadr, UINT64 *padr)
@@ -1738,33 +1686,6 @@
        }
 }
 
-TR_ENTRY *vcpu_match_tr_entry(VCPU *vcpu, TR_ENTRY *trp, UINT64 ifa, int count)
-{
-       unsigned long rid = (get_rr(ifa) & RR_RID_MASK);
-       int i;
-
-       for (i = 0; i < count; i++, trp++) {
-               if (!trp->p) continue;
-               if (physicalize_rid(vcpu,trp->rid) != rid) continue;
-               if (ifa < trp->vadr) continue;
-               if (ifa >= (trp->vadr + (1L << trp->ps)) - 1) continue;
-               //if (trp->key && !match_pkr(vcpu,trp->key)) continue;
-               return trp;
-       }
-       return 0;
-}
-
-TR_ENTRY *match_tr(VCPU *vcpu, unsigned long ifa)
-{
-       TR_ENTRY *trp;
-
-       trp = vcpu_match_tr_entry(vcpu,vcpu->arch.dtrs,ifa,NDTRS);
-       if (trp) return trp;
-       trp = vcpu_match_tr_entry(vcpu,vcpu->arch.itrs,ifa,NITRS);
-       if (trp) return trp;
-       return 0;
-}
-
 IA64FAULT vcpu_itr_d(VCPU *vcpu, UINT64 slot, UINT64 pte,
                UINT64 itir, UINT64 ifa)
 {
@@ -1774,6 +1695,7 @@
        trp = &PSCBX(vcpu,dtrs[slot]);
 //printf("***** itr.d: setting slot %d: ifa=%p\n",slot,ifa);
        vcpu_set_tr_entry(trp,pte,itir,ifa);
+       vcpu_quick_region_set(PSCBX(vcpu,dtr_regions),ifa);
        return IA64_NO_FAULT;
 }
 
@@ -1786,6 +1708,7 @@
        trp = &PSCBX(vcpu,itrs[slot]);
 //printf("***** itr.i: setting slot %d: ifa=%p\n",slot,ifa);
        vcpu_set_tr_entry(trp,pte,itir,ifa);
+       vcpu_quick_region_set(PSCBX(vcpu,itr_regions),ifa);
        return IA64_NO_FAULT;
 }
 
@@ -1837,17 +1760,6 @@
        }
 }
 
-// NOTE: returns a physical pte, NOT a "metaphysical" pte, so do not check
-// the physical address contained for correctness
-TR_ENTRY *match_dtlb(VCPU *vcpu, unsigned long ifa)
-{
-       TR_ENTRY *trp;
-
-       if (trp = vcpu_match_tr_entry(vcpu,&vcpu->arch.dtlb,ifa,1))
-               return (&vcpu->arch.dtlb);
-       return 0UL;
-}
-
 IA64FAULT vcpu_itc_d(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa)
 {
        unsigned long pteval, logps = (itir >> 2) & 0x3f;
@@ -1954,12 +1866,14 @@
 IA64FAULT vcpu_ptr_d(VCPU *vcpu,UINT64 vadr,UINT64 addr_range)
 {
        printf("vcpu_ptr_d: Purging TLB is unsupported\n");
+       // don't forget to recompute dtr_regions
        return (IA64_ILLOP_FAULT);
 }
 
 IA64FAULT vcpu_ptr_i(VCPU *vcpu,UINT64 vadr,UINT64 addr_range)
 {
        printf("vcpu_ptr_i: Purging TLB is unsupported\n");
+       // don't forget to recompute itr_regions
        return (IA64_ILLOP_FAULT);
 }
 
diff -r c03dc328bf3a -r 70de2b71f439 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h     Thu Oct 13 22:02:35 2005
+++ b/xen/include/asm-ia64/domain.h     Fri Oct 14 17:56:18 2005
@@ -49,6 +49,8 @@
        TR_ENTRY dtrs[NDTRS];
        TR_ENTRY itlb;
        TR_ENTRY dtlb;
+       unsigned int itr_regions;
+       unsigned int dtr_regions;
        unsigned long itlb_pte;
        unsigned long dtlb_pte;
        unsigned long irr[4];

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Fix itir bugs in vcpu_transalte and do some cleanup, Xen patchbot -unstable <=