IA64: improve handle_fpu_swa()

It tries to get a bundle in guest.
Make it more robust using vmx_get_domain_bundle() instead of
__get_domain_bundle().

Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]>

diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c
--- a/xen/arch/ia64/xen/faults.c
+++ b/xen/arch/ia64/xen/faults.c
@@ -318,6 +318,7 @@ handle_fpu_swa(int fp_fault, struct pt_r
        IA64_BUNDLE bundle;
        unsigned long fault_ip;
        fpswa_ret_t ret;
+       unsigned long rc;
 
        fault_ip = regs->cr_iip;
        /*
@@ -329,15 +330,18 @@ handle_fpu_swa(int fp_fault, struct pt_r
                fault_ip -= 16;
 
        if (VMX_DOMAIN(current)) {
-               if (IA64_RETRY == __vmx_get_domain_bundle(fault_ip, &bundle))
-                       return IA64_RETRY;
-       } else
-               bundle = __get_domain_bundle(fault_ip);
-
-       if (!bundle.i64[0] && !bundle.i64[1]) {
-               printk("%s: floating-point bundle at 0x%lx not mapped\n",
-                      __FUNCTION__, fault_ip);
-               return -1;
+               rc = __vmx_get_domain_bundle(fault_ip, &bundle);
+       } else {
+               rc = 0;
+               if (vcpu_get_domain_bundle(current, regs, fault_ip,
+                                          &bundle) == 0)
+                       rc = IA64_RETRY;
+       }
+       if (rc == IA64_RETRY) {
+               gdprintk(XENLOG_DEBUG,
+                        "%s(%s): floating-point bundle at 0x%lx not mapped\n",
+                        __FUNCTION__, fp_fault ? "fault" : "trap", fault_ip);
+               return IA64_RETRY;
        }
 
        ret = fp_emulate(fp_fault, &bundle, &regs->cr_ipsr, &regs->ar_fpsr,
@@ -689,8 +693,10 @@ ia64_handle_reflection(unsigned long ifa
                if (!status)
                        return;
                // fetch code fail
-               if (IA64_RETRY == status)
+               if (IA64_RETRY == status) {
+                       vcpu_decrement_iip(v);
                        return;
+               }
                printk("ia64_handle_reflection: handling FP trap\n");
                vector = IA64_FP_TRAP_VECTOR;
                break;
diff --git a/xen/arch/ia64/xen/vcpu.c b/xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c
+++ b/xen/arch/ia64/xen/vcpu.c
@@ -1355,6 +1355,26 @@ vcpu_get_domain_bundle(VCPU * vcpu, REGS
                // copy its value to the variable, tr, before use.
                TR_ENTRY tr;
 
+               // fast path:
+               // try to access gip with guest virtual address directly.
+               // This may cause tlb miss. see vcpu_translate(). Be careful!
+               swap_rr0 = (!region && PSCB(vcpu, metaphysical_mode));
+               if (swap_rr0) {
+                       set_virtual_rr0();
+               }
+               *bundle = __get_domain_bundle(gip);
+               if (swap_rr0) {
+                       set_metaphysical_rr0();
+               }
+               
+               if (!bundle->i64[0] && !bundle->i64[1]) {
+                       dprintk(XENLOG_INFO, "%s gip 0x%lx\n", __func__, gip);
+               } else {
+                       // Okay, mDTC successed
+                       return 1;
+               }
+               // mDTC failed, so try vTLB.
+
                trp = vcpu_tr_lookup(vcpu, gip, rid, 0);
                if (trp != NULL) {
                        tr = *trp;
@@ -1374,28 +1394,13 @@ vcpu_get_domain_bundle(VCPU * vcpu, REGS
                        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_virtual_rr0();
-               }
-               *bundle = __get_domain_bundle(gip);
-               if (swap_rr0) {
-                       set_metaphysical_rr0();
-               }
-               if (bundle->i64[0] == 0 && bundle->i64[1] == 0) {
-                       dprintk(XENLOG_INFO, "%s gip 0x%lx\n", __func__, gip);
-                       return 0;
-               }
-               return 1;
+               // mDTC and vTLB failed. so reflect tlb miss into the guest.
+               return 0;
 
        found:
                gpip = ((tr.pte.ppn >> (tr.ps - 12)) << tr.ps) |
IA64: improve handle_fpu_swa()

It tries to get a bundle in guest.
Make it more robust using vmx_get_domain_bundle() instead of
__get_domain_bundle().

Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]>

diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c
--- a/xen/arch/ia64/xen/faults.c
+++ b/xen/arch/ia64/xen/faults.c
@@ -318,6 +318,7 @@ handle_fpu_swa(int fp_fault, struct pt_r
 	IA64_BUNDLE bundle;
 	unsigned long fault_ip;
 	fpswa_ret_t ret;
+	unsigned long rc;
 
 	fault_ip = regs->cr_iip;
 	/*
@@ -329,15 +330,18 @@ handle_fpu_swa(int fp_fault, struct pt_r
 		fault_ip -= 16;
 
 	if (VMX_DOMAIN(current)) {
-		if (IA64_RETRY == __vmx_get_domain_bundle(fault_ip, &bundle))
-			return IA64_RETRY;
-	} else
-		bundle = __get_domain_bundle(fault_ip);
-
-	if (!bundle.i64[0] && !bundle.i64[1]) {
-		printk("%s: floating-point bundle at 0x%lx not mapped\n",
-		       __FUNCTION__, fault_ip);
-		return -1;
+		rc = __vmx_get_domain_bundle(fault_ip, &bundle);
+	} else {
+		rc = 0;
+		if (vcpu_get_domain_bundle(current, regs, fault_ip,
+					   &bundle) == 0)
+			rc = IA64_RETRY;
+	}
+	if (rc == IA64_RETRY) {
+		gdprintk(XENLOG_DEBUG,
+			 "%s(%s): floating-point bundle at 0x%lx not mapped\n",
+			 __FUNCTION__, fp_fault ? "fault" : "trap", fault_ip);
+		return IA64_RETRY;
 	}
 
 	ret = fp_emulate(fp_fault, &bundle, &regs->cr_ipsr, &regs->ar_fpsr,
@@ -689,8 +693,10 @@ ia64_handle_reflection(unsigned long ifa
 		if (!status)
 			return;
 		// fetch code fail
-		if (IA64_RETRY == status)
+		if (IA64_RETRY == status) {
+			vcpu_decrement_iip(v);
 			return;
+		}
 		printk("ia64_handle_reflection: handling FP trap\n");
 		vector = IA64_FP_TRAP_VECTOR;
 		break;
diff --git a/xen/arch/ia64/xen/vcpu.c b/xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c
+++ b/xen/arch/ia64/xen/vcpu.c
@@ -1355,6 +1355,26 @@ vcpu_get_domain_bundle(VCPU * vcpu, REGS
 		// copy its value to the variable, tr, before use.
 		TR_ENTRY tr;
 
+		// fast path:
+		// try to access gip with guest virtual address directly.
+		// This may cause tlb miss. see vcpu_translate(). Be careful!
+		swap_rr0 = (!region && PSCB(vcpu, metaphysical_mode));
+		if (swap_rr0) {
+			set_virtual_rr0();
+		}
+		*bundle = __get_domain_bundle(gip);
+		if (swap_rr0) {
+			set_metaphysical_rr0();
+		}
+		
+		if (!bundle->i64[0] && !bundle->i64[1]) {
+			dprintk(XENLOG_INFO, "%s gip 0x%lx\n", __func__, gip);
+		} else {
+			// Okay, mDTC successed
+			return 1;
+		}
+		// mDTC failed, so try vTLB.
+
 		trp = vcpu_tr_lookup(vcpu, gip, rid, 0);
 		if (trp != NULL) {
 			tr = *trp;
@@ -1374,28 +1394,13 @@ vcpu_get_domain_bundle(VCPU * vcpu, REGS
 			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_virtual_rr0();
-		}
-		*bundle = __get_domain_bundle(gip);
-		if (swap_rr0) {
-			set_metaphysical_rr0();
-		}
-		if (bundle->i64[0] == 0 && bundle->i64[1] == 0) {
-			dprintk(XENLOG_INFO, "%s gip 0x%lx\n", __func__, gip);
-			return 0;
-		}
-		return 1;
+		// mDTC and vTLB failed. so reflect tlb miss into the guest.
+		return 0;
 
 	found:
 		gpip = ((tr.pte.ppn >> (tr.ps - 12)) << tr.ps) |
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel

Reply via email to