Module Name:    src
Committed By:   riastradh
Date:           Wed Jan 22 16:40:44 UTC 2014

Modified Files:
        src/sys/external/bsd/drm2/dist/include/drm [riastradh-drm2]: drmP.h
        src/sys/external/bsd/drm2/drm [riastradh-drm2]: drm_drv.c drm_gem_vm.c
            drm_vm.c

Log Message:
Tidy up and reuse the code I had already written for gem mmapping.


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.1.2.55 -r1.1.1.1.2.56 \
    src/sys/external/bsd/drm2/dist/include/drm/drmP.h
cvs rdiff -u -r1.1.2.32 -r1.1.2.33 src/sys/external/bsd/drm2/drm/drm_drv.c
cvs rdiff -u -r1.1.2.3 -r1.1.2.4 src/sys/external/bsd/drm2/drm/drm_gem_vm.c \
    src/sys/external/bsd/drm2/drm/drm_vm.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/external/bsd/drm2/dist/include/drm/drmP.h
diff -u src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.1.1.1.2.55 src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.1.1.1.2.56
--- src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.1.1.1.2.55	Wed Jan 15 21:25:29 2014
+++ src/sys/external/bsd/drm2/dist/include/drm/drmP.h	Wed Jan 22 16:40:44 2014
@@ -1494,6 +1494,8 @@ extern int drm_release(struct inode *ino
 
 				/* Mapping support (drm_vm.h) */
 #ifdef __NetBSD__
+extern int drm_mmap_object(struct drm_device *, off_t, size_t, int,
+    struct uvm_object **);
 extern paddr_t drm_mmap_paddr(struct drm_device *, off_t, int);
 #else
 extern int drm_mmap(struct file *filp, struct vm_area_struct *vma);
@@ -1846,7 +1848,7 @@ void drm_gem_object_handle_free(struct d
 #ifdef __NetBSD__
 void drm_gem_pager_reference(struct uvm_object *);
 void drm_gem_pager_detach(struct uvm_object *);
-int drm_gem_mmap_object(struct drm_device *, off_t *, size_t,
+int drm_gem_mmap_object(struct drm_device *, off_t, size_t, int,
     struct uvm_object **);
 #else
 void drm_gem_vm_open(struct vm_area_struct *vma);

Index: src/sys/external/bsd/drm2/drm/drm_drv.c
diff -u src/sys/external/bsd/drm2/drm/drm_drv.c:1.1.2.32 src/sys/external/bsd/drm2/drm/drm_drv.c:1.1.2.33
--- src/sys/external/bsd/drm2/drm/drm_drv.c:1.1.2.32	Wed Jan 22 14:58:47 2014
+++ src/sys/external/bsd/drm2/drm/drm_drv.c	Wed Jan 22 16:40:44 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_drv.c,v 1.1.2.32 2014/01/22 14:58:47 riastradh Exp $	*/
+/*	$NetBSD: drm_drv.c,v 1.1.2.33 2014/01/22 16:40:44 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_drv.c,v 1.1.2.32 2014/01/22 14:58:47 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_drv.c,v 1.1.2.33 2014/01/22 16:40:44 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -43,13 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: drm_drv.c,v 
 #include <sys/poll.h>
 #include <sys/select.h>
 
-#include <uvm/uvm.h>
-#include <uvm/uvm_device.h>
 #include <uvm/uvm_extern.h>
-#include <uvm/uvm_fault.h>
-#include <uvm/uvm_page.h>
-#include <uvm/uvm_pmap.h>
-#include <uvm/uvm_prot.h>
 
 #include <drm/drmP.h>
 
@@ -104,8 +98,6 @@ static int	drm_stat(struct file *, struc
 static int	drm_ioctl(struct file *, unsigned long, void *);
 static int	drm_version_string(char *, size_t *, const char *);
 static paddr_t	drm_mmap(dev_t, off_t, int);
-static int	drm_do_mmap(struct uvm_object *, vm_prot_t, voff_t, size_t,
-		    vaddr_t *);
 
 static drm_ioctl_t	drm_version;
 static drm_ioctl_t	drm_mmap_ioctl;
@@ -886,101 +878,56 @@ drm_mmap_ioctl(struct drm_device *dev, v
 	const int prot = args->dnm_prot;
 	const int flags = args->dnm_flags;
 	const off_t offset = args->dnm_offset;
-	struct drm_gem_mm *const mm = dev->mm_private;
-	struct drm_hash_item *hash;
-	vm_prot_t vm_prot;
-	dev_t devno;
 	struct uvm_object *uobj;
-	vaddr_t vaddr;
+	const vm_prot_t vm_maxprot = (VM_PROT_READ | VM_PROT_WRITE);
+	vm_prot_t vm_prot;
+	int uvmflag;
+	vaddr_t align, vaddr;
 	int ret;
 
 	/* XXX Copypasta from drm_gem_mmap.  */
 	if (drm_device_is_unplugged(dev))
 		return -ENODEV;
 
-	if (prot != (PROT_READ | PROT_WRITE))
+	if (prot != (prot & (PROT_READ | PROT_WRITE)))
 		return -EACCES;
 	if (flags != MAP_SHARED)
 		return -EINVAL;
 	(void)addr;		/* XXX ignore -- no MAP_FIXED for now */
 
-	KASSERT(prot == (PROT_READ | PROT_WRITE));
-	vm_prot = (VM_PROT_READ | VM_PROT_WRITE);
-
-	mutex_lock(&dev->struct_mutex);
-	if (drm_ht_find_item(&mm->offset_hash, atop(offset), &hash) == 0) {
-		/* GEM object.  Map the GEM shared-memory uobj.  */
-
-		struct drm_local_map *const map =
-		    drm_hash_entry(hash, struct drm_map_list, hash)->map;
-		if ((map == NULL) ||
-		    (ISSET(map->flags, _DRM_RESTRICTED) && !DRM_SUSER())) {
-			ret = -EPERM;
-			goto out_unlock;
-		}
-		if (map->size < size) {
-			ret = -EINVAL;
-			goto out_unlock;
-		}
-
-		struct drm_gem_object *const obj = map->handle;
-		if (obj->dev->driver->gem_uvm_ops == NULL) {
-			ret = -EINVAL;
-			goto out_unlock;
-		}
-
-		uobj = obj->gemo_shm_uao;
-		ret = drm_do_mmap(uobj, prot, offset, size, &vaddr);
-		if (ret)
-			goto out_unlock;
-		drm_gem_object_reference(obj);
-
-out_unlock:	mutex_unlock(&dev->struct_mutex);
-	} else {
-		/*
-		 * Not a GEM object.  Use the old mmap.
-		 *
-		 * XXX Unlocking is wrong here, but the uvm device mmap
-		 * API will call cdev_mmap immediately (where we can
-		 * control whether or not the device is locked) and in
-		 * the fault handler (where the device is unlocked and
-		 * we can't do a thing about it), so we have to unlock
-		 * the device first.  The good news is that this should
-		 * only enable a broken application to use paddrs that
-		 * it is allowed to use anyway but that perhaps are not
-		 * the ones it expected.
-		 */
-		mutex_unlock(&dev->struct_mutex);
-
-		devno = file->minor->device;
-		uobj = udv_attach(&devno, prot, offset, size);
-		if (uobj == NULL) {
-			ret = -EINVAL;
-			goto out;
-		}
+	/* Try a GEM object mapping first.  */
+	ret = drm_gem_mmap_object(dev, offset, size, prot, &uobj);
+	if (ret)
+		return ret;
+	if (uobj != NULL)
+		goto map;
 
-		ret = drm_do_mmap(uobj, prot, offset, size, &vaddr);
-	}
+	/* Try a traditional DRM mapping second.  */
+	ret = drm_mmap_object(dev, offset, size, prot, &uobj);
+	if (ret)
+		return ret;
+	if (uobj != NULL)
+		goto map;
 
-out:	if (ret == 0)
-		args->dnm_addr = (void *)vaddr;
+	/* Fail.  */
 	return ret;
-}
 
-static int
-drm_do_mmap(struct uvm_object *uobj, vm_prot_t prot, voff_t offset,
-    size_t size, vaddr_t *vaddr)
-{
-	vaddr_t align;
-	int uvmflag;
+map:	vm_prot = ((ISSET(prot, PROT_READ)? VM_PROT_READ : 0) |
+	    (ISSET(prot, PROT_WRITE)? VM_PROT_WRITE : 0));
+	KASSERT(vm_prot == (vm_prot & vm_maxprot));
+	uvmflag = UVM_MAPFLAG(vm_prot, vm_maxprot, UVM_INH_COPY,
+	    UVM_ADV_RANDOM, UVM_FLAG_COPYONW);
 
 	align = 0;		/* XXX */
-	uvmflag = UVM_MAPFLAG(prot, prot, UVM_INH_COPY, UVM_ADV_RANDOM,
-	    UVM_FLAG_COPYONW);
-
-	*vaddr = (*curproc->p_emul->e_vm_default_addr)(curproc,
+	vaddr = (*curproc->p_emul->e_vm_default_addr)(curproc,
 	    (vaddr_t)curproc->p_vmspace->vm_daddr, size);
 	/* XXX errno NetBSD->Linux */
-	return -uvm_map(&curproc->p_vmspace->vm_map, vaddr, size, uobj, offset,
+	ret = -uvm_map(&curproc->p_vmspace->vm_map, &vaddr, size, uobj, offset,
 	    align, uvmflag);
+	if (ret)
+		return ret;
+
+	/* Success!  */
+	args->dnm_addr = (void *)vaddr;
+	return 0;
 }

Index: src/sys/external/bsd/drm2/drm/drm_gem_vm.c
diff -u src/sys/external/bsd/drm2/drm/drm_gem_vm.c:1.1.2.3 src/sys/external/bsd/drm2/drm/drm_gem_vm.c:1.1.2.4
--- src/sys/external/bsd/drm2/drm/drm_gem_vm.c:1.1.2.3	Sun Sep  8 15:56:32 2013
+++ src/sys/external/bsd/drm2/drm/drm_gem_vm.c	Wed Jan 22 16:40:44 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_gem_vm.c,v 1.1.2.3 2013/09/08 15:56:32 riastradh Exp $	*/
+/*	$NetBSD: drm_gem_vm.c,v 1.1.2.4 2014/01/22 16:40:44 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_gem_vm.c,v 1.1.2.3 2013/09/08 15:56:32 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_gem_vm.c,v 1.1.2.4 2014/01/22 16:40:44 riastradh Exp $");
 
 #include <sys/types.h>
 
@@ -38,8 +38,8 @@ __KERNEL_RCSID(0, "$NetBSD: drm_gem_vm.c
 
 #include <drm/drmP.h>
 
-static int	drm_gem_mmap_object_locked(struct drm_device *, off_t *,
-		    size_t, struct uvm_object **);
+static int	drm_gem_mmap_object_locked(struct drm_device *, off_t, size_t,
+		    int, struct uvm_object **);
 
 void
 drm_gem_pager_reference(struct uvm_object *uobj)
@@ -60,30 +60,31 @@ drm_gem_pager_detach(struct uvm_object *
 }
 
 int
-drm_gem_mmap_object(struct drm_device *dev, off_t *byte_offsetp, size_t nbytes,
-    struct uvm_object **uobjp)
+drm_gem_mmap_object(struct drm_device *dev, off_t byte_offset, size_t nbytes,
+    int prot, struct uvm_object **uobjp)
 {
-	int error;
+	int ret;
 
 	mutex_lock(&dev->struct_mutex);
-	error = drm_gem_mmap_object_locked(dev, byte_offsetp, nbytes, uobjp);
+	ret = drm_gem_mmap_object_locked(dev, byte_offset, nbytes, prot,
+	    uobjp);
 	mutex_unlock(&dev->struct_mutex);
 
-	return error;
+	return ret;
 }
 
 static int
-drm_gem_mmap_object_locked(struct drm_device *dev, off_t *byte_offsetp,
-    size_t nbytes, struct uvm_object **uobjp)
+drm_gem_mmap_object_locked(struct drm_device *dev, off_t byte_offset,
+    size_t nbytes, int prot __unused, struct uvm_object **uobjp)
 {
 	struct drm_gem_mm *const mm = dev->mm_private;
-	const off_t byte_offset = *byte_offsetp;
 	const off_t page_offset = (byte_offset >> PAGE_SHIFT);
 	struct drm_hash_item *hash;
 
 	KASSERT(mutex_is_locked(&dev->struct_mutex));
 	KASSERT(drm_core_check_feature(dev, DRIVER_GEM));
 	KASSERT(dev->driver->gem_uvm_ops != NULL);
+	KASSERT(prot == (prot & (PROT_READ | PROT_WRITE)));
 
 	if (byte_offset != (byte_offset & ~(PAGE_SIZE-1))) /* XXX kassert?  */
 		return -EINVAL;
Index: src/sys/external/bsd/drm2/drm/drm_vm.c
diff -u src/sys/external/bsd/drm2/drm/drm_vm.c:1.1.2.3 src/sys/external/bsd/drm2/drm/drm_vm.c:1.1.2.4
--- src/sys/external/bsd/drm2/drm/drm_vm.c:1.1.2.3	Wed Jan 22 14:58:47 2014
+++ src/sys/external/bsd/drm2/drm/drm_vm.c	Wed Jan 22 16:40:44 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_vm.c,v 1.1.2.3 2014/01/22 14:58:47 riastradh Exp $	*/
+/*	$NetBSD: drm_vm.c,v 1.1.2.4 2014/01/22 16:40:44 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,11 +30,13 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_vm.c,v 1.1.2.3 2014/01/22 14:58:47 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_vm.c,v 1.1.2.4 2014/01/22 16:40:44 riastradh Exp $");
 
 #include <sys/types.h>
+#include <sys/conf.h>
 
 #include <uvm/uvm_extern.h>
+#include <uvm/uvm_device.h>
 
 #include <drm/drmP.h>
 
@@ -43,6 +45,23 @@ static paddr_t	drm_mmap_dma_paddr(struct
 static paddr_t	drm_mmap_map_paddr(struct drm_device *, struct drm_local_map *,
 		    off_t, int);
 
+extern struct cdevsw drm_cdevsw;	/* XXX */
+
+int
+drm_mmap_object(struct drm_device *dev, off_t offset, size_t size, int prot,
+    struct uvm_object **uobjp)
+{
+	dev_t devno = cdevsw_lookup_major(&drm_cdevsw);
+	struct uvm_object *uobj;
+
+	uobj = udv_attach(&devno, prot, offset, size);
+	if (uobj == NULL)
+		return -EINVAL;
+
+	*uobjp = uobj;
+	return 0;
+}
+
 paddr_t
 drm_mmap_paddr(struct drm_device *dev, off_t byte_offset, int prot)
 {

Reply via email to