Commit 15a49b9a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'vfio-v3.11' of git://github.com/awilliam/linux-vfio

Pull vfio updates from Alex Williamson:
 "Largely hugepage support for vfio/type1 iommu and surrounding cleanups
  and fixes"

* tag 'vfio-v3.11' of git://github.com/awilliam/linux-vfio:
  vfio/type1: Fix leak on error path
  vfio: Limit group opens
  vfio/type1: Fix missed frees and zero sized removes
  vfio: fix documentation
  vfio: Provide module option to disable vfio_iommu_type1 hugepage support
  vfio: hugepage support for vfio_iommu_type1
  vfio: Convert type1 iommu to use rbtree
parents 8d10aae2 8d38ef19
...@@ -172,12 +172,12 @@ group and can access them as follows: ...@@ -172,12 +172,12 @@ group and can access them as follows:
struct vfio_device_info device_info = { .argsz = sizeof(device_info) }; struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
/* Create a new container */ /* Create a new container */
container = open("/dev/vfio/vfio, O_RDWR); container = open("/dev/vfio/vfio", O_RDWR);
if (ioctl(container, VFIO_GET_API_VERSION) != VFIO_API_VERSION) if (ioctl(container, VFIO_GET_API_VERSION) != VFIO_API_VERSION)
/* Unknown API version */ /* Unknown API version */
if (!ioctl(container, VFIO_CHECK_EXTENSION, VFIO_X86_IOMMU)) if (!ioctl(container, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU))
/* Doesn't support the IOMMU driver we want. */ /* Doesn't support the IOMMU driver we want. */
/* Open the group */ /* Open the group */
...@@ -193,7 +193,7 @@ group and can access them as follows: ...@@ -193,7 +193,7 @@ group and can access them as follows:
ioctl(group, VFIO_GROUP_SET_CONTAINER, &container); ioctl(group, VFIO_GROUP_SET_CONTAINER, &container);
/* Enable the IOMMU model we want */ /* Enable the IOMMU model we want */
ioctl(container, VFIO_SET_IOMMU, VFIO_X86_IOMMU) ioctl(container, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU)
/* Get addition IOMMU info */ /* Get addition IOMMU info */
ioctl(container, VFIO_IOMMU_GET_INFO, &iommu_info); ioctl(container, VFIO_IOMMU_GET_INFO, &iommu_info);
......
...@@ -76,6 +76,7 @@ struct vfio_group { ...@@ -76,6 +76,7 @@ struct vfio_group {
struct notifier_block nb; struct notifier_block nb;
struct list_head vfio_next; struct list_head vfio_next;
struct list_head container_next; struct list_head container_next;
atomic_t opened;
}; };
struct vfio_device { struct vfio_device {
...@@ -206,6 +207,7 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group) ...@@ -206,6 +207,7 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group)
INIT_LIST_HEAD(&group->device_list); INIT_LIST_HEAD(&group->device_list);
mutex_init(&group->device_lock); mutex_init(&group->device_lock);
atomic_set(&group->container_users, 0); atomic_set(&group->container_users, 0);
atomic_set(&group->opened, 0);
group->iommu_group = iommu_group; group->iommu_group = iommu_group;
group->nb.notifier_call = vfio_iommu_group_notifier; group->nb.notifier_call = vfio_iommu_group_notifier;
...@@ -1236,12 +1238,22 @@ static long vfio_group_fops_compat_ioctl(struct file *filep, ...@@ -1236,12 +1238,22 @@ static long vfio_group_fops_compat_ioctl(struct file *filep,
static int vfio_group_fops_open(struct inode *inode, struct file *filep) static int vfio_group_fops_open(struct inode *inode, struct file *filep)
{ {
struct vfio_group *group; struct vfio_group *group;
int opened;
group = vfio_group_get_from_minor(iminor(inode)); group = vfio_group_get_from_minor(iminor(inode));
if (!group) if (!group)
return -ENODEV; return -ENODEV;
/* Do we need multiple instances of the group open? Seems not. */
opened = atomic_cmpxchg(&group->opened, 0, 1);
if (opened) {
vfio_group_put(group);
return -EBUSY;
}
/* Is something still in use from a previous open? */
if (group->container) { if (group->container) {
atomic_dec(&group->opened);
vfio_group_put(group); vfio_group_put(group);
return -EBUSY; return -EBUSY;
} }
...@@ -1259,6 +1271,8 @@ static int vfio_group_fops_release(struct inode *inode, struct file *filep) ...@@ -1259,6 +1271,8 @@ static int vfio_group_fops_release(struct inode *inode, struct file *filep)
vfio_group_try_dissolve_container(group); vfio_group_try_dissolve_container(group);
atomic_dec(&group->opened);
vfio_group_put(group); vfio_group_put(group);
return 0; return 0;
......
This diff is collapsed.
...@@ -362,10 +362,14 @@ struct vfio_iommu_type1_dma_map { ...@@ -362,10 +362,14 @@ struct vfio_iommu_type1_dma_map {
#define VFIO_IOMMU_MAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 13) #define VFIO_IOMMU_MAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 13)
/** /**
* VFIO_IOMMU_UNMAP_DMA - _IOW(VFIO_TYPE, VFIO_BASE + 14, struct vfio_dma_unmap) * VFIO_IOMMU_UNMAP_DMA - _IOWR(VFIO_TYPE, VFIO_BASE + 14,
* struct vfio_dma_unmap)
* *
* Unmap IO virtual addresses using the provided struct vfio_dma_unmap. * Unmap IO virtual addresses using the provided struct vfio_dma_unmap.
* Caller sets argsz. * Caller sets argsz. The actual unmapped size is returned in the size
* field. No guarantee is made to the user that arbitrary unmaps of iova
* or size different from those used in the original mapping call will
* succeed.
*/ */
struct vfio_iommu_type1_dma_unmap { struct vfio_iommu_type1_dma_unmap {
__u32 argsz; __u32 argsz;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment