summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuis R. Rodriguez <mcgrof@do-not-panic.com>2013-04-05 09:38:15 -0700
committerJohannes Berg <johannes.berg@intel.com>2013-04-05 21:19:35 +0200
commit34a22a6c0ef56244443a30a9b840afe88714d19b (patch)
treeeff6d5d3b6540c01d72a82a235ad89bdc6c2a277
parent4e133e70121b5ad4a8b58ede85bdf4ab66990f84 (diff)
compat: backport dma-buf
dma-buf was added via commit d15bd7ee on v3.3 but completed in a more sound fassion in later kernels, you should preferably be at v3.5 a least, so we take the latest dma-buf implementation and port it for usage on kernels [3.0-3.4]. This is implemented as a non modular solution upstream but we can carry the implementation into our compat module. Note that although commit f23513e8d was added on v2.6.23 that allowed the kernel to call get_unused_fd_flags(flags) for O_CLOEXEC setting, this routine was not exported until v3.7. dma-buf makes use of it, and since our backported dma-buf implementation is modular it means we have to work around the lack of get_unused_fd_flags() exported symbol on older kernels. Due to the security concerns noted by Ulrich on f23513e8 we need to ensure the operatin is atomic so we fix this on our port of dma-buf for older kernels by adding our own dma_buf_fd_set_flag() to be called when dma_buf_fd() is used. This implementation is available for usage on kernels >= 3.0. We disable it for v3.5 as we're happy with that implementation. mcgrof@frijol ~/linux-next (git::master)$ git describe --contains \ d15bd7ee445d0702ad801fdaece348fdb79e6581 v3.3-rc1~161^2~2 mcgrof@frijol ~/linux-next (git::master)$ git describe --contains \ f23513e8d96cf5e6cf8d2ff0cb5dd6bbc33995e4 v2.6.23-rc1~894 mcgrof@frijol ~/linux-stable (git::linux-3.2.y)$ git describe --contains \ 1a7bd226 v3.7-rc1~134^2~69 commit d15bd7ee445d0702ad801fdaece348fdb79e6581 Author: Sumit Semwal <sumit.semwal@ti.com> Date: Mon Dec 26 14:53:15 2011 +0530 dma-buf: Introduce dma buffer sharing mechanism This is the first step in defining a dma buffer sharing mechanism. A new buffer object dma_buf is added, with operations and API to allow easy sharing of this buffer object across devices. The framework allows: - creation of a buffer object, its association with a file pointer, and associated allocator-defined operations on that buffer. This operation is called the 'export' operation. - different devices to 'attach' themselves to this exported buffer object, to facilitate backing storage negotiation, using dma_buf_attach() API. - the exported buffer object to be shared with the other entity by asking for its 'file-descriptor (fd)', and sharing the fd across. - a received fd to get the buffer object back, where it can be accessed using the associated exporter-defined operations. - the exporter and user to share the scatterlist associated with this buffer object using map_dma_buf and unmap_dma_buf operations. Atleast one 'attach()' call is required to be made prior to calling the map_dma_buf() operation. Couple of building blocks in map_dma_buf() are added to ease introduction of sync'ing across exporter and users, and late allocation by the exporter. For this first version, this framework will work with certain conditions: - *ONLY* exporter will be allowed to mmap to userspace (outside of this framework - mmap is not a buffer object operation), - currently, *ONLY* users that do not need CPU access to the buffer are allowed. More details are there in the documentation patch. This is based on design suggestions from many people at the mini-summits[1], most notably from Arnd Bergmann <arnd@arndb.de>, Rob Clark <rob@ti.com> and Daniel Vetter <daniel@ffwll.ch>. The implementation is inspired from proof-of-concept patch-set from Tomasz Stanislawski <t.stanislaws@samsung.com>, who demonstrated buffer sharing between two v4l2 devices. [2] [1]: https://wiki.linaro.org/OfficeofCTO/MemoryManagement [2]: http://lwn.net/Articles/454389 Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org> Signed-off-by: Sumit Semwal <sumit.semwal@ti.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Dave Airlie <airlied@redhat.com> Reviewed-and-Tested-by: Rob Clark <rob.clark@linaro.org> Signed-off-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Luis R. Rodriguez <mcgrof@do-not-panic.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--backport/compat/Kconfig11
-rw-r--r--patches/backport-adjustments/dma-buf.patch52
2 files changed, 63 insertions, 0 deletions
diff --git a/backport/compat/Kconfig b/backport/compat/Kconfig
index 0edd2fb6..679e9e73 100644
--- a/backport/compat/Kconfig
+++ b/backport/compat/Kconfig
@@ -127,7 +127,18 @@ config BACKPORT_OPTION_USB_URB_THREAD_FIX
config BACKPORT_MII
bool
+config BACKPORT_BUILD_DMA_SHARED_BUFFER
+ bool
+ depends on ANON_INODES
+ depends on !BACKPORT_KERNEL_3_0
+ depends on !DMA_SHARED_BUFFER || BACKPORT_KERNEL_3_5
+ default y if BACKPORT_DMA_SHARED_BUFFER
+ default y if BACKPORT_USERSEL_BUILD_ALL
+ #h-file linux/dma-buf.h
+ #c-file drivers/base/dma-buf.c
+config BACKPORT_DMA_SHARED_BUFFER
+ bool
config BACKPORT_USERSEL_BUILD_ALL
bool "Build all compat code"
diff --git a/patches/backport-adjustments/dma-buf.patch b/patches/backport-adjustments/dma-buf.patch
new file mode 100644
index 00000000..cec56269
--- /dev/null
+++ b/patches/backport-adjustments/dma-buf.patch
@@ -0,0 +1,52 @@
+--- a/compat/dma-buf.c
++++ b/compat/dma-buf.c
+@@ -27,6 +27,9 @@
+ #include <linux/dma-buf.h>
+ #include <linux/anon_inodes.h>
+ #include <linux/export.h>
++#include <linux/file.h>
++#include <linux/fdtable.h>
++#include <linux/bitops.h>
+
+ static inline int is_dma_buf_file(struct file *);
+
+@@ -126,6 +129,27 @@ struct dma_buf *dma_buf_export(void *pri
+ }
+ EXPORT_SYMBOL_GPL(dma_buf_export);
+
++static void dma_buf_fd_set_flag(int fd, int flags)
++{
++ struct fdtable *fdt;
++ struct files_struct *files = current->files;
++
++ spin_lock(&files->file_lock);
++ fdt = files_fdtable(files);
++ if (flags & O_CLOEXEC)
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
++ __set_bit(fd, fdt->close_on_exec);
++#else
++ FD_SET(fd, fdt->close_on_exec);
++#endif
++ else
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
++ __clear_bit(fd, fdt->close_on_exec);
++#else
++ FD_CLR(fd, fdt->close_on_exec);
++#endif
++ spin_unlock(&files->file_lock);
++}
+
+ /**
+ * dma_buf_fd - returns a file descriptor for the given dma_buf
+@@ -141,9 +165,10 @@ int dma_buf_fd(struct dma_buf *dmabuf, i
+ if (!dmabuf || !dmabuf->file)
+ return -EINVAL;
+
+- fd = get_unused_fd_flags(flags);
++ fd = get_unused_fd();
+ if (fd < 0)
+ return fd;
++ dma_buf_fd_set_flag(fd, flags);
+
+ fd_install(fd, dmabuf->file);
+