cloud-hypervisor/hypervisor/src/kvm/x86_64/mod.rs
Wei Liu 45fbf840db hypervisor, vmm: move away from CpuId type
CpuId is an alias type for the flexible array structure type over
CpuIdEntry. The type itself and the type of the element in the array
portion are tied to the underlying hypervisor.

Switch to using CpuIdEntry slice or vector directly. The construction of
CpuId type is left to hypervisors.

This allows us to decouple CpuIdEntry from hypervisors more easily.

No functional change intended.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2022-07-18 22:15:30 +01:00

224 lines
6.0 KiB
Rust

// Copyright © 2019 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//
// Copyright © 2020, Microsoft Corporation
//
// Copyright 2018-2019 CrowdStrike, Inc.
//
//
use crate::arch::x86::{DescriptorTable, SegmentRegister, SpecialRegisters, StandardRegisters};
use crate::kvm::{Cap, Kvm, KvmError, KvmResult};
use serde::{Deserialize, Serialize};
///
/// Export generically-named wrappers of kvm-bindings for Unix-based platforms
///
pub use {
kvm_bindings::kvm_cpuid_entry2 as CpuIdEntry, kvm_bindings::kvm_dtable,
kvm_bindings::kvm_fpu as FpuState, kvm_bindings::kvm_lapic_state as LapicState,
kvm_bindings::kvm_mp_state as MpState, kvm_bindings::kvm_msr_entry as MsrEntry,
kvm_bindings::kvm_regs, kvm_bindings::kvm_segment, kvm_bindings::kvm_sregs,
kvm_bindings::kvm_vcpu_events as VcpuEvents,
kvm_bindings::kvm_xcrs as ExtendedControlRegisters, kvm_bindings::kvm_xsave as Xsave,
kvm_bindings::CpuId, kvm_bindings::MsrList, kvm_bindings::Msrs as MsrEntries,
kvm_bindings::KVM_CPUID_FLAG_SIGNIFCANT_INDEX as CPUID_FLAG_VALID_INDEX,
};
///
/// Check KVM extension for Linux
///
pub fn check_required_kvm_extensions(kvm: &Kvm) -> KvmResult<()> {
if !kvm.check_extension(Cap::SignalMsi) {
return Err(KvmError::CapabilityMissing(Cap::SignalMsi));
}
if !kvm.check_extension(Cap::TscDeadlineTimer) {
return Err(KvmError::CapabilityMissing(Cap::TscDeadlineTimer));
}
if !kvm.check_extension(Cap::SplitIrqchip) {
return Err(KvmError::CapabilityMissing(Cap::SplitIrqchip));
}
if !kvm.check_extension(Cap::SetIdentityMapAddr) {
return Err(KvmError::CapabilityMissing(Cap::SetIdentityMapAddr));
}
if !kvm.check_extension(Cap::SetTssAddr) {
return Err(KvmError::CapabilityMissing(Cap::SetTssAddr));
}
if !kvm.check_extension(Cap::ImmediateExit) {
return Err(KvmError::CapabilityMissing(Cap::ImmediateExit));
}
Ok(())
}
#[derive(Clone, Serialize, Deserialize)]
pub struct VcpuKvmState {
pub cpuid: Vec<CpuIdEntry>,
pub msrs: MsrEntries,
pub vcpu_events: VcpuEvents,
pub regs: kvm_regs,
pub sregs: kvm_sregs,
pub fpu: FpuState,
pub lapic_state: LapicState,
pub xsave: Xsave,
pub xcrs: ExtendedControlRegisters,
pub mp_state: MpState,
}
impl From<StandardRegisters> for kvm_regs {
fn from(regs: StandardRegisters) -> Self {
Self {
rax: regs.rax,
rbx: regs.rbx,
rcx: regs.rcx,
rdx: regs.rdx,
rsi: regs.rsi,
rdi: regs.rdi,
rsp: regs.rsp,
rbp: regs.rbp,
r8: regs.r8,
r9: regs.r9,
r10: regs.r10,
r11: regs.r11,
r12: regs.r12,
r13: regs.r13,
r14: regs.r14,
r15: regs.r15,
rip: regs.rip,
rflags: regs.rflags,
}
}
}
impl From<kvm_regs> for StandardRegisters {
fn from(regs: kvm_regs) -> Self {
Self {
rax: regs.rax,
rbx: regs.rbx,
rcx: regs.rcx,
rdx: regs.rdx,
rsi: regs.rsi,
rdi: regs.rdi,
rsp: regs.rsp,
rbp: regs.rbp,
r8: regs.r8,
r9: regs.r9,
r10: regs.r10,
r11: regs.r11,
r12: regs.r12,
r13: regs.r13,
r14: regs.r14,
r15: regs.r15,
rip: regs.rip,
rflags: regs.rflags,
}
}
}
impl From<SegmentRegister> for kvm_segment {
fn from(s: SegmentRegister) -> Self {
Self {
base: s.base,
limit: s.limit,
selector: s.selector,
type_: s.type_,
present: s.present,
dpl: s.dpl,
db: s.db,
s: s.s,
l: s.l,
g: s.g,
avl: s.avl,
unusable: s.unusable,
..Default::default()
}
}
}
impl From<kvm_segment> for SegmentRegister {
fn from(s: kvm_segment) -> Self {
Self {
base: s.base,
limit: s.limit,
selector: s.selector,
type_: s.type_,
present: s.present,
dpl: s.dpl,
db: s.db,
s: s.s,
l: s.l,
g: s.g,
avl: s.avl,
unusable: s.unusable,
}
}
}
impl From<DescriptorTable> for kvm_dtable {
fn from(dt: DescriptorTable) -> Self {
Self {
base: dt.base,
limit: dt.limit,
..Default::default()
}
}
}
impl From<kvm_dtable> for DescriptorTable {
fn from(dt: kvm_dtable) -> Self {
Self {
base: dt.base,
limit: dt.limit,
}
}
}
impl From<SpecialRegisters> for kvm_sregs {
fn from(s: SpecialRegisters) -> Self {
Self {
cs: s.cs.into(),
ds: s.ds.into(),
es: s.es.into(),
fs: s.fs.into(),
gs: s.gs.into(),
ss: s.ss.into(),
tr: s.tr.into(),
ldt: s.ldt.into(),
gdt: s.gdt.into(),
idt: s.idt.into(),
cr0: s.cr0,
cr2: s.cr2,
cr3: s.cr3,
cr4: s.cr4,
cr8: s.cr8,
efer: s.efer,
apic_base: s.apic_base,
interrupt_bitmap: s.interrupt_bitmap,
}
}
}
impl From<kvm_sregs> for SpecialRegisters {
fn from(s: kvm_sregs) -> Self {
Self {
cs: s.cs.into(),
ds: s.ds.into(),
es: s.es.into(),
fs: s.fs.into(),
gs: s.gs.into(),
ss: s.ss.into(),
tr: s.tr.into(),
ldt: s.ldt.into(),
gdt: s.gdt.into(),
idt: s.idt.into(),
cr0: s.cr0,
cr2: s.cr2,
cr3: s.cr3,
cr4: s.cr4,
cr8: s.cr8,
efer: s.efer,
apic_base: s.apic_base,
interrupt_bitmap: s.interrupt_bitmap,
}
}
}