]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
xen/pci:use hypercall PHYSDEVOP_restore_msi_ext to restore MSI/MSI-X vectors
authorLiang Tang <liang.tang@oracle.com>
Thu, 29 Sep 2011 02:32:49 +0000 (10:32 +0800)
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Wed, 19 Oct 2011 17:08:39 +0000 (13:08 -0400)
.. to use the new hypercall to restore the vectors for MSI/MSI-X devices.
If the new hypercall fail, we will call the old one (PHYSDEVOP_restore_msi).

[v1: Attempt only once to make the new hypercall, not everytime]
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Liang Tang <liang.tang@oracle.com>
arch/x86/pci/xen.c
include/xen/interface/physdev.h

index f140999aed47e0de998b6fcda82c3c9a891f1fdf..32f17f0fcdd70c93d5a7f4c729f749897115e228 100644 (file)
@@ -185,6 +185,8 @@ static void xen_teardown_msi_irq(unsigned int irq)
 }
 
 #ifdef CONFIG_XEN_DOM0
+static bool __read_mostly pci_seg_supported = true;
+
 static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 {
        int ret = 0;
@@ -245,12 +247,27 @@ out:
 static void xen_initdom_restore_msi_irqs(struct pci_dev *dev, int irq)
 {
        int ret = 0;
-       struct physdev_restore_msi restore;
 
-       restore.bus = dev->bus->number;
-       restore.devfn = dev->devfn;
-       ret = HYPERVISOR_physdev_op(PHYSDEVOP_restore_msi, &restore);
-       WARN(ret && ret != -ENOSYS, "restore_msi -> %d\n", ret);
+       if (pci_seg_supported) {
+               struct physdev_pci_device restore_ext;
+
+               restore_ext.seg = pci_domain_nr(dev->bus);
+               restore_ext.bus = dev->bus->number;
+               restore_ext.devfn = dev->devfn;
+               ret = HYPERVISOR_physdev_op(PHYSDEVOP_restore_msi_ext,
+                                           &restore_ext);
+               if (ret == -ENOSYS)
+                       pci_seg_supported = false;
+               WARN(ret && ret != -ENOSYS, "restore_msi_ext -> %d\n", ret);
+       }
+       if (!pci_seg_supported) {
+               struct physdev_restore_msi restore;
+
+               restore.bus = dev->bus->number;
+               restore.devfn = dev->devfn;
+               ret = HYPERVISOR_physdev_op(PHYSDEVOP_restore_msi, &restore);
+               WARN(ret && ret != -ENOSYS, "restore_msi -> %d\n", ret);
+       }
 }
 #endif
 #endif
index 44aefa92598d880dba609e0324cd2f546b1595ef..9818456e40b88bbd71b58e70f2b402a57e409614 100644 (file)
@@ -205,6 +205,14 @@ struct physdev_get_free_pirq {
     uint32_t pirq;
 };
 
+#define PHYSDEVOP_restore_msi_ext       27
+struct physdev_pci_device {
+       /* IN */
+       uint16_t seg;
+       uint8_t bus;
+       uint8_t devfn;
+};
+
 /*
  * Notify that some PIRQ-bound event channels have been unmasked.
  * ** This command is obsolete since interface version 0x00030202 and is **