@@ -13,6 +13,7 @@ use std::sync::mpsc;
13
13
use std:: sync:: { Arc , Mutex } ;
14
14
15
15
use event_manager:: { MutEventSubscriber , SubscriberOps } ;
16
+ use kvm_ioctls:: Cap ;
16
17
use libc:: EFD_NONBLOCK ;
17
18
use linux_loader:: cmdline:: Cmdline as LoaderKernelCmdline ;
18
19
use utils:: time:: TimestampUs ;
@@ -68,7 +69,7 @@ use crate::vmm_config::snapshot::{LoadSnapshotParams, MemBackendType};
68
69
use crate :: vstate:: kvm:: Kvm ;
69
70
use crate :: vstate:: memory:: { MaybeBounce , create_memfd} ;
70
71
use 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 } ;
72
73
use crate :: { EventManager , Vmm , VmmError , device_manager} ;
73
74
74
75
/// Errors associated with starting the instance.
@@ -147,9 +148,15 @@ fn create_vmm_and_vcpus(
147
148
instance_info : & InstanceInfo ,
148
149
event_manager : & mut EventManager ,
149
150
vcpu_count : u8 ,
150
- kvm_capabilities : Vec < KvmCapability > ,
151
+ mut kvm_capabilities : Vec < KvmCapability > ,
151
152
secret_free : bool ,
152
153
) -> 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
+
153
160
let kvm = Kvm :: new ( kvm_capabilities) ?;
154
161
// Set up Kvm Vm and register memory regions.
155
162
// Build custom CPU config if a custom template is provided.
@@ -238,23 +245,21 @@ pub fn build_microvm_for_boot(
238
245
239
246
let secret_free = vm_resources. machine_config . secret_free ;
240
247
241
- #[ cfg( target_arch = "x86_64" ) ]
242
- if secret_free {
243
- boot_cmdline. insert_str ( "no-kvmclock" ) ?;
244
- }
245
-
246
248
let ( mut vmm, mut vcpus) = create_vmm_and_vcpus (
247
249
instance_info,
248
250
event_manager,
249
251
vm_resources. machine_config . vcpu_count ,
250
252
cpu_template. kvm_capabilities . clone ( ) ,
251
- vm_resources . machine_config . secret_free ,
253
+ secret_free,
252
254
) ?;
253
255
254
256
let guest_memfd = match secret_free {
255
257
true => Some (
256
258
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
+ )
258
263
. map_err ( VmmError :: Vm ) ?,
259
264
) ,
260
265
false => None ,
@@ -268,9 +273,6 @@ pub fn build_microvm_for_boot(
268
273
. register_memory_regions ( guest_memory, None )
269
274
. map_err ( VmmError :: Vm ) ?;
270
275
271
- #[ cfg( target_arch = "x86_64" ) ]
272
- vmm. vm . set_memory_private ( ) . map_err ( VmmError :: Vm ) ?;
273
-
274
276
let entry_point = load_kernel (
275
277
MaybeBounce :: < _ , 4096 > :: new_persistent (
276
278
boot_config. kernel_file . try_clone ( ) . unwrap ( ) ,
@@ -518,6 +520,10 @@ fn memfd_to_slice(memfd: &Option<File>) -> Option<&mut [u8]> {
518
520
}
519
521
}
520
522
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
+
521
527
/// Builds and starts a microVM based on the provided MicrovmState.
522
528
///
523
529
/// 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(
531
537
params : & LoadSnapshotParams ,
532
538
vm_resources : & mut VmResources ,
533
539
) -> 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
-
537
540
// Build Vmm.
538
541
debug ! ( "event_start: build microvm from snapshot" ) ;
539
542
540
543
let secret_free = vm_resources. machine_config . secret_free ;
541
544
542
545
let mut kvm_capabilities = microvm_state. kvm_state . kvm_cap_modifiers . clone ( ) ;
546
+
543
547
if secret_free {
544
548
kvm_capabilities. push ( KvmCapability :: Add ( KVM_CAP_USERFAULT ) ) ;
545
549
}
@@ -556,7 +560,10 @@ pub fn build_microvm_from_snapshot(
556
560
let guest_memfd = match secret_free {
557
561
true => Some (
558
562
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
+ )
560
567
. map_err ( VmmError :: Vm ) ?,
561
568
) ,
562
569
false => None ,
@@ -622,9 +629,6 @@ pub fn build_microvm_from_snapshot(
622
629
vmm. uffd = uffd;
623
630
vmm. uffd_socket = socket;
624
631
625
- #[ cfg( target_arch = "x86_64" ) ]
626
- vmm. vm . set_memory_private ( ) . map_err ( VmmError :: Vm ) ?;
627
-
628
632
#[ cfg( target_arch = "x86_64" ) ]
629
633
{
630
634
// Scale TSC to match, extract the TSC freq from the state if specified
0 commit comments