From patchwork Fri Mar 31 18:05:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 9657115 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 6E93B60350 for ; Fri, 31 Mar 2017 18:06:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 62F72286B7 for ; Fri, 31 Mar 2017 18:06:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 56973286EF; Fri, 31 Mar 2017 18:06:14 +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 D4049286F2 for ; Fri, 31 Mar 2017 18:06:13 +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 1cu0tj-0005QU-1i; Fri, 31 Mar 2017 18:03:43 +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-0005OI-TO for xen-devel@lists.xenproject.org; Fri, 31 Mar 2017 18:03:42 +0000 Received: from [85.158.137.68] by server-16.bemta-3.messagelabs.com id EB/5B-06437-DF99ED85; Fri, 31 Mar 2017 18:03:41 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrCLMWRWlGSWpSXmKPExsVysyfVTffPzHs RBisPaVh83zKZyYHR4/CHKywBjFGsmXlJ+RUJrBlPl+xmLrivWfH2UitrA+MrhS5GLg4hgU2M Ei83zGCGcJYzSnyY2MTSxcjJwSagK7Hj5mtmEFtEIFTi6YLvQDYHB7NApUT3In4QU1jAReLx+ QoQk0VAVWLN+RCQYl4BG4mvH46ANUoIyEk0nL8PZnMCxefv+sEKYgsJWEs0fLrLPIGRewEjwy pGjeLUorLUIl0jE72kosz0jJLcxMwcXUMDY73c1OLixPTUnMSkYr3k/NxNjEDf1jMwMO5gfHX c7xCjJAeTkijv9+J7EUJ8SfkplRmJxRnxRaU5qcWHGGU4OJQkeK/PAMoJFqWmp1akZeYAgwwm LcHBoyTC+wAkzVtckJhbnJkOkTrFqCglznsMJCEAksgozYNrgwX2JUZZKWFeRgYGBiGegtSi3 MwSVPlXjOIcjErCvKrAOBHiycwrgZv+CmgxE9Bii693QRaXJCKkpBoYg43VJNdY/2BsWND20S J/9cLyyk3Vp6re3Ht3uMJqZaiZ+dxiiX8n7GP0ZWXm9/y7v2Dm+SD5XT7Ox0SXbd+60Obw/+s Tcx4pVO5c+FCO2YjRuPjVXf3qzZkFdwSX7VoYmjSv+GHSxsOaT9RufbthI2vnNm256LKsZlZP D6lHYeIGxY8rZ0k8VmIpzkg01GIuKk4EABdjJfVnAgAA X-Env-Sender: andre.przywara@arm.com X-Msg-Ref: server-8.tower-31.messagelabs.com!1490983420!93343734!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 48618 invoked from network); 31 Mar 2017 18:03:40 -0000 Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by server-8.tower-31.messagelabs.com with SMTP; 31 Mar 2017 18:03:40 -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 B4A64B16; Fri, 31 Mar 2017 11:03:39 -0700 (PDT) Received: from e104803-lin.lan (unknown [10.1.207.46]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id D14FE3F59A; Fri, 31 Mar 2017 11:03:38 -0700 (PDT) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Fri, 31 Mar 2017 19:05:08 +0100 Message-Id: <20170331180525.30038-10-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 09/26] ARM: GICv3: forward pending LPIs to guests 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 Upon receiving an LPI, we need to find the right VCPU and virtual IRQ number to get this IRQ injected. Iterate our two-level LPI table to find this information quickly when the host takes an LPI. Call the existing injection function to let the GIC emulation deal with this interrupt. Signed-off-by: Andre Przywara --- xen/arch/arm/gic-v3-lpi.c | 42 ++++++++++++++++++++++++++++++++++++++++++ xen/arch/arm/gic.c | 8 +++++++- xen/arch/arm/vgic-v3.c | 11 +++++++++++ xen/arch/arm/vgic.c | 9 ++++++++- xen/include/asm-arm/irq.h | 2 ++ xen/include/asm-arm/vgic.h | 2 ++ 6 files changed, 72 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/gic-v3-lpi.c b/xen/arch/arm/gic-v3-lpi.c index d642cc5..df75cf6 100644 --- a/xen/arch/arm/gic-v3-lpi.c +++ b/xen/arch/arm/gic-v3-lpi.c @@ -115,6 +115,48 @@ uint64_t gicv3_get_redist_address(unsigned int cpu, bool use_pta) return per_cpu(lpi_redist, cpu).redist_id << 16; } +/* + * Handle incoming LPIs, which are a bit special, because they are potentially + * numerous and also only get injected into guests. Treat them specially here, + * by just looking up their target vCPU and virtual LPI number and hand it + * over to the injection function. + */ +void do_LPI(unsigned int lpi) +{ + struct domain *d; + union host_lpi *hlpip, hlpi; + struct vcpu *vcpu; + + WRITE_SYSREG32(lpi, ICC_EOIR1_EL1); + + hlpip = gic_get_host_lpi(lpi); + if ( !hlpip ) + return; + + hlpi.data = read_u64_atomic(&hlpip->data); + + /* Unmapped events are marked with an invalid LPI ID. */ + if ( hlpi.virt_lpi == INVALID_LPI ) + return; + + d = rcu_lock_domain_by_id(hlpi.dom_id); + if ( !d ) + return; + + /* Make sure we don't step beyond the vcpu array. */ + if ( hlpi.vcpu_id >= d->max_vcpus ) + { + rcu_unlock_domain(d); + return; + } + + vcpu = d->vcpu[hlpi.vcpu_id]; + + vgic_vcpu_inject_irq(vcpu, hlpi.virt_lpi); + + rcu_unlock_domain(d); +} + static int gicv3_lpi_allocate_pendtable(uint64_t *reg) { uint64_t val; diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 6a5c882..41cd2d1 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -710,7 +710,13 @@ void gic_interrupt(struct cpu_user_regs *regs, int is_fiq) do_IRQ(regs, irq, is_fiq); local_irq_disable(); } - else if (unlikely(irq < 16)) +#ifdef CONFIG_HAS_ITS + else if ( is_lpi(irq) ) + { + do_LPI(irq); + } +#endif + else if ( unlikely(irq < 16) ) { do_sgi(regs, irq); } diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c index 29c97eb..69572e3 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -348,6 +348,17 @@ struct pending_irq *lpi_to_pending(struct domain *d, unsigned int lpi) return pirq; } +/* Retrieve the priority of an LPI from its struct pending_irq. */ +int vgic_lpi_get_priority(struct domain *d, uint32_t vlpi) +{ + struct pending_irq *p = lpi_to_pending(d, vlpi); + + if ( !p ) + return GIC_PRI_IRQ; + + return p->lpi_priority; +} + static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info, uint32_t gicr_reg, register_t r) diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c index 15c8ef8..2aee20f 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -244,10 +244,17 @@ struct vcpu *vgic_get_target_vcpu(struct vcpu *v, unsigned int virq) static int vgic_get_virq_priority(struct vcpu *v, unsigned int virq) { - struct vgic_irq_rank *rank = vgic_rank_irq(v, virq); + struct vgic_irq_rank *rank; unsigned long flags; int priority; +#ifdef CONFIG_HAS_ITS + /* LPIs don't have a rank, also store their priority separately. */ + if ( is_lpi(virq) ) + return vgic_lpi_get_priority(v->domain, virq); +#endif + + rank = vgic_rank_irq(v, virq); vgic_lock_rank(v, rank, flags); priority = rank->priority[virq & INTERRUPT_RANK_MASK]; vgic_unlock_rank(v, rank, flags); diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h index d16affc..3fdf1e0 100644 --- a/xen/include/asm-arm/irq.h +++ b/xen/include/asm-arm/irq.h @@ -47,6 +47,8 @@ static inline bool is_lpi(unsigned int irq) return irq >= LPI_OFFSET; } +void do_LPI(unsigned int irq); + #define domain_pirq_to_irq(d, pirq) (pirq) bool_t is_assignable_irq(unsigned int irq); diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h index e6dad38..eabdf91 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -66,12 +66,14 @@ struct pending_irq #define GIC_IRQ_GUEST_VISIBLE 2 #define GIC_IRQ_GUEST_ENABLED 3 #define GIC_IRQ_GUEST_MIGRATING 4 +#define GIC_IRQ_GUEST_LPI_PENDING 5 unsigned long status; struct irq_desc *desc; /* only set it the irq corresponds to a physical irq */ unsigned int irq; #define GIC_INVALID_LR (uint8_t)~0 uint8_t lr; uint8_t priority; + uint8_t lpi_priority; /* Caches the priority if this is an LPI. */ /* inflight is used to append instances of pending_irq to * vgic.inflight_irqs */ struct list_head inflight;