Commit 81305c9c authored by Jim Mattson's avatar Jim Mattson Committed by Zheng Zengkai
Browse files

KVM: x86/pmu: Use different raw event masks for AMD and Intel

stable inclusion
from stable-v5.10.137
commit 2ba1feb14363fd311f2cc912b58e5bb0b2b73662
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I60PLB

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=2ba1feb14363fd311f2cc912b58e5bb0b2b73662



--------------------------------

[ Upstream commit 95b065bf ]

The third nybble of AMD's event select overlaps with Intel's IN_TX and
IN_TXCP bits. Therefore, we can't use AMD64_RAW_EVENT_MASK on Intel
platforms that support TSX.

Declare a raw_event_mask in the kvm_pmu structure, initialize it in
the vendor-specific pmu_refresh() functions, and use that mask for
PERF_TYPE_RAW configurations in reprogram_gp_counter().

Fixes: 710c4765 ("KVM: x86/pmu: Use AMD64_RAW_EVENT_MASK for PERF_TYPE_RAW")
Signed-off-by: default avatarJim Mattson <jmattson@google.com>
Message-Id: <20220308012452.3468611-1-jmattson@google.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
Reviewed-by: default avatarWei Li <liwei391@huawei.com>
parent 6a083241
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -458,6 +458,7 @@ struct kvm_pmu {
	u64 global_ctrl_mask;
	u64 global_ovf_ctrl_mask;
	u64 reserved_bits;
	u64 raw_event_mask;
	u8 version;
	struct kvm_pmc gp_counters[INTEL_PMC_MAX_GENERIC];
	struct kvm_pmc fixed_counters[INTEL_PMC_MAX_FIXED];
+2 −1
Original line number Diff line number Diff line
@@ -184,6 +184,7 @@ void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
	u32 type = PERF_TYPE_RAW;
	struct kvm *kvm = pmc->vcpu->kvm;
	struct kvm_pmu_event_filter *filter;
	struct kvm_pmu *pmu = vcpu_to_pmu(pmc->vcpu);
	bool allow_event = true;

	if (eventsel & ARCH_PERFMON_EVENTSEL_PIN_CONTROL)
@@ -220,7 +221,7 @@ void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
	}

	if (type == PERF_TYPE_RAW)
		config = eventsel & AMD64_RAW_EVENT_MASK;
		config = eventsel & pmu->raw_event_mask;

	if (pmc->current_config == eventsel && pmc_resume_counter(pmc))
		return;
+1 −0
Original line number Diff line number Diff line
@@ -296,6 +296,7 @@ static void amd_pmu_refresh(struct kvm_vcpu *vcpu)

	pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << 48) - 1;
	pmu->reserved_bits = 0xfffffff000280000ull;
	pmu->raw_event_mask = AMD64_RAW_EVENT_MASK;
	pmu->version = 1;
	/* not applicable to AMD; but clean them to prevent any fall out */
	pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
+1 −0
Original line number Diff line number Diff line
@@ -474,6 +474,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
	pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
	pmu->version = 0;
	pmu->reserved_bits = 0xffffffff00200000ull;
	pmu->raw_event_mask = X86_RAW_EVENT_MASK;

	entry = kvm_find_cpuid_entry(vcpu, 0xa, 0);
	if (!entry)