pub fn sys_vmar_map(
        &self,
        vmar_handle: HandleValue,
        options: u32,
        vmar_offset: usize,
        vmo_handle: HandleValue,
        vmo_offset: usize,
        len: usize,
        mut mapped_addr: UserOutPtr<VirtAddr>,
    ) -> ZxResult {
        info!(
            "vmar.map: vmar_handle={:#x?}, options={:#x?}, vmar_offset={:#x?}, vmo_handle={:#x?}, vmo_offset={:#x?}, len={:#x?}",
            vmar_handle, options, vmar_offset, vmo_handle, vmo_offset, len
        );
        let options = VmOptions::from_bits(options).ok_or(ZxError::INVALID_ARGS)?;
        let proc = self.thread.proc();
        let (vmar, vmar_rights) = proc.get_object_and_rights::<VmAddressRegion>(vmar_handle)?;
        let (vmo, vmo_rights) = proc.get_object_and_rights::<VmObject>(vmo_handle)?;
        if !vmo_rights.contains(Rights::MAP) {
            return Err(ZxError::ACCESS_DENIED);
        };
        if options
            .intersects(VmOptions::CAN_MAP_RXW | VmOptions::CAN_MAP_SPECIFIC | VmOptions::COMPACT)
        {
            return Err(ZxError::INVALID_ARGS);
        }
        if options.contains(VmOptions::REQUIRE_NON_RESIZABLE) && vmo.is_resizable() {
            return Err(ZxError::NOT_SUPPORTED);
        }
        // check SPECIFIC options with offset
        let is_specific = options.contains(VmOptions::SPECIFIC)
            || options.contains(VmOptions::SPECIFIC_OVERWRITE);
        if !is_specific && vmar_offset != 0 {
            return Err(ZxError::INVALID_ARGS);
        }
        if !vmar_rights.contains(options.to_required_rights()) {
            return Err(ZxError::ACCESS_DENIED);
        }
        let mut permissions = MMUFlags::empty();
        permissions.set(MMUFlags::READ, vmo_rights.contains(Rights::READ));
        permissions.set(MMUFlags::WRITE, vmo_rights.contains(Rights::WRITE));
        permissions.set(MMUFlags::EXECUTE, vmo_rights.contains(Rights::EXECUTE));
        let mut mapping_flags = MMUFlags::USER;
        mapping_flags.set(MMUFlags::READ, options.contains(VmOptions::PERM_READ));
        mapping_flags.set(MMUFlags::WRITE, options.contains(VmOptions::PERM_WRITE));
        mapping_flags.set(MMUFlags::EXECUTE, options.contains(VmOptions::PERM_EXECUTE));
        let overwrite = options.contains(VmOptions::SPECIFIC_OVERWRITE);
        #[cfg(feature = "deny-page-fault")]
        let map_range = true;
        #[cfg(not(feature = "deny-page-fault"))]
        let map_range = options.contains(VmOptions::MAP_RANGE);

        info!(
            "mmuflags: {:?}, is_specific {:?}, overwrite {:?}, map_range {:?}",
            mapping_flags, is_specific, overwrite, map_range
        );
        if map_range && overwrite {
            return Err(ZxError::INVALID_ARGS);
        }
        // Note: we should reject non-page-aligned length here,
        // but since zCore use different memory layout from zircon,
        // we should not reject them and round up them instead
        // TODO: reject non-page-aligned length after we have the same memory layout with zircon
        let len = roundup_pages(len);
        if len == 0 {
            return Err(ZxError::INVALID_ARGS);
        }
        let vmar_offset = if is_specific { Some(vmar_offset) } else { None };
        let vaddr = vmar.map_ext(
            vmar_offset,
            vmo,
            vmo_offset,
            len,
            permissions,
            mapping_flags,
            overwrite,
            map_range,
        )?;
        info!("vmar.map: at {:#x?}", vaddr);
        mapped_addr.write(vaddr)?;
        Ok(())
    }
