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
This commit is contained in:
parent
4b539f02f5
commit
91a35e7870
@ -527,6 +527,7 @@ devfs_rule_match(struct devfs_krule *dk, struct devfs_dirent *de)
|
||||
{
|
||||
struct devfs_rule *dr = &dk->dk_rule;
|
||||
struct cdev *dev;
|
||||
struct cdevsw *dsw;
|
||||
|
||||
dev = devfs_rule_getdev(de);
|
||||
/*
|
||||
@ -540,13 +541,19 @@ devfs_rule_match(struct devfs_krule *dk, struct devfs_dirent *de)
|
||||
* They're actually testing to see whether the condition does
|
||||
* *not* match, since the default is to assume the rule should
|
||||
* be run (such as if there are no conditions).
|
||||
*
|
||||
* XXX: lacks threadref on dev
|
||||
*/
|
||||
if (dr->dr_icond & DRC_DSWFLAGS)
|
||||
if (dev == NULL ||
|
||||
(dev->si_devsw->d_flags & dr->dr_dswflags) == 0)
|
||||
if (dr->dr_icond & DRC_DSWFLAGS) {
|
||||
if (dev == NULL)
|
||||
return (0);
|
||||
dsw = dev_refthread(dev);
|
||||
if (dsw == NULL)
|
||||
return (0);
|
||||
if ((dsw->d_flags & dr->dr_dswflags) == 0) {
|
||||
dev_relthread(dev);
|
||||
return (0);
|
||||
}
|
||||
dev_relthread(dev);
|
||||
}
|
||||
if (dr->dr_icond & DRC_PATHPTRN)
|
||||
if (!devfs_rule_matchpath(dk, de))
|
||||
return (0);
|
||||
|
@ -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.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user