@@ -29,6 +29,7 @@
#include <linux/anon_inodes.h>
#include <linux/export.h>
#include <linux/debugfs.h>
+#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/poll.h>
#include <linux/reservation.h>
@@ -64,6 +65,7 @@ static int dma_buf_release(struct inode *inode, struct file *file)
BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active);
dmabuf->ops->release(dmabuf);
+ module_put(dmabuf->ops->owner);
mutex_lock(&db_list.lock);
list_del(&dmabuf->list_node);
@@ -302,9 +304,14 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
return ERR_PTR(-EINVAL);
}
+ if (!try_module_get(exp_info->ops->owner))
+ return ERR_PTR(-ENOENT);
+
dmabuf = kzalloc(alloc_size, GFP_KERNEL);
- if (dmabuf == NULL)
+ if (!dmabuf) {
+ module_put(exp_info->ops->owner);
return ERR_PTR(-ENOMEM);
+ }
dmabuf->priv = exp_info->priv;
dmabuf->ops = exp_info->ops;
@@ -524,6 +524,7 @@ armada_gem_dmabuf_mmap(struct dma_buf *buf, struct vm_area_struct *vma)
}
static const struct dma_buf_ops armada_gem_prime_dmabuf_ops = {
+ .owner = THIS_MODULE,
.map_dma_buf = armada_gem_prime_map_dma_buf,
.unmap_dma_buf = armada_gem_prime_unmap_dma_buf,
.release = drm_gem_dmabuf_release,
@@ -289,6 +289,7 @@ static int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf,
}
static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = {
+ .owner = THIS_MODULE,
.attach = drm_gem_map_attach,
.detach = drm_gem_map_detach,
.map_dma_buf = drm_gem_map_dma_buf,
@@ -169,6 +169,7 @@ static int exynos_gem_dmabuf_mmap(struct dma_buf *dma_buf,
}
static struct dma_buf_ops exynos_dmabuf_ops = {
+ .owner = THIS_MODULE,
.attach = exynos_gem_attach_dma_buf,
.detach = exynos_gem_detach_dma_buf,
.map_dma_buf = exynos_gem_map_dma_buf,
@@ -213,6 +213,7 @@ static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size
}
static const struct dma_buf_ops i915_dmabuf_ops = {
+ .owner = THIS_MODULE,
.map_dma_buf = i915_gem_map_dma_buf,
.unmap_dma_buf = i915_gem_unmap_dma_buf,
.release = drm_gem_dmabuf_release,
@@ -156,6 +156,7 @@ static int omap_gem_dmabuf_mmap(struct dma_buf *buffer,
}
static struct dma_buf_ops omap_dmabuf_ops = {
+ .owner = THIS_MODULE,
.map_dma_buf = omap_gem_map_dma_buf,
.unmap_dma_buf = omap_gem_unmap_dma_buf,
.release = omap_gem_dmabuf_release,
@@ -611,6 +611,7 @@ static void tegra_gem_prime_vunmap(struct dma_buf *buf, void *vaddr)
}
static const struct dma_buf_ops tegra_gem_prime_dmabuf_ops = {
+ .owner = THIS_MODULE,
.map_dma_buf = tegra_gem_prime_map_dma_buf,
.unmap_dma_buf = tegra_gem_prime_unmap_dma_buf,
.release = tegra_gem_prime_release,
@@ -187,6 +187,7 @@ static int udl_dmabuf_mmap(struct dma_buf *dma_buf,
}
static struct dma_buf_ops udl_dmabuf_ops = {
+ .owner = THIS_MODULE,
.attach = udl_attach_dma_buf,
.detach = udl_detach_dma_buf,
.map_dma_buf = udl_map_dma_buf,
@@ -103,6 +103,7 @@ static int vmw_prime_dmabuf_mmap(struct dma_buf *dma_buf,
}
const struct dma_buf_ops vmw_prime_dmabuf_ops = {
+ .owner = THIS_MODULE,
.attach = vmw_prime_map_attach,
.detach = vmw_prime_map_detach,
.map_dma_buf = vmw_prime_map_dma_buf,
@@ -365,6 +365,7 @@ static int vb2_dc_dmabuf_ops_mmap(struct dma_buf *dbuf,
}
static struct dma_buf_ops vb2_dc_dmabuf_ops = {
+ .owner = THIS_MODULE,
.attach = vb2_dc_dmabuf_ops_attach,
.detach = vb2_dc_dmabuf_ops_detach,
.map_dma_buf = vb2_dc_dmabuf_ops_map,
@@ -568,6 +568,7 @@ static int vb2_dma_sg_dmabuf_ops_mmap(struct dma_buf *dbuf,
}
static struct dma_buf_ops vb2_dma_sg_dmabuf_ops = {
+ .owner = THIS_MODULE,
.attach = vb2_dma_sg_dmabuf_ops_attach,
.detach = vb2_dma_sg_dmabuf_ops_detach,
.map_dma_buf = vb2_dma_sg_dmabuf_ops_map,
@@ -353,6 +353,7 @@ static int vb2_vmalloc_dmabuf_ops_mmap(struct dma_buf *dbuf,
}
static struct dma_buf_ops vb2_vmalloc_dmabuf_ops = {
+ .owner = THIS_MODULE,
.attach = vb2_vmalloc_dmabuf_ops_attach,
.detach = vb2_vmalloc_dmabuf_ops_detach,
.map_dma_buf = vb2_vmalloc_dmabuf_ops_map,
@@ -1088,6 +1088,7 @@ static void ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, size_t start,
}
static struct dma_buf_ops dma_buf_ops = {
+ .owner = THIS_MODULE,
.map_dma_buf = ion_map_dma_buf,
.unmap_dma_buf = ion_unmap_dma_buf,
.mmap = ion_mmap,
@@ -39,6 +39,7 @@ struct dma_buf_attachment;
/**
* struct dma_buf_ops - operations possible on struct dma_buf
+ * @owner: the module that implements dma_buf operations
* @attach: [optional] allows different devices to 'attach' themselves to the
* given buffer. It might return -EBUSY to signal that backing storage
* is already allocated and incompatible with the requirements
@@ -72,6 +73,7 @@ struct dma_buf_attachment;
* @vunmap: [optional] unmaps a vmap from the buffer
*/
struct dma_buf_ops {
+ struct module *owner;
int (*attach)(struct dma_buf *, struct device *,
struct dma_buf_attachment *);