This patch fixes the deadlock issue when another process requested mmap system call. This issue can incur the deadlock if another process sharing the same file called mmap system call between ->f_op pointer chaning and restoring. So this patch calls down_write(&mm->mmap_sem) before do_mmap_pgoff call and then up_write(&mm->mmap_sem) after do_mmap_pg_off call so that when another process called mmap system call, the process can wait for up_write() call until the ->f_op pointer is restored. Signed-off-by: Inki Dae <inki.dae@xxxxxxxxxxx> Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx> --- drivers/gpu/drm/exynos/exynos_drm_gem.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 49f9cd2..779c2d7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -13,6 +13,7 @@ #include <drm/drm_vma_manager.h> #include <linux/shmem_fs.h> +#include <linux/security.h> #include <drm/exynos_drm.h> #include "exynos_drm_drv.h" @@ -420,6 +421,7 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, { struct drm_exynos_gem_mmap *args = data; struct drm_gem_object *obj; + struct mm_struct *mm = current->mm; unsigned long addr; if (!(dev->driver->driver_features & DRIVER_GEM)) { @@ -433,6 +435,8 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, return -EINVAL; } + down_write(&mm->mmap_sem); + /* * We have to use gem object and its fops for specific mmaper, * but vm_mmap() can deliver only filp. So we have to change @@ -457,8 +461,17 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, */ file_priv->filp->private_data = obj; - addr = vm_mmap(file_priv->filp, 0, args->size, - PROT_READ | PROT_WRITE, MAP_SHARED, 0); + addr = security_mmap_file(file_priv->filp, PROT_READ | PROT_WRITE, + MAP_SHARED); + if (!addr) { + unsigned long populate; + + addr = do_mmap_pgoff(file_priv->filp, 0, args->size, + PROT_READ | PROT_WRITE, + MAP_SHARED, 0, &populate); + if (populate) + mm_populate(addr, populate); + } drm_gem_object_unreference(obj); @@ -469,10 +482,13 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, file_priv->filp->private_data = file_priv; } mutex_unlock(&dev->struct_mutex); + up_write(&mm->mmap_sem); + return (int)addr; } mutex_unlock(&dev->struct_mutex); + up_write(&mm->mmap_sem); args->mapped = addr; -- 1.7.9.5 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel