diff options
Diffstat (limited to 'sys/vm/vm_map.c')
-rw-r--r-- | sys/vm/vm_map.c | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index b8f4aee..0ff3763 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -159,7 +159,7 @@ vm_map_modify(struct vas vas, vaddr_t va, paddr_t pa, vm_prot_t prot, bool unmap * crashes. */ void * -mmap_at(void *addr, size_t len, int prot, int flags, int fildes, off_t off) +mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { struct vm_object *map_obj = NULL; struct cdevsw *cdevp; @@ -179,11 +179,6 @@ mmap_at(void *addr, size_t len, int prot, int flags, int fildes, off_t off) npgs = len / DEFAULT_PAGESIZE; vas = pmap_read_vas(); - if (addr == NULL) { - pr_error("mmap: NULL addr not supported\n"); - return NULL; - } - /* Validate flags */ if (ISSET(flags, MAP_FIXED)) { pr_error("mmap: fixed mappings not yet supported\n"); @@ -216,11 +211,29 @@ mmap_at(void *addr, size_t len, int prot, int flags, int fildes, off_t off) } cdevp = map_obj->data; - if ((pa = cdevp->mmap(vp->dev, off, 0)) == 0) { + if ((pa = cdevp->mmap(vp->dev, len, off, 0)) == 0) { kprintf("mmap: dev mmap() gave 0\n"); return NULL; } + /* + * If the address passed is NULL, just identity + * map everything. + * + * XXX: This is why the bounds check done in the + * cdev mmap() *must* be correct. + * + * TODO: Use copy-on-write for this instead. Since mapping + * certain devices may required a lot of memory to + * be referenced anyways, we could use a buffered + * copy-on-write technique where only a window of + * pages can be mapped on-demand and other pages + * freed when that window is exceeded. + */ + if (addr == NULL) { + addr = (void *)pa; + } + va = ALIGN_DOWN((vaddr_t)addr, DEFAULT_PAGESIZE); error = vm_map(vas, va, pa, prot, len); if (error != 0) { @@ -231,6 +244,11 @@ mmap_at(void *addr, size_t len, int prot, int flags, int fildes, off_t off) goto done; } + if (addr == NULL) { + pr_error("mmap: NULL addr not supported\n"); + return NULL; + } + /* Only allocate new obj if needed */ if (map_obj == NULL) { map_obj = dynalloc(sizeof(*map_obj)); @@ -292,7 +310,7 @@ done: * multiple of the machine page size. */ int -munmap_at(void *addr, size_t len) +munmap(void *addr, size_t len) { int pgno; vaddr_t va; @@ -348,7 +366,7 @@ munmap_at(void *addr, size_t len) * arg5 -> off */ scret_t -mmap(struct syscall_args *scargs) +sys_mmap(struct syscall_args *scargs) { void *addr; size_t len; @@ -357,11 +375,11 @@ mmap(struct syscall_args *scargs) addr = (void *)scargs->arg0; len = scargs->arg1; - prot = scargs->arg2; + prot = scargs->arg2 | PROT_USER; flags = scargs->arg3; fildes = scargs->arg4; off = scargs->arg5; - return (scret_t)mmap_at(addr, len, prot, flags, fildes, off); + return (scret_t)mmap(addr, len, prot, flags, fildes, off); } /* @@ -371,14 +389,14 @@ mmap(struct syscall_args *scargs) * arg1 -> len */ scret_t -munmap(struct syscall_args *scargs) +sys_munmap(struct syscall_args *scargs) { void *addr; size_t len; addr = (void *)scargs->arg0; len = scargs->arg1; - return (scret_t)munmap_at(addr, len); + return (scret_t)munmap(addr, len); } /* |