@@ -5,6 +5,8 @@ use std::collections::hash_map::Entry;
5
5
use std:: collections:: HashMap ;
6
6
use std:: convert:: TryInto ;
7
7
use std:: env;
8
+ #[ cfg( feature = "tee" ) ]
9
+ use std:: ffi:: c_void;
8
10
use std:: ffi:: CStr ;
9
11
#[ cfg( target_os = "linux" ) ]
10
12
use std:: ffi:: CString ;
@@ -20,7 +22,7 @@ use std::sync::atomic::{AtomicI32, Ordering};
20
22
use std:: sync:: LazyLock ;
21
23
use std:: sync:: Mutex ;
22
24
23
- #[ cfg( target_os = "macos" ) ]
25
+ #[ cfg( any ( target_os = "macos" , feature = "tee" ) ) ]
24
26
use crossbeam_channel:: unbounded;
25
27
#[ cfg( feature = "blk" ) ]
26
28
use devices:: virtio:: block:: ImageType ;
@@ -54,6 +56,17 @@ use vmm::vmm_config::machine_config::VmConfig;
54
56
use vmm:: vmm_config:: net:: NetworkInterfaceConfig ;
55
57
use vmm:: vmm_config:: vsock:: VsockDeviceConfig ;
56
58
59
+ #[ cfg( feature = "tee" ) ]
60
+ use kvm_bindings:: { kvm_memory_attributes, KVM_MEMORY_ATTRIBUTE_PRIVATE } ;
61
+
62
+ #[ cfg( feature = "tee" ) ]
63
+ use vm_memory:: { guest_memory:: GuestMemory , GuestAddress , GuestMemoryRegion , MemoryRegionAddress } ;
64
+
65
+ #[ cfg( feature = "tee" ) ]
66
+ use libc:: {
67
+ fallocate, madvise, EFD_SEMAPHORE , FALLOC_FL_KEEP_SIZE , FALLOC_FL_PUNCH_HOLE , MADV_DONTNEED ,
68
+ } ;
69
+
57
70
// Value returned on success. We use libc's errors otherwise.
58
71
const KRUN_SUCCESS : i32 = 0 ;
59
72
// Maximum number of arguments/environment variables we allow
@@ -1454,12 +1467,25 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
1454
1467
#[ cfg( target_os = "macos" ) ]
1455
1468
let ( sender, receiver) = unbounded ( ) ;
1456
1469
1470
+ #[ cfg( feature = "tee" ) ]
1471
+ let ( pm_sender, pm_receiver) = unbounded ( ) ;
1472
+ #[ cfg( feature = "tee" ) ]
1473
+ let pm_efd =
1474
+ EventFd :: new ( EFD_SEMAPHORE ) . expect ( "unable to create TEE memory properties eventfd" ) ;
1475
+
1457
1476
let _vmm = match vmm:: builder:: build_microvm (
1458
1477
& ctx_cfg. vmr ,
1459
1478
& mut event_manager,
1460
1479
ctx_cfg. shutdown_efd ,
1461
1480
#[ cfg( target_os = "macos" ) ]
1462
1481
sender,
1482
+ #[ cfg( feature = "tee" ) ]
1483
+ (
1484
+ pm_sender,
1485
+ pm_efd
1486
+ . try_clone ( )
1487
+ . expect ( "unable to clone TEE memory properties eventfd" ) ,
1488
+ ) ,
1463
1489
) {
1464
1490
Ok ( vmm) => vmm,
1465
1491
Err ( e) => {
@@ -1468,7 +1494,7 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
1468
1494
}
1469
1495
} ;
1470
1496
1471
- #[ cfg( target_os = "macos" ) ]
1497
+ #[ cfg( any ( target_os = "macos" , feature = "tee" ) ) ]
1472
1498
let mapper_vmm = _vmm. clone ( ) ;
1473
1499
1474
1500
#[ cfg( target_os = "macos" ) ]
@@ -1491,6 +1517,93 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
1491
1517
. unwrap ( ) ;
1492
1518
}
1493
1519
1520
+ #[ cfg( feature = "tee" ) ]
1521
+ let guest_mem = _vmm. lock ( ) . unwrap ( ) . guest_memory ( ) . clone ( ) ;
1522
+
1523
+ #[ cfg( feature = "tee" ) ]
1524
+ std:: thread:: Builder :: new ( )
1525
+ . name ( "TEE memory properties worker" . into ( ) )
1526
+ . spawn ( move || loop {
1527
+ match pm_receiver. recv ( ) {
1528
+ Err ( e) => error ! ( "Error in pm receiver: {:?}" , e) ,
1529
+ Ok ( m) => {
1530
+ let ( guest_memfd, region_start) = mapper_vmm
1531
+ . lock ( )
1532
+ . unwrap ( )
1533
+ . kvm_vm ( )
1534
+ . guest_memfd_get ( m. gpa )
1535
+ . unwrap_or_else ( || panic ! ( "unable to find KVM guest_memfd for memory region corresponding to GPA 0x{:x}" , m. gpa) ) ;
1536
+
1537
+ let attributes: u64 = if m. private {
1538
+ KVM_MEMORY_ATTRIBUTE_PRIVATE as u64
1539
+ } else {
1540
+ 0
1541
+ } ;
1542
+
1543
+ let attr = kvm_memory_attributes {
1544
+ address : m. gpa ,
1545
+ size : m. size ,
1546
+ attributes,
1547
+ flags : 0 ,
1548
+ } ;
1549
+
1550
+ mapper_vmm
1551
+ . lock ( )
1552
+ . unwrap ( )
1553
+ . kvm_vm ( )
1554
+ . fd ( )
1555
+ . set_memory_attributes ( attr)
1556
+ . unwrap_or_else ( |_| panic ! ( "unable to set memory attributes for memory region corresponding to guest address 0x{:x}" , m. gpa) ) ;
1557
+
1558
+ let region = guest_mem. find_region ( GuestAddress ( m. gpa ) ) ;
1559
+ if region. is_none ( ) {
1560
+ error ! ( "{}" , format!( "guest memory region corresponding to GPA 0x{:x} not found" , m. gpa) ) ;
1561
+ pm_efd. write ( 1 ) . unwrap ( ) ;
1562
+ continue ;
1563
+ }
1564
+
1565
+ let offset = m. gpa - region_start;
1566
+
1567
+ if m. private {
1568
+ let region_addr = MemoryRegionAddress ( offset) ;
1569
+
1570
+ let host_startaddr = region
1571
+ . unwrap ( )
1572
+ . get_host_address ( region_addr)
1573
+ . expect ( "host address corresponding to memory region address 0x{:x} not found" ) ;
1574
+
1575
+ let ret = unsafe {
1576
+ madvise (
1577
+ host_startaddr as * mut c_void ,
1578
+ m. size . try_into ( ) . unwrap ( ) ,
1579
+ MADV_DONTNEED ,
1580
+ )
1581
+ } ;
1582
+
1583
+ if ret < 0 {
1584
+ error ! ( "{}" , format!( "unable to advise kernel that memory region corresponding to GPA 0x{:x} will likely not be needed (madvise)" , m. gpa) ) ;
1585
+ }
1586
+ } else {
1587
+ let ret = unsafe {
1588
+ fallocate (
1589
+ guest_memfd,
1590
+ FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE ,
1591
+ offset as i64 ,
1592
+ m. size as i64 ,
1593
+ )
1594
+ } ;
1595
+
1596
+ if ret < 0 {
1597
+ error ! ( "{}" , format!( "unable to allocate space in guest_memfd for shared memory (fallocate)" ) ) ;
1598
+ }
1599
+ }
1600
+
1601
+ pm_efd. write ( 1 ) . unwrap ( ) ;
1602
+ }
1603
+ }
1604
+ } )
1605
+ . unwrap ( ) ;
1606
+
1494
1607
loop {
1495
1608
match event_manager. run ( ) {
1496
1609
Ok ( _) => { }
0 commit comments