93 lines
2.7 KiB
C
93 lines
2.7 KiB
C
/*
|
|
* 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 <common/errno.h>
|
|
#include <common/kprint.h>
|
|
#include <common/macro.h>
|
|
#include <common/util.h>
|
|
#include <ipc/ipc.h>
|
|
#include <exception/irq.h>
|
|
#include <common/kmalloc.h>
|
|
#include <common/mm.h>
|
|
#include <common/uaccess.h>
|
|
#include <process/thread.h>
|
|
#include <sched/context.h>
|
|
#include <sched/sched.h>
|
|
|
|
#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);
|
|
}
|