@@ -4134,6 +4134,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);
@@ -4141,6 +4162,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)) {