hypervsior: implemented sys_vcpu_read_state & sys_vcpu_write_state

This commit is contained in:
equation314 2020-07-16 00:03:50 +08:00
parent afac963748
commit 0a47a003d9
4 changed files with 88 additions and 7 deletions

View File

@ -3,16 +3,16 @@
mod guest;
mod vcpu;
pub use guest::{Guest, GUEST_PHYSICAL_ASPACE_BASE, GUEST_PHYSICAL_ASPACE_SIZE};
pub use rvm::TrapKind;
pub use vcpu::Vcpu;
use super::ZxError;
use kernel_hal::{MMUFlags, PageTableTrait};
use rvm::{
ArchRvmPageTable, GuestPhysAddr, HostPhysAddr, IntoRvmPageTableFlags, RvmError, RvmPageTable,
};
pub use guest::{Guest, GUEST_PHYSICAL_ASPACE_BASE, GUEST_PHYSICAL_ASPACE_SIZE};
pub use rvm::{TrapKind, VcpuIo, VcpuReadWriteKind, VcpuState};
pub use vcpu::Vcpu;
impl From<RvmError> for ZxError {
fn from(e: RvmError) -> Self {
match e {

View File

@ -1,5 +1,9 @@
use {
crate::{hypervisor::Guest, object::*, signal::*},
crate::{
hypervisor::{Guest, VcpuIo, VcpuState},
object::*,
signal::*,
},
alloc::sync::Arc,
core::convert::TryInto,
rvm::{self, Vcpu as VcpuInner},
@ -17,6 +21,7 @@ define_count_helper!(Vcpu);
impl Vcpu {
pub fn new(guest: Arc<Guest>, entry: u64) -> ZxResult<Arc<Self>> {
// TODO: check thread
Ok(Arc::new(Vcpu {
base: KObjectBase::new(),
_counter: CountHelper::new(),
@ -32,8 +37,24 @@ impl Vcpu {
}
pub fn resume(&self) -> ZxResult<PortPacket> {
// TODO: check thread
self.inner.lock().resume()?.try_into()
}
pub fn read_state(&self) -> ZxResult<VcpuState> {
// TODO: check thread
self.inner.lock().read_state().map_err(From::from)
}
pub fn write_state(&self, state: &VcpuState) -> ZxResult {
// TODO: check thread
self.inner.lock().write_state(state).map_err(From::from)
}
pub fn write_io_state(&self, state: &VcpuIo) -> ZxResult {
// TODO: check thread
self.inner.lock().write_io_state(state).map_err(From::from)
}
}
impl From<rvm::IoPacket> for PacketGuestIo {

View File

@ -1,8 +1,9 @@
use {
super::*,
core::mem::size_of,
zircon_object::{
dev::{Resource, ResourceKind},
hypervisor::{Guest, Vcpu},
hypervisor::{Guest, Vcpu, VcpuIo, VcpuReadWriteKind, VcpuState},
signal::{Port, PortPacket},
vm::VmarFlags,
},
@ -98,7 +99,7 @@ impl Syscall<'_> {
handle: HandleValue,
mut user_packet: UserOutPtr<PortPacket>,
) -> ZxResult {
error!("hypervisor.vcpu_resume: handle={:#x?}", handle);
info!("hypervisor.vcpu_resume: handle={:#x?}", handle);
let proc = self.thread.proc();
let vcpu = proc.get_object_with_rights::<Vcpu>(handle, Rights::EXECUTE)?;
let packet = vcpu.resume()?;
@ -116,4 +117,59 @@ impl Syscall<'_> {
vcpu.virtual_interrupt(vector)?;
Ok(())
}
pub fn sys_vcpu_read_state(
&self,
handle: HandleValue,
kind: u32,
mut user_buffer: UserOutPtr<VcpuState>,
buffer_size: usize,
) -> ZxResult {
info!(
"hypervisor.vcpu_read_state: handle={:#x?}, kind={:?}, buffer_size={:?}",
handle, kind, buffer_size
);
if kind != VcpuReadWriteKind::VcpuState as u32 || buffer_size != size_of::<VcpuState>() {
return Err(ZxError::INVALID_ARGS);
}
let proc = self.thread.proc();
let vcpu = proc.get_object_with_rights::<Vcpu>(handle, Rights::READ)?;
let state = vcpu.read_state()?;
user_buffer.write(state)?;
Ok(())
}
pub fn sys_vcpu_write_state(
&self,
handle: HandleValue,
kind: u32,
user_buffer: usize,
buffer_size: usize,
) -> ZxResult {
info!(
"hypervisor.vcpu_write_state: handle={:#x?}, kind={:?}, user_buffer={:#x?}, buffer_size={:?}",
handle, kind, user_buffer, buffer_size
);
let proc = self.thread.proc();
let vcpu = proc.get_object_with_rights::<Vcpu>(handle, Rights::WRITE)?;
match VcpuReadWriteKind::try_from(kind) {
Ok(VcpuReadWriteKind::VcpuState) => {
if buffer_size != size_of::<VcpuState>() {
return Err(ZxError::INVALID_ARGS);
}
let state: UserInPtr<VcpuState> = user_buffer.into();
vcpu.write_state(&state.read()?)?;
}
Ok(VcpuReadWriteKind::VcpuIo) => {
if buffer_size != size_of::<VcpuIo>() {
return Err(ZxError::INVALID_ARGS);
}
let state: UserInPtr<VcpuIo> = user_buffer.into();
vcpu.write_io_state(&state.read()?)?;
}
Err(_) => return Err(ZxError::INVALID_ARGS),
}
Ok(())
}
}

View File

@ -367,6 +367,10 @@ impl Syscall<'_> {
Sys::VCPU_RESUME => self.sys_vcpu_resume(a0 as _, a1.into()),
#[cfg(feature = "hypervisor")]
Sys::VCPU_INTERRUPT => self.sys_vcpu_interrupt(a0 as _, a1 as _),
#[cfg(feature = "hypervisor")]
Sys::VCPU_READ_STATE => self.sys_vcpu_read_state(a0 as _, a1 as _, a2.into(), a3 as _),
#[cfg(feature = "hypervisor")]
Sys::VCPU_WRITE_STATE => self.sys_vcpu_write_state(a0 as _, a1 as _, a2, a3 as _),
_ => {
error!("syscall unimplemented: {:?}", sys_type);
Err(ZxError::NOT_SUPPORTED)