syscall.rs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. use core::{
  2. ffi::{c_int, c_void},
  3. sync::atomic::compiler_fence,
  4. };
  5. use log::{error, warn};
  6. use system_error::SystemError;
  7. use crate::{
  8. arch::{
  9. ipc::signal::{SigCode, SigFlags, SigSet, Signal},
  10. MMArch,
  11. },
  12. filesystem::vfs::{
  13. file::{File, FileMode},
  14. FilePrivateData,
  15. },
  16. ipc::shm::{shm_manager_lock, IPC_PRIVATE},
  17. libs::align::page_align_up,
  18. libs::spinlock::SpinLock,
  19. mm::{
  20. allocator::page_frame::{PageFrameCount, PhysPageFrame, VirtPageFrame},
  21. page::{page_manager_lock_irqsave, EntryFlags, PageFlushAll},
  22. syscall::ProtFlags,
  23. ucontext::{AddressSpace, VMA},
  24. VirtAddr, VmFlags,
  25. },
  26. process::{Pid, ProcessManager},
  27. syscall::{
  28. user_access::{UserBufferReader, UserBufferWriter},
  29. Syscall,
  30. },
  31. };
  32. use super::{
  33. pipe::{LockedPipeInode, PipeFsPrivateData},
  34. shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey},
  35. signal_types::{
  36. SaHandlerType, SigInfo, SigType, Sigaction, SigactionType, UserSigaction, USER_SIG_DFL,
  37. USER_SIG_ERR, USER_SIG_IGN,
  38. },
  39. };
  40. impl Syscall {
  41. /// # 创建带参数的匿名管道
  42. ///
  43. /// ## 参数
  44. ///
  45. /// - `fd`: 用于返回文件描述符的数组
  46. /// - `flags`:设置管道的参数
  47. pub fn pipe2(fd: *mut i32, flags: FileMode) -> Result<usize, SystemError> {
  48. if !flags
  49. .difference(FileMode::O_CLOEXEC | FileMode::O_NONBLOCK | FileMode::O_DIRECT)
  50. .is_empty()
  51. {
  52. return Err(SystemError::EINVAL);
  53. }
  54. let mut user_buffer = UserBufferWriter::new(fd, core::mem::size_of::<[c_int; 2]>(), true)?;
  55. let fd = user_buffer.buffer::<i32>(0)?;
  56. let pipe_ptr = LockedPipeInode::new();
  57. let mut read_file = File::new(
  58. pipe_ptr.clone(),
  59. FileMode::O_RDONLY | (flags & FileMode::O_NONBLOCK),
  60. )?;
  61. read_file.private_data = SpinLock::new(FilePrivateData::Pipefs(PipeFsPrivateData::new(
  62. FileMode::O_RDONLY,
  63. )));
  64. let mut write_file = File::new(
  65. pipe_ptr.clone(),
  66. FileMode::O_WRONLY | (flags & (FileMode::O_NONBLOCK | FileMode::O_DIRECT)),
  67. )?;
  68. write_file.private_data = SpinLock::new(FilePrivateData::Pipefs(PipeFsPrivateData::new(
  69. FileMode::O_WRONLY | (flags & (FileMode::O_NONBLOCK | FileMode::O_DIRECT)),
  70. )));
  71. if flags.contains(FileMode::O_CLOEXEC) {
  72. read_file.set_close_on_exec(true);
  73. write_file.set_close_on_exec(true);
  74. }
  75. let fd_table_ptr = ProcessManager::current_pcb().fd_table();
  76. let mut fd_table_guard = fd_table_ptr.write();
  77. let read_fd = fd_table_guard.alloc_fd(read_file, None)?;
  78. let write_fd = fd_table_guard.alloc_fd(write_file, None)?;
  79. drop(fd_table_guard);
  80. fd[0] = read_fd;
  81. fd[1] = write_fd;
  82. Ok(0)
  83. }
  84. pub fn kill(pid: Pid, sig: c_int) -> Result<usize, SystemError> {
  85. let sig = Signal::from(sig);
  86. if sig == Signal::INVALID {
  87. // 传入的signal数值不合法
  88. warn!("Not a valid signal number");
  89. return Err(SystemError::EINVAL);
  90. }
  91. // 初始化signal info
  92. let mut info = SigInfo::new(sig, 0, SigCode::User, SigType::Kill(pid));
  93. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  94. let retval = sig
  95. .send_signal_info(Some(&mut info), pid)
  96. .map(|x| x as usize);
  97. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  98. return retval;
  99. }
  100. /// 通用信号注册函数
  101. ///
  102. /// ## 参数
  103. ///
  104. /// - `sig` 信号的值
  105. /// - `act` 用户空间传入的 Sigaction 指针
  106. /// - `old_act` 用户空间传入的用来保存旧 Sigaction 的指针
  107. /// - `from_user` 用来标识这个函数调用是否来自用户空间
  108. ///
  109. /// @return int 错误码
  110. #[no_mangle]
  111. pub fn sigaction(
  112. sig: c_int,
  113. new_act: usize,
  114. old_act: usize,
  115. from_user: bool,
  116. ) -> Result<usize, SystemError> {
  117. // 请注意:用户态传进来的user_sigaction结构体类型,请注意,这个结构体与内核实际的不一样
  118. let act: *mut UserSigaction = new_act as *mut UserSigaction;
  119. let old_act = old_act as *mut UserSigaction;
  120. let mut new_ka: Sigaction = Default::default();
  121. let mut old_sigaction: Sigaction = Default::default();
  122. // 如果传入的,新的sigaction不为空
  123. if !act.is_null() {
  124. // 如果参数的范围不在用户空间,则返回错误
  125. let r = UserBufferWriter::new(act, core::mem::size_of::<Sigaction>(), from_user);
  126. if r.is_err() {
  127. return Err(SystemError::EFAULT);
  128. }
  129. let mask: SigSet = unsafe { (*act).mask };
  130. let input_sighandler = unsafe { (*act).handler as u64 };
  131. match input_sighandler {
  132. USER_SIG_DFL => {
  133. new_ka = Sigaction::DEFAULT_SIGACTION;
  134. *new_ka.flags_mut() = unsafe { (*act).flags };
  135. new_ka.set_restorer(None);
  136. }
  137. USER_SIG_IGN => {
  138. new_ka = Sigaction::DEFAULT_SIGACTION_IGNORE;
  139. *new_ka.flags_mut() = unsafe { (*act).flags };
  140. new_ka.set_restorer(None);
  141. }
  142. _ => {
  143. // 从用户空间获得sigaction结构体
  144. // TODO mask是default还是用户空间传入
  145. new_ka = Sigaction::new(
  146. SigactionType::SaHandler(SaHandlerType::Customized(unsafe {
  147. VirtAddr::new((*act).handler as usize)
  148. })),
  149. unsafe { (*act).flags },
  150. SigSet::default(),
  151. unsafe { Some(VirtAddr::new((*act).restorer as usize)) },
  152. );
  153. }
  154. }
  155. // TODO 如果为空,赋默认值?
  156. // debug!("new_ka={:?}", new_ka);
  157. // 如果用户手动给了sa_restorer,那么就置位SA_FLAG_RESTORER,否则报错。(用户必须手动指定restorer)
  158. if new_ka.restorer().is_some() {
  159. new_ka.flags_mut().insert(SigFlags::SA_RESTORER);
  160. } else if new_ka.action().is_customized() {
  161. error!(
  162. "pid:{:?}: in sys_sigaction: User must manually sprcify a sa_restorer for signal {}.",
  163. ProcessManager::current_pcb().pid(),
  164. sig
  165. );
  166. return Err(SystemError::EINVAL);
  167. }
  168. *new_ka.mask_mut() = mask;
  169. }
  170. let sig = Signal::from(sig);
  171. // 如果给出的信号值不合法
  172. if sig == Signal::INVALID {
  173. return Err(SystemError::EINVAL);
  174. }
  175. let retval = super::signal::do_sigaction(
  176. sig,
  177. if act.is_null() {
  178. None
  179. } else {
  180. Some(&mut new_ka)
  181. },
  182. if old_act.is_null() {
  183. None
  184. } else {
  185. Some(&mut old_sigaction)
  186. },
  187. );
  188. //
  189. if (retval == Ok(())) && (!old_act.is_null()) {
  190. let r =
  191. UserBufferWriter::new(old_act, core::mem::size_of::<UserSigaction>(), from_user);
  192. if r.is_err() {
  193. return Err(SystemError::EFAULT);
  194. }
  195. let sigaction_handler = match old_sigaction.action() {
  196. SigactionType::SaHandler(handler) => {
  197. if let SaHandlerType::Customized(hand) = handler {
  198. hand
  199. } else if handler.is_sig_ignore() {
  200. VirtAddr::new(USER_SIG_IGN as usize)
  201. } else if handler.is_sig_error() {
  202. VirtAddr::new(USER_SIG_ERR as usize)
  203. } else {
  204. VirtAddr::new(USER_SIG_DFL as usize)
  205. }
  206. }
  207. SigactionType::SaSigaction(_) => {
  208. error!("unsupported type: SaSigaction");
  209. VirtAddr::new(USER_SIG_DFL as usize)
  210. }
  211. };
  212. unsafe {
  213. (*old_act).handler = sigaction_handler.data() as *mut c_void;
  214. (*old_act).flags = old_sigaction.flags();
  215. (*old_act).mask = old_sigaction.mask();
  216. if old_sigaction.restorer().is_some() {
  217. (*old_act).restorer = old_sigaction.restorer().unwrap().data() as *mut c_void;
  218. }
  219. }
  220. }
  221. return retval.map(|_| 0);
  222. }
  223. /// # SYS_SHMGET系统调用函数,用于获取共享内存
  224. ///
  225. /// ## 参数
  226. ///
  227. /// - `key`: 共享内存键值
  228. /// - `size`: 共享内存大小(bytes)
  229. /// - `shmflg`: 共享内存标志
  230. ///
  231. /// ## 返回值
  232. ///
  233. /// 成功:共享内存id
  234. /// 失败:错误码
  235. pub fn shmget(key: ShmKey, size: usize, shmflg: ShmFlags) -> Result<usize, SystemError> {
  236. // 暂不支持巨页
  237. if shmflg.contains(ShmFlags::SHM_HUGETLB) {
  238. error!("shmget: not support huge page");
  239. return Err(SystemError::ENOSYS);
  240. }
  241. let mut shm_manager_guard = shm_manager_lock();
  242. match key {
  243. // 创建共享内存段
  244. IPC_PRIVATE => shm_manager_guard.add(key, size, shmflg),
  245. _ => {
  246. // 查找key对应的共享内存段是否存在
  247. let id = shm_manager_guard.contains_key(&key);
  248. if let Some(id) = id {
  249. // 不能重复创建
  250. if shmflg.contains(ShmFlags::IPC_CREAT | ShmFlags::IPC_EXCL) {
  251. return Err(SystemError::EEXIST);
  252. }
  253. // key值存在,说明有对应共享内存,返回该共享内存id
  254. return Ok(id.data());
  255. } else {
  256. // key不存在且shm_flags不包含IPC_CREAT创建IPC对象标志,则返回错误码
  257. if !shmflg.contains(ShmFlags::IPC_CREAT) {
  258. return Err(SystemError::ENOENT);
  259. }
  260. // 存在创建IPC对象标志
  261. return shm_manager_guard.add(key, size, shmflg);
  262. }
  263. }
  264. }
  265. }
  266. /// # SYS_SHMAT系统调用函数,用于连接共享内存段
  267. ///
  268. /// ## 参数
  269. ///
  270. /// - `id`: 共享内存id
  271. /// - `vaddr`: 连接共享内存的进程虚拟内存区域起始地址
  272. /// - `shmflg`: 共享内存标志
  273. ///
  274. /// ## 返回值
  275. ///
  276. /// 成功:映射到共享内存的虚拟内存区域起始地址
  277. /// 失败:错误码
  278. pub fn shmat(id: ShmId, vaddr: VirtAddr, shmflg: ShmFlags) -> Result<usize, SystemError> {
  279. let mut shm_manager_guard = shm_manager_lock();
  280. let current_address_space = AddressSpace::current()?;
  281. let mut address_write_guard = current_address_space.write();
  282. let kernel_shm = shm_manager_guard.get_mut(&id).ok_or(SystemError::EINVAL)?;
  283. let size = page_align_up(kernel_shm.size());
  284. let mut phys = PhysPageFrame::new(kernel_shm.start_paddr());
  285. let count = PageFrameCount::from_bytes(size).unwrap();
  286. let r = match vaddr.data() {
  287. // 找到空闲区域并映射到共享内存
  288. 0 => {
  289. // 找到空闲区域
  290. let region = address_write_guard
  291. .mappings
  292. .find_free(vaddr, size)
  293. .ok_or(SystemError::EINVAL)?;
  294. let vm_flags = VmFlags::from(shmflg);
  295. let destination = VirtPageFrame::new(region.start());
  296. let page_flags: EntryFlags<MMArch> =
  297. EntryFlags::from_prot_flags(ProtFlags::from(vm_flags), true);
  298. let flusher: PageFlushAll<MMArch> = PageFlushAll::new();
  299. // 将共享内存映射到对应虚拟区域
  300. let vma = VMA::physmap(
  301. phys,
  302. destination,
  303. count,
  304. vm_flags,
  305. page_flags,
  306. &mut address_write_guard.user_mapper.utable,
  307. flusher,
  308. )?;
  309. // 将VMA加入到当前进程的VMA列表中
  310. address_write_guard.mappings.insert_vma(vma);
  311. region.start().data()
  312. }
  313. // 指定虚拟地址
  314. _ => {
  315. // 获取对应vma
  316. let vma = address_write_guard
  317. .mappings
  318. .contains(vaddr)
  319. .ok_or(SystemError::EINVAL)?;
  320. if vma.lock().region().start() != vaddr {
  321. return Err(SystemError::EINVAL);
  322. }
  323. // 验证用户虚拟内存区域是否有效
  324. let _ = UserBufferReader::new(vaddr.data() as *const u8, size, true)?;
  325. // 必须在取消映射前获取到EntryFlags
  326. let page_flags = address_write_guard
  327. .user_mapper
  328. .utable
  329. .translate(vaddr)
  330. .ok_or(SystemError::EINVAL)?
  331. .1;
  332. // 取消原映射
  333. let flusher: PageFlushAll<MMArch> = PageFlushAll::new();
  334. vma.unmap(&mut address_write_guard.user_mapper.utable, flusher);
  335. // 将该虚拟内存区域映射到共享内存区域
  336. let page_manager_guard = page_manager_lock_irqsave();
  337. let mut virt = VirtPageFrame::new(vaddr);
  338. for _ in 0..count.data() {
  339. let r = unsafe {
  340. address_write_guard.user_mapper.utable.map_phys(
  341. virt.virt_address(),
  342. phys.phys_address(),
  343. page_flags,
  344. )
  345. }
  346. .expect("Failed to map zero, may be OOM error");
  347. r.flush();
  348. // 将vma加入到对应Page的anon_vma
  349. page_manager_guard
  350. .get_unwrap(&phys.phys_address())
  351. .write()
  352. .insert_vma(vma.clone());
  353. phys = phys.next();
  354. virt = virt.next();
  355. }
  356. // 更新vma的映射状态
  357. vma.lock().set_mapped(true);
  358. vaddr.data()
  359. }
  360. };
  361. // 更新最后一次连接时间
  362. kernel_shm.update_atim();
  363. Ok(r)
  364. }
  365. /// # SYS_SHMDT系统调用函数,用于取消对共享内存的连接
  366. ///
  367. /// ## 参数
  368. ///
  369. /// - `vaddr`: 需要取消映射的虚拟内存区域起始地址
  370. ///
  371. /// ## 返回值
  372. ///
  373. /// 成功:0
  374. /// 失败:错误码
  375. pub fn shmdt(vaddr: VirtAddr) -> Result<usize, SystemError> {
  376. let current_address_space = AddressSpace::current()?;
  377. let mut address_write_guard = current_address_space.write();
  378. // 获取vma
  379. let vma = address_write_guard
  380. .mappings
  381. .contains(vaddr)
  382. .ok_or(SystemError::EINVAL)?;
  383. // 判断vaddr是否为起始地址
  384. if vma.lock().region().start() != vaddr {
  385. return Err(SystemError::EINVAL);
  386. }
  387. // 获取映射的物理地址
  388. let paddr = address_write_guard
  389. .user_mapper
  390. .utable
  391. .translate(vaddr)
  392. .ok_or(SystemError::EINVAL)?
  393. .0;
  394. // 如果物理页的shm_id为None,代表不是共享页
  395. let page_manager_guard = page_manager_lock_irqsave();
  396. let page = page_manager_guard.get(&paddr).ok_or(SystemError::EINVAL)?;
  397. let shm_id = page.read().shm_id().ok_or(SystemError::EINVAL)?;
  398. drop(page_manager_guard);
  399. // 获取对应共享页管理信息
  400. let mut shm_manager_guard = shm_manager_lock();
  401. let kernel_shm = shm_manager_guard
  402. .get_mut(&shm_id)
  403. .ok_or(SystemError::EINVAL)?;
  404. // 更新最后一次断开连接时间
  405. kernel_shm.update_dtim();
  406. drop(shm_manager_guard);
  407. // 取消映射
  408. let flusher: PageFlushAll<MMArch> = PageFlushAll::new();
  409. vma.unmap(&mut address_write_guard.user_mapper.utable, flusher);
  410. return Ok(0);
  411. }
  412. /// # SYS_SHMCTL系统调用函数,用于管理共享内存段
  413. ///
  414. /// ## 参数
  415. ///
  416. /// - `id`: 共享内存id
  417. /// - `cmd`: 操作码
  418. /// - `user_buf`: 用户缓冲区
  419. /// - `from_user`: buf_vaddr是否来自用户地址空间
  420. ///
  421. /// ## 返回值
  422. ///
  423. /// 成功:0
  424. /// 失败:错误码
  425. pub fn shmctl(
  426. id: ShmId,
  427. cmd: ShmCtlCmd,
  428. user_buf: *const u8,
  429. from_user: bool,
  430. ) -> Result<usize, SystemError> {
  431. let mut shm_manager_guard = shm_manager_lock();
  432. match cmd {
  433. // 查看共享内存元信息
  434. ShmCtlCmd::IpcInfo => shm_manager_guard.ipc_info(user_buf, from_user),
  435. // 查看共享内存使用信息
  436. ShmCtlCmd::ShmInfo => shm_manager_guard.shm_info(user_buf, from_user),
  437. // 查看id对应的共享内存信息
  438. ShmCtlCmd::ShmStat | ShmCtlCmd::ShmtStatAny | ShmCtlCmd::IpcStat => {
  439. shm_manager_guard.shm_stat(id, cmd, user_buf, from_user)
  440. }
  441. // 设置KernIpcPerm
  442. ShmCtlCmd::IpcSet => shm_manager_guard.ipc_set(id, user_buf, from_user),
  443. // 将共享内存段设置为可回收状态
  444. ShmCtlCmd::IpcRmid => shm_manager_guard.ipc_rmid(id),
  445. // 锁住共享内存段,不允许内存置换
  446. ShmCtlCmd::ShmLock => shm_manager_guard.shm_lock(id),
  447. // 解锁共享内存段,允许内存置换
  448. ShmCtlCmd::ShmUnlock => shm_manager_guard.shm_unlock(id),
  449. // 无效操作码
  450. ShmCtlCmd::Default => Err(SystemError::EINVAL),
  451. }
  452. }
  453. }