fn handle_vspace(arg1: u64, arg2: u64, arg3: u64) -> Result<(u64, u64), KError> {
    let op = VSpaceOperation::from(arg1);
    let base = VAddr::from(arg2);
    let region_size = arg3;
    trace!("handle_vspace {:?} {:#x} {:#x}", op, base, region_size);

    let kcb = super::kcb::get_kcb();
    let mut p = kcb.arch.current_executor()?;

    match op {
        VSpaceOperation::MapMem | VSpaceOperation::MapPMem => unsafe {
            let (bp, lp) = crate::memory::size_to_pages(region_size as usize);
            let mut frames = Vec::try_with_capacity(bp + lp)?;
            let mem_type = match op {
                VSpaceOperation::MapMem => MemType::Mem,
                VSpaceOperation::MapPMem => MemType::PMem,
                _ => unreachable!(), // We already checked before coming here.
            };
            crate::memory::KernelAllocator::try_refill_tcache(20 + bp, lp, mem_type)?;

            // TODO(apihell): This `paddr` is bogus, it will return the PAddr of the
            // first frame mapped but if you map multiple Frames, no chance getting that
            // Better would be a function to request physically consecutive DMA memory
            // or use IO-MMU translation (see also rumpuser_pci_dmalloc)
            // also better to just return what NR replies with...
            let mut paddr = None;
            let mut total_len = 0;
            {
                let mut pmanager = match mem_type {
                    MemType::Mem => kcb.mem_manager(),
                    MemType::PMem => kcb.pmem_manager(),
                    _ => unreachable!(),
                };

                for _i in 0..lp {
                    let mut frame = pmanager
                        .allocate_large_page()
                        .expect("We refilled so allocation should work.");
                    total_len += frame.size;
                    unsafe { frame.zero() };
                    frames
                        .try_push(frame)
                        .expect("Can't fail see `try_with_capacity`");
                    if paddr.is_none() {
                        paddr = Some(frame.base);
                    }
                }
                for _i in 0..bp {
                    let mut frame = pmanager
                        .allocate_base_page()
                        .expect("We refilled so allocation should work.");
                    total_len += frame.size;
                    unsafe { frame.zero() };
                    frames
                        .try_push(frame)
                        .expect("Can't fail see `try_with_capacity`");
                    if paddr.is_none() {
                        paddr = Some(frame.base);
                    }
                }
            }

            nrproc::NrProcess::<Ring3Process>::map_frames(
                p.pid,
                base,
                frames,
                MapAction::ReadWriteUser,
            )
            .expect("Can't map memory");

            Ok((paddr.unwrap().as_u64(), total_len as u64))
        },
        VSpaceOperation::MapDevice => unsafe {
            let paddr = PAddr::from(base.as_u64());
            let size = region_size as usize;

            let frame = Frame::new(paddr, size, kcb.node);

            nrproc::NrProcess::<Ring3Process>::map_device_frame(
                p.pid,
                frame,
                MapAction::ReadWriteUser,
            )
        },
        VSpaceOperation::MapMemFrame => unsafe {
            let base = VAddr::from(arg2);
            let frame_id: FrameId = arg3.try_into().map_err(|_e| KError::InvalidFrameId)?;

            let (paddr, size) = nrproc::NrProcess::<Ring3Process>::map_frame_id(
                p.pid,
                frame_id,
                base,
                MapAction::ReadWriteUser,
            )?;
            Ok((paddr.as_u64(), size as u64))
        },
        VSpaceOperation::UnmapMem | VSpaceOperation::UnmapPMem => {
            let handle = nrproc::NrProcess::<Ring3Process>::unmap(p.pid, base)?;
            let va: u64 = handle.vaddr.as_u64();
            let sz: u64 = handle.frame.size as u64;
            super::tlb::shootdown(handle);

            Ok((va, sz))
        }
        VSpaceOperation::Identify => unsafe {
            trace!("Identify base {:#x}.", base);
            nrproc::NrProcess::<Ring3Process>::resolve(p.pid, base)
        },
        VSpaceOperation::Unknown => {
            error!("Got an invalid VSpaceOperation code.");
            Err(KError::InvalidVSpaceOperation { a: arg1 })
        }
    }
}
/// System call handler for vspace operations
System call handler for vspace operations
System call handler for vspace operations
fn handle_vspace(arg1: u64, arg2: u64, arg3: u64) -> Result<(u64, u64), KError> {
    let op = VSpaceOperation::from(arg1);
    let base = VAddr::from(arg2);
    let region_size = arg3;
    trace!("handle_vspace {:?} {:#x} {:#x}", op, base, region_size);
    let kcb = super::kcb::get_kcb();
    let mut p = kcb.arch.current_executor()?;
    match op {
        VSpaceOperation::MapMem | VSpaceOperation::MapPMem => unsafe {
            let (bp, lp) = crate::memory::size_to_pages(region_size as usize);
            let mut frames = Vec::try_with_capacity(bp + lp)?;
            let mem_type = match op {
                VSpaceOperation::MapMem => MemType::Mem,
                VSpaceOperation::MapPMem => MemType::PMem,
                _ => unreachable!(), // We already checked before coming here.
            };
            crate::memory::KernelAllocator::try_refill_tcache(20 + bp, lp, mem_type)?;
            // TODO(apihell): This `paddr` is bogus, it will return the PAddr of the
            // first frame mapped but if you map multiple Frames, no chance getting that
            // Better would be a function to request physically consecutive DMA memory
            // or use IO-MMU translation (see also rumpuser_pci_dmalloc)
            // also better to just return what NR replies with...
            let mut paddr = None;
            let mut total_len = 0;
            {
                let mut pmanager = match mem_type {
                    MemType::Mem => kcb.mem_manager(),
                    MemType::PMem => kcb.pmem_manager(),
                    _ => unreachable!(),
                };
                for _i in 0..lp {
                    let mut frame = pmanager
                        .allocate_large_page()
                        .expect("We refilled so allocation should work.");
                    total_len += frame.size;
                    unsafe { frame.zero() };
                    frames
                        .try_push(frame)
                        .expect("Can't fail see `try_with_capacity`");
                    if paddr.is_none() {
                        paddr = Some(frame.base);
                    }
                }
                for _i in 0..bp {
                    let mut frame = pmanager
                        .allocate_base_page()
                        .expect("We refilled so allocation should work.");
                    total_len += frame.size;
                    unsafe { frame.zero() };
                    frames
                        .try_push(frame)
                        .expect("Can't fail see `try_with_capacity`");
                    if paddr.is_none() {
                        paddr = Some(frame.base);
                    }
                }
            }
            nrproc::NrProcess::<Ring3Process>::map_frames(
                p.pid,
                base,
                frames,
                MapAction::ReadWriteUser,
            )
            .expect("Can't map memory");
            Ok((paddr.unwrap().as_u64(), total_len as u64))
        },
        VSpaceOperation::MapDevice => unsafe {
            let paddr = PAddr::from(base.as_u64());
            let size = region_size as usize;
            let frame = Frame::new(paddr, size, kcb.node);
            nrproc::NrProcess::<Ring3Process>::map_device_frame(
                p.pid,
                frame,
                MapAction::ReadWriteUser,
            )
        },
        VSpaceOperation::MapMemFrame => unsafe {
            let base = VAddr::from(arg2);
            let frame_id: FrameId = arg3.try_into().map_err(|_e| KError::InvalidFrameId)?;
            let (paddr, size) = nrproc::NrProcess::<Ring3Process>::map_frame_id(
                p.pid,
                frame_id,
                base,
                MapAction::ReadWriteUser,
            )?;
            Ok((paddr.as_u64(), size as u64))
        },
        VSpaceOperation::UnmapMem | VSpaceOperation::UnmapPMem => {
            let handle = nrproc::NrProcess::<Ring3Process>::unmap(p.pid, base)?;
            let va: u64 = handle.vaddr.as_u64();
            let sz: u64 = handle.frame.size as u64;
            super::tlb::shootdown(handle);
            Ok((va, sz))
        }
        VSpaceOperation::Identify => unsafe {
            trace!("Identify base {:#x}.", base);
            nrproc::NrProcess::<Ring3Process>::resolve(p.pid, base)
        },
        VSpaceOperation::Unknown => {
            error!("Got an invalid VSpaceOperation code.");
            Err(KError::InvalidVSpaceOperation { a: arg1 })
        }
    }
}
fn handle_vspace ( arg1 : u64 , arg2 : u64 , arg3 : u64 ) -> Result < ( u64 , u64 ) , KError > { let op = VSpaceOperation :: from ( arg1 ) ; let base = VAddr :: from ( arg2 ) ; let region_size = arg3 ; trace ! ( " " op base region_size ) ; let kcb = super :: kcb :: get_kcb ( ) ; let mut p = kcb . arch . current_executor ( ) ? ; match op { VSpaceOperation :: MapMem | VSpaceOperation :: MapPMem => unsafe { let ( bp , lp ) = crate :: memory :: size_to_pages ( region_size as usize ) ; let mut frames = Vec :: try_with_capacity ( bp + lp ) ? ; let mem_type = match op { VSpaceOperation :: MapMem => MemType :: Mem , VSpaceOperation :: MapPMem => MemType :: PMem , _ => unreachable ! ( ) , // We already checked before coming here. } ; crate :: memory :: KernelAllocator :: try_refill_tcache ( 20 + bp , lp , mem_type ) ? ; // TODO(apihell): This `paddr` is bogus, it will return the PAddr of the // first frame mapped but if you map multiple Frames, no chance getting that // Better would be a function to request physically consecutive DMA memory // or use IO-MMU translation (see also rumpuser_pci_dmalloc) // also better to just return what NR replies with... let mut paddr = None ; let mut total_len = 0 ; { let mut pmanager = match mem_type { MemType :: Mem => kcb . mem_manager ( ) , MemType :: PMem => kcb . pmem_manager ( ) , _ => unreachable ! ( ) , } ; for _i in 0 .. lp { let mut frame = pmanager . allocate_large_page ( ) . expect ( " " ) ; total_len += frame . size ; unsafe { frame . zero ( ) } ; frames . try_push ( frame ) . expect ( " " ) ; if paddr . is_none ( ) { paddr = Some ( frame . base ) ; } } for _i in 0 .. bp { let mut frame = pmanager . allocate_base_page ( ) . expect ( " " ) ; total_len += frame . size ; unsafe { frame . zero ( ) } ; frames . try_push ( frame ) . expect ( " " ) ; if paddr . is_none ( ) { paddr = Some ( frame . base ) ; } } } nrproc :: NrProcess :: < Ring3Process > :: map_frames ( p . pid , base , frames , MapAction :: ReadWriteUser , ) . expect ( " " ) ; Ok ( ( paddr . unwrap ( ) . as_u64 ( ) , total_len as u64 ) ) } , VSpaceOperation :: MapDevice => unsafe { let paddr = PAddr :: from ( base . as_u64 ( ) ) ; let size = region_size as usize ; let frame = Frame :: new ( paddr , size , kcb . node ) ; nrproc :: NrProcess :: < Ring3Process > :: map_device_frame ( p . pid , frame , MapAction :: ReadWriteUser , ) } , VSpaceOperation :: MapMemFrame => unsafe { let base = VAddr :: from ( arg2 ) ; let frame_id : FrameId = arg3 . try_into ( ) . map_err ( | _e | KError :: InvalidFrameId ) ? ; let ( paddr , size ) = nrproc :: NrProcess :: < Ring3Process > :: map_frame_id ( p . pid , frame_id , base , MapAction :: ReadWriteUser , ) ? ; Ok ( ( paddr . as_u64 ( ) , size as u64 ) ) } , VSpaceOperation :: UnmapMem | VSpaceOperation :: UnmapPMem => { let handle = nrproc :: NrProcess :: < Ring3Process > :: unmap ( p . pid , base ) ? ; let va : u64 = handle . vaddr . as_u64 ( ) ; let sz : u64 = handle . frame . size as u64 ; super :: tlb :: shootdown ( handle ) ; Ok ( ( va , sz ) ) } VSpaceOperation :: Identify => unsafe { trace ! ( " " base ) ; nrproc :: NrProcess :: < Ring3Process > :: resolve ( p . pid , base ) } , VSpaceOperation :: Unknown => { error ! ( " " ) ; Err ( KError :: InvalidVSpaceOperation { a : arg1 } ) } } }
System call handler for vspace operations
System call handler for vspace operations
arg1
u64
arg2
u64
arg3
u64
arg1
u64
arg2
u64
arg3
u64