@@ -13,6 +13,7 @@ use std::sync::mpsc;
1313use  std:: sync:: { Arc ,  Mutex } ; 
1414
1515use  event_manager:: { MutEventSubscriber ,  SubscriberOps } ; 
16+ use  kvm_ioctls:: Cap ; 
1617use  libc:: EFD_NONBLOCK ; 
1718use  linux_loader:: cmdline:: Cmdline  as  LoaderKernelCmdline ; 
1819use  utils:: time:: TimestampUs ; 
@@ -68,7 +69,7 @@ use crate::vmm_config::snapshot::{LoadSnapshotParams, MemBackendType};
6869use  crate :: vstate:: kvm:: Kvm ; 
6970use  crate :: vstate:: memory:: { MaybeBounce ,  create_memfd} ; 
7071use  crate :: vstate:: vcpu:: { Vcpu ,  VcpuError } ; 
71- use  crate :: vstate:: vm:: { KVM_GMEM_NO_DIRECT_MAP ,  Vm } ; 
72+ use  crate :: vstate:: vm:: { GUEST_MEMFD_FLAG_NO_DIRECT_MAP ,   GUEST_MEMFD_FLAG_SUPPORT_SHARED ,  Vm } ; 
7273use  crate :: { EventManager ,  Vmm ,  VmmError ,  device_manager} ; 
7374
7475/// Errors associated with starting the instance. 
@@ -147,9 +148,15 @@ fn create_vmm_and_vcpus(
147148    instance_info :  & InstanceInfo , 
148149    event_manager :  & mut  EventManager , 
149150    vcpu_count :  u8 , 
150-     kvm_capabilities :  Vec < KvmCapability > , 
151+     mut   kvm_capabilities :  Vec < KvmCapability > , 
151152    secret_free :  bool , 
152153)  -> Result < ( Vmm ,  Vec < Vcpu > ) ,  VmmError >  { 
154+     if  secret_free { 
155+         kvm_capabilities. push ( KvmCapability :: Add ( Cap :: GuestMemfd  as  u32 ) ) ; 
156+         kvm_capabilities. push ( KvmCapability :: Add ( KVM_CAP_GMEM_SHARED_MEM ) ) ; 
157+         kvm_capabilities. push ( KvmCapability :: Add ( KVM_CAP_GMEM_NO_DIRECT_MAP ) ) ; 
158+     } 
159+ 
153160    let  kvm = Kvm :: new ( kvm_capabilities) ?; 
154161    // Set up Kvm Vm and register memory regions. 
155162    // Build custom CPU config if a custom template is provided. 
@@ -238,23 +245,21 @@ pub fn build_microvm_for_boot(
238245
239246    let  secret_free = vm_resources. machine_config . secret_free ; 
240247
241-     #[ cfg( target_arch = "x86_64" ) ]  
242-     if  secret_free { 
243-         boot_cmdline. insert_str ( "no-kvmclock" ) ?; 
244-     } 
245- 
246248    let  ( mut  vmm,  mut  vcpus)  = create_vmm_and_vcpus ( 
247249        instance_info, 
248250        event_manager, 
249251        vm_resources. machine_config . vcpu_count , 
250252        cpu_template. kvm_capabilities . clone ( ) , 
251-         vm_resources . machine_config . secret_free , 
253+         secret_free, 
252254    ) ?; 
253255
254256    let  guest_memfd = match  secret_free { 
255257        true  => Some ( 
256258            vmm. vm 
257-                 . create_guest_memfd ( vm_resources. memory_size ( ) ,  KVM_GMEM_NO_DIRECT_MAP ) 
259+                 . create_guest_memfd ( 
260+                     vm_resources. memory_size ( ) , 
261+                     GUEST_MEMFD_FLAG_SUPPORT_SHARED  | GUEST_MEMFD_FLAG_NO_DIRECT_MAP , 
262+                 ) 
258263                . map_err ( VmmError :: Vm ) ?, 
259264        ) , 
260265        false  => None , 
@@ -268,9 +273,6 @@ pub fn build_microvm_for_boot(
268273        . register_memory_regions ( guest_memory,  None ) 
269274        . map_err ( VmmError :: Vm ) ?; 
270275
271-     #[ cfg( target_arch = "x86_64" ) ]  
272-     vmm. vm . set_memory_private ( ) . map_err ( VmmError :: Vm ) ?; 
273- 
274276    let  entry_point = load_kernel ( 
275277        MaybeBounce :: < _ ,  4096 > :: new_persistent ( 
276278            boot_config. kernel_file . try_clone ( ) . unwrap ( ) , 
@@ -518,6 +520,10 @@ fn memfd_to_slice(memfd: &Option<File>) -> Option<&mut [u8]> {
518520    } 
519521} 
520522
523+ const  KVM_CAP_GMEM_SHARED_MEM :  u32  = 243 ; 
524+ const  KVM_CAP_GMEM_NO_DIRECT_MAP :  u32  = 244 ; 
525+ const  KVM_CAP_USERFAULT :  u32  = 245 ; 
526+ 
521527/// Builds and starts a microVM based on the provided MicrovmState. 
522528/// 
523529/// An `Arc` reference of the built `Vmm` is also plugged in the `EventManager`, while another 
@@ -531,15 +537,13 @@ pub fn build_microvm_from_snapshot(
531537    params :  & LoadSnapshotParams , 
532538    vm_resources :  & mut  VmResources , 
533539)  -> Result < Arc < Mutex < Vmm > > ,  BuildMicrovmFromSnapshotError >  { 
534-     // TODO: take it from kvm-bindings when userfault support is merged upstream 
535-     const  KVM_CAP_USERFAULT :  u32  = 241 ; 
536- 
537540    // Build Vmm. 
538541    debug ! ( "event_start: build microvm from snapshot" ) ; 
539542
540543    let  secret_free = vm_resources. machine_config . secret_free ; 
541544
542-     let  mut  kvm_capabilities = microvm_state. kvm_state . kvm_cap_modifiers . clone ( ) ; 
545+     let  kvm_capabilities = microvm_state. kvm_state . kvm_cap_modifiers . clone ( ) ; 
546+ 
543547    if  secret_free { 
544548        kvm_capabilities. push ( KvmCapability :: Add ( KVM_CAP_USERFAULT ) ) ; 
545549    } 
@@ -556,7 +560,10 @@ pub fn build_microvm_from_snapshot(
556560    let  guest_memfd = match  secret_free { 
557561        true  => Some ( 
558562            vmm. vm 
559-                 . create_guest_memfd ( vm_resources. memory_size ( ) ,  KVM_GMEM_NO_DIRECT_MAP ) 
563+                 . create_guest_memfd ( 
564+                     vm_resources. memory_size ( ) , 
565+                     GUEST_MEMFD_FLAG_SUPPORT_SHARED  | GUEST_MEMFD_FLAG_NO_DIRECT_MAP , 
566+                 ) 
560567                . map_err ( VmmError :: Vm ) ?, 
561568        ) , 
562569        false  => None , 
@@ -622,9 +629,6 @@ pub fn build_microvm_from_snapshot(
622629    vmm. uffd  = uffd; 
623630    vmm. uffd_socket  = socket; 
624631
625-     #[ cfg( target_arch = "x86_64" ) ]  
626-     vmm. vm . set_memory_private ( ) . map_err ( VmmError :: Vm ) ?; 
627- 
628632    #[ cfg( target_arch = "x86_64" ) ]  
629633    { 
630634        // Scale TSC to match, extract the TSC freq from the state if specified 
0 commit comments