Skip to content

Commit

Permalink
vxge: fix crash of VF when unloading PF
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jon Mason authored and David S. Miller committed Dec 11, 2010
1 parent 528f727 commit c92bf70
Showing 1 changed file with 18 additions and 7 deletions.
25 changes: 18 additions & 7 deletions drivers/net/vxge/vxge-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4182,6 +4182,20 @@ static int vxge_probe_fw_update(struct vxgedev *vdev)
return ret;
}

static int __devinit is_sriov_initialized(struct pci_dev *pdev)
{
int pos;
u16 ctrl;

pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
if (pos) {
pci_read_config_word(pdev, pos + PCI_SRIOV_CTRL, &ctrl);
if (ctrl & PCI_SRIOV_CTRL_VFE)
return 1;
}
return 0;
}

/**
* vxge_probe
* @pdev : structure containing the PCI related information of the device.
Expand Down Expand Up @@ -4370,14 +4384,13 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
num_vfs = vxge_get_num_vfs(function_mode) - 1;

/* Enable SRIOV mode, if firmware has SRIOV support and if it is a PF */
if (is_sriov(function_mode) && (max_config_dev > 1) &&
(ll_config->intr_type != INTA) &&
(is_privileged == VXGE_HW_OK)) {
ret = pci_enable_sriov(pdev, ((max_config_dev - 1) < num_vfs)
? (max_config_dev - 1) : num_vfs);
if (is_sriov(function_mode) && !is_sriov_initialized(pdev) &&
(ll_config->intr_type != INTA)) {
ret = pci_enable_sriov(pdev, num_vfs);
if (ret)
vxge_debug_ll_config(VXGE_ERR,
"Failed in enabling SRIOV mode: %d\n", ret);
/* No need to fail out, as an error here is non-fatal */
}

/*
Expand Down Expand Up @@ -4673,8 +4686,6 @@ static void __devexit vxge_remove(struct pci_dev *pdev)

iounmap(vdev->bar0);

pci_disable_sriov(pdev);

/* we are safe to free it now */
free_netdev(dev);

Expand Down

0 comments on commit c92bf70

Please sign in to comment.