@@ -11,6 +11,7 @@ use std::cell::Cell;
11
11
use std:: fmt:: { Display , Formatter } ;
12
12
use std:: io;
13
13
use std:: os:: fd:: RawFd ;
14
+ use std:: cmp:: max;
14
15
15
16
#[ cfg( feature = "tee" ) ]
16
17
use std:: os:: unix:: io:: RawFd ;
@@ -48,8 +49,9 @@ use kvm_bindings::{
48
49
KVM_MAX_CPUID_ENTRIES , KVM_PIT_SPEAKER_DUMMY ,
49
50
} ;
50
51
use kvm_bindings:: {
51
- kvm_create_guest_memfd, kvm_userspace_memory_region, kvm_userspace_memory_region2,
52
- KVM_API_VERSION , KVM_MEM_GUEST_MEMFD ,
52
+ kvm_create_guest_memfd, kvm_userspace_memory_region, kvm_userspace_memory_region2, kvm_memory_attributes,
53
+ KVM_API_VERSION , KVM_MEM_GUEST_MEMFD , KVM_VM_TYPE_ARM_REALM , KVM_VM_TYPE_ARM_IPA_SIZE_MASK ,
54
+ KVM_MEMORY_ATTRIBUTE_PRIVATE
53
55
} ;
54
56
use kvm_ioctls:: * ;
55
57
use utils:: eventfd:: EventFd ;
@@ -65,6 +67,9 @@ use sev::launch::sev as sev_launch;
65
67
#[ cfg( feature = "amd-sev" ) ]
66
68
use sev:: launch:: snp;
67
69
70
+ #[ cfg( feature = "cca" ) ]
71
+ use cca:: Realm ;
72
+
68
73
/// Signal number (SIGRTMIN) used to kick Vcpus.
69
74
pub ( crate ) const VCPU_RTSIG_OFFSET : i32 = 0 ;
70
75
@@ -483,11 +488,14 @@ pub struct Vm {
483
488
484
489
#[ cfg( feature = "amd-sev" ) ]
485
490
pub tee : Tee ,
491
+
492
+ #[ cfg( feature = "cca" ) ]
493
+ pub realm : Realm ,
486
494
}
487
495
488
496
impl Vm {
489
497
/// Constructs a new `Vm` using the given `Kvm` instance.
490
- #[ cfg( not( feature = "tee" ) ) ]
498
+ #[ cfg( all ( not( feature = "tee" ) , not ( feature = "cca" ) ) ) ]
491
499
pub fn new ( kvm : & Kvm ) -> Result < Self > {
492
500
//create fd for interacting with kvm-vm specific functions
493
501
let vm_fd = kvm. create_vm ( ) . map_err ( Error :: VmFd ) ?;
@@ -511,6 +519,22 @@ impl Vm {
511
519
} )
512
520
}
513
521
522
+ #[ cfg( feature = "cca" ) ]
523
+ pub fn new ( kvm : & Kvm , max_ipa : usize ) -> Result < Self > {
524
+ //create fd for interacting with kvm-vm specific functions
525
+ let ipa_bits = max ( 64u32 - max_ipa. leading_zeros ( ) - 1 , 32 ) + 1 ;
526
+ let vm_fd = kvm. create_vm_with_type ( ( KVM_VM_TYPE_ARM_REALM | ( ipa_bits & KVM_VM_TYPE_ARM_IPA_SIZE_MASK ) ) . into ( ) ) . map_err ( Error :: VmFd ) ?;
527
+
528
+ let realm = Realm :: new ( ) . unwrap ( ) ;
529
+
530
+ Ok ( Vm {
531
+ fd : vm_fd,
532
+ #[ cfg( target_arch = "aarch64" ) ]
533
+ irqchip_handle : None ,
534
+ realm,
535
+ } )
536
+ }
537
+
514
538
#[ cfg( feature = "amd-sev" ) ]
515
539
pub fn new ( kvm : & Kvm , tee_config : & TeeConfig ) -> Result < Self > {
516
540
//create fd for interacting with kvm-vm specific functions
@@ -581,7 +605,7 @@ impl Vm {
581
605
. create_guest_memfd ( gmem)
582
606
. map_err ( Error :: CreateGuestMemfd ) ?;
583
607
584
- let memory_region = kvm_userspace_memory_region2 {
608
+ let memory_region: kvm_userspace_memory_region2 = kvm_userspace_memory_region2 {
585
609
slot : index as u32 ,
586
610
flags : KVM_MEM_GUEST_MEMFD ,
587
611
guest_phys_addr : region. start_addr ( ) . raw_value ( ) ,
@@ -600,6 +624,14 @@ impl Vm {
600
624
. set_user_memory_region2 ( memory_region)
601
625
. map_err ( Error :: SetUserMemoryRegion2 ) ?;
602
626
} ;
627
+ // set private by default when using guestmemfd
628
+ let attr = kvm_memory_attributes {
629
+ address : region. start_addr ( ) . raw_value ( ) ,
630
+ size : region. len ( ) ,
631
+ attributes : KVM_MEMORY_ATTRIBUTE_PRIVATE as u64 ,
632
+ flags : 0 ,
633
+ } ;
634
+ self . fd . set_memory_attributes ( attr) . unwrap ( ) ;
603
635
} else {
604
636
let memory_region = kvm_userspace_memory_region {
605
637
slot : index as u32 ,
@@ -808,7 +840,7 @@ type VcpuCell = Cell<Option<*mut Vcpu>>;
808
840
809
841
/// A wrapper around creating and using a kvm-based VCPU.
810
842
pub struct Vcpu {
811
- fd : VcpuFd ,
843
+ pub fd : VcpuFd ,
812
844
id : u8 ,
813
845
mmio_bus : Option < devices:: Bus > ,
814
846
#[ allow( dead_code) ]
@@ -1267,6 +1299,12 @@ impl Vcpu {
1267
1299
info ! ( "Received KVM_EXIT_SHUTDOWN signal" ) ;
1268
1300
Ok ( VcpuEmulation :: Stopped )
1269
1301
}
1302
+ VcpuExit :: MemoryFault { flags, gpa, size} => {
1303
+ println ! ( "ignore memoryfault at {} {}" , gpa, size) ;
1304
+ // TODO: To setup the setmemoryproperties I need to have access to vm
1305
+ // but vm is not a shared resource
1306
+ Ok ( VcpuEmulation :: Handled )
1307
+ }
1270
1308
// Documentation specifies that below kvm exits are considered
1271
1309
// errors.
1272
1310
VcpuExit :: FailEntry ( reason, vcpu) => {
@@ -1280,6 +1318,7 @@ impl Vcpu {
1280
1318
r => {
1281
1319
// TODO: Are we sure we want to finish running a vcpu upon
1282
1320
// receiving a vm exit that is not necessarily an error?
1321
+ println ! ( "error! {:?}" , r) ;
1283
1322
error ! ( "Unexpected exit reason on vcpu run: {:?}" , r) ;
1284
1323
Err ( Error :: VcpuUnhandledKvmExit )
1285
1324
}
0 commit comments