mod.rs 5.1 KB

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