The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/norma/kern_task.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* 
    2  * Mach Operating System
    3  * Copyright (c) 1991 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie Mellon
   24  * the rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        kern_task.c,v $
   29  * Revision 2.9  92/03/10  16:28:44  jsb
   30  *      Check for null parent task in task_create.
   31  *      [92/03/10  13:46:21  jsb]
   32  * 
   33  *      Merged in norma branch changes as of NORMA_MK7.
   34  *      [92/03/09  12:50:50  jsb]
   35  * 
   36  * Revision 2.7.2.4  92/03/04  16:07:16  jeffreyh
   37  *      Converted to use out-of-line forms of task_{get,set}_emulation_vector.
   38  *      [92/03/04  14:55:51  jsb]
   39  * 
   40  * Revision 2.7.2.3  92/02/21  11:25:15  jsb
   41  *      Release send right to memory_object after mapping it in remote task
   42  *      in task_copy_vm.
   43  *      [92/02/20  10:29:45  jsb]
   44  * 
   45  *      Set copy flag TRUE in r_vm_map call in task_copy_vm.
   46  *      This is now practical due to smarter copy strategy management
   47  *      in xmm_svm (compared to when it always used MEMORY_OBJECT_COPY_NONE).
   48  *      It also keeps xmm_copy from having to deal with data writes without
   49  *      having to use an xmm_shadow layer.
   50  *      [92/02/11  11:39:23  jsb]
   51  * 
   52  *      Release map reference in task_copy_vm.
   53  *      [92/01/22  10:29:57  jsb]
   54  * 
   55  * Revision 2.7.2.2  92/01/09  18:46:08  jsb
   56  *      Added logic in task_create to alternate task creation between local
   57  *      node and a patchable remote node. For testing purposes only.
   58  *      [92/01/08  16:41:27  jsb]
   59  * 
   60  *      Use varargs for debugging printfs.
   61  *      [92/01/08  10:22:12  jsb]
   62  * 
   63  *      Use remote_host() instead of norma_get_special_port().
   64  *      [92/01/04  18:17:46  jsb]
   65  * 
   66  * Revision 2.7.2.1  92/01/03  16:38:29  jsb
   67  *      Removed unused routine ipc_task_reinit.
   68  *      [91/12/28  17:59:18  jsb]
   69  * 
   70  * Revision 2.7  91/12/13  13:53:22  jsb
   71  *      Changed name of task_create_remote to norma_task_create.
   72  *      Added check for local case in norma_task_create.
   73  * 
   74  * Revision 2.6  91/12/10  13:26:19  jsb
   75  *      Changed printfs to frets.
   76  *      [91/12/10  11:34:35  jsb]
   77  * 
   78  * Revision 2.5  91/11/14  16:51:51  rpd
   79  *      Use new child_node task field in place of task_server_node to decide
   80  *      upon what node to create child task. Also add task_set_child_node().
   81  *      [91/09/23  09:22:18  jsb]
   82  * 
   83  * Revision 2.4  91/08/28  11:16:18  jsb
   84  *      Turned off remaining printf.
   85  *      [91/08/26  11:16:11  jsb]
   86  * 
   87  *      Added support for remote task creation with inherited memory.
   88  *      Remove task creation is accessible either via task_create_remote,
   89  *      or task_create with task_server_node patched to some reasonable value.
   90  *      [91/08/15  13:55:54  jsb]
   91  * 
   92  * Revision 2.3  91/06/17  15:48:07  jsb
   93  *      Moved routines here from kern/ipc_tt.c and kern/task.c.
   94  *      [91/06/17  11:01:51  jsb]
   95  * 
   96  * Revision 2.2  91/06/06  17:08:15  jsb
   97  *      First checkin.
   98  *      [91/05/25  11:47:39  jsb]
   99  * 
  100  */
  101 /*
  102  *      File:   norma/kern_task.c
  103  *      Author: Joseph S. Barrera III
  104  *
  105  *      NORMA task support.
  106  */
  107 
  108 #include <norma_task.h>
  109 
  110 #include <mach/machine/vm_types.h>
  111 #include <mach/vm_param.h>
  112 #include <mach/task_info.h>
  113 #include <mach/task_special_ports.h>
  114 #include <ipc/ipc_space.h>
  115 #include <kern/mach_param.h>
  116 #include <kern/task.h>
  117 #include <kern/host.h>
  118 #include <kern/thread.h>
  119 #include <kern/zalloc.h>
  120 #include <kern/kalloc.h>
  121 #include <kern/processor.h>
  122 #include <kern/ipc_tt.h>
  123 #include <sys/varargs.h>
  124 
  125 ipc_port_t norma_task_server;
  126 decl_simple_lock_data(,norma_task_server_lock)
  127 
  128 extern zone_t task_zone;
  129 
  130 /*
  131  * XXX This definition should be elsewhere
  132  */
  133 norma_node_self(host, node)
  134         host_t host;
  135         int *node;
  136 {
  137         *node = node_self();
  138         return KERN_SUCCESS;
  139 }
  140 
  141 #if     NORMA_TASK
  142 
  143 int fff = 1;
  144 int mmm = 0;
  145 int bbb = 0;
  146 extern cnputc();
  147 
  148 fret(fmt, va_alist)
  149         char* fmt;
  150         va_dcl
  151 {
  152         va_list listp;
  153 
  154         if (fff) {
  155                 va_start(listp);
  156                 _doprnt(fmt, &listp, cnputc, 0);
  157                 va_end(listp);
  158         }
  159 }
  160 
  161 mumble(fmt, va_alist)
  162         char* fmt;
  163         va_dcl
  164 {
  165         va_list listp;
  166 
  167         if (mmm) {
  168                 va_start(listp);
  169                 _doprnt(fmt, &listp, cnputc, 0);
  170                 va_end(listp);
  171         }
  172 }
  173 
  174 babble(fmt, va_alist)
  175         char* fmt;
  176         va_dcl
  177 {
  178         va_list listp;
  179 
  180         if (bbb) {
  181                 va_start(listp);
  182                 _doprnt(fmt, &listp, cnputc, 0);
  183                 va_end(listp);
  184         }
  185 }
  186 
  187 int task_create_remote_node = -1;
  188 boolean_t task_create_use_remote = FALSE;
  189 
  190 kern_return_t task_create(parent_task, inherit_memory, child_task)
  191         task_t          parent_task;
  192         boolean_t       inherit_memory;
  193         task_t          *child_task;            /* OUT */
  194 {
  195         if (task_create_remote_node != -1) {
  196                 task_create_use_remote = ! task_create_use_remote;
  197                 if (task_create_use_remote) {
  198                         return norma_task_create(parent_task, inherit_memory,
  199                                                  task_create_remote_node,
  200                                                  child_task);
  201                 } else {
  202                         return task_create_local(parent_task, inherit_memory,
  203                                                  child_task);
  204                 }
  205         }
  206         if (! parent_task || parent_task->child_node == -1) {
  207                 return task_create_local(parent_task, inherit_memory,
  208                                          child_task);
  209         } else {
  210                 return norma_task_create(parent_task, inherit_memory,
  211                                          parent_task->child_node,
  212                                          child_task);
  213         }
  214 }
  215 
  216 kern_return_t task_set_child_node(task, child_node)
  217         task_t  task;
  218         int     child_node;
  219 {
  220         if (task == TASK_NULL) {
  221                 return KERN_INVALID_ARGUMENT;
  222         } else {
  223                 task->child_node = child_node;
  224                 return KERN_SUCCESS;
  225         }
  226 }
  227 
  228 /*
  229  * This allows us to create a task without providing a parent.
  230  */
  231 kern_return_t norma_task_allocate(host, task)
  232         host_t  host;
  233         task_t  *task;          /* OUT */
  234 {
  235         babble("norma_task_allocate: called...\n");
  236         return task_create_local(TASK_NULL, FALSE, task);
  237 }
  238 
  239 kern_return_t
  240 task_get_inherited_ports(task, r0, r1, r2, r3, exception, bootstrap)
  241         task_t task;
  242         ipc_port_t *r0;
  243         ipc_port_t *r1;
  244         ipc_port_t *r2;
  245         ipc_port_t *r3;
  246         ipc_port_t *exception;
  247         ipc_port_t *bootstrap;
  248 {
  249         if (task == TASK_NULL) {
  250                 return KERN_INVALID_ARGUMENT;
  251         }
  252         itk_lock(task);
  253         *r0 = ipc_port_copy_send(task->itk_registered[0]);
  254         *r1 = ipc_port_copy_send(task->itk_registered[1]);
  255         *r2 = ipc_port_copy_send(task->itk_registered[2]);
  256         *r3 = ipc_port_copy_send(task->itk_registered[3]);
  257         *exception = ipc_port_copy_send(task->itk_exception);
  258         *bootstrap = ipc_port_copy_send(task->itk_bootstrap);
  259         itk_unlock(task);
  260         return KERN_SUCCESS;
  261 }
  262 
  263 kern_return_t
  264 task_set_inherited_ports(task, r0, r1, r2, r3, exception, bootstrap)
  265         task_t task;
  266         ipc_port_t r0;
  267         ipc_port_t r1;
  268         ipc_port_t r2;
  269         ipc_port_t r3;
  270         ipc_port_t exception;
  271         ipc_port_t bootstrap;
  272 {
  273         int i;
  274 
  275         if (task == TASK_NULL) {
  276                 return KERN_INVALID_ARGUMENT;
  277         }
  278         itk_lock(task);
  279         for (i = 0; i < 4; i++) {
  280                 if (IP_VALID(task->itk_registered[i])) {
  281                         ipc_port_release_send(task->itk_registered[i]);
  282                 }
  283         }
  284         if (IP_VALID(task->itk_exception)) {
  285                 ipc_port_release_send(task->itk_exception);
  286         }
  287         if (IP_VALID(task->itk_bootstrap)) {
  288                 ipc_port_release_send(task->itk_bootstrap);
  289         }
  290         task->itk_registered[0] = r0;
  291         task->itk_registered[1] = r1;
  292         task->itk_registered[2] = r2;
  293         task->itk_registered[3] = r3;
  294         task->itk_exception = exception;
  295         task->itk_bootstrap = bootstrap;
  296         itk_unlock(task);
  297         return KERN_SUCCESS;
  298 }
  299 
  300 kern_return_t norma_task_create(parent_task, inherit_memory, child_node,
  301                                 child_task)
  302         task_t          parent_task;
  303         boolean_t       inherit_memory;
  304         int             child_node;
  305         task_t          *child_task;            /* OUT */
  306 {
  307         ipc_port_t remote_task;
  308         task_t new_task;
  309         kern_return_t kr;
  310         int vector_start;
  311         unsigned int entry_vector_count;
  312         mach_port_t r0, r1, r2, r3, exception, bootstrap;
  313         emulation_vector_t *entry_vector;
  314 
  315         if (child_node == node_self()) {
  316                 return task_create_local(parent_task, inherit_memory,
  317                                          child_task);
  318         }
  319 
  320         babble("task_create: doing %d -> %d\n", node_self(), child_node);
  321 
  322         kr = r_norma_task_allocate(remote_host(child_node), &remote_task);
  323         if (kr != KERN_SUCCESS) {
  324                 return kr;
  325         }
  326 
  327         kr = task_get_emulation_vector(parent_task, &vector_start,
  328                                        &entry_vector, &entry_vector_count);
  329         if (kr != KERN_SUCCESS) {
  330                 fret("task_get_emulation_vector failed: kr %d %x\n", kr, kr);
  331                 return kr;
  332         }
  333 
  334         kr = r_task_set_emulation_vector(remote_task, vector_start,
  335                                          entry_vector, entry_vector_count);
  336         if (kr != KERN_SUCCESS) {
  337                 fret("task_set_emulation_vector failed: kr %d %x\n", kr, kr);
  338                 return kr;
  339         }
  340 
  341         kr = task_get_inherited_ports(parent_task, &r0, &r1, &r2, &r3,
  342                                       &exception, &bootstrap);
  343         if (kr != KERN_SUCCESS) {
  344                 fret("task_get_inherited_ports failed: kr %d %x\n", kr, kr);
  345                 return kr;
  346         }
  347 
  348         mumble("%x %x %x %x %x %x\n", r0, r1, r2, r3, exception, bootstrap);
  349         kr = r_task_set_inherited_ports(remote_task, r0, r1, r2, r3,
  350                                         exception, bootstrap);
  351         if (kr != KERN_SUCCESS) {
  352                 fret("task_set_inherited_ports failed: kr %d %x\n", kr, kr);
  353                 return kr;
  354         }
  355 
  356         if (inherit_memory) {
  357                 kr = task_copy_vm(parent_task->map, remote_task);
  358                 mumble("task_create: task_copy_vm: (%x)\n", kr);
  359                 if (kr != KERN_SUCCESS) {
  360                         return kr;
  361                 }
  362         }
  363 
  364         /*
  365          * Create a placeholder task for the benefit of convert_task_to_port.
  366          * Set new_task->map to VM_MAP_NULL so that task_deallocate will
  367          * know that this is only a placeholder task.
  368          * XXX decr send-right count?
  369          */
  370         new_task = (task_t) zalloc(task_zone);
  371         if (new_task == TASK_NULL) {
  372                 panic("task_create: no memory for task structure");
  373         }
  374 
  375         /* only one ref, for our caller */
  376         new_task->ref_count = 1;
  377 
  378         new_task->map = VM_MAP_NULL;
  379         new_task->itk_self = remote_task;
  380         simple_lock_init(&new_task->lock);
  381 
  382         babble("task_create: did   %d -> %d\n", node_self(), child_node);
  383 
  384         *child_task = new_task;
  385         return(KERN_SUCCESS);
  386 }
  387 
  388 task_copy_vm(from0, to)
  389         vm_map_t from0;
  390         ipc_port_t to;
  391 {
  392         vm_offset_t address;
  393         vm_size_t size;
  394         vm_prot_t protection, max_protection;
  395         vm_inherit_t inheritance;
  396         boolean_t shared;
  397         port_t object_name;
  398         vm_offset_t offset;
  399         kern_return_t kr;
  400         vm_map_t from;
  401         ipc_port_t memory_object;
  402         
  403         from = vm_map_fork(from0);
  404         if (from == VM_MAP_NULL) {
  405                 panic("task_copy_vm: vm_map_fork\n");
  406         }
  407         for (address = 0;; address += size) {
  408                 kr = vm_region(from, &address, &size, &protection,
  409                                &max_protection, &inheritance, &shared,
  410                                &object_name, &offset);
  411                 if (kr == KERN_NO_SPACE) {
  412                         break;
  413                 }
  414                 switch (inheritance) {
  415                         case VM_INHERIT_NONE:
  416                         break;
  417 
  418                         case VM_INHERIT_SHARE:
  419                         fret("task_copy_vm: VM_INHERIT_SHARE!\n");
  420                         return KERN_FAILURE;
  421 
  422                         case VM_INHERIT_COPY:
  423                         kr = norma_copy_create(from, address, size,
  424                                                &memory_object);
  425                         if (kr != KERN_SUCCESS) {
  426                                 fret("task_cv: copy_create: %d 0x%x\n",
  427                                      kr, kr);
  428                                 return kr;
  429                         }
  430                         kr = r_vm_map(to, &address, size, 0, FALSE,
  431                                       memory_object, 0, TRUE,
  432                                       protection, max_protection,
  433                                       inheritance);
  434                         if (kr != KERN_SUCCESS) {
  435                                 fret("task_cv: vm_map: %d 0x%x\n",
  436                                      kr, kr);
  437                                 return kr;
  438                         }
  439                         ipc_port_release_send(memory_object);
  440                         break;
  441 
  442                         default:
  443                         panic("task_copy_vm: inheritance=%d!\n",
  444                               inheritance);
  445                 }
  446         }
  447         vm_map_deallocate(from);
  448         return KERN_SUCCESS;
  449 }
  450 #else   NORMA_TASK
  451 task_create_local()
  452 {
  453 }
  454 
  455 norma_task_allocate()
  456 {
  457 }
  458 
  459 task_get_inherited_ports()
  460 {
  461 }
  462 
  463 task_set_inherited_ports()
  464 {
  465 }
  466 
  467 norma_task_create()
  468 {
  469 }
  470 
  471 norma_copy_create()
  472 {
  473 }
  474 
  475 #endif  NORMA_TASK

Cache object: b919628131911cbf73482ab89925e6d3


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.