Skip to content

Commit 5f5edb2

Browse files
sandreimandreeaflorescu
authored andcommitted
vcpu: Add wrapper for KVM_GET_ONE_REG.
- add ioctl definition in kvm_ioctls.rs - implement vcpu.get_one_reg() Signed-off-by: Andrei Sandu <[email protected]>
1 parent c0ccfce commit 5f5edb2

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

src/ioctls/vcpu.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,30 @@ impl VcpuFd {
972972
Ok(())
973973
}
974974

975+
/// Returns the value of the specified vCPU register.
976+
///
977+
/// The id of the register is encoded as specified in the kernel documentation
978+
/// for `KVM_GET_ONE_REG`.
979+
///
980+
/// # Arguments
981+
///
982+
/// * `reg_id` - ID of the register.
983+
///
984+
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
985+
pub fn get_one_reg(&self, reg_id: u64) -> Result<u64> {
986+
let mut reg_value = 0;
987+
let mut onereg = kvm_one_reg {
988+
id: reg_id,
989+
addr: &mut reg_value as *mut u64 as u64,
990+
};
991+
992+
let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_ONE_REG(), &mut onereg) };
993+
if ret < 0 {
994+
return Err(io::Error::last_os_error());
995+
}
996+
Ok(reg_value)
997+
}
998+
975999
/// Triggers the running of the current virtual CPU returning an exit reason.
9761000
///
9771001
/// See documentation for `KVM_RUN`.
@@ -1623,6 +1647,39 @@ mod tests {
16231647
.expect("Failed to set pstate register");
16241648
}
16251649

1650+
#[test]
1651+
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
1652+
fn test_get_one_reg() {
1653+
let kvm = Kvm::new().unwrap();
1654+
let vm = kvm.create_vm().unwrap();
1655+
let vcpu = vm.create_vcpu(0).unwrap();
1656+
1657+
let mut kvi: kvm_bindings::kvm_vcpu_init = kvm_bindings::kvm_vcpu_init::default();
1658+
vm.get_preferred_target(&mut kvi)
1659+
.expect("Cannot get preferred target");
1660+
vcpu.vcpu_init(&kvi).expect("Cannot initialize vcpu");
1661+
1662+
// PSR (Processor State Register) bits.
1663+
// Taken from arch/arm64/include/uapi/asm/ptrace.h.
1664+
const PSR_MODE_EL1H: u64 = 0x0000_0005;
1665+
const PSR_F_BIT: u64 = 0x0000_0040;
1666+
const PSR_I_BIT: u64 = 0x0000_0080;
1667+
const PSR_A_BIT: u64 = 0x0000_0100;
1668+
const PSR_D_BIT: u64 = 0x0000_0200;
1669+
const PSTATE_FAULT_BITS_64: u64 =
1670+
(PSR_MODE_EL1H | PSR_A_BIT | PSR_F_BIT | PSR_I_BIT | PSR_D_BIT);
1671+
let data: u64 = PSTATE_FAULT_BITS_64;
1672+
const PSTATE_REG_ID: u64 = 0x6030_0000_0010_0042;
1673+
vcpu.set_one_reg(PSTATE_REG_ID, data)
1674+
.expect("Failed to set pstate register");
1675+
1676+
assert_eq!(
1677+
vcpu.get_one_reg(PSTATE_REG_ID)
1678+
.expect("Failed to get pstate register"),
1679+
PSTATE_FAULT_BITS_64
1680+
);
1681+
}
1682+
16261683
#[test]
16271684
fn set_kvm_immediate_exit() {
16281685
let kvm = Kvm::new().unwrap();

src/kvm_ioctls.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ ioctl_iow_nr!(KVM_ENABLE_CAP, KVMIO, 0xa3, kvm_enable_cap);
187187
ioctl_iow_nr!(KVM_SIGNAL_MSI, KVMIO, 0xa5, kvm_msi);
188188
/* Available with KVM_CAP_ONE_REG */
189189
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
190+
ioctl_iow_nr!(KVM_GET_ONE_REG, KVMIO, 0xab, kvm_one_reg);
191+
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
190192
ioctl_iow_nr!(KVM_SET_ONE_REG, KVMIO, 0xac, kvm_one_reg);
191193
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
192194
ioctl_iow_nr!(KVM_ARM_VCPU_INIT, KVMIO, 0xae, kvm_vcpu_init);

0 commit comments

Comments
 (0)