root/uvm/uvm_unix.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sys_obreak
  2. uvm_grow
  3. sys_ovadvise
  4. uvm_coredump

    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 

/* [<][>][^][v][top][bottom][index][help] */