Commit baeb705f authored by Jacob Keller's avatar Jacob Keller Committed by Tony Nguyen

ice: always check VF VSI pointer values

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: default avatarJacob Keller <jacob.e.keller@intel.com>
Reviewed-by: default avatarPaul Menzel <pmenzel@molgen.mpg.de>
Tested-by: default avatarKonrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 9880d3d6
......@@ -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;
......
......@@ -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;
......@@ -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);
......
......@@ -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);
}
......@@ -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);
......@@ -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);
......@@ -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);
}
......@@ -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) {
......@@ -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;
......@@ -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
......
......@@ -220,8 +220,10 @@ static void ice_vf_clear_counters(struct ice_vf *vf)
{
struct ice_vsi *vsi = ice_get_vf_vsi(vf);
vf->num_mac = 0;
if (vsi)
vsi->num_vlan = 0;
vf->num_mac = 0;
memset(&vf->mdd_tx_events, 0, sizeof(vf->mdd_tx_events));
memset(&vf->mdd_rx_events, 0, sizeof(vf->mdd_rx_events));
}
......@@ -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);
......@@ -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);
......@@ -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);
......@@ -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);
......@@ -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;
......@@ -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) {
......@@ -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))
......
......@@ -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;
......
......@@ -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));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment