summaryrefslogtreecommitdiffstats
path: root/drivers/vfio
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2015-10-27 16:53:04 -0400
committerAlex Williamson <alex.williamson@redhat.com>2015-10-27 16:53:04 -0400
commit5f096b14d421ba23249b752e41989ecfaa6ae226 (patch)
tree6fdfa589dc0888699202d9545779b52fab71a976 /drivers/vfio
parent32b88194f71d6ae7768a29f87fbba454728273ee (diff)
vfio: Whitelist PCI bridges
When determining whether a group is viable, we already allow devices bound to pcieport. Generalize this to include any PCI bridge device. Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'drivers/vfio')
-rw-r--r--drivers/vfio/vfio.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 563c510f285c..1c0f98c2f634 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -25,6 +25,7 @@
25#include <linux/miscdevice.h> 25#include <linux/miscdevice.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <linux/pci.h>
28#include <linux/rwsem.h> 29#include <linux/rwsem.h>
29#include <linux/sched.h> 30#include <linux/sched.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
@@ -438,16 +439,33 @@ static struct vfio_device *vfio_group_get_device(struct vfio_group *group,
438} 439}
439 440
440/* 441/*
441 * Whitelist some drivers that we know are safe (no dma) or just sit on 442 * Some drivers, like pci-stub, are only used to prevent other drivers from
442 * a device. It's not always practical to leave a device within a group 443 * claiming a device and are therefore perfectly legitimate for a user owned
443 * driverless as it could get re-bound to something unsafe. 444 * group. The pci-stub driver has no dependencies on DMA or the IOVA mapping
445 * of the device, but it does prevent the user from having direct access to
446 * the device, which is useful in some circumstances.
447 *
448 * We also assume that we can include PCI interconnect devices, ie. bridges.
449 * IOMMU grouping on PCI necessitates that if we lack isolation on a bridge
450 * then all of the downstream devices will be part of the same IOMMU group as
451 * the bridge. Thus, if placing the bridge into the user owned IOVA space
452 * breaks anything, it only does so for user owned devices downstream. Note
453 * that error notification via MSI can be affected for platforms that handle
454 * MSI within the same IOVA space as DMA.
444 */ 455 */
445static const char * const vfio_driver_whitelist[] = { "pci-stub", "pcieport" }; 456static const char * const vfio_driver_whitelist[] = { "pci-stub" };
446 457
447static bool vfio_whitelisted_driver(struct device_driver *drv) 458static bool vfio_dev_whitelisted(struct device *dev, struct device_driver *drv)
448{ 459{
449 int i; 460 int i;
450 461
462 if (dev_is_pci(dev)) {
463 struct pci_dev *pdev = to_pci_dev(dev);
464
465 if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
466 return true;
467 }
468
451 for (i = 0; i < ARRAY_SIZE(vfio_driver_whitelist); i++) { 469 for (i = 0; i < ARRAY_SIZE(vfio_driver_whitelist); i++) {
452 if (!strcmp(drv->name, vfio_driver_whitelist[i])) 470 if (!strcmp(drv->name, vfio_driver_whitelist[i]))
453 return true; 471 return true;
@@ -462,6 +480,7 @@ static bool vfio_whitelisted_driver(struct device_driver *drv)
462 * - driver-less 480 * - driver-less
463 * - bound to a vfio driver 481 * - bound to a vfio driver
464 * - bound to a whitelisted driver 482 * - bound to a whitelisted driver
483 * - a PCI interconnect device
465 * 484 *
466 * We use two methods to determine whether a device is bound to a vfio 485 * We use two methods to determine whether a device is bound to a vfio
467 * driver. The first is to test whether the device exists in the vfio 486 * driver. The first is to test whether the device exists in the vfio
@@ -486,7 +505,7 @@ static int vfio_dev_viable(struct device *dev, void *data)
486 } 505 }
487 mutex_unlock(&group->unbound_lock); 506 mutex_unlock(&group->unbound_lock);
488 507
489 if (!ret || !drv || vfio_whitelisted_driver(drv)) 508 if (!ret || !drv || vfio_dev_whitelisted(dev, drv))
490 return 0; 509 return 0;
491 510
492 device = vfio_group_get_device(group, dev); 511 device = vfio_group_get_device(group, dev);