]> xenbits.xensource.com Git - people/iwj/xen.git/commitdiff
x86/AMD: Stop counters on VPMU save
authorBoris Ostrovsky <boris.ostrovsky@oracle.com>
Mon, 15 Apr 2013 09:25:18 +0000 (11:25 +0200)
committerJan Beulich <jbeulich@suse.com>
Mon, 15 Apr 2013 09:25:18 +0000 (11:25 +0200)
Stop the counters during VPMU save operation since they shouldn't be
running when VPCU that controls them is not. This also makes it
unnecessary to check for overflow in context_restore()

Set LVTPC vector before loading the context during vpmu_restore().
Otherwise it is possible to trigger an interrupt without proper vector.

Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Reviewed-by: Dietmar Hahn <dietmar.hahn@ts.fujitsu.com>
xen/arch/x86/hvm/svm/vpmu.c

index 4be56524dbdff34bd0a7caa9e1c6b5a7bc5b0644..51e5495bc6615162abf2c60cafeee69c825c4cbd 100644 (file)
@@ -196,21 +196,10 @@ static inline void context_restore(struct vcpu *v)
     struct vpmu_struct *vpmu = vcpu_vpmu(v);
     struct amd_vpmu_context *ctxt = vpmu->context;
 
-    for ( i = 0; i < num_counters; i++ )
-        wrmsrl(ctrls[i], ctxt->ctrls[i]);
-
     for ( i = 0; i < num_counters; i++ )
     {
         wrmsrl(counters[i], ctxt->counters[i]);
-
-        /* Force an interrupt to allow guest reset the counter,
-        if the value is positive */
-        if ( is_overflowed(ctxt->counters[i]) && (ctxt->counters[i] > 0) )
-        {
-            gdprintk(XENLOG_WARNING, "VPMU: Force a performance counter "
-                "overflow interrupt!\n");
-            amd_vpmu_do_interrupt(0);
-        }
+        wrmsrl(ctrls[i], ctxt->ctrls[i]);
     }
 }
 
@@ -223,8 +212,8 @@ static void amd_vpmu_restore(struct vcpu *v)
            vpmu_is_set(vpmu, VPMU_RUNNING)) )
         return;
 
-    context_restore(v);
     apic_write(APIC_LVTPC, ctxt->hw_lapic_lvtpc);
+    context_restore(v);
 
     vpmu_set(vpmu, VPMU_CONTEXT_LOADED);
 }
@@ -236,10 +225,11 @@ static inline void context_save(struct vcpu *v)
     struct amd_vpmu_context *ctxt = vpmu->context;
 
     for ( i = 0; i < num_counters; i++ )
-        rdmsrl(counters[i], ctxt->counters[i]);
-
-    for ( i = 0; i < num_counters; i++ )
+    {
         rdmsrl(ctrls[i], ctxt->ctrls[i]);
+        wrmsrl(ctrls[i], 0);
+        rdmsrl(counters[i], ctxt->counters[i]);
+    }
 }
 
 static void amd_vpmu_save(struct vcpu *v)