From patchwork Tue Aug 8 11:47:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 13345981 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 04A35C001DF for ; Tue, 8 Aug 2023 11:48:32 +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:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=B+Vq5BB86gPvBbdkT1Z9pTu0WIvwdOYRW+mxNDHj6go=; b=FVtf3mCWzEvcxp E24AoyHX/z8MQMaF2Zk+9NXLaZWcMQBoe22RPmkwCdiNkJc8qoz9yZmF16z8I9f9gGSIfQ4fSv6rm thTxM4U4W1sH5WvVhN77E0lIug+Qa2N2UgWEtU1y1o+dvDTtfYPp92nhvzX3prg0b1T0n1OBgKi7a 8POI7845+YibmWDDWX4phniVonztOTceolzVGPvza874ErogQYlwfxnPyalskol3vVbpDO+8SiTQe xXkk9GQTVOP1/5y8XRbLbzNQVOme58U56Kf7mktBo/6VWIk+SAMkH2eX4gNw5wbAd4MHMQIyvPGwh 065Ps/2NnOz8GQolQgJw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qTLBv-002UmL-38; Tue, 08 Aug 2023 11:47:59 +0000 Received: from dfw.source.kernel.org ([2604:1380:4641:c500::1]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qTLBq-002Ui5-1z for linux-arm-kernel@lists.infradead.org; Tue, 08 Aug 2023 11:47:57 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 094FA624FF; Tue, 8 Aug 2023 11:47:54 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 667A1C43391; Tue, 8 Aug 2023 11:47:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1691495273; bh=E7EfyLyZQV58kos+RRoOBuTQq3eMGoMuJaAqA7RmAmY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CHWe1Yo2fK+uxBnwGai9xbOcO6Je68qZpEneRX/3AJ380miaHhzhuyNVBXMLFu8Cv qd8PMf5WXIr0YmicU73LLn6cc4wB6GXmi7pAIjXxewDqYdY0Hpmomp/8JbcmQ54s2S 9bylpUmQL6Pyy63A76GtOAAvlIBZ1cruEV6rSU1gLE1ZOIW9ZT+S/ULzPj1PGLHi+O 9fW/ZmZ6s4A816x1QtXhQhhFxbdbrh6TVe8l/IcvrT+N8nzvXR+tyT0kvmaVvuoraJ eiQe+gkyFUXDNRGijc5HFx6ERLTZYC+Bc94aJQEeW2LR1gFj6DHMKRdXZySY4NFDds D8FLmPXvvLZGQ== Received: from sofa.misterjones.org ([185.219.108.64] helo=valley-girl.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1qTLBJ-0037Ph-BU; Tue, 08 Aug 2023 12:47:21 +0100 From: Marc Zyngier To: kvmarm@lists.linux.dev, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Catalin Marinas , Eric Auger , Mark Brown , Mark Rutland , Will Deacon , Alexandru Elisei , Andre Przywara , Chase Conklin , Ganapatrao Kulkarni , Darren Hart , Miguel Luis , James Morse , Suzuki K Poulose , Oliver Upton , Zenghui Yu Subject: [PATCH v3 19/27] KVM: arm64: nv: Add fine grained trap forwarding infrastructure Date: Tue, 8 Aug 2023 12:47:03 +0100 Message-Id: <20230808114711.2013842-20-maz@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230808114711.2013842-1-maz@kernel.org> References: <20230808114711.2013842-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 185.219.108.64 X-SA-Exim-Rcpt-To: kvmarm@lists.linux.dev, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, catalin.marinas@arm.com, eric.auger@redhat.com, broonie@kernel.org, mark.rutland@arm.com, will@kernel.org, alexandru.elisei@arm.com, andre.przywara@arm.com, chase.conklin@arm.com, gankulkarni@os.amperecomputing.com, darren@os.amperecomputing.com, miguel.luis@oracle.com, james.morse@arm.com, suzuki.poulose@arm.com, oliver.upton@linux.dev, yuzenghui@huawei.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230808_044754_771523_8563373D X-CRM114-Status: GOOD ( 20.18 ) 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 Fine Grained Traps are fun. Not. Implement the fine grained trap forwarding, reusing the Coarse Grained Traps infrastructure previously implemented. Each sysreg/instruction inserted in the xarray gets a FGT group (vaguely equivalent to a register number), a bit number in that register, and a polarity. It is then pretty easy to check the FGT state at handling time, just like we do for the coarse version (it is just faster). Reviewed-by: Eric Auger Signed-off-by: Marc Zyngier --- arch/arm64/kvm/emulate-nested.c | 78 ++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c index cd0544c3577e..af75c2775638 100644 --- a/arch/arm64/kvm/emulate-nested.c +++ b/arch/arm64/kvm/emulate-nested.c @@ -928,6 +928,27 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = { static DEFINE_XARRAY(sr_forward_xa); +enum fgt_group_id { + __NO_FGT_GROUP__, + + /* Must be last */ + __NR_FGT_GROUP_IDS__ +}; + +#define SR_FGT(sr, g, b, p) \ + { \ + .encoding = sr, \ + .end = sr, \ + .tc = { \ + .fgt = g ## _GROUP, \ + .bit = g ## _EL2_ ## b ## _SHIFT, \ + .pol = p, \ + }, \ + } + +static const struct encoding_to_trap_config encoding_to_fgt[] __initconst = { +}; + static union trap_config get_trap_config(u32 sysreg) { return (union trap_config) { @@ -941,6 +962,7 @@ int __init populate_nv_trap_config(void) BUILD_BUG_ON(sizeof(union trap_config) != sizeof(void *)); BUILD_BUG_ON(__NR_TRAP_GROUP_IDS__ > BIT(TC_CGT_BITS)); + BUILD_BUG_ON(__NR_FGT_GROUP_IDS__ > BIT(TC_FGT_BITS)); for (int i = 0; i < ARRAY_SIZE(encoding_to_cgt); i++) { const struct encoding_to_trap_config *cgt = &encoding_to_cgt[i]; @@ -963,6 +985,34 @@ int __init populate_nv_trap_config(void) kvm_info("nv: %ld coarse grained trap handlers\n", ARRAY_SIZE(encoding_to_cgt)); + if (!cpus_have_final_cap(ARM64_HAS_FGT)) + goto check_mcb; + + for (int i = 0; i < ARRAY_SIZE(encoding_to_fgt); i++) { + const struct encoding_to_trap_config *fgt = &encoding_to_fgt[i]; + union trap_config tc; + + tc = get_trap_config(fgt->encoding); + + if (tc.fgt) { + kvm_err("Duplicate FGT for (%d, %d, %d, %d, %d)\n", + sys_reg_Op0(fgt->encoding), + sys_reg_Op1(fgt->encoding), + sys_reg_CRn(fgt->encoding), + sys_reg_CRm(fgt->encoding), + sys_reg_Op2(fgt->encoding)); + ret = -EINVAL; + } + + tc.val |= fgt->tc.val; + xa_store(&sr_forward_xa, fgt->encoding, + xa_mk_value(tc.val), GFP_KERNEL); + } + + kvm_info("nv: %ld fine grained trap handlers\n", + ARRAY_SIZE(encoding_to_fgt)); + +check_mcb: for (int id = __MULTIPLE_CONTROL_BITS__; id < (__COMPLEX_CONDITIONS__ - 1); id++) { @@ -1031,13 +1081,26 @@ static enum trap_behaviour compute_trap_behaviour(struct kvm_vcpu *vcpu, return __do_compute_trap_behaviour(vcpu, tc.cgt, b); } +static bool check_fgt_bit(u64 val, const union trap_config tc) +{ + return ((val >> tc.bit) & 1) == tc.pol; +} + +#define sanitised_sys_reg(vcpu, reg) \ + ({ \ + u64 __val; \ + __val = __vcpu_sys_reg(vcpu, reg); \ + __val &= ~__ ## reg ## _RES0; \ + (__val); \ + }) + bool __check_nv_sr_forward(struct kvm_vcpu *vcpu) { union trap_config tc; enum trap_behaviour b; bool is_read; u32 sysreg; - u64 esr; + u64 esr, val; if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu)) return false; @@ -1060,6 +1123,19 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu) if (!tc.val) return false; + switch ((enum fgt_group_id)tc.fgt) { + case __NO_FGT_GROUP__: + break; + + case __NR_FGT_GROUP_IDS__: + /* Something is really wrong, bail out */ + WARN_ONCE(1, "__NR_FGT_GROUP_IDS__"); + return false; + } + + if (tc.fgt != __NO_FGT_GROUP__ && check_fgt_bit(val, tc)) + goto inject; + b = compute_trap_behaviour(vcpu, tc); if (((b & BEHAVE_FORWARD_READ) && is_read) ||