Start to fix the coherency issues for non PCI devices by adding a dma_coherent
flag to the DMA-buf.

The flag should be set by the exporter if only devices which can do coherent
DMA-access with respect to the CPU cache are allowed to access the buffer.

Signed-off-by: Christian König <christian.koe...@amd.com>
---
 drivers/dma-buf/dma-buf.c |  5 +++++
 include/linux/dma-buf.h   | 16 ++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index c40d72d318fd..7509807bf485 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/dma-buf.h>
 #include <linux/dma-fence.h>
+#include <linux/dma-map-ops.h>
 #include <linux/anon_inodes.h>
 #include <linux/export.h>
 #include <linux/debugfs.h>
@@ -635,6 +636,7 @@ struct dma_buf *dma_buf_export(const struct 
dma_buf_export_info *exp_info)
 
        dmabuf->priv = exp_info->priv;
        dmabuf->ops = exp_info->ops;
+       dmabuf->dma_coherent = exp_info->coherent;
        dmabuf->size = exp_info->size;
        dmabuf->exp_name = exp_info->exp_name;
        dmabuf->owner = exp_info->owner;
@@ -894,6 +896,9 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct 
device *dev,
        if (WARN_ON(importer_ops && !importer_ops->move_notify))
                return ERR_PTR(-EINVAL);
 
+       if (dmabuf->dma_coherent && !dev_is_dma_coherent(dev))
+               return ERR_PTR(-EINVAL);
+
        attach = kzalloc(sizeof(*attach), GFP_KERNEL);
        if (!attach)
                return ERR_PTR(-ENOMEM);
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index 6fa8d4e29719..f2083b94b116 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -326,6 +326,20 @@ struct dma_buf {
        /** @ops: dma_buf_ops associated with this buffer object. */
        const struct dma_buf_ops *ops;
 
+       /**
+        * @dma_coherent:
+        *
+        * True if the buffer is backed by DMA coherent memory with respect to
+        * the CPU cache even if the architecture can support incoherent
+        * devices.
+        *
+        * Usually mirrors the result of dev_is_dma_coherent() of the exporter,
+        * but can be cleared by the exporter to allow incoherent devices
+        * access to the buffer if the exporter takes care of coherency for CPU
+        * accesses.
+        */
+       bool dma_coherent;
+
        /**
         * @vmapping_counter:
         *
@@ -524,6 +538,7 @@ struct dma_buf_attachment {
  * @ops:       Attach allocator-defined dma buf ops to the new buffer
  * @size:      Size of the buffer - invariant over the lifetime of the buffer
  * @flags:     mode flags for the file
+ * @coherent:  If DMA accesses must be coherent to the CPU cache.
  * @resv:      reservation-object, NULL to allocate default one
  * @priv:      Attach private data of allocator to this buffer
  *
@@ -536,6 +551,7 @@ struct dma_buf_export_info {
        const struct dma_buf_ops *ops;
        size_t size;
        int flags;
+       bool coherent;
        struct dma_resv *resv;
        void *priv;
 };
-- 
2.25.1

Reply via email to