Annotation of XNU/bsd/vm/vm_unix.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /* 
                     23:  * Mach Operating System
                     24:  * Copyright (c) 1987 Carnegie-Mellon University
                     25:  * All rights reserved.  The CMU software License Agreement specifies
                     26:  * the terms and conditions for use and redistribution.
                     27:  */
                     28: 
                     29: /*
                     30:  */
                     31: #include <mach_nbc.h>
                     32: #include <meta_features.h>
                     33: 
                     34: #include <kern/task.h>
                     35: #include <kern/thread.h>
                     36: #include <mach/time_value.h>
                     37: #include <mach/vm_param.h>
                     38: #include <mach/vm_prot.h>
                     39: #include <mach/port.h>
                     40: 
                     41: #include <sys/param.h>
                     42: #include <sys/systm.h>
                     43: #include <sys/dir.h>
                     44: #include <sys/namei.h>
                     45: #include <sys/proc.h>
                     46: #include <sys/vm.h>
                     47: #include <sys/file.h>
                     48: #include <sys/vnode.h>
                     49: #include <sys/buf.h>
                     50: #include <sys/mount.h>
                     51: #include <sys/trace.h>
                     52: #include <sys/kernel.h>
                     53: 
                     54: #include <kern/kalloc.h>
                     55: #include <kern/parallel.h>
                     56: #include <kern/mapfs.h>
                     57: #include <vm/vm_map.h>
                     58: #include <vm/vm_kern.h>
                     59: 
                     60: #include <machine/spl.h>
                     61: #include <mach/shared_memory_server.h>
                     62: 
                     63: useracc(addr, len, prot)
                     64:        caddr_t addr;
                     65:        u_int   len;
                     66:        int     prot;
                     67: {
                     68:        return (vm_map_check_protection(
                     69:                        current_map(),
                     70:                        trunc_page(addr), round_page(addr+len),
                     71:                        prot == B_READ ? VM_PROT_READ : VM_PROT_WRITE));
                     72: }
                     73: 
                     74: vslock(addr, len)
                     75:        caddr_t addr;
                     76:        int     len;
                     77: {
                     78:        vm_map_wire(current_map(), trunc_page(addr),
                     79:                        round_page(addr+len), 
                     80:                        VM_PROT_READ | VM_PROT_WRITE ,FALSE);
                     81: }
                     82: 
                     83: vsunlock(addr, len, dirtied)
                     84:        caddr_t addr;
                     85:        int     len;
                     86:        int dirtied;
                     87: {
                     88:        pmap_t          pmap;
                     89: #if FIXME  /* [ */
                     90:        vm_page_t       pg;
                     91: #endif  /* FIXME ] */
                     92:        vm_offset_t     vaddr, paddr;
                     93: 
                     94: #if FIXME  /* [ */
                     95:        if (dirtied) {
                     96:                pmap = get_task_pmap(current_task());
                     97:                for (vaddr = trunc_page(addr); vaddr < round_page(addr+len);
                     98:                                vaddr += PAGE_SIZE) {
                     99:                        paddr = pmap_extract(pmap, vaddr);
                    100:                        pg = PHYS_TO_VM_PAGE(paddr);
                    101:                        vm_page_set_modified(pg);
                    102:                }
                    103:        }
                    104: #endif  /* FIXME ] */
                    105: #ifdef lint
                    106:        dirtied++;
                    107: #endif /* lint */
                    108:        vm_map_unwire(current_map(), trunc_page(addr),
                    109:                                round_page(addr+len), FALSE);
                    110: }
                    111: 
                    112: #if    defined(sun) || BALANCE || defined(m88k)
                    113: #else  /*defined(sun) || BALANCE || defined(m88k)*/
                    114: subyte(addr, byte)
                    115:        void * addr;
                    116:        int byte;
                    117: {
                    118:        char character;
                    119:        
                    120:        character = (char)byte;
                    121:        return (copyout((void *)&(character), addr, sizeof(char)) == 0 ? 0 : -1);
                    122: }
                    123: 
                    124: suibyte(addr, byte)
                    125:        void * addr;
                    126:        int byte;
                    127: {
                    128:        char character;
                    129:        
                    130:        character = (char)byte;
                    131:        return (copyout((void *) &(character), addr, sizeof(char)) == 0 ? 0 : -1);
                    132: }
                    133: 
                    134: int fubyte(addr)
                    135:        void * addr;
                    136: {
                    137:        unsigned char byte;
                    138: 
                    139:        if (copyin(addr, (void *) &byte, sizeof(char)))
                    140:                return(-1);
                    141:        return(byte);
                    142: }
                    143: 
                    144: int fuibyte(addr)
                    145:        void * addr;
                    146: {
                    147:        unsigned char byte;
                    148: 
                    149:        if (copyin(addr, (void *) &(byte), sizeof(char)))
                    150:                return(-1);
                    151:        return(byte);
                    152: }
                    153: 
                    154: suword(addr, word)
                    155:        void * addr;
                    156:        long word;
                    157: {
                    158:        return (copyout((void *) &word, addr, sizeof(int)) == 0 ? 0 : -1);
                    159: }
                    160: 
                    161: long fuword(addr)
                    162:        void * addr;
                    163: {
                    164:        long word;
                    165: 
                    166:        if (copyin(addr, (void *) &word, sizeof(int)))
                    167:                return(-1);
                    168:        return(word);
                    169: }
                    170: 
                    171: /* suiword and fuiword are the same as suword and fuword, respectively */
                    172: 
                    173: suiword(addr, word)
                    174:        void * addr;
                    175:        long word;
                    176: {
                    177:        return (copyout((void *) &word, addr, sizeof(int)) == 0 ? 0 : -1);
                    178: }
                    179: 
                    180: long fuiword(addr)
                    181:        void * addr;
                    182: {
                    183:        long word;
                    184: 
                    185:        if (copyin(addr, (void *) &word, sizeof(int)))
                    186:                return(-1);
                    187:        return(word);
                    188: }
                    189: #endif /* defined(sun) || BALANCE || defined(m88k) || defined(i386) */
                    190: 
                    191: int
                    192: swapon()
                    193: {
                    194:        return(EOPNOTSUPP);
                    195: }
                    196: 
                    197: thread_t procdup(
                    198:        struct proc             *child,
                    199:        struct proc             *parent)
                    200: {
                    201:        thread_t                thread;
                    202:        task_t                  task;
                    203:        kern_return_t   result;
                    204: 
                    205:        if (parent->task == kernel_task)
                    206:                result = task_create_local(TASK_NULL, FALSE, FALSE, &task);
                    207:        else
                    208:                result = task_create_local(parent->task, TRUE, FALSE, &task);
                    209:        if (result != KERN_SUCCESS)
                    210:            printf("fork/procdup: task_create failed. Code: 0x%x\n", result);
                    211:        child->task = task;
                    212:        /* task->proc = child; */
                    213:        set_bsdtask_info(task, child);
                    214: 
                    215:        task_deallocate(task); // extra ref for convert_task_to_port()
                    216: 
                    217:        result = thread_create(task, &thread);
                    218:        if (result != KERN_SUCCESS)
                    219:            printf("fork/procdup: thread_create failed. Code: 0x%x\n", result);
                    220:        act_deallocate(thread); 
                    221: 
                    222: #if FIXME /* [ */
                    223:        thread_deallocate(thread); // extra ref
                    224: 
                    225:        /*
                    226:         *      Don't need to lock thread here because it can't
                    227:         *      possibly execute and no one else knows about it.
                    228:         */
                    229:        /* compute_priority(thread, FALSE); */
                    230: #endif /* ] */
                    231:        return(thread);
                    232: }
                    233: 
                    234: kern_return_t  pid_for_task(t, x)
                    235:        mach_port_t     t;
                    236:        int     *x;
                    237: {
                    238:        struct proc * p;
                    239:        task_t          t1;
                    240:        extern task_t port_name_to_task(mach_port_t t);
                    241:        int     pid = -1;
                    242:        kern_return_t   err;
                    243: 
                    244:        t1 = port_name_to_task(t);
                    245: 
                    246:        if (t1 == TASK_NULL) {
                    247:                err = KERN_FAILURE;
                    248:        } else {
                    249:                p = get_bsdtask_info(t1);
                    250:                if (p) {
                    251:                        pid  = p->p_pid;
                    252:                        err = KERN_SUCCESS;
                    253:                } else {
                    254:                        err = KERN_FAILURE;
                    255:                }
                    256:        }
                    257:        task_deallocate(t1);
                    258:        (void) copyout((char *) &pid, (char *) x, sizeof(*x));
                    259:        return err;
                    260: }
                    261: 
                    262: /*
                    263:  *     Routine:        task_by_unix_pid
                    264:  *     Purpose:
                    265:  *             Get the task port for another "process", named by its
                    266:  *             process ID on the same host as "target_task".
                    267:  *
                    268:  *             Only permitted to privileged processes, or processes
                    269:  *             with the same user ID.
                    270:  */
                    271: kern_return_t  task_for_pid(target_tport, pid, t)
                    272:        mach_port_t     target_tport;
                    273:        int             pid;
                    274:        mach_port_t     *t;
                    275: {
                    276:        struct proc     *p;
                    277:        struct proc *p1;
                    278:        task_t          t1;
                    279:        mach_port_t     tret;
                    280:        extern task_t port_name_to_task(mach_port_t tp);
                    281:        void * sright;
                    282: 
                    283:        unix_master();
                    284:        t1 = port_name_to_task(target_tport);
                    285:        if (t1 == TASK_NULL) {
                    286:                *t = TASK_NULL;
                    287:                unix_release();
                    288:                return (KERN_FAILURE);
                    289:        } 
                    290: 
                    291:        p1 = get_bsdtask_info(t1);
                    292:        if (
                    293:                ((p = pfind(pid)) != (struct proc *) 0)
                    294:                && (p1 != (struct proc *) 0)
                    295:                && ((p->p_ucred->cr_uid == p1->p_ucred->cr_uid)
                    296:                || !(suser(p1->p_ucred, &p1->p_acflag)))
                    297:                && (p->p_stat != SZOMB)
                    298:                ) {
                    299:                        task_deallocate(t1);
                    300:                        if (p->task != TASK_NULL) {
                    301:                                task_reference(p->task);
                    302: #if 0
                    303:                                sright = retrieve_task_self_fast(p->task);
                    304: #else
                    305:                                sright = convert_task_to_port(p->task);
                    306: #endif
                    307:                                tret = ipc_port_copyout_send(sright, get_task_ipcspace(current_task()));
                    308:                        } else
                    309:                                tret  = MACH_PORT_NULL;
                    310:                        (void ) copyout((char *)&tret, (char *) t, sizeof(mach_port_t));
                    311:                        /* compatibility with NeXT 2.0 debuggers, launchers */
                    312:                        if (suser(p->p_ucred, &p->p_acflag)) {
                    313:                                /* don't set it for anyone; could exec a careless nameserver */
                    314:                        struct proc *p=get_bsdtask_info(current_task());
                    315: 
                    316:                                if (p)
                    317:                                        p->p_debugger = 1;
                    318:                        }
                    319:                        unix_release();
                    320:                        return(KERN_SUCCESS);
                    321:        }
                    322:         task_deallocate(t1);
                    323:        tret = MACH_PORT_NULL;
                    324:        (void) copyout((char *) &tret, (char *) t, sizeof(mach_port_t));
                    325: 
                    326:        unix_release();
                    327:        return(KERN_FAILURE);
                    328: }
                    329: 
                    330: #if 0
                    331: /*
                    332:  *     Routine:        task_by_pid
                    333:  *     Purpose:
                    334:  *             Trap form of "task_by_unix_pid"; soon to be eliminated.
                    335:  */
                    336: mach_port_t            task_by_pid(pid)
                    337:        int             pid;
                    338: {
                    339:        task_t          self = current_task();
                    340:        port_t          t = PORT_NULL;
                    341:        task_t          result_task;
                    342: 
                    343:        if (task_by_unix_pid(self, pid, &result_task) == KERN_SUCCESS) {
                    344:                t = convert_task_to_port(result_task);
                    345:                if (t != PORT_NULL)
                    346:                        object_copyout(self, t, MSG_TYPE_PORT, &t);
                    347:        }
                    348: 
                    349:        return(t);
                    350: }
                    351: #endif /* 0 */
                    352: 
                    353: 
                    354: 
                    355: 
                    356: int
                    357: load_shared_file(
                    358:        caddr_t         mapped_file_addr,
                    359:        u_long          mapped_file_size,
                    360:         caddr_t                *base_address,
                    361:         int             map_cnt,
                    362:         sf_mapping_t       *mappings,
                    363:         char            *filename,
                    364:         int             *flags)
                    365: {
                    366:        struct vnode            *vp = 0; 
                    367:        struct nameidata        nd, *ndp;
                    368:        struct proc             *p =  current_proc();
                    369:        register int            error;
                    370:        kern_return_t           kr;
                    371: 
                    372:        struct vattr    vattr;
                    373:        void            *pager_cport;
                    374:        void            *object;
                    375:        void            *file_object;
                    376:         sf_mapping_t    *map_list;
                    377:         caddr_t                local_base;
                    378:        int             local_flags;
                    379:        kern_return_t   kret;
                    380: 
                    381:        ndp = &nd;
                    382: 
                    383: 
                    384: 
                    385:        unix_master();
                    386: 
                    387:        /* Retrieve the base address */
                    388:        if (copyin(base_address, &local_base, sizeof (caddr_t))) {
                    389:                        error = EINVAL;
                    390:                        goto lsf_bailout;
                    391:         }
                    392:        if (copyin(flags, &local_flags, sizeof (int))) {
                    393:                        error = EINVAL;
                    394:                        goto lsf_bailout;
                    395:         }
                    396:        kret = kmem_alloc(kernel_map, &map_list,
                    397:                        (vm_size_t)(map_cnt*sizeof(sf_mapping_t)));
                    398:        if (kret != KERN_SUCCESS) {
                    399:                        error = ENOMEM;
                    400:                        goto lsf_bailout;
                    401:        }
                    402: 
                    403:        if (copyin(mappings, map_list, (map_cnt*sizeof(sf_mapping_t)))) {
                    404:                        kmem_free(kernel_map, map_list, 
                    405:                                (vm_size_t)(map_cnt*sizeof(sf_mapping_t)));
                    406:                        error = EINVAL;
                    407:                        goto lsf_bailout;
                    408:        }
                    409: 
                    410:        /*
                    411:         * Get a vnode for the target file
                    412:         */
                    413:        NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE,
                    414:            filename, p);
                    415: 
                    416:        if ((error = namei(ndp))) {
                    417:                error = EINVAL;
                    418:                kmem_free(kernel_map, map_list, 
                    419:                                (vm_size_t)(map_cnt*sizeof(sf_mapping_t)));
                    420:                goto lsf_bailout;
                    421:        }
                    422: 
                    423:        vp = ndp->ni_vp;
                    424: 
                    425:        if (vp->v_type != VREG) {
                    426:                error = EINVAL;
                    427:                kmem_free(kernel_map, map_list, 
                    428:                                (vm_size_t)(map_cnt*sizeof(sf_mapping_t)));
                    429:                VOP_UNLOCK(vp, 0, p);
                    430:                goto lsf_bailout;
                    431:        }
                    432: 
                    433:        if (!vp->v_vm_info) {
                    434:                vm_info_init(vp);
                    435:        }
                    436: 
                    437:        if (error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) {
                    438:                VOP_UNLOCK(vp, 0, p);
                    439:                kmem_free(kernel_map, map_list, 
                    440:                                (vm_size_t)(map_cnt*sizeof(sf_mapping_t)));
                    441:                goto lsf_bailout;
                    442:        }
                    443: 
                    444: 
                    445:        if(pager_cport = (void *)vnode_pager_lookup(vp, vp->v_vm_info->pager)) {
                    446:                if(file_object = (void *)vm_object_lookup(pager_cport)) {
                    447:                        error = 0;
                    448:                } else {
                    449:                        VOP_UNLOCK(vp, 0, p);
                    450:                        kmem_free(kernel_map, map_list, 
                    451:                                (vm_size_t)(map_cnt*sizeof(sf_mapping_t)));
                    452:                        error = EINVAL;
                    453:                        goto lsf_bailout;
                    454:                }
                    455:        } else {
                    456:                VOP_UNLOCK(vp, 0, p);
                    457:                error = EINVAL;
                    458:                goto lsf_bailout;
                    459:        }
                    460: 
                    461:        vp->v_vm_info->vnode_size = vattr.va_size;
                    462: 
                    463:        if(vattr.va_size != mapped_file_size) {
                    464:                VOP_UNLOCK(vp, 0, p);
                    465:                kmem_free(kernel_map, map_list, 
                    466:                                (vm_size_t)(map_cnt*sizeof(sf_mapping_t)));
                    467:                error = EINVAL;
                    468:                goto lsf_bailout;
                    469:        }
                    470: 
                    471:        VREF(vp);
                    472:        if(copyin_shared_file(mapped_file_addr, mapped_file_size, &local_base,
                    473:                        map_cnt, map_list, file_object, &local_flags)) {
                    474:                vrele(vp);
                    475:                error = EINVAL;
                    476:        } else {
                    477:                copyout(&local_flags, flags, sizeof (int));
                    478:                copyout(&local_base, base_address, sizeof (caddr_t));
                    479:                if (local_flags & SF_PREV_LOADED) {
                    480:                        vrele(vp);
                    481:                }
                    482:        }
                    483:        kmem_free(kernel_map, map_list, 
                    484:                                (vm_size_t)(map_cnt*sizeof(sf_mapping_t)));
                    485:        VOP_UNLOCK(vp, 0, p);
                    486: 
                    487: lsf_bailout:
                    488:        /* deallocate any remaining remnants of mapped file sent by caller */
                    489:        vm_deallocate(current_map(), mapped_file_addr, mapped_file_size);
                    490:        unix_release();
                    491:        return error;
                    492: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.