[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] IA64: improve handle_fpu_swa()



# HG changeset patch
# User Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1228891186 -32400
# Node ID e239a47180fb97e8c907cead1f6acec72cee0322
# Parent  dd7ac569579a971f1501798f58aa3a25fdc295bb
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 <yamahata@xxxxxxxxxxxxx>
---
 xen/arch/ia64/xen/faults.c |   28 +++++++++++++++++-----------
 xen/arch/ia64/xen/vcpu.c   |   41 +++++++++++++++++++++++------------------
 2 files changed, 40 insertions(+), 29 deletions(-)

diff -r dd7ac569579a -r e239a47180fb xen/arch/ia64/xen/faults.c
--- a/xen/arch/ia64/xen/faults.c        Wed Dec 10 15:39:44 2008 +0900
+++ b/xen/arch/ia64/xen/faults.c        Wed Dec 10 15:39:46 2008 +0900
@@ -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)
-                       return;
+               if (IA64_RETRY == status) {
+                       vcpu_decrement_iip(v);
+                       return;
+               }
                printk("ia64_handle_reflection: handling FP trap\n");
                vector = IA64_FP_TRAP_VECTOR;
                break;
diff -r dd7ac569579a -r e239a47180fb xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c  Wed Dec 10 15:39:44 2008 +0900
+++ b/xen/arch/ia64/xen/vcpu.c  Wed Dec 10 15:39:46 2008 +0900
@@ -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-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.