From patchwork Fri Sep 1 07:28:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Xiong Y" X-Patchwork-Id: 13372138 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 185FACA0FE1 for ; Fri, 1 Sep 2023 07:29:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245743AbjIAH3T (ORCPT ); Fri, 1 Sep 2023 03:29:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37662 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231947AbjIAH3S (ORCPT ); Fri, 1 Sep 2023 03:29:18 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 91C7710D0 for ; Fri, 1 Sep 2023 00:29:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1693553355; x=1725089355; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GJPzNvzdyK2Ch7vK1oYz0qZLq7UvVihJ20wTnlTgsVA=; b=lrPA+Inco5IhYEl0+7cqgAWTrQMW5PQCIu7ImjFqZWBr8ypgS/3pz60A IvoOvhKCHNNX2lzfEgVlNfZRUCngJDcSpuYOB8TJgsQdzQsN64RSWbsMW n+739eOa+ogLoRvWf/i6W7hT678GLKMVvuzEPcyIv1UOeeDLaXqLfCHi7 SuBfJDSam59pSjtLLZ7h511LIXLShftCGgJPI3aBg4f8Dp5CbQLmQcZst d4mVVyleEyvTF/SCcfW+FOBmD2KGBiu/4KAC2BkiEpC2j8rXPU+07yhwR 1xkgyC5+RJj+M5m/V1rvndeesjvjjpSAiiYyPswgZ44sLSklhyfaIXIh/ w==; X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="373550294" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="373550294" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:15 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="716671239" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="716671239" Received: from wangdere-mobl2.ccr.corp.intel.com (HELO xiongzha-desk1.ccr.corp.intel.com) ([10.255.29.239]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:12 -0700 From: Xiong Zhang To: kvm@vger.kernel.org Cc: seanjc@google.com, like.xu.linux@gmail.com, zhiyuan.lv@intel.com, zhenyu.z.wang@intel.com, kan.liang@intel.com, dapeng1.mi@linux.intel.com, Xiong Zhang Subject: [PATCH 1/9] KVM: x86/PMU: Don't release vLBR caused by PMI Date: Fri, 1 Sep 2023 15:28:01 +0800 Message-Id: <20230901072809.640175-2-xiong.y.zhang@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230901072809.640175-1-xiong.y.zhang@intel.com> References: <20230901072809.640175-1-xiong.y.zhang@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org vLBR event will be released at vcpu sched-in time if LBR_EN bit is not set in GUEST_IA32_DEBUGCTL VMCS field, this bit is cleared in two cases: 1. guest disable LBR through WRMSR 2. KVM disable LBR at PMI injection to emulate guest FREEZE_LBR_ON_PMI. The first case is guest LBR won't be used anymore and vLBR event can be released, but guest LBR is still be used in the second case, vLBR event can not be released. Considering this serial: 1. vPMC overflow, KVM injects vPMI and clears guest LBR_EN 2. guest handles PMI, and reads LBR records. 3. vCPU is sched-out, later sched-in, vLBR event is released. 4. Guest continue reading LBR records, KVM creates vLBR event again, the vLBR event is the only LBR user on host now, host PMU driver will reset HW LBR facility at vLBR creataion. 5. Guest gets the remain LBR records with reset state. This is conflict with FREEZE_LBR_ON_PMI meaning, so vLBR event can not be release on PMI. This commit adds a freeze_on_pmi flag, this flag is set at pmi injection and is cleared when guest operates guest DEBUGCTL_MSR. If this flag is true, vLBR event will not be released. Signed-off-by: Xiong Zhang Reviewed-by: Dapeng Mi --- arch/x86/kvm/vmx/pmu_intel.c | 5 ++++- arch/x86/kvm/vmx/vmx.c | 12 +++++++++--- arch/x86/kvm/vmx/vmx.h | 3 +++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index f2efa0bf7ae8..3a36a91638c6 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -628,6 +628,7 @@ static void intel_pmu_init(struct kvm_vcpu *vcpu) lbr_desc->records.nr = 0; lbr_desc->event = NULL; lbr_desc->msr_passthrough = false; + lbr_desc->freeze_on_pmi = false; } static void intel_pmu_reset(struct kvm_vcpu *vcpu) @@ -670,6 +671,7 @@ static void intel_pmu_legacy_freezing_lbrs_on_pmi(struct kvm_vcpu *vcpu) if (data & DEBUGCTLMSR_FREEZE_LBRS_ON_PMI) { data &= ~DEBUGCTLMSR_LBR; vmcs_write64(GUEST_IA32_DEBUGCTL, data); + vcpu_to_lbr_desc(vcpu)->freeze_on_pmi = true; } } @@ -761,7 +763,8 @@ 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)) + if (!(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR) && + !vcpu_to_lbr_desc(vcpu)->freeze_on_pmi) intel_pmu_release_guest_lbr_event(vcpu); } diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index e6849f780dba..199d0da1dbee 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2223,9 +2223,15 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) get_vmcs12(vcpu)->guest_ia32_debugctl = data; vmcs_write64(GUEST_IA32_DEBUGCTL, data); - if (intel_pmu_lbr_is_enabled(vcpu) && !to_vmx(vcpu)->lbr_desc.event && - (data & DEBUGCTLMSR_LBR)) - intel_pmu_create_guest_lbr_event(vcpu); + + if (intel_pmu_lbr_is_enabled(vcpu)) { + struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu); + + lbr_desc->freeze_on_pmi = false; + if (!lbr_desc->event && (data & DEBUGCTLMSR_LBR)) + intel_pmu_create_guest_lbr_event(vcpu); + } + return 0; } case MSR_IA32_BNDCFGS: diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index c2130d2c8e24..9729ccfa75ae 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -107,6 +107,9 @@ struct lbr_desc { /* True if LBRs are marked as not intercepted in the MSR bitmap */ bool msr_passthrough; + + /* True if LBR is frozen on PMI */ + bool freeze_on_pmi; }; /* From patchwork Fri Sep 1 07:28:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Xiong Y" X-Patchwork-Id: 13372139 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1152BCA0FE1 for ; Fri, 1 Sep 2023 07:29:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232191AbjIAH3Z (ORCPT ); Fri, 1 Sep 2023 03:29:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35162 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348491AbjIAH3X (ORCPT ); Fri, 1 Sep 2023 03:29:23 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3303910D5 for ; Fri, 1 Sep 2023 00:29:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1693553360; x=1725089360; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=z0wVXXRYmruZ4sJE29Br4nwX5WxuWH1zxAHI0a7i0gI=; b=cUDwqa2neKR9965F99WqVZebGx5MiJpl7rvQCdAWjULKE5+F8LOUptn9 KoVV4fKPQV+urnkpdlus7bDUNqYW8t1TTdBQzpTBZOCoHq+niUpergVuF 7AuDWzkVCj7G79Cj7s6ifL+eRXgyxFHpyaa1ZXt2nbAg5an8ooEKAeWAX N0eEEMz9MmOaRtjR334Sv3vzhbh3syT13phF24hBVUXAlbuXJ7UzwurSv B8TXwawMmjgIPRlnFC457JiMJxtiGnpW4Zj7UigXuyy99wgXq3Ecz+V0n g5NX3wK+33SKVeoVwOmh3bsf37hDFgVEbEwZ4aBdo1ZyGcFOAQ1zaT0lL Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="373550308" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="373550308" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:19 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="716671257" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="716671257" Received: from wangdere-mobl2.ccr.corp.intel.com (HELO xiongzha-desk1.ccr.corp.intel.com) ([10.255.29.239]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:16 -0700 From: Xiong Zhang To: kvm@vger.kernel.org Cc: seanjc@google.com, like.xu.linux@gmail.com, zhiyuan.lv@intel.com, zhenyu.z.wang@intel.com, kan.liang@intel.com, dapeng1.mi@linux.intel.com, Xiong Zhang Subject: [PATCH 2/9] KVM: x85/pmu: Add Streamlined FREEZE_LBR_ON_PMI for vPMU v4 Date: Fri, 1 Sep 2023 15:28:02 +0800 Message-Id: <20230901072809.640175-3-xiong.y.zhang@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230901072809.640175-1-xiong.y.zhang@intel.com> References: <20230901072809.640175-1-xiong.y.zhang@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Arch PMU version 4 adds a streamlined FREEZE_LBR_ON_PMI feature, this feature adds LBR_FRZ[bit 58] into IA32_PERF_GLOBAL_STATUS, this bit is set due to the following conditions: -- IA32_DEBUGCTL.FREEZE_LBR_ON_PMI has been set -- A performance counter, configured to generate PMI, has overflowed to signal a PMI. Consequently the LBR stack is frozen. Effectively, this bit also serves as a control to enabled capturing data in the LBR stack. When this bit is set, LBR stack is frozen, and new LBR records won't be filled. The sequence of streamlined freeze LBR is: 1. Profiling agent set IA32_DEBUGCTL.FREEZE_LBR_ON_PMI, and enable a performance counter to generate PMI on overflow. 2. Processor generates PMI and sets IA32_PERF_GLOBAL_STATUS.LBR_FRZ, then LBR stack is forzen. 3. Profiling agent PMI handler handles overflow, and clears IA32_PERF_GLOBAL_STATUS. 4. When IA32_PERF_GLOBAL_STATUS.LBR_FRZ is cleared in step 3, processor resume LBR stack, and new LBR records can be filled again. In order to emulate this behavior, LBR stack must be frozen on PMI. KVM has two choice to do this: 1. KVM stops vLBR event through perf_event_pause(), and put vLBR event into off state, then vLBR lose LBR hw resource, finally guest couldn't read LBR records in guest PMI handler. This choice couldn't be used. 2. KVM clear guest DEBUGCTLMSR_LBR bit in VMCS on PMI, so when guest is running, LBR HW stack is disabled, while vLBR event is still active and own LBR HW, so guest could still read LBR records in guest PMI handler. But the sequence of streamlined freeze LBR doesn't clear DEBUGCTLMSR_LBR bit, so when guest read guest DEBUGCTL_MSR, KVM will return a value with DEBUGCTLMSR_LBR bit set during LBR freezing. Once guest clears IA32_PERF_GLOBAL_STATUS.LBR_FRZ in step 4, KVM will re-enable guest LBR through setting guest DEBUGCTL_LBR bit in VMCS. As KVM will re-enable guest LBR when guest clears global status, the handling of GLOBAL_OVF_CTRL MSR is moved from common pmu.c into vmx/pmu_intel.c. Signed-off-by: Xiong Zhang Reviewed-by: Dapeng Mi --- arch/x86/include/asm/msr-index.h | 1 + arch/x86/kvm/pmu.c | 8 ------ arch/x86/kvm/vmx/pmu_intel.c | 44 ++++++++++++++++++++++++++++++++ arch/x86/kvm/vmx/vmx.c | 3 +++ 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 3aedae61af4f..4fce37ae5a90 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -1041,6 +1041,7 @@ /* PERF_GLOBAL_OVF_CTL bits */ #define MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT 55 #define MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI (1ULL << MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT) +#define MSR_CORE_PERF_GLOBAL_OVF_CTRL_LBR_FREEZE BIT_ULL(58) #define MSR_CORE_PERF_GLOBAL_OVF_CTRL_OVF_BUF_BIT 62 #define MSR_CORE_PERF_GLOBAL_OVF_CTRL_OVF_BUF (1ULL << MSR_CORE_PERF_GLOBAL_OVF_CTRL_OVF_BUF_BIT) #define MSR_CORE_PERF_GLOBAL_OVF_CTRL_COND_CHGD_BIT 63 diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index edb89b51b383..4b6a508f3f0b 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c @@ -640,14 +640,6 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) reprogram_counters(pmu, diff); } break; - case MSR_CORE_PERF_GLOBAL_OVF_CTRL: - /* - * GLOBAL_OVF_CTRL, a.k.a. GLOBAL STATUS_RESET, clears bits in - * GLOBAL_STATUS, and so the set of reserved bits is the same. - */ - if (data & pmu->global_status_mask) - return 1; - fallthrough; case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR: if (!msr_info->host_initiated) pmu->global_status &= ~data; diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index 3a36a91638c6..ba7695a64ff1 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -426,6 +426,29 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) pmu->pebs_data_cfg = data; break; + case MSR_CORE_PERF_GLOBAL_OVF_CTRL: + /* + * GLOBAL_OVF_CTRL, a.k.a. GLOBAL STATUS_RESET, clears bits in + * GLOBAL_STATUS, and so the set of reserved bits is the same. + */ + if (data & pmu->global_status_mask) + return 1; + if (pmu->version >= 4 && !msr_info->host_initiated && + (data & MSR_CORE_PERF_GLOBAL_OVF_CTRL_LBR_FREEZE)) { + u64 debug_ctl = vmcs_read64(GUEST_IA32_DEBUGCTL); + struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu); + + if (!(debug_ctl & DEBUGCTLMSR_LBR) && + lbr_desc->freeze_on_pmi) { + debug_ctl |= DEBUGCTLMSR_LBR; + vmcs_write64(GUEST_IA32_DEBUGCTL, debug_ctl); + lbr_desc->freeze_on_pmi = false; + } + } + + if (!msr_info->host_initiated) + pmu->global_status &= ~data; + break; default: if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) || (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) { @@ -565,6 +588,9 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) if (vmx_pt_mode_is_host_guest()) pmu->global_status_mask &= ~MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI; + if (pmu->version >= 4) + pmu->global_status_mask &= + ~MSR_CORE_PERF_GLOBAL_OVF_CTRL_LBR_FREEZE; entry = kvm_find_cpuid_entry_index(vcpu, 7, 0); if (entry && @@ -675,6 +701,22 @@ static void intel_pmu_legacy_freezing_lbrs_on_pmi(struct kvm_vcpu *vcpu) } } +static void intel_pmu_streamlined_freezing_lbrs_on_pmi(struct kvm_vcpu *vcpu) +{ + u64 data = vmcs_read64(GUEST_IA32_DEBUGCTL); + struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); + + /* + * Even if streamlined freezing LBR won't clear LBR_EN like legacy + * freezing LBR, here legacy freezing LBR is called to freeze LBR HW + * for streamlined freezing LBR when guest run. But guest VM will + * see a fake guest DEBUGCTL MSR with LBR_EN bit set. + */ + intel_pmu_legacy_freezing_lbrs_on_pmi(vcpu); + if ((data & DEBUGCTLMSR_FREEZE_LBRS_ON_PMI) && (data & DEBUGCTLMSR_LBR)) + pmu->global_status |= MSR_CORE_PERF_GLOBAL_OVF_CTRL_LBR_FREEZE; +} + static void intel_pmu_deliver_pmi(struct kvm_vcpu *vcpu) { u8 version = vcpu_to_pmu(vcpu)->version; @@ -684,6 +726,8 @@ static void intel_pmu_deliver_pmi(struct kvm_vcpu *vcpu) if (version > 1 && version < 4) intel_pmu_legacy_freezing_lbrs_on_pmi(vcpu); + else if (version >= 4) + intel_pmu_streamlined_freezing_lbrs_on_pmi(vcpu); } static void vmx_update_intercept_for_lbr_msrs(struct kvm_vcpu *vcpu, bool set) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 199d0da1dbee..3bd64879aab3 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2098,6 +2098,9 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) break; case MSR_IA32_DEBUGCTLMSR: msr_info->data = vmcs_read64(GUEST_IA32_DEBUGCTL); + if (vcpu_to_lbr_desc(vcpu)->freeze_on_pmi && + vcpu_to_pmu(vcpu)->version >= 4) + msr_info->data |= DEBUGCTLMSR_LBR; break; default: find_uret_msr: From patchwork Fri Sep 1 07:28:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Xiong Y" X-Patchwork-Id: 13372140 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8DC2CCA0FE6 for ; Fri, 1 Sep 2023 07:29:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348489AbjIAH3a (ORCPT ); Fri, 1 Sep 2023 03:29:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345419AbjIAH32 (ORCPT ); Fri, 1 Sep 2023 03:29:28 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 55DF210D2 for ; Fri, 1 Sep 2023 00:29:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1693553364; x=1725089364; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=gB/YX0LD6k+ooMHcDDKKsOdkMRRWbYYzCUtvYTA4lTI=; b=ANDnCdi1JbLe7sHbTAEcc/H6MeAtyG8xaL21M7rJPTzrYL4H9veFTOJv S8JWT/46xCMGYgYauuHU4RJX5mZRxGpEiAA1tCyLGtD90m9iTYPf3Vvhw u96wtIUXZ9MMvtHPPgS+2DWWkbyrzV9auSiBNz4StNXseCMAWTZzNAacF rAARNXOETo9f2cAqX/9CNt3vHzwWwhttqaTr3CgKuKg4N7dfF5QUl5XqF mhdtcDjuthVUOAGikyQiZrbn2qXwazF2AtF3Nun52G64PLiQOw1pWnSdj JwkOxYVLylUiJ7m4vwO9BL9uGFXcs6uFbJg1AmCnMPLvxIuQIQSKdiX7Q w==; X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="373550315" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="373550315" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:24 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="716671275" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="716671275" Received: from wangdere-mobl2.ccr.corp.intel.com (HELO xiongzha-desk1.ccr.corp.intel.com) ([10.255.29.239]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:21 -0700 From: Xiong Zhang To: kvm@vger.kernel.org Cc: seanjc@google.com, like.xu.linux@gmail.com, zhiyuan.lv@intel.com, zhenyu.z.wang@intel.com, kan.liang@intel.com, dapeng1.mi@linux.intel.com, Xiong Zhang Subject: [PATCH 3/9] KVM: x86/pmu: Add PERF_GLOBAL_STATUS_SET MSR emulation Date: Fri, 1 Sep 2023 15:28:03 +0800 Message-Id: <20230901072809.640175-4-xiong.y.zhang@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230901072809.640175-1-xiong.y.zhang@intel.com> References: <20230901072809.640175-1-xiong.y.zhang@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The IA32_PERF_GLOBAL_STATUS_SET MSR is introduced with arch PMU version 4. It allows software to set individual bits in IA32_PERF_GLOBAL_STATUS MSR. It can be used by a VMM to virtualize the state of IA32_PERF_GLOBAL_STATUS across VMS. If the running VM owns the whole PMU, different VM will have different perf global status, VMM needs to restore IA32_PERF_GLOBAL_STATUS MSR at VM switch, but IA32_PERF_GLOBAL_STATUS MSR is read only, so VMM can use IA32_PERF_GLOBAL_STATUS_SET MSR to restore VM's PERF_GLOBAL_STATUS MSR. This commit adds this MSR emulation, so that L1 VMM could use it. As it is mainly used by VMM to restore VM's PERF_GLOBAL_STATUS MSR during VM switch, it doesn't need to inject PMI or FREEZE_LBR when VMM write it. Signed-off-by: Xiong Zhang --- arch/x86/include/asm/msr-index.h | 1 + arch/x86/kvm/vmx/pmu_intel.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 4fce37ae5a90..7c8cf6b53a76 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -1035,6 +1035,7 @@ #define MSR_CORE_PERF_GLOBAL_STATUS 0x0000038e #define MSR_CORE_PERF_GLOBAL_CTRL 0x0000038f #define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x00000390 +#define MSR_CORE_PERF_GLOBAL_STATUS_SET 0x00000391 #define MSR_PERF_METRICS 0x00000329 diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index ba7695a64ff1..b25df421cd75 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -206,6 +206,8 @@ static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr) switch (msr) { case MSR_CORE_PERF_FIXED_CTR_CTRL: return kvm_pmu_has_perf_global_ctrl(pmu); + case MSR_CORE_PERF_GLOBAL_STATUS_SET: + return vcpu_to_pmu(vcpu)->version >= 4; case MSR_IA32_PEBS_ENABLE: ret = vcpu_get_perf_capabilities(vcpu) & PERF_CAP_PEBS_FORMAT; break; @@ -355,6 +357,9 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_CORE_PERF_FIXED_CTR_CTRL: msr_info->data = pmu->fixed_ctr_ctrl; break; + case MSR_CORE_PERF_GLOBAL_STATUS_SET: + msr_info->data = 0; + break; case MSR_IA32_PEBS_ENABLE: msr_info->data = pmu->pebs_enable; break; @@ -449,6 +454,17 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) if (!msr_info->host_initiated) pmu->global_status &= ~data; break; + case MSR_CORE_PERF_GLOBAL_STATUS_SET: + /* + * GLOBAL STATUS_SET, sets bits in GLOBAL_STATUS, so the + * set of reserved bits are the same. + */ + if (data & pmu->global_status_mask) + return 1; + + if (!msr_info->host_initiated) + pmu->global_status |= data; + break; default: if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)) || (pmc = get_gp_pmc(pmu, msr, MSR_IA32_PMC0))) { From patchwork Fri Sep 1 07:28:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Xiong Y" X-Patchwork-Id: 13372141 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0F79FCA0FE6 for ; Fri, 1 Sep 2023 07:29:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348492AbjIAH3i (ORCPT ); Fri, 1 Sep 2023 03:29:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54080 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345348AbjIAH3h (ORCPT ); Fri, 1 Sep 2023 03:29:37 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A323510FF for ; Fri, 1 Sep 2023 00:29:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1693553368; x=1725089368; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=e9GBmb6MYZj2FZWMLl6IWpX0FvqtRaMTkPeuCa6J3RQ=; b=QBZrsKH2wLGO0GWpgZ00X4lG4wp7/7Ct8lFiA7/OtNk0wqooXUG+2SUA c2r8e1085+sLXypiKBAqT3ms+t5VBcMbExMwSUUzg43op+ewEyUdgNUlt TNItLWP/V/dRiEXWdFRHhGC4c5Bny+QpWgOaJHn7ym9ZvGS38kHCZ5rGf NxGuI2X9vkFaXg52doS0V9nvOt8IqqyJfjltQvkITJLYCcl7fBvZF/uHb SYVAN9imxAe31OW06NUnQ1L4Zo55qA8WmU7qniPQMrQ4GpFhj1DI+JmMT Q0DGqmOneW8PLXl+YzSGqFTmZy9P5zTMcxUn7JWqG/v6lHzr5YDVMGrA4 w==; X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="373550324" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="373550324" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="716671288" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="716671288" Received: from wangdere-mobl2.ccr.corp.intel.com (HELO xiongzha-desk1.ccr.corp.intel.com) ([10.255.29.239]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:25 -0700 From: Xiong Zhang To: kvm@vger.kernel.org Cc: seanjc@google.com, like.xu.linux@gmail.com, zhiyuan.lv@intel.com, zhenyu.z.wang@intel.com, kan.liang@intel.com, dapeng1.mi@linux.intel.com, Xiong Zhang Subject: [PATCH 4/9] KVM: x86/pmu: Add MSR_PERF_GLOBAL_INUSE emulation Date: Fri, 1 Sep 2023 15:28:04 +0800 Message-Id: <20230901072809.640175-5-xiong.y.zhang@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230901072809.640175-1-xiong.y.zhang@intel.com> References: <20230901072809.640175-1-xiong.y.zhang@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Arch PMU v4 introduces a new MSR, IA32_PERF_GLOBAL_INUSE. It provides as "InUse" bit for each GP counter and fixed counter in processor. Additionally PMI InUse[bit 63] indicates if the PMI mechanism has been configured. Each bit's definition references Architectural Performance Monitoring Version 4 section of SDM. Signed-off-by: Xiong Zhang --- arch/x86/include/asm/msr-index.h | 4 +++ arch/x86/kvm/vmx/pmu_intel.c | 58 ++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 7c8cf6b53a76..31bb425899fb 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -1036,6 +1036,7 @@ #define MSR_CORE_PERF_GLOBAL_CTRL 0x0000038f #define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x00000390 #define MSR_CORE_PERF_GLOBAL_STATUS_SET 0x00000391 +#define MSR_CORE_PERF_GLOBAL_INUSE 0x00000392 #define MSR_PERF_METRICS 0x00000329 @@ -1048,6 +1049,9 @@ #define MSR_CORE_PERF_GLOBAL_OVF_CTRL_COND_CHGD_BIT 63 #define MSR_CORE_PERF_GLOBAL_OVF_CTRL_COND_CHGD (1ULL << MSR_CORE_PERF_GLOBAL_OVF_CTRL_COND_CHGD_BIT) +/* PERF_GLOBAL_INUSE bits */ +#define MSR_CORE_PERF_GLOBAL_INUSE_PMI BIT_ULL(63) + /* Geode defined MSRs */ #define MSR_GEODE_BUSCONT_CONF0 0x00001900 diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index b25df421cd75..46363ac82a79 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -207,6 +207,7 @@ static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr) case MSR_CORE_PERF_FIXED_CTR_CTRL: return kvm_pmu_has_perf_global_ctrl(pmu); case MSR_CORE_PERF_GLOBAL_STATUS_SET: + case MSR_CORE_PERF_GLOBAL_INUSE: return vcpu_to_pmu(vcpu)->version >= 4; case MSR_IA32_PEBS_ENABLE: ret = vcpu_get_perf_capabilities(vcpu) & PERF_CAP_PEBS_FORMAT; @@ -347,6 +348,58 @@ static bool intel_pmu_handle_lbr_msrs_access(struct kvm_vcpu *vcpu, return true; } +static u64 intel_pmu_global_inuse_emulation(struct kvm_pmu *pmu) +{ + u64 data = 0; + int i; + + for (i = 0; i < pmu->nr_arch_gp_counters; i++) { + struct kvm_pmc *pmc = &pmu->gp_counters[i]; + + /* + * IA32_PERF_GLOBAL_INUSE.PERFEVTSELn_InUse[bit n]: This bit + * reflects the logical state of (IA32_PERFEVTSELn[7:0]), + * n < CPUID.0AH.EAX[15:8]. + */ + if (pmc->eventsel & ARCH_PERFMON_EVENTSEL_EVENT) + data |= 1 << i; + /* + * IA32_PERF_GLOBAL_INUSE.PMI_InUse[bit 63]: This bit is set if + * IA32_PERFEVTSELn.INT[bit 20], n < CPUID.0AH.EAX[15:8] is set. + */ + if (pmc->eventsel & ARCH_PERFMON_EVENTSEL_INT) + data |= MSR_CORE_PERF_GLOBAL_INUSE_PMI; + } + + for (i = 0; i < pmu->nr_arch_fixed_counters; i++) { + /* + * IA32_PERF_GLOBAL_INUSE.FCi_InUse[bit (i + 32)]: This bit + * reflects the logical state of + * IA32_FIXED_CTR_CTRL[i * 4 + 1, i * 4] != 0 + */ + if (pmu->fixed_ctr_ctrl & + intel_fixed_bits_by_idx(i, INTEL_FIXED_0_KERNEL | INTEL_FIXED_0_USER)) + data |= 1ULL << (i + INTEL_PMC_IDX_FIXED); + /* + * IA32_PERF_GLOBAL_INUSE.PMI_InUse[bit 63]: This bit is set if + * IA32_FIXED_CTR_CTRL.ENi_PMI, i = 0, 1, 2 is set. + */ + if (pmu->fixed_ctr_ctrl & + intel_fixed_bits_by_idx(i, INTEL_FIXED_0_ENABLE_PMI)) + data |= MSR_CORE_PERF_GLOBAL_INUSE_PMI; + } + + /* + * IA32_PERF_GLOBAL_INUSE.PMI_InUse[bit 63]: This bit is set if + * any IA32_PEBS_ENABLES bit is set, which enables PEBS for a GP or + * fixed counter. + */ + if (pmu->pebs_enable) + data |= MSR_CORE_PERF_GLOBAL_INUSE_PMI; + + return data; +} + static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) { struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); @@ -360,6 +413,9 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_CORE_PERF_GLOBAL_STATUS_SET: msr_info->data = 0; break; + case MSR_CORE_PERF_GLOBAL_INUSE: + msr_info->data = intel_pmu_global_inuse_emulation(pmu); + break; case MSR_IA32_PEBS_ENABLE: msr_info->data = pmu->pebs_enable; break; @@ -409,6 +465,8 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) if (pmu->fixed_ctr_ctrl != data) reprogram_fixed_counters(pmu, data); break; + case MSR_CORE_PERF_GLOBAL_INUSE: + return 1; /* RO MSR */ case MSR_IA32_PEBS_ENABLE: if (data & pmu->pebs_enable_mask) return 1; From patchwork Fri Sep 1 07:28:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Xiong Y" X-Patchwork-Id: 13372142 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2C488CA0FE6 for ; Fri, 1 Sep 2023 07:29:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348495AbjIAH3r (ORCPT ); Fri, 1 Sep 2023 03:29:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40792 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240592AbjIAH3q (ORCPT ); Fri, 1 Sep 2023 03:29:46 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0022910F2 for ; Fri, 1 Sep 2023 00:29:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1693553372; x=1725089372; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=b0+sx3iOFFdvgVqFfT3IKEJQOAHLBAvTFXOuu4XWNXc=; b=C/VaJpdL+qpp7xG53JpC+EvH2dY8SUvRAYf2E/cFz8ifFKV5TXjrHnft 811+tNg3B+1Bdp+jrH35LR71/p0krF4g3b9oK8LZ4hf/nPEUp+UJzlKIA Ij9sLncd8OgY7YufUeMJT913HFSN/M7zfweeu2HdMHpaxcI/Jq16Ih/KK 7NERCWwlb0gqeje9DxYfbTUxIImkrGiJ9TLG1GU9zeYf5H/pg+cOCdhA5 gtwrRUap/SsacXVdgf3my16534xufIu5mbsJUlFiolli9OB6IKqfKPY4Y mXKWCY553S6pnRXC8/yLr0J/Tsq4SctEGvFo7t+GdAgZJ3+W6Fy4bpJvO A==; X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="373550332" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="373550332" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:32 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="716671306" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="716671306" Received: from wangdere-mobl2.ccr.corp.intel.com (HELO xiongzha-desk1.ccr.corp.intel.com) ([10.255.29.239]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:29 -0700 From: Xiong Zhang To: kvm@vger.kernel.org Cc: seanjc@google.com, like.xu.linux@gmail.com, zhiyuan.lv@intel.com, zhenyu.z.wang@intel.com, kan.liang@intel.com, dapeng1.mi@linux.intel.com, Xiong Zhang Subject: [PATCH 5/9] KVM: x86/pmu: Check CPUID.0AH.ECX consistency Date: Fri, 1 Sep 2023 15:28:05 +0800 Message-Id: <20230901072809.640175-6-xiong.y.zhang@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230901072809.640175-1-xiong.y.zhang@intel.com> References: <20230901072809.640175-1-xiong.y.zhang@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org With Arch PMU V5, register CPUID.0AH.ECX indicates Fixed Counter enumeration. It is a bit mask which enumerates the supported Fixed counters. FxCtrl[i]_is_supported := ECX[i] || (EDX[4:0] > i) where EDX[4:0] is Number of continuous fixed-function performance counters starting from 0 (if version ID > 1). Here ECX and EDX[4:0] should satisfy the following consistency: 1. if 1 < pmu_version < 5, ECX == 0; 2. if pmu_version == 5 && edx[4:0] == 0, ECX[bit 0] == 0 3. if pmu_version == 5 && edx[4:0] > 0, ecx & ((1 << edx[4:0]) - 1) == (1 << edx[4:0]) -1 Otherwise it is mess to decide whether a fixed counter is supported or not. i.e. pmu_version = 5, edx[4:0] = 3, ecx = 0x10, it is hard to decide whether fixed counters 0 ~ 2 are supported or not. User can call SET_CPUID2 ioctl to set guest CPUID.0AH, this commit adds a check to guarantee ecx and edx consistency specified by user. Once user specifies an un-consistency value, KVM can return an error to user and drop user setting, or correct the un-consistency data and accept the corrected data, this commit chooses to return an error to user. Signed-off-by: Xiong Zhang --- arch/x86/kvm/cpuid.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index e961e9a05847..95dc5e8847e0 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -150,6 +150,33 @@ static int kvm_check_cpuid(struct kvm_vcpu *vcpu, return -EINVAL; } + best = cpuid_entry2_find(entries, nent, 0xa, + KVM_CPUID_INDEX_NOT_SIGNIFICANT); + if (best && vcpu->kvm->arch.enable_pmu) { + union cpuid10_eax eax; + union cpuid10_edx edx; + + eax.full = best->eax; + edx.full = best->edx; + + if (eax.split.version_id > 1 && + eax.split.version_id < 5 && + best->ecx != 0) { + return -EINVAL; + } else if (eax.split.version_id >= 5) { + int fixed_count = edx.split.num_counters_fixed; + + if (fixed_count == 0 && (best->ecx & 0x1)) { + return -EINVAL; + } else if (fixed_count > 0) { + int low_fixed_mask = (1 << fixed_count) - 1; + + if ((best->ecx & low_fixed_mask) != low_fixed_mask) + return -EINVAL; + } + } + } + /* * Exposing dynamic xfeatures to the guest requires additional * enabling in the FPU, e.g. to expand the guest XSAVE state size. From patchwork Fri Sep 1 07:28:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Xiong Y" X-Patchwork-Id: 13372143 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 388BDCA0FE6 for ; Fri, 1 Sep 2023 07:29:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348497AbjIAH34 (ORCPT ); Fri, 1 Sep 2023 03:29:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47890 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240592AbjIAH3z (ORCPT ); Fri, 1 Sep 2023 03:29:55 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B7C1A1711 for ; Fri, 1 Sep 2023 00:29:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1693553377; x=1725089377; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zqKRMWergCOeIYJ0KZKuPMl8biseQ+9UVZ0L2iovay4=; b=F4pjnGHM1a6S0n4itXMmGIrW4Y1Lg+reztIgKvnz+zfk9Bt4iNNT4aQE 2S+fAF5I9KC7F7ayQuo8G5cy4aqk4Rqi1lHGhrgfDhr5e1Vns02UXcGXV jpGXYQbVvHmRu8HEkBzqLauPD8fr5JFvct2UUnumjFCS1SOhDRbgZ0Ktl p/g3NhNy3Nkpwc17sqXyE+qQ3CFMwVrGvpnnjvKTUPZTBsJKIurV+yVz2 TB99XFN5Qb6aQcIJ5iphHeTWHrP1+0bta/4wHF0SXvUm3dQNxCoTe6UW5 Zlna1M+YKQQR1SUahzlGI3r0zSXKQJHlMA+krnFcciB0qSL+Ko31tlP1K w==; X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="373550350" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="373550350" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="716671325" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="716671325" Received: from wangdere-mobl2.ccr.corp.intel.com (HELO xiongzha-desk1.ccr.corp.intel.com) ([10.255.29.239]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:34 -0700 From: Xiong Zhang To: kvm@vger.kernel.org Cc: seanjc@google.com, like.xu.linux@gmail.com, zhiyuan.lv@intel.com, zhenyu.z.wang@intel.com, kan.liang@intel.com, dapeng1.mi@linux.intel.com, Like Xu , Xiong Zhang Subject: [PATCH 6/9] KVM: x86/pmu: Add Intel PMU supported fixed counters mask Date: Fri, 1 Sep 2023 15:28:06 +0800 Message-Id: <20230901072809.640175-7-xiong.y.zhang@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230901072809.640175-1-xiong.y.zhang@intel.com> References: <20230901072809.640175-1-xiong.y.zhang@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Like Xu Per Intel SDM, fixed-function performance counter 'i' is supported: FxCtr[i]_is_supported := ECX[i] || (EDX[4:0] > i); if pmu.version >=5, ECX is supported fixed counters bit mask. if 1 < pmu.version < 5, EDX[4:0] is number of contiguous fixed-function performance counters starting from 0. which means that the KVM user space can use EDX to limit the number of fixed counters starting from 0 and at the same time, using ECX to enable part of other KVM supported fixed counters. i.e: pmu.version = 5, ECX= 0x5, EDX[4:0]=1, FxCtrl[2, 0] are supported, FxCtrl[1] isn't supported. Add Fixed counter bit mask into all_valid_pmc_idx, and use it to perform the semantic checks. Since fixed counter may be non-continuous, nr_arch_fixed_counters can not be used to enumerate fixed counters, for_each_set_bit_from() is used to enumerate fixed counters, and nr_arch_fixed_counters is deleted. Signed-off-by: Like Xu Signed-off-by: Xiong Zhang Reviewed-by: Dapeng Mi --- arch/x86/include/asm/kvm_host.h | 1 - arch/x86/kvm/pmu.h | 12 +++++- arch/x86/kvm/svm/pmu.c | 1 - arch/x86/kvm/vmx/pmu_intel.c | 69 ++++++++++++++++++++------------- 4 files changed, 52 insertions(+), 31 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 9f57aa33798b..ceba4f89dec5 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -515,7 +515,6 @@ struct kvm_pmc { struct kvm_pmu { u8 version; unsigned nr_arch_gp_counters; - unsigned nr_arch_fixed_counters; unsigned available_event_types; u64 fixed_ctr_ctrl; u64 fixed_ctr_ctrl_mask; diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h index 7d9ba301c090..4bab4819ea6c 100644 --- a/arch/x86/kvm/pmu.h +++ b/arch/x86/kvm/pmu.h @@ -125,14 +125,22 @@ static inline struct kvm_pmc *get_gp_pmc(struct kvm_pmu *pmu, u32 msr, return NULL; } +static inline bool fixed_ctr_is_supported(struct kvm_pmu *pmu, unsigned int idx) +{ + return test_bit(INTEL_PMC_IDX_FIXED + idx, pmu->all_valid_pmc_idx); +} + /* returns fixed PMC with the specified MSR */ static inline struct kvm_pmc *get_fixed_pmc(struct kvm_pmu *pmu, u32 msr) { int base = MSR_CORE_PERF_FIXED_CTR0; - if (msr >= base && msr < base + pmu->nr_arch_fixed_counters) { + if (msr >= base && msr < base + KVM_PMC_MAX_FIXED) { u32 index = array_index_nospec(msr - base, - pmu->nr_arch_fixed_counters); + KVM_PMC_MAX_FIXED); + + if (!fixed_ctr_is_supported(pmu, index)) + return NULL; return &pmu->fixed_counters[index]; } diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c index cef5a3d0abd0..d0a12e739989 100644 --- a/arch/x86/kvm/svm/pmu.c +++ b/arch/x86/kvm/svm/pmu.c @@ -213,7 +213,6 @@ static void amd_pmu_refresh(struct kvm_vcpu *vcpu) pmu->raw_event_mask = AMD64_RAW_EVENT_MASK; /* not applicable to AMD; but clean them to prevent any fall out */ pmu->counter_bitmask[KVM_PMC_FIXED] = 0; - pmu->nr_arch_fixed_counters = 0; bitmap_set(pmu->all_valid_pmc_idx, 0, pmu->nr_arch_gp_counters); } diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index 46363ac82a79..ce6d06ec562c 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -72,10 +72,12 @@ static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 data) { struct kvm_pmc *pmc; u8 old_fixed_ctr_ctrl = pmu->fixed_ctr_ctrl; - int i; + int s = INTEL_PMC_IDX_FIXED; pmu->fixed_ctr_ctrl = data; - for (i = 0; i < pmu->nr_arch_fixed_counters; i++) { + for_each_set_bit_from(s, pmu->all_valid_pmc_idx, + INTEL_PMC_IDX_FIXED + INTEL_PMC_MAX_FIXED) { + int i = s - INTEL_PMC_IDX_FIXED; u8 new_ctrl = fixed_ctrl_field(data, i); u8 old_ctrl = fixed_ctrl_field(old_fixed_ctr_ctrl, i); @@ -132,7 +134,7 @@ static bool intel_is_valid_rdpmc_ecx(struct kvm_vcpu *vcpu, unsigned int idx) idx &= ~(3u << 30); - return fixed ? idx < pmu->nr_arch_fixed_counters + return fixed ? fixed_ctr_is_supported(pmu, idx) : idx < pmu->nr_arch_gp_counters; } @@ -144,16 +146,17 @@ static struct kvm_pmc *intel_rdpmc_ecx_to_pmc(struct kvm_vcpu *vcpu, struct kvm_pmc *counters; unsigned int num_counters; + if (!intel_is_valid_rdpmc_ecx(vcpu, idx)) + return NULL; + idx &= ~(3u << 30); if (fixed) { counters = pmu->fixed_counters; - num_counters = pmu->nr_arch_fixed_counters; + num_counters = KVM_PMC_MAX_FIXED; } else { counters = pmu->gp_counters; num_counters = pmu->nr_arch_gp_counters; } - if (idx >= num_counters) - return NULL; *mask &= pmu->counter_bitmask[fixed ? KVM_PMC_FIXED : KVM_PMC_GP]; return &counters[array_index_nospec(idx, num_counters)]; } @@ -352,6 +355,7 @@ static u64 intel_pmu_global_inuse_emulation(struct kvm_pmu *pmu) { u64 data = 0; int i; + int s = INTEL_PMC_IDX_FIXED; for (i = 0; i < pmu->nr_arch_gp_counters; i++) { struct kvm_pmc *pmc = &pmu->gp_counters[i]; @@ -371,7 +375,10 @@ static u64 intel_pmu_global_inuse_emulation(struct kvm_pmu *pmu) data |= MSR_CORE_PERF_GLOBAL_INUSE_PMI; } - for (i = 0; i < pmu->nr_arch_fixed_counters; i++) { + for_each_set_bit_from(s, pmu->all_valid_pmc_idx, + INTEL_PMC_IDX_FIXED + INTEL_PMC_MAX_FIXED) { + i = s - INTEL_PMC_IDX_FIXED; + /* * IA32_PERF_GLOBAL_INUSE.FCi_InUse[bit (i + 32)]: This bit * reflects the logical state of @@ -379,7 +386,7 @@ static u64 intel_pmu_global_inuse_emulation(struct kvm_pmu *pmu) */ if (pmu->fixed_ctr_ctrl & intel_fixed_bits_by_idx(i, INTEL_FIXED_0_KERNEL | INTEL_FIXED_0_USER)) - data |= 1ULL << (i + INTEL_PMC_IDX_FIXED); + data |= 1ULL << s; /* * IA32_PERF_GLOBAL_INUSE.PMI_InUse[bit 63]: This bit is set if * IA32_FIXED_CTR_CTRL.ENi_PMI, i = 0, 1, 2 is set. @@ -565,12 +572,14 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) static void setup_fixed_pmc_eventsel(struct kvm_pmu *pmu) { - int i; + int s = INTEL_PMC_IDX_FIXED; BUILD_BUG_ON(ARRAY_SIZE(fixed_pmc_events) != KVM_PMC_MAX_FIXED); - for (i = 0; i < pmu->nr_arch_fixed_counters; i++) { - int index = array_index_nospec(i, KVM_PMC_MAX_FIXED); + for_each_set_bit_from(s, pmu->all_valid_pmc_idx, + INTEL_PMC_IDX_FIXED + INTEL_PMC_MAX_FIXED) { + int index = array_index_nospec(s - INTEL_PMC_IDX_FIXED, + KVM_PMC_MAX_FIXED); struct kvm_pmc *pmc = &pmu->fixed_counters[index]; u32 event = fixed_pmc_events[index]; @@ -591,7 +600,6 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) int i; pmu->nr_arch_gp_counters = 0; - pmu->nr_arch_fixed_counters = 0; pmu->counter_bitmask[KVM_PMC_GP] = 0; pmu->counter_bitmask[KVM_PMC_FIXED] = 0; pmu->version = 0; @@ -633,11 +641,22 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) pmu->available_event_types = ~entry->ebx & ((1ull << eax.split.mask_length) - 1); - if (pmu->version == 1) { - pmu->nr_arch_fixed_counters = 0; - } else { - pmu->nr_arch_fixed_counters = min_t(int, edx.split.num_counters_fixed, - kvm_pmu_cap.num_counters_fixed); + counter_mask = ~(BIT_ULL(pmu->nr_arch_gp_counters) - 1); + bitmap_set(pmu->all_valid_pmc_idx, 0, pmu->nr_arch_gp_counters); + + if (pmu->version > 1) { + for (i = 0; i < kvm_pmu_cap.num_counters_fixed; i++) { + /* + * FxCtr[i]_is_supported := + * CPUID.0xA.ECX[i] || EDX[4:0] > i + */ + if (!(entry->ecx & BIT_ULL(i) || edx.split.num_counters_fixed > i)) + continue; + + set_bit(INTEL_PMC_IDX_FIXED + i, pmu->all_valid_pmc_idx); + pmu->fixed_ctr_ctrl_mask &= ~(0xbull << (i * 4)); + counter_mask &= ~BIT_ULL(INTEL_PMC_IDX_FIXED + i); + } edx.split.bit_width_fixed = min_t(int, edx.split.bit_width_fixed, kvm_pmu_cap.bit_width_fixed); pmu->counter_bitmask[KVM_PMC_FIXED] = @@ -645,10 +664,6 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) setup_fixed_pmc_eventsel(pmu); } - for (i = 0; i < pmu->nr_arch_fixed_counters; i++) - pmu->fixed_ctr_ctrl_mask &= ~(0xbull << (i * 4)); - counter_mask = ~(((1ull << pmu->nr_arch_gp_counters) - 1) | - (((1ull << pmu->nr_arch_fixed_counters) - 1) << INTEL_PMC_IDX_FIXED)); pmu->global_ctrl_mask = counter_mask; /* @@ -674,11 +689,6 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) pmu->raw_event_mask |= (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED); } - bitmap_set(pmu->all_valid_pmc_idx, - 0, pmu->nr_arch_gp_counters); - 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)) @@ -691,9 +701,14 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) if (perf_capabilities & PERF_CAP_PEBS_FORMAT) { if (perf_capabilities & PERF_CAP_PEBS_BASELINE) { + int s = INTEL_PMC_IDX_FIXED; + int e = INTEL_PMC_IDX_FIXED + INTEL_PMC_MAX_FIXED; + pmu->pebs_enable_mask = counter_mask; pmu->reserved_bits &= ~ICL_EVENTSEL_ADAPTIVE; - for (i = 0; i < pmu->nr_arch_fixed_counters; i++) { + + for_each_set_bit_from(s, pmu->all_valid_pmc_idx, e) { + i = s - INTEL_PMC_IDX_FIXED; pmu->fixed_ctr_ctrl_mask &= ~(1ULL << (INTEL_PMC_IDX_FIXED + i * 4)); } From patchwork Fri Sep 1 07:28:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Xiong Y" X-Patchwork-Id: 13372144 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A402CCA0FE1 for ; Fri, 1 Sep 2023 07:30:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348498AbjIAHaD (ORCPT ); Fri, 1 Sep 2023 03:30:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45312 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238793AbjIAHaC (ORCPT ); Fri, 1 Sep 2023 03:30:02 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 98D0F171E for ; Fri, 1 Sep 2023 00:29:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1693553381; x=1725089381; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cRvvaoqt29ES3Mx7bTKA8fiZt2RGm+2unAl9XvbkbdE=; b=A0COPPA764zwm0y/PH8c8NCr+n+p5s9z/8BkJaiDAGqNeZkE1XPqc9DL G0t15wGYPG2A/v6ziu1CYjHqdN5dkmByC1g0Eyzvg7fLlMqIDofNpzoKf lN6mBETHZKakepuu/y+icNQg535eiRy62LPtqqngFjpQrGD642psV8SNP Xlr9h/3JyjkQUWL1ei3WKkAmPidDDtXHaC3ekG1uC4dunFHB6+6DrcXEa 2ilI1a3BzsekDq67whY/N1zfC1/q/ha0cFkVTTqkhts0AUAlcwhdp4QnP 5QODzXDtbbESP8jrtnv11fCEJe2QiD3vLsvhRZkcDkVXOxikVevH/hXgW A==; X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="373550359" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="373550359" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="716671339" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="716671339" Received: from wangdere-mobl2.ccr.corp.intel.com (HELO xiongzha-desk1.ccr.corp.intel.com) ([10.255.29.239]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:38 -0700 From: Xiong Zhang To: kvm@vger.kernel.org Cc: seanjc@google.com, like.xu.linux@gmail.com, zhiyuan.lv@intel.com, zhenyu.z.wang@intel.com, kan.liang@intel.com, dapeng1.mi@linux.intel.com, Xiong Zhang Subject: [PATCH 7/9] KVM: x86/pmu: Add fixed counter enumeration for pmu v5 Date: Fri, 1 Sep 2023 15:28:07 +0800 Message-Id: <20230901072809.640175-8-xiong.y.zhang@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230901072809.640175-1-xiong.y.zhang@intel.com> References: <20230901072809.640175-1-xiong.y.zhang@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org With Arch PMU v5, CPUID.0AH.ECX is a bit mask which enumerates the supported Fixed Counters. If bit 'i' is set, it implies that Fixed Counter 'i' is supported. This commit adds CPUID.0AH.ECX emulation for vPMU version 5, KVM supports Fixed Counter enumeration starting from 0 by default, user can modify it through SET_CPUID2 ioctl. Signed-off-by: Xiong Zhang --- arch/x86/kvm/cpuid.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 95dc5e8847e0..2bffed010c9e 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -1028,7 +1028,10 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) entry->eax = eax.full; entry->ebx = kvm_pmu_cap.events_mask; - entry->ecx = 0; + if (kvm_pmu_cap.version < 5) + entry->ecx = 0; + else + entry->ecx = (1ULL << kvm_pmu_cap.num_counters_fixed) - 1; entry->edx = edx.full; break; } From patchwork Fri Sep 1 07:28:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Xiong Y" X-Patchwork-Id: 13372145 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 07258CA0FE6 for ; Fri, 1 Sep 2023 07:30:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238793AbjIAHaM (ORCPT ); Fri, 1 Sep 2023 03:30:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45446 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348500AbjIAHaK (ORCPT ); Fri, 1 Sep 2023 03:30:10 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9DCAC1724 for ; Fri, 1 Sep 2023 00:29:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1693553385; x=1725089385; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=YPa75IoSHXcqVnGyb8+Uwwta16Yye+wwmIWExyWjphA=; b=KqDildXGMMtqD7pr1dde4l7zUhc2lxtI7t6CCSpuxBSxMDvgIXzTVNSX ls5QnpXJqyTuo/8Ly8lxdUDv+Fbb16Xj86Ek+EfLCsAMAqiN/HkxGSl+L jkYVuBOrpVbVyebGIOy7UAWiRZ/bhtCvvCJ/RDtuyP6VxyZdISCU5hIDH Ii9/pIbpqqAjOasVY+uDDhRXSmj7+zzZC5PvqOAStEImKbPcrnaoAiocm U8hf9vvkb8WuHHbgjV+rLAAKih3DorE6zq5ZPji8DjQniQzpHO54qCRR3 Uxt8Uq3Myg94kdVkXF5xVaF8qgdwKI6ev3P9AiWrJx9nmFagHNbIcyr94 A==; X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="373550369" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="373550369" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:45 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="716671365" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="716671365" Received: from wangdere-mobl2.ccr.corp.intel.com (HELO xiongzha-desk1.ccr.corp.intel.com) ([10.255.29.239]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:42 -0700 From: Xiong Zhang To: kvm@vger.kernel.org Cc: seanjc@google.com, like.xu.linux@gmail.com, zhiyuan.lv@intel.com, zhenyu.z.wang@intel.com, kan.liang@intel.com, dapeng1.mi@linux.intel.com, Xiong Zhang Subject: [PATCH 8/9] KVM: x86/pmu: Upgrade pmu version to 5 on intel processor Date: Fri, 1 Sep 2023 15:28:08 +0800 Message-Id: <20230901072809.640175-9-xiong.y.zhang@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230901072809.640175-1-xiong.y.zhang@intel.com> References: <20230901072809.640175-1-xiong.y.zhang@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Modern intel processors have supported Architectural Performance Monitoring Version 5, this commit upgrade Intel vcpu's vPMU version from 2 to 5. Go through PMU features from version 3 to 5, the following features are not supported: 1. AnyThread counting: it is added in v3, and deprecated in v5. 2. Streamed Freeze_PerfMon_On_PMI in v4, since legacy Freeze_PerMon_ON_PMI isn't supported, the new one won't be supported neither. 3. IA32_PERF_GLOBAL_STATUS.ASCI[bit 60]: Related to SGX, and will be emulated by SGX developer later. 4. Domain Separation in v5. When INV flag in IA32_PERFEVTSELx is used, a counter stops counting when logical processor exits the C0 ACPI C-state. First guest INV flag isn't supported, second guest ACPI C-state is vague. When a guest enable unsupported features through WRMSR, KVM will inject a #GP into the guest. Signed-off-by: Xiong Zhang --- arch/x86/kvm/pmu.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h index 4bab4819ea6c..8e6bc9b1a747 100644 --- a/arch/x86/kvm/pmu.h +++ b/arch/x86/kvm/pmu.h @@ -215,7 +215,10 @@ static inline void kvm_init_pmu_capability(const struct kvm_pmu_ops *pmu_ops) return; } - kvm_pmu_cap.version = min(kvm_pmu_cap.version, 2); + if (is_intel) + kvm_pmu_cap.version = min(kvm_pmu_cap.version, 5); + else + kvm_pmu_cap.version = min(kvm_pmu_cap.version, 2); kvm_pmu_cap.num_counters_gp = min(kvm_pmu_cap.num_counters_gp, pmu_ops->MAX_NR_GP_COUNTERS); kvm_pmu_cap.num_counters_fixed = min(kvm_pmu_cap.num_counters_fixed, From patchwork Fri Sep 1 07:28:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Xiong Y" X-Patchwork-Id: 13372146 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7E5EACA0FE6 for ; Fri, 1 Sep 2023 07:30:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348505AbjIAHaU (ORCPT ); Fri, 1 Sep 2023 03:30:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39204 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348499AbjIAHaU (ORCPT ); Fri, 1 Sep 2023 03:30:20 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BFA1E10D4 for ; Fri, 1 Sep 2023 00:29:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1693553394; x=1725089394; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ZlJm63XsJYbPCtU6pjKTIlK5jdBIk4qSUq5NaaZ/EzQ=; b=AeVnL9IJBd9NyUJcQ2e15s7gxDaCYqNmBX9tX/ErEPGEltY8o+/i0dqA +xXndFgQKdt/hqz+WuhRvf7MzrIclaLLG0p4UbIzQBnbTkKx3DRvnOWHG bYo3A5GpWzCbnj0XE+knGkzyXFZMLbSmzADyhpRLqqeFOWnyXrEDJ8oYw gEo190E5ZOl96XRXg8rFhxb3tnuuWTOXp1QWT5IXHJBa8lHIi1Ea6OLpL RiC7SGJFl389hZ9eWcht/78L1QFWgIT3HKR1oQhldrkJgHgpkQKyJgnpx ii6VxMSp2Xp5n5rLk8IIvxAEEm9shjTDTSauFzFkqli87zEYNe1XuUwm5 A==; X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="373550376" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="373550376" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10819"; a="716671394" X-IronPort-AV: E=Sophos;i="6.02,219,1688454000"; d="scan'208";a="716671394" Received: from wangdere-mobl2.ccr.corp.intel.com (HELO xiongzha-desk1.ccr.corp.intel.com) ([10.255.29.239]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Sep 2023 00:29:46 -0700 From: Xiong Zhang To: kvm@vger.kernel.org Cc: seanjc@google.com, like.xu.linux@gmail.com, zhiyuan.lv@intel.com, zhenyu.z.wang@intel.com, kan.liang@intel.com, dapeng1.mi@linux.intel.com, Xiong Zhang Subject: [PATCH 9/9] KVM: selftests: Add fixed counters enumeration test case Date: Fri, 1 Sep 2023 15:28:09 +0800 Message-Id: <20230901072809.640175-10-xiong.y.zhang@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230901072809.640175-1-xiong.y.zhang@intel.com> References: <20230901072809.640175-1-xiong.y.zhang@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org vPMU v5 adds fixed counter enumeration, which allows user space to specify which fixed counters are supported through emulated CPUID.0Ah.ECX. This commit adds a test case which specify the max fixed counter supported only, so guest can access the max fixed counter only, #GP exception will be happen once guest access other fixed counters. Signed-off-by: Xiong Zhang --- .../selftests/kvm/x86_64/vmx_pmu_caps_test.c | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c b/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c index ebbcb0a3f743..e37dc39164fe 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c @@ -18,6 +18,8 @@ #include "kvm_util.h" #include "vmx.h" +uint8_t fixed_counter_num; + union perf_capabilities { struct { u64 lbr_format:6; @@ -233,6 +235,86 @@ static void test_lbr_perf_capabilities(union perf_capabilities host_cap) kvm_vm_free(vm); } +static void guest_v5_code(void) +{ + uint8_t vector, i; + uint64_t val; + + for (i = 0; i < fixed_counter_num; i++) { + vector = rdmsr_safe(MSR_CORE_PERF_FIXED_CTR0 + i, &val); + + /* + * Only the max fixed counter is supported, #GP will be generated + * when guest access other fixed counters. + */ + if (i == fixed_counter_num - 1) + __GUEST_ASSERT(vector != GP_VECTOR, + "Max Fixed counter is accessible, but get #GP"); + else + __GUEST_ASSERT(vector == GP_VECTOR, + "Fixed counter isn't accessible, but access is ok"); + } + + GUEST_DONE(); +} + +#define PMU_NR_FIXED_COUNTERS_MASK 0x1f + +static void test_fixed_counter_enumeration(void) +{ + struct kvm_vcpu *vcpu; + struct kvm_vm *vm; + int r; + struct kvm_cpuid_entry2 *ent; + struct ucall uc; + uint32_t fixed_counter_bit_mask; + + if (kvm_cpu_property(X86_PROPERTY_PMU_VERSION) != 5) + return; + + vm = vm_create_with_one_vcpu(&vcpu, guest_v5_code); + vm_init_descriptor_tables(vm); + vcpu_init_descriptor_tables(vcpu); + + ent = vcpu_get_cpuid_entry(vcpu, 0xa); + fixed_counter_num = ent->edx & PMU_NR_FIXED_COUNTERS_MASK; + TEST_ASSERT(fixed_counter_num > 0, "fixed counter isn't supported"); + fixed_counter_bit_mask = (1ul << fixed_counter_num) - 1; + TEST_ASSERT(ent->ecx == fixed_counter_bit_mask, + "cpuid.0xa.ecx != %x", fixed_counter_bit_mask); + + /* Fixed counter 0 isn't in ecx, but in edx, set_cpuid should be error. */ + ent->ecx &= ~0x1; + r = __vcpu_set_cpuid(vcpu); + TEST_ASSERT(r, "Setting in-consistency cpuid.0xa.ecx and edx success"); + + if (fixed_counter_num == 1) { + kvm_vm_free(vm); + return; + } + + /* Support the max Fixed Counter only */ + ent->ecx = 1UL << (fixed_counter_num - 1); + ent->edx &= ~(u32)PMU_NR_FIXED_COUNTERS_MASK; + + r = __vcpu_set_cpuid(vcpu); + TEST_ASSERT(!r, "Setting modified cpuid.0xa.ecx and edx failed"); + + vcpu_run(vcpu); + + switch (get_ucall(vcpu, &uc)) { + case UCALL_ABORT: + REPORT_GUEST_ASSERT(uc); + break; + case UCALL_DONE: + break; + default: + TEST_FAIL("Unexpected ucall: %lu", uc.cmd); + } + + kvm_vm_free(vm); +} + int main(int argc, char *argv[]) { union perf_capabilities host_cap; @@ -253,4 +335,6 @@ int main(int argc, char *argv[]) test_immutable_perf_capabilities(host_cap); test_guest_wrmsr_perf_capabilities(host_cap); test_lbr_perf_capabilities(host_cap); + + test_fixed_counter_enumeration(); }