diff --git a/zircon-object/src/vm/vmo/mod.rs b/zircon-object/src/vm/vmo/mod.rs index 3f3ea35e3..1e7567046 100644 --- a/zircon-object/src/vm/vmo/mod.rs +++ b/zircon-object/src/vm/vmo/mod.rs @@ -156,21 +156,12 @@ impl VmObject { } /// Create a VM object referring to a specific contiguous range of physical frame. - pub fn new_contiguous(p_size: usize, align_log2: usize) -> ZxResult> { - assert!(align_log2 < 8 * core::mem::size_of::()); - let size = roundup_pages(p_size); - if size < p_size { - return Err(ZxError::INVALID_ARGS); - } - let base = KObjectBase::with_signal(Signal::VMO_ZERO_CHILDREN); - let size_page = pages(size); - let trait_ = VMObjectPaged::new(size_page); - trait_.create_contiguous(size, align_log2)?; + pub fn new_contiguous(pages: usize, align_log2: usize) -> ZxResult> { let vmo = Arc::new(VmObject { - base, + base: KObjectBase::with_signal(Signal::VMO_ZERO_CHILDREN), resizable: false, _counter: CountHelper::new(), - trait_, + trait_: VMObjectPaged::new_contiguous(pages, align_log2)?, inner: Mutex::new(VmObjectInner::default()), }); Ok(vmo) diff --git a/zircon-object/src/vm/vmo/paged.rs b/zircon-object/src/vm/vmo/paged.rs index 33b032bc4..76703f9b1 100644 --- a/zircon-object/src/vm/vmo/paged.rs +++ b/zircon-object/src/vm/vmo/paged.rs @@ -177,6 +177,26 @@ impl VMObjectPaged { ) } + /// Create a new VMO backing on contiguous pages. + pub fn new_contiguous(pages: usize, align_log2: usize) -> ZxResult> { + let vmo = Self::new(pages); + let mut frames = PhysFrame::alloc_contiguous(pages, align_log2 - PAGE_SIZE_LOG2); + if frames.is_empty() { + return Err(ZxError::NO_MEMORY); + } + { + let (_guard, mut inner) = vmo.get_inner_mut(); + inner.contiguous = true; + for (i, f) in frames.drain(0..).enumerate() { + kernel_hal::pmem_zero(f.addr(), PAGE_SIZE); + let mut state = PageState::new(f); + state.pin_count += 1; + inner.frames.insert(i, state); + } + } + Ok(vmo) + } + /// Internal: Wrap an inner struct to object. fn wrap(inner: VMObjectPagedInner, lock_ref: Option>>) -> Arc { let obj = Arc::new(VMObjectPaged { @@ -429,27 +449,6 @@ enum CommitResult { NewPage(PhysFrame), } -impl VMObjectPaged { - /// Create a list of contiguous pages - pub fn create_contiguous(&self, size: usize, align_log2: usize) -> ZxResult { - assert!(page_aligned(size)); - let size_page = pages(size); - let mut frames = PhysFrame::alloc_contiguous(size_page, align_log2 - PAGE_SIZE_LOG2); - if frames.is_empty() { - return Err(ZxError::NO_MEMORY); - } - let (_guard, mut inner) = self.get_inner_mut(); - inner.contiguous = true; - for (i, f) in frames.drain(0..).enumerate() { - kernel_hal::pmem_zero(f.addr(), PAGE_SIZE); - let mut state = PageState::new(f); - state.pin_count += 1; - inner.frames.insert(i, state); - } - Ok(()) - } -} - impl VMObjectPagedInner { /// Helper function to split range into sub-ranges within pages. /// diff --git a/zircon-syscall/src/vmo.rs b/zircon-syscall/src/vmo.rs index fc1d8cdc7..b5cdd32d0 100644 --- a/zircon-syscall/src/vmo.rs +++ b/zircon-syscall/src/vmo.rs @@ -230,7 +230,7 @@ impl Syscall<'_> { let proc = self.thread.proc(); proc.check_policy(PolicyCondition::NewVMO)?; let _bti = proc.get_object_with_rights::(bti, Rights::MAP)?; - let vmo = VmObject::new_contiguous(size, align_log2)?; + let vmo = VmObject::new_contiguous(pages(size), align_log2)?; let handle_value = proc.add_handle(Handle::new(vmo, Rights::DEFAULT_VMO)); out.write(handle_value)?; Ok(())