x86/VPMU: mark context LOADED before registers are loaded
authorBoris Ostrovsky <boris.ostrovsky@oracle.com>
Wed, 11 Jun 2014 08:55:43 +0000 (10:55 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 11 Jun 2014 08:55:43 +0000 (10:55 +0200)
Because a PMU interrupt may be generated as soon as PMU registers are
loaded (or, more precisely, as soon as HW PMU is "armed") we don't want
to delay marking context as LOADED until after registers are loaded.
Otherwise during interrupt handling VPMU_CONTEXT_LOADED may not be set
and this could be confusing.

(Technically, only SVM needs this change right now since VMX will "arm"
PMU later, during VMRUN when global control register is loaded from
VMCS. However, both AMD and Intel code will require this patch when we
introduce PV VPMU.)

Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Dietmar Hahn <dietmar.hahn@ts.fujitsu.com>
Tested-by: Dietmar Hahn <dietmar.hahn@ts.fujitsu.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/arch/x86/hvm/svm/vpmu.c
xen/arch/x86/hvm/vmx/vpmu_core2.c
xen/arch/x86/hvm/vpmu.c

index 66a381525cc0ec3e4167c6b2645bf6785547dedd..3ac7d537ebe0c33af584471b7f537dd0068ee7b8 100644 (file)
@@ -203,6 +203,8 @@ static void amd_vpmu_load(struct vcpu *v)
         return;
     }
 
+    vpmu_set(vpmu, VPMU_CONTEXT_LOADED);
+
     context_load(v);
 }
 
index 3129ebd5c44e7930aa04ebcd29856f3e0adc4915..ccd14d923b5a9de3e3d1bdee36ea0a39561f7e56 100644 (file)
@@ -369,6 +369,8 @@ static void core2_vpmu_load(struct vcpu *v)
     if ( vpmu_is_set(vpmu, VPMU_CONTEXT_LOADED) )
         return;
 
+    vpmu_set(vpmu, VPMU_CONTEXT_LOADED);
+
     __core2_vpmu_load(v);
 }
 
index 21fbabaa950000f96f7cd3069e49169ced51047f..63765fa2fe7721643caadcd558d0da23f0b19f13 100644 (file)
@@ -211,10 +211,9 @@ void vpmu_load(struct vcpu *v)
     if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->arch_vpmu_load )
     {
         apic_write_around(APIC_LVTPC, vpmu->hw_lapic_lvtpc);
+        /* Arch code needs to set VPMU_CONTEXT_LOADED */
         vpmu->arch_vpmu_ops->arch_vpmu_load(v);
     }
-
-    vpmu_set(vpmu, VPMU_CONTEXT_LOADED);
 }
 
 void vpmu_initialise(struct vcpu *v)