mod.rs 4.5 KB

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