Skip to content

Commit d22ef1f

Browse files
author
Sebastien Boeuf
committed
Add support for KVM_SET_IDENTITY_MAP_ADDR
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 <[email protected]>
1 parent 0ba3f5d commit d22ef1f

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

coverage_config_x86_64.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"coverage_score": 87.7,
2+
"coverage_score": 87.9,
33
"exclude_path": "",
44
"crate_features": ""
55
}

src/ioctls/vm.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,34 @@ impl VmFd {
136136
}
137137
}
138138

139+
/// Sets the address of the one-page region in the VM's address space.
140+
///
141+
/// See the documentation for `KVM_SET_IDENTITY_MAP_ADDR`.
142+
///
143+
/// # Arguments
144+
///
145+
/// * `address` - Physical address of a one-page region in the guest's physical address space.
146+
///
147+
/// # Example
148+
///
149+
/// ```rust
150+
/// # extern crate kvm_ioctls;
151+
/// # use kvm_ioctls::Kvm;
152+
/// let kvm = Kvm::new().unwrap();
153+
/// let vm = kvm.create_vm().unwrap();
154+
/// vm.set_identity_map_address(0xfffb_c000).unwrap();
155+
/// ```
156+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
157+
pub fn set_identity_map_address(&self, address: u64) -> Result<()> {
158+
// Safe because we know that our file is a VM fd and we verify the return result.
159+
let ret = unsafe { ioctl_with_ref(self, KVM_SET_IDENTITY_MAP_ADDR(), &address) };
160+
if ret == 0 {
161+
Ok(())
162+
} else {
163+
Err(errno::Error::last())
164+
}
165+
}
166+
139167
/// Creates an in-kernel interrupt controller.
140168
///
141169
/// See the documentation for `KVM_CREATE_IRQCHIP`.
@@ -1584,6 +1612,19 @@ mod tests {
15841612
assert!(vm.set_tss_address(0xfffb_d000).is_ok());
15851613
}
15861614

1615+
#[test]
1616+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
1617+
fn test_set_identity_map_address() {
1618+
let kvm = Kvm::new().unwrap();
1619+
if kvm.check_extension(Cap::SetIdentityMapAddr) {
1620+
let vm = kvm.create_vm().unwrap();
1621+
assert!(vm.set_identity_map_address(0xfffb_c000).is_ok());
1622+
vm.create_vcpu(0).unwrap();
1623+
// Setting the identity map after creating a vCPU must fail.
1624+
assert!(vm.set_identity_map_address(0xfffb_c000).is_err());
1625+
}
1626+
}
1627+
15871628
#[test]
15881629
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
15891630
fn test_irq_chip() {

src/kvm_ioctls.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ ioctl_iow_nr!(
3636
/* Available with KVM_CAP_SET_TSS_ADDR */
3737
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3838
ioctl_io_nr!(KVM_SET_TSS_ADDR, KVMIO, 0x47);
39+
/* Available with KVM_CAP_SET_IDENTITY_MAP_ADDR */
40+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
41+
ioctl_iow_nr!(KVM_SET_IDENTITY_MAP_ADDR, KVMIO, 0x48, u64);
3942
/* Available with KVM_CAP_IRQCHIP */
4043
#[cfg(any(
4144
target_arch = "x86",

0 commit comments

Comments
 (0)