vmo: refactor new_contiguous

This commit is contained in:
Runji Wang 2021-04-04 23:00:57 +08:00
parent ccad37f096
commit 1207746b1a
3 changed files with 24 additions and 34 deletions

View File

@ -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<Arc<Self>> {
assert!(align_log2 < 8 * core::mem::size_of::<usize>());
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<Arc<Self>> {
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)

View File

@ -177,6 +177,26 @@ impl VMObjectPaged {
)
}
/// Create a new VMO backing on contiguous pages.
pub fn new_contiguous(pages: usize, align_log2: usize) -> ZxResult<Arc<Self>> {
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<Mutex<()>>>) -> Arc<Self> {
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.
///

View File

@ -230,7 +230,7 @@ impl Syscall<'_> {
let proc = self.thread.proc();
proc.check_policy(PolicyCondition::NewVMO)?;
let _bti = proc.get_object_with_rights::<BusTransactionInitiator>(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(())