All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/15] Introduce Architectural LBR for vPMU
@ 2022-11-25  4:05 Yang Weijiang
  2022-11-25  4:05 ` [PATCH v2 01/15] perf/x86/lbr: Simplify the exposure check for the LBR_INFO registers Yang Weijiang
                   ` (16 more replies)
  0 siblings, 17 replies; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:05 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang

Intel CPU model-specific LBR(Legacy LBR) has evolved to Architectural
LBR(Arch LBR [0]), it's the replacement of legacy LBR on new platforms.
The native support patches were merged into 5.9 kernel tree, and this
patch series is to enable Arch LBR in vPMU so that guest can benefit
from the feature.

The main advantages of Arch LBR are [1]:
- Faster context switching due to XSAVES support and faster reset of
  LBR MSRs via the new DEPTH MSR
- Faster LBR read for a non-PEBS event due to XSAVES support, which
  lowers the overhead of the NMI handler.
- Linux kernel can support the LBR features without knowing the model
  number of the current CPU.

From end user's point of view, the usage of Arch LBR is the same as
the Legacy LBR that has been merged in the mainline.

Note, in this series, there's one restriction for guest Arch LBR, i.e.,
guest can only set its LBR record depth the same as host's. This is due
to the special behavior of MSR_ARCH_LBR_DEPTH: 
1) On write to the MSR, it'll reset all Arch LBR recording MSRs to 0s.
2) XRSTORS resets all record MSRs to 0s if the saved depth mismatches
MSR_ARCH_LBR_DEPTH.
Enforcing the restriction keeps KVM Arch LBR vPMU working flow simple
and straightforward.

Paolo refactored the old series and the resulting patches became the
base of this new series, therefore he's the author of some patches.

[0] https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
[1] https://lore.kernel.org/lkml/1593780569-62993-1-git-send-email-kan.liang@linux.intel.com/

v1:
https://lore.kernel.org/all/20220831223438.413090-1-weijiang.yang@intel.com/

Changes v2:
1. Removed Paolo's SOBs from some patches. [Sean]
2. Modified some patches due to KVM changes, e.g., SMM/vPMU refactor.
3. Rebased to https://git.kernel.org/pub/scm/virt/kvm/kvm.git : queue branch.


Like Xu (3):
  perf/x86/lbr: Simplify the exposure check for the LBR_INFO registers
  KVM: vmx/pmu: Emulate MSR_ARCH_LBR_DEPTH for guest Arch LBR
  KVM: x86: Add XSAVE Support for Architectural LBR

Paolo Bonzini (4):
  KVM: PMU: disable LBR handling if architectural LBR is available
  KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL for guest Arch LBR
  KVM: VMX: Support passthrough of architectural LBRs
  KVM: x86: Refine the matching and clearing logic for supported_xss

Sean Christopherson (1):
  KVM: x86: Report XSS as an MSR to be saved if there are supported
    features

Yang Weijiang (7):
  KVM: x86: Refresh CPUID on writes to MSR_IA32_XSS
  KVM: x86: Add Arch LBR MSRs to msrs_to_save_all list
  KVM: x86/vmx: Check Arch LBR config when return perf capabilities
  KVM: x86/vmx: Disable Arch LBREn bit in #DB and warm reset
  KVM: x86/vmx: Save/Restore guest Arch LBR Ctrl msr at SMM entry/exit
  KVM: x86: Add Arch LBR data MSR access interface
  KVM: x86/cpuid: Advertise Arch LBR feature in CPUID

 arch/x86/events/intel/lbr.c      |   6 +-
 arch/x86/include/asm/kvm_host.h  |   3 +
 arch/x86/include/asm/msr-index.h |   1 +
 arch/x86/include/asm/vmx.h       |   4 +
 arch/x86/kvm/cpuid.c             |  52 +++++++++-
 arch/x86/kvm/smm.c               |   1 +
 arch/x86/kvm/smm.h               |   3 +-
 arch/x86/kvm/vmx/capabilities.h  |   5 +
 arch/x86/kvm/vmx/nested.c        |   8 ++
 arch/x86/kvm/vmx/pmu_intel.c     | 161 +++++++++++++++++++++++++++----
 arch/x86/kvm/vmx/vmx.c           |  74 +++++++++++++-
 arch/x86/kvm/vmx/vmx.h           |   6 +-
 arch/x86/kvm/x86.c               |  27 +++++-
 13 files changed, 316 insertions(+), 35 deletions(-)


base-commit: da5f28e10aa7df1a925dbc10656cc89d9c061358
-- 
2.27.0


^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 01/15] perf/x86/lbr: Simplify the exposure check for the LBR_INFO registers
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
@ 2022-11-25  4:05 ` Yang Weijiang
  2022-12-22 10:57   ` Like Xu
  2022-12-27 11:58   ` [tip: perf/core] " tip-bot2 for Like Xu
  2022-11-25  4:05 ` [PATCH v2 02/15] KVM: x86: Report XSS as an MSR to be saved if there are supported features Yang Weijiang
                   ` (15 subsequent siblings)
  16 siblings, 2 replies; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:05 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang, Like Xu,
	Peter Zijlstra, Andi Kleen

From: Like Xu <like.xu@linux.intel.com>

The x86_pmu.lbr_info is 0 unless explicitly initialized, so there's
no point checking x86_pmu.intel_cap.lbr_format.

Cc: Peter Zijlstra <peterz@infradead.org>
Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Like Xu <like.xu@linux.intel.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 arch/x86/events/intel/lbr.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 4dbde69c423b..e7caabfa1377 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -1606,12 +1606,10 @@ void __init intel_pmu_arch_lbr_init(void)
  */
 void x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
 {
-	int lbr_fmt = x86_pmu.intel_cap.lbr_format;
-
 	lbr->nr = x86_pmu.lbr_nr;
 	lbr->from = x86_pmu.lbr_from;
 	lbr->to = x86_pmu.lbr_to;
-	lbr->info = (lbr_fmt == LBR_FORMAT_INFO) ? x86_pmu.lbr_info : 0;
+	lbr->info = x86_pmu.lbr_info;
 }
 EXPORT_SYMBOL_GPL(x86_perf_get_lbr);
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 02/15] KVM: x86: Report XSS as an MSR to be saved if there are supported features
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
  2022-11-25  4:05 ` [PATCH v2 01/15] perf/x86/lbr: Simplify the exposure check for the LBR_INFO registers Yang Weijiang
@ 2022-11-25  4:05 ` Yang Weijiang
  2022-11-25  4:05 ` [PATCH v2 03/15] KVM: x86: Refresh CPUID on writes to MSR_IA32_XSS Yang Weijiang
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:05 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang, Sean Christopherson

From: Sean Christopherson <sean.j.christopherson@intel.com>

Add MSR_IA32_XSS to the list of MSRs reported to userspace if
supported_xss is non-zero, i.e. KVM supports at least one XSS based
feature.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 arch/x86/kvm/x86.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f18f579ebde8..16726b44061b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1465,6 +1465,7 @@ static const u32 msrs_to_save_all[] = {
 	MSR_F15H_PERF_CTR3, MSR_F15H_PERF_CTR4, MSR_F15H_PERF_CTR5,
 
 	MSR_IA32_XFD, MSR_IA32_XFD_ERR,
+	MSR_IA32_XSS,
 };
 
 static u32 msrs_to_save[ARRAY_SIZE(msrs_to_save_all)];
@@ -7061,6 +7062,10 @@ static void kvm_init_msr_list(void)
 			if (!kvm_cpu_cap_has(X86_FEATURE_XFD))
 				continue;
 			break;
+		case MSR_IA32_XSS:
+			if (!kvm_caps.supported_xss)
+				continue;
+			break;
 		default:
 			break;
 		}
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 03/15] KVM: x86: Refresh CPUID on writes to MSR_IA32_XSS
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
  2022-11-25  4:05 ` [PATCH v2 01/15] perf/x86/lbr: Simplify the exposure check for the LBR_INFO registers Yang Weijiang
  2022-11-25  4:05 ` [PATCH v2 02/15] KVM: x86: Report XSS as an MSR to be saved if there are supported features Yang Weijiang
@ 2022-11-25  4:05 ` Yang Weijiang
  2023-01-26 19:50   ` Sean Christopherson
  2022-11-25  4:05 ` [PATCH v2 04/15] KVM: PMU: disable LBR handling if architectural LBR is available Yang Weijiang
                   ` (13 subsequent siblings)
  16 siblings, 1 reply; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:05 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang, Zhang Yi Z

Updated CPUID.0xD.0x1, which reports the current required storage size
of all features enabled via XCR0 | XSS, when the guest's XSS is modified.

Note, KVM does not yet support any XSS based features, i.e. supported_xss
is guaranteed to be zero at this time.

Co-developed-by: Zhang Yi Z <yi.z.zhang@linux.intel.com>
Signed-off-by: Zhang Yi Z <yi.z.zhang@linux.intel.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 arch/x86/kvm/cpuid.c | 16 +++++++++++++---
 arch/x86/kvm/x86.c   |  6 ++++--
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 6b5912578edd..85e3df6217af 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -272,9 +272,19 @@ static void __kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu, struct kvm_cpuid_e
 		best->ebx = xstate_required_size(vcpu->arch.xcr0, false);
 
 	best = cpuid_entry2_find(entries, nent, 0xD, 1);
-	if (best && (cpuid_entry_has(best, X86_FEATURE_XSAVES) ||
-		     cpuid_entry_has(best, X86_FEATURE_XSAVEC)))
-		best->ebx = xstate_required_size(vcpu->arch.xcr0, true);
+	if (best) {
+		if (cpuid_entry_has(best, X86_FEATURE_XSAVES) ||
+		    cpuid_entry_has(best, X86_FEATURE_XSAVEC))  {
+			u64 xstate = vcpu->arch.xcr0 | vcpu->arch.ia32_xss;
+
+			best->ebx = xstate_required_size(xstate, true);
+		}
+
+		if (!cpuid_entry_has(best, X86_FEATURE_XSAVES)) {
+			best->ecx = 0;
+			best->edx = 0;
+		}
+	}
 
 	best = __kvm_find_kvm_cpuid_features(vcpu, entries, nent);
 	if (kvm_hlt_in_guest(vcpu->kvm) && best &&
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 16726b44061b..888a153e32bc 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3685,8 +3685,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 		 */
 		if (data & ~kvm_caps.supported_xss)
 			return 1;
-		vcpu->arch.ia32_xss = data;
-		kvm_update_cpuid_runtime(vcpu);
+		if (vcpu->arch.ia32_xss != data) {
+			vcpu->arch.ia32_xss = data;
+			kvm_update_cpuid_runtime(vcpu);
+		}
 		break;
 	case MSR_SMI_COUNT:
 		if (!msr_info->host_initiated)
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 04/15] KVM: PMU: disable LBR handling if architectural LBR is available
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
                   ` (2 preceding siblings ...)
  2022-11-25  4:05 ` [PATCH v2 03/15] KVM: x86: Refresh CPUID on writes to MSR_IA32_XSS Yang Weijiang
@ 2022-11-25  4:05 ` Yang Weijiang
  2023-01-27 20:10   ` Sean Christopherson
  2022-11-25  4:05 ` [PATCH v2 05/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_DEPTH for guest Arch LBR Yang Weijiang
                   ` (12 subsequent siblings)
  16 siblings, 1 reply; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:05 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang

From: Paolo Bonzini <pbonzini@redhat.com>

Traditional LBR is absent on CPU models that have architectural LBR, so
disable all processing of traditional LBR MSRs if they are not there.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 arch/x86/kvm/vmx/pmu_intel.c | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index e5cec07ca8d9..905673228932 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -170,19 +170,23 @@ static inline struct kvm_pmc *get_fw_gp_pmc(struct kvm_pmu *pmu, u32 msr)
 static bool intel_pmu_is_valid_lbr_msr(struct kvm_vcpu *vcpu, u32 index)
 {
 	struct x86_pmu_lbr *records = vcpu_to_lbr_records(vcpu);
-	bool ret = false;
 
 	if (!intel_pmu_lbr_is_enabled(vcpu))
-		return ret;
+		return false;
 
-	ret = (index == MSR_LBR_SELECT) || (index == MSR_LBR_TOS) ||
-		(index >= records->from && index < records->from + records->nr) ||
-		(index >= records->to && index < records->to + records->nr);
+	if (!guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) &&
+	    (index == MSR_LBR_SELECT || index == MSR_LBR_TOS))
+		return true;
 
-	if (!ret && records->info)
-		ret = (index >= records->info && index < records->info + records->nr);
+	if ((index >= records->from && index < records->from + records->nr) ||
+	    (index >= records->to && index < records->to + records->nr))
+		return true;
 
-	return ret;
+	if (records->info && index >= records->info &&
+	    index < records->info + records->nr)
+		return true;
+
+	return false;
 }
 
 static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)
@@ -702,6 +706,9 @@ static void vmx_update_intercept_for_lbr_msrs(struct kvm_vcpu *vcpu, bool set)
 			vmx_set_intercept_for_msr(vcpu, lbr->info + i, MSR_TYPE_RW, set);
 	}
 
+	if (guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR))
+		return;
+
 	vmx_set_intercept_for_msr(vcpu, MSR_LBR_SELECT, MSR_TYPE_RW, set);
 	vmx_set_intercept_for_msr(vcpu, MSR_LBR_TOS, MSR_TYPE_RW, set);
 }
@@ -742,10 +749,12 @@ void vmx_passthrough_lbr_msrs(struct kvm_vcpu *vcpu)
 {
 	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
 	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
+	bool lbr_enable = !guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) &&
+		(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR);
 
 	if (!lbr_desc->event) {
 		vmx_disable_lbr_msrs_passthrough(vcpu);
-		if (vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR)
+		if (lbr_enable)
 			goto warn;
 		if (test_bit(INTEL_PMC_IDX_FIXED_VLBR, pmu->pmc_in_use))
 			goto warn;
@@ -768,7 +777,10 @@ void vmx_passthrough_lbr_msrs(struct kvm_vcpu *vcpu)
 
 static void intel_pmu_cleanup(struct kvm_vcpu *vcpu)
 {
-	if (!(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR))
+	bool lbr_enable = !guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) &&
+		(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR);
+
+	if (!lbr_enable)
 		intel_pmu_release_guest_lbr_event(vcpu);
 }
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 05/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_DEPTH for guest Arch LBR
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
                   ` (3 preceding siblings ...)
  2022-11-25  4:05 ` [PATCH v2 04/15] KVM: PMU: disable LBR handling if architectural LBR is available Yang Weijiang
@ 2022-11-25  4:05 ` Yang Weijiang
  2022-12-22 11:00   ` Like Xu
                     ` (2 more replies)
  2022-11-25  4:05 ` [PATCH v2 06/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL " Yang Weijiang
                   ` (11 subsequent siblings)
  16 siblings, 3 replies; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:05 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang, Like Xu

From: Like Xu <like.xu@linux.intel.com>

The number of Arch LBR entries available is determined by the value
in host MSR_ARCH_LBR_DEPTH.DEPTH. The supported LBR depth values are
enumerated in CPUID.(EAX=01CH, ECX=0):EAX[7:0]. For each bit "n" set
in this field, the MSR_ARCH_LBR_DEPTH.DEPTH value of "8*(n+1)" is
supported. In the first generation of Arch LBR, max entry size is 32,
host configures the max size and guest always honors the setting.

Write to MSR_ARCH_LBR_DEPTH has side-effect, all LBR entries are reset
to 0. Kernel PMU driver can leverage this effect to do fask reset to
LBR record MSRs. KVM allows guest to achieve it when Arch LBR records
MSRs are passed through to the guest.

Signed-off-by: Like Xu <like.xu@linux.intel.com>
Co-developed-by: Yang Weijiang <weijiang.yang@intel.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 arch/x86/include/asm/kvm_host.h |  3 ++
 arch/x86/kvm/vmx/pmu_intel.c    | 58 +++++++++++++++++++++++++++++++--
 2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 70af7240a1d5..2dba2fdd9cdc 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -571,6 +571,9 @@ struct kvm_pmu {
 	 * redundant check before cleanup if guest don't use vPMU at all.
 	 */
 	u8 event_count;
+
+	/* Guest arch lbr depth supported by KVM. */
+	u64 kvm_arch_lbr_depth;
 };
 
 struct kvm_pmu_ops;
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index 905673228932..0c78cb4b72be 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -178,6 +178,10 @@ static bool intel_pmu_is_valid_lbr_msr(struct kvm_vcpu *vcpu, u32 index)
 	    (index == MSR_LBR_SELECT || index == MSR_LBR_TOS))
 		return true;
 
+	if (index == MSR_ARCH_LBR_DEPTH)
+		return kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
+		       guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR);
+
 	if ((index >= records->from && index < records->from + records->nr) ||
 	    (index >= records->to && index < records->to + records->nr))
 		return true;
@@ -345,6 +349,7 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 {
 	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
 	struct kvm_pmc *pmc;
+	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
 	u32 msr = msr_info->index;
 
 	switch (msr) {
@@ -369,6 +374,9 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 	case MSR_PEBS_DATA_CFG:
 		msr_info->data = pmu->pebs_data_cfg;
 		return 0;
+	case MSR_ARCH_LBR_DEPTH:
+		msr_info->data = lbr_desc->records.nr;
+		return 0;
 	default:
 		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
 		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
@@ -395,6 +403,7 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 {
 	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
 	struct kvm_pmc *pmc;
+	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
 	u32 msr = msr_info->index;
 	u64 data = msr_info->data;
 	u64 reserved_bits, diff;
@@ -456,6 +465,24 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 			return 0;
 		}
 		break;
+	case MSR_ARCH_LBR_DEPTH:
+		if (!pmu->kvm_arch_lbr_depth && !msr_info->host_initiated)
+			return 1;
+		/*
+		 * When guest/host depth are different, the handling would be tricky,
+		 * so only max depth is supported for both host and guest.
+		 */
+		if (data != pmu->kvm_arch_lbr_depth)
+			return 1;
+
+		lbr_desc->records.nr = data;
+		/*
+		 * Writing depth MSR from guest could either setting the
+		 * MSR or resetting the LBR records with the side-effect.
+		 */
+		if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR))
+			wrmsrl(MSR_ARCH_LBR_DEPTH, lbr_desc->records.nr);
+		return 0;
 	default:
 		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
 		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
@@ -506,6 +533,32 @@ static void setup_fixed_pmc_eventsel(struct kvm_pmu *pmu)
 	}
 }
 
+static bool cpuid_enable_lbr(struct kvm_vcpu *vcpu)
+{
+	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+	struct kvm_cpuid_entry2 *entry;
+	int depth_bit;
+
+	if (!kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR))
+		return !static_cpu_has(X86_FEATURE_ARCH_LBR) &&
+			cpuid_model_is_consistent(vcpu);
+
+	pmu->kvm_arch_lbr_depth = 0;
+	if (!guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR))
+		return false;
+
+	entry = kvm_find_cpuid_entry(vcpu, 0x1C);
+	if (!entry)
+		return false;
+
+	depth_bit = fls(cpuid_eax(0x1C) & 0xff);
+	if ((entry->eax & 0xff) != (1 << (depth_bit - 1)))
+		return false;
+
+	pmu->kvm_arch_lbr_depth = depth_bit * 8;
+	return true;
+}
+
 static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
 {
 	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
@@ -589,9 +642,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
 	bitmap_set(pmu->all_valid_pmc_idx,
 		INTEL_PMC_MAX_GENERIC, pmu->nr_arch_fixed_counters);
 
-	perf_capabilities = vcpu_get_perf_capabilities(vcpu);
-	if (cpuid_model_is_consistent(vcpu) &&
-	    (perf_capabilities & PMU_CAP_LBR_FMT))
+	if (cpuid_enable_lbr(vcpu))
 		x86_perf_get_lbr(&lbr_desc->records);
 	else
 		lbr_desc->records.nr = 0;
@@ -599,6 +650,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
 	if (lbr_desc->records.nr)
 		bitmap_set(pmu->all_valid_pmc_idx, INTEL_PMC_IDX_FIXED_VLBR, 1);
 
+	perf_capabilities = vcpu_get_perf_capabilities(vcpu);
 	if (perf_capabilities & PERF_CAP_PEBS_FORMAT) {
 		if (perf_capabilities & PERF_CAP_PEBS_BASELINE) {
 			pmu->pebs_enable_mask = counter_mask;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 06/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL for guest Arch LBR
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
                   ` (4 preceding siblings ...)
  2022-11-25  4:05 ` [PATCH v2 05/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_DEPTH for guest Arch LBR Yang Weijiang
@ 2022-11-25  4:05 ` Yang Weijiang
  2022-12-22 11:09   ` Like Xu
                     ` (3 more replies)
  2022-11-25  4:05 ` [PATCH v2 07/15] KVM: VMX: Support passthrough of architectural LBRs Yang Weijiang
                   ` (10 subsequent siblings)
  16 siblings, 4 replies; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:05 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang, Like Xu

From: Paolo Bonzini <pbonzini@redhat.com>

Arch LBR is enabled by setting MSR_ARCH_LBR_CTL.LBREn to 1. A new guest
state field named "Guest IA32_LBR_CTL" is added to enhance guest LBR usage.
When guest Arch LBR is enabled, a guest LBR event will be created like the
model-specific LBR does. Clear guest LBR enable bit on host PMI handling so
guest can see expected config.

On processors that support Arch LBR, MSR_IA32_DEBUGCTLMSR[bit 0] has no
meaning. It can be written to 0 or 1, but reads will always return 0.
Like IA32_DEBUGCTL, IA32_ARCH_LBR_CTL msr is also preserved on INIT.

Regardless of the Arch LBR or legacy LBR, when the LBR_EN bit 0 of the
corresponding control MSR is set to 1, LBR recording will be enabled.

Signed-off-by: Like Xu <like.xu@linux.intel.com>
Co-developed-by: Like Xu <like.xu@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Co-developed-by: Yang Weijiang <weijiang.yang@intel.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 arch/x86/events/intel/lbr.c      |  2 -
 arch/x86/include/asm/msr-index.h |  1 +
 arch/x86/include/asm/vmx.h       |  2 +
 arch/x86/kvm/vmx/pmu_intel.c     | 67 ++++++++++++++++++++++++++++----
 arch/x86/kvm/vmx/vmx.c           |  7 ++++
 5 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index e7caabfa1377..ef589984b907 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -100,8 +100,6 @@
 	 ARCH_LBR_RETURN		|\
 	 ARCH_LBR_OTHER_BRANCH)
 
-#define ARCH_LBR_CTL_MASK			0x7f000e
-
 static void intel_pmu_lbr_filter(struct cpu_hw_events *cpuc);
 
 static __always_inline bool is_lbr_call_stack_bit_set(u64 config)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 10ac52705892..2a9eaab2fdb1 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -220,6 +220,7 @@
 #define LBR_INFO_BR_TYPE		(0xfull << LBR_INFO_BR_TYPE_OFFSET)
 
 #define MSR_ARCH_LBR_CTL		0x000014ce
+#define ARCH_LBR_CTL_MASK		0x7f000e
 #define ARCH_LBR_CTL_LBREN		BIT(0)
 #define ARCH_LBR_CTL_CPL_OFFSET		1
 #define ARCH_LBR_CTL_CPL		(0x3ull << ARCH_LBR_CTL_CPL_OFFSET)
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index 498dc600bd5c..8502c068202c 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -257,6 +257,8 @@ enum vmcs_field {
 	GUEST_BNDCFGS_HIGH              = 0x00002813,
 	GUEST_IA32_RTIT_CTL		= 0x00002814,
 	GUEST_IA32_RTIT_CTL_HIGH	= 0x00002815,
+	GUEST_IA32_LBR_CTL		= 0x00002816,
+	GUEST_IA32_LBR_CTL_HIGH		= 0x00002817,
 	HOST_IA32_PAT			= 0x00002c00,
 	HOST_IA32_PAT_HIGH		= 0x00002c01,
 	HOST_IA32_EFER			= 0x00002c02,
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index 0c78cb4b72be..b57944d5e7d8 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -19,6 +19,7 @@
 #include "pmu.h"
 
 #define MSR_PMC_FULL_WIDTH_BIT      (MSR_IA32_PMC0 - MSR_IA32_PERFCTR0)
+#define KVM_ARCH_LBR_CTL_MASK  (ARCH_LBR_CTL_MASK | ARCH_LBR_CTL_LBREN)
 
 static struct kvm_event_hw_type_mapping intel_arch_events[] = {
 	[0] = { 0x3c, 0x00, PERF_COUNT_HW_CPU_CYCLES },
@@ -178,7 +179,7 @@ static bool intel_pmu_is_valid_lbr_msr(struct kvm_vcpu *vcpu, u32 index)
 	    (index == MSR_LBR_SELECT || index == MSR_LBR_TOS))
 		return true;
 
-	if (index == MSR_ARCH_LBR_DEPTH)
+	if (index == MSR_ARCH_LBR_DEPTH || index == MSR_ARCH_LBR_CTL)
 		return kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
 		       guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR);
 
@@ -345,6 +346,30 @@ static bool intel_pmu_handle_lbr_msrs_access(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+static bool arch_lbr_ctl_is_valid(struct kvm_vcpu *vcpu, u64 ctl)
+{
+	struct kvm_cpuid_entry2 *entry;
+	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+
+	if (!pmu->kvm_arch_lbr_depth)
+		return false;
+
+	if (ctl & ~KVM_ARCH_LBR_CTL_MASK)
+		return false;
+
+	entry = kvm_find_cpuid_entry(vcpu, 0x1c);
+	if (!entry)
+		return false;
+
+	if (!(entry->ebx & BIT(0)) && (ctl & ARCH_LBR_CTL_CPL))
+		return false;
+	if (!(entry->ebx & BIT(2)) && (ctl & ARCH_LBR_CTL_STACK))
+		return false;
+	if (!(entry->ebx & BIT(1)) && (ctl & ARCH_LBR_CTL_FILTER))
+		return false;
+	return true;
+}
+
 static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 {
 	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
@@ -377,6 +402,14 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 	case MSR_ARCH_LBR_DEPTH:
 		msr_info->data = lbr_desc->records.nr;
 		return 0;
+	case MSR_ARCH_LBR_CTL:
+		if (!kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR)) {
+			WARN_ON_ONCE(!msr_info->host_initiated);
+			msr_info->data = 0;
+		} else {
+			msr_info->data = vmcs_read64(GUEST_IA32_LBR_CTL);
+		}
+		return 0;
 	default:
 		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
 		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
@@ -483,6 +516,18 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 		if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR))
 			wrmsrl(MSR_ARCH_LBR_DEPTH, lbr_desc->records.nr);
 		return 0;
