Annotation of Gnu-Mach/vm/memory_object_proxy.c, revision 1.1.1.1

1.1       root        1: /* memory_object_proxy.c - Proxy memory objects for Mach.
                      2:    Copyright (C) 2005 Free Software Foundation, Inc.
                      3:    Written by Marcus Brinkmann.
                      4: 
                      5:    This file is part of GNU Mach.
                      6: 
                      7:    GNU Mach is free software; you can redistribute it and/or modify it
                      8:    under the terms of the GNU General Public License as published by
                      9:    the Free Software Foundation; either version 2, or (at your option)
                     10:    any later version.
                     11: 
                     12:    GNU Mach is distributed in the hope that it will be useful, but
                     13:    WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     15:    General Public License for more details.
                     16: 
                     17:    You should have received a copy of the GNU General Public License
                     18:    along with this program; if not, write to the Free Software
                     19:    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
                     20: 
                     21: /* A proxy memory object is a kernel port that can be used like a real
                     22:    memory object in a vm_map call, except that the current and maximum
                     23:    protection are restricted to the proxy object's maximum protection
                     24:    at the time the mapping is established.  The kernel port will hold
                     25:    a reference to the real memory object for the life time of the
                     26:    proxy object.
                     27: 
                     28:    Note that we don't need to do any reference counting on the proxy
                     29:    object.  Our caller will hold a reference to the proxy object when
                     30:    looking it up, and is expected to acquire its own reference to the
                     31:    real memory object if needed before releasing the reference to the
                     32:    proxy object.
                     33: 
                     34:    The user provided real memory object and the maximum protection are
                     35:    not checked for validity.  The maximum protection is only used as a
                     36:    mask, and the memory object is validated at the time the mapping is
                     37:    established.  */
                     38: 
                     39: #include <mach/port.h>
                     40: #include <mach/kern_return.h>
                     41: #include <mach/notify.h>
                     42: #include <mach/vm_prot.h>
                     43: #include <kern/printf.h>
                     44: #include <kern/slab.h>
                     45: #include <ipc/ipc_port.h>
                     46: #include <ipc/ipc_space.h>
                     47: 
                     48: #include <vm/memory_object_proxy.h>
                     49: 
                     50: /* The cache which holds our proxy memory objects.  */
                     51: static struct kmem_cache memory_object_proxy_cache;
                     52: 
                     53: struct memory_object_proxy
                     54: {
                     55:   struct ipc_port *port;
                     56: 
                     57:   ipc_port_t object;
                     58:   vm_prot_t max_protection;
                     59: };
                     60: typedef struct memory_object_proxy *memory_object_proxy_t;
                     61: 
                     62: 
                     63: void
                     64: memory_object_proxy_init (void)
                     65: {
                     66:   kmem_cache_init (&memory_object_proxy_cache, "memory_object_proxy",
                     67:                   sizeof (struct memory_object_proxy), 0, NULL, NULL, NULL, 0);
                     68: }
                     69:   
                     70: /* Lookup a proxy memory object by its port.  */
                     71: static memory_object_proxy_t
                     72: memory_object_proxy_port_lookup (ipc_port_t port)
                     73: {
                     74:   memory_object_proxy_t proxy;
                     75: 
                     76:   if (!IP_VALID(port))
                     77:     return 0;
                     78: 
                     79:   ip_lock (port);
                     80:   if (ip_active (port) && (ip_kotype (port) == IKOT_PAGER_PROXY))
                     81:     proxy = (memory_object_proxy_t) port->ip_kobject;
                     82:   else
                     83:     proxy = 0;
                     84:   ip_unlock (port);
                     85:   return proxy;
                     86: }
                     87: 
                     88: 
                     89: /* Process a no-sender notification for the proxy memory object
                     90:    port.  */
                     91: boolean_t
                     92: memory_object_proxy_notify (mach_msg_header_t *msg)
                     93: {
                     94:   if (msg->msgh_id == MACH_NOTIFY_NO_SENDERS)
                     95:     {
                     96:       memory_object_proxy_t proxy;
                     97:       mach_no_senders_notification_t *ns;
                     98: 
                     99:       ns = (mach_no_senders_notification_t *) msg;
                    100:       proxy = memory_object_proxy_port_lookup
                    101:        ((ipc_port_t) ns->not_header.msgh_remote_port);
                    102:       assert (proxy);
                    103: 
                    104:       ipc_port_release_send (proxy->object);
                    105:       return TRUE;
                    106:     }
                    107: 
                    108:   printf ("memory_object_proxy_notify: strange notification %d\n",
                    109:          msg->msgh_id);
                    110:   return FALSE;
                    111: }
                    112: 
                    113: 
                    114: /* Create a new proxy memory object from [START;START+LEN) in the
                    115:    given OBJECT at OFFSET in the new object with the maximum
                    116:    protection MAX_PROTECTION and return it in *PORT.  */
                    117: kern_return_t
                    118: memory_object_create_proxy (ipc_space_t space, vm_prot_t max_protection,
                    119:                            ipc_port_t *object, natural_t object_count,
                    120:                            vm_offset_t *offset, natural_t offset_count,
                    121:                            vm_offset_t *start, natural_t start_count,
                    122:                            vm_offset_t *len, natural_t len_count,
                    123:                            ipc_port_t *port)
                    124: {
                    125:   memory_object_proxy_t proxy;
                    126:   ipc_port_t notify;
                    127: 
                    128:   if (space == IS_NULL)
                    129:     return KERN_INVALID_TASK;
                    130: 
                    131:   if (offset_count != object_count || start_count != object_count
                    132:       || len_count != object_count)
                    133:     return KERN_INVALID_ARGUMENT;
                    134: 
                    135:   /* FIXME: Support more than one memory object.  */
                    136:   if (object_count != 1)
                    137:     return KERN_INVALID_ARGUMENT;
                    138: 
                    139:   if (!IP_VALID(object[0]))
                    140:     return KERN_INVALID_NAME;
                    141: 
                    142:   /* FIXME: Support a different offset from 0.  */
                    143:   if (offset[0] != 0)
                    144:     return KERN_INVALID_ARGUMENT;
                    145: 
                    146:   /* FIXME: Support a different range from total.  */
                    147:   if (start[0] != 0 || len[0] != (vm_offset_t) ~0)
                    148:     return KERN_INVALID_ARGUMENT;
                    149: 
                    150:   proxy = (memory_object_proxy_t) kmem_cache_alloc (&memory_object_proxy_cache);
                    151: 
                    152:   /* Allocate port, keeping a reference for it.  */
                    153:   proxy->port = ipc_port_alloc_kernel ();
                    154:   if (proxy->port == IP_NULL)
                    155:     {
                    156:       kmem_cache_free (&memory_object_proxy_cache, (vm_offset_t) proxy);
                    157:       return KERN_RESOURCE_SHORTAGE;
                    158:     }
                    159:   /* Associate the port with the proxy memory object.  */
                    160:   ipc_kobject_set (proxy->port, (ipc_kobject_t) proxy, IKOT_PAGER_PROXY);
                    161: 
                    162:   /* Request no-senders notifications on the port.  */
                    163:   notify = ipc_port_make_sonce (proxy->port);
                    164:   ip_lock (proxy->port);
                    165:   ipc_port_nsrequest (proxy->port, 1, notify, &notify);
                    166:   assert (notify == IP_NULL);
                    167: 
                    168:   proxy->object = ipc_port_copy_send (object[0]);
                    169:   proxy->max_protection = max_protection;
                    170: 
                    171:   *port = ipc_port_make_send (proxy->port);
                    172:   return KERN_SUCCESS;
                    173: }
                    174: 
                    175: 
                    176: /* Lookup the real memory object and maximum protection for the proxy
                    177:    memory object port PORT, for which the caller holds a reference.
                    178:    *OBJECT is only guaranteed to be valid as long as the caller holds
                    179:    the reference to PORT (unless the caller acquires its own reference
                    180:    to it).  If PORT is not a proxy memory object, return
                    181:    KERN_INVALID_ARGUMENT.  */
                    182: kern_return_t
                    183: memory_object_proxy_lookup (ipc_port_t port, ipc_port_t *object,
                    184:                            vm_prot_t *max_protection)
                    185: {
                    186:   memory_object_proxy_t proxy;
                    187: 
                    188:   proxy = memory_object_proxy_port_lookup (port);
                    189:   if (!proxy)
                    190:     return KERN_INVALID_ARGUMENT;
                    191: 
                    192:    *object = proxy->object;
                    193:    *max_protection = proxy->max_protection;
                    194: 
                    195:   return KERN_SUCCESS;
                    196: }

unix.superglobalmegacorp.com

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