Skip to content

Commit

Permalink
ice: always check VF VSI pointer values
Browse files Browse the repository at this point in the history
The ice_get_vf_vsi function can return NULL in some cases, such as if
handling messages during a reset where the VSI is being removed and
recreated.

Several places throughout the driver do not bother to check whether this
VSI pointer is valid. Static analysis tools maybe report issues because
they detect paths where a potentially NULL pointer could be dereferenced.

Fix this by checking the return value of ice_get_vf_vsi everywhere.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
  • Loading branch information
Jacob Keller authored and Tony Nguyen committed May 5, 2022
1 parent 9880d3d commit baeb705
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 7 deletions.
5 changes: 4 additions & 1 deletion drivers/net/ethernet/intel/ice/ice_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -773,9 +773,12 @@ int ice_devlink_create_vf_port(struct ice_vf *vf)

pf = vf->pf;
dev = ice_pf_to_dev(pf);
vsi = ice_get_vf_vsi(vf);
devlink_port = &vf->devlink_port;

vsi = ice_get_vf_vsi(vf);
if (!vsi)
return -EINVAL;

attrs.flavour = DEVLINK_PORT_FLAVOUR_PCI_VF;
attrs.pci_vf.pf = pf->hw.bus.func;
attrs.pci_vf.vf = vf->vf_id;
Expand Down
7 changes: 6 additions & 1 deletion drivers/net/ethernet/intel/ice/ice_repr.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,13 @@ static int ice_repr_add(struct ice_vf *vf)
struct ice_q_vector *q_vector;
struct ice_netdev_priv *np;
struct ice_repr *repr;
struct ice_vsi *vsi;
int err;

vsi = ice_get_vf_vsi(vf);
if (!vsi)
return -EINVAL;

repr = kzalloc(sizeof(*repr), GFP_KERNEL);
if (!repr)
return -ENOMEM;
Expand All @@ -313,7 +318,7 @@ static int ice_repr_add(struct ice_vf *vf)
goto err_alloc;
}

repr->src_vsi = ice_get_vf_vsi(vf);
repr->src_vsi = vsi;
repr->vf = vf;
vf->repr = repr;
np = netdev_priv(repr->netdev);
Expand Down
32 changes: 29 additions & 3 deletions drivers/net/ethernet/intel/ice/ice_sriov.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@ static void ice_free_vf_entries(struct ice_pf *pf)
*/
static void ice_vf_vsi_release(struct ice_vf *vf)
{
ice_vsi_release(ice_get_vf_vsi(vf));
struct ice_vsi *vsi = ice_get_vf_vsi(vf);

if (WARN_ON(!vsi))
return;

ice_vsi_release(vsi);
ice_vf_invalidate_vsi(vf);
}

Expand Down Expand Up @@ -104,6 +109,8 @@ static void ice_dis_vf_mappings(struct ice_vf *vf)

hw = &pf->hw;
vsi = ice_get_vf_vsi(vf);
if (WARN_ON(!vsi))
return;

dev = ice_pf_to_dev(pf);
wr32(hw, VPINT_ALLOC(vf->vf_id), 0);
Expand Down Expand Up @@ -341,6 +348,9 @@ static void ice_ena_vf_q_mappings(struct ice_vf *vf, u16 max_txq, u16 max_rxq)
struct ice_hw *hw = &vf->pf->hw;
u32 reg;

if (WARN_ON(!vsi))
return;

/* set regardless of mapping mode */
wr32(hw, VPLAN_TXQ_MAPENA(vf->vf_id), VPLAN_TXQ_MAPENA_TX_ENA_M);

Expand Down Expand Up @@ -386,6 +396,9 @@ static void ice_ena_vf_mappings(struct ice_vf *vf)
{
struct ice_vsi *vsi = ice_get_vf_vsi(vf);

if (WARN_ON(!vsi))
return;

ice_ena_vf_msix_mappings(vf);
ice_ena_vf_q_mappings(vf, vsi->alloc_txq, vsi->alloc_rxq);
}
Expand Down Expand Up @@ -1128,6 +1141,8 @@ static struct ice_vf *ice_get_vf_from_pfq(struct ice_pf *pf, u16 pfq)
u16 rxq_idx;

vsi = ice_get_vf_vsi(vf);
if (!vsi)
continue;

ice_for_each_rxq(vsi, rxq_idx)
if (vsi->rxq_map[rxq_idx] == pfq) {
Expand Down Expand Up @@ -1521,8 +1536,15 @@ static int ice_calc_all_vfs_min_tx_rate(struct ice_pf *pf)
static bool
ice_min_tx_rate_oversubscribed(struct ice_vf *vf, int min_tx_rate)
{
int link_speed_mbps = ice_get_link_speed_mbps(ice_get_vf_vsi(vf));
int all_vfs_min_tx_rate = ice_calc_all_vfs_min_tx_rate(vf->pf);
struct ice_vsi *vsi = ice_get_vf_vsi(vf);
int all_vfs_min_tx_rate;
int link_speed_mbps;

if (WARN_ON(!vsi))
return false;

link_speed_mbps = ice_get_link_speed_mbps(vsi);
all_vfs_min_tx_rate = ice_calc_all_vfs_min_tx_rate(vf->pf);

/* this VF's previous rate is being overwritten */
all_vfs_min_tx_rate -= vf->min_tx_rate;
Expand Down Expand Up @@ -1566,6 +1588,10 @@ ice_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate,
goto out_put_vf;

vsi = ice_get_vf_vsi(vf);
if (!vsi) {
ret = -EINVAL;
goto out_put_vf;
}

/* when max_tx_rate is zero that means no max Tx rate limiting, so only
* check if max_tx_rate is non-zero
Expand Down
28 changes: 27 additions & 1 deletion drivers/net/ethernet/intel/ice/ice_vf_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,10 @@ static void ice_vf_clear_counters(struct ice_vf *vf)
{
struct ice_vsi *vsi = ice_get_vf_vsi(vf);

if (vsi)
vsi->num_vlan = 0;

vf->num_mac = 0;
vsi->num_vlan = 0;
memset(&vf->mdd_tx_events, 0, sizeof(vf->mdd_tx_events));
memset(&vf->mdd_rx_events, 0, sizeof(vf->mdd_rx_events));
}
Expand Down Expand Up @@ -251,6 +253,9 @@ static int ice_vf_rebuild_vsi(struct ice_vf *vf)
struct ice_vsi *vsi = ice_get_vf_vsi(vf);
struct ice_pf *pf = vf->pf;

if (WARN_ON(!vsi))
return -EINVAL;

if (ice_vsi_rebuild(vsi, true)) {
dev_err(ice_pf_to_dev(pf), "failed to rebuild VF %d VSI\n",
vf->vf_id);
Expand Down Expand Up @@ -514,6 +519,10 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
ice_trigger_vf_reset(vf, flags & ICE_VF_RESET_VFLR, false);

vsi = ice_get_vf_vsi(vf);
if (WARN_ON(!vsi)) {
err = -EIO;
goto out_unlock;
}

ice_dis_vf_qs(vf);

Expand Down Expand Up @@ -572,6 +581,11 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)

vf->vf_ops->post_vsi_rebuild(vf);
vsi = ice_get_vf_vsi(vf);
if (WARN_ON(!vsi)) {
err = -EINVAL;
goto out_unlock;
}

ice_eswitch_update_repr(vsi);
ice_eswitch_replay_vf_mac_rule(vf);

Expand Down Expand Up @@ -610,6 +624,9 @@ void ice_dis_vf_qs(struct ice_vf *vf)
{
struct ice_vsi *vsi = ice_get_vf_vsi(vf);

if (WARN_ON(!vsi))
return;

ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, vf->vf_id);
ice_vsi_stop_all_rx_rings(vsi);
ice_set_vf_state_qs_dis(vf);
Expand Down Expand Up @@ -790,6 +807,9 @@ static int ice_vf_rebuild_host_mac_cfg(struct ice_vf *vf)
u8 broadcast[ETH_ALEN];
int status;

if (WARN_ON(!vsi))
return -EINVAL;

if (ice_is_eswitch_mode_switchdev(vf->pf))
return 0;

Expand Down Expand Up @@ -875,6 +895,9 @@ static int ice_vf_rebuild_host_tx_rate_cfg(struct ice_vf *vf)
struct ice_vsi *vsi = ice_get_vf_vsi(vf);
int err;

if (WARN_ON(!vsi))
return -EINVAL;

if (vf->min_tx_rate) {
err = ice_set_min_bw_limit(vsi, (u64)vf->min_tx_rate * 1000);
if (err) {
Expand Down Expand Up @@ -938,6 +961,9 @@ void ice_vf_rebuild_host_cfg(struct ice_vf *vf)
struct device *dev = ice_pf_to_dev(vf->pf);
struct ice_vsi *vsi = ice_get_vf_vsi(vf);

if (WARN_ON(!vsi))
return;

ice_vf_set_host_trust_cfg(vf);

if (ice_vf_rebuild_host_mac_cfg(vf))
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_virtchnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2342,6 +2342,11 @@ static int ice_vc_ena_vlan_stripping(struct ice_vf *vf)
}

vsi = ice_get_vf_vsi(vf);
if (!vsi) {
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
goto error_param;
}

if (vsi->inner_vlan_ops.ena_stripping(vsi, ETH_P_8021Q))
v_ret = VIRTCHNL_STATUS_ERR_PARAM;

Expand Down
7 changes: 6 additions & 1 deletion drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1344,7 +1344,12 @@ static void ice_vf_fdir_dump_info(struct ice_vf *vf)
pf = vf->pf;
hw = &pf->hw;
dev = ice_pf_to_dev(pf);
vf_vsi = pf->vsi[vf->lan_vsi_idx];
vf_vsi = ice_get_vf_vsi(vf);
if (!vf_vsi) {
dev_dbg(dev, "VF %d: invalid VSI pointer\n", vf->vf_id);
return;
}

vsi_num = ice_get_hw_vsi_num(hw, vf_vsi->idx);

fd_size = rd32(hw, VSIQF_FD_SIZE(vsi_num));
Expand Down

0 comments on commit baeb705

Please sign in to comment.