From patchwork Mon Apr 3 20:28:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 9660589 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 6A7266032D for ; Mon, 3 Apr 2017 20:29:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 57DAE28403 for ; Mon, 3 Apr 2017 20:29:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4CE4A2841C; Mon, 3 Apr 2017 20:29:26 +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 D0B8328403 for ; Mon, 3 Apr 2017 20:29:25 +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 1cv8Yl-0004x7-NX; Mon, 03 Apr 2017 20:26:43 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cv8Yk-0004uh-JB for xen-devel@lists.xenproject.org; Mon, 03 Apr 2017 20:26:42 +0000 Received: from [85.158.143.35] by server-4.bemta-6.messagelabs.com id 5E/03-03012-200B2E85; Mon, 03 Apr 2017 20:26:42 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrGLMWRWlGSWpSXmKPExsVysyfVTZdxw6M Ig1kLtCy+b5nM5MDocfjDFZYAxijWzLyk/IoE1oyjn1eyF2zQqujZfYGtgbFRqYuRi0NIYCOj xKe216wQznJGiQtdHUAOJwebgK7EjpuvmUFsEYFQiacLvoPZzAJKEvvPXmMEsYWB4seP3mHqY uTgYBFQlVh3IhkkzCtgLTFnUQdYiYSAnETD+ftgrZxA8daPR8HiQgJWEhMeNjFNYORewMiwil GjOLWoLLVI19BEL6koMz2jJDcxM0fX0MBMLze1uDgxPTUnMalYLzk/dxMj0L8MQLCD8frGgEO MkhxMSqK86pMeRQjxJeWnVGYkFmfEF5XmpBYfYpTh4FCS4D22DignWJSanlqRlpkDDDSYtAQH j5II72aQNG9xQWJucWY6ROoUo6KUOC//eqCEAEgiozQPrg0W3JcYZaWEeRmBDhHiKUgtys0sQ ZV/xSjOwagkzPtiLdAUnsy8Erjpr4AWMwEtfnLnIcjikkSElFQD4+wVCmErVVreKwfd0Xeyln vbkvX2zj+egzvy3l+z8v53IG5Gv3a1VUfN7Ycvs7dpaS++cI/R/Y29/GftB+3XQ+Y94gkz+D0 5YGGRzZ6n312+B01Idey8dcuxO9NJOuXMYttVecbX2RW4AiUO8XLXFV86Gzjp2HwJlliz49FK nd9L/mVVtdZ8VmIpzkg01GIuKk4EAHzNMwBpAgAA X-Env-Sender: andre.przywara@arm.com X-Msg-Ref: server-5.tower-21.messagelabs.com!1491251199!53901271!2 X-Originating-IP: [217.140.101.70] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.2.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 27723 invoked from network); 3 Apr 2017 20:26:41 -0000 Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by server-5.tower-21.messagelabs.com with SMTP; 3 Apr 2017 20:26:41 -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 297C62B; Mon, 3 Apr 2017 13:26:41 -0700 (PDT) Received: from e104803-lin.lan (unknown [10.1.207.46]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 687AE3F4FF; Mon, 3 Apr 2017 13:26:40 -0700 (PDT) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Mon, 3 Apr 2017 21:28:11 +0100 Message-Id: <20170403202829.7278-10-andre.przywara@arm.com> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170403202829.7278-1-andre.przywara@arm.com> References: <20170403202829.7278-1-andre.przywara@arm.com> Cc: xen-devel@lists.xenproject.org Subject: [Xen-devel] [PATCH v4 09/27] 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. We also take care of checking for a NULL pointer in the VCPU exit path, should an LPI have been removed from the tree for any reason. Signed-off-by: Andre Przywara --- xen/arch/arm/gic.c | 12 ++++++++++++ xen/arch/arm/vgic-v3.c | 21 +++++++++++++++++++++ xen/arch/arm/vgic.c | 5 +++++ xen/include/asm-arm/domain.h | 2 ++ xen/include/asm-arm/vgic.h | 1 + 5 files changed, 41 insertions(+) diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 9522c6c..3ed6f81 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -461,7 +461,19 @@ static void gic_update_one_lr(struct vcpu *v, int i) gic_hw_ops->read_lr(i, &lr_val); irq = lr_val.virq; + p = irq_to_pending(v, irq); + /* An LPI might have been unmapped, in which case we just clean up here. */ + if ( !p ) + { + ASSERT(is_lpi(irq)); + + gic_hw_ops->clear_lr(i); + clear_bit(i, &this_cpu(lr_mask)); + + return; + } + if ( lr_val.state & GICH_LR_ACTIVE ) { set_bit(GIC_IRQ_GUEST_ACTIVE, &p->status); diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c index 3c7161b..95fa0ba 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -330,6 +330,23 @@ read_unknown: return 1; } +/* + * 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. + */ +struct pending_irq *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 int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info, uint32_t gicr_reg, register_t r) @@ -1452,6 +1469,9 @@ static int vgic_v3_domain_init(struct domain *d) spin_lock_init(&d->arch.vgic.its_devices_lock); d->arch.vgic.its_devices = RB_ROOT; + 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. @@ -1525,6 +1545,7 @@ static int vgic_v3_domain_init(struct domain *d) static void vgic_v3_domain_free(struct domain *d) { gicv3_its_unmap_all_devices(d); + radix_tree_destroy(&d->arch.vgic.pend_lpi_tree, NULL); xfree(d->arch.vgic.rdist_regions); } diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c index 67d75a6..28f6f66 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -431,10 +431,15 @@ bool vgic_to_sgi(struct vcpu *v, register_t sgir, enum gic_sgi_mode irqmode, struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq) { struct pending_irq *n; + /* Pending irqs allocation strategy: the first vgic.nr_spis irqs * are used for SPIs; the rests are used for per cpu irqs */ if ( irq < 32 ) n = &v->arch.vgic.pending_irqs[irq]; +#ifdef CONFIG_HAS_ITS + else if ( is_lpi(irq) ) + n = lpi_to_pending(v->domain, irq); +#endif 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 503a3cf..6ee7538 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 */ #endif } vgic; diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h index 894c3f1..69ef160 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -300,6 +300,7 @@ extern void vgic_vcpu_inject_spi(struct domain *d, unsigned int virq); extern void vgic_clear_pending_irqs(struct vcpu *v); extern struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq); extern struct pending_irq *spi_to_pending(struct domain *d, unsigned int irq); +extern struct pending_irq *lpi_to_pending(struct domain *d, unsigned int irq); extern struct vgic_irq_rank *vgic_rank_offset(struct vcpu *v, int b, int n, int s); extern struct vgic_irq_rank *vgic_rank_irq(struct vcpu *v, unsigned int irq); extern bool vgic_emulate(struct cpu_user_regs *regs, union hsr hsr);