xref: /DragonOS/kernel/src/arch/x86_64/syscall/mod.rs (revision 4fda81ce81939d83b74c8042d6fb4223deff3685)
1*4fda81ceSLoGin use core::ffi::c_void;
2*4fda81ceSLoGin 
3*4fda81ceSLoGin use crate::{
4*4fda81ceSLoGin     arch::{
5*4fda81ceSLoGin         ipc::signal::X86_64SignalArch,
6*4fda81ceSLoGin         syscall::nr::{SYS_ARCH_PRCTL, SYS_RT_SIGRETURN},
7*4fda81ceSLoGin         CurrentIrqArch,
8*4fda81ceSLoGin     },
9*4fda81ceSLoGin     exception::InterruptArch,
10*4fda81ceSLoGin     include::bindings::bindings::set_system_trap_gate,
11*4fda81ceSLoGin     ipc::signal_types::SignalArch,
12*4fda81ceSLoGin     libs::align::SafeForZero,
13*4fda81ceSLoGin     mm::VirtAddr,
14*4fda81ceSLoGin     process::ProcessManager,
15*4fda81ceSLoGin     syscall::{Syscall, SystemError, SYS_SCHED},
16*4fda81ceSLoGin };
17*4fda81ceSLoGin use alloc::string::String;
18*4fda81ceSLoGin 
19*4fda81ceSLoGin use super::{interrupt::TrapFrame, mm::barrier::mfence};
20*4fda81ceSLoGin 
21*4fda81ceSLoGin pub mod nr;
22*4fda81ceSLoGin 
23*4fda81ceSLoGin /// ### 存储PCB系统调用栈以及在syscall过程中暂存用户态rsp的结构体
24*4fda81ceSLoGin ///
25*4fda81ceSLoGin /// 在syscall指令中将会从该结构体中读取系统调用栈和暂存rsp,
26*4fda81ceSLoGin /// 使用`gsbase`寄存器实现,后续如果需要使用gsbase寄存器,需要相应设置正确的偏移量
27*4fda81ceSLoGin #[repr(C)]
28*4fda81ceSLoGin #[derive(Debug, Clone)]
29*4fda81ceSLoGin pub(super) struct X86_64GSData {
30*4fda81ceSLoGin     pub(super) kaddr: VirtAddr,
31*4fda81ceSLoGin     pub(super) uaddr: VirtAddr,
32*4fda81ceSLoGin }
33*4fda81ceSLoGin 
34*4fda81ceSLoGin impl X86_64GSData {
35*4fda81ceSLoGin     /// ### 设置系统调用栈,将会在下一个调度后写入KernelGsbase
36*4fda81ceSLoGin     pub fn set_kstack(&mut self, kstack: VirtAddr) {
37*4fda81ceSLoGin         self.kaddr = kstack;
38*4fda81ceSLoGin     }
39*4fda81ceSLoGin }
40*4fda81ceSLoGin 
41*4fda81ceSLoGin unsafe impl SafeForZero for X86_64GSData {}
42*4fda81ceSLoGin 
43*4fda81ceSLoGin extern "C" {
44*4fda81ceSLoGin     fn syscall_int();
45*4fda81ceSLoGin     fn syscall_64();
46*4fda81ceSLoGin }
47*4fda81ceSLoGin 
48*4fda81ceSLoGin macro_rules! syscall_return {
49*4fda81ceSLoGin     ($val:expr, $regs:expr, $show:expr) => {{
50*4fda81ceSLoGin         let ret = $val;
51*4fda81ceSLoGin         $regs.rax = ret as u64;
52*4fda81ceSLoGin 
53*4fda81ceSLoGin         if $show {
54*4fda81ceSLoGin             let pid = ProcessManager::current_pcb().pid();
55*4fda81ceSLoGin             crate::kdebug!("syscall return:pid={:?},ret= {:?}\n", pid, ret as isize);
56*4fda81ceSLoGin         }
57*4fda81ceSLoGin 
58*4fda81ceSLoGin         unsafe {
59*4fda81ceSLoGin             CurrentIrqArch::interrupt_disable();
60*4fda81ceSLoGin         }
61*4fda81ceSLoGin         return;
62*4fda81ceSLoGin     }};
63*4fda81ceSLoGin }
64*4fda81ceSLoGin 
65*4fda81ceSLoGin #[no_mangle]
66*4fda81ceSLoGin pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) -> () {
67*4fda81ceSLoGin     let syscall_num = frame.rax as usize;
68*4fda81ceSLoGin     // 防止sys_sched由于超时无法退出导致的死锁
69*4fda81ceSLoGin     if syscall_num != SYS_SCHED {
70*4fda81ceSLoGin         unsafe {
71*4fda81ceSLoGin             CurrentIrqArch::interrupt_enable();
72*4fda81ceSLoGin         }
73*4fda81ceSLoGin     }
74*4fda81ceSLoGin 
75*4fda81ceSLoGin     let args = [
76*4fda81ceSLoGin         frame.rdi as usize,
77*4fda81ceSLoGin         frame.rsi as usize,
78*4fda81ceSLoGin         frame.rdx as usize,
79*4fda81ceSLoGin         frame.r10 as usize,
80*4fda81ceSLoGin         frame.r8 as usize,
81*4fda81ceSLoGin         frame.r9 as usize,
82*4fda81ceSLoGin     ];
83*4fda81ceSLoGin     mfence();
84*4fda81ceSLoGin     let pid = ProcessManager::current_pcb().pid();
85*4fda81ceSLoGin     let show = false;
86*4fda81ceSLoGin     // let show = if syscall_num != SYS_SCHED && pid.data() > 3 {
87*4fda81ceSLoGin     //     true
88*4fda81ceSLoGin     // } else {
89*4fda81ceSLoGin     //     false
90*4fda81ceSLoGin     // };
91*4fda81ceSLoGin 
92*4fda81ceSLoGin     if show {
93*4fda81ceSLoGin         crate::kdebug!("syscall: pid: {:?}, num={:?}\n", pid, syscall_num);
94*4fda81ceSLoGin     }
95*4fda81ceSLoGin 
96*4fda81ceSLoGin     // Arch specific syscall
97*4fda81ceSLoGin     match syscall_num {
98*4fda81ceSLoGin         SYS_RT_SIGRETURN => {
99*4fda81ceSLoGin             syscall_return!(
100*4fda81ceSLoGin                 X86_64SignalArch::sys_rt_sigreturn(frame) as usize,
101*4fda81ceSLoGin                 frame,
102*4fda81ceSLoGin                 show
103*4fda81ceSLoGin             );
104*4fda81ceSLoGin         }
105*4fda81ceSLoGin         SYS_ARCH_PRCTL => {
106*4fda81ceSLoGin             syscall_return!(
107*4fda81ceSLoGin                 Syscall::arch_prctl(args[0], args[1])
108*4fda81ceSLoGin                     .unwrap_or_else(|e| e.to_posix_errno() as usize),
109*4fda81ceSLoGin                 frame,
110*4fda81ceSLoGin                 show
111*4fda81ceSLoGin             );
112*4fda81ceSLoGin         }
113*4fda81ceSLoGin         _ => {}
114*4fda81ceSLoGin     }
115*4fda81ceSLoGin     syscall_return!(
116*4fda81ceSLoGin         Syscall::handle(syscall_num, &args, frame).unwrap_or_else(|e| e.to_posix_errno() as usize)
117*4fda81ceSLoGin             as u64,
118*4fda81ceSLoGin         frame,
119*4fda81ceSLoGin         show
120*4fda81ceSLoGin     );
121*4fda81ceSLoGin }
122*4fda81ceSLoGin 
123*4fda81ceSLoGin /// 系统调用初始化
124*4fda81ceSLoGin pub fn arch_syscall_init() -> Result<(), SystemError> {
125*4fda81ceSLoGin     // kinfo!("arch_syscall_init\n");
126*4fda81ceSLoGin     unsafe { set_system_trap_gate(0x80, 0, syscall_int as *mut c_void) }; // 系统调用门
127*4fda81ceSLoGin     unsafe { init_syscall_64() };
128*4fda81ceSLoGin     return Ok(());
129*4fda81ceSLoGin }
130*4fda81ceSLoGin 
131*4fda81ceSLoGin /// 执行第一个用户进程的函数(只应该被调用一次)
132*4fda81ceSLoGin ///
133*4fda81ceSLoGin /// 当进程管理重构完成后,这个函数应该被删除。调整为别的函数。
134*4fda81ceSLoGin #[no_mangle]
135*4fda81ceSLoGin pub extern "C" fn rs_exec_init_process(frame: &mut TrapFrame) -> usize {
136*4fda81ceSLoGin     let path = String::from("/bin/shell.elf");
137*4fda81ceSLoGin     let argv = vec![String::from("/bin/shell.elf")];
138*4fda81ceSLoGin     let envp = vec![String::from("PATH=/bin")];
139*4fda81ceSLoGin     let r = Syscall::do_execve(path, argv, envp, frame);
140*4fda81ceSLoGin     // kdebug!("rs_exec_init_process: r: {:?}\n", r);
141*4fda81ceSLoGin     return r.map(|_| 0).unwrap_or_else(|e| e.to_posix_errno() as usize);
142*4fda81ceSLoGin }
143*4fda81ceSLoGin 
144*4fda81ceSLoGin /// syscall指令初始化函数
145*4fda81ceSLoGin pub(super) unsafe fn init_syscall_64() {
146*4fda81ceSLoGin     let mut efer = x86::msr::rdmsr(x86::msr::IA32_EFER);
147*4fda81ceSLoGin     efer |= 0x1;
148*4fda81ceSLoGin     x86::msr::wrmsr(x86::msr::IA32_EFER, efer);
149*4fda81ceSLoGin 
150*4fda81ceSLoGin     let syscall_base = (1 as u16) << 3;
151*4fda81ceSLoGin     let sysret_base = ((4 as u16) << 3) | 3;
152*4fda81ceSLoGin     let high = (u32::from(sysret_base) << 16) | u32::from(syscall_base);
153*4fda81ceSLoGin     // 初始化STAR寄存器
154*4fda81ceSLoGin     x86::msr::wrmsr(x86::msr::IA32_STAR, u64::from(high) << 32);
155*4fda81ceSLoGin 
156*4fda81ceSLoGin     // 初始化LSTAR,该寄存器存储syscall指令入口
157*4fda81ceSLoGin     x86::msr::wrmsr(x86::msr::IA32_LSTAR, syscall_64 as u64);
158*4fda81ceSLoGin     x86::msr::wrmsr(x86::msr::IA32_FMASK, 0xfffffffe);
159*4fda81ceSLoGin }
160