@@ -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
542545 let mut 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