|
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_ioctls::VmFd; |
| 15 | +use kvm_bindings::kvm_create_guest_memfd; |
| 16 | +use kvm_ioctls::{Cap, VmFd}; |
15 | 17 | use userfaultfd::{FeatureFlags, Uffd, UffdBuilder};
|
16 | 18 | use vmm_sys_util::eventfd::EventFd;
|
17 | 19 |
|
| 20 | +use crate::arch::host_page_size; |
18 | 21 | pub use crate::arch::{ArchVm as Vm, ArchVmError, VmState};
|
19 | 22 | use crate::logger::info;
|
20 | 23 | use crate::persist::{CreateSnapshotError, GuestRegionUffdMapping};
|
@@ -58,6 +61,10 @@ pub enum VmError {
|
58 | 61 | NotEnoughMemorySlots,
|
59 | 62 | /// Memory Error: {0}
|
60 | 63 | VmMemory(#[from] vm_memory::Error),
|
| 64 | + /// Failure to create guest_memfd: {0} |
| 65 | + GuestMemfd(kvm_ioctls::Error), |
| 66 | + /// guest_memfd is not supported on this host kernel. |
| 67 | + GuestMemfdNotSupported, |
61 | 68 | }
|
62 | 69 |
|
63 | 70 | /// Contains Vm functions that are usable across CPU architectures
|
@@ -128,6 +135,32 @@ impl Vm {
|
128 | 135 | Ok((vcpus, exit_evt))
|
129 | 136 | }
|
130 | 137 |
|
| 138 | + /// Create a guest_memfd of the specified size |
| 139 | + pub fn create_guest_memfd(&self, size: usize, flags: u64) -> Result<File, VmError> { |
| 140 | + assert_eq!( |
| 141 | + size & (host_page_size() - 1), |
| 142 | + 0, |
| 143 | + "guest_memfd size must be page aligned" |
| 144 | + ); |
| 145 | + |
| 146 | + if !self.fd().check_extension(Cap::GuestMemfd) { |
| 147 | + return Err(VmError::GuestMemfdNotSupported); |
| 148 | + } |
| 149 | + |
| 150 | + let kvm_gmem = kvm_create_guest_memfd { |
| 151 | + size: size as u64, |
| 152 | + flags, |
| 153 | + ..Default::default() |
| 154 | + }; |
| 155 | + |
| 156 | + self.fd() |
| 157 | + .create_guest_memfd(kvm_gmem) |
| 158 | + .map_err(VmError::GuestMemfd) |
| 159 | + // SAFETY: We know rawfd is a valid fd because create_guest_memfd didn't return an |
| 160 | + // error. |
| 161 | + .map(|rawfd| unsafe { File::from_raw_fd(rawfd) }) |
| 162 | + } |
| 163 | + |
131 | 164 | /// Register a list of new memory regions to this [`Vm`].
|
132 | 165 | pub fn register_memory_regions(
|
133 | 166 | &mut self,
|
|
0 commit comments