@@ -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 ( ) ;
0 commit comments