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