lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Sat, 11 Oct 2014 01:37:55 +0530
From:	Sumit Semwal <sumit.semwal@...aro.org>
To:	linux-kernel@...r.kernel.org
Cc:	linux-media@...r.kernel.org, dri-devel@...ts.freedesktop.org,
	linaro-mm-sig@...ts.linaro.org, linaro-kernel@...ts.linaro.org,
	Sumit Semwal <sumit.semwal@...aro.org>,
	Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Subject: [RFC 1/4] dma-buf: Add constraints sharing information

At present, struct device lacks a mechanism of exposing memory
access constraints for the device.

Consequently, there is also no mechanism to share these constraints
while sharing buffers using dma-buf.

If we add support for sharing such constraints, we could use that
to try to collect requirements of different buffer-sharing devices
to allocate buffers from a pool that satisfies requirements of all
such devices.

This is an attempt to add this support; at the moment, only a bitmask
is added, but if post discussion, we realise we need more information,
we could always extend the definition of constraint.

A new dma-buf op is also added, to allow exporters to interpret or decide
on constraint-masks on their own. A default implementation is provided to
just AND (&) all the constraint-masks.

What constitutes a constraint-mask could be left for interpretation on a
per-platform basis, while defining some common masks.

Signed-off-by: Sumit Semwal <sumit.semwal@...aro.org>
Cc: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc: linux-media@...r.kernel.org
Cc: dri-devel@...ts.freedesktop.org
Cc: linaro-mm-sig@...ts.linaro.org
---
 drivers/dma-buf/dma-buf.c | 50 ++++++++++++++++++++++++++++++++++++++++++-----
 include/linux/device.h    |  7 ++++++-
 include/linux/dma-buf.h   | 14 +++++++++++++
 3 files changed, 65 insertions(+), 6 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index f3014c4..33bdb6a 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -264,6 +264,30 @@ static inline int is_dma_buf_file(struct file *file)
 	return file->f_op == &dma_buf_fops;
 }
 
+/*
+ * def_calc_access_constraints - default implementation of constraint checking
+ */
+static int def_calc_access_constraints(struct dma_buf *dmabuf,
+		struct dma_buf_attachment *attach)
+{
+	unsigned long access_mask;
+
+	access_mask = attach->dev->dma_parms->access_constraints_mask;
+
+	if (!access_mask) {
+		pr_warn("%s dev has no access_constraints_mask; using default\n",
+				dev_name(attach->dev));
+		 access_mask = DMA_BUF_ALL_MEMORY_ACCESS_MASK;
+	}
+
+	dmabuf->access_constraints_mask &= access_mask;
+
+	if (!dmabuf->access_constraints_mask)
+		return -EINVAL;
+
+	return 0;
+}
+
 /**
  * dma_buf_export_named - Creates a new dma_buf, and associates an anon file
  * with this buffer, so it can be exported.
@@ -313,6 +337,8 @@ struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops,
 	dmabuf->ops = ops;
 	dmabuf->size = size;
 	dmabuf->exp_name = exp_name;
+	dmabuf->access_constraints_mask = DMA_BUF_ALL_MEMORY_ACCESS_MASK;
+
 	init_waitqueue_head(&dmabuf->poll);
 	dmabuf->cb_excl.poll = dmabuf->cb_shared.poll = &dmabuf->poll;
 	dmabuf->cb_excl.active = dmabuf->cb_shared.active = 0;
@@ -410,8 +436,10 @@ void dma_buf_put(struct dma_buf *dmabuf)
 EXPORT_SYMBOL_GPL(dma_buf_put);
 
 /**
- * dma_buf_attach - Add the device to dma_buf's attachments list; optionally,
- * calls attach() of dma_buf_ops to allow device-specific attach functionality
+ * dma_buf_attach - Add the device to dma_buf's attachments list;
+ *	calculates access_constraints and throws error if constraints aren't
+ *	satisfied. Optionally, calls attach() of dma_buf_ops to allow
+ *	device-specific attach functionality.
  * @dmabuf:	[in]	buffer to attach device to.
  * @dev:	[in]	device to be attached.
  *
@@ -436,11 +464,20 @@ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
 
 	mutex_lock(&dmabuf->lock);
 
+	if (!dmabuf->ops->calc_access_constraints)
+		ret = def_calc_access_constraints(dmabuf, attach);
+	else
+		ret = dmabuf->ops->calc_access_constraints(dmabuf, attach);
+
+	if (ret)
+		goto err_attach;
+
 	if (dmabuf->ops->attach) {
 		ret = dmabuf->ops->attach(dmabuf, dev, attach);
 		if (ret)
 			goto err_attach;
 	}
+
 	list_add(&attach->node, &dmabuf->attachments);
 
 	mutex_unlock(&dmabuf->lock);
@@ -785,7 +822,7 @@ static int dma_buf_describe(struct seq_file *s)
 		return ret;
 
 	seq_puts(s, "\nDma-buf Objects:\n");
-	seq_puts(s, "size\tflags\tmode\tcount\texp_name\n");
+	seq_puts(s, "size\tflags\tmode\tcount\tconstraints\texp_name\n");
 
 	list_for_each_entry(buf_obj, &db_list.head, list_node) {
 		ret = mutex_lock_interruptible(&buf_obj->lock);
@@ -796,10 +833,11 @@ static int dma_buf_describe(struct seq_file *s)
 			continue;
 		}
 
-		seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\n",
+		seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%08lx\t%s\n",
 				buf_obj->size,
 				buf_obj->file->f_flags, buf_obj->file->f_mode,
 				(long)(buf_obj->file->f_count.counter),
+				buf_obj->access_constraints_mask,
 				buf_obj->exp_name);
 
 		seq_puts(s, "\tAttached Devices:\n");
@@ -808,7 +846,9 @@ static int dma_buf_describe(struct seq_file *s)
 		list_for_each_entry(attach_obj, &buf_obj->attachments, node) {
 			seq_puts(s, "\t");
 
-			seq_printf(s, "%s\n", dev_name(attach_obj->dev));
+			seq_printf(s, "%s\t:%lx\n",
+					dev_name(attach_obj->dev),
+			  attach_obj->dev->dma_parms->access_constraints_mask);
 			attach_count++;
 		}
 
diff --git a/include/linux/device.h b/include/linux/device.h
index a608e23..f9aefa2 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -647,6 +647,11 @@ struct device_dma_parameters {
 	 */
 	unsigned int max_segment_size;
 	unsigned long segment_boundary_mask;
