Changelog v2: call mutex_lock before drm_vm_open_locked is called. Changelog v1: This patch makes it takes a reference to gem object when specific gem mmap is requested. For this, it sets dev->driver->gem_vm_ops to vma->vm_ops. And this patch is based on exynos-drm-next-iommu branch of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos Signed-off-by: Inki Dae <inki.dae@xxxxxxxxxxx> Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx> --- drivers/gpu/drm/exynos/exynos_drm_gem.c | 23 ++++++++++++++++++++++- 1 files changed, 22 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 50d73f1..de524d9 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -372,10 +372,13 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); struct exynos_drm_gem_buf *buffer; unsigned long vm_size; + int ret; DRM_DEBUG_KMS("%s\n", __FILE__); vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; + vma->vm_private_data = obj; + vma->vm_ops = obj->dev->driver->gem_vm_ops; update_vm_cache_attr(exynos_gem_obj, vma); @@ -391,9 +394,25 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, if (vm_size > buffer->size) return -EINVAL; - return dma_mmap_attrs(obj->dev->dev, vma, buffer->kvaddr, + ret = dma_mmap_attrs(obj->dev->dev, vma, buffer->kvaddr, buffer->dma_addr, buffer->size, &buffer->dma_attrs); + if (ret < 0) { + DRM_ERROR("failed to mmap.\n"); + return ret; + } + + /* + * take a reference to this mapping of the object. And this reference + * is unreferenced by the corresponding vm_close call. + */ + drm_gem_object_reference(obj); + + mutex_lock(&obj->dev->struct_mutex); + drm_vm_open_locked(obj->dev, vma); + mutex_unlock(&obj->dev->struct_mutex); + + return 0; } static const struct file_operations exynos_drm_gem_fops = { @@ -426,6 +445,8 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, addr = vm_mmap(obj->filp, 0, args->size, PROT_READ | PROT_WRITE, MAP_SHARED, 0); + /* restore it to drm_file object. */ + obj->filp->private_data = file_priv; drm_gem_object_unreference_unlocked(obj); if (IS_ERR((void *)addr)) -- 1.7.4.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel