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