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

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



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1259073787 0
# Node ID d44371e6e5d631f58d9a2ce829f12dafd1272f68
# Parent  45b4681b5be25acc8906daaa8548c4e4e5d7beb9
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/arch/x86/mpparse.c       |   11 +++++------
 xen/arch/x86/physdev.c       |   35 +++++++++++++++++++++++++++++++----
 xen/include/public/physdev.h |   13 +++++++++++++
 3 files changed, 49 insertions(+), 10 deletions(-)

diff -r 45b4681b5be2 -r d44371e6e5d6 xen/arch/x86/mpparse.c
--- a/xen/arch/x86/mpparse.c    Tue Nov 24 14:38:37 2009 +0000
+++ b/xen/arch/x86/mpparse.c    Tue Nov 24 14:43:07 2009 +0000
@@ -1122,7 +1122,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;
@@ -1141,12 +1141,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);
@@ -1180,14 +1180,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 45b4681b5be2 -r d44371e6e5d6 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Tue Nov 24 14:38:37 2009 +0000
+++ b/xen/arch/x86/physdev.c    Tue Nov 24 14:43:07 2009 +0000
@@ -62,13 +62,18 @@ static int physdev_map_pirq(struct physd
                 ret = -EINVAL;
                 goto free_domain;
             }
+
             irq = domain_pirq_to_irq(current->domain, map->index);
             if ( !irq )
             {
-                dprintk(XENLOG_G_ERR, "dom%d: map pirq with incorrect irq!\n",
-                        d->domain_id);
-                ret = -EINVAL;
-                goto free_domain;
+                if ( IS_PRIV(current->domain) )
+                    irq = map->index;
+                else {
+                    dprintk(XENLOG_G_ERR, "dom%d: map pirq with incorrect 
irq!\n",
+                            d->domain_id);
+                    ret = -EINVAL;
+                    goto free_domain;
+                }
             }
             break;
 
@@ -457,6 +462,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_gsi )
+            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 45b4681b5be2 -r d44371e6e5d6 xen/include/public/physdev.h
--- a/xen/include/public/physdev.h      Tue Nov 24 14:38:37 2009 +0000
+++ b/xen/include/public/physdev.h      Tue Nov 24 14:43:07 2009 +0000
@@ -227,6 +227,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®.