[PATCH] drm/exynos: fix deadlock issue at mmap

Inki Dae inki.dae at samsung.com
Mon Sep 23 21:58:22 PDT 2013


Please, ignore this patch. This patch has still some problems. I will post
it later.

Thanks,
Inki Dae

> -----Original Message-----
> From: Inki Dae [mailto:inki.dae at samsung.com]
> Sent: Monday, September 23, 2013 7:43 PM
> To: airlied at linux.ie; dri-devel at lists.freedesktop.org
> Cc: Inki Dae; Kyungmin Park
> Subject: [PATCH] drm/exynos: fix deadlock issue at mmap
> 
> 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 at samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>
> ---
>  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



More information about the dri-devel mailing list