hypervisor/kvm/
x86_64.rs

1// Copyright 2020 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::arch::x86_64::CpuidResult;
6use std::collections::BTreeMap;
7use std::sync::Arc;
8
9use base::errno_result;
10use base::error;
11use base::ioctl;
12use base::ioctl_with_mut_ptr;
13use base::ioctl_with_mut_ref;
14use base::ioctl_with_ptr;
15use base::ioctl_with_ref;
16use base::ioctl_with_val;
17use base::AsRawDescriptor;
18use base::Error;
19use base::IoctlNr;
20use base::MappedRegion;
21use base::Result;
22use kvm_sys::*;
23use libc::E2BIG;
24use libc::EAGAIN;
25use libc::EINVAL;
26use libc::EIO;
27use libc::ENOMEM;
28use libc::ENXIO;
29use serde::Deserialize;
30use serde::Serialize;
31use snapshot::AnySnapshot;
32use vm_memory::GuestAddress;
33use zerocopy::FromZeros;
34
35use super::Config;
36use super::Kvm;
37use super::KvmCap;
38use super::KvmVcpu;
39use super::KvmVm;
40use crate::host_phys_addr_bits;
41use crate::ClockState;
42use crate::CpuId;
43use crate::CpuIdEntry;
44use crate::DebugRegs;
45use crate::DescriptorTable;
46use crate::DeviceKind;
47use crate::Fpu;
48use crate::FpuReg;
49use crate::HypervisorX86_64;
50use crate::IoapicRedirectionTableEntry;
51use crate::IoapicState;
52use crate::IrqSourceChip;
53use crate::LapicState;
54use crate::PicSelect;
55use crate::PicState;
56use crate::PitChannelState;
57use crate::PitState;
58use crate::ProtectionType;
59use crate::Regs;
60use crate::Segment;
61use crate::Sregs;
62use crate::VcpuExit;
63use crate::VcpuX86_64;
64use crate::VmCap;
65use crate::VmX86_64;
66use crate::Xsave;
67use crate::NUM_IOAPIC_PINS;
68
69const KVM_XSAVE_MAX_SIZE: usize = 4096;
70const MSR_IA32_APICBASE: u32 = 0x0000001b;
71
72#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct VcpuEvents {
74    pub exception: VcpuExceptionState,
75    pub interrupt: VcpuInterruptState,
76    pub nmi: VcpuNmiState,
77    pub sipi_vector: Option<u32>,
78    pub smi: VcpuSmiState,
79    pub triple_fault: VcpuTripleFaultState,
80    pub exception_payload: Option<u64>,
81}
82
83#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct VcpuExceptionState {
85    pub injected: bool,
86    pub nr: u8,
87    pub has_error_code: bool,
88    pub pending: Option<bool>,
89    pub error_code: u32,
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
93pub struct VcpuInterruptState {
94    pub injected: bool,
95    pub nr: u8,
96    pub soft: bool,
97    pub shadow: Option<u8>,
98}
99
100#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct VcpuNmiState {
102    pub injected: bool,
103    pub pending: Option<bool>,
104    pub masked: bool,
105}
106
107#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct VcpuSmiState {
109    pub smm: Option<bool>,
110    pub pending: bool,
111    pub smm_inside_nmi: bool,
112    pub latched_init: u8,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
116pub struct VcpuTripleFaultState {
117    pub pending: Option<bool>,
118}
119
120pub fn get_cpuid_with_initial_capacity<T: AsRawDescriptor>(
121    descriptor: &T,
122    kind: IoctlNr,
123    initial_capacity: usize,
124) -> Result<CpuId> {
125    let mut entries: usize = initial_capacity;
126
127    loop {
128        let mut kvm_cpuid =
129            kvm_cpuid2::<[kvm_cpuid_entry2]>::new_box_zeroed_with_elems(entries).unwrap();
130        kvm_cpuid.nent = entries.try_into().unwrap();
131
132        let ret = {
133            // SAFETY:
134            // ioctl is unsafe. The kernel is trusted not to write beyond the bounds of the
135            // memory allocated for the struct. The limit is read from nent within kvm_cpuid2,
136            // which is set to the allocated size above.
137            unsafe { ioctl_with_mut_ref(descriptor, kind, &mut *kvm_cpuid) }
138        };
139        if ret < 0 {
140            let err = Error::last();
141            match err.errno() {
142                E2BIG => {
143                    // double the available memory for cpuid entries for kvm.
144                    if let Some(val) = entries.checked_mul(2) {
145                        entries = val;
146                    } else {
147                        return Err(err);
148                    }
149                }
150                _ => return Err(err),
151            }
152        } else {
153            return Ok(CpuId::from(&*kvm_cpuid));
154        }
155    }
156}
157
158impl Kvm {
159    pub fn get_cpuid(&self, kind: IoctlNr) -> Result<CpuId> {
160        const KVM_MAX_ENTRIES: usize = 256;
161        get_cpuid_with_initial_capacity(self, kind, KVM_MAX_ENTRIES)
162    }
163
164    pub fn get_vm_type(&self, protection_type: ProtectionType) -> Result<u32> {
165        if protection_type.isolates_memory() {
166            Ok(KVM_X86_PKVM_PROTECTED_VM)
167        } else {
168            Ok(KVM_X86_DEFAULT_VM)
169        }
170    }
171
172    /// Get the size of guest physical addresses in bits.
173    pub fn get_guest_phys_addr_bits(&self) -> u8 {
174        // Assume the guest physical address size is the same as the host.
175        host_phys_addr_bits()
176    }
177}
178
179impl HypervisorX86_64 for Kvm {
180    fn get_supported_cpuid(&self) -> Result<CpuId> {
181        self.get_cpuid(KVM_GET_SUPPORTED_CPUID)
182    }
183
184    fn get_msr_index_list(&self) -> Result<Vec<u32>> {
185        const MAX_KVM_MSR_ENTRIES: usize = 256;
186
187        let mut msr_list = kvm_msr_list::<[u32; MAX_KVM_MSR_ENTRIES]>::new_zeroed();
188        msr_list.nmsrs = MAX_KVM_MSR_ENTRIES as u32;
189
190        let ret = {
191            // SAFETY:
192            // ioctl is unsafe. The kernel is trusted not to write beyond the bounds of the memory
193            // allocated for the struct. The limit is read from nmsrs, which is set to the allocated
194            // size (MAX_KVM_MSR_ENTRIES) above.
195            unsafe { ioctl_with_mut_ref(self, KVM_GET_MSR_INDEX_LIST, &mut msr_list) }
196        };
197        if ret < 0 {
198            return errno_result();
199        }
200
201        let mut nmsrs = msr_list.nmsrs;
202        if nmsrs > MAX_KVM_MSR_ENTRIES as u32 {
203            nmsrs = MAX_KVM_MSR_ENTRIES as u32;
204        }
205
206        Ok(msr_list.indices[..nmsrs as usize].to_vec())
207    }
208}
209
210impl KvmVm {
211    /// Does platform specific initialization for the KvmVm.
212    pub fn init_arch(&self, _cfg: &Config) -> Result<()> {
213        Ok(())
214    }
215
216    /// Checks if a particular `VmCap` is available, or returns None if arch-independent
217    /// Vm.check_capability() should handle the check.
218    pub fn check_capability_arch(&self, c: VmCap) -> Option<bool> {
219        match c {
220            VmCap::PvClock => Some(true),
221            _ => None,
222        }
223    }
224
225    /// Returns the params to pass to KVM_CREATE_DEVICE for a `kind` device on this arch, or None to
226    /// let the arch-independent `KvmVm::create_device` handle it.
227    pub fn get_device_params_arch(&self, _kind: DeviceKind) -> Option<kvm_create_device> {
228        None
229    }
230
231    /// Arch-specific implementation of `Vm::get_pvclock`.
232    pub fn get_pvclock_arch(&self) -> Result<ClockState> {
233        let mut clock_data: kvm_clock_data = Default::default();
234        let ret =
235            // SAFETY:
236            // Safe because we know that our file is a VM fd, we know the kernel will only write correct
237            // amount of memory to our pointer, and we verify the return result.
238            unsafe { ioctl_with_mut_ref(self, KVM_GET_CLOCK, &mut clock_data) };
239        if ret == 0 {
240            Ok(ClockState::from(&clock_data))
241        } else {
242            errno_result()
243        }
244    }
245
246    /// Arch-specific implementation of `Vm::set_pvclock`.
247    pub fn set_pvclock_arch(&self, state: &ClockState) -> Result<()> {
248        let clock_data = kvm_clock_data::from(state);
249        // SAFETY:
250        // Safe because we know that our file is a VM fd, we know the kernel will only read correct
251        // amount of memory from our pointer, and we verify the return result.
252        let ret = unsafe { ioctl_with_ref(self, KVM_SET_CLOCK, &clock_data) };
253        if ret == 0 {
254            Ok(())
255        } else {
256            errno_result()
257        }
258    }
259
260    /// Signals an interrupt vector directly to a vCPU's Local APIC using MSI.
261    pub fn signal_msi_to_lapic(&self, apic_id: u32, vector: u8) -> Result<()> {
262        let msi = kvm_msi {
263            address_lo: 0xFEE0_0000 | ((apic_id & 0xFF) << 12),
264            address_hi: 0,
265            data: vector as u32,
266            flags: 0,
267            ..Default::default()
268        };
269        self.signal_msi(&msi)
270    }
271
272    /// Retrieves the state of given interrupt controller by issuing KVM_GET_IRQCHIP ioctl.
273    ///
274    /// Note that this call can only succeed after a call to `Vm::create_irq_chip`.
275    pub fn get_pic_state(&self, id: PicSelect) -> Result<kvm_pic_state> {
276        let mut irqchip_state = kvm_irqchip {
277            chip_id: id as u32,
278            ..Default::default()
279        };
280        let ret = {
281            // SAFETY:
282            // Safe because we know our file is a VM fd, we know the kernel will only write
283            // correct amount of memory to our pointer, and we verify the return result.
284            unsafe { ioctl_with_mut_ref(self, KVM_GET_IRQCHIP, &mut irqchip_state) }
285        };
286        if ret == 0 {
287            Ok(
288                // SAFETY:
289                // Safe as we know that we are retrieving data related to the
290                // PIC (primary or secondary) and not IOAPIC.
291                unsafe { irqchip_state.chip.pic },
292            )
293        } else {
294            errno_result()
295        }
296    }
297
298    /// Sets the state of given interrupt controller by issuing KVM_SET_IRQCHIP ioctl.
299    ///
300    /// Note that this call can only succeed after a call to `Vm::create_irq_chip`.
301    pub fn set_pic_state(&self, id: PicSelect, state: &kvm_pic_state) -> Result<()> {
302        let mut irqchip_state = kvm_irqchip {
303            chip_id: id as u32,
304            ..Default::default()
305        };
306        irqchip_state.chip.pic = *state;
307        // SAFETY:
308        // Safe because we know that our file is a VM fd, we know the kernel will only read
309        // correct amount of memory from our pointer, and we verify the return result.
310        let ret = unsafe { ioctl_with_ref(self, KVM_SET_IRQCHIP, &irqchip_state) };
311        if ret == 0 {
312            Ok(())
313        } else {
314            errno_result()
315        }
316    }
317
318    /// Retrieves the number of pins for emulated IO-APIC.
319    pub fn get_ioapic_num_pins(&self) -> Result<usize> {
320        Ok(NUM_IOAPIC_PINS)
321    }
322
323    /// Retrieves the state of IOAPIC by issuing KVM_GET_IRQCHIP ioctl.
324    ///
325    /// Note that this call can only succeed after a call to `Vm::create_irq_chip`.
326    pub fn get_ioapic_state(&self) -> Result<kvm_ioapic_state> {
327        let mut irqchip_state = kvm_irqchip {
328            chip_id: 2,
329            ..Default::default()
330        };
331        let ret = {
332            // SAFETY:
333            // Safe because we know our file is a VM fd, we know the kernel will only write
334            // correct amount of memory to our pointer, and we verify the return result.
335            unsafe { ioctl_with_mut_ref(self, KVM_GET_IRQCHIP, &mut irqchip_state) }
336        };
337        if ret == 0 {
338            Ok(
339                // SAFETY:
340                // Safe as we know that we are retrieving data related to the
341                // IOAPIC and not PIC.
342                unsafe { irqchip_state.chip.ioapic },
343            )
344        } else {
345            errno_result()
346        }
347    }
348
349    /// Sets the state of IOAPIC by issuing KVM_SET_IRQCHIP ioctl.
350    ///
351    /// Note that this call can only succeed after a call to `Vm::create_irq_chip`.
352    pub fn set_ioapic_state(&self, state: &kvm_ioapic_state) -> Result<()> {
353        let mut irqchip_state = kvm_irqchip {
354            chip_id: 2,
355            ..Default::default()
356        };
357        irqchip_state.chip.ioapic = *state;
358        // SAFETY:
359        // Safe because we know that our file is a VM fd, we know the kernel will only read
360        // correct amount of memory from our pointer, and we verify the return result.
361        let ret = unsafe { ioctl_with_ref(self, KVM_SET_IRQCHIP, &irqchip_state) };
362        if ret == 0 {
363            Ok(())
364        } else {
365            errno_result()
366        }
367    }
368
369    /// Creates a PIT as per the KVM_CREATE_PIT2 ioctl.
370    ///
371    /// Note that this call can only succeed after a call to `Vm::create_irq_chip`.
372    pub fn create_pit(&self) -> Result<()> {
373        let pit_config = kvm_pit_config::default();
374        // SAFETY:
375        // Safe because we know that our file is a VM fd, we know the kernel will only read the
376        // correct amount of memory from our pointer, and we verify the return result.
377        let ret = unsafe { ioctl_with_ref(self, KVM_CREATE_PIT2, &pit_config) };
378        if ret == 0 {
379            Ok(())
380        } else {
381            errno_result()
382        }
383    }
384
385    /// Retrieves the state of PIT by issuing KVM_GET_PIT2 ioctl.
386    ///
387    /// Note that this call can only succeed after a call to `Vm::create_pit`.
388    pub fn get_pit_state(&self) -> Result<kvm_pit_state2> {
389        let mut pit_state = Default::default();
390        // SAFETY:
391        // Safe because we know that our file is a VM fd, we know the kernel will only write
392        // correct amount of memory to our pointer, and we verify the return result.
393        let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_PIT2, &mut pit_state) };
394        if ret == 0 {
395            Ok(pit_state)
396        } else {
397            errno_result()
398        }
399    }
400
401    /// Sets the state of PIT by issuing KVM_SET_PIT2 ioctl.
402    ///
403    /// Note that this call can only succeed after a call to `Vm::create_pit`.
404    pub fn set_pit_state(&self, pit_state: &kvm_pit_state2) -> Result<()> {
405        // SAFETY:
406        // Safe because we know that our file is a VM fd, we know the kernel will only read
407        // correct amount of memory from our pointer, and we verify the return result.
408        let ret = unsafe { ioctl_with_ref(self, KVM_SET_PIT2, pit_state) };
409        if ret == 0 {
410            Ok(())
411        } else {
412            errno_result()
413        }
414    }
415
416    /// Set MSR_PLATFORM_INFO read access.
417    pub fn set_platform_info_read_access(&self, allow_read: bool) -> Result<()> {
418        let mut cap = kvm_enable_cap {
419            cap: KVM_CAP_MSR_PLATFORM_INFO,
420            ..Default::default()
421        };
422        cap.args[0] = allow_read as u64;
423
424        // SAFETY:
425        // Safe because we know that our file is a VM fd, we know that the
426        // kernel will only read correct amount of memory from our pointer, and
427        // we verify the return result.
428        let ret = unsafe { ioctl_with_ref(self, KVM_ENABLE_CAP, &cap) };
429        if ret < 0 {
430            errno_result()
431        } else {
432            Ok(())
433        }
434    }
435
436    /// Enable support for split-irqchip.
437    pub fn enable_split_irqchip(&self, ioapic_pins: usize) -> Result<()> {
438        let mut cap = kvm_enable_cap {
439            cap: KVM_CAP_SPLIT_IRQCHIP,
440            ..Default::default()
441        };
442        cap.args[0] = ioapic_pins as u64;
443        // SAFETY:
444        // safe becuase we allocated the struct and we know the kernel will read
445        // exactly the size of the struct
446        let ret = unsafe { ioctl_with_ref(self, KVM_ENABLE_CAP, &cap) };
447        if ret < 0 {
448            errno_result()
449        } else {
450            Ok(())
451        }
452    }
453
454    /// Get pKVM hypervisor details, e.g. the firmware size.
455    ///
456    /// Returns `Err` if not running under pKVM.
457    ///
458    /// Uses `KVM_ENABLE_CAP` internally, but it is only a getter, there should be no side effects
459    /// in KVM.
460    fn get_protected_vm_info(&self) -> Result<KvmProtectedVmInfo> {
461        let mut info = KvmProtectedVmInfo {
462            firmware_size: 0,
463            reserved: [0; 7],
464        };
465        // SAFETY:
466        // Safe because we allocated the struct and we know the kernel won't write beyond the end of
467        // the struct or keep a pointer to it.
468        unsafe {
469            self.enable_raw_capability(
470                KvmCap::X86ProtectedVm,
471                KVM_CAP_X86_PROTECTED_VM_FLAGS_INFO,
472                &[&mut info as *mut KvmProtectedVmInfo as u64, 0, 0, 0],
473            )
474        }?;
475        Ok(info)
476    }
477
478    fn set_protected_vm_firmware_gpa(&self, fw_addr: GuestAddress) -> Result<()> {
479        // SAFETY:
480        // Safe because none of the args are pointers.
481        unsafe {
482            self.enable_raw_capability(
483                KvmCap::X86ProtectedVm,
484                KVM_CAP_X86_PROTECTED_VM_FLAGS_SET_FW_GPA,
485                &[fw_addr.0, 0, 0, 0],
486            )
487        }
488    }
489}
490
491#[repr(C)]
492struct KvmProtectedVmInfo {
493    firmware_size: u64,
494    reserved: [u64; 7],
495}
496
497impl VmX86_64 for KvmVm {
498    fn get_hypervisor(&self) -> &dyn HypervisorX86_64 {
499        &self.kvm
500    }
501
502    fn load_protected_vm_firmware(&self, fw_addr: GuestAddress, fw_max_size: u64) -> Result<()> {
503        let info = self.get_protected_vm_info()?;
504        if info.firmware_size == 0 {
505            Err(Error::new(EINVAL))
506        } else {
507            if info.firmware_size > fw_max_size {
508                return Err(Error::new(ENOMEM));
509            }
510            self.set_protected_vm_firmware_gpa(fw_addr)
511        }
512    }
513
514    fn create_vcpu(&self, id: usize) -> Result<Arc<dyn VcpuX86_64>> {
515        // create_vcpu is declared separately in VmAArch64 and VmX86, so it can return VcpuAArch64
516        // or VcpuX86.  But both use the same implementation in KvmVm::create_vcpu.
517        Ok(Arc::new(KvmVm::create_kvm_vcpu(self, id)?))
518    }
519
520    /// Sets the address of the three-page region in the VM's address space.
521    ///
522    /// See the documentation on the KVM_SET_TSS_ADDR ioctl.
523    fn set_tss_addr(&self, addr: GuestAddress) -> Result<()> {
524        // SAFETY:
525        // Safe because we know that our file is a VM fd and we verify the return result.
526        let ret = unsafe { ioctl_with_val(self, KVM_SET_TSS_ADDR, addr.offset()) };
527        if ret == 0 {
528            Ok(())
529        } else {
530            errno_result()
531        }
532    }
533
534    /// Sets the address of a one-page region in the VM's address space.
535    ///
536    /// See the documentation on the KVM_SET_IDENTITY_MAP_ADDR ioctl.
537    fn set_identity_map_addr(&self, addr: GuestAddress) -> Result<()> {
538        // SAFETY:
539        // Safe because we know that our file is a VM fd and we verify the return result.
540        let ret = unsafe { ioctl_with_ref(self, KVM_SET_IDENTITY_MAP_ADDR, &addr.offset()) };
541        if ret == 0 {
542            Ok(())
543        } else {
544            errno_result()
545        }
546    }
547}
548
549impl KvmVcpu {
550    /// Handles a `KVM_EXIT_SYSTEM_EVENT` with event type `KVM_SYSTEM_EVENT_RESET` with the given
551    /// event flags and returns the appropriate `VcpuExit` value for the run loop to handle.
552    pub fn system_event_reset(&self, _event_flags: u64) -> Result<VcpuExit> {
553        Ok(VcpuExit::SystemEventReset)
554    }
555
556    /// Gets the Xsave size by checking the extension KVM_CAP_XSAVE2.
557    ///
558    /// Size should always be >=0. If size is negative, an error occurred.
559    /// If size <= 4096, XSAVE2 is not supported by the CPU or the kernel. KVM_XSAVE_MAX_SIZE is
560    /// returned (4096).
561    /// Otherwise, the size will be returned.
562    fn xsave_size(&self) -> Result<usize> {
563        let size = {
564            // SAFETY:
565            // Safe because we know that our file is a valid VM fd
566            unsafe { ioctl_with_val(&self.vm, KVM_CHECK_EXTENSION, KVM_CAP_XSAVE2 as u64) }
567        };
568        if size < 0 {
569            return errno_result();
570        }
571        // Safe to unwrap since we already tested for negative values
572        let size: usize = size.try_into().unwrap();
573        Ok(size.max(KVM_XSAVE_MAX_SIZE))
574    }
575
576    #[inline]
577    pub(crate) fn handle_vm_exit_arch(&self, run: &mut kvm_run) -> Option<VcpuExit> {
578        match run.exit_reason {
579            KVM_EXIT_IO => Some(VcpuExit::Io),
580            KVM_EXIT_IOAPIC_EOI => {
581                // SAFETY:
582                // Safe because the exit_reason (which comes from the kernel) told us which
583                // union field to use.
584                let vector = unsafe { run.__bindgen_anon_1.eoi.vector };
585                Some(VcpuExit::IoapicEoi { vector })
586            }
587            KVM_EXIT_HLT => Some(VcpuExit::Hlt),
588            KVM_EXIT_SET_TPR => Some(VcpuExit::SetTpr),
589            KVM_EXIT_TPR_ACCESS => Some(VcpuExit::TprAccess),
590            KVM_EXIT_X86_BUS_LOCK => Some(VcpuExit::BusLock),
591            _ => None,
592        }
593    }
594}
595
596#[derive(Debug, Serialize, Deserialize)]
597struct HypervisorState {
598    interrupts: VcpuEvents,
599    nested_state: Vec<u8>,
600}
601
602impl VcpuX86_64 for KvmVcpu {
603    #[allow(clippy::cast_ptr_alignment)]
604    fn set_interrupt_window_requested(&self, requested: bool) {
605        // SAFETY:
606        // Safe because we know we mapped enough memory to hold the kvm_run struct because the
607        // kernel told us how large it was. The pointer is page aligned so casting to a different
608        // type is well defined, hence the clippy allow attribute.
609        let run = unsafe { &mut *(self.run_mmap.as_ptr() as *mut kvm_run) };
610        run.request_interrupt_window = requested.into();
611    }
612
613    #[allow(clippy::cast_ptr_alignment)]
614    fn ready_for_interrupt(&self) -> bool {
615        // SAFETY:
616        // Safe because we know we mapped enough memory to hold the kvm_run struct because the
617        // kernel told us how large it was. The pointer is page aligned so casting to a different
618        // type is well defined, hence the clippy allow attribute.
619        let run = unsafe { &mut *(self.run_mmap.as_ptr() as *mut kvm_run) };
620        run.ready_for_interrupt_injection != 0 && run.if_flag != 0
621    }
622
623    /// Use the KVM_INTERRUPT ioctl to inject the specified interrupt vector.
624    ///
625    /// While this ioctl exists on PPC and MIPS as well as x86, the semantics are different and
626    /// ChromeOS doesn't support PPC or MIPS.
627    fn interrupt(&self, irq: u8) -> Result<()> {
628        if !self.ready_for_interrupt() {
629            return Err(Error::new(EAGAIN));
630        }
631
632        let interrupt = kvm_interrupt { irq: irq.into() };
633        // SAFETY:
634        // safe becuase we allocated the struct and we know the kernel will read
635        // exactly the size of the struct
636        let ret = unsafe { ioctl_with_ref(self, KVM_INTERRUPT, &interrupt) };
637        if ret == 0 {
638            Ok(())
639        } else {
640            errno_result()
641        }
642    }
643
644    fn inject_nmi(&self) -> Result<()> {
645        // SAFETY:
646        // Safe because we know that our file is a VCPU fd.
647        let ret = unsafe { ioctl(self, KVM_NMI) };
648        if ret == 0 {
649            Ok(())
650        } else {
651            errno_result()
652        }
653    }
654
655    fn get_regs(&self) -> Result<Regs> {
656        let mut regs: kvm_regs = Default::default();
657        let ret = {
658            // SAFETY:
659            // Safe because we know that our file is a VCPU fd, we know the kernel will only read
660            // the correct amount of memory from our pointer, and we verify the return
661            // result.
662            unsafe { ioctl_with_mut_ref(self, KVM_GET_REGS, &mut regs) }
663        };
664        if ret == 0 {
665            Ok(Regs::from(&regs))
666        } else {
667            errno_result()
668        }
669    }
670
671    fn set_regs(&self, regs: &Regs) -> Result<()> {
672        let regs = kvm_regs::from(regs);
673        let ret = {
674            // SAFETY:
675            // Safe because we know that our file is a VCPU fd, we know the kernel will only read
676            // the correct amount of memory from our pointer, and we verify the return
677            // result.
678            unsafe { ioctl_with_ref(self, KVM_SET_REGS, &regs) }
679        };
680        if ret == 0 {
681            Ok(())
682        } else {
683            errno_result()
684        }
685    }
686
687    fn get_sregs(&self) -> Result<Sregs> {
688        let mut regs: kvm_sregs = Default::default();
689        let ret = {
690            // SAFETY:
691            // Safe because we know that our file is a VCPU fd, we know the kernel will only write
692            // the correct amount of memory to our pointer, and we verify the return
693            // result.
694            unsafe { ioctl_with_mut_ref(self, KVM_GET_SREGS, &mut regs) }
695        };
696        if ret == 0 {
697            Ok(Sregs::from(&regs))
698        } else {
699            errno_result()
700        }
701    }
702
703    fn set_sregs(&self, sregs: &Sregs) -> Result<()> {
704        // Get the current `kvm_sregs` so we can use its `apic_base` and `interrupt_bitmap`, which
705        // are not present in `Sregs`.
706        let mut kvm_sregs: kvm_sregs = Default::default();
707        // SAFETY:
708        // Safe because we know that our file is a VCPU fd, we know the kernel will only write the
709        // correct amount of memory to our pointer, and we verify the return result.
710        let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_SREGS, &mut kvm_sregs) };
711        if ret != 0 {
712            return errno_result();
713        }
714
715        kvm_sregs.cs = kvm_segment::from(&sregs.cs);
716        kvm_sregs.ds = kvm_segment::from(&sregs.ds);
717        kvm_sregs.es = kvm_segment::from(&sregs.es);
718        kvm_sregs.fs = kvm_segment::from(&sregs.fs);
719        kvm_sregs.gs = kvm_segment::from(&sregs.gs);
720        kvm_sregs.ss = kvm_segment::from(&sregs.ss);
721        kvm_sregs.tr = kvm_segment::from(&sregs.tr);
722        kvm_sregs.ldt = kvm_segment::from(&sregs.ldt);
723        kvm_sregs.gdt = kvm_dtable::from(&sregs.gdt);
724        kvm_sregs.idt = kvm_dtable::from(&sregs.idt);
725        kvm_sregs.cr0 = sregs.cr0;
726        kvm_sregs.cr2 = sregs.cr2;
727        kvm_sregs.cr3 = sregs.cr3;
728        kvm_sregs.cr4 = sregs.cr4;
729        kvm_sregs.cr8 = sregs.cr8;
730        kvm_sregs.efer = sregs.efer;
731
732        // SAFETY:
733        // Safe because we know that our file is a VCPU fd, we know the kernel will only read the
734        // correct amount of memory from our pointer, and we verify the return result.
735        let ret = unsafe { ioctl_with_ref(self, KVM_SET_SREGS, &kvm_sregs) };
736        if ret == 0 {
737            Ok(())
738        } else {
739            errno_result()
740        }
741    }
742
743    fn get_fpu(&self) -> Result<Fpu> {
744        let mut fpu: kvm_fpu = Default::default();
745        // SAFETY:
746        // Safe because we know that our file is a VCPU fd, we know the kernel will only write the
747        // correct amount of memory to our pointer, and we verify the return result.
748        let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_FPU, &mut fpu) };
749        if ret == 0 {
750            Ok(Fpu::from(&fpu))
751        } else {
752            errno_result()
753        }
754    }
755
756    fn set_fpu(&self, fpu: &Fpu) -> Result<()> {
757        let fpu = kvm_fpu::from(fpu);
758        let ret = {
759            // SAFETY:
760            // Here we trust the kernel not to read past the end of the kvm_fpu struct.
761            unsafe { ioctl_with_ref(self, KVM_SET_FPU, &fpu) }
762        };
763        if ret == 0 {
764            Ok(())
765        } else {
766            errno_result()
767        }
768    }
769
770    /// If the VM reports using XSave2, the function will call XSave2.
771    fn get_xsave(&self) -> Result<Xsave> {
772        let size = self.xsave_size()?;
773        let ioctl_nr = if size > KVM_XSAVE_MAX_SIZE {
774            KVM_GET_XSAVE2
775        } else {
776            KVM_GET_XSAVE
777        };
778        let mut xsave = Xsave::new(size);
779
780        // SAFETY:
781        // Safe because we know that our file is a VCPU fd, we know the kernel will only write the
782        // correct amount of memory to our pointer, and we verify the return result.
783        let ret = unsafe { ioctl_with_mut_ptr(self, ioctl_nr, xsave.as_mut_ptr()) };
784        if ret == 0 {
785            Ok(xsave)
786        } else {
787            errno_result()
788        }
789    }
790
791    fn set_xsave(&self, xsave: &Xsave) -> Result<()> {
792        let size = self.xsave_size()?;
793        // Ensure xsave is the same size as used in get_xsave.
794        // Return err if sizes don't match => not the same extensions are enabled for CPU.
795        if xsave.len() != size {
796            return Err(Error::new(EIO));
797        }
798
799        // SAFETY:
800        // Safe because we know that our file is a VCPU fd, we know the kernel will only write the
801        // correct amount of memory to our pointer, and we verify the return result.
802        // Because of the len check above, and because the layout of `struct kvm_xsave` is
803        // compatible with a slice of `u32`, we can pass the pointer to `xsave` directly.
804        let ret = unsafe { ioctl_with_ptr(self, KVM_SET_XSAVE, xsave.as_ptr()) };
805        if ret == 0 {
806            Ok(())
807        } else {
808            errno_result()
809        }
810    }
811
812    fn get_hypervisor_specific_state(&self) -> Result<AnySnapshot> {
813        let mut vcpu_evts: kvm_vcpu_events = Default::default();
814        // SAFETY:
815        // Safe because we know that our file is a VCPU fd, we know the kernel will only write
816        // the correct amount of memory to our pointer, and we verify the return
817        // result.
818        let ret = { unsafe { ioctl_with_mut_ref(self, KVM_GET_VCPU_EVENTS, &mut vcpu_evts) } };
819        if ret != 0 {
820            return errno_result();
821        }
822        let interrupts = VcpuEvents::from(&vcpu_evts);
823        let ret =
824            // SAFETY:
825            // Safe because we know that our file is a valid VM fd
826            unsafe { ioctl_with_val(&self.vm, KVM_CHECK_EXTENSION, KVM_CAP_NESTED_STATE as u64) };
827        if ret < 0 {
828            return errno_result();
829        }
830        // 0 == unsupported
831        let nested_state = if ret == 0 {
832            Vec::new()
833        } else {
834            let mut nested_state: Vec<u8> = vec![0; ret as usize];
835            let nested_state_ptr = nested_state.as_ptr() as *mut kvm_nested_state;
836            assert!(nested_state_ptr.is_aligned());
837            // SAFETY:
838            // Casting this vector to kvm_nested_state meets all the requirements mentioned at
839            // https://doc.rust-lang.org/std/ptr/index.html#pointer-to-reference-conversion
840            // The pointer is validated to be aligned, the value is non-null, can be dereferenced,
841            // the pointer points to kvm_nested_state, which holds zeroes and is valid.
842            // No other references to this point exist and no other operation happens. The memory
843            // is only accessed via the reference the lifetime of the reference
844            unsafe {
845                (*nested_state_ptr).size = ret as u32;
846            }
847            assert!(nested_state.as_ptr().is_aligned());
848            // SAFETY:
849            // Safe because we know out FD is a valid VCPU fd, and  we got the size
850            // of nested state from the KVM_CAP_NESTED_STATE call.
851            let ret = unsafe {
852                ioctl_with_mut_ptr(self, KVM_GET_NESTED_STATE, nested_state.as_mut_ptr())
853            };
854            if ret < 0 {
855                return errno_result();
856            }
857            nested_state
858        };
859        AnySnapshot::to_any(HypervisorState {
860            interrupts,
861            nested_state,
862        })
863        .map_err(|e| {
864            error!("failed to serialize hypervisor state: {:?}", e);
865            Error::new(EIO)
866        })
867    }
868
869    fn set_hypervisor_specific_state(&self, data: AnySnapshot) -> Result<()> {
870        let hypervisor_state = AnySnapshot::from_any::<HypervisorState>(data).map_err(|e| {
871            error!("failed to deserialize hypervisor_state: {:?}", e);
872            Error::new(EIO)
873        })?;
874        let vcpu_events = kvm_vcpu_events::from(&hypervisor_state.interrupts);
875        let ret = {
876            // SAFETY:
877            // Safe because we know that our file is a VCPU fd, we know the kernel will only read
878            // the correct amount of memory from our pointer, and we verify the return
879            // result.
880            unsafe { ioctl_with_ref(self, KVM_SET_VCPU_EVENTS, &vcpu_events) }
881        };
882        if ret != 0 {
883            return errno_result();
884        }
885        if hypervisor_state.nested_state.is_empty() {
886            return Ok(());
887        }
888        // SAFETY:
889        // Casting this vector to kvm_nested_state meets all the requirements mentioned at
890        // https://doc.rust-lang.org/std/ptr/index.html#pointer-to-reference-conversion
891        // The pointer is validated to be aligned, the value is non-null, can be dereferenced,
892        // the pointer points to Vec<u8>, which is initialized and a valid value.
893        // No other references to this point exist and no other operation happens. The memory
894        // is not modified by any operation. The pointer is dropped after validating that size is
895        // smaller than the vector length.
896        unsafe {
897            let vec_len = hypervisor_state.nested_state.len();
898            assert!(
899                (hypervisor_state.nested_state.as_ptr() as *const kvm_nested_state).is_aligned()
900            );
901            if (*(hypervisor_state.nested_state.as_ptr() as *const kvm_nested_state)).size
902                > vec_len as u32
903            {
904                error!("Invalued nested state data, size larger than vec allocated.");
905                return Err(Error::new(EINVAL));
906            }
907        }
908        // SAFETY:
909        // Safe because we know that our file is a VCPU fd, we know the kernel will only read
910        // the correct amount of memory from our pointer, and we verify the return
911        // result.
912        let ret = unsafe {
913            ioctl_with_ptr(
914                self,
915                KVM_SET_NESTED_STATE,
916                hypervisor_state.nested_state.as_ptr(),
917            )
918        };
919        if ret == 0 {
920            Ok(())
921        } else {
922            errno_result()
923        }
924    }
925
926    fn get_debugregs(&self) -> Result<DebugRegs> {
927        let mut regs: kvm_debugregs = Default::default();
928        // SAFETY:
929        // Safe because we know that our file is a VCPU fd, we know the kernel will only write the
930        // correct amount of memory to our pointer, and we verify the return result.
931        let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_DEBUGREGS, &mut regs) };
932        if ret == 0 {
933            Ok(DebugRegs::from(&regs))
934        } else {
935            errno_result()
936        }
937    }
938
939    fn set_debugregs(&self, dregs: &DebugRegs) -> Result<()> {
940        let dregs = kvm_debugregs::from(dregs);
941        let ret = {
942            // SAFETY:
943            // Here we trust the kernel not to read past the end of the kvm_debugregs struct.
944            unsafe { ioctl_with_ref(self, KVM_SET_DEBUGREGS, &dregs) }
945        };
946        if ret == 0 {
947            Ok(())
948        } else {
949            errno_result()
950        }
951    }
952
953    fn get_xcrs(&self) -> Result<BTreeMap<u32, u64>> {
954        let mut regs: kvm_xcrs = Default::default();
955        // SAFETY:
956        // Safe because we know that our file is a VCPU fd, we know the kernel will only write the
957        // correct amount of memory to our pointer, and we verify the return result.
958        let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_XCRS, &mut regs) };
959        if ret < 0 {
960            return errno_result();
961        }
962
963        Ok(regs
964            .xcrs
965            .iter()
966            .take(regs.nr_xcrs as usize)
967            .map(|kvm_xcr| (kvm_xcr.xcr, kvm_xcr.value))
968            .collect())
969    }
970
971    fn set_xcr(&self, xcr_index: u32, value: u64) -> Result<()> {
972        let mut kvm_xcr = kvm_xcrs {
973            nr_xcrs: 1,
974            ..Default::default()
975        };
976        kvm_xcr.xcrs[0].xcr = xcr_index;
977        kvm_xcr.xcrs[0].value = value;
978
979        let ret = {
980            // SAFETY:
981            // Here we trust the kernel not to read past the end of the kvm_xcrs struct.
982            unsafe { ioctl_with_ref(self, KVM_SET_XCRS, &kvm_xcr) }
983        };
984        if ret == 0 {
985            Ok(())
986        } else {
987            errno_result()
988        }
989    }
990
991    fn get_msr(&self, msr_index: u32) -> Result<u64> {
992        let mut msrs = kvm_msrs::<[kvm_msr_entry; 1]>::new_zeroed();
993        msrs.nmsrs = 1;
994        msrs.entries[0].index = msr_index;
995
996        let ret = {
997            // SAFETY:
998            // Here we trust the kernel not to read or write past the end of the kvm_msrs struct.
999            unsafe { ioctl_with_mut_ref(self, KVM_GET_MSRS, &mut msrs) }
1000        };
1001        if ret < 0 {
1002            return errno_result();
1003        }
1004
1005        // KVM_GET_MSRS returns the number of msr entries written.
1006        if ret != 1 {
1007            return Err(base::Error::new(libc::ENOENT));
1008        }
1009
1010        Ok(msrs.entries[0].data)
1011    }
1012
1013    fn get_all_msrs(&self) -> Result<BTreeMap<u32, u64>> {
1014        let msr_index_list = self.kvm.get_msr_index_list()?;
1015
1016        let mut kvm_msrs =
1017            kvm_msrs::<[kvm_msr_entry]>::new_box_zeroed_with_elems(msr_index_list.len()).unwrap();
1018        kvm_msrs.nmsrs = msr_index_list.len() as u32;
1019        kvm_msrs
1020            .entries
1021            .iter_mut()
1022            .zip(msr_index_list.iter())
1023            .for_each(|(msr_entry, msr_index)| msr_entry.index = *msr_index);
1024
1025        let ret = {
1026            // SAFETY:
1027            // Here we trust the kernel not to read or write past the end of the kvm_msrs struct.
1028            unsafe { ioctl_with_mut_ref(self, KVM_GET_MSRS, &mut *kvm_msrs) }
1029        };
1030        if ret < 0 {
1031            return errno_result();
1032        }
1033
1034        // KVM_GET_MSRS returns the number of msr entries written.
1035        let count = ret as usize;
1036        if count != msr_index_list.len() {
1037            error!(
1038                "failed to get all MSRs: requested {}, got {}",
1039                msr_index_list.len(),
1040                count,
1041            );
1042            return Err(base::Error::new(libc::EPERM));
1043        }
1044
1045        let msrs = BTreeMap::from_iter(
1046            kvm_msrs
1047                .entries
1048                .iter()
1049                .map(|kvm_msr| (kvm_msr.index, kvm_msr.data)),
1050        );
1051
1052        Ok(msrs)
1053    }
1054
1055    fn set_msr(&self, msr_index: u32, value: u64) -> Result<()> {
1056        let mut kvm_msrs = kvm_msrs::<[kvm_msr_entry; 1]>::new_zeroed();
1057        kvm_msrs.nmsrs = 1;
1058        kvm_msrs.entries[0].index = msr_index;
1059        kvm_msrs.entries[0].data = value;
1060
1061        let ret = {
1062            // SAFETY:
1063            // Here we trust the kernel not to read past the end of the kvm_msrs struct.
1064            unsafe { ioctl_with_ref(self, KVM_SET_MSRS, &kvm_msrs) }
1065        };
1066        if ret < 0 {
1067            return errno_result();
1068        }
1069
1070        // KVM_SET_MSRS returns the number of msr entries written.
1071        if ret != 1 {
1072            error!("failed to set MSR {:#x} to {:#x}", msr_index, value);
1073            return Err(base::Error::new(libc::EPERM));
1074        }
1075
1076        Ok(())
1077    }
1078
1079    fn set_cpuid(&self, cpuid: &CpuId) -> Result<()> {
1080        let cpuid = Box::<kvm_cpuid2<[kvm_cpuid_entry2]>>::from(cpuid);
1081        let ret = {
1082            // SAFETY:
1083            // Here we trust the kernel not to read past the end of the kvm_msrs struct.
1084            unsafe { ioctl_with_ref(self, KVM_SET_CPUID2, &*cpuid) }
1085        };
1086        if ret == 0 {
1087            Ok(())
1088        } else {
1089            errno_result()
1090        }
1091    }
1092
1093    fn set_guest_debug(&self, addrs: &[GuestAddress], enable_singlestep: bool) -> Result<()> {
1094        use kvm_sys::*;
1095        let mut dbg: kvm_guest_debug = Default::default();
1096
1097        if addrs.len() > 4 {
1098            error!(
1099                "Support 4 breakpoints at most but {} addresses are passed",
1100                addrs.len()
1101            );
1102            return Err(base::Error::new(libc::EINVAL));
1103        }
1104
1105        dbg.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP;
1106        if enable_singlestep {
1107            dbg.control |= KVM_GUESTDBG_SINGLESTEP;
1108        }
1109
1110        // Set bits 9 and 10.
1111        // bit 9: GE (global exact breakpoint enable) flag.
1112        // bit 10: always 1.
1113        dbg.arch.debugreg[7] = 0x0600;
1114
1115        for (i, addr) in addrs.iter().enumerate() {
1116            dbg.arch.debugreg[i] = addr.0;
1117            // Set global breakpoint enable flag
1118            dbg.arch.debugreg[7] |= 2 << (i * 2);
1119        }
1120
1121        let ret = {
1122            // SAFETY:
1123            // Here we trust the kernel not to read past the end of the kvm_guest_debug struct.
1124            unsafe { ioctl_with_ref(self, KVM_SET_GUEST_DEBUG, &dbg) }
1125        };
1126        if ret == 0 {
1127            Ok(())
1128        } else {
1129            errno_result()
1130        }
1131    }
1132
1133    /// KVM does not support the VcpuExit::Cpuid exit type.
1134    fn handle_cpuid(&self, _entry: &CpuIdEntry) -> Result<()> {
1135        Err(Error::new(ENXIO))
1136    }
1137
1138    fn restore_timekeeping(&self, _host_tsc_reference_moment: u64, _tsc_offset: u64) -> Result<()> {
1139        // On KVM, the TSC MSR is restored as part of SET_MSRS, and no further action is required.
1140        Ok(())
1141    }
1142}
1143
1144impl KvmVcpu {
1145    /// X86 specific call to get the state of the "Local Advanced Programmable Interrupt
1146    /// Controller".
1147    ///
1148    /// See the documentation for KVM_GET_LAPIC.
1149    pub fn get_lapic(&self) -> Result<kvm_lapic_state> {
1150        let mut klapic: kvm_lapic_state = Default::default();
1151
1152        let ret = {
1153            // SAFETY:
1154            // The ioctl is unsafe unless you trust the kernel not to write past the end of the
1155            // local_apic struct.
1156            unsafe { ioctl_with_mut_ref(self, KVM_GET_LAPIC, &mut klapic) }
1157        };
1158        if ret < 0 {
1159            return errno_result();
1160        }
1161        Ok(klapic)
1162    }
1163
1164    /// X86 specific call to set the state of the "Local Advanced Programmable Interrupt
1165    /// Controller".
1166    ///
1167    /// See the documentation for KVM_SET_LAPIC.
1168    pub fn set_lapic(&self, klapic: &kvm_lapic_state) -> Result<()> {
1169        let ret = {
1170            // SAFETY:
1171            // The ioctl is safe because the kernel will only read from the klapic struct.
1172            unsafe { ioctl_with_ref(self, KVM_SET_LAPIC, klapic) }
1173        };
1174        if ret < 0 {
1175            return errno_result();
1176        }
1177        Ok(())
1178    }
1179
1180    /// X86 specific call to get the value of the APIC_BASE MSR.
1181    ///
1182    /// See the documentation for The kvm_run structure, and for KVM_GET_LAPIC.
1183    pub fn get_apic_base(&self) -> Result<u64> {
1184        self.get_msr(MSR_IA32_APICBASE)
1185    }
1186
1187    /// X86 specific call to set the value of the APIC_BASE MSR.
1188    ///
1189    /// See the documentation for The kvm_run structure, and for KVM_GET_LAPIC.
1190    pub fn set_apic_base(&self, apic_base: u64) -> Result<()> {
1191        self.set_msr(MSR_IA32_APICBASE, apic_base)
1192    }
1193
1194    /// Call to get pending interrupts acknowledged by the APIC but not yet injected into the CPU.
1195    ///
1196    /// See the documentation for KVM_GET_SREGS.
1197    pub fn get_interrupt_bitmap(&self) -> Result<[u64; 4usize]> {
1198        let mut regs: kvm_sregs = Default::default();
1199        // SAFETY:
1200        // Safe because we know that our file is a VCPU fd, we know the kernel will only write the
1201        // correct amount of memory to our pointer, and we verify the return result.
1202        let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_SREGS, &mut regs) };
1203        if ret >= 0 {
1204            Ok(regs.interrupt_bitmap)
1205        } else {
1206            errno_result()
1207        }
1208    }
1209
1210    /// Call to set pending interrupts acknowledged by the APIC but not yet injected into the CPU.
1211    ///
1212    /// See the documentation for KVM_GET_SREGS.
1213    pub fn set_interrupt_bitmap(&self, interrupt_bitmap: [u64; 4usize]) -> Result<()> {
1214        // Potentially racy code. Vcpu registers are set in a separate thread and this could result
1215        // in Sregs being modified from the Vcpu initialization thread and the Irq restoring
1216        // thread.
1217        let mut regs: kvm_sregs = Default::default();
1218        // SAFETY:
1219        // Safe because we know that our file is a VCPU fd, we know the kernel will only write the
1220        // correct amount of memory to our pointer, and we verify the return result.
1221        let ret = unsafe { ioctl_with_mut_ref(self, KVM_GET_SREGS, &mut regs) };
1222        if ret >= 0 {
1223            regs.interrupt_bitmap = interrupt_bitmap;
1224            // SAFETY:
1225            // Safe because we know that our file is a VCPU fd, we know the kernel will only read
1226            // the correct amount of memory from our pointer, and we verify the return
1227            // result.
1228            let ret = unsafe { ioctl_with_ref(self, KVM_SET_SREGS, &regs) };
1229            if ret >= 0 {
1230                Ok(())
1231            } else {
1232                errno_result()
1233            }
1234        } else {
1235            errno_result()
1236        }
1237    }
1238}
1239
1240impl<'a> From<&'a kvm_cpuid2<[kvm_cpuid_entry2]>> for CpuId {
1241    fn from(kvm_cpuid: &'a kvm_cpuid2<[kvm_cpuid_entry2]>) -> CpuId {
1242        let kvm_entries = &kvm_cpuid.entries[..kvm_cpuid.nent as usize];
1243        let mut cpu_id_entries = Vec::with_capacity(kvm_entries.len());
1244
1245        for entry in kvm_entries {
1246            let cpu_id_entry = CpuIdEntry {
1247                function: entry.function,
1248                index: entry.index,
1249                flags: entry.flags,
1250                cpuid: CpuidResult {
1251                    eax: entry.eax,
1252                    ebx: entry.ebx,
1253                    ecx: entry.ecx,
1254                    edx: entry.edx,
1255                },
1256            };
1257            cpu_id_entries.push(cpu_id_entry)
1258        }
1259        CpuId { cpu_id_entries }
1260    }
1261}
1262
1263impl From<&CpuId> for Box<kvm_cpuid2<[kvm_cpuid_entry2]>> {
1264    fn from(cpuid: &CpuId) -> Box<kvm_cpuid2<[kvm_cpuid_entry2]>> {
1265        let mut kvm =
1266            kvm_cpuid2::<[kvm_cpuid_entry2]>::new_box_zeroed_with_elems(cpuid.cpu_id_entries.len())
1267                .unwrap();
1268        kvm.nent = cpuid.cpu_id_entries.len().try_into().unwrap();
1269        for (i, &e) in cpuid.cpu_id_entries.iter().enumerate() {
1270            kvm.entries[i] = kvm_cpuid_entry2 {
1271                function: e.function,
1272                index: e.index,
1273                flags: e.flags,
1274                eax: e.cpuid.eax,
1275                ebx: e.cpuid.ebx,
1276                ecx: e.cpuid.ecx,
1277                edx: e.cpuid.edx,
1278                ..Default::default()
1279            };
1280        }
1281        kvm
1282    }
1283}
1284
1285impl From<&ClockState> for kvm_clock_data {
1286    fn from(state: &ClockState) -> Self {
1287        kvm_clock_data {
1288            clock: state.clock,
1289            ..Default::default()
1290        }
1291    }
1292}
1293
1294impl From<&kvm_clock_data> for ClockState {
1295    fn from(clock_data: &kvm_clock_data) -> Self {
1296        ClockState {
1297            clock: clock_data.clock,
1298        }
1299    }
1300}
1301
1302impl From<&kvm_pic_state> for PicState {
1303    fn from(item: &kvm_pic_state) -> Self {
1304        PicState {
1305            last_irr: item.last_irr,
1306            irr: item.irr,
1307            imr: item.imr,
1308            isr: item.isr,
1309            priority_add: item.priority_add,
1310            irq_base: item.irq_base,
1311            read_reg_select: item.read_reg_select != 0,
1312            poll: item.poll != 0,
1313            special_mask: item.special_mask != 0,
1314            init_state: item.init_state.into(),
1315            auto_eoi: item.auto_eoi != 0,
1316            rotate_on_auto_eoi: item.rotate_on_auto_eoi != 0,
1317            special_fully_nested_mode: item.special_fully_nested_mode != 0,
1318            use_4_byte_icw: item.init4 != 0,
1319            elcr: item.elcr,
1320            elcr_mask: item.elcr_mask,
1321        }
1322    }
1323}
1324
1325impl From<&PicState> for kvm_pic_state {
1326    fn from(item: &PicState) -> Self {
1327        kvm_pic_state {
1328            last_irr: item.last_irr,
1329            irr: item.irr,
1330            imr: item.imr,
1331            isr: item.isr,
1332            priority_add: item.priority_add,
1333            irq_base: item.irq_base,
1334            read_reg_select: item.read_reg_select as u8,
1335            poll: item.poll as u8,
1336            special_mask: item.special_mask as u8,
1337            init_state: item.init_state as u8,
1338            auto_eoi: item.auto_eoi as u8,
1339            rotate_on_auto_eoi: item.rotate_on_auto_eoi as u8,
1340            special_fully_nested_mode: item.special_fully_nested_mode as u8,
1341            init4: item.use_4_byte_icw as u8,
1342            elcr: item.elcr,
1343            elcr_mask: item.elcr_mask,
1344        }
1345    }
1346}
1347
1348impl From<&kvm_ioapic_state> for IoapicState {
1349    fn from(item: &kvm_ioapic_state) -> Self {
1350        let mut state = IoapicState {
1351            base_address: item.base_address,
1352            ioregsel: item.ioregsel as u8,
1353            ioapicid: item.id,
1354            current_interrupt_level_bitmap: item.irr,
1355            redirect_table: [IoapicRedirectionTableEntry::default(); NUM_IOAPIC_PINS],
1356        };
1357        for (in_state, out_state) in item.redirtbl.iter().zip(state.redirect_table.iter_mut()) {
1358            *out_state = in_state.into();
1359        }
1360        state
1361    }
1362}
1363
1364impl From<&IoapicRedirectionTableEntry> for kvm_ioapic_state__bindgen_ty_1 {
1365    fn from(item: &IoapicRedirectionTableEntry) -> Self {
1366        kvm_ioapic_state__bindgen_ty_1 {
1367            // IoapicRedirectionTableEntry layout matches the exact bit layout of a hardware
1368            // ioapic redirection table entry, so we can simply do a 64-bit copy
1369            bits: item.get(0, 64),
1370        }
1371    }
1372}
1373
1374impl From<&kvm_ioapic_state__bindgen_ty_1> for IoapicRedirectionTableEntry {
1375    fn from(item: &kvm_ioapic_state__bindgen_ty_1) -> Self {
1376        let mut entry = IoapicRedirectionTableEntry::default();
1377        // SAFETY:
1378        // Safe because the 64-bit layout of the IoapicRedirectionTableEntry matches the kvm_sys
1379        // table entry layout
1380        entry.set(0, 64, unsafe { item.bits });
1381        entry
1382    }
1383}
1384
1385impl From<&IoapicState> for kvm_ioapic_state {
1386    fn from(item: &IoapicState) -> Self {
1387        let mut state = kvm_ioapic_state {
1388            base_address: item.base_address,
1389            ioregsel: item.ioregsel as u32,
1390            id: item.ioapicid,
1391            irr: item.current_interrupt_level_bitmap,
1392            ..Default::default()
1393        };
1394        for (in_state, out_state) in item.redirect_table.iter().zip(state.redirtbl.iter_mut()) {
1395            *out_state = in_state.into();
1396        }
1397        state
1398    }
1399}
1400
1401impl From<&LapicState> for kvm_lapic_state {
1402    fn from(item: &LapicState) -> Self {
1403        let mut state = kvm_lapic_state::default();
1404        // There are 64 lapic registers
1405        for (reg, value) in item.regs.iter().enumerate() {
1406            // Each lapic register is 16 bytes, but only the first 4 are used
1407            let reg_offset = 16 * reg;
1408            let regs_slice = &mut state.regs[reg_offset..reg_offset + 4];
1409
1410            // to_le_bytes() produces an array of u8, not i8(c_char), so we can't directly use
1411            // copy_from_slice().
1412            for (i, v) in value.to_le_bytes().iter().enumerate() {
1413                regs_slice[i] = *v as i8;
1414            }
1415        }
1416        state
1417    }
1418}
1419
1420impl From<&kvm_lapic_state> for LapicState {
1421    fn from(item: &kvm_lapic_state) -> Self {
1422        let mut state = LapicState { regs: [0; 64] };
1423        // There are 64 lapic registers
1424        for reg in 0..64 {
1425            // Each lapic register is 16 bytes, but only the first 4 are used
1426            let reg_offset = 16 * reg;
1427
1428            // from_le_bytes() only works on arrays of u8, not i8(c_char).
1429            let reg_slice = &item.regs[reg_offset..reg_offset + 4];
1430            let mut bytes = [0u8; 4];
1431            for i in 0..4 {
1432                bytes[i] = reg_slice[i] as u8;
1433            }
1434            state.regs[reg] = u32::from_le_bytes(bytes);
1435        }
1436        state
1437    }
1438}
1439
1440impl From<&PitState> for kvm_pit_state2 {
1441    fn from(item: &PitState) -> Self {
1442        kvm_pit_state2 {
1443            channels: [
1444                kvm_pit_channel_state::from(&item.channels[0]),
1445                kvm_pit_channel_state::from(&item.channels[1]),
1446                kvm_pit_channel_state::from(&item.channels[2]),
1447            ],
1448            flags: item.flags,
1449            ..Default::default()
1450        }
1451    }
1452}
1453
1454impl From<&kvm_pit_state2> for PitState {
1455    fn from(item: &kvm_pit_state2) -> Self {
1456        PitState {
1457            channels: [
1458                PitChannelState::from(&item.channels[0]),
1459                PitChannelState::from(&item.channels[1]),
1460                PitChannelState::from(&item.channels[2]),
1461            ],
1462            flags: item.flags,
1463        }
1464    }
1465}
1466
1467impl From<&PitChannelState> for kvm_pit_channel_state {
1468    fn from(item: &PitChannelState) -> Self {
1469        kvm_pit_channel_state {
1470            count: item.count,
1471            latched_count: item.latched_count,
1472            count_latched: item.count_latched as u8,
1473            status_latched: item.status_latched as u8,
1474            status: item.status,
1475            read_state: item.read_state as u8,
1476            write_state: item.write_state as u8,
1477            // kvm's write_latch only stores the low byte of the reload value
1478            write_latch: item.reload_value as u8,
1479            rw_mode: item.rw_mode as u8,
1480            mode: item.mode,
1481            bcd: item.bcd as u8,
1482            gate: item.gate as u8,
1483            count_load_time: item.count_load_time as i64,
1484        }
1485    }
1486}
1487
1488impl From<&kvm_pit_channel_state> for PitChannelState {
1489    fn from(item: &kvm_pit_channel_state) -> Self {
1490        PitChannelState {
1491            count: item.count,
1492            latched_count: item.latched_count,
1493            count_latched: item.count_latched.into(),
1494            status_latched: item.status_latched != 0,
1495            status: item.status,
1496            read_state: item.read_state.into(),
1497            write_state: item.write_state.into(),
1498            // kvm's write_latch only stores the low byte of the reload value
1499            reload_value: item.write_latch as u16,
1500            rw_mode: item.rw_mode.into(),
1501            mode: item.mode,
1502            bcd: item.bcd != 0,
1503            gate: item.gate != 0,
1504            count_load_time: item.count_load_time as u64,
1505        }
1506    }
1507}
1508
1509// This function translates an IrqSrouceChip to the kvm u32 equivalent. It has a different
1510// implementation between x86_64 and aarch64 because the irqchip KVM constants are not defined on
1511// all architectures.
1512pub(super) fn chip_to_kvm_chip(chip: IrqSourceChip) -> u32 {
1513    match chip {
1514        IrqSourceChip::PicPrimary => KVM_IRQCHIP_PIC_MASTER,
1515        IrqSourceChip::PicSecondary => KVM_IRQCHIP_PIC_SLAVE,
1516        IrqSourceChip::Ioapic => KVM_IRQCHIP_IOAPIC,
1517        _ => {
1518            error!("Invalid IrqChipSource for X86 {:?}", chip);
1519            0
1520        }
1521    }
1522}
1523
1524impl From<&kvm_regs> for Regs {
1525    fn from(r: &kvm_regs) -> Self {
1526        Regs {
1527            rax: r.rax,
1528            rbx: r.rbx,
1529            rcx: r.rcx,
1530            rdx: r.rdx,
1531            rsi: r.rsi,
1532            rdi: r.rdi,
1533            rsp: r.rsp,
1534            rbp: r.rbp,
1535            r8: r.r8,
1536            r9: r.r9,
1537            r10: r.r10,
1538            r11: r.r11,
1539            r12: r.r12,
1540            r13: r.r13,
1541            r14: r.r14,
1542            r15: r.r15,
1543            rip: r.rip,
1544            rflags: r.rflags,
1545        }
1546    }
1547}
1548
1549impl From<&Regs> for kvm_regs {
1550    fn from(r: &Regs) -> Self {
1551        kvm_regs {
1552            rax: r.rax,
1553            rbx: r.rbx,
1554            rcx: r.rcx,
1555            rdx: r.rdx,
1556            rsi: r.rsi,
1557            rdi: r.rdi,
1558            rsp: r.rsp,
1559            rbp: r.rbp,
1560            r8: r.r8,
1561            r9: r.r9,
1562            r10: r.r10,
1563            r11: r.r11,
1564            r12: r.r12,
1565            r13: r.r13,
1566            r14: r.r14,
1567            r15: r.r15,
1568            rip: r.rip,
1569            rflags: r.rflags,
1570        }
1571    }
1572}
1573
1574impl From<&VcpuEvents> for kvm_vcpu_events {
1575    fn from(ve: &VcpuEvents) -> Self {
1576        let mut kvm_ve: kvm_vcpu_events = Default::default();
1577
1578        kvm_ve.exception.injected = ve.exception.injected as u8;
1579        kvm_ve.exception.nr = ve.exception.nr;
1580        kvm_ve.exception.has_error_code = ve.exception.has_error_code as u8;
1581        if let Some(pending) = ve.exception.pending {
1582            kvm_ve.exception.pending = pending as u8;
1583            if ve.exception_payload.is_some() {
1584                kvm_ve.exception_has_payload = true as u8;
1585            }
1586            kvm_ve.exception_payload = ve.exception_payload.unwrap_or(0);
1587            kvm_ve.flags |= KVM_VCPUEVENT_VALID_PAYLOAD;
1588        }
1589        kvm_ve.exception.error_code = ve.exception.error_code;
1590
1591        kvm_ve.interrupt.injected = ve.interrupt.injected as u8;
1592        kvm_ve.interrupt.nr = ve.interrupt.nr;
1593        kvm_ve.interrupt.soft = ve.interrupt.soft as u8;
1594        if let Some(shadow) = ve.interrupt.shadow {
1595            kvm_ve.interrupt.shadow = shadow;
1596            kvm_ve.flags |= KVM_VCPUEVENT_VALID_SHADOW;
1597        }
1598
1599        kvm_ve.nmi.injected = ve.nmi.injected as u8;
1600        if let Some(pending) = ve.nmi.pending {
1601            kvm_ve.nmi.pending = pending as u8;
1602            kvm_ve.flags |= KVM_VCPUEVENT_VALID_NMI_PENDING;
1603        }
1604        kvm_ve.nmi.masked = ve.nmi.masked as u8;
1605
1606        if let Some(sipi_vector) = ve.sipi_vector {
1607            kvm_ve.sipi_vector = sipi_vector;
1608            kvm_ve.flags |= KVM_VCPUEVENT_VALID_SIPI_VECTOR;
1609        }
1610
1611        if let Some(smm) = ve.smi.smm {
1612            kvm_ve.smi.smm = smm as u8;
1613            kvm_ve.flags |= KVM_VCPUEVENT_VALID_SMM;
1614        }
1615        kvm_ve.smi.pending = ve.smi.pending as u8;
1616        kvm_ve.smi.smm_inside_nmi = ve.smi.smm_inside_nmi as u8;
1617        kvm_ve.smi.latched_init = ve.smi.latched_init;
1618
1619        if let Some(pending) = ve.triple_fault.pending {
1620            kvm_ve.triple_fault.pending = pending as u8;
1621            kvm_ve.flags |= KVM_VCPUEVENT_VALID_TRIPLE_FAULT;
1622        }
1623        kvm_ve
1624    }
1625}
1626
1627impl From<&kvm_vcpu_events> for VcpuEvents {
1628    fn from(ve: &kvm_vcpu_events) -> Self {
1629        let exception = VcpuExceptionState {
1630            injected: ve.exception.injected != 0,
1631            nr: ve.exception.nr,
1632            has_error_code: ve.exception.has_error_code != 0,
1633            pending: if ve.flags & KVM_VCPUEVENT_VALID_PAYLOAD != 0 {
1634                Some(ve.exception.pending != 0)
1635            } else {
1636                None
1637            },
1638            error_code: ve.exception.error_code,
1639        };
1640
1641        let interrupt = VcpuInterruptState {
1642            injected: ve.interrupt.injected != 0,
1643            nr: ve.interrupt.nr,
1644            soft: ve.interrupt.soft != 0,
1645            shadow: if ve.flags & KVM_VCPUEVENT_VALID_SHADOW != 0 {
1646                Some(ve.interrupt.shadow)
1647            } else {
1648                None
1649            },
1650        };
1651
1652        let nmi = VcpuNmiState {
1653            injected: ve.interrupt.injected != 0,
1654            pending: if ve.flags & KVM_VCPUEVENT_VALID_NMI_PENDING != 0 {
1655                Some(ve.nmi.pending != 0)
1656            } else {
1657                None
1658            },
1659            masked: ve.nmi.masked != 0,
1660        };
1661
1662        let sipi_vector = if ve.flags & KVM_VCPUEVENT_VALID_SIPI_VECTOR != 0 {
1663            Some(ve.sipi_vector)
1664        } else {
1665            None
1666        };
1667
1668        let smi = VcpuSmiState {
1669            smm: if ve.flags & KVM_VCPUEVENT_VALID_SMM != 0 {
1670                Some(ve.smi.smm != 0)
1671            } else {
1672                None
1673            },
1674            pending: ve.smi.pending != 0,
1675            smm_inside_nmi: ve.smi.smm_inside_nmi != 0,
1676            latched_init: ve.smi.latched_init,
1677        };
1678
1679        let triple_fault = VcpuTripleFaultState {
1680            pending: if ve.flags & KVM_VCPUEVENT_VALID_TRIPLE_FAULT != 0 {
1681                Some(ve.triple_fault.pending != 0)
1682            } else {
1683                None
1684            },
1685        };
1686
1687        let exception_payload = if ve.flags & KVM_VCPUEVENT_VALID_PAYLOAD != 0 {
1688            Some(ve.exception_payload)
1689        } else {
1690            None
1691        };
1692
1693        VcpuEvents {
1694            exception,
1695            interrupt,
1696            nmi,
1697            sipi_vector,
1698            smi,
1699            triple_fault,
1700            exception_payload,
1701        }
1702    }
1703}
1704
1705impl From<&kvm_segment> for Segment {
1706    fn from(s: &kvm_segment) -> Self {
1707        Segment {
1708            base: s.base,
1709            limit_bytes: s.limit,
1710            selector: s.selector,
1711            type_: s.type_,
1712            present: s.present,
1713            dpl: s.dpl,
1714            db: s.db,
1715            s: s.s,
1716            l: s.l,
1717            g: s.g,
1718            avl: s.avl,
1719        }
1720    }
1721}
1722
1723impl From<&Segment> for kvm_segment {
1724    fn from(s: &Segment) -> Self {
1725        kvm_segment {
1726            base: s.base,
1727            limit: s.limit_bytes,
1728            selector: s.selector,
1729            type_: s.type_,
1730            present: s.present,
1731            dpl: s.dpl,
1732            db: s.db,
1733            s: s.s,
1734            l: s.l,
1735            g: s.g,
1736            avl: s.avl,
1737            unusable: match s.present {
1738                0 => 1,
1739                _ => 0,
1740            },
1741            ..Default::default()
1742        }
1743    }
1744}
1745
1746impl From<&kvm_dtable> for DescriptorTable {
1747    fn from(dt: &kvm_dtable) -> Self {
1748        DescriptorTable {
1749            base: dt.base,
1750            limit: dt.limit,
1751        }
1752    }
1753}
1754
1755impl From<&DescriptorTable> for kvm_dtable {
1756    fn from(dt: &DescriptorTable) -> Self {
1757        kvm_dtable {
1758            base: dt.base,
1759            limit: dt.limit,
1760            ..Default::default()
1761        }
1762    }
1763}
1764
1765impl From<&kvm_sregs> for Sregs {
1766    fn from(r: &kvm_sregs) -> Self {
1767        Sregs {
1768            cs: Segment::from(&r.cs),
1769            ds: Segment::from(&r.ds),
1770            es: Segment::from(&r.es),
1771            fs: Segment::from(&r.fs),
1772            gs: Segment::from(&r.gs),
1773            ss: Segment::from(&r.ss),
1774            tr: Segment::from(&r.tr),
1775            ldt: Segment::from(&r.ldt),
1776            gdt: DescriptorTable::from(&r.gdt),
1777            idt: DescriptorTable::from(&r.idt),
1778            cr0: r.cr0,
1779            cr2: r.cr2,
1780            cr3: r.cr3,
1781            cr4: r.cr4,
1782            cr8: r.cr8,
1783            efer: r.efer,
1784        }
1785    }
1786}
1787
1788impl From<&kvm_fpu> for Fpu {
1789    fn from(r: &kvm_fpu) -> Self {
1790        Fpu {
1791            fpr: FpuReg::from_16byte_arrays(&r.fpr),
1792            fcw: r.fcw,
1793            fsw: r.fsw,
1794            ftwx: r.ftwx,
1795            last_opcode: r.last_opcode,
1796            last_ip: r.last_ip,
1797            last_dp: r.last_dp,
1798            xmm: r.xmm,
1799            mxcsr: r.mxcsr,
1800        }
1801    }
1802}
1803
1804impl From<&Fpu> for kvm_fpu {
1805    fn from(r: &Fpu) -> Self {
1806        kvm_fpu {
1807            fpr: FpuReg::to_16byte_arrays(&r.fpr),
1808            fcw: r.fcw,
1809            fsw: r.fsw,
1810            ftwx: r.ftwx,
1811            last_opcode: r.last_opcode,
1812            last_ip: r.last_ip,
1813            last_dp: r.last_dp,
1814            xmm: r.xmm,
1815            mxcsr: r.mxcsr,
1816            ..Default::default()
1817        }
1818    }
1819}
1820
1821impl From<&kvm_debugregs> for DebugRegs {
1822    fn from(r: &kvm_debugregs) -> Self {
1823        DebugRegs {
1824            db: r.db,
1825            dr6: r.dr6,
1826            dr7: r.dr7,
1827        }
1828    }
1829}
1830
1831impl From<&DebugRegs> for kvm_debugregs {
1832    fn from(r: &DebugRegs) -> Self {
1833        kvm_debugregs {
1834            db: r.db,
1835            dr6: r.dr6,
1836            dr7: r.dr7,
1837            ..Default::default()
1838        }
1839    }
1840}
1841
1842#[cfg(test)]
1843mod tests {
1844    use super::*;
1845
1846    #[test]
1847    fn vcpu_event_to_from() {
1848        // All data is random.
1849        let mut kvm_ve: kvm_vcpu_events = Default::default();
1850        kvm_ve.exception.injected = 1;
1851        kvm_ve.exception.nr = 65;
1852        kvm_ve.exception.has_error_code = 1;
1853        kvm_ve.exception.error_code = 110;
1854        kvm_ve.exception.pending = 1;
1855
1856        kvm_ve.interrupt.injected = 1;
1857        kvm_ve.interrupt.nr = 100;
1858        kvm_ve.interrupt.soft = 1;
1859        kvm_ve.interrupt.shadow = 114;
1860
1861        kvm_ve.nmi.injected = 1;
1862        kvm_ve.nmi.pending = 1;
1863        kvm_ve.nmi.masked = 0;
1864
1865        kvm_ve.sipi_vector = 105;
1866
1867        kvm_ve.smi.smm = 1;
1868        kvm_ve.smi.pending = 1;
1869        kvm_ve.smi.smm_inside_nmi = 1;
1870        kvm_ve.smi.latched_init = 100;
1871
1872        kvm_ve.triple_fault.pending = 0;
1873
1874        kvm_ve.exception_payload = 33;
1875        kvm_ve.exception_has_payload = 1;
1876
1877        kvm_ve.flags = 0
1878            | KVM_VCPUEVENT_VALID_PAYLOAD
1879            | KVM_VCPUEVENT_VALID_SMM
1880            | KVM_VCPUEVENT_VALID_NMI_PENDING
1881            | KVM_VCPUEVENT_VALID_SIPI_VECTOR
1882            | KVM_VCPUEVENT_VALID_SHADOW;
1883
1884        let ve: VcpuEvents = VcpuEvents::from(&kvm_ve);
1885        assert_eq!(ve.exception.injected, true);
1886        assert_eq!(ve.exception.nr, 65);
1887        assert_eq!(ve.exception.has_error_code, true);
1888        assert_eq!(ve.exception.error_code, 110);
1889        assert_eq!(ve.exception.pending.unwrap(), true);
1890
1891        assert_eq!(ve.interrupt.injected, true);
1892        assert_eq!(ve.interrupt.nr, 100);
1893        assert_eq!(ve.interrupt.soft, true);
1894        assert_eq!(ve.interrupt.shadow.unwrap(), 114);
1895
1896        assert_eq!(ve.nmi.injected, true);
1897        assert_eq!(ve.nmi.pending.unwrap(), true);
1898        assert_eq!(ve.nmi.masked, false);
1899
1900        assert_eq!(ve.sipi_vector.unwrap(), 105);
1901
1902        assert_eq!(ve.smi.smm.unwrap(), true);
1903        assert_eq!(ve.smi.pending, true);
1904        assert_eq!(ve.smi.smm_inside_nmi, true);
1905        assert_eq!(ve.smi.latched_init, 100);
1906
1907        assert_eq!(ve.triple_fault.pending, None);
1908
1909        assert_eq!(ve.exception_payload.unwrap(), 33);
1910
1911        let kvm_ve_restored: kvm_vcpu_events = kvm_vcpu_events::from(&ve);
1912        assert_eq!(kvm_ve_restored.exception.injected, 1);
1913        assert_eq!(kvm_ve_restored.exception.nr, 65);
1914        assert_eq!(kvm_ve_restored.exception.has_error_code, 1);
1915        assert_eq!(kvm_ve_restored.exception.error_code, 110);
1916        assert_eq!(kvm_ve_restored.exception.pending, 1);
1917
1918        assert_eq!(kvm_ve_restored.interrupt.injected, 1);
1919        assert_eq!(kvm_ve_restored.interrupt.nr, 100);
1920        assert_eq!(kvm_ve_restored.interrupt.soft, 1);
1921        assert_eq!(kvm_ve_restored.interrupt.shadow, 114);
1922
1923        assert_eq!(kvm_ve_restored.nmi.injected, 1);
1924        assert_eq!(kvm_ve_restored.nmi.pending, 1);
1925        assert_eq!(kvm_ve_restored.nmi.masked, 0);
1926
1927        assert_eq!(kvm_ve_restored.sipi_vector, 105);
1928
1929        assert_eq!(kvm_ve_restored.smi.smm, 1);
1930        assert_eq!(kvm_ve_restored.smi.pending, 1);
1931        assert_eq!(kvm_ve_restored.smi.smm_inside_nmi, 1);
1932        assert_eq!(kvm_ve_restored.smi.latched_init, 100);
1933
1934        assert_eq!(kvm_ve_restored.triple_fault.pending, 0);
1935
1936        assert_eq!(kvm_ve_restored.exception_payload, 33);
1937        assert_eq!(kvm_ve_restored.exception_has_payload, 1);
1938    }
1939}