Received: by 2002:a25:868d:0:0:0:0:0 with SMTP id z13csp1150964ybk; Thu, 14 May 2020 01:33:40 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy2RPMCH1K5/DXRuYQVjB6p03UvMq+Ay2NHYLEoPisxr6nh8p6wJVDXzPR6blbULMTNR3tA X-Received: by 2002:a17:906:410a:: with SMTP id j10mr2693833ejk.378.1589445219783; Thu, 14 May 2020 01:33:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1589445219; cv=none; d=google.com; s=arc-20160816; b=FAmOll3PmXpSJjQEYhY9JwBmoS8I+zOst8ve3jPpmgKGSiR2c00HXBir7CictKwoSB 4Ob4IYh/ZkXAkyUzYr8thyoB2BFx3iMPJyWCR2nUl+mQ/CdbuYhgiyh35gVbnusK+5c7 ZAgC+ynmzGyljooS4UFisv4VwHt+eH2uQY3hJuFJD7HTkWVqDqoCZQNqlZAf4H4rEXh9 JBP8aiXKSalol/wUuvem1NwGiYOtZJYsw1rMCCkhR/JfX64Wd2MaKl9dNC5h77O+6ZZJ i/QEzUVw1z8PB8apvILOmKne1MeebuX1ZmPatfl9PZSr6PHMvBNNnstS/DqQit12wrjm ETGA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :ironport-sdr:ironport-sdr; bh=6jhAyz0o4LFtBRNZj35sgVA04CPiR97sqhNxYweQkls=; b=OInV45zKDGB0BwILQQp54BMxzOptQ9Tuuitc8WQqnwJlhYbKsPE5uWwa7K/fGi+Dra uA/WhHJ/4t8CuEDHxP/2FbnbyuRczxdo8XozT+rl5qdiFt8Ksh2ixoZf8dVUNgg6fLEK XCfzVx+2+IY9AfQWyUgMXUhqOkSCOmibLWaQzScMOHxICgBC/paG20p/OEaDGW0vOn+N 54zl/4LOv/r98/FcMiAACsMypFcVGkjOlCPPNb7vkdK6Hg15KIUPbjNo5yrAlwrpn3nX VQU4d1Er8fxrlKr9RUPTKXOEpcmRLyFRY3ZGdLp7DbfKpYOa+2SfEJOu6EcWu6a/EByn Q86g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id n8si1341001ejh.210.2020.05.14.01.33.16; Thu, 14 May 2020 01:33:39 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725935AbgENIbg (ORCPT + 99 others); Thu, 14 May 2020 04:31:36 -0400 Received: from mga18.intel.com ([134.134.136.126]:12089 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726347AbgENIbf (ORCPT ); Thu, 14 May 2020 04:31:35 -0400 IronPort-SDR: wTQiUBhBLvOyFJBrrJkXT8A0ajBdublVakAKTQNRxuJQWEgTBlYmNz5KXi9CYloYlvgBwEpe/r G+Hr336krtsg== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 May 2020 01:31:34 -0700 IronPort-SDR: AF5F1wOXH7YgJZ6pUeAOHhl3zP65NnhTkSMjvHwLwjQDB/dSCqWi1md6n3HACXv3B6PdvB0y2H V3PzvzDt5QKA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,390,1583222400"; d="scan'208";a="341539991" Received: from sqa-gate.sh.intel.com (HELO clx-ap-likexu.tsp.org) ([10.239.48.212]) by orsmga001.jf.intel.com with ESMTP; 14 May 2020 01:31:31 -0700 From: Like Xu To: Peter Zijlstra , Paolo Bonzini Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , Thomas Gleixner , ak@linux.intel.com, wei.w.wang@intel.com, Like Xu Subject: [PATCH v11 07/11] KVM: x86: Expose MSR_IA32_PERF_CAPABILITIES for LBR record format Date: Thu, 14 May 2020 16:30:50 +0800 Message-Id: <20200514083054.62538-8-like.xu@linux.intel.com> X-Mailer: git-send-email 2.21.3 In-Reply-To: <20200514083054.62538-1-like.xu@linux.intel.com> References: <20200514083054.62538-1-like.xu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The MSR_IA32_PERF_CAPABILITIES is a read only MSR that enumerates the existence of performance monitoring features and KVM would always set F(PDCM) since worst case it will just be zero. The bits [0, 5] of MSR_IA32_PERF_CAPABILITIES tells about the LBR format of the branch record addresses stored in the LBR stack. User space could enable guest LBR by setting the exactly supported LBR format bits for this msr_based_feature. Signed-off-by: Like Xu --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/cpuid.c | 2 +- arch/x86/kvm/vmx/capabilities.h | 15 +++++++++++++++ arch/x86/kvm/vmx/pmu_intel.c | 23 +++++++++++++++++++++++ arch/x86/kvm/vmx/vmx.c | 3 +++ arch/x86/kvm/x86.c | 1 + 6 files changed, 44 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 35a915787559..8c3ae83f63d9 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -599,6 +599,7 @@ struct kvm_vcpu_arch { u64 ia32_xss; u64 microcode_version; u64 arch_capabilities; + u64 perf_capabilities; /* * Paging state of the vcpu diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 35845704cf57..411ce1b58341 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -294,7 +294,7 @@ void kvm_set_cpu_caps(void) F(XMM3) | F(PCLMULQDQ) | 0 /* DTES64, MONITOR */ | 0 /* DS-CPL, VMX, SMX, EST */ | 0 /* TM2 */ | F(SSSE3) | 0 /* CNXT-ID */ | 0 /* Reserved */ | - F(FMA) | F(CX16) | 0 /* xTPR Update, PDCM */ | + F(FMA) | F(CX16) | 0 /* xTPR Update */ | F(PDCM) | F(PCID) | 0 /* Reserved, DCA */ | F(XMM4_1) | F(XMM4_2) | F(X2APIC) | F(MOVBE) | F(POPCNT) | 0 /* Reserved*/ | F(AES) | F(XSAVE) | 0 /* OSXSAVE */ | F(AVX) | diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h index 8903475f751e..27a66795665b 100644 --- a/arch/x86/kvm/vmx/capabilities.h +++ b/arch/x86/kvm/vmx/capabilities.h @@ -18,6 +18,8 @@ extern int __read_mostly pt_mode; #define PT_MODE_SYSTEM 0 #define PT_MODE_HOST_GUEST 1 +#define PERF_CAP_LBR_FMT 0x3f + struct nested_vmx_msrs { /* * We only store the "true" versions of the VMX capability MSRs. We @@ -367,4 +369,17 @@ static inline bool vmx_pt_mode_is_host_guest(void) return pt_mode == PT_MODE_HOST_GUEST; } +static inline u64 vmx_get_perf_capabilities(void) +{ + u64 perf_cap = 0; + + if (boot_cpu_has(X86_FEATURE_PDCM)) + rdmsrl(MSR_IA32_PERF_CAPABILITIES, perf_cap); + + /* Currently, KVM only supports LBR. */ + perf_cap &= PERF_CAP_LBR_FMT; + + return perf_cap; +} + #endif /* __KVM_X86_VMX_CAPS_H */ diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index e1a303fefc16..79e5bf36ffc8 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -162,6 +162,9 @@ static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr) case MSR_CORE_PERF_GLOBAL_OVF_CTRL: ret = pmu->version > 1; break; + case MSR_IA32_PERF_CAPABILITIES: + ret = guest_cpuid_has(vcpu, X86_FEATURE_PDCM); + break; default: ret = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0) || get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0) || @@ -203,6 +206,12 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_CORE_PERF_GLOBAL_OVF_CTRL: msr_info->data = pmu->global_ovf_ctrl; return 0; + case MSR_IA32_PERF_CAPABILITIES: + if (!msr_info->host_initiated && + !guest_cpuid_has(vcpu, X86_FEATURE_PDCM)) + return 1; + msr_info->data = vcpu->arch.perf_capabilities; + return 0; default: if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) { u64 val = pmc_read_counter(pmc); @@ -261,6 +270,16 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) return 0; } break; + case MSR_IA32_PERF_CAPABILITIES: + if (!msr_info->host_initiated || + !guest_cpuid_has(vcpu, X86_FEATURE_PDCM)) + return 1; + if (!(data & ~vmx_get_perf_capabilities())) + return 1; + if ((data ^ vmx_get_perf_capabilities()) & PERF_CAP_LBR_FMT) + return 1; + vcpu->arch.perf_capabilities = data; + return 0; default: if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) { if (!msr_info->host_initiated) @@ -315,6 +334,8 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) return; perf_get_x86_pmu_capability(&x86_pmu); + if (!guest_cpuid_has(vcpu, X86_FEATURE_PDCM)) + vcpu->arch.perf_capabilities = 0; pmu->nr_arch_gp_counters = min_t(int, eax.split.num_counters, x86_pmu.num_counters_gp); @@ -374,6 +395,8 @@ static void intel_pmu_init(struct kvm_vcpu *vcpu) pmu->fixed_counters[i].idx = i + INTEL_PMC_IDX_FIXED; pmu->fixed_counters[i].current_config = 0; } + + vcpu->arch.perf_capabilities = vmx_get_perf_capabilities(); } static void intel_pmu_reset(struct kvm_vcpu *vcpu) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index bc5e5cf1d4cc..ee94d94e855a 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1789,6 +1789,9 @@ static int vmx_get_msr_feature(struct kvm_msr_entry *msr) if (!nested) return 1; return vmx_get_vmx_msr(&vmcs_config.nested, msr->index, &msr->data); + case MSR_IA32_PERF_CAPABILITIES: + msr->data = vmx_get_perf_capabilities(); + return 0; default: return 1; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 23fe511c6ba0..b577fadffb1d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1323,6 +1323,7 @@ static const u32 msr_based_features_all[] = { MSR_F10H_DECFG, MSR_IA32_UCODE_REV, MSR_IA32_ARCH_CAPABILITIES, + MSR_IA32_PERF_CAPABILITIES, }; static u32 msr_based_features[ARRAY_SIZE(msr_based_features_all)]; -- 2.21.3