Commit f8bf2aeb authored by James Sewart's avatar James Sewart Committed by Bjorn Helgaas

PCI: Fix pci_add_dma_alias() bitmask size

The number of possible devfns is 256, but pci_add_dma_alias() allocated a
bitmap of size 255.  Fix this off-by-one error.

This fixes commits 338c3149 ("PCI: Add support for multiple DMA
aliases") and c6635792 ("PCI: Allocate dma_alias_mask with
bitmap_zalloc()"), but I doubt it was possible to see a problem because
it takes 4 64-bit longs (or 8 32-bit longs) to hold 255 bits, and
bitmap_zalloc() doesn't save the 255-bit size anywhere.

[bhelgaas: commit log, move #define to drivers/pci/pci.h, include loop
limit fix from Qian Cai:
https://lore.kernel.org/r/20191218170004.5297-1-cai@lca.pw]
Signed-off-by: default avatarJames Sewart <jamessewart@arista.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarLogan Gunthorpe <logang@deltatee.com>
parent 8c386cc8
...@@ -6017,7 +6017,7 @@ EXPORT_SYMBOL_GPL(pci_pr3_present); ...@@ -6017,7 +6017,7 @@ EXPORT_SYMBOL_GPL(pci_pr3_present);
void pci_add_dma_alias(struct pci_dev *dev, u8 devfn) void pci_add_dma_alias(struct pci_dev *dev, u8 devfn)
{ {
if (!dev->dma_alias_mask) if (!dev->dma_alias_mask)
dev->dma_alias_mask = bitmap_zalloc(U8_MAX, GFP_KERNEL); dev->dma_alias_mask = bitmap_zalloc(MAX_NR_DEVFNS, GFP_KERNEL);
if (!dev->dma_alias_mask) { if (!dev->dma_alias_mask) {
pci_warn(dev, "Unable to allocate DMA alias mask\n"); pci_warn(dev, "Unable to allocate DMA alias mask\n");
return; return;
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
#include <linux/pci.h> #include <linux/pci.h>
/* Number of possible devfns: 0.0 to 1f.7 inclusive */
#define MAX_NR_DEVFNS 256
#define PCI_FIND_CAP_TTL 48 #define PCI_FIND_CAP_TTL 48
#define PCI_VSEC_ID_INTEL_TBT 0x1234 /* Thunderbolt */ #define PCI_VSEC_ID_INTEL_TBT 0x1234 /* Thunderbolt */
......
...@@ -41,9 +41,9 @@ int pci_for_each_dma_alias(struct pci_dev *pdev, ...@@ -41,9 +41,9 @@ int pci_for_each_dma_alias(struct pci_dev *pdev,
* DMA, iterate over that too. * DMA, iterate over that too.
*/ */
if (unlikely(pdev->dma_alias_mask)) { if (unlikely(pdev->dma_alias_mask)) {
u8 devfn; unsigned int devfn;
for_each_set_bit(devfn, pdev->dma_alias_mask, U8_MAX) { for_each_set_bit(devfn, pdev->dma_alias_mask, MAX_NR_DEVFNS) {
ret = fn(pdev, PCI_DEVID(pdev->bus->number, devfn), ret = fn(pdev, PCI_DEVID(pdev->bus->number, devfn),
data); data);
if (ret) if (ret)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment