|
|
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: * @OSF_COPYRIGHT@ ! 24: */ ! 25: /* ! 26: * Mach Operating System ! 27: * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University ! 28: * All Rights Reserved. ! 29: * ! 30: * Permission to use, copy, modify and distribute this software and its ! 31: * documentation is hereby granted, provided that both the copyright ! 32: * notice and this permission notice appear in all copies of the ! 33: * software, derivative works or modified versions, and any portions ! 34: * thereof, and that both notices appear in supporting documentation. ! 35: * ! 36: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 37: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 38: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 39: * ! 40: * Carnegie Mellon requests users of this software to return to ! 41: * ! 42: * Software Distribution Coordinator or [email protected] ! 43: * School of Computer Science ! 44: * Carnegie Mellon University ! 45: * Pittsburgh PA 15213-3890 ! 46: * ! 47: * any improvements or extensions that they make and grant Carnegie Mellon ! 48: * the rights to redistribute these changes. ! 49: */ ! 50: /* ! 51: */ ! 52: ! 53: /* ! 54: * kern/ipc_host.c ! 55: * ! 56: * Routines to implement host ports. ! 57: */ ! 58: #include <mach/message.h> ! 59: #include <mach/mach_traps.h> ! 60: #include <mach/mach_host_server.h> ! 61: #include <kern/host.h> ! 62: #include <kern/processor.h> ! 63: #include <kern/task.h> ! 64: #include <kern/thread.h> ! 65: #include <kern/ipc_host.h> ! 66: #include <kern/ipc_kobject.h> ! 67: #include <kern/misc_protos.h> ! 68: #include <kern/spl.h> ! 69: #include <ipc/ipc_port.h> ! 70: #include <ipc/ipc_space.h> ! 71: ! 72: /* ! 73: * Forward declarations ! 74: */ ! 75: ! 76: void ! 77: ipc_processor_terminate( ! 78: processor_t processor); ! 79: ! 80: void ! 81: ipc_processor_disable( ! 82: processor_t processor); ! 83: ! 84: boolean_t ! 85: ref_pset_port_locked( ! 86: ipc_port_t port, boolean_t matchn, processor_set_t *ppset); ! 87: ! 88: /* ! 89: * ipc_host_init: set up various things. ! 90: */ ! 91: ! 92: void ipc_host_init(void) ! 93: { ! 94: ipc_port_t port; ! 95: /* ! 96: * Allocate and set up the two host ports. ! 97: */ ! 98: port = ipc_port_alloc_kernel(); ! 99: if (port == IP_NULL) ! 100: panic("ipc_host_init"); ! 101: ! 102: ipc_kobject_set(port, (ipc_kobject_t) &realhost, IKOT_HOST); ! 103: realhost.host_self = port; ! 104: ! 105: port = ipc_port_alloc_kernel(); ! 106: if (port == IP_NULL) ! 107: panic("ipc_host_init"); ! 108: ! 109: ipc_kobject_set(port, (ipc_kobject_t) &realhost, IKOT_HOST_PRIV); ! 110: realhost.host_priv_self = port; ! 111: ! 112: port = ipc_port_alloc_kernel(); ! 113: if (port == IP_NULL) ! 114: panic("ipc_host_init"); ! 115: ! 116: ipc_kobject_set(port, (ipc_kobject_t) &realhost, IKOT_HOST_SECURITY); ! 117: realhost.host_security_self = port; ! 118: /* ! 119: * Set up ipc for default processor set. ! 120: */ ! 121: ipc_pset_init(&default_pset); ! 122: ipc_pset_enable(&default_pset); ! 123: ! 124: /* ! 125: * And for master processor ! 126: */ ! 127: ipc_processor_init(master_processor); ! 128: ipc_processor_enable(master_processor); ! 129: } ! 130: ! 131: /* ! 132: * Routine: mach_host_self [mach trap] ! 133: * Purpose: ! 134: * Give the caller send rights for his own host port. ! 135: * Conditions: ! 136: * Nothing locked. ! 137: * Returns: ! 138: * MACH_PORT_NULL if there are any resource failures ! 139: * or other errors. ! 140: */ ! 141: ! 142: mach_port_name_t ! 143: mach_host_self(void) ! 144: { ! 145: ipc_port_t sright; ! 146: ! 147: sright = ipc_port_make_send(realhost.host_self); ! 148: return ipc_port_copyout_send(sright, current_space()); ! 149: } ! 150: ! 151: /* ! 152: * ipc_processor_init: ! 153: * ! 154: * Initialize ipc access to processor by allocating port. ! 155: */ ! 156: ! 157: void ! 158: ipc_processor_init( ! 159: processor_t processor) ! 160: { ! 161: ipc_port_t port; ! 162: ! 163: port = ipc_port_alloc_kernel(); ! 164: if (port == IP_NULL) ! 165: panic("ipc_processor_init"); ! 166: processor->processor_self = port; ! 167: } ! 168: ! 169: /* ! 170: * ipc_processor_enable: ! 171: * ! 172: * Enable ipc control of processor by setting port object. ! 173: */ ! 174: void ! 175: ipc_processor_enable( ! 176: processor_t processor) ! 177: { ! 178: ipc_port_t myport; ! 179: ! 180: myport = processor->processor_self; ! 181: ipc_kobject_set(myport, (ipc_kobject_t) processor, IKOT_PROCESSOR); ! 182: } ! 183: ! 184: /* ! 185: * ipc_processor_disable: ! 186: * ! 187: * Disable ipc control of processor by clearing port object. ! 188: */ ! 189: void ! 190: ipc_processor_disable( ! 191: processor_t processor) ! 192: { ! 193: ipc_port_t myport; ! 194: ! 195: myport = processor->processor_self; ! 196: if (myport == IP_NULL) ! 197: return; ! 198: ipc_kobject_set(myport, IKO_NULL, IKOT_NONE); ! 199: } ! 200: ! 201: /* ! 202: * ipc_processor_terminate: ! 203: * ! 204: * Processor is off-line. Destroy ipc control port. ! 205: */ ! 206: void ! 207: ipc_processor_terminate( ! 208: processor_t processor) ! 209: { ! 210: ipc_port_t myport; ! 211: spl_t s; ! 212: ! 213: s = splsched(); ! 214: processor_lock(processor); ! 215: myport = processor->processor_self; ! 216: if (myport == IP_NULL) { ! 217: processor_unlock(processor); ! 218: splx(s); ! 219: return; ! 220: } ! 221: ! 222: processor->processor_self = IP_NULL; ! 223: processor_unlock(processor); ! 224: splx(s); ! 225: ! 226: ipc_port_dealloc_kernel(myport); ! 227: } ! 228: ! 229: /* ! 230: * ipc_pset_init: ! 231: * ! 232: * Initialize ipc control of a processor set by allocating its ports. ! 233: */ ! 234: ! 235: void ! 236: ipc_pset_init( ! 237: processor_set_t pset) ! 238: { ! 239: ipc_port_t port; ! 240: ! 241: port = ipc_port_alloc_kernel(); ! 242: if (port == IP_NULL) ! 243: panic("ipc_pset_init"); ! 244: pset->pset_self = port; ! 245: ! 246: port = ipc_port_alloc_kernel(); ! 247: if (port == IP_NULL) ! 248: panic("ipc_pset_init"); ! 249: pset->pset_name_self = port; ! 250: } ! 251: ! 252: /* ! 253: * ipc_pset_enable: ! 254: * ! 255: * Enable ipc access to a processor set. ! 256: */ ! 257: void ! 258: ipc_pset_enable( ! 259: processor_set_t pset) ! 260: { ! 261: pset_lock(pset); ! 262: if (pset->active) { ! 263: ipc_kobject_set(pset->pset_self, ! 264: (ipc_kobject_t) pset, IKOT_PSET); ! 265: ipc_kobject_set(pset->pset_name_self, ! 266: (ipc_kobject_t) pset, IKOT_PSET_NAME); ! 267: pset->ref_count += 2; ! 268: } ! 269: pset_unlock(pset); ! 270: } ! 271: ! 272: /* ! 273: * ipc_pset_disable: ! 274: * ! 275: * Disable ipc access to a processor set by clearing the port objects. ! 276: * Caller must hold pset lock and a reference to the pset. Ok to ! 277: * just decrement pset reference count as a result. ! 278: */ ! 279: void ! 280: ipc_pset_disable( ! 281: processor_set_t pset) ! 282: { ! 283: ipc_kobject_set(pset->pset_self, IKO_NULL, IKOT_NONE); ! 284: ipc_kobject_set(pset->pset_name_self, IKO_NULL, IKOT_NONE); ! 285: pset->ref_count -= 2; ! 286: } ! 287: ! 288: /* ! 289: * ipc_pset_terminate: ! 290: * ! 291: * Processor set is dead. Deallocate the ipc control structures. ! 292: */ ! 293: void ! 294: ipc_pset_terminate( ! 295: processor_set_t pset) ! 296: { ! 297: ipc_port_dealloc_kernel(pset->pset_self); ! 298: ipc_port_dealloc_kernel(pset->pset_name_self); ! 299: } ! 300: ! 301: /* ! 302: * processor_set_default, processor_set_default_priv: ! 303: * ! 304: * Return ports for manipulating default_processor set. MiG code ! 305: * differentiates between these two routines. ! 306: */ ! 307: kern_return_t ! 308: processor_set_default( ! 309: host_t host, ! 310: processor_set_t *pset) ! 311: { ! 312: if (host == HOST_NULL) ! 313: return(KERN_INVALID_ARGUMENT); ! 314: ! 315: *pset = &default_pset; ! 316: pset_reference(*pset); ! 317: return(KERN_SUCCESS); ! 318: } ! 319: ! 320: /* ! 321: * Routine: convert_port_to_host ! 322: * Purpose: ! 323: * Convert from a port to a host. ! 324: * Doesn't consume the port ref; the host produced may be null. ! 325: * Conditions: ! 326: * Nothing locked. ! 327: */ ! 328: ! 329: host_t ! 330: convert_port_to_host( ! 331: ipc_port_t port) ! 332: { ! 333: host_t host = HOST_NULL; ! 334: ! 335: if (IP_VALID(port)) { ! 336: ip_lock(port); ! 337: if (ip_active(port) && ! 338: ((ip_kotype(port) == IKOT_HOST) || ! 339: (ip_kotype(port) == IKOT_HOST_PRIV) ! 340: )) ! 341: host = (host_t) port->ip_kobject; ! 342: ip_unlock(port); ! 343: } ! 344: ! 345: return host; ! 346: } ! 347: ! 348: /* ! 349: * Routine: convert_port_to_host_priv ! 350: * Purpose: ! 351: * Convert from a port to a host. ! 352: * Doesn't consume the port ref; the host produced may be null. ! 353: * Conditions: ! 354: * Nothing locked. ! 355: */ ! 356: ! 357: host_t ! 358: convert_port_to_host_priv( ! 359: ipc_port_t port) ! 360: { ! 361: host_t host = HOST_NULL; ! 362: ! 363: if (IP_VALID(port)) { ! 364: ip_lock(port); ! 365: if (ip_active(port) && ! 366: (ip_kotype(port) == IKOT_HOST_PRIV)) ! 367: host = (host_t) port->ip_kobject; ! 368: ip_unlock(port); ! 369: } ! 370: ! 371: return host; ! 372: } ! 373: ! 374: /* ! 375: * Routine: convert_port_to_processor ! 376: * Purpose: ! 377: * Convert from a port to a processor. ! 378: * Doesn't consume the port ref; ! 379: * the processor produced may be null. ! 380: * Conditions: ! 381: * Nothing locked. ! 382: */ ! 383: ! 384: processor_t ! 385: convert_port_to_processor( ! 386: ipc_port_t port) ! 387: { ! 388: processor_t processor = PROCESSOR_NULL; ! 389: ! 390: if (IP_VALID(port)) { ! 391: ip_lock(port); ! 392: if (ip_active(port) && ! 393: (ip_kotype(port) == IKOT_PROCESSOR)) ! 394: processor = (processor_t) port->ip_kobject; ! 395: ip_unlock(port); ! 396: } ! 397: ! 398: return processor; ! 399: } ! 400: ! 401: /* ! 402: * Routine: convert_port_to_pset ! 403: * Purpose: ! 404: * Convert from a port to a pset. ! 405: * Doesn't consume the port ref; produces a pset ref, ! 406: * which may be null. ! 407: * Conditions: ! 408: * Nothing locked. ! 409: */ ! 410: ! 411: processor_set_t ! 412: convert_port_to_pset( ! 413: ipc_port_t port) ! 414: { ! 415: boolean_t r; ! 416: processor_set_t pset = PROCESSOR_SET_NULL; ! 417: ! 418: r = FALSE; ! 419: while (!r && IP_VALID(port)) { ! 420: ip_lock(port); ! 421: r = ref_pset_port_locked(port, FALSE, &pset); ! 422: /* port unlocked */ ! 423: } ! 424: return pset; ! 425: } ! 426: ! 427: /* ! 428: * Routine: convert_port_to_pset_name ! 429: * Purpose: ! 430: * Convert from a port to a pset. ! 431: * Doesn't consume the port ref; produces a pset ref, ! 432: * which may be null. ! 433: * Conditions: ! 434: * Nothing locked. ! 435: */ ! 436: ! 437: processor_set_name_t ! 438: convert_port_to_pset_name( ! 439: ipc_port_t port) ! 440: { ! 441: boolean_t r; ! 442: processor_set_t pset = PROCESSOR_SET_NULL; ! 443: ! 444: r = FALSE; ! 445: while (!r && IP_VALID(port)) { ! 446: ip_lock(port); ! 447: r = ref_pset_port_locked(port, TRUE, &pset); ! 448: /* port unlocked */ ! 449: } ! 450: return pset; ! 451: } ! 452: ! 453: boolean_t ! 454: ref_pset_port_locked(ipc_port_t port, boolean_t matchn, processor_set_t *ppset) ! 455: { ! 456: processor_set_t pset; ! 457: ! 458: pset = PROCESSOR_SET_NULL; ! 459: if (ip_active(port) && ! 460: ((ip_kotype(port) == IKOT_PSET) || ! 461: (matchn && (ip_kotype(port) == IKOT_PSET_NAME)))) { ! 462: pset = (processor_set_t) port->ip_kobject; ! 463: if (!pset_lock_try(pset)) { ! 464: ip_unlock(port); ! 465: mutex_pause(); ! 466: return (FALSE); ! 467: } ! 468: pset->ref_count++; ! 469: pset_unlock(pset); ! 470: } ! 471: *ppset = pset; ! 472: ip_unlock(port); ! 473: return (TRUE); ! 474: } ! 475: ! 476: /* ! 477: * Routine: convert_host_to_port ! 478: * Purpose: ! 479: * Convert from a host to a port. ! 480: * Produces a naked send right which may be invalid. ! 481: * Conditions: ! 482: * Nothing locked. ! 483: */ ! 484: ! 485: ipc_port_t ! 486: convert_host_to_port( ! 487: host_t host) ! 488: { ! 489: ipc_port_t port; ! 490: ! 491: port = ipc_port_make_send(host->host_self); ! 492: ! 493: return port; ! 494: } ! 495: ! 496: /* ! 497: * Routine: convert_processor_to_port ! 498: * Purpose: ! 499: * Convert from a processor to a port. ! 500: * Produces a naked send right which may be invalid. ! 501: * Conditions: ! 502: * Nothing locked. ! 503: */ ! 504: ! 505: ipc_port_t ! 506: convert_processor_to_port( ! 507: processor_t processor) ! 508: { ! 509: ipc_port_t port; ! 510: spl_t s; ! 511: ! 512: s = splsched(); ! 513: processor_lock(processor); ! 514: ! 515: if (processor->processor_self != IP_NULL) ! 516: port = ipc_port_make_send(processor->processor_self); ! 517: else ! 518: port = IP_NULL; ! 519: ! 520: processor_unlock(processor); ! 521: splx(s); ! 522: ! 523: return port; ! 524: } ! 525: ! 526: /* ! 527: * Routine: convert_pset_to_port ! 528: * Purpose: ! 529: * Convert from a pset to a port. ! 530: * Consumes a pset ref; produces a naked send right ! 531: * which may be invalid. ! 532: * Conditions: ! 533: * Nothing locked. ! 534: */ ! 535: ! 536: ipc_port_t ! 537: convert_pset_to_port( ! 538: processor_set_t pset) ! 539: { ! 540: ipc_port_t port; ! 541: ! 542: pset_lock(pset); ! 543: if (pset->active) ! 544: port = ipc_port_make_send(pset->pset_self); ! 545: else ! 546: port = IP_NULL; ! 547: pset_unlock(pset); ! 548: ! 549: pset_deallocate(pset); ! 550: return port; ! 551: } ! 552: ! 553: /* ! 554: * Routine: convert_pset_name_to_port ! 555: * Purpose: ! 556: * Convert from a pset to a port. ! 557: * Consumes a pset ref; produces a naked send right ! 558: * which may be invalid. ! 559: * Conditions: ! 560: * Nothing locked. ! 561: */ ! 562: ! 563: ipc_port_t ! 564: convert_pset_name_to_port( ! 565: processor_set_name_t pset) ! 566: { ! 567: ipc_port_t port; ! 568: ! 569: pset_lock(pset); ! 570: if (pset->active) ! 571: port = ipc_port_make_send(pset->pset_name_self); ! 572: else ! 573: port = IP_NULL; ! 574: pset_unlock(pset); ! 575: ! 576: pset_deallocate(pset); ! 577: return port; ! 578: } ! 579: ! 580: /* ! 581: * Routine: convert_port_to_host_security ! 582: * Purpose: ! 583: * Convert from a port to a host security. ! 584: * Doesn't consume the port ref; the port produced may be null. ! 585: * Conditions: ! 586: * Nothing locked. ! 587: */ ! 588: ! 589: host_t ! 590: convert_port_to_host_security( ! 591: ipc_port_t port) ! 592: { ! 593: host_t host = HOST_NULL; ! 594: ! 595: if (IP_VALID(port)) { ! 596: ip_lock(port); ! 597: if (ip_active(port) && ! 598: (ip_kotype(port) == IKOT_HOST_SECURITY)) ! 599: host = (host_t) port->ip_kobject; ! 600: ip_unlock(port); ! 601: } ! 602: ! 603: return host; ! 604: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.