|
|
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.