kernel
Revision | 253542f224fd792ccb32e9fe9d4d32f1850141a9 (tree) |
---|---|
Time | 2020-03-17 03:12:50 |
Author | Liam Mark <lmark@code...> |
Commiter | Suren Baghdasaryan |
ANDROID: GKI: dma-buf: Add support to set a destructor on a dma-buf
dma-buf destructor support is useful as it allows clients an opportunity
to undo any attributes, such as security attributes, they have applied to
the dma-buf's memory.
The destructor is called when the dma-buf is freed, if the destructor
returns an error the dma-buf's exporter release function is not called in
order to ensure that memory which has not been properly cleaned up isn't
returned to the system.
Signed-off-by: Liam Mark <lmark@codeaurora.org>
Signed-off-by: Swathi Sridhar <swatsrid@codeaurora.org>
[surenb: cherry-picked from:
3af4db1543c9 "dma-buf: Add support to set a destructor on a dma-buf"]
Bug: 150611569
Test: build
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Change-Id: I2d435b99fb9b1747bc1b32a4e0d484957614a5a3
@@ -86,6 +86,7 @@ static struct file_system_type dma_buf_fs_type = { | ||
86 | 86 | static int dma_buf_release(struct inode *inode, struct file *file) |
87 | 87 | { |
88 | 88 | struct dma_buf *dmabuf; |
89 | + int dtor_ret = 0; | |
89 | 90 | |
90 | 91 | if (!is_dma_buf_file(file)) |
91 | 92 | return -EINVAL; |
@@ -104,12 +105,19 @@ static int dma_buf_release(struct inode *inode, struct file *file) | ||
104 | 105 | */ |
105 | 106 | BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active); |
106 | 107 | |
107 | - dmabuf->ops->release(dmabuf); | |
108 | - | |
109 | 108 | mutex_lock(&db_list.lock); |
110 | 109 | list_del(&dmabuf->list_node); |
111 | 110 | mutex_unlock(&db_list.lock); |
112 | 111 | |
112 | + if (dmabuf->dtor) | |
113 | + dtor_ret = dmabuf->dtor(dmabuf, dmabuf->dtor_data); | |
114 | + | |
115 | + if (!dtor_ret) | |
116 | + dmabuf->ops->release(dmabuf); | |
117 | + else | |
118 | + pr_warn_ratelimited("Leaking dmabuf %s because destructor failed error:%d\n", | |
119 | + dmabuf->name, dtor_ret); | |
120 | + | |
113 | 121 | if (dmabuf->resv == (struct reservation_object *)&dmabuf[1]) |
114 | 122 | reservation_object_fini(dmabuf->resv); |
115 | 123 |
@@ -322,6 +322,18 @@ struct dma_buf_ops { | ||
322 | 322 | }; |
323 | 323 | |
324 | 324 | /** |
325 | + * dma_buf_destructor - dma-buf destructor function | |
326 | + * @dmabuf: [in] pointer to dma-buf | |
327 | + * @dtor_data: [in] destructor data associated with this buffer | |
328 | + * | |
329 | + * The dma-buf destructor which is called when the dma-buf is freed. | |
330 | + * | |
331 | + * If the destructor returns an error the dma-buf's exporter release function | |
332 | + * won't be called. | |
333 | + */ | |
334 | +typedef int (*dma_buf_destructor)(struct dma_buf *dmabuf, void *dtor_data); | |
335 | + | |
336 | +/** | |
325 | 337 | * struct dma_buf - shared buffer object |
326 | 338 | * @size: size of the buffer |
327 | 339 | * @file: file pointer used for sharing buffers across, and for refcounting. |
@@ -377,6 +389,8 @@ struct dma_buf { | ||
377 | 389 | |
378 | 390 | __poll_t active; |
379 | 391 | } cb_excl, cb_shared; |
392 | + dma_buf_destructor dtor; | |
393 | + void *dtor_data; | |
380 | 394 | }; |
381 | 395 | |
382 | 396 | /** |
@@ -486,4 +500,18 @@ int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, | ||
486 | 500 | void *dma_buf_vmap(struct dma_buf *); |
487 | 501 | void dma_buf_vunmap(struct dma_buf *, void *vaddr); |
488 | 502 | int dma_buf_get_flags(struct dma_buf *dmabuf, unsigned long *flags); |
503 | + | |
504 | +/** | |
505 | + * dma_buf_set_destructor - set the dma-buf's destructor | |
506 | + * @dmabuf: [in] pointer to dma-buf | |
507 | + * @dma_buf_destructor [in] the destructor function | |
508 | + * @dtor_data: [in] destructor data associated with this buffer | |
509 | + */ | |
510 | +static inline void dma_buf_set_destructor(struct dma_buf *dmabuf, | |
511 | + dma_buf_destructor dtor, | |
512 | + void *dtor_data) | |
513 | +{ | |
514 | + dmabuf->dtor = dtor; | |
515 | + dmabuf->dtor_data = dtor_data; | |
516 | +} | |
489 | 517 | #endif /* __DMA_BUF_H__ */ |