---
  xen/arch/x86/hvm/svm/vpmu.c |   62 ++++++++++++++++++++++++-------------------
  1 file changed, 35 insertions(+), 27 deletions(-)
diff --git a/xen/arch/x86/hvm/svm/vpmu.c b/xen/arch/x86/hvm/svm/vpmu.c
index bf186fe..4854cf3 100644
--- a/xen/arch/x86/hvm/svm/vpmu.c
+++ b/xen/arch/x86/hvm/svm/vpmu.c
@@ -172,12 +172,16 @@ static inline void context_restore(struct vcpu *v)
      {
          wrmsrl(counters[i], ctxt->counters[i]);
  
+        if ( !vpmu_is_set(vpmu, VPMU_RUNNING) )
+            continue;
+
          /* 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");
+                "overflow interrupt! (counter:%u value:0x%lx)\n",
+                i, ctxt->counters[i]);
              amd_vpmu_do_interrupt(0);
          }
      }
@@ -188,12 +192,13 @@ static void amd_vpmu_restore(struct vcpu *v)
      struct vpmu_struct *vpmu = vcpu_vpmu(v);
      struct amd_vpmu_context *ctxt = vpmu->context;
  
-    if ( !(vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED) &&
-           vpmu_is_set(vpmu, VPMU_RUNNING)) )
+    if ( !(vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED)) )
          return;
  
      context_restore(v);
-    apic_write(APIC_LVTPC, ctxt->hw_lapic_lvtpc);
+
+    if ( vpmu_is_set(vpmu, VPMU_RUNNING) )
+        apic_write(APIC_LVTPC, ctxt->hw_lapic_lvtpc);
  }
  
  static inline void context_save(struct vcpu *v)
@@ -214,13 +219,16 @@ static void amd_vpmu_save(struct vcpu *v)
      struct vpmu_struct *vpmu = vcpu_vpmu(v);
      struct amd_vpmu_context *ctx = vpmu->context;
  
-    if ( !(vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED) &&
-           vpmu_is_set(vpmu, VPMU_RUNNING)) )
+    if ( !(vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED)) )
          return;
  
      context_save(v);
-    ctx->hw_lapic_lvtpc = apic_read(APIC_LVTPC);
-    apic_write(APIC_LVTPC,  ctx->hw_lapic_lvtpc | APIC_LVT_MASKED);
+
+    if ( vpmu_is_set(vpmu, VPMU_RUNNING) )
+    {
+        ctx->hw_lapic_lvtpc = apic_read(APIC_LVTPC);
+        apic_write(APIC_LVTPC,  ctx->hw_lapic_lvtpc | APIC_LVT_MASKED);
+    }
  }
  
  static void context_update(unsigned int msr, u64 msr_content)
@@ -303,25 +311,25 @@ static int amd_vpmu_initialise(struct vcpu *v)
  
      if ( counters == NULL )
      {
-         switch ( family )
-        {
-        case 0x15:
-            num_counters = F15H_NUM_COUNTERS;
-            counters = AMD_F15H_COUNTERS;
-            ctrls = AMD_F15H_CTRLS;
-            k7_counters_mirrored = 1;
-            break;
-        case 0x10:
-        case 0x12:
-        case 0x14:
-        case 0x16:
-        default:
-            num_counters = F10H_NUM_COUNTERS;
-            counters = AMD_F10H_COUNTERS;
-            ctrls = AMD_F10H_CTRLS;
-            k7_counters_mirrored = 0;
-            break;
-        }
+        switch ( family )
+        {
+        case 0x15:
+            num_counters = F15H_NUM_COUNTERS;
+            counters = AMD_F15H_COUNTERS;
+            ctrls = AMD_F15H_CTRLS;
+            k7_counters_mirrored = 1;
+            break;
+        case 0x10:
+        case 0x12:
+        case 0x14:
+        case 0x16:
+        default:
+            num_counters = F10H_NUM_COUNTERS;
+            counters = AMD_F10H_COUNTERS;
+            ctrls = AMD_F10H_CTRLS;
+            k7_counters_mirrored = 0;
+            break;
+        }
      }
  
      ctxt = xzalloc(struct amd_vpmu_context);