@@ -110,6 +110,14 @@ pub struct VmResources {
110110}
111111
112112impl VmResources {
113+ /// Whether this [`VmResources`] object contains any devices that require host kernel access
114+ /// into guest memory.
115+ pub fn has_any_io_devices ( & self ) -> bool {
116+ !self . block . devices . is_empty ( )
117+ || self . vsock . get ( ) . is_some ( )
118+ || self . net_builder . iter ( ) . next ( ) . is_some ( )
119+ }
120+
113121 /// Configures Vmm resources as described by the `config_json` param.
114122 pub fn from_json (
115123 config_json : & str ,
@@ -217,6 +225,11 @@ impl VmResources {
217225 BalloonConfigError :: IncompatibleWith ( "huge pages" ) ,
218226 ) ) ;
219227 }
228+ if self . machine_config . mem_config . secret_free {
229+ return Err ( ResourcesError :: BalloonDevice (
230+ BalloonConfigError :: IncompatibleWith ( "secret freedom" ) ,
231+ ) ) ;
232+ }
220233 }
221234
222235 SharedDeviceType :: Vsock ( vsock) => {
@@ -256,12 +269,28 @@ impl VmResources {
256269 return Err ( MachineConfigError :: IncompatibleBalloonSize ) ;
257270 }
258271
272+ if self . has_any_io_devices ( )
273+ && self . machine_config . mem_config . secret_free
274+ && !self . swiotlb_used ( )
275+ {
276+ return Err ( MachineConfigError :: Incompatible (
277+ "secret freedom" ,
278+ "I/O without swiotlb" ,
279+ ) ) ;
280+ }
281+
259282 if self . balloon . get ( ) . is_some ( ) && updated. huge_pages != HugePageConfig :: None {
260283 return Err ( MachineConfigError :: Incompatible (
261284 "balloon device" ,
262285 "huge pages" ,
263286 ) ) ;
264287 }
288+ if self . balloon . get ( ) . is_some ( ) && updated. mem_config . secret_free {
289+ return Err ( MachineConfigError :: Incompatible (
290+ "balloon device" ,
291+ "secret freedom" ,
292+ ) ) ;
293+ }
265294 self . machine_config = updated;
266295
267296 Ok ( ( ) )
@@ -320,6 +349,10 @@ impl VmResources {
320349 return Err ( BalloonConfigError :: IncompatibleWith ( "huge pages" ) ) ;
321350 }
322351
352+ if self . machine_config . mem_config . secret_free {
353+ return Err ( BalloonConfigError :: IncompatibleWith ( "secret freedom" ) ) ;
354+ }
355+
323356 self . balloon . set ( config)
324357 }
325358
@@ -343,6 +376,13 @@ impl VmResources {
343376 & mut self ,
344377 block_device_config : BlockDeviceConfig ,
345378 ) -> Result < ( ) , DriveError > {
379+ if self . has_any_io_devices ( )
380+ && self . machine_config . mem_config . secret_free
381+ && !self . swiotlb_used ( )
382+ {
383+ return Err ( DriveError :: SecretFreeWithoutSwiotlb ) ;
384+ }
385+
346386 self . block . insert ( block_device_config)
347387 }
348388
@@ -351,12 +391,26 @@ impl VmResources {
351391 & mut self ,
352392 body : NetworkInterfaceConfig ,
353393 ) -> Result < ( ) , NetworkInterfaceError > {
394+ if self . has_any_io_devices ( )
395+ && self . machine_config . mem_config . secret_free
396+ && !self . swiotlb_used ( )
397+ {
398+ return Err ( NetworkInterfaceError :: SecretFreeWithoutSwiotlb ) ;
399+ }
400+
354401 let _ = self . net_builder . build ( body) ?;
355402 Ok ( ( ) )
356403 }
357404
358405 /// Sets a vsock device to be attached when the VM starts.
359406 pub fn set_vsock_device ( & mut self , config : VsockDeviceConfig ) -> Result < ( ) , VsockConfigError > {
407+ if self . has_any_io_devices ( )
408+ && self . machine_config . mem_config . secret_free
409+ && !self . swiotlb_used ( )
410+ {
411+ return Err ( VsockConfigError :: SecretFreeWithoutSwiotlb ) ;
412+ }
413+
360414 self . vsock . insert ( config)
361415 }
362416
0 commit comments