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 | } |
