summaryrefslogtreecommitdiffstats
path: root/sys/amd64/amd64/mem.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-01-02 01:05:08 +0000
committerkib <kib@FreeBSD.org>2015-01-02 01:05:08 +0000
commit35b8c829918b84d6292cc7300d4513050b2cc425 (patch)
tree2ef55709e9983607804f02917acf78101f2389d3 /sys/amd64/amd64/mem.c
parenta9168eed4eca29df63a254d2adf1d97db024d4e3 (diff)
downloadFreeBSD-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.c14
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;
OpenPOWER on IntegriCloud