tpm/
logger.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! The definition of [`TpmLogger`] trait that enables TPM implementation
5//! to send log events to an external logger.
6
7use std::sync::Arc;
8use tpm_resources::TpmLoggerKind;
9use vm_resource::CanResolveTo;
10
11/// Events for [`TpmLogger`].
12pub enum TpmLogEvent {
13    /// Failed to renew AK cert
14    AkCertRenewalFailed,
15    /// Failed to change TPM seeds
16    IdentityChangeFailed,
17    /// Invalid PPI or NVRAM state
18    InvalidState,
19}
20
21impl CanResolveTo<ResolvedTpmLogger> for TpmLoggerKind {
22    // Workaround for async_trait not supporting GATs with missing lifetimes.
23    type Input<'a> = &'a ();
24}
25
26/// A resolved tpm logger resource.
27pub struct ResolvedTpmLogger(pub Arc<dyn TpmLogger>);
28
29impl<T: 'static + TpmLogger> From<T> for ResolvedTpmLogger {
30    fn from(value: T) -> Self {
31        Self(Arc::new(value))
32    }
33}
34
35/// A trait for sending log event to the host.
36#[async_trait::async_trait]
37pub trait TpmLogger: Send + Sync {
38    /// Send an event with the given id to the host and flush.
39    async fn log_event_and_flush(&self, event: TpmLogEvent);
40
41    /// Send an event with the given id to the host without flushing.
42    // TODO: This call is needed for the non-async context (callback of
43    // `PollDevice::poll_device` for AK cert requests). Remove the function
44    // once we do not have this constraint.
45    fn log_event(&self, event: TpmLogEvent);
46}
47
48#[async_trait::async_trait]
49impl TpmLogger for Option<Arc<dyn TpmLogger>> {
50    async fn log_event_and_flush(&self, event: TpmLogEvent) {
51        if let Some(logger) = self {
52            logger.log_event_and_flush(event).await;
53        }
54    }
55
56    fn log_event(&self, event: TpmLogEvent) {
57        if let Some(logger) = self {
58            logger.log_event(event);
59        }
60    }
61}