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] [xen-unstable] [IA64] rewrite priv_handle_op()

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [IA64] rewrite priv_handle_op()
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 16 Jun 2006 18:40:21 +0000
Delivery-date: Fri, 16 Jun 2006 11:42:16 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
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 awilliam@xxxxxxxxxxx
# Node ID b8711fcb1e9563b6b5af9981bfd724e3efa99cee
# Parent  25483d9b55d4307d125f4135b609a6387f247ba8
[IA64] rewrite priv_handle_op()

introduce vcpu_get_domain_bundle() and replace __get_domain_handle call
in priv_handle_op with it.
priv_handle_op() uses __get_domain_handle to domain's bundle.
it directly access guest ip with guest virtual address which may results
in data tlb miss which cause some trobles.
This patch also cleans up vcpu_translate().

Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
---
 xen/arch/ia64/xen/privop.c  |   15 +---
 xen/arch/ia64/xen/vcpu.c    |  162 +++++++++++++++++++++++++++++++++++++-------
 xen/include/asm-ia64/vcpu.h |    3 
 3 files changed, 145 insertions(+), 35 deletions(-)

diff -r 25483d9b55d4 -r b8711fcb1e95 xen/arch/ia64/xen/privop.c
--- a/xen/arch/ia64/xen/privop.c        Wed May 31 16:07:47 2006 -0600
+++ b/xen/arch/ia64/xen/privop.c        Sat Jun 03 11:16:34 2006 -0600
@@ -615,16 +615,11 @@ priv_handle_op(VCPU *vcpu, REGS *regs, i
        int x6;
        
        // make a local copy of the bundle containing the privop
-#if 1
-       bundle = __get_domain_bundle(iip);
-       if (!bundle.i64[0] && !bundle.i64[1])
-#else
-       if (__copy_from_user(&bundle,iip,sizeof(bundle)))
-#endif
-       {
-//printf("*** priv_handle_op: privop bundle at 0x%lx not mapped, 
retrying\n",iip);
-               return vcpu_force_data_miss(vcpu,regs->cr_iip);
-       }
+       if (!vcpu_get_domain_bundle(vcpu, regs, iip, &bundle)) {
+               //return vcpu_force_data_miss(vcpu, regs->cr_iip);
+               return vcpu_force_inst_miss(vcpu, regs->cr_iip);
+       }
+
 #if 0
        if (iip==0xa000000100001820) {
                static int firstpagefault = 1;
diff -r 25483d9b55d4 -r b8711fcb1e95 xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c  Wed May 31 16:07:47 2006 -0600
+++ b/xen/arch/ia64/xen/vcpu.c  Sat Jun 03 11:16:34 2006 -0600
@@ -17,6 +17,7 @@
 #include <asm/vmx_vcpu.h>
 #include <asm/vhpt.h>
 #include <asm/tlbflush.h>
+#include <asm/privop.h>
 #include <xen/event.h>
 #include <asm/vmx_phy_mode.h>
 
@@ -29,6 +30,7 @@ extern void setfpreg (unsigned long regn
 
 extern void panic_domain(struct pt_regs *, const char *, ...);
 extern unsigned long translate_domain_mpaddr(unsigned long);
+extern IA64_BUNDLE __get_domain_bundle(UINT64);
 
 typedef        union {
        struct ia64_psr ia64_psr;
@@ -1184,14 +1186,25 @@ Privileged operation emulation routines
 Privileged operation emulation routines
 **************************************************************************/
 
+static void
+vcpu_force_tlb_miss(VCPU* vcpu, UINT64 ifa)
+{
+       PSCB(vcpu, ifa) = ifa;
+       PSCB(vcpu, itir) = vcpu_get_itir_on_fault(vcpu, ifa);
+       vcpu_thash(current, ifa, &PSCB(current, iha));
+}
+
+IA64FAULT vcpu_force_inst_miss(VCPU *vcpu, UINT64 ifa)
+{
+       vcpu_force_tlb_miss(vcpu, ifa);
+       return (vcpu_get_rr_ve(vcpu, ifa)? IA64_INST_TLB_VECTOR: 
IA64_ALT_INST_TLB_VECTOR);
+}
+
 IA64FAULT vcpu_force_data_miss(VCPU *vcpu, UINT64 ifa)
 {
-       PSCB(vcpu,ifa) = ifa;
-       PSCB(vcpu,itir) = vcpu_get_itir_on_fault(vcpu,ifa);
-       vcpu_thash(current, ifa, &PSCB(current,iha));
-       return (vcpu_get_rr_ve(vcpu,ifa) ? IA64_DATA_TLB_VECTOR : 
IA64_ALT_DATA_TLB_VECTOR);
-}
-
+       vcpu_force_tlb_miss(vcpu, ifa);
+       return (vcpu_get_rr_ve(vcpu, ifa)? IA64_DATA_TLB_VECTOR: 
IA64_ALT_DATA_TLB_VECTOR);
+}
 
 IA64FAULT vcpu_rfi(VCPU *vcpu)
 {
@@ -1303,12 +1316,117 @@ static inline int vcpu_match_tr_entry(TR
        return trp->pte.p && vcpu_match_tr_entry_no_p(trp, ifa, rid);
 }
 
+static TR_ENTRY*
+vcpu_tr_lookup(VCPU* vcpu, unsigned long va, UINT64 rid, BOOLEAN is_data)
+{
+       unsigned int* regions;
+       TR_ENTRY *trp;
+       int tr_max;
+       int i;
+
+       if (is_data) {
+               // data
+               regions = &vcpu->arch.dtr_regions;
+               trp = vcpu->arch.dtrs;
+               tr_max = sizeof(vcpu->arch.dtrs)/sizeof(vcpu->arch.dtrs[0]);
+       } else {
+               // instruction
+               regions = &vcpu->arch.itr_regions;
+               trp = vcpu->arch.itrs;
+               tr_max = sizeof(vcpu->arch.itrs)/sizeof(vcpu->arch.itrs[0]);
+       }
+
+       if (!vcpu_quick_region_check(*regions, va)) {
+               return NULL;
+       }
+       for (i = 0; i < tr_max; i++, trp++) {
+               if (vcpu_match_tr_entry(trp, va, rid)) {
+                       return trp;
+               }
+       }
+       return NULL;
+}
+
+// return value
+// 0: failure
+// 1: success
+int
+vcpu_get_domain_bundle(VCPU* vcpu, REGS* regs, UINT64 gip, IA64_BUNDLE* bundle)
+{
+       UINT64 gpip;// guest pseudo phyiscal ip
+
+#if 0
+       // Currently xen doesn't track psr.it bits.
+       // it assumes always psr.it = 1.
+       if (!(VCPU(vcpu, vpsr) & IA64_PSR_IT)) {
+               gpip = gip;
+       } else
+#endif
+       {
+               unsigned long region = REGION_NUMBER(gip);
+               unsigned long rr = PSCB(vcpu, rrs)[region];
+               unsigned long rid = rr & RR_RID_MASK;
+               BOOLEAN swap_rr0;
+               TR_ENTRY* trp;
+
+               // vcpu->arch.{i, d}tlb are volatile,
+               // copy its value to the variable, tr, before use.
+               TR_ENTRY tr;
+
+               trp = vcpu_tr_lookup(vcpu, gip, rid, 0);
+               if (trp != NULL) {
+                       tr = *trp;
+                       goto found;
+               }
+               // When it failed to get a bundle, itlb miss is reflected.
+               // Last itc.i value is cached to PSCBX(vcpu, itlb).
+               tr = PSCBX(vcpu, itlb);
+               if (vcpu_match_tr_entry(&tr, gip, rid)) {
+                       //DPRINTK("%s gip 0x%lx gpip 0x%lx\n", __func__, gip, 
gpip);
+                       goto found;
+               }
+               trp = vcpu_tr_lookup(vcpu, gip, rid, 1);
+               if (trp != NULL) {
+                       tr = *trp;
+                       goto found;
+               }
+#if 0
+               tr = PSCBX(vcpu, dtlb);
+               if (vcpu_match_tr_entry(&tr, gip, rid)) {
+                       goto found;
+               }
+#endif
+
+               // try to access gip with guest virtual address
+               // This may cause tlb miss. see vcpu_translate(). Be careful!
+               swap_rr0 = (!region && PSCB(vcpu, metaphysical_mode));
+               if (swap_rr0) {
+                       set_one_rr(0x0, PSCB(vcpu, rrs[0]));
+               }
+               *bundle = __get_domain_bundle(gip);
+               if (swap_rr0) {
+                       set_metaphysical_rr0();
+               }
+               if (bundle->i64[0] == 0 && bundle->i64[1] == 0) {
+                       DPRINTK("%s gip 0x%lx\n", __func__, gip);
+                       return 0;
+               }
+               return 1;
+        
+       found:
+               gpip = ((tr.pte.ppn >> (tr.ps - 12)) << tr.ps) |
+                       (gip & ((1 << tr.ps) - 1));
+       }
+
+       *bundle = *((IA64_BUNDLE*)__va(__gpa_to_mpa(vcpu->domain, gpip)));
+       return 1;
+}
+
 IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 
*pteval, UINT64 *itir, UINT64 *iha)
 {
        unsigned long region = address >> 61;
        unsigned long pta, rid, rr;
        union pte_flags pte;
-       int i;
        TR_ENTRY *trp;
 
        if (PSCB(vcpu,metaphysical_mode) && !(!is_data && region)) {
@@ -1349,28 +1467,22 @@ IA64FAULT vcpu_translate(VCPU *vcpu, UIN
        rr = PSCB(vcpu,rrs)[region];
        rid = rr & 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->pte.val;
-                                       *itir = trp->itir;
-                                       tr_translate_count++;
-                                       return IA64_NO_FAULT;
-                               }
-                       }
+               trp = vcpu_tr_lookup(vcpu, address, rid, 1);
+               if (trp != NULL) {
+                       *pteval = trp->pte.val;
+                       *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->pte.val;
-                                       *itir = trp->itir;
-                                       tr_translate_count++;
-                                       return IA64_NO_FAULT;
-                               }
-                       }
+               trp = vcpu_tr_lookup(vcpu, address, rid, 0);
+               if (trp != NULL) {
+                       *pteval = trp->pte.val;
+                       *itir = trp->itir;
+                       tr_translate_count++;
+                       return IA64_NO_FAULT;
                }
        }
 
diff -r 25483d9b55d4 -r b8711fcb1e95 xen/include/asm-ia64/vcpu.h
--- a/xen/include/asm-ia64/vcpu.h       Wed May 31 16:07:47 2006 -0600
+++ b/xen/include/asm-ia64/vcpu.h       Sat Jun 03 11:16:34 2006 -0600
@@ -151,9 +151,12 @@ extern IA64FAULT vcpu_ptc_ga(VCPU *vcpu,
 extern IA64FAULT vcpu_ptc_ga(VCPU *vcpu, UINT64 vadr, UINT64 addr_range);
 extern IA64FAULT vcpu_ptr_d(VCPU *vcpu,UINT64 vadr, UINT64 addr_range);
 extern IA64FAULT vcpu_ptr_i(VCPU *vcpu,UINT64 vadr, UINT64 addr_range);
+union U_IA64_BUNDLE;
+extern int vcpu_get_domain_bundle(VCPU *vcpu, REGS *regs, UINT64 gip, union 
U_IA64_BUNDLE *bundle);
 extern IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data,
                                UINT64 *pteval, UINT64 *itir, UINT64 *iha);
 extern IA64FAULT vcpu_tpa(VCPU *vcpu, UINT64 vadr, UINT64 *padr);
+extern IA64FAULT vcpu_force_inst_miss(VCPU *vcpu, UINT64 ifa);
 extern IA64FAULT vcpu_force_data_miss(VCPU *vcpu, UINT64 ifa);
 extern IA64FAULT vcpu_fc(VCPU *vcpu, UINT64 vadr);
 /* misc */

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [IA64] rewrite priv_handle_op(), Xen patchbot-unstable <=