From: Liang Tang <liang.tang@xxxxxxxxxx> .. 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@xxxxxxxxxx> Signed-off-by: Liang Tang <liang.tang@xxxxxxxxxx> --- 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 9eea4ed..4521b05 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -248,6 +248,8 @@ error: } #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; @@ -308,12 +310,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 diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h index 44aefa9..9818456 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 ** -- 1.7.4.1 -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html