diff options
author | kib <kib@FreeBSD.org> | 2015-01-02 01:05:08 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2015-01-02 01:05:08 +0000 |
commit | 35b8c829918b84d6292cc7300d4513050b2cc425 (patch) | |
tree | 2ef55709e9983607804f02917acf78101f2389d3 /sys/amd64/amd64/mem.c | |
parent | a9168eed4eca29df63a254d2adf1d97db024d4e3 (diff) | |
download | FreeBSD-src-35b8c829918b84d6292cc7300d4513050b2cc425.zip FreeBSD-src-35b8c829918b84d6292cc7300d4513050b2cc425.tar.gz |
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
Diffstat (limited to 'sys/amd64/amd64/mem.c')
-rw-r--r-- | sys/amd64/amd64/mem.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/sys/amd64/amd64/mem.c b/sys/amd64/amd64/mem.c index 170da3f..2b6b112 100644 --- a/sys/amd64/amd64/mem.c +++ b/sys/amd64/amd64/mem.c @@ -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; |