Skip to content

Commit

Permalink
vfio/pci: Extract out a helper vfio_pci_get_pci_hot_reset_info
Browse files Browse the repository at this point in the history
This helper will be used by both legacy and iommufd backends.

No functional changes intended.

Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Tested-by: Eric Auger <eric.auger@redhat.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
  • Loading branch information
duanzhenzhong authored and legoater committed Dec 19, 2023
1 parent 714e9af commit 4d36ec2
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 17 deletions.
54 changes: 37 additions & 17 deletions hw/vfio/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2445,47 +2445,67 @@ static bool vfio_pci_host_match(PCIHostDeviceAddress *addr, const char *name)
return (strcmp(tmp, name) == 0);
}

static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single)
int vfio_pci_get_pci_hot_reset_info(VFIOPCIDevice *vdev,
struct vfio_pci_hot_reset_info **info_p)
{
VFIOGroup *group;
struct vfio_pci_hot_reset_info *info;
struct vfio_pci_dependent_device *devices;
struct vfio_pci_hot_reset *reset;
int32_t *fds;
int ret, i, count;
bool multi = false;
int ret, count;

trace_vfio_pci_hot_reset(vdev->vbasedev.name, single ? "one" : "multi");

if (!single) {
vfio_pci_pre_reset(vdev);
}
vdev->vbasedev.needs_reset = false;
assert(info_p && !*info_p);

info = g_malloc0(sizeof(*info));
info->argsz = sizeof(*info);

ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO, info);
if (ret && errno != ENOSPC) {
ret = -errno;
g_free(info);
if (!vdev->has_pm_reset) {
error_report("vfio: Cannot reset device %s, "
"no available reset mechanism.", vdev->vbasedev.name);
}
goto out_single;
return ret;
}

count = info->count;
info = g_realloc(info, sizeof(*info) + (count * sizeof(*devices)));
info->argsz = sizeof(*info) + (count * sizeof(*devices));
devices = &info->devices[0];
info = g_realloc(info, sizeof(*info) + (count * sizeof(info->devices[0])));
info->argsz = sizeof(*info) + (count * sizeof(info->devices[0]));

ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO, info);
if (ret) {
ret = -errno;
g_free(info);
error_report("vfio: hot reset info failed: %m");
return ret;
}

*info_p = info;
return 0;
}

static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single)
{
VFIOGroup *group;
struct vfio_pci_hot_reset_info *info = NULL;
struct vfio_pci_dependent_device *devices;
struct vfio_pci_hot_reset *reset;
int32_t *fds;
int ret, i, count;
bool multi = false;

trace_vfio_pci_hot_reset(vdev->vbasedev.name, single ? "one" : "multi");

if (!single) {
vfio_pci_pre_reset(vdev);
}
vdev->vbasedev.needs_reset = false;

ret = vfio_pci_get_pci_hot_reset_info(vdev, &info);

if (ret) {
goto out_single;
}
devices = &info->devices[0];

trace_vfio_pci_hot_reset_has_dep_devices(vdev->vbasedev.name);

Expand Down
3 changes: 3 additions & 0 deletions hw/vfio/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr);

extern const PropertyInfo qdev_prop_nv_gpudirect_clique;

int vfio_pci_get_pci_hot_reset_info(VFIOPCIDevice *vdev,
struct vfio_pci_hot_reset_info **info_p);

int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp);

int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
Expand Down

0 comments on commit 4d36ec2

Please sign in to comment.