summaryrefslogtreecommitdiffstats
path: root/sys/vm/device_pager.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-09-26 14:50:49 +0000
committerkib <kib@FreeBSD.org>2008-09-26 14:50:49 +0000
commit496b70bc6ae4c9f8b2f01168acbb39b39e6f3112 (patch)
tree83ec201504ae8c58d18c3600f36c7e08a41162df /sys/vm/device_pager.c
parentd421caabf98d87498154b13c49b8f5d352aea70c (diff)
downloadFreeBSD-src-496b70bc6ae4c9f8b2f01168acbb39b39e6f3112.zip
FreeBSD-src-496b70bc6ae4c9f8b2f01168acbb39b39e6f3112.tar.gz
Save previous content of the td_fpop before storing the current
filedescriptor into it. Make sure that td_fpop is NULL when calling d_mmap from dev_pager_getpages(). Change guards against td_fpop field being non-NULL with private state for another device, and against sudden clearing the td_fpop. This could occur when either a driver method calls another driver through the filedescriptor operation, or a page fault happen while driver is writing to a memory backed by another driver. Noted by: rwatson Tested by: rnoland MFC after: 3 days
Diffstat (limited to 'sys/vm/device_pager.c')
-rw-r--r--sys/vm/device_pager.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c
index e771928..5e31e2b 100644
--- a/sys/vm/device_pager.c
+++ b/sys/vm/device_pager.c
@@ -214,6 +214,8 @@ dev_pager_getpages(object, m, count, reqpage)
int i, ret;
int prot;
struct cdevsw *csw;
+ struct thread *td;
+ struct file *fpop;
VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
dev = object->handle;
@@ -224,8 +226,12 @@ dev_pager_getpages(object, m, count, reqpage)
panic("dev_pager_getpage: no cdevsw");
prot = PROT_READ; /* XXX should pass in? */
+ td = curthread;
+ fpop = td->td_fpop;
+ td->td_fpop = NULL;
ret = (*csw->d_mmap)(dev, (vm_offset_t)offset << PAGE_SHIFT, &paddr, prot);
KASSERT(ret == 0, ("dev_pager_getpage: map function returns error"));
+ td->td_fpop = fpop;
dev_relthread(dev);
if ((m[reqpage]->flags & PG_FICTITIOUS) != 0) {
OpenPOWER on IntegriCloud