diff options
Diffstat (limited to 'arch/x86/pci/xen.c')
-rw-r--r-- | arch/x86/pci/xen.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 103e702ec5a7..905956f16465 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c | |||
@@ -178,6 +178,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
178 | i = 0; | 178 | i = 0; |
179 | list_for_each_entry(msidesc, &dev->msi_list, list) { | 179 | list_for_each_entry(msidesc, &dev->msi_list, list) { |
180 | irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], | 180 | irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], |
181 | (type == PCI_CAP_ID_MSI) ? nvec : 1, | ||
181 | (type == PCI_CAP_ID_MSIX) ? | 182 | (type == PCI_CAP_ID_MSIX) ? |
182 | "pcifront-msi-x" : | 183 | "pcifront-msi-x" : |
183 | "pcifront-msi", | 184 | "pcifront-msi", |
@@ -245,6 +246,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
245 | "xen: msi already bound to pirq=%d\n", pirq); | 246 | "xen: msi already bound to pirq=%d\n", pirq); |
246 | } | 247 | } |
247 | irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, | 248 | irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, |
249 | (type == PCI_CAP_ID_MSI) ? nvec : 1, | ||
248 | (type == PCI_CAP_ID_MSIX) ? | 250 | (type == PCI_CAP_ID_MSIX) ? |
249 | "msi-x" : "msi", | 251 | "msi-x" : "msi", |
250 | DOMID_SELF); | 252 | DOMID_SELF); |
@@ -269,9 +271,6 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
269 | int ret = 0; | 271 | int ret = 0; |
270 | struct msi_desc *msidesc; | 272 | struct msi_desc *msidesc; |
271 | 273 | ||
272 | if (type == PCI_CAP_ID_MSI && nvec > 1) | ||
273 | return 1; | ||
274 | |||
275 | list_for_each_entry(msidesc, &dev->msi_list, list) { | 274 | list_for_each_entry(msidesc, &dev->msi_list, list) { |
276 | struct physdev_map_pirq map_irq; | 275 | struct physdev_map_pirq map_irq; |
277 | domid_t domid; | 276 | domid_t domid; |
@@ -291,7 +290,10 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
291 | (pci_domain_nr(dev->bus) << 16); | 290 | (pci_domain_nr(dev->bus) << 16); |
292 | map_irq.devfn = dev->devfn; | 291 | map_irq.devfn = dev->devfn; |
293 | 292 | ||
294 | if (type == PCI_CAP_ID_MSIX) { | 293 | if (type == PCI_CAP_ID_MSI && nvec > 1) { |
294 | map_irq.type = MAP_PIRQ_TYPE_MULTI_MSI; | ||
295 | map_irq.entry_nr = nvec; | ||
296 | } else if (type == PCI_CAP_ID_MSIX) { | ||
295 | int pos; | 297 | int pos; |
296 | u32 table_offset, bir; | 298 | u32 table_offset, bir; |
297 | 299 | ||
@@ -308,6 +310,16 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
308 | if (pci_seg_supported) | 310 | if (pci_seg_supported) |
309 | ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, | 311 | ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, |
310 | &map_irq); | 312 | &map_irq); |
313 | if (type == PCI_CAP_ID_MSI && nvec > 1 && ret) { | ||
314 | /* | ||
315 | * If MAP_PIRQ_TYPE_MULTI_MSI is not available | ||
316 | * there's nothing else we can do in this case. | ||
317 | * Just set ret > 0 so driver can retry with | ||
318 | * single MSI. | ||
319 | */ | ||
320 | ret = 1; | ||
321 | goto out; | ||
322 | } | ||
311 | if (ret == -EINVAL && !pci_domain_nr(dev->bus)) { | 323 | if (ret == -EINVAL && !pci_domain_nr(dev->bus)) { |
312 | map_irq.type = MAP_PIRQ_TYPE_MSI; | 324 | map_irq.type = MAP_PIRQ_TYPE_MSI; |
313 | map_irq.index = -1; | 325 | map_irq.index = -1; |
@@ -324,11 +336,10 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
324 | goto out; | 336 | goto out; |
325 | } | 337 | } |
326 | 338 | ||
327 | ret = xen_bind_pirq_msi_to_irq(dev, msidesc, | 339 | ret = xen_bind_pirq_msi_to_irq(dev, msidesc, map_irq.pirq, |
328 | map_irq.pirq, | 340 | (type == PCI_CAP_ID_MSI) ? nvec : 1, |
329 | (type == PCI_CAP_ID_MSIX) ? | 341 | (type == PCI_CAP_ID_MSIX) ? "msi-x" : "msi", |
330 | "msi-x" : "msi", | 342 | domid); |
331 | domid); | ||
332 | if (ret < 0) | 343 | if (ret < 0) |
333 | goto out; | 344 | goto out; |
334 | } | 345 | } |