get_resources/lib.rs
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Resource definitions for the GET family of devices.
5
6#![forbid(unsafe_code)]
7
8/// Guest Emulation Log device resources.
9pub mod gel {
10 use mesh::MeshPayload;
11 use vm_resource::ResourceId;
12 use vm_resource::kind::VmbusDeviceHandleKind;
13
14 /// Handle to a guest emulation log device.
15 #[derive(MeshPayload)]
16 pub struct GuestEmulationLogHandle;
17
18 impl ResourceId<VmbusDeviceHandleKind> for GuestEmulationLogHandle {
19 const ID: &'static str = "gel";
20 }
21}
22
23/// Guest crash device resources.
24pub mod crash {
25 use mesh::MeshPayload;
26 use mesh::rpc::FailableRpc;
27 use std::fs::File;
28 use vm_resource::ResourceId;
29 use vm_resource::kind::VmbusDeviceHandleKind;
30
31 /// Handle to a guest crash dump device.
32 #[derive(MeshPayload)]
33 pub struct GuestCrashDeviceHandle {
34 /// A channel the device can use to get a file to write a dump to.
35 pub request_dump: mesh::Sender<FailableRpc<mesh::OneshotReceiver<()>, File>>,
36 /// The maximum size of the dump that the device will write.
37 pub max_dump_size: u64,
38 }
39
40 impl ResourceId<VmbusDeviceHandleKind> for GuestCrashDeviceHandle {
41 const ID: &'static str = "guest_crash_device";
42 }
43}
44
45/// Guest Emulation Device resources.
46pub mod ged {
47 use inspect::Inspect;
48 use mesh::MeshPayload;
49 use mesh::error::RemoteError;
50 use mesh::payload::Protobuf;
51 use mesh::rpc::Rpc;
52 use thiserror::Error;
53 use vm_resource::Resource;
54 use vm_resource::ResourceId;
55 use vm_resource::kind::FramebufferHandleKind;
56 use vm_resource::kind::VmbusDeviceHandleKind;
57 use vmgs_resources::VmgsResource;
58
59 /// A resource handle for a guest emulation device.
60 #[derive(MeshPayload)]
61 pub struct GuestEmulationDeviceHandle {
62 /// The firmware configuration for the guest.
63 pub firmware: GuestFirmwareConfig,
64 /// Enable COM1 for VTL0 and the VMBUS redirector in VTL2.
65 pub com1: bool,
66 /// Enable COM2 for VTL0 and the VMBUS redirector in VTL2.
67 pub com2: bool,
68 /// Only allow guest to host serial traffic
69 pub serial_tx_only: bool,
70 /// Enable vmbus redirection.
71 pub vmbus_redirection: bool,
72 /// The TPM reference implementation version to expose to the guest.
73 pub tpm_version: Option<GedTpmVersion>,
74 /// Encoded VTL2 settings.
75 pub vtl2_settings: Option<Vec<u8>>,
76 /// The disk to back the GET's VMGS interface.
77 pub vmgs: VmgsResource,
78 /// Framebuffer device control.
79 pub framebuffer: Option<Resource<FramebufferHandleKind>>,
80 /// Access to VTL2 functionality.
81 pub guest_request_recv: mesh::Receiver<GuestEmulationRequest>,
82 /// Notification of firmware events.
83 pub firmware_event_send: Option<mesh::Sender<FirmwareEvent>>,
84 /// Optional Petri observer for IPMI SEL notifications already received over GET.
85 pub ipmi_sel_event_send: Option<mesh::Sender<IpmiSelEvent>>,
86 /// Enable secure boot.
87 pub secure_boot_enabled: bool,
88 /// The secure boot template type.
89 pub secure_boot_template: GuestSecureBootTemplateType,
90 /// Enable battery.
91 pub enable_battery: bool,
92 /// Enable the IPMI KCS interface.
93 pub enable_ipmi: bool,
94 /// Suppress attestation and disable TPM state persistence.
95 pub no_persistent_secrets: bool,
96 /// Test configuration for IGVM Attest message.
97 pub igvm_attest_test_config: Option<IgvmAttestTestConfig>,
98 /// Send the test seed for GspById requests
99 pub test_gsp_by_id: bool,
100 /// EFI diagnostics log level
101 pub efi_diagnostics_log_level: EfiDiagnosticsLogLevelType,
102 /// Force UEFI to bounce-buffer all DMA traffic.
103 pub force_dma_bounce_enabled: bool,
104 /// Enable hibernation.
105 pub enable_hibernation: bool,
106 /// SMBIOS identity overrides delivered to the guest firmware.
107 pub smbios: smbios_defs::SmbiosConfig,
108 }
109
110 /// An IPMI SEL notification received from OpenHCL.
111 #[derive(Debug, Clone, Copy, MeshPayload, PartialEq, Eq)]
112 pub struct IpmiSelEvent {
113 /// BMC-assigned SEL record identifier.
114 pub record_id: u16,
115 /// Completed SEL record.
116 pub record: ipmi_protocol::SelRecord,
117 }
118
119 /// The firmware and chipset configuration for the guest.
120 #[derive(MeshPayload)]
121 pub enum GuestFirmwareConfig {
122 /// Boot from UEFI with Hyper-V generation 2 devices.
123 Uefi {
124 /// Tell UEFI to consider booting from VPCI.
125 enable_vpci_boot: bool,
126 /// Enable UEFI firmware debugging for VTL0.
127 firmware_debug: bool,
128 /// Enable UEFI memory protections for VTL0.
129 enable_memory_protections: bool,
130 /// Disable the UEFI frontpage which will cause the VM to shutdown instead when unable to boot.
131 disable_frontpage: bool,
132 /// Where to send UEFI console output
133 console_mode: UefiConsoleMode,
134 /// Perform a default boot even if boot entries exist and fail
135 default_boot_always_attempt: bool,
136 },
137 /// Boot from PC/AT BIOS with Hyper-V generation 1 devices.
138 Pcat {
139 /// The boot order for the PC/AT firmware.
140 boot_order: [PcatBootDevice; 4],
141 },
142 }
143
144 /// UEFI Console Mode
145 #[derive(MeshPayload, Clone, Debug, Copy)]
146 pub enum UefiConsoleMode {
147 /// video+kbd (having a head)
148 Default = 0,
149 /// headless with COM1 serial console
150 COM1 = 1,
151 /// headless with COM2 serial console
152 COM2 = 2,
153 /// headless
154 None = 3,
155 }
156
157 /// The guest's secure boot template type to use.
158 #[derive(MeshPayload, Clone, Debug, Copy)]
159 pub enum GuestSecureBootTemplateType {
160 /// No template specified.
161 None,
162 /// The microsoft windows template.
163 MicrosoftWindows,
164 /// The Microsoft UEFI certificate authority template.
165 MicrosoftUefiCertificateAuthority,
166 }
167
168 /// The guest's EFI diagnostics log level type to use.
169 #[derive(MeshPayload, Clone, Debug, Copy, Default)]
170 pub enum EfiDiagnosticsLogLevelType {
171 /// Default log level
172 #[default]
173 Default,
174 /// Include INFO logs
175 Info,
176 /// All logs
177 Full,
178 }
179
180 /// The TPM reference implementation version to expose to the guest.
181 #[derive(MeshPayload, Clone, Debug, Copy, PartialEq)]
182 pub enum GedTpmVersion {
183 /// TPM reference implementation version 1.38
184 V138,
185 /// TPM reference implementation version 1.85
186 V185,
187 }
188
189 /// The boot devices for a PC/AT BIOS.
190 #[derive(MeshPayload, Debug, Clone, Copy, PartialEq)]
191 pub enum PcatBootDevice {
192 /// Boot from a floppy disk.
193 Floppy,
194 /// Boot from a hard drive.
195 HardDrive,
196 /// Boot from an optical drive.
197 Optical,
198 /// Boot from the network.
199 Network,
200 }
201
202 impl ResourceId<VmbusDeviceHandleKind> for GuestEmulationDeviceHandle {
203 const ID: &'static str = "ged";
204 }
205
206 /// Define servicing behavior.
207 #[derive(MeshPayload, Default)]
208 pub struct GuestServicingFlags {
209 /// Retain memory for NVMe devices.
210 pub nvme_keepalive: bool,
211 /// Retain memory for MANA devices.
212 pub mana_keepalive: bool,
213 }
214
215 /// Actions a client can request that the Guest Emulation
216 /// Device perform.
217 #[derive(MeshPayload)]
218 pub enum GuestEmulationRequest {
219 /// Wait for VTL2 to connect to the GET.
220 WaitForConnect(Rpc<(), ()>),
221 /// Wait for VTL2 to start VTL0.
222 WaitForVtl0Start(Rpc<(), Result<(), Vtl0StartError>>),
223 /// Save VTL2 state.
224 SaveGuestVtl2State(Rpc<GuestServicingFlags, Result<(), SaveRestoreError>>),
225 /// Update the VTL2 settings.
226 ModifyVtl2Settings(Rpc<Vec<u8>, Result<(), ModifyVtl2SettingsError>>),
227 }
228
229 /// An error waiting to start VTL0.
230 #[derive(Debug, Error, Clone, MeshPayload)]
231 #[error("guest reported VTL0 start error: {0}")]
232 pub struct Vtl0StartError(pub String);
233
234 /// The various errors that can occur during a save or restore
235 /// operation for guest VTL2 state.
236 #[derive(Debug, Error, MeshPayload)]
237 #[expect(missing_docs)]
238 pub enum SaveRestoreError {
239 #[error("an operation is in progress")]
240 OperationInProgress,
241 #[error("vmbus io error")]
242 Io(#[source] RemoteError),
243 #[error("guest error")]
244 GuestError,
245 }
246
247 /// An error that can occur during a VTL2 settings update.
248 #[derive(Debug, Error, MeshPayload)]
249 #[expect(missing_docs)]
250 pub enum ModifyVtl2SettingsError {
251 #[error("large settings not supported")]
252 LargeSettingsNotSupported,
253 #[error("an operation is already in progress")]
254 OperationInProgress,
255 #[error("guest error: {0}")]
256 Guest(String),
257 }
258
259 /// Firmware events generated by the guest.
260 ///
261 /// TODO: For now, these mainly represent UEFI events without the corresponding extra information. This should be
262 /// rethought when OpenVMM supports Linux Direct, IGVM, and other types.
263 #[derive(Debug, Protobuf, PartialEq, Eq, Copy, Clone)]
264 pub enum FirmwareEvent {
265 /// Boot was successful.
266 BootSuccess,
267 /// Boot failed.
268 BootFailed,
269 /// No boot device could be found.
270 NoBootDevice,
271 /// A boot attempt was made.
272 BootAttempt,
273 }
274
275 /// Configuration for the GED's IGVM Attest request handler in test
276 /// scenarios.
277 ///
278 /// Non-extended variants (`AkCertRequestFailureAndRetry`,
279 /// `AkCertPersistentAcrossBoot`) are used by OpenVMM-hosted tests
280 /// that invoke the GED directly. Extended variants and the
281 /// `KeyReleaseFailure*` variants are used by Hyper-V tests via
282 /// the `test_igvm_agent_rpc_server`, where the Hyper-V boot
283 /// sequence (including `initial_reboot`) generates extra IGVM
284 /// attest requests before the test code runs.
285 #[derive(Debug, MeshPayload, Copy, Clone, Inspect)]
286 pub enum IgvmAttestTestConfig {
287 /// Config for testing AK cert retry after failure.
288 ///
289 /// Plan: two failures then one success. Used by OpenVMM-hosted
290 /// tests where no extra boot-time requests occur.
291 AkCertRequestFailureAndRetry,
292 /// Config for testing AK cert retry after failure — extended
293 /// plan for Hyper-V tests.
294 ///
295 /// Hyper-V VMs go through an `initial_reboot` and may generate
296 /// multiple background AK cert requests during the initial boot
297 /// and the reboot. The extra failure actions absorb those
298 /// requests so the final success action is available when the
299 /// guest test code runs.
300 AkCertRequestFailureAndRetryExtended,
301 /// Config for testing AK cert persistency across boots.
302 ///
303 /// Plan: one success then always-no-response. Used by
304 /// OpenVMM-hosted tests where no extra boot-time requests occur.
305 AkCertPersistentAcrossBoot,
306 /// Config for testing AK cert persistency across boots —
307 /// extended plan for Hyper-V tests.
308 ///
309 /// Hyper-V VMs go through an `initial_reboot` that can consume
310 /// the first success action before the test code runs. The
311 /// extra `RespondSuccess` ensures the cert is still provisioned
312 /// after the reboot, so the subsequent boot can validate that
313 /// the cert is served from the persistent cache.
314 AkCertPersistentAcrossBootExtended,
315 /// Config for testing the `skip_hw_unsealing` signal from the
316 /// IGVM agent.
317 ///
318 /// When the agent responds with `skip_hw_unsealing`, the
319 /// attestation code skips the hardware unsealing step even if
320 /// the hardware key protector and derived keys are available.
321 /// This causes `initialize_platform_security` to fall through
322 /// to a scheme-specific error (KP / GSP / GspById), making
323 /// VMGS unlock fail.
324 KeyReleaseFailureSkipHwUnsealing,
325 /// Config for testing key release failure without the
326 /// `skip_hw_unsealing` signal.
327 ///
328 /// When the agent responds with a plain failure (no skip
329 /// signal), the attestation code falls back to hardware
330 /// unsealing using the hardware key protector saved on the
331 /// previous successful boot. The VM should boot normally.
332 KeyReleaseFailure,
333 /// Config for testing a host/agent-requested TPM state refresh.
334 ///
335 /// The agent's GSP RPC reports `state_refresh_request`, which
336 /// drives `refresh_tpm_seeds` in OpenHCL and causes the vTPM
337 /// seeds (and therefore the AK) to be regenerated on the next
338 /// boot. AK cert requests are served so the guest has a valid
339 /// AK to read across boots.
340 StateRefresh,
341 }
342}