virtio/
resolver.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Resolver for virtio device infrastructure.
5
6use crate::PciInterruptModel;
7use crate::VirtioPciDevice;
8use crate::resolve::VirtioResolveInput;
9use async_trait::async_trait;
10use pci_resources::ResolvePciDeviceHandleParams;
11use pci_resources::ResolvedPciDevice;
12use thiserror::Error;
13use virtio_resources::VirtioPciDeviceHandle;
14use vm_resource::AsyncResolveResource;
15use vm_resource::ResolveError;
16use vm_resource::ResourceResolver;
17use vm_resource::declare_static_async_resolver;
18use vm_resource::kind::PciDeviceHandleKind;
19
20declare_static_async_resolver! {
21    VirtioPciResolver,
22    (PciDeviceHandleKind, VirtioPciDeviceHandle),
23}
24
25/// Resolver for [`VirtioPciDeviceHandle`].
26pub struct VirtioPciResolver;
27
28#[derive(Debug, Error)]
29pub enum ResolveVirtioPciError {
30    #[error("failed to resolve virtio device")]
31    Virtio(#[source] ResolveError),
32    #[error("failed to create PCI device")]
33    Pci(#[source] std::io::Error),
34}
35
36#[async_trait]
37impl AsyncResolveResource<PciDeviceHandleKind, VirtioPciDeviceHandle> for VirtioPciResolver {
38    type Output = ResolvedPciDevice;
39    type Error = ResolveVirtioPciError;
40
41    async fn resolve(
42        &self,
43        resolver: &ResourceResolver,
44        resource: VirtioPciDeviceHandle,
45        input: ResolvePciDeviceHandleParams<'_>,
46    ) -> Result<Self::Output, Self::Error> {
47        let inner = resolver
48            .resolve(
49                resource.0,
50                VirtioResolveInput {
51                    driver_source: input.driver_source,
52                    guest_memory: input.guest_memory,
53                },
54            )
55            .await
56            .map_err(ResolveVirtioPciError::Virtio)?;
57
58        let device = VirtioPciDevice::new(
59            inner.0,
60            PciInterruptModel::Msix(input.register_msi),
61            input.doorbell_registration,
62            input.register_mmio,
63            input.shared_mem_mapper,
64        )
65        .map_err(ResolveVirtioPciError::Pci)?;
66
67        Ok(device.into())
68    }
69}