From patchwork Tue Aug 17 08:11:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fuad Tabba X-Patchwork-Id: 12440855 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 56B97C4338F for ; Tue, 17 Aug 2021 08:19:51 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 2115660FC3 for ; Tue, 17 Aug 2021 08:19:51 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 2115660FC3 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org 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:References: Mime-Version:Message-Id: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=9O7ZcvnMPHcfGHf1wXdfJH5PgF+ZeZrgxC9ZaWkLZCw=; b=KxZVxVW7b2EwjyXpao+zqagDmi CSQdnTP72l6s5MI6PIiNcwfHOYdptwvctzmgmlHdBgo4eAFuc1g3ZFpRP9kywMY2n2iZXxVQuzSTf skwsiuEwIusKGDHulViz7vHOnUJfz0QJN9MXsp6tpozUa+MUUQTNlZ03ld3flVeMkXJWZVqf8ISVO bxgm3OUsBe6+LRCxKrsaNdjM0LtsvObM+QUZXKci4LzpCUM0Y0XxlNq5/cjjYCnvjrgls15Y91Nw4 OWNJEcPONFmidP0QE/xZgqzxvrmwr1/IJlEnu8mH2rSJgDx911WqJ9YdbuVKV+K9vT0FgDUEQu4ie YOR9g3Ew==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mFuHR-001XRw-Ng; Tue, 17 Aug 2021 08:17:06 +0000 Received: from mail-wm1-x349.google.com ([2a00:1450:4864:20::349]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mFuCX-001VHq-SX for linux-arm-kernel@lists.infradead.org; Tue, 17 Aug 2021 08:12:03 +0000 Received: by mail-wm1-x349.google.com with SMTP id m13-20020a7bcf2d000000b002e6cd9941a9so701645wmg.1 for ; Tue, 17 Aug 2021 01:12:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=wCAlPucxwkxQDsZjrMwYYiCi5QbYeNWxBim5zrWnq2Y=; b=Aakqhp0ujPFBkz2t9XKF2sWAACl4G7B5hxJDrt2uXINVbL4SDQRXJFOegBUQ1cWZ/J 0jUUeLw9Od7HUTBaHF2bEbcWHbDSiLs7WOuMmHvkgQ9aKAKEc1Se9jaIc0RdmvVOh0fO 2EN/wB6tJc5Zuqxbzk63h/bmcGOdULfseyFm4sZABt1qcXnPvBSlGoCTvs5yVR6Y8Yo1 YMuBWKj78N9MEBXEHK0yav34qJ6J/ferOrSpzyXe15duHhdaVH3IinJtQB7TmOXkIdhf EGOlFmuP1fTlBQFW97lGVUPjXY5ipiWvG/UMC6271totgCudngPKM0tiXwaU5gQ9KdQm 5UzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=wCAlPucxwkxQDsZjrMwYYiCi5QbYeNWxBim5zrWnq2Y=; b=MMSROuLUYc1D4yMTWRE+7Ryp0YogYougq6pHhhL8WUthIunVdEcxo9t4uysL7Z2kF5 EHCBEd0PON+YbvCde4pGlPkGN7AxqMnHnU2/yRRnx8BWD8JaMj3G46ZELeR61k0IChgE DQvQKUvPh7LkpPrz2Y8ZelKXKZzwB571mEqdSWp49W4InvYcGt9UB2o+Tb7H+Ue8yxik ra+ogQs/wa4R7aua9A9lJVMbGLbswsFxq7mQ9YlL3PKYR3tvimiLzMHmQWAwAxqzwmVW MGKEP1DXaMxFKmBkWSZqKYOQ/tSPDpnicVkb9esuQvfUwlvkc8XBQBkCejffrETX86vp GtVQ== X-Gm-Message-State: AOAM531OEVf4ruLIAW+VbppHIrxoF85QA5MZDZPI1quUMLG5jvboDZM8 jMw9MTCvYkmKuB3XV41xIpHUGLu/vA== X-Google-Smtp-Source: ABdhPJyYTcbz4UVboGo7zKDmnSidrFF2RAjsx5lYf6M4UE4X0H/bCAlk0j+kiCGYLkR2pXqzSg2USK4ZwA== X-Received: from tabba.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:482]) (user=tabba job=sendgmr) by 2002:a1c:c914:: with SMTP id f20mr2057147wmb.140.1629187919570; Tue, 17 Aug 2021 01:11:59 -0700 (PDT) Date: Tue, 17 Aug 2021 09:11:30 +0100 In-Reply-To: <20210817081134.2918285-1-tabba@google.com> Message-Id: <20210817081134.2918285-12-tabba@google.com> Mime-Version: 1.0 References: <20210817081134.2918285-1-tabba@google.com> X-Mailer: git-send-email 2.33.0.rc1.237.g0d66db33f3-goog Subject: [PATCH v4 11/15] KVM: arm64: Guest exit handlers for nVHE hyp From: Fuad Tabba To: kvmarm@lists.cs.columbia.edu Cc: maz@kernel.org, will@kernel.org, james.morse@arm.com, alexandru.elisei@arm.com, suzuki.poulose@arm.com, mark.rutland@arm.com, christoffer.dall@arm.com, pbonzini@redhat.com, drjones@redhat.com, oupton@google.com, qperret@google.com, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel-team@android.com, tabba@google.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210817_011201_970671_192ED49D X-CRM114-Status: GOOD ( 17.51 ) 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 Add an array of pointers to handlers for various trap reasons in nVHE code. The current code selects how to fixup a guest on exit based on a series of if/else statements. Future patches will also require different handling for guest exists. Create an array of handlers to consolidate them. No functional change intended as the array isn't populated yet. Acked-by: Will Deacon Signed-off-by: Fuad Tabba --- arch/arm64/kvm/hyp/include/hyp/switch.h | 43 +++++++++++++++++++++++++ arch/arm64/kvm/hyp/nvhe/switch.c | 33 +++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h index a0e78a6027be..5a2b89b96c67 100644 --- a/arch/arm64/kvm/hyp/include/hyp/switch.h +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h @@ -409,6 +409,46 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu) return true; } +typedef int (*exit_handle_fn)(struct kvm_vcpu *); + +exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu); + +static exit_handle_fn kvm_get_hyp_exit_handler(struct kvm_vcpu *vcpu) +{ + return is_nvhe_hyp_code() ? kvm_get_nvhe_exit_handler(vcpu) : NULL; +} + +/* + * Allow the hypervisor to handle the exit with an exit handler if it has one. + * + * Returns true if the hypervisor handled the exit, and control should go back + * to the guest, or false if it hasn't. + */ +static bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu) +{ + bool is_handled = false; + exit_handle_fn exit_handler = kvm_get_hyp_exit_handler(vcpu); + + if (exit_handler) { + /* + * There's limited vcpu context here since it's not synced yet. + * Ensure that relevant vcpu context that might be used by the + * exit_handler is in sync before it's called and if handled. + */ + *vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR); + *vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR); + + is_handled = exit_handler(vcpu); + + if (is_handled) { + write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR); + write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR); + } + } + + return is_handled; +} + /* * Return true when we were able to fixup the guest exit and should return to * the guest, false when we should restore the host state and return to the @@ -496,6 +536,9 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) goto guest; } + /* Check if there's an exit handler and allow it to handle the exit. */ + if (kvm_hyp_handle_exit(vcpu)) + goto guest; exit: /* Return to the host kernel and handle the exit */ return false; diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c index 86f3d6482935..b7f25307a7b9 100644 --- a/arch/arm64/kvm/hyp/nvhe/switch.c +++ b/arch/arm64/kvm/hyp/nvhe/switch.c @@ -158,6 +158,39 @@ static void __pmu_switch_to_host(struct kvm_cpu_context *host_ctxt) write_sysreg(pmu->events_host, pmcntenset_el0); } +static exit_handle_fn hyp_exit_handlers[] = { + [0 ... ESR_ELx_EC_MAX] = NULL, + [ESR_ELx_EC_WFx] = NULL, + [ESR_ELx_EC_CP15_32] = NULL, + [ESR_ELx_EC_CP15_64] = NULL, + [ESR_ELx_EC_CP14_MR] = NULL, + [ESR_ELx_EC_CP14_LS] = NULL, + [ESR_ELx_EC_CP14_64] = NULL, + [ESR_ELx_EC_HVC32] = NULL, + [ESR_ELx_EC_SMC32] = NULL, + [ESR_ELx_EC_HVC64] = NULL, + [ESR_ELx_EC_SMC64] = NULL, + [ESR_ELx_EC_SYS64] = NULL, + [ESR_ELx_EC_SVE] = NULL, + [ESR_ELx_EC_IABT_LOW] = NULL, + [ESR_ELx_EC_DABT_LOW] = NULL, + [ESR_ELx_EC_SOFTSTP_LOW] = NULL, + [ESR_ELx_EC_WATCHPT_LOW] = NULL, + [ESR_ELx_EC_BREAKPT_LOW] = NULL, + [ESR_ELx_EC_BKPT32] = NULL, + [ESR_ELx_EC_BRK64] = NULL, + [ESR_ELx_EC_FP_ASIMD] = NULL, + [ESR_ELx_EC_PAC] = NULL, +}; + +exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu) +{ + u32 esr = kvm_vcpu_get_esr(vcpu); + u8 esr_ec = ESR_ELx_EC(esr); + + return hyp_exit_handlers[esr_ec]; +} + /* Switch to the guest for legacy non-VHE systems */ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) {