chipset_device_worker/
resolver.rs1use crate::RemoteDynamicResolvers;
7use crate::guestmem::GuestMemoryProxy;
8use crate::proxy::ChipsetDeviceProxy;
9use crate::worker::RemoteChipsetDeviceHandleParams;
10use crate::worker::RemoteChipsetDeviceWorkerParameters;
11use crate::worker::remote_chipset_device_worker_id;
12use async_trait::async_trait;
13use chipset_device_resources::ResolveChipsetDeviceHandleParams;
14use chipset_device_resources::ResolvedChipsetDevice;
15use chipset_device_worker_defs::RemoteChipsetDeviceHandle;
16use thiserror::Error;
17use vm_resource::AsyncResolveResource;
18use vm_resource::ResourceResolver;
19use vm_resource::kind::ChipsetDeviceHandleKind;
20
21pub struct RemoteChipsetDeviceResolver<T: RemoteDynamicResolvers>(pub T);
26
27#[derive(Debug, Error)]
29pub enum ResolveRemoteChipsetDeviceError {
30 #[error("error launching worker")]
32 LaunchWorker(#[source] anyhow::Error),
33 #[error("error constructing proxy device")]
35 ConstructProxy(#[source] anyhow::Error),
36}
37
38#[async_trait]
39impl<T: RemoteDynamicResolvers>
40 AsyncResolveResource<ChipsetDeviceHandleKind, RemoteChipsetDeviceHandle>
41 for RemoteChipsetDeviceResolver<T>
42{
43 type Error = ResolveRemoteChipsetDeviceError;
44 type Output = ResolvedChipsetDevice;
45
46 async fn resolve(
47 &self,
48 _resolver: &ResourceResolver,
49 resource: RemoteChipsetDeviceHandle,
50 input: ResolveChipsetDeviceHandleParams<'_>,
51 ) -> Result<Self::Output, Self::Error> {
52 let RemoteChipsetDeviceHandle {
53 device,
54 worker_host,
55 } = resource;
56
57 let (req_send, req_recv) = mesh::channel();
58 let (resp_send, resp_recv) = mesh::channel();
59 let (cap_send, cap_recv) = mesh::oneshot();
60
61 let (gm_proxy, gm_remote) = GuestMemoryProxy::new(input.guest_memory.clone());
62 let (enc_gm_proxy, enc_gm_remote) =
63 GuestMemoryProxy::new(input.encrypted_guest_memory.clone());
64
65 let worker = worker_host
66 .launch_worker(
67 remote_chipset_device_worker_id(),
68 RemoteChipsetDeviceWorkerParameters {
69 device,
70 dyn_resolvers: self.0.clone(),
71 inputs: RemoteChipsetDeviceHandleParams {
72 device_name: input.device_name.to_string(),
73 vmtime: input.vmtime.builder().clone(),
74 is_restoring: input.is_restoring,
75 guest_memory: gm_remote,
76 encrypted_guest_memory: enc_gm_remote,
77 },
78 req_recv,
79 resp_send,
80 cap_send,
81 },
82 )
83 .await
84 .map_err(ResolveRemoteChipsetDeviceError::LaunchWorker)?;
85
86 let proxy = ChipsetDeviceProxy::new(
87 req_send,
88 resp_recv,
89 cap_recv,
90 worker,
91 gm_proxy,
92 enc_gm_proxy,
93 input,
94 )
95 .await
96 .map_err(ResolveRemoteChipsetDeviceError::ConstructProxy)?;
97
98 Ok(proxy.into())
99 }
100}