aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2013-04-16 08:14:52 -0400
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2013-06-08 03:14:03 -0400
commit1c5aafa6eee2d5712f774676d407e5ab6dae9a1b (patch)
tree5cb8d947cca86c336977ad86a5e0f76eac0e0533
parent328a4719b6a0930721b5f8d5c69993d3b6e3913f (diff)
drm/gem: Split drm_gem_mmap() into object search and object mapping
The drm_gem_mmap() function first finds the GEM object to be mapped based on the fake mmap offset and then maps the object. Split the object mapping code into a standalone drm_gem_mmap_obj() function that can be used to implement dma-buf mmap() operations. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Reviewed-by: Rob Clark <robdclark@gmail.com>
-rw-r--r--drivers/gpu/drm/drm_gem.c83
-rw-r--r--include/drm/drmP.h2
2 files changed, 54 insertions, 31 deletions
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index cf919e36e8ae..43217138816d 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -644,6 +644,55 @@ void drm_gem_vm_close(struct vm_area_struct *vma)
644} 644}
645EXPORT_SYMBOL(drm_gem_vm_close); 645EXPORT_SYMBOL(drm_gem_vm_close);
646 646
647/**
648 * drm_gem_mmap_obj - memory map a GEM object
649 * @obj: the GEM object to map
650 * @obj_size: the object size to be mapped, in bytes
651 * @vma: VMA for the area to be mapped
652 *
653 * Set up the VMA to prepare mapping of the GEM object using the gem_vm_ops
654 * provided by the driver. Depending on their requirements, drivers can either
655 * provide a fault handler in their gem_vm_ops (in which case any accesses to
656 * the object will be trapped, to perform migration, GTT binding, surface
657 * register allocation, or performance monitoring), or mmap the buffer memory
658 * synchronously after calling drm_gem_mmap_obj.
659 *
660 * This function is mainly intended to implement the DMABUF mmap operation, when
661 * the GEM object is not looked up based on its fake offset. To implement the
662 * DRM mmap operation, drivers should use the drm_gem_mmap() function.
663 *
664 * Return 0 or success or -EINVAL if the object size is smaller than the VMA
665 * size, or if no gem_vm_ops are provided.
666 */
667int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
668 struct vm_area_struct *vma)
669{
670 struct drm_device *dev = obj->dev;
671
672 /* Check for valid size. */
673 if (obj_size < vma->vm_end - vma->vm_start)
674 return -EINVAL;
675
676 if (!dev->driver->gem_vm_ops)
677 return -EINVAL;
678
679 vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
680 vma->vm_ops = dev->driver->gem_vm_ops;
681 vma->vm_private_data = obj;
682 vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
683
684 /* Take a ref for this mapping of the object, so that the fault
685 * handler can dereference the mmap offset's pointer to the object.
686 * This reference is cleaned up by the corresponding vm_close
687 * (which should happen whether the vma was created by this call, or
688 * by a vm_open due to mremap or partial unmap or whatever).
689 */
690 drm_gem_object_reference(obj);
691
692 drm_vm_open_locked(dev, vma);
693 return 0;
694}
695EXPORT_SYMBOL(drm_gem_mmap_obj);
647 696
648/** 697/**
649 * drm_gem_mmap - memory map routine for GEM objects 698 * drm_gem_mmap - memory map routine for GEM objects
@@ -653,11 +702,9 @@ EXPORT_SYMBOL(drm_gem_vm_close);
653 * If a driver supports GEM object mapping, mmap calls on the DRM file 702 * If a driver supports GEM object mapping, mmap calls on the DRM file
654 * descriptor will end up here. 703 * descriptor will end up here.
655 * 704 *
656 * If we find the object based on the offset passed in (vma->vm_pgoff will 705 * Look up the GEM object based on the offset passed in (vma->vm_pgoff will
657 * contain the fake offset we created when the GTT map ioctl was called on 706 * contain the fake offset we created when the GTT map ioctl was called on
658 * the object), we set up the driver fault handler so that any accesses 707 * the object) and map it with a call to drm_gem_mmap_obj().
659 * to the object can be trapped, to perform migration, GTT binding, surface
660 * register allocation, or performance monitoring.
661 */ 708 */
662int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) 709int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
663{ 710{
@@ -665,7 +712,6 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
665 struct drm_device *dev = priv->minor->dev; 712 struct drm_device *dev = priv->minor->dev;
666 struct drm_gem_mm *mm = dev->mm_private; 713 struct drm_gem_mm *mm = dev->mm_private;
667 struct drm_local_map *map = NULL; 714 struct drm_local_map *map = NULL;
668 struct drm_gem_object *obj;
669 struct drm_hash_item *hash; 715 struct drm_hash_item *hash;
670 int ret = 0; 716 int ret = 0;
671 717
@@ -686,32 +732,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
686 goto out_unlock; 732 goto out_unlock;
687 } 733 }
688 734
689 /* Check for valid size. */ 735 ret = drm_gem_mmap_obj(map->handle, map->size, vma);
690 if (map->size < vma->vm_end - vma->vm_start) {
691 ret = -EINVAL;
692 goto out_unlock;
693 }
694
695 obj = map->handle;
696 if (!obj->dev->driver->gem_vm_ops) {
697 ret = -EINVAL;
698 goto out_unlock;
699 }
700
701 vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
702 vma->vm_ops = obj->dev->driver->gem_vm_ops;
703 vma->vm_private_data = map->handle;
704 vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
705
706 /* Take a ref for this mapping of the object, so that the fault
707 * handler can dereference the mmap offset's pointer to the object.
708 * This reference is cleaned up by the corresponding vm_close
709 * (which should happen whether the vma was created by this call, or
710 * by a vm_open due to mremap or partial unmap or whatever).
711 */
712 drm_gem_object_reference(obj);
713
714 drm_vm_open_locked(dev, vma);
715 736
716out_unlock: 737out_unlock:
717 mutex_unlock(&dev->struct_mutex); 738 mutex_unlock(&dev->struct_mutex);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index b06f5afe10ce..79fb4c7b6c72 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1616,6 +1616,8 @@ int drm_gem_private_object_init(struct drm_device *dev,
1616void drm_gem_object_handle_free(struct drm_gem_object *obj); 1616void drm_gem_object_handle_free(struct drm_gem_object *obj);
1617void drm_gem_vm_open(struct vm_area_struct *vma); 1617void drm_gem_vm_open(struct vm_area_struct *vma);
1618void drm_gem_vm_close(struct vm_area_struct *vma); 1618void drm_gem_vm_close(struct vm_area_struct *vma);
1619int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
1620 struct vm_area_struct *vma);
1619int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); 1621int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
1620 1622
1621#include <drm/drm_global.h> 1623#include <drm/drm_global.h>