From patchwork Tue Sep 27 18:05:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 9352449 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 009036077B for ; Tue, 27 Sep 2016 18:06:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EAB1029272 for ; Tue, 27 Sep 2016 18:06:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DFDB129260; Tue, 27 Sep 2016 18:06:23 +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=-6.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4DC0729272 for ; Tue, 27 Sep 2016 18:06:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935099AbcI0SGT (ORCPT ); Tue, 27 Sep 2016 14:06:19 -0400 Received: from mail-wm0-f43.google.com ([74.125.82.43]:36443 "EHLO mail-wm0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756117AbcI0SGC (ORCPT ); Tue, 27 Sep 2016 14:06:02 -0400 Received: by mail-wm0-f43.google.com with SMTP id w84so190349500wmg.1 for ; Tue, 27 Sep 2016 11:06:01 -0700 (PDT) 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=UbutXDyMhlWXxEmYNcNT9cg4ABkibEzxY/9KQJUfCnk=; b=VL2DMYYxf6LbqWcvmI7d/90AuH0t0YrOIJPuaP83qR1qR2gHYfDBbo4oMGasWuaiuk Yi87YvQg7th9sTfINgJEtPQYoSEQdcrZXCQfxCBExC5v2GKeLV588kN2TWrp23ok0fTb i8LMYOfXgVqqGvnVjDBGnjiIpO3msnfC9m+KA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=UbutXDyMhlWXxEmYNcNT9cg4ABkibEzxY/9KQJUfCnk=; b=mIQ9Cy0+X0RXyCBlX0qSU6OKhK9bJF6hqceSuz6RG2VBS876jvplu8Rnq5y1zNHjoO i3T3IdrowsGvX7L7Pvr6nIRnv0BlVh5nSdYU9PApa0/HiSJc7BSATQFczgI//Fyio23b YWezwSp0N5z00mCBpmbuDhLIbU3+pdpCx5omsp3ad7S93jl+gqUz4/RZC3rc2mGFimoI 3n0GQKggzAV0shdPMivKGGbcYmtmzhGEQs6IcFrAgG572JjBX8rS8BrVih30ijeiRPEU LUxoe0zdlPY/Xn+ontVcJrBKN/DnUEJZUVxFPV7UNhyZQwmqPYk9RT4J+1i490hFLN7R Kq0g== X-Gm-Message-State: AE9vXwMtpYnWz47vnC9LTWFNnSLzesKZQkgerpJdXPBU1qxiwbESoHzgJvang0ZZH3pOJiIq X-Received: by 10.194.206.68 with SMTP id lm4mr23986769wjc.106.1474999560657; Tue, 27 Sep 2016 11:06:00 -0700 (PDT) Received: from localhost.localdomain ([94.18.191.146]) by smtp.gmail.com with ESMTPSA id k2sm17932539wmg.23.2016.09.27.11.05.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 27 Sep 2016 11:05:59 -0700 (PDT) From: Christoffer Dall To: Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Cc: Marc Zyngier , kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Christoffer Dall Subject: [PULL 15/50] arm64: KVM: vgic-v2: Add GICV access from HYP Date: Tue, 27 Sep 2016 20:05:23 +0200 Message-Id: <20160927180558.14699-16-christoffer.dall@linaro.org> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20160927180558.14699-1-christoffer.dall@linaro.org> References: <20160927180558.14699-1-christoffer.dall@linaro.org> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Marc Zyngier Now that we have the necessary infrastructure to handle MMIO accesses in HYP, perform the GICV access on behalf of the guest. This requires checking that the access is strictly 32bit, properly aligned, and falls within the expected range. When all condition are satisfied, we perform the access and tell the rest of the HYP code that the instruction has been correctly emulated. Reviewed-by: Christoffer Dall Signed-off-by: Marc Zyngier Signed-off-by: Christoffer Dall --- include/kvm/arm_vgic.h | 3 +++ virt/kvm/arm/hyp/vgic-v2-sr.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 8eb1501..bb46c03 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -50,6 +50,9 @@ struct vgic_global { /* Physical address of vgic virtual cpu interface */ phys_addr_t vcpu_base; + /* GICV mapping */ + void __iomem *vcpu_base_va; + /* virtual control interface mapping */ void __iomem *vctrl_base; diff --git a/virt/kvm/arm/hyp/vgic-v2-sr.c b/virt/kvm/arm/hyp/vgic-v2-sr.c index 3e2a62e..a052f20 100644 --- a/virt/kvm/arm/hyp/vgic-v2-sr.c +++ b/virt/kvm/arm/hyp/vgic-v2-sr.c @@ -19,6 +19,7 @@ #include #include +#include #include static void __hyp_text save_maint_int_state(struct kvm_vcpu *vcpu, @@ -171,6 +172,44 @@ void __hyp_text __vgic_v2_restore_state(struct kvm_vcpu *vcpu) #ifdef CONFIG_ARM64 bool __hyp_text __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu) { + struct kvm *kvm = kern_hyp_va(vcpu->kvm); + struct vgic_dist *vgic = &kvm->arch.vgic; + phys_addr_t fault_ipa; + void __iomem *addr; + int rd; + + /* Build the full address */ + fault_ipa = kvm_vcpu_get_fault_ipa(vcpu); + fault_ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0); + + /* If not for GICV, move on */ + if (fault_ipa < vgic->vgic_cpu_base || + fault_ipa >= (vgic->vgic_cpu_base + KVM_VGIC_V2_CPU_SIZE)) return false; + + /* Reject anything but a 32bit access */ + if (kvm_vcpu_dabt_get_as(vcpu) != sizeof(u32)) + return false; + + /* Not aligned? Don't bother */ + if (fault_ipa & 3) + return false; + + rd = kvm_vcpu_dabt_get_rd(vcpu); + addr = kern_hyp_va((kern_hyp_va(&kvm_vgic_global_state))->vcpu_base_va); + addr += fault_ipa - vgic->vgic_cpu_base; + + if (kvm_vcpu_dabt_iswrite(vcpu)) { + u32 data = vcpu_data_guest_to_host(vcpu, + vcpu_get_reg(vcpu, rd), + sizeof(u32)); + writel_relaxed(data, addr); + } else { + u32 data = readl_relaxed(addr); + vcpu_set_reg(vcpu, rd, vcpu_data_host_to_guest(vcpu, data, + sizeof(u32))); + } + + return true; } #endif