diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/pci/xen.c | 22 | ||||
-rw-r--r-- | arch/x86/xen/Kconfig | 3 |
2 files changed, 20 insertions, 5 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 |
255 | static bool __read_mostly pci_seg_supported = true; | ||
256 | |||
255 | static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | 257 | static 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); |
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig index ae559fe91c25..26c731a106af 100644 --- a/arch/x86/xen/Kconfig +++ b/arch/x86/xen/Kconfig | |||
@@ -25,8 +25,7 @@ config XEN_PRIVILEGED_GUEST | |||
25 | 25 | ||
26 | config XEN_PVHVM | 26 | config XEN_PVHVM |
27 | def_bool y | 27 | def_bool y |
28 | depends on XEN | 28 | depends on XEN && PCI && X86_LOCAL_APIC |
29 | depends on X86_LOCAL_APIC | ||
30 | 29 | ||
31 | config XEN_MAX_DOMAIN_MEMORY | 30 | config XEN_MAX_DOMAIN_MEMORY |
32 | int | 31 | int |