diff options
author | kib <kib@FreeBSD.org> | 2008-03-20 16:08:42 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2008-03-20 16:08:42 +0000 |
commit | de73f6b678cf8f5836987c1992865893e3db34f9 (patch) | |
tree | 50fc8dd9632a119a44a8a40dc17a7e777a5e5b2f /sys/vm | |
parent | c8f58c14c0a0d193084549ee0a04e3049c6a3463 (diff) | |
download | FreeBSD-src-de73f6b678cf8f5836987c1992865893e3db34f9.zip FreeBSD-src-de73f6b678cf8f5836987c1992865893e3db34f9.tar.gz |
Do not dereference cdev->si_cdevsw, use the dev_refthread() to properly
obtain the reference. In particular, this fixes the panic reported in
the PR. Remove the comments stating that this needs to be done.
PR: kern/119422
MFC after: 1 week
Diffstat (limited to 'sys/vm')
-rw-r--r-- | sys/vm/vm_mmap.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 8a496a6..f622d99 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -1160,6 +1160,7 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize, void *handle; vm_object_t obj; struct mount *mp; + struct cdevsw *dsw; int error, flags, type; int vfslocked; @@ -1190,13 +1191,19 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize, type = OBJT_DEVICE; handle = vp->v_rdev; - /* XXX: lack thredref on device */ - if(vp->v_rdev->si_devsw->d_flags & D_MMAP_ANON) { + dsw = dev_refthread(handle); + if (dsw == NULL) { + error = ENXIO; + goto done; + } + if (dsw->d_flags & D_MMAP_ANON) { + dev_relthread(handle); *maxprotp = VM_PROT_ALL; *flagsp |= MAP_ANON; error = 0; goto done; } + dev_relthread(handle); /* * cdevs does not provide private mappings of any kind. */ @@ -1273,16 +1280,21 @@ vm_mmap_cdev(struct thread *td, vm_size_t objsize, struct cdev *cdev, vm_ooffset_t foff, vm_object_t *objp) { vm_object_t obj; + struct cdevsw *dsw; int flags; flags = *flagsp; - /* XXX: lack thredref on device */ - if (cdev->si_devsw->d_flags & D_MMAP_ANON) { + dsw = dev_refthread(cdev); + if (dsw == NULL) + return (ENXIO); + if (dsw->d_flags & D_MMAP_ANON) { + dev_relthread(cdev); *maxprotp = VM_PROT_ALL; *flagsp |= MAP_ANON; return (0); } + dev_relthread(cdev); /* * cdevs does not provide private mappings of any kind. */ |