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