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

[Xen-ia64-devel] [PATCH] fix ptc.ga emulation



cset14829(c42ae7839750) was incomplete.

The region register 0 will be clobbered as follows.

time    pcpu0   pcpu1   pcpu2
 |      vcpu0   vcpu1   idle  // assignment of vcpu
 V
        1.vcpu0 issues ptc.ga
        2.vcpu0 sends IPI to vcpu1(pcpu1)
                3.vcpu1 migrates from pcpu1 to pcpu2
                4.pcpu1 receives IPI of 2 and exec ptc_ga_remote_func()
                5.pcpu1 saves and modifies vrr[0]
                        6.vcpu1(pcpu2) modifies vrr[0]
                7.pcpu1 restores vrr[0]         // vrr[0] of 6 is lost

Windows will crash due to this issue.

-- Kouya   

Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>

diff -r 4ca4374eabd5 xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c  Fri May 11 13:15:53 2007 -0600
+++ b/xen/arch/ia64/vmx/vmmu.c  Mon May 14 12:04:04 2007 +0900
@@ -563,11 +563,17 @@ struct ptc_ga_args {
 
 static void ptc_ga_remote_func (void *varg)
 {
-    u64 oldrid, moldrid, mpta, oldpsbits, vadr;
+    u64 oldrid, moldrid, mpta, oldpsbits, vadr, flags;
     struct ptc_ga_args *args = (struct ptc_ga_args *)varg;
     VCPU *v = args->vcpu;
     vadr = args->vadr;
 
+    /* Try again if VCPU has migrated.  */
+    if (v->processor != current->processor)
+        return;
+    vcpu_schedule_lock_irqsave(v, flags);
+    if (v->processor != current->processor)
+        goto bail;
     oldrid = VMX(v, vrr[0]);
     VMX(v, vrr[0]) = args->rid;
     oldpsbits = VMX(v, psbits[0]);
@@ -584,6 +590,9 @@ static void ptc_ga_remote_func (void *va
     ia64_set_rr(0x0,moldrid);
     ia64_set_pta(mpta);
     ia64_dv_serialize_data();
+    args->vcpu = NULL;
+  bail:
+    vcpu_schedule_unlock_irqrestore(v, flags);
 }
 
 
@@ -602,28 +611,21 @@ IA64FAULT vmx_vcpu_ptc_ga(VCPU *vcpu, u6
         if (!v->is_initialised)
             continue;
 
+        if (v == vcpu) {
+            vmx_vcpu_ptc_l(v, va, ps);
+            continue;
+        }
+
         args.vcpu = v;
-again: /* Try again if VCPU has migrated.  */
-        proc = v->processor;
-        if (proc != vcpu->processor) {
-            /* Flush VHPT on remote processors.  */
-            smp_call_function_single(v->processor,
-                                     &ptc_ga_remote_func, &args, 0, 1);
-            if (proc != v->processor)
-                goto again;
-        } else if (v == vcpu) {
-            vmx_vcpu_ptc_l(v, va, ps);
-        } else {
-            vcpu_schedule_lock_irq(v);
+        do {
             proc = v->processor;
-            if (proc == vcpu->processor)
+            if (proc != vcpu->processor)
+                /* Flush VHPT on remote processors.  */
+                smp_call_function_single(proc,
+                                         &ptc_ga_remote_func, &args, 0, 1);
+            else
                 ptc_ga_remote_func(&args);
-            else
-                proc = INVALID_PROCESSOR;
-            vcpu_schedule_unlock_irq(v);
-            if (proc == INVALID_PROCESSOR)
-                goto again;
-        }
+        } while (args.vcpu != NULL);
     }
     return IA64_NO_FAULT;
 }
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel

 


Rackspace

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