From: YoungJun Cho Date: Tue, 4 Feb 2014 07:24:35 +0000 (+0900) Subject: drm/prime: resolve race for drm_gem_prime_handle_to_fd() X-Git-Tag: accepted/tizen/mobile/20151223.235519~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cf0ea65cd31feb199d78b15ab0fbcedde852019f;p=profile%2Fmobile%2Fplatform%2Fkernel%2Flinux-3.10-sc7730.git drm/prime: resolve race for drm_gem_prime_handle_to_fd() This patch resolves race for drm_gem_prime_handle_to_fd(). There could be a race when drm_gem_prime_handle_to_fd() is requested during __fput() is executed with same dmabuf. Change-Id: I8ab68a7184ce974ded84c75a7805b9aa1d021ee2 Signed-off-by: YoungJun Cho Signed-off-by: Rohit kumar --- diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 0d71f81..83cc31c 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -63,6 +63,28 @@ struct drm_prime_member { uint32_t handle; }; +bool drm_prime_check_dmabuf_valid(struct dma_buf *dmabuf) +{ + struct file *file = dmabuf->file; + + /* + * There could be a race when drm_gem_prime_handle_to_fd() is requested + * during __fput() is executed with same dmabuf. + * Let's suppose that there are process A and B. A creates a gem obj + * and exports it to dmabuf, B opens gem name which comes from A. + * And A is closing dmabuf and B tries to import dmabuf at that time. + * In this case, the dmabuf is in obj->export_dma_buf cache, because + * gem obj is still valid, and B could get dmabuf from this cache, + * but this dmabuf is invalid already, so B has to get a new dmabuf + * directly. + */ + if (!atomic_long_read(&file->f_count)) + return false; + + return true; +} +EXPORT_SYMBOL(drm_prime_check_dmabuf_valid); + static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, enum dma_data_direction dir) { diff --git a/include/drm/drmP.h b/include/drm/drmP.h index c1b5619..c73fe7e 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -56,6 +56,7 @@ #include #include #include +#include #if defined(__alpha__) || defined(__powerpc__) #include /* For pte_wrprotect */ #endif @@ -1606,6 +1607,7 @@ void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv); int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle); int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle); void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf); +bool drm_prime_check_dmabuf_valid(struct dma_buf *dmabuf); int drm_prime_add_dma_buf(struct drm_device *dev, struct drm_gem_object *obj); int drm_prime_lookup_obj(struct drm_device *dev, struct dma_buf *buf,