xref: /DragonOS/kernel/src/arch/x86_64/process/syscall.rs (revision a17651b14b86dd70655090381db4a2f710853aa1)
1971462beSGnoCiYeH use alloc::{string::String, sync::Arc, vec::Vec};
291e9d4abSLoGin use system_error::SystemError;
31496ba7bSLoGin 
41496ba7bSLoGin use crate::{
51496ba7bSLoGin     arch::{
61496ba7bSLoGin         interrupt::TrapFrame,
71496ba7bSLoGin         process::table::{USER_CS, USER_DS},
81496ba7bSLoGin         CurrentIrqArch,
91496ba7bSLoGin     },
101496ba7bSLoGin     exception::InterruptArch,
111496ba7bSLoGin     mm::ucontext::AddressSpace,
121496ba7bSLoGin     process::{
131496ba7bSLoGin         exec::{load_binary_file, ExecParam, ExecParamFlags},
14971462beSGnoCiYeH         ProcessControlBlock, ProcessManager,
151496ba7bSLoGin     },
1691e9d4abSLoGin     syscall::{user_access::UserBufferWriter, Syscall},
171496ba7bSLoGin };
181496ba7bSLoGin 
191496ba7bSLoGin impl Syscall {
201496ba7bSLoGin     pub fn do_execve(
211496ba7bSLoGin         path: String,
221496ba7bSLoGin         argv: Vec<String>,
231496ba7bSLoGin         envp: Vec<String>,
241496ba7bSLoGin         regs: &mut TrapFrame,
251496ba7bSLoGin     ) -> Result<(), SystemError> {
26bf4a4899SLoGin         // 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。
27bf4a4899SLoGin         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
28bf4a4899SLoGin         let pcb = ProcessManager::current_pcb();
29bf4a4899SLoGin         // crate::kdebug!(
30bf4a4899SLoGin         //     "pid: {:?}  do_execve: path: {:?}, argv: {:?}, envp: {:?}\n",
31bf4a4899SLoGin         //     pcb.pid(),
321496ba7bSLoGin         //     path,
331496ba7bSLoGin         //     argv,
341496ba7bSLoGin         //     envp
351496ba7bSLoGin         // );
361496ba7bSLoGin 
371496ba7bSLoGin         let mut basic_info = pcb.basic_mut();
381496ba7bSLoGin         // 暂存原本的用户地址空间的引用(因为如果在切换页表之前释放了它,可能会造成内存use after free)
391496ba7bSLoGin         let old_address_space = basic_info.user_vm();
401496ba7bSLoGin 
411496ba7bSLoGin         // 在pcb中原来的用户地址空间
421496ba7bSLoGin         unsafe {
431496ba7bSLoGin             basic_info.set_user_vm(None);
441496ba7bSLoGin         }
451496ba7bSLoGin         // 创建新的地址空间并设置为当前地址空间
461496ba7bSLoGin         let address_space = AddressSpace::new(true).expect("Failed to create new address space");
471496ba7bSLoGin         unsafe {
481496ba7bSLoGin             basic_info.set_user_vm(Some(address_space.clone()));
491496ba7bSLoGin         }
501496ba7bSLoGin 
511496ba7bSLoGin         // to avoid deadlock
521496ba7bSLoGin         drop(basic_info);
531496ba7bSLoGin 
541496ba7bSLoGin         assert!(
551496ba7bSLoGin             AddressSpace::is_current(&address_space),
561496ba7bSLoGin             "Failed to set address space"
571496ba7bSLoGin         );
581496ba7bSLoGin         // kdebug!("Switch to new address space");
591496ba7bSLoGin 
601496ba7bSLoGin         // 切换到新的用户地址空间
611496ba7bSLoGin         unsafe { address_space.read().user_mapper.utable.make_current() };
621496ba7bSLoGin 
631496ba7bSLoGin         drop(old_address_space);
641496ba7bSLoGin         drop(irq_guard);
651496ba7bSLoGin         // kdebug!("to load binary file");
66a02ce654SChiichen         let mut param = ExecParam::new(path.as_str(), address_space.clone(), ExecParamFlags::EXEC)?;
671496ba7bSLoGin 
681496ba7bSLoGin         // 加载可执行文件
691496ba7bSLoGin         let load_result = load_binary_file(&mut param)
701496ba7bSLoGin             .unwrap_or_else(|e| panic!("Failed to load binary file: {:?}, path: {:?}", e, path));
711496ba7bSLoGin         // kdebug!("load binary file done");
721496ba7bSLoGin         // kdebug!("argv: {:?}, envp: {:?}", argv, envp);
731496ba7bSLoGin         param.init_info_mut().args = argv;
741496ba7bSLoGin         param.init_info_mut().envs = envp;
751496ba7bSLoGin 
761496ba7bSLoGin         // 把proc_init_info写到用户栈上
77*a17651b1SMemoryShore         let mut ustack_message = unsafe {
78*a17651b1SMemoryShore             address_space
79*a17651b1SMemoryShore                 .write()
80*a17651b1SMemoryShore                 .user_stack_mut()
81*a17651b1SMemoryShore                 .expect("No user stack found")
82*a17651b1SMemoryShore                 .clone_info_only()
83*a17651b1SMemoryShore         };
841496ba7bSLoGin         let (user_sp, argv_ptr) = unsafe {
851496ba7bSLoGin             param
861496ba7bSLoGin                 .init_info()
871496ba7bSLoGin                 .push_at(
88*a17651b1SMemoryShore                     // address_space
89*a17651b1SMemoryShore                     //     .write()
90*a17651b1SMemoryShore                     //     .user_stack_mut()
91*a17651b1SMemoryShore                     //     .expect("No user stack found"),
92*a17651b1SMemoryShore                     &mut ustack_message,
931496ba7bSLoGin                 )
941496ba7bSLoGin                 .expect("Failed to push proc_init_info to user stack")
951496ba7bSLoGin         };
96*a17651b1SMemoryShore         address_space.write().user_stack = Some(ustack_message);
971496ba7bSLoGin 
981496ba7bSLoGin         // kdebug!("write proc_init_info to user stack done");
991496ba7bSLoGin 
1001496ba7bSLoGin         // (兼容旧版libc)把argv的指针写到寄存器内
1011496ba7bSLoGin         // TODO: 改写旧版libc,不再需要这个兼容
1021496ba7bSLoGin         regs.rdi = param.init_info().args.len() as u64;
1031496ba7bSLoGin         regs.rsi = argv_ptr.data() as u64;
1041496ba7bSLoGin 
1051496ba7bSLoGin         // 设置系统调用返回时的寄存器状态
1061496ba7bSLoGin         // TODO: 中断管理重构后,这里的寄存器状态设置要删掉!!!改为对trap frame的设置。要增加架构抽象。
1071496ba7bSLoGin         regs.rsp = user_sp.data() as u64;
1081496ba7bSLoGin         regs.rbp = user_sp.data() as u64;
1091496ba7bSLoGin         regs.rip = load_result.entry_point().data() as u64;
1101496ba7bSLoGin 
1111496ba7bSLoGin         regs.cs = USER_CS.bits() as u64;
1121496ba7bSLoGin         regs.ds = USER_DS.bits() as u64;
1131496ba7bSLoGin         regs.ss = USER_DS.bits() as u64;
1141496ba7bSLoGin         regs.es = 0;
1151496ba7bSLoGin         regs.rflags = 0x200;
1161496ba7bSLoGin         regs.rax = 1;
1171496ba7bSLoGin 
118971462beSGnoCiYeH         drop(param);
119971462beSGnoCiYeH 
1201496ba7bSLoGin         // kdebug!("regs: {:?}\n", regs);
1211496ba7bSLoGin 
122bf4a4899SLoGin         // crate::kdebug!(
1231496ba7bSLoGin         //     "tmp_rs_execve: done, load_result.entry_point()={:?}",
1241496ba7bSLoGin         //     load_result.entry_point()
1251496ba7bSLoGin         // );
126876cb89eSGnoCiYeH 
1271496ba7bSLoGin         return Ok(());
1281496ba7bSLoGin     }
129971462beSGnoCiYeH 
130971462beSGnoCiYeH     /// ## 用于控制和查询与体系结构相关的进程特定选项
131971462beSGnoCiYeH     pub fn arch_prctl(option: usize, arg2: usize) -> Result<usize, SystemError> {
132971462beSGnoCiYeH         let pcb = ProcessManager::current_pcb();
133971462beSGnoCiYeH         if let Err(SystemError::EINVAL) = Self::do_arch_prctl_64(&pcb, option, arg2, true) {
134971462beSGnoCiYeH             Self::do_arch_prctl_common(option, arg2)?;
1351496ba7bSLoGin         }
136971462beSGnoCiYeH         Ok(0)
137971462beSGnoCiYeH     }
138971462beSGnoCiYeH 
139971462beSGnoCiYeH     /// ## 64位下控制fs/gs base寄存器的方法
140971462beSGnoCiYeH     pub fn do_arch_prctl_64(
141971462beSGnoCiYeH         pcb: &Arc<ProcessControlBlock>,
142971462beSGnoCiYeH         option: usize,
143971462beSGnoCiYeH         arg2: usize,
144971462beSGnoCiYeH         from_user: bool,
145971462beSGnoCiYeH     ) -> Result<usize, SystemError> {
146971462beSGnoCiYeH         let mut arch_info = pcb.arch_info_irqsave();
147971462beSGnoCiYeH         match option {
148971462beSGnoCiYeH             ARCH_GET_FS => {
149971462beSGnoCiYeH                 unsafe { arch_info.save_fsbase() };
150971462beSGnoCiYeH                 let mut writer = UserBufferWriter::new(
151971462beSGnoCiYeH                     arg2 as *mut usize,
152971462beSGnoCiYeH                     core::mem::size_of::<usize>(),
153971462beSGnoCiYeH                     from_user,
154971462beSGnoCiYeH                 )?;
155971462beSGnoCiYeH                 writer.copy_one_to_user(&arch_info.fsbase, 0)?;
156971462beSGnoCiYeH             }
157971462beSGnoCiYeH             ARCH_GET_GS => {
158971462beSGnoCiYeH                 unsafe { arch_info.save_gsbase() };
159971462beSGnoCiYeH                 let mut writer = UserBufferWriter::new(
160971462beSGnoCiYeH                     arg2 as *mut usize,
161971462beSGnoCiYeH                     core::mem::size_of::<usize>(),
162971462beSGnoCiYeH                     from_user,
163971462beSGnoCiYeH                 )?;
164971462beSGnoCiYeH                 writer.copy_one_to_user(&arch_info.gsbase, 0)?;
165971462beSGnoCiYeH             }
166971462beSGnoCiYeH             ARCH_SET_FS => {
167971462beSGnoCiYeH                 arch_info.fsbase = arg2;
168971462beSGnoCiYeH                 // 如果是当前进程则直接写入寄存器
169971462beSGnoCiYeH                 if pcb.pid() == ProcessManager::current_pcb().pid() {
170971462beSGnoCiYeH                     unsafe { arch_info.restore_fsbase() }
171971462beSGnoCiYeH                 }
172971462beSGnoCiYeH             }
173971462beSGnoCiYeH             ARCH_SET_GS => {
174971462beSGnoCiYeH                 arch_info.gsbase = arg2;
175971462beSGnoCiYeH                 if pcb.pid() == ProcessManager::current_pcb().pid() {
176971462beSGnoCiYeH                     unsafe { arch_info.restore_gsbase() }
177971462beSGnoCiYeH                 }
178971462beSGnoCiYeH             }
179971462beSGnoCiYeH             _ => {
180971462beSGnoCiYeH                 return Err(SystemError::EINVAL);
181971462beSGnoCiYeH             }
182971462beSGnoCiYeH         }
183971462beSGnoCiYeH         Ok(0)
184971462beSGnoCiYeH     }
185971462beSGnoCiYeH 
186971462beSGnoCiYeH     #[allow(dead_code)]
187971462beSGnoCiYeH     pub fn do_arch_prctl_common(_option: usize, _arg2: usize) -> Result<usize, SystemError> {
188971462beSGnoCiYeH         todo!("do_arch_prctl_common not unimplemented");
189971462beSGnoCiYeH     }
190971462beSGnoCiYeH }
191971462beSGnoCiYeH 
192971462beSGnoCiYeH pub const ARCH_SET_GS: usize = 0x1001;
193971462beSGnoCiYeH pub const ARCH_SET_FS: usize = 0x1002;
194971462beSGnoCiYeH pub const ARCH_GET_FS: usize = 0x1003;
195971462beSGnoCiYeH pub const ARCH_GET_GS: usize = 0x1004;
196