> @@ -2629,6 +2638,46 @@ static long vfio_iommu_type1_ioctl(void *iommu_data, > } > kfree(gbind_data); > return ret; > + } else if (cmd == VFIO_IOMMU_CACHE_INVALIDATE) { Please refactor the spaghetti in this ioctl handler to use a switch statement and a helper function per command before growing it even more. > + /* Get the version of struct iommu_cache_invalidate_info */ > + if (copy_from_user(&version, > + (void __user *) (arg + minsz), sizeof(version))) > + return -EFAULT; > + > + info_size = iommu_uapi_get_data_size( > + IOMMU_UAPI_CACHE_INVAL, version); > + > + cache_info = kzalloc(info_size, GFP_KERNEL); > + if (!cache_info) > + return -ENOMEM; > + > + if (copy_from_user(cache_info, > + (void __user *) (arg + minsz), info_size)) { The user might have changed the version while you were allocating and freeing the memory, introducing potentially exploitable racing conditions.