mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-28 17:44:10 +00:00
x86_64: move Fpu initialization to vcpu_init
Implement Default for Fpu to initialize the floating point registers to their officially documented reset values, and use the default Fpu values to initialize all VCPU floating point state. These are the same values as used in the previous setup_fpu() function, so there is no change in behavior. (We now set the FPU state for both BIOS and non-BIOS, but since the FPU values should match the ones used at CPU reset, it should not cause any actual behavior change.) BUG=b:237095693 TEST=boot x86-64 Linux kernel Change-Id: I4eb656822d8fa4730203970aee178043c19af9ff Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3723799 Reviewed-by: Alexandre Courbot <acourbot@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
parent
1b7d5b8fba
commit
e30f4fda83
4 changed files with 28 additions and 24 deletions
|
@ -176,6 +176,9 @@ pub(crate) fn host_phys_addr_bits() -> u8 {
|
|||
pub struct VcpuInitX86_64 {
|
||||
/// General-purpose registers.
|
||||
pub regs: Regs,
|
||||
|
||||
/// Floating-point registers.
|
||||
pub fpu: Fpu,
|
||||
}
|
||||
|
||||
/// A CpuId Entry contains supported feature information for the given processor.
|
||||
|
@ -651,7 +654,7 @@ pub struct Sregs {
|
|||
|
||||
/// State of a VCPU's floating point unit.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Default, Copy, Clone)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Fpu {
|
||||
pub fpr: [[u8; 16usize]; 8usize],
|
||||
pub fcw: u16,
|
||||
|
@ -664,6 +667,22 @@ pub struct Fpu {
|
|||
pub mxcsr: u32,
|
||||
}
|
||||
|
||||
impl Default for Fpu {
|
||||
fn default() -> Self {
|
||||
Fpu {
|
||||
fpr: Default::default(),
|
||||
fcw: 0x37f, // Intel SDM Vol. 1, 13.6
|
||||
fsw: 0,
|
||||
ftwx: 0,
|
||||
last_opcode: 0,
|
||||
last_ip: 0,
|
||||
last_dp: 0,
|
||||
xmm: Default::default(),
|
||||
mxcsr: 0x1f80, // Intel SDM Vol. 1, 11.6.4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// State of a VCPU's debug registers.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Default, Copy, Clone)]
|
||||
|
|
|
@ -184,7 +184,7 @@ pub enum Error {
|
|||
#[error("failed to set up cpuid: {0}")]
|
||||
SetupCpuid(cpuid::Error),
|
||||
#[error("failed to set up FPU: {0}")]
|
||||
SetupFpu(regs::Error),
|
||||
SetupFpu(base::Error),
|
||||
#[error("failed to set up guest memory: {0}")]
|
||||
SetupGuestMemory(GuestMemoryError),
|
||||
#[error("failed to set up mptable: {0}")]
|
||||
|
@ -788,6 +788,8 @@ impl arch::LinuxArch for X8664arch {
|
|||
.map_err(Error::SetupCpuid)?;
|
||||
}
|
||||
|
||||
vcpu.set_fpu(&vcpu_init.fpu).map_err(Error::SetupFpu)?;
|
||||
|
||||
if has_bios {
|
||||
regs::set_reset_vector(vcpu).map_err(Error::SetupRegs)?;
|
||||
regs::reset_msrs(vcpu).map_err(Error::SetupMsrs)?;
|
||||
|
@ -797,7 +799,6 @@ impl arch::LinuxArch for X8664arch {
|
|||
let guest_mem = vm.get_memory();
|
||||
regs::setup_msrs(vm, vcpu, read_pci_mmio_before_32bit().start).map_err(Error::SetupMsrs)?;
|
||||
vcpu.set_regs(&vcpu_init.regs).map_err(Error::WriteRegs)?;
|
||||
regs::setup_fpu(vcpu).map_err(Error::SetupFpu)?;
|
||||
regs::setup_sregs(guest_mem, vcpu).map_err(Error::SetupSregs)?;
|
||||
interrupts::set_lint(vcpu_id, irq_chip).map_err(Error::SetLint)?;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
use std::{mem, result};
|
||||
|
||||
use base::{self, warn};
|
||||
use hypervisor::{Fpu, Register, Sregs, VcpuX86_64, Vm};
|
||||
use hypervisor::{Register, Sregs, VcpuX86_64, Vm};
|
||||
use remain::sorted;
|
||||
use thiserror::Error;
|
||||
use vm_memory::{GuestAddress, GuestMemory};
|
||||
|
@ -15,9 +15,6 @@ use crate::gdt;
|
|||
#[sorted]
|
||||
#[derive(Error, Debug)]
|
||||
pub enum Error {
|
||||
/// Failed to configure the FPU.
|
||||
#[error("failed to configure the FPU: {0}")]
|
||||
FpuIoctlFailed(base::Error),
|
||||
/// Failed to get sregs for this cpu.
|
||||
#[error("failed to get sregs for this cpu: {0}")]
|
||||
GetSRegsIoctlFailed(base::Error),
|
||||
|
@ -204,21 +201,6 @@ pub fn setup_msrs(vm: &dyn Vm, vcpu: &dyn VcpuX86_64, pci_start: u64) -> Result<
|
|||
vcpu.set_msrs(&msrs).map_err(Error::MsrIoctlFailed)
|
||||
}
|
||||
|
||||
/// Configure FPU registers for x86
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `vcpu` - Structure for the vcpu that holds the vcpu fd.
|
||||
pub fn setup_fpu(vcpu: &dyn VcpuX86_64) -> Result<()> {
|
||||
let fpu = Fpu {
|
||||
fcw: 0x37f,
|
||||
mxcsr: 0x1f80,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
vcpu.set_fpu(&fpu).map_err(Error::FpuIoctlFailed)
|
||||
}
|
||||
|
||||
const X86_CR0_PE: u64 = 0x1;
|
||||
const X86_CR0_PG: u64 = 0x80000000;
|
||||
const X86_CR4_PAE: u64 = 0x20;
|
||||
|
|
|
@ -21,7 +21,7 @@ use vm_memory::{GuestAddress, GuestMemory};
|
|||
|
||||
use super::cpuid::setup_cpuid;
|
||||
use super::interrupts::set_lint;
|
||||
use super::regs::{setup_fpu, setup_msrs, setup_sregs};
|
||||
use super::regs::{setup_msrs, setup_sregs};
|
||||
use super::X8664arch;
|
||||
use super::{
|
||||
acpi, arch_memory_regions, bootparam, init_low_memory_layout, mptable,
|
||||
|
@ -265,7 +265,9 @@ where
|
|||
vcpu_regs.rcx = 0x0;
|
||||
vcpu.set_regs(&vcpu_regs).expect("set regs failed");
|
||||
|
||||
setup_fpu(&vcpu).unwrap();
|
||||
let vcpu_fpu_regs = Default::default();
|
||||
vcpu.set_fpu(&vcpu_fpu_regs).expect("set fpu regs failed");
|
||||
|
||||
setup_sregs(&guest_mem, &vcpu).unwrap();
|
||||
set_lint(0, &mut irq_chip).unwrap();
|
||||
|
||||
|
|
Loading…
Reference in a new issue