Changeset 7c23af9 in mainline
- Timestamp:
- 2006-05-14T17:16:52Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 14b502e2
- Parents:
- 68965ec5
- Location:
- generic
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/include/ipc/ipc.h
r68965ec5 r7c23af9 123 123 /** Interrupt notification */ 124 124 #define IPC_M_INTERRUPT 4 125 /** Send as_area over ipc 126 * - ARG2 - src base address 127 * - ARG3 - size of src as(filled automatically by kernel) 128 * - on answer ARG1 - dst base adress 129 */ 130 #define IPC_M_AS_SEND 5 125 131 126 132 -
generic/include/mm/as.h
r68965ec5 r7c23af9 30 30 #define __AS_H__ 31 31 32 /** Address space area flags. */ 33 #define AS_AREA_READ 1 34 #define AS_AREA_WRITE 2 35 #define AS_AREA_EXEC 4 36 #define AS_AREA_DEVICE 8 37 38 39 #ifdef KERNEL 40 32 41 #include <mm/as_arg.h> 33 42 #include <arch/mm/page.h> … … 54 63 #define FLAG_AS_KERNEL (1 << 0) /**< Kernel address space. */ 55 64 56 /** Address space area flags. */57 #define AS_AREA_READ 158 #define AS_AREA_WRITE 259 #define AS_AREA_EXEC 460 #define AS_AREA_DEVICE 861 65 62 66 /** Address space area attributes. */ … … 130 134 extern void as_switch(as_t *old, as_t *new); 131 135 extern void as_free(as_t *as); 136 int as_area_steal(task_t *src_task, __address src_base, size_t acc_size, __address dst_base); 137 extern size_t as_get_size(__address base); 132 138 133 139 /* Interface to be implemented by architectures. */ … … 140 146 extern __native sys_as_area_resize(__address address, size_t size, int flags); 141 147 extern __native sys_as_area_destroy(__address address); 142 extern __native sys_as_area_accept(as_area_acptsnd_arg_t *uspace_accept_arg); 143 extern __native sys_as_area_send(as_area_acptsnd_arg_t *uspace_send_arg); 148 149 #endif /* KERNEL */ 144 150 145 151 #endif -
generic/include/syscall/syscall.h
r68965ec5 r7c23af9 41 41 SYS_AS_AREA_RESIZE, 42 42 SYS_AS_AREA_DESTROY, 43 SYS_AS_AREA_ACCEPT,44 SYS_AS_AREA_SEND,45 43 SYS_IPC_CALL_SYNC_FAST, 46 44 SYS_IPC_CALL_SYNC, -
generic/src/ipc/sysipc.c
r68965ec5 r7c23af9 41 41 #include <syscall/copy.h> 42 42 #include <security/cap.h> 43 #include <mm/as.h> 43 44 44 45 #define GET_CHECK_PHONE(phone,phoneid,err) { \ … … 83 84 if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_ME_TO) 84 85 return 1; 86 if (IPC_GET_METHOD(call->data) == IPC_M_AS_SEND) 87 return 1; 85 88 return 0; 86 89 } 87 90 88 91 /** Interpret process answer as control information */ 89 static inline voidanswer_preprocess(call_t *answer, ipc_data_t *olddata)92 static inline int answer_preprocess(call_t *answer, ipc_data_t *olddata) 90 93 { 91 94 int phoneid; … … 106 109 107 110 if (!olddata) 108 return ;111 return 0; 109 112 110 113 if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) { … … 125 128 &TASK->answerbox); 126 129 } 127 } 130 } else if (IPC_GET_METHOD(*olddata) == IPC_M_AS_SEND) { 131 if (!IPC_GET_RETVAL(answer->data)) { /* Accepted, handle As_area receival */ 132 return as_area_steal(answer->sender, 133 IPC_GET_ARG2(*olddata),IPC_GET_ARG3(*olddata), 134 IPC_GET_ARG1(answer->data)); 135 } 136 } 137 return 0; 128 138 } 129 139 … … 135 145 { 136 146 int newphid; 147 size_t size; 137 148 138 149 switch (IPC_GET_METHOD(call->data)) { … … 146 157 call->private = newphid; 147 158 break; 159 case IPC_M_AS_SEND: 160 size = as_get_size(IPC_GET_ARG2(call->data)); 161 if (!size) { 162 return EPERM; 163 } 164 IPC_SET_ARG3(call->data, size); 165 break; 148 166 default: 149 167 break; … … 377 395 ipc_data_t saved_data; 378 396 int saveddata = 0; 397 int rc; 379 398 380 399 call = get_call(callid); … … 390 409 IPC_SET_ARG1(call->data, arg1); 391 410 IPC_SET_ARG2(call->data, arg2); 392 answer_preprocess(call, saveddata ? &saved_data : NULL);411 rc = answer_preprocess(call, saveddata ? &saved_data : NULL); 393 412 394 413 ipc_answer(&TASK->answerbox, call); 395 return 0;414 return rc; 396 415 } 397 416 … … 417 436 return rc; 418 437 419 answer_preprocess(call, saveddata ? &saved_data : NULL);438 rc = answer_preprocess(call, saveddata ? &saved_data : NULL); 420 439 421 440 ipc_answer(&TASK->answerbox, call); 422 441 423 return 0;442 return rc; 424 443 } 425 444 -
generic/src/mm/as.c
r68965ec5 r7c23af9 365 365 } 366 366 367 /** Send address space area to another task. 368 * 369 * Address space area is sent to the specified task. 370 * If the destination task is willing to accept the 371 * area, a new area is created according to the 372 * source area. Moreover, any existing mapping 367 /** Steal address space area from another task. 368 * 369 * Address space area is stolen from another task 370 * Moreover, any existing mapping 373 371 * is copied as well, providing thus a mechanism 374 372 * for sharing group of pages. The source address 375 373 * space area and any associated mapping is preserved. 376 374 * 377 * @param dst_id Task ID of the accepting task.375 * @param src_task Pointer of source task 378 376 * @param src_base Base address of the source address space area. 377 * @param acc_size Expected size of the source area 378 * @param dst_base Target base address 379 379 * 380 380 * @return Zero on success or ENOENT if there is no such task or … … 384 384 * address space area. 385 385 */ 386 int as_area_send(task_id_t dst_id, __address src_base) 386 int as_area_steal(task_t *src_task, __address src_base, size_t acc_size, 387 __address dst_base) 387 388 { 388 389 ipl_t ipl; 389 task_t *t;390 390 count_t i; 391 as_t *dst_as; 392 __address dst_base; 391 as_t *src_as; 393 392 int src_flags; 394 393 size_t src_size; 395 394 as_area_t *src_area, *dst_area; 396 395 397 396 ipl = interrupts_disable(); 398 spinlock_lock(&tasks_lock); 399 400 t = task_find_by_id(dst_id); 401 if (!NULL) { 402 spinlock_unlock(&tasks_lock); 403 interrupts_restore(ipl); 404 return ENOENT; 405 } 406 407 spinlock_lock(&t->lock); 408 spinlock_unlock(&tasks_lock); 409 410 dst_as = t->as; 411 dst_base = (__address) t->accept_arg.base; 412 413 if (dst_as == AS) { 414 /* 415 * The two tasks share the entire address space. 416 * Return error since there is no point in continuing. 417 */ 418 spinlock_unlock(&t->lock); 419 interrupts_restore(ipl); 420 return EPERM; 421 } 422 423 spinlock_lock(&AS->lock); 424 src_area = find_area_and_lock(AS, src_base); 397 spinlock_lock(&src_task->lock); 398 src_as = src_task->as; 399 400 spinlock_lock(&src_as->lock); 401 src_area = find_area_and_lock(src_as, src_base); 425 402 if (!src_area) { 426 403 /* 427 404 * Could not find the source address space area. 428 405 */ 429 spinlock_unlock(& t->lock);430 spinlock_unlock(& AS->lock);406 spinlock_unlock(&src_task->lock); 407 spinlock_unlock(&src_as->lock); 431 408 interrupts_restore(ipl); 432 409 return ENOENT; … … 435 412 src_flags = src_area->flags; 436 413 spinlock_unlock(&src_area->lock); 437 spinlock_unlock(&AS->lock); 438 439 if ((t->accept_arg.task_id != TASK->taskid) || (t->accept_arg.size != src_size) || 440 (t->accept_arg.flags != src_flags)) { 441 /* 442 * Discrepancy in either task ID, size or flags. 443 */ 444 spinlock_unlock(&t->lock); 414 spinlock_unlock(&src_as->lock); 415 416 417 if (src_size != acc_size) { 418 spinlock_unlock(&src_task->lock); 445 419 interrupts_restore(ipl); 446 420 return EPERM; 447 421 } 448 449 422 /* 450 423 * Create copy of the source address space area. … … 453 426 * preliminary as_page_fault() calls. 454 427 */ 455 dst_area = as_area_create( dst_as, src_flags, src_size, dst_base, AS_AREA_ATTR_PARTIAL);428 dst_area = as_area_create(AS, src_flags, src_size, dst_base, AS_AREA_ATTR_PARTIAL); 456 429 if (!dst_area) { 457 430 /* 458 431 * Destination address space area could not be created. 459 432 */ 460 spinlock_unlock(& t->lock);433 spinlock_unlock(&src_task->lock); 461 434 interrupts_restore(ipl); 462 435 return ENOMEM; 463 436 } 464 437 465 memsetb((__address) &t->accept_arg, sizeof(as_area_acptsnd_arg_t), 0); 466 spinlock_unlock(&t->lock); 438 spinlock_unlock(&src_task->lock); 467 439 468 440 /* 469 441 * Avoid deadlock by first locking the address space with lower address. 470 442 */ 471 if (dst_as < AS) { 472 spinlock_lock(&dst_as->lock); 443 if (AS < src_as) { 473 444 spinlock_lock(&AS->lock); 445 spinlock_lock(&src_as->lock); 474 446 } else { 475 447 spinlock_lock(&AS->lock); 476 spinlock_lock(& dst_as->lock);448 spinlock_lock(&src_as->lock); 477 449 } 478 450 … … 481 453 __address frame; 482 454 483 page_table_lock( AS, false);484 pte = page_mapping_find( AS, src_base + i*PAGE_SIZE);455 page_table_lock(src_as, false); 456 pte = page_mapping_find(src_as, src_base + i*PAGE_SIZE); 485 457 if (pte && PTE_VALID(pte)) { 486 458 ASSERT(PTE_PRESENT(pte)); … … 488 460 if (!(src_flags & AS_AREA_DEVICE)) 489 461 frame_reference_add(ADDR2PFN(frame)); 490 page_table_unlock( AS, false);462 page_table_unlock(src_as, false); 491 463 } else { 492 page_table_unlock( AS, false);464 page_table_unlock(src_as, false); 493 465 continue; 494 466 } 495 467 496 page_table_lock( dst_as, false);497 page_mapping_insert( dst_as, dst_base + i*PAGE_SIZE, frame, area_flags_to_page_flags(src_flags));498 page_table_unlock( dst_as, false);468 page_table_lock(AS, false); 469 page_mapping_insert(AS, dst_base + i*PAGE_SIZE, frame, area_flags_to_page_flags(src_flags)); 470 page_table_unlock(AS, false); 499 471 } 500 472 … … 509 481 510 482 spinlock_unlock(&AS->lock); 511 spinlock_unlock(& dst_as->lock);483 spinlock_unlock(&src_as->lock); 512 484 interrupts_restore(ipl); 513 485 … … 946 918 } 947 919 920 /** Return size of address space of current task pointed to by base */ 921 size_t as_get_size(__address base) 922 { 923 ipl_t ipl; 924 as_area_t *src_area; 925 size_t size; 926 927 ipl = interrupts_disable(); 928 src_area = find_area_and_lock(AS, base); 929 if (src_area){ 930 size = src_area->pages * PAGE_SIZE; 931 spinlock_unlock(&src_area->lock); 932 } else { 933 size = 0; 934 } 935 interrupts_restore(ipl); 936 return size; 937 } 938 948 939 /* 949 940 * Address space related syscalls. … … 971 962 } 972 963 973 /** Prepare task for accepting address space area from another task.974 *975 * @param uspace_accept_arg Accept structure passed from userspace.976 *977 * @return EPERM if the task ID encapsulated in @uspace_accept_arg references978 * TASK. Otherwise zero is returned.979 */980 __native sys_as_area_accept(as_area_acptsnd_arg_t *uspace_accept_arg)981 {982 as_area_acptsnd_arg_t arg;983 int rc;984 985 rc = copy_from_uspace(&arg, uspace_accept_arg, sizeof(as_area_acptsnd_arg_t));986 if (rc != 0)987 return rc;988 989 if (!arg.size)990 return (__native) EPERM;991 992 if (arg.task_id == TASK->taskid) {993 /*994 * Accepting from itself is not allowed.995 */996 return (__native) EPERM;997 }998 999 memcpy(&TASK->accept_arg, &arg, sizeof(as_area_acptsnd_arg_t));1000 1001 return 0;1002 }1003 1004 /** Wrapper for as_area_send. */1005 __native sys_as_area_send(as_area_acptsnd_arg_t *uspace_send_arg)1006 {1007 as_area_acptsnd_arg_t arg;1008 int rc;1009 1010 rc = copy_from_uspace(&arg, uspace_send_arg, sizeof(as_area_acptsnd_arg_t));1011 if (rc != 0)1012 return rc;1013 1014 if (!arg.size)1015 return (__native) EPERM;1016 1017 if (arg.task_id == TASK->taskid) {1018 /*1019 * Sending to itself is not allowed.1020 */1021 return (__native) EPERM;1022 }1023 1024 return (__native) as_area_send(arg.task_id, (__address) arg.base);1025 } -
generic/src/syscall/syscall.c
r68965ec5 r7c23af9 87 87 sys_as_area_resize, 88 88 sys_as_area_destroy, 89 sys_as_area_accept,90 sys_as_area_send,91 89 92 90 /* IPC related syscalls. */
Note:
See TracChangeset
for help on using the changeset viewer.