partial `vmo_op_range`

This commit is contained in:
PanQL 2020-03-09 22:43:31 +08:00
parent ef8c93e57a
commit bd0ac9242e
6 changed files with 71 additions and 1 deletions

View File

@ -156,6 +156,9 @@ pub fn run_userboot(images: &Images<impl AsRef<[u8]>>, cmdline: &str) -> Arc<Pro
// FIXME correct rights for decompressor engine
handles[K_USERBOOT_DECOMPRESSOR] =
Handle::new(decompressor_vmo, Rights::DEFAULT_VMO | Rights::EXECUTE);
// TODO CrashLogVmo handle
// check: handle to root proc should be only
let mut data = Vec::from(cmdline);
data.push(0);

View File

@ -41,6 +41,9 @@ pub trait VMObject: KernelObject {
/// Commit allocating physical memory.
fn commit(&self, offset: usize, len: usize);
/// Decommit allocated physical memory.
fn decommit(&self, offset: usize, len: usize);
}
#[cfg(test)]

View File

@ -94,6 +94,15 @@ impl VMObject for VMObjectPaged {
inner.commit(start_page + i);
}
}
fn decommit(&self, offset: usize, len: usize) {
let start_page = offset / PAGE_SIZE;
let pages = len / PAGE_SIZE;
let mut inner = self.inner.lock();
for i in 0..pages {
inner.decommit(start_page + i);
}
}
}
impl VMObjectPagedInner {
@ -142,6 +151,10 @@ impl VMObjectPagedInner {
self.frames[page_idx]
.get_or_insert_with(|| PhysFrame::alloc().expect("failed to alloc frame"))
}
fn decommit(&mut self, page_idx: usize) {
self.frames[page_idx] = None;
}
}
#[cfg(test)]

View File

@ -65,7 +65,13 @@ impl VMObject for VMObjectPhysical {
}
// TODO empty function should be denied
fn commit(&self, _offset: usize, _len: usize) {}
fn commit(&self, _offset: usize, _len: usize) {
unimplemented!()
}
fn decommit(&self, _offset: usize, _len: usize) {
unimplemented!()
}
}
#[cfg(test)]

View File

@ -151,6 +151,9 @@ impl Syscall<'_> {
a5 as _,
a6.into(),
),
SyscallType::VMO_OP_RANGE => {
self.sys_vmo_op_range(a0 as _, a1 as _, a2 as _, a3 as _, a4.into(), a5 as _)
}
_ => {
warn!("syscall unimplemented: {:?}", sys_type);
Err(ZxError::NOT_SUPPORTED)

View File

@ -131,6 +131,44 @@ impl Syscall<'_> {
vmo.set_len(pages(size as usize));
Ok(0)
}
pub fn sys_vmo_op_range(
&self,
handle_value: HandleValue,
op: u32,
offset: usize,
len: usize,
_buffer: UserOutPtr<u8>,
_buffer_size: usize,
) -> ZxResult<usize> {
info!(
"vmo.op_range: handle={}, op={:#X}, offset={:#x}, len={:#x}, buffer_size={:#x}",
handle_value, op, offset, len, _buffer_size,
);
let (vmo, rights) = self.thread.proc().get_vmo_and_rights(handle_value)?;
if !page_aligned(offset) || !page_aligned(len) {
return Err(ZxError::INVALID_ARGS);
}
match op {
VMO_OP_COMMIT => {
if rights.contains(Rights::WRITE) {
vmo.commit(offset, len);
Ok(0)
} else {
Err(ZxError::ACCESS_DENIED)
}
}
VMO_OP_DECOMMIT => {
if rights.contains(Rights::WRITE) {
vmo.decommit(offset, len);
Ok(0)
} else {
Err(ZxError::ACCESS_DENIED)
}
}
_ => unimplemented!(),
}
}
}
bitflags! {
@ -143,3 +181,7 @@ bitflags! {
const NO_WRITE = 1 << 5;
}
}
/// VMO Opcodes (for vmo_op_range)
const VMO_OP_COMMIT: u32 = 1;
const VMO_OP_DECOMMIT: u32 = 2;