@@ -1324,6 +1324,81 @@ impl VmFd {
1324
1324
// and we know where it will write it (op.error).
1325
1325
unsafe { self . encrypt_op ( op) }
1326
1326
}
1327
+
1328
+ /// Register a guest memory region which may contain encrypted data.
1329
+ ///
1330
+ /// It is used in the SEV-enabled guest.
1331
+ ///
1332
+ /// See the documentation for `KVM_MEMORY_ENCRYPT_REG_REGION` in the
1333
+ /// [KVM API doc](https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt).
1334
+ ///
1335
+ /// # Arguments
1336
+ ///
1337
+ /// * `memory_region` - Guest physical memory region.
1338
+ ///
1339
+ /// # Example
1340
+ #[ cfg_attr( has_sev, doc = "```rust" ) ]
1341
+ #[ cfg_attr( not( has_sev) , doc = "```rust,no_run" ) ]
1342
+ /// # extern crate kvm_bindings;
1343
+ /// # extern crate kvm_ioctls;
1344
+ /// # extern crate libc;
1345
+ /// # use std::{fs::OpenOptions, ptr::null_mut};
1346
+ /// # use std::os::unix::io::AsRawFd;
1347
+ /// use kvm_bindings::bindings::{kvm_enc_region, kvm_sev_cmd, kvm_sev_launch_start, sev_cmd_id_KVM_SEV_LAUNCH_START};
1348
+ /// # use kvm_ioctls::Kvm;
1349
+ /// use libc;
1350
+ ///
1351
+ /// let kvm = Kvm::new().unwrap();
1352
+ /// let vm = kvm.create_vm().unwrap();
1353
+ /// let sev = OpenOptions::new()
1354
+ /// .read(true)
1355
+ /// .write(true)
1356
+ /// .open("/dev/sev")
1357
+ /// .unwrap();
1358
+ ///
1359
+ /// // Initialize the SEV platform context.
1360
+ /// let mut init: kvm_sev_cmd = Default::default();
1361
+ /// assert!(vm.encrypt_op_sev(&mut init).is_ok());
1362
+ ///
1363
+ /// // Create the memory encryption context.
1364
+ /// let start_data: kvm_sev_launch_start = Default::default();
1365
+ /// let mut start = kvm_sev_cmd {
1366
+ /// id: sev_cmd_id_KVM_SEV_LAUNCH_START,
1367
+ /// data: &start_data as *const kvm_sev_launch_start as _,
1368
+ /// sev_fd: sev.as_raw_fd() as _,
1369
+ /// ..Default::default()
1370
+ /// };
1371
+ /// assert!(vm.encrypt_op_sev(&mut start).is_ok());
1372
+ ///
1373
+ /// let addr = unsafe {
1374
+ /// libc::mmap(
1375
+ /// null_mut(),
1376
+ /// 4096,
1377
+ /// libc::PROT_READ | libc::PROT_WRITE,
1378
+ /// libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
1379
+ /// -1,
1380
+ /// 0,
1381
+ /// )
1382
+ /// };
1383
+ /// assert_ne!(addr, libc::MAP_FAILED);
1384
+ ///
1385
+ /// let memory_region = kvm_enc_region {
1386
+ /// addr: addr as _,
1387
+ /// size: 4096,
1388
+ /// };
1389
+ /// vm.register_enc_memory_region(&memory_region).unwrap();
1390
+ /// ```
1391
+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
1392
+ pub fn register_enc_memory_region ( & self , memory_region : & kvm_enc_region ) -> Result < ( ) > {
1393
+ // Safe because we know that our file is a VM fd, we know the kernel will only read the
1394
+ // correct amount of memory from our pointer, and we verify the return result.
1395
+ let ret = unsafe { ioctl_with_ref ( self , KVM_MEMORY_ENCRYPT_REG_REGION ( ) , memory_region) } ;
1396
+ if ret == 0 {
1397
+ Ok ( ( ) )
1398
+ } else {
1399
+ Err ( errno:: Error :: last ( ) )
1400
+ }
1401
+ }
1327
1402
}
1328
1403
1329
1404
/// Helper function to create a new `VmFd`.
0 commit comments