From patchwork Wed Apr 5 23:19:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 9665867 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 E833A60364 for ; Wed, 5 Apr 2017 23:22:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D9FE82816B for ; Wed, 5 Apr 2017 23:22:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CED7F2858A; Wed, 5 Apr 2017 23:22:45 +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 C4C9B28584 for ; Wed, 5 Apr 2017 23:22:44 +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 1cvuEU-0004ea-GS; Wed, 05 Apr 2017 23:20:58 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cvuET-0004bz-2l for xen-devel@lists.xenproject.org; Wed, 05 Apr 2017 23:20:57 +0000 Received: from [193.109.254.147] by server-2.bemta-6.messagelabs.com id FB/92-19731-8DB75E85; Wed, 05 Apr 2017 23:20:56 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrKLMWRWlGSWpSXmKPExsVysyfVTfd69dM Ig01PTC2+b5nM5MDocfjDFZYAxijWzLyk/IoE1ozJXfPZC96qV7xsamRvYPwn38XIxSEksIlR orWtkw3C2csosb75NFMXIycHm4CuxI6br5lBbBGBUIk5Px8B2RwczAKVEt2L+EHCwkDhLdePg pWwCKhKzHv1C8zmFXCXeLprPTtIuYSAnMSVfwkgYU6g8MvWYywgtpCAm8S1iVNZJjByL2BkWM WoUZxaVJZapGtooZdUlJmeUZKbmJmja2hgppebWlycmJ6ak5hUrJecn7uJEehdBiDYwXhzY8A hRkkOJiVRXgWfJxFCfEn5KZUZicUZ8UWlOanFhxhlODiUJHi3VT2NEBIsSk1PrUjLzAGGGUxa goNHSYT3PUiat7ggMbc4Mx0idYpRUUqcdxNIQgAkkVGaB9cGC+1LjLJSwryMQIcI8RSkFuVml qDKv2IU52BUEublBkaKEE9mXgnc9FdAi5mAFj+58xBkcUkiQkqqgdHi0fTUmusFd+7tLNzcyy Uk4C5Vd+G7/Po7HAdmZ27ZweeZaRj2tFn+o8WheNuPL+5HPZ5838czXbjPqGzjzfB1h8wmKe/ QDFI5KNAyK2NOuKP2JssljGv9lE163FvOvlfdVBi3I6SiYO3z2RPd4pw+pt7Ljb+7/8hSqyn2 Ws8lbqW835a6VleJpTgj0VCLuag4EQAD90lgaAIAAA== X-Env-Sender: andre.przywara@arm.com X-Msg-Ref: server-7.tower-27.messagelabs.com!1491434455!91318239!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.12; banners=-,-,- X-VirusChecked: Checked Received: (qmail 8220 invoked from network); 5 Apr 2017 23:20:55 -0000 Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by server-7.tower-27.messagelabs.com with SMTP; 5 Apr 2017 23:20:55 -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 09D41B16; Wed, 5 Apr 2017 16:20:55 -0700 (PDT) Received: from slackpad.lan (usa-sjc-mx-foss1.foss.arm.com [217.140.101.70]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BD9F73F4FF; Wed, 5 Apr 2017 16:20:53 -0700 (PDT) From: Andre Przywara To: Stefano Stabellini , Julien Grall Date: Thu, 6 Apr 2017 00:19:04 +0100 Message-Id: <1491434362-30310-13-git-send-email-andre.przywara@arm.com> X-Mailer: git-send-email 2.8.2 In-Reply-To: <1491434362-30310-1-git-send-email-andre.przywara@arm.com> References: <1491434362-30310-1-git-send-email-andre.przywara@arm.com> Cc: xen-devel@lists.xenproject.org, Shanker Donthineni , Vijay Kilari Subject: [Xen-devel] [PATCH v5 12/30] 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 --- xen/arch/arm/vgic-v2.c | 8 ++++++++ xen/arch/arm/vgic-v3.c | 22 ++++++++++++++++++++++ xen/arch/arm/vgic.c | 2 ++ xen/include/asm-arm/domain.h | 2 ++ xen/include/asm-arm/vgic.h | 2 ++ 5 files changed, 36 insertions(+) diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c index 0674f7b..3cad68f 100644 --- a/xen/arch/arm/vgic-v2.c +++ b/xen/arch/arm/vgic-v2.c @@ -703,10 +703,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 142eb64..5128f13 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -1451,6 +1451,9 @@ static int vgic_v3_domain_init(struct domain *d) vgic_v3_its_init_domain(d); + 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. @@ -1524,14 +1527,33 @@ static int vgic_v3_domain_init(struct domain *d) static void vgic_v3_domain_free(struct domain *d) { vgic_v3_its_free_domain(d); + 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). + */ +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 67d75a6..d704d7c 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -435,6 +435,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 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..7c86f5b 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; };