mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 13:45:20 +00:00
hypervisor: Add Vm trait
This VM trait should be implemented by each underlying hypervisor. Previously created hypervisor object should create the VM based on already selected hypervisor. This is just the trait definition. For each of supported hypervisor we need to implement the trait. Later we will implement this trait for KVM and then Microsoft Hyper-V. Signed-off-by: Muminul Islam <muislam@microsoft.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
parent
f9b51a41b5
commit
f5afc288d8
@ -18,7 +18,10 @@ pub use x86_64::{CpuId, ExtendedControlRegisters, LapicState, MsrEntries, Xsave}
|
||||
/// Export generically-named wrappers of kvm-bindings for Unix-based platforms
|
||||
///
|
||||
pub use {
|
||||
kvm_bindings::kvm_fpu as FpuState, kvm_bindings::kvm_mp_state as MpState,
|
||||
kvm_bindings::kvm_create_device as CreateDevice, kvm_bindings::kvm_fpu as FpuState,
|
||||
kvm_bindings::kvm_irq_routing as IrqRouting, kvm_bindings::kvm_mp_state as MpState,
|
||||
kvm_bindings::kvm_regs as StandardRegisters, kvm_bindings::kvm_sregs as SpecialRegisters,
|
||||
kvm_bindings::kvm_vcpu_events as VcpuEvents, kvm_ioctls::VcpuExit,
|
||||
kvm_bindings::kvm_userspace_memory_region as MemoryRegion,
|
||||
kvm_bindings::kvm_vcpu_events as VcpuEvents, kvm_ioctls::DeviceFd, kvm_ioctls::IoEventAddress,
|
||||
kvm_ioctls::VcpuExit,
|
||||
};
|
||||
|
@ -21,6 +21,9 @@
|
||||
/// KVM implementation module
|
||||
pub mod kvm;
|
||||
|
||||
/// Vm related module
|
||||
pub mod vm;
|
||||
|
||||
/// CPU related module
|
||||
mod cpu;
|
||||
|
||||
|
144
hypervisor/src/vm.rs
Normal file
144
hypervisor/src/vm.rs
Normal file
@ -0,0 +1,144 @@
|
||||
// Copyright © 2019 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// Copyright © 2020, Microsoft Corporation
|
||||
//
|
||||
// Copyright 2018-2019 CrowdStrike, Inc.
|
||||
//
|
||||
//
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use crate::aarch64::VcpuInit;
|
||||
use crate::cpu::Vcpu;
|
||||
use crate::{CreateDevice, DeviceFd, IoEventAddress, IrqRouting, MemoryRegion};
|
||||
use std::sync::Arc;
|
||||
use thiserror::Error;
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
|
||||
///
|
||||
/// I/O events data matches (32 or 64 bits).
|
||||
///
|
||||
pub enum DataMatch {
|
||||
DataMatch32(u32),
|
||||
DataMatch64(u64),
|
||||
}
|
||||
|
||||
impl Into<u64> for DataMatch {
|
||||
fn into(self) -> u64 {
|
||||
match self {
|
||||
DataMatch::DataMatch32(dm) => dm.into(),
|
||||
DataMatch::DataMatch64(dm) => dm,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
///
|
||||
/// Enum for VM error
|
||||
pub enum HypervisorVmError {
|
||||
///
|
||||
/// Create Vcpu error
|
||||
///
|
||||
#[error("Failed to create Vcpu: {0}")]
|
||||
CreateVcpu(#[source] anyhow::Error),
|
||||
///
|
||||
/// TSS address error
|
||||
///
|
||||
#[error("Failed to set TSS address: {0}")]
|
||||
SetTssAddress(#[source] anyhow::Error),
|
||||
///
|
||||
/// Create interrupt controller error
|
||||
///
|
||||
#[error("Failed to create interrupt controller: {0}")]
|
||||
CreateIrq(#[source] anyhow::Error),
|
||||
///
|
||||
/// Register interrupt event error
|
||||
///
|
||||
#[error("Failed to register interrupt event: {0}")]
|
||||
RegisterIrqFd(#[source] anyhow::Error),
|
||||
///
|
||||
/// Un register interrupt event error
|
||||
///
|
||||
#[error("Failed to unregister interrupt event: {0}")]
|
||||
UnregisterIrqFd(#[source] anyhow::Error),
|
||||
///
|
||||
/// Register IO event error
|
||||
///
|
||||
#[error("Failed to register IO event: {0}")]
|
||||
RegisterIoEvent(#[source] anyhow::Error),
|
||||
///
|
||||
/// Unregister IO event error
|
||||
///
|
||||
#[error("Failed to unregister IO event: {0}")]
|
||||
UnregisterIoEvent(#[source] anyhow::Error),
|
||||
///
|
||||
/// Set GSI routing error
|
||||
///
|
||||
#[error("Failed to set GSI routing: {0}")]
|
||||
SetGsiRouting(#[source] anyhow::Error),
|
||||
///
|
||||
/// Set user memory error
|
||||
///
|
||||
#[error("Failed to set user memory: {0}")]
|
||||
SetUserMemory(#[source] anyhow::Error),
|
||||
///
|
||||
/// Create device error
|
||||
///
|
||||
#[error("Failed to set GSI routing: {0}")]
|
||||
CreateDevice(#[source] anyhow::Error),
|
||||
///
|
||||
/// Get preferred target error
|
||||
///
|
||||
#[error("Failed to get preferred target: {0}")]
|
||||
GetPreferredTarget(#[source] anyhow::Error),
|
||||
///
|
||||
/// Enable split Irq error
|
||||
///
|
||||
#[error("Failed to enable split Irq: {0}")]
|
||||
EnableSplitIrq(#[source] anyhow::Error),
|
||||
}
|
||||
///
|
||||
/// Result type for returning from a function
|
||||
///
|
||||
pub type Result<T> = std::result::Result<T, HypervisorVmError>;
|
||||
|
||||
///
|
||||
/// Trait to represent a Vm
|
||||
///
|
||||
/// This crate provides a hypervisor-agnostic interfaces for Vm
|
||||
///
|
||||
pub trait Vm: Send + Sync {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
/// Sets the address of the three-page region in the VM's address space.
|
||||
fn set_tss_address(&self, offset: usize) -> Result<()>;
|
||||
/// Creates an in-kernel interrupt controller.
|
||||
fn create_irq_chip(&self) -> Result<()>;
|
||||
/// Registers an event that will, when signaled, trigger the `gsi` IRQ.
|
||||
fn register_irqfd(&self, fd: &EventFd, gsi: u32) -> Result<()>;
|
||||
/// Unregister an event that will, when signaled, trigger the `gsi` IRQ.
|
||||
fn unregister_irqfd(&self, fd: &EventFd, gsi: u32) -> Result<()>;
|
||||
/// Creates a new KVM vCPU file descriptor and maps the memory corresponding
|
||||
fn create_vcpu(&self, id: u8) -> Result<Arc<dyn Vcpu>>;
|
||||
/// Registers an event to be signaled whenever a certain address is written to.
|
||||
fn register_ioevent(
|
||||
&self,
|
||||
fd: &EventFd,
|
||||
addr: &IoEventAddress,
|
||||
datamatch: Option<DataMatch>,
|
||||
) -> Result<()>;
|
||||
/// Unregister an event from a certain address it has been previously registered to.
|
||||
fn unregister_ioevent(&self, fd: &EventFd, addr: &IoEventAddress) -> Result<()>;
|
||||
/// Sets the GSI routing table entries, overwriting any previously set
|
||||
fn set_gsi_routing(&self, irq_routing: &IrqRouting) -> Result<()>;
|
||||
/// Creates/modifies a guest physical memory slot.
|
||||
fn set_user_memory_region(&self, user_memory_region: MemoryRegion) -> Result<()>;
|
||||
/// Creates an emulated device in the kernel.
|
||||
fn create_device(&self, device: &mut CreateDevice) -> Result<DeviceFd>;
|
||||
/// Returns the preferred CPU target type which can be emulated by KVM on underlying host.
|
||||
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
|
||||
fn get_preferred_target(&self, kvi: &mut VcpuInit) -> Result<()>;
|
||||
/// Enable split Irq capability
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn enable_split_irq(&self) -> Result<()>;
|
||||
}
|
Loading…
Reference in New Issue
Block a user