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.koenig@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; };