Skip to content

Commit b1fadea

Browse files
rbradfordjiangliu
authored andcommitted
Expose supplying a type when creating the VM
The KVM_CREATE_VM ioctl can take a parameter that is a platform and architecture specific VM type. This can be used for SEV or TDX VMs on x86_64 platforms of for conveying the IPA size on aarch64 platforms. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
1 parent 96c3d36 commit b1fadea

File tree

1 file changed

+37
-18
lines changed

1 file changed

+37
-18
lines changed

src/ioctls/system.rs

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -382,17 +382,7 @@ impl Kvm {
382382
/// ```
383383
///
384384
pub fn create_vm(&self) -> Result<VmFd> {
385-
// Safe because we know `self.kvm` is a real KVM fd as this module is the only one that
386-
// create Kvm objects.
387-
let ret = unsafe { ioctl(&self.kvm, KVM_CREATE_VM()) };
388-
if ret >= 0 {
389-
// Safe because we verify the value of ret and we are the owners of the fd.
390-
let vm_file = unsafe { File::from_raw_fd(ret) };
391-
let run_mmap_size = self.get_vcpu_mmap_size()?;
392-
Ok(new_vmfd(vm_file, run_mmap_size))
393-
} else {
394-
Err(errno::Error::last())
395-
}
385+
self.create_vm_with_type(0) // Create using default VM type
396386
}
397387

398388
/// AArch64 specific function to create a VM fd using the KVM fd with flexible IPA size.
@@ -428,15 +418,31 @@ impl Kvm {
428418
///
429419
#[cfg(any(target_arch = "aarch64"))]
430420
pub fn create_vm_with_ipa_size(&self, ipa_size: u32) -> Result<VmFd> {
421+
self.create_vm_with_type((ipa_size & KVM_VM_TYPE_ARM_IPA_SIZE_MASK).into())
422+
}
423+
424+
/// Creates a VM fd using the KVM fd of a specific type.
425+
///
426+
/// See the documentation for `KVM_CREATE_VM`.
427+
/// A call to this function will also initialize the size of the vcpu mmap area using the
428+
/// `KVM_GET_VCPU_MMAP_SIZE` ioctl.
429+
///
430+
/// * `vm_type` - Platform and architecture specific platform VM type. A value of 0 is the equivalent
431+
/// to using the default VM type.
432+
/// # Example
433+
///
434+
/// ```
435+
/// # use kvm_ioctls::Kvm;
436+
/// let kvm = Kvm::new().unwrap();
437+
/// let vm = kvm.create_vm_with_type(0).unwrap();
438+
/// // Check that the VM mmap size is the same reported by `KVM_GET_VCPU_MMAP_SIZE`.
439+
/// assert!(vm.run_size() == kvm.get_vcpu_mmap_size().unwrap());
440+
/// ```
441+
///
442+
pub fn create_vm_with_type(&self, vm_type: u64) -> Result<VmFd> {
431443
// Safe because we know `self.kvm` is a real KVM fd as this module is the only one that
432444
// create Kvm objects.
433-
let ret = unsafe {
434-
ioctl_with_val(
435-
&self.kvm,
436-
KVM_CREATE_VM(),
437-
(ipa_size & KVM_VM_TYPE_ARM_IPA_SIZE_MASK).into(),
438-
)
439-
};
445+
let ret = unsafe { ioctl_with_val(&self.kvm, KVM_CREATE_VM(), vm_type) };
440446
if ret >= 0 {
441447
// Safe because we verify the value of ret and we are the owners of the fd.
442448
let vm_file = unsafe { File::from_raw_fd(ret) };
@@ -596,6 +602,19 @@ mod tests {
596602
assert_eq!(vm.run_size(), kvm.get_vcpu_mmap_size().unwrap());
597603
}
598604

605+
#[test]
606+
fn test_create_vm_with_type() {
607+
let kvm = Kvm::new().unwrap();
608+
let vm = kvm.create_vm_with_type(0).unwrap();
609+
610+
// Test create_vmfd_from_rawfd()
611+
let rawfd = unsafe { libc::dup(vm.as_raw_fd()) };
612+
assert!(rawfd >= 0);
613+
let vm = unsafe { kvm.create_vmfd_from_rawfd(rawfd).unwrap() };
614+
615+
assert_eq!(vm.run_size(), kvm.get_vcpu_mmap_size().unwrap());
616+
}
617+
599618
#[test]
600619
#[cfg(any(target_arch = "aarch64"))]
601620
fn test_create_vm_with_ipa_size() {

0 commit comments

Comments
 (0)