mirror of https://github.com/xemu-project/xemu.git
vfio/ccw: Use vfio_[attach/detach]_device
Let the vfio-ccw device use vfio_attach_device() and vfio_detach_device(), hence hiding the details of the used IOMMU backend. Note that the migration reduces the following trace "vfio: subchannel %s has already been attached" (featuring cssid.ssid.devid) into "device is already attached" Also now all the devices have been migrated to use the new vfio_attach_device/vfio_detach_device API, let's turn the legacy functions into static functions, local to container.c. Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Yi Liu <yi.l.liu@intel.com> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
parent
c95d128ee3
commit
e08041ece7
117
hw/vfio/ccw.c
117
hw/vfio/ccw.c
|
@ -572,88 +572,14 @@ static void vfio_ccw_put_region(VFIOCCWDevice *vcdev)
|
||||||
g_free(vcdev->io_region);
|
g_free(vcdev->io_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vfio_ccw_put_device(VFIOCCWDevice *vcdev)
|
|
||||||
{
|
|
||||||
g_free(vcdev->vdev.name);
|
|
||||||
vfio_put_base_device(&vcdev->vdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vfio_ccw_get_device(VFIOGroup *group, VFIOCCWDevice *vcdev,
|
|
||||||
Error **errp)
|
|
||||||
{
|
|
||||||
S390CCWDevice *cdev = S390_CCW_DEVICE(vcdev);
|
|
||||||
char *name = g_strdup_printf("%x.%x.%04x", cdev->hostid.cssid,
|
|
||||||
cdev->hostid.ssid,
|
|
||||||
cdev->hostid.devid);
|
|
||||||
VFIODevice *vbasedev;
|
|
||||||
|
|
||||||
QLIST_FOREACH(vbasedev, &group->device_list, next) {
|
|
||||||
if (strcmp(vbasedev->name, name) == 0) {
|
|
||||||
error_setg(errp, "vfio: subchannel %s has already been attached",
|
|
||||||
name);
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* All vfio-ccw devices are believed to operate in a way compatible with
|
|
||||||
* discarding of memory in RAM blocks, ie. pages pinned in the host are
|
|
||||||
* in the current working set of the guest driver and therefore never
|
|
||||||
* overlap e.g., with pages available to the guest balloon driver. This
|
|
||||||
* needs to be set before vfio_get_device() for vfio common to handle
|
|
||||||
* ram_block_discard_disable().
|
|
||||||
*/
|
|
||||||
vcdev->vdev.ram_block_discard_allowed = true;
|
|
||||||
|
|
||||||
if (vfio_get_device(group, cdev->mdevid, &vcdev->vdev, errp)) {
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
vcdev->vdev.ops = &vfio_ccw_ops;
|
|
||||||
vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW;
|
|
||||||
vcdev->vdev.name = name;
|
|
||||||
vcdev->vdev.dev = DEVICE(vcdev);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
out_err:
|
|
||||||
g_free(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, Error **errp)
|
|
||||||
{
|
|
||||||
char *tmp, group_path[PATH_MAX];
|
|
||||||
ssize_t len;
|
|
||||||
int groupid;
|
|
||||||
|
|
||||||
tmp = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/%s/iommu_group",
|
|
||||||
cdev->hostid.cssid, cdev->hostid.ssid,
|
|
||||||
cdev->hostid.devid, cdev->mdevid);
|
|
||||||
len = readlink(tmp, group_path, sizeof(group_path));
|
|
||||||
g_free(tmp);
|
|
||||||
|
|
||||||
if (len <= 0 || len >= sizeof(group_path)) {
|
|
||||||
error_setg(errp, "vfio: no iommu_group found");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
group_path[len] = 0;
|
|
||||||
|
|
||||||
if (sscanf(basename(group_path), "%d", &groupid) != 1) {
|
|
||||||
error_setg(errp, "vfio: failed to read %s", group_path);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return vfio_get_group(groupid, &address_space_memory, errp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vfio_ccw_realize(DeviceState *dev, Error **errp)
|
static void vfio_ccw_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
VFIOGroup *group;
|
|
||||||
S390CCWDevice *cdev = S390_CCW_DEVICE(dev);
|
S390CCWDevice *cdev = S390_CCW_DEVICE(dev);
|
||||||
VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
|
VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
|
||||||
S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
|
S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
|
||||||
|
VFIODevice *vbasedev = &vcdev->vdev;
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* Call the class init function for subchannel. */
|
/* Call the class init function for subchannel. */
|
||||||
if (cdc->realize) {
|
if (cdc->realize) {
|
||||||
|
@ -663,14 +589,27 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
group = vfio_ccw_get_group(cdev, &err);
|
vbasedev->ops = &vfio_ccw_ops;
|
||||||
if (!group) {
|
vbasedev->type = VFIO_DEVICE_TYPE_CCW;
|
||||||
goto out_group_err;
|
vbasedev->name = g_strdup_printf("%x.%x.%04x", vcdev->cdev.hostid.cssid,
|
||||||
}
|
vcdev->cdev.hostid.ssid,
|
||||||
|
vcdev->cdev.hostid.devid);
|
||||||
|
vbasedev->dev = dev;
|
||||||
|
|
||||||
vfio_ccw_get_device(group, vcdev, &err);
|
/*
|
||||||
if (err) {
|
* All vfio-ccw devices are believed to operate in a way compatible with
|
||||||
goto out_device_err;
|
* discarding of memory in RAM blocks, ie. pages pinned in the host are
|
||||||
|
* in the current working set of the guest driver and therefore never
|
||||||
|
* overlap e.g., with pages available to the guest balloon driver. This
|
||||||
|
* needs to be set before vfio_get_device() for vfio common to handle
|
||||||
|
* ram_block_discard_disable().
|
||||||
|
*/
|
||||||
|
vbasedev->ram_block_discard_allowed = true;
|
||||||
|
|
||||||
|
ret = vfio_attach_device(cdev->mdevid, vbasedev,
|
||||||
|
&address_space_memory, errp);
|
||||||
|
if (ret) {
|
||||||
|
goto out_attach_dev_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
vfio_ccw_get_region(vcdev, &err);
|
vfio_ccw_get_region(vcdev, &err);
|
||||||
|
@ -708,10 +647,9 @@ out_irq_notifier_err:
|
||||||
out_io_notifier_err:
|
out_io_notifier_err:
|
||||||
vfio_ccw_put_region(vcdev);
|
vfio_ccw_put_region(vcdev);
|
||||||
out_region_err:
|
out_region_err:
|
||||||
vfio_ccw_put_device(vcdev);
|
vfio_detach_device(vbasedev);
|
||||||
out_device_err:
|
out_attach_dev_err:
|
||||||
vfio_put_group(group);
|
g_free(vbasedev->name);
|
||||||
out_group_err:
|
|
||||||
if (cdc->unrealize) {
|
if (cdc->unrealize) {
|
||||||
cdc->unrealize(cdev);
|
cdc->unrealize(cdev);
|
||||||
}
|
}
|
||||||
|
@ -724,14 +662,13 @@ static void vfio_ccw_unrealize(DeviceState *dev)
|
||||||
S390CCWDevice *cdev = S390_CCW_DEVICE(dev);
|
S390CCWDevice *cdev = S390_CCW_DEVICE(dev);
|
||||||
VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
|
VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
|
||||||
S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
|
S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
|
||||||
VFIOGroup *group = vcdev->vdev.group;
|
|
||||||
|
|
||||||
vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX);
|
vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX);
|
||||||
vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX);
|
vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX);
|
||||||
vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
|
vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
|
||||||
vfio_ccw_put_region(vcdev);
|
vfio_ccw_put_region(vcdev);
|
||||||
vfio_ccw_put_device(vcdev);
|
vfio_detach_device(&vcdev->vdev);
|
||||||
vfio_put_group(group);
|
g_free(vcdev->vdev.name);
|
||||||
|
|
||||||
if (cdc->unrealize) {
|
if (cdc->unrealize) {
|
||||||
cdc->unrealize(cdev);
|
cdc->unrealize(cdev);
|
||||||
|
|
|
@ -2335,7 +2335,7 @@ static void vfio_disconnect_container(VFIOGroup *group)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp)
|
static VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp)
|
||||||
{
|
{
|
||||||
VFIOGroup *group;
|
VFIOGroup *group;
|
||||||
char path[32];
|
char path[32];
|
||||||
|
@ -2402,7 +2402,7 @@ free_group_exit:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vfio_put_group(VFIOGroup *group)
|
static void vfio_put_group(VFIOGroup *group)
|
||||||
{
|
{
|
||||||
if (!group || !QLIST_EMPTY(&group->device_list)) {
|
if (!group || !QLIST_EMPTY(&group->device_list)) {
|
||||||
return;
|
return;
|
||||||
|
@ -2447,7 +2447,7 @@ retry:
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vfio_get_device(VFIOGroup *group, const char *name,
|
static int vfio_get_device(VFIOGroup *group, const char *name,
|
||||||
VFIODevice *vbasedev, Error **errp)
|
VFIODevice *vbasedev, Error **errp)
|
||||||
{
|
{
|
||||||
g_autofree struct vfio_device_info *info = NULL;
|
g_autofree struct vfio_device_info *info = NULL;
|
||||||
|
@ -2506,7 +2506,7 @@ int vfio_get_device(VFIOGroup *group, const char *name,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vfio_put_base_device(VFIODevice *vbasedev)
|
static void vfio_put_base_device(VFIODevice *vbasedev)
|
||||||
{
|
{
|
||||||
if (!vbasedev->group) {
|
if (!vbasedev->group) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -202,7 +202,6 @@ typedef struct {
|
||||||
hwaddr pages;
|
hwaddr pages;
|
||||||
} VFIOBitmap;
|
} VFIOBitmap;
|
||||||
|
|
||||||
void vfio_put_base_device(VFIODevice *vbasedev);
|
|
||||||
void vfio_disable_irqindex(VFIODevice *vbasedev, int index);
|
void vfio_disable_irqindex(VFIODevice *vbasedev, int index);
|
||||||
void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index);
|
void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index);
|
||||||
void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index);
|
void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index);
|
||||||
|
@ -220,11 +219,7 @@ void vfio_region_unmap(VFIORegion *region);
|
||||||
void vfio_region_exit(VFIORegion *region);
|
void vfio_region_exit(VFIORegion *region);
|
||||||
void vfio_region_finalize(VFIORegion *region);
|
void vfio_region_finalize(VFIORegion *region);
|
||||||
void vfio_reset_handler(void *opaque);
|
void vfio_reset_handler(void *opaque);
|
||||||
VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp);
|
|
||||||
void vfio_put_group(VFIOGroup *group);
|
|
||||||
struct vfio_device_info *vfio_get_device_info(int fd);
|
struct vfio_device_info *vfio_get_device_info(int fd);
|
||||||
int vfio_get_device(VFIOGroup *group, const char *name,
|
|
||||||
VFIODevice *vbasedev, Error **errp);
|
|
||||||
int vfio_attach_device(char *name, VFIODevice *vbasedev,
|
int vfio_attach_device(char *name, VFIODevice *vbasedev,
|
||||||
AddressSpace *as, Error **errp);
|
AddressSpace *as, Error **errp);
|
||||||
void vfio_detach_device(VFIODevice *vbasedev);
|
void vfio_detach_device(VFIODevice *vbasedev);
|
||||||
|
|
Loading…
Reference in New Issue