mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
hypervisor: aarch64: Use offset_of for nested fields
`std::mem::offset_of` could be used for calculating nested fields, use this feature to shorten aarch64 reg offset calculation. Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
This commit is contained in:
@@ -95,10 +95,10 @@ pub use kvm_bindings::{
|
|||||||
};
|
};
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use kvm_bindings::{
|
use kvm_bindings::{
|
||||||
kvm_regs, user_fpsimd_state, user_pt_regs, KVM_GUESTDBG_USE_HW, KVM_NR_SPSR, KVM_REG_ARM64,
|
kvm_regs, user_pt_regs, KVM_GUESTDBG_USE_HW, KVM_NR_SPSR, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG,
|
||||||
KVM_REG_ARM64_SYSREG, KVM_REG_ARM64_SYSREG_CRM_MASK, KVM_REG_ARM64_SYSREG_CRN_MASK,
|
KVM_REG_ARM64_SYSREG_CRM_MASK, KVM_REG_ARM64_SYSREG_CRN_MASK, KVM_REG_ARM64_SYSREG_OP0_MASK,
|
||||||
KVM_REG_ARM64_SYSREG_OP0_MASK, KVM_REG_ARM64_SYSREG_OP1_MASK, KVM_REG_ARM64_SYSREG_OP2_MASK,
|
KVM_REG_ARM64_SYSREG_OP1_MASK, KVM_REG_ARM64_SYSREG_OP2_MASK, KVM_REG_ARM_CORE,
|
||||||
KVM_REG_ARM_CORE, KVM_REG_SIZE_U128, KVM_REG_SIZE_U32, KVM_REG_SIZE_U64,
|
KVM_REG_SIZE_U128, KVM_REG_SIZE_U32, KVM_REG_SIZE_U64,
|
||||||
};
|
};
|
||||||
#[cfg(target_arch = "riscv64")]
|
#[cfg(target_arch = "riscv64")]
|
||||||
use kvm_bindings::{kvm_riscv_core, KVM_REG_RISCV_CORE};
|
use kvm_bindings::{kvm_riscv_core, KVM_REG_RISCV_CORE};
|
||||||
@@ -1440,7 +1440,7 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
|
|
||||||
// Now moving on to floating point registers which are stored in the user_fpsimd_state in the kernel:
|
// Now moving on to floating point registers which are stored in the user_fpsimd_state in the kernel:
|
||||||
// https://elixir.free-electrons.com/linux/v4.9.62/source/arch/arm64/include/uapi/asm/kvm.h#L53
|
// https://elixir.free-electrons.com/linux/v4.9.62/source/arch/arm64/include/uapi/asm/kvm.h#L53
|
||||||
let mut off = offset_of!(kvm_regs, fp_regs) + offset_of!(user_fpsimd_state, vregs);
|
let mut off = offset_of!(kvm_regs, fp_regs.vregs);
|
||||||
for i in 0..32 {
|
for i in 0..32 {
|
||||||
let mut bytes = [0_u8; 16];
|
let mut bytes = [0_u8; 16];
|
||||||
self.fd
|
self.fd
|
||||||
@@ -1453,7 +1453,7 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Floating-point Status Register
|
// Floating-point Status Register
|
||||||
let off = offset_of!(kvm_regs, fp_regs) + offset_of!(user_fpsimd_state, fpsr);
|
let off = offset_of!(kvm_regs, fp_regs.fpsr);
|
||||||
let mut bytes = [0_u8; 4];
|
let mut bytes = [0_u8; 4];
|
||||||
self.fd
|
self.fd
|
||||||
.lock()
|
.lock()
|
||||||
@@ -1463,7 +1463,7 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
state.fp_regs.fpsr = u32::from_le_bytes(bytes);
|
state.fp_regs.fpsr = u32::from_le_bytes(bytes);
|
||||||
|
|
||||||
// Floating-point Control Register
|
// Floating-point Control Register
|
||||||
let off = offset_of!(kvm_regs, fp_regs) + offset_of!(user_fpsimd_state, fpcr);
|
let off = offset_of!(kvm_regs, fp_regs.fpcr);
|
||||||
let mut bytes = [0_u8; 4];
|
let mut bytes = [0_u8; 4];
|
||||||
self.fd
|
self.fd
|
||||||
.lock()
|
.lock()
|
||||||
@@ -1644,7 +1644,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) + offset_of!(user_fpsimd_state, vregs);
|
let mut off = offset_of!(kvm_regs, fp_regs.vregs);
|
||||||
for i in 0..32 {
|
for i in 0..32 {
|
||||||
self.fd
|
self.fd
|
||||||
.lock()
|
.lock()
|
||||||
@@ -1657,7 +1657,7 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
off += mem::size_of::<u128>();
|
off += mem::size_of::<u128>();
|
||||||
}
|
}
|
||||||
|
|
||||||
let off = offset_of!(kvm_regs, fp_regs) + offset_of!(user_fpsimd_state, fpsr);
|
let off = offset_of!(kvm_regs, fp_regs.fpsr);
|
||||||
self.fd
|
self.fd
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -1667,7 +1667,7 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
)
|
)
|
||||||
.map_err(|e| cpu::HypervisorCpuError::SetAarchCoreRegister(e.into()))?;
|
.map_err(|e| cpu::HypervisorCpuError::SetAarchCoreRegister(e.into()))?;
|
||||||
|
|
||||||
let off = offset_of!(kvm_regs, fp_regs) + offset_of!(user_fpsimd_state, fpcr);
|
let off = offset_of!(kvm_regs, fp_regs.fpcr);
|
||||||
self.fd
|
self.fd
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -2281,10 +2281,8 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
///
|
///
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
fn setup_regs(&self, cpu_id: u8, boot_ip: u64, fdt_start: u64) -> cpu::Result<()> {
|
fn setup_regs(&self, cpu_id: u8, boot_ip: u64, fdt_start: u64) -> cpu::Result<()> {
|
||||||
let kreg_off = offset_of!(kvm_regs, regs);
|
|
||||||
|
|
||||||
// Get the register index of the PSTATE (Processor State) register.
|
// Get the register index of the PSTATE (Processor State) register.
|
||||||
let pstate = offset_of!(user_pt_regs, pstate) + kreg_off;
|
let pstate = offset_of!(kvm_regs, regs.pstate);
|
||||||
self.fd
|
self.fd
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -2297,7 +2295,7 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
// Other vCPUs are powered off initially awaiting PSCI wakeup.
|
// Other vCPUs are powered off initially awaiting PSCI wakeup.
|
||||||
if cpu_id == 0 {
|
if cpu_id == 0 {
|
||||||
// Setting the PC (Processor Counter) to the current program address (kernel address).
|
// Setting the PC (Processor Counter) to the current program address (kernel address).
|
||||||
let pc = offset_of!(user_pt_regs, pc) + kreg_off;
|
let pc = offset_of!(kvm_regs, regs.pc);
|
||||||
self.fd
|
self.fd
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -2311,7 +2309,7 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
// "The device tree blob (dtb) must be placed on an 8-byte boundary and must
|
// "The device tree blob (dtb) must be placed on an 8-byte boundary and must
|
||||||
// not exceed 2 megabytes in size." -> https://www.kernel.org/doc/Documentation/arm64/booting.txt.
|
// not exceed 2 megabytes in size." -> https://www.kernel.org/doc/Documentation/arm64/booting.txt.
|
||||||
// We are choosing to place it the end of DRAM. See `get_fdt_addr`.
|
// We are choosing to place it the end of DRAM. See `get_fdt_addr`.
|
||||||
let regs0 = offset_of!(user_pt_regs, regs) + kreg_off;
|
let regs0 = offset_of!(kvm_regs, regs.regs);
|
||||||
self.fd
|
self.fd
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|||||||
@@ -2963,19 +2963,19 @@ mod tests {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#[cfg(feature = "kvm")]
|
#[cfg(feature = "kvm")]
|
||||||
use std::mem;
|
use std::{mem, mem::offset_of};
|
||||||
|
|
||||||
use arch::layout;
|
use arch::layout;
|
||||||
use hypervisor::arch::aarch64::regs::MPIDR_EL1;
|
use hypervisor::arch::aarch64::regs::MPIDR_EL1;
|
||||||
#[cfg(feature = "kvm")]
|
#[cfg(feature = "kvm")]
|
||||||
|
use hypervisor::arm64_core_reg_id;
|
||||||
|
#[cfg(feature = "kvm")]
|
||||||
use hypervisor::kvm::aarch64::is_system_register;
|
use hypervisor::kvm::aarch64::is_system_register;
|
||||||
#[cfg(feature = "kvm")]
|
#[cfg(feature = "kvm")]
|
||||||
use hypervisor::kvm::kvm_bindings::{
|
use hypervisor::kvm::kvm_bindings::{
|
||||||
user_pt_regs, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG, KVM_REG_ARM_CORE, KVM_REG_SIZE_U64,
|
user_pt_regs, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG, KVM_REG_ARM_CORE, KVM_REG_SIZE_U64,
|
||||||
};
|
};
|
||||||
use hypervisor::HypervisorCpuError;
|
use hypervisor::HypervisorCpuError;
|
||||||
#[cfg(feature = "kvm")]
|
|
||||||
use hypervisor::{arm64_core_reg_id, offset_of};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_setup_regs() {
|
fn test_setup_regs() {
|
||||||
|
|||||||
Reference in New Issue
Block a user