Annotation of Gnu-Mach/vm/memory_object_proxy.c, revision 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.