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