From: Jacob Keller <jacob.e.keller@intel.com> mainline inclusion from mainline-v6.1-rc5 commit f23df5220d2bf8d5e639f074b76f206a736d09e1 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBP3Y9 CVE: CVE-2022-49722 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... ---------------------- The ice_reset_vf function performs actions which must be taken only while holding the VF configuration lock. Some flows already acquired the lock, while other flows must acquire it just for the reset function. Add the ICE_VF_RESET_LOCK flag to the function so that it can handle taking and releasing the lock instead at the appropriate scope. Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> Conflicts: drivers/net/ethernet/intel/ice/ice_main.c drivers/net/ethernet/intel/ice/ice_sriov.c drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h [The conflicts were due to previous commits not merged.] Signed-off-by: Xiaomeng Zhang <zhangxiaomeng13@huawei.com> --- drivers/net/ethernet/intel/ice/ice_main.c | 4 +--- .../net/ethernet/intel/ice/ice_virtchnl_pf.c | 17 +++++++++++++---- .../net/ethernet/intel/ice/ice_virtchnl_pf.h | 1 + 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index ffcb71ccf9ad..0fc0963ec622 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -1608,9 +1608,7 @@ static void ice_handle_mdd_event(struct ice_pf *pf) * reset, so print the event prior to reset. */ ice_print_vf_rx_mdd_event(vf); - mutex_lock(&pf->vf[i].cfg_lock); - ice_reset_vf(&pf->vf[i], 0); - mutex_unlock(&pf->vf[i].cfg_lock); + ice_reset_vf(&pf->vf[i], ICE_VF_RESET_LOCK); } } } diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c index 5b3aef70ac2a..76ecb9dec2ad 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c @@ -1293,11 +1293,10 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags) struct ice_hw *hw; bool rsd = false; u8 promisc_m; + int err = 0; u32 reg; int i; - lockdep_assert_held(&vf->cfg_lock); - dev = ice_pf_to_dev(pf); if (test_bit(__ICE_VF_RESETS_DISABLED, pf->state)) { @@ -1322,6 +1321,11 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags) return 0; } + if (flags & ICE_VF_RESET_LOCK) + mutex_lock(&vf->cfg_lock); + else + lockdep_assert_held(&vf->cfg_lock); + /* Set VF disable bit state here, before triggering reset */ set_bit(ICE_VF_STATE_DIS, vf->vf_states); ice_trigger_vf_reset(vf, flags & ICE_VF_RESET_VFLR, false); @@ -1380,12 +1384,17 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags) if (ice_vf_rebuild_vsi_with_release(vf)) { dev_err(dev, "Failed to release and setup the VF%u's VSI\n", vf->vf_id); - return -EFAULT; + err = -EFAULT; + goto out_unlock; } ice_vf_post_vsi_rebuild(vf); - return 0; +out_unlock: + if (flags & ICE_VF_RESET_LOCK) + mutex_unlock(&vf->cfg_lock); + + return err; } /** diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h index 32eee438ef2e..91f67fa08c51 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h @@ -107,6 +107,7 @@ struct ice_vf { /* Flags for controlling behavior of ice_reset_vf */ enum ice_vf_reset_flags { ICE_VF_RESET_VFLR = BIT(0), /* Indicate a VFLR reset */ + ICE_VF_RESET_LOCK = BIT(1), /* Acquire the VF cfg_lock */ }; #ifdef CONFIG_PCI_IOV -- 2.34.1