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

[Xen-devel] [PATCH] x86-64/physdevop: reduce generated code duplication



At least all the helper functions can be used by both the native and
the compat-mode implementations, requiring their parameters to be
adjusted.

Additionally, rather than having the compat mode wrapper source file
blindly define the native structures to be replaced by the compat mode
ones, replace unnecessary (un-)definitions by layout match checks.

In a second step, do_physdev_op() could be split into a part that needs
re-compilation for compat mode handling and one that can be used for
native and compat mode.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>

--- a/xen/arch/x86/physdev.c
+++ b/xen/arch/x86/physdev.c
@@ -17,17 +17,20 @@
 #include <xsm/xsm.h>
 #include <asm/p2m.h>
 
+int physdev_map_pirq(domid_t, int type, int *index, int *pirq_p,
+                     struct msi_info *);
+int physdev_unmap_pirq(domid_t, int pirq);
+
 #ifndef COMPAT
 typedef long ret_t;
-#endif
 
 static int physdev_hvm_map_pirq(
-    struct domain *d, struct physdev_map_pirq *map)
+    struct domain *d, int type, int *index, int *pirq)
 {
-    int pirq, ret = 0;
+    int ret = 0;
 
     spin_lock(&d->event_lock);
-    switch ( map->type )
+    switch ( type )
     {
     case MAP_PIRQ_TYPE_GSI: {
         struct hvm_irq_dpci *hvm_irq_dpci;
@@ -40,33 +43,31 @@ static int physdev_hvm_map_pirq(
         if ( hvm_irq_dpci )
         {
             list_for_each_entry ( girq,
-                                  &hvm_irq_dpci->girq[map->index],
+                                  &hvm_irq_dpci->girq[*index],
                                   list )
                 machine_gsi = girq->machine_gsi;
         }
         /* found one, this mean we are dealing with a pt device */
         if ( machine_gsi )
         {
-            map->index = domain_pirq_to_irq(d, machine_gsi);
-            pirq = machine_gsi;
-            ret = (pirq > 0) ? 0 : pirq;
+            *index = domain_pirq_to_irq(d, machine_gsi);
+            *pirq = machine_gsi;
+            ret = (*pirq > 0) ? 0 : *pirq;
         }
         /* we didn't find any, this means we are dealing
          * with an emulated device */
         else
         {
-            pirq = map->pirq;
-            if ( pirq < 0 )
-                pirq = get_free_pirq(d, map->type, map->index);
-            ret = map_domain_emuirq_pirq(d, pirq, map->index);
+            if ( *pirq < 0 )
+                *pirq = get_free_pirq(d, type, *index);
+            ret = map_domain_emuirq_pirq(d, *pirq, *index);
         }
-        map->pirq = pirq;
         break;
     }
 
     default:
         ret = -EINVAL;
-        dprintk(XENLOG_G_WARNING, "map type %d not supported yet\n", 
map->type);
+        dprintk(XENLOG_G_WARNING, "map type %d not supported yet\n", type);
         break;
     }
 
@@ -74,20 +75,20 @@ static int physdev_hvm_map_pirq(
     return ret;
 }
 
-static int physdev_map_pirq(struct physdev_map_pirq *map)
+int physdev_map_pirq(domid_t domid, int type, int *index, int *pirq_p,
+                     struct msi_info *msi)
 {
     struct domain *d;
     int pirq, irq, ret = 0;
-    struct msi_info _msi;
     void *map_data = NULL;
 
-    ret = rcu_lock_target_domain_by_id(map->domid, &d);
+    ret = rcu_lock_target_domain_by_id(domid, &d);
     if ( ret )
         return ret;
 
-    if ( map->domid == DOMID_SELF && is_hvm_domain(d) )
+    if ( domid == DOMID_SELF && is_hvm_domain(d) )
     {
-        ret = physdev_hvm_map_pirq(d, map);
+        ret = physdev_hvm_map_pirq(d, type, index, pirq_p);
         goto free_domain;
     }
 
@@ -98,22 +99,22 @@ static int physdev_map_pirq(struct physd
     }
 
     /* Verify or get irq. */
-    switch ( map->type )
+    switch ( type )
     {
     case MAP_PIRQ_TYPE_GSI:
-        if ( map->index < 0 || map->index >= nr_irqs_gsi )
+        if ( *index < 0 || *index >= nr_irqs_gsi )
         {
             dprintk(XENLOG_G_ERR, "dom%d: map invalid irq %d\n",
-                    d->domain_id, map->index);
+                    d->domain_id, *index);
             ret = -EINVAL;
             goto free_domain;
         }
 
-        irq = domain_pirq_to_irq(current->domain, map->index);
+        irq = domain_pirq_to_irq(current->domain, *index);
         if ( irq <= 0 )
         {
             if ( IS_PRIV(current->domain) )
-                irq = map->index;
+                irq = *index;
             else {
                 dprintk(XENLOG_G_ERR, "dom%d: map pirq with incorrect irq!\n",
                         d->domain_id);
@@ -124,7 +125,7 @@ static int physdev_map_pirq(struct physd
         break;
 
     case MAP_PIRQ_TYPE_MSI:
-        irq = map->index;
+        irq = *index;
         if ( irq == -1 )
             irq = create_irq();
 
@@ -136,17 +137,13 @@ static int physdev_map_pirq(struct physd
             goto free_domain;
         }
 
-        _msi.bus = map->bus;
-        _msi.devfn = map->devfn;
-        _msi.entry_nr = map->entry_nr;
-        _msi.table_base = map->table_base;
-        _msi.irq = irq;
-        map_data = &_msi;
+        msi->irq = irq;
+        map_data = msi;
         break;
 
     default:
         dprintk(XENLOG_G_ERR, "dom%d: wrong map_pirq type %x\n",
-                d->domain_id, map->type);
+                d->domain_id, type);
         ret = -EINVAL;
         goto free_domain;
     }
@@ -155,13 +152,12 @@ static int physdev_map_pirq(struct physd
     /* Verify or get pirq. */
     spin_lock(&d->event_lock);
     pirq = domain_irq_to_pirq(d, irq);
-    if ( map->pirq < 0 )
+    if ( *pirq_p < 0 )
     {
         if ( pirq )
         {
             dprintk(XENLOG_G_ERR, "dom%d: %d:%d already mapped to %d\n",
-                    d->domain_id, map->index, map->pirq,
-                    pirq);
+                    d->domain_id, *index, *pirq_p, pirq);
             if ( pirq < 0 )
             {
                 ret = -EBUSY;
@@ -170,7 +166,7 @@ static int physdev_map_pirq(struct physd
         }
         else
         {
-            pirq = get_free_pirq(d, map->type, map->index);
+            pirq = get_free_pirq(d, type, *index);
             if ( pirq < 0 )
             {
                 dprintk(XENLOG_G_ERR, "dom%d: no free pirq\n", d->domain_id);
@@ -181,20 +177,20 @@ static int physdev_map_pirq(struct physd
     }
     else
     {
-        if ( pirq && pirq != map->pirq )
+        if ( pirq && pirq != *pirq_p )
         {
             dprintk(XENLOG_G_ERR, "dom%d: pirq %d conflicts with irq %d\n",
-                    d->domain_id, map->index, map->pirq);
+                    d->domain_id, *index, *pirq_p);
             ret = -EEXIST;
             goto done;
         }
         else
-            pirq = map->pirq;
+            pirq = *pirq_p;
     }
 
-    ret = map_domain_pirq(d, pirq, irq, map->type, map_data);
+    ret = map_domain_pirq(d, pirq, irq, type, map_data);
     if ( ret == 0 )
-        map->pirq = pirq;
+        *pirq_p = pirq;
 
     if ( !ret && is_hvm_domain(d) )
         map_domain_emuirq_pirq(d, pirq, IRQ_PT);
@@ -202,28 +198,28 @@ static int physdev_map_pirq(struct physd
  done:
     spin_unlock(&d->event_lock);
     spin_unlock(&pcidevs_lock);
-    if ( (ret != 0) && (map->type == MAP_PIRQ_TYPE_MSI) && (map->index == -1) )
+    if ( (ret != 0) && (type == MAP_PIRQ_TYPE_MSI) && (*index == -1) )
         destroy_irq(irq);
  free_domain:
     rcu_unlock_domain(d);
     return ret;
 }
 
-static int physdev_unmap_pirq(struct physdev_unmap_pirq *unmap)
+int physdev_unmap_pirq(domid_t domid, int pirq)
 {
     struct domain *d;
     int ret;
 
-    ret = rcu_lock_target_domain_by_id(unmap->domid, &d);
+    ret = rcu_lock_target_domain_by_id(domid, &d);
     if ( ret )
         return ret;
 
     if ( is_hvm_domain(d) )
     {
         spin_lock(&d->event_lock);
-        ret = unmap_domain_pirq_emuirq(d, unmap->pirq);
+        ret = unmap_domain_pirq_emuirq(d, pirq);
         spin_unlock(&d->event_lock);
-        if ( unmap->domid == DOMID_SELF || ret )
+        if ( domid == DOMID_SELF || ret )
             goto free_domain;
     }
 
@@ -233,7 +229,7 @@ static int physdev_unmap_pirq(struct phy
 
     spin_lock(&pcidevs_lock);
     spin_lock(&d->event_lock);
-    ret = unmap_domain_pirq(d, unmap->pirq);
+    ret = unmap_domain_pirq(d, pirq);
     spin_unlock(&d->event_lock);
     spin_unlock(&pcidevs_lock);
 
@@ -241,6 +237,7 @@ static int physdev_unmap_pirq(struct phy
     rcu_unlock_domain(d);
     return ret;
 }
+#endif /* COMPAT */
 
 ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
 {
@@ -352,13 +349,19 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
     }
 
     case PHYSDEVOP_map_pirq: {
-        struct physdev_map_pirq map;
+        physdev_map_pirq_t map;
+        struct msi_info msi;
 
         ret = -EFAULT;
         if ( copy_from_guest(&map, arg, 1) != 0 )
             break;
 
-        ret = physdev_map_pirq(&map);
+        msi.bus = map.bus;
+        msi.devfn = map.devfn;
+        msi.entry_nr = map.entry_nr;
+        msi.table_base = map.table_base;
+        ret = physdev_map_pirq(map.domid, map.type, &map.index, &map.pirq,
+                               &msi);
 
         if ( copy_to_guest(arg, &map, 1) != 0 )
             ret = -EFAULT;
@@ -372,7 +375,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
         if ( copy_from_guest(&unmap, arg, 1) != 0 )
             break;
 
-        ret = physdev_unmap_pirq(&unmap);
+        ret = physdev_unmap_pirq(unmap.domid, unmap.pirq);
         break;
     }
 
--- a/xen/arch/x86/x86_64/physdev.c
+++ b/xen/arch/x86/x86_64/physdev.c
@@ -15,8 +15,9 @@
 #define physdev_apic               compat_physdev_apic
 #define physdev_apic_t             physdev_apic_compat_t
 
-#define physdev_eoi                compat_physdev_eoi
-#define physdev_eoi_t              physdev_eoi_compat_t
+#define xen_physdev_eoi physdev_eoi
+CHECK_physdev_eoi;
+#undef xen_physdev_eoi
 
 #define physdev_pirq_eoi_gmfn      compat_physdev_pirq_eoi_gmfn
 #define physdev_pirq_eoi_gmfn_t    physdev_pirq_eoi_gmfn_compat_t
@@ -24,35 +25,43 @@
 #define physdev_set_iobitmap       compat_physdev_set_iobitmap
 #define physdev_set_iobitmap_t     physdev_set_iobitmap_compat_t
 
-#define physdev_set_iopl           compat_physdev_set_iopl
-#define physdev_set_iopl_t         physdev_set_iopl_compat_t
+#define xen_physdev_set_iopl physdev_set_iopl
+CHECK_physdev_set_iopl;
+#undef xen_physdev_set_iopl
+
+#define xen_physdev_irq physdev_irq
+CHECK_physdev_irq;
+#undef xen_physdev_irq
+
+#define xen_physdev_irq_status_query physdev_irq_status_query
+CHECK_physdev_irq_status_query;
+#undef xen_physdev_irq_status_query
 
-#define physdev_irq                compat_physdev_irq
-#define physdev_irq_t              physdev_irq_compat_t
-
-#define physdev_irq_status_query   compat_physdev_irq_status_query
-#define physdev_irq_status_query_t physdev_irq_status_query_compat_t
-
-#define physdev_map_pirq           compat_physdev_map_pirq
 #define physdev_map_pirq_t         physdev_map_pirq_compat_t
 
-#define physdev_unmap_pirq         compat_physdev_unmap_pirq
-#define physdev_unmap_pirq_t       physdev_unmap_pirq_compat_t
-
-#define physdev_manage_pci         compat_physdev_manage_pci
-#define physdev_manage_pci_t       physdev_manage_pci_compat_t
-
-#define physdev_manage_pci_ext     compat_physdev_manage_pci_ext
-#define physdev_manage_pci_ext_t   physdev_manage_pci_ext_compat_t
-
-#define physdev_restore_msi        compat_physdev_restore_msi
-#define physdev_restore_msi_t      physdev_restore_msi_compat_t
-
-#define physdev_setup_gsi          compat_physdev_setup_gsi
-#define physdev_setup_gsi_t        physdev_setup_gsi_compat_t
-
-#define physdev_get_free_pirq      compat_physdev_get_free_pirq
-#define physdev_get_free_pirq_t    physdev_get_free_pirq_compat_t
+#define xen_physdev_unmap_pirq physdev_unmap_pirq
+CHECK_physdev_unmap_pirq;
+#undef xen_physdev_unmap_pirq
+
+#define xen_physdev_manage_pci physdev_manage_pci
+CHECK_physdev_manage_pci;
+#undef xen_physdev_manage_pci
+
+#define xen_physdev_manage_pci_ext physdev_manage_pci_ext
+CHECK_physdev_manage_pci_ext;
+#undef xen_physdev_manage_pci_ext
+
+#define xen_physdev_restore_msi physdev_restore_msi
+CHECK_physdev_restore_msi;
+#undef xen_physdev_restore_msi
+
+#define xen_physdev_setup_gsi physdev_setup_gsi
+CHECK_physdev_setup_gsi;
+#undef xen_physdev_setup_gsi
+
+#define xen_physdev_get_free_pirq physdev_get_free_pirq
+CHECK_physdev_get_free_pirq;
+#undef xen_physdev_get_free_pirq
 
 #define COMPAT
 #undef guest_handle_okay
--- a/xen/include/xlat.lst
+++ b/xen/include/xlat.lst
@@ -59,6 +59,16 @@
 !      memory_map                      memory.h
 !      memory_reservation              memory.h
 !      pod_target                      memory.h
+?      physdev_eoi                     physdev.h
+?      physdev_get_free_pirq           physdev.h
+?      physdev_irq                     physdev.h
+?      physdev_irq_status_query        physdev.h
+?      physdev_manage_pci              physdev.h
+?      physdev_manage_pci_ext          physdev.h
+?      physdev_unmap_pirq              physdev.h
+?      physdev_restore_msi             physdev.h
+?      physdev_set_iopl                physdev.h
+?      physdev_setup_gsi               physdev.h
 !      sched_poll                      sched.h
 ?      sched_remote_shutdown           sched.h
 ?      sched_shutdown                  sched.h


Attachment: 32on64-physdevop.patch
Description: Text document

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

 


Rackspace

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