From patchwork Thu Oct 19 12:48:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 10016655 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 0F09F60224 for ; Thu, 19 Oct 2017 12:51:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E39F828D3F for ; Thu, 19 Oct 2017 12:51:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D752C28D43; Thu, 19 Oct 2017 12:51:41 +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, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6EBA128D3F for ; Thu, 19 Oct 2017 12:51:41 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e5AGD-0004Y0-Qa; Thu, 19 Oct 2017 12:49:17 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e5AGC-0004W3-Lb for xen-devel@lists.xenproject.org; Thu, 19 Oct 2017 12:49:16 +0000 Received: from [85.158.139.211] by server-10.bemta-5.messagelabs.com id D9/61-19067-B4F98E95; Thu, 19 Oct 2017 12:49:15 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrCLMWRWlGSWpSXmKPExsVysyfVTdd7/ot Ig4/7xCy+b5nM5MDocfjDFZYAxijWzLyk/IoE1oyzW5wKdmhV7H/5ibWBsUWxi5GTQ0hgM6PE lqvWEPZyRon1S8RBbDYBXYkdN18zg9giAhESpx9fYgKxmQWUJPafvcbYxcjBISzgJHF+BitIm EVAVWL7iqdMIGFeAWuJ9YeUQMISAvIS5x7cBpvCCRS+vfcGI8QmK4ltD98xTmDkXsDIsIpRoz i1qCy1SNfIQC+pKDM9oyQ3MTNH19DAVC83tbg4MT01JzGpWC85P3cTI9Cv9QwMjDsYG2f7HWK U5GBSEuX9WPUiUogvKT+lMiOxOCO+qDQntfgQowwHh5IE7+G5QDnBotT01Iq0zBxggMGkJTh4 lER4vecBpXmLCxJzizPTIVKnGI05fky68oeJo+Pm3T9MQix5+XmpUuK8d0EmCYCUZpTmwQ2CB f4lRlkpYV5GBgYGIZ6C1KLczBJU+VeM4hyMSsK8z0Cm8GTmlcDtewV0ChPQKez2YKeUJCKkpB oYBT3untnloqb+OePa8o2FrP+ernobYLYkeOX/x31zSzhmde2T/BL99FiO1vrd0ckqEgaqKuE a0VO1pe6IXV+VWRf4adv2j8uKo/LmJWvV/3p0rO7p1D89kprPF+2Me7nj6pcFm/cKLvXabb6/ Lpjvs+yTOdGujImur/h+uR28pq4p+qIg99vLY0osxRmJhlrMRcWJAEskpyp3AgAA X-Env-Sender: andre.przywara@arm.com X-Msg-Ref: server-6.tower-206.messagelabs.com!1508417354!104887120!1 X-Originating-IP: [217.140.101.70] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.4.45; banners=-,-,- X-VirusChecked: Checked Received: (qmail 28344 invoked from network); 19 Oct 2017 12:49:15 -0000 Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by server-6.tower-206.messagelabs.com with SMTP; 19 Oct 2017 12:49:15 -0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6EE591596; Thu, 19 Oct 2017 05:49:14 -0700 (PDT) Received: from e104803-lin.lan (unknown [10.1.207.46]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 82F813F3E1; Thu, 19 Oct 2017 05:49:13 -0700 (PDT) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Thu, 19 Oct 2017 13:48:45 +0100 Message-Id: <20171019124847.5978-11-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171019124847.5978-1-andre.przywara@arm.com> References: <20171019124847.5978-1-andre.przywara@arm.com> Cc: xen-devel@lists.xenproject.org Subject: [Xen-devel] [PATCH 10/12] ARM: VGIC: factor out vgic_connect_hw_irq() X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP At the moment we happily access VGIC internal data structures like the rank and struct pending_irq in gic.c, which should be VGIC agnostic. Factor out a new function vgic_connect_hw_irq(), which allows a virtual IRQ to be connected to a hardware IRQ (using the hw bit in the LR). This removes said accesses to VGIC data structures and improves abstraction. Signed-off-by: Andre Przywara Acked-by: Stefano Stabellini --- xen/arch/arm/gic-vgic.c | 31 +++++++++++++++++++++++++++++++ xen/arch/arm/gic.c | 42 ++++++------------------------------------ xen/include/asm-arm/vgic.h | 2 ++ 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/xen/arch/arm/gic-vgic.c b/xen/arch/arm/gic-vgic.c index 66cae21e82..bf9455a34e 100644 --- a/xen/arch/arm/gic-vgic.c +++ b/xen/arch/arm/gic-vgic.c @@ -385,6 +385,37 @@ void gic_inject(struct vcpu *v) gic_hw_ops->update_hcr_status(GICH_HCR_UIE, 1); } +int vgic_connect_hw_irq(struct domain *d, struct vcpu *v, unsigned int virq, + struct irq_desc *desc) +{ + unsigned long flags; + /* Use vcpu0 to retrieve the pending_irq struct. Given that we only + * route SPIs to guests, it doesn't make any difference. */ + struct vcpu *v_target = vgic_get_target_vcpu(d->vcpu[0], virq); + struct vgic_irq_rank *rank = vgic_rank_irq(v_target, virq); + struct pending_irq *p = irq_to_pending(v_target, virq); + int ret = 0; + + /* We are taking to rank lock to prevent parallel connections. */ + vgic_lock_rank(v_target, rank, flags); + + if ( desc ) + { + /* The VIRQ should not be already enabled by the guest */ + if ( !p->desc && + !test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) ) + p->desc = desc; + else + ret = -EBUSY; + } + else + p->desc = NULL; + + vgic_unlock_rank(v_target, rank, flags); + + return ret; +} + /* * Local variables: * mode: C diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 4cb74d449e..d46a6d54b3 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -128,27 +128,12 @@ void gic_route_irq_to_xen(struct irq_desc *desc, unsigned int priority) int gic_route_irq_to_guest(struct domain *d, unsigned int virq, struct irq_desc *desc, unsigned int priority) { - unsigned long flags; - /* Use vcpu0 to retrieve the pending_irq struct. Given that we only - * route SPIs to guests, it doesn't make any difference. */ - struct vcpu *v_target = vgic_get_target_vcpu(d->vcpu[0], virq); - struct vgic_irq_rank *rank = vgic_rank_irq(v_target, virq); - struct pending_irq *p = irq_to_pending(v_target, virq); - int res = -EBUSY; - ASSERT(spin_is_locked(&desc->lock)); /* Caller has already checked that the IRQ is an SPI */ ASSERT(virq >= 32); ASSERT(virq < vgic_num_irqs(d)); ASSERT(!is_lpi(virq)); - vgic_lock_rank(v_target, rank, flags); - - if ( p->desc || - /* The VIRQ should not be already enabled by the guest */ - test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) ) - goto out; - desc->handler = gic_hw_ops->gic_guest_irq_type; set_bit(_IRQ_GUEST, &desc->status); @@ -156,31 +141,19 @@ int gic_route_irq_to_guest(struct domain *d, unsigned int virq, gic_set_irq_type(desc, desc->arch.type); gic_set_irq_priority(desc, priority); - p->desc = desc; - res = 0; - -out: - vgic_unlock_rank(v_target, rank, flags); - - return res; + return vgic_connect_hw_irq(d, NULL, virq, desc); } /* This function only works with SPIs for now */ int gic_remove_irq_from_guest(struct domain *d, unsigned int virq, struct irq_desc *desc) { - struct vcpu *v_target = vgic_get_target_vcpu(d->vcpu[0], virq); - struct vgic_irq_rank *rank = vgic_rank_irq(v_target, virq); - struct pending_irq *p = irq_to_pending(v_target, virq); - unsigned long flags; + int ret; ASSERT(spin_is_locked(&desc->lock)); ASSERT(test_bit(_IRQ_GUEST, &desc->status)); - ASSERT(p->desc == desc); ASSERT(!is_lpi(virq)); - vgic_lock_rank(v_target, rank, flags); - if ( d->is_dying ) { desc->handler->shutdown(desc); @@ -198,19 +171,16 @@ int gic_remove_irq_from_guest(struct domain *d, unsigned int virq, */ if ( test_bit(_IRQ_INPROGRESS, &desc->status) || !test_bit(_IRQ_DISABLED, &desc->status) ) - { - vgic_unlock_rank(v_target, rank, flags); return -EBUSY; - } } + ret = vgic_connect_hw_irq(d, NULL, virq, NULL); + if ( ret ) + return ret; + clear_bit(_IRQ_GUEST, &desc->status); desc->handler = &no_irq_type; - p->desc = NULL; - - vgic_unlock_rank(v_target, rank, flags); - return 0; } diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h index dcdb1acaf3..cf02dc6394 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -220,6 +220,8 @@ int vgic_v2_init(struct domain *d, int *mmio_count); int vgic_v3_init(struct domain *d, int *mmio_count); bool vgic_evtchn_irq_pending(struct vcpu *v); +int vgic_connect_hw_irq(struct domain *d, struct vcpu *v, unsigned int virq, + struct irq_desc *desc); extern int domain_vgic_register(struct domain *d, int *mmio_count); extern int vcpu_vgic_free(struct vcpu *v);