Various fix and workaround for vmar test

This commit is contained in:
Ben Pig Chu 2020-06-21 22:36:43 +08:00
parent 42bd799d97
commit 36d2840017
5 changed files with 49 additions and 11 deletions

View File

@ -70,7 +70,13 @@ impl PageTableImpl {
.unwrap() .unwrap()
.flush(); .flush();
}; };
trace!("map: {:x?} -> {:x?}, flags={:?}", vaddr, paddr, flags); trace!(
"map: {:x?} -> {:x?}, flags={:?} in {:#x?}",
vaddr,
paddr,
flags,
self.root_paddr
);
Ok(()) Ok(())
} }
@ -79,10 +85,25 @@ impl PageTableImpl {
pub fn unmap(&mut self, vaddr: x86_64::VirtAddr) -> Result<(), ()> { pub fn unmap(&mut self, vaddr: x86_64::VirtAddr) -> Result<(), ()> {
let mut pt = self.get(); let mut pt = self.get();
let page = Page::<Size4KiB>::from_start_address(vaddr).unwrap(); let page = Page::<Size4KiB>::from_start_address(vaddr).unwrap();
if let Ok((_, flush)) = pt.unmap(page) { // This is a workaround to an issue in the x86-64 crate
flush.flush(); // A page without PRESENT bit is not unmappable AND mapable
// So we add PRESENT bit here
unsafe {
pt.update_flags(page, PTF::PRESENT | PTF::NO_EXECUTE).ok();
}
match pt.unmap(page) {
Ok((_, flush)) => {
flush.flush();
trace!("unmap: {:x?} in {:#x?}", vaddr, self.root_paddr);
}
Err(err) => {
debug!(
"unmap failed: {:x?} err={:x?} in {:#x?}",
vaddr, err, self.root_paddr
);
return Err(());
}
} }
trace!("unmap: {:x?}", vaddr);
Ok(()) Ok(())
} }

View File

@ -84,6 +84,9 @@ impl<T, P: Policy> UserPtr<T, P> {
if self.ptr.is_null() { if self.ptr.is_null() {
return Err(Error::InvalidPointer); return Err(Error::InvalidPointer);
} }
if (self.ptr as usize) % core::mem::align_of::<T>() != 0 {
return Err(Error::InvalidPointer);
}
Ok(()) Ok(())
} }
} }

View File

@ -20,7 +20,9 @@
-Threads.Reading*State -Threads.Reading*State
-Threads.WriteReadDebugRegisterState -Threads.WriteReadDebugRegisterState
-Threads.DebugRegistersValidation -Threads.DebugRegistersValidation
-Vmar.* -Vmar.ProtectOverDemandPagedTest
-Vmar.ProtectLargeUncomittedTest
-Vmar.UnmapLargeUncommittedTest
-VmoTestCase.ReadOnlyMap -VmoTestCase.ReadOnlyMap
-VmoTestCase.NoPermMap -VmoTestCase.NoPermMap
-VmoTestCase.NoPermProtect -VmoTestCase.NoPermProtect

View File

@ -292,9 +292,12 @@ impl VmAddressRegion {
fn destroy_internal(&self) -> ZxResult { fn destroy_internal(&self) -> ZxResult {
let mut guard = self.inner.lock(); let mut guard = self.inner.lock();
let inner = guard.as_mut().ok_or(ZxError::BAD_STATE)?; let inner = guard.as_mut().ok_or(ZxError::BAD_STATE)?;
for vmar in inner.children.iter() { for vmar in inner.children.drain(..) {
vmar.destroy_internal()?; vmar.destroy_internal()?;
} }
for mapping in inner.mappings.drain(..) {
drop(mapping);
}
*guard = None; *guard = None;
Ok(()) Ok(())
} }

View File

@ -1,8 +1,11 @@
use {super::*, bitflags::bitflags, zircon_object::vm::*}; use {super::*, bitflags::bitflags, zircon_object::vm::*};
fn amount_of_alignments(options: u32) -> ZxResult<usize> { fn amount_of_alignments(options: u32) -> ZxResult<usize> {
let align_pow2 = (options >> 24) as usize; let mut align_pow2 = (options >> 24) as usize;
if (align_pow2 < 10 && align_pow2 != 0) || (align_pow2 > 32) { if align_pow2 == 0 {
align_pow2 = PAGE_SIZE_LOG2;
}
if (align_pow2 < PAGE_SIZE_LOG2) || (align_pow2 > 32) {
Err(ZxError::INVALID_ARGS) Err(ZxError::INVALID_ARGS)
} else { } else {
Ok(1 << align_pow2) Ok(1 << align_pow2)
@ -55,11 +58,12 @@ impl Syscall<'_> {
None None
}; };
let size = roundup_pages(size as usize);
// check `size` // check `size`
if size == 0u64 { if size == 0usize {
return Err(ZxError::INVALID_ARGS); return Err(ZxError::INVALID_ARGS);
} }
let child = parent.allocate(offset, size as usize, vmar_flags, align)?; let child = parent.allocate(offset, size, vmar_flags, align)?;
let child_addr = child.addr(); let child_addr = child.addr();
let child_handle = proc.add_handle(Handle::new(child, Rights::DEFAULT_VMAR | perm_rights)); let child_handle = proc.add_handle(Handle::new(child, Rights::DEFAULT_VMAR | perm_rights));
info!("vmar.allocate: at {:#x?}", child_addr); info!("vmar.allocate: at {:#x?}", child_addr);
@ -181,7 +185,12 @@ impl Syscall<'_> {
mapping_flags.set(MMUFlags::READ, options.contains(VmOptions::PERM_READ)); mapping_flags.set(MMUFlags::READ, options.contains(VmOptions::PERM_READ));
mapping_flags.set(MMUFlags::WRITE, options.contains(VmOptions::PERM_WRITE)); mapping_flags.set(MMUFlags::WRITE, options.contains(VmOptions::PERM_WRITE));
mapping_flags.set(MMUFlags::EXECUTE, options.contains(VmOptions::PERM_EXECUTE)); mapping_flags.set(MMUFlags::EXECUTE, options.contains(VmOptions::PERM_EXECUTE));
vmar.protect(addr as usize, len as usize, mapping_flags)?;
let len = roundup_pages(len as usize);
if len == 0usize {
return Err(ZxError::INVALID_ARGS);
}
vmar.protect(addr as usize, len, mapping_flags)?;
Ok(()) Ok(())
} }