i40e: Check if the BAR size is large enough before writing to registers
authorAdam Ludkiewicz <adam.ludkiewicz@intel.com>
Wed, 24 Apr 2019 12:20:53 +0000 (05:20 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 14 Jun 2019 20:03:27 +0000 (13:03 -0700)
This patch fixes the problem with a kernel panic occurring when trying
to bind the i40e driver to a non-i40e port. The problem is fixed by
checking if the BAR size in the device is large enough by reading the
highest register.

Signed-off-by: Adam Ludkiewicz <adam.ludkiewicz@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_main.c

index 12ae4d99109b565d6b7cb6d9dea17237c84597fb..1d78db15c65ae033f9762b10d580e86749a41270 100644 (file)
@@ -14205,7 +14205,17 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        pf->ioremap_len = min_t(int, pci_resource_len(pdev, 0),
                                I40E_MAX_CSR_SPACE);
-
+       /* We believe that the highest register to read is
+        * I40E_GLGEN_STAT_CLEAR, so we check if the BAR size
+        * is not less than that before mapping to prevent a
+        * kernel panic.
+        */
+       if (pf->ioremap_len < I40E_GLGEN_STAT_CLEAR) {
+               dev_err(&pdev->dev, "Cannot map registers, bar size 0x%X too small, aborting\n",
+                       pf->ioremap_len);
+               err = -ENOMEM;
+               goto err_ioremap;
+       }
        hw->hw_addr = ioremap(pci_resource_start(pdev, 0), pf->ioremap_len);
        if (!hw->hw_addr) {
                err = -EIO;