cvs commit: src/sys/dev/drm drm_bufs.h

John Baldwin jhb at FreeBSD.org
Mon Feb 28 21:46:20 GMT 2005


On Friday 25 February 2005 02:35 am, Maxim Konovalov wrote:
> On Tue, 22 Feb 2005, 13:56-0000, Poul-Henning Kamp wrote:
> > phk         2005-02-22 13:56:15 UTC
> >
> >   FreeBSD src repository
> >
> >   Modified files:
> >     sys/dev/drm          drm_bufs.h
> >   Log:
> >   Neuter DRM(mapbufs) until somebody finds time to try to fix it.
> >
> >   It is _never_ OK to find a vnode from a struct cdev because you have
> >   no way of telling if you get the right one.  You might be in jail or
> >   chroot for instance.
>
> Thankyou for breaking my workstation and only development machine,
> radeon(4) doesn't work now.
>
> How and who is going to fix this?

I have a patch to allow vm_mmap() to operate on a cdev directly.  It fixed X 
for my laptop with a mobility 7500 radeon.  This is an older version, I've 
changed the interface locally to not use a MAP_CDEV flag, but I haven't 
tested that yet and this is a known-working version. :)

--- //depot/vendor/freebsd/src/sys/dev/drm/drm_bufs.h	2005/02/22 14:00:48
+++ //depot/user/jhb/acpipci/dev/drm/drm_bufs.h	2005/02/25 19:55:35
@@ -923,12 +923,8 @@
 
 #ifdef __FreeBSD__
 	vaddr = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ);
-#ifdef this_is_just_plain_bogus
 	retcode = vm_mmap(&vms->vm_map, &vaddr, size, PROT_READ | PROT_WRITE,
-	    VM_PROT_ALL, MAP_SHARED, SLIST_FIRST(&kdev->si_hlist), foff );
-#else
-	retcode = EOPNOTSUPP;
-#endif
+	    VM_PROT_ALL, MAP_SHARED | MAP_CDEV, kdev, foff );
 #elif defined(__NetBSD__)
 	vaddr = round_page((vaddr_t)vms->vm_daddr + MAXDSIZ);
 	retcode = uvm_mmap(&vms->vm_map, &vaddr, size,
--- //depot/vendor/freebsd/src/sys/sys/mman.h	2004/04/27 13:15:33
+++ //depot/user/jhb/acpipci/sys/mman.h	2005/02/25 19:55:35
@@ -84,6 +84,10 @@
  * Extended flags
  */
 #define	MAP_NOCORE	 0x00020000 /* dont include these pages in a coredump */
+#ifdef _KERNEL
+#define	MAP_CDEV	 0x00040000 /* map from a cdev, not a vnode */
+#define	MAP_KERNEL_ONLY	 MAP_CDEV
+#endif
 #endif /* __BSD_VISIBLE */
 
 #if __POSIX_VISIBLE >= 199309
--- //depot/vendor/freebsd/src/sys/vm/vm_mmap.c	2005/01/25 00:40:30
+++ //depot/user/jhb/acpipci/vm/vm_mmap.c	2005/02/25 20:00:21
@@ -109,6 +109,8 @@
 
 static int vm_mmap_vnode(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *,
     int *, struct vnode *, vm_ooffset_t, vm_object_t *);
+static int vm_mmap_cdev(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *,
+    int *, struct cdev *, vm_ooffset_t, vm_object_t *);
 
 /*
  * MPSAFE
@@ -218,7 +220,7 @@
 	fp = NULL;
 	/* make sure mapping fits into numeric range etc */
 	if ((ssize_t) uap->len < 0 ||
-	    ((flags & MAP_ANON) && uap->fd != -1))
+	    ((flags & MAP_ANON) && uap->fd != -1) || (flags & MAP_KERNEL_ONLY))
 		return (EINVAL);
 
 	if (flags & MAP_STACK) {
@@ -1166,6 +1168,55 @@
 }
 
 /*
+ * vm_mmap_cdev()
+ *
+ * MPSAFE
+ *
+ * Helper function for vm_mmap.  Perform sanity check specific for mmap
+ * operations on cdevs.
+ */
+int
+vm_mmap_cdev(struct thread *td, vm_size_t objsize,
+    vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp,
+    struct cdev *cdev, vm_ooffset_t foff, vm_object_t *objp)
+{
+	vm_object_t obj;
+	int flags;
+
+	flags = *flagsp;
+
+	/* XXX: lack thredref on device */
+	if (cdev->si_devsw->d_flags & D_MMAP_ANON) {
+		*maxprotp = VM_PROT_ALL;
+		*flagsp |= MAP_ANON;
+		return (0);
+	}
+	/*
+	 * cdevs does not provide private mappings of any kind.
+	 */
+	if ((*maxprotp & VM_PROT_WRITE) == 0 &&
+	    (prot & PROT_WRITE) != 0)
+		return (EACCES);
+	if (flags & (MAP_PRIVATE|MAP_COPY))
+		return (EINVAL);
+	/*
+	 * Force device mappings to be shared.
+	 */
+	flags |= MAP_SHARED;
+#ifdef MAC_XXX
+	error = mac_check_vnode_mmap(td->td_ucred, vp, prot);
+	if (error != 0)
+		return (error);
+#endif
+	obj = vm_pager_allocate(OBJT_DEVICE, cdev, objsize, prot, foff);
+	if (obj == NULL)
+		return (EINVAL);
+	*objp = obj;
+	*flagsp = flags;
+	return (0);
+}
+
+/*
  * vm_mmap()
  *
  * MPSAFE
@@ -1223,11 +1274,14 @@
 	 * Lookup/allocate object.
 	 */
 	if (handle != NULL) {
-		error = vm_mmap_vnode(td, size, prot, &maxprot, &flags,
-		    handle, foff, &object);
-		if (error) {
+		if (flags & MAP_CDEV)
+			error = vm_mmap_cdev(td, size, prot, &maxprot, &flags,
+			    handle, foff, &object);
+		else
+			error = vm_mmap_vnode(td, size, prot, &maxprot, &flags,
+			    handle, foff, &object);
+		if (error)
 			return (error);
-		}
 	}
 	if (flags & MAP_ANON) {
 		object = NULL;


-- 
John Baldwin <jhb at FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve"  =  http://www.FreeBSD.org


More information about the cvs-all mailing list