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
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 the
24 * rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: xmm_import.c,v $
29 * Revision 2.6 92/03/10 16:29:11 jsb
30 * Merged in norma branch changes as of NORMA_MK7.
31 * [92/03/09 12:51:19 jsb]
32 *
33 * Revision 2.5.2.5 92/02/21 11:25:54 jsb
34 * Reference mobj on port to mobj conversion; release when done.
35 * [92/02/20 10:53:45 jsb]
36 *
37 * Deallocate all resources upon termination.
38 * Deallocate allocated replies.
39 * Changed MACH_PORT_NULL uses to IP_NULL.
40 * [92/02/18 07:56:15 jsb]
41 *
42 * Explicitly provide name parameter to xmm_decl macro.
43 * Handle m_import_terminate being called before proxy_set_ready has been.
44 * This can happen because the vm system may terminate an object after
45 * it has been initialized but before it is ready.
46 * [92/02/16 15:26:31 jsb]
47 *
48 * Don't call proxy_terminate on a null port.
49 * [92/02/11 18:21:03 jsb]
50 *
51 * Added ipc_kobject_set to null to break port/mobj association.
52 * Accordingly, removed dead field and associated logic.
53 * [92/02/11 13:22:39 jsb]
54 *
55 * Renamed xmm_import_notify to xmm_kernel_notify.
56 * [92/02/10 17:26:50 jsb]
57 *
58 * Use xmm object instead of <guessed host, memory_object> pair in
59 * proxy_init. Renamed {mobj,kobj}_port to xmm_{pager,kernel}.
60 * [92/02/10 16:56:20 jsb]
61 *
62 * Use new xmm_decl, and new memory_object_name and deallocation protocol.
63 * [92/02/09 12:51:12 jsb]
64 *
65 * Revision 2.5.2.4 92/01/21 22:22:24 jsb
66 * 18-Jan-92 David L. Black (dlb) at Open Software Foundation
67 * Add dead field to mobj and use to synchronize termination
68 * against other operations.
69 *
70 * Revision 2.5.2.3 92/01/21 21:54:12 jsb
71 * Added xmm_import_notify stub.
72 * [92/01/21 18:20:54 jsb]
73 *
74 * Use ports instead of pointers when communicating with xmm_export.c.
75 * De-linted. Supports new (dlb) memory object routines.
76 * Supports arbitrary reply ports to lock_request, etc.
77 * Converted mach_port_t (and port_t) to ipc_port_t.
78 * [92/01/20 17:22:22 jsb]
79 *
80 * Fixes from OSF.
81 * [92/01/17 14:15:01 jsb]
82 *
83 * Revision 2.5.2.2.1.1 92/01/15 12:16:26 jeffreyh
84 * Pass memory_object_name port to proxy terminate. (dlb)
85 *
86 * Revision 2.5.2.2 92/01/09 18:46:13 jsb
87 * Use remote_host_priv() instead of norma_get_special_port().
88 * [92/01/04 18:33:18 jsb]
89 *
90 * Revision 2.5.2.1 92/01/03 16:38:50 jsb
91 * Corrected log.
92 * [91/12/24 14:33:29 jsb]
93 *
94 * Revision 2.5 91/12/10 13:26:24 jsb
95 * Added missing third parameter in call to proxy_terminate.
96 * [91/12/10 12:48:52 jsb]
97 *
98 * Revision 2.4 91/11/14 16:52:34 rpd
99 * Replaced master_device_port_at_node call with calls to
100 * norma_get_special_port and norma_port_location_hint.
101 * [91/11/00 jsb]
102 *
103 * Revision 2.3 91/07/01 08:26:12 jsb
104 * Fixed object importation protocol. Return valid return values.
105 * [91/06/29 15:30:10 jsb]
106 *
107 * Revision 2.2 91/06/17 15:48:18 jsb
108 * First checkin.
109 * [91/06/17 11:03:28 jsb]
110 *
111 */
112 /*
113 * File: norma/xmm_import.c
114 * Author: Joseph S. Barrera III
115 * Date: 1991
116 *
117 * Xmm layer for mapping a remote object.
118 */
119
120 #include <norma/xmm_obj.h>
121 #include <norma/ipc_node.h>
122 #include <ipc/ipc_space.h>
123 #include <ipc/ipc_port.h>
124 #include <mach/notify.h>
125 #include <mach/proxy.h>
126
127 struct mobj {
128 struct xmm_obj obj;
129 ipc_port_t xmm_object;
130 ipc_port_t xmm_pager;
131 ipc_port_t xmm_kernel;
132 boolean_t terminated;
133 };
134
135 #undef KOBJ
136 #define KOBJ ((struct mobj *) kobj)
137
138 #define m_import_deallocate m_interpose_deallocate
139 #define k_import_data_unavailable k_invalid_data_unavailable
140 #define k_import_get_attributes k_invalid_get_attributes
141 #define k_import_lock_request k_invalid_lock_request
142 #define k_import_data_error k_invalid_data_error
143 #define k_import_set_ready k_invalid_set_ready
144 #define k_import_destroy k_invalid_destroy
145 #define k_import_data_supply k_invalid_data_supply
146
147 xmm_decl(import, "import", sizeof(struct mobj));
148
149 kern_return_t
150 xmm_import_create(xmm_object, new_mobj)
151 ipc_port_t xmm_object;
152 xmm_obj_t *new_mobj;
153 {
154 xmm_obj_t mobj;
155 kern_return_t kr;
156
157 kr = xmm_obj_allocate(&import_class, XMM_OBJ_NULL, &mobj);
158 if (kr != KERN_SUCCESS) {
159 return kr;
160 }
161
162 MOBJ->xmm_object = xmm_object;
163 MOBJ->xmm_pager = IP_NULL;
164 MOBJ->xmm_kernel = IP_NULL;
165 MOBJ->terminated = FALSE;
166
167 *new_mobj = mobj;
168 return KERN_SUCCESS;
169 }
170
171 m_import_init(mobj, k_kobj, pagesize, internal, size)
172 xmm_obj_t mobj;
173 xmm_obj_t k_kobj;
174 vm_size_t pagesize;
175 boolean_t internal;
176 vm_size_t size;
177 {
178 kern_return_t kr;
179 xmm_obj_t kobj = mobj;
180
181 #ifdef lint
182 M_INIT(mobj, k_kobj, pagesize, internal, size);
183 #endif lint
184 xmm_kobj_link(kobj, k_kobj);
185
186 MOBJ->xmm_kernel = ipc_port_alloc_kernel();
187 if (MOBJ->xmm_kernel == IP_NULL) {
188 panic("m_import_init: allocate xmm_kernel");
189 }
190 xmm_obj_reference(mobj);
191 ipc_kobject_set(MOBJ->xmm_kernel, (ipc_kobject_t) mobj,
192 IKOT_XMM_KERNEL);
193
194 kr = proxy_init(MOBJ->xmm_object, MOBJ->xmm_kernel, pagesize,
195 internal, size);
196 #if 1
197 if (kr) {
198 panic("m_import_init: proxy_init returns %x\n", kr);
199 }
200 #endif
201 return KERN_SUCCESS;
202 }
203
204 m_import_terminate(mobj, kobj)
205 xmm_obj_t mobj;
206 xmm_obj_t kobj;
207 {
208 kern_return_t kr;
209
210 #ifdef lint
211 M_TERMINATE(mobj, kobj);
212 #endif lint
213 assert(MOBJ->xmm_kernel != IP_NULL);
214 if (MOBJ->xmm_pager == IP_NULL) {
215 /*
216 * This can happen because the vm system only waits
217 * until the object is initialized before terminating
218 * it; it does not wait until the object is ready.
219 * We must therefore wait for _proxy_set_ready ourselves
220 * before terminating the object. We don't even have the
221 * option of calling proxy_terminate on xmm_object, since
222 * we no longer have send rights for xmm_object.
223 *
224 * We need to retain the xmm_kernel to mobj association
225 * so that we can process _proxy_set_ready. Fortunately,
226 * there is no need to break this association, since the
227 * only call that we should receive is _proxy_set_ready.
228 * Any spurious calls to anything else will be caught
229 * at the xmm_server level.
230 */
231 printf("m_import_terminate on unready object 0x%x\n", mobj);
232 MOBJ->terminated = TRUE;
233 return KERN_SUCCESS;
234 }
235 /*
236 * Deallocate resources associated with mobj.
237 * MOBJ->xmm_object was deallocated via proxy_init.
238 * MOBJ->xmm_kernel will be deallocated via proxy_terminate.
239 * We must explicitly deallocate MOBJ->xmm_pager
240 * (to make mobj inaccessible) and then release mobj.
241 */
242 ipc_kobject_set(MOBJ->xmm_kernel, IKO_NULL, IKOT_NONE);
243 ipc_port_dealloc_kernel(MOBJ->xmm_kernel);
244 kr = proxy_terminate(MOBJ->xmm_pager);
245 assert(kr == KERN_SUCCESS);
246 xmm_obj_release(mobj);
247 return KERN_SUCCESS;
248 }
249
250 m_import_copy(mobj, kobj, offset, length, new_mobj)
251 xmm_obj_t mobj;
252 xmm_obj_t kobj;
253 vm_offset_t offset;
254 vm_size_t length;
255 xmm_obj_t new_mobj;
256 {
257 #ifdef lint
258 M_COPY(mobj, kobj, offset, length, new_mobj);
259 #endif lint
260 panic("m_import_copy\n");
261 }
262
263 /*
264 * VM system should handle ready synchronization for everything else
265 */
266
267 m_import_data_request(mobj, kobj, offset, length, desired_access)
268 xmm_obj_t mobj;
269 xmm_obj_t kobj;
270 vm_offset_t offset;
271 vm_size_t length;
272 vm_prot_t desired_access;
273 {
274 #ifdef lint
275 M_DATA_REQUEST(mobj, kobj, offset, length, desired_access);
276 #endif lint
277 return proxy_data_request(MOBJ->xmm_pager, offset, length,
278 desired_access);
279 }
280
281 m_import_data_unlock(mobj, kobj, offset, length, desired_access)
282 xmm_obj_t mobj;
283 xmm_obj_t kobj;
284 vm_offset_t offset;
285 vm_size_t length;
286 vm_prot_t desired_access;
287 {
288 #ifdef lint
289 M_DATA_UNLOCK(mobj, kobj, offset, length, desired_access);
290 #endif lint
291 return proxy_data_unlock(MOBJ->xmm_pager, offset, length,
292 desired_access);
293 }
294
295 m_import_data_write(mobj, kobj, offset, data, length)
296 xmm_obj_t mobj;
297 xmm_obj_t kobj;
298 vm_offset_t offset;
299 vm_offset_t data;
300 vm_size_t length;
301 {
302 #ifdef lint
303 M_DATA_WRITE(mobj, kobj, offset, data, length);
304 #endif lint
305 return proxy_data_write(MOBJ->xmm_pager, offset, data, length);
306 }
307
308 m_import_lock_completed(reply, offset, length)
309 xmm_reply_t reply;
310 vm_offset_t offset;
311 vm_size_t length;
312 {
313 ipc_port_t reply_to = reply->reply_to;
314
315 #ifdef lint
316 M_LOCK_COMPLETED(reply, offset, length);
317 #endif lint
318 assert(reply->reply_to_type == MACH_MSG_TYPE_PORT_SEND_ONCE);
319 xmm_reply_deallocate(reply);
320 return proxy_lock_completed(reply_to, offset, length);
321 }
322
323 m_import_supply_completed(reply, offset, length, result, error_offset)
324 xmm_reply_t reply;
325 vm_offset_t offset;
326 vm_size_t length;
327 kern_return_t result;
328 vm_offset_t error_offset;
329 {
330 ipc_port_t reply_to = reply->reply_to;
331
332 #ifdef lint
333 M_SUPPLY_COMPLETED(reply, offset, length, result, error_offset);
334 #endif lint
335 assert(reply->reply_to_type == MACH_MSG_TYPE_PORT_SEND_ONCE);
336 xmm_reply_deallocate(reply);
337 return proxy_supply_completed(reply_to, offset, length, result,
338 error_offset);
339 }
340
341 m_import_data_return(mobj, kobj, offset, data, length)
342 xmm_obj_t mobj;
343 xmm_obj_t kobj;
344 vm_offset_t offset;
345 vm_offset_t data;
346 vm_size_t length;
347 {
348 #ifdef lint
349 M_DATA_RETURN(mobj, kobj, offset, data, length);
350 #endif lint
351 return proxy_data_return(MOBJ->xmm_pager, offset, data, length);
352 }
353
354 m_import_change_completed(reply, may_cache, copy_strategy)
355 xmm_reply_t reply;
356 boolean_t may_cache;
357 memory_object_copy_strategy_t copy_strategy;
358 {
359 ipc_port_t reply_to = reply->reply_to;
360
361 #ifdef lint
362 M_CHANGE_COMPLETED(reply, may_cache, copy_strategy);
363 #endif lint
364 assert(reply->reply_to_type == MACH_MSG_TYPE_PORT_SEND_ONCE);
365 xmm_reply_deallocate(reply);
366 return proxy_change_completed(reply_to, may_cache, copy_strategy);
367 }
368
369 xmm_obj_t
370 convert_xmm_kernel_to_kobj(xmm_kernel)
371 ipc_port_t xmm_kernel;
372 {
373 xmm_obj_t kobj = XMM_OBJ_NULL;
374
375 if (IP_VALID(xmm_kernel)) {
376 ip_lock(xmm_kernel);
377 if (ip_active(xmm_kernel) &&
378 ip_kotype(xmm_kernel) == IKOT_XMM_KERNEL) {
379 kobj = (xmm_obj_t) xmm_kernel->ip_kobject;
380 xmm_obj_reference(kobj);
381 }
382 ip_unlock(xmm_kernel);
383 }
384 return kobj;
385 }
386
387 boolean_t
388 xmm_kernel_notify(msg)
389 mach_msg_header_t *msg;
390 {
391 return FALSE;
392 }
393
394 _proxy_data_unavailable(xmm_kernel, offset, length)
395 ipc_port_t xmm_kernel;
396 vm_offset_t offset;
397 vm_size_t length;
398 {
399 xmm_obj_t kobj;
400 kern_return_t kr;
401
402 kobj = convert_xmm_kernel_to_kobj(xmm_kernel);
403 if (kobj == XMM_OBJ_NULL) {
404 return KERN_FAILURE;
405 }
406 kr = K_DATA_UNAVAILABLE(kobj, offset, length);
407 xmm_obj_release(kobj);
408 return kr;
409 }
410
411 _proxy_get_attributes(xmm_kernel, object_ready, may_cache, copy_strategy)
412 ipc_port_t xmm_kernel;
413 boolean_t *object_ready;
414 boolean_t *may_cache;
415 memory_object_copy_strategy_t *copy_strategy;
416 {
417 xmm_obj_t kobj;
418 kern_return_t kr;
419
420 kobj = convert_xmm_kernel_to_kobj(xmm_kernel);
421 if (kobj == XMM_OBJ_NULL) {
422 return KERN_FAILURE;
423 }
424 kr = K_GET_ATTRIBUTES(kobj, object_ready, may_cache, copy_strategy);
425 xmm_obj_release(kobj);
426 return kr;
427 }
428
429 _proxy_lock_request(xmm_kernel, offset, length, should_clean, should_flush,
430 prot, reply_to)
431 ipc_port_t xmm_kernel;
432 vm_offset_t offset;
433 vm_size_t length;
434 boolean_t should_clean;
435 boolean_t should_flush;
436 vm_prot_t prot;
437 ipc_port_t reply_to;
438 {
439 kern_return_t kr;
440 xmm_reply_t reply;
441 xmm_obj_t kobj;
442
443 kobj = convert_xmm_kernel_to_kobj(xmm_kernel);
444 if (kobj == XMM_OBJ_NULL) {
445 /*
446 * XXX What about reply message???
447 * XXX Printf here for now.
448 * XXX Same thing goes for other calls that ask for replies.
449 */
450 printf("Rejecting proxy_lock_request on dead object\n");
451 return KERN_FAILURE;
452 }
453 kr = xmm_reply_allocate_send_once(kobj, reply_to, &reply);
454 if (kr != KERN_SUCCESS) {
455 return kr;
456 }
457 kr = K_LOCK_REQUEST(kobj, offset, length, should_clean, should_flush,
458 prot, reply);
459 xmm_obj_release(kobj);
460 return kr;
461 }
462
463 _proxy_data_error(xmm_kernel, offset, length, error_value)
464 ipc_port_t xmm_kernel;
465 vm_offset_t offset;
466 vm_size_t length;
467 kern_return_t error_value;
468 {
469 xmm_obj_t kobj;
470 kern_return_t kr;
471
472 kobj = convert_xmm_kernel_to_kobj(xmm_kernel);
473 if (kobj == XMM_OBJ_NULL) {
474 return KERN_FAILURE;
475 }
476 kr = K_DATA_ERROR(kobj, offset, length, error_value);
477 xmm_obj_release(kobj);
478 return kr;
479 }
480
481 _proxy_set_ready(xmm_kernel, xmm_pager, object_ready, may_cache, copy_strategy,
482 error_value, use_old_pageout, memory_object_name, reply_to)
483 ipc_port_t xmm_kernel;
484 ipc_port_t xmm_pager;
485 boolean_t object_ready;
486 boolean_t may_cache;
487 memory_object_copy_strategy_t copy_strategy;
488 kern_return_t error_value;
489 boolean_t use_old_pageout;
490 ipc_port_t memory_object_name;
491 ipc_port_t reply_to;
492 {
493 xmm_obj_t kobj;
494 xmm_reply_t reply;
495 kern_return_t kr;
496
497 if (error_value) {
498 /* destroy? or should export have done that? */
499 printf("proxy_set_ready loses\n");
500 }
501 kobj = convert_xmm_kernel_to_kobj(xmm_kernel);
502 if (kobj == XMM_OBJ_NULL) {
503 return KERN_FAILURE;
504 }
505 KOBJ->xmm_pager = xmm_pager;
506 if (KOBJ->terminated) {
507 /*
508 * Now that we have xmm_pager, we can process the
509 * pending m_import_terminate.
510 *
511 * XXX what should we do with reply?
512 */
513 printf("_proxy_set_ready on terminated 0x%x\n", kobj);
514 kr = m_import_terminate(kobj, kobj);
515 xmm_obj_release(kobj);
516 return kr;
517 }
518 kr = xmm_reply_allocate_send_once(kobj, reply_to, &reply);
519 if (kr != KERN_SUCCESS) {
520 return kr;
521 }
522 kr = K_SET_READY(kobj, object_ready, may_cache, copy_strategy,
523 use_old_pageout, memory_object_name, reply);
524 xmm_obj_release(kobj);
525 return kr;
526 }
527
528 _proxy_destroy(xmm_kernel, reason)
529 ipc_port_t xmm_kernel;
530 kern_return_t reason;
531 {
532 xmm_obj_t kobj;
533 kern_return_t kr;
534
535 kobj = convert_xmm_kernel_to_kobj(xmm_kernel);
536 if (kobj == XMM_OBJ_NULL) {
537 return KERN_FAILURE;
538 }
539 kr = K_DESTROY(kobj, reason);
540 xmm_obj_release(kobj);
541 return kr;
542 }
543
544 _proxy_data_supply(xmm_kernel, offset, data, length, lock_value, precious,
545 reply_to)
546 ipc_port_t xmm_kernel;
547 vm_offset_t offset;
548 pointer_t data;
549 unsigned int length;
550 vm_prot_t lock_value;
551 ipc_port_t reply_to;
552 {
553 xmm_obj_t kobj;
554 xmm_reply_t reply;
555 kern_return_t kr;
556
557 kobj = convert_xmm_kernel_to_kobj(xmm_kernel);
558 if (kobj == XMM_OBJ_NULL) {
559 return KERN_FAILURE;
560 }
561 kr = xmm_reply_allocate_send_once(kobj, reply_to, &reply);
562 if (kr != KERN_SUCCESS) {
563 return kr;
564 }
565 kr = K_DATA_SUPPLY(kobj, offset, data, length, lock_value, precious,
566 reply);
567 xmm_obj_release(kobj);
568 return kr;
569 }
Cache object: 3a84859720f0d76cf6c6ae8dbe555281
|