@@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize};
99
1010use crate :: cpu_config:: templates:: CustomCpuTemplate ;
1111use crate :: device_manager:: persist:: SharedDeviceType ;
12+ use crate :: devices:: virtio:: block:: device:: Block ;
1213use crate :: logger:: info;
1314use crate :: mmds;
1415use crate :: mmds:: data_store:: { Mmds , MmdsVersion } ;
@@ -217,6 +218,11 @@ impl VmResources {
217218 BalloonConfigError :: IncompatibleWith ( "huge pages" ) ,
218219 ) ) ;
219220 }
221+ if self . machine_config . secret_free {
222+ return Err ( ResourcesError :: BalloonDevice (
223+ BalloonConfigError :: IncompatibleWith ( "secret freedom" ) ,
224+ ) ) ;
225+ }
220226 }
221227
222228 SharedDeviceType :: Vsock ( vsock) => {
@@ -262,6 +268,27 @@ impl VmResources {
262268 "huge pages" ,
263269 ) ) ;
264270 }
271+ if self . balloon . get ( ) . is_some ( ) && updated. secret_free {
272+ return Err ( MachineConfigError :: Incompatible (
273+ "balloon device" ,
274+ "secret freedom" ,
275+ ) ) ;
276+ }
277+ if updated. secret_free {
278+ if self . vhost_user_devices_used ( ) {
279+ return Err ( MachineConfigError :: Incompatible (
280+ "vhost-user devices" ,
281+ "userspace bounce buffers" ,
282+ ) ) ;
283+ }
284+
285+ if self . async_block_engine_used ( ) {
286+ return Err ( MachineConfigError :: Incompatible (
287+ "async block engine" ,
288+ "userspace bounce buffers" ,
289+ ) ) ;
290+ }
291+ }
265292 self . machine_config = updated;
266293
267294 Ok ( ( ) )
@@ -320,6 +347,10 @@ impl VmResources {
320347 return Err ( BalloonConfigError :: IncompatibleWith ( "huge pages" ) ) ;
321348 }
322349
350+ if self . machine_config . secret_free {
351+ return Err ( BalloonConfigError :: IncompatibleWith ( "secret freedom" ) ) ;
352+ }
353+
323354 self . balloon . set ( config)
324355 }
325356
@@ -343,6 +374,17 @@ impl VmResources {
343374 & mut self ,
344375 block_device_config : BlockDeviceConfig ,
345376 ) -> Result < ( ) , DriveError > {
377+ if self . machine_config . secret_free {
378+ if block_device_config. file_engine_type == Some ( FileEngineType :: Async ) {
379+ return Err ( DriveError :: IncompatibleWithSecretFreedom (
380+ "async file engine" ,
381+ ) ) ;
382+ }
383+
384+ if block_device_config. socket . is_some ( ) {
385+ return Err ( DriveError :: IncompatibleWithSecretFreedom ( "vhost-user-blk" ) ) ;
386+ }
387+ }
346388 self . block . insert ( block_device_config)
347389 }
348390
@@ -442,17 +484,29 @@ impl VmResources {
442484 Ok ( ( ) )
443485 }
444486
487+ /// Returns true if any vhost user devices are configured int his [`VmResources`] object
488+ pub fn vhost_user_devices_used ( & self ) -> bool {
489+ self . block
490+ . devices
491+ . iter ( )
492+ . any ( |b| b. lock ( ) . expect ( "Poisoned lock" ) . is_vhost_user ( ) )
493+ }
494+
495+ fn async_block_engine_used ( & self ) -> bool {
496+ self . block
497+ . devices
498+ . iter ( )
499+ . any ( |b| match & * b. lock ( ) . unwrap ( ) {
500+ Block :: Virtio ( b) => b. file_engine_type ( ) == FileEngineType :: Async ,
501+ Block :: VhostUser ( _) => false ,
502+ } )
503+ }
504+
445505 /// Allocates guest memory in a configuration most appropriate for these [`VmResources`].
446506 ///
447507 /// If vhost-user-blk devices are in use, allocates memfd-backed shared memory, otherwise
448508 /// prefers anonymous memory for performance reasons.
449509 pub fn allocate_guest_memory ( & self ) -> Result < Vec < GuestRegionMmap > , MemoryError > {
450- let vhost_user_device_used = self
451- . block
452- . devices
453- . iter ( )
454- . any ( |b| b. lock ( ) . expect ( "Poisoned lock" ) . is_vhost_user ( ) ) ;
455-
456510 // Page faults are more expensive for shared memory mapping, including memfd.
457511 // For this reason, we only back guest memory with a memfd
458512 // if a vhost-user-blk device is configured in the VM, otherwise we fall back to
@@ -464,7 +518,7 @@ impl VmResources {
464518 // that would not be worth the effort.
465519 let regions =
466520 crate :: arch:: arch_memory_regions ( 0 , mib_to_bytes ( self . machine_config . mem_size_mib ) ) ;
467- if vhost_user_device_used {
521+ if self . vhost_user_devices_used ( ) {
468522 memory:: memfd_backed (
469523 regions. as_ref ( ) ,
470524 self . machine_config . track_dirty_pages ,
@@ -1307,6 +1361,7 @@ mod tests {
13071361 let mut aux_vm_config = MachineConfigUpdate {
13081362 vcpu_count : Some ( 32 ) ,
13091363 mem_size_mib : Some ( 512 ) ,
1364+ secret_free : Some ( false ) ,
13101365 smt : Some ( false ) ,
13111366 #[ cfg( target_arch = "x86_64" ) ]
13121367 cpu_template : Some ( StaticCpuTemplate :: T2 ) ,
0 commit comments