Skip to content

Commit

Permalink
Add kvm guest memfd related capabilities
Browse files Browse the repository at this point in the history
The capabilities are required to properly setup a guest_memfd to provide better
host and guest memory isolation. The memory attributes capability returns an
integer with each bits representing different configs. For example, the return
integer & KVM_MEMORY_ATTRIBUTE_PRIVATE > 0 means the vm is capable of setting
memory pages to private.

Signed-off-by: Sida Chen <[email protected]>
  • Loading branch information
KeyboardNerd committed Jan 2, 2025
1 parent ade910b commit 4809bf7
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 4 deletions.
2 changes: 2 additions & 0 deletions kvm-ioctls/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
- [[#273](https://github.com/rust-vmm/kvm-ioctls/pull/273)]: `DeviceFd::get_device_attr` is now
marked as unsafe.
- [[#277](https://github.com/rust-vmm/kvm-ioctls/pull/277)]: Updated kvm-bindings to 0.9.1.
- [[#288](https://github.com/rust-vmm/kvm-ioctls/pull/288)]: Add kvm guest memfd related
capabilities.

## v0.18.0

Expand Down
63 changes: 59 additions & 4 deletions kvm-ioctls/src/ioctls/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1402,10 +1402,51 @@ impl VmFd {
/// Wrapper over `KVM_CHECK_EXTENSION`.
///
/// Returns 0 if the capability is not available and a positive integer otherwise.
fn check_extension_int(&self, c: Cap) -> i32 {
// SAFETY: Safe because we know that our file is a VM fd and that the extension is one of
// the ones defined by kernel.
unsafe { ioctl_with_val(self, KVM_CHECK_EXTENSION(), c as c_ulong) }
/// See the documentation for `KVM_CHECK_EXTENSION`.
///
/// # Arguments
///
/// * `c` - KVM capability to check.
///
/// # Example
///
/// ```
/// # use kvm_bindings::{KVM_MEMORY_ATTRIBUTE_PRIVATE};
/// # use kvm_ioctls::Kvm;
/// use kvm_ioctls::Cap;
///
/// let kvm = Kvm::new().unwrap();
/// let vm = kvm.create_vm().unwrap();
/// assert!(vm.check_extension_int(Cap::MaxVcpus) > 0);
/// ```
pub fn check_extension_int(&self, c: Cap) -> i32 {
self.check_extension_raw(c as c_ulong)
}

/// Wrapper over `KVM_CHECK_EXTENSION`.
///
/// Returns 0 if the capability is not available and a positive integer otherwise.
/// See the documentation for `KVM_CHECK_EXTENSION`.
///
/// # Arguments
///
/// * `c` - KVM capability to check in a form of a raw integer.
///
/// # Example
///
/// ```
/// # use kvm_ioctls::Kvm;
/// # use std::os::raw::c_ulong;
/// use kvm_ioctls::Cap;
///
/// let kvm = Kvm::new().unwrap();
/// let vm = kvm.create_vm().unwrap();
/// assert!(vm.check_extension_raw(Cap::MaxVcpus as c_ulong) > 0);
/// ```
pub fn check_extension_raw(&self, c: c_ulong) -> i32 {
// SAFETY: Safe because we know that our file is a KVM fd.
// If `c` is not a known kernel extension, kernel will return 0.
unsafe { ioctl_with_val(self, KVM_CHECK_EXTENSION(), c) }
}

/// Checks if a particular `Cap` is available.
Expand Down Expand Up @@ -2669,6 +2710,20 @@ mod tests {
assert!(vm.check_extension(Cap::MpState));
}

#[test]
fn test_check_extension_raw() {
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
assert!(vm.check_extension_raw(Cap::MpState as c_ulong) > 0);
}

#[test]
fn test_check_extension_raw() {
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
assert!(vm.check_extension_raw(Cap::MpState as c_ulong) > 0);
}

#[test]
#[cfg(target_arch = "x86_64")]
#[cfg_attr(not(has_sev), ignore)]
Expand Down

0 comments on commit 4809bf7

Please sign in to comment.