hyperv_ic/
resolver.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Resource resolvers for the ICs.
5
6use crate::kvp::KvpIc;
7use crate::shutdown::ShutdownIc;
8use crate::timesync::TimesyncIc;
9use anyhow::Context as _;
10use async_trait::async_trait;
11use hyperv_ic_resources::kvp::KvpIcHandle;
12use hyperv_ic_resources::shutdown::ShutdownIcHandle;
13use hyperv_ic_resources::timesync::TimesyncIcHandle;
14use std::convert::Infallible;
15use vm_resource::AsyncResolveResource;
16use vm_resource::IntoResource;
17use vm_resource::PlatformResource;
18use vm_resource::ResolveResource;
19use vm_resource::ResourceResolver;
20use vm_resource::declare_static_async_resolver;
21use vm_resource::declare_static_resolver;
22use vm_resource::kind::VmbusDeviceHandleKind;
23use vmbus_channel::resources::ResolveVmbusDeviceHandleParams;
24use vmbus_channel::resources::ResolvedVmbusDevice;
25use vmbus_channel::simple::SimpleDeviceWrapper;
26use vmcore::reference_time::ReferenceTimeSourceKind;
27
28/// Resource resolver for the shutdown IC.
29pub struct ShutdownIcResolver;
30
31declare_static_resolver! {
32    ShutdownIcResolver,
33    (VmbusDeviceHandleKind, ShutdownIcHandle),
34}
35
36impl ResolveResource<VmbusDeviceHandleKind, ShutdownIcHandle> for ShutdownIcResolver {
37    type Output = ResolvedVmbusDevice;
38    type Error = Infallible;
39
40    fn resolve(
41        &self,
42        resource: ShutdownIcHandle,
43        input: ResolveVmbusDeviceHandleParams<'_>,
44    ) -> Result<Self::Output, Self::Error> {
45        Ok(
46            SimpleDeviceWrapper::new(input.driver_source.simple(), ShutdownIc::new(resource.recv))
47                .into(),
48        )
49    }
50}
51
52/// Resource resolver for the KVP IC.
53pub struct KvpIcResolver;
54
55declare_static_resolver! {
56    KvpIcResolver,
57    (VmbusDeviceHandleKind, KvpIcHandle),
58}
59
60impl ResolveResource<VmbusDeviceHandleKind, KvpIcHandle> for KvpIcResolver {
61    type Output = ResolvedVmbusDevice;
62    type Error = Infallible;
63
64    fn resolve(
65        &self,
66        resource: KvpIcHandle,
67        input: ResolveVmbusDeviceHandleParams<'_>,
68    ) -> Result<Self::Output, Self::Error> {
69        Ok(
70            SimpleDeviceWrapper::new(input.driver_source.simple(), KvpIc::new(resource.recv))
71                .into(),
72        )
73    }
74}
75
76/// Resource resolver for the timesync IC.
77pub struct TimesyncIcResolver;
78
79declare_static_async_resolver! {
80    TimesyncIcResolver,
81    (VmbusDeviceHandleKind, TimesyncIcHandle),
82}
83
84#[async_trait]
85impl AsyncResolveResource<VmbusDeviceHandleKind, TimesyncIcHandle> for TimesyncIcResolver {
86    type Output = ResolvedVmbusDevice;
87    type Error = anyhow::Error;
88
89    async fn resolve(
90        &self,
91        resolver: &ResourceResolver,
92        TimesyncIcHandle: TimesyncIcHandle,
93        input: ResolveVmbusDeviceHandleParams<'_>,
94    ) -> Result<Self::Output, Self::Error> {
95        let ref_time = resolver
96            .resolve::<ReferenceTimeSourceKind, _>(PlatformResource.into_resource(), ())
97            .await
98            .context("failed to resolve reference time")?;
99
100        Ok(SimpleDeviceWrapper::new(
101            input.driver_source.simple(),
102            TimesyncIc::new(&input.driver_source.simple(), ref_time),
103        )
104        .into())
105    }
106}