diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index fb752049c..223a4a86e 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -14,7 +14,8 @@ use crate::cpu::Vcpu; use crate::hypervisor; use crate::vm::{self, VmmOps}; pub use mshv_bindings::*; -use mshv_ioctls::{set_registers_64, InterruptRequest, Mshv, VcpuFd, VmFd}; +pub use mshv_ioctls::IoEventAddress; +use mshv_ioctls::{set_registers_64, InterruptRequest, Mshv, NoDatamatch, VcpuFd, VmFd}; use serde_derive::{Deserialize, Serialize}; use std::sync::Arc; use vm::DataMatch; @@ -28,7 +29,6 @@ pub use x86_64::VcpuMshvState as CpuState; #[cfg(target_arch = "x86_64")] pub use x86_64::*; -// Wei: for emulating ioeventfd use std::collections::HashMap; use std::os::unix::io::AsRawFd; use std::sync::RwLock; @@ -101,13 +101,11 @@ impl hypervisor::Hypervisor for MshvHypervisor { } let vm_fd = Arc::new(fd); - let ioeventfds = Arc::new(RwLock::new(HashMap::new())); let gsi_routes = Arc::new(RwLock::new(HashMap::new())); Ok(Arc::new(MshvVm { fd: vm_fd, msrs, - ioeventfds, gsi_routes, hv_state: hv_state_init(), vmmops: None, @@ -170,7 +168,6 @@ pub struct MshvVcpu { vp_index: u8, cpuid: CpuId, msrs: MsrEntries, - ioeventfds: Arc, EventFd)>>>, gsi_routes: Arc>>, hv_state: Arc>, // Mshv State vmmops: Option>>, @@ -573,19 +570,6 @@ impl<'a> PlatformEmulator for MshvEmulatorContext<'a> { gpa ); - if let Some((datamatch, efd)) = self - .vcpu - .ioeventfds - .read() - .unwrap() - .get(&IoEventAddress::Mmio(gpa)) - { - debug!("ioevent {:x} {:x?} {}", gpa, datamatch, efd.as_raw_fd()); - - /* TODO: use datamatch to provide the correct semantics */ - efd.write(1).unwrap(); - } - if let Some(vmmops) = &self.vcpu.vmmops { vmmops .mmio_write(gpa, data) @@ -654,8 +638,6 @@ impl<'a> PlatformEmulator for MshvEmulatorContext<'a> { pub struct MshvVm { fd: Arc, msrs: MsrEntries, - // Emulate ioeventfd - ioeventfds: Arc, EventFd)>>>, // GSI routing information gsi_routes: Arc>>, // Hypervisor State @@ -743,7 +725,6 @@ impl vm::Vm for MshvVm { vp_index: id, cpuid: CpuId::new(1), msrs: self.msrs.clone(), - ioeventfds: self.ioeventfds.clone(), gsi_routes: self.gsi_routes.clone(), hv_state: self.hv_state.clone(), vmmops, @@ -760,26 +741,36 @@ impl vm::Vm for MshvVm { addr: &IoEventAddress, datamatch: Option, ) -> vm::Result<()> { - let dup_fd = fd.try_clone().unwrap(); - debug!( "register_ioevent fd {} addr {:x?} datamatch {:?}", fd.as_raw_fd(), addr, datamatch ); - - self.ioeventfds - .write() - .unwrap() - .insert(*addr, (datamatch, dup_fd)); - Ok(()) + if let Some(dm) = datamatch { + match dm { + vm::DataMatch::DataMatch32(mshv_dm32) => self + .fd + .register_ioevent(fd, addr, mshv_dm32) + .map_err(|e| vm::HypervisorVmError::RegisterIoEvent(e.into())), + vm::DataMatch::DataMatch64(mshv_dm64) => self + .fd + .register_ioevent(fd, addr, mshv_dm64) + .map_err(|e| vm::HypervisorVmError::RegisterIoEvent(e.into())), + } + } else { + self.fd + .register_ioevent(fd, addr, NoDatamatch) + .map_err(|e| vm::HypervisorVmError::RegisterIoEvent(e.into())) + } } /// Unregister an event from a certain address it has been previously registered to. fn unregister_ioevent(&self, fd: &EventFd, addr: &IoEventAddress) -> vm::Result<()> { debug!("unregister_ioevent fd {} addr {:x?}", fd.as_raw_fd(), addr); - self.ioeventfds.write().unwrap().remove(addr).unwrap(); - Ok(()) + + self.fd + .unregister_ioevent(fd, addr, NoDatamatch) + .map_err(|e| vm::HypervisorVmError::UnregisterIoEvent(e.into())) } /// Creates/modifies a guest physical memory slot. diff --git a/hypervisor/src/mshv/x86_64/mod.rs b/hypervisor/src/mshv/x86_64/mod.rs index ad8aacd2c..c1f5cfdda 100644 --- a/hypervisor/src/mshv/x86_64/mod.rs +++ b/hypervisor/src/mshv/x86_64/mod.rs @@ -42,14 +42,6 @@ pub struct IrqRouting {} pub enum VcpuExit {} pub struct MpState {} -#[derive(Eq, PartialEq, Hash, Clone, Debug, Copy)] -pub enum IoEventAddress { - /// Representation of an programmable I/O address. - Pio(u64), - /// Representation of an memory mapped I/O address. - Mmio(u64), -} - impl SegmentRegisterOps for SegmentRegister { fn segment_type(&self) -> u8 { self.type_