when do virtual secondary bus reset, the vfio device under this bus need to do host bus reset to reset the device. so add this case.
Signed-off-by: Chen Fan <chen.fan.f...@cn.fujitsu.com> --- hw/vfio/pci.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index aeb489e..9181c15 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -4158,6 +4158,27 @@ static void vfio_exitfn(PCIDevice *pdev) vfio_unregister_bars(vdev); } +static int vfio_pci_is_single_function(VFIOPCIDevice *vdev) +{ + struct vfio_pci_hot_reset_info *info = NULL; + int ret; + + ret = vfio_get_hot_reset_info(vdev, &info); + if (ret) { + goto out; + } + + if (info->count > 1) { + ret = 0; + goto out; + } + + ret = 1; +out: + g_free(info); + return ret; +} + static void vfio_pci_reset(DeviceState *dev) { PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, dev); @@ -4165,6 +4186,16 @@ static void vfio_pci_reset(DeviceState *dev) trace_vfio_pci_reset(vdev->vbasedev.name); + if (vdev->needs_bus_reset) { + vdev->needs_bus_reset = false; + /* Avoid duplicate bus reset */ + if (vdev->vbasedev.needs_reset) { + vfio_pci_hot_reset(vdev, + vfio_pci_is_single_function(vdev) ? true : false); + } + return; + } + vfio_pci_pre_reset(vdev); if (vdev->resetfn && !vdev->resetfn(vdev)) { -- 1.9.3