summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/cavium
diff options
context:
space:
mode:
authorRick Farrington <ricardo.farrington@cavium.com>2017-08-30 16:19:53 -0700
committerDavid S. Miller <davem@davemloft.net>2017-08-30 22:07:09 -0700
commitacfb98b99647aa7dc7c111db52d5f4199d2b641f (patch)
tree60f309fcdf3198d3f7ee00b319dfd43a3051b27c /drivers/net/ethernet/cavium
parent12bdc5e1e58304d27cb16e30597e2e706e536fb1 (diff)
downloadlinux-acfb98b99647aa7dc7c111db52d5f4199d2b641f.tar.gz
linux-acfb98b99647aa7dc7c111db52d5f4199d2b641f.tar.bz2
linux-acfb98b99647aa7dc7c111db52d5f4199d2b641f.zip
liquidio: fix crash in presence of zeroed-out base address regs
Fix crash in linux PF driver when BARs have been cleared/de-programmed; fail early init (prior to mapping BARs) if the BAR0 or BAR1 registers are zero. This situation can arise when the PF is added to a VM (PCI pass-through), then a PF FLR is issued (in the VM). After this occurs, the BAR registers will be zero. If we attempt to load the PF driver in the host (after VM has been shutdown), the host can reset. Signed-off-by: Rick Farrington <ricardo.farrington@cavium.com> Signed-off-by: Raghu Vatsavayi <raghu.vatsavayi@cavium.com> Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/cavium')
-rw-r--r--drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
index f6c0bad78cd4..e8b290473ee2 100644
--- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
+++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
@@ -1305,6 +1305,26 @@ static int cn23xx_sriov_config(struct octeon_device *oct)
int setup_cn23xx_octeon_pf_device(struct octeon_device *oct)
{
+ u32 data32;
+ u64 BAR0, BAR1;
+
+ pci_read_config_dword(oct->pci_dev, PCI_BASE_ADDRESS_0, &data32);
+ BAR0 = (u64)(data32 & ~0xf);
+ pci_read_config_dword(oct->pci_dev, PCI_BASE_ADDRESS_1, &data32);
+ BAR0 |= ((u64)data32 << 32);
+ pci_read_config_dword(oct->pci_dev, PCI_BASE_ADDRESS_2, &data32);
+ BAR1 = (u64)(data32 & ~0xf);
+ pci_read_config_dword(oct->pci_dev, PCI_BASE_ADDRESS_3, &data32);
+ BAR1 |= ((u64)data32 << 32);
+
+ if (!BAR0 || !BAR1) {
+ if (!BAR0)
+ dev_err(&oct->pci_dev->dev, "device BAR0 unassigned\n");
+ if (!BAR1)
+ dev_err(&oct->pci_dev->dev, "device BAR1 unassigned\n");
+ return 1;
+ }
+
if (octeon_map_pci_barx(oct, 0, 0))
return 1;