MCPcopy Create free account
hub / github.com/cloud-hypervisor/cloud-hypervisor / state

Method state

hypervisor/src/kvm/mod.rs:2862–2955  ·  view source on GitHub ↗

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.

(&self)

Source from the content-addressed store, hash-verified

2860 /// let state = vcpu.state().unwrap();
2861 /// ```
2862 fn state(&self) -> cpu::Result<CpuState> {
2863 let cpuid = self.get_cpuid2(kvm_bindings::KVM_MAX_CPUID_ENTRIES)?;
2864 let mp_state = self.get_mp_state()?.into();
2865 let regs = self.get_regs()?;
2866 let sregs = self.get_sregs()?;
2867 let xsave = if self.xsave_size > 0 {
2868 self.get_xsave2()?
2869 } else {
2870 self.get_xsave()?
2871 };
2872 let xcrs = self.get_xcrs()?;
2873 let lapic_state = self.get_lapic()?;
2874 let fpu = self.get_fpu()?;
2875 let nested_state = self.nested_state()?;
2876
2877 // Try to get all MSRs based on the list previously retrieved from KVM.
2878 // If the number of MSRs obtained from GET_MSRS is different from the
2879 // expected amount, we fallback onto a slower method by getting MSRs
2880 // by chunks. This is the only way to make sure we try to get as many
2881 // MSRs as possible, even if some MSRs are not supported.
2882 let mut msr_entries = self.msrs.clone();
2883
2884 // Save extra MSRs if the Hyper-V synthetic interrupt controller is
2885 // emulated.
2886 let hyperv_synic = self.hyperv_synic.load(Ordering::Acquire);
2887 if hyperv_synic {
2888 let hyperv_synic_msrs = vec![
2889 0x40000020, 0x40000021, 0x40000080, 0x40000081, 0x40000082, 0x40000083, 0x40000084,
2890 0x40000090, 0x40000091, 0x40000092, 0x40000093, 0x40000094, 0x40000095, 0x40000096,
2891 0x40000097, 0x40000098, 0x40000099, 0x4000009a, 0x4000009b, 0x4000009c, 0x4000009d,
2892 0x4000009e, 0x4000009f, 0x400000b0, 0x400000b1, 0x400000b2, 0x400000b3, 0x400000b4,
2893 0x400000b5, 0x400000b6, 0x400000b7,
2894 ];
2895 for index in hyperv_synic_msrs {
2896 let msr = kvm_msr_entry {
2897 index,
2898 ..Default::default()
2899 };
2900 msr_entries.push(msr.into());
2901 }
2902 }
2903
2904 let expected_num_msrs = msr_entries.len();
2905 let num_msrs = self.get_msrs(&mut msr_entries)?;
2906 let msrs = if num_msrs == expected_num_msrs {
2907 msr_entries
2908 } else {
2909 let mut faulty_msr_index = num_msrs;
2910 let mut msr_entries_tmp = msr_entries[..faulty_msr_index].to_vec();
2911
2912 loop {
2913 warn!(
2914 "Detected faulty MSR 0x{:x} while getting MSRs",
2915 msr_entries[faulty_msr_index].index
2916 );
2917
2918 // Skip the first bad MSR
2919 let start_pos = faulty_msr_index + 1;

Callers

nothing calls this directly

Calls 15

newFunction · 0.85
is_system_registerFunction · 0.85
is_non_core_registerFunction · 0.85
get_xsave2Method · 0.80
get_xsaveMethod · 0.80
nested_stateMethod · 0.80
as_sliceMethod · 0.80
iterMethod · 0.80
get_cpuid2Method · 0.45
get_mp_stateMethod · 0.45
get_regsMethod · 0.45
get_sregsMethod · 0.45

Tested by

no test coverage detected