--- Net2/vm/vm_mmap.c 2018/04/24 18:03:57 1.1 +++ Net2/vm/vm_mmap.c 2018/04/24 18:14:56 1.1.1.4 @@ -37,7 +37,8 @@ * * from: Utah $Hdr: vm_mmap.c 1.3 90/01/21$ * - * @(#)vm_mmap.c 7.5 (Berkeley) 6/28/91 + * from: @(#)vm_mmap.c 7.5 (Berkeley) 6/28/91 + * vm_mmap.c,v 1.10 1993/07/17 15:24:54 mycroft Exp */ /* @@ -77,12 +78,14 @@ getpagesize(p, uap, retval) return (0); } +struct sbrk_args { + int incr; +}; + /* ARGSUSED */ sbrk(p, uap, retval) struct proc *p; - struct args { - int incr; - } *uap; + struct sbrk_args *uap; int *retval; { @@ -90,12 +93,14 @@ sbrk(p, uap, retval) return (EOPNOTSUPP); } +struct sstk_args { + int incr; +}; + /* ARGSUSED */ sstk(p, uap, retval) struct proc *p; - struct args { - int incr; - } *uap; + struct sstk_args *uap; int *retval; { @@ -103,16 +108,18 @@ sstk(p, uap, retval) return (EOPNOTSUPP); } +struct smmap_args { + caddr_t addr; + int len; + int prot; + int flags; + int fd; + off_t pos; +}; + smmap(p, uap, retval) struct proc *p; - register struct args { - caddr_t addr; - int len; - int prot; - int flags; - int fd; - off_t pos; - } *uap; + register struct smmap_args *uap; int *retval; { register struct filedesc *fdp = p->p_fd; @@ -121,19 +128,21 @@ smmap(p, uap, retval) vm_offset_t addr; vm_size_t size; vm_prot_t prot; + vm_prot_t maxprot; caddr_t handle; int mtype, error; + int flags = uap->flags; #ifdef DEBUG if (mmapdebug & MDB_FOLLOW) printf("mmap(%d): addr %x len %x pro %x flg %x fd %d pos %x\n", p->p_pid, uap->addr, uap->len, uap->prot, - uap->flags, uap->fd, uap->pos); + flags, uap->fd, uap->pos); #endif /* * Make sure one of the sharing types is specified */ - mtype = uap->flags & MAP_TYPE; + mtype = flags & MAP_TYPE; switch (mtype) { case MAP_FILE: case MAP_ANON: @@ -146,9 +155,11 @@ smmap(p, uap, retval) * Size is implicitly rounded to a page boundary. */ addr = (vm_offset_t) uap->addr; - if ((uap->flags & MAP_FIXED) && (addr & page_mask) || uap->len < 0) + if ((flags & MAP_FIXED) && (addr & page_mask) || uap->len < 0) return(EINVAL); size = (vm_size_t) round_page(uap->len); + if ((flags & MAP_FIXED) && (addr + size > VM_MAXUSER_ADDRESS)) + return EINVAL; /* * XXX if no hint provided for a non-fixed mapping place it after * the end of the largest possible heap. @@ -156,7 +167,7 @@ smmap(p, uap, retval) * There should really be a pmap call to determine a reasonable * location. */ - if (addr == 0 && (uap->flags & MAP_FIXED) == 0) + if (addr == 0 && (flags & MAP_FIXED) == 0) addr = round_page(p->p_vmspace->vm_daddr + MAXDSIZ); /* * Mapping file or named anonymous, get fp for validation @@ -182,19 +193,34 @@ smmap(p, uap, retval) /* * Ensure that file protection and desired protection * are compatible. Note that we only worry about writability - * if mapping is shared. + * if mapping is shared. XXX (cgd) -- coalese access checks + * and permissions setting. */ if ((uap->prot & PROT_READ) && (fp->f_flag & FREAD) == 0 || - ((uap->flags & MAP_SHARED) && + ((flags & MAP_SHARED) && (uap->prot & PROT_WRITE) && (fp->f_flag & FWRITE) == 0)) return(EACCES); handle = (caddr_t)vp; - } else if (uap->fd != -1) + /* + * Map maximum protections to MACH style + */ + maxprot = VM_PROT_EXECUTE; /* ??? */ + if (fp->f_flag & FREAD) + maxprot |= VM_PROT_READ; + if(uap->flags & MAP_SHARED) { + if (fp->f_flag & FWRITE) + maxprot |= VM_PROT_WRITE; + } else + maxprot |= VM_PROT_WRITE; + } else if (uap->fd != -1) { + maxprot = VM_PROT_ALL; handle = (caddr_t)fp; - else + } else { + maxprot = VM_PROT_ALL; handle = NULL; + } /* - * Map protections to MACH style + * Map current protections to MACH style */ prot = VM_PROT_NONE; if (uap->prot & PROT_READ) @@ -204,19 +230,21 @@ smmap(p, uap, retval) if (uap->prot & PROT_EXEC) prot |= VM_PROT_EXECUTE; - error = vm_mmap(&p->p_vmspace->vm_map, &addr, size, prot, - uap->flags, handle, (vm_offset_t)uap->pos); + error = vm_mmap(&p->p_vmspace->vm_map, &addr, size, prot, maxprot, + flags, handle, (vm_offset_t)uap->pos); if (error == 0) *retval = (int) addr; return(error); } +struct msync_args { + caddr_t addr; + int len; +}; + msync(p, uap, retval) struct proc *p; - struct args { - caddr_t addr; - int len; - } *uap; + struct msync_args *uap; int *retval; { vm_offset_t addr, objoff, oaddr; @@ -283,12 +311,14 @@ msync(p, uap, retval) return(0); } +struct munmap_args { + caddr_t addr; + int len; +}; + munmap(p, uap, retval) register struct proc *p; - register struct args { - caddr_t addr; - int len; - } *uap; + register struct munmap_args *uap; int *retval; { vm_offset_t addr; @@ -306,6 +336,8 @@ munmap(p, uap, retval) size = (vm_size_t) round_page(uap->len); if (size == 0) return(0); + if (addr + size >= VM_MAXUSER_ADDRESS) + return EINVAL; if (!vm_map_is_allocated(&p->p_vmspace->vm_map, addr, addr+size, FALSE)) return(EINVAL); @@ -314,26 +346,29 @@ munmap(p, uap, retval) return(0); } -munmapfd(fd) +munmapfd(p, fd) + register struct proc *p; { #ifdef DEBUG if (mmapdebug & MDB_FOLLOW) - printf("munmapfd(%d): fd %d\n", curproc->p_pid, fd); + printf("munmapfd(%d): fd %d\n", p->p_pid, fd); #endif /* * XXX -- should vm_deallocate any regions mapped to this file */ - curproc->p_fd->fd_ofileflags[fd] &= ~UF_MAPPED; + p->p_fd->fd_ofileflags[fd] &= ~UF_MAPPED; } +struct mprotect_args { + caddr_t addr; + int len; + int prot; +}; + mprotect(p, uap, retval) struct proc *p; - struct args { - caddr_t addr; - int len; - int prot; - } *uap; + struct mprotect_args *uap; int *retval; { vm_offset_t addr; @@ -371,14 +406,16 @@ mprotect(p, uap, retval) return (EINVAL); } +struct madvise_args { + caddr_t addr; + int len; + int behav; +}; + /* ARGSUSED */ madvise(p, uap, retval) struct proc *p; - struct args { - caddr_t addr; - int len; - int behav; - } *uap; + struct madvise_args *uap; int *retval; { @@ -386,14 +423,16 @@ madvise(p, uap, retval) return (EOPNOTSUPP); } +struct mincore_args { + caddr_t addr; + int len; + char *vec; +}; + /* ARGSUSED */ mincore(p, uap, retval) struct proc *p; - struct args { - caddr_t addr; - int len; - char *vec; - } *uap; + struct mincore_args *uap; int *retval; { @@ -408,11 +447,12 @@ mincore(p, uap, retval) * MAP_FILE: a vnode pointer * MAP_ANON: NULL or a file pointer */ -vm_mmap(map, addr, size, prot, flags, handle, foff) +vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff) register vm_map_t map; register vm_offset_t *addr; register vm_size_t size; vm_prot_t prot; + vm_prot_t maxprot; register int flags; caddr_t handle; /* XXX should be vp */ vm_offset_t foff; @@ -473,6 +513,13 @@ vm_mmap(map, addr, size, prot, flags, ha goto out; } /* + * The object of unnamed anonymous regions was just created + * find it for pager_cache. + */ + if (handle == NULL) + object = vm_object_lookup(pager); + + /* * Don't cache anonymous objects. * Loses the reference gained by vm_pager_allocate. */ @@ -621,16 +668,23 @@ vm_mmap(map, addr, size, prot, flags, ha /* * Correct protection (default is VM_PROT_ALL). * Note that we set the maximum protection. This may not be - * entirely correct. Maybe the maximum protection should be based - * on the object permissions where it makes sense (e.g. a vnode). - * - * Changed my mind: leave max prot at VM_PROT_ALL. + * entirely correct. The maximum protection is be based on + * the object permissions where it makes sense (e.g. a vnode). */ - if (prot != VM_PROT_ALL) { rv = vm_map_protect(map, *addr, *addr+size, prot, FALSE); if (rv != KERN_SUCCESS) { (void) vm_deallocate(map, *addr, size); goto out; + } + /* + * We only need to set max_protection in case it's + * unequal to its default, which is VM_PROT_DEFAULT. + */ + if(maxprot != VM_PROT_DEFAULT) { + rv = vm_map_protect(map, *addr, *addr+size, maxprot, TRUE); + if (rv != KERN_SUCCESS) { + (void) vm_deallocate(map, *addr, size); + goto out; } } /*