xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Julien Grall <julien.grall@linaro.org>
To: xen-devel@lists.xenproject.org
Cc: stefano.stabellini@citrix.com,
	Julien Grall <julien.grall@linaro.org>,
	tim@xen.org, ian.campbell@citrix.com
Subject: [PATCH v2 09/21] xen/arm: Release IRQ routed to a domain when it's destroying
Date: Thu, 31 Jul 2014 16:00:40 +0100	[thread overview]
Message-ID: <1406818852-31856-10-git-send-email-julien.grall@linaro.org> (raw)
In-Reply-To: <1406818852-31856-1-git-send-email-julien.grall@linaro.org>

Xen has to release IRQ routed to a domain in order to reuse later. Currently
only SPIs can be routed to the guest so we only need to browse SPIs for a
specific domain.

Futhermore, a guest can crash and let the IRQ in an incorrect state (i.e has
not being EOIed). Xen will have to reset the IRQ in order to be able to reuse
the IRQ later.

Introduce 2 new functions for release an IRQ routed to a domain:
    - release_guest_irq: upper level to retrieve the IRQ, call the GIC
    code and release the action
    - gic_remove_guest_irq: Check if we can remove the IRQ, and reset
    it if necessary

Signed-off-by: Julien Grall <julien.grall@linaro.org>

---
    Changes in v2:
        - Drop the desc->handler = &no_irq_type in release_irq as it's
        buggy the IRQ is routed to Xen
        - Add release_guest_irq and gic_remove_guest_irq
---
 xen/arch/arm/gic.c        |   36 ++++++++++++++++++++++++++++++++++
 xen/arch/arm/irq.c        |   48 +++++++++++++++++++++++++++++++++++++++++++++
 xen/arch/arm/vgic.c       |   16 +++++++++++++++
 xen/include/asm-arm/gic.h |    4 ++++
 xen/include/asm-arm/irq.h |    2 ++
 5 files changed, 106 insertions(+)

diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 8ef8764..22f331a 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -144,6 +144,42 @@ void gic_route_irq_to_guest(struct domain *d, unsigned int virq,
     p->desc = desc;
 }
 
+/* This function only works with SPIs for now */
+int gic_remove_irq_from_guest(struct domain *d, unsigned int virq,
+                              struct irq_desc *desc)
+{
+    struct pending_irq *p = irq_to_pending(d->vcpu[0], virq);
+
+    ASSERT(spin_is_locked(&desc->lock));
+    ASSERT(test_bit(_IRQ_GUEST, &desc->status));
+    ASSERT(p->desc == desc);
+
+    /* If the IRQ is removed when the domain is dying, we only need to
+     * EOI the IRQ if it has not been done by the guest
+     */
+    if ( d->is_dying )
+    {
+        desc->handler->shutdown(desc);
+        if ( test_bit(_IRQ_INPROGRESS, &desc->status) )
+            gic_hw_ops->deactivate_irq(desc);
+        clear_bit(_IRQ_INPROGRESS, &desc->status);
+        goto end;
+    }
+
+    /* TODO: Handle eviction from LRs. For now, deny remove if the IRQ
+     * is inflight and not disabled.
+     */
+    if ( test_bit(_IRQ_INPROGRESS, &desc->status) ||
+         test_bit(_IRQ_DISABLED, &desc->status) )
+        return -EBUSY;
+
+end:
+    desc->handler = &no_irq_type;
+    p->desc = NULL;
+
+    return 0;
+}
+
 int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
                   unsigned int *out_hwirq,
                   unsigned int *out_type)
diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
index 7eeb8dd..ba33571 100644
--- a/xen/arch/arm/irq.c
+++ b/xen/arch/arm/irq.c
@@ -292,6 +292,7 @@ void release_irq(unsigned int irq, const void *dev_id)
     if ( !desc->action )
     {
         desc->handler->shutdown(desc);
+
         clear_bit(_IRQ_GUEST, &desc->status);
     }
 
@@ -479,6 +480,53 @@ out:
     return retval;
 }
 
