mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
hypervisor: Extract FPSIMD register access into helper methods
Move the inline FPSIMD register read/write code from `get_regs()` and
`set_regs()` into dedicated `get_fpsimd_regs()` and `set_fpsimd_regs()`
methods on `KvmVcpu`.
This helps keep the larger `{get,set}_regs()` easier to understand and
prepares them for a subsequent commit that needs to conditionally
skip FPSIMD access when SVE registers are used instead.
Signed-off-by: Ruben Hakobyan <hruben@meta.com>
This commit is contained in:
committed by
Rob Bradford
parent
2b61bda35a
commit
177d8b80e2
@@ -1895,33 +1895,7 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
off += std::mem::size_of::<u64>();
|
off += std::mem::size_of::<u64>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now moving on to floating point registers which are stored in the user_fpsimd_state in the kernel:
|
self.get_fpsimd_regs(&mut state)?;
|
||||||
// https://elixir.bootlin.com/linux/v4.9.62/source/arch/arm64/include/uapi/asm/kvm.h#L53
|
|
||||||
let mut off = offset_of!(kvm_regs, fp_regs.vregs);
|
|
||||||
for i in 0..32 {
|
|
||||||
let mut bytes = [0_u8; 16];
|
|
||||||
self.fd
|
|
||||||
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U128, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetAarchCoreRegister(e.into()))?;
|
|
||||||
state.fp_regs.vregs[i] = u128::from_le_bytes(bytes);
|
|
||||||
off += mem::size_of::<u128>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Floating-point Status Register
|
|
||||||
let off = offset_of!(kvm_regs, fp_regs.fpsr);
|
|
||||||
let mut bytes = [0_u8; 4];
|
|
||||||
self.fd
|
|
||||||
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U32, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetAarchCoreRegister(e.into()))?;
|
|
||||||
state.fp_regs.fpsr = u32::from_le_bytes(bytes);
|
|
||||||
|
|
||||||
// Floating-point Control Register
|
|
||||||
let off = offset_of!(kvm_regs, fp_regs.fpcr);
|
|
||||||
let mut bytes = [0_u8; 4];
|
|
||||||
self.fd
|
|
||||||
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U32, off), &mut bytes)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::GetAarchCoreRegister(e.into()))?;
|
|
||||||
state.fp_regs.fpcr = u32::from_le_bytes(bytes);
|
|
||||||
Ok(state.into())
|
Ok(state.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2075,32 +2049,7 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
off += std::mem::size_of::<u64>();
|
off += std::mem::size_of::<u64>();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut off = offset_of!(kvm_regs, fp_regs.vregs);
|
self.set_fpsimd_regs(&kvm_regs_state)?;
|
||||||
for i in 0..32 {
|
|
||||||
self.fd
|
|
||||||
.set_one_reg(
|
|
||||||
arm64_core_reg_id!(KVM_REG_SIZE_U128, off),
|
|
||||||
&kvm_regs_state.fp_regs.vregs[i].to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetAarchCoreRegister(e.into()))?;
|
|
||||||
off += mem::size_of::<u128>();
|
|
||||||
}
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_regs, fp_regs.fpsr);
|
|
||||||
self.fd
|
|
||||||
.set_one_reg(
|
|
||||||
arm64_core_reg_id!(KVM_REG_SIZE_U32, off),
|
|
||||||
&kvm_regs_state.fp_regs.fpsr.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetAarchCoreRegister(e.into()))?;
|
|
||||||
|
|
||||||
let off = offset_of!(kvm_regs, fp_regs.fpcr);
|
|
||||||
self.fd
|
|
||||||
.set_one_reg(
|
|
||||||
arm64_core_reg_id!(KVM_REG_SIZE_U32, off),
|
|
||||||
&kvm_regs_state.fp_regs.fpcr.to_le_bytes(),
|
|
||||||
)
|
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetAarchCoreRegister(e.into()))?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3454,6 +3403,76 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
impl KvmVcpu {
|
||||||
|
fn get_fpsimd_regs(&self, regs: &mut kvm_regs) -> cpu::Result<()> {
|
||||||
|
// Floating point registers are stored in the user_fpsimd_state in the kernel:
|
||||||
|
// https://elixir.bootlin.com/linux/v4.9.62/source/arch/arm64/include/uapi/asm/kvm.h#L53
|
||||||
|
let mut off = offset_of!(kvm_regs, fp_regs.vregs);
|
||||||
|
for i in 0..32 {
|
||||||
|
let mut bytes = [0_u8; 16];
|
||||||
|
self.fd
|
||||||
|
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U128, off), &mut bytes)
|
||||||
|
.map_err(|e| cpu::HypervisorCpuError::GetAarchCoreRegister(e.into()))?;
|
||||||
|
regs.fp_regs.vregs[i] = u128::from_le_bytes(bytes);
|
||||||
|
off += mem::size_of::<u128>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Floating-point Status Register
|
||||||
|
let off = offset_of!(kvm_regs, fp_regs.fpsr);
|
||||||
|
let mut bytes = [0_u8; 4];
|
||||||
|
self.fd
|
||||||
|
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U32, off), &mut bytes)
|
||||||
|
.map_err(|e| cpu::HypervisorCpuError::GetAarchCoreRegister(e.into()))?;
|
||||||
|
regs.fp_regs.fpsr = u32::from_le_bytes(bytes);
|
||||||
|
|
||||||
|
// Floating-point Control Register
|
||||||
|
let off = offset_of!(kvm_regs, fp_regs.fpcr);
|
||||||
|
let mut bytes = [0_u8; 4];
|
||||||
|
self.fd
|
||||||
|
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U32, off), &mut bytes)
|
||||||
|
.map_err(|e| cpu::HypervisorCpuError::GetAarchCoreRegister(e.into()))?;
|
||||||
|
regs.fp_regs.fpcr = u32::from_le_bytes(bytes);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_fpsimd_regs(&self, regs: &kvm_regs) -> cpu::Result<()> {
|
||||||
|
// Floating point registers are stored in the user_fpsimd_state in the kernel:
|
||||||
|
// https://elixir.bootlin.com/linux/v4.9.62/source/arch/arm64/include/uapi/asm/kvm.h#L53
|
||||||
|
let mut off = offset_of!(kvm_regs, fp_regs.vregs);
|
||||||
|
for i in 0..32 {
|
||||||
|
self.fd
|
||||||
|
.set_one_reg(
|
||||||
|
arm64_core_reg_id!(KVM_REG_SIZE_U128, off),
|
||||||
|
®s.fp_regs.vregs[i].to_le_bytes(),
|
||||||
|
)
|
||||||
|
.map_err(|e| cpu::HypervisorCpuError::SetAarchCoreRegister(e.into()))?;
|
||||||
|
off += mem::size_of::<u128>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Floating-point Status Register
|
||||||
|
let off = offset_of!(kvm_regs, fp_regs.fpsr);
|
||||||
|
self.fd
|
||||||
|
.set_one_reg(
|
||||||
|
arm64_core_reg_id!(KVM_REG_SIZE_U32, off),
|
||||||
|
®s.fp_regs.fpsr.to_le_bytes(),
|
||||||
|
)
|
||||||
|
.map_err(|e| cpu::HypervisorCpuError::SetAarchCoreRegister(e.into()))?;
|
||||||
|
|
||||||
|
// Floating-point Control Register
|
||||||
|
let off = offset_of!(kvm_regs, fp_regs.fpcr);
|
||||||
|
self.fd
|
||||||
|
.set_one_reg(
|
||||||
|
arm64_core_reg_id!(KVM_REG_SIZE_U32, off),
|
||||||
|
®s.fp_regs.fpcr.to_le_bytes(),
|
||||||
|
)
|
||||||
|
.map_err(|e| cpu::HypervisorCpuError::SetAarchCoreRegister(e.into()))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl KvmVcpu {
|
impl KvmVcpu {
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
///
|
///
|
||||||
|
|||||||
Reference in New Issue
Block a user