1 /* 2 * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU) 3 * Licensed under the Mulan PSL v2. 4 * You can use this software according to the terms and conditions of the Mulan PSL v2. 5 * You may obtain a copy of Mulan PSL v2 at: 6 * http://license.coscl.org.cn/MulanPSL2 7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR 8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR 9 * PURPOSE. 10 * See the Mulan PSL v2 for more details. 11 */ 12 #ifndef IPC_CONNECTION_H 13 #define IPC_CONNECTION_H 14 15 #include <object/thread.h> 16 17 /* 18 * An ipc_server_handler_thread has such config which stores its information. 19 * Note that the ipc_server_handler_thread is used for handling IPC requests. 20 */ 21 struct ipc_server_handler_config { 22 /* Avoid invoking the same handler_thread concurrently */ 23 struct lock ipc_lock; 24 25 /* PC */ 26 vaddr_t ipc_routine_entry; 27 /* SP */ 28 vaddr_t ipc_routine_stack; 29 /* Entry point of shadow thread exit routine */ 30 vaddr_t ipc_exit_routine_entry; 31 vaddr_t destructor; 32 33 /* 34 * Record which connection uses this handler thread now. 35 * Multiple connection can use the same handler_thread. 36 */ 37 struct ipc_connection *active_conn; 38 }; 39 40 /* 41 * An ipc_server_register_cb_thread has such config which stores its 42 * information. This thread is used for handling IPC registration. 43 */ 44 struct ipc_server_register_cb_config { 45 struct lock register_lock; 46 /* PC */ 47 vaddr_t register_cb_entry; 48 /* SP */ 49 vaddr_t register_cb_stack; 50 vaddr_t destructor; 51 52 /* The caps for the connection currently building */ 53 cap_t conn_cap_in_client; 54 /* Not used now (can be exposed to server in future) */ 55 cap_t conn_cap_in_server; 56 cap_t shm_cap_in_server; 57 }; 58 59 /* 60 * An ipc_server_thread which invokes "reigster_server" has such config. 61 * This thread, which declares an IPC service in the server process, 62 * will be exposed to clients. Then, clients invokes "register_client" 63 * with such ipc_server_thread. 64 */ 65 struct ipc_server_config { 66 /* Callback_thread for handling client registration */ 67 struct thread *register_cb_thread; 68 69 /* Record the argument from the server thread */ 70 unsigned long declared_ipc_routine_entry; 71 }; 72 73 /* 74 * Each connection owns one shm for exchanging data between client and server. 75 * Client process registers one PMO_SHM and copies the shm_cap to the server. 76 * But, client and server can map the PMO_SHM at different addresses. 77 */ 78 struct shm_for_ipc_connection { 79 /* 80 * The starting address of the shm in the client process's vmspace. 81 * uaddr: user-level virtual address. 82 */ 83 vaddr_t client_shm_uaddr; 84 85 /* The starting address of the shm in the server process's vmspace. */ 86 vaddr_t server_shm_uaddr; 87 size_t shm_size; 88 89 /* For resource recycle */ 90 cap_t shm_cap_in_client; 91 cap_t shm_cap_in_server; 92 }; 93 94 struct ipc_connection { 95 /* 96 * current client who uses this connection. 97 * Note that all threads in the client process can use this connection. 98 */ 99 struct thread *current_client_thread; 100 101 /* 102 * server_handler_thread is always fixed after establishing the 103 * connection. 104 * i.e., ipc_server_handler_thread 105 */ 106 struct thread *server_handler_thread; 107 108 /* 109 * Identification of the client (cap_group). 110 * This badge is always fixed with the ipc_connection and 111 * will be transferred to the server during each IPC. 112 * Thus, the server can identify different client processes. 113 * 114 * NOTE: an connection cannot be shared between multiple clients. 115 */ 116 badge_t client_badge; 117 118 /* The vaddr of user_ipc_msg: used when returning caps from server to client */ 119 struct ipc_msg *user_ipc_msg; 120 121 struct shm_for_ipc_connection shm; 122 123 /* For resource recycle */ 124 struct lock ownership; 125 cap_t conn_cap_in_client; 126 cap_t conn_cap_in_server; 127 int is_valid; 128 }; 129 130 struct ipc_msg { 131 unsigned int data_len; 132 unsigned int cap_slot_number; 133 unsigned int data_offset; 134 unsigned int cap_slots_offset; 135 }; 136 137 void connection_deinit(void *conn); 138 139 /* IPC related system calls */ 140 int sys_register_server(unsigned long ipc_rountine, cap_t register_cb_cap, 141 unsigned long destructor); 142 cap_t sys_register_client(cap_t server_cap, unsigned long vm_config_ptr); 143 int sys_ipc_register_cb_return(cap_t server_thread_cap, 144 unsigned long server_thread_exit_routine, 145 unsigned long server_shm_addr); 146 147 unsigned long sys_ipc_call(cap_t conn_cap, struct ipc_msg *ipc_msg, 148 unsigned int cap_num); 149 int sys_ipc_return(unsigned long ret, unsigned int cap_num); 150 void sys_ipc_exit_routine_return(void); 151 152 #endif /* IPC_CONNECTION_H */