Skip to content

Commit

Permalink
Use sealed trait pattern to avoid private trait in public interface w…
Browse files Browse the repository at this point in the history
…arning
  • Loading branch information
jounathaen committed Jan 24, 2025
1 parent 0a49cd9 commit e5d8927
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 29 deletions.
10 changes: 8 additions & 2 deletions src/linux/x86_64/kvm_cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ use crate::{
stats::{CpuStats, VmExit},
vcpu::{VcpuStopReason, VirtualCPU},
virtio::*,
vm::{KernelInfo, VirtualizationBackend, VmPeripherals},
vm::{
internal::VirtualizationBackendInternal, KernelInfo, VirtualizationBackend, VmPeripherals,
},
HypervisorResult,
};

Expand All @@ -34,7 +36,7 @@ pub struct KvmVm {
vm_fd: VmFd,
peripherals: Arc<VmPeripherals>,
}
impl VirtualizationBackend for KvmVm {
impl VirtualizationBackendInternal for KvmVm {
type VCPU = KvmCpu;
const NAME: &str = "KvmVm";

Expand Down Expand Up @@ -154,6 +156,10 @@ impl VirtualizationBackend for KvmVm {
}
}

impl VirtualizationBackend for KvmVm {
type BACKEND = Self;
}

pub struct KvmCpu {
id: u32,
vcpu: VcpuFd,
Expand Down
8 changes: 6 additions & 2 deletions src/macos/aarch64/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ use crate::{
params::Params,
stats::{CpuStats, VmExit},
vcpu::{VcpuStopReason, VirtualCPU},
vm::{KernelInfo, VirtualizationBackend, VmPeripherals},
vm::{KernelInfo, VirtualizationBackend, internal::VirtualizationBackendInternal, VmPeripherals},
HypervisorResult,
};

pub struct XhyveVm {
peripherals: Arc<VmPeripherals>,
}
impl VirtualizationBackend for XhyveVm {
impl VirtualizationBackendInternal for XhyveVm {
type VCPU = XhyveCpu;
const NAME: &str = "XhyveVm";

Expand Down Expand Up @@ -67,6 +67,10 @@ impl VirtualizationBackend for XhyveVm {
}
}

impl VirtualizationBackend for XhyveVm {
type BACKEND = Self;
}

pub struct XhyveCpu {
id: u32,
vcpu: xhypervisor::VirtualCpu,
Expand Down
8 changes: 6 additions & 2 deletions src/macos/x86_64/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use crate::{
params::Params,
stats::{CpuStats, VmExit},
vcpu::{VcpuStopReason, VirtualCPU},
vm::{UhyveVm, VirtualizationBackend},
vm::{internal::VirtualizationBackendInternal, UhyveVm, VirtualizationBackend},
HypervisorResult,
};

Expand Down Expand Up @@ -158,7 +158,7 @@ static CAP_EXIT: LazyLock<u64> = LazyLock::new(|| {
});

pub struct XhyveVm {}
impl VirtualizationBackend for XhyveVm {
impl VirtualizationBackendInternal for XhyveVm {
type VCPU = XhyveCpu;
const NAME: &str = "XhyveVm";

Expand Down Expand Up @@ -194,6 +194,10 @@ impl VirtualizationBackend for XhyveVm {
}
}

impl VirtualizationBackend for XhyveVm {
type BACKEND = Self;
}

pub struct XhyveCpu {
id: u32,
vcpu: xhypervisor::VirtualCpu,
Expand Down
59 changes: 36 additions & 23 deletions src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::{
num::NonZeroU32,
os::unix::prelude::JoinHandleExt,
path::PathBuf,
str,
sync::{Arc, Barrier, Mutex},
thread,
time::SystemTime,
Expand All @@ -15,6 +14,7 @@ use hermit_entry::{
boot_info::{BootInfo, HardwareInfo, LoadInfo, PlatformInfo, RawBootInfo, SerialPortBase},
elf::{KernelObject, LoadedKernel, ParseKernelError},
};
use internal::VirtualizationBackendInternal;
use log::error;
use thiserror::Error;
use uhyve_interface::GuestPhysAddr;
Expand Down Expand Up @@ -53,24 +53,37 @@ pub type DefaultBackend = crate::linux::x86_64::kvm_cpu::KvmVm;
#[cfg(target_os = "macos")]
pub type DefaultBackend = crate::macos::XhyveVm;

/// Trait marking a interface for creating (accelerated) VMs.
pub trait VirtualizationBackend: Sized {
type VCPU: 'static + VirtualCPU;
const NAME: &str;

/// Create a new CPU object
fn new_cpu(
&self,
id: u32,
kernel_info: Arc<KernelInfo>,
enable_stats: bool,
) -> HypervisorResult<Self::VCPU>;

fn new(
memory: &MmapMemory,
peripherals: Arc<VmPeripherals>,
params: &Params,
) -> HypervisorResult<Self>;
pub(crate) mod internal {
use crate::{
mem::MmapMemory,
vm::{KernelInfo, Params, VirtualCPU, VmPeripherals},
HypervisorResult,
};
use std::sync::Arc;

/// Trait marking a interface for creating (accelerated) VMs.
pub trait VirtualizationBackendInternal: Sized {
type VCPU: 'static + VirtualCPU;
const NAME: &str;

/// Create a new CPU object
fn new_cpu(
&self,
id: u32,
kernel_info: Arc<KernelInfo>,
enable_stats: bool,
) -> HypervisorResult<Self::VCPU>;

fn new(
memory: &MmapMemory,
peripherals: Arc<VmPeripherals>,
params: &Params,
) -> HypervisorResult<Self>;
}
}

pub trait VirtualizationBackend {
type BACKEND: internal::VirtualizationBackendInternal;
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -106,7 +119,7 @@ pub(crate) struct KernelInfo {
}

pub struct UhyveVm<VirtBackend: VirtualizationBackend> {
pub(crate) vcpus: Vec<VirtBackend::VCPU>,
pub(crate) vcpus: Vec<<VirtBackend::BACKEND as VirtualizationBackendInternal>::VCPU>,
pub(crate) peripherals: Arc<VmPeripherals>,
pub(crate) kernel_info: Arc<KernelInfo>,
}
Expand Down Expand Up @@ -166,7 +179,7 @@ impl<VirtBackend: VirtualizationBackend> UhyveVm<VirtBackend> {
});

let virt_backend =
VirtBackend::new(&peripherals.mem, peripherals.clone(), &kernel_info.params)?;
VirtBackend::BACKEND::new(&peripherals.mem, peripherals.clone(), &kernel_info.params)?;

let cpu_count = kernel_info.params.cpu_count.get();

Expand Down Expand Up @@ -225,7 +238,7 @@ impl<VirtBackend: VirtualizationBackend> UhyveVm<VirtBackend> {
let barrier = barrier.clone();
let local_cpu_affinity = cpu_affinity
.as_ref()
.and_then(|core_ids| core_ids.get(cpu_id as usize).copied());
.and_then(|core_ids| core_ids.get(cpu_id).copied());

thread::spawn(move || {
debug!("Create thread for CPU {}", cpu_id);
Expand Down Expand Up @@ -307,7 +320,7 @@ d?"

impl<VirtIf: VirtualizationBackend> fmt::Debug for UhyveVm<VirtIf> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct(&format!("UhyveVm<{}>", VirtIf::NAME))
f.debug_struct(&format!("UhyveVm<{}>", VirtIf::BACKEND::NAME))
.field("entry_point", &self.kernel_info.entry_point)
.field("stack_address", &self.kernel_info.stack_address)
.field("mem", &self.peripherals.mem)
Expand Down

0 comments on commit e5d8927

Please sign in to comment.