Author: kib
Date: Fri Jan  2 01:05:08 2015
New Revision: 276523
URL: https://svnweb.freebsd.org/changeset/base/276523

Log:
  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

Modified:
  head/sys/amd64/amd64/mem.c

Modified: head/sys/amd64/amd64/mem.c
==============================================================================
--- head/sys/amd64/amd64/mem.c  Fri Jan  2 01:00:38 2015        (r276522)
+++ head/sys/amd64/amd64/mem.c  Fri Jan  2 01:05:08 2015        (r276523)
@@ -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,
 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;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to