mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-18 20:16:42 +00:00
Remove the shim kernel crate
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
d76c7a5b1e
commit
dafd16075f
358
kernel/src/syscall/mod.rs
Normal file
358
kernel/src/syscall/mod.rs
Normal file
@ -0,0 +1,358 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
//! Read the Cpu ctx content then dispatch syscall to corrsponding handler
|
||||
//! The each sub module contains functions that handle real syscall logic.
|
||||
pub use clock_gettime::ClockId;
|
||||
use ostd::cpu::UserContext;
|
||||
|
||||
use crate::{context::Context, cpu::LinuxAbi, prelude::*};
|
||||
|
||||
mod accept;
|
||||
mod access;
|
||||
mod alarm;
|
||||
mod arch;
|
||||
mod arch_prctl;
|
||||
mod bind;
|
||||
mod brk;
|
||||
mod capget;
|
||||
mod capset;
|
||||
mod chdir;
|
||||
mod chmod;
|
||||
mod chown;
|
||||
mod chroot;
|
||||
mod clock_gettime;
|
||||
mod clone;
|
||||
mod close;
|
||||
mod connect;
|
||||
mod constants;
|
||||
mod dup;
|
||||
mod epoll;
|
||||
mod eventfd;
|
||||
mod execve;
|
||||
mod exit;
|
||||
mod exit_group;
|
||||
mod fallocate;
|
||||
mod fcntl;
|
||||
mod flock;
|
||||
mod fork;
|
||||
mod fsync;
|
||||
mod futex;
|
||||
mod getcwd;
|
||||
mod getdents64;
|
||||
mod getegid;
|
||||
mod geteuid;
|
||||
mod getgid;
|
||||
mod getgroups;
|
||||
mod getpeername;
|
||||
mod getpgrp;
|
||||
mod getpid;
|
||||
mod getppid;
|
||||
mod getrandom;
|
||||
mod getresgid;
|
||||
mod getresuid;
|
||||
mod getrusage;
|
||||
mod getsid;
|
||||
mod getsockname;
|
||||
mod getsockopt;
|
||||
mod gettid;
|
||||
mod gettimeofday;
|
||||
mod getuid;
|
||||
mod ioctl;
|
||||
mod kill;
|
||||
mod link;
|
||||
mod listen;
|
||||
mod lseek;
|
||||
mod madvise;
|
||||
mod mkdir;
|
||||
mod mknod;
|
||||
mod mmap;
|
||||
mod mount;
|
||||
mod mprotect;
|
||||
mod msync;
|
||||
mod munmap;
|
||||
mod nanosleep;
|
||||
mod open;
|
||||
mod pause;
|
||||
mod pipe;
|
||||
mod poll;
|
||||
mod prctl;
|
||||
mod pread64;
|
||||
mod preadv;
|
||||
mod prlimit64;
|
||||
mod pselect6;
|
||||
mod pwrite64;
|
||||
mod pwritev;
|
||||
mod read;
|
||||
mod readlink;
|
||||
mod recvfrom;
|
||||
mod recvmsg;
|
||||
mod rename;
|
||||
mod rmdir;
|
||||
mod rt_sigaction;
|
||||
mod rt_sigpending;
|
||||
mod rt_sigprocmask;
|
||||
mod rt_sigreturn;
|
||||
mod rt_sigsuspend;
|
||||
mod sched_getaffinity;
|
||||
mod sched_yield;
|
||||
mod select;
|
||||
mod semctl;
|
||||
mod semget;
|
||||
mod semop;
|
||||
mod sendfile;
|
||||
mod sendmsg;
|
||||
mod sendto;
|
||||
mod set_get_priority;
|
||||
mod set_robust_list;
|
||||
mod set_tid_address;
|
||||
mod setfsgid;
|
||||
mod setfsuid;
|
||||
mod setgid;
|
||||
mod setgroups;
|
||||
mod setitimer;
|
||||
mod setpgid;
|
||||
mod setregid;
|
||||
mod setresgid;
|
||||
mod setresuid;
|
||||
mod setreuid;
|
||||
mod setsid;
|
||||
mod setsockopt;
|
||||
mod setuid;
|
||||
mod shutdown;
|
||||
mod sigaltstack;
|
||||
mod socket;
|
||||
mod socketpair;
|
||||
mod stat;
|
||||
mod statfs;
|
||||
mod symlink;
|
||||
mod sync;
|
||||
mod tgkill;
|
||||
mod time;
|
||||
mod timer_create;
|
||||
mod timer_settime;
|
||||
mod truncate;
|
||||
mod umask;
|
||||
mod umount;
|
||||
mod uname;
|
||||
mod unlink;
|
||||
mod utimens;
|
||||
mod wait4;
|
||||
mod waitid;
|
||||
mod write;
|
||||
|
||||
/// This macro is used to define syscall handler.
|
||||
/// The first param is ths number of parameters,
|
||||
/// The second param is the function name of syscall handler,
|
||||
/// The third is optional, means the args(if parameter number > 0),
|
||||
/// The third is optional, means if cpu ctx is required.
|
||||
macro_rules! syscall_handler {
|
||||
(0, $fn_name: ident, $args: ident, $ctx: expr) => {
|
||||
$fn_name($ctx)
|
||||
};
|
||||
(0, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => {
|
||||
$fn_name($ctx, $user_ctx)
|
||||
};
|
||||
|
||||
(1, $fn_name: ident, $args: ident, $ctx: expr) => {
|
||||
$fn_name($args[0] as _, $ctx)
|
||||
};
|
||||
(1, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => {
|
||||
$fn_name($args[0] as _, $ctx, $user_ctx)
|
||||
};
|
||||
|
||||
(2, $fn_name: ident, $args: ident, $ctx: expr) => {
|
||||
$fn_name($args[0] as _, $args[1] as _, $ctx)
|
||||
};
|
||||
(2, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => {
|
||||
$fn_name($args[0] as _, $args[1] as _, $ctx, $user_ctx)
|
||||
};
|
||||
|
||||
(3, $fn_name: ident, $args: ident, $ctx: expr) => {
|
||||
$fn_name($args[0] as _, $args[1] as _, $args[2] as _, $ctx)
|
||||
};
|
||||
(3, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => {
|
||||
$fn_name($args[0] as _, $args[1] as _, $args[2] as _, $ctx, $user_ctx)
|
||||
};
|
||||
|
||||
(4, $fn_name: ident, $args: ident, $ctx: expr) => {
|
||||
$fn_name(
|
||||
$args[0] as _,
|
||||
$args[1] as _,
|
||||
$args[2] as _,
|
||||
$args[3] as _,
|
||||
$ctx,
|
||||
)
|
||||
};
|
||||
(4, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => {
|
||||
$fn_name(
|
||||
$args[0] as _,
|
||||
$args[1] as _,
|
||||
$args[2] as _,
|
||||
$args[3] as _,
|
||||
$ctx,
|
||||
$user_ctx,
|
||||
)
|
||||
};
|
||||
|
||||
(5, $fn_name: ident, $args: ident, $ctx: expr) => {
|
||||
$fn_name(
|
||||
$args[0] as _,
|
||||
$args[1] as _,
|
||||
$args[2] as _,
|
||||
$args[3] as _,
|
||||
$args[4] as _,
|
||||
$ctx,
|
||||
)
|
||||
};
|
||||
(5, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => {
|
||||
$fn_name(
|
||||
$args[0] as _,
|
||||
$args[1] as _,
|
||||
$args[2] as _,
|
||||
$args[3] as _,
|
||||
$args[4] as _,
|
||||
$ctx,
|
||||
$user_ctx,
|
||||
)
|
||||
};
|
||||
|
||||
(6, $fn_name: ident, $args: ident, $ctx: expr) => {
|
||||
$fn_name(
|
||||
$args[0] as _,
|
||||
$args[1] as _,
|
||||
$args[2] as _,
|
||||
$args[3] as _,
|
||||
$args[4] as _,
|
||||
$args[5] as _,
|
||||
$ctx,
|
||||
)
|
||||
};
|
||||
(6, $fn_name: ident, $args: ident, $ctx: expr, $user_ctx: expr) => {
|
||||
$fn_name(
|
||||
$args[0] as _,
|
||||
$args[1] as _,
|
||||
$args[2] as _,
|
||||
$args[3] as _,
|
||||
$args[4] as _,
|
||||
$args[5] as _,
|
||||
$ctx,
|
||||
$user_ctx,
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! dispatch_fn_inner {
|
||||
( $args: ident, $ctx: ident, $user_ctx: ident, $handler: ident ( args[ .. $cnt: tt ] ) ) => {
|
||||
$crate::syscall::syscall_handler!($cnt, $handler, $args, $ctx)
|
||||
};
|
||||
( $args: ident, $ctx: ident, $user_ctx: ident, $handler: ident ( args[ .. $cnt: tt ] , &user_ctx ) ) => {
|
||||
$crate::syscall::syscall_handler!($cnt, $handler, $args, $ctx, &$user_ctx)
|
||||
};
|
||||
( $args: ident, $ctx: ident, $user_ctx: ident, $handler: ident ( args[ .. $cnt: tt ] , &mut user_ctx ) ) => {
|
||||
// `$user_ctx` is already of type `&mut ostd::cpu::UserContext`,
|
||||
// so no need to take `&mut` again
|
||||
$crate::syscall::syscall_handler!($cnt, $handler, $args, $ctx, $user_ctx)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_syscall_nums_and_dispatch_fn {
|
||||
// $args, $user_ctx, and $dispatcher_name are needed since Rust macro is hygienic
|
||||
( $( $name: ident = $num: literal => $handler: ident $args: tt );* $(;)? ) => {
|
||||
// First, define the syscall numbers
|
||||
$(
|
||||
pub const $name: u64 = $num;
|
||||
)*
|
||||
|
||||
// Then, define the dispatcher function
|
||||
pub fn syscall_dispatch(
|
||||
syscall_number: u64,
|
||||
args: [u64; 6],
|
||||
ctx: &crate::context::Context,
|
||||
user_ctx: &mut ostd::cpu::UserContext,
|
||||
) -> $crate::prelude::Result<$crate::syscall::SyscallReturn> {
|
||||
match syscall_number {
|
||||
$(
|
||||
$num => {
|
||||
$crate::log_syscall_entry!($name);
|
||||
$crate::syscall::dispatch_fn_inner!(args, ctx, user_ctx, $handler $args)
|
||||
}
|
||||
)*
|
||||
_ => {
|
||||
log::warn!("Unimplemented syscall number: {}", syscall_number);
|
||||
$crate::return_errno_with_message!($crate::error::Errno::ENOSYS, "Syscall was unimplemented");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Export macros to sub-modules
|
||||
use dispatch_fn_inner;
|
||||
use impl_syscall_nums_and_dispatch_fn;
|
||||
use syscall_handler;
|
||||
|
||||
pub struct SyscallArgument {
|
||||
syscall_number: u64,
|
||||
args: [u64; 6],
|
||||
}
|
||||
|
||||
/// Syscall return
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum SyscallReturn {
|
||||
/// return isize, this value will be used to set rax
|
||||
Return(isize),
|
||||
/// does not need to set rax
|
||||
NoReturn,
|
||||
}
|
||||
|
||||
impl SyscallArgument {
|
||||
fn new_from_context(user_ctx: &UserContext) -> Self {
|
||||
let syscall_number = user_ctx.syscall_num() as u64;
|
||||
let args = user_ctx.syscall_args().map(|x| x as u64);
|
||||
Self {
|
||||
syscall_number,
|
||||
args,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_syscall(ctx: &Context, user_ctx: &mut UserContext) {
|
||||
let syscall_frame = SyscallArgument::new_from_context(user_ctx);
|
||||
let syscall_return = arch::syscall_dispatch(
|
||||
syscall_frame.syscall_number,
|
||||
syscall_frame.args,
|
||||
ctx,
|
||||
user_ctx,
|
||||
);
|
||||
|
||||
match syscall_return {
|
||||
Ok(return_value) => {
|
||||
if let SyscallReturn::Return(return_value) = return_value {
|
||||
user_ctx.set_syscall_ret(return_value as usize);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
debug!("syscall return error: {:?}", err);
|
||||
let errno = err.error() as i32;
|
||||
user_ctx.set_syscall_ret((-errno) as usize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! log_syscall_entry {
|
||||
($syscall_name: tt) => {
|
||||
if log::log_enabled!(log::Level::Info) {
|
||||
let syscall_name_str = stringify!($syscall_name);
|
||||
let pid = $crate::current!().pid();
|
||||
let tid = $crate::current_thread!().tid();
|
||||
log::info!(
|
||||
"[pid={}][tid={}][id={}][{}]",
|
||||
pid,
|
||||
tid,
|
||||
$syscall_name,
|
||||
syscall_name_str
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user