From patchwork Sat Mar 18 12:56:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 9632165 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 D8AD760249 for ; Sat, 18 Mar 2017 12:57:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BFA782833C for ; Sat, 18 Mar 2017 12:57:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A17D628482; Sat, 18 Mar 2017 12:57:43 +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=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=ham 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 1B70E2833C for ; Sat, 18 Mar 2017 12:57:42 +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: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:In-Reply-To: References:List-Owner; bh=CH71CSSUB2742dTCmHIThE1IyjphekbS49PYL0Yk3fU=; b=ZFB 6ruLRFfbQXm6dnVnctxWqJiRVsuAB6/31PpDJi7noQG+APIDD1FGXNV0BI97Bwxuit854sNSq5Dx4 Ex0AbETpuF63Vy6b7yhSgFdZtuaeDmtY0X6CQ5f6VobDyxwMEP4NTuKuCV3Q42Lk8EsYq5h+dm4eh Seq1B8AgaH7nv9gAHWZd1ueu93+lJT4PIeyGLvesVi9IANuPNja6So/zrOJJ5RS3FgCI46Y2zamJg W27ErPTOj7e0DVvfIsNP7sI4NCLJ43LS4nOWzmj9+K4BhML7s/nnHSWhbNvz1D0sPFWq8G+wRSdTb STJmRJaea07WfQHHTcpkiZkGLXrvD3Q==; 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 1cpDvP-0001sk-G6; Sat, 18 Mar 2017 12:57:39 +0000 Received: from mail-wm0-x22d.google.com ([2a00:1450:400c:c09::22d]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cpDvK-0001r3-33 for linux-arm-kernel@lists.infradead.org; Sat, 18 Mar 2017 12:57:36 +0000 Received: by mail-wm0-x22d.google.com with SMTP id t189so34006413wmt.1 for ; Sat, 18 Mar 2017 05:57:13 -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; bh=gWCtTXdWsRVDtFvrB05zQ3SeDTAVnf7Dbbu2UXfXdlI=; b=MYe65i0C8v94eWxGI9phoQcAnc5CvLm+/um4iU733vxyquxb+F5iIxTJk7/1fFpgTs sHrA+uZ6wvJMOhRO6l3v8ZKtrhnz7hK74EWHDUsHIcLTD4oYe7LrT0YxrMU5qz9EL3VX +o2+/OMxalRbGtb4SdX+xRRL2Vzl1WxH8y8x8= 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; bh=gWCtTXdWsRVDtFvrB05zQ3SeDTAVnf7Dbbu2UXfXdlI=; b=TJc+dWWTFFzfqretEl8ZOqqxGksdW3k06ogsCp5KnkuJHZEuR1mh61ncu0Y5aMUPk2 LwLhLgjJqcjBsHzTIRn/3pkX+tP489wlZY0FoAyGgd5gtPLpfFY3OCeudOH7ntwqIU2f 0BYOOQTSlmki+Kzkzj0EEYCnELHRoJxBYIdMFp7gDqvdj+6b4mhot57+tpqXRET5zq+e H8vyCcGxq6LfNwbQX4Oyb0NDnA2F5TSVolMg3+i+RSSdGga0AExhv6bd77EYYEiDMvaL BM89eQV39ZpXurjM/6jtHAu3EzW3ihf6rbpDi3iRdNegJImmwCpg/WA0yPRt3Nnc+wHK cgyA== X-Gm-Message-State: AFeK/H25A9lmH2v6Lar2nQZ015iFuo4+8ZVagPe0l9UaI4jVbD3UiaXgtiU6A9hcISX8+gv8 X-Received: by 10.28.218.197 with SMTP id r188mr533167wmg.0.1489841832122; Sat, 18 Mar 2017 05:57:12 -0700 (PDT) Received: from localhost.localdomain (xd93ddc2d.cust.hiper.dk. [217.61.220.45]) by smtp.gmail.com with ESMTPSA id g18sm6213062wme.2.2017.03.18.05.57.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 18 Mar 2017 05:57:11 -0700 (PDT) From: Christoffer Dall To: kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH] KVM: arm64: Ensure LRs are clear when they should be Date: Sat, 18 Mar 2017 13:56:56 +0100 Message-Id: <20170318125656.16523-1-cdall@linaro.org> X-Mailer: git-send-email 2.9.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170318_055734_296223_827E27D5 X-CRM114-Status: GOOD ( 16.88 ) 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 , Andre Przywara , Christoffer Dall , kvm@vger.kernel.org, Eric Auger 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 From: Christoffer Dall We currently have some code to clear the list registers on GICv3, but we never call this code, because the caller got nuked when removing the old vgic. We also used to have a similar GICv2 part, but that got lost in the process too. Let's reintroduce the logic for GICv2 and call the logic when we initialize the use of hypervisors on the CPU, for example when first loading KVM or when exiting a low power state. Signed-off-by: Christoffer Dall Reviewed-by: Marc Zyngier --- Marc, Eric, Andre, I'm unable to convince myself that the LRs should already be clear via the reset of the hardware, and for any power management scenario I suppose it's possible for secure-side firmware to have messed with the LRs behind our backs; plus we used to have this functionality and it got dropped for the new vgic. Am I forgetting some discussion where we decided it wasn't needed anymore? Thanks, -Christoffer arch/arm/kvm/arm.c | 3 +++ include/kvm/arm_vgic.h | 1 + virt/kvm/arm/vgic/vgic-init.c | 19 +++++++++++++++++++ virt/kvm/arm/vgic/vgic-v2.c | 15 +++++++++++++++ virt/kvm/arm/vgic/vgic.h | 2 ++ 5 files changed, 40 insertions(+) diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index c9a2103..d775aac 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -1121,6 +1121,9 @@ static void cpu_hyp_reinit(void) if (__hyp_get_vectors() == hyp_default_vectors) cpu_init_hyp_mode(NULL); } + + if (vgic_present) + kvm_vgic_init_cpu_hardware(); } static void cpu_hyp_reset(void) diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index b72dd2a..c0b3d99 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -295,6 +295,7 @@ void kvm_vgic_vcpu_early_init(struct kvm_vcpu *vcpu); void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu); int kvm_vgic_map_resources(struct kvm *kvm); int kvm_vgic_hyp_init(void); +void kvm_vgic_init_cpu_hardware(void); int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, bool level); diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c index 276139a..702f810 100644 --- a/virt/kvm/arm/vgic/vgic-init.c +++ b/virt/kvm/arm/vgic/vgic-init.c @@ -392,6 +392,25 @@ static irqreturn_t vgic_maintenance_handler(int irq, void *data) } /** + * kvm_vgic_init_cpu_hardware - initialize the GIC VE hardware + * + * For a specific CPU, initialize the GIC VE hardware. + */ +void kvm_vgic_init_cpu_hardware(void) +{ + BUG_ON(preemptible()); + + /* + * We want to make sure the list registers start out clear so that we + * only have the program the used registers. + */ + if (kvm_vgic_global_state.type == VGIC_V2) + vgic_v2_init_lrs(); + else + kvm_call_hyp(__vgic_v3_init_lrs); +} + +/** * kvm_vgic_hyp_init: populates the kvm_vgic_global_state variable * according to the host GIC model. Accordingly calls either * vgic_v2/v3_probe which registers the KVM_DEVICE that can be diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c index b834ecd..94cf4b9 100644 --- a/virt/kvm/arm/vgic/vgic-v2.c +++ b/virt/kvm/arm/vgic/vgic-v2.c @@ -36,6 +36,21 @@ static unsigned long *u64_to_bitmask(u64 *val) return (unsigned long *)val; } +static inline void vgic_v2_write_lr(int lr, u32 val) +{ + void __iomem *base = kvm_vgic_global_state.vctrl_base; + + writel_relaxed(val, base + GICH_LR0 + (lr * 4)); +} + +void vgic_v2_init_lrs(void) +{ + int i; + + for (i = 0; i < kvm_vgic_global_state.nr_lr; i++) + vgic_v2_write_lr(i, 0); +} + void vgic_v2_process_maintenance(struct kvm_vcpu *vcpu) { struct vgic_v2_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v2; diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h index db28f7c..91566f5 100644 --- a/virt/kvm/arm/vgic/vgic.h +++ b/virt/kvm/arm/vgic/vgic.h @@ -130,6 +130,8 @@ int vgic_v2_map_resources(struct kvm *kvm); int vgic_register_dist_iodev(struct kvm *kvm, gpa_t dist_base_address, enum vgic_type); +void vgic_v2_init_lrs(void); + static inline void vgic_get_irq_kref(struct vgic_irq *irq) { if (irq->intid < VGIC_MIN_LPI)