This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
Home Products Support Community News


[Xen-devel] [PATCH 11/20] xen: fix shared irq device passthrough

To: linux-kernel@xxxxxxxxxxxxxxx, xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 11/20] xen: fix shared irq device passthrough
From: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
Date: Wed, 4 Aug 2010 14:19:06 -0400
Cc: alex.williamson@xxxxxxxxxx, Jeremy Fitzhardinge <jeremy.fitzhardinge@xxxxxxxxxx>, Weidong Han <weidong.han@xxxxxxxxx>, Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
Delivery-date: Wed, 04 Aug 2010 11:27:14 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1280945955-14229-1-git-send-email-konrad.wilk@xxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <1280945955-14229-1-git-send-email-konrad.wilk@xxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
From: Weidong Han <weidong.han@xxxxxxxxx>

In driver/xen/events.c, whether bind_pirq is shareable or not is
determined by desc->action is NULL or not. But in __setup_irq,
startup(irq) is invoked before desc->action is assigned with
new action. So desc->action in startup_irq is always NULL, and
bind_pirq is always not shareable. This results in pt_irq_create_bind
failure when passthrough a device which shares irq to other devices.

This patch doesn't use probing_irq to determine if pirq is shareable
or not, instead set shareable flag in irq_info according to trigger
mode in xen_allocate_pirq. Set level triggered interrupts shareable.
Thus use this flag to set bind_pirq flag accordingly.

[v2: arch/x86/xen/pci.c no more, so file skipped]

Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@xxxxxxxxxx>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
 drivers/xen/events.c |   11 ++++++++---
 include/xen/events.h |    2 +-
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 9d85707..78c1525 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -92,6 +92,7 @@ struct irq_info
        } u;
 #define PIRQ_NEEDS_EOI (1 << 0)
+#define PIRQ_SHAREABLE (1 << 1)
 static struct irq_info *irq_info;
@@ -431,6 +432,7 @@ static unsigned int startup_pirq(unsigned int irq)
        struct evtchn_bind_pirq bind_pirq;
        struct irq_info *info = info_for_irq(irq);
        int evtchn = evtchn_from_irq(irq);
+       int rc;
        BUG_ON(info->type != IRQT_PIRQ);
@@ -439,8 +441,10 @@ static unsigned int startup_pirq(unsigned int irq)
        bind_pirq.pirq = irq;
        /* NB. We are happy to share unless we are probing. */
-       bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
-       if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq) != 0) {
+       bind_pirq.flags = info->u.pirq.flags & PIRQ_SHAREABLE ?
+                                       BIND_PIRQ__WILL_SHARE : 0;
+       rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq);
+       if (rc != 0) {
                if (!probing_irq(irq))
                        printk(KERN_INFO "Failed to obtain physical IRQ %d\n",
@@ -543,7 +547,7 @@ static int find_irq_by_gsi(unsigned gsi)
  * event channel until the irq actually started up.  Return an
  * existing irq if we've already got one for the gsi.
-int xen_allocate_pirq(unsigned gsi, char *name)
+int xen_allocate_pirq(unsigned gsi, int shareable, char *name)
        int irq;
        struct physdev_irq irq_op;
@@ -575,6 +579,7 @@ int xen_allocate_pirq(unsigned gsi, char *name)
        irq_info[irq] = mk_pirq_info(0, gsi, irq_op.vector);
+       irq_info[irq].u.pirq.flags |= shareable ? PIRQ_SHAREABLE : 0;
diff --git a/include/xen/events.h b/include/xen/events.h
index 91143b4..20e27c3 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -63,7 +63,7 @@ unsigned irq_from_evtchn(unsigned int evtchn);
 /* Allocate an irq for a physical interrupt, given a gsi.  "Legacy"
    GSIs are identity mapped; others are dynamically allocated as
    usual. */
-int xen_allocate_pirq(unsigned gsi, char *name);
+int xen_allocate_pirq(unsigned gsi, int shareable, char *name);
 /* Return vector allocated to pirq */
 int xen_vector_from_irq(unsigned pirq);

Xen-devel mailing list

<Prev in Thread] Current Thread [Next in Thread>