]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.14/kvm-x86-pmu-do-not-mask-the-value-that-is-written-to.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / queue-4.14 / kvm-x86-pmu-do-not-mask-the-value-that-is-written-to.patch
1 From 4c3cb7edd7486fe181bd76a71258244b2b5697d9 Mon Sep 17 00:00:00 2001
2 From: Paolo Bonzini <pbonzini@redhat.com>
3 Date: Mon, 20 May 2019 17:34:30 +0200
4 Subject: KVM: x86/pmu: do not mask the value that is written to fixed PMUs
5
6 [ Upstream commit 2924b52117b2812e9633d5ea337333299166d373 ]
7
8 According to the SDM, for MSR_IA32_PERFCTR0/1 "the lower-order 32 bits of
9 each MSR may be written with any value, and the high-order 8 bits are
10 sign-extended according to the value of bit 31", but the fixed counters
11 in real hardware are limited to the width of the fixed counters ("bits
12 beyond the width of the fixed-function counter are reserved and must be
13 written as zeros"). Fix KVM to do the same.
14
15 Reported-by: Nadav Amit <nadav.amit@gmail.com>
16 Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
17 Signed-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
22 diff --git a/arch/x86/kvm/pmu_intel.c b/arch/x86/kvm/pmu_intel.c
23 index 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 --
47 2.20.1
48