blob: a0c16b7b9bcd0872534812f28204a19427caac66 [file] [log] [blame]
commit 00da3403d175d8c8a1277b8ef72c2b548cf08b16
Author: Gerald Yang <gerald.yang@canonical.com>
Date: Fri Nov 15 11:54:03 2019 +0800
UBUNTU: SAUCE: i40e Fix GPF when deleting VMs
BugLink: https://bugs.launchpad.net/bugs/1852663
Fix a general protection in i40e_config_vf_promiscuous_mode
When deleting VMs with VFs created by i40e, a general protection
fault occurs in i40e_config_vf_promiscuous_mode due to race
condition for vsi->mac_filter_hash
And it also happens when deleteing pod with VFs
This issue was reported in e1000-devel mailling list
https://sourceforge.net/p/e1000/mailman/message/36766306/
Suggested-by: Billy McFall <bmcfall@redhat.com>
Signed-off-by: Gerald Yang <gerald.yang@canonical.com>
Acked-by: Sultan Alsawaf <sultan.alsawaf@canonical.com>
Acked-by: Connor Kuehl <connor.kuehl@canonical.com>
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 3d2440838822..c40f0586b76c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -1127,6 +1127,7 @@ static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
struct i40e_pf *pf = vf->pf;
struct i40e_hw *hw = &pf->hw;
struct i40e_mac_filter *f;
+ struct hlist_node *h;
i40e_status aq_ret = 0;
struct i40e_vsi *vsi;
int bkt;
@@ -1166,7 +1167,8 @@ static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
}
return aq_ret;
} else if (i40e_getnum_vf_vsi_vlan_filters(vsi)) {
- hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) {
+ spin_lock_bh(&vsi->mac_filter_hash_lock);
+ hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) {
if (f->vlan < 0 || f->vlan > I40E_MAX_VLANID)
continue;
aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan(hw,
@@ -1199,6 +1201,7 @@ static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
i40e_aq_str(&pf->hw, aq_err));
}
}
+ spin_unlock_bh(&vsi->mac_filter_hash_lock);
return aq_ret;
}
aq_ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, allmulti,