aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorHidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>2009-06-23 23:08:27 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-06-29 15:10:10 -0400
commit0d07348931daef854aca8c834a89f1a99ba4ff2b (patch)
tree3cc936fd7f31d00ce9c452ac39ce772f628fccc3 /drivers/pci
parent2bfdd79eaa0043346e773ba5f6cfd811ea31b73d (diff)
PCI MSI: Return if alloc_msi_entry for MSI-X failed
In current code it continues setup even if alloc_msi_entry() for MSI-X is failed due to lack of memory. It means arch_setup_msi_irqs() might be called with msi_desc entries less than its argument nvec. At least x86's arch_setup_msi_irqs() uses list_for_each_entry() for dev->msi_list that suspected to have entries same numbers as nvec, and it doesn't check the number of allocated vectors and passed arg nvec. Therefore it will result in success of pci_enable_msix(), with less vectors allocated than requested. This patch fixes the error route to return -ENOMEM, instead of continuing the setup (proposed by Matthew Wilcox). Note that there is no iounmap in msi_free_irqs() if no msi_disc is allocated. Reviewed-by: Matthew Wilcox <matthew@wil.cx> Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/msi.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index d9f06fbfa0bf..628c14150d49 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -439,8 +439,14 @@ static int msix_capability_init(struct pci_dev *dev,
439 439
440 for (i = 0; i < nvec; i++) { 440 for (i = 0; i < nvec; i++) {
441 entry = alloc_msi_entry(dev); 441 entry = alloc_msi_entry(dev);
442 if (!entry) 442 if (!entry) {
443 break; 443 if (!i)
444 iounmap(base);
445 else
446 msi_free_irqs(dev);
447 /* No enough memory. Don't try again */
448 return -ENOMEM;
449 }
444 450
445 j = entries[i].entry; 451 j = entries[i].entry;
446 entry->msi_attrib.is_msix = 1; 452 entry->msi_attrib.is_msix = 1;