xref: /DragonOS/kernel/src/mm/syscall.rs (revision 4cfa009b87c8431a41fab740ffdbd7b008965c9a)
140fe15e0SLoGin use core::intrinsics::unlikely;
240fe15e0SLoGin 
340fe15e0SLoGin use alloc::sync::Arc;
491e9d4abSLoGin use system_error::SystemError;
540fe15e0SLoGin 
6ab5c8ca4Slogin use crate::{
740fe15e0SLoGin     arch::MMArch,
840fe15e0SLoGin     kerror,
940fe15e0SLoGin     libs::align::{check_aligned, page_align_up},
1040fe15e0SLoGin     mm::MemoryManagementArch,
1191e9d4abSLoGin     syscall::Syscall,
12ab5c8ca4Slogin };
13ab5c8ca4Slogin 
1440fe15e0SLoGin use super::{
1540fe15e0SLoGin     allocator::page_frame::{PageFrameCount, VirtPageFrame},
1640fe15e0SLoGin     ucontext::{AddressSpace, DEFAULT_MMAP_MIN_ADDR},
17*4cfa009bSJomo     verify_area, VirtAddr, VmFlags,
1840fe15e0SLoGin };
1940fe15e0SLoGin 
2040fe15e0SLoGin bitflags! {
2140fe15e0SLoGin     /// Memory protection flags
2240fe15e0SLoGin     pub struct ProtFlags: u64 {
2340fe15e0SLoGin         const PROT_NONE = 0x0;
2440fe15e0SLoGin         const PROT_READ = 0x1;
2540fe15e0SLoGin         const PROT_WRITE = 0x2;
2640fe15e0SLoGin         const PROT_EXEC = 0x4;
27ab5c8ca4Slogin     }
2840fe15e0SLoGin 
2940fe15e0SLoGin     /// Memory mapping flags
3040fe15e0SLoGin     pub struct MapFlags: u64 {
3140fe15e0SLoGin         const MAP_NONE = 0x0;
3240fe15e0SLoGin         /// share changes
3340fe15e0SLoGin         const MAP_SHARED = 0x1;
3440fe15e0SLoGin         /// changes are private
3540fe15e0SLoGin         const MAP_PRIVATE = 0x2;
3640fe15e0SLoGin         /// Interpret addr exactly
3740fe15e0SLoGin         const MAP_FIXED = 0x10;
3840fe15e0SLoGin         /// don't use a file
3940fe15e0SLoGin         const MAP_ANONYMOUS = 0x20;
4040fe15e0SLoGin         // linux-6.1-rc5/include/uapi/asm-generic/mman.h#7
4140fe15e0SLoGin         /// stack-like segment
4240fe15e0SLoGin         const MAP_GROWSDOWN = 0x100;
4340fe15e0SLoGin         /// ETXTBSY
4440fe15e0SLoGin         const MAP_DENYWRITE = 0x800;
4540fe15e0SLoGin         /// Mark it as an executable
4640fe15e0SLoGin         const MAP_EXECUTABLE = 0x1000;
4740fe15e0SLoGin         /// Pages are locked
4840fe15e0SLoGin         const MAP_LOCKED = 0x2000;
4940fe15e0SLoGin         /// don't check for reservations
5040fe15e0SLoGin         const MAP_NORESERVE = 0x4000;
5140fe15e0SLoGin         /// populate (prefault) pagetables
5240fe15e0SLoGin         const MAP_POPULATE = 0x8000;
5340fe15e0SLoGin         /// do not block on IO
5440fe15e0SLoGin         const MAP_NONBLOCK = 0x10000;
5540fe15e0SLoGin         /// give out an address that is best suited for process/thread stacks
5640fe15e0SLoGin         const MAP_STACK = 0x20000;
5740fe15e0SLoGin         /// create a huge page mapping
5840fe15e0SLoGin         const MAP_HUGETLB = 0x40000;
5940fe15e0SLoGin         /// perform synchronous page faults for the mapping
6040fe15e0SLoGin         const MAP_SYNC = 0x80000;
6140fe15e0SLoGin         /// MAP_FIXED which doesn't unmap underlying mapping
6240fe15e0SLoGin         const MAP_FIXED_NOREPLACE = 0x100000;
6340fe15e0SLoGin 
6440fe15e0SLoGin         /// For anonymous mmap, memory could be uninitialized
6540fe15e0SLoGin         const MAP_UNINITIALIZED = 0x4000000;
66*4cfa009bSJomo     }
6740fe15e0SLoGin 
68*4cfa009bSJomo     /// Memory mremapping flags
69*4cfa009bSJomo     pub struct MremapFlags: u8 {
70*4cfa009bSJomo         const MREMAP_MAYMOVE = 1;
71*4cfa009bSJomo         const MREMAP_FIXED = 2;
72*4cfa009bSJomo         const MREMAP_DONTUNMAP = 4;
73*4cfa009bSJomo     }
74*4cfa009bSJomo }
75*4cfa009bSJomo 
76*4cfa009bSJomo impl From<MapFlags> for VmFlags {
77*4cfa009bSJomo     fn from(map_flags: MapFlags) -> Self {
78*4cfa009bSJomo         let mut vm_flags = VmFlags::VM_NONE;
79*4cfa009bSJomo 
80*4cfa009bSJomo         if map_flags.contains(MapFlags::MAP_GROWSDOWN) {
81*4cfa009bSJomo             vm_flags |= VmFlags::VM_GROWSDOWN;
82*4cfa009bSJomo         }
83*4cfa009bSJomo 
84*4cfa009bSJomo         if map_flags.contains(MapFlags::MAP_LOCKED) {
85*4cfa009bSJomo             vm_flags |= VmFlags::VM_LOCKED;
86*4cfa009bSJomo         }
87*4cfa009bSJomo 
88*4cfa009bSJomo         if map_flags.contains(MapFlags::MAP_SYNC) {
89*4cfa009bSJomo             vm_flags |= VmFlags::VM_SYNC;
90*4cfa009bSJomo         }
91*4cfa009bSJomo 
92*4cfa009bSJomo         vm_flags
93*4cfa009bSJomo     }
94*4cfa009bSJomo }
95*4cfa009bSJomo 
96*4cfa009bSJomo impl From<ProtFlags> for VmFlags {
97*4cfa009bSJomo     fn from(prot_flags: ProtFlags) -> Self {
98*4cfa009bSJomo         let mut vm_flags = VmFlags::VM_NONE;
99*4cfa009bSJomo 
100*4cfa009bSJomo         if prot_flags.contains(ProtFlags::PROT_READ) {
101*4cfa009bSJomo             vm_flags |= VmFlags::VM_READ;
102*4cfa009bSJomo         }
103*4cfa009bSJomo 
104*4cfa009bSJomo         if prot_flags.contains(ProtFlags::PROT_WRITE) {
105*4cfa009bSJomo             vm_flags |= VmFlags::VM_WRITE;
106*4cfa009bSJomo         }
107*4cfa009bSJomo 
108*4cfa009bSJomo         if prot_flags.contains(ProtFlags::PROT_EXEC) {
109*4cfa009bSJomo             vm_flags |= VmFlags::VM_EXEC;
110*4cfa009bSJomo         }
111*4cfa009bSJomo 
112*4cfa009bSJomo         vm_flags
113*4cfa009bSJomo     }
114*4cfa009bSJomo }
115*4cfa009bSJomo 
116*4cfa009bSJomo impl Into<MapFlags> for VmFlags {
117*4cfa009bSJomo     fn into(self) -> MapFlags {
118*4cfa009bSJomo         let mut map_flags = MapFlags::MAP_NONE;
119*4cfa009bSJomo 
120*4cfa009bSJomo         if self.contains(VmFlags::VM_GROWSDOWN) {
121*4cfa009bSJomo             map_flags |= MapFlags::MAP_GROWSDOWN;
122*4cfa009bSJomo         }
123*4cfa009bSJomo 
124*4cfa009bSJomo         if self.contains(VmFlags::VM_LOCKED) {
125*4cfa009bSJomo             map_flags |= MapFlags::MAP_LOCKED;
126*4cfa009bSJomo         }
127*4cfa009bSJomo 
128*4cfa009bSJomo         if self.contains(VmFlags::VM_SYNC) {
129*4cfa009bSJomo             map_flags |= MapFlags::MAP_SYNC;
130*4cfa009bSJomo         }
131*4cfa009bSJomo 
132*4cfa009bSJomo         map_flags
133*4cfa009bSJomo     }
134*4cfa009bSJomo }
135*4cfa009bSJomo 
136*4cfa009bSJomo impl Into<ProtFlags> for VmFlags {
137*4cfa009bSJomo     fn into(self) -> ProtFlags {
138*4cfa009bSJomo         let mut prot_flags = ProtFlags::PROT_NONE;
139*4cfa009bSJomo 
140*4cfa009bSJomo         if self.contains(VmFlags::VM_READ) {
141*4cfa009bSJomo             prot_flags |= ProtFlags::PROT_READ;
142*4cfa009bSJomo         }
143*4cfa009bSJomo 
144*4cfa009bSJomo         if self.contains(VmFlags::VM_WRITE) {
145*4cfa009bSJomo             prot_flags |= ProtFlags::PROT_WRITE;
146*4cfa009bSJomo         }
147*4cfa009bSJomo 
148*4cfa009bSJomo         if self.contains(VmFlags::VM_EXEC) {
149*4cfa009bSJomo             prot_flags |= ProtFlags::PROT_EXEC;
150*4cfa009bSJomo         }
151*4cfa009bSJomo 
152*4cfa009bSJomo         prot_flags
15340fe15e0SLoGin     }
15440fe15e0SLoGin }
15540fe15e0SLoGin 
156ab5c8ca4Slogin impl Syscall {
15740fe15e0SLoGin     pub fn brk(new_addr: VirtAddr) -> Result<VirtAddr, SystemError> {
15840fe15e0SLoGin         // kdebug!("brk: new_addr={:?}", new_addr);
15940fe15e0SLoGin         let address_space = AddressSpace::current()?;
16040fe15e0SLoGin         let mut address_space = address_space.write();
16140fe15e0SLoGin 
1626d81180bSLoGin         if new_addr < address_space.brk_start || new_addr >= MMArch::USER_END_VADDR {
1636d81180bSLoGin             return Ok(address_space.brk);
1646d81180bSLoGin         }
1656d81180bSLoGin         if new_addr == address_space.brk {
1666d81180bSLoGin             return Ok(address_space.brk);
1676d81180bSLoGin         }
1686d81180bSLoGin 
16940fe15e0SLoGin         unsafe {
17040fe15e0SLoGin             address_space
17140fe15e0SLoGin                 .set_brk(VirtAddr::new(page_align_up(new_addr.data())))
17240fe15e0SLoGin                 .ok();
17340fe15e0SLoGin 
17440fe15e0SLoGin             return Ok(address_space.sbrk(0).unwrap());
175ab5c8ca4Slogin         }
176d8ad0a5eSLoGin     }
177d8ad0a5eSLoGin 
17840fe15e0SLoGin     pub fn sbrk(incr: isize) -> Result<VirtAddr, SystemError> {
17940fe15e0SLoGin         let address_space = AddressSpace::current()?;
1801496ba7bSLoGin         assert!(address_space.read().user_mapper.utable.is_current());
18140fe15e0SLoGin         let mut address_space = address_space.write();
18240fe15e0SLoGin         let r = unsafe { address_space.sbrk(incr) };
18340fe15e0SLoGin 
18440fe15e0SLoGin         return r;
185d8ad0a5eSLoGin     }
186d8ad0a5eSLoGin 
18740fe15e0SLoGin     /// ## mmap系统调用
188d8ad0a5eSLoGin     ///
18940fe15e0SLoGin     /// 该函数的实现参考了Linux内核的实现,但是并不完全相同。因为有些功能咱们还没实现
19040fe15e0SLoGin     ///
19140fe15e0SLoGin     /// ## 参数
19240fe15e0SLoGin     ///
19340fe15e0SLoGin     /// - `start_vaddr`:映射的起始地址
19440fe15e0SLoGin     /// - `len`:映射的长度
19540fe15e0SLoGin     /// - `prot`:保护标志
19640fe15e0SLoGin     /// - `flags`:映射标志
19740fe15e0SLoGin     /// - `fd`:文件描述符(暂时不支持)
19840fe15e0SLoGin     /// - `offset`:文件偏移量 (暂时不支持)
19940fe15e0SLoGin     ///
20040fe15e0SLoGin     /// ## 返回值
20140fe15e0SLoGin     ///
20240fe15e0SLoGin     /// 成功时返回映射的起始地址,失败时返回错误码
20340fe15e0SLoGin     pub fn mmap(
20440fe15e0SLoGin         start_vaddr: VirtAddr,
20540fe15e0SLoGin         len: usize,
20640fe15e0SLoGin         prot_flags: usize,
20740fe15e0SLoGin         map_flags: usize,
20840fe15e0SLoGin         _fd: i32,
20940fe15e0SLoGin         _offset: usize,
21040fe15e0SLoGin     ) -> Result<usize, SystemError> {
21140fe15e0SLoGin         let map_flags = MapFlags::from_bits_truncate(map_flags as u64);
21240fe15e0SLoGin         let prot_flags = ProtFlags::from_bits_truncate(prot_flags as u64);
21340fe15e0SLoGin 
21440fe15e0SLoGin         if start_vaddr < VirtAddr::new(DEFAULT_MMAP_MIN_ADDR)
21540fe15e0SLoGin             && map_flags.contains(MapFlags::MAP_FIXED)
21640fe15e0SLoGin         {
21740fe15e0SLoGin             kerror!(
21840fe15e0SLoGin                 "mmap: MAP_FIXED is not supported for address below {}",
21940fe15e0SLoGin                 DEFAULT_MMAP_MIN_ADDR
22040fe15e0SLoGin             );
22140fe15e0SLoGin             return Err(SystemError::EINVAL);
222d8ad0a5eSLoGin         }
22340fe15e0SLoGin         // 暂时不支持除匿名页以外的映射
22440fe15e0SLoGin         if !map_flags.contains(MapFlags::MAP_ANONYMOUS) {
22540fe15e0SLoGin             kerror!("mmap: not support file mapping");
22640fe15e0SLoGin             return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
22740fe15e0SLoGin         }
22840fe15e0SLoGin 
22940fe15e0SLoGin         // 暂时不支持巨页映射
23040fe15e0SLoGin         if map_flags.contains(MapFlags::MAP_HUGETLB) {
23140fe15e0SLoGin             kerror!("mmap: not support huge page mapping");
23240fe15e0SLoGin             return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
23340fe15e0SLoGin         }
23440fe15e0SLoGin         let current_address_space = AddressSpace::current()?;
23540fe15e0SLoGin         let start_page = current_address_space.write().map_anonymous(
23640fe15e0SLoGin             start_vaddr,
23740fe15e0SLoGin             len,
23840fe15e0SLoGin             prot_flags,
23940fe15e0SLoGin             map_flags,
24040fe15e0SLoGin             true,
24140fe15e0SLoGin         )?;
24240fe15e0SLoGin         return Ok(start_page.virt_address().data());
24340fe15e0SLoGin     }
24440fe15e0SLoGin 
245*4cfa009bSJomo     /// ## mremap系统调用
246*4cfa009bSJomo     ///
247*4cfa009bSJomo     ///
248*4cfa009bSJomo     /// ## 参数
249*4cfa009bSJomo     ///
250*4cfa009bSJomo     /// - `old_vaddr`:原映射的起始地址
251*4cfa009bSJomo     /// - `old_len`:原映射的长度
252*4cfa009bSJomo     /// - `new_len`:重新映射的长度
253*4cfa009bSJomo     /// - `mremap_flags`:重映射标志
254*4cfa009bSJomo     /// - `new_vaddr`:重新映射的起始地址
255*4cfa009bSJomo     ///
256*4cfa009bSJomo     /// ## 返回值
257*4cfa009bSJomo     ///
258*4cfa009bSJomo     /// 成功时返回重映射的起始地址,失败时返回错误码
259*4cfa009bSJomo     pub fn mremap(
260*4cfa009bSJomo         old_vaddr: VirtAddr,
261*4cfa009bSJomo         old_len: usize,
262*4cfa009bSJomo         new_len: usize,
263*4cfa009bSJomo         mremap_flags: MremapFlags,
264*4cfa009bSJomo         new_vaddr: VirtAddr,
265*4cfa009bSJomo     ) -> Result<usize, SystemError> {
266*4cfa009bSJomo         // 需要重映射到新内存区域的情况下,必须包含MREMAP_MAYMOVE并且指定新地址
267*4cfa009bSJomo         if mremap_flags.contains(MremapFlags::MREMAP_FIXED)
268*4cfa009bSJomo             && (!mremap_flags.contains(MremapFlags::MREMAP_MAYMOVE)
269*4cfa009bSJomo                 || new_vaddr == VirtAddr::new(0))
270*4cfa009bSJomo         {
271*4cfa009bSJomo             return Err(SystemError::EINVAL);
272*4cfa009bSJomo         }
273*4cfa009bSJomo 
274*4cfa009bSJomo         // 不取消旧映射的情况下,必须包含MREMAP_MAYMOVE并且新内存大小等于旧内存大小
275*4cfa009bSJomo         if mremap_flags.contains(MremapFlags::MREMAP_DONTUNMAP)
276*4cfa009bSJomo             && (!mremap_flags.contains(MremapFlags::MREMAP_MAYMOVE) || old_len != new_len)
277*4cfa009bSJomo         {
278*4cfa009bSJomo             return Err(SystemError::EINVAL);
279*4cfa009bSJomo         }
280*4cfa009bSJomo 
281*4cfa009bSJomo         // 旧内存地址必须对齐
282*4cfa009bSJomo         if !old_vaddr.check_aligned(MMArch::PAGE_SIZE) {
283*4cfa009bSJomo             return Err(SystemError::EINVAL);
284*4cfa009bSJomo         }
285*4cfa009bSJomo 
286*4cfa009bSJomo         // 将old_len、new_len 对齐页面大小
287*4cfa009bSJomo         let old_len = page_align_up(old_len);
288*4cfa009bSJomo         let new_len = page_align_up(new_len);
289*4cfa009bSJomo 
290*4cfa009bSJomo         // 不允许重映射内存区域大小为0
291*4cfa009bSJomo         if new_len == 0 {
292*4cfa009bSJomo             return Err(SystemError::EINVAL);
293*4cfa009bSJomo         }
294*4cfa009bSJomo 
295*4cfa009bSJomo         let current_address_space = AddressSpace::current()?;
296*4cfa009bSJomo         let vma = current_address_space.read().mappings.contains(old_vaddr);
297*4cfa009bSJomo         if vma.is_none() {
298*4cfa009bSJomo             return Err(SystemError::EINVAL);
299*4cfa009bSJomo         }
300*4cfa009bSJomo         let vma = vma.unwrap();
301*4cfa009bSJomo         let vm_flags = vma.lock().vm_flags().clone();
302*4cfa009bSJomo 
303*4cfa009bSJomo         // 暂时不支持巨页映射
304*4cfa009bSJomo         if vm_flags.contains(VmFlags::VM_HUGETLB) {
305*4cfa009bSJomo             kerror!("mmap: not support huge page mapping");
306*4cfa009bSJomo             return Err(SystemError::ENOSYS);
307*4cfa009bSJomo         }
308*4cfa009bSJomo 
309*4cfa009bSJomo         // 缩小旧内存映射区域
310*4cfa009bSJomo         if old_len > new_len {
311*4cfa009bSJomo             Self::munmap(old_vaddr + new_len, old_len - new_len)?;
312*4cfa009bSJomo             return Ok(old_vaddr.data());
313*4cfa009bSJomo         }
314*4cfa009bSJomo 
315*4cfa009bSJomo         // 重映射到新内存区域
316*4cfa009bSJomo         let r = current_address_space.write().mremap(
317*4cfa009bSJomo             old_vaddr,
318*4cfa009bSJomo             old_len,
319*4cfa009bSJomo             new_len,
320*4cfa009bSJomo             mremap_flags,
321*4cfa009bSJomo             new_vaddr,
322*4cfa009bSJomo             vm_flags,
323*4cfa009bSJomo         )?;
324*4cfa009bSJomo 
325*4cfa009bSJomo         if !mremap_flags.contains(MremapFlags::MREMAP_DONTUNMAP) {
326*4cfa009bSJomo             Self::munmap(old_vaddr, old_len)?;
327*4cfa009bSJomo         }
328*4cfa009bSJomo 
329*4cfa009bSJomo         return Ok(r.data());
330*4cfa009bSJomo     }
331*4cfa009bSJomo 
33240fe15e0SLoGin     /// ## munmap系统调用
33340fe15e0SLoGin     ///
33440fe15e0SLoGin     /// ## 参数
33540fe15e0SLoGin     ///
33640fe15e0SLoGin     /// - `start_vaddr`:取消映射的起始地址(已经对齐到页)
33740fe15e0SLoGin     /// - `len`:取消映射的字节数(已经对齐到页)
33840fe15e0SLoGin     ///
33940fe15e0SLoGin     /// ## 返回值
34040fe15e0SLoGin     ///
34140fe15e0SLoGin     /// 成功时返回0,失败时返回错误码
34240fe15e0SLoGin     pub fn munmap(start_vaddr: VirtAddr, len: usize) -> Result<usize, SystemError> {
34340fe15e0SLoGin         assert!(start_vaddr.check_aligned(MMArch::PAGE_SIZE));
34440fe15e0SLoGin         assert!(check_aligned(len, MMArch::PAGE_SIZE));
34540fe15e0SLoGin 
34640fe15e0SLoGin         if unlikely(verify_area(start_vaddr, len).is_err()) {
34740fe15e0SLoGin             return Err(SystemError::EINVAL);
34840fe15e0SLoGin         }
34940fe15e0SLoGin         if unlikely(len == 0) {
35040fe15e0SLoGin             return Err(SystemError::EINVAL);
35140fe15e0SLoGin         }
35240fe15e0SLoGin 
35340fe15e0SLoGin         let current_address_space: Arc<AddressSpace> = AddressSpace::current()?;
35440fe15e0SLoGin         let start_frame = VirtPageFrame::new(start_vaddr);
35540fe15e0SLoGin         let page_count = PageFrameCount::new(len / MMArch::PAGE_SIZE);
35640fe15e0SLoGin 
35740fe15e0SLoGin         current_address_space
35840fe15e0SLoGin             .write()
35940fe15e0SLoGin             .munmap(start_frame, page_count)
36040fe15e0SLoGin             .map_err(|_| SystemError::EINVAL)?;
361*4cfa009bSJomo 
36240fe15e0SLoGin         return Ok(0);
36340fe15e0SLoGin     }
36440fe15e0SLoGin 
36540fe15e0SLoGin     /// ## mprotect系统调用
36640fe15e0SLoGin     ///
36740fe15e0SLoGin     /// ## 参数
36840fe15e0SLoGin     ///
36940fe15e0SLoGin     /// - `start_vaddr`:起始地址(已经对齐到页)
37040fe15e0SLoGin     /// - `len`:长度(已经对齐到页)
37140fe15e0SLoGin     /// - `prot_flags`:保护标志
37240fe15e0SLoGin     pub fn mprotect(
37340fe15e0SLoGin         start_vaddr: VirtAddr,
37440fe15e0SLoGin         len: usize,
37540fe15e0SLoGin         prot_flags: usize,
37640fe15e0SLoGin     ) -> Result<usize, SystemError> {
37740fe15e0SLoGin         assert!(start_vaddr.check_aligned(MMArch::PAGE_SIZE));
37840fe15e0SLoGin         assert!(check_aligned(len, MMArch::PAGE_SIZE));
37940fe15e0SLoGin 
38040fe15e0SLoGin         if unlikely(verify_area(start_vaddr, len).is_err()) {
38140fe15e0SLoGin             return Err(SystemError::EINVAL);
38240fe15e0SLoGin         }
38340fe15e0SLoGin         if unlikely(len == 0) {
38440fe15e0SLoGin             return Err(SystemError::EINVAL);
38540fe15e0SLoGin         }
38640fe15e0SLoGin 
38740fe15e0SLoGin         let prot_flags = ProtFlags::from_bits(prot_flags as u64).ok_or(SystemError::EINVAL)?;
38840fe15e0SLoGin 
38940fe15e0SLoGin         let current_address_space: Arc<AddressSpace> = AddressSpace::current()?;
39040fe15e0SLoGin         let start_frame = VirtPageFrame::new(start_vaddr);
39140fe15e0SLoGin         let page_count = PageFrameCount::new(len / MMArch::PAGE_SIZE);
39240fe15e0SLoGin 
39340fe15e0SLoGin         current_address_space
39440fe15e0SLoGin             .write()
39540fe15e0SLoGin             .mprotect(start_frame, page_count, prot_flags)
39640fe15e0SLoGin             .map_err(|_| SystemError::EINVAL)?;
39740fe15e0SLoGin         return Ok(0);
398ab5c8ca4Slogin     }
399ab5c8ca4Slogin }
400