@@ -99,6 +99,11 @@ pub struct MemoryConfig {
9999 #[ cfg( target_arch = "aarch64" ) ]
100100 #[ serde( default ) ]
101101 pub initial_swiotlb_size : usize ,
102+ /// Whether guest_memfd should be used to back normal guest memory. If this is enabled
103+ /// and any devices are attached to the VM, then initial_swiotlb_size must be non-zero,
104+ /// as I/O into secret free memory is not possible.
105+ #[ serde( default ) ]
106+ pub secret_free : bool ,
102107}
103108
104109/// Struct used in PUT `/machine-config` API call.
@@ -289,6 +294,7 @@ impl MachineConfig {
289294 let mem_size_mib = update. mem_size_mib . unwrap_or ( self . mem_size_mib ) ;
290295 let page_config = update. huge_pages . unwrap_or ( self . huge_pages ) ;
291296 let mem_config = update. mem_config . unwrap_or ( self . mem_config ) ;
297+ let track_dirty_pages = update. track_dirty_pages . unwrap_or ( self . track_dirty_pages ) ;
292298
293299 if mem_size_mib == 0 || !page_config. is_valid_mem_size ( mem_size_mib) {
294300 return Err ( MachineConfigError :: InvalidMemorySize ) ;
@@ -301,6 +307,20 @@ impl MachineConfig {
301307 return Err ( MachineConfigError :: InvalidSwiotlbRegionSize ) ;
302308 }
303309
310+ if mem_config. secret_free && page_config != HugePageConfig :: None {
311+ return Err ( MachineConfigError :: Incompatible (
312+ "secret freedom" ,
313+ "huge pages" ,
314+ ) ) ;
315+ }
316+
317+ if mem_config. secret_free && track_dirty_pages {
318+ return Err ( MachineConfigError :: Incompatible (
319+ "secret freedom" ,
320+ "diff snapshots" ,
321+ ) ) ;
322+ }
323+
304324 let cpu_template = match update. cpu_template {
305325 None => self . cpu_template . clone ( ) ,
306326 Some ( StaticCpuTemplate :: None ) => None ,
@@ -313,7 +333,7 @@ impl MachineConfig {
313333 mem_config,
314334 smt,
315335 cpu_template,
316- track_dirty_pages : update . track_dirty_pages . unwrap_or ( self . track_dirty_pages ) ,
336+ track_dirty_pages,
317337 huge_pages : page_config,
318338 #[ cfg( feature = "gdb" ) ]
319339 gdb_socket_path : update. gdb_socket_path . clone ( ) ,
@@ -325,7 +345,7 @@ impl MachineConfig {
325345mod tests {
326346 use crate :: cpu_config:: templates:: { CpuTemplateType , CustomCpuTemplate , StaticCpuTemplate } ;
327347 use crate :: vmm_config:: machine_config:: {
328- HugePageConfig , MachineConfig , MachineConfigError , MachineConfigUpdate ,
348+ HugePageConfig , MachineConfig , MachineConfigError , MachineConfigUpdate , MemoryConfig ,
329349 } ;
330350
331351 #[ test]
@@ -379,6 +399,38 @@ mod tests {
379399 . unwrap ( ) ;
380400 assert_eq ! ( updated. huge_pages, HugePageConfig :: Hugetlbfs2M ) ;
381401 assert_eq ! ( updated. mem_size_mib, 32 ) ;
402+
403+ let res = mconf. update ( & MachineConfigUpdate {
404+ huge_pages : Some ( HugePageConfig :: Hugetlbfs2M ) ,
405+ mem_config : Some ( MemoryConfig {
406+ secret_free : true ,
407+ ..Default :: default ( )
408+ } ) ,
409+ ..Default :: default ( )
410+ } ) ;
411+ assert_eq ! (
412+ res,
413+ Err ( MachineConfigError :: Incompatible (
414+ "secret freedom" ,
415+ "huge pages"
416+ ) )
417+ ) ;
418+
419+ let res = mconf. update ( & MachineConfigUpdate {
420+ track_dirty_pages : Some ( true ) ,
421+ mem_config : Some ( MemoryConfig {
422+ secret_free : true ,
423+ ..Default :: default ( )
424+ } ) ,
425+ ..Default :: default ( )
426+ } ) ;
427+ assert_eq ! (
428+ res,
429+ Err ( MachineConfigError :: Incompatible (
430+ "secret freedom" ,
431+ "diff snapshots"
432+ ) )
433+ ) ;
382434 }
383435
384436 #[ test]
0 commit comments