Skip to content

Commit 371e576

Browse files
CuriousPanCakeanguy11
authored andcommitted
i40e: Restore VF MSI-X state during PCI reset
During a PCI FLR the MSI-X Enable flag in the VF PCI MSI-X capability register will be cleared. This can lead to issues when a VF is assigned to a VM because in these cases the VF driver receives no indication of the PF PCI error/reset and additionally it is incapable of restoring the cleared flag in the hypervisor configuration space without fully reinitializing the driver interrupt functionality. Since the VF driver is unable to easily resolve this condition on its own, restore the VF MSI-X flag during the PF PCI reset handling. Fixes: 19b7960 ("i40e: implement split PCI error reset handler") Co-developed-by: Karen Ostrowska <karen.ostrowska@intel.com> Signed-off-by: Karen Ostrowska <karen.ostrowska@intel.com> Co-developed-by: Mateusz Palczewski <mateusz.palczewski@intel.com> Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com> Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Signed-off-by: Andrii Staikov <andrii.staikov@intel.com> Tested-by: Rafal Romanowski <rafal.romanowski@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
1 parent 6a15584 commit 371e576

File tree

3 files changed

+32
-0
lines changed

3 files changed

+32
-0
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16518,6 +16518,9 @@ static void i40e_pci_error_reset_done(struct pci_dev *pdev)
1651816518
return;
1651916519

1652016520
i40e_reset_and_rebuild(pf, false, false);
16521+
#ifdef CONFIG_PCI_IOV
16522+
i40e_restore_all_vfs_msi_state(pdev);
16523+
#endif /* CONFIG_PCI_IOV */
1652116524
}
1652216525

1652316526
/**

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,32 @@ void i40e_vc_notify_reset(struct i40e_pf *pf)
154154
(u8 *)&pfe, sizeof(struct virtchnl_pf_event));
155155
}
156156

157+
#ifdef CONFIG_PCI_IOV
158+
void i40e_restore_all_vfs_msi_state(struct pci_dev *pdev)
159+
{
160+
u16 vf_id;
161+
u16 pos;
162+
163+
/* Continue only if this is a PF */
164+
if (!pdev->is_physfn)
165+
return;
166+
167+
if (!pci_num_vf(pdev))
168+
return;
169+
170+
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
171+
if (pos) {
172+
struct pci_dev *vf_dev = NULL;
173+
174+
pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &vf_id);
175+
while ((vf_dev = pci_get_device(pdev->vendor, vf_id, vf_dev))) {
176+
if (vf_dev->is_virtfn && vf_dev->physfn == pdev)
177+
pci_restore_msi_state(vf_dev);
178+
}
179+
}
180+
}
181+
#endif /* CONFIG_PCI_IOV */
182+
157183
/**
158184
* i40e_vc_notify_vf_reset
159185
* @vf: pointer to the VF structure

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ int i40e_ndo_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool enable);
137137

138138
void i40e_vc_notify_link_state(struct i40e_pf *pf);
139139
void i40e_vc_notify_reset(struct i40e_pf *pf);
140+
#ifdef CONFIG_PCI_IOV
141+
void i40e_restore_all_vfs_msi_state(struct pci_dev *pdev);
142+
#endif /* CONFIG_PCI_IOV */
140143
int i40e_get_vf_stats(struct net_device *netdev, int vf_id,
141144
struct ifla_vf_stats *vf_stats);
142145

0 commit comments

Comments
 (0)