From patchwork Mon Oct 9 23:08:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 13414654 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6FC8AE94137 for ; Mon, 9 Oct 2023 23:09:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:Message-ID: References:Mime-Version:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=CB05frRVec8pFiwNFw4823QVofjfxaYaPX5oMJ+qM1Q=; b=baziQ8/srUzK80L3k9fAb0YyEz kf6nR5sYgxvdseJW2EPBvrMrwl2GRiire5J1pO1F/X7Hy9w+Ln+qtjT0TRyg7f6Db3npqBUW2aoT8 50jf0wGe/yVw0aTvbS7kEKnvxHxKOqswIk2h9G1Th2mhqXlWJi2QncVNqD8WndZlZktnvvCR6b2Hd IMcMNB3fkHa43KpNTys1DGCBe3x1UJGyzvPeZtdU+cBbWcap4FtzuvH+MdNNRvWV0fsQaeqXE84nX OuxKn7upYTaNjnZXI6MeX5YeImqnzznVrJHqpeABZ7XrAjAVGHfEgrdCxPNPilh9HqmqAWr6LJGC4 TU4SDtyg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qpzNQ-00Bmtz-0d; Mon, 09 Oct 2023 23:09:28 +0000 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qpzNA-00BmlH-0e for linux-arm-kernel@lists.infradead.org; Mon, 09 Oct 2023 23:09:13 +0000 Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-d9a4fb3e096so389961276.1 for ; Mon, 09 Oct 2023 16:09:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1696892951; x=1697497751; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=fdARUUKusxUQMjGBXV+ANnlmYThkUVs6hxgDwUx3ZvE=; b=C/vwDMUwKLVMN41vtkO4zeFrcsfPXp8yAE5Vb/ZlDNR37QKWaaSmY8L4awORvl9Ile TEZ7popVe6zgBf/VVlArJxJFXUQ2zd6nr4GJLAgiaC+H5lzqssaTLo4iUZe9DarQrfeb 3utK5R2NaVSYnPBkj+QaOgX5ZdohiNZK3OPon37YClVTb8ya3EkbUrtFRSVowOBgN+vh d2PNzWUQEghzOokGOBSHCo+lUqjzxY3gdAHjkRpN0kSUDb5vR0E5AQh9m3eVHRLUVow6 XQEgg7V37otCTIBr3aql7aPIZF2KF7eSI8TSYQ2rAuvhKnGj29WIh+Q/G+zudNZ8viTF JxcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696892951; x=1697497751; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=fdARUUKusxUQMjGBXV+ANnlmYThkUVs6hxgDwUx3ZvE=; b=A28YR5Z6C7xsvkv0rx/Xz6Q8lW14NsdEUhfrkZIaEb1EC1rmdtVfDzCyi+VNK3GNUs O5TmgALVpVMWwEMWYYTzkz78e1li2txWDdfVet6dgGjJCGUnH/lq2kBgAyiXfJyDqTwT br/jOsTwI6lwIIqWLTTeX0b+v1CvA9OTITIPnM3G+fs9iqCxRduN9GP3cc/FDqmwSpCf glW1CBkFJ1wKdiLKLH7bDuA35caSiaSCDrguzhOOf2+h+WIdxu75cDE26UFL0nBJgprr XHBzz+0BIjEd8w+CdvlcdGv29yB0fdCQVLC7qa9Y6m+85VJfKdp3x0HWlu3YJ0chyeEj Q1JQ== X-Gm-Message-State: AOJu0Yx7WeTLi7gjbQSLFUNhKDARpYv0ZbPYSQcMqQJ1+G7tItjYJExx cp4nOynjg+uYPZr9ajCUsIBr32FXQ5ZP X-Google-Smtp-Source: AGHT+IFPG5m5pY2ciF7RtIv45EznHHERUOKqerEgN7jSlF+TN5zmlITE81O6tL7BoA7o1uHqO3aJ59+EsvnC X-Received: from rananta-linux.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:20a1]) (user=rananta job=sendgmr) by 2002:a05:6902:180e:b0:d77:984e:c770 with SMTP id cf14-20020a056902180e00b00d77984ec770mr291052ybb.5.1696892951029; Mon, 09 Oct 2023 16:09:11 -0700 (PDT) Date: Mon, 9 Oct 2023 23:08:53 +0000 In-Reply-To: <20231009230858.3444834-1-rananta@google.com> Mime-Version: 1.0 References: <20231009230858.3444834-1-rananta@google.com> X-Mailer: git-send-email 2.42.0.609.gbb76f46606-goog Message-ID: <20231009230858.3444834-8-rananta@google.com> Subject: [PATCH v7 07/12] KVM: arm64: PMU: Set PMCR_EL0.N for vCPU based on the associated PMU From: Raghavendra Rao Ananta To: Oliver Upton , Marc Zyngier Cc: Alexandru Elisei , James Morse , Suzuki K Poulose , Paolo Bonzini , Zenghui Yu , Shaoqin Huang , Jing Zhang , Reiji Watanabe , Colton Lewis , Raghavendra Rao Anata , linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, kvm@vger.kernel.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20231009_160912_240014_4F4189D9 X-CRM114-Status: GOOD ( 20.48 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Reiji Watanabe The number of PMU event counters is indicated in PMCR_EL0.N. For a vCPU with PMUv3 configured, the value is set to the same value as the current PE on every vCPU reset. Unless the vCPU is pinned to PEs that has the PMU associated to the guest from the initial vCPU reset, the value might be different from the PMU's PMCR_EL0.N on heterogeneous PMU systems. Fix this by setting the vCPU's PMCR_EL0.N to the PMU's PMCR_EL0.N value. Track the PMCR_EL0.N per guest, as only one PMU can be set for the guest (PMCR_EL0.N must be the same for all vCPUs of the guest), and it is convenient for updating the value. KVM does not yet support userspace modifying PMCR_EL0.N. The following patch will add support for that. Signed-off-by: Reiji Watanabe Signed-off-by: Raghavendra Rao Ananta --- arch/arm64/include/asm/kvm_host.h | 3 +++ arch/arm64/kvm/pmu-emul.c | 14 +++++++++++++- arch/arm64/kvm/sys_regs.c | 15 +++++++++------ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index f7e5132c0a23..a7f326a85077 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -283,6 +283,9 @@ struct kvm_arch { cpumask_var_t supported_cpus; + /* PMCR_EL0.N value for the guest */ + u8 pmcr_n; + /* Hypercall features firmware registers' descriptor */ struct kvm_smccc_features smccc_feat; struct maple_tree smccc_filter; diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index 84aa8efd9163..4daa9f6b170a 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -690,6 +690,9 @@ void kvm_host_pmu_init(struct arm_pmu *pmu) if (!entry) goto out_unlock; + WARN_ON((pmu->num_events <= 0) || + (pmu->num_events > ARMV8_PMU_MAX_COUNTERS)); + entry->arm_pmu = pmu; list_add_tail(&entry->entry, &arm_pmus); @@ -895,6 +898,7 @@ static void kvm_arm_set_pmu(struct kvm *kvm, struct arm_pmu *arm_pmu) lockdep_assert_held(&kvm->arch.config_lock); kvm->arch.arm_pmu = arm_pmu; + kvm->arch.pmcr_n = kvm_arm_get_num_counters(kvm); } /** @@ -1105,8 +1109,16 @@ u8 kvm_arm_pmu_get_pmuver_limit(void) /** * kvm_vcpu_read_pmcr - Read PMCR_EL0 register for the vCPU * @vcpu: The vcpu pointer + * + * The function returns the value of PMCR.N based on the per-VM tracked + * value (kvm->arch.pmcr_n). This is to ensure that the register field + * remains consistent for the VM, even on heterogeneous systems where + * the value may vary when read from different CPUs (during vCPU reset). */ u64 kvm_vcpu_read_pmcr(struct kvm_vcpu *vcpu) { - return __vcpu_sys_reg(vcpu, PMCR_EL0); + u64 pmcr = __vcpu_sys_reg(vcpu, PMCR_EL0) & + ~(ARMV8_PMU_PMCR_N_MASK << ARMV8_PMU_PMCR_N_SHIFT); + + return pmcr | ((u64)vcpu->kvm->arch.pmcr_n << ARMV8_PMU_PMCR_N_SHIFT); } diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index ff0f7095eaca..c750722fbe4a 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -745,12 +745,8 @@ static u64 reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { u64 pmcr; - /* No PMU available, PMCR_EL0 may UNDEF... */ - if (!kvm_arm_support_pmu_v3()) - return 0; - /* Only preserve PMCR_EL0.N, and reset the rest to 0 */ - pmcr = read_sysreg(pmcr_el0) & (ARMV8_PMU_PMCR_N_MASK << ARMV8_PMU_PMCR_N_SHIFT); + pmcr = kvm_vcpu_read_pmcr(vcpu) & (ARMV8_PMU_PMCR_N_MASK << ARMV8_PMU_PMCR_N_SHIFT); if (!kvm_supports_32bit_el0()) pmcr |= ARMV8_PMU_PMCR_LC; @@ -1084,6 +1080,13 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, return true; } +static int get_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, + u64 *val) +{ + *val = kvm_vcpu_read_pmcr(vcpu); + return 0; +} + /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */ #define DBG_BCR_BVR_WCR_WVR_EL1(n) \ { SYS_DESC(SYS_DBGBVRn_EL1(n)), \ @@ -2148,7 +2151,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_SVCR), undef_access }, { PMU_SYS_REG(PMCR_EL0), .access = access_pmcr, - .reset = reset_pmcr, .reg = PMCR_EL0 }, + .reset = reset_pmcr, .reg = PMCR_EL0, .get_user = get_pmcr }, { PMU_SYS_REG(PMCNTENSET_EL0), .access = access_pmcnten, .reg = PMCNTENSET_EL0 }, { PMU_SYS_REG(PMCNTENCLR_EL0),