/* * Copyright (c) 2020 Institute of Parallel And Distributed Systems (IPADS), * Shanghai Jiao Tong University (SJTU) OS-Lab-2020 (i.e., ChCore) is licensed * under the Mulan PSL v1. You can use this software according to the terms and * conditions of the Mulan PSL v1. You may obtain a copy of Mulan PSL v1 at: * http://license.coscl.org.cn/MulanPSL * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the * Mulan PSL v1 for more details. */ #include #include #include #include #include #include #include #include #include #include #include #include #define SHADOW_THREAD_PRIO MAX_PRIO - 1 /** * The core function for registering the server */ static int register_server(struct thread *server, u64 callback, u64 max_client, u64 vm_config_ptr) { int r; struct server_ipc_config *server_ipc_config; struct ipc_vm_config *vm_config; BUG_ON(server == NULL); // Create the server ipc_config server_ipc_config = kmalloc(sizeof(struct server_ipc_config)); if (!server_ipc_config) { r = -ENOMEM; goto out_fail; } server->server_ipc_config = server_ipc_config; // Init the server ipc_config server_ipc_config->callback = callback; if (max_client > IPC_MAX_CONN_PER_SERVER) { r = -EINVAL; goto out_free_server_ipc_config; } server_ipc_config->max_client = max_client; server_ipc_config->conn_bmp = kzalloc(BITS_TO_LONGS(max_client) * sizeof(long)); if (!server_ipc_config->conn_bmp) { r = -ENOMEM; goto out_free_server_ipc_config; } // Get and check the parameter vm_config vm_config = &server_ipc_config->vm_config; r = copy_from_user((char *)vm_config, (char *)vm_config_ptr, sizeof(*vm_config)); if (r < 0) goto out_free_conn_bmp; if (!is_user_addr_range(vm_config->stack_base_addr, vm_config->stack_size) || !is_user_addr_range(vm_config->buf_base_addr, vm_config->buf_size) || !IS_ALIGNED(vm_config->stack_base_addr, PAGE_SIZE) || !IS_ALIGNED(vm_config->stack_size, PAGE_SIZE) || !IS_ALIGNED(vm_config->buf_base_addr, PAGE_SIZE) || !IS_ALIGNED(vm_config->buf_size, PAGE_SIZE)) { r = -EINVAL; goto out_free_conn_bmp; } return r; out_free_conn_bmp: kfree(server_ipc_config->conn_bmp); out_free_server_ipc_config: kfree(server_ipc_config); out_fail: return r; } u64 sys_register_server(u64 callback, u64 max_client, u64 vm_config_ptr) { return register_server(current_thread, callback, max_client, vm_config_ptr); }