|
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_MEM_LOG_DIRTY_PAGES, kvm_create_guest_memfd, kvm_userspace_memory_region}; |
| 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