pcie_sriov: Reset SR-IOV extended capability
pcie_sriov_pf_disable_vfs() is called when resetting the PF, but it only disables VFs and does not reset SR-IOV extended capability, leaking the state and making the VF Enable register inconsistent with the actual state. Replace pcie_sriov_pf_disable_vfs() with pcie_sriov_pf_reset(), which does not only disable VFs but also resets the capability. Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> Message-Id: <20240228-reuse-v8-3-282660281e60@daynix.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Sriram Yagnaraman <sriram.yagnaraman@ericsson.com>
This commit is contained in:
parent
6081b4243c
commit
c8bc4db403
@ -493,7 +493,7 @@ static void igb_qdev_reset_hold(Object *obj)
|
|||||||
|
|
||||||
trace_e1000e_cb_qdev_reset_hold();
|
trace_e1000e_cb_qdev_reset_hold();
|
||||||
|
|
||||||
pcie_sriov_pf_disable_vfs(d);
|
pcie_sriov_pf_reset(d);
|
||||||
igb_core_reset(&s->core);
|
igb_core_reset(&s->core);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7116,7 +7116,7 @@ static void nvme_ctrl_reset(NvmeCtrl *n, NvmeResetType rst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rst != NVME_RESET_CONTROLLER) {
|
if (rst != NVME_RESET_CONTROLLER) {
|
||||||
pcie_sriov_pf_disable_vfs(pci_dev);
|
pcie_sriov_pf_reset(pci_dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,16 +249,26 @@ void pcie_sriov_config_write(PCIDevice *dev, uint32_t address,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Reset SR/IOV VF Enable bit to trigger an unregister of all VFs */
|
/* Reset SR/IOV */
|
||||||
void pcie_sriov_pf_disable_vfs(PCIDevice *dev)
|
void pcie_sriov_pf_reset(PCIDevice *dev)
|
||||||
{
|
{
|
||||||
uint16_t sriov_cap = dev->exp.sriov_cap;
|
uint16_t sriov_cap = dev->exp.sriov_cap;
|
||||||
if (sriov_cap) {
|
if (!sriov_cap) {
|
||||||
uint32_t val = pci_get_byte(dev->config + sriov_cap + PCI_SRIOV_CTRL);
|
return;
|
||||||
if (val & PCI_SRIOV_CTRL_VFE) {
|
}
|
||||||
val &= ~PCI_SRIOV_CTRL_VFE;
|
|
||||||
pcie_sriov_config_write(dev, sriov_cap + PCI_SRIOV_CTRL, val, 1);
|
pci_set_word(dev->config + sriov_cap + PCI_SRIOV_CTRL, 0);
|
||||||
}
|
unregister_vfs(dev);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default is to use 4K pages, software can modify it
|
||||||
|
* to any of the supported bits
|
||||||
|
*/
|
||||||
|
pci_set_word(dev->config + sriov_cap + PCI_SRIOV_SYS_PGSIZE, 0x1);
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < PCI_NUM_REGIONS; i++) {
|
||||||
|
pci_set_quad(dev->config + sriov_cap + PCI_SRIOV_BAR + i * 4,
|
||||||
|
dev->exp.sriov_pf.vf_bar_type[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,8 +58,8 @@ void pcie_sriov_pf_add_sup_pgsize(PCIDevice *dev, uint16_t opt_sup_pgsize);
|
|||||||
void pcie_sriov_config_write(PCIDevice *dev, uint32_t address,
|
void pcie_sriov_config_write(PCIDevice *dev, uint32_t address,
|
||||||
uint32_t val, int len);
|
uint32_t val, int len);
|
||||||
|
|
||||||
/* Reset SR/IOV VF Enable bit to unregister all VFs */
|
/* Reset SR/IOV */
|
||||||
void pcie_sriov_pf_disable_vfs(PCIDevice *dev);
|
void pcie_sriov_pf_reset(PCIDevice *dev);
|
||||||
|
|
||||||
/* Get logical VF number of a VF - only valid for VFs */
|
/* Get logical VF number of a VF - only valid for VFs */
|
||||||
uint16_t pcie_sriov_vf_number(PCIDevice *dev);
|
uint16_t pcie_sriov_vf_number(PCIDevice *dev);
|
||||||
|
Loading…
Reference in New Issue
Block a user