From patchwork Thu Dec 7 17:06:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 10100343 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DD22360325 for ; Thu, 7 Dec 2017 17:17:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C1B3228464 for ; Thu, 7 Dec 2017 17:17:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B54F4284DA; Thu, 7 Dec 2017 17:17:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D7F4028464 for ; Thu, 7 Dec 2017 17:17:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=bppxou4WFPfqlrbojZtS7wcs1IZiUeA91DDgqtxhc2U=; b=pBrPrajvGOSTfNQ8/utIVwqRE1 2Rd165LiXSlmH6rleAasGVKMnG6ap8i5lyLkZ9hDXXTgJH0bQmpp1ZZBVsMbFek2tm8iRpHWFoTWb xyr/Uo1osKh3lWYvN6PuHTPcaL+AJ6BhJm4coa5QxOD3uDb853ly+CAr4XkWkEqv4DFBgHd/BiLTV QtlkuLtWA9n4CDdkvyYWDKhR852iV/mMxGQSuhwJKoFQ2W825GuSVDG1yKvfsFTj/S9IG2BBMJbAa S6v7RB2rMRKeHR0vUHt2bg1A3aocC1p0mEFKOE6ojBowvnOtyP9cv7/UMvvnaPmaUIMyZ8NcwFIP6 O9+AWGlg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1eMzo0-0006a0-0E; Thu, 07 Dec 2017 17:17:52 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1eMzfR-0004Pb-VA for linux-arm-kernel@bombadil.infradead.org; Thu, 07 Dec 2017 17:09:02 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=hy9MYsO3WClyU4ZGHHeCuTp7wVSFCdTf8j7PQg54SoY=; b=MN7f90zWFJBrKSAwKgjgdA+G1 MLNfA4TX6zCWh+hgRLygtZUUKcvbeS+a/Nf2/+FfF+9MvZhikABzqAcmUmvX+naZPlNqJteH1p5N7 lVJWG/5jQyD5z1NQ6uvn/XdOkwNaYCFgXkQ0CJxr9ZWi0N1hk1EkHFGssr4qnoNsVUtZQLjOGFUoT D8B135BV+QeE+t68dgF+3weqN1at8D8MSAuBB+X3TYSQl6/g6zXDmgmd+bNF/f5QkjsQc8qJidHe6 VXUIPu08d7TfjrbuuGjF3nFQWjVARwF0A/ADRqLIGFdhUz9rhFDbPimfiz+BmmpUZRwaarCwsorVX xNKTLkSug==; Received: from mail-wm0-x241.google.com ([2a00:1450:400c:c09::241]) by casper.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1eMzdl-0001vv-VK for linux-arm-kernel@lists.infradead.org; Thu, 07 Dec 2017 17:07:22 +0000 Received: by mail-wm0-x241.google.com with SMTP id 9so14260538wme.4 for ; Thu, 07 Dec 2017 09:06:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=hy9MYsO3WClyU4ZGHHeCuTp7wVSFCdTf8j7PQg54SoY=; b=Lhk1XEDP6XLyeBi6A+gPWdUSc6LhfBevhN1gP4vmIJcYw10zVrThw/rrBtH7BvzojR i+gVrGgbHQL41/+guc0hg6mRfNHnRtOECJXFt7TmoIupgxKvLh8Dwmty8/9Ri0LahjiC Qy0nAiOKJkHrT2KIa8KY8Z0V6gcRJMNHgoyYo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hy9MYsO3WClyU4ZGHHeCuTp7wVSFCdTf8j7PQg54SoY=; b=G4kcaXio25/gGsjSd2PxFnDaW7uSt16JiCUjzhN6XquPfq7uhJB65YM2ZsJD+Vfbuu 7fPpnApFo6PfwZjZ/Xso0QvD9cX6hORvuJm5tdWCCJJgHpZyUHWqlk1cGrU1RHuIp1Cy ZPaiyEEQOstrfS0D1UyYQjpbgWbvikl5ySEyYwO43C+2RT2fD+FrJ4+pXaIyeN23s5Dl dYlvB3KhjF/U/G05CFyB1hzEPF7fcrh2PJABp/38xUL+L7ph6K9vlCen2SfBludER9vh KcQQdGGPqnI6hKTtx5pkOnq+1ipRfusr9/a9BH0YS5jcKldbjMCFEOP9pedUoOU4qG2g xC6w== X-Gm-Message-State: AKGB3mJsbMidCTyjJUruQu8UofFN8kTXn9Uhvgeeb0F127ywO0n6XEGU npYv8U5b/GVuRJrhdvn4I4QHAA== X-Google-Smtp-Source: AGs4zMZWD5OnqkkDoxMBjKVgDRTGJAlwR702UuX2ftAR7bgtUXXRoH51A+sK3+wVwgdEPdhI8ONkUA== X-Received: by 10.80.141.141 with SMTP id r13mr13721757edh.122.1512666416209; Thu, 07 Dec 2017 09:06:56 -0800 (PST) Received: from localhost.localdomain (x50d2404e.cust.hiper.dk. [80.210.64.78]) by smtp.gmail.com with ESMTPSA id a16sm2868270edd.19.2017.12.07.09.06.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 07 Dec 2017 09:06:55 -0800 (PST) From: Christoffer Dall To: kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 10/36] KVM: arm64: Factor out fault info population and gic workarounds Date: Thu, 7 Dec 2017 18:06:04 +0100 Message-Id: <20171207170630.592-11-christoffer.dall@linaro.org> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20171207170630.592-1-christoffer.dall@linaro.org> References: <20171207170630.592-1-christoffer.dall@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171207_170718_045902_AEB64C5A X-CRM114-Status: GOOD ( 23.94 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marc Zyngier , Andrew Jones , Christoffer Dall , Shih-Wei Li , kvm@vger.kernel.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The current world-switch function has functionality to detect a number of cases where we need to fixup some part of the exit condition and possibly run the guest again, before having restored the host state. This includes populating missing fault info, emulating GICv2 CPU interface accesses when mapped at unaligned addresses, and emulating the GICv3 CPU interface on systems that need it. As we are about to have an alternative switch function for VHE systems, but VHE systems still need the same early fixup logic, factor out this logic into a separate function that can be shared by both switch functions. No functional change. Signed-off-by: Christoffer Dall Acked-by: Marc Zyngier --- Notes: Changes since v1: - Fixed typos in commit message - Changed comment in fixup_guest_exit - Us do-while instead of jumping to a label arch/arm64/kvm/hyp/switch.c | 99 ++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 45 deletions(-) diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c index 6982392745f5..845e3bece399 100644 --- a/arch/arm64/kvm/hyp/switch.c +++ b/arch/arm64/kvm/hyp/switch.c @@ -274,50 +274,24 @@ static bool __hyp_text __skip_instr(struct kvm_vcpu *vcpu) } } -int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu) +/* + * 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 + * main run loop. + */ +static bool __hyp_text fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) { - struct kvm_cpu_context *host_ctxt; - struct kvm_cpu_context *guest_ctxt; - u64 exit_code; - - vcpu = kern_hyp_va(vcpu); - - host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context); - host_ctxt->__hyp_running_vcpu = vcpu; - guest_ctxt = &vcpu->arch.ctxt; - - __sysreg_save_host_state(host_ctxt); - - __activate_traps(vcpu); - __activate_vm(vcpu); - - __vgic_restore_state(vcpu); - __timer_enable_traps(vcpu); - - /* - * We must restore the 32-bit state before the sysregs, thanks - * to erratum #852523 (Cortex-A57) or #853709 (Cortex-A72). - */ - __sysreg32_restore_state(vcpu); - __sysreg_restore_guest_state(guest_ctxt); - __debug_switch_to_guest(vcpu); - - /* Jump in the fire! */ -again: - exit_code = __guest_enter(vcpu, host_ctxt); - /* And we're baaack! */ - /* * We're using the raw exception code in order to only process * the trap if no SError is pending. We will come back to the * same PC once the SError has been injected, and replay the * trapping instruction. */ - if (exit_code == ARM_EXCEPTION_TRAP && !__populate_fault_info(vcpu)) - goto again; + if (*exit_code == ARM_EXCEPTION_TRAP && !__populate_fault_info(vcpu)) + return true; if (static_branch_unlikely(&vgic_v2_cpuif_trap) && - exit_code == ARM_EXCEPTION_TRAP) { + *exit_code == ARM_EXCEPTION_TRAP) { bool valid; valid = kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_DABT_LOW && @@ -331,9 +305,9 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu) if (ret == 1) { if (__skip_instr(vcpu)) - goto again; + return true; else - exit_code = ARM_EXCEPTION_TRAP; + *exit_code = ARM_EXCEPTION_TRAP; } if (ret == -1) { @@ -345,29 +319,64 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu) */ if (!__skip_instr(vcpu)) *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS; - exit_code = ARM_EXCEPTION_EL1_SERROR; + *exit_code = ARM_EXCEPTION_EL1_SERROR; } - - /* 0 falls through to be handler out of EL2 */ } } if (static_branch_unlikely(&vgic_v3_cpuif_trap) && - exit_code == ARM_EXCEPTION_TRAP && + *exit_code == ARM_EXCEPTION_TRAP && (kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_SYS64 || kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_CP15_32)) { int ret = __vgic_v3_perform_cpuif_access(vcpu); if (ret == 1) { if (__skip_instr(vcpu)) - goto again; + return true; else - exit_code = ARM_EXCEPTION_TRAP; + *exit_code = ARM_EXCEPTION_TRAP; } - - /* 0 falls through to be handled out of EL2 */ } + /* Return to the host kernel and handle the exit */ + return false; +} + +int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu) +{ + struct kvm_cpu_context *host_ctxt; + struct kvm_cpu_context *guest_ctxt; + u64 exit_code; + + vcpu = kern_hyp_va(vcpu); + + host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context); + host_ctxt->__hyp_running_vcpu = vcpu; + guest_ctxt = &vcpu->arch.ctxt; + + __sysreg_save_host_state(host_ctxt); + + __activate_traps(vcpu); + __activate_vm(vcpu); + + __vgic_restore_state(vcpu); + __timer_enable_traps(vcpu); + + /* + * We must restore the 32-bit state before the sysregs, thanks + * to erratum #852523 (Cortex-A57) or #853709 (Cortex-A72). + */ + __sysreg32_restore_state(vcpu); + __sysreg_restore_guest_state(guest_ctxt); + __debug_switch_to_guest(vcpu); + + do { + /* Jump in the fire! */ + exit_code = __guest_enter(vcpu, host_ctxt); + + /* And we're baaack! */ + } while (fixup_guest_exit(vcpu, &exit_code)); + __sysreg_save_guest_state(guest_ctxt); __sysreg32_save_state(vcpu); __timer_disable_traps(vcpu);