@@ -40,19 +40,18 @@ use kvm_bindings::{
40
40
KVM_CLOCK_TSC_STABLE , KVM_IRQCHIP_IOAPIC , KVM_IRQCHIP_PIC_MASTER , KVM_IRQCHIP_PIC_SLAVE ,
41
41
KVM_MAX_CPUID_ENTRIES ,
42
42
} ;
43
- #[ cfg( feature = "tee" ) ]
44
43
use kvm_bindings:: {
45
- kvm_create_guest_memfd, kvm_memory_attributes, kvm_userspace_memory_region2, KVM_API_VERSION ,
46
- KVM_MEMORY_ATTRIBUTE_PRIVATE , KVM_MEM_GUEST_MEMFD ,
44
+ kvm_create_guest_memfd, kvm_memory_attributes, kvm_userspace_memory_region,
45
+ kvm_userspace_memory_region2, KVM_API_VERSION , KVM_MEMORY_ATTRIBUTE_PRIVATE ,
46
+ KVM_MEM_GUEST_MEMFD ,
47
47
} ;
48
- #[ cfg( not( feature = "tee" ) ) ]
49
- use kvm_bindings:: { kvm_userspace_memory_region, KVM_API_VERSION } ;
50
- use kvm_ioctls:: * ;
48
+ use kvm_ioctls:: { Cap :: * , * } ;
51
49
use utils:: eventfd:: EventFd ;
52
50
use utils:: signal:: { register_signal_handler, sigrtmin, Killable } ;
53
51
use utils:: sm:: StateMachine ;
54
52
use vm_memory:: {
55
53
Address , GuestAddress , GuestMemory , GuestMemoryError , GuestMemoryMmap , GuestMemoryRegion ,
54
+ GuestRegionMmap ,
56
55
} ;
57
56
58
57
#[ cfg( feature = "amd-sev" ) ]
@@ -67,6 +66,8 @@ pub enum Error {
67
66
#[ cfg( target_arch = "x86_64" ) ]
68
67
/// A call to cpuid instruction failed.
69
68
CpuId ( cpuid:: Error ) ,
69
+ /// Unable to create a KVM guest_memfd.
70
+ CreateGuestMemfd ( kvm_ioctls:: Error ) ,
70
71
#[ cfg( target_arch = "x86_64" ) ]
71
72
/// Error configuring the floating point related registers
72
73
FPUConfiguration ( arch:: x86_64:: regs:: Error ) ,
@@ -103,16 +104,12 @@ pub enum Error {
103
104
#[ cfg( target_arch = "x86_64" ) ]
104
105
/// Error configuring the general purpose registers
105
106
REGSConfiguration ( arch:: x86_64:: regs:: Error ) ,
107
+ /// Cannot set memory region attributes.
108
+ SetMemoryAttributes ( kvm_ioctls:: Error ) ,
106
109
/// Cannot set the memory regions.
107
110
SetUserMemoryRegion ( kvm_ioctls:: Error ) ,
108
111
/// Error creating memory map for SHM region.
109
112
ShmMmap ( io:: Error ) ,
110
- #[ cfg( feature = "tee" ) ]
111
- /// Cannot set the memory regions.
112
- SetUserMemoryRegion2 ( kvm_ioctls:: Error ) ,
113
- #[ cfg( feature = "tee" ) ]
114
- /// Cannot create guest memfd.
115
- CreateGuestMemfd ( kvm_ioctls:: Error ) ,
116
113
#[ cfg( feature = "amd-sev" ) ]
117
114
/// Error initializing the Secure Virtualization Backend (SNP).
118
115
SnpSecVirtInit ( SnpError ) ,
@@ -238,6 +235,7 @@ impl Display for Error {
238
235
match self {
239
236
#[ cfg( target_arch = "x86_64" ) ]
240
237
CpuId ( e) => write ! ( f, "Cpuid error: {e:?}" ) ,
238
+ CreateGuestMemfd ( e) => write ! ( f, "Unable to create KVM guest_memfd: {e:?}" ) ,
241
239
GuestMemoryMmap ( e) => write ! ( f, "Guest memory error: {e:?}" ) ,
242
240
#[ cfg( target_arch = "x86_64" ) ]
243
241
GuestMSRs ( e) => write ! ( f, "Retrieving supported guest MSRs fails: {e:?}" ) ,
@@ -262,13 +260,10 @@ impl Display for Error {
262
260
f,
263
261
"Cannot set the local interruption due to bad configuration: {e:?}"
264
262
) ,
263
+ SetMemoryAttributes ( e) => write ! ( f, "Cannot set memory region attributes: {e}" ) ,
265
264
SetUserMemoryRegion ( e) => write ! ( f, "Cannot set the memory regions: {e}" ) ,
266
265
ShmMmap ( e) => write ! ( f, "Error creating memory map for SHM region: {e}" ) ,
267
266
#[ cfg( feature = "tee" ) ]
268
- SetUserMemoryRegion2 ( e) => write ! ( f, "Cannot set the memory regions: {e}" ) ,
269
- #[ cfg( feature = "tee" ) ]
270
- CreateGuestMemfd ( e) => write ! ( f, "Cannot create guest memfd: {e}" ) ,
271
- #[ cfg( feature = "tee" ) ]
272
267
SnpSecVirtInit ( e) => write ! (
273
268
f,
274
269
"Error initializing the Secure Virtualization Backend (SEV): {e:?}"
@@ -392,7 +387,6 @@ pub struct KvmContext {
392
387
393
388
impl KvmContext {
394
389
pub fn new ( ) -> Result < Self > {
395
- use kvm_ioctls:: Cap :: * ;
396
390
let kvm = Kvm :: new ( ) . expect ( "Error creating the Kvm object" ) ;
397
391
398
392
// Check that KVM has the correct version.
@@ -519,80 +513,14 @@ impl Vm {
519
513
pub fn memory_init (
520
514
& mut self ,
521
515
guest_mem : & GuestMemoryMmap ,
522
- #[ cfg( feature = "tee" ) ] guest_memfd : & mut Vec < RawFd > ,
523
516
kvm_max_memslots : usize ,
524
517
) -> Result < ( ) > {
525
518
if guest_mem. num_regions ( ) > kvm_max_memslots {
526
519
return Err ( Error :: NotEnoughMemorySlots ) ;
527
520
}
528
- for region in guest_mem. iter ( ) {
529
- // It's safe to unwrap because the guest address is valid.
530
- let host_addr = guest_mem. get_host_address ( region. start_addr ( ) ) . unwrap ( ) ;
531
- info ! ( "Guest memory starts at {:x?}" , host_addr) ;
532
521
533
- #[ cfg( feature = "tee" ) ]
534
- {
535
- let gmem = kvm_create_guest_memfd {
536
- size : region. len ( ) ,
537
- flags : 0 ,
538
- reserved : [ 0 ; 6 ] ,
539
- } ;
540
-
541
- let id: RawFd = self
542
- . fd
543
- . create_guest_memfd ( gmem)
544
- . map_err ( Error :: CreateGuestMemfd ) ?;
545
-
546
- guest_memfd. push ( id) ;
547
-
548
- let memory_region = kvm_userspace_memory_region2 {
549
- slot : self . next_mem_slot as u32 ,
550
- flags : KVM_MEM_GUEST_MEMFD ,
551
- guest_phys_addr : region. start_addr ( ) . raw_value ( ) ,
552
- memory_size : region. len ( ) ,
553
- userspace_addr : host_addr as u64 ,
554
- guest_memfd_offset : 0 ,
555
- guest_memfd : id as u32 ,
556
- pad1 : 0 ,
557
- pad2 : [ 0 ; 14 ] ,
558
- } ;
559
-
560
- // Safe because we mapped the memory region, we made sure that the regions
561
- // are not overlapping.
562
- unsafe {
563
- self . fd
564
- . set_user_memory_region2 ( memory_region)
565
- . map_err ( Error :: SetUserMemoryRegion2 ) ?;
566
- } ;
567
-
568
- // set private by default when using guestmemfd
569
- // this imitates QEMU behavior
570
- let attr = kvm_memory_attributes {
571
- address : region. start_addr ( ) . raw_value ( ) ,
572
- size : region. len ( ) ,
573
- attributes : KVM_MEMORY_ATTRIBUTE_PRIVATE as u64 ,
574
- flags : 0 ,
575
- } ;
576
- self . fd . set_memory_attributes ( attr) . unwrap ( ) ;
577
- }
578
- #[ cfg( not( feature = "tee" ) ) ]
579
- {
580
- let memory_region = kvm_userspace_memory_region {
581
- slot : self . next_mem_slot as u32 ,
582
- guest_phys_addr : region. start_addr ( ) . raw_value ( ) ,
583
- memory_size : region. len ( ) ,
584
- userspace_addr : host_addr as u64 ,
585
- flags : 0 ,
586
- } ;
587
- // Safe because we mapped the memory region, we made sure that the regions
588
- // are not overlapping.
589
- unsafe {
590
- self . fd
591
- . set_user_memory_region ( memory_region)
592
- . map_err ( Error :: SetUserMemoryRegion ) ?;
593
- } ;
594
- } ;
595
- self . next_mem_slot += 1 ;
522
+ for region in guest_mem. iter ( ) {
523
+ self . memory_region_set ( guest_mem, region) ?;
596
524
}
597
525
598
526
#[ cfg( target_arch = "x86_64" ) ]
@@ -603,6 +531,76 @@ impl Vm {
603
531
Ok ( ( ) )
604
532
}
605
533
534
+ fn memory_region_set (
535
+ & mut self ,
536
+ guest_mem : & GuestMemoryMmap ,
537
+ region : & GuestRegionMmap ,
538
+ ) -> Result < ( ) > {
539
+ let host_addr = guest_mem. get_host_address ( region. start_addr ( ) ) . unwrap ( ) ;
540
+ if !self . fd . check_extension ( GuestMemfd ) {
541
+ let memory_region = kvm_userspace_memory_region {
542
+ slot : self . next_mem_slot ,
543
+ guest_phys_addr : region. start_addr ( ) . raw_value ( ) ,
544
+ memory_size : region. len ( ) ,
545
+ userspace_addr : host_addr as u64 ,
546
+ flags : 0 ,
547
+ } ;
548
+
549
+ // Safe because we mapped the memory region, we made sure that the regions
550
+ // are not overlapping.
551
+ unsafe {
552
+ self . fd
553
+ . set_user_memory_region ( memory_region)
554
+ . map_err ( Error :: SetUserMemoryRegion ) ?;
555
+ } ;
556
+ } else {
557
+ // Create a guest_memfd and set the region.
558
+ let guest_memfd = self
559
+ . fd
560
+ . create_guest_memfd ( kvm_create_guest_memfd {
561
+ size : region. size ( ) as u64 ,
562
+ flags : 0 ,
563
+ reserved : [ 0 ; 6 ] ,
564
+ } )
565
+ . map_err ( Error :: CreateGuestMemfd ) ?;
566
+
567
+ let memory_region = kvm_userspace_memory_region2 {
568
+ slot : self . next_mem_slot ,
569
+ flags : KVM_MEM_GUEST_MEMFD ,
570
+ guest_phys_addr : region. start_addr ( ) . raw_value ( ) ,
571
+ memory_size : region. len ( ) ,
572
+ userspace_addr : host_addr as u64 ,
573
+ guest_memfd_offset : 0 ,
574
+ guest_memfd : guest_memfd as u32 ,
575
+ pad1 : 0 ,
576
+ pad2 : [ 0 ; 14 ] ,
577
+ } ;
578
+
579
+ // Safe because we mapped the memory region, we made sure that the regions
580
+ // are not overlapping.
581
+ unsafe {
582
+ self . fd
583
+ . set_user_memory_region2 ( memory_region)
584
+ . map_err ( Error :: SetUserMemoryRegion ) ?;
585
+ } ;
586
+
587
+ let attr = kvm_memory_attributes {
588
+ address : region. start_addr ( ) . raw_value ( ) ,
589
+ size : region. len ( ) ,
590
+ attributes : KVM_MEMORY_ATTRIBUTE_PRIVATE as u64 ,
591
+ flags : 0 ,
592
+ } ;
593
+
594
+ self . fd
595
+ . set_memory_attributes ( attr)
596
+ . map_err ( Error :: SetMemoryAttributes ) ?;
597
+ }
598
+
599
+ self . next_mem_slot += 1 ;
600
+
601
+ Ok ( ( ) )
602
+ }
603
+
606
604
#[ cfg( feature = "amd-sev" ) ]
607
605
pub fn snp_secure_virt_prepare (
608
606
& self ,
0 commit comments