syscall.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. use core::ffi::c_void;
  2. use crate::{
  3. include::bindings::bindings::{
  4. pt_regs, set_system_trap_gate, verify_area, CLONE_FS, CLONE_SIGNAL, CLONE_VM, PAGE_4K_SIZE,
  5. },
  6. ipc::signal::sys_rt_sigreturn,
  7. kinfo,
  8. syscall::{Syscall, SystemError, SYS_EXECVE, SYS_FORK, SYS_RT_SIGRETURN, SYS_VFORK},
  9. };
  10. use super::{asm::ptrace::user_mode, mm::barrier::mfence};
  11. extern "C" {
  12. fn do_fork(regs: *mut pt_regs, clone_flags: u64, stack_start: u64, stack_size: u64) -> u64;
  13. fn c_sys_execve(
  14. path: *const u8,
  15. argv: *const *const u8,
  16. envp: *const *const u8,
  17. regs: &mut pt_regs,
  18. ) -> u64;
  19. fn syscall_int();
  20. }
  21. macro_rules! syscall_return {
  22. ($val:expr, $regs:expr) => {{
  23. let ret = $val;
  24. $regs.rax = ret as u64;
  25. return;
  26. }};
  27. }
  28. #[no_mangle]
  29. pub extern "C" fn syscall_handler(regs: &mut pt_regs) -> () {
  30. let syscall_num = regs.rax as usize;
  31. let args = [
  32. regs.r8 as usize,
  33. regs.r9 as usize,
  34. regs.r10 as usize,
  35. regs.r11 as usize,
  36. regs.r12 as usize,
  37. regs.r13 as usize,
  38. regs.r14 as usize,
  39. regs.r15 as usize,
  40. ];
  41. mfence();
  42. mfence();
  43. let from_user = user_mode(regs);
  44. // 由于进程管理未完成重构,有些系统调用需要在这里临时处理,以后这里的特殊处理要删掉。
  45. match syscall_num {
  46. SYS_FORK => unsafe {
  47. syscall_return!(do_fork(regs, 0, regs.rsp, 0), regs);
  48. },
  49. SYS_VFORK => unsafe {
  50. syscall_return!(
  51. do_fork(
  52. regs,
  53. (CLONE_VM | CLONE_FS | CLONE_SIGNAL) as u64,
  54. regs.rsp,
  55. 0,
  56. ),
  57. regs
  58. );
  59. },
  60. SYS_EXECVE => {
  61. let path_ptr = args[0];
  62. let argv_ptr = args[1];
  63. let env_ptr = args[2];
  64. // 权限校验
  65. if from_user
  66. && (unsafe { !verify_area(path_ptr as u64, PAGE_4K_SIZE as u64) }
  67. || unsafe { !verify_area(argv_ptr as u64, PAGE_4K_SIZE as u64) })
  68. || unsafe { !verify_area(env_ptr as u64, PAGE_4K_SIZE as u64) }
  69. {
  70. syscall_return!(SystemError::EFAULT.to_posix_errno() as u64, regs);
  71. } else {
  72. syscall_return!(
  73. unsafe {
  74. c_sys_execve(
  75. path_ptr as *const u8,
  76. argv_ptr as *const *const u8,
  77. env_ptr as *const *const u8,
  78. regs,
  79. )
  80. },
  81. regs
  82. );
  83. }
  84. }
  85. SYS_RT_SIGRETURN => {
  86. syscall_return!(sys_rt_sigreturn(regs), regs);
  87. }
  88. // SYS_SCHED => {
  89. // syscall_return!(sched(from_user) as u64, regs);
  90. // }
  91. _ => {}
  92. }
  93. syscall_return!(Syscall::handle(syscall_num, &args, from_user) as u64, regs);
  94. }
  95. /// 系统调用初始化
  96. pub fn arch_syscall_init() -> Result<(), SystemError> {
  97. kinfo!("arch_syscall_init\n");
  98. unsafe { set_system_trap_gate(0x80, 0, syscall_int as *mut c_void) }; // 系统调用门
  99. return Ok(());
  100. }