From patchwork Mon Oct 9 23:08:54 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: 13414652 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 26290E81E18 for ; Mon, 9 Oct 2023 23:09:54 +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=jaBbMX2en+H8RlZRo6gZWxn/DJILYxOpXJHQpGJRrZE=; b=cAitNolUa8N8cwN3CL96x45bh1 o5SgICWC7/Cm33B9wYePbmmz087V3SIKMPm4Ud+fVOK1dJP4JKa6pbWhm+TpO6s3Qb/2cJ1JQBaQ7 fLJqsX/+CQvIYe2dqeuRhcX86Ipedhr/TnCDAkp6/ySAJzovE0DuuyqwuOxdPuNgX5Q3ZyMq0IqD0 ivhi7c0dm2+sprRSJdzy8GAME93X2sP1h2LzYBfAdMlPU0D2866GIvLcmDphva+td4+iu+m2Exgjf SP+jHwye2RyS5tkxsogKJmed4jJFOdz2UfIPazcxPQo1V7e/kvKHhHrrN0QzVAksVzf3f4OKTC/pt exb9oedQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qpzNQ-00BmuY-35; Mon, 09 Oct 2023 23:09:28 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qpzNA-00Bmle-1g for linux-arm-kernel@lists.infradead.org; Mon, 09 Oct 2023 23:09:14 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id 3f1490d57ef6-d9a581346c4so137347276.0 for ; Mon, 09 Oct 2023 16:09:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1696892952; x=1697497752; 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=WVPLom817QijAmu2ToM6KNwT4YXyplIKJbzjUf63Skc=; b=vY3ePbrB6bMrC2kRPGMineypt7Euncs7Vqfvsi2/R6pH3suHROFWGC5jViYRgoNEzd rY5zRBYlRV02Q9G0bdgVZJOUKc2y4qxaWYBcwOlUZNTUu/TUt3svX3QehzRARJMIr7WO 6Pbs0kq1xDCFcqSqNxZIb7lqKhEPKE5Nx2xxhlynMrYy7ZhJqIeHQYbWKsgFAITAw/Xf kZjCybwK22zxrfRLjdD+TH9uOudlVA8D8BSp+WKT4ouJjlr6+NDsMf2kP7AtI55TNXTK GPWzeerCfIFoNIICcb5WOrKebefY3/dDUZbu5qX96HWaEyKEqvjQ+StWZfS6otpiTHYe HXzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696892952; x=1697497752; 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=WVPLom817QijAmu2ToM6KNwT4YXyplIKJbzjUf63Skc=; b=oQU6ryJmMCq8vxBtxsoCjplnauOKjmtq6BtLlzPLMpQm1XCI3LWBHfi1aGQfBaTR4w JyGRemDBoh7kCSzAOK/DIEsz26qs7ARFHGXX85FSgrIYOYhCl3U+Nypzr8nuJB5gnt1q sfR2Y9VNA9tCwHpoEHfHXbQ70ha2g4sJa/wofAV5ecTLGpHaZ6JrojVd/4NEwZ7OqI7v LJkFPxLfF70kuoPF4Rerv9FX9itvDis9zABVoD0qP5eqfyK6dEd/gEg+iy1foRipxr11 aXhhCUKqVXz41yexBzKVKO6bTN+csGqKCJRZfuvLrlUgUgqUZoQyjPZwmGHdLTBxQich 9QKg== X-Gm-Message-State: AOJu0Yx+eYQpIl3iB/KuK7jHw3A0zO2H3ye54hHoVWOsGgiiPjczS5cG Ehxre2lG/hiDPp7GDOf69W6GZJvY3/Ww X-Google-Smtp-Source: AGHT+IFyNG907oCnWxlCAmcf3y3TzafJxvxtebFLo6APkYcTiodd1Eri22KDLIo7rsKWPkhluSmUKsZppbb+ X-Received: from rananta-linux.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:20a1]) (user=rananta job=sendgmr) by 2002:a25:5057:0:b0:d9a:5e8f:1562 with SMTP id e84-20020a255057000000b00d9a5e8f1562mr1171ybb.6.1696892951907; Mon, 09 Oct 2023 16:09:11 -0700 (PDT) Date: Mon, 9 Oct 2023 23:08:54 +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-9-rananta@google.com> Subject: [PATCH v7 08/12] KVM: arm64: PMU: Allow userspace to limit PMCR_EL0.N for the guest 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_560580_D2A8FD44 X-CRM114-Status: GOOD ( 20.93 ) 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 KVM does not yet support userspace modifying PMCR_EL0.N (With the previous patch, KVM ignores what is written by userspace). Add support userspace limiting PMCR_EL0.N. Disallow userspace to set PMCR_EL0.N to a value that is greater than the host value as KVM doesn't support more event counters than what the host HW implements. Also, make this register immutable after the VM has started running. To maintain the existing expectations, instead of returning an error, KVM returns a success for these two cases. Finally, ignore writes to read-only bits that are cleared on vCPU reset, and RES{0,1} bits (including writable bits that KVM doesn't support yet), as those bits shouldn't be modified (at least with the current KVM). Signed-off-by: Reiji Watanabe Signed-off-by: Raghavendra Rao Ananta --- arch/arm64/kvm/sys_regs.c | 57 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index c750722fbe4a..0c8d337b0370 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1087,6 +1087,59 @@ static int get_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, return 0; } +static int set_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, + u64 val) +{ + struct kvm *kvm = vcpu->kvm; + u64 new_n, mutable_mask; + + mutex_lock(&kvm->arch.config_lock); + + /* + * Make PMCR immutable once the VM has started running, but do + * not return an error (-EBUSY) to meet the existing expectations. + */ + if (kvm_vm_has_ran_once(vcpu->kvm)) { + mutex_unlock(&kvm->arch.config_lock); + return 0; + } + + new_n = (val >> ARMV8_PMU_PMCR_N_SHIFT) & ARMV8_PMU_PMCR_N_MASK; + if (new_n != kvm->arch.pmcr_n) { + u8 pmcr_n_limit = kvm_arm_get_num_counters(kvm); + + /* + * The vCPU can't have more counters than the PMU hardware + * implements. Ignore this error to maintain compatibility + * with the existing KVM behavior. + */ + if (new_n <= pmcr_n_limit) + kvm->arch.pmcr_n = new_n; + } + mutex_unlock(&kvm->arch.config_lock); + + /* + * Ignore writes to RES0 bits, read only bits that are cleared on + * vCPU reset, and writable bits that KVM doesn't support yet. + * (i.e. only PMCR.N and bits [7:0] are mutable from userspace) + * The LP bit is RES0 when FEAT_PMUv3p5 is not supported on the vCPU. + * But, we leave the bit as it is here, as the vCPU's PMUver might + * be changed later (NOTE: the bit will be cleared on first vCPU run + * if necessary). + */ + mutable_mask = (ARMV8_PMU_PMCR_MASK | + (ARMV8_PMU_PMCR_N_MASK << ARMV8_PMU_PMCR_N_SHIFT)); + val &= mutable_mask; + val |= (__vcpu_sys_reg(vcpu, r->reg) & ~mutable_mask); + + /* The LC bit is RES1 when AArch32 is not supported */ + if (!kvm_supports_32bit_el0()) + val |= ARMV8_PMU_PMCR_LC; + + __vcpu_sys_reg(vcpu, r->reg) = val; + 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)), \ @@ -2150,8 +2203,8 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_CTR_EL0), access_ctr }, { SYS_DESC(SYS_SVCR), undef_access }, - { PMU_SYS_REG(PMCR_EL0), .access = access_pmcr, - .reset = reset_pmcr, .reg = PMCR_EL0, .get_user = get_pmcr }, + { PMU_SYS_REG(PMCR_EL0), .access = access_pmcr, .reset = reset_pmcr, + .reg = PMCR_EL0, .get_user = get_pmcr, .set_user = set_pmcr }, { PMU_SYS_REG(PMCNTENSET_EL0), .access = access_pmcnten, .reg = PMCNTENSET_EL0 }, { PMU_SYS_REG(PMCNTENCLR_EL0),