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

[Xen-changelog] [xen-3.4-testing] x86: Add a new physdev_op PHYSDEVOP_setup_gsi for GSI setup.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1261481821 0
# Node ID 608ebc959c359fb43e10a84121f68995191b078c
# Parent  95c6e90fcfefaa8d83f414a04086f4544b00f5ca
x86: Add a new physdev_op PHYSDEVOP_setup_gsi for GSI setup.

GSI 0-15 is setup by hypervisor, and GSI > =16 is setup by dom0
this physdev_op PHYSDEVOP_setup_gsi. This patch can help dom0
to get rid of intrusive changes of ioapic.

Signed-off-by: Xiantao Zhang <xiantao.zhang@xxxxxxxxx>
xen-unstable changeset:   20491:d44371e6e5d6
xen-unstable date:        Tue Nov 24 14:43:07 2009 +0000
---
 xen/arch/x86/mpparse.c       |   11 +++++------
 xen/arch/x86/physdev.c       |   42 ++++++++++++++++++++++++++++++++++++------
 xen/include/public/physdev.h |   13 +++++++++++++
 3 files changed, 54 insertions(+), 12 deletions(-)

diff -r 95c6e90fcfef -r 608ebc959c35 xen/arch/x86/mpparse.c
--- a/xen/arch/x86/mpparse.c    Mon Dec 21 10:58:23 2009 +0000
+++ b/xen/arch/x86/mpparse.c    Tue Dec 22 11:37:01 2009 +0000
@@ -1081,7 +1081,7 @@ int mp_register_gsi (u32 gsi, int trigge
        ioapic = mp_find_ioapic(gsi);
        if (ioapic < 0) {
                printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
-               return gsi;
+               return -EINVAL;
        }
 
        ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
@@ -1100,12 +1100,12 @@ int mp_register_gsi (u32 gsi, int trigge
                printk(KERN_ERR "Invalid reference to IOAPIC pin "
                        "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, 
                        ioapic_pin);
-               return gsi;
+               return -EINVAL;
        }
        if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
                Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
                        mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
-               return gsi_to_irq[gsi];
+               return -EEXIST;
        }
 
        mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
@@ -1139,14 +1139,13 @@ int mp_register_gsi (u32 gsi, int trigge
                        gsi_to_irq[irq] = gsi;
                } else {
                        printk(KERN_ERR "GSI %u is too high\n", gsi);
-                       return gsi;
+                       return -E2BIG;
                }
        }
 
-       io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
+       return io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
                    triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
                    polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
-       return gsi;
 }
 
 #endif /* CONFIG_X86_IO_APIC */
diff -r 95c6e90fcfef -r 608ebc959c35 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Mon Dec 21 10:58:23 2009 +0000
+++ b/xen/arch/x86/physdev.c    Tue Dec 22 11:37:01 2009 +0000
@@ -65,13 +65,21 @@ static int physdev_map_pirq(struct physd
             vector = domain_irq_to_vector(current->domain, map->index);
             if ( !vector )
             {
-                dprintk(XENLOG_G_ERR, "dom%d: map irq with no vector %d\n",
-                        d->domain_id, vector);
-                ret = -EINVAL;
-                goto free_domain;
+                if ( IS_PRIV(current->domain) ) {
+                    vector = assign_irq_vector(map->index);
+                    if ( vector < 0 ) {
+                        ret = vector;
+                        goto free_domain;
+                    }
+                }
+                else {
+                    dprintk(XENLOG_G_ERR, "dom%d: map irq with no vector %d\n",
+                            d->domain_id, vector);
+                    ret = -EINVAL;
+                    goto free_domain;
+                }
             }
-            break;
-
+        break;
         case MAP_PIRQ_TYPE_MSI:
             vector = map->index;
             if ( vector == -1 )
@@ -465,6 +473,28 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
         spin_unlock(&pcidevs_lock);
         break;
     }
+    case PHYSDEVOP_setup_gsi: {
+        struct physdev_setup_gsi setup_gsi;
+
+        ret = -EPERM;
+        if ( !IS_PRIV(v->domain) )
+            break;
+
+        ret = -EFAULT;
+        if ( copy_from_guest(&setup_gsi, arg, 1) != 0 )
+            break;
+        
+        ret = -EINVAL;
+        if ( setup_gsi.gsi < 0 || setup_gsi.gsi >= NR_IRQS )
+            break;
+        /* GSI < 16 has been setup by hypervisor */
+        if ( setup_gsi.gsi >= 16 )
+            ret = mp_register_gsi(setup_gsi.gsi, setup_gsi.triggering,
+                            setup_gsi.polarity);
+        else 
+            ret = -EEXIST;
+        break; 
+    }
     default:
         ret = -ENOSYS;
         break;
diff -r 95c6e90fcfef -r 608ebc959c35 xen/include/public/physdev.h
--- a/xen/include/public/physdev.h      Mon Dec 21 10:58:23 2009 +0000
+++ b/xen/include/public/physdev.h      Tue Dec 22 11:37:01 2009 +0000
@@ -225,6 +225,19 @@ typedef struct physdev_op physdev_op_t;
 typedef struct physdev_op physdev_op_t;
 DEFINE_XEN_GUEST_HANDLE(physdev_op_t);
 
+#define PHYSDEVOP_setup_gsi    21
+struct physdev_setup_gsi {
+    int gsi;
+    /* IN */
+    uint8_t triggering;
+    /* IN */
+    uint8_t polarity;
+    /* IN */
+};
+
+typedef struct physdev_setup_gsi physdev_setup_gsi_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_setup_gsi_t);
+
 /*
  * Notify that some PIRQ-bound event channels have been unmasked.
  * ** This command is obsolete since interface version 0x00030202 and is **

_______________________________________________
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®.