+	/*
+	 * access_constraints_mask: this would be used to share constraints
+	 * about memories that this device can access.
+	 */
+	unsigned long access_constraints_mask;
 };
 
 struct acpi_device;
@@ -696,7 +701,7 @@ struct acpi_dev_node {
  * 		such descriptors.
  * @dma_pfn_offset: offset of DMA memory range relatively of RAM
  * @dma_parms:	A low level driver may set these to teach IOMMU code about
- * 		segment limitations.
+ *		segment limitations, and access constraints.
  * @dma_pools:	Dma pools (if dma'ble device).
  * @dma_mem:	Internal for coherent mem override.
  * @cma_area:	Contiguous memory area for dma allocations
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index 694e1fe..8429a38 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -37,6 +37,8 @@ struct device;
 struct dma_buf;
 struct dma_buf_attachment;
 
+#define DMA_BUF_ALL_MEMORY_ACCESS_MASK ((unsigned long)-1)
+
 /**
  * struct dma_buf_ops - operations possible on struct dma_buf
  * @attach: [optional] allows different devices to 'attach' themselves to the
@@ -44,6 +46,12 @@ struct dma_buf_attachment;
  *	    is already allocated and incompatible with the requirements
  *	    of requesting device.
  * @detach: [optional] detach a given device from this buffer.
+ * @calc_access_constraints(): [optional] will be called at the end of each
+ *		attach - to calculate and set the constraints for this dma_buf
+ *		according to this attachment's access_constraint_mask in
+ *		dev->dma_parms.
+ *		A default implementation is provided, but exporters are free to
+ *		provide	custom version if needed.
  * @map_dma_buf: returns list of scatter pages allocated, increases usecount
  *		 of the buffer. Requires atleast one attach to be called
  *		 before. Returned sg list should already be mapped into
@@ -77,6 +85,9 @@ struct dma_buf_ops {
 
 	void (*detach)(struct dma_buf *, struct dma_buf_attachment *);
 
+	int (*calc_access_constraints)(struct dma_buf *,
+			struct dma_buf_attachment *);
+
 	/* For {map,unmap}_dma_buf below, any specific buffer attributes
 	 * required should get added to device_dma_parameters accessible
 	 * via dev->dma_params.
@@ -86,6 +97,7 @@ struct dma_buf_ops {
 	void (*unmap_dma_buf)(struct dma_buf_attachment *,
 						struct sg_table *,
 						enum dma_data_direction);
+
 	/* TODO: Add try_map_dma_buf version, to return immed with -EBUSY
 	 * if the call would block.
 	 */
@@ -116,6 +128,7 @@ struct dma_buf_ops {
  * @ops: dma_buf_ops associated with this buffer object.
  * @exp_name: name of the exporter; useful for debugging.
  * @list_node: node for dma_buf accounting and debugging.
+ * @access_constraints_mask: mask to share access constraints.
  * @priv: exporter specific private data for this buffer object.
  * @resv: reservation object linked to this dma-buf
  */
@@ -130,6 +143,7 @@ struct dma_buf {
 	void *vmap_ptr;
 	const char *exp_name;
 	struct list_head list_node;
+	unsigned long access_constraints_mask;
 	void *priv;
 	struct reservation_object *resv;
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