]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/kvm-x86-pmu-do-not-mask-the-value-that-is-written-to.patch
Fix up backported ptrace patch
[thirdparty/kernel/stable-queue.git] / queue-4.19 / kvm-x86-pmu-do-not-mask-the-value-that-is-written-to.patch
1 From 5a3b25545d1dd31e8b1e84d7c2dd0a849c949542 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 ad7ea81fbfbf..c3f103e2b08e 100644
24 --- a/arch/x86/kvm/pmu_intel.c
25 +++ b/arch/x86/kvm/pmu_intel.c
26 @@ -240,11 +240,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