+int release_guest_irq(struct domain *d, unsigned int virq)
+{
+    struct irq_desc *desc;
+    struct irq_guest *info;
+    unsigned long flags;
+    struct pending_irq *p;
+    int ret;
+
+    if ( virq >= vgic_num_irqs(d) )
+        return -EINVAL;
+
+    p = irq_to_pending(d->vcpu[0], virq);
+    if ( !p->desc )
+        return -EINVAL;
+
+    desc = p->desc;
+
+    spin_lock_irqsave(&desc->lock, flags);
+
+    ret = -EINVAL;
+    if ( !test_bit(_IRQ_GUEST, &desc->status) )
+        goto unlock;
+
+    ret = -EINVAL;
+
+    info = irq_get_guest_info(desc);
+    if ( d != info->d )
+        goto unlock;
+
+    ret = gic_remove_irq_from_guest(d, virq, desc);
+
+    spin_unlock_irqrestore(&desc->lock, flags);
+
+    if ( !ret )
+    {
+        release_irq(desc->irq, info);
+        xfree(info);
+    }
+
+    return ret;
+
+unlock:
+    spin_unlock_irqrestore(&desc->lock, flags);
+
+    return ret;
+}
+
 /*
  * pirq event channels. We don't use these on ARM, instead we use the
  * features of the GIC to inject virtualised normal interrupts.
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index a037ecc..2a5fc18 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -118,6 +118,22 @@ void register_vgic_ops(struct domain *d, const struct vgic_ops *ops)
 
 void domain_vgic_free(struct domain *d)
 {
+    int i;
+    int ret;
+
+    for ( i = 0; i < (d->arch.vgic.nr_spis); i++ )
+    {
+        struct pending_irq *p = &d->arch.vgic.pending_irqs[i];
+
+        if ( p->desc )
+        {
+            ret = release_guest_irq(d, p->irq);
+            if ( ret )
+                dprintk(XENLOG_G_WARNING, "d%u: Failed to release virq %u ret = %d\n",
+                        d->domain_id, p->irq, ret);
+        }
+    }
+
     xfree(d->arch.vgic.shared_irqs);
     xfree(d->arch.vgic.pending_irqs);
 }
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index 89816cd..46d7fd6 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -201,6 +201,10 @@ extern void gic_route_irq_to_guest(struct domain *, unsigned int virq,
                                    const cpumask_t *cpu_mask,
                                    unsigned int priority);
 
+/* Remove an IRQ passthrough to a guest */
+int gic_remove_irq_from_guest(struct domain *d, unsigned int virq,
+                              struct irq_desc *desc);
+
 extern void gic_inject(void);
 extern void gic_clear_pending_irqs(struct vcpu *v);
 extern int gic_events_need_delivery(void);
diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h
index a7174f3..d25e1a1 100644
--- a/xen/include/asm-arm/irq.h
+++ b/xen/include/asm-arm/irq.h
@@ -44,6 +44,8 @@ void init_secondary_IRQ(void);
 
 int route_irq_to_guest(struct domain *d, unsigned int virq,
                        unsigned int irq, const char *devname);
+int release_guest_irq(struct domain *d, unsigned int irq);
+
 void arch_move_irqs(struct vcpu *v);
 
 /* Set IRQ type for an SPI */
-- 
1.7.10.4

  parent reply	other threads:[~2014-07-31 15:01 UTC|newest]

