aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSinan Kaya <okaya@codeaurora.org>2016-07-19 09:01:47 -0400
committerAlex Williamson <alex.williamson@redhat.com>2016-07-19 12:26:46 -0400
commitb5add544d677d36386c3559cf5db1485b59c4d7d (patch)
treea0e8a1f56b2fbdb9fdef04bbd14857e792b3cde7
parentd30daa33ec1d035acfdfc7662d7a5360592af44c (diff)
vfio, platform: make reset driver a requirement by default
The code was allowing platform devices to be used without a supporting VFIO reset driver. The hardware can be left in some inconsistent state after a guest machine abort. The reset driver will put the hardware back to safe state and disable interrupts before returning the control back to the host machine. Adding a new reset_required kernel module option to platform VFIO drivers. The default value is true for the DT and ACPI based drivers. The reset requirement value for AMBA drivers is set to false and is unchangeable to maintain the existing functionality. New requirements are: 1. A reset function needs to be implemented by the corresponding driver via DT/ACPI. 2. The reset function needs to be discovered via DT/ACPI. The probe of the driver will fail if any of the above conditions are not satisfied. Signed-off-by: Sinan Kaya <okaya@codeaurora.org> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
-rw-r--r--drivers/vfio/platform/vfio_amba.c1
-rw-r--r--drivers/vfio/platform/vfio_platform.c5
-rw-r--r--drivers/vfio/platform/vfio_platform_common.c15
-rw-r--r--drivers/vfio/platform/vfio_platform_private.h2
4 files changed, 19 insertions, 4 deletions
diff --git a/drivers/vfio/platform/vfio_amba.c b/drivers/vfio/platform/vfio_amba.c
index a66479bd0edf..31372fbf6c5b 100644
--- a/drivers/vfio/platform/vfio_amba.c
+++ b/drivers/vfio/platform/vfio_amba.c
@@ -68,6 +68,7 @@ static int vfio_amba_probe(struct amba_device *adev, const struct amba_id *id)
68 vdev->get_resource = get_amba_resource; 68 vdev->get_resource = get_amba_resource;
69 vdev->get_irq = get_amba_irq; 69 vdev->get_irq = get_amba_irq;
70 vdev->parent_module = THIS_MODULE; 70 vdev->parent_module = THIS_MODULE;
71 vdev->reset_required = false;
71 72
72 ret = vfio_platform_probe_common(vdev, &adev->dev); 73 ret = vfio_platform_probe_common(vdev, &adev->dev);
73 if (ret) { 74 if (ret) {
diff --git a/drivers/vfio/platform/vfio_platform.c b/drivers/vfio/platform/vfio_platform.c
index b1cc3a768784..6561751a1063 100644
--- a/drivers/vfio/platform/vfio_platform.c
+++ b/drivers/vfio/platform/vfio_platform.c
@@ -23,6 +23,10 @@
23#define DRIVER_AUTHOR "Antonios Motakis <a.motakis@virtualopensystems.com>" 23#define DRIVER_AUTHOR "Antonios Motakis <a.motakis@virtualopensystems.com>"
24#define DRIVER_DESC "VFIO for platform devices - User Level meta-driver" 24#define DRIVER_DESC "VFIO for platform devices - User Level meta-driver"
25 25
26static bool reset_required = true;
27module_param(reset_required, bool, 0444);
28MODULE_PARM_DESC(reset_required, "override reset requirement (default: 1)");
29
26/* probing devices from the linux platform bus */ 30/* probing devices from the linux platform bus */
27 31
28static struct resource *get_platform_resource(struct vfio_platform_device *vdev, 32static struct resource *get_platform_resource(struct vfio_platform_device *vdev,
@@ -66,6 +70,7 @@ static int vfio_platform_probe(struct platform_device *pdev)
66 vdev->get_resource = get_platform_resource; 70 vdev->get_resource = get_platform_resource;
67 vdev->get_irq = get_platform_irq; 71 vdev->get_irq = get_platform_irq;
68 vdev->parent_module = THIS_MODULE; 72 vdev->parent_module = THIS_MODULE;
73 vdev->reset_required = reset_required;
69 74
70 ret = vfio_platform_probe_common(vdev, &pdev->dev); 75 ret = vfio_platform_probe_common(vdev, &pdev->dev);
71 if (ret) 76 if (ret)
diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c
index a15a69b52080..d8755d2c6053 100644
--- a/drivers/vfio/platform/vfio_platform_common.c
+++ b/drivers/vfio/platform/vfio_platform_common.c
@@ -115,10 +115,10 @@ static bool vfio_platform_has_reset(struct vfio_platform_device *vdev)
115 return vdev->of_reset ? true : false; 115 return vdev->of_reset ? true : false;
116} 116}
117 117
118static void vfio_platform_get_reset(struct vfio_platform_device *vdev) 118static int vfio_platform_get_reset(struct vfio_platform_device *vdev)
119{ 119{
120 if (VFIO_PLATFORM_IS_ACPI(vdev)) 120 if (VFIO_PLATFORM_IS_ACPI(vdev))
121 return; 121 return vfio_platform_acpi_has_reset(vdev) ? 0 : -ENOENT;
122 122
123 vdev->of_reset = vfio_platform_lookup_reset(vdev->compat, 123 vdev->of_reset = vfio_platform_lookup_reset(vdev->compat,
124 &vdev->reset_module); 124 &vdev->reset_module);
@@ -127,6 +127,8 @@ static void vfio_platform_get_reset(struct vfio_platform_device *vdev)
127 vdev->of_reset = vfio_platform_lookup_reset(vdev->compat, 127 vdev->of_reset = vfio_platform_lookup_reset(vdev->compat,
128 &vdev->reset_module); 128 &vdev->reset_module);
129 } 129 }
130
131 return vdev->of_reset ? 0 : -ENOENT;
130} 132}
131 133
132static void vfio_platform_put_reset(struct vfio_platform_device *vdev) 134static void vfio_platform_put_reset(struct vfio_platform_device *vdev)
@@ -667,6 +669,13 @@ int vfio_platform_probe_common(struct vfio_platform_device *vdev,
667 669
668 vdev->device = dev; 670 vdev->device = dev;
669 671
672 ret = vfio_platform_get_reset(vdev);
673 if (ret && vdev->reset_required) {
674 pr_err("vfio: no reset function found for device %s\n",
675 vdev->name);
676 return ret;
677 }
678
670 group = vfio_iommu_group_get(dev); 679 group = vfio_iommu_group_get(dev);
671 if (!group) { 680 if (!group) {
672 pr_err("VFIO: No IOMMU group for device %s\n", vdev->name); 681 pr_err("VFIO: No IOMMU group for device %s\n", vdev->name);
@@ -679,8 +688,6 @@ int vfio_platform_probe_common(struct vfio_platform_device *vdev,
679 return ret; 688 return ret;
680 } 689 }
681 690
682 vfio_platform_get_reset(vdev);
683
684 mutex_init(&vdev->igate); 691 mutex_init(&vdev->igate);
685 692
686 return 0; 693 return 0;
diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h
index ba9e4f8b0746..85ffe5d9d1ab 100644
--- a/drivers/vfio/platform/vfio_platform_private.h
+++ b/drivers/vfio/platform/vfio_platform_private.h
@@ -73,6 +73,8 @@ struct vfio_platform_device {
73 (*get_resource)(struct vfio_platform_device *vdev, int i); 73 (*get_resource)(struct vfio_platform_device *vdev, int i);
74 int (*get_irq)(struct vfio_platform_device *vdev, int i); 74 int (*get_irq)(struct vfio_platform_device *vdev, int i);
75 int (*of_reset)(struct vfio_platform_device *vdev); 75 int (*of_reset)(struct vfio_platform_device *vdev);
76
77 bool reset_required;
76}; 78};
77 79
78typedef int (*vfio_platform_reset_fn_t)(struct vfio_platform_device *vdev); 80typedef int (*vfio_platform_reset_fn_t)(struct vfio_platform_device *vdev);