/// Add a memory mapping.
///
/// Maps the given VMO into the given virtual memory address region.
Add a memory mapping.
Maps the given VMO into the given virtual memory address region.
Add a memory mapping . Maps the given VMO into the given virtual memory address region .
pub fn sys_vmar_map(
        &self,
        vmar_handle: HandleValue,
        options: u32,
        vmar_offset: usize,
        vmo_handle: HandleValue,
        vmo_offset: usize,
        len: usize,
        mut mapped_addr: UserOutPtr<VirtAddr>,
    ) -> ZxResult {
        info!(
            "vmar.map: vmar_handle={:#x?}, options={:#x?}, vmar_offset={:#x?}, vmo_handle={:#x?}, vmo_offset={:#x?}, len={:#x?}",
            vmar_handle, options, vmar_offset, vmo_handle, vmo_offset, len
        );
        let options = VmOptions::from_bits(options).ok_or(ZxError::INVALID_ARGS)?;
        let proc = self.thread.proc();
        let (vmar, vmar_rights) = proc.get_object_and_rights::<VmAddressRegion>(vmar_handle)?;
        let (vmo, vmo_rights) = proc.get_object_and_rights::<VmObject>(vmo_handle)?;
        if !vmo_rights.contains(Rights::MAP) {
            return Err(ZxError::ACCESS_DENIED);
        };
        if options
            .intersects(VmOptions::CAN_MAP_RXW | VmOptions::CAN_MAP_SPECIFIC | VmOptions::COMPACT)
        {
            return Err(ZxError::INVALID_ARGS);
        }
        if options.contains(VmOptions::REQUIRE_NON_RESIZABLE) && vmo.is_resizable() {
            return Err(ZxError::NOT_SUPPORTED);
        }
        // check SPECIFIC options with offset
        let is_specific = options.contains(VmOptions::SPECIFIC)
            || options.contains(VmOptions::SPECIFIC_OVERWRITE);
        if !is_specific && vmar_offset != 0 {
            return Err(ZxError::INVALID_ARGS);
        }
        if !vmar_rights.contains(options.to_required_rights()) {
            return Err(ZxError::ACCESS_DENIED);
        }
        let mut permissions = MMUFlags::empty();
        permissions.set(MMUFlags::READ, vmo_rights.contains(Rights::READ));
        permissions.set(MMUFlags::WRITE, vmo_rights.contains(Rights::WRITE));
        permissions.set(MMUFlags::EXECUTE, vmo_rights.contains(Rights::EXECUTE));
        let mut mapping_flags = MMUFlags::USER;
        mapping_flags.set(MMUFlags::READ, options.contains(VmOptions::PERM_READ));
        mapping_flags.set(MMUFlags::WRITE, options.contains(VmOptions::PERM_WRITE));
        mapping_flags.set(MMUFlags::EXECUTE, options.contains(VmOptions::PERM_EXECUTE));
        let overwrite = options.contains(VmOptions::SPECIFIC_OVERWRITE);
        #[cfg(feature = "deny-page-fault")]
        let map_range = true;
        #[cfg(not(feature = "deny-page-fault"))]
        let map_range = options.contains(VmOptions::MAP_RANGE);
        info!(
            "mmuflags: {:?}, is_specific {:?}, overwrite {:?}, map_range {:?}",
            mapping_flags, is_specific, overwrite, map_range
        );
        if map_range && overwrite {
            return Err(ZxError::INVALID_ARGS);
        }
        // Note: we should reject non-page-aligned length here,
        // but since zCore use different memory layout from zircon,
        // we should not reject them and round up them instead
        // TODO: reject non-page-aligned length after we have the same memory layout with zircon
        let len = roundup_pages(len);
        if len == 0 {
            return Err(ZxError::INVALID_ARGS);
        }
        let vmar_offset = if is_specific { Some(vmar_offset) } else { None };
        let vaddr = vmar.map_ext(
            vmar_offset,
            vmo,
            vmo_offset,
            len,
            permissions,
            mapping_flags,
            overwrite,
            map_range,
        )?;
        info!("vmar.map: at {:#x?}", vaddr);
        mapped_addr.write(vaddr)?;
        Ok(())
    }
