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 };
14*2eab6dd7S曾俊 use log::debug;
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
set_kstack(&mut self, kstack: VirtAddr)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" {
syscall_int()454fda81ceSLoGin fn syscall_int();
syscall_64()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();
56*2eab6dd7S曾俊 debug!("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]
syscall_handler(frame: &mut TrapFrame)67b5b571e0SLoGin 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;
91d623e902SGnoCiYeH // let show = if syscall_num != SYS_SCHED && pid.data() >= 7 {
924fda81ceSLoGin // true
934fda81ceSLoGin // } else {
944fda81ceSLoGin // false
954fda81ceSLoGin // };
964fda81ceSLoGin
974fda81ceSLoGin if show {
98*2eab6dd7S曾俊 debug!("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 /// 系统调用初始化
arch_syscall_init() -> Result<(), SystemError>1294fda81ceSLoGin pub fn arch_syscall_init() -> Result<(), SystemError> {
130*2eab6dd7S曾俊 // info!("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 /// syscall指令初始化函数
init_syscall_64()1374fda81ceSLoGin pub(super) unsafe fn init_syscall_64() {
1384fda81ceSLoGin let mut efer = x86::msr::rdmsr(x86::msr::IA32_EFER);
1394fda81ceSLoGin efer |= 0x1;
1404fda81ceSLoGin x86::msr::wrmsr(x86::msr::IA32_EFER, efer);
1414fda81ceSLoGin
142b5b571e0SLoGin let syscall_base = (1_u16) << 3;
143b5b571e0SLoGin let sysret_base = ((4_u16) << 3) | 3;
1444fda81ceSLoGin let high = (u32::from(sysret_base) << 16) | u32::from(syscall_base);
1454fda81ceSLoGin // 初始化STAR寄存器
1464fda81ceSLoGin x86::msr::wrmsr(x86::msr::IA32_STAR, u64::from(high) << 32);
1474fda81ceSLoGin
1484fda81ceSLoGin // 初始化LSTAR,该寄存器存储syscall指令入口
149b5b571e0SLoGin x86::msr::wrmsr(x86::msr::IA32_LSTAR, syscall_64 as usize as u64);
1504fda81ceSLoGin x86::msr::wrmsr(x86::msr::IA32_FMASK, 0xfffffffe);
1514fda81ceSLoGin }
152