in vfio.c [1411:1476]
static long vfio_group_fops_unl_ioctl(struct file *filep,
unsigned int cmd, unsigned long arg)
{
struct vfio_group *group = filep->private_data;
long ret = -ENOTTY;
switch (cmd) {
case VFIO_GROUP_GET_STATUS:
{
struct vfio_group_status status;
unsigned long minsz;
minsz = offsetofend(struct vfio_group_status, flags);
if (copy_from_user(&status, (void __user *)arg, minsz))
return -EFAULT;
if (status.argsz < minsz)
return -EINVAL;
status.flags = 0;
if (vfio_group_viable(group))
status.flags |= VFIO_GROUP_FLAGS_VIABLE;
if (group->container)
status.flags |= VFIO_GROUP_FLAGS_CONTAINER_SET;
if (copy_to_user((void __user *)arg, &status, minsz))
return -EFAULT;
ret = 0;
break;
}
case VFIO_GROUP_SET_CONTAINER:
{
int fd;
if (get_user(fd, (int __user *)arg))
return -EFAULT;
if (fd < 0)
return -EINVAL;
ret = vfio_group_set_container(group, fd);
break;
}
case VFIO_GROUP_UNSET_CONTAINER:
ret = vfio_group_unset_container(group);
break;
case VFIO_GROUP_GET_DEVICE_FD:
{
char *buf;
buf = strndup_user((const char __user *)arg, PAGE_SIZE);
if (IS_ERR(buf))
return PTR_ERR(buf);
ret = vfio_group_get_device_fd(group, buf);
kfree(buf);
break;
}
}
return ret;
}