aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/pci')
-rw-r--r--arch/x86/pci/xen.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 11a9301d52d4..492ade8c978e 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -252,6 +252,8 @@ error:
252} 252}
253 253
254#ifdef CONFIG_XEN_DOM0 254#ifdef CONFIG_XEN_DOM0
255static bool __read_mostly pci_seg_supported = true;
256
255static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 257static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
256{ 258{
257 int ret = 0; 259 int ret = 0;
@@ -269,10 +271,11 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
269 271
270 memset(&map_irq, 0, sizeof(map_irq)); 272 memset(&map_irq, 0, sizeof(map_irq));
271 map_irq.domid = domid; 273 map_irq.domid = domid;
272 map_irq.type = MAP_PIRQ_TYPE_MSI; 274 map_irq.type = MAP_PIRQ_TYPE_MSI_SEG;
273 map_irq.index = -1; 275 map_irq.index = -1;
274 map_irq.pirq = -1; 276 map_irq.pirq = -1;
275 map_irq.bus = dev->bus->number; 277 map_irq.bus = dev->bus->number |
278 (pci_domain_nr(dev->bus) << 16);
276 map_irq.devfn = dev->devfn; 279 map_irq.devfn = dev->devfn;
277 280
278 if (type == PCI_CAP_ID_MSIX) { 281 if (type == PCI_CAP_ID_MSIX) {
@@ -289,7 +292,20 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
289 map_irq.entry_nr = msidesc->msi_attrib.entry_nr; 292 map_irq.entry_nr = msidesc->msi_attrib.entry_nr;
290 } 293 }
291 294
292 ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); 295 ret = -EINVAL;
296 if (pci_seg_supported)
297 ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq,
298 &map_irq);
299 if (ret == -EINVAL && !pci_domain_nr(dev->bus)) {
300 map_irq.type = MAP_PIRQ_TYPE_MSI;
301 map_irq.index = -1;
302 map_irq.pirq = -1;
303 map_irq.bus = dev->bus->number;
304 ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq,
305 &map_irq);
306 if (ret != -EINVAL)
307 pci_seg_supported = false;
308 }
293 if (ret) { 309 if (ret) {
294 dev_warn(&dev->dev, "xen map irq failed %d for %d domain\n", 310 dev_warn(&dev->dev, "xen map irq failed %d for %d domain\n",
295 ret, domid); 311 ret, domid);