From: Luwei Kang <luwei.kang@intel.com>
To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: pbonzini@redhat.com, rkrcmar@redhat.com,
sean.j.christopherson@intel.com, vkuznets@redhat.com,
wanpengli@tencent.com, jmattson@google.com, joro@8bytes.org,
tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
hpa@zytor.com, x86@kernel.org, ak@linux.intel.com,
thomas.lendacky@amd.com, peterz@infradead.org, acme@kernel.org,
mark.rutland@arm.com, alexander.shishkin@linux.intel.com,
jolsa@redhat.com, namhyung@kernel.org,
Luwei Kang <luwei.kang@intel.com>
Subject: [PATCH v1 2/8] KVM: x86: PEBS output to Intel PT MSRs emulation
Date: Sun, 27 Oct 2019 19:11:11 -0400 [thread overview]
Message-ID: <1572217877-26484-3-git-send-email-luwei.kang@intel.com> (raw)
In-Reply-To: <1572217877-26484-1-git-send-email-luwei.kang@intel.com>
Intel new hardware introduces a mechanism to direct PEBS records
output into the Intel PT buffer that can be used for enabling PEBS
in KVM guest. This patch implements the registers read and write
emulation when PEBS is supported in KVM guest.
KMM needs to reprogram the counters when the value of these MSRs
be changed that to make sure it can take effect in hardware.
Signed-off-by: Luwei Kang <luwei.kang@intel.com>
---
arch/x86/include/asm/kvm_host.h | 4 +++
arch/x86/include/asm/msr-index.h | 6 ++++
arch/x86/kvm/vmx/capabilities.h | 15 ++++++++++
arch/x86/kvm/vmx/pmu_intel.c | 63 ++++++++++++++++++++++++++++++++++++++--
4 files changed, 86 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 50eb430..ed01936 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -448,6 +448,7 @@ struct kvm_pmc {
enum pmc_type type;
u8 idx;
u64 counter;
+ u64 reload_cnt;
u64 eventsel;
struct perf_event *perf_event;
struct kvm_vcpu *vcpu;
@@ -465,7 +466,10 @@ struct kvm_pmu {
u64 global_ctrl_mask;
u64 global_ovf_ctrl_mask;
u64 reserved_bits;
+ u64 pebs_enable;
+ u64 pebs_enable_mask;
u8 version;
+ bool pebs_via_pt; /* PEBS output to Intel PT */
struct kvm_pmc gp_counters[INTEL_PMC_MAX_GENERIC];
struct kvm_pmc fixed_counters[INTEL_PMC_MAX_FIXED];
struct irq_work irq_work;
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 20ce682..d22f8d9 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -131,9 +131,13 @@
#define LBR_INFO_ABORT BIT_ULL(61)
#define LBR_INFO_CYCLES 0xffff
+#define MSR_IA32_PEBS_PMI_AFTER_REC BIT_ULL(60)
+#define MSR_IA32_PEBS_OUTPUT_PT BIT_ULL(61)
+#define MSR_IA32_PEBS_OUTPUT_MASK (3ULL << 61)
#define MSR_IA32_PEBS_ENABLE 0x000003f1
#define MSR_PEBS_DATA_CFG 0x000003f2
#define MSR_IA32_DS_AREA 0x00000600
+#define MSR_IA32_PERF_CAP_PEBS_OUTPUT_PT BIT_ULL(16)
#define MSR_IA32_PERF_CAPABILITIES 0x00000345
#define MSR_PEBS_LD_LAT_THRESHOLD 0x000003f6
@@ -665,6 +669,8 @@
#define MSR_IA32_MISC_ENABLE_FERR (1ULL << MSR_IA32_MISC_ENABLE_FERR_BIT)
#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX_BIT 10
#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX (1ULL << MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX_BIT)
+#define MSR_IA32_MISC_ENABLE_PEBS_BIT 12
+#define MSR_IA32_MISC_ENABLE_PEBS (1ULL << MSR_IA32_MISC_ENABLE_PEBS_BIT)
#define MSR_IA32_MISC_ENABLE_TM2_BIT 13
#define MSR_IA32_MISC_ENABLE_TM2 (1ULL << MSR_IA32_MISC_ENABLE_TM2_BIT)
#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE_BIT 19
diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h
index 7aa6971..fc861d4 100644
--- a/arch/x86/kvm/vmx/capabilities.h
+++ b/arch/x86/kvm/vmx/capabilities.h
@@ -348,4 +348,19 @@ static inline bool cpu_has_vmx_intel_pt(void)
(vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_RTIT_CTL);
}
+static inline bool cpu_has_vmx_pebs_output_pt(void)
+{
+ u64 misc, perf_cap;
+
+ rdmsrl(MSR_IA32_MISC_ENABLE, misc);
+ rdmsrl(MSR_IA32_PERF_CAPABILITIES, perf_cap);
+
+ /*
+ * Support Processor Event Based Sampling (PEBS) and
+ * PEBS output to Intel PT.
+ */
+ return (!(misc & MSR_IA32_MISC_ENABLE_PEBS) &&
+ (perf_cap & MSR_IA32_PERF_CAP_PEBS_OUTPUT_PT));
+}
+
#endif /* __KVM_X86_VMX_CAPS_H */
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index 2a485b5..3f723a3 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -12,6 +12,7 @@
#include <linux/kvm_host.h>
#include <linux/perf_event.h>
#include <asm/perf_event.h>
+#include "capabilities.h"
#include "x86.h"
#include "cpuid.h"
#include "lapic.h"
@@ -65,6 +66,20 @@ static void global_ctrl_changed(struct kvm_pmu *pmu, u64 data)
reprogram_counter(pmu, bit);
}
+static void pebs_enable_changed(struct kvm_pmu *pmu, u64 data)
+{
+ int bit;
+ u64 mask = (BIT_ULL(pmu->nr_arch_gp_counters) - 1) |
+ ((BIT_ULL(pmu->nr_arch_fixed_counters) - 1) <<
+ INTEL_PMC_IDX_FIXED);
+ u64 diff = (pmu->pebs_enable ^ data) & mask;
+
+ pmu->pebs_enable = data;
+
+ for_each_set_bit(bit, (unsigned long *)&diff, X86_PMC_IDX_MAX)
+ reprogram_counter(pmu, bit);
+}
+
static unsigned intel_find_arch_event(struct kvm_pmu *pmu,
u8 event_select,
u8 unit_mask)
@@ -154,10 +169,15 @@ static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)
case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
ret = pmu->version > 1;
break;
+ case MSR_IA32_PEBS_ENABLE:
+ ret = pmu->pebs_via_pt;
+ break;
default:
ret = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0) ||
get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0) ||
- get_fixed_pmc(pmu, msr, MSR_CORE_PERF_FIXED_CTR0);
+ get_fixed_pmc(pmu, msr, MSR_CORE_PERF_FIXED_CTR0) ||
+ get_gp_pmc(pmu, msr, MSR_RELOAD_PMC0) ||
+ get_fixed_pmc(pmu, msr, MSR_RELOAD_FIXED_CTR0);
break;
}
@@ -182,6 +202,9 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *data)
case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
*data = pmu->global_ovf_ctrl;
return 0;
+ case MSR_IA32_PEBS_ENABLE:
+ *data = pmu->pebs_enable;
+ return 0;
default:
if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) {
u64 val = pmc_read_counter(pmc);
@@ -195,6 +218,11 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *data)
} else if ((pmc = get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0))) {
*data = pmc->eventsel;
return 0;
+ } else if ((pmc = get_gp_pmc(pmu, msr, MSR_RELOAD_PMC0)) ||
+ (pmc = get_fixed_pmc(pmu, msr,
+ MSR_RELOAD_FIXED_CTR0))) {
+ *data = pmc->reload_cnt;
+ return 0;
}
}
@@ -239,6 +267,16 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
return 0;
}
break;
+ case MSR_IA32_PEBS_ENABLE:
+ if (pmu->pebs_enable == data)
+ return 0;
+ if (!data || (!(data & pmu->pebs_enable_mask) &&
+ (data & MSR_IA32_PEBS_OUTPUT_MASK) ==
+ MSR_IA32_PEBS_OUTPUT_PT)) {
+ pebs_enable_changed(pmu, data);
+ return 0;
+ }
+ break;
default:
if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) {
if (msr_info->host_initiated)
@@ -257,6 +295,18 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
reprogram_gp_counter(pmc, data);
return 0;
}
+ } else if ((pmc = get_gp_pmc(pmu, msr, MSR_RELOAD_PMC0)) ||
+ (pmc = get_fixed_pmc(pmu, msr,
+ MSR_RELOAD_FIXED_CTR0))) {
+ if (data == pmc->reload_cnt)
+ return 0;
+ if (!(data & ~pmc_bitmask(pmc))) {
+ int pmc_idx = pmc_is_fixed(pmc) ? pmc->idx +
+ INTEL_PMC_IDX_FIXED : pmc->idx;
+ pmc->reload_cnt = data;
+ reprogram_counter(pmu, pmc_idx);
+ return 0;
+ }
}
}
@@ -308,14 +358,23 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
pmu->global_ctrl = ((1ull << pmu->nr_arch_gp_counters) - 1) |
(((1ull << pmu->nr_arch_fixed_counters) - 1) << INTEL_PMC_IDX_FIXED);
+
pmu->global_ctrl_mask = ~pmu->global_ctrl;
pmu->global_ovf_ctrl_mask = pmu->global_ctrl_mask
& ~(MSR_CORE_PERF_GLOBAL_OVF_CTRL_OVF_BUF |
MSR_CORE_PERF_GLOBAL_OVF_CTRL_COND_CHGD);
- if (kvm_x86_ops->pt_supported())
+ if (kvm_x86_ops->pt_supported()) {
pmu->global_ovf_ctrl_mask &=
~MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI;
+ if (cpu_has_vmx_pebs_output_pt()) {
+ pmu->pebs_via_pt = true;
+ pmu->pebs_enable_mask = ~(pmu->global_ctrl |
+ MSR_IA32_PEBS_PMI_AFTER_REC |
+ MSR_IA32_PEBS_OUTPUT_MASK);
+ }
+ }
+
entry = kvm_find_cpuid_entry(vcpu, 7, 0);
if (entry &&
(boot_cpu_has(X86_FEATURE_HLE) || boot_cpu_has(X86_FEATURE_RTM)) &&
--
1.8.3.1
next prev parent reply other threads:[~2019-10-27 11:12 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-27 23:11 [PATCH v1 0/8] PEBS enabling in KVM guest Luwei Kang
2019-10-27 23:11 ` [PATCH v1 1/8] KVM: x86: Add base address parameter for get_fixed_pmc function Luwei Kang
2019-10-27 23:11 ` Luwei Kang [this message]
2019-10-29 15:02 ` [PATCH v1 2/8] KVM: x86: PEBS output to Intel PT MSRs emulation Peter Zijlstra
2019-10-30 4:06 ` Kang, Luwei
2019-10-27 23:11 ` [PATCH v1 3/8] KVM: x86: Allocate performance counter for PEBS event Luwei Kang
2019-10-29 14:46 ` Peter Zijlstra
2019-10-30 4:06 ` Kang, Luwei
2019-10-30 6:42 ` Alexander Shishkin
2019-10-30 6:49 ` Kang, Luwei
2019-10-30 9:51 ` Peter Zijlstra
2019-10-30 9:50 ` Peter Zijlstra
2019-10-30 9:49 ` Peter Zijlstra
2019-10-30 13:41 ` Alexander Shishkin
2019-10-31 11:10 ` Kang, Luwei
2019-11-06 7:44 ` Kang, Luwei
2019-10-27 23:11 ` [PATCH v1 4/8] KVM: x86: Aviod clear the PEBS counter when PEBS enabled in guest Luwei Kang
2019-10-29 14:55 ` Peter Zijlstra
2019-10-30 4:06 ` Kang, Luwei
2019-10-27 23:11 ` [PATCH v1 5/8] KVM: X86: Expose PDCM cpuid to guest Luwei Kang
2019-10-27 23:11 ` [PATCH v1 6/8] KVM: X86: MSR_IA32_PERF_CAPABILITIES MSR emulation Luwei Kang
2019-10-27 23:11 ` [PATCH v1 7/8] KVM: x86: Expose PEBS feature to guest Luwei Kang
2019-10-29 15:05 ` Peter Zijlstra
2019-10-30 4:07 ` Kang, Luwei
2019-10-30 9:52 ` Peter Zijlstra
2019-10-31 4:21 ` Kang, Luwei
2019-10-27 23:11 ` [PATCH v1 8/8] perf/x86: Add event owner check when PEBS output to Intel PT Luwei Kang
2019-10-29 15:13 ` Peter Zijlstra
2019-10-30 4:07 ` Kang, Luwei
2019-10-30 9:54 ` Peter Zijlstra
2019-10-31 6:55 ` Kang, Luwei
2019-10-31 7:39 ` Alexander Shishkin
2019-10-31 10:31 ` Kang, Luwei
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1572217877-26484-3-git-send-email-luwei.kang@intel.com \
--to=luwei.kang@intel.com \
--cc=acme@kernel.org \
--cc=ak@linux.intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=bp@alien8.de \
--cc=hpa@zytor.com \
--cc=jmattson@google.com \
--cc=jolsa@redhat.com \
--cc=joro@8bytes.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=rkrcmar@redhat.com \
--cc=sean.j.christopherson@intel.com \
--cc=tglx@linutronix.de \
--cc=thomas.lendacky@amd.com \
--cc=vkuznets@redhat.com \
--cc=wanpengli@tencent.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.