mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-11-04 19:11:11 +00:00
hypervisor: provide a generic FpuState structure
Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
parent
08135fa085
commit
6a8c0fc887
@ -10,8 +10,7 @@ use crate::layout::{BOOT_GDT_START, BOOT_IDT_START, PVH_INFO_START};
|
|||||||
use crate::GuestMemoryMmap;
|
use crate::GuestMemoryMmap;
|
||||||
use hypervisor::arch::x86::gdt::{gdt_entry, segment_from_gdt};
|
use hypervisor::arch::x86::gdt::{gdt_entry, segment_from_gdt};
|
||||||
use hypervisor::arch::x86::regs::CR0_PE;
|
use hypervisor::arch::x86::regs::CR0_PE;
|
||||||
use hypervisor::arch::x86::{SpecialRegisters, StandardRegisters};
|
use hypervisor::arch::x86::{FpuState, SpecialRegisters, StandardRegisters};
|
||||||
use hypervisor::x86_64::FpuState;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{mem, result};
|
use std::{mem, result};
|
||||||
use vm_memory::{Address, Bytes, GuestMemory, GuestMemoryError};
|
use vm_memory::{Address, Bytes, GuestMemory, GuestMemoryError};
|
||||||
|
@ -241,3 +241,16 @@ pub struct CpuIdEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const CPUID_FLAG_VALID_INDEX: u32 = 1;
|
pub const CPUID_FLAG_VALID_INDEX: u32 = 1;
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub struct FpuState {
|
||||||
|
pub fpr: [[u8; 16usize]; 8usize],
|
||||||
|
pub fcw: u16,
|
||||||
|
pub fsw: u16,
|
||||||
|
pub ftwx: u8,
|
||||||
|
pub last_opcode: u16,
|
||||||
|
pub last_ip: u64,
|
||||||
|
pub last_dp: u64,
|
||||||
|
pub xmm: [[u8; 16usize]; 16usize],
|
||||||
|
pub mxcsr: u32,
|
||||||
|
}
|
||||||
|
@ -13,7 +13,7 @@ use crate::aarch64::VcpuInit;
|
|||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use crate::aarch64::{RegList, Register, StandardRegisters};
|
use crate::aarch64::{RegList, Register, StandardRegisters};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::arch::x86::{CpuIdEntry, SpecialRegisters, StandardRegisters};
|
use crate::arch::x86::{CpuIdEntry, FpuState, SpecialRegisters, StandardRegisters};
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
use crate::kvm::{TdxExitDetails, TdxExitStatus};
|
use crate::kvm::{TdxExitDetails, TdxExitStatus};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -21,7 +21,7 @@ use crate::x86_64::LapicState;
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::x86_64::Xsave;
|
use crate::x86_64::Xsave;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::x86_64::{ExtendedControlRegisters, FpuState, MsrEntries, VcpuEvents};
|
use crate::x86_64::{ExtendedControlRegisters, MsrEntries, VcpuEvents};
|
||||||
use crate::CpuState;
|
use crate::CpuState;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use crate::DeviceAttr;
|
use crate::DeviceAttr;
|
||||||
|
@ -46,7 +46,9 @@ use vmm_sys_util::eventfd::EventFd;
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub mod x86_64;
|
pub mod x86_64;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::arch::x86::{CpuIdEntry, SpecialRegisters, StandardRegisters, NUM_IOAPIC_PINS};
|
use crate::arch::x86::{
|
||||||
|
CpuIdEntry, FpuState, SpecialRegisters, StandardRegisters, NUM_IOAPIC_PINS,
|
||||||
|
};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::ClockData;
|
use crate::ClockData;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -61,7 +63,7 @@ use kvm_bindings::{
|
|||||||
KVM_CAP_SPLIT_IRQCHIP, KVM_GUESTDBG_ENABLE, KVM_GUESTDBG_SINGLESTEP, KVM_GUESTDBG_USE_HW_BP,
|
KVM_CAP_SPLIT_IRQCHIP, KVM_GUESTDBG_ENABLE, KVM_GUESTDBG_SINGLESTEP, KVM_GUESTDBG_USE_HW_BP,
|
||||||
};
|
};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use x86_64::{check_required_kvm_extensions, FpuState};
|
use x86_64::check_required_kvm_extensions;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub use x86_64::{CpuId, ExtendedControlRegisters, LapicState, MsrEntries, VcpuKvmState, Xsave};
|
pub use x86_64::{CpuId, ExtendedControlRegisters, LapicState, MsrEntries, VcpuKvmState, Xsave};
|
||||||
// aarch64 dependencies
|
// aarch64 dependencies
|
||||||
@ -1306,17 +1308,20 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
/// Returns the floating point state (FPU) from the vCPU.
|
/// Returns the floating point state (FPU) from the vCPU.
|
||||||
///
|
///
|
||||||
fn get_fpu(&self) -> cpu::Result<FpuState> {
|
fn get_fpu(&self) -> cpu::Result<FpuState> {
|
||||||
self.fd
|
Ok(self
|
||||||
|
.fd
|
||||||
.get_fpu()
|
.get_fpu()
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetFloatingPointRegs(e.into()))
|
.map_err(|e| cpu::HypervisorCpuError::GetFloatingPointRegs(e.into()))?
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
///
|
///
|
||||||
/// Set the floating point state (FPU) of a vCPU using the `KVM_SET_FPU` ioct.
|
/// Set the floating point state (FPU) of a vCPU using the `KVM_SET_FPU` ioct.
|
||||||
///
|
///
|
||||||
fn set_fpu(&self, fpu: &FpuState) -> cpu::Result<()> {
|
fn set_fpu(&self, fpu: &FpuState) -> cpu::Result<()> {
|
||||||
|
let fpu: kvm_bindings::kvm_fpu = (*fpu).clone().into();
|
||||||
self.fd
|
self.fd
|
||||||
.set_fpu(fpu)
|
.set_fpu(&fpu)
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetFloatingPointRegs(e.into()))
|
.map_err(|e| cpu::HypervisorCpuError::SetFloatingPointRegs(e.into()))
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
use crate::arch::x86::{
|
use crate::arch::x86::{
|
||||||
CpuIdEntry, DescriptorTable, SegmentRegister, SpecialRegisters, StandardRegisters,
|
CpuIdEntry, DescriptorTable, FpuState, SegmentRegister, SpecialRegisters, StandardRegisters,
|
||||||
CPUID_FLAG_VALID_INDEX,
|
CPUID_FLAG_VALID_INDEX,
|
||||||
};
|
};
|
||||||
use crate::kvm::{Cap, Kvm, KvmError, KvmResult};
|
use crate::kvm::{Cap, Kvm, KvmError, KvmResult};
|
||||||
@ -19,7 +19,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
/// Export generically-named wrappers of kvm-bindings for Unix-based platforms
|
/// Export generically-named wrappers of kvm-bindings for Unix-based platforms
|
||||||
///
|
///
|
||||||
pub use {
|
pub use {
|
||||||
kvm_bindings::kvm_cpuid_entry2, kvm_bindings::kvm_dtable, kvm_bindings::kvm_fpu as FpuState,
|
kvm_bindings::kvm_cpuid_entry2, kvm_bindings::kvm_dtable, kvm_bindings::kvm_fpu,
|
||||||
kvm_bindings::kvm_lapic_state as LapicState, kvm_bindings::kvm_mp_state as MpState,
|
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_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_sregs, kvm_bindings::kvm_vcpu_events as VcpuEvents,
|
||||||
@ -262,3 +262,36 @@ impl From<kvm_cpuid_entry2> for CpuIdEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<kvm_fpu> for FpuState {
|
||||||
|
fn from(s: kvm_fpu) -> Self {
|
||||||
|
Self {
|
||||||
|
fpr: s.fpr,
|
||||||
|
fcw: s.fcw,
|
||||||
|
fsw: s.fsw,
|
||||||
|
ftwx: s.ftwx,
|
||||||
|
last_opcode: s.last_opcode,
|
||||||
|
last_ip: s.last_ip,
|
||||||
|
last_dp: s.last_dp,
|
||||||
|
xmm: s.xmm,
|
||||||
|
mxcsr: s.mxcsr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<FpuState> for kvm_fpu {
|
||||||
|
fn from(s: FpuState) -> Self {
|
||||||
|
Self {
|
||||||
|
fpr: s.fpr,
|
||||||
|
fcw: s.fcw,
|
||||||
|
fsw: s.fsw,
|
||||||
|
ftwx: s.ftwx,
|
||||||
|
last_opcode: s.last_opcode,
|
||||||
|
last_ip: s.last_ip,
|
||||||
|
last_dp: s.last_dp,
|
||||||
|
xmm: s.xmm,
|
||||||
|
mxcsr: s.mxcsr,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -37,7 +37,7 @@ use std::fs::File;
|
|||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::arch::x86::{CpuIdEntry, SpecialRegisters, StandardRegisters};
|
use crate::arch::x86::{CpuIdEntry, FpuState, SpecialRegisters, StandardRegisters};
|
||||||
|
|
||||||
const DIRTY_BITMAP_CLEAR_DIRTY: u64 = 0x4;
|
const DIRTY_BITMAP_CLEAR_DIRTY: u64 = 0x4;
|
||||||
const DIRTY_BITMAP_SET_DIRTY: u64 = 0x8;
|
const DIRTY_BITMAP_SET_DIRTY: u64 = 0x8;
|
||||||
@ -317,17 +317,20 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
/// Returns the floating point state (FPU) from the vCPU.
|
/// Returns the floating point state (FPU) from the vCPU.
|
||||||
///
|
///
|
||||||
fn get_fpu(&self) -> cpu::Result<FpuState> {
|
fn get_fpu(&self) -> cpu::Result<FpuState> {
|
||||||
self.fd
|
Ok(self
|
||||||
|
.fd
|
||||||
.get_fpu()
|
.get_fpu()
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetFloatingPointRegs(e.into()))
|
.map_err(|e| cpu::HypervisorCpuError::GetFloatingPointRegs(e.into()))?
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
///
|
///
|
||||||
/// Set the floating point state (FPU) of a vCPU.
|
/// Set the floating point state (FPU) of a vCPU.
|
||||||
///
|
///
|
||||||
fn set_fpu(&self, fpu: &FpuState) -> cpu::Result<()> {
|
fn set_fpu(&self, fpu: &FpuState) -> cpu::Result<()> {
|
||||||
|
let fpu: mshv_bindings::FloatingPointUnit = (*fpu).clone().into();
|
||||||
self.fd
|
self.fd
|
||||||
.set_fpu(fpu)
|
.set_fpu(&fpu)
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetFloatingPointRegs(e.into()))
|
.map_err(|e| cpu::HypervisorCpuError::SetFloatingPointRegs(e.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
//
|
//
|
||||||
use crate::arch::x86::{
|
use crate::arch::x86::{
|
||||||
CpuIdEntry, DescriptorTable, SegmentRegister, SpecialRegisters, StandardRegisters,
|
CpuIdEntry, DescriptorTable, FpuState, SegmentRegister, SpecialRegisters, StandardRegisters,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -19,7 +19,7 @@ use std::fmt;
|
|||||||
pub use {
|
pub use {
|
||||||
mshv_bindings::hv_cpuid_entry, mshv_bindings::mshv_user_mem_region as MemoryRegion,
|
mshv_bindings::hv_cpuid_entry, mshv_bindings::mshv_user_mem_region as MemoryRegion,
|
||||||
mshv_bindings::msr_entry as MsrEntry, mshv_bindings::CpuId, mshv_bindings::DebugRegisters,
|
mshv_bindings::msr_entry as MsrEntry, mshv_bindings::CpuId, mshv_bindings::DebugRegisters,
|
||||||
mshv_bindings::FloatingPointUnit as FpuState, mshv_bindings::LapicState,
|
mshv_bindings::FloatingPointUnit, mshv_bindings::LapicState,
|
||||||
mshv_bindings::MiscRegs as MiscRegisters, mshv_bindings::MsrList,
|
mshv_bindings::MiscRegs as MiscRegisters, mshv_bindings::MsrList,
|
||||||
mshv_bindings::Msrs as MsrEntries, mshv_bindings::Msrs,
|
mshv_bindings::Msrs as MsrEntries, mshv_bindings::Msrs,
|
||||||
mshv_bindings::SegmentRegister as MshvSegmentRegister,
|
mshv_bindings::SegmentRegister as MshvSegmentRegister,
|
||||||
@ -252,3 +252,36 @@ impl From<hv_cpuid_entry> for CpuIdEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<FloatingPointUnit> for FpuState {
|
||||||
|
fn from(s: FloatingPointUnit) -> Self {
|
||||||
|
Self {
|
||||||
|
fpr: s.fpr,
|
||||||
|
fcw: s.fcw,
|
||||||
|
fsw: s.fsw,
|
||||||
|
ftwx: s.ftwx,
|
||||||
|
last_opcode: s.last_opcode,
|
||||||
|
last_ip: s.last_ip,
|
||||||
|
last_dp: s.last_dp,
|
||||||
|
xmm: s.xmm,
|
||||||
|
mxcsr: s.mxcsr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<FpuState> for FloatingPointUnit {
|
||||||
|
fn from(s: FpuState) -> Self {
|
||||||
|
Self {
|
||||||
|
fpr: s.fpr,
|
||||||
|
fcw: s.fcw,
|
||||||
|
fsw: s.fsw,
|
||||||
|
ftwx: s.ftwx,
|
||||||
|
last_opcode: s.last_opcode,
|
||||||
|
last_ip: s.last_ip,
|
||||||
|
last_dp: s.last_dp,
|
||||||
|
xmm: s.xmm,
|
||||||
|
mxcsr: s.mxcsr,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2336,8 +2336,8 @@ impl CpuElf64Writable for CpuManager {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use arch::x86_64::interrupts::*;
|
use arch::x86_64::interrupts::*;
|
||||||
use arch::x86_64::regs::*;
|
use arch::x86_64::regs::*;
|
||||||
use hypervisor::arch::x86::StandardRegisters;
|
use hypervisor::arch::x86::{FpuState, StandardRegisters};
|
||||||
use hypervisor::x86_64::{FpuState, LapicState};
|
use hypervisor::x86_64::LapicState;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_setlint() {
|
fn test_setlint() {
|
||||||
|
Loading…
Reference in New Issue
Block a user