mod.rs 4.5 KB

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