14fda81ceSLoGin use crate::{ 24fda81ceSLoGin arch::{ 34fda81ceSLoGin ipc::signal::X86_64SignalArch, 44fda81ceSLoGin syscall::nr::{SYS_ARCH_PRCTL, SYS_RT_SIGRETURN}, 54fda81ceSLoGin CurrentIrqArch, 64fda81ceSLoGin }, 74fda81ceSLoGin exception::InterruptArch, 84fda81ceSLoGin ipc::signal_types::SignalArch, 94fda81ceSLoGin libs::align::SafeForZero, 104fda81ceSLoGin mm::VirtAddr, 114fda81ceSLoGin process::ProcessManager, 1291e9d4abSLoGin syscall::{Syscall, SYS_SCHED}, 134fda81ceSLoGin }; 144fda81ceSLoGin use alloc::string::String; 1591e9d4abSLoGin use system_error::SystemError; 164fda81ceSLoGin 17f2022a8aSLoGin use super::{ 18f2022a8aSLoGin interrupt::{entry::set_system_trap_gate, TrapFrame}, 19f2022a8aSLoGin mm::barrier::mfence, 20f2022a8aSLoGin }; 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] 67*b5b571e0SLoGin pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) { 684fda81ceSLoGin let syscall_num = frame.rax as usize; 694fda81ceSLoGin // 防止sys_sched由于超时无法退出导致的死锁 700d6cf65aSLoGin if syscall_num == SYS_SCHED { 710d6cf65aSLoGin unsafe { 720d6cf65aSLoGin CurrentIrqArch::interrupt_disable(); 730d6cf65aSLoGin } 740d6cf65aSLoGin } else { 754fda81ceSLoGin unsafe { 764fda81ceSLoGin CurrentIrqArch::interrupt_enable(); 774fda81ceSLoGin } 784fda81ceSLoGin } 794fda81ceSLoGin 804fda81ceSLoGin let args = [ 814fda81ceSLoGin frame.rdi as usize, 824fda81ceSLoGin frame.rsi as usize, 834fda81ceSLoGin frame.rdx as usize, 844fda81ceSLoGin frame.r10 as usize, 854fda81ceSLoGin frame.r8 as usize, 864fda81ceSLoGin frame.r9 as usize, 874fda81ceSLoGin ]; 884fda81ceSLoGin mfence(); 894fda81ceSLoGin let pid = ProcessManager::current_pcb().pid(); 904fda81ceSLoGin let show = false; 914fda81ceSLoGin // let show = if syscall_num != SYS_SCHED && pid.data() > 3 { 924fda81ceSLoGin // true 934fda81ceSLoGin // } else { 944fda81ceSLoGin // false 954fda81ceSLoGin // }; 964fda81ceSLoGin 974fda81ceSLoGin if show { 984fda81ceSLoGin crate::kdebug!("syscall: pid: {:?}, num={:?}\n", pid, syscall_num); 994fda81ceSLoGin } 1004fda81ceSLoGin 1014fda81ceSLoGin // Arch specific syscall 1024fda81ceSLoGin match syscall_num { 1034fda81ceSLoGin SYS_RT_SIGRETURN => { 1044fda81ceSLoGin syscall_return!( 1054fda81ceSLoGin X86_64SignalArch::sys_rt_sigreturn(frame) as usize, 1064fda81ceSLoGin frame, 1074fda81ceSLoGin show 1084fda81ceSLoGin ); 1094fda81ceSLoGin } 1104fda81ceSLoGin SYS_ARCH_PRCTL => { 1114fda81ceSLoGin syscall_return!( 1124fda81ceSLoGin Syscall::arch_prctl(args[0], args[1]) 1134fda81ceSLoGin .unwrap_or_else(|e| e.to_posix_errno() as usize), 1144fda81ceSLoGin frame, 1154fda81ceSLoGin show 1164fda81ceSLoGin ); 1174fda81ceSLoGin } 1184fda81ceSLoGin _ => {} 1194fda81ceSLoGin } 1204fda81ceSLoGin syscall_return!( 1214fda81ceSLoGin Syscall::handle(syscall_num, &args, frame).unwrap_or_else(|e| e.to_posix_errno() as usize) 1224fda81ceSLoGin as u64, 1234fda81ceSLoGin frame, 1244fda81ceSLoGin show 1254fda81ceSLoGin ); 1264fda81ceSLoGin } 1274fda81ceSLoGin 1284fda81ceSLoGin /// 系统调用初始化 1294fda81ceSLoGin pub fn arch_syscall_init() -> Result<(), SystemError> { 1304fda81ceSLoGin // kinfo!("arch_syscall_init\n"); 131f2022a8aSLoGin unsafe { set_system_trap_gate(0x80, 0, VirtAddr::new(syscall_int as usize)) }; // 系统调用门 1324fda81ceSLoGin unsafe { init_syscall_64() }; 1334fda81ceSLoGin return Ok(()); 1344fda81ceSLoGin } 1354fda81ceSLoGin 1364fda81ceSLoGin /// 执行第一个用户进程的函数(只应该被调用一次) 1374fda81ceSLoGin /// 1384fda81ceSLoGin /// 当进程管理重构完成后,这个函数应该被删除。调整为别的函数。 1394fda81ceSLoGin #[no_mangle] 1404fda81ceSLoGin pub extern "C" fn rs_exec_init_process(frame: &mut TrapFrame) -> usize { 1414fda81ceSLoGin let path = String::from("/bin/shell.elf"); 1424fda81ceSLoGin let argv = vec![String::from("/bin/shell.elf")]; 1434fda81ceSLoGin let envp = vec![String::from("PATH=/bin")]; 1444fda81ceSLoGin let r = Syscall::do_execve(path, argv, envp, frame); 1454fda81ceSLoGin // kdebug!("rs_exec_init_process: r: {:?}\n", r); 1464fda81ceSLoGin return r.map(|_| 0).unwrap_or_else(|e| e.to_posix_errno() as usize); 1474fda81ceSLoGin } 1484fda81ceSLoGin 1494fda81ceSLoGin /// syscall指令初始化函数 1504fda81ceSLoGin pub(super) unsafe fn init_syscall_64() { 1514fda81ceSLoGin let mut efer = x86::msr::rdmsr(x86::msr::IA32_EFER); 1524fda81ceSLoGin efer |= 0x1; 1534fda81ceSLoGin x86::msr::wrmsr(x86::msr::IA32_EFER, efer); 1544fda81ceSLoGin 155*b5b571e0SLoGin let syscall_base = (1_u16) << 3; 156*b5b571e0SLoGin let sysret_base = ((4_u16) << 3) | 3; 1574fda81ceSLoGin let high = (u32::from(sysret_base) << 16) | u32::from(syscall_base); 1584fda81ceSLoGin // 初始化STAR寄存器 1594fda81ceSLoGin x86::msr::wrmsr(x86::msr::IA32_STAR, u64::from(high) << 32); 1604fda81ceSLoGin 1614fda81ceSLoGin // 初始化LSTAR,该寄存器存储syscall指令入口 162*b5b571e0SLoGin x86::msr::wrmsr(x86::msr::IA32_LSTAR, syscall_64 as usize as u64); 1634fda81ceSLoGin x86::msr::wrmsr(x86::msr::IA32_FMASK, 0xfffffffe); 1644fda81ceSLoGin } 165