pub fn sys_vmar_map ( & self , vmar_handle : HandleValue , options : u32 , vmar_offset : usize , vmo_handle : HandleValue , vmo_offset : usize , len : usize , mut mapped_addr : UserOutPtr < VirtAddr > , ) -> ZxResult { info ! ( " " vmar_handle options vmar_offset vmo_handle vmo_offset len ) ; let options = VmOptions :: from_bits ( options ) . ok_or ( ZxError :: INVALID_ARGS ) ? ; let proc = self . thread . proc ( ) ; let ( vmar , vmar_rights ) = proc . get_object_and_rights :: < VmAddressRegion > ( vmar_handle ) ? ; let ( vmo , vmo_rights ) = proc . get_object_and_rights :: < VmObject > ( vmo_handle ) ? ; if ! vmo_rights . contains ( Rights :: MAP ) { return Err ( ZxError :: ACCESS_DENIED ) ; } ; if options . intersects ( VmOptions :: CAN_MAP_RXW | VmOptions :: CAN_MAP_SPECIFIC | VmOptions :: COMPACT ) { return Err ( ZxError :: INVALID_ARGS ) ; } if options . contains ( VmOptions :: REQUIRE_NON_RESIZABLE ) && vmo . is_resizable ( ) { return Err ( ZxError :: NOT_SUPPORTED ) ; } // check SPECIFIC options with offset let is_specific = options . contains ( VmOptions :: SPECIFIC ) || options . contains ( VmOptions :: SPECIFIC_OVERWRITE ) ; if ! is_specific && vmar_offset != 0 { return Err ( ZxError :: INVALID_ARGS ) ; } if ! vmar_rights . contains ( options . to_required_rights ( ) ) { return Err ( ZxError :: ACCESS_DENIED ) ; } let mut permissions = MMUFlags :: empty ( ) ; permissions . set ( MMUFlags :: READ , vmo_rights . contains ( Rights :: READ ) ) ; permissions . set ( MMUFlags :: WRITE , vmo_rights . contains ( Rights :: WRITE ) ) ; permissions . set ( MMUFlags :: EXECUTE , vmo_rights . contains ( Rights :: EXECUTE ) ) ; let mut mapping_flags = MMUFlags :: USER ; mapping_flags . set ( MMUFlags :: READ , options . contains ( VmOptions :: PERM_READ ) ) ; mapping_flags . set ( MMUFlags :: WRITE , options . contains ( VmOptions :: PERM_WRITE ) ) ; mapping_flags . set ( MMUFlags :: EXECUTE , options . contains ( VmOptions :: PERM_EXECUTE ) ) ; let overwrite = options . contains ( VmOptions :: SPECIFIC_OVERWRITE ) ; # [ cfg ( feature " " ) ] let map_range = true ; # [ cfg ( not ( feature " " ) ) ] let map_range = options . contains ( VmOptions :: MAP_RANGE ) ; info ! ( " " mapping_flags is_specific overwrite map_range ) ; if map_range && overwrite { return Err ( ZxError :: INVALID_ARGS ) ; } // Note: we should reject non-page-aligned length here, // but since zCore use different memory layout from zircon, // we should not reject them and round up them instead // TODO: reject non-page-aligned length after we have the same memory layout with zircon let len = roundup_pages ( len ) ; if len == 0 { return Err ( ZxError :: INVALID_ARGS ) ; } let vmar_offset = if is_specific { Some ( vmar_offset ) } else { None } ; let vaddr = vmar . map_ext ( vmar_offset , vmo , vmo_offset , len , permissions , mapping_flags , overwrite , map_range , ) ? ; info ! ( " " vaddr ) ; mapped_addr . write ( vaddr ) ? ; Ok ( ( ) ) }
Add a memory mapping.
Add a memory mapping .
&self
vmar_handle
HandleValue
options
u32
vmar_offset
usize
vmo_handle
HandleValue
vmo_offset
usize
len
usize
mapped_addr
UserOutPtr<VirtAddr>
&self
vmar_handle
HandleValue
options
u32
vmar_offset
usize
vmo_handle
HandleValue
vmo_offset
usize
len
usize
mapped_addr
UserOutPtr<VirtAddr>