|
@@ -1528,6 +1528,7 @@ bool vfio_attach_device(char *name, VFIODevice *vbasedev,
|
|
|
{
|
|
|
const VFIOIOMMUClass *ops =
|
|
|
VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_LEGACY));
|
|
|
+ HostIOMMUDevice *hiod;
|
|
|
|
|
|
if (vbasedev->iommufd) {
|
|
|
ops = VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_IOMMUFD));
|
|
@@ -1535,7 +1536,19 @@ bool vfio_attach_device(char *name, VFIODevice *vbasedev,
|
|
|
|
|
|
assert(ops);
|
|
|
|
|
|
- return ops->attach_device(name, vbasedev, as, errp);
|
|
|
+ if (!ops->attach_device(name, vbasedev, as, errp)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ hiod = HOST_IOMMU_DEVICE(object_new(ops->hiod_typename));
|
|
|
+ if (!HOST_IOMMU_DEVICE_GET_CLASS(hiod)->realize(hiod, vbasedev, errp)) {
|
|
|
+ object_unref(hiod);
|
|
|
+ ops->detach_device(vbasedev);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ vbasedev->hiod = hiod;
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
void vfio_detach_device(VFIODevice *vbasedev)
|
|
@@ -1543,5 +1556,6 @@ void vfio_detach_device(VFIODevice *vbasedev)
|
|
|
if (!vbasedev->bcontainer) {
|
|
|
return;
|
|
|
}
|
|
|
+ object_unref(vbasedev->hiod);
|
|
|
vbasedev->bcontainer->ops->detach_device(vbasedev);
|
|
|
}
|