From patchwork Fri Jun 9 17:41:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 9779023 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 98A9A60318 for ; Fri, 9 Jun 2017 17:44:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 84E8A286E0 for ; Fri, 9 Jun 2017 17:44:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 797C9286F9; Fri, 9 Jun 2017 17:44:12 +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 90E8D286E0 for ; Fri, 9 Jun 2017 17:44:11 +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 1dJNv1-0003VI-GL; Fri, 09 Jun 2017 17:41:55 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dJNv0-0003UA-Le for xen-devel@lists.xenproject.org; Fri, 09 Jun 2017 17:41:54 +0000 Received: from [193.109.254.147] by server-9.bemta-6.messagelabs.com id 37/43-03557-2EDDA395; Fri, 09 Jun 2017 17:41:54 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrGLMWRWlGSWpSXmKPExsVysyfVTffhXat Ig2mfpCy+b5nM5MDocfjDFZYAxijWzLyk/IoE1ozdf3azFlzXqfj37CdrA+Ne5S5GLg4hgc2M EvO+TmWFcJYzSlxe/Iy5i5GTg01AV2LHzddgtohAqMTTBd+ZQYqYBa4zSpzeMZ+ti5GDQ1ggT KLxrwtIDYuAqsSNTVuZQcK8AtYSex+xgoQlBOQkGs7fBxvDCRTetmctG4gtJGAl0XLoMvsERu 4FjAyrGDWKU4vKUot0Dc30kooy0zNKchMzc3QNDcz0clOLixPTU3MSk4r1kvNzNzEC/csABDs Y728MOMQoycGkJMo7rcAqUogvKT+lMiOxOCO+qDQntfgQowwHh5IEb88doJxgUWp6akVaZg4w 0GDSEhw8SiK8L04CpXmLCxJzizPTIVKnGBWlxHmdgOEpJACSyCjNg2uDBfclRlkpYV5GoEOEe ApSi3IzS1DlXzGKczAqCfPuAtnOk5lXAjf9FdBiJqDFS95ZgCwuSURISTUwRp10SxQ2/XZiuR GL1LeoDObWbc+i4nR/pkzlKjVwPNs+f+Y0q8h17lP5Cljjklct1s1NWfe460hAQcWEqBrVMxP 4amMOXCg0Np81YynrDz2F8jd/VBK45XJn/Olpcv7h/nfKiS+z503Tf6fEf05FL5gtQmLeyQqh t4b/pydkeOg/YhXl2X9AiaU4I9FQi7moOBEAiKA4aWkCAAA= X-Env-Sender: andre.przywara@arm.com X-Msg-Ref: server-8.tower-27.messagelabs.com!1497030112!96670135!1 X-Originating-IP: [217.140.101.70] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 9.4.19; banners=-,-,- X-VirusChecked: Checked Received: (qmail 10063 invoked from network); 9 Jun 2017 17:41:53 -0000 Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by server-8.tower-27.messagelabs.com with SMTP; 9 Jun 2017 17:41:53 -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 95B7C1596; Fri, 9 Jun 2017 10:41:52 -0700 (PDT) Received: from e104803-lin.lan (unknown [10.1.207.46]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2D0273F578; Fri, 9 Jun 2017 10:41:50 -0700 (PDT) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Fri, 9 Jun 2017 18:41:16 +0100 Message-Id: <20170609174141.5068-10-andre.przywara@arm.com> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170609174141.5068-1-andre.przywara@arm.com> References: <20170609174141.5068-1-andre.przywara@arm.com> Cc: xen-devel@lists.xenproject.org, Vijaya Kumar K , Vijay Kilari , Shanker Donthineni , Manish Jaggi Subject: [Xen-devel] [PATCH v11 09/34] ARM: GICv3: introduce separate pending_irq structs for LPIs 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 For the same reason that allocating a struct irq_desc for each possible LPI is not an option, having a struct pending_irq for each LPI is also not feasible. We only care about mapped LPIs, so we can get away with having struct pending_irq's only for them. Maintain a radix tree per domain where we drop the pointer to the respective pending_irq. The index used is the virtual LPI number. The memory for the actual structures has been allocated already per device at device mapping time. Teach the existing VGIC functions to find the right pointer when being given a virtual LPI number. Signed-off-by: Andre Przywara Acked-by: Julien Grall Reviewed-by: Stefano Stabellini --- xen/arch/arm/vgic-v2.c | 8 ++++++++ xen/arch/arm/vgic-v3.c | 30 ++++++++++++++++++++++++++++++ xen/arch/arm/vgic.c | 2 ++ xen/include/asm-arm/domain.h | 2 ++ xen/include/asm-arm/vgic.h | 2 ++ 5 files changed, 44 insertions(+) diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c index 5370020..ce2b96f 100644 --- a/xen/arch/arm/vgic-v2.c +++ b/xen/arch/arm/vgic-v2.c @@ -705,10 +705,18 @@ static void vgic_v2_domain_free(struct domain *d) /* Nothing to be cleanup for this driver */ } +static struct pending_irq *vgic_v2_lpi_to_pending(struct domain *d, + unsigned int vlpi) +{ + /* Dummy function, no LPIs on a VGICv2. */ + BUG(); +} + static const struct vgic_ops vgic_v2_ops = { .vcpu_init = vgic_v2_vcpu_init, .domain_init = vgic_v2_domain_init, .domain_free = vgic_v2_domain_free, + .lpi_to_pending = vgic_v2_lpi_to_pending, .max_vcpus = 8, }; diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c index 2b2b4e9..e116ae7 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -1457,6 +1457,9 @@ static int vgic_v3_domain_init(struct domain *d) d->arch.vgic.nr_regions = rdist_count; d->arch.vgic.rdist_regions = rdist_regions; + rwlock_init(&d->arch.vgic.pend_lpi_tree_lock); + radix_tree_init(&d->arch.vgic.pend_lpi_tree); + /* * Domain 0 gets the hardware address. * Guests get the virtual platform layout. @@ -1545,14 +1548,41 @@ static int vgic_v3_domain_init(struct domain *d) static void vgic_v3_domain_free(struct domain *d) { vgic_v3_its_free_domain(d); + /* + * It is expected that at this point all actual ITS devices have been + * cleaned up already. The struct pending_irq's, for which the pointers + * have been stored in the radix tree, are allocated and freed by device. + * On device unmapping all the entries are removed from the tree and + * the backing memory is freed. + */ + radix_tree_destroy(&d->arch.vgic.pend_lpi_tree, NULL); xfree(d->arch.vgic.rdist_regions); } +/* + * Looks up a virtual LPI number in our tree of mapped LPIs. This will return + * the corresponding struct pending_irq, which we also use to store the + * enabled and pending bit plus the priority. + * Returns NULL if an LPI cannot be found (or no LPIs are supported). + */ +static struct pending_irq *vgic_v3_lpi_to_pending(struct domain *d, + unsigned int lpi) +{ + struct pending_irq *pirq; + + read_lock(&d->arch.vgic.pend_lpi_tree_lock); + pirq = radix_tree_lookup(&d->arch.vgic.pend_lpi_tree, lpi); + read_unlock(&d->arch.vgic.pend_lpi_tree_lock); + + return pirq; +} + static const struct vgic_ops v3_ops = { .vcpu_init = vgic_v3_vcpu_init, .domain_init = vgic_v3_domain_init, .domain_free = vgic_v3_domain_free, .emulate_reg = vgic_v3_emulate_reg, + .lpi_to_pending = vgic_v3_lpi_to_pending, /* * We use both AFF1 and AFF0 in (v)MPIDR. Thus, the max number of CPU * that can be supported is up to 4096(==256*16) in theory. diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c index 1edf93d..2e4820f 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -469,6 +469,8 @@ struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq) * are used for SPIs; the rests are used for per cpu irqs */ if ( irq < 32 ) n = &v->arch.vgic.pending_irqs[irq]; + else if ( is_lpi(irq) ) + n = v->domain->arch.vgic.handler->lpi_to_pending(v->domain, irq); else n = &v->domain->arch.vgic.pending_irqs[irq - 32]; return n; diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h index 7c3829d..3d8e84c 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -111,6 +111,8 @@ struct arch_domain uint32_t rdist_stride; /* Re-Distributor stride */ struct rb_root its_devices; /* Devices mapped to an ITS */ spinlock_t its_devices_lock; /* Protects the its_devices tree */ + struct radix_tree_root pend_lpi_tree; /* Stores struct pending_irq's */ + rwlock_t pend_lpi_tree_lock; /* Protects the pend_lpi_tree */ unsigned int intid_bits; #endif } vgic; diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h index df75064..c9075a9 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -134,6 +134,8 @@ struct vgic_ops { void (*domain_free)(struct domain *d); /* vGIC sysreg/cpregs emulate */ bool (*emulate_reg)(struct cpu_user_regs *regs, union hsr hsr); + /* lookup the struct pending_irq for a given LPI interrupt */ + struct pending_irq *(*lpi_to_pending)(struct domain *d, unsigned int vlpi); /* Maximum number of vCPU supported */ const unsigned int max_vcpus; };