|
6 | 6 | // found in the THIRD-PARTY file. |
7 | 7 |
|
8 | 8 | use std::collections::HashMap; |
9 | | -use std::fs::OpenOptions; |
| 9 | +use std::fs::{File, OpenOptions}; |
10 | 10 | use std::io::Write; |
| 11 | +use std::os::fd::FromRawFd; |
11 | 12 | use std::path::Path; |
12 | 13 | use std::sync::Arc; |
13 | 14 |
|
14 | | -use kvm_bindings::{KVM_MEM_LOG_DIRTY_PAGES, kvm_userspace_memory_region}; |
15 | | -use kvm_ioctls::VmFd; |
| 15 | +use kvm_bindings::{kvm_create_guest_memfd, kvm_userspace_memory_region, KVM_MEM_LOG_DIRTY_PAGES}; |
| 16 | +use kvm_ioctls::{Cap, VmFd}; |
16 | 17 | use vmm_sys_util::eventfd::EventFd; |
17 | 18 |
|
| 19 | +use crate::arch::host_page_size; |
18 | 20 | pub use crate::arch::{ArchVm as Vm, ArchVmError, VmState}; |
19 | 21 | use crate::logger::info; |
20 | 22 | use crate::persist::CreateSnapshotError; |
@@ -55,6 +57,10 @@ pub enum VmError { |
55 | 57 | NotEnoughMemorySlots, |
56 | 58 | /// Memory Error: {0} |
57 | 59 | VmMemory(#[from] vm_memory::Error), |
| 60 | + /// Failure to create guest_memfd: {0} |
| 61 | + GuestMemfd(kvm_ioctls::Error), |
| 62 | + /// guest_memfd is not supported on this host kernel. |
| 63 | + GuestMemfdNotSupported, |
58 | 64 | } |
59 | 65 |
|
60 | 66 | /// Contains Vm functions that are usable across CPU architectures |
@@ -124,6 +130,32 @@ impl Vm { |
124 | 130 | Ok((vcpus, exit_evt)) |
125 | 131 | } |
126 | 132 |
|
| 133 | + /// Create a guest_memfd of the specified size |
| 134 | + pub fn create_guest_memfd(&self, size: usize, flags: u64) -> Result<File, VmError> { |
| 135 | + assert_eq!( |
| 136 | + size & (host_page_size() - 1), |
| 137 | + 0, |
| 138 | + "guest_memfd size must be page aligned" |
| 139 | + ); |
| 140 | + |
| 141 | + if !self.fd().check_extension(Cap::GuestMemfd) { |
| 142 | + return Err(VmError::GuestMemfdNotSupported); |
| 143 | + } |
| 144 | + |
| 145 | + let kvm_gmem = kvm_create_guest_memfd { |
| 146 | + size: size as u64, |
| 147 | + flags, |
| 148 | + ..Default::default() |
| 149 | + }; |
| 150 | + |
| 151 | + self.fd() |
| 152 | + .create_guest_memfd(kvm_gmem) |
| 153 | + .map_err(VmError::GuestMemfd) |
| 154 | + // SAFETY: We know rawfd is a valid fd because create_guest_memfd didn't return an |
| 155 | + // error. |
| 156 | + .map(|rawfd| unsafe { File::from_raw_fd(rawfd) }) |
| 157 | + } |
| 158 | + |
127 | 159 | /// Register a list of new memory regions to this [`Vm`]. |
128 | 160 | pub fn register_memory_regions( |
129 | 161 | &mut self, |
|
0 commit comments