Skip to content

Commit 97cc258

Browse files
committed
i40e: fix vf may be used uninitialized in this function warning
jira LE-1907 cve CVE-2024-36020 Rebuild_History Non-Buildable kernel-4.18.0-553.16.1.el8_10 commit-author Aleksandr Loktionov <[email protected]> commit f37c4ea To fix the regression introduced by commit 52424f9, which causes servers hang in very hard to reproduce conditions with resets races. Using two sources for the information is the root cause. In this function before the fix bumping v didn't mean bumping vf pointer. But the code used this variables interchangeably, so stale vf could point to different/not intended vf. Remove redundant "v" variable and iterate via single VF pointer across whole function instead to guarantee VF pointer validity. Fixes: 52424f9 ("i40e: Fix VF hang when reset is triggered on another VF") Signed-off-by: Aleksandr Loktionov <[email protected]> Reviewed-by: Arkadiusz Kubalewski <[email protected]> Reviewed-by: Przemek Kitszel <[email protected]> Reviewed-by: Paul Menzel <[email protected]> Tested-by: Rafal Romanowski <[email protected]> Signed-off-by: Tony Nguyen <[email protected]> (cherry picked from commit f37c4ea) Signed-off-by: Jonathan Maple <[email protected]>
1 parent e761cb3 commit 97cc258

File tree

1 file changed

+16
-18
lines changed

1 file changed

+16
-18
lines changed

drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,8 +1601,8 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
16011601
{
16021602
struct i40e_hw *hw = &pf->hw;
16031603
struct i40e_vf *vf;
1604-
int i, v;
16051604
u32 reg;
1605+
int i;
16061606

16071607
/* If we don't have any VFs, then there is nothing to reset */
16081608
if (!pf->num_alloc_vfs)
@@ -1613,11 +1613,10 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
16131613
return false;
16141614

16151615
/* Begin reset on all VFs at once */
1616-
for (v = 0; v < pf->num_alloc_vfs; v++) {
1617-
vf = &pf->vf[v];
1616+
for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
16181617
/* If VF is being reset no need to trigger reset again */
16191618
if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
1620-
i40e_trigger_vf_reset(&pf->vf[v], flr);
1619+
i40e_trigger_vf_reset(vf, flr);
16211620
}
16221621

16231622
/* HW requires some time to make sure it can flush the FIFO for a VF
@@ -1626,14 +1625,13 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
16261625
* the VFs using a simple iterator that increments once that VF has
16271626
* finished resetting.
16281627
*/
1629-
for (i = 0, v = 0; i < 10 && v < pf->num_alloc_vfs; i++) {
1628+
for (i = 0, vf = &pf->vf[0]; i < 10 && vf < &pf->vf[pf->num_alloc_vfs]; ++i) {
16301629
usleep_range(10000, 20000);
16311630

16321631
/* Check each VF in sequence, beginning with the VF to fail
16331632
* the previous check.
16341633
*/
1635-
while (v < pf->num_alloc_vfs) {
1636-
vf = &pf->vf[v];
1634+
while (vf < &pf->vf[pf->num_alloc_vfs]) {
16371635
if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) {
16381636
reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id));
16391637
if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK))
@@ -1643,7 +1641,7 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
16431641
/* If the current VF has finished resetting, move on
16441642
* to the next VF in sequence.
16451643
*/
1646-
v++;
1644+
++vf;
16471645
}
16481646
}
16491647

@@ -1653,39 +1651,39 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
16531651
/* Display a warning if at least one VF didn't manage to reset in
16541652
* time, but continue on with the operation.
16551653
*/
1656-
if (v < pf->num_alloc_vfs)
1654+
if (vf < &pf->vf[pf->num_alloc_vfs])
16571655
dev_err(&pf->pdev->dev, "VF reset check timeout on VF %d\n",
1658-
pf->vf[v].vf_id);
1656+
vf->vf_id);
16591657
usleep_range(10000, 20000);
16601658

16611659
/* Begin disabling all the rings associated with VFs, but do not wait
16621660
* between each VF.
16631661
*/
1664-
for (v = 0; v < pf->num_alloc_vfs; v++) {
1662+
for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
16651663
/* On initial reset, we don't have any queues to disable */
1666-
if (pf->vf[v].lan_vsi_idx == 0)
1664+
if (vf->lan_vsi_idx == 0)
16671665
continue;
16681666

16691667
/* If VF is reset in another thread just continue */
16701668
if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
16711669
continue;
16721670

1673-
i40e_vsi_stop_rings_no_wait(pf->vsi[pf->vf[v].lan_vsi_idx]);
1671+
i40e_vsi_stop_rings_no_wait(pf->vsi[vf->lan_vsi_idx]);
16741672
}
16751673

16761674
/* Now that we've notified HW to disable all of the VF rings, wait
16771675
* until they finish.
16781676
*/
1679-
for (v = 0; v < pf->num_alloc_vfs; v++) {
1677+
for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
16801678
/* On initial reset, we don't have any queues to disable */
1681-
if (pf->vf[v].lan_vsi_idx == 0)
1679+
if (vf->lan_vsi_idx == 0)
16821680
continue;
16831681

16841682
/* If VF is reset in another thread just continue */
16851683
if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
16861684
continue;
16871685

1688-
i40e_vsi_wait_queues_disabled(pf->vsi[pf->vf[v].lan_vsi_idx]);
1686+
i40e_vsi_wait_queues_disabled(pf->vsi[vf->lan_vsi_idx]);
16891687
}
16901688

16911689
/* Hw may need up to 50ms to finish disabling the RX queues. We
@@ -1694,12 +1692,12 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
16941692
mdelay(50);
16951693

16961694
/* Finish the reset on each VF */
1697-
for (v = 0; v < pf->num_alloc_vfs; v++) {
1695+
for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
16981696
/* If VF is reset in another thread just continue */
16991697
if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
17001698
continue;
17011699

1702-
i40e_cleanup_reset_vf(&pf->vf[v]);
1700+
i40e_cleanup_reset_vf(vf);
17031701
}
17041702

17051703
i40e_flush(hw);

0 commit comments

Comments
 (0)