forked from rcore-os/zCore
hypervisor: partially implemented sys_guest_set_trap
(without using port to set asynchronous trap)
This commit is contained in:
parent
6d74374576
commit
ae34b594b4
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue