fn state(&self) -> cpu::Result<CpuState> {
        let cpuid = self.get_cpuid2(kvm_bindings::KVM_MAX_CPUID_ENTRIES)?;
        let mp_state = self.get_mp_state()?;
        let regs = self.get_regs()?;
        let sregs = self.get_sregs()?;
        let xsave = self.get_xsave()?;
        let xcrs = self.get_xcrs()?;
        let lapic_state = self.get_lapic()?;
        let fpu = self.get_fpu()?;

        // Try to get all MSRs based on the list previously retrieved from KVM.
        // If the number of MSRs obtained from GET_MSRS is different from the
        // expected amount, we fallback onto a slower method by getting MSRs
        // by chunks. This is the only way to make sure we try to get as many
        // MSRs as possible, even if some MSRs are not supported.
        let mut msr_entries = self.msrs.clone();

        // Save extra MSRs if the Hyper-V synthetic interrupt controller is
        // emulated.
        if self.hyperv_synic.load(Ordering::Acquire) {
            let hyperv_synic_msrs = vec![
                0x40000020, 0x40000021, 0x40000080, 0x40000081, 0x40000082, 0x40000083, 0x40000084,
                0x40000090, 0x40000091, 0x40000092, 0x40000093, 0x40000094, 0x40000095, 0x40000096,
                0x40000097, 0x40000098, 0x40000099, 0x4000009a, 0x4000009b, 0x4000009c, 0x4000009d,
                0x4000009f, 0x400000b0, 0x400000b1, 0x400000b2, 0x400000b3, 0x400000b4, 0x400000b5,
                0x400000b6, 0x400000b7,
            ];
            for index in hyperv_synic_msrs {
                let msr = kvm_msr_entry {
                    index,
                    ..Default::default()
                };
                msr_entries.push(msr).unwrap();
            }
        }

        let expected_num_msrs = msr_entries.as_fam_struct_ref().nmsrs as usize;
        let num_msrs = self.get_msrs(&mut msr_entries)?;
        let msrs = if num_msrs != expected_num_msrs {
            let mut faulty_msr_index = num_msrs;
            let mut msr_entries_tmp =
                MsrEntries::from_entries(&msr_entries.as_slice()[..faulty_msr_index]);

            loop {
                warn!(
                    "Detected faulty MSR 0x{:x} while getting MSRs",
                    msr_entries.as_slice()[faulty_msr_index].index
                );

                let start_pos = faulty_msr_index + 1;
                let mut sub_msr_entries =
                    MsrEntries::from_entries(&msr_entries.as_slice()[start_pos..]);
                let expected_num_msrs = sub_msr_entries.as_fam_struct_ref().nmsrs as usize;
                let num_msrs = self.get_msrs(&mut sub_msr_entries)?;

                for i in 0..num_msrs {
                    msr_entries_tmp
                        .push(sub_msr_entries.as_slice()[i])
                        .map_err(|e| {
                            cpu::HypervisorCpuError::GetMsrEntries(anyhow!(
                                "Failed adding MSR entries: {:?}",
                                e
                            ))
                        })?;
                }

                if num_msrs == expected_num_msrs {
                    break;
                }

                faulty_msr_index = start_pos + num_msrs;
            }

            msr_entries_tmp
        } else {
            msr_entries
        };

        let vcpu_events = self.get_vcpu_events()?;

        Ok(CpuState {
            cpuid,
            msrs,
            vcpu_events,
            regs,
            sregs,
            fpu,
            lapic_state,
            xsave,
            xcrs,
            mp_state,
        })
    }
///
/// Get the current CPU state
///
/// Ordering requirements:
///
/// KVM_GET_MP_STATE calls kvm_apic_accept_events(), which might modify
/// vCPU/LAPIC state. As such, it must be done before most everything
/// else, otherwise we cannot restore everything and expect it to work.
///
/// KVM_GET_VCPU_EVENTS/KVM_SET_VCPU_EVENTS is unsafe if other vCPUs are
/// still running.
///
/// KVM_GET_LAPIC may change state of LAPIC before returning it.
///
/// GET_VCPU_EVENTS should probably be last to save. The code looks as
/// it might as well be affected by internal state modifications of the
/// GET ioctls.
///
/// SREGS saves/restores a pending interrupt, similar to what
/// VCPU_EVENTS also does.
///
/// GET_MSRS requires a pre-populated data structure to do something
/// meaningful. For SET_MSRS it will then contain good data.
///
/// # Example
///
/// ```rust
/// # extern crate hypervisor;
/// # use hypervisor::KvmHypervisor;
/// # use std::sync::Arc;
/// let kvm = hypervisor::kvm::KvmHypervisor::new().unwrap();
/// let hv: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
/// let vm = hv.create_vm().expect("new VM fd creation failed");
/// vm.enable_split_irq().unwrap();
/// let vcpu = vm.create_vcpu(0, None).unwrap();
/// let state = vcpu.state().unwrap();
/// ```
Get the current CPU state
Ordering requirements.

KVM_GET_MP_STATE calls kvm_apic_accept_events(), which might modify
vCPU/LAPIC state. As such, it must be done before most everything
else, otherwise we cannot restore everything and expect it to work.



KVM_GET_LAPIC may change state of LAPIC before returning it.

GET_VCPU_EVENTS should probably be last to save. The code looks as
it might as well be affected by internal state modifications of the
GET ioctls.

SREGS saves/restores a pending interrupt, similar to what
VCPU_EVENTS also does.

GET_MSRS requires a pre-populated data structure to do something
meaningful. For SET_MSRS it will then contain good data.
Get the current CPU state Ordering requirements . KVM_GET_MP_STATE calls kvm_apic_accept_events () which might modify vCPU / LAPIC state . As such it must be done before most everything else otherwise we cannot restore everything and expect it to work . KVM_GET_LAPIC may change state of LAPIC before returning it . GET_VCPU_EVENTS should probably be last to save . The code looks as it might as well be affected by internal state modifications of the GET ioctls . SREGS saves / restores a pending interrupt similar to what VCPU_EVENTS also does . GET_MSRS requires a pre - populated data structure to do something meaningful . For SET_MSRS it will then contain good data .
fn state(&self) -> cpu::Result<CpuState> {
        let cpuid = self.get_cpuid2(kvm_bindings::KVM_MAX_CPUID_ENTRIES)?;
        let mp_state = self.get_mp_state()?;
        let regs = self.get_regs()?;
        let sregs = self.get_sregs()?;
        let xsave = self.get_xsave()?;
        let xcrs = self.get_xcrs()?;
        let lapic_state = self.get_lapic()?;
        let fpu = self.get_fpu()?;
        // Try to get all MSRs based on the list previously retrieved from KVM.
        // If the number of MSRs obtained from GET_MSRS is different from the
        // expected amount, we fallback onto a slower method by getting MSRs
        // by chunks. This is the only way to make sure we try to get as many
        // MSRs as possible, even if some MSRs are not supported.
        let mut msr_entries = self.msrs.clone();
        // Save extra MSRs if the Hyper-V synthetic interrupt controller is
        // emulated.
        if self.hyperv_synic.load(Ordering::Acquire) {
            let hyperv_synic_msrs = vec![
                0x40000020, 0x40000021, 0x40000080, 0x40000081, 0x40000082, 0x40000083, 0x40000084,
                0x40000090, 0x40000091, 0x40000092, 0x40000093, 0x40000094, 0x40000095, 0x40000096,
                0x40000097, 0x40000098, 0x40000099, 0x4000009a, 0x4000009b, 0x4000009c, 0x4000009d,
                0x4000009f, 0x400000b0, 0x400000b1, 0x400000b2, 0x400000b3, 0x400000b4, 0x400000b5,
                0x400000b6, 0x400000b7,
            ];
            for index in hyperv_synic_msrs {
                let msr = kvm_msr_entry {
                    index,
                    ..Default::default()
                };
                msr_entries.push(msr).unwrap();
            }
        }
        let expected_num_msrs = msr_entries.as_fam_struct_ref().nmsrs as usize;
        let num_msrs = self.get_msrs(&mut msr_entries)?;
        let msrs = if num_msrs != expected_num_msrs {
            let mut faulty_msr_index = num_msrs;
            let mut msr_entries_tmp =
                MsrEntries::from_entries(&msr_entries.as_slice()[..faulty_msr_index]);
            loop {
                warn!(
                    "Detected faulty MSR 0x{:x} while getting MSRs",
                    msr_entries.as_slice()[faulty_msr_index].index
                );
                let start_pos = faulty_msr_index + 1;
                let mut sub_msr_entries =
                    MsrEntries::from_entries(&msr_entries.as_slice()[start_pos..]);
                let expected_num_msrs = sub_msr_entries.as_fam_struct_ref().nmsrs as usize;
                let num_msrs = self.get_msrs(&mut sub_msr_entries)?;
                for i in 0..num_msrs {
                    msr_entries_tmp
                        .push(sub_msr_entries.as_slice()[i])
                        .map_err(|e| {
                            cpu::HypervisorCpuError::GetMsrEntries(anyhow!(
                                "Failed adding MSR entries: {:?}",
                                e
                            ))
                        })?;
                }
                if num_msrs == expected_num_msrs {
                    break;
                }
                faulty_msr_index = start_pos + num_msrs;
            }
            msr_entries_tmp
        } else {
            msr_entries
        };
        let vcpu_events = self.get_vcpu_events()?;
        Ok(CpuState {
            cpuid,
            msrs,
            vcpu_events,
            regs,
            sregs,
            fpu,
            lapic_state,
            xsave,
            xcrs,
            mp_state,
        })
    }
