linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Wei Wang <wei.w.wang@intel.com>
To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
	pbonzini@redhat.com, ak@linux.intel.com
Cc: kan.liang@intel.com, peterz@infradead.org, mingo@redhat.com,
	rkrcmar@redhat.com, like.xu@intel.com, wei.w.wang@intel.com
Subject: [PATCH v2 6/8] perf/x86/intel/lbr: guest requesting KVM for lbr stack save/restore
Date: Thu,  6 Sep 2018 19:30:54 +0800	[thread overview]
Message-ID: <1536233456-12173-7-git-send-email-wei.w.wang@intel.com> (raw)
In-Reply-To: <1536233456-12173-1-git-send-email-wei.w.wang@intel.com>

This patch adds an interface to enable a guest to request KVM to save
and restore the lbr stack on vCPU context switching.

KVM couldn't capture the info about whether the guest is actively using
the lbr feature via the lbr enable bit in the debugctl MSR, because that
control bit is frequently enabled and disabled by the guest, and in some
csaes, it is disabled even when the guest is actively using the lbr
feature. For example, perf_pmu_sched_task in the guest disables the bit
before reading out the lbr stack. In this case, the bit is disabled though
the guest is still using the lbr feature.

So, a KVM-specific MSR, MSR_KVM_PV_LBR_CTRL, is used by the guest at a
proper place to tell KVM if the LBR is actively in use or not. Basically,
the lbr user callstack mode needs the lbr stack to be saved/restored on a
context switching, so we set the ACTIVE bit of MSR_KVM_PV_LBR_CTRL only
when the user callstack mode is used. The KVM hypervisor will add the lbr
stack save/restore support on vCPU switching after the ACTIVE bit is set.

Signed-off-by: Like Xu <like.xu@intel.com>
Signed-off-by: Wei Wang <wei.w.wang@intel.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/events/intel/lbr.c          | 21 +++++++++++++++++++++
 arch/x86/include/asm/perf_event.h    |  3 +++
 arch/x86/include/uapi/asm/kvm_para.h |  2 ++
 3 files changed, 26 insertions(+)

diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 7c3958e..50921d3 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/perf_event.h>
 #include <linux/types.h>
+#include <linux/kvm_para.h>
 
 #include <asm/perf_event.h>
 #include <asm/msr.h>
@@ -454,6 +455,24 @@ static inline bool branch_user_callstack(unsigned br_sel)
 	return (br_sel & X86_BR_USER) && (br_sel & X86_BR_CALL_STACK);
 }
 
+static inline void set_pv_lbr_ctrl_active(bool active)
+{
+	u64 lbr_ctrl_old, lbr_ctrl_new;
+
+	if (!boot_cpu_has(X86_FEATURE_HYPERVISOR) ||
+	    !kvm_para_has_feature(KVM_FEATURE_PV_LBR_CTRL))
+		return;
+
+	rdmsrl(MSR_KVM_PV_LBR_CTRL, lbr_ctrl_old);
+	if (active)
+		lbr_ctrl_new = lbr_ctrl_old | KVM_PV_LBR_CTRL_ACTIVE;
+	else
+		lbr_ctrl_new = lbr_ctrl_old & ~KVM_PV_LBR_CTRL_ACTIVE;
+
+	if (lbr_ctrl_new != lbr_ctrl_old)
+		wrmsrl(MSR_KVM_PV_LBR_CTRL, lbr_ctrl_new);
+}
+
 void intel_pmu_lbr_add(struct perf_event *event)
 {
 	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
@@ -467,6 +486,7 @@ void intel_pmu_lbr_add(struct perf_event *event)
 	if (branch_user_callstack(cpuc->br_sel) && event->ctx->task_ctx_data) {
 		task_ctx = event->ctx->task_ctx_data;
 		task_ctx->lbr_callstack_users++;
+		set_pv_lbr_ctrl_active(true);
 	}
 
 	/*
@@ -505,6 +525,7 @@ void intel_pmu_lbr_del(struct perf_event *event)
 	    event->ctx->task_ctx_data) {
 		task_ctx = event->ctx->task_ctx_data;
 		task_ctx->lbr_callstack_users--;
+		set_pv_lbr_ctrl_active(false);
 	}
 
 	cpuc->lbr_users--;
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 161165f..9fb0f7e 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -162,6 +162,9 @@ struct x86_pmu_capability {
  */
 #define INTEL_PMC_IDX_FIXED_BTS				(INTEL_PMC_IDX_FIXED + 16)
 
+/* Indicate to the hypervisor that the guest LBR is active */
+#define KVM_PV_LBR_CTRL_ACTIVE		(1UL << 0)
+
 #define GLOBAL_STATUS_COND_CHG				BIT_ULL(63)
 #define GLOBAL_STATUS_BUFFER_OVF			BIT_ULL(62)
 #define GLOBAL_STATUS_UNC_OVF				BIT_ULL(61)
diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h
index 19980ec..87764dd 100644
--- a/arch/x86/include/uapi/asm/kvm_para.h
+++ b/arch/x86/include/uapi/asm/kvm_para.h
@@ -29,6 +29,7 @@
 #define KVM_FEATURE_PV_TLB_FLUSH	9
 #define KVM_FEATURE_ASYNC_PF_VMEXIT	10
 #define KVM_FEATURE_PV_SEND_IPI	11
+#define KVM_FEATURE_PV_LBR_CTRL	12
 
 #define KVM_HINTS_REALTIME      0
 
@@ -47,6 +48,7 @@
 #define MSR_KVM_ASYNC_PF_EN 0x4b564d02
 #define MSR_KVM_STEAL_TIME  0x4b564d03
 #define MSR_KVM_PV_EOI_EN      0x4b564d04
+#define MSR_KVM_PV_LBR_CTRL    0x4b564d05
 
 struct kvm_steal_time {
 	__u64 steal;
-- 
2.7.4


  parent reply	other threads:[~2018-09-06 12:01 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-06 11:30 [PATCH v2 0/8] Guest LBR Enabling Wei Wang
2018-09-06 11:30 ` [PATCH v2 1/8] perf/x86: add a function to get the lbr stack Wei Wang
2018-09-07  3:28   ` Andi Kleen
2018-09-07  6:45     ` Wei Wang
2018-09-06 11:30 ` [PATCH v2 2/8] KVM/x86: KVM_CAP_X86_GUEST_LBR Wei Wang
2018-09-06 11:30 ` [PATCH v2 3/8] KVM/vmx: Pass through the lbr stack to a guest Wei Wang
2018-09-06 11:30 ` [PATCH v2 4/8] KVM/x86: expose MSR_IA32_PERF_CAPABILITIES to the guest Wei Wang
2018-09-06 11:30 ` [PATCH v2 5/8] KVM/x86: enable the guest to access the debugctl msr Wei Wang
2018-09-06 11:30 ` Wei Wang [this message]
2018-09-07  3:27   ` [PATCH v2 6/8] perf/x86/intel/lbr: guest requesting KVM for lbr stack save/restore Andi Kleen
2018-09-07  5:24     ` Wei Wang
2018-09-07 14:10       ` Andi Kleen
2018-09-07 15:20         ` Wang, Wei W
2018-09-07 20:05           ` Andi Kleen
2018-09-08  1:34             ` Wang, Wei W
2018-09-06 11:30 ` [PATCH v2 7/8] KVM: PMU: support to save/restore the guest lbr stack on vCPU switching Wei Wang
2018-09-07 14:36   ` Jann Horn
2018-09-07 15:21     ` Wang, Wei W
2018-09-18  0:58   ` Gonglei (Arei)
2018-09-18  2:56     ` Andi Kleen
2018-09-18  9:57       ` Wei Wang
2018-09-18 10:34         ` Gonglei (Arei)
2018-09-06 11:30 ` [PATCH v2 8/8] perf/x86/intel/lbr: add the guest_lbr boolean to cpuc 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=1536233456-12173-7-git-send-email-wei.w.wang@intel.com \
    --to=wei.w.wang@intel.com \
    --cc=ak@linux.intel.com \
    --cc=kan.liang@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=rkrcmar@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).