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-ia64-devel

Re: [Xen-ia64-devel] Some things to be considered for ptc.ga emulation

To: "Tian, Kevin" <kevin.tian@xxxxxxxxx>, <xen-ia64-devel@xxxxxxxxxxxxxxxxxxx>
Subject: Re: [Xen-ia64-devel] Some things to be considered for ptc.ga emulation
From: Tristan Gingold <Tristan.Gingold@xxxxxxxx>
Date: Thu, 6 Apr 2006 08:27:52 +0100
Delivery-date: Thu, 06 Apr 2006 00:24:09 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <571ACEFD467F7749BC50E0A98C17CDD8094E7A8F@pdsmsx403>
List-help: <mailto:xen-ia64-devel-request@lists.xensource.com?subject=help>
List-id: Discussion of the ia64 port of Xen <xen-ia64-devel.lists.xensource.com>
List-post: <mailto:xen-ia64-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=unsubscribe>
References: <571ACEFD467F7749BC50E0A98C17CDD8094E7A8F@pdsmsx403>
Sender: xen-ia64-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: KMail/1.5
Le Jeudi 06 Avril 2006 03:12, Tian, Kevin a écrit :
> From: Tristan Gingold [mailto:Tristan.Gingold@xxxxxxxx]
>
> >Sent: 2006?4?5? 17:28
> >
> >> the lock
> >>                    * Only vcpu_translate stamps tlb_inuse count
> >> now.
> >> However all places with access needs same lock sense like tlb
> >
> >insertion
> >
> >> emulation.
> >
> >I am not sure about that.
> >If both are writing, we can have incomplete insertion (eg: only dtlb but
> > no vhpt nor itc), but it shouldn't matter.
>
> As we talked previously, the effect of purge may be override by another
> write if both writing without lock protection.
Sure but if we have an itc and ptc in progress at the same time, we don't know 
which one will success.

[...]
> >BTW, I am still working on direct purge.
>
> Sure. You can post again once ready and people can see whether it
> addresses concerns.
Here is comes.
I have tested it during this night: 5 segfaults for 98 linux compilation.  This 
is domU UP fault rate.
This doesn't mean it is error free :-(

Thank you for comments.
Tristan.

diff -r 65b3a99122e5 xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c  Tue Apr  4 03:57:29 2006
+++ b/xen/arch/ia64/vmx/vmmu.c  Thu Apr  6 05:08:57 2006
@@ -459,7 +459,7 @@
     va = PAGEALIGN(ifa, ps);
     index = vtr_find_overlap(vcpu, va, ps, DSIDE_TLB);
     if (index>=0) {
-        vcpu->arch.dtrs[index].p=0;
+        vcpu->arch.dtrs[index].pte.p=0;
         index = vtr_find_overlap(vcpu, va, ps, DSIDE_TLB);
     }
     hcb = vmx_vcpu_get_vtlb(vcpu);
@@ -476,7 +476,7 @@
     va = PAGEALIGN(ifa, ps);
     index = vtr_find_overlap(vcpu, va, ps, ISIDE_TLB);
     if (index>=0) {
-        vcpu->arch.itrs[index].p=0;
+        vcpu->arch.itrs[index].pte.p=0;
         index = vtr_find_overlap(vcpu, va, ps, ISIDE_TLB);
     }
     hcb = vmx_vcpu_get_vtlb(vcpu);
diff -r 65b3a99122e5 xen/arch/ia64/xen/process.c
--- a/xen/arch/ia64/xen/process.c       Tue Apr  4 03:57:29 2006
+++ b/xen/arch/ia64/xen/process.c       Thu Apr  6 05:08:57 2006
@@ -290,12 +290,24 @@
                return;
        }
 
+ again:
        fault = vcpu_translate(current,address,is_data,0,&pteval,&itir,&iha);