+	case MSR_ARCH_LBR_CTL:
+		if (msr_info->host_initiated && !pmu->kvm_arch_lbr_depth)
+			return data != 0;
+
+		if (!arch_lbr_ctl_is_valid(vcpu, data))
+			break;
+
+		vmcs_write64(GUEST_IA32_LBR_CTL, data);
+		if (intel_pmu_lbr_is_enabled(vcpu) && !lbr_desc->event &&
+		    (data & ARCH_LBR_CTL_LBREN))
+			intel_pmu_create_guest_lbr_event(vcpu);
+		return 0;
 	default:
 		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
 		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
@@ -727,12 +772,16 @@ static void intel_pmu_reset(struct kvm_vcpu *vcpu)
  */
 static void intel_pmu_legacy_freezing_lbrs_on_pmi(struct kvm_vcpu *vcpu)
 {
-	u64 data = vmcs_read64(GUEST_IA32_DEBUGCTL);
+	u32 lbr_ctl_field = GUEST_IA32_DEBUGCTL;
 
-	if (data & DEBUGCTLMSR_FREEZE_LBRS_ON_PMI) {
-		data &= ~DEBUGCTLMSR_LBR;
-		vmcs_write64(GUEST_IA32_DEBUGCTL, data);
-	}
+	if (!(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_FREEZE_LBRS_ON_PMI))
+		return;
+
+	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
+	    guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR))
+		lbr_ctl_field = GUEST_IA32_LBR_CTL;
+
+	vmcs_write64(lbr_ctl_field, vmcs_read64(lbr_ctl_field) & ~0x1ULL);
 }
 
 static void intel_pmu_deliver_pmi(struct kvm_vcpu *vcpu)
@@ -801,7 +850,8 @@ void vmx_passthrough_lbr_msrs(struct kvm_vcpu *vcpu)
 {
 	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
 	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
-	bool lbr_enable = !guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) &&
+	bool lbr_enable = guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) ?
+		(vmcs_read64(GUEST_IA32_LBR_CTL) & ARCH_LBR_CTL_LBREN) :
 		(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR);
 
 	if (!lbr_desc->event) {
@@ -829,7 +879,8 @@ void vmx_passthrough_lbr_msrs(struct kvm_vcpu *vcpu)
 
 static void intel_pmu_cleanup(struct kvm_vcpu *vcpu)
 {
-	bool lbr_enable = !guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) &&
+	bool lbr_enable = guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) ?
+		(vmcs_read64(GUEST_IA32_LBR_CTL) & ARCH_LBR_CTL_LBREN) :
 		(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR);
 
 	if (!lbr_enable)
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index cea8c07f5229..1ae2efc29546 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -2120,6 +2120,13 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 						VM_EXIT_SAVE_DEBUG_CONTROLS)
 			get_vmcs12(vcpu)->guest_ia32_debugctl = data;
 
+		/*
+		 * For Arch LBR, IA32_DEBUGCTL[bit 0] has no meaning.
+		 * It can be written to 0 or 1, but reads will always return 0.
+		 */
+		if (guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR))
+			data &= ~DEBUGCTLMSR_LBR;
+
 		vmcs_write64(GUEST_IA32_DEBUGCTL, data);
 		if (intel_pmu_lbr_is_enabled(vcpu) && !to_vmx(vcpu)->lbr_desc.event &&
 		    (data & DEBUGCTLMSR_LBR))
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 07/15] KVM: VMX: Support passthrough of architectural LBRs
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
                   ` (5 preceding siblings ...)
  2022-11-25  4:05 ` [PATCH v2 06/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL " Yang Weijiang
@ 2022-11-25  4:05 ` Yang Weijiang
  2022-11-25  4:05 ` [PATCH v2 08/15] KVM: x86: Add Arch LBR MSRs to msrs_to_save_all list Yang Weijiang
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:05 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang

From: Paolo Bonzini <pbonzini@redhat.com>

MSR_ARCH_LBR_* can be pointed to by records->from, records->to and
records->info, so list them in is_valid_passthrough_msr.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 arch/x86/kvm/vmx/vmx.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 1ae2efc29546..9bd52ad3bbf4 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -638,6 +638,9 @@ static bool is_valid_passthrough_msr(u32 msr)
 	case MSR_LBR_NHM_TO ... MSR_LBR_NHM_TO + 31:
 	case MSR_LBR_CORE_FROM ... MSR_LBR_CORE_FROM + 8:
 	case MSR_LBR_CORE_TO ... MSR_LBR_CORE_TO + 8:
+	case MSR_ARCH_LBR_FROM_0 ... MSR_ARCH_LBR_FROM_0 + 31:
+	case MSR_ARCH_LBR_TO_0 ... MSR_ARCH_LBR_TO_0 + 31:
+	case MSR_ARCH_LBR_INFO_0 ... MSR_ARCH_LBR_INFO_0 + 31:
 		/* LBR MSRs. These are handled in vmx_update_intercept_for_lbr_msrs() */
 		return true;
 	}
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 08/15] KVM: x86: Add Arch LBR MSRs to msrs_to_save_all list
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
                   ` (6 preceding siblings ...)
  2022-11-25  4:05 ` [PATCH v2 07/15] KVM: VMX: Support passthrough of architectural LBRs Yang Weijiang
@ 2022-11-25  4:05 ` Yang Weijiang
  2023-01-27 21:43   ` Sean Christopherson
  2022-11-25  4:05 ` [PATCH v2 09/15] KVM: x86: Refine the matching and clearing logic for supported_xss Yang Weijiang
                   ` (8 subsequent siblings)
  16 siblings, 1 reply; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:05 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang

Arch LBR MSR_ARCH_LBR_DEPTH and MSR_ARCH_LBR_CTL are queried by
userspace application before it wants to {save|restore} the Arch LBR
data. Other LBR related data MSRs are omitted here intentionally due
to lengthy list(32*3). Userspace can still use KVM_{GET|SET}_MSRS to
access them if necessary.

Suggested-by: Jim Mattson <jmattson@google.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 arch/x86/kvm/x86.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 888a153e32bc..74c858eaa1ea 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1466,6 +1466,7 @@ static const u32 msrs_to_save_all[] = {
 
 	MSR_IA32_XFD, MSR_IA32_XFD_ERR,
 	MSR_IA32_XSS,
+	MSR_ARCH_LBR_CTL, MSR_ARCH_LBR_DEPTH,
 };
 
 static u32 msrs_to_save[ARRAY_SIZE(msrs_to_save_all)];
@@ -3877,6 +3878,8 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 	case MSR_IA32_PEBS_ENABLE:
 	case MSR_IA32_DS_AREA:
 	case MSR_PEBS_DATA_CFG:
+	case MSR_ARCH_LBR_CTL:
+	case MSR_ARCH_LBR_DEPTH:
 	case MSR_F15H_PERF_CTL0 ... MSR_F15H_PERF_CTR5:
 		if (kvm_pmu_is_valid_msr(vcpu, msr))
 			return kvm_pmu_set_msr(vcpu, msr_info);
@@ -3980,6 +3983,8 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 	case MSR_IA32_PEBS_ENABLE:
 	case MSR_IA32_DS_AREA:
 	case MSR_PEBS_DATA_CFG:
+	case MSR_ARCH_LBR_CTL:
+	case MSR_ARCH_LBR_DEPTH:
 	case MSR_F15H_PERF_CTL0 ... MSR_F15H_PERF_CTR5:
 		if (kvm_pmu_is_valid_msr(vcpu, msr_info->index))
 			return kvm_pmu_get_msr(vcpu, msr_info);
@@ -7068,6 +7073,11 @@ static void kvm_init_msr_list(void)
 			if (!kvm_caps.supported_xss)
 				continue;
 			break;
+		case MSR_ARCH_LBR_DEPTH:
+		case MSR_ARCH_LBR_CTL:
+			if (!kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR))
+				continue;
+			break;
 		default:
 			break;
 		}
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 09/15] KVM: x86: Refine the matching and clearing logic for supported_xss
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
                   ` (7 preceding siblings ...)
  2022-11-25  4:05 ` [PATCH v2 08/15] KVM: x86: Add Arch LBR MSRs to msrs_to_save_all list Yang Weijiang
@ 2022-11-25  4:05 ` Yang Weijiang
  2023-01-27 21:46   ` Sean Christopherson
  2022-11-25  4:05 ` [PATCH v2 10/15] KVM: x86/vmx: Check Arch LBR config when return perf capabilities Yang Weijiang
                   ` (7 subsequent siblings)
  16 siblings, 1 reply; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:05 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang

From: Paolo Bonzini <pbonzini@redhat.com>

Refine the code path of the existing clearing of supported_xss in this way:
initialize the supported_xss with the filter of KVM_SUPPORTED_XSS mask and
update its value in a bit clear manner (rather than bit setting).

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Like Xu <like.xu@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 arch/x86/kvm/vmx/vmx.c | 5 +++--
 arch/x86/kvm/x86.c     | 6 +++++-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 9bd52ad3bbf4..2ab4c33b5008 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -7738,9 +7738,10 @@ static __init void vmx_set_cpu_caps(void)
 		kvm_cpu_cap_set(X86_FEATURE_UMIP);
 
 	/* CPUID 0xD.1 */
-	kvm_caps.supported_xss = 0;
-	if (!cpu_has_vmx_xsaves())
+	if (!cpu_has_vmx_xsaves()) {
 		kvm_cpu_cap_clear(X86_FEATURE_XSAVES);
+		kvm_caps.supported_xss = 0;
+	}
 
 	/* CPUID 0x80000001 and 0x7 (RDPID) */
 	if (!cpu_has_vmx_rdtscp()) {
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 74c858eaa1ea..889be0c9176d 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -217,6 +217,8 @@ static struct kvm_user_return_msrs __percpu *user_return_msrs;
 				| XFEATURE_MASK_BNDCSR | XFEATURE_MASK_AVX512 \
 				| XFEATURE_MASK_PKRU | XFEATURE_MASK_XTILE)
 
+#define KVM_SUPPORTED_XSS     0
+
 u64 __read_mostly host_efer;
 EXPORT_SYMBOL_GPL(host_efer);
 
@@ -11999,8 +12001,10 @@ int kvm_arch_hardware_setup(void *opaque)
 
 	rdmsrl_safe(MSR_EFER, &host_efer);
 
-	if (boot_cpu_has(X86_FEATURE_XSAVES))
+	if (boot_cpu_has(X86_FEATURE_XSAVES)) {
 		rdmsrl(MSR_IA32_XSS, host_xss);
+		kvm_caps.supported_xss = host_xss & KVM_SUPPORTED_XSS;
+	}
 
 	kvm_init_pmu_capability();
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 10/15] KVM: x86/vmx: Check Arch LBR config when return perf capabilities
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
                   ` (8 preceding siblings ...)
  2022-11-25  4:05 ` [PATCH v2 09/15] KVM: x86: Refine the matching and clearing logic for supported_xss Yang Weijiang
@ 2022-11-25  4:05 ` Yang Weijiang
  2022-12-22 11:06   ` Like Xu
  2023-01-27 22:04   ` Sean Christopherson
  2022-11-25  4:06 ` [PATCH v2 11/15] KVM: x86: Add XSAVE Support for Architectural LBR Yang Weijiang
                   ` (6 subsequent siblings)
  16 siblings, 2 replies; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:05 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang, Like Xu

Two new bit fields(VM_EXIT_CLEAR_IA32_LBR_CTL, VM_ENTRY_LOAD_IA32_LBR_CTL)
are added to support guest Arch LBR. These two bits should be set in order
to make Arch LBR workable in both guest and host. Since we don't support
Arch LBR in nested guest, clear the two bits before run L2 VM.

Co-developed-by: Like Xu <like.xu@linux.intel.com>
Signed-off-by: Like Xu <like.xu@linux.intel.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 arch/x86/include/asm/vmx.h      |  2 ++
 arch/x86/kvm/vmx/capabilities.h |  5 +++++
 arch/x86/kvm/vmx/nested.c       |  8 ++++++++
 arch/x86/kvm/vmx/vmx.c          | 11 +++++++++++
 arch/x86/kvm/vmx/vmx.h          |  6 ++++--
 5 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index 8502c068202c..59f7c6baffd2 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -102,6 +102,7 @@
 #define VM_EXIT_CLEAR_BNDCFGS                   0x00800000
 #define VM_EXIT_PT_CONCEAL_PIP			0x01000000
 #define VM_EXIT_CLEAR_IA32_RTIT_CTL		0x02000000
+#define VM_EXIT_CLEAR_IA32_LBR_CTL		0x04000000
 
 #define VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR	0x00036dff
 
@@ -115,6 +116,7 @@
 #define VM_ENTRY_LOAD_BNDCFGS                   0x00010000
 #define VM_ENTRY_PT_CONCEAL_PIP			0x00020000
 #define VM_ENTRY_LOAD_IA32_RTIT_CTL		0x00040000
+#define VM_ENTRY_LOAD_IA32_LBR_CTL		0x00200000
 
 #define VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR	0x000011ff
 
diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h
index cd2ac9536c99..5affd2b5123e 100644
--- a/arch/x86/kvm/vmx/capabilities.h
+++ b/arch/x86/kvm/vmx/capabilities.h
@@ -395,6 +395,11 @@ static inline bool vmx_pebs_supported(void)
 	return boot_cpu_has(X86_FEATURE_PEBS) && kvm_pmu_cap.pebs_ept;
 }
 
+static inline bool cpu_has_vmx_arch_lbr(void)
+{
+	return vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_LBR_CTL;
+}
+
 static inline bool cpu_has_notify_vmexit(void)
 {
 	return vmcs_config.cpu_based_2nd_exec_ctrl &
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index b28be793de29..59bdd9873fb5 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -2360,6 +2360,10 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0
 		if (guest_efer != host_efer)
 			exec_control |= VM_ENTRY_LOAD_IA32_EFER;
 	}
+
+	if (cpu_has_vmx_arch_lbr())
+		exec_control &= ~VM_ENTRY_LOAD_IA32_LBR_CTL;
+
 	vm_entry_controls_set(vmx, exec_control);
 
 	/*
@@ -2374,6 +2378,10 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0
 		exec_control |= VM_EXIT_LOAD_IA32_EFER;
 	else
 		exec_control &= ~VM_EXIT_LOAD_IA32_EFER;
+
+	if (cpu_has_vmx_arch_lbr())
+		exec_control &= ~VM_EXIT_CLEAR_IA32_LBR_CTL;
+
 	vm_exit_controls_set(vmx, exec_control);
 
 	/*
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 2ab4c33b5008..359da38a19a1 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -2599,6 +2599,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf,
 		{ VM_ENTRY_LOAD_IA32_EFER,		VM_EXIT_LOAD_IA32_EFER },
 		{ VM_ENTRY_LOAD_BNDCFGS,		VM_EXIT_CLEAR_BNDCFGS },
 		{ VM_ENTRY_LOAD_IA32_RTIT_CTL,		VM_EXIT_CLEAR_IA32_RTIT_CTL },
+		{ VM_ENTRY_LOAD_IA32_LBR_CTL, 		VM_EXIT_CLEAR_IA32_LBR_CTL },
 	};
 
 	memset(vmcs_conf, 0, sizeof(*vmcs_conf));
@@ -4794,6 +4795,9 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
 	vpid_sync_context(vmx->vpid);
 
 	vmx_update_fb_clear_dis(vcpu, vmx);
+
+	if (!init_event && cpu_has_vmx_arch_lbr())
+		vmcs_write64(GUEST_IA32_LBR_CTL, 0);
 }
 
 static void vmx_enable_irq_window(struct kvm_vcpu *vcpu)
@@ -6191,6 +6195,10 @@ void dump_vmcs(struct kvm_vcpu *vcpu)
 	    vmentry_ctl & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL)
 		pr_err("PerfGlobCtl = 0x%016llx\n",
 		       vmcs_read64(GUEST_IA32_PERF_GLOBAL_CTRL));
+	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
+	    vmentry_ctl & VM_ENTRY_LOAD_IA32_LBR_CTL)
+		pr_err("ArchLBRCtl = 0x%016llx\n",
+		       vmcs_read64(GUEST_IA32_LBR_CTL));
 	if (vmentry_ctl & VM_ENTRY_LOAD_BNDCFGS)
 		pr_err("BndCfgS = 0x%016llx\n", vmcs_read64(GUEST_BNDCFGS));
 	pr_err("Interruptibility = %08x  ActivityState = %08x\n",
@@ -7700,6 +7708,9 @@ static u64 vmx_get_perf_capabilities(void)
 			perf_cap &= ~PERF_CAP_PEBS_BASELINE;
 	}
 
+	if (boot_cpu_has(X86_FEATURE_ARCH_LBR) && !cpu_has_vmx_arch_lbr())
+		perf_cap &= ~PMU_CAP_LBR_FMT;
+
 	return perf_cap;
 }
 
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index a3da84f4ea45..f68c8a53a248 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -493,7 +493,8 @@ static inline u8 vmx_get_rvi(void)
 	 VM_ENTRY_LOAD_IA32_EFER |					\
 	 VM_ENTRY_LOAD_BNDCFGS |					\
 	 VM_ENTRY_PT_CONCEAL_PIP |					\
-	 VM_ENTRY_LOAD_IA32_RTIT_CTL)
+	 VM_ENTRY_LOAD_IA32_RTIT_CTL |					\
+	 VM_ENTRY_LOAD_IA32_LBR_CTL)
 
 #define __KVM_REQUIRED_VMX_VM_EXIT_CONTROLS				\
 	(VM_EXIT_SAVE_DEBUG_CONTROLS |					\
@@ -515,7 +516,8 @@ static inline u8 vmx_get_rvi(void)
 	       VM_EXIT_LOAD_IA32_EFER |					\
 	       VM_EXIT_CLEAR_BNDCFGS |					\
 	       VM_EXIT_PT_CONCEAL_PIP |					\
-	       VM_EXIT_CLEAR_IA32_RTIT_CTL)
+	       VM_EXIT_CLEAR_IA32_RTIT_CTL |				\
+	       VM_EXIT_CLEAR_IA32_LBR_CTL)
 
 #define KVM_REQUIRED_VMX_PIN_BASED_VM_EXEC_CONTROL			\
 	(PIN_BASED_EXT_INTR_MASK |					\
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 11/15] KVM: x86: Add XSAVE Support for Architectural LBR
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
                   ` (9 preceding siblings ...)
  2022-11-25  4:05 ` [PATCH v2 10/15] KVM: x86/vmx: Check Arch LBR config when return perf capabilities Yang Weijiang
@ 2022-11-25  4:06 ` Yang Weijiang
  2023-01-27 22:07   ` Sean Christopherson
  2022-11-25  4:06 ` [PATCH v2 12/15] KVM: x86/vmx: Disable Arch LBREn bit in #DB and warm reset Yang Weijiang
                   ` (5 subsequent siblings)
  16 siblings, 1 reply; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:06 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang, Like Xu

From: Like Xu <like.xu@linux.intel.com>

On processors supporting XSAVES and XRSTORS, Architectural LBR XSAVE
support is enumerated from CPUID.(EAX=0DH, ECX=1):ECX[bit 15].
The detailed sub-leaf for Arch LBR is enumerated in CPUID.(0DH, 0FH).

XSAVES provides a faster means than RDMSR for guest to read all LBRs.
When guest IA32_XSS[bit 15] is set, the Arch LBR state can be saved using
XSAVES and restored by XRSTORS with the appropriate RFBM.

Signed-off-by: Like Xu <like.xu@linux.intel.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 arch/x86/kvm/vmx/vmx.c | 4 ++++
 arch/x86/kvm/x86.c     | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 359da38a19a1..3bc892e8cf7a 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -7733,6 +7733,10 @@ static __init void vmx_set_cpu_caps(void)
 		kvm_cpu_cap_check_and_set(X86_FEATURE_DS);
 		kvm_cpu_cap_check_and_set(X86_FEATURE_DTES64);
 	}
+	if (!cpu_has_vmx_arch_lbr()) {
+		kvm_cpu_cap_clear(X86_FEATURE_ARCH_LBR);
+		kvm_caps.supported_xss &= ~XFEATURE_MASK_LBR;
+	}
 
 	if (!enable_pmu)
 		kvm_cpu_cap_clear(X86_FEATURE_PDCM);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 889be0c9176d..38df08d9d0cb 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -217,7 +217,7 @@ static struct kvm_user_return_msrs __percpu *user_return_msrs;
 				| XFEATURE_MASK_BNDCSR | XFEATURE_MASK_AVX512 \
 				| XFEATURE_MASK_PKRU | XFEATURE_MASK_XTILE)
 
-#define KVM_SUPPORTED_XSS     0
+#define KVM_SUPPORTED_XSS     XFEATURE_MASK_LBR
 
 u64 __read_mostly host_efer;
 EXPORT_SYMBOL_GPL(host_efer);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 12/15] KVM: x86/vmx: Disable Arch LBREn bit in #DB and warm reset
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
                   ` (10 preceding siblings ...)
  2022-11-25  4:06 ` [PATCH v2 11/15] KVM: x86: Add XSAVE Support for Architectural LBR Yang Weijiang
@ 2022-11-25  4:06 ` Yang Weijiang
  2022-12-22 11:22   ` Like Xu
  2023-01-27 22:09   ` Sean Christopherson
  2022-11-25  4:06 ` [PATCH v2 13/15] KVM: x86/vmx: Save/Restore guest Arch LBR Ctrl msr at SMM entry/exit Yang Weijiang
                   ` (4 subsequent siblings)
  16 siblings, 2 replies; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:06 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang

Per SDM 3B, Chapter 18:
“On a debug breakpoint event (#DB), IA32_LBR_CTL.LBREn is cleared.”
and "On a warm reset, all LBR MSRs, including IA32_LBR_DEPTH, have their
values preserved. However, IA32_LBR_CTL.LBREn is cleared to 0, disabling
LBRs.", clear the bit manually before inject #DB or when vCPU is in warm
reset.

Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 arch/x86/kvm/vmx/vmx.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 3bc892e8cf7a..6ad765ea4059 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -1695,6 +1695,20 @@ static void vmx_clear_hlt(struct kvm_vcpu *vcpu)
 		vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE);
 }
 
+static void disable_arch_lbr_ctl(struct kvm_vcpu *vcpu)
+{
+	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
+	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+
+	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
+	    test_bit(INTEL_PMC_IDX_FIXED_VLBR, pmu->pmc_in_use) &&
+	    lbr_desc->event) {
+		u64 ctl = vmcs_read64(GUEST_IA32_LBR_CTL);
+
+		vmcs_write64(GUEST_IA32_LBR_CTL, ctl & ~ARCH_LBR_CTL_LBREN);
+	}
+}
+
 static void vmx_inject_exception(struct kvm_vcpu *vcpu)
 {
 	struct kvm_queued_exception *ex = &vcpu->arch.exception;
@@ -1738,6 +1752,9 @@ static void vmx_inject_exception(struct kvm_vcpu *vcpu)
 	vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
 
 	vmx_clear_hlt(vcpu);
+
+	if (ex->vector == DB_VECTOR)
+		disable_arch_lbr_ctl(vcpu);
 }
 
 static void vmx_setup_uret_msr(struct vcpu_vmx *vmx, unsigned int msr,
@@ -4796,7 +4813,9 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
 
 	vmx_update_fb_clear_dis(vcpu, vmx);
 
-	if (!init_event && cpu_has_vmx_arch_lbr())
+	if (init_event)
+		disable_arch_lbr_ctl(vcpu);
+	else if (cpu_has_vmx_arch_lbr())
 		vmcs_write64(GUEST_IA32_LBR_CTL, 0);
 }
 
@@ -4873,6 +4892,9 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
 			INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR);
 
 	vmx_clear_hlt(vcpu);
+
+	if (vcpu->arch.exception.vector == DB_VECTOR)
+		disable_arch_lbr_ctl(vcpu);
 }
 
 bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu)
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 13/15] KVM: x86/vmx: Save/Restore guest Arch LBR Ctrl msr at SMM entry/exit
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
                   ` (11 preceding siblings ...)
  2022-11-25  4:06 ` [PATCH v2 12/15] KVM: x86/vmx: Disable Arch LBREn bit in #DB and warm reset Yang Weijiang
@ 2022-11-25  4:06 ` Yang Weijiang
  2023-01-27 22:11   ` Sean Christopherson
  2022-11-25  4:06 ` [PATCH v2 14/15] KVM: x86: Add Arch LBR data MSR access interface Yang Weijiang
                   ` (3 subsequent siblings)
  16 siblings, 1 reply; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:06 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang

Per SDM 3B Chapter 18: "IA32_LBR_CTL.LBREn is saved and cleared on #SMI,
and restored on RSM", store guest IA32_LBR_CTL in SMRAM and clear LBREn
in VMCS at SMM entry, and do reverse things at SMM exit.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 arch/x86/kvm/smm.c     |  1 +
 arch/x86/kvm/smm.h     |  3 ++-
 arch/x86/kvm/vmx/vmx.c | 22 ++++++++++++++++++++++
 3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/smm.c b/arch/x86/kvm/smm.c
index a9c1c2af8d94..5987090b440f 100644
--- a/arch/x86/kvm/smm.c
+++ b/arch/x86/kvm/smm.c
@@ -86,6 +86,7 @@ static void check_smram_offsets(void)
 	CHECK_SMRAM64_OFFSET(smm_revison,		0xFEFC);
 	CHECK_SMRAM64_OFFSET(smbase,			0xFF00);
 	CHECK_SMRAM64_OFFSET(reserved4,			0xFF04);
+	CHECK_SMRAM64_OFFSET(arch_lbr_ctl,		0xFF10);
 	CHECK_SMRAM64_OFFSET(ssp,			0xFF18);
 	CHECK_SMRAM64_OFFSET(svm_guest_pat,		0xFF20);
 	CHECK_SMRAM64_OFFSET(svm_host_efer,		0xFF28);
diff --git a/arch/x86/kvm/smm.h b/arch/x86/kvm/smm.h
index a1cf2ac5bd78..5a6479205d91 100644
--- a/arch/x86/kvm/smm.h
+++ b/arch/x86/kvm/smm.h
@@ -114,7 +114,8 @@ struct kvm_smram_state_64 {
 	u32 reserved3[3];
 	u32 smm_revison;
 	u32 smbase;
-	u32 reserved4[5];
+	u32 reserved4[3];
+	u64 arch_lbr_ctl;
 
 	/* ssp and svm_* fields below are not implemented by KVM */
 	u64 ssp;
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 6ad765ea4059..cc782233c075 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -8006,11 +8006,21 @@ static int vmx_enter_smm(struct kvm_vcpu *vcpu, union kvm_smram *smram)
 	vmx->nested.smm.vmxon = vmx->nested.vmxon;
 	vmx->nested.vmxon = false;
 	vmx_clear_hlt(vcpu);
+
+	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
+	    guest_cpuid_has(vcpu, X86_FEATURE_LM)) {
+		u64 ctl = vmcs_read64(GUEST_IA32_LBR_CTL);
+
+		smram->smram64.arch_lbr_ctl = ctl;
+		vmcs_write64(GUEST_IA32_LBR_CTL, ctl & ~ARCH_LBR_CTL_LBREN);
+	}
+
 	return 0;
 }
 
 static int vmx_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)
 {
+	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	int ret;
 
@@ -8027,6 +8037,18 @@ static int vmx_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)
 		vmx->nested.nested_run_pending = 1;
 		vmx->nested.smm.guest_mode = false;
 	}
+
+	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
+	    guest_cpuid_has(vcpu, X86_FEATURE_LM)) {
+		u64 ctl = smram->smram64.arch_lbr_ctl;
+
+		vmcs_write64(GUEST_IA32_LBR_CTL, ctl & ARCH_LBR_CTL_LBREN);
+
+		if (intel_pmu_lbr_is_enabled(vcpu) &&
+		    (ctl & ARCH_LBR_CTL_LBREN) && !lbr_desc->event)
+			intel_pmu_create_guest_lbr_event(vcpu);
+	}
+
 	return 0;
 }
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 14/15] KVM: x86: Add Arch LBR data MSR access interface
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
                   ` (12 preceding siblings ...)
  2022-11-25  4:06 ` [PATCH v2 13/15] KVM: x86/vmx: Save/Restore guest Arch LBR Ctrl msr at SMM entry/exit Yang Weijiang
@ 2022-11-25  4:06 ` Yang Weijiang
  2023-01-27 22:13   ` Sean Christopherson
  2022-11-25  4:06 ` [PATCH v2 15/15] KVM: x86/cpuid: Advertise Arch LBR feature in CPUID Yang Weijiang
                   ` (2 subsequent siblings)
  16 siblings, 1 reply; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:06 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang

Arch LBR MSRs are xsave-supported, but they're operated as "independent"
xsave feature by PMU code, i.e., during thread/process context switch,
the MSRs are saved/restored with perf_event_task_sched_{in|out} instead
of generic kernel fpu switch code, i.e.,save_fpregs_to_fpstate() and
restore_fpregs_from_fpstate(). When vcpu guest/host fpu state swap happens,
Arch LBR MSRs are retained so they can be accessed directly.

Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
---
 arch/x86/kvm/vmx/pmu_intel.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index b57944d5e7d8..241128972776 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -410,6 +410,11 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 			msr_info->data = vmcs_read64(GUEST_IA32_LBR_CTL);
 		}
 		return 0;
+	case MSR_ARCH_LBR_FROM_0 ... MSR_ARCH_LBR_FROM_0 + 31:
+	case MSR_ARCH_LBR_TO_0 ... MSR_ARCH_LBR_TO_0 + 31:
+	case MSR_ARCH_LBR_INFO_0 ... MSR_ARCH_LBR_INFO_0 + 31:
+		rdmsrl(msr_info->index, msr_info->data);
+		return 0;
 	default:
 		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
 		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
@@ -528,6 +533,11 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 		    (data & ARCH_LBR_CTL_LBREN))
 			intel_pmu_create_guest_lbr_event(vcpu);
 		return 0;
+	case MSR_ARCH_LBR_FROM_0 ... MSR_ARCH_LBR_FROM_0 + 31:
+	case MSR_ARCH_LBR_TO_0 ... MSR_ARCH_LBR_TO_0 + 31:
+	case MSR_ARCH_LBR_INFO_0 ... MSR_ARCH_LBR_INFO_0 + 31:
+		wrmsrl(msr_info->index, msr_info->data);
+		return 0;
 	default:
 		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
 		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 15/15] KVM: x86/cpuid: Advertise Arch LBR feature in CPUID
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
                   ` (13 preceding siblings ...)
  2022-11-25  4:06 ` [PATCH v2 14/15] KVM: x86: Add Arch LBR data MSR access interface Yang Weijiang
@ 2022-11-25  4:06 ` Yang Weijiang
  2022-12-22 11:03   ` Like Xu
  2023-01-27 22:15   ` Sean Christopherson
  2023-01-12  1:57 ` [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang, Weijiang
  2023-01-27 22:46 ` Sean Christopherson
  16 siblings, 2 replies; 64+ messages in thread
From: Yang Weijiang @ 2022-11-25  4:06 UTC (permalink / raw)
  To: seanjc, pbonzini, jmattson, kvm, linux-kernel
  Cc: like.xu.linux, kan.liang, wei.w.wang, weijiang.yang, Like Xu

Add Arch LBR feature bit in CPU cap-mask to expose the feature.
Only max LBR depth is supported for guest, and it's consistent
with host Arch LBR settings.

Co-developed-by: Like Xu <like.xu@linux.intel.com>
Signed-off-by: Like Xu <like.xu@linux.intel.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
---
 arch/x86/kvm/cpuid.c | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 85e3df6217af..60b3c591d462 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -134,6 +134,19 @@ static int kvm_check_cpuid(struct kvm_vcpu *vcpu,
 		if (vaddr_bits != 48 && vaddr_bits != 57 && vaddr_bits != 0)
 			return -EINVAL;
 	}
+	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR)) {
+		best = cpuid_entry2_find(entries, nent, 0x1c, 0);
+		if (best) {
+			unsigned int eax, ebx, ecx, edx;
+
+			/* Reject user-space CPUID if depth is different from host's.*/
+			cpuid_count(0x1c, 0, &eax, &ebx, &ecx, &edx);
+
+			if ((eax & 0xff) &&
+			    (best->eax & 0xff) != BIT(fls(eax & 0xff) - 1))
+				return -EINVAL;
+		}
+	}
 
 	/*
 	 * Exposing dynamic xfeatures to the guest requires additional
@@ -652,7 +665,7 @@ void kvm_set_cpu_caps(void)
 		F(SPEC_CTRL_SSBD) | F(ARCH_CAPABILITIES) | F(INTEL_STIBP) |
 		F(MD_CLEAR) | F(AVX512_VP2INTERSECT) | F(FSRM) |
 		F(SERIALIZE) | F(TSXLDTRK) | F(AVX512_FP16) |
-		F(AMX_TILE) | F(AMX_INT8) | F(AMX_BF16)
+		F(AMX_TILE) | F(AMX_INT8) | F(AMX_BF16) | F(ARCH_LBR)
 	);
 
 	/* TSC_ADJUST and ARCH_CAPABILITIES are emulated in software. */
@@ -1074,6 +1087,27 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
 				goto out;
 		}
 		break;
+	/* Architectural LBR */
+	case 0x1c: {
+		u32 lbr_depth_mask = entry->eax & 0xff;
+
+		if (!lbr_depth_mask ||
+		    !kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR)) {
+			entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
+			break;
+		}
+		/*
+		 * KVM only exposes the maximum supported depth, which is the
+		 * fixed value used on the host side.
+		 * KVM doesn't allow VMM userspace to adjust LBR depth because
+		 * guest LBR emulation depends on the configuration of host LBR
+		 * driver.
+		 */
+		lbr_depth_mask = BIT((fls(lbr_depth_mask) - 1));
+		entry->eax &= ~0xff;
+		entry->eax |= lbr_depth_mask;
+		break;
+	}
 	/* Intel AMX TILE */
 	case 0x1d:
 		if (!kvm_cpu_cap_has(X86_FEATURE_AMX_TILE)) {
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 01/15] perf/x86/lbr: Simplify the exposure check for the LBR_INFO registers
  2022-11-25  4:05 ` [PATCH v2 01/15] perf/x86/lbr: Simplify the exposure check for the LBR_INFO registers Yang Weijiang
@ 2022-12-22 10:57   ` Like Xu
  2022-12-22 13:29     ` Peter Zijlstra
  2022-12-22 17:41     ` Sean Christopherson
  2022-12-27 11:58   ` [tip: perf/core] " tip-bot2 for Like Xu
  1 sibling, 2 replies; 64+ messages in thread
From: Like Xu @ 2022-12-22 10:57 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: kan.liang, wei.w.wang, Like Xu, Andi Kleen,
	Paolo Bonzini - Distinguished Engineer (kernel-recipes.org) (KVM
	HoF),
	Jim Mattson, kvm list, Sean Christopherson, linux-kernel,
	Yang Weijiang

Hi Peter, would you help apply this one in your tip/perf tree,
as it doesn't seem to be closely tied to the KVM changes. Thanks.

On 25/11/2022 12:05 pm, Yang Weijiang wrote:
> From: Like Xu <like.xu@linux.intel.com>
> 
> The x86_pmu.lbr_info is 0 unless explicitly initialized, so there's
> no point checking x86_pmu.intel_cap.lbr_format.
> 
> Cc: Peter Zijlstra <peterz@infradead.org>
> Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
> Reviewed-by: Andi Kleen <ak@linux.intel.com>
> Signed-off-by: Like Xu <like.xu@linux.intel.com>
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> ---
>   arch/x86/events/intel/lbr.c | 4 +---
>   1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
> index 4dbde69c423b..e7caabfa1377 100644
> --- a/arch/x86/events/intel/lbr.c
> +++ b/arch/x86/events/intel/lbr.c
> @@ -1606,12 +1606,10 @@ void __init intel_pmu_arch_lbr_init(void)
>    */
>   void x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
>   {
> -	int lbr_fmt = x86_pmu.intel_cap.lbr_format;
> -
>   	lbr->nr = x86_pmu.lbr_nr;
>   	lbr->from = x86_pmu.lbr_from;
>   	lbr->to = x86_pmu.lbr_to;
> -	lbr->info = (lbr_fmt == LBR_FORMAT_INFO) ? x86_pmu.lbr_info : 0;
> +	lbr->info = x86_pmu.lbr_info;
>   }
>   EXPORT_SYMBOL_GPL(x86_perf_get_lbr);
>   

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 05/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_DEPTH for guest Arch LBR
  2022-11-25  4:05 ` [PATCH v2 05/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_DEPTH for guest Arch LBR Yang Weijiang
@ 2022-12-22 11:00   ` Like Xu
  2022-12-25  4:30     ` Yang, Weijiang
  2022-12-22 11:15   ` Like Xu
  2023-01-27 20:25   ` Sean Christopherson
  2 siblings, 1 reply; 64+ messages in thread
From: Like Xu @ 2022-12-22 11:00 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: kan.liang, wei.w.wang, seanjc, pbonzini, jmattson, kvm, linux-kernel

On 25/11/2022 12:05 pm, Yang Weijiang wrote:
> @@ -571,6 +571,9 @@ struct kvm_pmu {
>   	 * redundant check before cleanup if guest don't use vPMU at all.
>   	 */
>   	u8 event_count;
> +
> +	/* Guest arch lbr depth supported by KVM. */
> +	u64 kvm_arch_lbr_depth;

Please drop the "kvm_" prefix for per-vcpu "struct kvm_pmu".

>   };
>   

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 15/15] KVM: x86/cpuid: Advertise Arch LBR feature in CPUID
  2022-11-25  4:06 ` [PATCH v2 15/15] KVM: x86/cpuid: Advertise Arch LBR feature in CPUID Yang Weijiang
@ 2022-12-22 11:03   ` Like Xu
  2022-12-25  4:31     ` Yang, Weijiang
  2023-01-27 22:15   ` Sean Christopherson
  1 sibling, 1 reply; 64+ messages in thread
From: Like Xu @ 2022-12-22 11:03 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: kan.liang, wei.w.wang, seanjc, pbonzini, jmattson, kvm, linux-kernel

On 25/11/2022 12:06 pm, Yang Weijiang wrote:
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index 85e3df6217af..60b3c591d462 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -134,6 +134,19 @@ static int kvm_check_cpuid(struct kvm_vcpu *vcpu,
>   		if (vaddr_bits != 48 && vaddr_bits != 57 && vaddr_bits != 0)
>   			return -EINVAL;
>   	}
> +	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR)) {
> +		best = cpuid_entry2_find(entries, nent, 0x1c, 0);
> +		if (best) {
> +			unsigned int eax, ebx, ecx, edx;
> +
> +			/* Reject user-space CPUID if depth is different from host's.*/

Try to verify this in the KVM selftest, as this behavior is different from the host.

> +			cpuid_count(0x1c, 0, &eax, &ebx, &ecx, &edx); > +
> +			if ((eax & 0xff) &&
> +			    (best->eax & 0xff) != BIT(fls(eax & 0xff) - 1))
> +				return -EINVAL;
> +		}
> +	}

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 10/15] KVM: x86/vmx: Check Arch LBR config when return perf capabilities
  2022-11-25  4:05 ` [PATCH v2 10/15] KVM: x86/vmx: Check Arch LBR config when return perf capabilities Yang Weijiang
@ 2022-12-22 11:06   ` Like Xu
  2022-12-25  4:28     ` Yang, Weijiang
  2023-01-27 22:04   ` Sean Christopherson
  1 sibling, 1 reply; 64+ messages in thread
From: Like Xu @ 2022-12-22 11:06 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: kan.liang, wei.w.wang, seanjc, pbonzini, jmattson, kvm, linux-kernel

On 25/11/2022 12:05 pm, Yang Weijiang wrote:
> diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> index b28be793de29..59bdd9873fb5 100644
> --- a/arch/x86/kvm/vmx/nested.c
> +++ b/arch/x86/kvm/vmx/nested.c
> @@ -2360,6 +2360,10 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0
>   		if (guest_efer != host_efer)
>   			exec_control |= VM_ENTRY_LOAD_IA32_EFER;
>   	}
> +
> +	if (cpu_has_vmx_arch_lbr())
> +		exec_control &= ~VM_ENTRY_LOAD_IA32_LBR_CTL;

Please verify that (arch) lbr is not available in the nested test case.
Thus when we support nested lbr, the developer will be aware of the need for 
test case updates

> +
>   	vm_entry_controls_set(vmx, exec_control);
>   
>   	/*

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 06/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL for guest Arch LBR
  2022-11-25  4:05 ` [PATCH v2 06/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL " Yang Weijiang
@ 2022-12-22 11:09   ` Like Xu
  2022-12-25  4:27     ` Yang, Weijiang
  2022-12-22 11:19   ` Like Xu
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 64+ messages in thread
From: Like Xu @ 2022-12-22 11:09 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: kan.liang, wei.w.wang, seanjc, pbonzini, jmattson, kvm, linux-kernel

On 25/11/2022 12:05 pm, Yang Weijiang wrote:
>   static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>   {
>   	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
> @@ -377,6 +402,14 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>   	case MSR_ARCH_LBR_DEPTH:
>   		msr_info->data = lbr_desc->records.nr;
>   		return 0;
> +	case MSR_ARCH_LBR_CTL:
> +		if (!kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR)) {
> +			WARN_ON_ONCE(!msr_info->host_initiated);

Why we need this warning even in the format of WARN_ON_ONCE() ?
And why not for MSR_ARCH_LBR_DEPTH msr ?

> +			msr_info->data = 0;
> +		} else {
> +			msr_info->data = vmcs_read64(GUEST_IA32_LBR_CTL);
> +		}
> +		return 0;

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 05/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_DEPTH for guest Arch LBR
  2022-11-25  4:05 ` [PATCH v2 05/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_DEPTH for guest Arch LBR Yang Weijiang
  2022-12-22 11:00   ` Like Xu
@ 2022-12-22 11:15   ` Like Xu
  2023-01-27 20:25   ` Sean Christopherson
  2 siblings, 0 replies; 64+ messages in thread
From: Like Xu @ 2022-12-22 11:15 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: kan.liang, wei.w.wang, seanjc, pbonzini, jmattson, kvm, linux-kernel

On 25/11/2022 12:05 pm, Yang Weijiang wrote:
> +static bool cpuid_enable_lbr(struct kvm_vcpu *vcpu)
> +{
> +	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
> +	struct kvm_cpuid_entry2 *entry;
> +	int depth_bit;
> +
> +	if (!kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR))
> +		return !static_cpu_has(X86_FEATURE_ARCH_LBR) &&
> +			cpuid_model_is_consistent(vcpu);

Please add selftests to cover this incompatibility.

And running the SPR vcpu model on a GNR host, the guest arch lbr
should be fully supported as long as both hosts have the same lbr_depth.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 06/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL for guest Arch LBR
  2022-11-25  4:05 ` [PATCH v2 06/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL " Yang Weijiang
  2022-12-22 11:09   ` Like Xu
@ 2022-12-22 11:19   ` Like Xu
  2022-12-25  4:16     ` Yang, Weijiang
  2022-12-22 11:24   ` Like Xu
  2023-01-27 21:42   ` Sean Christopherson
  3 siblings, 1 reply; 64+ messages in thread
From: Like Xu @ 2022-12-22 11:19 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: kan.liang, wei.w.wang, seanjc, pbonzini, jmattson, kvm, linux-kernel

On 25/11/2022 12:05 pm, Yang Weijiang wrote:
> @@ -727,12 +772,16 @@ static void intel_pmu_reset(struct kvm_vcpu *vcpu)
>    */
>   static void intel_pmu_legacy_freezing_lbrs_on_pmi(struct kvm_vcpu *vcpu)
>   {
> -	u64 data = vmcs_read64(GUEST_IA32_DEBUGCTL);
> +	u32 lbr_ctl_field = GUEST_IA32_DEBUGCTL;
>   
> -	if (data & DEBUGCTLMSR_FREEZE_LBRS_ON_PMI) {
> -		data &= ~DEBUGCTLMSR_LBR;
> -		vmcs_write64(GUEST_IA32_DEBUGCTL, data);
> -	}
> +	if (!(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_FREEZE_LBRS_ON_PMI))
> +		return;
> +
> +	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
> +	    guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR))
> +		lbr_ctl_field = GUEST_IA32_LBR_CTL;
> +
> +	vmcs_write64(lbr_ctl_field, vmcs_read64(lbr_ctl_field) & ~0x1ULL);
>   }
>   
>   static void intel_pmu_deliver_pmi(struct kvm_vcpu *vcpu)

The legacy lbr test case in KUT does not cover this scenario, but
arch lbr contributor should take the opportunity to fill this gap. Thanks.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 12/15] KVM: x86/vmx: Disable Arch LBREn bit in #DB and warm reset
  2022-11-25  4:06 ` [PATCH v2 12/15] KVM: x86/vmx: Disable Arch LBREn bit in #DB and warm reset Yang Weijiang
@ 2022-12-22 11:22   ` Like Xu
  2022-12-25  4:12     ` Yang, Weijiang
  2023-01-27 22:09   ` Sean Christopherson
  1 sibling, 1 reply; 64+ messages in thread
From: Like Xu @ 2022-12-22 11:22 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: kan.liang, wei.w.wang, seanjc, pbonzini, jmattson, kvm, linux-kernel

On 25/11/2022 12:06 pm, Yang Weijiang wrote:
> +static void disable_arch_lbr_ctl(struct kvm_vcpu *vcpu)
> +{
> +	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
> +	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
> +
> +	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
> +	    test_bit(INTEL_PMC_IDX_FIXED_VLBR, pmu->pmc_in_use) &&
> +	    lbr_desc->event) {
> +		u64 ctl = vmcs_read64(GUEST_IA32_LBR_CTL);
> +
> +		vmcs_write64(GUEST_IA32_LBR_CTL, ctl & ~ARCH_LBR_CTL_LBREN);
> +	}
> +}
> +
>   static void vmx_inject_exception(struct kvm_vcpu *vcpu)
>   {
>   	struct kvm_queued_exception *ex = &vcpu->arch.exception;
> @@ -1738,6 +1752,9 @@ static void vmx_inject_exception(struct kvm_vcpu *vcpu)
>   	vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
>   
>   	vmx_clear_hlt(vcpu);
> +
> +	if (ex->vector == DB_VECTOR)
> +		disable_arch_lbr_ctl(vcpu);

Please verify this with KUT testcase, once I failed and did not confirm
if it is a hardware issue. Good Luck.

>   }

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 06/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL for guest Arch LBR
  2022-11-25  4:05 ` [PATCH v2 06/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL " Yang Weijiang
  2022-12-22 11:09   ` Like Xu
  2022-12-22 11:19   ` Like Xu
@ 2022-12-22 11:24   ` Like Xu
  2022-12-25  4:08     ` Yang, Weijiang
  2023-01-27 21:42   ` Sean Christopherson
  3 siblings, 1 reply; 64+ messages in thread
From: Like Xu @ 2022-12-22 11:24 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: kan.liang, wei.w.wang, seanjc, pbonzini, jmattson, kvm, linux-kernel

On 25/11/2022 12:05 pm, Yang Weijiang wrote:
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index cea8c07f5229..1ae2efc29546 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -2120,6 +2120,13 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>   						VM_EXIT_SAVE_DEBUG_CONTROLS)
>   			get_vmcs12(vcpu)->guest_ia32_debugctl = data;
>   
> +		/*
> +		 * For Arch LBR, IA32_DEBUGCTL[bit 0] has no meaning.
> +		 * It can be written to 0 or 1, but reads will always return 0.
> +		 */

The comment looks good, please verify it with a test.

> +		if (guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR))
> +			data &= ~DEBUGCTLMSR_LBR;
> +
>   		vmcs_write64(GUEST_IA32_DEBUGCTL, data);
>   		if (intel_pmu_lbr_is_enabled(vcpu) && !to_vmx(vcpu)->lbr_desc.event &&
>   		    (data & DEBUGCTLMSR_LBR))

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 01/15] perf/x86/lbr: Simplify the exposure check for the LBR_INFO registers
  2022-12-22 10:57   ` Like Xu
@ 2022-12-22 13:29     ` Peter Zijlstra
  2022-12-22 17:41     ` Sean Christopherson
  1 sibling, 0 replies; 64+ messages in thread
From: Peter Zijlstra @ 2022-12-22 13:29 UTC (permalink / raw)
  To: Like Xu
  Cc: kan.liang, wei.w.wang, Like Xu, Andi Kleen,
	Paolo Bonzini - Distinguished Engineer (kernel-recipes.org) (KVM
	HoF),
	Jim Mattson, kvm list, Sean Christopherson, linux-kernel,
	Yang Weijiang

On Thu, Dec 22, 2022 at 06:57:50PM +0800, Like Xu wrote:
> Hi Peter, would you help apply this one in your tip/perf tree,
> as it doesn't seem to be closely tied to the KVM changes. Thanks.

OK, I'll go queue it for perf/core after -rc1

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 01/15] perf/x86/lbr: Simplify the exposure check for the LBR_INFO registers
  2022-12-22 10:57   ` Like Xu
  2022-12-22 13:29     ` Peter Zijlstra
@ 2022-12-22 17:41     ` Sean Christopherson
  2022-12-23  2:12       ` Like Xu
  1 sibling, 1 reply; 64+ messages in thread
From: Sean Christopherson @ 2022-12-22 17:41 UTC (permalink / raw)
  To: Like Xu
  Cc: Peter Zijlstra, kan.liang, wei.w.wang, Like Xu, Andi Kleen,
	Paolo Bonzini - Distinguished Engineer (kernel-recipes.org) (KVM
	HoF),
	Jim Mattson, kvm list, linux-kernel, Yang Weijiang

On Thu, Dec 22, 2022, Like Xu wrote:
> Hi Peter, would you help apply this one in your tip/perf tree,
> as it doesn't seem to be closely tied to the KVM changes. Thanks.
> 
> On 25/11/2022 12:05 pm, Yang Weijiang wrote:
> > From: Like Xu <like.xu@linux.intel.com>
> > 
> > The x86_pmu.lbr_info is 0 unless explicitly initialized, so there's
> > no point checking x86_pmu.intel_cap.lbr_format.
> > 
> > Cc: Peter Zijlstra <peterz@infradead.org>
> > Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
> > Reviewed-by: Andi Kleen <ak@linux.intel.com>
> > Signed-off-by: Like Xu <like.xu@linux.intel.com>
> > Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> > ---
> >   arch/x86/events/intel/lbr.c | 4 +---
> >   1 file changed, 1 insertion(+), 3 deletions(-)
> > 
> > diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
> > index 4dbde69c423b..e7caabfa1377 100644
> > --- a/arch/x86/events/intel/lbr.c
> > +++ b/arch/x86/events/intel/lbr.c
> > @@ -1606,12 +1606,10 @@ void __init intel_pmu_arch_lbr_init(void)
> >    */
> >   void x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
> >   {
> > -	int lbr_fmt = x86_pmu.intel_cap.lbr_format;
> > -
> >   	lbr->nr = x86_pmu.lbr_nr;
> >   	lbr->from = x86_pmu.lbr_from;
> >   	lbr->to = x86_pmu.lbr_to;
> > -	lbr->info = (lbr_fmt == LBR_FORMAT_INFO) ? x86_pmu.lbr_info : 0;
> > +	lbr->info = x86_pmu.lbr_info;

This stable-worthy a bug fix, no?  E.g. won't the existing code misreport lbr->info
if the format is LBR_FORMAT_INFO2?

> >   }
> >   EXPORT_SYMBOL_GPL(x86_perf_get_lbr);

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 01/15] perf/x86/lbr: Simplify the exposure check for the LBR_INFO registers
  2022-12-22 17:41     ` Sean Christopherson
@ 2022-12-23  2:12       ` Like Xu
  0 siblings, 0 replies; 64+ messages in thread
From: Like Xu @ 2022-12-23  2:12 UTC (permalink / raw)
  To: Peter Zijlstra, Sean Christopherson
  Cc: kan.liang, wei.w.wang, Andi Kleen,
	Paolo Bonzini - Distinguished Engineer (kernel-recipes.org) (KVM
	HoF),
	Jim Mattson, kvm list, linux-kernel, Yang Weijiang

On 23/12/2022 1:41 am, Sean Christopherson wrote:
> On Thu, Dec 22, 2022, Like Xu wrote:
>> Hi Peter, would you help apply this one in your tip/perf tree,
>> as it doesn't seem to be closely tied to the KVM changes. Thanks.
>>
>> On 25/11/2022 12:05 pm, Yang Weijiang wrote:
>>> From: Like Xu <like.xu@linux.intel.com>
>>>
>>> The x86_pmu.lbr_info is 0 unless explicitly initialized, so there's
>>> no point checking x86_pmu.intel_cap.lbr_format.
>>>
>>> Cc: Peter Zijlstra <peterz@infradead.org>
>>> Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
>>> Reviewed-by: Andi Kleen <ak@linux.intel.com>
>>> Signed-off-by: Like Xu <like.xu@linux.intel.com>
>>> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
>>> ---
>>>    arch/x86/events/intel/lbr.c | 4 +---
>>>    1 file changed, 1 insertion(+), 3 deletions(-)
>>>
>>> diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
>>> index 4dbde69c423b..e7caabfa1377 100644
>>> --- a/arch/x86/events/intel/lbr.c
>>> +++ b/arch/x86/events/intel/lbr.c
>>> @@ -1606,12 +1606,10 @@ void __init intel_pmu_arch_lbr_init(void)
>>>     */
>>>    void x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
>>>    {
>>> -	int lbr_fmt = x86_pmu.intel_cap.lbr_format;
>>> -
>>>    	lbr->nr = x86_pmu.lbr_nr;
>>>    	lbr->from = x86_pmu.lbr_from;
>>>    	lbr->to = x86_pmu.lbr_to;
>>> -	lbr->info = (lbr_fmt == LBR_FORMAT_INFO) ? x86_pmu.lbr_info : 0;
>>> +	lbr->info = x86_pmu.lbr_info;
> 
> This stable-worthy a bug fix, no?  E.g. won't the existing code misreport lbr->info
> if the format is LBR_FORMAT_INFO2?

Sure, we need "Cc: stable@vger.kernel.org" in order not to lose misprediction 
and cycles
information on the LBR_FORMAT_INFO2 platforms like Goldmont plus.

> 
>>>    }
>>>    EXPORT_SYMBOL_GPL(x86_perf_get_lbr);

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 06/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL for guest Arch LBR
  2022-12-22 11:24   ` Like Xu
@ 2022-12-25  4:08     ` Yang, Weijiang
  0 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2022-12-25  4:08 UTC (permalink / raw)
  To: Like Xu
  Cc: kan.liang, wei.w.wang, seanjc, pbonzini, jmattson, kvm, linux-kernel


On 12/22/2022 7:24 PM, Like Xu wrote:
> On 25/11/2022 12:05 pm, Yang Weijiang wrote:
>> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
>> index cea8c07f5229..1ae2efc29546 100644
>> --- a/arch/x86/kvm/vmx/vmx.c
>> +++ b/arch/x86/kvm/vmx/vmx.c
>> @@ -2120,6 +2120,13 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, 
>> struct msr_data *msr_info)
>>                           VM_EXIT_SAVE_DEBUG_CONTROLS)
>>               get_vmcs12(vcpu)->guest_ia32_debugctl = data;
>>   +        /*
>> +         * For Arch LBR, IA32_DEBUGCTL[bit 0] has no meaning.
>> +         * It can be written to 0 or 1, but reads will always return 0.
>> +         */
>
> The comment looks good, please verify it with a test.


OK, I'll add the test into pmu_lbr KUT test together with arch-lbr test 
cases.



>
>> +        if (guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR))
>> +            data &= ~DEBUGCTLMSR_LBR;
>> +
>>           vmcs_write64(GUEST_IA32_DEBUGCTL, data);
>>           if (intel_pmu_lbr_is_enabled(vcpu) && 
>> !to_vmx(vcpu)->lbr_desc.event &&
>>               (data & DEBUGCTLMSR_LBR))

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 12/15] KVM: x86/vmx: Disable Arch LBREn bit in #DB and warm reset
  2022-12-22 11:22   ` Like Xu
@ 2022-12-25  4:12     ` Yang, Weijiang
  0 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2022-12-25  4:12 UTC (permalink / raw)
  To: Like Xu
  Cc: kan.liang, wei.w.wang, seanjc, pbonzini, jmattson, kvm, linux-kernel


On 12/22/2022 7:22 PM, Like Xu wrote:
> On 25/11/2022 12:06 pm, Yang Weijiang wrote:
>> +static void disable_arch_lbr_ctl(struct kvm_vcpu *vcpu)
>> +{
>> +    struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
>> +    struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
>> +
>> +    if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
>> +        test_bit(INTEL_PMC_IDX_FIXED_VLBR, pmu->pmc_in_use) &&
>> +        lbr_desc->event) {
>> +        u64 ctl = vmcs_read64(GUEST_IA32_LBR_CTL);
>> +
>> +        vmcs_write64(GUEST_IA32_LBR_CTL, ctl & ~ARCH_LBR_CTL_LBREN);
>> +    }
>> +}
>> +
>>   static void vmx_inject_exception(struct kvm_vcpu *vcpu)
>>   {
>>       struct kvm_queued_exception *ex = &vcpu->arch.exception;
>> @@ -1738,6 +1752,9 @@ static void vmx_inject_exception(struct 
>> kvm_vcpu *vcpu)
>>       vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
>>         vmx_clear_hlt(vcpu);
>> +
>> +    if (ex->vector == DB_VECTOR)
>> +        disable_arch_lbr_ctl(vcpu);
>
> Please verify this with KUT testcase, once I failed and did not confirm
> if it is a hardware issue. Good Luck.


Can  you detail what you want to verify with?



>
>>   }

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 06/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL for guest Arch LBR
  2022-12-22 11:19   ` Like Xu
@ 2022-12-25  4:16     ` Yang, Weijiang
  0 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2022-12-25  4:16 UTC (permalink / raw)
  To: Like Xu
  Cc: kan.liang, wei.w.wang, seanjc, pbonzini, jmattson, kvm, linux-kernel


On 12/22/2022 7:19 PM, Like Xu wrote:
> On 25/11/2022 12:05 pm, Yang Weijiang wrote:
>> @@ -727,12 +772,16 @@ static void intel_pmu_reset(struct kvm_vcpu *vcpu)
>>    */
>>   static void intel_pmu_legacy_freezing_lbrs_on_pmi(struct kvm_vcpu 
>> *vcpu)
>>   {
>> -    u64 data = vmcs_read64(GUEST_IA32_DEBUGCTL);
>> +    u32 lbr_ctl_field = GUEST_IA32_DEBUGCTL;
>>   -    if (data & DEBUGCTLMSR_FREEZE_LBRS_ON_PMI) {
>> -        data &= ~DEBUGCTLMSR_LBR;
>> -        vmcs_write64(GUEST_IA32_DEBUGCTL, data);
>> -    }
>> +    if (!(vmcs_read64(GUEST_IA32_DEBUGCTL) & 
>> DEBUGCTLMSR_FREEZE_LBRS_ON_PMI))
>> +        return;
>> +
>> +    if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
>> +        guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR))
>> +        lbr_ctl_field = GUEST_IA32_LBR_CTL;
>> +
>> +    vmcs_write64(lbr_ctl_field, vmcs_read64(lbr_ctl_field) & ~0x1ULL);
>>   }
>>     static void intel_pmu_deliver_pmi(struct kvm_vcpu *vcpu)
>
> The legacy lbr test case in KUT does not cover this scenario, but
> arch lbr contributor should take the opportunity to fill this gap. 
> Thanks.


OK,  will try to add this missing part check.


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 06/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL for guest Arch LBR
  2022-12-22 11:09   ` Like Xu
@ 2022-12-25  4:27     ` Yang, Weijiang
  0 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2022-12-25  4:27 UTC (permalink / raw)
  To: Like Xu
  Cc: kan.liang, wei.w.wang, seanjc, pbonzini, jmattson, kvm, linux-kernel


On 12/22/2022 7:09 PM, Like Xu wrote:
> On 25/11/2022 12:05 pm, Yang Weijiang wrote:
>>   static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data 
>> *msr_info)
>>   {
>>       struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
>> @@ -377,6 +402,14 @@ static int intel_pmu_get_msr(struct kvm_vcpu 
>> *vcpu, struct msr_data *msr_info)
>>       case MSR_ARCH_LBR_DEPTH:
>>           msr_info->data = lbr_desc->records.nr;
>>           return 0;
>> +    case MSR_ARCH_LBR_CTL:
>> +        if (!kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR)) {
>> +            WARN_ON_ONCE(!msr_info->host_initiated);
>
> Why we need this warning even in the format of WARN_ON_ONCE() ?
> And why not for MSR_ARCH_LBR_DEPTH msr ?


IMO, this is just to give some informative message. Not necessary for every

arch-lbr MSRs as MSR_ARCH_LBR_CTL is the master control msr.



>
>> +            msr_info->data = 0;
>> +        } else {
>> +            msr_info->data = vmcs_read64(GUEST_IA32_LBR_CTL);
>> +        }
>> +        return 0;

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 10/15] KVM: x86/vmx: Check Arch LBR config when return perf capabilities
  2022-12-22 11:06   ` Like Xu
@ 2022-12-25  4:28     ` Yang, Weijiang
  0 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2022-12-25  4:28 UTC (permalink / raw)
  To: Like Xu
  Cc: kan.liang, wei.w.wang, seanjc, pbonzini, jmattson, kvm, linux-kernel


On 12/22/2022 7:06 PM, Like Xu wrote:
> On 25/11/2022 12:05 pm, Yang Weijiang wrote:
>> diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
>> index b28be793de29..59bdd9873fb5 100644
>> --- a/arch/x86/kvm/vmx/nested.c
>> +++ b/arch/x86/kvm/vmx/nested.c
>> @@ -2360,6 +2360,10 @@ static void prepare_vmcs02_early(struct 
>> vcpu_vmx *vmx, struct loaded_vmcs *vmcs0
>>           if (guest_efer != host_efer)
>>               exec_control |= VM_ENTRY_LOAD_IA32_EFER;
>>       }
>> +
>> +    if (cpu_has_vmx_arch_lbr())
>> +        exec_control &= ~VM_ENTRY_LOAD_IA32_LBR_CTL;
>
> Please verify that (arch) lbr is not available in the nested test case.
> Thus when we support nested lbr, the developer will be aware of the 
> need for test case updates


It's not available in either KUT or selftest cases now.



>
>> +
>>       vm_entry_controls_set(vmx, exec_control);
>>         /*

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 05/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_DEPTH for guest Arch LBR
  2022-12-22 11:00   ` Like Xu
@ 2022-12-25  4:30     ` Yang, Weijiang
  0 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2022-12-25  4:30 UTC (permalink / raw)
  To: Like Xu
  Cc: kan.liang, wei.w.wang, seanjc, pbonzini, jmattson, kvm, linux-kernel


On 12/22/2022 7:00 PM, Like Xu wrote:
> On 25/11/2022 12:05 pm, Yang Weijiang wrote:
>> @@ -571,6 +571,9 @@ struct kvm_pmu {
>>        * redundant check before cleanup if guest don't use vPMU at all.
>>        */
>>       u8 event_count;
>> +
>> +    /* Guest arch lbr depth supported by KVM. */
>> +    u64 kvm_arch_lbr_depth;
>
> Please drop the "kvm_" prefix for per-vcpu "struct kvm_pmu".


OK, will remove it.



>
>>   };

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 15/15] KVM: x86/cpuid: Advertise Arch LBR feature in CPUID
  2022-12-22 11:03   ` Like Xu
@ 2022-12-25  4:31     ` Yang, Weijiang
  0 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2022-12-25  4:31 UTC (permalink / raw)
  To: Like Xu
  Cc: kan.liang, wei.w.wang, seanjc, pbonzini, jmattson, kvm, linux-kernel


On 12/22/2022 7:03 PM, Like Xu wrote:
> On 25/11/2022 12:06 pm, Yang Weijiang wrote:
>> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
>> index 85e3df6217af..60b3c591d462 100644
>> --- a/arch/x86/kvm/cpuid.c
>> +++ b/arch/x86/kvm/cpuid.c
>> @@ -134,6 +134,19 @@ static int kvm_check_cpuid(struct kvm_vcpu *vcpu,
>>           if (vaddr_bits != 48 && vaddr_bits != 57 && vaddr_bits != 0)
>>               return -EINVAL;
>>       }
>> +    if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR)) {
>> +        best = cpuid_entry2_find(entries, nent, 0x1c, 0);
>> +        if (best) {
>> +            unsigned int eax, ebx, ecx, edx;
>> +
>> +            /* Reject user-space CPUID if depth is different from 
>> host's.*/
>
> Try to verify this in the KVM selftest, as this behavior is different 
> from the host.


Will do it.



>
>> +            cpuid_count(0x1c, 0, &eax, &ebx, &ecx, &edx); > +
>> +            if ((eax & 0xff) &&
>> +                (best->eax & 0xff) != BIT(fls(eax & 0xff) - 1))
>> +                return -EINVAL;
>> +        }
>> +    }

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [tip: perf/core] perf/x86/lbr: Simplify the exposure check for the LBR_INFO registers
  2022-11-25  4:05 ` [PATCH v2 01/15] perf/x86/lbr: Simplify the exposure check for the LBR_INFO registers Yang Weijiang
  2022-12-22 10:57   ` Like Xu
@ 2022-12-27 11:58   ` tip-bot2 for Like Xu
  1 sibling, 0 replies; 64+ messages in thread
From: tip-bot2 for Like Xu @ 2022-12-27 11:58 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Like Xu, Yang Weijiang, Peter Zijlstra (Intel),
	Kan Liang, Andi Kleen, x86, linux-kernel

The following commit has been merged into the perf/core branch of tip:

Commit-ID:     03c4c7f88709fac0e20b6a48357c73d6fc50e544
Gitweb:        https://git.kernel.org/tip/03c4c7f88709fac0e20b6a48357c73d6fc50e544
Author:        Like Xu <like.xu@linux.intel.com>
AuthorDate:    Thu, 24 Nov 2022 23:05:50 -05:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 27 Dec 2022 12:52:07 +01:00

perf/x86/lbr: Simplify the exposure check for the LBR_INFO registers

The x86_pmu.lbr_info is 0 unless explicitly initialized, so there's
no point checking x86_pmu.intel_cap.lbr_format.

Signed-off-by: Like Xu <like.xu@linux.intel.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Link: https://lkml.kernel.org/r/20221125040604.5051-2-weijiang.yang@intel.com
---
 arch/x86/events/intel/lbr.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 1f21f57..c3b0d15 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -1606,12 +1606,10 @@ clear_arch_lbr:
  */
 void x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
 {
-	int lbr_fmt = x86_pmu.intel_cap.lbr_format;
-
 	lbr->nr = x86_pmu.lbr_nr;
 	lbr->from = x86_pmu.lbr_from;
 	lbr->to = x86_pmu.lbr_to;
-	lbr->info = (lbr_fmt == LBR_FORMAT_INFO) ? x86_pmu.lbr_info : 0;
+	lbr->info = x86_pmu.lbr_info;
 }
 EXPORT_SYMBOL_GPL(x86_perf_get_lbr);
 

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 00/15] Introduce Architectural LBR for vPMU
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
                   ` (14 preceding siblings ...)
  2022-11-25  4:06 ` [PATCH v2 15/15] KVM: x86/cpuid: Advertise Arch LBR feature in CPUID Yang Weijiang
@ 2023-01-12  1:57 ` Yang, Weijiang
  2023-01-27 22:46 ` Sean Christopherson
  16 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2023-01-12  1:57 UTC (permalink / raw)
  To: Christopherson,, Sean
  Cc: like.xu.linux, kan.liang, Wang, Wei W, pbonzini, jmattson, kvm,
	linux-kernel


Hi, Sean,

Sorry to bother,  do you have time to review this series? The feature 
has been pending

for a long time, and I want to move it forward.

Thanks!


On 11/25/2022 12:05 PM, Yang, Weijiang wrote:
> Intel CPU model-specific LBR(Legacy LBR) has evolved to Architectural
> LBR(Arch LBR [0]), it's the replacement of legacy LBR on new platforms.
> The native support patches were merged into 5.9 kernel tree, and this
> patch series is to enable Arch LBR in vPMU so that guest can benefit
> from the feature.
>
> The main advantages of Arch LBR are [1]:
> - Faster context switching due to XSAVES support and faster reset of
>    LBR MSRs via the new DEPTH MSR
> - Faster LBR read for a non-PEBS event due to XSAVES support, which
>    lowers the overhead of the NMI handler.
> - Linux kernel can support the LBR features without knowing the model
>    number of the current CPU.
>
>  From end user's point of view, the usage of Arch LBR is the same as
> the Legacy LBR that has been merged in the mainline.
>
> Note, in this series, there's one restriction for guest Arch LBR, i.e.,
> guest can only set its LBR record depth the same as host's. This is due
> to the special behavior of MSR_ARCH_LBR_DEPTH:
> 1) On write to the MSR, it'll reset all Arch LBR recording MSRs to 0s.
> 2) XRSTORS resets all record MSRs to 0s if the saved depth mismatches
> MSR_ARCH_LBR_DEPTH.
> Enforcing the restriction keeps KVM Arch LBR vPMU working flow simple
> and straightforward.
>
> Paolo refactored the old series and the resulting patches became the
> base of this new series, therefore he's the author of some patches.
>
> [0] https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
> [1] https://lore.kernel.org/lkml/1593780569-62993-1-git-send-email-kan.liang@linux.intel.com/
>
> v1:
> https://lore.kernel.org/all/20220831223438.413090-1-weijiang.yang@intel.com/
>
> Changes v2:
> 1. Removed Paolo's SOBs from some patches. [Sean]
> 2. Modified some patches due to KVM changes, e.g., SMM/vPMU refactor.
> 3. Rebased to https://git.kernel.org/pub/scm/virt/kvm/kvm.git : queue branch.
>
>
> Like Xu (3):
>    perf/x86/lbr: Simplify the exposure check for the LBR_INFO registers
>    KVM: vmx/pmu: Emulate MSR_ARCH_LBR_DEPTH for guest Arch LBR
>    KVM: x86: Add XSAVE Support for Architectural LBR
>
> Paolo Bonzini (4):
>    KVM: PMU: disable LBR handling if architectural LBR is available
>    KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL for guest Arch LBR
>    KVM: VMX: Support passthrough of architectural LBRs
>    KVM: x86: Refine the matching and clearing logic for supported_xss
>
> Sean Christopherson (1):
>    KVM: x86: Report XSS as an MSR to be saved if there are supported
>      features
>
> Yang Weijiang (7):
>    KVM: x86: Refresh CPUID on writes to MSR_IA32_XSS
>    KVM: x86: Add Arch LBR MSRs to msrs_to_save_all list
>    KVM: x86/vmx: Check Arch LBR config when return perf capabilities
>    KVM: x86/vmx: Disable Arch LBREn bit in #DB and warm reset
>    KVM: x86/vmx: Save/Restore guest Arch LBR Ctrl msr at SMM entry/exit
>    KVM: x86: Add Arch LBR data MSR access interface
>    KVM: x86/cpuid: Advertise Arch LBR feature in CPUID
>
>   arch/x86/events/intel/lbr.c      |   6 +-
>   arch/x86/include/asm/kvm_host.h  |   3 +
>   arch/x86/include/asm/msr-index.h |   1 +
>   arch/x86/include/asm/vmx.h       |   4 +
>   arch/x86/kvm/cpuid.c             |  52 +++++++++-
>   arch/x86/kvm/smm.c               |   1 +
>   arch/x86/kvm/smm.h               |   3 +-
>   arch/x86/kvm/vmx/capabilities.h  |   5 +
>   arch/x86/kvm/vmx/nested.c        |   8 ++
>   arch/x86/kvm/vmx/pmu_intel.c     | 161 +++++++++++++++++++++++++++----
>   arch/x86/kvm/vmx/vmx.c           |  74 +++++++++++++-
>   arch/x86/kvm/vmx/vmx.h           |   6 +-
>   arch/x86/kvm/x86.c               |  27 +++++-
>   13 files changed, 316 insertions(+), 35 deletions(-)
>
>
> base-commit: da5f28e10aa7df1a925dbc10656cc89d9c061358

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 03/15] KVM: x86: Refresh CPUID on writes to MSR_IA32_XSS
  2022-11-25  4:05 ` [PATCH v2 03/15] KVM: x86: Refresh CPUID on writes to MSR_IA32_XSS Yang Weijiang
@ 2023-01-26 19:50   ` Sean Christopherson
  2023-01-30  6:33     ` Yang, Weijiang
  0 siblings, 1 reply; 64+ messages in thread
From: Sean Christopherson @ 2023-01-26 19:50 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang, Zhang Yi Z

On Thu, Nov 24, 2022, Yang Weijiang wrote:
> Updated CPUID.0xD.0x1, which reports the current required storage size
> of all features enabled via XCR0 | XSS, when the guest's XSS is modified.
> 
> Note, KVM does not yet support any XSS based features, i.e. supported_xss
> is guaranteed to be zero at this time.
> 
> Co-developed-by: Zhang Yi Z <yi.z.zhang@linux.intel.com>
> Signed-off-by: Zhang Yi Z <yi.z.zhang@linux.intel.com>
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> ---
>  arch/x86/kvm/cpuid.c | 16 +++++++++++++---
>  arch/x86/kvm/x86.c   |  6 ++++--
>  2 files changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index 6b5912578edd..85e3df6217af 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -272,9 +272,19 @@ static void __kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu, struct kvm_cpuid_e
>  		best->ebx = xstate_required_size(vcpu->arch.xcr0, false);
>  
>  	best = cpuid_entry2_find(entries, nent, 0xD, 1);
> -	if (best && (cpuid_entry_has(best, X86_FEATURE_XSAVES) ||
> -		     cpuid_entry_has(best, X86_FEATURE_XSAVEC)))
> -		best->ebx = xstate_required_size(vcpu->arch.xcr0, true);
> +	if (best) {
> +		if (cpuid_entry_has(best, X86_FEATURE_XSAVES) ||
> +		    cpuid_entry_has(best, X86_FEATURE_XSAVEC))  {
> +			u64 xstate = vcpu->arch.xcr0 | vcpu->arch.ia32_xss;
> +
> +			best->ebx = xstate_required_size(xstate, true);
> +		}
> +
> +		if (!cpuid_entry_has(best, X86_FEATURE_XSAVES)) {
> +			best->ecx = 0;
> +			best->edx = 0;

ECX and EDX should be left alone, it is userspace's responsibility to provide a
sane CPUID model.  E.g. KVM doesn't clear EBX or EDX in CPUID.0xD.0x1 when XSAVE
is unsupported.

> +		}
> +	}
>  
>  	best = __kvm_find_kvm_cpuid_features(vcpu, entries, nent);
>  	if (kvm_hlt_in_guest(vcpu->kvm) && best &&
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 16726b44061b..888a153e32bc 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -3685,8 +3685,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  		 */
>  		if (data & ~kvm_caps.supported_xss)
>  			return 1;
> -		vcpu->arch.ia32_xss = data;
> -		kvm_update_cpuid_runtime(vcpu);
> +		if (vcpu->arch.ia32_xss != data) {
> +			vcpu->arch.ia32_xss = data;
> +			kvm_update_cpuid_runtime(vcpu);
> +		}
>  		break;
>  	case MSR_SMI_COUNT:
>  		if (!msr_info->host_initiated)
> -- 
> 2.27.0
> 

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 04/15] KVM: PMU: disable LBR handling if architectural LBR is available
  2022-11-25  4:05 ` [PATCH v2 04/15] KVM: PMU: disable LBR handling if architectural LBR is available Yang Weijiang
@ 2023-01-27 20:10   ` Sean Christopherson
  2023-01-30  8:10     ` Yang, Weijiang
  0 siblings, 1 reply; 64+ messages in thread
From: Sean Christopherson @ 2023-01-27 20:10 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang

On Thu, Nov 24, 2022, Yang Weijiang wrote:
> From: Paolo Bonzini <pbonzini@redhat.com>
> 
> Traditional LBR is absent on CPU models that have architectural LBR, so
> disable all processing of traditional LBR MSRs if they are not there.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> ---
>  arch/x86/kvm/vmx/pmu_intel.c | 32 ++++++++++++++++++++++----------
>  1 file changed, 22 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
> index e5cec07ca8d9..905673228932 100644
> --- a/arch/x86/kvm/vmx/pmu_intel.c
> +++ b/arch/x86/kvm/vmx/pmu_intel.c
> @@ -170,19 +170,23 @@ static inline struct kvm_pmc *get_fw_gp_pmc(struct kvm_pmu *pmu, u32 msr)
>  static bool intel_pmu_is_valid_lbr_msr(struct kvm_vcpu *vcpu, u32 index)
>  {
>  	struct x86_pmu_lbr *records = vcpu_to_lbr_records(vcpu);
> -	bool ret = false;
>  
>  	if (!intel_pmu_lbr_is_enabled(vcpu))
> -		return ret;
> +		return false;
>  
> -	ret = (index == MSR_LBR_SELECT) || (index == MSR_LBR_TOS) ||
> -		(index >= records->from && index < records->from + records->nr) ||
> -		(index >= records->to && index < records->to + records->nr);
> +	if (!guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) &&

IIUC, the MSRs flat out don't exist _and_ KVM expects to passthrough MSRs to the
guest, i.e. KVM should check host support, not guest support.  Probably a moot
point from a functionality perspective since KVM shouldn't allow LBRs to shouldn't
be enabled for the guest, but from a performance perspective, checking guest CPUID
is slooow.

That brings me to point #2, which is that KVM needs to disallow enabling legacy
LBRs on CPUs that support arch LBRs.  Again, IIUC, because KVM doesn't have the
option to fallback to legacy LBRs, that restriction needs to be treated as a bug
fix.  I'll post a separate patch unless my understanding is wrong.

> +	    (index == MSR_LBR_SELECT || index == MSR_LBR_TOS))
> +		return true;
>  
> -	if (!ret && records->info)
> -		ret = (index >= records->info && index < records->info + records->nr);
> +	if ((index >= records->from && index < records->from + records->nr) ||
> +	    (index >= records->to && index < records->to + records->nr))
> +		return true;
>  
> -	return ret;
> +	if (records->info && index >= records->info &&
> +	    index < records->info + records->nr)
> +		return true;
> +
> +	return false;
>  }
>  
>  static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)
> @@ -702,6 +706,9 @@ static void vmx_update_intercept_for_lbr_msrs(struct kvm_vcpu *vcpu, bool set)
>  			vmx_set_intercept_for_msr(vcpu, lbr->info + i, MSR_TYPE_RW, set);
>  	}
>  
> +	if (guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR))

Similar to above, I really don't want to query guest CPUID in the VM-Enter path.
If we establish the rule that LBRs can be enabled if and only if the correct type
is enabled (traditional/legacy vs. arch), then this can simply check host support.

> +		return;
> +
>  	vmx_set_intercept_for_msr(vcpu, MSR_LBR_SELECT, MSR_TYPE_RW, set);
>  	vmx_set_intercept_for_msr(vcpu, MSR_LBR_TOS, MSR_TYPE_RW, set);
>  }
> @@ -742,10 +749,12 @@ void vmx_passthrough_lbr_msrs(struct kvm_vcpu *vcpu)
>  {
>  	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
>  	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
> +	bool lbr_enable = !guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) &&
> +		(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR);

Unnecessary guest CPUID lookup and VMCS read, i.e. this can be deferred to the
!lbr_desc->event path.

>  
>  	if (!lbr_desc->event) {
>  		vmx_disable_lbr_msrs_passthrough(vcpu);
> -		if (vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR)
> +		if (lbr_enable)
>  			goto warn;
>  		if (test_bit(INTEL_PMC_IDX_FIXED_VLBR, pmu->pmc_in_use))
>  			goto warn;
> @@ -768,7 +777,10 @@ void vmx_passthrough_lbr_msrs(struct kvm_vcpu *vcpu)
>  
>  static void intel_pmu_cleanup(struct kvm_vcpu *vcpu)
>  {
> -	if (!(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR))
> +	bool lbr_enable = !guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) &&
> +		(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR);
> +
> +	if (!lbr_enable)
>  		intel_pmu_release_guest_lbr_event(vcpu);
>  }
>  
> -- 
> 2.27.0
> 

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 05/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_DEPTH for guest Arch LBR
  2022-11-25  4:05 ` [PATCH v2 05/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_DEPTH for guest Arch LBR Yang Weijiang
  2022-12-22 11:00   ` Like Xu
  2022-12-22 11:15   ` Like Xu
@ 2023-01-27 20:25   ` Sean Christopherson
  2023-01-30 11:46     ` Yang, Weijiang
  2 siblings, 1 reply; 64+ messages in thread
From: Sean Christopherson @ 2023-01-27 20:25 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang, Like Xu

On Thu, Nov 24, 2022, Yang Weijiang wrote:
> Write to MSR_ARCH_LBR_DEPTH has side-effect, all LBR entries are reset
> to 0. Kernel PMU driver can leverage this effect to do fask reset to
> LBR record MSRs. KVM allows guest to achieve it when Arch LBR records
> MSRs are passed through to the guest.
> 
> Signed-off-by: Like Xu <like.xu@linux.intel.com>
> Co-developed-by: Yang Weijiang <weijiang.yang@intel.com>
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> ---
>  arch/x86/include/asm/kvm_host.h |  3 ++
>  arch/x86/kvm/vmx/pmu_intel.c    | 58 +++++++++++++++++++++++++++++++--
>  2 files changed, 58 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 70af7240a1d5..2dba2fdd9cdc 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -571,6 +571,9 @@ struct kvm_pmu {
>  	 * redundant check before cleanup if guest don't use vPMU at all.
>  	 */
>  	u8 event_count;
> +
> +	/* Guest arch lbr depth supported by KVM. */
> +	u64 kvm_arch_lbr_depth;

There is zero reason to store this separately.  KVM already records the allowed
depth in kvm_vcpu.lbr_desc.records.nr.

>  };
>  
>  struct kvm_pmu_ops;
> diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
> index 905673228932..0c78cb4b72be 100644
> --- a/arch/x86/kvm/vmx/pmu_intel.c
> +++ b/arch/x86/kvm/vmx/pmu_intel.c
> @@ -178,6 +178,10 @@ static bool intel_pmu_is_valid_lbr_msr(struct kvm_vcpu *vcpu, u32 index)
>  	    (index == MSR_LBR_SELECT || index == MSR_LBR_TOS))
>  		return true;
>  
> +	if (index == MSR_ARCH_LBR_DEPTH)
> +		return kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&

Like the previous patch, since intel_pmu_lbr_is_enabled() effectively serves as
a generic kvm_cpu_cap_has(LBRS) check, this can be distilled to:

	if (cpu_feature_enabled(X86_FEATURE_ARCH_LBR)) {
		if (index == MSR_ARCH_LBR_DEPTH || index == MSR_ARCH_LBR_CTL)
			return true;
	} else {
		if (index == MSR_LBR_SELECT || index == MSR_LBR_TOS))
			return true;
	}

> +		       guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR);
> +
>  	if ((index >= records->from && index < records->from + records->nr) ||
>  	    (index >= records->to && index < records->to + records->nr))
>  		return true;
> @@ -345,6 +349,7 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  {
>  	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
>  	struct kvm_pmc *pmc;
> +	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
>  	u32 msr = msr_info->index;
>  
>  	switch (msr) {
> @@ -369,6 +374,9 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  	case MSR_PEBS_DATA_CFG:
>  		msr_info->data = pmu->pebs_data_cfg;
>  		return 0;
> +	case MSR_ARCH_LBR_DEPTH:
> +		msr_info->data = lbr_desc->records.nr;
> +		return 0;
>  	default:
>  		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
>  		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
> @@ -395,6 +403,7 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  {
>  	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
>  	struct kvm_pmc *pmc;
> +	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
>  	u32 msr = msr_info->index;
>  	u64 data = msr_info->data;
>  	u64 reserved_bits, diff;
> @@ -456,6 +465,24 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  			return 0;
>  		}
>  		break;
> +	case MSR_ARCH_LBR_DEPTH:
> +		if (!pmu->kvm_arch_lbr_depth && !msr_info->host_initiated)

Don't invent a new check, just prevent KVM from reaching this path via the
existing intel_pmu_lbr_is_enabled().

> +			return 1;
> +		/*
> +		 * When guest/host depth are different, the handling would be tricky,
> +		 * so only max depth is supported for both host and guest.
> +		 */

This semi-arbitrary restriction is fine because Intel's architecture allows KVM
to enumerate support for a single depth, but somewhere in the changelog and/or
code that actually needs to be state.  This blurb

  In the first generation of Arch LBR, max entry size is 32,
  host configures the max size and guest always honors the setting.

makes it sound like KVM is relying on the guest to do the right thing, and this
code looks like KVM is making up it's own behavior.

> +		if (data != pmu->kvm_arch_lbr_depth)
> +			return 1;
> +
> +		lbr_desc->records.nr = data;
> +		/*
> +		 * Writing depth MSR from guest could either setting the
> +		 * MSR or resetting the LBR records with the side-effect.
> +		 */
> +		if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR))

Another check, really?  KVM shouldn't reach this point if KVM doesn't support
Arch LBRs.  And if that isn't guarantee (honestly forgot what this series actually
proposed at this point), then that's a bug, full stop.

> +			wrmsrl(MSR_ARCH_LBR_DEPTH, lbr_desc->records.nr);

IIUC, this is subtly broken.  Piecing together all of the undocumented bits, my
understanding is that arch LBRs piggyback KVM's existing LBR support, i.e. use a
"virtual" perf event.  And like traditional LBR support, the host can steal control
of the LBRs in IRQ context by disabling the perf event via IPI.  And since writes
to MSR_ARCH_LBR_DEPTH purge LBR records, this needs to be treated as if it were a
write to an LBR record, i.e. belongs in the IRQs disabled section of
intel_pmu_handle_lbr_msrs_access().

If for some magical reason it's safe to access arch LBR MSRs without disabling IRQs
and confirming perf event ownership, I want to see a very detailed changelog
explaining exactly how that magic works.

> +		return 0;
>  	default:
>  		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
>  		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
> @@ -506,6 +533,32 @@ static void setup_fixed_pmc_eventsel(struct kvm_pmu *pmu)
>  	}
>  }
>  
> +static bool cpuid_enable_lbr(struct kvm_vcpu *vcpu)
> +{
> +	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
> +	struct kvm_cpuid_entry2 *entry;
> +	int depth_bit;
> +
> +	if (!kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR))
> +		return !static_cpu_has(X86_FEATURE_ARCH_LBR) &&
> +			cpuid_model_is_consistent(vcpu);
> +
> +	pmu->kvm_arch_lbr_depth = 0;
> +	if (!guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR))
> +		return false;
> +
> +	entry = kvm_find_cpuid_entry(vcpu, 0x1C);
> +	if (!entry)
> +		return false;
> +
> +	depth_bit = fls(cpuid_eax(0x1C) & 0xff);

This is unnecessarily fragile.  Get the LBR depth from perf, don't read CPUID and
assume perf will always configured the max depth.,

This enabling also belongs at the tail end of the series, i.e. KVM shouldn't let
userspace enable LBRs until all the support pieces are in place.

> +	if ((entry->eax & 0xff) != (1 << (depth_bit - 1)))
> +		return false;
> +
> +	pmu->kvm_arch_lbr_depth = depth_bit * 8;
> +	return true;
> +}
> +
>  static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
>  {
>  	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
> @@ -589,9 +642,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
>  	bitmap_set(pmu->all_valid_pmc_idx,
>  		INTEL_PMC_MAX_GENERIC, pmu->nr_arch_fixed_counters);
>  
> -	perf_capabilities = vcpu_get_perf_capabilities(vcpu);
> -	if (cpuid_model_is_consistent(vcpu) &&
> -	    (perf_capabilities & PMU_CAP_LBR_FMT))
> +	if (cpuid_enable_lbr(vcpu))
>  		x86_perf_get_lbr(&lbr_desc->records);
>  	else
>  		lbr_desc->records.nr = 0;
> @@ -599,6 +650,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
>  	if (lbr_desc->records.nr)
>  		bitmap_set(pmu->all_valid_pmc_idx, INTEL_PMC_IDX_FIXED_VLBR, 1);
>  
> +	perf_capabilities = vcpu_get_perf_capabilities(vcpu);
>  	if (perf_capabilities & PERF_CAP_PEBS_FORMAT) {
>  		if (perf_capabilities & PERF_CAP_PEBS_BASELINE) {
>  			pmu->pebs_enable_mask = counter_mask;
> -- 
> 2.27.0
> 

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 06/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL for guest Arch LBR
  2022-11-25  4:05 ` [PATCH v2 06/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL " Yang Weijiang
                     ` (2 preceding siblings ...)
  2022-12-22 11:24   ` Like Xu
@ 2023-01-27 21:42   ` Sean Christopherson
  3 siblings, 0 replies; 64+ messages in thread
From: Sean Christopherson @ 2023-01-27 21:42 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang, Like Xu

On Thu, Nov 24, 2022, Yang Weijiang wrote:
> @@ -345,6 +346,30 @@ static bool intel_pmu_handle_lbr_msrs_access(struct kvm_vcpu *vcpu,
>  	return true;
>  }
>  
> +static bool arch_lbr_ctl_is_valid(struct kvm_vcpu *vcpu, u64 ctl)
> +{
> +	struct kvm_cpuid_entry2 *entry;
> +	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
> +
> +	if (!pmu->kvm_arch_lbr_depth)
> +		return false;
> +
> +	if (ctl & ~KVM_ARCH_LBR_CTL_MASK)
> +		return false;
> +
> +	entry = kvm_find_cpuid_entry(vcpu, 0x1c);

Why!?!?!  Why does this series reinvent the wheel so many times.  We already have
a huge pile of reserved bits masks that are computed in intel_pmu_refresh(), just
do the easy thing and follow the established pattern.

> +	if (!entry)
> +		return false;
> +
> +	if (!(entry->ebx & BIT(0)) && (ctl & ARCH_LBR_CTL_CPL))
> +		return false;
> +	if (!(entry->ebx & BIT(2)) && (ctl & ARCH_LBR_CTL_STACK))
> +		return false;
> +	if (!(entry->ebx & BIT(1)) && (ctl & ARCH_LBR_CTL_FILTER))
> +		return false;
> +	return true;
> +}
> +
>  static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  {
>  	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
> @@ -377,6 +402,14 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  	case MSR_ARCH_LBR_DEPTH:
>  		msr_info->data = lbr_desc->records.nr;
>  		return 0;
> +	case MSR_ARCH_LBR_CTL:
> +		if (!kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR)) {

So I assume the point of this code is to allow reading MSR_ARCH_LBR_CTL from
userspace before doing KVM_SET_CPUID2, but I would much rather do that in a
generic way, i.e. build this series on 
https://lore.kernel.org/all/20230124234905.3774678-7-seanjc@google.com

> +			WARN_ON_ONCE(!msr_info->host_initiated);
> +			msr_info->data = 0;
> +		} else {
> +			msr_info->data = vmcs_read64(GUEST_IA32_LBR_CTL);
> +		}
> +		return 0;
>  	default:
>  		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
>  		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
> @@ -483,6 +516,18 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  		if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR))
>  			wrmsrl(MSR_ARCH_LBR_DEPTH, lbr_desc->records.nr);
>  		return 0;
> +	case MSR_ARCH_LBR_CTL:
> +		if (msr_info->host_initiated && !pmu->kvm_arch_lbr_depth)
> +			return data != 0;
> +
> +		if (!arch_lbr_ctl_is_valid(vcpu, data))
> +			break;
> +
> +		vmcs_write64(GUEST_IA32_LBR_CTL, data);
> +		if (intel_pmu_lbr_is_enabled(vcpu) && !lbr_desc->event &&
> +		    (data & ARCH_LBR_CTL_LBREN))
> +			intel_pmu_create_guest_lbr_event(vcpu);
> +		return 0;
>  	default:
>  		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
>  		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
> @@ -727,12 +772,16 @@ static void intel_pmu_reset(struct kvm_vcpu *vcpu)
>   */
>  static void intel_pmu_legacy_freezing_lbrs_on_pmi(struct kvm_vcpu *vcpu)
>  {
> -	u64 data = vmcs_read64(GUEST_IA32_DEBUGCTL);
> +	u32 lbr_ctl_field = GUEST_IA32_DEBUGCTL;
>  
> -	if (data & DEBUGCTLMSR_FREEZE_LBRS_ON_PMI) {
> -		data &= ~DEBUGCTLMSR_LBR;
> -		vmcs_write64(GUEST_IA32_DEBUGCTL, data);
> -	}
> +	if (!(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_FREEZE_LBRS_ON_PMI))
> +		return;
> +
> +	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
> +	    guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR))
> +		lbr_ctl_field = GUEST_IA32_LBR_CTL;

Similar to other comments, just rely on KVM not allowing LBRs to be enabled unless
the guest is configured with the correct flavor.

> +
> +	vmcs_write64(lbr_ctl_field, vmcs_read64(lbr_ctl_field) & ~0x1ULL);

Open coding a bit just because it happens to be in the same position in both fields
is ridiculous.

	u64 debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL);

	if (!debugctl & DEBUGCTLMSR_FREEZE_LBRS_ON_PMI))
		return;

	if (cpu_feature_enabled(X86_FEATURE_ARCH_LBR))
		vmcs_clear_bits64(GUEST_IA32_LBR_CTL, ARCH_LBR_CTL_LBREN);
	else
		vmcs_write64(GUEST_IA32_DEBUGCTL, debugctl & ~DEBUGCTLMSR_LBR);

>  }
>  
>  static void intel_pmu_deliver_pmi(struct kvm_vcpu *vcpu)
> @@ -801,7 +850,8 @@ void vmx_passthrough_lbr_msrs(struct kvm_vcpu *vcpu)
>  {
>  	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
>  	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
> -	bool lbr_enable = !guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) &&
> +	bool lbr_enable = guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) ?
> +		(vmcs_read64(GUEST_IA32_LBR_CTL) & ARCH_LBR_CTL_LBREN) :
>  		(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR);
>  
>  	if (!lbr_desc->event) {
> @@ -829,7 +879,8 @@ void vmx_passthrough_lbr_msrs(struct kvm_vcpu *vcpu)
>  
>  static void intel_pmu_cleanup(struct kvm_vcpu *vcpu)
>  {
> -	bool lbr_enable = !guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) &&
> +	bool lbr_enable = guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) ?
> +		(vmcs_read64(GUEST_IA32_LBR_CTL) & ARCH_LBR_CTL_LBREN) :
>  		(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR);

Instead of open coding the same ugly ternary operator in multiple locations, add
a helper.

>  
>  	if (!lbr_enable)
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index cea8c07f5229..1ae2efc29546 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -2120,6 +2120,13 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  						VM_EXIT_SAVE_DEBUG_CONTROLS)
>  			get_vmcs12(vcpu)->guest_ia32_debugctl = data;
>  
> +		/*
> +		 * For Arch LBR, IA32_DEBUGCTL[bit 0] has no meaning.
> +		 * It can be written to 0 or 1, but reads will always return 0.
> +		 */
> +		if (guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR))

This can be dependent solely on the host CPU.  If LBRs are unsupported, the bit
will be marked invalid and cleared above.  And as mentioned multiple times, KVM
needs to allow enabling LBRs iff the guest and host flavors match.

> +			data &= ~DEBUGCTLMSR_LBR;

This needs to be done before shoving the value into vmcs12.

> +
>  		vmcs_write64(GUEST_IA32_DEBUGCTL, data);
>  		if (intel_pmu_lbr_is_enabled(vcpu) && !to_vmx(vcpu)->lbr_desc.event &&
>  		    (data & DEBUGCTLMSR_LBR))
> -- 
> 2.27.0
> 

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 08/15] KVM: x86: Add Arch LBR MSRs to msrs_to_save_all list
  2022-11-25  4:05 ` [PATCH v2 08/15] KVM: x86: Add Arch LBR MSRs to msrs_to_save_all list Yang Weijiang
@ 2023-01-27 21:43   ` Sean Christopherson
  2023-01-30 12:27     ` Yang, Weijiang
  0 siblings, 1 reply; 64+ messages in thread
From: Sean Christopherson @ 2023-01-27 21:43 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang

On Thu, Nov 24, 2022, Yang Weijiang wrote:
> Arch LBR MSR_ARCH_LBR_DEPTH and MSR_ARCH_LBR_CTL are queried by
> userspace application before it wants to {save|restore} the Arch LBR
> data. Other LBR related data MSRs are omitted here intentionally due
> to lengthy list(32*3). Userspace can still use KVM_{GET|SET}_MSRS to
> access them if necessary.

Absolutely not.  "there are a lot of them" isn't sufficient justification.  If
the MSRs need to be migrated, then KVM needs to report them.  If the expectation
is that XSAVES will handle them, then KVM needs to take a dependency on XSAVES
when enabling arch LBRs.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 09/15] KVM: x86: Refine the matching and clearing logic for supported_xss
  2022-11-25  4:05 ` [PATCH v2 09/15] KVM: x86: Refine the matching and clearing logic for supported_xss Yang Weijiang
@ 2023-01-27 21:46   ` Sean Christopherson
  2023-01-30 12:37     ` Yang, Weijiang
  0 siblings, 1 reply; 64+ messages in thread
From: Sean Christopherson @ 2023-01-27 21:46 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang

On Thu, Nov 24, 2022, Yang Weijiang wrote:
> From: Paolo Bonzini <pbonzini@redhat.com>
> 
> Refine the code path of the existing clearing of supported_xss in this way:
> initialize the supported_xss with the filter of KVM_SUPPORTED_XSS mask and
> update its value in a bit clear manner (rather than bit setting).
> 
> Suggested-by: Sean Christopherson <seanjc@google.com>
> Signed-off-by: Like Xu <like.xu@linux.intel.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> ---
>  arch/x86/kvm/vmx/vmx.c | 5 +++--
>  arch/x86/kvm/x86.c     | 6 +++++-
>  2 files changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index 9bd52ad3bbf4..2ab4c33b5008 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -7738,9 +7738,10 @@ static __init void vmx_set_cpu_caps(void)
>  		kvm_cpu_cap_set(X86_FEATURE_UMIP);
>  
>  	/* CPUID 0xD.1 */
> -	kvm_caps.supported_xss = 0;

This needs to stay until VMX actually supports something.

> -	if (!cpu_has_vmx_xsaves())
> +	if (!cpu_has_vmx_xsaves()) {
>  		kvm_cpu_cap_clear(X86_FEATURE_XSAVES);
> +		kvm_caps.supported_xss = 0;

This is already handled in common KVM.

> +	}
>  
>  	/* CPUID 0x80000001 and 0x7 (RDPID) */
>  	if (!cpu_has_vmx_rdtscp()) {
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 74c858eaa1ea..889be0c9176d 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -217,6 +217,8 @@ static struct kvm_user_return_msrs __percpu *user_return_msrs;
>  				| XFEATURE_MASK_BNDCSR | XFEATURE_MASK_AVX512 \
>  				| XFEATURE_MASK_PKRU | XFEATURE_MASK_XTILE)
>  
> +#define KVM_SUPPORTED_XSS     0
> +
>  u64 __read_mostly host_efer;
>  EXPORT_SYMBOL_GPL(host_efer);
>  
> @@ -11999,8 +12001,10 @@ int kvm_arch_hardware_setup(void *opaque)
>  
>  	rdmsrl_safe(MSR_EFER, &host_efer);
>  
> -	if (boot_cpu_has(X86_FEATURE_XSAVES))
> +	if (boot_cpu_has(X86_FEATURE_XSAVES)) {
>  		rdmsrl(MSR_IA32_XSS, host_xss);
> +		kvm_caps.supported_xss = host_xss & KVM_SUPPORTED_XSS;
> +	}
>  
>  	kvm_init_pmu_capability();
>  
> -- 
> 2.27.0
> 

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 10/15] KVM: x86/vmx: Check Arch LBR config when return perf capabilities
  2022-11-25  4:05 ` [PATCH v2 10/15] KVM: x86/vmx: Check Arch LBR config when return perf capabilities Yang Weijiang
  2022-12-22 11:06   ` Like Xu
@ 2023-01-27 22:04   ` Sean Christopherson
  1 sibling, 0 replies; 64+ messages in thread
From: Sean Christopherson @ 2023-01-27 22:04 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang, Like Xu

On Thu, Nov 24, 2022, Yang Weijiang wrote:
>  	return vmcs_config.cpu_based_2nd_exec_ctrl &
> diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> index b28be793de29..59bdd9873fb5 100644
> --- a/arch/x86/kvm/vmx/nested.c
> +++ b/arch/x86/kvm/vmx/nested.c
> @@ -2360,6 +2360,10 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0
>  		if (guest_efer != host_efer)
>  			exec_control |= VM_ENTRY_LOAD_IA32_EFER;
>  	}
> +
> +	if (cpu_has_vmx_arch_lbr())
> +		exec_control &= ~VM_ENTRY_LOAD_IA32_LBR_CTL;
> +
>  	vm_entry_controls_set(vmx, exec_control);
>  
>  	/*
> @@ -2374,6 +2378,10 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0
>  		exec_control |= VM_EXIT_LOAD_IA32_EFER;
>  	else
>  		exec_control &= ~VM_EXIT_LOAD_IA32_EFER;
> +
> +	if (cpu_has_vmx_arch_lbr())
> +		exec_control &= ~VM_EXIT_CLEAR_IA32_LBR_CTL;

This is wrong.  If KVM doesn't enumerate suport to L1, then L1's value needs to
be preserved on entry/exit to/from L1<->L2.  I.e. just delete these lines.

>  	vm_exit_controls_set(vmx, exec_control);
>  
>  	/*
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index 2ab4c33b5008..359da38a19a1 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -2599,6 +2599,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf,
>  		{ VM_ENTRY_LOAD_IA32_EFER,		VM_EXIT_LOAD_IA32_EFER },
>  		{ VM_ENTRY_LOAD_BNDCFGS,		VM_EXIT_CLEAR_BNDCFGS },
>  		{ VM_ENTRY_LOAD_IA32_RTIT_CTL,		VM_EXIT_CLEAR_IA32_RTIT_CTL },
> +		{ VM_ENTRY_LOAD_IA32_LBR_CTL, 		VM_EXIT_CLEAR_IA32_LBR_CTL },
>  	};
>  
>  	memset(vmcs_conf, 0, sizeof(*vmcs_conf));
> @@ -4794,6 +4795,9 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>  	vpid_sync_context(vmx->vpid);
>  
>  	vmx_update_fb_clear_dis(vcpu, vmx);
> +
> +	if (!init_event && cpu_has_vmx_arch_lbr())
> +		vmcs_write64(GUEST_IA32_LBR_CTL, 0);

This belongs in init_vmcs().

>  }
>  
>  static void vmx_enable_irq_window(struct kvm_vcpu *vcpu)
> @@ -6191,6 +6195,10 @@ void dump_vmcs(struct kvm_vcpu *vcpu)
>  	    vmentry_ctl & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL)
>  		pr_err("PerfGlobCtl = 0x%016llx\n",
>  		       vmcs_read64(GUEST_IA32_PERF_GLOBAL_CTRL));
> +	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&

Follow every other field and check the VMCS support, not the cap.

> +	    vmentry_ctl & VM_ENTRY_LOAD_IA32_LBR_CTL)
> +		pr_err("ArchLBRCtl = 0x%016llx\n",
> +		       vmcs_read64(GUEST_IA32_LBR_CTL));
>  	if (vmentry_ctl & VM_ENTRY_LOAD_BNDCFGS)
>  		pr_err("BndCfgS = 0x%016llx\n", vmcs_read64(GUEST_BNDCFGS));
>  	pr_err("Interruptibility = %08x  ActivityState = %08x\n",

...

> diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
> index a3da84f4ea45..f68c8a53a248 100644
> --- a/arch/x86/kvm/vmx/vmx.h
> +++ b/arch/x86/kvm/vmx/vmx.h
> @@ -493,7 +493,8 @@ static inline u8 vmx_get_rvi(void)
>  	 VM_ENTRY_LOAD_IA32_EFER |					\
>  	 VM_ENTRY_LOAD_BNDCFGS |					\
>  	 VM_ENTRY_PT_CONCEAL_PIP |					\
> -	 VM_ENTRY_LOAD_IA32_RTIT_CTL)
> +	 VM_ENTRY_LOAD_IA32_RTIT_CTL |					\
> +	 VM_ENTRY_LOAD_IA32_LBR_CTL)
>  
>  #define __KVM_REQUIRED_VMX_VM_EXIT_CONTROLS				\
>  	(VM_EXIT_SAVE_DEBUG_CONTROLS |					\
> @@ -515,7 +516,8 @@ static inline u8 vmx_get_rvi(void)
>  	       VM_EXIT_LOAD_IA32_EFER |					\
>  	       VM_EXIT_CLEAR_BNDCFGS |					\
>  	       VM_EXIT_PT_CONCEAL_PIP |					\
> -	       VM_EXIT_CLEAR_IA32_RTIT_CTL)
> +	       VM_EXIT_CLEAR_IA32_RTIT_CTL |				\
> +	       VM_EXIT_CLEAR_IA32_LBR_CTL)

Enabling these flags by default is wrong.  KVM will clear LBR_CTL on VM-Exit when
arch LBRs are supported, and AFAICT, never restore the host's values.  And that
will happen regardless of whether or not the guest is using arch LBRs.  I assume
the correct approach is to toggle these fields, but I'll be damned if I can figure
out what the intended behavior of the existing LBR suport is.  I'll follow up in
the cover letter.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 11/15] KVM: x86: Add XSAVE Support for Architectural LBR
  2022-11-25  4:06 ` [PATCH v2 11/15] KVM: x86: Add XSAVE Support for Architectural LBR Yang Weijiang
@ 2023-01-27 22:07   ` Sean Christopherson
  2023-01-30 13:13     ` Yang, Weijiang
  0 siblings, 1 reply; 64+ messages in thread
From: Sean Christopherson @ 2023-01-27 22:07 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang, Like Xu

On Thu, Nov 24, 2022, Yang Weijiang wrote:
> From: Like Xu <like.xu@linux.intel.com>
> 
> On processors supporting XSAVES and XRSTORS, Architectural LBR XSAVE
> support is enumerated from CPUID.(EAX=0DH, ECX=1):ECX[bit 15].
> The detailed sub-leaf for Arch LBR is enumerated in CPUID.(0DH, 0FH).
> 
> XSAVES provides a faster means than RDMSR for guest to read all LBRs.
> When guest IA32_XSS[bit 15] is set, the Arch LBR state can be saved using
> XSAVES and restored by XRSTORS with the appropriate RFBM.
> 
> Signed-off-by: Like Xu <like.xu@linux.intel.com>
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> ---
>  arch/x86/kvm/vmx/vmx.c | 4 ++++
>  arch/x86/kvm/x86.c     | 2 +-
>  2 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index 359da38a19a1..3bc892e8cf7a 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -7733,6 +7733,10 @@ static __init void vmx_set_cpu_caps(void)
>  		kvm_cpu_cap_check_and_set(X86_FEATURE_DS);
>  		kvm_cpu_cap_check_and_set(X86_FEATURE_DTES64);
>  	}
> +	if (!cpu_has_vmx_arch_lbr()) {
> +		kvm_cpu_cap_clear(X86_FEATURE_ARCH_LBR);

No, this needs to be opt-in, not opt-out.  I.e. omit the flag from common CPUID
code and set it if and only if it's fully supported.  It's not out of the realm
of possibilities that AMD might want to support arch LBRs, at which point those
CPUs would explode.

> +		kvm_caps.supported_xss &= ~XFEATURE_MASK_LBR;
> +	}
>  
>  	if (!enable_pmu)
>  		kvm_cpu_cap_clear(X86_FEATURE_PDCM);
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 889be0c9176d..38df08d9d0cb 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -217,7 +217,7 @@ static struct kvm_user_return_msrs __percpu *user_return_msrs;
>  				| XFEATURE_MASK_BNDCSR | XFEATURE_MASK_AVX512 \
>  				| XFEATURE_MASK_PKRU | XFEATURE_MASK_XTILE)
>  
> -#define KVM_SUPPORTED_XSS     0
> +#define KVM_SUPPORTED_XSS     XFEATURE_MASK_LBR
>  
>  u64 __read_mostly host_efer;
>  EXPORT_SYMBOL_GPL(host_efer);
> -- 
> 2.27.0
> 

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 12/15] KVM: x86/vmx: Disable Arch LBREn bit in #DB and warm reset
  2022-11-25  4:06 ` [PATCH v2 12/15] KVM: x86/vmx: Disable Arch LBREn bit in #DB and warm reset Yang Weijiang
  2022-12-22 11:22   ` Like Xu
@ 2023-01-27 22:09   ` Sean Christopherson
  2023-01-30 13:09     ` Yang, Weijiang
  1 sibling, 1 reply; 64+ messages in thread
From: Sean Christopherson @ 2023-01-27 22:09 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang

On Thu, Nov 24, 2022, Yang Weijiang wrote:
> Per SDM 3B, Chapter 18:
> “On a debug breakpoint event (#DB), IA32_LBR_CTL.LBREn is cleared.”
> and "On a warm reset, all LBR MSRs, including IA32_LBR_DEPTH, have their
> values preserved. However, IA32_LBR_CTL.LBREn is cleared to 0, disabling
> LBRs.", clear the bit manually before inject #DB or when vCPU is in warm
> reset.
> 
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> ---
>  arch/x86/kvm/vmx/vmx.c | 24 +++++++++++++++++++++++-
>  1 file changed, 23 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index 3bc892e8cf7a..6ad765ea4059 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -1695,6 +1695,20 @@ static void vmx_clear_hlt(struct kvm_vcpu *vcpu)
>  		vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE);
>  }
>  
> +static void disable_arch_lbr_ctl(struct kvm_vcpu *vcpu)
> +{
> +	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
> +	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
> +
> +	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
> +	    test_bit(INTEL_PMC_IDX_FIXED_VLBR, pmu->pmc_in_use) &&
> +	    lbr_desc->event) {

I don't see any reason to check that an event is actually assigned.  The behavior
is architectural, whether or not KVM is actively exposing LBRs to the guest is
irrelevant.

> +		u64 ctl = vmcs_read64(GUEST_IA32_LBR_CTL);
> +
> +		vmcs_write64(GUEST_IA32_LBR_CTL, ctl & ~ARCH_LBR_CTL_LBREN);
> +	}
> +}
> +
>  static void vmx_inject_exception(struct kvm_vcpu *vcpu)
>  {
>  	struct kvm_queued_exception *ex = &vcpu->arch.exception;
> @@ -1738,6 +1752,9 @@ static void vmx_inject_exception(struct kvm_vcpu *vcpu)
>  	vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
>  
>  	vmx_clear_hlt(vcpu);
> +
> +	if (ex->vector == DB_VECTOR)
> +		disable_arch_lbr_ctl(vcpu);
>  }
>  
>  static void vmx_setup_uret_msr(struct vcpu_vmx *vmx, unsigned int msr,
> @@ -4796,7 +4813,9 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>  
>  	vmx_update_fb_clear_dis(vcpu, vmx);
>  
> -	if (!init_event && cpu_has_vmx_arch_lbr())
> +	if (init_event)

INIT and warm RESET are not the same thing, i.e. this is flat out wrong.

> +		disable_arch_lbr_ctl(vcpu);
> +	else if (cpu_has_vmx_arch_lbr())
>  		vmcs_write64(GUEST_IA32_LBR_CTL, 0);
>  }
>  
> @@ -4873,6 +4892,9 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
>  			INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR);
>  
>  	vmx_clear_hlt(vcpu);
> +
> +	if (vcpu->arch.exception.vector == DB_VECTOR)

Huh?  This is _very_ obviously injecting NMIs, not #DBs.

> +		disable_arch_lbr_ctl(vcpu);
>  }
>  
>  bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu)
> -- 
> 2.27.0
> 

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 13/15] KVM: x86/vmx: Save/Restore guest Arch LBR Ctrl msr at SMM entry/exit
  2022-11-25  4:06 ` [PATCH v2 13/15] KVM: x86/vmx: Save/Restore guest Arch LBR Ctrl msr at SMM entry/exit Yang Weijiang
@ 2023-01-27 22:11   ` Sean Christopherson
  2023-01-30 12:50     ` Yang, Weijiang
  0 siblings, 1 reply; 64+ messages in thread
From: Sean Christopherson @ 2023-01-27 22:11 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang

On Thu, Nov 24, 2022, Yang Weijiang wrote:
> Per SDM 3B Chapter 18: "IA32_LBR_CTL.LBREn is saved and cleared on #SMI,
> and restored on RSM", store guest IA32_LBR_CTL in SMRAM and clear LBREn
> in VMCS at SMM entry, and do reverse things at SMM exit.
> 
> Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> ---
>  arch/x86/kvm/smm.c     |  1 +
>  arch/x86/kvm/smm.h     |  3 ++-
>  arch/x86/kvm/vmx/vmx.c | 22 ++++++++++++++++++++++
>  3 files changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kvm/smm.c b/arch/x86/kvm/smm.c
> index a9c1c2af8d94..5987090b440f 100644
> --- a/arch/x86/kvm/smm.c
> +++ b/arch/x86/kvm/smm.c
> @@ -86,6 +86,7 @@ static void check_smram_offsets(void)
>  	CHECK_SMRAM64_OFFSET(smm_revison,		0xFEFC);
>  	CHECK_SMRAM64_OFFSET(smbase,			0xFF00);
>  	CHECK_SMRAM64_OFFSET(reserved4,			0xFF04);
> +	CHECK_SMRAM64_OFFSET(arch_lbr_ctl,		0xFF10);
>  	CHECK_SMRAM64_OFFSET(ssp,			0xFF18);
>  	CHECK_SMRAM64_OFFSET(svm_guest_pat,		0xFF20);
>  	CHECK_SMRAM64_OFFSET(svm_host_efer,		0xFF28);
> diff --git a/arch/x86/kvm/smm.h b/arch/x86/kvm/smm.h
> index a1cf2ac5bd78..5a6479205d91 100644
> --- a/arch/x86/kvm/smm.h
> +++ b/arch/x86/kvm/smm.h
> @@ -114,7 +114,8 @@ struct kvm_smram_state_64 {
>  	u32 reserved3[3];
>  	u32 smm_revison;
>  	u32 smbase;
> -	u32 reserved4[5];
> +	u32 reserved4[3];
> +	u64 arch_lbr_ctl;
>  
>  	/* ssp and svm_* fields below are not implemented by KVM */
>  	u64 ssp;
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index 6ad765ea4059..cc782233c075 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -8006,11 +8006,21 @@ static int vmx_enter_smm(struct kvm_vcpu *vcpu, union kvm_smram *smram)
>  	vmx->nested.smm.vmxon = vmx->nested.vmxon;
>  	vmx->nested.vmxon = false;
>  	vmx_clear_hlt(vcpu);
> +
> +	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
> +	    guest_cpuid_has(vcpu, X86_FEATURE_LM)) {

Uh, so this arbitrary dependency on 64-bit vCPUs needs to be factored into the
enabling.  And KVM should WARN if arch LBRs get enabled for a 32-bit vCPU.

> +		u64 ctl = vmcs_read64(GUEST_IA32_LBR_CTL);
> +
> +		smram->smram64.arch_lbr_ctl = ctl;
> +		vmcs_write64(GUEST_IA32_LBR_CTL, ctl & ~ARCH_LBR_CTL_LBREN);
> +	}
> +
>  	return 0;
>  }
>  
>  static int vmx_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)
>  {
> +	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
>  	struct vcpu_vmx *vmx = to_vmx(vcpu);
>  	int ret;
>  
> @@ -8027,6 +8037,18 @@ static int vmx_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)
>  		vmx->nested.nested_run_pending = 1;
>  		vmx->nested.smm.guest_mode = false;
>  	}
> +
> +	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
> +	    guest_cpuid_has(vcpu, X86_FEATURE_LM)) {
> +		u64 ctl = smram->smram64.arch_lbr_ctl;
> +
> +		vmcs_write64(GUEST_IA32_LBR_CTL, ctl & ARCH_LBR_CTL_LBREN);

IIUC, this should set only LBREn and preserve all other bits, not clobber the
entire MSR.

> +
> +		if (intel_pmu_lbr_is_enabled(vcpu) &&
> +		    (ctl & ARCH_LBR_CTL_LBREN) && !lbr_desc->event)
> +			intel_pmu_create_guest_lbr_event(vcpu);
> +	}
> +
>  	return 0;
>  }
>  
> -- 
> 2.27.0
> 

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 14/15] KVM: x86: Add Arch LBR data MSR access interface
  2022-11-25  4:06 ` [PATCH v2 14/15] KVM: x86: Add Arch LBR data MSR access interface Yang Weijiang
@ 2023-01-27 22:13   ` Sean Christopherson
  2023-01-30 12:46     ` Yang, Weijiang
  0 siblings, 1 reply; 64+ messages in thread
From: Sean Christopherson @ 2023-01-27 22:13 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang

On Thu, Nov 24, 2022, Yang Weijiang wrote:
> Arch LBR MSRs are xsave-supported, but they're operated as "independent"
> xsave feature by PMU code, i.e., during thread/process context switch,
> the MSRs are saved/restored with perf_event_task_sched_{in|out} instead
> of generic kernel fpu switch code, i.e.,save_fpregs_to_fpstate() and
> restore_fpregs_from_fpstate(). When vcpu guest/host fpu state swap happens,
> Arch LBR MSRs are retained so they can be accessed directly.
> 
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
> ---
>  arch/x86/kvm/vmx/pmu_intel.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
> index b57944d5e7d8..241128972776 100644
> --- a/arch/x86/kvm/vmx/pmu_intel.c
> +++ b/arch/x86/kvm/vmx/pmu_intel.c
> @@ -410,6 +410,11 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  			msr_info->data = vmcs_read64(GUEST_IA32_LBR_CTL);
>  		}
>  		return 0;
> +	case MSR_ARCH_LBR_FROM_0 ... MSR_ARCH_LBR_FROM_0 + 31:
> +	case MSR_ARCH_LBR_TO_0 ... MSR_ARCH_LBR_TO_0 + 31:
> +	case MSR_ARCH_LBR_INFO_0 ... MSR_ARCH_LBR_INFO_0 + 31:
> +		rdmsrl(msr_info->index, msr_info->data);

I don't see how this is correct.  As called out in patch 5:

 : If for some magical reason it's safe to access arch LBR MSRs without disabling
 : IRQs and confirming perf event ownership, I want to see a very detailed changelog
 : explaining exactly how that magic works.

> +		return 0;
>  	default:
>  		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
>  		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
> @@ -528,6 +533,11 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  		    (data & ARCH_LBR_CTL_LBREN))
>  			intel_pmu_create_guest_lbr_event(vcpu);
>  		return 0;
> +	case MSR_ARCH_LBR_FROM_0 ... MSR_ARCH_LBR_FROM_0 + 31:
> +	case MSR_ARCH_LBR_TO_0 ... MSR_ARCH_LBR_TO_0 + 31:
> +	case MSR_ARCH_LBR_INFO_0 ... MSR_ARCH_LBR_INFO_0 + 31:
> +		wrmsrl(msr_info->index, msr_info->data);
> +		return 0;
>  	default:
>  		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
>  		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
> -- 
> 2.27.0
> 

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 15/15] KVM: x86/cpuid: Advertise Arch LBR feature in CPUID
  2022-11-25  4:06 ` [PATCH v2 15/15] KVM: x86/cpuid: Advertise Arch LBR feature in CPUID Yang Weijiang
  2022-12-22 11:03   ` Like Xu
@ 2023-01-27 22:15   ` Sean Christopherson
  1 sibling, 0 replies; 64+ messages in thread
From: Sean Christopherson @ 2023-01-27 22:15 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang, Like Xu

On Thu, Nov 24, 2022, Yang Weijiang wrote:
> Add Arch LBR feature bit in CPU cap-mask to expose the feature.
> Only max LBR depth is supported for guest, and it's consistent
> with host Arch LBR settings.
> 
> Co-developed-by: Like Xu <like.xu@linux.intel.com>
> Signed-off-by: Like Xu <like.xu@linux.intel.com>
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
> ---
>  arch/x86/kvm/cpuid.c | 36 +++++++++++++++++++++++++++++++++++-
>  1 file changed, 35 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index 85e3df6217af..60b3c591d462 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -134,6 +134,19 @@ static int kvm_check_cpuid(struct kvm_vcpu *vcpu,
>  		if (vaddr_bits != 48 && vaddr_bits != 57 && vaddr_bits != 0)
>  			return -EINVAL;
>  	}
> +	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR)) {
> +		best = cpuid_entry2_find(entries, nent, 0x1c, 0);
> +		if (best) {
> +			unsigned int eax, ebx, ecx, edx;
> +
> +			/* Reject user-space CPUID if depth is different from host's.*/
> +			cpuid_count(0x1c, 0, &eax, &ebx, &ecx, &edx);
> +
> +			if ((eax & 0xff) &&
> +			    (best->eax & 0xff) != BIT(fls(eax & 0xff) - 1))
> +				return -EINVAL;
> +		}
> +	}

Drop this.  While I think everyone agrees that KVM's CPUID uAPI sucks, the status
quo is to let userspace shoot itself in the foot.  I.e. disallow enabling LBRs
with a "bad" config, but don't reject the ioctl().

>  
>  	/*
>  	 * Exposing dynamic xfeatures to the guest requires additional
> @@ -652,7 +665,7 @@ void kvm_set_cpu_caps(void)
>  		F(SPEC_CTRL_SSBD) | F(ARCH_CAPABILITIES) | F(INTEL_STIBP) |
>  		F(MD_CLEAR) | F(AVX512_VP2INTERSECT) | F(FSRM) |
>  		F(SERIALIZE) | F(TSXLDTRK) | F(AVX512_FP16) |
> -		F(AMX_TILE) | F(AMX_INT8) | F(AMX_BF16)
> +		F(AMX_TILE) | F(AMX_INT8) | F(AMX_BF16) | F(ARCH_LBR)

As mentioned earlier, omit this and make it opt-in.

>  	);
>  
>  	/* TSC_ADJUST and ARCH_CAPABILITIES are emulated in software. */
> @@ -1074,6 +1087,27 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
>  				goto out;
>  		}
>  		break;
> +	/* Architectural LBR */
> +	case 0x1c: {
> +		u32 lbr_depth_mask = entry->eax & 0xff;
> +
> +		if (!lbr_depth_mask ||
> +		    !kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR)) {
> +			entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
> +			break;
> +		}
> +		/*
> +		 * KVM only exposes the maximum supported depth, which is the
> +		 * fixed value used on the host side.
> +		 * KVM doesn't allow VMM userspace to adjust LBR depth because
> +		 * guest LBR emulation depends on the configuration of host LBR
> +		 * driver.
> +		 */
> +		lbr_depth_mask = BIT((fls(lbr_depth_mask) - 1));

C'mon.  More unnecessary dependencies on perf using the max depth.

> +		entry->eax &= ~0xff;
> +		entry->eax |= lbr_depth_mask;
> +		break;
> +	}
>  	/* Intel AMX TILE */
>  	case 0x1d:
>  		if (!kvm_cpu_cap_has(X86_FEATURE_AMX_TILE)) {
> -- 
> 2.27.0
> 

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 00/15] Introduce Architectural LBR for vPMU
  2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
                   ` (15 preceding siblings ...)
  2023-01-12  1:57 ` [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang, Weijiang
@ 2023-01-27 22:46 ` Sean Christopherson
  2023-01-30 13:38   ` Yang, Weijiang
  2023-06-05  9:50   ` Like Xu
  16 siblings, 2 replies; 64+ messages in thread
From: Sean Christopherson @ 2023-01-27 22:46 UTC (permalink / raw)
  To: Yang Weijiang
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang

On Thu, Nov 24, 2022, Yang Weijiang wrote:
> Intel CPU model-specific LBR(Legacy LBR) has evolved to Architectural
> LBR(Arch LBR [0]), it's the replacement of legacy LBR on new platforms.
> The native support patches were merged into 5.9 kernel tree, and this
> patch series is to enable Arch LBR in vPMU so that guest can benefit
> from the feature.
> 
> The main advantages of Arch LBR are [1]:
> - Faster context switching due to XSAVES support and faster reset of
>   LBR MSRs via the new DEPTH MSR
> - Faster LBR read for a non-PEBS event due to XSAVES support, which
>   lowers the overhead of the NMI handler.
> - Linux kernel can support the LBR features without knowing the model
>   number of the current CPU.
> 
> From end user's point of view, the usage of Arch LBR is the same as
> the Legacy LBR that has been merged in the mainline.
> 
> Note, in this series, there's one restriction for guest Arch LBR, i.e.,
> guest can only set its LBR record depth the same as host's. This is due
> to the special behavior of MSR_ARCH_LBR_DEPTH: 
> 1) On write to the MSR, it'll reset all Arch LBR recording MSRs to 0s.
> 2) XRSTORS resets all record MSRs to 0s if the saved depth mismatches
> MSR_ARCH_LBR_DEPTH.
> Enforcing the restriction keeps KVM Arch LBR vPMU working flow simple
> and straightforward.
> 
> Paolo refactored the old series and the resulting patches became the
> base of this new series, therefore he's the author of some patches.

To be very blunt, this series is a mess.  I don't want to point fingers as there
is plenty of blame to go around.  The existing LBR support is a confusing mess,
vPMU as a whole has been neglected for too long, review feedback has been relatively
non-existent, and I'm sure some of the mess is due to Paolo trying to hastily fix
things up back when this was temporarily queued.

However, for arch LBR support to be merged, things need to change.

First and foremost, the existing LBR support needs to be documented.  Someone,
I don't care who, needs to provide a detailed writeup of the contract between KVM
and perf.  Specifically, I want to know:

  1. When exactly is perf allowed to take control of LBR MRS.  Task switch?  IRQ?
     NMI?

  2. What is the expected behavior when perf is using LBRs?  Is the guest supposed
     to be traced?

  3. Why does KVM snapshot DEBUGCTL with IRQs enabled, but disables IRQs when
     accessing LBR MSRs?

It doesn't have to be polished, e.g. I'll happily wordsmith things into proper
documentation, but I want to have a very clear understanding of how LBR support
is _intended_ to function and how it all _actually_ functions without having to
make guesses.

And depending on the answers, I want to revisit KVM's LBR implementation before
tackling arch LBRs.  Letting perf usurp LBRs while KVM has the vCPU loaded is
frankly ridiculous.  Just have perf set a flag telling KVM that it needs to take
control of LBRs and have KVM service the flag as a request or something.  Stealing
the LBRs back in IRQ context adds a stupid amount of complexity without much value,
e.g. waiting a few branches for KVM to get to a safe place isn't going to meaningfully
change the traces.  If that can't actually happen, then why on earth does KVM need
to disable IRQs to read MSRs?

And AFAICT, since KVM unconditionally loads the guest's DEBUGCTL, whether or not
guest branches show up in the LBRs when the host is tracing is completely up to
the whims of the guest.  If that's correct, then again, what's the point of the
dance between KVM and perf?

Beyond the "how does this work" issues, there needs to be tests.  At the absolute
minimum, there needs to be selftests showing that this stuff actually works, that
save/restore (migration) works, that the MSRs can/can't be accessed when guest
CPUID is (in)correctly configured, etc. And I would really, really like to have
tests that force contention between host and guests, e.g. to make sure that KVM
isn't leaking host state or outright exploding, but I can understand that those
types of tests would be very difficult to write.

I've pushed a heavily reworked, but definitely broken, version to

  git@github.com:sean-jc/linux.git x86/arch_lbrs

It compiles, but it's otherwise untested and there are known gaps.  E.g. I omitted
toggling load+clear of ARCH_LBR_CTL because I couldn't figure out the intended
behavior.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 03/15] KVM: x86: Refresh CPUID on writes to MSR_IA32_XSS
  2023-01-26 19:50   ` Sean Christopherson
@ 2023-01-30  6:33     ` Yang, Weijiang
  0 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2023-01-30  6:33 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang


On 1/27/2023 3:50 AM, Sean Christopherson wrote:
> On Thu, Nov 24, 2022, Yang Weijiang wrote:
>> Updated CPUID.0xD.0x1, which reports the current required storage size
>> of all features enabled via XCR0 | XSS, when the guest's XSS is modified.
>>
>> Note, KVM does not yet support any XSS based features, i.e. supported_xss
>> is guaranteed to be zero at this time.
>>
>> Co-developed-by: Zhang Yi Z <yi.z.zhang@linux.intel.com>
>> Signed-off-by: Zhang Yi Z <yi.z.zhang@linux.intel.com>
>> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
>> ---
>>   arch/x86/kvm/cpuid.c | 16 +++++++++++++---
>>   arch/x86/kvm/x86.c   |  6 ++++--
>>   2 files changed, 17 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
>> index 6b5912578edd..85e3df6217af 100644
>> --- a/arch/x86/kvm/cpuid.c
>> +++ b/arch/x86/kvm/cpuid.c
>> @@ -272,9 +272,19 @@ static void __kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu, struct kvm_cpuid_e
>>   		best->ebx = xstate_required_size(vcpu->arch.xcr0, false);
>>   
>>   	best = cpuid_entry2_find(entries, nent, 0xD, 1);
>> -	if (best && (cpuid_entry_has(best, X86_FEATURE_XSAVES) ||
>> -		     cpuid_entry_has(best, X86_FEATURE_XSAVEC)))
>> -		best->ebx = xstate_required_size(vcpu->arch.xcr0, true);
>> +	if (best) {
>> +		if (cpuid_entry_has(best, X86_FEATURE_XSAVES) ||
>> +		    cpuid_entry_has(best, X86_FEATURE_XSAVEC))  {
>> +			u64 xstate = vcpu->arch.xcr0 | vcpu->arch.ia32_xss;
>> +
>> +			best->ebx = xstate_required_size(xstate, true);
>> +		}
>> +
>> +		if (!cpuid_entry_has(best, X86_FEATURE_XSAVES)) {
>> +			best->ecx = 0;
>> +			best->edx = 0;
> ECX and EDX should be left alone, it is userspace's responsibility to provide a
> sane CPUID model.  E.g. KVM doesn't clear EBX or EDX in CPUID.0xD.0x1 when XSAVE
> is unsupported.


Thanks for review!

Sure, I'll remove it.



>
>> +		}
>> +	}
>>   
>>   	best = __kvm_find_kvm_cpuid_features(vcpu, entries, nent);
>>   	if (kvm_hlt_in_guest(vcpu->kvm) && best &&
>> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
>> index 16726b44061b..888a153e32bc 100644
>> --- a/arch/x86/kvm/x86.c
>> +++ b/arch/x86/kvm/x86.c
>> @@ -3685,8 +3685,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>>   		 */
>>   		if (data & ~kvm_caps.supported_xss)
>>   			return 1;
>> -		vcpu->arch.ia32_xss = data;
>> -		kvm_update_cpuid_runtime(vcpu);
>> +		if (vcpu->arch.ia32_xss != data) {
>> +			vcpu->arch.ia32_xss = data;
>> +			kvm_update_cpuid_runtime(vcpu);
>> +		}
>>   		break;
>>   	case MSR_SMI_COUNT:
>>   		if (!msr_info->host_initiated)
>> -- 
>> 2.27.0
>>

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 04/15] KVM: PMU: disable LBR handling if architectural LBR is available
  2023-01-27 20:10   ` Sean Christopherson
@ 2023-01-30  8:10     ` Yang, Weijiang
  0 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2023-01-30  8:10 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang


On 1/28/2023 4:10 AM, Sean Christopherson wrote:
> On Thu, Nov 24, 2022, Yang Weijiang wrote:
>> From: Paolo Bonzini <pbonzini@redhat.com>
>>
>> Traditional LBR is absent on CPU models that have architectural LBR, so
>> disable all processing of traditional LBR MSRs if they are not there.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
>> ---
>>   arch/x86/kvm/vmx/pmu_intel.c | 32 ++++++++++++++++++++++----------
>>   1 file changed, 22 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
>> index e5cec07ca8d9..905673228932 100644
>> --- a/arch/x86/kvm/vmx/pmu_intel.c
>> +++ b/arch/x86/kvm/vmx/pmu_intel.c
>> @@ -170,19 +170,23 @@ static inline struct kvm_pmc *get_fw_gp_pmc(struct kvm_pmu *pmu, u32 msr)
>>   static bool intel_pmu_is_valid_lbr_msr(struct kvm_vcpu *vcpu, u32 index)
>>   {
>>   	struct x86_pmu_lbr *records = vcpu_to_lbr_records(vcpu);
>> -	bool ret = false;
>>   
>>   	if (!intel_pmu_lbr_is_enabled(vcpu))
>> -		return ret;
>> +		return false;
>>   
>> -	ret = (index == MSR_LBR_SELECT) || (index == MSR_LBR_TOS) ||
>> -		(index >= records->from && index < records->from + records->nr) ||
>> -		(index >= records->to && index < records->to + records->nr);
>> +	if (!guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) &&
> IIUC, the MSRs flat out don't exist _and_ KVM expects to passthrough MSRs to the
> guest, i.e. KVM should check host support, not guest support.  Probably a moot
> point from a functionality perspective since KVM shouldn't allow LBRs to shouldn't
> be enabled for the guest, but from a performance perspective, checking guest CPUID
> is slooow.


OK, I'll change the check.


>
> That brings me to point #2, which is that KVM needs to disallow enabling legacy
> LBRs on CPUs that support arch LBRs.  Again, IIUC, because KVM doesn't have the
> option to fallback to legacy LBRs,


Legacy LBR and Arch-lbr are exclusive on any platforms, on old 
platforms, legacy LBR is available,

on new platforms, e.g., SPR, arch-lbr is present, so we don't have 
fallback logic.


> that restriction needs to be treated as a bug
> fix.  I'll post a separate patch unless my understanding is wrong.
>
>> +	    (index == MSR_LBR_SELECT || index == MSR_LBR_TOS))
>> +		return true;
>>   
>> -	if (!ret && records->info)
>> -		ret = (index >= records->info && index < records->info + records->nr);
>> +	if ((index >= records->from && index < records->from + records->nr) ||
>> +	    (index >= records->to && index < records->to + records->nr))
>> +		return true;
>>   
>> -	return ret;
>> +	if (records->info && index >= records->info &&
>> +	    index < records->info + records->nr)
>> +		return true;
>> +
>> +	return false;
>>   }
>>   
>>   static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)
>> @@ -702,6 +706,9 @@ static void vmx_update_intercept_for_lbr_msrs(struct kvm_vcpu *vcpu, bool set)
>>   			vmx_set_intercept_for_msr(vcpu, lbr->info + i, MSR_TYPE_RW, set);
>>   	}
>>   
>> +	if (guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR))
> Similar to above, I really don't want to query guest CPUID in the VM-Enter path.
> If we establish the rule that LBRs can be enabled if and only if the correct type
> is enabled (traditional/legacy vs. arch), then this can simply check host support.

I understand your concerns, will try to use other efficient ways to 
check guest arch-lbr support.


>
>> +		return;
>> +
>>   	vmx_set_intercept_for_msr(vcpu, MSR_LBR_SELECT, MSR_TYPE_RW, set);
>>   	vmx_set_intercept_for_msr(vcpu, MSR_LBR_TOS, MSR_TYPE_RW, set);
>>   }
>> @@ -742,10 +749,12 @@ void vmx_passthrough_lbr_msrs(struct kvm_vcpu *vcpu)
>>   {
>>   	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
>>   	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
>> +	bool lbr_enable = !guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) &&
>> +		(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR);
> Unnecessary guest CPUID lookup and VMCS read, i.e. this can be deferred to the
> !lbr_desc->event path.

OK


>
>>   
>>   	if (!lbr_desc->event) {
>>   		vmx_disable_lbr_msrs_passthrough(vcpu);
>> -		if (vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR)
>> +		if (lbr_enable)
>>   			goto warn;
>>   		if (test_bit(INTEL_PMC_IDX_FIXED_VLBR, pmu->pmc_in_use))
>>   			goto warn;
>> @@ -768,7 +777,10 @@ void vmx_passthrough_lbr_msrs(struct kvm_vcpu *vcpu)
>>   
>>   static void intel_pmu_cleanup(struct kvm_vcpu *vcpu)
>>   {
>> -	if (!(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR))
>> +	bool lbr_enable = !guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR) &&
>> +		(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR);
>> +
>> +	if (!lbr_enable)
>>   		intel_pmu_release_guest_lbr_event(vcpu);
>>   }
>>   
>> -- 
>> 2.27.0
>>

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 05/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_DEPTH for guest Arch LBR
  2023-01-27 20:25   ` Sean Christopherson
@ 2023-01-30 11:46     ` Yang, Weijiang
  0 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2023-01-30 11:46 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang


On 1/28/2023 4:25 AM, Sean Christopherson wrote:
> On Thu, Nov 24, 2022, Yang Weijiang wrote:
>> [...]
>> +++ b/arch/x86/include/asm/kvm_host.h
>> @@ -571,6 +571,9 @@ struct kvm_pmu {
>>   	 * redundant check before cleanup if guest don't use vPMU at all.
>>   	 */
>>   	u8 event_count;
>> +
>> +	/* Guest arch lbr depth supported by KVM. */
>> +	u64 kvm_arch_lbr_depth;
> There is zero reason to store this separately.  KVM already records the allowed
> depth in kvm_vcpu.lbr_desc.records.nr.

kvm_vcpu.lbr_desc.records.nr alone cannot tell whether it's legacy lbr or arch-lbr unless

binding host arch-lbr checking.


>
>>   };
>>   
>>   struct kvm_pmu_ops;
>> diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
>> index 905673228932..0c78cb4b72be 100644
>> --- a/arch/x86/kvm/vmx/pmu_intel.c
>> +++ b/arch/x86/kvm/vmx/pmu_intel.c
>> @@ -178,6 +178,10 @@ static bool intel_pmu_is_valid_lbr_msr(struct kvm_vcpu *vcpu, u32 index)
>>   	    (index == MSR_LBR_SELECT || index == MSR_LBR_TOS))
>>   		return true;
>>   
>> +	if (index == MSR_ARCH_LBR_DEPTH)
>> +		return kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
> Like the previous patch, since intel_pmu_lbr_is_enabled() effectively serves as
> a generic kvm_cpu_cap_has(LBRS) check, this can be distilled to:
>
> 	if (cpu_feature_enabled(X86_FEATURE_ARCH_LBR)) {
> 		if (index == MSR_ARCH_LBR_DEPTH || index == MSR_ARCH_LBR_CTL)
> 			return true;
> 	} else {
> 		if (index == MSR_LBR_SELECT || index == MSR_LBR_TOS))
> 			return true;
> 	}


yes, exactly, thanks!


>> +		       guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR);
>> +
>>   	if ((index >= records->from && index < records->from + records->nr) ||
>>   	    (index >= records->to && index < records->to + records->nr))
>>   		return true;
>> @@ -345,6 +349,7 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>>   {
>>   	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
>>   	struct kvm_pmc *pmc;
>> +	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
>>   	u32 msr = msr_info->index;
>>   
>>   	switch (msr) {
>> @@ -369,6 +374,9 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>>   	case MSR_PEBS_DATA_CFG:
>>   		msr_info->data = pmu->pebs_data_cfg;
>>   		return 0;
>> +	case MSR_ARCH_LBR_DEPTH:
>> +		msr_info->data = lbr_desc->records.nr;
>> +		return 0;
>>   	default:
>>   		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
>>   		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
>> @@ -395,6 +403,7 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>>   {
>>   	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
>>   	struct kvm_pmc *pmc;
>> +	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
>>   	u32 msr = msr_info->index;
>>   	u64 data = msr_info->data;
>>   	u64 reserved_bits, diff;
>> @@ -456,6 +465,24 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>>   			return 0;
>>   		}
>>   		break;
>> +	case MSR_ARCH_LBR_DEPTH:
>> +		if (!pmu->kvm_arch_lbr_depth && !msr_info->host_initiated)
> Don't invent a new check, just prevent KVM from reaching this path via the
> existing intel_pmu_lbr_is_enabled().

intel_pmu_lbr_is_enabled() only indicates LBR is on(either legacy or 
arch-lbr), but

MSR_ARCH_LBR_DEPTH is only for arch-lbr.

>
>> +			return 1;
>> +		/*
>> +		 * When guest/host depth are different, the handling would be tricky,
>> +		 * so only max depth is supported for both host and guest.
>> +		 */
> This semi-arbitrary restriction is fine because Intel's architecture allows KVM
> to enumerate support for a single depth, but somewhere in the changelog and/or
> code that actually needs to be state.  This blurb
>
>    In the first generation of Arch LBR, max entry size is 32,
>    host configures the max size and guest always honors the setting.
>
> makes it sound like KVM is relying on the guest to do the right thing, and this
> code looks like KVM is making up it's own behavior.

Will modify the change log.

>
>> +		if (data != pmu->kvm_arch_lbr_depth)
>> +			return 1;
>> +
>> +		lbr_desc->records.nr = data;
>> +		/*
>> +		 * Writing depth MSR from guest could either setting the
>> +		 * MSR or resetting the LBR records with the side-effect.
>> +		 */
>> +		if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR))
> Another check, really?  KVM shouldn't reach this point if KVM doesn't support
> Arch LBRs.  And if that isn't guarantee (honestly forgot what this series actually
> proposed at this point), then that's a bug, full stop.

Right, this check is unnecessary.


>
>> +			wrmsrl(MSR_ARCH_LBR_DEPTH, lbr_desc->records.nr);
> IIUC, this is subtly broken.  Piecing together all of the undocumented bits, my
> understanding is that arch LBRs piggyback KVM's existing LBR support, i.e. use a
> "virtual" perf event.

Yes.

> And like traditional LBR support, the host can steal control
> of the LBRs in IRQ context by disabling the perf event via IPI.  And since writes
> to MSR_ARCH_LBR_DEPTH purge LBR records, this needs to be treated as if it were a
> write to an LBR record, i.e. belongs in the IRQs disabled section of
> intel_pmu_handle_lbr_msrs_access().

I assume you're referring to host events preempt guest events. In that 
case, it's possible

guest operations interfere host events/data. But this series 
implementation focus on

"guest only" mode, i.e., it sets {Load|Clear}_LBR_CTL at VM entry/exit, 
that way, we don't

need to care about host preempt, the event data is saved/restored at 
event sched_{out|in}.


>
> If for some magical reason it's safe to access arch LBR MSRs without disabling IRQs
> and confirming perf event ownership, I want to see a very detailed changelog
> explaining exactly how that magic works.

Will change the commit log to explain more.


>
>> +		return 0;
>>   	default:
>>   		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
>>   		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
>> @@ -506,6 +533,32 @@ static void setup_fixed_pmc_eventsel(struct kvm_pmu *pmu)
>>   	}
>>   }
>>   
>> +static bool cpuid_enable_lbr(struct kvm_vcpu *vcpu)
>> +{
>> +	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
>> +	struct kvm_cpuid_entry2 *entry;
>> +	int depth_bit;
>> +
>> +	if (!kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR))
>> +		return !static_cpu_has(X86_FEATURE_ARCH_LBR) &&
>> +			cpuid_model_is_consistent(vcpu);
>> +
>> +	pmu->kvm_arch_lbr_depth = 0;
>> +	if (!guest_cpuid_has(vcpu, X86_FEATURE_ARCH_LBR))
>> +		return false;
>> +
>> +	entry = kvm_find_cpuid_entry(vcpu, 0x1C);
>> +	if (!entry)
>> +		return false;
>> +
>> +	depth_bit = fls(cpuid_eax(0x1C) & 0xff);
> This is unnecessarily fragile.  Get the LBR depth from perf, don't read CPUID and
> assume perf will always configured the max depth.,

Make sense, will refactor the function in next version.

>
> This enabling also belongs at the tail end of the series, i.e. KVM shouldn't let
> userspace enable LBRs until all the support pieces are in place.

OK.


>
>> +	if ((entry->eax & 0xff) != (1 << (depth_bit - 1)))
>> +		return false;
>> +
>> +	pmu->kvm_arch_lbr_depth = depth_bit * 8;
>> +	return true;
>> +}
>> +
[...]

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 08/15] KVM: x86: Add Arch LBR MSRs to msrs_to_save_all list
  2023-01-27 21:43   ` Sean Christopherson
@ 2023-01-30 12:27     ` Yang, Weijiang
  0 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2023-01-30 12:27 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang


On 1/28/2023 5:43 AM, Sean Christopherson wrote:
> On Thu, Nov 24, 2022, Yang Weijiang wrote:
>> Arch LBR MSR_ARCH_LBR_DEPTH and MSR_ARCH_LBR_CTL are queried by
>> userspace application before it wants to {save|restore} the Arch LBR
>> data. Other LBR related data MSRs are omitted here intentionally due
>> to lengthy list(32*3). Userspace can still use KVM_{GET|SET}_MSRS to
>> access them if necessary.
> Absolutely not.  "there are a lot of them" isn't sufficient justification.  If
> the MSRs need to be migrated, then KVM needs to report them.  If the expectation
> is that XSAVES will handle them, then KVM needs to take a dependency on XSAVES
> when enabling arch LBRs.

OK, will add the full MSR list.


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 09/15] KVM: x86: Refine the matching and clearing logic for supported_xss
  2023-01-27 21:46   ` Sean Christopherson
@ 2023-01-30 12:37     ` Yang, Weijiang
  0 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2023-01-30 12:37 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang


On 1/28/2023 5:46 AM, Sean Christopherson wrote:
> On Thu, Nov 24, 2022, Yang Weijiang wrote:
>> From: Paolo Bonzini <pbonzini@redhat.com>
>>
>> Refine the code path of the existing clearing of supported_xss in this way:
>> initialize the supported_xss with the filter of KVM_SUPPORTED_XSS mask and
>> update its value in a bit clear manner (rather than bit setting).
>>
>> Suggested-by: Sean Christopherson <seanjc@google.com>
>> Signed-off-by: Like Xu <like.xu@linux.intel.com>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
>> ---
>>   arch/x86/kvm/vmx/vmx.c | 5 +++--
>>   arch/x86/kvm/x86.c     | 6 +++++-
>>   2 files changed, 8 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
>> index 9bd52ad3bbf4..2ab4c33b5008 100644
>> --- a/arch/x86/kvm/vmx/vmx.c
>> +++ b/arch/x86/kvm/vmx/vmx.c
>> @@ -7738,9 +7738,10 @@ static __init void vmx_set_cpu_caps(void)
>>   		kvm_cpu_cap_set(X86_FEATURE_UMIP);
>>   
>>   	/* CPUID 0xD.1 */
>> -	kvm_caps.supported_xss = 0;
> This needs to stay until VMX actually supports something.

Will modify this patch.


>
>> -	if (!cpu_has_vmx_xsaves())
>> +	if (!cpu_has_vmx_xsaves()) {
>>   		kvm_cpu_cap_clear(X86_FEATURE_XSAVES);
>> +		kvm_caps.supported_xss = 0;
> This is already handled in common KVM.
>
>> +	}
>>   
>>   	/* CPUID 0x80000001 and 0x7 (RDPID) */
>>   	if (!cpu_has_vmx_rdtscp()) {
>> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
>> index 74c858eaa1ea..889be0c9176d 100644
>> --- a/arch/x86/kvm/x86.c
>> +++ b/arch/x86/kvm/x86.c
>> @@ -217,6 +217,8 @@ static struct kvm_user_return_msrs __percpu *user_return_msrs;
>>   				| XFEATURE_MASK_BNDCSR | XFEATURE_MASK_AVX512 \
>>   				| XFEATURE_MASK_PKRU | XFEATURE_MASK_XTILE)
>>   
>> +#define KVM_SUPPORTED_XSS     0
>> +
>>   u64 __read_mostly host_efer;
>>   EXPORT_SYMBOL_GPL(host_efer);
>>   
>> @@ -11999,8 +12001,10 @@ int kvm_arch_hardware_setup(void *opaque)
>>   
>>   	rdmsrl_safe(MSR_EFER, &host_efer);
>>   
>> -	if (boot_cpu_has(X86_FEATURE_XSAVES))
>> +	if (boot_cpu_has(X86_FEATURE_XSAVES)) {
>>   		rdmsrl(MSR_IA32_XSS, host_xss);
>> +		kvm_caps.supported_xss = host_xss & KVM_SUPPORTED_XSS;
>> +	}
>>   
>>   	kvm_init_pmu_capability();
>>   
>> -- 
>> 2.27.0
>>

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 14/15] KVM: x86: Add Arch LBR data MSR access interface
  2023-01-27 22:13   ` Sean Christopherson
@ 2023-01-30 12:46     ` Yang, Weijiang
  2023-01-30 17:30       ` Sean Christopherson
  0 siblings, 1 reply; 64+ messages in thread
From: Yang, Weijiang @ 2023-01-30 12:46 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang


On 1/28/2023 6:13 AM, Sean Christopherson wrote:
> On Thu, Nov 24, 2022, Yang Weijiang wrote:
>> Arch LBR MSRs are xsave-supported, but they're operated as "independent"
>> xsave feature by PMU code, i.e., during thread/process context switch,
>> the MSRs are saved/restored with perf_event_task_sched_{in|out} instead
>> of generic kernel fpu switch code, i.e.,save_fpregs_to_fpstate() and
>> restore_fpregs_from_fpstate(). When vcpu guest/host fpu state swap happens,
>> Arch LBR MSRs are retained so they can be accessed directly.
>>
>> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
>> Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
>> ---
>>   arch/x86/kvm/vmx/pmu_intel.c | 10 ++++++++++
>>   1 file changed, 10 insertions(+)
>>
>> diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
>> index b57944d5e7d8..241128972776 100644
>> --- a/arch/x86/kvm/vmx/pmu_intel.c
>> +++ b/arch/x86/kvm/vmx/pmu_intel.c
>> @@ -410,6 +410,11 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>>   			msr_info->data = vmcs_read64(GUEST_IA32_LBR_CTL);
>>   		}
>>   		return 0;
>> +	case MSR_ARCH_LBR_FROM_0 ... MSR_ARCH_LBR_FROM_0 + 31:
>> +	case MSR_ARCH_LBR_TO_0 ... MSR_ARCH_LBR_TO_0 + 31:
>> +	case MSR_ARCH_LBR_INFO_0 ... MSR_ARCH_LBR_INFO_0 + 31:
>> +		rdmsrl(msr_info->index, msr_info->data);
> I don't see how this is correct.  As called out in patch 5:
>
>   : If for some magical reason it's safe to access arch LBR MSRs without disabling
>   : IRQs and confirming perf event ownership, I want to see a very detailed changelog
>   : explaining exactly how that magic works.

The MSR lists here are just for live migration. When arch-lbr is active, 
these MSRs are passed through

to guest.


>
>> +		return 0;
>>   	default:
>>   		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
>>   		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
>> @@ -528,6 +533,11 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>>   		    (data & ARCH_LBR_CTL_LBREN))
>>   			intel_pmu_create_guest_lbr_event(vcpu);
>>   		return 0;
>> +	case MSR_ARCH_LBR_FROM_0 ... MSR_ARCH_LBR_FROM_0 + 31:
>> +	case MSR_ARCH_LBR_TO_0 ... MSR_ARCH_LBR_TO_0 + 31:
>> +	case MSR_ARCH_LBR_INFO_0 ... MSR_ARCH_LBR_INFO_0 + 31:
>> +		wrmsrl(msr_info->index, msr_info->data);
>> +		return 0;
>>   	default:
>>   		if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
>>   		    (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
>> -- 
>> 2.27.0
>>

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 13/15] KVM: x86/vmx: Save/Restore guest Arch LBR Ctrl msr at SMM entry/exit
  2023-01-27 22:11   ` Sean Christopherson
@ 2023-01-30 12:50     ` Yang, Weijiang
  0 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2023-01-30 12:50 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang


On 1/28/2023 6:11 AM, Sean Christopherson wrote:
> On Thu, Nov 24, 2022, Yang Weijiang wrote:
>> Per SDM 3B Chapter 18: "IA32_LBR_CTL.LBREn is saved and cleared on #SMI,
>> and restored on RSM", store guest IA32_LBR_CTL in SMRAM and clear LBREn
>> in VMCS at SMM entry, and do reverse things at SMM exit.

[...]


>> @@ -8006,11 +8006,21 @@ static int vmx_enter_smm(struct kvm_vcpu *vcpu, union kvm_smram *smram)
>>   	vmx->nested.smm.vmxon = vmx->nested.vmxon;
>>   	vmx->nested.vmxon = false;
>>   	vmx_clear_hlt(vcpu);
>> +
>> +	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
>> +	    guest_cpuid_has(vcpu, X86_FEATURE_LM)) {
> Uh, so this arbitrary dependency on 64-bit vCPUs needs to be factored into the
> enabling.  And KVM should WARN if arch LBRs get enabled for a 32-bit vCPU.

OK, will add the check while creating event.

>
>> +		u64 ctl = vmcs_read64(GUEST_IA32_LBR_CTL);
>> +
>> +		smram->smram64.arch_lbr_ctl = ctl;
>> +		vmcs_write64(GUEST_IA32_LBR_CTL, ctl & ~ARCH_LBR_CTL_LBREN);
>> +	}
>> +
>>   	return 0;
>>   }
>>   
>>   static int vmx_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)
>>   {
>> +	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
>>   	struct vcpu_vmx *vmx = to_vmx(vcpu);
>>   	int ret;
>>   
>> @@ -8027,6 +8037,18 @@ static int vmx_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)
>>   		vmx->nested.nested_run_pending = 1;
>>   		vmx->nested.smm.guest_mode = false;
>>   	}
>> +
>> +	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
>> +	    guest_cpuid_has(vcpu, X86_FEATURE_LM)) {
>> +		u64 ctl = smram->smram64.arch_lbr_ctl;
>> +
>> +		vmcs_write64(GUEST_IA32_LBR_CTL, ctl & ARCH_LBR_CTL_LBREN);
> IIUC, this should set only LBREn and preserve all other bits, not clobber the
> entire MSR.

Oops, it's a typo, thanks!

>
>> +
>> +		if (intel_pmu_lbr_is_enabled(vcpu) &&
>> +		    (ctl & ARCH_LBR_CTL_LBREN) && !lbr_desc->event)
>> +			intel_pmu_create_guest_lbr_event(vcpu);
>> +	}
>> +
>>   	return 0;
>>   }
>>   
>> -- 
>> 2.27.0
>>

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 12/15] KVM: x86/vmx: Disable Arch LBREn bit in #DB and warm reset
  2023-01-27 22:09   ` Sean Christopherson
@ 2023-01-30 13:09     ` Yang, Weijiang
  0 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2023-01-30 13:09 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang


On 1/28/2023 6:09 AM, Sean Christopherson wrote:
> On Thu, Nov 24, 2022, Yang Weijiang wrote:
>> Per SDM 3B, Chapter 18:
>> “On a debug breakpoint event (#DB), IA32_LBR_CTL.LBREn is cleared.”
>> and "On a warm reset, all LBR MSRs, including IA32_LBR_DEPTH, have their
>> values preserved. However, IA32_LBR_CTL.LBREn is cleared to 0, disabling
>> LBRs.", clear the bit manually before inject #DB or when vCPU is in warm
>> reset.
>>
>> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
>> ---
>>   arch/x86/kvm/vmx/vmx.c | 24 +++++++++++++++++++++++-
>>   1 file changed, 23 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
>> index 3bc892e8cf7a..6ad765ea4059 100644
>> --- a/arch/x86/kvm/vmx/vmx.c
>> +++ b/arch/x86/kvm/vmx/vmx.c
>> @@ -1695,6 +1695,20 @@ static void vmx_clear_hlt(struct kvm_vcpu *vcpu)
>>   		vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE);
>>   }
>>   
>> +static void disable_arch_lbr_ctl(struct kvm_vcpu *vcpu)
>> +{
>> +	struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu);
>> +	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
>> +
>> +	if (kvm_cpu_cap_has(X86_FEATURE_ARCH_LBR) &&
>> +	    test_bit(INTEL_PMC_IDX_FIXED_VLBR, pmu->pmc_in_use) &&
>> +	    lbr_desc->event) {
> I don't see any reason to check that an event is actually assigned.  The behavior
> is architectural, whether or not KVM is actively exposing LBRs to the guest is
> irrelevant

Agree, will remove them.

>
>> +		u64 ctl = vmcs_read64(GUEST_IA32_LBR_CTL);
>> +
>> +		vmcs_write64(GUEST_IA32_LBR_CTL, ctl & ~ARCH_LBR_CTL_LBREN);
>> +	}
>> +}
>> +
>>   static void vmx_inject_exception(struct kvm_vcpu *vcpu)
>>   {
>>   	struct kvm_queued_exception *ex = &vcpu->arch.exception;
>> @@ -1738,6 +1752,9 @@ static void vmx_inject_exception(struct kvm_vcpu *vcpu)
>>   	vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
>>   
>>   	vmx_clear_hlt(vcpu);
>> +
>> +	if (ex->vector == DB_VECTOR)
>> +		disable_arch_lbr_ctl(vcpu);
>>   }
>>   
>>   static void vmx_setup_uret_msr(struct vcpu_vmx *vmx, unsigned int msr,
>> @@ -4796,7 +4813,9 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>>   
>>   	vmx_update_fb_clear_dis(vcpu, vmx);
>>   
>> -	if (!init_event && cpu_has_vmx_arch_lbr())
>> +	if (init_event)
> INIT and warm RESET are not the same thing, i.e. this is flat out wrong.

I was confused a bit. Is there's a way to intercept guest warm RESET so 
as to disable the bit?

Or what should be followed per spec.?

>
>> +		disable_arch_lbr_ctl(vcpu);
>> +	else if (cpu_has_vmx_arch_lbr())
>>   		vmcs_write64(GUEST_IA32_LBR_CTL, 0);
>>   }
>>   
>> @@ -4873,6 +4892,9 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
>>   			INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR);
>>   
>>   	vmx_clear_hlt(vcpu);
>> +
>> +	if (vcpu->arch.exception.vector == DB_VECTOR)
> Huh?  This is _very_ obviously injecting NMIs, not #DBs.

My fault, will remove it.

>
>> +		disable_arch_lbr_ctl(vcpu);
>>   }
>>   
>>   bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu)
>> -- 
>> 2.27.0
>>

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 11/15] KVM: x86: Add XSAVE Support for Architectural LBR
  2023-01-27 22:07   ` Sean Christopherson
@ 2023-01-30 13:13     ` Yang, Weijiang
  0 siblings, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2023-01-30 13:13 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang, Like Xu


On 1/28/2023 6:07 AM, Sean Christopherson wrote:
> On Thu, Nov 24, 2022, Yang Weijiang wrote:
>> From: Like Xu <like.xu@linux.intel.com>
>>
>> On processors supporting XSAVES and XRSTORS, Architectural LBR XSAVE
>> support is enumerated from CPUID.(EAX=0DH, ECX=1):ECX[bit 15].
>> The detailed sub-leaf for Arch LBR is enumerated in CPUID.(0DH, 0FH).
>>
>> XSAVES provides a faster means than RDMSR for guest to read all LBRs.
>> When guest IA32_XSS[bit 15] is set, the Arch LBR state can be saved using
>> XSAVES and restored by XRSTORS with the appropriate RFBM.
>>
>> Signed-off-by: Like Xu <like.xu@linux.intel.com>
>> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
>> ---
>>   arch/x86/kvm/vmx/vmx.c | 4 ++++
>>   arch/x86/kvm/x86.c     | 2 +-
>>   2 files changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
>> index 359da38a19a1..3bc892e8cf7a 100644
>> --- a/arch/x86/kvm/vmx/vmx.c
>> +++ b/arch/x86/kvm/vmx/vmx.c
>> @@ -7733,6 +7733,10 @@ static __init void vmx_set_cpu_caps(void)
>>   		kvm_cpu_cap_check_and_set(X86_FEATURE_DS);
>>   		kvm_cpu_cap_check_and_set(X86_FEATURE_DTES64);
>>   	}
>> +	if (!cpu_has_vmx_arch_lbr()) {
>> +		kvm_cpu_cap_clear(X86_FEATURE_ARCH_LBR);
> No, this needs to be opt-in, not opt-out.  I.e. omit the flag from common CPUID
> code and set it if and only if it's fully supported.  It's not out of the realm
> of possibilities that AMD might want to support arch LBRs, at which point those
> CPUs would explode.

Will modify this patch.

>
>> +		kvm_caps.supported_xss &= ~XFEATURE_MASK_LBR;
>> +	}
>>   
>>   	if (!enable_pmu)
>>   		kvm_cpu_cap_clear(X86_FEATURE_PDCM);
>> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
>> index 889be0c9176d..38df08d9d0cb 100644
>> --- a/arch/x86/kvm/x86.c
>> +++ b/arch/x86/kvm/x86.c
>> @@ -217,7 +217,7 @@ static struct kvm_user_return_msrs __percpu *user_return_msrs;
>>   				| XFEATURE_MASK_BNDCSR | XFEATURE_MASK_AVX512 \
>>   				| XFEATURE_MASK_PKRU | XFEATURE_MASK_XTILE)
>>   
>> -#define KVM_SUPPORTED_XSS     0
>> +#define KVM_SUPPORTED_XSS     XFEATURE_MASK_LBR
>>   
>>   u64 __read_mostly host_efer;
>>   EXPORT_SYMBOL_GPL(host_efer);
>> -- 
>> 2.27.0
>>

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 00/15] Introduce Architectural LBR for vPMU
  2023-01-27 22:46 ` Sean Christopherson
@ 2023-01-30 13:38   ` Yang, Weijiang
  2023-06-05  9:50   ` Like Xu
  1 sibling, 0 replies; 64+ messages in thread
From: Yang, Weijiang @ 2023-01-30 13:38 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang


On 1/28/2023 6:46 AM, Sean Christopherson wrote:
> On Thu, Nov 24, 2022, Yang Weijiang wrote:
>> Intel CPU model-specific LBR(Legacy LBR) has evolved to Architectural
>> LBR(Arch LBR [0]), it's the replacement of legacy LBR on new platforms.
>> The native support patches were merged into 5.9 kernel tree, and this
>> patch series is to enable Arch LBR in vPMU so that guest can benefit
>> from the feature.
>>
>> The main advantages of Arch LBR are [1]:
>> - Faster context switching due to XSAVES support and faster reset of
>>    LBR MSRs via the new DEPTH MSR
>> - Faster LBR read for a non-PEBS event due to XSAVES support, which
>>    lowers the overhead of the NMI handler.
>> - Linux kernel can support the LBR features without knowing the model
>>    number of the current CPU.
>>
>>  From end user's point of view, the usage of Arch LBR is the same as
>> the Legacy LBR that has been merged in the mainline.
>>
>> Note, in this series, there's one restriction for guest Arch LBR, i.e.,
>> guest can only set its LBR record depth the same as host's. This is due
>> to the special behavior of MSR_ARCH_LBR_DEPTH:
>> 1) On write to the MSR, it'll reset all Arch LBR recording MSRs to 0s.
>> 2) XRSTORS resets all record MSRs to 0s if the saved depth mismatches
>> MSR_ARCH_LBR_DEPTH.
>> Enforcing the restriction keeps KVM Arch LBR vPMU working flow simple
>> and straightforward.
>>
>> Paolo refactored the old series and the resulting patches became the
>> base of this new series, therefore he's the author of some patches.
> To be very blunt, this series is a mess.  I don't want to point fingers as there
> is plenty of blame to go around.  The existing LBR support is a confusing mess,
> vPMU as a whole has been neglected for too long, review feedback has been relatively
> non-existent, and I'm sure some of the mess is due to Paolo trying to hastily fix
> things up back when this was temporarily queued.
>
> However, for arch LBR support to be merged, things need to change.
>
> First and foremost, the existing LBR support needs to be documented.  Someone,
> I don't care who, needs to provide a detailed writeup of the contract between KVM
> and perf.  Specifically, I want to know:
>
>    1. When exactly is perf allowed to take control of LBR MRS.  Task switch?  IRQ?
>       NMI?
>
>    2. What is the expected behavior when perf is using LBRs?  Is the guest supposed
>       to be traced?
>
>    3. Why does KVM snapshot DEBUGCTL with IRQs enabled, but disables IRQs when
>       accessing LBR MSRs?
>
> It doesn't have to be polished, e.g. I'll happily wordsmith things into proper
> documentation, but I want to have a very clear understanding of how LBR support
> is _intended_ to function and how it all _actually_ functions without having to
> make guesses.
>
> And depending on the answers, I want to revisit KVM's LBR implementation before
> tackling arch LBRs.  Letting perf usurp LBRs while KVM has the vCPU loaded is
> frankly ridiculous.  Just have perf set a flag telling KVM that it needs to take
> control of LBRs and have KVM service the flag as a request or something.  Stealing
> the LBRs back in IRQ context adds a stupid amount of complexity without much value,
> e.g. waiting a few branches for KVM to get to a safe place isn't going to meaningfully
> change the traces.  If that can't actually happen, then why on earth does KVM need
> to disable IRQs to read MSRs?
>
> And AFAICT, since KVM unconditionally loads the guest's DEBUGCTL, whether or not
> guest branches show up in the LBRs when the host is tracing is completely up to
> the whims of the guest.  If that's correct, then again, what's the point of the
> dance between KVM and perf?
>
> Beyond the "how does this work" issues, there needs to be tests.  At the absolute
> minimum, there needs to be selftests showing that this stuff actually works, that
> save/restore (migration) works, that the MSRs can/can't be accessed when guest
> CPUID is (in)correctly configured, etc. And I would really, really like to have
> tests that force contention between host and guests, e.g. to make sure that KVM
> isn't leaking host state or outright exploding, but I can understand that those
> types of tests would be very difficult to write.
>
> I've pushed a heavily reworked, but definitely broken, version to
>
>    git@github.com:sean-jc/linux.git x86/arch_lbrs
>
> It compiles, but it's otherwise untested and there are known gaps.  E.g. I omitted
> toggling load+clear of ARCH_LBR_CTL because I couldn't figure out the intended
> behavior.

Appreciated for your elaborate review and comments!

I'll check your reworked version and discuss with stakeholders on how to 
move the work forward.



^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 14/15] KVM: x86: Add Arch LBR data MSR access interface
  2023-01-30 12:46     ` Yang, Weijiang
@ 2023-01-30 17:30       ` Sean Christopherson
  2023-01-31 13:14         ` Yang, Weijiang
  0 siblings, 1 reply; 64+ messages in thread
From: Sean Christopherson @ 2023-01-30 17:30 UTC (permalink / raw)
  To: Yang, Weijiang
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	wei.w.wang

On Mon, Jan 30, 2023, Yang, Weijiang wrote:
> 
> On 1/28/2023 6:13 AM, Sean Christopherson wrote:
> > On Thu, Nov 24, 2022, Yang Weijiang wrote:
> > > Arch LBR MSRs are xsave-supported, but they're operated as "independent"
> > > xsave feature by PMU code, i.e., during thread/process context switch,
> > > the MSRs are saved/restored with perf_event_task_sched_{in|out} instead
> > > of generic kernel fpu switch code, i.e.,save_fpregs_to_fpstate() and
> > > restore_fpregs_from_fpstate(). When vcpu guest/host fpu state swap happens,
> > > Arch LBR MSRs are retained so they can be accessed directly.
> > > 
> > > Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> > > Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
> > > ---
> > >   arch/x86/kvm/vmx/pmu_intel.c | 10 ++++++++++
> > >   1 file changed, 10 insertions(+)
> > > 
> > > diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
> > > index b57944d5e7d8..241128972776 100644
> > > --- a/arch/x86/kvm/vmx/pmu_intel.c
> > > +++ b/arch/x86/kvm/vmx/pmu_intel.c
> > > @@ -410,6 +410,11 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
> > >   			msr_info->data = vmcs_read64(GUEST_IA32_LBR_CTL);
> > >   		}
> > >   		return 0;
> > > +	case MSR_ARCH_LBR_FROM_0 ... MSR_ARCH_LBR_FROM_0 + 31:
> > > +	case MSR_ARCH_LBR_TO_0 ... MSR_ARCH_LBR_TO_0 + 31:
> > > +	case MSR_ARCH_LBR_INFO_0 ... MSR_ARCH_LBR_INFO_0 + 31:
> > > +		rdmsrl(msr_info->index, msr_info->data);
> > I don't see how this is correct.  As called out in patch 5:
> > 
> >   : If for some magical reason it's safe to access arch LBR MSRs without disabling
> >   : IRQs and confirming perf event ownership, I want to see a very detailed changelog
> >   : explaining exactly how that magic works.
> 
> The MSR lists here are just for live migration. When arch-lbr is active,
> these MSRs are passed through to guest.

None of that explains how the guest's MSR values are guaranteed to be resident
in hardware.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 14/15] KVM: x86: Add Arch LBR data MSR access interface
  2023-01-30 17:30       ` Sean Christopherson
@ 2023-01-31 13:14         ` Yang, Weijiang
  2023-01-31 16:05           ` Sean Christopherson
  0 siblings, 1 reply; 64+ messages in thread
From: Yang, Weijiang @ 2023-01-31 13:14 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	Wang, Wei W


On 1/31/2023 1:30 AM, Sean Christopherson wrote:
> On Mon, Jan 30, 2023, Yang, Weijiang wrote:
>> On 1/28/2023 6:13 AM, Sean Christopherson wrote:
>>> On Thu, Nov 24, 2022, Yang Weijiang wrote:
>>>> Arch LBR MSRs are xsave-supported, but they're operated as "independent"
>>>> xsave feature by PMU code, i.e., during thread/process context switch,
>>>> the MSRs are saved/restored with perf_event_task_sched_{in|out} instead
>>>> of generic kernel fpu switch code, i.e.,save_fpregs_to_fpstate() and
>>>> restore_fpregs_from_fpstate(). When vcpu guest/host fpu state swap happens,
>>>> Arch LBR MSRs are retained so they can be accessed directly.
>>>>
>>>> Signed-off-by: Yang Weijiang<weijiang.yang@intel.com>
>>>> Reviewed-by: Kan Liang<kan.liang@linux.intel.com>
>>>> ---
>>>>    arch/x86/kvm/vmx/pmu_intel.c | 10 ++++++++++
>>>>    1 file changed, 10 insertions(+)
>>>>
>>>> diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
>>>> index b57944d5e7d8..241128972776 100644
>>>> --- a/arch/x86/kvm/vmx/pmu_intel.c
>>>> +++ b/arch/x86/kvm/vmx/pmu_intel.c
>>>> @@ -410,6 +410,11 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>>>>    			msr_info->data = vmcs_read64(GUEST_IA32_LBR_CTL);
>>>>    		}
>>>>    		return 0;
>>>> +	case MSR_ARCH_LBR_FROM_0 ... MSR_ARCH_LBR_FROM_0 + 31:
>>>> +	case MSR_ARCH_LBR_TO_0 ... MSR_ARCH_LBR_TO_0 + 31:
>>>> +	case MSR_ARCH_LBR_INFO_0 ... MSR_ARCH_LBR_INFO_0 + 31:
>>>> +		rdmsrl(msr_info->index, msr_info->data);
>>> I don't see how this is correct.  As called out in patch 5:
>>>
>>>    : If for some magical reason it's safe to access arch LBR MSRs without disabling
>>>    : IRQs and confirming perf event ownership, I want to see a very detailed changelog
>>>    : explaining exactly how that magic works.
>> The MSR lists here are just for live migration. When arch-lbr is active,
>> these MSRs are passed through to guest.
> None of that explains how the guest's MSR values are guaranteed to be resident
> in hardware.

I ignored host *event* scheduling case in commit log.

My understanding is, host LBR *event* could break in at any point when 
the vCPU is running,

in this case disabling IRQs before read/write the MSRs is pointless 
because the HW context could have

been swapped. I need to do more investigation for the issue.



^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 14/15] KVM: x86: Add Arch LBR data MSR access interface
  2023-01-31 13:14         ` Yang, Weijiang
@ 2023-01-31 16:05           ` Sean Christopherson
  0 siblings, 0 replies; 64+ messages in thread
From: Sean Christopherson @ 2023-01-31 16:05 UTC (permalink / raw)
  To: Yang, Weijiang
  Cc: pbonzini, jmattson, kvm, linux-kernel, like.xu.linux, kan.liang,
	Wang, Wei W

On Tue, Jan 31, 2023, Yang, Weijiang wrote:
> 
> On 1/31/2023 1:30 AM, Sean Christopherson wrote:
> > On Mon, Jan 30, 2023, Yang, Weijiang wrote:
> > > On 1/28/2023 6:13 AM, Sean Christopherson wrote:
> > > > On Thu, Nov 24, 2022, Yang Weijiang wrote:
> > > > > Arch LBR MSRs are xsave-supported, but they're operated as "independent"
> > > > > xsave feature by PMU code, i.e., during thread/process context switch,
> > > > > the MSRs are saved/restored with perf_event_task_sched_{in|out} instead
> > > > > of generic kernel fpu switch code, i.e.,save_fpregs_to_fpstate() and
> > > > > restore_fpregs_from_fpstate(). When vcpu guest/host fpu state swap happens,
> > > > > Arch LBR MSRs are retained so they can be accessed directly.
> > > > > 
> > > > > Signed-off-by: Yang Weijiang<weijiang.yang@intel.com>
> > > > > Reviewed-by: Kan Liang<kan.liang@linux.intel.com>
> > > > > ---
> > > > >    arch/x86/kvm/vmx/pmu_intel.c | 10 ++++++++++
> > > > >    1 file changed, 10 insertions(+)
> > > > > 
> > > > > diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
> > > > > index b57944d5e7d8..241128972776 100644
> > > > > --- a/arch/x86/kvm/vmx/pmu_intel.c
> > > > > +++ b/arch/x86/kvm/vmx/pmu_intel.c
> > > > > @@ -410,6 +410,11 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
> > > > >    			msr_info->data = vmcs_read64(GUEST_IA32_LBR_CTL);
> > > > >    		}
> > > > >    		return 0;
> > > > > +	case MSR_ARCH_LBR_FROM_0 ... MSR_ARCH_LBR_FROM_0 + 31:
> > > > > +	case MSR_ARCH_LBR_TO_0 ... MSR_ARCH_LBR_TO_0 + 31:
> > > > > +	case MSR_ARCH_LBR_INFO_0 ... MSR_ARCH_LBR_INFO_0 + 31:
> > > > > +		rdmsrl(msr_info->index, msr_info->data);
> > > > I don't see how this is correct.  As called out in patch 5:
> > > > 
> > > >    : If for some magical reason it's safe to access arch LBR MSRs without disabling
> > > >    : IRQs and confirming perf event ownership, I want to see a very detailed changelog
> > > >    : explaining exactly how that magic works.
> > > The MSR lists here are just for live migration. When arch-lbr is active,
> > > these MSRs are passed through to guest.
> > None of that explains how the guest's MSR values are guaranteed to be resident
> > in hardware.
> 
> I ignored host *event* scheduling case in commit log.
> 
> My understanding is, host LBR *event* could break in at any point when the
> vCPU is running,
> 
> in this case disabling IRQs before read/write the MSRs is pointless because
> the HW context could have been swapped. I need to do more investigation for
> the issue.

Which is presumably why intel_pmu_handle_lbr_msrs_access() checks that the LBR
perf event is active prior to accessing the MSRs, with IRQs disabled...

	/*
	 * Disable irq to ensure the LBR feature doesn't get reclaimed by the
	 * host at the time the value is read from the msr, and this avoids the
	 * host LBR value to be leaked to the guest. If LBR has been reclaimed,
	 * return 0 on guest reads.
	 */
	local_irq_disable();
	if (lbr_desc->event->state == PERF_EVENT_STATE_ACTIVE) {
		if (read)
			rdmsrl(index, msr_info->data);
		else
			wrmsrl(index, msr_info->data);
		__set_bit(INTEL_PMC_IDX_FIXED_VLBR, vcpu_to_pmu(vcpu)->pmc_in_use);
		local_irq_enable();
		return true;
	}
	clear_bit(INTEL_PMC_IDX_FIXED_VLBR, vcpu_to_pmu(vcpu)->pmc_in_use);
	local_irq_enable();

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 00/15] Introduce Architectural LBR for vPMU
  2023-01-27 22:46 ` Sean Christopherson
  2023-01-30 13:38   ` Yang, Weijiang
@ 2023-06-05  9:50   ` Like Xu
  1 sibling, 0 replies; 64+ messages in thread
From: Like Xu @ 2023-06-05  9:50 UTC (permalink / raw)
  To: Sean Christopherson, xiong.y.zhang
  Cc: pbonzini, jmattson, kvm, linux-kernel, kan.liang

+xiongzha to follow up.

On 28/1/2023 6:46 am, Sean Christopherson wrote:
> On Thu, Nov 24, 2022, Yang Weijiang wrote:
>> Intel CPU model-specific LBR(Legacy LBR) has evolved to Architectural
>> LBR(Arch LBR [0]), it's the replacement of legacy LBR on new platforms.
>> The native support patches were merged into 5.9 kernel tree, and this
>> patch series is to enable Arch LBR in vPMU so that guest can benefit
>> from the feature.
>>
>> The main advantages of Arch LBR are [1]:
>> - Faster context switching due to XSAVES support and faster reset of
>>    LBR MSRs via the new DEPTH MSR
>> - Faster LBR read for a non-PEBS event due to XSAVES support, which
>>    lowers the overhead of the NMI handler.
>> - Linux kernel can support the LBR features without knowing the model
>>    number of the current CPU.
>>
>>  From end user's point of view, the usage of Arch LBR is the same as
>> the Legacy LBR that has been merged in the mainline.
>>
>> Note, in this series, there's one restriction for guest Arch LBR, i.e.,
>> guest can only set its LBR record depth the same as host's. This is due
>> to the special behavior of MSR_ARCH_LBR_DEPTH:
>> 1) On write to the MSR, it'll reset all Arch LBR recording MSRs to 0s.
>> 2) XRSTORS resets all record MSRs to 0s if the saved depth mismatches
>> MSR_ARCH_LBR_DEPTH.
>> Enforcing the restriction keeps KVM Arch LBR vPMU working flow simple
>> and straightforward.
>>
>> Paolo refactored the old series and the resulting patches became the
>> base of this new series, therefore he's the author of some patches.
> 
> To be very blunt, this series is a mess.  I don't want to point fingers as there
> is plenty of blame to go around.  The existing LBR support is a confusing mess,
> vPMU as a whole has been neglected for too long, review feedback has been relatively
> non-existent, and I'm sure some of the mess is due to Paolo trying to hastily fix
> things up back when this was temporarily queued.
> 
> However, for arch LBR support to be merged, things need to change.
> 
> First and foremost, the existing LBR support needs to be documented.  Someone,
> I don't care who, needs to provide a detailed writeup of the contract between KVM
> and perf.  Specifically, I want to know:
> 
>    1. When exactly is perf allowed to take control of LBR MRS.  Task switch?  IRQ?
>       NMI?
> 
>    2. What is the expected behavior when perf is using LBRs?  Is the guest supposed
>       to be traced?
> 
>    3. Why does KVM snapshot DEBUGCTL with IRQs enabled, but disables IRQs when
>       accessing LBR MSRs?
> 
> It doesn't have to be polished, e.g. I'll happily wordsmith things into proper
> documentation, but I want to have a very clear understanding of how LBR support
> is _intended_ to function and how it all _actually_ functions without having to
> make guesses.

This is a very good topic for LPC KVM Microconference.

Many thanks to Sean for ranting about something that only I was thinking
about before. Having host and guest be able to use PMU at the same time
in peace (hybrid profiling mode) is a very use-case worthy goal rather than
introducing exclusivity, and it's clear that kvm+perf lacks reasonable and
well-documented support when there is host perf user interference.

Ref: https://lpc.events/event/17/page/200-proposed-microconferences#kvm

> 
> And depending on the answers, I want to revisit KVM's LBR implementation before
> tackling arch LBRs.  Letting perf usurp LBRs while KVM has the vCPU loaded is
> frankly ridiculous.  Just have perf set a flag telling KVM that it needs to take
> control of LBRs and have KVM service the flag as a request or something.  Stealing
> the LBRs back in IRQ context adds a stupid amount of complexity without much value,
> e.g. waiting a few branches for KVM to get to a safe place isn't going to meaningfully
> change the traces.  If that can't actually happen, then why on earth does KVM need
> to disable IRQs to read MSRs?
> 
> And AFAICT, since KVM unconditionally loads the guest's DEBUGCTL, whether or not
> guest branches show up in the LBRs when the host is tracing is completely up to
> the whims of the guest.  If that's correct, then again, what's the point of the
> dance between KVM and perf?
> 
> Beyond the "how does this work" issues, there needs to be tests.  At the absolute
> minimum, there needs to be selftests showing that this stuff actually works, that
> save/restore (migration) works, that the MSRs can/can't be accessed when guest
> CPUID is (in)correctly configured, etc. And I would really, really like to have
> tests that force contention between host and guests, e.g. to make sure that KVM
> isn't leaking host state or outright exploding, but I can understand that those
> types of tests would be very difficult to write.
> 
> I've pushed a heavily reworked, but definitely broken, version to
> 
>    git@github.com:sean-jc/linux.git x86/arch_lbrs
> 
> It compiles, but it's otherwise untested and there are known gaps.  E.g. I omitted
> toggling load+clear of ARCH_LBR_CTL because I couldn't figure out the intended
> behavior.

^ permalink raw reply	[flat|nested] 64+ messages in thread

end of thread, other threads:[~2023-06-05  9:50 UTC | newest]

Thread overview: 64+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-25  4:05 [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang Weijiang
2022-11-25  4:05 ` [PATCH v2 01/15] perf/x86/lbr: Simplify the exposure check for the LBR_INFO registers Yang Weijiang
2022-12-22 10:57   ` Like Xu
2022-12-22 13:29     ` Peter Zijlstra
2022-12-22 17:41     ` Sean Christopherson
2022-12-23  2:12       ` Like Xu
2022-12-27 11:58   ` [tip: perf/core] " tip-bot2 for Like Xu
2022-11-25  4:05 ` [PATCH v2 02/15] KVM: x86: Report XSS as an MSR to be saved if there are supported features Yang Weijiang
2022-11-25  4:05 ` [PATCH v2 03/15] KVM: x86: Refresh CPUID on writes to MSR_IA32_XSS Yang Weijiang
2023-01-26 19:50   ` Sean Christopherson
2023-01-30  6:33     ` Yang, Weijiang
2022-11-25  4:05 ` [PATCH v2 04/15] KVM: PMU: disable LBR handling if architectural LBR is available Yang Weijiang
2023-01-27 20:10   ` Sean Christopherson
2023-01-30  8:10     ` Yang, Weijiang
2022-11-25  4:05 ` [PATCH v2 05/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_DEPTH for guest Arch LBR Yang Weijiang
2022-12-22 11:00   ` Like Xu
2022-12-25  4:30     ` Yang, Weijiang
2022-12-22 11:15   ` Like Xu
2023-01-27 20:25   ` Sean Christopherson
2023-01-30 11:46     ` Yang, Weijiang
2022-11-25  4:05 ` [PATCH v2 06/15] KVM: vmx/pmu: Emulate MSR_ARCH_LBR_CTL " Yang Weijiang
2022-12-22 11:09   ` Like Xu
2022-12-25  4:27     ` Yang, Weijiang
2022-12-22 11:19   ` Like Xu
2022-12-25  4:16     ` Yang, Weijiang
2022-12-22 11:24   ` Like Xu
2022-12-25  4:08     ` Yang, Weijiang
2023-01-27 21:42   ` Sean Christopherson
2022-11-25  4:05 ` [PATCH v2 07/15] KVM: VMX: Support passthrough of architectural LBRs Yang Weijiang
2022-11-25  4:05 ` [PATCH v2 08/15] KVM: x86: Add Arch LBR MSRs to msrs_to_save_all list Yang Weijiang
2023-01-27 21:43   ` Sean Christopherson
2023-01-30 12:27     ` Yang, Weijiang
2022-11-25  4:05 ` [PATCH v2 09/15] KVM: x86: Refine the matching and clearing logic for supported_xss Yang Weijiang
2023-01-27 21:46   ` Sean Christopherson
2023-01-30 12:37     ` Yang, Weijiang
2022-11-25  4:05 ` [PATCH v2 10/15] KVM: x86/vmx: Check Arch LBR config when return perf capabilities Yang Weijiang
2022-12-22 11:06   ` Like Xu
2022-12-25  4:28     ` Yang, Weijiang
2023-01-27 22:04   ` Sean Christopherson
2022-11-25  4:06 ` [PATCH v2 11/15] KVM: x86: Add XSAVE Support for Architectural LBR Yang Weijiang
2023-01-27 22:07   ` Sean Christopherson
2023-01-30 13:13     ` Yang, Weijiang
2022-11-25  4:06 ` [PATCH v2 12/15] KVM: x86/vmx: Disable Arch LBREn bit in #DB and warm reset Yang Weijiang
2022-12-22 11:22   ` Like Xu
2022-12-25  4:12     ` Yang, Weijiang
2023-01-27 22:09   ` Sean Christopherson
2023-01-30 13:09     ` Yang, Weijiang
2022-11-25  4:06 ` [PATCH v2 13/15] KVM: x86/vmx: Save/Restore guest Arch LBR Ctrl msr at SMM entry/exit Yang Weijiang
2023-01-27 22:11   ` Sean Christopherson
2023-01-30 12:50     ` Yang, Weijiang
2022-11-25  4:06 ` [PATCH v2 14/15] KVM: x86: Add Arch LBR data MSR access interface Yang Weijiang
2023-01-27 22:13   ` Sean Christopherson
2023-01-30 12:46     ` Yang, Weijiang
2023-01-30 17:30       ` Sean Christopherson
2023-01-31 13:14         ` Yang, Weijiang
2023-01-31 16:05           ` Sean Christopherson
2022-11-25  4:06 ` [PATCH v2 15/15] KVM: x86/cpuid: Advertise Arch LBR feature in CPUID Yang Weijiang
2022-12-22 11:03   ` Like Xu
2022-12-25  4:31     ` Yang, Weijiang
2023-01-27 22:15   ` Sean Christopherson
2023-01-12  1:57 ` [PATCH v2 00/15] Introduce Architectural LBR for vPMU Yang, Weijiang
2023-01-27 22:46 ` Sean Christopherson
2023-01-30 13:38   ` Yang, Weijiang
2023-06-05  9:50   ` Like Xu

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.