mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-03 20:15:45 +00:00
mshv: Use in-kernel ioeventfd mechanism
Signed-off-by: Vineeth Pillai <viremana@linux.microsoft.com>
This commit is contained in:
parent
5209bd6120
commit
7659055eec
@ -14,7 +14,8 @@ use crate::cpu::Vcpu;
|
|||||||
use crate::hypervisor;
|
use crate::hypervisor;
|
||||||
use crate::vm::{self, VmmOps};
|
use crate::vm::{self, VmmOps};
|
||||||
pub use mshv_bindings::*;
|
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 serde_derive::{Deserialize, Serialize};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use vm::DataMatch;
|
use vm::DataMatch;
|
||||||
@ -28,7 +29,6 @@ pub use x86_64::VcpuMshvState as CpuState;
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub use x86_64::*;
|
pub use x86_64::*;
|
||||||
|
|
||||||
// Wei: for emulating ioeventfd
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
@ -101,13 +101,11 @@ impl hypervisor::Hypervisor for MshvHypervisor {
|
|||||||
}
|
}
|
||||||
let vm_fd = Arc::new(fd);
|
let vm_fd = Arc::new(fd);
|
||||||
|
|
||||||
let ioeventfds = Arc::new(RwLock::new(HashMap::new()));
|
|
||||||
let gsi_routes = Arc::new(RwLock::new(HashMap::new()));
|
let gsi_routes = Arc::new(RwLock::new(HashMap::new()));
|
||||||
|
|
||||||
Ok(Arc::new(MshvVm {
|
Ok(Arc::new(MshvVm {
|
||||||
fd: vm_fd,
|
fd: vm_fd,
|
||||||
msrs,
|
msrs,
|
||||||
ioeventfds,
|
|
||||||
gsi_routes,
|
gsi_routes,
|
||||||
hv_state: hv_state_init(),
|
hv_state: hv_state_init(),
|
||||||
vmmops: None,
|
vmmops: None,
|
||||||
@ -170,7 +168,6 @@ pub struct MshvVcpu {
|
|||||||
vp_index: u8,
|
vp_index: u8,
|
||||||
cpuid: CpuId,
|
cpuid: CpuId,
|
||||||
msrs: MsrEntries,
|
msrs: MsrEntries,
|
||||||
ioeventfds: Arc<RwLock<HashMap<IoEventAddress, (Option<DataMatch>, EventFd)>>>,
|
|
||||||
gsi_routes: Arc<RwLock<HashMap<u32, MshvIrqRoutingEntry>>>,
|
gsi_routes: Arc<RwLock<HashMap<u32, MshvIrqRoutingEntry>>>,
|
||||||
hv_state: Arc<RwLock<HvState>>, // Mshv State
|
hv_state: Arc<RwLock<HvState>>, // Mshv State
|
||||||
vmmops: Option<Arc<Box<dyn vm::VmmOps>>>,
|
vmmops: Option<Arc<Box<dyn vm::VmmOps>>>,
|
||||||
@ -573,19 +570,6 @@ impl<'a> PlatformEmulator for MshvEmulatorContext<'a> {
|
|||||||
gpa
|
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 {
|
if let Some(vmmops) = &self.vcpu.vmmops {
|
||||||
vmmops
|
vmmops
|
||||||
.mmio_write(gpa, data)
|
.mmio_write(gpa, data)
|
||||||
@ -654,8 +638,6 @@ impl<'a> PlatformEmulator for MshvEmulatorContext<'a> {
|
|||||||
pub struct MshvVm {
|
pub struct MshvVm {
|
||||||
fd: Arc<VmFd>,
|
fd: Arc<VmFd>,
|
||||||
msrs: MsrEntries,
|
msrs: MsrEntries,
|
||||||
// Emulate ioeventfd
|
|
||||||
ioeventfds: Arc<RwLock<HashMap<IoEventAddress, (Option<DataMatch>, EventFd)>>>,
|
|
||||||
// GSI routing information
|
// GSI routing information
|
||||||
gsi_routes: Arc<RwLock<HashMap<u32, MshvIrqRoutingEntry>>>,
|
gsi_routes: Arc<RwLock<HashMap<u32, MshvIrqRoutingEntry>>>,
|
||||||
// Hypervisor State
|
// Hypervisor State
|
||||||
@ -743,7 +725,6 @@ impl vm::Vm for MshvVm {
|
|||||||
vp_index: id,
|
vp_index: id,
|
||||||
cpuid: CpuId::new(1),
|
cpuid: CpuId::new(1),
|
||||||
msrs: self.msrs.clone(),
|
msrs: self.msrs.clone(),
|
||||||
ioeventfds: self.ioeventfds.clone(),
|
|
||||||
gsi_routes: self.gsi_routes.clone(),
|
gsi_routes: self.gsi_routes.clone(),
|
||||||
hv_state: self.hv_state.clone(),
|
hv_state: self.hv_state.clone(),
|
||||||
vmmops,
|
vmmops,
|
||||||
@ -760,26 +741,36 @@ impl vm::Vm for MshvVm {
|
|||||||
addr: &IoEventAddress,
|
addr: &IoEventAddress,
|
||||||
datamatch: Option<DataMatch>,
|
datamatch: Option<DataMatch>,
|
||||||
) -> vm::Result<()> {
|
) -> vm::Result<()> {
|
||||||
let dup_fd = fd.try_clone().unwrap();
|
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"register_ioevent fd {} addr {:x?} datamatch {:?}",
|
"register_ioevent fd {} addr {:x?} datamatch {:?}",
|
||||||
fd.as_raw_fd(),
|
fd.as_raw_fd(),
|
||||||
addr,
|
addr,
|
||||||
datamatch
|
datamatch
|
||||||
);
|
);
|
||||||
|
if let Some(dm) = datamatch {
|
||||||
self.ioeventfds
|
match dm {
|
||||||
.write()
|
vm::DataMatch::DataMatch32(mshv_dm32) => self
|
||||||
.unwrap()
|
.fd
|
||||||
.insert(*addr, (datamatch, dup_fd));
|
.register_ioevent(fd, addr, mshv_dm32)
|
||||||
Ok(())
|
.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.
|
/// Unregister an event from a certain address it has been previously registered to.
|
||||||
fn unregister_ioevent(&self, fd: &EventFd, addr: &IoEventAddress) -> vm::Result<()> {
|
fn unregister_ioevent(&self, fd: &EventFd, addr: &IoEventAddress) -> vm::Result<()> {
|
||||||
debug!("unregister_ioevent fd {} addr {:x?}", fd.as_raw_fd(), addr);
|
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.
|
/// Creates/modifies a guest physical memory slot.
|
||||||
|
@ -42,14 +42,6 @@ pub struct IrqRouting {}
|
|||||||
pub enum VcpuExit {}
|
pub enum VcpuExit {}
|
||||||
pub struct MpState {}
|
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 {
|
impl SegmentRegisterOps for SegmentRegister {
|
||||||
fn segment_type(&self) -> u8 {
|
fn segment_type(&self) -> u8 {
|
||||||
self.type_
|
self.type_
|
||||||
|
Loading…
Reference in New Issue
Block a user