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