syscall.rs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. use alloc::sync::Arc;
  2. use system_error::SystemError;
  3. use crate::{
  4. arch::{
  5. interrupt::TrapFrame,
  6. process::table::{USER_CS, USER_DS},
  7. },
  8. mm::VirtAddr,
  9. process::{
  10. exec::{BinaryLoaderResult, ExecParam},
  11. ProcessControlBlock, ProcessManager,
  12. },
  13. syscall::{user_access::UserBufferWriter, Syscall},
  14. };
  15. impl Syscall {
  16. pub fn arch_do_execve(
  17. regs: &mut TrapFrame,
  18. param: &ExecParam,
  19. load_result: &BinaryLoaderResult,
  20. user_sp: VirtAddr,
  21. argv_ptr: VirtAddr,
  22. ) -> Result<(), SystemError> {
  23. // debug!("write proc_init_info to user stack done");
  24. // (兼容旧版libc)把argv的指针写到寄存器内
  25. // TODO: 改写旧版libc,不再需要这个兼容
  26. regs.rdi = param.init_info().args.len() as u64;
  27. regs.rsi = argv_ptr.data() as u64;
  28. // 设置系统调用返回时的寄存器状态
  29. // TODO: 中断管理重构后,这里的寄存器状态设置要删掉!!!改为对trap frame的设置。要增加架构抽象。
  30. regs.rsp = user_sp.data() as u64;
  31. regs.rbp = user_sp.data() as u64;
  32. regs.rip = load_result.entry_point().data() as u64;
  33. regs.cs = USER_CS.bits() as u64;
  34. regs.ds = USER_DS.bits() as u64;
  35. regs.ss = USER_DS.bits() as u64;
  36. regs.es = 0;
  37. regs.rflags = 0x200;
  38. regs.rax = 1;
  39. // debug!("regs: {:?}\n", regs);
  40. // crate::debug!(
  41. // "tmp_rs_execve: done, load_result.entry_point()={:?}",
  42. // load_result.entry_point()
  43. // );
  44. return Ok(());
  45. }
  46. /// ## 用于控制和查询与体系结构相关的进程特定选项
  47. /// https://code.dragonos.org.cn/xref/linux-6.6.21/arch/x86/kernel/process_64.c#913
  48. pub fn arch_prctl(option: usize, arg2: usize) -> Result<usize, SystemError> {
  49. let pcb = ProcessManager::current_pcb();
  50. if let Err(SystemError::EINVAL) = Self::do_arch_prctl_64(&pcb, option, arg2, true) {
  51. Self::do_arch_prctl_common(option, arg2)?;
  52. }
  53. Ok(0)
  54. }
  55. /// ## 64位下控制fs/gs base寄存器的方法
  56. pub fn do_arch_prctl_64(
  57. pcb: &Arc<ProcessControlBlock>,
  58. option: usize,
  59. arg2: usize,
  60. from_user: bool,
  61. ) -> Result<usize, SystemError> {
  62. let mut arch_info = pcb.arch_info_irqsave();
  63. match option {
  64. ARCH_GET_FS => {
  65. unsafe { arch_info.save_fsbase() };
  66. let mut writer = UserBufferWriter::new(
  67. arg2 as *mut usize,
  68. core::mem::size_of::<usize>(),
  69. from_user,
  70. )?;
  71. writer.copy_one_to_user(&arch_info.fsbase, 0)?;
  72. }
  73. ARCH_GET_GS => {
  74. unsafe { arch_info.save_gsbase() };
  75. let mut writer = UserBufferWriter::new(
  76. arg2 as *mut usize,
  77. core::mem::size_of::<usize>(),
  78. from_user,
  79. )?;
  80. writer.copy_one_to_user(&arch_info.gsbase, 0)?;
  81. }
  82. ARCH_SET_FS => {
  83. arch_info.fsbase = arg2;
  84. // 如果是当前进程则直接写入寄存器
  85. if pcb.raw_pid() == ProcessManager::current_pcb().raw_pid() {
  86. unsafe { arch_info.restore_fsbase() }
  87. }
  88. }
  89. ARCH_SET_GS => {
  90. arch_info.gsbase = arg2;
  91. if pcb.raw_pid() == ProcessManager::current_pcb().raw_pid() {
  92. unsafe { arch_info.restore_gsbase() }
  93. }
  94. }
  95. _ => {
  96. return Err(SystemError::EINVAL);
  97. }
  98. }
  99. Ok(0)
  100. }
  101. #[allow(dead_code)]
  102. pub fn do_arch_prctl_common(option: usize, arg2: usize) -> Result<usize, SystemError> {
  103. // Don't use 0x3001-0x3004 because of old glibcs
  104. if (0x3001..=0x3004).contains(&option) {
  105. return Err(SystemError::EINVAL);
  106. }
  107. todo!(
  108. "do_arch_prctl_common not unimplemented, option: {}, arg2: {}",
  109. option,
  110. arg2
  111. );
  112. }
  113. }
  114. pub const ARCH_SET_GS: usize = 0x1001;
  115. pub const ARCH_SET_FS: usize = 0x1002;
  116. pub const ARCH_GET_FS: usize = 0x1003;
  117. pub const ARCH_GET_GS: usize = 0x1004;