petri/vm/openvmm/
modify.rs1use super::MANA_INSTANCE;
11use super::NIC_MAC_ADDRESS;
12use super::PetriVmConfigOpenVmm;
13use chipset_resources::battery::BatteryDeviceHandleX64;
14use chipset_resources::battery::HostBatteryUpdate;
15use gdma_resources::GdmaDeviceHandle;
16use gdma_resources::VportDefinition;
17use get_resources::ged::IgvmAttestTestConfig;
18use hvlite_defs::config::Config;
19use hvlite_defs::config::DeviceVtl;
20use hvlite_defs::config::LoadMode;
21use hvlite_defs::config::VpciDeviceConfig;
22use hvlite_defs::config::Vtl2BaseAddressType;
23use tpm_resources::TpmDeviceHandle;
24use tpm_resources::TpmRegisterLayout;
25use vm_resource::IntoResource;
26use vmcore::non_volatile_store::resources::EphemeralNonVolatileStoreHandle;
27use vmotherboard::ChipsetDeviceHandle;
28use vtl2_settings_proto::Vtl2Settings;
29
30impl PetriVmConfigOpenVmm {
31 pub fn with_vtl0_alias_map(mut self) -> Self {
34 self.config
35 .hypervisor
36 .with_vtl2
37 .as_mut()
38 .expect("Not an openhcl config.")
39 .vtl0_alias_map = true;
40 self
41 }
42
43 pub fn with_tpm(mut self) -> Self {
45 if self.firmware.is_openhcl() {
46 self.ged.as_mut().unwrap().enable_tpm = true;
47 } else {
48 self.config.chipset_devices.push(ChipsetDeviceHandle {
49 name: "tpm".to_string(),
50 resource: TpmDeviceHandle {
51 ppi_store: EphemeralNonVolatileStoreHandle.into_resource(),
52 nvram_store: EphemeralNonVolatileStoreHandle.into_resource(),
53 refresh_tpm_seeds: false,
54 ak_cert_type: tpm_resources::TpmAkCertTypeResource::None,
55 register_layout: TpmRegisterLayout::IoPort,
56 guest_secret_key: None,
57 logger: None,
58 is_confidential_vm: self.firmware.isolation().is_some(),
59 bios_guid: guid::guid!("00000000-0000-0000-0000-000000000000"),
61 }
62 .into_resource(),
63 });
64 if let LoadMode::Uefi { enable_tpm, .. } = &mut self.config.load_mode {
65 *enable_tpm = true;
66 }
67 }
68
69 self
70 }
71
72 pub fn with_battery(mut self) -> Self {
74 if self.firmware.is_openhcl() {
75 self.ged.as_mut().unwrap().enable_battery = true;
76 } else {
77 self.config.chipset_devices.push(ChipsetDeviceHandle {
78 name: "battery".to_string(),
79 resource: BatteryDeviceHandleX64 {
80 battery_status_recv: {
81 let (tx, rx) = mesh::channel();
82 tx.send(HostBatteryUpdate::default_present());
83 rx
84 },
85 }
86 .into_resource(),
87 });
88 if let LoadMode::Uefi { enable_battery, .. } = &mut self.config.load_mode {
89 *enable_battery = true;
90 }
91 }
92 self
93 }
94
95 pub fn with_tpm_state_persistence(mut self, tpm_state_persistence: bool) -> Self {
97 if !self.firmware.is_openhcl() {
98 panic!("TPM state persistence is only supported for OpenHCL.")
99 };
100
101 let ged = self.ged.as_mut().expect("No GED to configure TPM");
102
103 ged.no_persistent_secrets = !tpm_state_persistence;
106
107 self
108 }
109
110 pub fn with_igvm_attest_test_config(mut self, config: IgvmAttestTestConfig) -> Self {
112 if !self.firmware.is_openhcl() {
113 panic!("IGVM Attest test config is only supported for OpenHCL.")
114 };
115
116 let ged = self.ged.as_mut().expect("No GED to configure TPM");
117
118 ged.igvm_attest_test_config = Some(config);
119
120 self
121 }
122
123 pub fn with_nic(mut self) -> Self {
127 let endpoint =
128 net_backend_resources::consomme::ConsommeHandle { cidr: None }.into_resource();
129 if self.resources.vtl2_settings.is_some() {
130 self.config.vpci_devices.push(VpciDeviceConfig {
131 vtl: DeviceVtl::Vtl2,
132 instance_id: MANA_INSTANCE,
133 resource: GdmaDeviceHandle {
134 vports: vec![VportDefinition {
135 mac_address: NIC_MAC_ADDRESS,
136 endpoint,
137 }],
138 }
139 .into_resource(),
140 });
141
142 self.resources
143 .vtl2_settings
144 .as_mut()
145 .unwrap()
146 .dynamic
147 .as_mut()
148 .unwrap()
149 .nic_devices
150 .push(vtl2_settings_proto::NicDeviceLegacy {
151 instance_id: MANA_INSTANCE.to_string(),
152 subordinate_instance_id: None,
153 max_sub_channels: None,
154 });
155 } else {
156 const NETVSP_INSTANCE: guid::Guid = guid::guid!("c6c46cc3-9302-4344-b206-aef65e5bd0a2");
157 self.config.vmbus_devices.push((
158 DeviceVtl::Vtl0,
159 netvsp_resources::NetvspHandle {
160 instance_id: NETVSP_INSTANCE,
161 mac_address: NIC_MAC_ADDRESS,
162 endpoint,
163 max_queues: None,
164 }
165 .into_resource(),
166 ));
167 }
168
169 self
170 }
171
172 pub fn with_custom_vtl2_settings(mut self, f: impl FnOnce(&mut Vtl2Settings)) -> Self {
176 f(self
177 .resources
178 .vtl2_settings
179 .as_mut()
180 .expect("Custom VTL 2 settings are only supported with OpenHCL."));
181 self
182 }
183
184 pub fn with_vtl2_relocation_mode(mut self, mode: Vtl2BaseAddressType) -> Self {
186 let LoadMode::Igvm {
187 vtl2_base_address, ..
188 } = &mut self.config.load_mode
189 else {
190 panic!("vtl2 relocation mode is only supported for OpenHCL firmware")
191 };
192 *vtl2_base_address = mode;
193 self
194 }
195
196 pub fn with_custom_config(mut self, f: impl FnOnce(&mut Config)) -> Self {
200 f(&mut self.config);
201 self
202 }
203
204 pub fn with_allow_early_vtl0_access(mut self, allow: bool) -> Self {
210 self.config
211 .hypervisor
212 .with_vtl2
213 .as_mut()
214 .unwrap()
215 .late_map_vtl0_memory =
216 (!allow).then_some(hvlite_defs::config::LateMapVtl0MemoryPolicy::InjectException);
217
218 self
219 }
220}