starry/
syscall.rs

1use axerrno::LinuxError;
2use axhal::{
3    arch::TrapFrame,
4    trap::{SYSCALL, register_trap_handler},
5};
6use starry_api::*;
7use starry_core::task::{time_stat_from_kernel_to_user, time_stat_from_user_to_kernel};
8use syscalls::Sysno;
9
10#[register_trap_handler(SYSCALL)]
11fn handle_syscall(tf: &mut TrapFrame, syscall_num: usize) -> isize {
12    let sysno = Sysno::from(syscall_num as u32);
13    info!("Syscall {}", sysno);
14    time_stat_from_user_to_kernel();
15    let result = match sysno {
16        // fs ctl
17        Sysno::ioctl => sys_ioctl(tf.arg0() as _, tf.arg1() as _, tf.arg2().into()),
18        Sysno::chdir => sys_chdir(tf.arg0().into()),
19        Sysno::mkdirat => sys_mkdirat(tf.arg0() as _, tf.arg1().into(), tf.arg2() as _),
20        Sysno::getdents64 => sys_getdents64(tf.arg0() as _, tf.arg1().into(), tf.arg2() as _),
21        Sysno::linkat => sys_linkat(
22            tf.arg0() as _,
23            tf.arg1().into(),
24            tf.arg2() as _,
25            tf.arg3().into(),
26            tf.arg4() as _,
27        ),
28        #[cfg(target_arch = "x86_64")]
29        Sysno::link => sys_link(tf.arg0().into(), tf.arg1().into()),
30        Sysno::unlinkat => sys_unlinkat(tf.arg0() as _, tf.arg1().into(), tf.arg2() as _),
31        #[cfg(target_arch = "x86_64")]
32        Sysno::unlink => sys_unlink(tf.arg0().into()),
33        Sysno::getcwd => sys_getcwd(tf.arg0().into(), tf.arg1() as _),
34
35        // fd ops
36        Sysno::openat => sys_openat(
37            tf.arg0() as _,
38            tf.arg1().into(),
39            tf.arg2() as _,
40            tf.arg3() as _,
41        ),
42        #[cfg(target_arch = "x86_64")]
43        Sysno::open => sys_open(tf.arg0().into(), tf.arg1() as _, tf.arg2() as _),
44        Sysno::close => sys_close(tf.arg0() as _),
45        Sysno::dup => sys_dup(tf.arg0() as _),
46        #[cfg(target_arch = "x86_64")]
47        Sysno::dup2 => sys_dup2(tf.arg0() as _, tf.arg1() as _),
48        Sysno::dup3 => sys_dup2(tf.arg0() as _, tf.arg1() as _),
49        Sysno::fcntl => sys_fcntl(tf.arg0() as _, tf.arg1() as _, tf.arg2() as _),
50
51        // io
52        Sysno::read => sys_read(tf.arg0() as _, tf.arg1().into(), tf.arg2() as _),
53        Sysno::readv => sys_readv(tf.arg0() as _, tf.arg1().into(), tf.arg2() as _),
54        Sysno::write => sys_write(tf.arg0() as _, tf.arg1().into(), tf.arg2() as _),
55        Sysno::writev => sys_writev(tf.arg0() as _, tf.arg1().into(), tf.arg2() as _),
56        Sysno::lseek => sys_lseek(tf.arg0() as _, tf.arg1() as _, tf.arg2() as _),
57
58        // fs mount
59        Sysno::mount => sys_mount(
60            tf.arg0().into(),
61            tf.arg1().into(),
62            tf.arg2().into(),
63            tf.arg3() as _,
64            tf.arg4().into(),
65        ) as _,
66        Sysno::umount2 => sys_umount2(tf.arg0().into(), tf.arg1() as _) as _,
67
68        // pipe
69        Sysno::pipe2 => sys_pipe2(tf.arg0().into(), tf.arg1() as _),
70        #[cfg(target_arch = "x86_64")]
71        Sysno::pipe => sys_pipe2(tf.arg0().into(), 0),
72
73        // fs stat
74        #[cfg(target_arch = "x86_64")]
75        Sysno::stat => sys_stat(tf.arg0().into(), tf.arg1().into()),
76        Sysno::fstat => sys_fstat(tf.arg0() as _, tf.arg1().into()),
77        #[cfg(target_arch = "x86_64")]
78        Sysno::lstat => sys_lstat(tf.arg0().into(), tf.arg1().into()),
79        #[cfg(target_arch = "x86_64")]
80        Sysno::newfstatat => sys_fstatat(
81            tf.arg0() as _,
82            tf.arg1().into(),
83            tf.arg2().into(),
84            tf.arg3() as _,
85        ),
86        #[cfg(not(target_arch = "x86_64"))]
87        Sysno::fstatat => sys_fstatat(
88            tf.arg0() as _,
89            tf.arg1().into(),
90            tf.arg2().into(),
91            tf.arg3() as _,
92        ),
93        Sysno::statx => sys_statx(
94            tf.arg0() as _,
95            tf.arg1().into(),
96            tf.arg2() as _,
97            tf.arg3() as _,
98            tf.arg4().into(),
99        ),
100
101        // mm
102        Sysno::brk => sys_brk(tf.arg0() as _),
103        Sysno::mmap => sys_mmap(
104            tf.arg0(),
105            tf.arg1() as _,
106            tf.arg2() as _,
107            tf.arg3() as _,
108            tf.arg4() as _,
109            tf.arg5() as _,
110        ),
111        Sysno::munmap => sys_munmap(tf.arg0(), tf.arg1() as _),
112        Sysno::mprotect => sys_mprotect(tf.arg0(), tf.arg1() as _, tf.arg2() as _),
113
114        // task info
115        Sysno::getpid => sys_getpid(),
116        Sysno::getppid => sys_getppid(),
117        Sysno::gettid => sys_gettid(),
118
119        // task sched
120        Sysno::sched_yield => sys_sched_yield(),
121        Sysno::nanosleep => sys_nanosleep(tf.arg0().into(), tf.arg1().into()),
122
123        // task ops
124        Sysno::execve => sys_execve(tf, tf.arg0().into(), tf.arg1().into(), tf.arg2().into()),
125        Sysno::set_tid_address => sys_set_tid_address(tf.arg0()),
126        #[cfg(target_arch = "x86_64")]
127        Sysno::arch_prctl => sys_arch_prctl(tf, tf.arg0() as _, tf.arg1() as _),
128
129        // task management
130        Sysno::clone => sys_clone(
131            tf,
132            tf.arg0() as _,
133            tf.arg1() as _,
134            tf.arg2(),
135            tf.arg3(),
136            tf.arg4(),
137        ),
138        #[cfg(target_arch = "x86_64")]
139        Sysno::fork => sys_fork(tf),
140        Sysno::exit => sys_exit(tf.arg0() as _),
141        Sysno::exit_group => sys_exit_group(tf.arg0() as _),
142        Sysno::wait4 => sys_waitpid(tf.arg0() as _, tf.arg1().into(), tf.arg2() as _),
143
144        // signal
145        Sysno::rt_sigprocmask => sys_rt_sigprocmask(
146            tf.arg0() as _,
147            tf.arg1().into(),
148            tf.arg2().into(),
149            tf.arg3() as _,
150        ),
151        Sysno::rt_sigaction => sys_rt_sigaction(
152            tf.arg0() as _,
153            tf.arg1().into(),
154            tf.arg2().into(),
155            tf.arg3() as _,
156        ),
157        Sysno::rt_sigpending => sys_rt_sigpending(tf.arg0().into(), tf.arg1() as _),
158        Sysno::rt_sigreturn => sys_rt_sigreturn(tf),
159        Sysno::rt_sigtimedwait => sys_rt_sigtimedwait(
160            tf.arg0().into(),
161            tf.arg1().into(),
162            tf.arg2().into(),
163            tf.arg3() as _,
164        ),
165        Sysno::rt_sigsuspend => sys_rt_sigsuspend(tf, tf.arg0().into(), tf.arg1() as _),
166        Sysno::kill => sys_kill(tf.arg0() as _, tf.arg1() as _),
167        Sysno::tkill => sys_tkill(tf.arg0() as _, tf.arg1() as _),
168        Sysno::tgkill => sys_tgkill(tf.arg0() as _, tf.arg1() as _, tf.arg2() as _),
169        Sysno::rt_sigqueueinfo => sys_rt_sigqueueinfo(
170            tf.arg0() as _,
171            tf.arg1() as _,
172            tf.arg2().into(),
173            tf.arg3() as _,
174        ),
175        Sysno::rt_tgsigqueueinfo => sys_rt_tgsigqueueinfo(
176            tf.arg0() as _,
177            tf.arg1() as _,
178            tf.arg2() as _,
179            tf.arg3().into(),
180            tf.arg4() as _,
181        ),
182        Sysno::sigaltstack => sys_sigaltstack(tf.arg0().into(), tf.arg1().into()),
183        Sysno::futex => sys_futex(
184            tf.arg0().into(),
185            tf.arg1() as _,
186            tf.arg2() as _,
187            tf.arg3().into(),
188            tf.arg4().into(),
189            tf.arg5() as _,
190        ),
191
192        // sys
193        Sysno::getuid => sys_getuid(),
194        Sysno::geteuid => sys_geteuid(),
195        Sysno::getgid => sys_getgid(),
196        Sysno::getegid => sys_getegid(),
197        Sysno::uname => sys_uname(tf.arg0().into()),
198
199        // time
200        Sysno::gettimeofday => sys_gettimeofday(tf.arg0().into()),
201        Sysno::times => sys_times(tf.arg0().into()),
202        Sysno::clock_gettime => sys_clock_gettime(tf.arg0() as _, tf.arg1().into()),
203
204        _ => {
205            warn!("Unimplemented syscall: {}", sysno);
206            Err(LinuxError::ENOSYS)
207        }
208    };
209    let ans = result.unwrap_or_else(|err| -err.code() as _);
210    time_stat_from_kernel_to_user();
211    info!("Syscall {:?} return {}", sysno, ans);
212    ans
213}