Thread overview: 119+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-31 15:00 [PATCH v2 00/21] xen/arm: Add support for non-pci passthrough Julien Grall
2014-07-31 15:00 ` [PATCH v2 01/21] xen/common: do not implicitly permit access to mapped I/O memory Julien Grall
2014-07-31 15:22   ` Julien Grall
2014-07-31 15:00 ` [PATCH v2 02/21] xen: guestcopy: Provide an helper to safely copy string from guest Julien Grall
2014-08-01  8:40   ` Jan Beulich
2014-08-06 14:18     ` Julien Grall
2014-09-09 12:52     ` Ian Campbell
2014-09-09 13:17       ` Jan Beulich
2014-09-09 13:40         ` Ian Campbell
2014-08-06 13:56   ` Stefano Stabellini
2014-08-06 14:22     ` Julien Grall
2014-08-06 16:06   ` Daniel De Graaf
2014-07-31 15:00 ` [PATCH v2 03/21] xen/arm: vgic: Rename nr_lines into nr_spis Julien Grall
2014-08-06 13:58   ` Stefano Stabellini
2014-07-31 15:00 ` [PATCH v2 04/21] xen/arm: vgic: Introduce a function to initialize pending_irq Julien Grall
2014-08-06 14:06   ` Stefano Stabellini
2014-08-06 14:52     ` Julien Grall
2014-08-06 14:57       ` Stefano Stabellini
2014-07-31 15:00 ` [PATCH v2 05/21] xen/arm: follow-up to allow DOM0 manage IRQ and MMIO Julien Grall
2014-09-09 13:07   ` Ian Campbell
2014-09-11 22:32     ` Julien Grall
2014-09-12 10:13       ` Ian Campbell
2014-09-12 19:04         ` Julien Grall
2014-07-31 15:00 ` [PATCH v2 06/21] xen/arm: Allow virq != irq Julien Grall
2014-08-06 14:50   ` Stefano Stabellini
2014-08-06 15:07     ` Julien Grall
2014-08-06 16:48       ` Stefano Stabellini
2014-09-09 13:29   ` Ian Campbell
2014-09-09 18:42     ` Julien Grall
2014-09-11 22:50       ` Julien Grall
2014-09-12 10:13         ` Ian Campbell
2014-09-12 10:19         ` Ian Campbell
2014-07-31 15:00 ` [PATCH v2 07/21] xen/arm: route_irq_to_guest: Check validity of the IRQ Julien Grall
2014-08-06 14:56   ` Stefano Stabellini
2014-07-31 15:00 ` [PATCH v2 08/21] xen/arm: Initialize the virtual GIC later Julien Grall
2014-08-06 15:35   ` Stefano Stabellini
2014-09-09 13:35     ` Ian Campbell
2014-09-09 18:57       ` Julien Grall
2014-09-10 10:08         ` Ian Campbell
2014-09-11 23:01     ` Julien Grall
2014-09-12 10:14       ` Ian Campbell
2014-08-06 17:06   ` Daniel De Graaf
2014-08-29 13:09   ` Andrii Tseglytskyi
2014-08-29 18:57     ` Julien Grall
2014-08-29 19:49       ` Andrii Tseglytskyi
2014-08-29 20:04         ` Julien Grall
2014-08-29 20:14           ` Andrii Tseglytskyi
2014-09-09 13:33           ` Ian Campbell
2014-09-09 19:11             ` Julien Grall
2014-09-10  9:45               ` Andrii Tseglytskyi
2014-09-09 13:37   ` Ian Campbell
     [not found]   ` <CAAHg+HhhsZonrEDdHET93dy=dR1+YF-VPGJ=VwB20RRxWqdSYA@mail.gmail.com>
2014-10-06 16:04     ` Julien Grall
2014-07-31 15:00 ` Julien Grall [this message]
2014-08-06 15:49   ` [PATCH v2 09/21] xen/arm: Release IRQ routed to a domain when it's destroying Stefano Stabellini
2014-08-06 16:01     ` Julien Grall
2014-08-06 16:53       ` Stefano Stabellini
2014-08-06 17:09         ` Julien Grall
2014-08-07 15:36           ` Stefano Stabellini
2014-08-07 15:40             ` Julien Grall
2014-08-07 16:31               ` Stefano Stabellini
2014-08-07 16:35                 ` Julien Grall
2014-08-07 16:39                   ` Stefano Stabellini
2014-09-09 13:53                     ` Ian Campbell
2014-09-09 22:29                       ` Stefano Stabellini
2014-07-31 15:00 ` [PATCH v2 10/21] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq Julien Grall
2014-08-06 16:10   ` Stefano Stabellini
2014-08-29 12:34   ` Andrii Tseglytskyi
2014-08-29 19:08     ` Julien Grall
2014-08-29 19:44       ` Andrii Tseglytskyi
2014-07-31 15:00 ` [PATCH v2 11/21] xen/dts: Use unsigned int for MMIO and IRQ index Julien Grall
2014-08-06 16:12   ` Stefano Stabellini
2014-07-31 15:00 ` [PATCH v2 12/21] xen/dts: Provide an helper to get a DT node from a path provided by a guest Julien Grall
2014-09-09 13:55   ` Ian Campbell
2014-07-31 15:00 ` [PATCH v2 13/21] xen/dts: Add hypercalls to retrieve device node information Julien Grall
2014-08-01  8:50   ` Jan Beulich
2014-08-06 15:17     ` Julien Grall
2014-08-06 15:47       ` Jan Beulich
2014-07-31 15:00 ` [PATCH v2 14/21] xen/passthrough: Introduce iommu_construct Julien Grall
2014-08-01  8:55   ` Jan Beulich
2014-07-31 15:00 ` [PATCH v2 15/21] xen/passthrough: Call arch_iommu_domain_destroy before calling iommu_teardown Julien Grall
2014-08-01  9:00   ` Jan Beulich
2014-07-31 15:00 ` [PATCH v2 16/21] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody Julien Grall
2014-08-06 16:23   ` Stefano Stabellini
2015-01-12 16:33     ` Julien Grall
2014-07-31 15:00 ` [PATCH v2 17/21] xen/iommu: arm: Wire iommu DOMCTL for ARM Julien Grall
2014-08-06 16:24   ` Stefano Stabellini
2014-07-31 15:00 ` [PATCH v2 18/21] xen/passthrough: dt: Add new domctl XEN_DOMCTL_assign_dt_device Julien Grall
2014-08-01  9:05   ` Jan Beulich
2014-07-31 15:00 ` [PATCH v2 19/21] xen/arm: Reserve region in guest memory for device passthrough Julien Grall
2014-08-06 16:27   ` Stefano Stabellini
2014-08-06 16:33     ` Julien Grall
2014-08-06 16:44       ` Stefano Stabellini
2014-08-06 16:45         ` Stefano Stabellini
2014-08-06 16:55           ` Julien Grall
2014-08-06 16:57             ` Stefano Stabellini
2014-08-06 16:47         ` Julien Grall
2014-07-31 15:00 ` [PATCH v2 20/21] libxl: Add support for non-PCI passthrough Julien Grall
2014-08-06 16:44   ` Stefano Stabellini
2014-08-06 16:50     ` Julien Grall
2014-08-06 16:58       ` Stefano Stabellini
2014-08-08 14:15         ` Julien Grall
2014-09-09 19:12         ` Julien Grall
2014-09-10 10:08           ` Ian Campbell
2014-07-31 15:00 ` [PATCH v2 21/21] xl: Add new option dtdev Julien Grall
2014-09-09 14:34 ` [PATCH v2 00/21] xen/arm: Add support for non-pci passthrough Ian Campbell
2014-09-09 19:34   ` Julien Grall
2014-09-10  9:22     ` Christoffer Dall
2014-09-10 10:51       ` Ian Campbell
2014-09-10 11:45         ` Christoffer Dall
2014-09-10 12:05           ` Ian Campbell
2014-09-10 22:03           ` Stefano Stabellini
2014-09-11  4:03             ` Christoffer Dall
2014-09-11  8:56               ` Ian Campbell
2014-09-12 19:16         ` Julien Grall
2014-09-10 10:11     ` Ian Campbell
2014-09-10 18:45       ` Julien Grall
2014-09-11  8:58         ` Ian Campbell
2014-09-11 19:11           ` Julien Grall
2014-09-12 10:16             ` Ian Campbell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1406818852-31856-10-git-send-email-julien.grall@linaro.org \
    --to=julien.grall@linaro.org \
    --cc=ian.campbell@citrix.com \
    --cc=stefano.stabellini@citrix.com \
    --cc=tim@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).