[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 3/3] x86/VPMU: Handle APIC_LVTPC accesses
Don't have the hypervisor update APIC_LVTPC when _it_ thinks the vector should be updated. Instead, handle guest's APIC_LVTPC accesses and write what the guest explicitly wanted (but only when VPMU is enabled). This is updated version of commit 8097616fbdda that was reverted by cc3404093c85. Unlike the previous version, we don't update APIC_LVTPC when VPMU is disabled to avoid interfering with NMI watchdog (which runs only when VPMU is off). Signed-off-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> Acked-by: Kevin Tian <kevin.tian@xxxxxxxxx> --- xen/arch/x86/hvm/svm/vpmu.c | 4 ---- xen/arch/x86/hvm/vlapic.c | 3 +++ xen/arch/x86/hvm/vmx/vpmu_core2.c | 17 ----------------- xen/arch/x86/hvm/vpmu.c | 13 +++++++++++++ xen/include/asm-x86/hvm/vpmu.h | 1 + 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/xen/arch/x86/hvm/svm/vpmu.c b/xen/arch/x86/hvm/svm/vpmu.c index 19777e3..64dc167 100644 --- a/xen/arch/x86/hvm/svm/vpmu.c +++ b/xen/arch/x86/hvm/svm/vpmu.c @@ -302,8 +302,6 @@ static int amd_vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content, if ( !acquire_pmu_ownership(PMU_OWNER_HVM) ) return 1; vpmu_set(vpmu, VPMU_RUNNING); - apic_write(APIC_LVTPC, PMU_APIC_VECTOR); - vpmu->hw_lapic_lvtpc = PMU_APIC_VECTOR; if ( has_hvm_container_vcpu(v) && !((struct amd_vpmu_context *)vpmu->context)->msr_bitmap_set ) @@ -314,8 +312,6 @@ static int amd_vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content, if ( (get_pmu_reg_type(msr) == MSR_TYPE_CTRL) && (is_pmu_enabled(msr_content) == 0) && vpmu_is_set(vpmu, VPMU_RUNNING) ) { - apic_write(APIC_LVTPC, PMU_APIC_VECTOR | APIC_LVT_MASKED); - vpmu->hw_lapic_lvtpc = PMU_APIC_VECTOR | APIC_LVT_MASKED; vpmu_reset(vpmu, VPMU_RUNNING); if ( has_hvm_container_vcpu(v) && ((struct amd_vpmu_context *)vpmu->context)->msr_bitmap_set ) diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c index 8062f31..5da6d8f 100644 --- a/xen/arch/x86/hvm/vlapic.c +++ b/xen/arch/x86/hvm/vlapic.c @@ -38,6 +38,7 @@ #include <asm/hvm/support.h> #include <asm/hvm/vmx/vmx.h> #include <asm/hvm/nestedhvm.h> +#include <asm/hvm/vpmu.h> #include <public/hvm/ioreq.h> #include <public/hvm/params.h> @@ -777,6 +778,8 @@ static int vlapic_reg_write(struct vcpu *v, } if ( (offset == APIC_LVTT) && !(val & APIC_LVT_MASKED) ) pt_may_unmask_irq(NULL, &vlapic->pt); + if ( offset == APIC_LVTPC ) + vpmu_lvtpc_update(val); break; case APIC_TMICT: diff --git a/xen/arch/x86/hvm/vmx/vpmu_core2.c b/xen/arch/x86/hvm/vmx/vpmu_core2.c index 4d0e9a8..7793145 100644 --- a/xen/arch/x86/hvm/vmx/vpmu_core2.c +++ b/xen/arch/x86/hvm/vmx/vpmu_core2.c @@ -519,19 +519,6 @@ static int core2_vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content, else vpmu_reset(vpmu, VPMU_RUNNING); - /* Setup LVTPC in local apic */ - if ( vpmu_is_set(vpmu, VPMU_RUNNING) && - is_vlapic_lvtpc_enabled(vcpu_vlapic(v)) ) - { - apic_write_around(APIC_LVTPC, PMU_APIC_VECTOR); - vpmu->hw_lapic_lvtpc = PMU_APIC_VECTOR; - } - else - { - apic_write_around(APIC_LVTPC, PMU_APIC_VECTOR | APIC_LVT_MASKED); - vpmu->hw_lapic_lvtpc = PMU_APIC_VECTOR | APIC_LVT_MASKED; - } - if ( type != MSR_TYPE_GLOBAL ) { u64 mask; @@ -697,10 +684,6 @@ static int core2_vpmu_do_interrupt(struct cpu_user_regs *regs) return 0; } - /* HW sets the MASK bit when performance counter interrupt occurs*/ - vpmu->hw_lapic_lvtpc = apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED; - apic_write_around(APIC_LVTPC, vpmu->hw_lapic_lvtpc); - return 1; } diff --git a/xen/arch/x86/hvm/vpmu.c b/xen/arch/x86/hvm/vpmu.c index 68cb3f8..ee2b109 100644 --- a/xen/arch/x86/hvm/vpmu.c +++ b/xen/arch/x86/hvm/vpmu.c @@ -65,6 +65,19 @@ static void __init parse_vpmu_param(char *s) } } +void vpmu_lvtpc_update(uint32_t val) +{ + struct vpmu_struct *vpmu; + + if ( !opt_vpmu_enabled ) + return; + + vpmu = vcpu_vpmu(current); + + vpmu->hw_lapic_lvtpc = PMU_APIC_VECTOR | (val & APIC_LVT_MASKED); + apic_write(APIC_LVTPC, vpmu->hw_lapic_lvtpc); +} + int vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content, uint64_t supported) { struct vpmu_struct *vpmu = vcpu_vpmu(current); diff --git a/xen/include/asm-x86/hvm/vpmu.h b/xen/include/asm-x86/hvm/vpmu.h index ddc2748..9c4e65a 100644 --- a/xen/include/asm-x86/hvm/vpmu.h +++ b/xen/include/asm-x86/hvm/vpmu.h @@ -104,6 +104,7 @@ static inline bool_t vpmu_are_all_set(const struct vpmu_struct *vpmu, return !!((vpmu->flags & mask) == mask); } +void vpmu_lvtpc_update(uint32_t val); int vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content, uint64_t supported); int vpmu_do_rdmsr(unsigned int msr, uint64_t *msr_content); void vpmu_do_interrupt(struct cpu_user_regs *regs); -- 1.8.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |