[PATCH v9 16/17] KVM: x86: Add Arch LBR MSR access interface

From: Yang Weijiang
Date: Wed Feb 16 2022 - 05:27:48 EST


When userspace wants to access guest Arch LBR data MSRs, these
MSRs actually reside in guest FPU area, so need to load them to
HW before RDMSR and save them back into FPU area after WRMSR.

Signed-off-by: Yang Weijiang <weijiang.yang@xxxxxxxxx>
---
arch/x86/kvm/vmx/pmu_intel.c | 10 ++++++++++
arch/x86/kvm/x86.c | 9 ++++++++-
2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index e2cae30614b1..976789245917 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -431,6 +431,11 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
case MSR_ARCH_LBR_CTL:
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:
+ kvm_get_xsave_msr(msr_info);
+ return 0;
default:
if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
(pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
@@ -511,6 +516,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:
+ kvm_set_xsave_msr(msr_info);
+ return 0;
default:
if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) ||
(pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) {
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 64de3ed2cd74..de6fc8d4b500 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4105,7 +4105,14 @@ EXPORT_SYMBOL_GPL(kvm_set_xsave_msr);
*/
static bool is_xsaves_msr(u32 index)
{
- return false;
+ bool xsaves_msr = (index >= MSR_ARCH_LBR_FROM_0 &&
+ index <= MSR_ARCH_LBR_FROM_0 + 31) ||
+ (index >= MSR_ARCH_LBR_TO_0 &&
+ index <= MSR_ARCH_LBR_TO_0 + 31) ||
+ (index >= MSR_ARCH_LBR_INFO_0 &&
+ index <= MSR_ARCH_LBR_INFO_0 + 31);
+
+ return xsaves_msr;
}

/*
--
2.27.0