-       if (fault == IA64_NO_FAULT) {
+       if (fault == IA64_NO_FAULT || fault == IA64_USE_TLB) {
                pteval = translate_domain_pte(pteval,address,itir);
                
vcpu_itc_no_srlz(current,is_data?2:1,address,pteval,-1UL,(itir>>2)&0x3f);
+               if (fault == IA64_USE_TLB && !current->arch.dtlb.pte.p) {
+                       /* dtlb has been purged in-between.  This dtlb was
+                          matching.  Undo the work.  */
+#ifdef VHPT_GLOBAL
+                       vhpt_flush_address (address, 1);
+#endif
+                       ia64_ptcl(address, 1<<2);
+                       ia64_srlz_i();
+                       goto again;
+               }
                return;
        }
+
        if (!user_mode (regs)) {
                /* The fault occurs inside Xen.  */
                if (!ia64_done_with_exception(regs)) {
diff -r 65b3a99122e5 xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c  Tue Apr  4 03:57:29 2006
+++ b/xen/arch/ia64/xen/vcpu.c  Thu Apr  6 05:08:57 2006
@@ -1274,17 +1274,23 @@
 int warn_region0_address = 0; // FIXME later: tie to a boot parameter?
 
 // FIXME: also need to check && (!trp->key || vcpu_pkr_match(trp->key))
-static inline int vcpu_match_tr_entry(TR_ENTRY *trp, UINT64 ifa, UINT64 rid)
-{
-       return trp->p && trp->rid == rid 
+static inline int vcpu_match_tr_entry_no_p(TR_ENTRY *trp, UINT64 ifa, UINT64 
rid)
+{
+       return trp->rid == rid 
                && ifa >= trp->vadr
                && ifa <= (trp->vadr + (1L << trp->ps) - 1);
 }
 
+static inline int vcpu_match_tr_entry(TR_ENTRY *trp, UINT64 ifa, UINT64 rid)
+{
+       return trp->pte.p && vcpu_match_tr_entry_no_p(trp, ifa, rid);
+}
+
 IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, BOOLEAN 
in_tpa, UINT64 *pteval, UINT64 *itir, UINT64 *iha)
 {
        unsigned long region = address >> 61;
-       unsigned long pta, pte, rid, rr;
+       unsigned long pta, rid, rr;
+       union pte_flags pte;
        int i;
        TR_ENTRY *trp;
 
@@ -1304,6 +1310,9 @@
                         */           
                        printk("vcpu_translate: bad physical address: 0x%lx\n",
                               address);
+                       printf(" cr_iip=%lx, iip=%lx\n",
+                              vcpu_regs(vcpu)->cr_iip, PSCB(vcpu,iip));
+                       show_stack(NULL,NULL);
                } else {
                        *pteval = (address & _PAGE_PPN_MASK) | __DIRTY_BITS |
                                  _PAGE_PL_2 | _PAGE_AR_RWX;
@@ -1328,7 +1337,7 @@
                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;
+                                       *pteval = trp->pte.val;
                                        *itir = trp->itir;
                                        tr_translate_count++;
                                        return IA64_NO_FAULT;
@@ -1341,7 +1350,7 @@
                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;
+                                       *pteval = trp->pte.val;
                                        *itir = trp->itir;
                                        tr_translate_count++;
                                        return IA64_NO_FAULT;
@@ -1353,12 +1362,14 @@
        /* check 1-entry TLB */
        // 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;
+       pte = trp->pte;
+       if (/* is_data && */ pte.p
+           && vcpu_match_tr_entry_no_p(trp,address,rid)) {
+               if (vcpu->domain==dom0 && !in_tpa) *pteval = pte.val;
                else *pteval = vcpu->arch.dtlb_pte;
                *itir = trp->itir;
                dtlb_translate_count++;
-               return IA64_NO_FAULT;
+               return IA64_USE_TLB;
        }
 
        /* check guest VHPT */
@@ -1379,7 +1390,8 @@
        if (((address ^ pta) & ((itir_mask(pta) << 3) >> 3)) == 0)
                return (is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR);
 
-       if (__copy_from_user(&pte, (void *)(*iha), sizeof(pte)) != 0)
+       if (!__access_ok (*iha)
+           || __copy_from_user(&pte, (void *)(*iha), sizeof(pte)) != 0)
                // virtual VHPT walker "missed" in TLB
                return IA64_VHPT_FAULT;
 
@@ -1388,12 +1400,12 @@
        * instead of inserting a not-present translation, this allows
        * vectoring directly to the miss handler.
        */
-       if (!(pte & _PAGE_P))
+       if (!pte.p)
                return (is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR);
 
        /* found mapping in guest VHPT! */
        *itir = rr & RR_PS_MASK;
-       *pteval = pte;
+       *pteval = pte.val;
        vhpt_translate_count++;
        return IA64_NO_FAULT;
 }
@@ -1404,7 +1416,7 @@
        IA64FAULT fault;
 
        fault = vcpu_translate(vcpu, vadr, TRUE, TRUE, &pteval, &itir, &iha);
-       if (fault == IA64_NO_FAULT)
+       if (fault == IA64_NO_FAULT || fault == IA64_USE_TLB)
        {
                mask = itir_mask(itir);
                *padr = (pteval & _PAGE_PPN_MASK & mask) | (vadr & ~mask);
@@ -1691,24 +1703,27 @@
 
 static inline void vcpu_purge_tr_entry(TR_ENTRY *trp)
 {
-       trp->p = 0;
+       trp->pte.val = 0;
 }
 
 static void vcpu_set_tr_entry(TR_ENTRY *trp, UINT64 pte, UINT64 itir, UINT64 
ifa)
 {
        UINT64 ps;
+       union pte_flags new_pte;
 
        trp->itir = itir;
        trp->rid = VCPU(current,rrs[ifa>>61]) & RR_RID_MASK;
-       trp->p = 1;
        ps = trp->ps;
-       trp->page_flags = pte;
-       if (trp->pl < 2) trp->pl = 2;
+       new_pte.val = pte;
+       if (new_pte.pl < 2) new_pte.pl = 2;
        trp->vadr = ifa & ~0xfff;
        if (ps > 12) { // "ignore" relevant low-order bits
-               trp->ppn &= ~((1UL<<(ps-12))-1);
+               new_pte.ppn &= ~((1UL<<(ps-12))-1);
                trp->vadr &= ~((1UL<<ps)-1);
        }
+
+       /* Atomic write.  */
+       trp->pte.val = new_pte.val;
 }
 
 IA64FAULT vcpu_itr_d(VCPU *vcpu, UINT64 slot, UINT64 pte,
@@ -1718,7 +1733,8 @@
 
        if (slot >= NDTRS) return IA64_RSVDREG_FAULT;
        trp = &PSCBX(vcpu,dtrs[slot]);
-//printf("***** itr.d: setting slot %d: ifa=%p\n",slot,ifa);
+       /*printf("***** itr.d: setting slot %d: ifa=%lx pte=%lx,itir=%lx from 
%lx\n",
+         slot,ifa,pte, itir, vcpu_regs (vcpu)->cr_iip); */
        vcpu_set_tr_entry(trp,pte,itir,ifa);
        vcpu_quick_region_set(PSCBX(vcpu,dtr_regions),ifa);
        return IA64_NO_FAULT;
@@ -1873,19 +1889,6 @@
        return IA64_ILLOP_FAULT;
 }
 
-#if defined(CONFIG_XEN_SMP) && defined(VHPT_GLOBAL)
-struct ptc_ga_args {
-       unsigned long vadr;
-       unsigned long addr_range;
-};
-
-static void ptc_ga_remote_func (void *varg)
-{
-       struct ptc_ga_args *args = (struct ptc_ga_args *)varg;
-       vhpt_flush_address (args->vadr, args->addr_range);
-}
-#endif
-
 IA64FAULT vcpu_ptc_ga(VCPU *vcpu,UINT64 vadr,UINT64 addr_range)
 {
        // FIXME: validate not flushing Xen addresses
@@ -1896,32 +1899,20 @@
 #ifdef CONFIG_XEN_SMP
        struct domain *d = vcpu->domain;
        struct vcpu *v;
-       struct ptc_ga_args args;
-
-       args.vadr = vadr;
-       args.addr_range = addr_range;
-
-       /* This method is very conservative and should be optimized:
-          - maybe IPI calls can be avoided,
-          - a processor map can be built to avoid duplicate purge
-          - maybe ptc.ga can be replaced by ptc.l+invala.
-          Hopefully, it has no impact when UP.
-       */
+
        for_each_vcpu (d, v) {
-               if (v != vcpu) {
-                       /* Purge tc entry.
-                          Can we do this directly ?  Well, this is just a
-                          single atomic write.  */
-                       vcpu_purge_tr_entry(&PSCBX(v,dtlb));
-                       vcpu_purge_tr_entry(&PSCBX(v,itlb));
+               if (v == vcpu)
+                       continue;
+
+               /* Purge TC entries.
+                  FIXME: clear only if match.  */
+               vcpu_purge_tr_entry(&PSCBX(vcpu,dtlb));
+               vcpu_purge_tr_entry(&PSCBX(vcpu,itlb));
+
 #ifdef VHPT_GLOBAL
-                       /* Flush VHPT on remote processors.
-                          FIXME: invalidate directly the entries? */
-                       smp_call_function_single
-                               (v->processor, &ptc_ga_remote_func,
-                                &args, 0, 1);
-#endif
-               }
+               /* Invalidate VHPT entries.  */
+               vhpt_flush_address_remote (v->processor, vadr, addr_range);
+#endif
        }
 #endif
 
diff -r 65b3a99122e5 xen/arch/ia64/xen/vhpt.c
--- a/xen/arch/ia64/xen/vhpt.c  Tue Apr  4 03:57:29 2006
+++ b/xen/arch/ia64/xen/vhpt.c  Thu Apr  6 05:08:57 2006
@@ -71,6 +71,20 @@
 //printf("vhpt_flush_address: blowing away valid tag for vadr=%p\n",vadr);
 //}
                vlfe->ti_tag |= INVALID_TI_TAG;
+               addr_range -= PAGE_SIZE;
+               vadr += PAGE_SIZE;
+       }
+}
+
+void vhpt_flush_address_remote(int cpu,
+                              unsigned long vadr, unsigned long addr_range)
+{
+       while ((long)addr_range > 0) {
+               /* Get the VHPT entry.  */
+               unsigned int off = ia64_thash(vadr) - VHPT_ADDR;
+               volatile struct vhpt_lf_entry *v;
+               v =__va(per_cpu(vhpt_paddr, cpu) + off);
+               v->ti_tag = INVALID_TI_TAG;
                addr_range -= PAGE_SIZE;
                vadr += PAGE_SIZE;
        }
diff -r 65b3a99122e5 xen/arch/ia64/xen/xenirq.c
--- a/xen/arch/ia64/xen/xenirq.c        Tue Apr  4 03:57:29 2006
+++ b/xen/arch/ia64/xen/xenirq.c        Thu Apr  6 05:08:57 2006
@@ -70,6 +70,7 @@
  */
 void process_soft_irq(void)
 {
+       BUG_ON (in_interrupt());
        if (!in_interrupt() && local_softirq_pending()) {
                add_preempt_count(SOFTIRQ_OFFSET);
                do_softirq();
diff -r 65b3a99122e5 xen/include/asm-ia64/ia64_int.h
--- a/xen/include/asm-ia64/ia64_int.h   Tue Apr  4 03:57:29 2006
+++ b/xen/include/asm-ia64/ia64_int.h   Thu Apr  6 05:08:57 2006
@@ -38,6 +38,7 @@
 #define        IA64_RFI_IN_PROGRESS    0x0002
 #define IA64_RETRY              0x0003
 #define IA64_FORCED_IFA         0x0004
+#define IA64_USE_TLB           0x0005
 #define        IA64_ILLOP_FAULT        (IA64_GENEX_VECTOR | 0x00)
 #define        IA64_PRIVOP_FAULT       (IA64_GENEX_VECTOR | 0x10)
 #define        IA64_PRIVREG_FAULT      (IA64_GENEX_VECTOR | 0x20)
diff -r 65b3a99122e5 xen/include/asm-ia64/tlb.h
--- a/xen/include/asm-ia64/tlb.h        Tue Apr  4 03:57:29 2006
+++ b/xen/include/asm-ia64/tlb.h        Thu Apr  6 05:08:57 2006
@@ -4,23 +4,24 @@
 #define        NITRS   8
 #define NDTRS  8
 
+union pte_flags {
+    struct {
+       unsigned long p    :  1; // 0
+           unsigned long      :  1; // 1
+           unsigned long ma   :  3; // 2-4
+           unsigned long a    :  1; // 5
+           unsigned long d    :  1; // 6
+           unsigned long pl   :  2; // 7-8
+           unsigned long ar   :  3; // 9-11
+           unsigned long ppn  : 38; // 12-49
+           unsigned long      :  2; // 50-51
+           unsigned long ed   :  1; // 52
+    };
+    unsigned long val;
+};
+
 typedef struct {
-    union {
-        struct {
-            unsigned long p    :  1; // 0
-            unsigned long      :  1; // 1
-            unsigned long ma   :  3; // 2-4
-            unsigned long a    :  1; // 5
-            unsigned long d    :  1; // 6
-            unsigned long pl   :  2; // 7-8
-            unsigned long ar   :  3; // 9-11
-            unsigned long ppn  : 38; // 12-49
-            unsigned long      :  2; // 50-51
-            unsigned long ed   :  1; // 52
-        };
-        unsigned long page_flags;
-    };
-
+    volatile union pte_flags pte;
     union {
         struct {
             unsigned long      :  2; // 0-1
diff -r 65b3a99122e5 xen/include/asm-ia64/vhpt.h
--- a/xen/include/asm-ia64/vhpt.h       Tue Apr  4 03:57:29 2006
+++ b/xen/include/asm-ia64/vhpt.h       Thu Apr  6 05:08:57 2006
@@ -122,6 +122,8 @@
 extern void zero_vhpt_stats(void);
 extern int dump_vhpt_stats(char *buf);
 extern void vhpt_flush_address(unsigned long vadr, unsigned long addr_range);
+extern void vhpt_flush_address_remote(int cpu, unsigned long vadr,
+                                     unsigned long addr_range);
 extern void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte,
                                 unsigned long logps);
 extern void vhpt_insert (unsigned long vadr, unsigned long ptr,

Attachment: smpg-0406-1.diffs
Description: Text Data

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