fn state ( & self ) -> cpu :: Result < CpuState > { let cpuid = self . get_cpuid2 ( kvm_bindings :: KVM_MAX_CPUID_ENTRIES ) ? ; let mp_state = self . get_mp_state ( ) ? ; let regs = self . get_regs ( ) ? ; let sregs = self . get_sregs ( ) ? ; let xsave = self . get_xsave ( ) ? ; let xcrs = self . get_xcrs ( ) ? ; let lapic_state = self . get_lapic ( ) ? ; let fpu = self . get_fpu ( ) ? ; // Try to get all MSRs based on the list previously retrieved from KVM. // If the number of MSRs obtained from GET_MSRS is different from the // expected amount, we fallback onto a slower method by getting MSRs // by chunks. This is the only way to make sure we try to get as many // MSRs as possible, even if some MSRs are not supported. let mut msr_entries = self . msrs . clone ( ) ; // Save extra MSRs if the Hyper-V synthetic interrupt controller is // emulated. if self . hyperv_synic . load ( Ordering :: Acquire ) { let hyperv_synic_msrs = vec ! [ 0x40000020 0x40000021 0x40000080 0x40000081 0x40000082 0x40000083 0x40000084 0x40000090 0x40000091 0x40000092 0x40000093 0x40000094 0x40000095 0x40000096 0x40000097 0x40000098 0x40000099 0x4000009a 0x4000009b 0x4000009c 0x4000009d 0x4000009f 0x400000b0 0x400000b1 0x400000b2 0x400000b3 0x400000b4 0x400000b5 0x400000b6 0x400000b7 ] ; for index in hyperv_synic_msrs { let msr = kvm_msr_entry { index , .. Default :: default ( ) } ; msr_entries . push ( msr ) . unwrap ( ) ; } } let expected_num_msrs = msr_entries . as_fam_struct_ref ( ) . nmsrs as usize ; let num_msrs = self . get_msrs ( & mut msr_entries ) ? ; let msrs = if num_msrs != expected_num_msrs { let mut faulty_msr_index = num_msrs ; let mut msr_entries_tmp = MsrEntries :: from_entries ( & msr_entries . as_slice ( ) [ .. faulty_msr_index ] ) ; loop { warn ! ( " " msr_entries as_slice ( ) [ faulty_msr_index ] index ) ; let start_pos = faulty_msr_index + 1 ; let mut sub_msr_entries = MsrEntries :: from_entries ( & msr_entries . as_slice ( ) [ start_pos .. ] ) ; let expected_num_msrs = sub_msr_entries . as_fam_struct_ref ( ) . nmsrs as usize ; let num_msrs = self . get_msrs ( & mut sub_msr_entries ) ? ; for i in 0 .. num_msrs { msr_entries_tmp . push ( sub_msr_entries . as_slice ( ) [ i ] ) . map_err ( | e | { cpu :: HypervisorCpuError :: GetMsrEntries ( anyhow ! ( " " e ) ) } ) ? ; } if num_msrs == expected_num_msrs { break ; } faulty_msr_index = start_pos + num_msrs ; } msr_entries_tmp } else { msr_entries } ; let vcpu_events = self . get_vcpu_events ( ) ? ; Ok ( CpuState { cpuid , msrs , vcpu_events , regs , sregs , fpu , lapic_state , xsave , xcrs , mp_state , } ) }
Get the current CPU state
Ordering requirements:
Get the current CPU state Ordering requirements :
&self
&self
example
None
extern crate hypervisor;
None
use hypervisor::kvmhypervisor;
None
use std::sync::arc;
let kvm = hypervisor::kvm::KvmHypervisor::new().unwrap();
let hv: Arc = Arc::new(kvm);
let vm = hv.create_vm().expect("new VM fd creation failed");
vm.enable_split_irq().unwrap();
let vcpu = vm.create_vcpu(0, None).unwrap();
let state = vcpu.state().unwrap();
```
let kvm = hypervisor :: kvm :: KvmHypervisor :: new () . unwrap () ; let hv : Arc = Arc :: new ( kvm ) ; let vm = hv . create_vm () . expect ( " new VM fd creation failed " ) ; vm . enable_split_irq () . unwrap () ; let vcpu = vm . create_vcpu ( 0 None ) . unwrap () ; let state = vcpu . state () . unwrap () ; ` ` `