xref: /DragonOS/kernel/src/arch/x86_64/syscall/mod.rs (revision 91e9d4ab55ef960f57a1b6287bc523ca4341f67a)
14fda81ceSLoGin use core::ffi::c_void;
24fda81ceSLoGin 
34fda81ceSLoGin use crate::{
44fda81ceSLoGin     arch::{
54fda81ceSLoGin         ipc::signal::X86_64SignalArch,
64fda81ceSLoGin         syscall::nr::{SYS_ARCH_PRCTL, SYS_RT_SIGRETURN},
74fda81ceSLoGin         CurrentIrqArch,
84fda81ceSLoGin     },
94fda81ceSLoGin     exception::InterruptArch,
104fda81ceSLoGin     include::bindings::bindings::set_system_trap_gate,
114fda81ceSLoGin     ipc::signal_types::SignalArch,
124fda81ceSLoGin     libs::align::SafeForZero,
134fda81ceSLoGin     mm::VirtAddr,
144fda81ceSLoGin     process::ProcessManager,
15*91e9d4abSLoGin     syscall::{Syscall, SYS_SCHED},
164fda81ceSLoGin };
174fda81ceSLoGin use alloc::string::String;
18*91e9d4abSLoGin use system_error::SystemError;
194fda81ceSLoGin 
204fda81ceSLoGin use super::{interrupt::TrapFrame, mm::barrier::mfence};
214fda81ceSLoGin 
224fda81ceSLoGin pub mod nr;
234fda81ceSLoGin 
244fda81ceSLoGin /// ### 存储PCB系统调用栈以及在syscall过程中暂存用户态rsp的结构体
254fda81ceSLoGin ///
264fda81ceSLoGin /// 在syscall指令中将会从该结构体中读取系统调用栈和暂存rsp,
274fda81ceSLoGin /// 使用`gsbase`寄存器实现,后续如果需要使用gsbase寄存器,需要相应设置正确的偏移量
284fda81ceSLoGin #[repr(C)]
294fda81ceSLoGin #[derive(Debug, Clone)]
304fda81ceSLoGin pub(super) struct X86_64GSData {
314fda81ceSLoGin     pub(super) kaddr: VirtAddr,
324fda81ceSLoGin     pub(super) uaddr: VirtAddr,
334fda81ceSLoGin }
344fda81ceSLoGin 
354fda81ceSLoGin impl X86_64GSData {
364fda81ceSLoGin     /// ### 设置系统调用栈,将会在下一个调度后写入KernelGsbase
374fda81ceSLoGin     pub fn set_kstack(&mut self, kstack: VirtAddr) {
384fda81ceSLoGin         self.kaddr = kstack;
394fda81ceSLoGin     }
404fda81ceSLoGin }
414fda81ceSLoGin 
424fda81ceSLoGin unsafe impl SafeForZero for X86_64GSData {}
434fda81ceSLoGin 
444fda81ceSLoGin extern "C" {
454fda81ceSLoGin     fn syscall_int();
464fda81ceSLoGin     fn syscall_64();
474fda81ceSLoGin }
484fda81ceSLoGin 
494fda81ceSLoGin macro_rules! syscall_return {
504fda81ceSLoGin     ($val:expr, $regs:expr, $show:expr) => {{
514fda81ceSLoGin         let ret = $val;
524fda81ceSLoGin         $regs.rax = ret as u64;
534fda81ceSLoGin 
544fda81ceSLoGin         if $show {
554fda81ceSLoGin             let pid = ProcessManager::current_pcb().pid();
564fda81ceSLoGin             crate::kdebug!("syscall return:pid={:?},ret= {:?}\n", pid, ret as isize);
574fda81ceSLoGin         }
584fda81ceSLoGin 
594fda81ceSLoGin         unsafe {
604fda81ceSLoGin             CurrentIrqArch::interrupt_disable();
614fda81ceSLoGin         }
624fda81ceSLoGin         return;
634fda81ceSLoGin     }};
644fda81ceSLoGin }
654fda81ceSLoGin 
664fda81ceSLoGin #[no_mangle]
674fda81ceSLoGin pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) -> () {
684fda81ceSLoGin     let syscall_num = frame.rax as usize;
694fda81ceSLoGin     // 防止sys_sched由于超时无法退出导致的死锁
704fda81ceSLoGin     if syscall_num != SYS_SCHED {
714fda81ceSLoGin         unsafe {
724fda81ceSLoGin             CurrentIrqArch::interrupt_enable();
734fda81ceSLoGin         }
744fda81ceSLoGin     }
754fda81ceSLoGin 
764fda81ceSLoGin     let args = [
774fda81ceSLoGin         frame.rdi as usize,
784fda81ceSLoGin         frame.rsi as usize,
794fda81ceSLoGin         frame.rdx as usize,
804fda81ceSLoGin         frame.r10 as usize,
814fda81ceSLoGin         frame.r8 as usize,
824fda81ceSLoGin         frame.r9 as usize,
834fda81ceSLoGin     ];
844fda81ceSLoGin     mfence();
854fda81ceSLoGin     let pid = ProcessManager::current_pcb().pid();
864fda81ceSLoGin     let show = false;
874fda81ceSLoGin     // let show = if syscall_num != SYS_SCHED && pid.data() > 3 {
884fda81ceSLoGin     //     true
894fda81ceSLoGin     // } else {
904fda81ceSLoGin     //     false
914fda81ceSLoGin     // };
924fda81ceSLoGin 
934fda81ceSLoGin     if show {
944fda81ceSLoGin         crate::kdebug!("syscall: pid: {:?}, num={:?}\n", pid, syscall_num);
954fda81ceSLoGin     }
964fda81ceSLoGin 
974fda81ceSLoGin     // Arch specific syscall
984fda81ceSLoGin     match syscall_num {
994fda81ceSLoGin         SYS_RT_SIGRETURN => {
1004fda81ceSLoGin             syscall_return!(
1014fda81ceSLoGin                 X86_64SignalArch::sys_rt_sigreturn(frame) as usize,
1024fda81ceSLoGin                 frame,
1034fda81ceSLoGin                 show
1044fda81ceSLoGin             );
1054fda81ceSLoGin         }
1064fda81ceSLoGin         SYS_ARCH_PRCTL => {
1074fda81ceSLoGin             syscall_return!(
1084fda81ceSLoGin                 Syscall::arch_prctl(args[0], args[1])
1094fda81ceSLoGin                     .unwrap_or_else(|e| e.to_posix_errno() as usize),
1104fda81ceSLoGin                 frame,
1114fda81ceSLoGin                 show
1124fda81ceSLoGin             );
1134fda81ceSLoGin         }
1144fda81ceSLoGin         _ => {}
1154fda81ceSLoGin     }
1164fda81ceSLoGin     syscall_return!(
1174fda81ceSLoGin         Syscall::handle(syscall_num, &args, frame).unwrap_or_else(|e| e.to_posix_errno() as usize)
1184fda81ceSLoGin             as u64,
1194fda81ceSLoGin         frame,
1204fda81ceSLoGin         show
1214fda81ceSLoGin     );
1224fda81ceSLoGin }
1234fda81ceSLoGin 
1244fda81ceSLoGin /// 系统调用初始化
1254fda81ceSLoGin pub fn arch_syscall_init() -> Result<(), SystemError> {
1264fda81ceSLoGin     // kinfo!("arch_syscall_init\n");
1274fda81ceSLoGin     unsafe { set_system_trap_gate(0x80, 0, syscall_int as *mut c_void) }; // 系统调用门
1284fda81ceSLoGin     unsafe { init_syscall_64() };
1294fda81ceSLoGin     return Ok(());
1304fda81ceSLoGin }
1314fda81ceSLoGin 
1324fda81ceSLoGin /// 执行第一个用户进程的函数(只应该被调用一次)
1334fda81ceSLoGin ///
1344fda81ceSLoGin /// 当进程管理重构完成后,这个函数应该被删除。调整为别的函数。
1354fda81ceSLoGin #[no_mangle]
1364fda81ceSLoGin pub extern "C" fn rs_exec_init_process(frame: &mut TrapFrame) -> usize {
1374fda81ceSLoGin     let path = String::from("/bin/shell.elf");
1384fda81ceSLoGin     let argv = vec![String::from("/bin/shell.elf")];
1394fda81ceSLoGin     let envp = vec![String::from("PATH=/bin")];
1404fda81ceSLoGin     let r = Syscall::do_execve(path, argv, envp, frame);
1414fda81ceSLoGin     // kdebug!("rs_exec_init_process: r: {:?}\n", r);
1424fda81ceSLoGin     return r.map(|_| 0).unwrap_or_else(|e| e.to_posix_errno() as usize);
1434fda81ceSLoGin }
1444fda81ceSLoGin 
1454fda81ceSLoGin /// syscall指令初始化函数
1464fda81ceSLoGin pub(super) unsafe fn init_syscall_64() {
1474fda81ceSLoGin     let mut efer = x86::msr::rdmsr(x86::msr::IA32_EFER);
1484fda81ceSLoGin     efer |= 0x1;
1494fda81ceSLoGin     x86::msr::wrmsr(x86::msr::IA32_EFER, efer);
1504fda81ceSLoGin 
1514fda81ceSLoGin     let syscall_base = (1 as u16) << 3;
1524fda81ceSLoGin     let sysret_base = ((4 as u16) << 3) | 3;
1534fda81ceSLoGin     let high = (u32::from(sysret_base) << 16) | u32::from(syscall_base);
1544fda81ceSLoGin     // 初始化STAR寄存器
1554fda81ceSLoGin     x86::msr::wrmsr(x86::msr::IA32_STAR, u64::from(high) << 32);
1564fda81ceSLoGin 
1574fda81ceSLoGin     // 初始化LSTAR,该寄存器存储syscall指令入口
1584fda81ceSLoGin     x86::msr::wrmsr(x86::msr::IA32_LSTAR, syscall_64 as u64);
1594fda81ceSLoGin     x86::msr::wrmsr(x86::msr::IA32_FMASK, 0xfffffffe);
1604fda81ceSLoGin }
161