summaryrefslogtreecommitdiff
path: root/drivers/cdx
diff options
context:
space:
mode:
authorNipun Gupta <nipun.gupta@amd.com>2023-06-05 18:40:09 +0530
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-06-15 13:42:16 +0200
commitb8c5ff76059ded3758de3db83e04189a072ac01f (patch)
treeefc56ff8f617ccd88c024133aa1f53c9f1d00ee5 /drivers/cdx
parent9e66fb52449538406cea43e9f3889c391350e76e (diff)
cdx: fix driver managed dma support
The devices on cdx could be bound to drivers with the device DMA managed by kernel drivers or user-space applications. As multiple devices can be placed in the same IOMMU group, the DMA on these devices must either be entirely under kernel control or userspace control. Fix the CDX bus driver to acknowlege the driver_managed_dma flag and call the appropriate iommu APIs. Fixes: 2959ab247061 ("cdx: add the cdx bus driver") Signed-off-by: Nipun Gupta <nipun.gupta@amd.com> Reported-by: Alex Williamson <alex.williamson@redhat.com> Closes: https://lore.kernel.org/lkml/20230524134831.28dc97e2.alex.williamson@redhat.com/ Reviewed-by: Nikhil Agarwal <nikhil.agarwal@amd.com> Message-ID: <20230605131009.6869-1-nipun.gupta@amd.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/cdx')
-rw-r--r--drivers/cdx/cdx.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/cdx/cdx.c b/drivers/cdx/cdx.c
index 38511fd36325..d2cad4c670a0 100644
--- a/drivers/cdx/cdx.c
+++ b/drivers/cdx/cdx.c
@@ -62,6 +62,8 @@
#include <linux/mm.h>
#include <linux/xarray.h>
#include <linux/cdx/cdx_bus.h>
+#include <linux/iommu.h>
+#include <linux/dma-map-ops.h>
#include "cdx.h"
/* Default DMA mask for devices on a CDX bus */
@@ -257,6 +259,7 @@ static void cdx_shutdown(struct device *dev)
static int cdx_dma_configure(struct device *dev)
{
+ struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver);
struct cdx_device *cdx_dev = to_cdx_device(dev);
u32 input_id = cdx_dev->req_id;
int ret;
@@ -267,9 +270,23 @@ static int cdx_dma_configure(struct device *dev)
return ret;
}
+ if (!ret && !cdx_drv->driver_managed_dma) {
+ ret = iommu_device_use_default_domain(dev);
+ if (ret)
+ arch_teardown_dma_ops(dev);
+ }
+
return 0;
}
+static void cdx_dma_cleanup(struct device *dev)
+{
+ struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver);
+
+ if (!cdx_drv->driver_managed_dma)
+ iommu_device_unuse_default_domain(dev);
+}
+
/* show configuration fields */
#define cdx_config_attr(field, format_string) \
static ssize_t \
@@ -405,6 +422,7 @@ struct bus_type cdx_bus_type = {
.remove = cdx_remove,
.shutdown = cdx_shutdown,
.dma_configure = cdx_dma_configure,
+ .dma_cleanup = cdx_dma_cleanup,
.bus_groups = cdx_bus_groups,
.dev_groups = cdx_dev_groups,
};