@@ -13,6 +13,12 @@ use std::io;
1313
1414use std:: os:: unix:: io:: RawFd ;
1515
16+ #[ cfg( feature = "tee" ) ]
17+ use kvm_ioctls:: VcpuExit :: Unsupported ;
18+
19+ use std:: sync:: Arc ;
20+ use std:: sync:: Mutex ;
21+
1622use std:: result;
1723use std:: sync:: atomic:: { fence, Ordering } ;
1824#[ cfg( not( test) ) ]
@@ -39,18 +45,18 @@ use kvm_bindings::{
3945 KVM_CLOCK_TSC_STABLE , KVM_IRQCHIP_IOAPIC , KVM_IRQCHIP_PIC_MASTER , KVM_IRQCHIP_PIC_SLAVE ,
4046 KVM_MAX_CPUID_ENTRIES ,
4147} ;
42- use kvm_bindings:: {
43- kvm_userspace_memory_region, KVM_API_VERSION , KVM_SYSTEM_EVENT_RESET , KVM_SYSTEM_EVENT_SHUTDOWN ,
44- } ;
4548#[ cfg( feature = "tee" ) ]
4649use kvm_bindings:: {
47- kvm_create_guest_memfd, kvm_memory_attributes, kvm_userspace_memory_region ,
48- kvm_userspace_memory_region2 , KVM_API_VERSION , KVM_MEMORY_ATTRIBUTE_PRIVATE ,
50+ kvm_create_guest_memfd, kvm_memory_attributes, kvm_userspace_memory_region2 , KVM_API_VERSION ,
51+ KVM_EXIT_MEMORY_FAULT , KVM_MEMORY_ATTRIBUTE_PRIVATE , KVM_MEMORY_EXIT_FLAG_PRIVATE ,
4952 KVM_MEM_GUEST_MEMFD ,
5053} ;
51- #[ cfg( feature = "tee" ) ]
52- use kvm_bindings:: { kvm_enable_cap, KVM_CAP_EXIT_HYPERCALL } ;
53- use kvm_ioctls:: { Cap :: * , * } ;
54+ #[ cfg( not( feature = "tee" ) ) ]
55+ use kvm_bindings:: { kvm_userspace_memory_region, KVM_API_VERSION } ;
56+ use kvm_bindings:: {
57+ kvm_userspace_memory_region, KVM_API_VERSION , KVM_SYSTEM_EVENT_RESET , KVM_SYSTEM_EVENT_SHUTDOWN ,
58+ } ;
59+ use kvm_ioctls:: * ;
5460use utils:: eventfd:: EventFd ;
5561use utils:: signal:: { register_signal_handler, sigrtmin, Killable } ;
5662use utils:: sm:: StateMachine ;
@@ -775,6 +781,13 @@ pub struct VcpuConfig {
775781 pub cpu_template : Option < CpuFeaturesTemplate > ,
776782}
777783
784+ #[ cfg( feature = "tee" ) ]
785+ pub struct MemProperties {
786+ pub addr : u64 ,
787+ pub size : u64 ,
788+ pub attributes : u32 ,
789+ }
790+
778791// Using this for easier explicit type-casting to help IDEs interpret the code.
779792type VcpuCell = Cell < Option < * mut Vcpu > > ;
780793
@@ -797,6 +810,10 @@ pub struct Vcpu {
797810 #[ cfg( target_arch = "aarch64" ) ]
798811 mpidr : u64 ,
799812
813+ // The transmitting end of the events channel which will be given to the vcpu side
814+ #[ cfg( feature = "tee" ) ]
815+ sender_io : Sender < MemProperties > ,
816+
800817 // The receiving end of events channel owned by the vcpu side.
801818 event_receiver : Receiver < VcpuEvent > ,
802819 // The transmitting end of the events channel which will be given to the handler.
@@ -944,7 +961,12 @@ impl Vcpu {
944961 /// * `exit_evt` - An `EventFd` that will be written into when this vcpu exits.
945962 /// * `create_ts` - A timestamp used by the vcpu to calculate its lifetime.
946963 #[ cfg( target_arch = "aarch64" ) ]
947- pub fn new_aarch64 ( id : u8 , vm_fd : & VmFd , exit_evt : EventFd ) -> Result < Self > {
964+ pub fn new_aarch64 (
965+ id : u8 ,
966+ vm_fd : & VmFd ,
967+ exit_evt : EventFd ,
968+ #[ cfg( feature = "tee" ) ] sender_io : Sender < MemProperties > ,
969+ ) -> Result < Self > {
948970 let kvm_vcpu = vm_fd. create_vcpu ( id as u64 ) . map_err ( Error :: VcpuFd ) ?;
949971 let ( event_sender, event_receiver) = unbounded ( ) ;
950972 let ( response_sender, response_receiver) = unbounded ( ) ;
@@ -959,6 +981,8 @@ impl Vcpu {
959981 event_sender : Some ( event_sender) ,
960982 response_receiver : Some ( response_receiver) ,
961983 response_sender,
984+ #[ cfg( feature = "tee" ) ]
985+ sender_io,
962986 } )
963987 }
964988
@@ -1270,6 +1294,38 @@ impl Vcpu {
12701294 info ! ( "Received KVM_EXIT_SHUTDOWN signal" ) ;
12711295 Ok ( VcpuEmulation :: Stopped )
12721296 }
1297+ #[ cfg( feature = "tee" ) ]
1298+ VcpuExit :: MemoryFault { flags, gpa, size } => {
1299+ if flags & !KVM_MEMORY_EXIT_FLAG_PRIVATE as u64 != 0 {
1300+ error ! ( "KVM_EXIT_MEMORY_FAULT: Unknown flag {}" , flags) ;
1301+ Err ( Error :: VcpuUnhandledKvmExit )
1302+ } else {
1303+ // from private to shared
1304+ let mut attr = 0 ;
1305+ // from shared to private
1306+ if flags & KVM_MEMORY_EXIT_FLAG_PRIVATE as u64
1307+ == KVM_MEMORY_EXIT_FLAG_PRIVATE as u64
1308+ {
1309+ attr = KVM_MEMORY_ATTRIBUTE_PRIVATE ;
1310+ } ;
1311+
1312+ let _ = self . sender_io . try_send ( MemProperties {
1313+ addr : gpa,
1314+ size,
1315+ attributes : attr,
1316+ } ) ;
1317+ Ok ( VcpuEmulation :: Handled )
1318+ }
1319+ }
1320+ // Documentation specifices that when KVM exists with KVM_EXIT_MEMORY_FAULT,
1321+ // userspace should assume kvm_run.exit_reason is stale/undefined for error numbers
1322+ // different than EFAULT or EHWPOISON
1323+ #[ cfg( feature = "tee" ) ]
1324+ Unsupported ( KVM_EXIT_MEMORY_FAULT ) => Ok ( VcpuEmulation :: Handled ) ,
1325+ VcpuExit :: InternalError => {
1326+ error ! ( "Received KVM_EXIT_INTERNAL_ERROR signal" ) ;
1327+ Err ( Error :: VcpuUnhandledKvmExit )
1328+ }
12731329 // Documentation specifies that below kvm exits are considered
12741330 // errors.
12751331 VcpuExit :: FailEntry ( reason, vcpu) => {
0 commit comments