diff options
Diffstat (limited to 'sys/amd64/amd64/mem.c')
-rw-r--r-- | sys/amd64/amd64/mem.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/sys/amd64/amd64/mem.c b/sys/amd64/amd64/mem.c index a5a9135..8671530 100644 --- a/sys/amd64/amd64/mem.c +++ b/sys/amd64/amd64/mem.c @@ -50,6 +50,8 @@ #include <sys/fcntl.h> #include <sys/ioccom.h> #include <sys/kernel.h> +#include <sys/lock.h> +#include <sys/mutex.h> #include <sys/malloc.h> #include <sys/memrange.h> #include <sys/proc.h> @@ -153,13 +155,17 @@ mmrw(dev_t dev, struct uio *uio, int flags) case 0: v = uio->uio_offset; v &= ~PAGE_MASK; + mtx_lock(&vm_mtx); pmap_kenter((vm_offset_t)ptvmmap, v); + mtx_unlock(&vm_mtx); o = (int)uio->uio_offset & PAGE_MASK; c = (u_int)(PAGE_SIZE - ((int)iov->iov_base & PAGE_MASK)); c = min(c, (u_int)(PAGE_SIZE - o)); c = min(c, (u_int)iov->iov_len); error = uiomove((caddr_t)&ptvmmap[o], (int)c, uio); + mtx_lock(&vm_mtx); pmap_kremove((vm_offset_t)ptvmmap); + mtx_unlock(&vm_mtx); continue; /* minor device 1 is kernel memory */ @@ -177,14 +183,20 @@ mmrw(dev_t dev, struct uio *uio, int flags) return EFAULT; if (eaddr >= (vm_offset_t)VADDR(APTDPTDI, 0)) return EFAULT; + mtx_lock(&vm_mtx); for (; addr < eaddr; addr += PAGE_SIZE) - if (pmap_extract(kernel_pmap, addr) == 0) + if (pmap_extract(kernel_pmap, addr) == 0) { + mtx_unlock(&vm_mtx); return EFAULT; - + } + if (!kernacc((caddr_t)(int)uio->uio_offset, c, uio->uio_rw == UIO_READ ? - VM_PROT_READ : VM_PROT_WRITE)) + VM_PROT_READ : VM_PROT_WRITE)) { + mtx_unlock(&vm_mtx); return (EFAULT); + } + mtx_unlock(&vm_mtx); error = uiomove((caddr_t)(int)uio->uio_offset, (int)c, uio); continue; } |