@@ -43,6 +43,11 @@ use kvm_bindings::{
4343use kvm_bindings:: {
4444 kvm_userspace_memory_region, KVM_API_VERSION , KVM_SYSTEM_EVENT_RESET , KVM_SYSTEM_EVENT_SHUTDOWN ,
4545} ;
46+ #[ cfg( feature = "tee" ) ]
47+ use kvm_bindings:: {
48+ kvm_create_guest_memfd, kvm_memory_attributes, kvm_userspace_memory_region2, KVM_API_VERSION ,
49+ KVM_MEMORY_ATTRIBUTE_PRIVATE , KVM_MEM_GUEST_MEMFD ,
50+ } ;
4651use kvm_ioctls:: * ;
4752use utils:: eventfd:: EventFd ;
4853use utils:: signal:: { register_signal_handler, sigrtmin, Killable } ;
@@ -103,6 +108,12 @@ pub enum Error {
103108 SetUserMemoryRegion ( kvm_ioctls:: Error ) ,
104109 /// Error creating memory map for SHM region.
105110 ShmMmap ( io:: Error ) ,
111+ #[ cfg( feature = "tee" ) ]
112+ /// Cannot set the memory regions.
113+ SetUserMemoryRegion2 ( kvm_ioctls:: Error ) ,
114+ #[ cfg( feature = "tee" ) ]
115+ /// Cannot create guest memfd.
116+ CreateGuestMemfd ( kvm_ioctls:: Error ) ,
106117 #[ cfg( feature = "amd-sev" ) ]
107118 /// Error initializing the Secure Virtualization Backend (SNP).
108119 SnpSecVirtInit ( SnpError ) ,
@@ -255,6 +266,10 @@ impl Display for Error {
255266 SetUserMemoryRegion ( e) => write ! ( f, "Cannot set the memory regions: {e}" ) ,
256267 ShmMmap ( e) => write ! ( f, "Error creating memory map for SHM region: {e}" ) ,
257268 #[ cfg( feature = "tee" ) ]
269+ SetUserMemoryRegion2 ( e) => write ! ( f, "Cannot set the memory regions: {e}" ) ,
270+ #[ cfg( feature = "tee" ) ]
271+ CreateGuestMemfd ( e) => write ! ( f, "Cannot create guest memfd: {e}" ) ,
272+ #[ cfg( feature = "tee" ) ]
258273 SnpSecVirtInit ( e) => write ! (
259274 f,
260275 "Error initializing the Secure Virtualization Backend (SEV): {e:?}"
@@ -505,6 +520,7 @@ impl Vm {
505520 pub fn memory_init (
506521 & mut self ,
507522 guest_mem : & GuestMemoryMmap ,
523+ #[ cfg( feature = "tee" ) ] guest_memfd : & mut Vec < RawFd > ,
508524 kvm_max_memslots : usize ,
509525 ) -> Result < ( ) > {
510526 if guest_mem. num_regions ( ) > kvm_max_memslots {
@@ -513,20 +529,69 @@ impl Vm {
513529 for region in guest_mem. iter ( ) {
514530 // It's safe to unwrap because the guest address is valid.
515531 let host_addr = guest_mem. get_host_address ( region. start_addr ( ) ) . unwrap ( ) ;
516- debug ! ( "Guest memory starts at {:x?}" , host_addr) ;
517- let memory_region = kvm_userspace_memory_region {
518- slot : self . next_mem_slot ,
519- guest_phys_addr : region. start_addr ( ) . raw_value ( ) ,
520- memory_size : region. len ( ) ,
521- userspace_addr : host_addr as u64 ,
522- flags : 0 ,
523- } ;
524- // Safe because we mapped the memory region, we made sure that the regions
525- // are not overlapping.
526- unsafe {
527- self . fd
528- . set_user_memory_region ( memory_region)
529- . map_err ( Error :: SetUserMemoryRegion ) ?;
532+ info ! ( "Guest memory starts at {:x?}" , host_addr) ;
533+
534+ #[ cfg( feature = "tee" ) ]
535+ {
536+ let gmem = kvm_create_guest_memfd {
537+ size : region. len ( ) ,
538+ flags : 0 ,
539+ reserved : [ 0 ; 6 ] ,
540+ } ;
541+
542+ let id: RawFd = self
543+ . fd
544+ . create_guest_memfd ( gmem)
545+ . map_err ( Error :: CreateGuestMemfd ) ?;
546+
547+ guest_memfd. push ( id) ;
548+
549+ let memory_region = kvm_userspace_memory_region2 {
550+ slot : self . next_mem_slot as u32 ,
551+ flags : KVM_MEM_GUEST_MEMFD ,
552+ guest_phys_addr : region. start_addr ( ) . raw_value ( ) ,
553+ memory_size : region. len ( ) ,
554+ userspace_addr : host_addr as u64 ,
555+ guest_memfd_offset : 0 ,
556+ guest_memfd : id as u32 ,
557+ pad1 : 0 ,
558+ pad2 : [ 0 ; 14 ] ,
559+ } ;
560+
561+ // Safe because we mapped the memory region, we made sure that the regions
562+ // are not overlapping.
563+ unsafe {
564+ self . fd
565+ . set_user_memory_region2 ( memory_region)
566+ . map_err ( Error :: SetUserMemoryRegion2 ) ?;
567+ } ;
568+
569+ // set private by default when using guestmemfd
570+ // this imitates QEMU behavior
571+ let attr = kvm_memory_attributes {
572+ address : region. start_addr ( ) . raw_value ( ) ,
573+ size : region. len ( ) ,
574+ attributes : KVM_MEMORY_ATTRIBUTE_PRIVATE as u64 ,
575+ flags : 0 ,
576+ } ;
577+ self . fd . set_memory_attributes ( attr) . unwrap ( ) ;
578+ }
579+ #[ cfg( not( feature = "tee" ) ) ]
580+ {
581+ let memory_region = kvm_userspace_memory_region {
582+ slot : self . next_mem_slot as u32 ,
583+ guest_phys_addr : region. start_addr ( ) . raw_value ( ) ,
584+ memory_size : region. len ( ) ,
585+ userspace_addr : host_addr as u64 ,
586+ flags : 0 ,
587+ } ;
588+ // Safe because we mapped the memory region, we made sure that the regions
589+ // are not overlapping.
590+ unsafe {
591+ self . fd
592+ . set_user_memory_region ( memory_region)
593+ . map_err ( Error :: SetUserMemoryRegion ) ?;
594+ } ;
530595 } ;
531596 self . next_mem_slot += 1 ;
532597 }
0 commit comments