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