Commit 2924b521 authored by Paolo Bonzini's avatar Paolo Bonzini

KVM: x86/pmu: do not mask the value that is written to fixed PMUs

According to the SDM, for MSR_IA32_PERFCTR0/1 "the lower-order 32 bits of
each MSR may be written with any value, and the high-order 8 bits are
sign-extended according to the value of bit 31", but the fixed counters
in real hardware are limited to the width of the fixed counters ("bits
beyond the width of the fixed-function counter are reserved and must be
written as zeros").  Fix KVM to do the same.
Reported-by: default avatarNadav Amit <nadav.amit@gmail.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 0e6f467e
...@@ -240,11 +240,14 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) ...@@ -240,11 +240,14 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
} }
break; break;
default: default:
if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) || if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) {
(pmc = get_fixed_pmc(pmu, msr))) { if (msr_info->host_initiated)
if (!msr_info->host_initiated) pmc->counter = data;
data = (s64)(s32)data; else
pmc->counter += data - pmc_read_counter(pmc); pmc->counter = (s32)data;
return 0;
} else if ((pmc = get_fixed_pmc(pmu, msr))) {
pmc->counter = data;
return 0; return 0;
} else if ((pmc = get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0))) { } else if ((pmc = get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0))) {
if (data == pmc->eventsel) if (data == pmc->eventsel)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment