Callers of pmap_kextract() cannot distinguish between failure and

physical address zero.  Assume that the lowest page is always mapped
by direct map.

This restores access to the page at zero through /dev/mem after
r263475.

Reported and tested by:	neel
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2015-01-02 01:05:08 +00:00
parent ae7c85e9b0
commit 91a82f9585
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=276523

View File

@ -77,7 +77,7 @@ int
memrw(struct cdev *dev, struct uio *uio, int flags)
{
struct iovec *iov;
u_long c, v;
u_long c, v, vd;
int error, o, sflags;
vm_offset_t addr, eaddr;
@ -98,15 +98,15 @@ memrw(struct cdev *dev, struct uio *uio, int flags)
kmemphys:
o = v & PAGE_MASK;
c = min(uio->uio_resid, (u_int)(PAGE_SIZE - o));
v = PHYS_TO_DMAP(v);
if (v < DMAP_MIN_ADDRESS ||
(v > DMAP_MIN_ADDRESS + dmaplimit &&
v <= DMAP_MAX_ADDRESS) ||
pmap_kextract(v) == 0) {
vd = PHYS_TO_DMAP(v);
if (vd < DMAP_MIN_ADDRESS ||
(vd > DMAP_MIN_ADDRESS + dmaplimit &&
vd <= DMAP_MAX_ADDRESS) ||
(pmap_kextract(vd) == 0 && (v & PG_FRAME) != 0)) {
error = EFAULT;
goto ret;
}
error = uiomove((void *)v, (int)c, uio);
error = uiomove((void *)vd, (int)c, uio);
continue;
} else if (dev2unit(dev) == CDEV_MINOR_KMEM) {
v = uio->uio_offset;