Skip to content

Commit

Permalink
Add support for KVM_SET_IDENTITY_MAP_ADDR
Browse files Browse the repository at this point in the history
Adding a missing ioctl to the list of supported ioctls. It is useful
to define the address of a one-page region that is needed on Intel
hardware because of a quirk in the virtualization implementation.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
  • Loading branch information
Sebastien Boeuf committed Dec 3, 2021
1 parent 0ba3f5d commit d22ef1f
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
2 changes: 1 addition & 1 deletion coverage_config_x86_64.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"coverage_score": 87.7,
"coverage_score": 87.9,
"exclude_path": "",
"crate_features": ""
}
41 changes: 41 additions & 0 deletions src/ioctls/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,34 @@ impl VmFd {
}
}

/// Sets the address of the one-page region in the VM's address space.
///
/// See the documentation for `KVM_SET_IDENTITY_MAP_ADDR`.
///
/// # Arguments
///
/// * `address` - Physical address of a one-page region in the guest's physical address space.
///
/// # Example
///
/// ```rust
/// # extern crate kvm_ioctls;
/// # use kvm_ioctls::Kvm;
/// let kvm = Kvm::new().unwrap();
/// let vm = kvm.create_vm().unwrap();
/// vm.set_identity_map_address(0xfffb_c000).unwrap();
/// ```
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub fn set_identity_map_address(&self, address: u64) -> Result<()> {
// Safe because we know that our file is a VM fd and we verify the return result.
let ret = unsafe { ioctl_with_ref(self, KVM_SET_IDENTITY_MAP_ADDR(), &address) };
if ret == 0 {
Ok(())
} else {
Err(errno::Error::last())
}
}

/// Creates an in-kernel interrupt controller.
///
/// See the documentation for `KVM_CREATE_IRQCHIP`.
Expand Down Expand Up @@ -1584,6 +1612,19 @@ mod tests {
assert!(vm.set_tss_address(0xfffb_d000).is_ok());
}

#[test]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn test_set_identity_map_address() {
let kvm = Kvm::new().unwrap();
if kvm.check_extension(Cap::SetIdentityMapAddr) {
let vm = kvm.create_vm().unwrap();
assert!(vm.set_identity_map_address(0xfffb_c000).is_ok());
vm.create_vcpu(0).unwrap();
// Setting the identity map after creating a vCPU must fail.
assert!(vm.set_identity_map_address(0xfffb_c000).is_err());
}
}

#[test]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn test_irq_chip() {
Expand Down
3 changes: 3 additions & 0 deletions src/kvm_ioctls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ ioctl_iow_nr!(
/* Available with KVM_CAP_SET_TSS_ADDR */
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
ioctl_io_nr!(KVM_SET_TSS_ADDR, KVMIO, 0x47);
/* Available with KVM_CAP_SET_IDENTITY_MAP_ADDR */
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
ioctl_iow_nr!(KVM_SET_IDENTITY_MAP_ADDR, KVMIO, 0x48, u64);
/* Available with KVM_CAP_IRQCHIP */
#[cfg(any(
target_arch = "x86",
Expand Down

0 comments on commit d22ef1f

Please sign in to comment.