hypervisor: partially implemented sys_guest_set_trap

(without using port to set asynchronous trap)
This commit is contained in:
equation314 2020-07-11 17:51:55 +08:00
parent 6d74374576
commit ae34b594b4
4 changed files with 53 additions and 3 deletions

View File

@ -1,7 +1,7 @@
use {
crate::{object::*, vm::*},
crate::{object::*, signal::Port, vm::VmAddressRegion},
alloc::sync::Arc,
rvm::{Guest as GuestInner, RvmError, RvmResult},
rvm::{Guest as GuestInner, RvmError, RvmResult, TrapKind},
rvm::{GuestPhysAddr, GuestPhysMemorySetTrait, HostPhysAddr},
};
@ -30,6 +30,21 @@ impl Guest {
}))
}
pub fn set_trap(
&self,
kind: u32,
addr: usize,
size: usize,
_port: Option<Arc<Port>>,
key: u64,
) -> ZxResult {
// TODO: port
use core::convert::TryFrom;
self.inner
.set_trap(TrapKind::try_from(kind)?, addr, size, key)
.map_err(From::from)
}
pub fn vmar(&self) -> Arc<VmAddressRegion> {
self.gpm.vmar.clone()
}
@ -61,9 +76,15 @@ impl GuestPhysMemorySetTrait for GuestPhysMemorySet {
_size: usize,
_hpaddr: Option<HostPhysAddr>,
) -> RvmResult {
// All mappings was created by VMAR, should not call this function.
Err(RvmError::NotSupported)
}
/// Remove a guest physical memory region, destroy the mapping.
fn remove_map(&self, gpaddr: GuestPhysAddr, size: usize) -> RvmResult {
self.vmar.unmap(gpaddr, size).map_err(From::from)
}
/// Called when accessed a non-mapped guest physical adderss `gpaddr`.
fn handle_page_fault(&self, gpaddr: GuestPhysAddr) -> RvmResult {
if let Some(mapping) = self.vmar.find_mapping(gpaddr) {

View File

@ -4,7 +4,8 @@ mod guest;
mod page_table;
pub use guest::Guest;
pub use page_table::VmmPageTable;
pub(crate) use page_table::VmmPageTable;
pub use rvm::TrapKind;
use super::ZxError;
use rvm::RvmError;

View File

@ -3,6 +3,7 @@ use {
zircon_object::{
dev::{Resource, ResourceKind},
hypervisor::Guest,
signal::Port,
vm::VmarFlags,
},
};
@ -46,4 +47,27 @@ impl Syscall<'_> {
vmar_handle.write(vmar_handle_value)?;
Ok(())
}
pub fn sys_guest_set_trap(
&self,
handle: HandleValue,
kind: u32,
addr: u64,
size: u64,
port_handle: HandleValue,
key: u64,
) -> ZxResult {
info!(
"hypervisor.guest_set_trap: handle={:#x?}, kind={:#x?}, addr={:#x?}, size={:#x?}, port_handle={:#x?}, key={:#x?}",
handle, kind, addr, size, port_handle, key
);
let proc = self.thread.proc();
let guest = proc.get_object_with_rights::<Guest>(handle, Rights::WRITE)?;
let port = if port_handle != INVALID_HANDLE {
Some(proc.get_object_with_rights::<Port>(port_handle, Rights::WRITE)?)
} else {
None
};
guest.set_trap(kind, addr as usize, size as usize, port, key)
}
}

View File

@ -357,6 +357,10 @@ impl Syscall<'_> {
}
#[cfg(feature = "hypervisor")]
Sys::GUEST_CREATE => self.sys_guest_create(a0 as _, a1 as _, a2.into(), a3.into()),
#[cfg(feature = "hypervisor")]
Sys::GUEST_SET_TRAP => {
self.sys_guest_set_trap(a0 as _, a1 as _, a2 as _, a3 as _, a4 as _, a5 as _)
}
_ => {
error!("syscall unimplemented: {:?}", sys_type);
Err(ZxError::NOT_SUPPORTED)