From: Sandipan Das <sandipan.das@xxxxxxx> Implement the AMD-specific handlers to save and restore the state of PMU-related MSRs when using passthrough PMU. Signed-off-by: Sandipan Das <sandipan.das@xxxxxxx> Signed-off-by: Mingwei Zhang <mizhang@xxxxxxxxxx> --- arch/x86/kvm/svm/pmu.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c index 2b7cc7616162..86818da66bbe 100644 --- a/arch/x86/kvm/svm/pmu.c +++ b/arch/x86/kvm/svm/pmu.c @@ -307,6 +307,36 @@ static void amd_passthrough_pmu_msrs(struct kvm_vcpu *vcpu) set_msr_interception(vcpu, svm->msrpm, MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_SET, msr_clear, msr_clear); } +static void amd_save_pmu_context(struct kvm_vcpu *vcpu) +{ + struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); + + rdmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, pmu->global_ctrl); + wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, 0); + rdmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS, pmu->global_status); + + /* Clear global status bits if non-zero */ + if (pmu->global_status) + wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, pmu->global_status); +} + +static void amd_restore_pmu_context(struct kvm_vcpu *vcpu) +{ + struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); + u64 global_status; + + wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, 0); + rdmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS, global_status); + + /* Clear host global_status MSR if non-zero. */ + if (global_status) + wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, global_status); + + wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_SET, pmu->global_status); + + wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, pmu->global_ctrl); +} + struct kvm_pmu_ops amd_pmu_ops __initdata = { .rdpmc_ecx_to_pmc = amd_rdpmc_ecx_to_pmc, .msr_idx_to_pmc = amd_msr_idx_to_pmc, @@ -318,6 +348,8 @@ struct kvm_pmu_ops amd_pmu_ops __initdata = { .init = amd_pmu_init, .is_rdpmc_passthru_allowed = amd_is_rdpmc_passthru_allowed, .passthrough_pmu_msrs = amd_passthrough_pmu_msrs, + .save_pmu_context = amd_save_pmu_context, + .restore_pmu_context = amd_restore_pmu_context, .EVENTSEL_EVENT = AMD64_EVENTSEL_EVENT, .MAX_NR_GP_COUNTERS = KVM_AMD_PMC_MAX_GENERIC, .MIN_NR_GP_COUNTERS = AMD64_NUM_COUNTERS, -- 2.46.0.rc1.232.g9752f9e123-goog