summaryrefslogtreecommitdiffstats
path: root/drivers/vfio
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2015-10-15 17:08:48 -0400
committerAlex Williamson <alex.williamson@redhat.com>2015-11-04 11:56:16 -0500
commit033291eccbdb1b70ffc02641edae19ac825dc75d (patch)
tree9aa8159b1f29b389102c29f9e1ca265712d32f89 /drivers/vfio
parente324fc82ea453fcbd3898ec7afb792f750c68979 (diff)
vfio: Include No-IOMMU mode
There is really no way to safely give a user full access to a DMA capable device without an IOMMU to protect the host system. There is also no way to provide DMA translation, for use cases such as device assignment to virtual machines. However, there are still those users that want userspace drivers even under those conditions. The UIO driver exists for this use case, but does not provide the degree of device access and programming that VFIO has. In an effort to avoid code duplication, this introduces a No-IOMMU mode for VFIO. This mode requires building VFIO with CONFIG_VFIO_NOIOMMU and enabling the "enable_unsafe_noiommu_mode" option on the vfio driver. This should make it very clear that this mode is not safe. Additionally, CAP_SYS_RAWIO privileges are necessary to work with groups and containers using this mode. Groups making use of this support are named /dev/vfio/noiommu-$GROUP and can only make use of the special VFIO_NOIOMMU_IOMMU for the container. Use of this mode, specifically binding a device without a native IOMMU group to a VFIO bus driver will taint the kernel and should therefore not be considered supported. This patch includes no-iommu support for the vfio-pci bus driver only. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/vfio')
-rw-r--r--drivers/vfio/Kconfig15
-rw-r--r--drivers/vfio/pci/vfio_pci.c8
-rw-r--r--drivers/vfio/vfio.c186
3 files changed, 199 insertions, 10 deletions
diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig
index 454017928ed0..b6d3cdc2791b 100644
--- a/drivers/vfio/Kconfig
+++ b/drivers/vfio/Kconfig
@@ -31,5 +31,20 @@ menuconfig VFIO
31 31
32 If you don't know what to do here, say N. 32 If you don't know what to do here, say N.
33 33
34menuconfig VFIO_NOIOMMU
35 bool "VFIO No-IOMMU support"
36 depends on VFIO
37 help
38 VFIO is built on the ability to isolate devices using the IOMMU.
39 Only with an IOMMU can userspace access to DMA capable devices be
40 considered secure. VFIO No-IOMMU mode enables IOMMU groups for
41 devices without IOMMU backing for the purpose of re-using the VFIO
42 infrastructure in a non-secure mode. Use of this mode will result
43 in an unsupportable kernel and will therefore taint the kernel.
44 Device assignment to virtual machines is also not possible with
45 this mode since there is no IOMMU to provide DMA translation.
46
47 If you don't know what to do here, say N.
48
34source "drivers/vfio/pci/Kconfig" 49source "drivers/vfio/pci/Kconfig"
35source "drivers/vfio/platform/Kconfig" 50source "drivers/vfio/platform/Kconfig"
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 964ad572aaee..32b88bd2c82c 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -940,13 +940,13 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
940 if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL) 940 if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
941 return -EINVAL; 941 return -EINVAL;
942 942
943 group = iommu_group_get(&pdev->dev); 943 group = vfio_iommu_group_get(&pdev->dev);
944 if (!group) 944 if (!group)
945 return -EINVAL; 945 return -EINVAL;
946 946
947 vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); 947 vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
948 if (!vdev) { 948 if (!vdev) {
949 iommu_group_put(group); 949 vfio_iommu_group_put(group, &pdev->dev);
950 return -ENOMEM; 950 return -ENOMEM;
951 } 951 }
952 952
@@ -957,7 +957,7 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
957 957
958 ret = vfio_add_group_dev(&pdev->dev, &vfio_pci_ops, vdev); 958 ret = vfio_add_group_dev(&pdev->dev, &vfio_pci_ops, vdev);
959 if (ret) { 959 if (ret) {
960 iommu_group_put(group); 960 vfio_iommu_group_put(group, &pdev->dev);
961 kfree(vdev); 961 kfree(vdev);
962 return ret; 962 return ret;
963 } 963 }
@@ -993,7 +993,7 @@ static void vfio_pci_remove(struct pci_dev *pdev)
993 if (!vdev) 993 if (!vdev)
994 return; 994 return;
995 995
996 iommu_group_put(pdev->dev.iommu_group); 996 vfio_iommu_group_put(pdev->dev.iommu_group, &pdev->dev);
997 kfree(vdev); 997 kfree(vdev);
998 998
999 if (vfio_pci_is_vga(pdev)) { 999 if (vfio_pci_is_vga(pdev)) {
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index ab056f7af54d..de632da2e22f 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -62,6 +62,7 @@ struct vfio_container {
62 struct rw_semaphore group_lock; 62 struct rw_semaphore group_lock;
63 struct vfio_iommu_driver *iommu_driver; 63 struct vfio_iommu_driver *iommu_driver;
64 void *iommu_data; 64 void *iommu_data;
65 bool noiommu;
65}; 66};
66 67
67struct vfio_unbound_dev { 68struct vfio_unbound_dev {
@@ -84,6 +85,7 @@ struct vfio_group {
84 struct list_head unbound_list; 85 struct list_head unbound_list;
85 struct mutex unbound_lock; 86 struct mutex unbound_lock;
86 atomic_t opened; 87 atomic_t opened;
88 bool noiommu;
87}; 89};
88 90
89struct vfio_device { 91struct vfio_device {
@@ -95,6 +97,147 @@ struct vfio_device {
95 void *device_data; 97 void *device_data;
96}; 98};
97 99
100#ifdef CONFIG_VFIO_NOIOMMU
101static bool noiommu __read_mostly;
102module_param_named(enable_unsafe_noiommu_support,
103 noiommu, bool, S_IRUGO | S_IWUSR);
104MODULE_PARM_DESC(enable_unsafe_noiommu_mode, "Enable UNSAFE, no-IOMMU mode. This mode provides no device isolation, no DMA translation, no host kernel protection, cannot be used for device assignment to virtual machines, requires RAWIO permissions, and will taint the kernel. If you do not know what this is for, step away. (default: false)");
105#endif
106
107/*
108 * vfio_iommu_group_{get,put} are only intended for VFIO bus driver probe
109 * and remove functions, any use cases other than acquiring the first
110 * reference for the purpose of calling vfio_add_group_dev() or removing
111 * that symmetric reference after vfio_del_group_dev() should use the raw
112 * iommu_group_{get,put} functions. In particular, vfio_iommu_group_put()
113 * removes the device from the dummy group and cannot be nested.
114 */
115struct iommu_group *vfio_iommu_group_get(struct device *dev)
116{
117 struct iommu_group *group;
118 int __maybe_unused ret;
119
120 group = iommu_group_get(dev);
121
122#ifdef CONFIG_VFIO_NOIOMMU
123 /*
124 * With noiommu enabled, an IOMMU group will be created for a device
125 * that doesn't already have one and doesn't have an iommu_ops on their
126 * bus. We use iommu_present() again in the main code to detect these
127 * fake groups.
128 */
129 if (group || !noiommu || iommu_present(dev->bus))
130 return group;
131
132 group = iommu_group_alloc();
133 if (IS_ERR(group))
134 return NULL;
135
136 iommu_group_set_name(group, "vfio-noiommu");
137 ret = iommu_group_add_device(group, dev);
138 iommu_group_put(group);
139 if (ret)
140 return NULL;
141
142 /*
143 * Where to taint? At this point we've added an IOMMU group for a
144 * device that is not backed by iommu_ops, therefore any iommu_
145 * callback using iommu_ops can legitimately Oops. So, while we may
146 * be about to give a DMA capable device to a user without IOMMU
147 * protection, which is clearly taint-worthy, let's go ahead and do
148 * it here.
149 */
150 add_taint(TAINT_USER, LOCKDEP_STILL_OK);
151 dev_warn(dev, "Adding kernel taint for vfio-noiommu group on device\n");
152#endif
153
154 return group;
155}
156EXPORT_SYMBOL_GPL(vfio_iommu_group_get);
157
158void vfio_iommu_group_put(struct iommu_group *group, struct device *dev)
159{
160#ifdef CONFIG_VFIO_NOIOMMU
161 if (!iommu_present(dev->bus))
162 iommu_group_remove_device(dev);
163#endif
164
165 iommu_group_put(group);
166}
167EXPORT_SYMBOL_GPL(vfio_iommu_group_put);
168
169#ifdef CONFIG_VFIO_NOIOMMU
170static void *vfio_noiommu_open(unsigned long arg)
171{
172 if (arg != VFIO_NOIOMMU_IOMMU)
173 return ERR_PTR(-EINVAL);
174 if (!capable(CAP_SYS_RAWIO))
175 return ERR_PTR(-EPERM);
176
177 return NULL;
178}
179
180static void vfio_noiommu_release(void *iommu_data)
181{
182}
183
184static long vfio_noiommu_ioctl(void *iommu_data,
185 unsigned int cmd, unsigned long arg)
186{
187 if (cmd == VFIO_CHECK_EXTENSION)
188 return arg == VFIO_NOIOMMU_IOMMU ? 1 : 0;
189
190 return -ENOTTY;
191}
192
193static int vfio_iommu_present(struct device *dev, void *unused)
194{
195 return iommu_present(dev->bus) ? 1 : 0;
196}
197
198static int vfio_noiommu_attach_group(void *iommu_data,
199 struct iommu_group *iommu_group)
200{
201 return iommu_group_for_each_dev(iommu_group, NULL,
202 vfio_iommu_present) ? -EINVAL : 0;
203}
204
205static void vfio_noiommu_detach_group(void *iommu_data,
206 struct iommu_group *iommu_group)
207{
208}
209
210static struct vfio_iommu_driver_ops vfio_noiommu_ops = {
211 .name = "vfio-noiommu",
212 .owner = THIS_MODULE,
213 .open = vfio_noiommu_open,
214 .release = vfio_noiommu_release,
215 .ioctl = vfio_noiommu_ioctl,
216 .attach_group = vfio_noiommu_attach_group,
217 .detach_group = vfio_noiommu_detach_group,
218};
219
220static struct vfio_iommu_driver vfio_noiommu_driver = {
221 .ops = &vfio_noiommu_ops,
222};
223
224/*
225 * Wrap IOMMU drivers, the noiommu driver is the one and only driver for
226 * noiommu groups (and thus containers) and not available for normal groups.
227 */
228#define vfio_for_each_iommu_driver(con, pos) \
229 for (pos = con->noiommu ? &vfio_noiommu_driver : \
230 list_first_entry(&vfio.iommu_drivers_list, \
231 struct vfio_iommu_driver, vfio_next); \
232 (con->noiommu ? pos != NULL : \
233 &pos->vfio_next != &vfio.iommu_drivers_list); \
234 pos = con->noiommu ? NULL : list_next_entry(pos, vfio_next))
235#else
236#define vfio_for_each_iommu_driver(con, pos) \
237 list_for_each_entry(pos, &vfio.iommu_drivers_list, vfio_next)
238#endif
239
240
98/** 241/**
99 * IOMMU driver registration 242 * IOMMU driver registration
100 */ 243 */
@@ -199,7 +342,8 @@ static void vfio_group_unlock_and_free(struct vfio_group *group)
199/** 342/**
200 * Group objects - create, release, get, put, search 343 * Group objects - create, release, get, put, search
201 */ 344 */
202static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group) 345static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
346 bool noiommu)
203{ 347{
204 struct vfio_group *group, *tmp; 348 struct vfio_group *group, *tmp;
205 struct device *dev; 349 struct device *dev;
@@ -217,6 +361,7 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group)
217 atomic_set(&group->container_users, 0); 361 atomic_set(&group->container_users, 0);
218 atomic_set(&group->opened, 0); 362 atomic_set(&group->opened, 0);
219 group->iommu_group = iommu_group; 363 group->iommu_group = iommu_group;
364 group->noiommu = noiommu;
220 365
221 group->nb.notifier_call = vfio_iommu_group_notifier; 366 group->nb.notifier_call = vfio_iommu_group_notifier;
222 367
@@ -252,7 +397,8 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group)
252 397
253 dev = device_create(vfio.class, NULL, 398 dev = device_create(vfio.class, NULL,
254 MKDEV(MAJOR(vfio.group_devt), minor), 399 MKDEV(MAJOR(vfio.group_devt), minor),
255 group, "%d", iommu_group_id(iommu_group)); 400 group, "%s%d", noiommu ? "noiommu-" : "",
401 iommu_group_id(iommu_group));
256 if (IS_ERR(dev)) { 402 if (IS_ERR(dev)) {
257 vfio_free_group_minor(minor); 403 vfio_free_group_minor(minor);
258 vfio_group_unlock_and_free(group); 404 vfio_group_unlock_and_free(group);
@@ -640,7 +786,8 @@ int vfio_add_group_dev(struct device *dev,
640 786
641 group = vfio_group_get_from_iommu(iommu_group); 787 group = vfio_group_get_from_iommu(iommu_group);
642 if (!group) { 788 if (!group) {
643 group = vfio_create_group(iommu_group); 789 group = vfio_create_group(iommu_group,
790 !iommu_present(dev->bus));
644 if (IS_ERR(group)) { 791 if (IS_ERR(group)) {
645 iommu_group_put(iommu_group); 792 iommu_group_put(iommu_group);
646 return PTR_ERR(group); 793 return PTR_ERR(group);
@@ -852,8 +999,7 @@ static long vfio_ioctl_check_extension(struct vfio_container *container,
852 */ 999 */
853 if (!driver) { 1000 if (!driver) {
854 mutex_lock(&vfio.iommu_drivers_lock); 1001 mutex_lock(&vfio.iommu_drivers_lock);
855 list_for_each_entry(driver, &vfio.iommu_drivers_list, 1002 vfio_for_each_iommu_driver(container, driver) {
856 vfio_next) {
857 if (!try_module_get(driver->ops->owner)) 1003 if (!try_module_get(driver->ops->owner))
858 continue; 1004 continue;
859 1005
@@ -922,7 +1068,7 @@ static long vfio_ioctl_set_iommu(struct vfio_container *container,
922 } 1068 }
923 1069
924 mutex_lock(&vfio.iommu_drivers_lock); 1070 mutex_lock(&vfio.iommu_drivers_lock);
925 list_for_each_entry(driver, &vfio.iommu_drivers_list, vfio_next) { 1071 vfio_for_each_iommu_driver(container, driver) {
926 void *data; 1072 void *data;
927 1073
928 if (!try_module_get(driver->ops->owner)) 1074 if (!try_module_get(driver->ops->owner))
@@ -1187,6 +1333,9 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
1187 if (atomic_read(&group->container_users)) 1333 if (atomic_read(&group->container_users))
1188 return -EINVAL; 1334 return -EINVAL;
1189 1335
1336 if (group->noiommu && !capable(CAP_SYS_RAWIO))
1337 return -EPERM;
1338
1190 f = fdget(container_fd); 1339 f = fdget(container_fd);
1191 if (!f.file) 1340 if (!f.file)
1192 return -EBADF; 1341 return -EBADF;
@@ -1202,6 +1351,13 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
1202 1351
1203 down_write(&container->group_lock); 1352 down_write(&container->group_lock);
1204 1353
1354 /* Real groups and fake groups cannot mix */
1355 if (!list_empty(&container->group_list) &&
1356 container->noiommu != group->noiommu) {
1357 ret = -EPERM;
1358 goto unlock_out;
1359 }
1360
1205 driver = container->iommu_driver; 1361 driver = container->iommu_driver;
1206 if (driver) { 1362 if (driver) {
1207 ret = driver->ops->attach_group(container->iommu_data, 1363 ret = driver->ops->attach_group(container->iommu_data,
@@ -1211,6 +1367,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
1211 } 1367 }
1212 1368
1213 group->container = container; 1369 group->container = container;
1370 container->noiommu = group->noiommu;
1214 list_add(&group->container_next, &container->group_list); 1371 list_add(&group->container_next, &container->group_list);
1215 1372
1216 /* Get a reference on the container and mark a user within the group */ 1373 /* Get a reference on the container and mark a user within the group */
@@ -1241,6 +1398,9 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
1241 !group->container->iommu_driver || !vfio_group_viable(group)) 1398 !group->container->iommu_driver || !vfio_group_viable(group))
1242 return -EINVAL; 1399 return -EINVAL;
1243 1400
1401 if (group->noiommu && !capable(CAP_SYS_RAWIO))
1402 return -EPERM;
1403
1244 device = vfio_device_get_from_name(group, buf); 1404 device = vfio_device_get_from_name(group, buf);
1245 if (!device) 1405 if (!device)
1246 return -ENODEV; 1406 return -ENODEV;
@@ -1283,6 +1443,10 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
1283 1443
1284 fd_install(ret, filep); 1444 fd_install(ret, filep);
1285 1445
1446 if (group->noiommu)
1447 dev_warn(device->dev, "vfio-noiommu device opened by user "
1448 "(%s:%d)\n", current->comm, task_pid_nr(current));
1449
1286 return ret; 1450 return ret;
1287} 1451}
1288 1452
@@ -1371,6 +1535,11 @@ static int vfio_group_fops_open(struct inode *inode, struct file *filep)
1371 if (!group) 1535 if (!group)
1372 return -ENODEV; 1536 return -ENODEV;
1373 1537
1538 if (group->noiommu && !capable(CAP_SYS_RAWIO)) {
1539 vfio_group_put(group);
1540 return -EPERM;
1541 }
1542
1374 /* Do we need multiple instances of the group open? Seems not. */ 1543 /* Do we need multiple instances of the group open? Seems not. */
1375 opened = atomic_cmpxchg(&group->opened, 0, 1); 1544 opened = atomic_cmpxchg(&group->opened, 0, 1);
1376 if (opened) { 1545 if (opened) {
@@ -1533,6 +1702,11 @@ struct vfio_group *vfio_group_get_external_user(struct file *filep)
1533 if (!atomic_inc_not_zero(&group->container_users)) 1702 if (!atomic_inc_not_zero(&group->container_users))
1534 return ERR_PTR(-EINVAL); 1703 return ERR_PTR(-EINVAL);
1535 1704
1705 if (group->noiommu) {
1706 atomic_dec(&group->container_users);
1707 return ERR_PTR(-EPERM);
1708 }
1709
1536 if (!group->container->iommu_driver || 1710 if (!group->container->iommu_driver ||
1537 !vfio_group_viable(group)) { 1711 !vfio_group_viable(group)) {
1538 atomic_dec(&group->container_users); 1712 atomic_dec(&group->container_users);