cvs commit: src/sys/dev/drm drm_bufs.h
John Baldwin
jhb at FreeBSD.org
Mon Feb 28 21:46:24 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-src
mailing list