]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.9.183/kvm-x86-pmu-do-not-mask-the-value-that-is-written-to.patch
Linux 4.9.183
[thirdparty/kernel/stable-queue.git] / releases / 4.9.183 / kvm-x86-pmu-do-not-mask-the-value-that-is-written-to.patch
CommitLineData
97c569a1
SL
1From 1abdc7e52abb4227689ac20ac0eadff1b0454019 Mon Sep 17 00:00:00 2001
2From: Paolo Bonzini <pbonzini@redhat.com>
3Date: Mon, 20 May 2019 17:34:30 +0200
4Subject: KVM: x86/pmu: do not mask the value that is written to fixed PMUs
5
6[ Upstream commit 2924b52117b2812e9633d5ea337333299166d373 ]
7
8According to the SDM, for MSR_IA32_PERFCTR0/1 "the lower-order 32 bits of
9each MSR may be written with any value, and the high-order 8 bits are
10sign-extended according to the value of bit 31", but the fixed counters
11in real hardware are limited to the width of the fixed counters ("bits
12beyond the width of the fixed-function counter are reserved and must be
13written as zeros"). Fix KVM to do the same.
14
15Reported-by: Nadav Amit <nadav.amit@gmail.com>
16Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
17Signed-off-by: Sasha Levin <sashal@kernel.org>
18---
19 arch/x86/kvm/pmu_intel.c | 13 ++++++++-----
20 1 file changed, 8 insertions(+), 5 deletions(-)
21
22diff --git a/arch/x86/kvm/pmu_intel.c b/arch/x86/kvm/pmu_intel.c
23index 5ab4a364348e..2729131fe9bf 100644
24--- a/arch/x86/kvm/pmu_intel.c
25+++ b/arch/x86/kvm/pmu_intel.c
26@@ -235,11 +235,14 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
27 }
28 break;
29 default:
30- if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
31- (pmc = get_fixed_pmc(pmu, msr))) {
32- if (!msr_info->host_initiated)
33- data = (s64)(s32)data;
34- pmc->counter += data - pmc_read_counter(pmc);
35+ if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) {
36+ if (msr_info->host_initiated)
37+ pmc->counter = data;
38+ else
39+ pmc->counter = (s32)data;
40+ return 0;
41+ } else if ((pmc = get_fixed_pmc(pmu, msr))) {
42+ pmc->counter = data;
43 return 0;
44 } else if ((pmc = get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0))) {
45 if (data == pmc->eventsel)
46--
472.20.1
48