From patchwork Fri Mar 31 18:05:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 9657107 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 4DD3060350 for ; Fri, 31 Mar 2017 18:06:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 42217286EF for ; Fri, 31 Mar 2017 18:06:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 36F34286F2; Fri, 31 Mar 2017 18:06:13 +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 BBA9F286EF for ; Fri, 31 Mar 2017 18:06:12 +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 1cu0ti-0005Pu-QT; Fri, 31 Mar 2017 18:03:42 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cu0th-0005Nl-Bv for xen-devel@lists.xenproject.org; Fri, 31 Mar 2017 18:03:41 +0000 Received: from [85.158.137.68] by server-4.bemta-3.messagelabs.com id 0A/36-03705-CF99ED85; Fri, 31 Mar 2017 18:03:40 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrGLMWRWlGSWpSXmKPExsVysyfVTff3zHs RBisvKVh83zKZyYHR4/CHKywBjFGsmXlJ+RUJrBkr5rSwFGzQqmjoa2ZrYGxU6mLk4hAS2MQo sfbHBBYIZzmjxMzb65m6GDk52AR0JXbcfM0MYosIhEo8XfAdyObgYBaolOhexA8SFgYKbzzfx AhiswioSrzZuoEVxOYVsJY4smkyWKuEgJxEw/n7YDangI3E/F0/wGqEgGoaPt1lnsDIvYCRYR WjRnFqUVlqka6RhV5SUWZ6RkluYmaOrqGBsV5uanFxYnpqTmJSsV5yfu4mRqB/6xkYGHcwtp/ wO8QoycGkJMr7vfhehBBfUn5KZUZicUZ8UWlOavEhRhkODiUJ3uszgHKCRanpqRVpmTnAQINJ S3DwKInwPgBJ8xYXJOYWZ6ZDpE4xKkqJ87oDw1NIACSRUZoH1wYL7kuMslLCvIwMDAxCPAWpR bmZJajyrxjFORiVhHlfgIznycwrgZv+CmgxE9Bii693QRaXJCKkpBoYs0456Xrxzd+1XvBasN 3MRX3Z36ds+dHvc+fJNSvF5PUSAsLToybf0UqJNJJU4pTxzeVs/MCdNyXs7YeFX+OyFrgZit9 375xu3tOs/nrzk9k7k1btbOQQFmfgv6Yz127d/rioycf8mu9ceRIasG6Ce5HRjH+NQac/6nEn huy3dit/8+bPo1YWJZbijERDLeai4kQAP2GEnWkCAAA= X-Env-Sender: andre.przywara@arm.com X-Msg-Ref: server-2.tower-31.messagelabs.com!1490983418!81594393!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.2.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 7707 invoked from network); 31 Mar 2017 18:03:39 -0000 Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by server-2.tower-31.messagelabs.com with SMTP; 31 Mar 2017 18:03:39 -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 96C2880D; Fri, 31 Mar 2017 11:03:38 -0700 (PDT) Received: from e104803-lin.lan (unknown [10.1.207.46]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B2FF73F59A; Fri, 31 Mar 2017 11:03:37 -0700 (PDT) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Fri, 31 Mar 2017 19:05:07 +0100 Message-Id: <20170331180525.30038-9-andre.przywara@arm.com> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170331180525.30038-1-andre.przywara@arm.com> References: <20170331180525.30038-1-andre.przywara@arm.com> Cc: xen-devel@lists.xenproject.org, Shanker Donthineni , Vijay Kilari Subject: [Xen-devel] [PATCH v3 08/26] 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 a5348f2..6a5c882 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -462,7 +462,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 6242252..29c97eb 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -331,6 +331,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) @@ -1453,6 +1470,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. @@ -1526,6 +1546,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 364d5f0..15c8ef8 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -449,10 +449,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 e559027..a83904a 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -112,6 +112,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 467333c..e6dad38 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -298,6 +298,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);