mod passthrough;
mod pools;
use core::ops::Range;
use std::vec::Vec;
use axdevice::*;
use crate::{AxVmResult, config::AxVMConfig};
pub(crate) struct VmDevicePlan {
graph: ResolvedDeviceGraph,
}
impl VmDevicePlan {
pub(crate) fn with_pools_for_vm(
config: &AxVMConfig,
nodes: Vec<DeviceNodeSpec>,
replacement_ranges: &[Range<u64>],
mut pools: ResourcePools,
) -> AxVmResult<Self> {
pools::reserve_guest_memory(config, &mut pools)?;
Self::build(config, nodes, replacement_ranges, &mut pools)
}
fn build(
config: &AxVMConfig,
nodes: Vec<DeviceNodeSpec>,
replacement_ranges: &[Range<u64>],
pools: &mut ResourcePools,
) -> AxVmResult<Self> {
let mut builder = DeviceGraphBuilder::new();
for node in nodes {
builder.add(node).map_err(DeviceManagerError::from)?;
}
passthrough::add_host_nodes(config, replacement_ranges, &mut builder)?;
let declared = builder.declare().map_err(DeviceManagerError::from)?;
let requests = declared.requests()?;
pools::allow_fixed_requirements(&requests, pools)?;
let graph = declared.resolve(core::mem::take(pools))?;
Ok(Self { graph })
}
pub(crate) const fn graph(&self) -> &ResolvedDeviceGraph {
&self.graph
}
}
pub(crate) trait ArchitectureVmPlan {
fn devices(&self) -> &VmDevicePlan;
}
pub(crate) struct SimpleVmPlan(VmDevicePlan);
impl SimpleVmPlan {
pub(crate) const fn new(devices: VmDevicePlan) -> Self {
Self(devices)
}
}
impl ArchitectureVmPlan for SimpleVmPlan {
fn devices(&self) -> &VmDevicePlan {
&self.0
}
}