mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
hypervisor, vmm: Fix aarch64 SVE register save/restore
When SVE is enabled, KVM replaces the FPSIMD V-registers with wider SVE Z-registers. Attempting to access the old FPSIMD offsets returns EINVAL. Fix by classifying each register from KVM_GET_REG_LIST as core, system, or extended. Extended registers (currently SVE only) are saved as generic `ExtendedReg` entries split into `pre_finalize_regs` (registers like SVE VLS that must be written before `vcpu_finalize`) and `extended_regs`. FPSIMD registers are only accessed when SVE is absent. Unrecognized register families error immediately so future extensions like SME fail clearly rather than silently losing state. The snapshot is deserialized before vCPU init to make pre-finalize register state available for the init -> VLS -> finalize ordering required by KVM. Signed-off-by: Ruben Hakobyan <hruben@meta.com>
This commit is contained in:
committed by
Rob Bradford
parent
e390f0bdc1
commit
5c25d82f59
@@ -18,6 +18,8 @@ use {anyhow::anyhow, vm_memory::GuestAddress};
|
||||
use crate::RegList;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use crate::VcpuInit;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use crate::arch::aarch64::ExtendedReg;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::arch::x86::{CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters};
|
||||
#[cfg(feature = "tdx")]
|
||||
@@ -221,6 +223,16 @@ pub enum HypervisorCpuError {
|
||||
#[error("Failed to set aarch64 core register")]
|
||||
SetAarchCoreRegister(#[source] anyhow::Error),
|
||||
///
|
||||
/// Getting extended register error
|
||||
///
|
||||
#[error("Failed to get extended register")]
|
||||
GetExtendedRegister(#[source] anyhow::Error),
|
||||
///
|
||||
/// Setting extended register error
|
||||
///
|
||||
#[error("Failed to set extended register")]
|
||||
SetExtendedRegister(#[source] anyhow::Error),
|
||||
///
|
||||
/// Getting RISC-V 64-bit core register error
|
||||
///
|
||||
#[error("Failed to get riscv64 core register")]
|
||||
@@ -460,6 +472,14 @@ pub trait Vcpu: Send + Sync {
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn vcpu_finalize(&self, feature: i32) -> Result<()>;
|
||||
///
|
||||
/// Sets pre-finalize registers (e.g. SVE VLS).
|
||||
/// Must be called after vcpu_init and before vcpu_finalize.
|
||||
///
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn set_pre_finalize_regs(&self, _regs: &[ExtendedReg]) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
///
|
||||
/// Gets the features that have been finalized for a given CPU.
|
||||
///
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
|
||||
Reference in New Issue
Block a user