Index: sys/arm64/arm64/mem.c =================================================================== --- sys/arm64/arm64/mem.c +++ sys/arm64/arm64/mem.c @@ -49,11 +49,10 @@ memrw(struct cdev *dev, struct uio *uio, int flags) { struct iovec *iov; - struct vm_page m; - vm_page_t marr; - vm_offset_t off, v; + vm_offset_t off, v, p; u_int cnt; int error; + void *ptr; error = 0; @@ -67,7 +66,7 @@ continue; } - v = uio->uio_offset; + p = v = uio->uio_offset; off = v & PAGE_MASK; cnt = ulmin(iov->iov_len, PAGE_SIZE - (u_int)off); if (cnt == 0) @@ -88,8 +87,8 @@ } /* Get the physical address to read */ - v = pmap_extract(kernel_pmap, v); - if (v == 0) { + p = pmap_extract(kernel_pmap, v); + if (p == 0) { error = EFAULT; break; } @@ -97,16 +96,17 @@ /* FALLTHROUGH */ case CDEV_MINOR_MEM: /* If within the DMAP use this to copy from */ - if (PHYS_IN_DMAP(v)) { - v = PHYS_TO_DMAP(v); - error = uiomove((void *)v, cnt, uio); - break; + if (PHYS_IN_DMAP(p)) { + v = PHYS_TO_DMAP(p); + if (pmap_kextract(v) != 0) { + error = uiomove((void *)v, cnt, uio); + break; + } } - /* Have uiomove_fromphys handle the data */ - m.phys_addr = trunc_page(v); - marr = &m; - uiomove_fromphys(&marr, off, cnt, uio); + ptr = pmap_mapdev(p, PAGE_SIZE); + error = uiomove((void*)ptr, cnt, uio); + pmap_unmapdev((vm_offset_t)ptr, PAGE_SIZE); break; } }