Skip to content

Commit 2924b52

Browse files
committed
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: Nadav Amit <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 0e6f467 commit 2924b52

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

arch/x86/kvm/vmx/pmu_intel.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -240,11 +240,14 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
240240
}
241241
break;
242242
default:
243-
if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
244-
(pmc = get_fixed_pmc(pmu, msr))) {
245-
if (!msr_info->host_initiated)
246-
data = (s64)(s32)data;
247-
pmc->counter += data - pmc_read_counter(pmc);
243+
if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) {
244+
if (msr_info->host_initiated)
245+
pmc->counter = data;
246+
else
247+
pmc->counter = (s32)data;
248+
return 0;
249+
} else if ((pmc = get_fixed_pmc(pmu, msr))) {
250+
pmc->counter = data;
248251
return 0;
249252
} else if ((pmc = get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0))) {
250253
if (data == pmc->eventsel)

0 commit comments

Comments
 (0)