Subversion Repositories Kolibri OS

Rev

Rev 6937 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6937 Rev 7144
Line 785... Line 785...
785
	if (dev->driver->gem_free_object != NULL)
785
	if (dev->driver->gem_free_object != NULL)
786
		dev->driver->gem_free_object(obj);
786
		dev->driver->gem_free_object(obj);
787
}
787
}
788
EXPORT_SYMBOL(drm_gem_object_free);
788
EXPORT_SYMBOL(drm_gem_object_free);
Line -... Line 789...
-
 
789
 
-
 
790
/**
-
 
791
 * drm_gem_vm_open - vma->ops->open implementation for GEM
789
 
792
 * @vma: VM area structure
-
 
793
 *
-
 
794
 * This function implements the #vm_operations_struct open() callback for GEM
-
 
795
 * drivers. This must be used together with drm_gem_vm_close().
790
 
796
 */
791
#if 0
797
#if 0
792
void drm_gem_vm_open(struct vm_area_struct *vma)
798
void drm_gem_vm_open(struct vm_area_struct *vma)
793
{
799
{
Line 794... Line 800...
794
	struct drm_gem_object *obj = vma->vm_private_data;
800
	struct drm_gem_object *obj = vma->vm_private_data;
795
 
801
 
796
	drm_gem_object_reference(obj);
802
	drm_gem_object_reference(obj);
Line -... Line 803...
-
 
803
}
-
 
804
EXPORT_SYMBOL(drm_gem_vm_open);
-
 
805
 
-
 
806
/**
-
 
807
 * drm_gem_vm_close - vma->ops->close implementation for GEM
-
 
808
 * @vma: VM area structure
-
 
809
 *
797
}
810
 * This function implements the #vm_operations_struct close() callback for GEM
798
EXPORT_SYMBOL(drm_gem_vm_open);
811
 * drivers. This must be used together with drm_gem_vm_open().
799
 
812
 */
800
void drm_gem_vm_close(struct vm_area_struct *vma)
-
 
Line 801... Line -...
801
{
-
 
802
	struct drm_gem_object *obj = vma->vm_private_data;
-
 
803
	struct drm_device *dev = obj->dev;
813
void drm_gem_vm_close(struct vm_area_struct *vma)
804
 
-
 
805
	mutex_lock(&dev->struct_mutex);
814
{
806
	drm_vm_close_locked(obj->dev, vma);
815
	struct drm_gem_object *obj = vma->vm_private_data;
Line -... Line 816...
-
 
816
 
-
 
817
	drm_gem_object_unreference_unlocked(obj);
-
 
818
}
-
 
819
EXPORT_SYMBOL(drm_gem_vm_close);
-
 
820
 
-
 
821
/**
-
 
822
 * drm_gem_mmap_obj - memory map a GEM object
-
 
823
 * @obj: the GEM object to map
-
 
824
 * @obj_size: the object size to be mapped, in bytes
-
 
825
 * @vma: VMA for the area to be mapped
-
 
826
 *
-
 
827
 * Set up the VMA to prepare mapping of the GEM object using the gem_vm_ops
-
 
828
 * provided by the driver. Depending on their requirements, drivers can either
-
 
829
 * provide a fault handler in their gem_vm_ops (in which case any accesses to
-
 
830
 * the object will be trapped, to perform migration, GTT binding, surface
-
 
831
 * register allocation, or performance monitoring), or mmap the buffer memory
-
 
832
 * synchronously after calling drm_gem_mmap_obj.
-
 
833
 *
-
 
834
 * This function is mainly intended to implement the DMABUF mmap operation, when
-
 
835
 * the GEM object is not looked up based on its fake offset. To implement the
-
 
836
 * DRM mmap operation, drivers should use the drm_gem_mmap() function.
-
 
837
 *
-
 
838
 * drm_gem_mmap_obj() assumes the user is granted access to the buffer while
-
 
839
 * drm_gem_mmap() prevents unprivileged users from mapping random objects. So
-
 
840
 * callers must verify access restrictions before calling this helper.
-
 
841
 *
-
 
842
 * Return 0 or success or -EINVAL if the object size is smaller than the VMA
-
 
843
 * size, or if no gem_vm_ops are provided.
-
 
844
 */
-
 
845
int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
-
 
846
		     struct vm_area_struct *vma)
-
 
847
{
-
 
848
	struct drm_device *dev = obj->dev;
-
 
849
 
-
 
850
	/* Check for valid size. */
-
 
851
	if (obj_size < vma->vm_end - vma->vm_start)
-
 
852
		return -EINVAL;
-
 
853
 
-
 
854
	if (!dev->driver->gem_vm_ops)
-
 
855
		return -EINVAL;
-
 
856
 
-
 
857
	vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
-
 
858
	vma->vm_ops = dev->driver->gem_vm_ops;
-
 
859
	vma->vm_private_data = obj;
-
 
860
	vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
-
 
861
 
-
 
862
	/* Take a ref for this mapping of the object, so that the fault
-
 
863
	 * handler can dereference the mmap offset's pointer to the object.
-
 
864
	 * This reference is cleaned up by the corresponding vm_close
-
 
865
	 * (which should happen whether the vma was created by this call, or
-
 
866
	 * by a vm_open due to mremap or partial unmap or whatever).
-
 
867
	 */
-
 
868
	drm_gem_object_reference(obj);
-
 
869
 
-
 
870
	return 0;
-
 
871
}
-
 
872
EXPORT_SYMBOL(drm_gem_mmap_obj);
-
 
873
 
-
 
874
/**
-
 
875
 * drm_gem_mmap - memory map routine for GEM objects
-
 
876
 * @filp: DRM file pointer
-
 
877
 * @vma: VMA for the area to be mapped
-
 
878
 *
-
 
879
 * If a driver supports GEM object mapping, mmap calls on the DRM file
-
 
880
 * descriptor will end up here.
-
 
881
 *
-
 
882
 * Look up the GEM object based on the offset passed in (vma->vm_pgoff will
-
 
883
 * contain the fake offset we created when the GTT map ioctl was called on
-
 
884
 * the object) and map it with a call to drm_gem_mmap_obj().
-
 
885
 *
-
 
886
 * If the caller is not granted access to the buffer object, the mmap will fail
-
 
887
 * with EACCES. Please see the vma manager for more information.
-
 
888
 */
-
 
889
int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
-
 
890
{
-
 
891
	struct drm_file *priv = filp->private_data;
-
 
892
	struct drm_device *dev = priv->minor->dev;
-
 
893
	struct drm_gem_object *obj = NULL;
-
 
894
	struct drm_vma_offset_node *node;
-
 
895
	int ret;
-
 
896
 
-
 
897
	if (drm_device_is_unplugged(dev))
-
 
898
		return -ENODEV;
-
 
899
 
-
 
900
	drm_vma_offset_lock_lookup(dev->vma_offset_manager);
-
 
901
	node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager,
-
 
902
						  vma->vm_pgoff,
-
 
903
						  vma_pages(vma));
-
 
904
	if (likely(node)) {
-
 
905
		obj = container_of(node, struct drm_gem_object, vma_node);
-
 
906
		/*
-
 
907
		 * When the object is being freed, after it hits 0-refcnt it
-
 
908
		 * proceeds to tear down the object. In the process it will
-
 
909
		 * attempt to remove the VMA offset and so acquire this
807
	drm_gem_object_unreference(obj);
910
		 * mgr->vm_lock.  Therefore if we find an object with a 0-refcnt
-
 
911
		 * that matches our range, we know it is in the process of being
-
 
912
		 * destroyed and will be freed as soon as we release the lock -
-
 
913
		 * so we have to check for the 0-refcnted object and treat it as
-
 
914
		 * invalid.
-
 
915
		 */
-
 
916
		if (!kref_get_unless_zero(&obj->refcount))
-
 
917
			obj = NULL;
-
 
918
	}
-
 
919
	drm_vma_offset_unlock_lookup(dev->vma_offset_manager);
-
 
920
 
-
 
921
	if (!obj)
-
 
922
		return -EINVAL;
Line -... Line 923...
-
 
923
 
-
 
924
	if (!drm_vma_node_is_allowed(node, filp)) {
Line -... Line 925...
-
 
925
		drm_gem_object_unreference_unlocked(obj);
Line -... Line 926...
-
 
926
		return -EACCES;
-
 
927
	}
-
 
928
 
-
 
929
	ret = drm_gem_mmap_obj(obj, drm_vma_node_size(node) << PAGE_SHIFT,
808
	mutex_unlock(&dev->struct_mutex);
930
			       vma);