diff options
Diffstat (limited to 'arch/x86/kvm/pmu.c')
-rw-r--r-- | arch/x86/kvm/pmu.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index cfc258a6bf97..c53e797e7369 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c | |||
@@ -360,10 +360,12 @@ int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data) | |||
360 | return 1; | 360 | return 1; |
361 | } | 361 | } |
362 | 362 | ||
363 | int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data) | 363 | int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) |
364 | { | 364 | { |
365 | struct kvm_pmu *pmu = &vcpu->arch.pmu; | 365 | struct kvm_pmu *pmu = &vcpu->arch.pmu; |
366 | struct kvm_pmc *pmc; | 366 | struct kvm_pmc *pmc; |
367 | u32 index = msr_info->index; | ||
368 | u64 data = msr_info->data; | ||
367 | 369 | ||
368 | switch (index) { | 370 | switch (index) { |
369 | case MSR_CORE_PERF_FIXED_CTR_CTRL: | 371 | case MSR_CORE_PERF_FIXED_CTR_CTRL: |
@@ -375,6 +377,10 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data) | |||
375 | } | 377 | } |
376 | break; | 378 | break; |
377 | case MSR_CORE_PERF_GLOBAL_STATUS: | 379 | case MSR_CORE_PERF_GLOBAL_STATUS: |
380 | if (msr_info->host_initiated) { | ||
381 | pmu->global_status = data; | ||
382 | return 0; | ||
383 | } | ||
378 | break; /* RO MSR */ | 384 | break; /* RO MSR */ |
379 | case MSR_CORE_PERF_GLOBAL_CTRL: | 385 | case MSR_CORE_PERF_GLOBAL_CTRL: |
380 | if (pmu->global_ctrl == data) | 386 | if (pmu->global_ctrl == data) |
@@ -386,7 +392,8 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data) | |||
386 | break; | 392 | break; |
387 | case MSR_CORE_PERF_GLOBAL_OVF_CTRL: | 393 | case MSR_CORE_PERF_GLOBAL_OVF_CTRL: |
388 | if (!(data & (pmu->global_ctrl_mask & ~(3ull<<62)))) { | 394 | if (!(data & (pmu->global_ctrl_mask & ~(3ull<<62)))) { |
389 | pmu->global_status &= ~data; | 395 | if (!msr_info->host_initiated) |
396 | pmu->global_status &= ~data; | ||
390 | pmu->global_ovf_ctrl = data; | 397 | pmu->global_ovf_ctrl = data; |
391 | return 0; | 398 | return 0; |
392 | } | 399 | } |
@@ -394,7 +401,8 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data) | |||
394 | default: | 401 | default: |
395 | if ((pmc = get_gp_pmc(pmu, index, MSR_IA32_PERFCTR0)) || | 402 | if ((pmc = get_gp_pmc(pmu, index, MSR_IA32_PERFCTR0)) || |
396 | (pmc = get_fixed_pmc(pmu, index))) { | 403 | (pmc = get_fixed_pmc(pmu, index))) { |
397 | data = (s64)(s32)data; | 404 | if (!msr_info->host_initiated) |
405 | data = (s64)(s32)data; | ||
398 | pmc->counter += data - read_pmc(pmc); | 406 | pmc->counter += data - read_pmc(pmc); |
399 | return 0; | 407 | return 0; |
400 | } else if ((pmc = get_gp_pmc(pmu, index, MSR_P6_EVNTSEL0))) { | 408 | } else if ((pmc = get_gp_pmc(pmu, index, MSR_P6_EVNTSEL0))) { |