From ee78caa16a0ce327e77f8ff14fba4d76bd5adf54 Mon Sep 17 00:00:00 2001 From: Liang Tang Date: Thu, 29 Sep 2011 10:32:49 +0800 Subject: [PATCH] xen/pci:use hypercall PHYSDEVOP_restore_msi_ext to restore MSI/MSI-X vectors .. 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 Signed-off-by: Liang Tang --- arch/x86/pci/xen.c | 27 ++++++++++++++++++++++----- include/xen/interface/physdev.h | 8 ++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index f140999aed47e..32f17f0fcdd70 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -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 diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h index 44aefa92598d8..9818456e40b88 100644 --- a/include/xen/interface/physdev.h +++ b/include/xen/interface/physdev.h @@ -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 ** -- 2.50.1