aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSlawomir Laba <slawomirx.laba@intel.com>2019-07-23 06:01:39 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2019-08-22 13:24:14 -0700
commit9889707b06acfe9bb37a6edcaae627d4a5eacc72 (patch)
tree80a0c117a328e4565283adc33ce45216f33ddaa8
parenti40e: reset veb.tc_stats when resetting veb.stats (diff)
downloadlinux-dev-9889707b06acfe9bb37a6edcaae627d4a5eacc72.tar.xz
linux-dev-9889707b06acfe9bb37a6edcaae627d4a5eacc72.zip
i40e: Fix crash caused by stress setting of VF MAC addresses
Add update to the VSI pointer passed to the i40e_set_vf_mac function. If VF is in reset state the driver waits in i40e_set_vf_mac function for the reset to be complete, yet after reset the vsi pointer that was passed into this function is no longer valid. The patch updates local VSI pointer directly from pf->vsi array, by using the id stored in VF pointer (lan_vsi_idx). Without this commit the driver might occasionally invoke general protection fault in kernel and disable the OS entirely. Signed-off-by: Slawomir Laba <slawomirx.laba@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 4601f9e4e998..f8aa4deceb5e 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -3967,10 +3967,15 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
/* When the VF is resetting wait until it is done.
* It can take up to 200 milliseconds,
* but wait for up to 300 milliseconds to be safe.
+ * If the VF is indeed in reset, the vsi pointer has
+ * to show on the newly loaded vsi under pf->vsi[id].
*/
for (i = 0; i < 15; i++) {
- if (test_bit(I40E_VF_STATE_INIT, &vf->vf_states))
+ if (test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) {
+ if (i > 0)
+ vsi = pf->vsi[vf->lan_vsi_idx];
break;
+ }
msleep(20);
}
if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) {