[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86: Move pirq logic to irq.c.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1223459328 -3600
# Node ID ed398097c03e16dacb1f3af19fa8faddf2deae1f
# Parent  1f85f7b216b34bfda4911b6a46548478f0e5d682
x86: Move pirq logic to irq.c.

Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/irq.c        |  156 +++++++++++++++++++++++++++++++++++++
 xen/arch/x86/physdev.c    |  189 +++++-----------------------------------------
 xen/include/asm-x86/irq.h |    5 +
 3 files changed, 183 insertions(+), 167 deletions(-)

diff -r 1f85f7b216b3 -r ed398097c03e xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Wed Oct 08 10:03:47 2008 +0100
+++ b/xen/arch/x86/irq.c        Wed Oct 08 10:48:48 2008 +0100
@@ -14,8 +14,11 @@
 #include <xen/sched.h>
 #include <xen/keyhandler.h>
 #include <xen/compat.h>
+#include <xen/iocap.h>
+#include <xen/iommu.h>
+#include <asm/msi.h>
 #include <asm/current.h>
-#include <xen/iommu.h>
+#include <public/physdev.h>
 
 /* opt_noirqbalance: If true, software IRQ balancing/affinity is disabled. */
 int opt_noirqbalance = 0;
@@ -731,6 +734,157 @@ int pirq_guest_force_unbind(struct domai
     return bound;
 }
 
+int get_free_pirq(struct domain *d, int type, int index)
+{
+    int i;
+
+    ASSERT(spin_is_locked(&d->evtchn_lock));
+
+    if ( type == MAP_PIRQ_TYPE_GSI )
+    {
+        for ( i = 16; i < NR_PIRQS; i++ )
+            if ( !d->arch.pirq_vector[i] )
+                break;
+        if ( i == NR_PIRQS )
+            return -ENOSPC;
+    }
+    else
+    {
+        for ( i = NR_PIRQS - 1; i >= 16; i-- )
+            if ( !d->arch.pirq_vector[i] )
+                break;
+        if ( i == 16 )
+            return -ENOSPC;
+    }
+
+    return i;
+}
+
+int map_domain_pirq(
+    struct domain *d, int pirq, int vector, int type, void *data)
+{
+    int ret = 0;
+    int old_vector, old_pirq;
+    irq_desc_t *desc;
+    unsigned long flags;
+
+    ASSERT(spin_is_locked(&d->evtchn_lock));
+
+    if ( !IS_PRIV(current->domain) )
+        return -EPERM;
+
+    if ( pirq < 0 || pirq >= NR_PIRQS || vector < 0 || vector >= NR_VECTORS )
+    {
+        dprintk(XENLOG_G_ERR, "dom%d: invalid pirq %d or vector %d\n",
+                d->domain_id, pirq, vector);
+        return -EINVAL;
+    }
+
+    old_vector = d->arch.pirq_vector[pirq];
+    old_pirq = d->arch.vector_pirq[vector];
+
+    if ( (old_vector && (old_vector != vector) ) ||
+         (old_pirq && (old_pirq != pirq)) )
+    {
+        dprintk(XENLOG_G_ERR, "dom%d: pirq %d or vector %d already mapped\n",
+                d->domain_id, pirq, vector);
+        return -EINVAL;
+    }
+
+    ret = irq_permit_access(d, pirq);
+    if ( ret )
+    {
+        dprintk(XENLOG_G_ERR, "dom%d: could not permit access to irq %d\n",
+                d->domain_id, pirq);
+        return ret;
+    }
+
+    desc = &irq_desc[vector];
+    spin_lock_irqsave(&desc->lock, flags);
+
+    if ( type == MAP_PIRQ_TYPE_MSI )
+    {
+        struct msi_info *msi = (struct msi_info *)data;
+        if ( desc->handler != &no_irq_type )
+            dprintk(XENLOG_G_ERR, "dom%d: vector %d in use\n",
+                    d->domain_id, vector);
+        desc->handler = &pci_msi_type;
+        ret = pci_enable_msi(msi);
+        if ( ret )
+            goto done;
+    }
+
+    d->arch.pirq_vector[pirq] = vector;
+    d->arch.vector_pirq[vector] = pirq;
+
+done:
+    spin_unlock_irqrestore(&desc->lock, flags);
+    return ret;
+}
+
+/* The pirq should have been unbound before this call. */
+int unmap_domain_pirq(struct domain *d, int pirq)
+{
+    unsigned long flags;
+    irq_desc_t *desc;
+    int vector, ret = 0;
+    bool_t forced_unbind;
+
+    if ( (pirq < 0) || (pirq >= NR_PIRQS) )
+        return -EINVAL;
+
+    if ( !IS_PRIV(current->domain) )
+        return -EINVAL;
+
+    ASSERT(spin_is_locked(&d->evtchn_lock));
+
+    vector = d->arch.pirq_vector[pirq];
+    if ( vector <= 0 )
+    {
+        dprintk(XENLOG_G_ERR, "dom%d: pirq %d not mapped\n",
+                d->domain_id, pirq);
+        ret = -EINVAL;
+        goto done;
+    }
+
+    forced_unbind = pirq_guest_force_unbind(d, pirq);
+    if ( forced_unbind )
+        dprintk(XENLOG_G_WARNING, "dom%d: forcing unbind of pirq %d\n",
+                d->domain_id, pirq);
+
+    desc = &irq_desc[vector];
+    spin_lock_irqsave(&desc->lock, flags);
+
+    BUG_ON(vector != d->arch.pirq_vector[pirq]);
+
+    if ( desc->msi_desc )
+        pci_disable_msi(vector);
+
+    if ( desc->handler == &pci_msi_type )
+        desc->handler = &no_irq_type;
+
+    if ( !forced_unbind )
+    {
+        d->arch.pirq_vector[pirq] = 0;
+        d->arch.vector_pirq[vector] = 0;
+    }
+    else
+    {
+        d->arch.pirq_vector[pirq] = -vector;
+        d->arch.vector_pirq[vector] = -pirq;
+    }
+
+    spin_unlock_irqrestore(&desc->lock, flags);
+
+    ret = irq_deny_access(d, pirq);
+    if ( ret )
+        dprintk(XENLOG_G_ERR, "dom%d: could not deny access to irq %d\n",
+                d->domain_id, pirq);
+
+ done:
+    return ret;
+}
+
 extern void dump_ioapic_irq_info(void);
 
 static void dump_irqs(unsigned char key)
diff -r 1f85f7b216b3 -r ed398097c03e xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Wed Oct 08 10:03:47 2008 +0100
+++ b/xen/arch/x86/physdev.c    Wed Oct 08 10:48:48 2008 +0100
@@ -26,168 +26,12 @@ ioapic_guest_write(
 ioapic_guest_write(
     unsigned long physbase, unsigned int reg, u32 pval);
 
-static int get_free_pirq(struct domain *d, int type, int index)
-{
-    int i;
-
-    ASSERT(spin_is_locked(&d->evtchn_lock));
-
-    if ( type == MAP_PIRQ_TYPE_GSI )
-    {
-        for ( i = 16; i < NR_PIRQS; i++ )
-            if ( !d->arch.pirq_vector[i] )
-                break;
-        if ( i == NR_PIRQS )
-            return -ENOSPC;
-    }
-    else
-    {
-        for ( i = NR_PIRQS - 1; i >= 16; i-- )
-            if ( !d->arch.pirq_vector[i] )
-                break;
-        if ( i == 16 )
-            return -ENOSPC;
-    }
-
-    return i;
-}
-
-static int map_domain_pirq(struct domain *d, int pirq, int vector,
-                           struct physdev_map_pirq *map)
-{
-    int ret = 0;
-    int old_vector, old_pirq;
-    struct msi_info msi;
-    irq_desc_t *desc;
-    unsigned long flags;
-
-    ASSERT(spin_is_locked(&d->evtchn_lock));
-
-    if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
-    if ( pirq < 0 || pirq >= NR_PIRQS || vector < 0 || vector >= NR_VECTORS )
-    {
-        dprintk(XENLOG_G_ERR, "dom%d: invalid pirq %d or vector %d\n",
-                d->domain_id, pirq, vector);
-        return -EINVAL;
-    }
-
-    old_vector = d->arch.pirq_vector[pirq];
-    old_pirq = d->arch.vector_pirq[vector];
-
-    if ( (old_vector && (old_vector != vector) ) ||
-         (old_pirq && (old_pirq != pirq)) )
-    {
-        dprintk(XENLOG_G_ERR, "dom%d: pirq %d or vector %d already mapped\n",
-                d->domain_id, pirq, vector);
-        return -EINVAL;
-    }
-
-    ret = irq_permit_access(d, pirq);
-    if ( ret )
-    {
-        dprintk(XENLOG_G_ERR, "dom%d: could not permit access to irq %d\n",
-                d->domain_id, pirq);
-        return ret;
-    }
-
-    desc = &irq_desc[vector];
-    spin_lock_irqsave(&desc->lock, flags);
-
-    if ( map && MAP_PIRQ_TYPE_MSI == map->type )
-    {
-        if ( desc->handler != &no_irq_type )
-            dprintk(XENLOG_G_ERR, "dom%d: vector %d in use\n",
-                    d->domain_id, vector);
-        desc->handler = &pci_msi_type;
-
-        msi.bus = map->bus;
-        msi.devfn = map->devfn;
-        msi.entry_nr = map->entry_nr;
-        msi.table_base = map->table_base;
-        msi.vector = vector;
-
-        ret = pci_enable_msi(&msi);
-        if ( ret )
-            goto done;
-    }
-
-    d->arch.pirq_vector[pirq] = vector;
-    d->arch.vector_pirq[vector] = pirq;
-
-done:
-    spin_unlock_irqrestore(&desc->lock, flags);
-    return ret;
-}
-
-/* The pirq should have been unbound before this call. */
-static int unmap_domain_pirq(struct domain *d, int pirq)
-{
-    unsigned long flags;
-    irq_desc_t *desc;
-    int vector, ret = 0;
-    bool_t forced_unbind;
-
-    if ( (pirq < 0) || (pirq >= NR_PIRQS) )
-        return -EINVAL;
-
-    if ( !IS_PRIV(current->domain) )
-        return -EINVAL;
-
-    ASSERT(spin_is_locked(&d->evtchn_lock));
-
-    vector = d->arch.pirq_vector[pirq];
-    if ( vector <= 0 )
-    {
-        dprintk(XENLOG_G_ERR, "dom%d: pirq %d not mapped\n",
-                d->domain_id, pirq);
-        ret = -EINVAL;
-        goto done;
-    }
-
-    forced_unbind = pirq_guest_force_unbind(d, pirq);
-    if ( forced_unbind )
-        dprintk(XENLOG_G_WARNING, "dom%d: forcing unbind of pirq %d\n",
-                d->domain_id, pirq);
-
-    desc = &irq_desc[vector];
-    spin_lock_irqsave(&desc->lock, flags);
-
-    BUG_ON(vector != d->arch.pirq_vector[pirq]);
-
-    if ( desc->msi_desc )
-        pci_disable_msi(vector);
-
-    if ( desc->handler == &pci_msi_type )
-        desc->handler = &no_irq_type;
-
-    if ( !forced_unbind )
-    {
-        d->arch.pirq_vector[pirq] = 0;
-        d->arch.vector_pirq[vector] = 0;
-    }
-    else
-    {
-        d->arch.pirq_vector[pirq] = -vector;
-        d->arch.vector_pirq[vector] = -pirq;
-    }
-
-    spin_unlock_irqrestore(&desc->lock, flags);
-
-    ret = irq_deny_access(d, pirq);
-    if ( ret )
-        dprintk(XENLOG_G_ERR, "dom%d: could not deny access to irq %d\n",
-                d->domain_id, pirq);
-
- done:
-    return ret;
-}
-
 static int physdev_map_pirq(struct physdev_map_pirq *map)
 {
     struct domain *d;
     int vector, pirq, ret = 0;
+    struct msi_info _msi;
+    void *map_data = NULL;
 
     if ( !IS_PRIV(current->domain) )
         return -EPERM;
@@ -206,6 +50,7 @@ static int physdev_map_pirq(struct physd
         goto free_domain;
     }
 
+    /* Verify or get vector. */
     switch ( map->type )
     {
         case MAP_PIRQ_TYPE_GSI:
@@ -220,15 +65,16 @@ static int physdev_map_pirq(struct physd
             if ( !vector )
             {
                 dprintk(XENLOG_G_ERR, "dom%d: map irq with no vector %d\n",
-                        d->domain_id, map->index);
+                        d->domain_id, vector);
                 ret = -EINVAL;
                 goto free_domain;
             }
             break;
+
         case MAP_PIRQ_TYPE_MSI:
             vector = map->index;
-                       if ( vector == -1 )
-                               vector = assign_irq_vector(AUTO_ASSIGN);
+            if ( vector == -1 )
+                vector = assign_irq_vector(AUTO_ASSIGN);
 
             if ( vector < 0 || vector >= NR_VECTORS )
             {
@@ -237,13 +83,23 @@ static int physdev_map_pirq(struct physd
                 ret = -EINVAL;
                 goto free_domain;
             }
-            break;
+
+            _msi.bus = map->bus;
+            _msi.devfn = map->devfn;
+            _msi.entry_nr = map->entry_nr;
+            _msi.table_base = map->table_base;
+            _msi.vector = vector;
+            map_data = &_msi;
+            break;
+
         default:
-            dprintk(XENLOG_G_ERR, "dom%d: wrong map_pirq type %x\n", 
d->domain_id, map->type);
+            dprintk(XENLOG_G_ERR, "dom%d: wrong map_pirq type %x\n",
+                    d->domain_id, map->type);
             ret = -EINVAL;
             goto free_domain;
     }
 
+    /* Verify or get pirq. */
     spin_lock(&d->evtchn_lock);
     if ( map->pirq < 0 )
     {
@@ -285,10 +141,10 @@ static int physdev_map_pirq(struct physd
     }
 
 
-    ret = map_domain_pirq(d, pirq, vector, map);
-
+    ret = map_domain_pirq(d, pirq, vector, map->type, map_data);
     if ( !ret )
         map->pirq = pirq;
+
 done:
     spin_unlock(&d->evtchn_lock);
 free_domain:
@@ -442,7 +298,8 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
         irq_op.vector = assign_irq_vector(irq);
 
         spin_lock(&dom0->evtchn_lock);
-        ret = map_domain_pirq(dom0, irq_op.irq, irq_op.vector, NULL);
+        ret = map_domain_pirq(dom0, irq_op.irq, irq_op.vector,
+                              MAP_PIRQ_TYPE_GSI, NULL);
         spin_unlock(&dom0->evtchn_lock);
 
         if ( copy_to_guest(arg, &irq_op, 1) != 0 )
diff -r 1f85f7b216b3 -r ed398097c03e xen/include/asm-x86/irq.h
--- a/xen/include/asm-x86/irq.h Wed Oct 08 10:03:47 2008 +0100
+++ b/xen/include/asm-x86/irq.h Wed Oct 08 10:48:48 2008 +0100
@@ -52,6 +52,11 @@ int pirq_acktype(struct domain *d, int i
 int pirq_acktype(struct domain *d, int irq);
 int pirq_shared(struct domain *d , int irq);
 
+int map_domain_pirq(struct domain *d, int pirq, int vector, int type,
+                           void *data);
+int unmap_domain_pirq(struct domain *d, int pirq);
+int get_free_pirq(struct domain *d, int type, int index);
+
 #define domain_irq_to_vector(d, irq) ((d)->arch.pirq_vector[(irq)])
 #define domain_vector_to_irq(d, vec) ((d)->arch.vector_pirq[(vec)])
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.