| 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, |