xref: /DragonOS/kernel/src/arch/riscv64/process/syscall.rs (revision 471d65cf158c9bf741c21f5d0ab92efe7bf1c3d4)
14fda81ceSLoGin use alloc::{string::String, vec::Vec};
2*471d65cfSLoGin use riscv::register::sstatus::{Sstatus, FS, SPP};
391e9d4abSLoGin use system_error::SystemError;
44fda81ceSLoGin 
5*471d65cfSLoGin use crate::{
6*471d65cfSLoGin     arch::{interrupt::TrapFrame, CurrentIrqArch},
7*471d65cfSLoGin     exception::InterruptArch,
8*471d65cfSLoGin     kdebug,
9*471d65cfSLoGin     mm::ucontext::AddressSpace,
10*471d65cfSLoGin     process::{
11*471d65cfSLoGin         exec::{load_binary_file, ExecParam, ExecParamFlags},
12*471d65cfSLoGin         ProcessManager,
13*471d65cfSLoGin     },
14*471d65cfSLoGin     syscall::Syscall,
15*471d65cfSLoGin };
164fda81ceSLoGin 
174fda81ceSLoGin impl Syscall {
184fda81ceSLoGin     pub fn do_execve(
194fda81ceSLoGin         path: String,
204fda81ceSLoGin         argv: Vec<String>,
214fda81ceSLoGin         envp: Vec<String>,
224fda81ceSLoGin         regs: &mut TrapFrame,
234fda81ceSLoGin     ) -> Result<(), SystemError> {
24*471d65cfSLoGin         // 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。
25*471d65cfSLoGin         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
26*471d65cfSLoGin         let pcb = ProcessManager::current_pcb();
27*471d65cfSLoGin         // crate::kdebug!(
28*471d65cfSLoGin         //     "pid: {:?}  do_execve: path: {:?}, argv: {:?}, envp: {:?}\n",
29*471d65cfSLoGin         //     pcb.pid(),
30*471d65cfSLoGin         //     path,
31*471d65cfSLoGin         //     argv,
32*471d65cfSLoGin         //     envp
33*471d65cfSLoGin         // );
34*471d65cfSLoGin 
35*471d65cfSLoGin         let mut basic_info = pcb.basic_mut();
36*471d65cfSLoGin         // 暂存原本的用户地址空间的引用(因为如果在切换页表之前释放了它,可能会造成内存use after free)
37*471d65cfSLoGin         let old_address_space = basic_info.user_vm();
38*471d65cfSLoGin 
39*471d65cfSLoGin         // 在pcb中原来的用户地址空间
40*471d65cfSLoGin         unsafe {
41*471d65cfSLoGin             basic_info.set_user_vm(None);
42*471d65cfSLoGin         }
43*471d65cfSLoGin         // 创建新的地址空间并设置为当前地址空间
44*471d65cfSLoGin         let address_space = AddressSpace::new(true).expect("Failed to create new address space");
45*471d65cfSLoGin         unsafe {
46*471d65cfSLoGin             basic_info.set_user_vm(Some(address_space.clone()));
47*471d65cfSLoGin         }
48*471d65cfSLoGin 
49*471d65cfSLoGin         // to avoid deadlock
50*471d65cfSLoGin         drop(basic_info);
51*471d65cfSLoGin 
52*471d65cfSLoGin         assert!(
53*471d65cfSLoGin             AddressSpace::is_current(&address_space),
54*471d65cfSLoGin             "Failed to set address space"
55*471d65cfSLoGin         );
56*471d65cfSLoGin         // kdebug!("Switch to new address space");
57*471d65cfSLoGin 
58*471d65cfSLoGin         // 切换到新的用户地址空间
59*471d65cfSLoGin         unsafe { address_space.read().user_mapper.utable.make_current() };
60*471d65cfSLoGin 
61*471d65cfSLoGin         drop(old_address_space);
62*471d65cfSLoGin         drop(irq_guard);
63*471d65cfSLoGin         // kdebug!("to load binary file");
64*471d65cfSLoGin         let mut param = ExecParam::new(path.as_str(), address_space.clone(), ExecParamFlags::EXEC)?;
65*471d65cfSLoGin 
66*471d65cfSLoGin         // 加载可执行文件
67*471d65cfSLoGin         let load_result = load_binary_file(&mut param)
68*471d65cfSLoGin             .unwrap_or_else(|e| panic!("Failed to load binary file: {:?}, path: {:?}", e, path));
69*471d65cfSLoGin         // kdebug!("load binary file done");
70*471d65cfSLoGin         // kdebug!("argv: {:?}, envp: {:?}", argv, envp);
71*471d65cfSLoGin         param.init_info_mut().args = argv;
72*471d65cfSLoGin         param.init_info_mut().envs = envp;
73*471d65cfSLoGin 
74*471d65cfSLoGin         // 把proc_init_info写到用户栈上
75*471d65cfSLoGin         let mut ustack_message = unsafe {
76*471d65cfSLoGin             address_space
77*471d65cfSLoGin                 .write()
78*471d65cfSLoGin                 .user_stack_mut()
79*471d65cfSLoGin                 .expect("No user stack found")
80*471d65cfSLoGin                 .clone_info_only()
81*471d65cfSLoGin         };
82*471d65cfSLoGin         let (user_sp, argv_ptr) = unsafe {
83*471d65cfSLoGin             param
84*471d65cfSLoGin                 .init_info()
85*471d65cfSLoGin                 .push_at(
86*471d65cfSLoGin                     // address_space
87*471d65cfSLoGin                     //     .write()
88*471d65cfSLoGin                     //     .user_stack_mut()
89*471d65cfSLoGin                     //     .expect("No user stack found"),
90*471d65cfSLoGin                     &mut ustack_message,
91*471d65cfSLoGin                 )
92*471d65cfSLoGin                 .expect("Failed to push proc_init_info to user stack")
93*471d65cfSLoGin         };
94*471d65cfSLoGin         address_space.write().user_stack = Some(ustack_message);
95*471d65cfSLoGin 
96*471d65cfSLoGin         // kdebug!("write proc_init_info to user stack done");
97*471d65cfSLoGin 
98*471d65cfSLoGin         regs.a0 = param.init_info().args.len();
99*471d65cfSLoGin         regs.a1 = argv_ptr.data();
100*471d65cfSLoGin 
101*471d65cfSLoGin         // 设置系统调用返回时的寄存器状态
102*471d65cfSLoGin         regs.sp = user_sp.data();
103*471d65cfSLoGin 
104*471d65cfSLoGin         regs.epc = load_result.entry_point().data();
105*471d65cfSLoGin         regs.status.update_spp(SPP::User);
106*471d65cfSLoGin         regs.status.update_fs(FS::Clean);
107*471d65cfSLoGin         regs.status.update_sie(true);
108*471d65cfSLoGin         regs.status.update_sum(true);
109*471d65cfSLoGin 
110*471d65cfSLoGin         drop(param);
111*471d65cfSLoGin 
112*471d65cfSLoGin         return Ok(());
1134fda81ceSLoGin     }
1144fda81ceSLoGin 
1154fda81ceSLoGin     /// ## 用于控制和查询与体系结构相关的进程特定选项
1164fda81ceSLoGin     pub fn arch_prctl(option: usize, arg2: usize) -> Result<usize, SystemError> {
1174fda81ceSLoGin         unimplemented!("Syscall::arch_prctl")
1184fda81ceSLoGin     }
1194fda81ceSLoGin }
120