sys_mprotect.rs 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. //! System call handler for the mprotect system call.
  2. use crate::arch::{interrupt::TrapFrame, syscall::nr::SYS_MPROTECT, MMArch};
  3. use crate::mm::{
  4. syscall::{check_aligned, PageFrameCount, ProtFlags},
  5. ucontext::AddressSpace,
  6. MemoryManagementArch, VirtPageFrame, {verify_area, VirtAddr},
  7. };
  8. use crate::syscall::table::{FormattedSyscallParam, Syscall};
  9. use system_error::SystemError;
  10. use alloc::sync::Arc;
  11. use alloc::vec::Vec;
  12. /// Handles the mprotect system call.
  13. pub struct SysMprotectHandle;
  14. impl Syscall for SysMprotectHandle {
  15. fn num_args(&self) -> usize {
  16. 3
  17. }
  18. /// ## mprotect系统调用
  19. ///
  20. /// ## 参数
  21. ///
  22. /// - `start_vaddr`:起始地址(已经对齐到页)
  23. /// - `len`:长度(已经对齐到页)
  24. /// - `prot_flags`:保护标志
  25. fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
  26. let start_vaddr = VirtAddr::new(Self::start_vaddr(args));
  27. let len = Self::len(args);
  28. let prot_flags =
  29. ProtFlags::from_bits(Self::prot_flags(args) as u64).ok_or(SystemError::EINVAL)?;
  30. assert!(start_vaddr.check_aligned(MMArch::PAGE_SIZE));
  31. assert!(check_aligned(len, MMArch::PAGE_SIZE));
  32. if verify_area(start_vaddr, len).is_err() {
  33. return Err(SystemError::EINVAL);
  34. }
  35. if len == 0 {
  36. return Err(SystemError::EINVAL);
  37. }
  38. let current_address_space: Arc<AddressSpace> = AddressSpace::current()?;
  39. let start_frame = VirtPageFrame::new(start_vaddr);
  40. let page_count = PageFrameCount::new(len / MMArch::PAGE_SIZE);
  41. current_address_space
  42. .write()
  43. .mprotect(start_frame, page_count, prot_flags)
  44. .map_err(|_| SystemError::EINVAL)?;
  45. return Ok(0);
  46. }
  47. /// Formats the syscall arguments for display/debugging purposes.
  48. fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
  49. vec![
  50. FormattedSyscallParam::new("start_vaddr", format!("{:#x}", Self::start_vaddr(args))),
  51. FormattedSyscallParam::new("len", format!("{:#x}", Self::len(args))),
  52. FormattedSyscallParam::new("prot_flags", format!("{:#x}", Self::prot_flags(args))),
  53. ]
  54. }
  55. }
  56. impl SysMprotectHandle {
  57. /// Extracts the start_vaddr argument from syscall parameters.
  58. fn start_vaddr(args: &[usize]) -> usize {
  59. args[0]
  60. }
  61. /// Extracts the len argument from syscall parameters.
  62. fn len(args: &[usize]) -> usize {
  63. args[1]
  64. }
  65. /// Extracts the prot_flags argument from syscall parameters.
  66. fn prot_flags(args: &[usize]) -> usize {
  67. args[2]
  68. }
  69. }
  70. syscall_table_macros::declare_syscall!(SYS_MPROTECT, SysMprotectHandle);