[BACK]Return to uvm_unix.c CVS log [TXT][DIR] Up to [local] / sys / uvm

Annotation of sys/uvm/uvm_unix.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: uvm_unix.c,v 1.28 2007/04/11 12:51:51 miod Exp $      */
                      2: /*     $NetBSD: uvm_unix.c,v 1.18 2000/09/13 15:00:25 thorpej Exp $    */
                      3:
                      4: /*
                      5:  * Copyright (c) 1997 Charles D. Cranor and Washington University.
                      6:  * Copyright (c) 1991, 1993 The Regents of the University of California.
                      7:  * Copyright (c) 1988 University of Utah.
                      8:  *
                      9:  * All rights reserved.
                     10:  *
                     11:  * This code is derived from software contributed to Berkeley by
                     12:  * the Systems Programming Group of the University of Utah Computer
                     13:  * Science Department.
                     14:  *
                     15:  * Redistribution and use in source and binary forms, with or without
                     16:  * modification, are permitted provided that the following conditions
                     17:  * are met:
                     18:  * 1. Redistributions of source code must retain the above copyright
                     19:  *    notice, this list of conditions and the following disclaimer.
                     20:  * 2. Redistributions in binary form must reproduce the above copyright
                     21:  *    notice, this list of conditions and the following disclaimer in the
                     22:  *    documentation and/or other materials provided with the distribution.
                     23:  * 3. All advertising materials mentioning features or use of this software
                     24:  *    must display the following acknowledgement:
                     25:  *      This product includes software developed by Charles D. Cranor,
                     26:  *     Washington University, the University of California, Berkeley and
                     27:  *     its contributors.
                     28:  * 4. Neither the name of the University nor the names of its contributors
                     29:  *    may be used to endorse or promote products derived from this software
                     30:  *    without specific prior written permission.
                     31:  *
                     32:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     33:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     34:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     35:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     36:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     37:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     38:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     39:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     40:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     41:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     42:  * SUCH DAMAGE.
                     43:  *
                     44:  * from: Utah $Hdr: vm_unix.c 1.1 89/11/07$
                     45:  *      @(#)vm_unix.c   8.1 (Berkeley) 6/11/93
                     46:  * from: Id: uvm_unix.c,v 1.1.2.2 1997/08/25 18:52:30 chuck Exp
                     47:  */
                     48:
                     49: /*
                     50:  * uvm_unix.c: traditional sbrk/grow interface to vm.
                     51:  */
                     52:
                     53: #include <sys/param.h>
                     54: #include <sys/systm.h>
                     55: #include <sys/proc.h>
                     56: #include <sys/resourcevar.h>
                     57: #include <sys/vnode.h>
                     58: #include <sys/core.h>
                     59:
                     60: #include <sys/mount.h>
                     61: #include <sys/syscallargs.h>
                     62:
                     63: #include <uvm/uvm.h>
                     64:
                     65: /*
                     66:  * sys_obreak: set break
                     67:  */
                     68:
                     69: int
                     70: sys_obreak(p, v, retval)
                     71:        struct proc *p;
                     72:        void *v;
                     73:        register_t *retval;
                     74: {
                     75:        struct sys_obreak_args /* {
                     76:                syscallarg(char *) nsize;
                     77:        } */ *uap = v;
                     78:        struct vmspace *vm = p->p_vmspace;
                     79:        vaddr_t new, old;
                     80:        int error;
                     81:
                     82:        old = (vaddr_t)vm->vm_daddr;
                     83:        new = round_page((vaddr_t)SCARG(uap, nsize));
                     84:        if ((new - old) > p->p_rlimit[RLIMIT_DATA].rlim_cur)
                     85:                return (ENOMEM);
                     86:
                     87:        old = round_page(old + ptoa(vm->vm_dsize));
                     88:
                     89:        if (new == old)
                     90:                return (0);
                     91:
                     92:        /*
                     93:         * grow or shrink?
                     94:         */
                     95:        if (new > old) {
                     96:                error = uvm_map(&vm->vm_map, &old, new - old, NULL,
                     97:                    UVM_UNKNOWN_OFFSET, 0,
                     98:                    UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RWX, UVM_INH_COPY,
                     99:                    UVM_ADV_NORMAL, UVM_FLAG_AMAPPAD|UVM_FLAG_FIXED|
                    100:                    UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW));
                    101:                if (error) {
                    102:                        uprintf("sbrk: grow %ld failed, error = %d\n",
                    103:                            new - old, error);
                    104:                        return (ENOMEM);
                    105:                }
                    106:                vm->vm_dsize += atop(new - old);
                    107:        } else {
                    108:                uvm_deallocate(&vm->vm_map, new, old - new);
                    109:                vm->vm_dsize -= atop(old - new);
                    110:        }
                    111:
                    112:        return (0);
                    113: }
                    114:
                    115: /*
                    116:  * uvm_grow: enlarge the "stack segment" to include sp.
                    117:  */
                    118:
                    119: void
                    120: uvm_grow(p, sp)
                    121:        struct proc *p;
                    122:        vaddr_t sp;
                    123: {
                    124:        struct vmspace *vm = p->p_vmspace;
                    125:        int si;
                    126:
                    127:        /*
                    128:         * For user defined stacks (from sendsig).
                    129:         */
                    130:        if (sp < (vaddr_t)vm->vm_maxsaddr)
                    131:                return;
                    132:
                    133:        /*
                    134:         * For common case of already allocated (from trap).
                    135:         */
                    136: #ifdef MACHINE_STACK_GROWS_UP
                    137:        if (sp < USRSTACK + ctob(vm->vm_ssize))
                    138: #else
                    139:        if (sp >= USRSTACK - ctob(vm->vm_ssize))
                    140: #endif
                    141:                return;
                    142:
                    143:        /*
                    144:         * Really need to check vs limit and increment stack size if ok.
                    145:         */
                    146: #ifdef MACHINE_STACK_GROWS_UP
                    147:        si = btoc(sp - USRSTACK) - vm->vm_ssize;
                    148: #else
                    149:        si = btoc(USRSTACK - sp) - vm->vm_ssize;
                    150: #endif
                    151:        if (vm->vm_ssize + si <= btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur))
                    152:                vm->vm_ssize += si;
                    153: }
                    154:
                    155: /*
                    156:  * sys_oadvise: old advice system call
                    157:  */
                    158:
                    159: /* ARGSUSED */
                    160: int
                    161: sys_ovadvise(p, v, retval)
                    162:        struct proc *p;
                    163:        void *v;
                    164:        register_t *retval;
                    165: {
                    166: #if 0
                    167:        struct sys_ovadvise_args /* {
                    168:                syscallarg(int) anom;
                    169:        } */ *uap = v;
                    170: #endif
                    171:
                    172:        return (EINVAL);
                    173: }
                    174:
                    175: /*
                    176:  * uvm_coredump: dump core!
                    177:  */
                    178:
                    179: int
                    180: uvm_coredump(p, vp, cred, chdr)
                    181:        struct proc *p;
                    182:        struct vnode *vp;
                    183:        struct ucred *cred;
                    184:        struct core *chdr;
                    185: {
                    186:        struct vmspace *vm = p->p_vmspace;
                    187:        vm_map_t map = &vm->vm_map;
                    188:        vm_map_entry_t entry;
                    189:        vaddr_t start, end;
                    190:        struct coreseg cseg;
                    191:        off_t offset;
                    192:        int flag, error = 0;
                    193:
                    194:        offset = chdr->c_hdrsize + chdr->c_seghdrsize + chdr->c_cpusize;
                    195:
                    196:        for (entry = map->header.next; entry != &map->header;
                    197:            entry = entry->next) {
                    198:
                    199:                /* should never happen for a user process */
                    200:                if (UVM_ET_ISSUBMAP(entry)) {
                    201:                        panic("uvm_coredump: user process with submap?");
                    202:                }
                    203:
                    204:                if (!(entry->protection & VM_PROT_WRITE))
                    205:                        continue;
                    206:
                    207:                /*
                    208:                 * Don't dump mmaped devices.
                    209:                 */
                    210:                if (entry->object.uvm_obj != NULL &&
                    211:                    UVM_OBJ_IS_DEVICE(entry->object.uvm_obj))
                    212:                        continue;
                    213:
                    214:                start = entry->start;
                    215:                end = entry->end;
                    216:
                    217:                if (start >= VM_MAXUSER_ADDRESS)
                    218:                        continue;
                    219:
                    220:                if (end > VM_MAXUSER_ADDRESS)
                    221:                        end = VM_MAXUSER_ADDRESS;
                    222:
                    223: #ifdef MACHINE_STACK_GROWS_UP
                    224:                if (USRSTACK <= start && start < (USRSTACK + MAXSSIZ)) {
                    225:                        end = round_page(USRSTACK + ctob(vm->vm_ssize));
                    226:                        if (start >= end)
                    227:                                continue;
                    228:                        start = USRSTACK;
                    229: #else
                    230:                if (start >= (vaddr_t)vm->vm_maxsaddr) {
                    231:                        start = trunc_page(USRSTACK - ctob(vm->vm_ssize));
                    232:
                    233:                        if (start >= end)
                    234:                                continue;
                    235: #endif
                    236:                        flag = CORE_STACK;
                    237:                } else
                    238:                        flag = CORE_DATA;
                    239:
                    240:                /*
                    241:                 * Set up a new core file segment.
                    242:                 */
                    243:                CORE_SETMAGIC(cseg, CORESEGMAGIC, CORE_GETMID(*chdr), flag);
                    244:                cseg.c_addr = start;
                    245:                cseg.c_size = end - start;
                    246:
                    247:                error = vn_rdwr(UIO_WRITE, vp,
                    248:                    (caddr_t)&cseg, chdr->c_seghdrsize,
                    249:                    offset, UIO_SYSSPACE,
                    250:                    IO_NODELOCKED|IO_UNIT, cred, NULL, p);
                    251:                /*
                    252:                 * We might get an EFAULT on objects mapped beyond
                    253:                 * EOF. Ignore the error.
                    254:                 */
                    255:                if (error && error != EFAULT)
                    256:                        break;
                    257:
                    258:                offset += chdr->c_seghdrsize;
                    259:                error = vn_rdwr(UIO_WRITE, vp,
                    260:                    (caddr_t)(u_long)cseg.c_addr, (int)cseg.c_size,
                    261:                    offset, UIO_USERSPACE,
                    262:                    IO_NODELOCKED|IO_UNIT, cred, NULL, p);
                    263:                if (error)
                    264:                        break;
                    265:
                    266:                offset += cseg.c_size;
                    267:                chdr->c_nseg++;
                    268:        }
                    269:
                    270:        return (error);
                    271: }
                    272:

CVSweb