From: Like Xu <like.xu@linux.intel.com>
To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Cc: like.xu@intel.com, wei.w.wang@intel.com,
Andi Kleen <ak@linux.intel.com>,
Peter Zijlstra <peterz@infradead.org>,
Kan Liang <kan.liang@linux.intel.com>,
Ingo Molnar <mingo@redhat.com>,
Paolo Bonzini <pbonzini@redhat.com>
Subject: [RFC] [PATCH v2 2/5] KVM/x86/vPMU: add pmc operations for vmx and count to track release
Date: Sat, 23 Mar 2019 22:18:05 +0800 [thread overview]
Message-ID: <1553350688-39627-3-git-send-email-like.xu@linux.intel.com> (raw)
In-Reply-To: <1553350688-39627-1-git-send-email-like.xu@linux.intel.com>
The introduced hw_life_count is initialized with HW_LIFE_COUNT_MAX
when the vPMC holds a hw-assigned perf_event and the kvm_pmu_sched ctx
would start counting down (0 means to be released) if not be charged.
If vPMC is assigned, the intel_pmc_read_counter() would use rdpmcl
directly not perf_event_read_value() and charge hw_life_count to max.
To clear out responsibility for potential operating space in kvm,
this patch is not going to invoke similar functions from host perf.
Signed-off-by: Wang Wei <wei.w.wang@intel.com>
Signed-off-by: Like Xu <like.xu@linux.intel.com>
---
arch/x86/include/asm/kvm_host.h | 2 +
arch/x86/kvm/vmx/pmu_intel.c | 98 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 100 insertions(+)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index a5db447..2a2c78f2 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -449,6 +449,7 @@ enum pmc_type {
KVM_PMC_FIXED,
};
+#define HW_LIFE_COUNT_MAX 2
struct kvm_pmc {
enum pmc_type type;
u8 idx;
@@ -456,6 +457,7 @@ struct kvm_pmc {
u64 eventsel;
struct perf_event *perf_event;
struct kvm_vcpu *vcpu;
+ int hw_life_count;
};
struct kvm_pmu {
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index 5ab4a36..bb16031 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -35,6 +35,104 @@
/* mapping between fixed pmc index and intel_arch_events array */
static int fixed_pmc_events[] = {1, 0, 7};
+static bool intel_pmc_is_assigned(struct kvm_pmc *pmc)
+{
+ return pmc->perf_event != NULL &&
+ pmc->perf_event->hw.idx != -1 &&
+ pmc->perf_event->oncpu != -1;
+}
+
+static int intel_pmc_read_counter(struct kvm_vcpu *vcpu,
+ unsigned int idx, u64 *data)
+{
+ struct kvm_pmc *pmc = kvm_x86_ops->pmu_ops->msr_idx_to_pmc(vcpu, idx);
+
+ if (intel_pmc_is_assigned(pmc)) {
+ rdpmcl(pmc->perf_event->hw.event_base_rdpmc, *data);
+ pmc->counter = *data;
+ pmc->hw_life_count = HW_LIFE_COUNT_MAX;
+ } else {
+ *data = pmc->counter;
+ }
+ return 0;
+}
+
+static void intel_pmu_enable_host_gp_counter(struct kvm_pmc *pmc)
+{
+ u64 config;
+
+ if (!intel_pmc_is_assigned(pmc))
+ return;
+
+ config = (pmc->type == KVM_PMC_GP) ? pmc->eventsel :
+ pmc->perf_event->hw.config | ARCH_PERFMON_EVENTSEL_ENABLE;
+ wrmsrl(pmc->perf_event->hw.config_base, config);
+}
+
+static void intel_pmu_disable_host_gp_counter(struct kvm_pmc *pmc)
+{
+ if (!intel_pmc_is_assigned(pmc))
+ return;
+
+ wrmsrl(pmc->perf_event->hw.config_base, 0);
+}
+
+static void intel_pmu_enable_host_fixed_counter(struct kvm_pmc *pmc)
+{
+ struct kvm_pmu *pmu = vcpu_to_pmu(pmc->vcpu);
+ int host_idx = pmc->perf_event->hw.idx - INTEL_PMC_IDX_FIXED;
+ u64 ctrl_val, mask, bits = 0;
+
+ if (!intel_pmc_is_assigned(pmc))
+ return;
+
+ if (!pmc->perf_event->attr.precise_ip)
+ bits |= 0x8;
+ if (pmc->perf_event->hw.config & ARCH_PERFMON_EVENTSEL_USR)
+ bits |= 0x2;
+ if (pmc->perf_event->hw.config & ARCH_PERFMON_EVENTSEL_OS)
+ bits |= 0x1;
+
+ if (pmu->version > 2
+ && (pmc->perf_event->hw.config & ARCH_PERFMON_EVENTSEL_ANY))
+ bits |= 0x4;
+
+ bits <<= (host_idx * 4);
+ mask = 0xfULL << (host_idx * 4);
+
+ rdmsrl(pmc->perf_event->hw.config_base, ctrl_val);
+ ctrl_val &= ~mask;
+ ctrl_val |= bits;
+ wrmsrl(pmc->perf_event->hw.config_base, ctrl_val);
+}
+
+static void intel_pmu_disable_host_fixed_counter(struct kvm_pmc *pmc)
+{
+ u64 ctrl_val, mask = 0;
+ u8 host_idx;
+
+ if (!intel_pmc_is_assigned(pmc))
+ return;
+
+ host_idx = pmc->perf_event->hw.idx - INTEL_PMC_IDX_FIXED;
+ mask = 0xfULL << (host_idx * 4);
+ rdmsrl(pmc->perf_event->hw.config_base, ctrl_val);
+ ctrl_val &= ~mask;
+ wrmsrl(pmc->perf_event->hw.config_base, ctrl_val);
+}
+
+static void intel_pmu_update_host_fixed_ctrl(u64 new_ctrl, u8 host_idx)
+{
+ u64 host_ctrl, mask;
+
+ rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, host_ctrl);
+ mask = 0xfULL << (host_idx * 4);
+ host_ctrl &= ~mask;
+ new_ctrl <<= (host_idx * 4);
+ host_ctrl |= new_ctrl;
+ wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, host_ctrl);
+}
+
static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 data)
{
int i;
--
1.8.3.1
next prev parent reply other threads:[~2019-03-23 14:18 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-23 14:18 [RFC] [PATCH v2 0/5] Intel Virtual PMU Optimization Like Xu
2019-03-23 14:18 ` [RFC] [PATCH v2 1/5] perf/x86: avoid host changing counter state for kvm_intel events holder Like Xu
2019-03-23 14:18 ` Like Xu [this message]
2019-03-23 14:18 ` [RFC] [PATCH v2 3/5] KVM/x86/vPMU: add Intel vPMC enable/disable and save/restore support Like Xu
2019-03-23 14:18 ` [RFC] [PATCH v2 4/5] KVM/x86/vPMU: add vCPU scheduling support for hw-assigned vPMC Like Xu
2019-03-23 14:18 ` [RFC] [PATCH v2 5/5] KVM/x86/vPMU: not do reprogram_counter for Intel " Like Xu
2019-03-23 17:28 ` [RFC] [PATCH v2 0/5] Intel Virtual PMU Optimization Peter Zijlstra
2019-03-23 23:15 ` Andi Kleen
2019-03-25 6:07 ` Like Xu
2019-03-25 6:47 ` Like Xu
2019-03-25 7:19 ` Peter Zijlstra
2019-03-25 15:58 ` Andi Kleen
2019-04-01 9:08 ` Wei Wang
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=1553350688-39627-3-git-send-email-like.xu@linux.intel.com \
--to=like.xu@linux.intel.com \
--cc=ak@linux.intel.com \
--cc=kan.liang@linux.intel.com \
--cc=kvm@vger.kernel.org \
--cc=like.xu@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=wei.w.wang@intel.com \
/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.