forked from rcore-os/zCore
hypervsior: implemented sys_vcpu_read_state & sys_vcpu_write_state
This commit is contained in:
parent
afac963748
commit
0a47a003d9
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue