Skip to content

Commit 24610fc

Browse files
committed
add Vm::create_guest_memfd
Add a utility function for creating a guest_memfd and wrapping it into a `File` object. Signed-off-by: Patrick Roy <roypat@amazon.co.uk>
1 parent 6da974c commit 24610fc

File tree

1 file changed

+35
-3
lines changed

1 file changed

+35
-3
lines changed

src/vmm/src/vstate/vm.rs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@
66
// found in the THIRD-PARTY file.
77

88
use std::collections::HashMap;
9-
use std::fs::OpenOptions;
9+
use std::fs::{File, OpenOptions};
1010
use std::io::Write;
11+
use std::os::fd::FromRawFd;
1112
use std::path::Path;
1213
use std::sync::Arc;
1314

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};
1617
use vmm_sys_util::eventfd::EventFd;
1718

19+
use crate::arch::host_page_size;
1820
pub use crate::arch::{ArchVm as Vm, ArchVmError, VmState};
1921
use crate::logger::info;
2022
use crate::persist::CreateSnapshotError;
@@ -55,6 +57,10 @@ pub enum VmError {
5557
NotEnoughMemorySlots,
5658
/// Memory Error: {0}
5759
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,
5864
}
5965

6066
/// Contains Vm functions that are usable across CPU architectures
@@ -124,6 +130,32 @@ impl Vm {
124130
Ok((vcpus, exit_evt))
125131
}
126132

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+
127159
/// Register a list of new memory regions to this [`Vm`].
128160
pub fn register_memory_regions(
129161
&mut self,

0 commit comments

Comments
 (0)