aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Mason <jon.mason@exar.com>2010-12-10 09:02:57 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-10 19:08:22 -0500
commitc92bf70dcb9d08f821e4c9f09f8fc328495ba998 (patch)
treeafe424dc0035569e81494750420c3e40e5b39f72
parent528f727279ae840db8a06c94f5e82cdaeb00da6f (diff)
vxge: fix crash of VF when unloading PF
Calling pci_disable_sriov when unloading a SR-IOV physical function driver from a host when a guest is using a virtual function from that device can cause a host crash or VM crash. The crash is caused by the virtual config space no longer being present when PF is removed (due to the pci_disable_sriov). This can be avoided by not calling pci_disable_sriov to disable the PCI space when shutting down the PF. Each function in the X3100 operates independently and in this case will operate properly in the absence of the PF. Also, added improved logic in the detection of SR-IOV initialization. Signed-off-by: Jon Mason <jon.mason@exar.com> Signed-off-by: Ram Vepa <ram.vepa@exar.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/vxge/vxge-main.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index 70c327910f09..9c68c60f27d8 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -4182,6 +4182,20 @@ static int vxge_probe_fw_update(struct vxgedev *vdev)
4182 return ret; 4182 return ret;
4183} 4183}
4184 4184
4185static int __devinit is_sriov_initialized(struct pci_dev *pdev)
4186{
4187 int pos;
4188 u16 ctrl;
4189
4190 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
4191 if (pos) {
4192 pci_read_config_word(pdev, pos + PCI_SRIOV_CTRL, &ctrl);
4193 if (ctrl & PCI_SRIOV_CTRL_VFE)
4194 return 1;
4195 }
4196 return 0;
4197}
4198
4185/** 4199/**
4186 * vxge_probe 4200 * vxge_probe
4187 * @pdev : structure containing the PCI related information of the device. 4201 * @pdev : structure containing the PCI related information of the device.
@@ -4370,14 +4384,13 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
4370 num_vfs = vxge_get_num_vfs(function_mode) - 1; 4384 num_vfs = vxge_get_num_vfs(function_mode) - 1;
4371 4385
4372 /* Enable SRIOV mode, if firmware has SRIOV support and if it is a PF */ 4386 /* Enable SRIOV mode, if firmware has SRIOV support and if it is a PF */
4373 if (is_sriov(function_mode) && (max_config_dev > 1) && 4387 if (is_sriov(function_mode) && !is_sriov_initialized(pdev) &&
4374 (ll_config->intr_type != INTA) && 4388 (ll_config->intr_type != INTA)) {
4375 (is_privileged == VXGE_HW_OK)) { 4389 ret = pci_enable_sriov(pdev, num_vfs);
4376 ret = pci_enable_sriov(pdev, ((max_config_dev - 1) < num_vfs)
4377 ? (max_config_dev - 1) : num_vfs);
4378 if (ret) 4390 if (ret)
4379 vxge_debug_ll_config(VXGE_ERR, 4391 vxge_debug_ll_config(VXGE_ERR,
4380 "Failed in enabling SRIOV mode: %d\n", ret); 4392 "Failed in enabling SRIOV mode: %d\n", ret);
4393 /* No need to fail out, as an error here is non-fatal */
4381 } 4394 }
4382 4395
4383 /* 4396 /*
@@ -4673,8 +4686,6 @@ static void __devexit vxge_remove(struct pci_dev *pdev)
4673 4686
4674 iounmap(vdev->bar0); 4687 iounmap(vdev->bar0);
4675 4688
4676 pci_disable_sriov(pdev);
4677
4678 /* we are safe to free it now */ 4689 /* we are safe to free it now */
4679 free_netdev(dev); 4690 free_netdev(dev);
4680 4691