From ba262e45a4bf9166a5096be1bff28922cab148a5 Mon Sep 17 00:00:00 2001 From: Jinank Jain Date: Wed, 28 Aug 2024 11:08:08 +0000 Subject: [PATCH] hypervisor: vmm: Switch to common StandardRegisters implementation Use the StandardRegisters defined in the hypervisor crate instead of re-defining it from MSHV/KVM crate. Signed-off-by: Jinank Jain --- hypervisor/src/cpu.rs | 3 +-- hypervisor/src/kvm/mod.rs | 32 ++++++++++++++++---------------- vmm/src/cpu.rs | 24 +++++++++++------------- 3 files changed, 28 insertions(+), 31 deletions(-) diff --git a/hypervisor/src/cpu.rs b/hypervisor/src/cpu.rs index 4e5312fdd..985f89608 100644 --- a/hypervisor/src/cpu.rs +++ b/hypervisor/src/cpu.rs @@ -9,14 +9,13 @@ // #[cfg(target_arch = "aarch64")] -use crate::aarch64::{RegList, StandardRegisters, VcpuInit}; +use crate::aarch64::{RegList, VcpuInit}; #[cfg(target_arch = "x86_64")] use crate::arch::x86::{CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters}; #[cfg(feature = "tdx")] use crate::kvm::{TdxExitDetails, TdxExitStatus}; use crate::CpuState; use crate::MpState; -#[cfg(target_arch = "x86_64")] use crate::StandardRegisters; use thiserror::Error; use vm_memory::GuestAddress; diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index 0d99bd65d..fc87a7510 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -48,14 +48,13 @@ use crate::arch::x86::{ }; #[cfg(target_arch = "x86_64")] use crate::ClockData; -#[cfg(target_arch = "x86_64")] use crate::StandardRegisters; use crate::{ CpuState, IoEventAddress, IrqRoutingEntry, MpState, UserMemoryRegion, USER_MEMORY_REGION_LOG_DIRTY, USER_MEMORY_REGION_READ, USER_MEMORY_REGION_WRITE, }; #[cfg(target_arch = "aarch64")] -use aarch64::{RegList, Register, StandardRegisters}; +use aarch64::{RegList, Register}; #[cfg(target_arch = "x86_64")] use kvm_bindings::{ kvm_enable_cap, kvm_msr_entry, MsrList, KVM_CAP_HYPERV_SYNIC, KVM_CAP_SPLIT_IRQCHIP, @@ -1236,7 +1235,7 @@ impl cpu::Vcpu for KvmVcpu { /// #[cfg(target_arch = "aarch64")] fn get_regs(&self) -> cpu::Result { - let mut state: StandardRegisters = kvm_regs::default(); + let mut state = kvm_regs::default(); let mut off = offset_of!(user_pt_regs, regs); // There are 31 user_pt_regs: // https://elixir.free-electrons.com/linux/v4.14.174/source/arch/arm64/include/uapi/asm/ptrace.h#L72 @@ -1351,7 +1350,7 @@ impl cpu::Vcpu for KvmVcpu { .get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U32, off), &mut bytes) .map_err(|e| cpu::HypervisorCpuError::GetCoreRegister(e.into()))?; state.fp_regs.fpcr = u32::from_le_bytes(bytes); - Ok(state) + Ok(state.into()) } #[cfg(target_arch = "x86_64")] @@ -1376,6 +1375,7 @@ impl cpu::Vcpu for KvmVcpu { fn set_regs(&self, state: &StandardRegisters) -> cpu::Result<()> { // The function follows the exact identical order from `state`. Look there // for some additional info on registers. + let kvm_regs_state: kvm_regs = (*state).into(); let mut off = offset_of!(user_pt_regs, regs); for i in 0..31 { self.fd @@ -1383,7 +1383,7 @@ impl cpu::Vcpu for KvmVcpu { .unwrap() .set_one_reg( arm64_core_reg_id!(KVM_REG_SIZE_U64, off), - &state.regs.regs[i].to_le_bytes(), + &kvm_regs_state.regs.regs[i].to_le_bytes(), ) .map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?; off += std::mem::size_of::(); @@ -1395,7 +1395,7 @@ impl cpu::Vcpu for KvmVcpu { .unwrap() .set_one_reg( arm64_core_reg_id!(KVM_REG_SIZE_U64, off), - &state.regs.sp.to_le_bytes(), + &kvm_regs_state.regs.sp.to_le_bytes(), ) .map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?; @@ -1405,7 +1405,7 @@ impl cpu::Vcpu for KvmVcpu { .unwrap() .set_one_reg( arm64_core_reg_id!(KVM_REG_SIZE_U64, off), - &state.regs.pc.to_le_bytes(), + &kvm_regs_state.regs.pc.to_le_bytes(), ) .map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?; @@ -1415,7 +1415,7 @@ impl cpu::Vcpu for KvmVcpu { .unwrap() .set_one_reg( arm64_core_reg_id!(KVM_REG_SIZE_U64, off), - &state.regs.pstate.to_le_bytes(), + &kvm_regs_state.regs.pstate.to_le_bytes(), ) .map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?; @@ -1425,7 +1425,7 @@ impl cpu::Vcpu for KvmVcpu { .unwrap() .set_one_reg( arm64_core_reg_id!(KVM_REG_SIZE_U64, off), - &state.sp_el1.to_le_bytes(), + &kvm_regs_state.sp_el1.to_le_bytes(), ) .map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?; @@ -1435,7 +1435,7 @@ impl cpu::Vcpu for KvmVcpu { .unwrap() .set_one_reg( arm64_core_reg_id!(KVM_REG_SIZE_U64, off), - &state.elr_el1.to_le_bytes(), + &kvm_regs_state.elr_el1.to_le_bytes(), ) .map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?; @@ -1446,7 +1446,7 @@ impl cpu::Vcpu for KvmVcpu { .unwrap() .set_one_reg( arm64_core_reg_id!(KVM_REG_SIZE_U64, off), - &state.spsr[i].to_le_bytes(), + &kvm_regs_state.spsr[i].to_le_bytes(), ) .map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?; off += std::mem::size_of::(); @@ -1459,7 +1459,7 @@ impl cpu::Vcpu for KvmVcpu { .unwrap() .set_one_reg( arm64_core_reg_id!(KVM_REG_SIZE_U128, off), - &state.fp_regs.vregs[i].to_le_bytes(), + &kvm_regs_state.fp_regs.vregs[i].to_le_bytes(), ) .map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?; off += mem::size_of::(); @@ -1471,7 +1471,7 @@ impl cpu::Vcpu for KvmVcpu { .unwrap() .set_one_reg( arm64_core_reg_id!(KVM_REG_SIZE_U32, off), - &state.fp_regs.fpsr.to_le_bytes(), + &kvm_regs_state.fp_regs.fpsr.to_le_bytes(), ) .map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?; @@ -1481,7 +1481,7 @@ impl cpu::Vcpu for KvmVcpu { .unwrap() .set_one_reg( arm64_core_reg_id!(KVM_REG_SIZE_U32, off), - &state.fp_regs.fpcr.to_le_bytes(), + &kvm_regs_state.fp_regs.fpcr.to_le_bytes(), ) .map_err(|e| cpu::HypervisorCpuError::SetCoreRegister(e.into()))?; Ok(()) @@ -2123,7 +2123,7 @@ impl cpu::Vcpu for KvmVcpu { ..Default::default() }; // Get core registers - state.core_regs = self.get_regs()?; + state.core_regs = self.get_regs()?.into(); // Get systerm register // Call KVM_GET_REG_LIST to get all registers available to the guest. @@ -2263,7 +2263,7 @@ impl cpu::Vcpu for KvmVcpu { fn set_state(&self, state: &CpuState) -> cpu::Result<()> { let state: VcpuKvmState = state.clone().into(); // Set core registers - self.set_regs(&state.core_regs)?; + self.set_regs(&state.core_regs.into())?; // Set system registers for reg in &state.sys_regs { self.fd diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index aa149f60f..7ca7764e1 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -42,8 +42,6 @@ use devices::interrupt_controller::InterruptController; use gdbstub_arch::aarch64::reg::AArch64CoreRegs as CoreRegs; #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] use gdbstub_arch::x86::reg::{X86SegmentRegs, X86_64CoreRegs as CoreRegs}; -#[cfg(all(target_arch = "aarch64", feature = "guest_debug"))] -use hypervisor::aarch64::StandardRegisters; #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] use hypervisor::arch::x86::msr_index; #[cfg(target_arch = "x86_64")] @@ -62,7 +60,7 @@ use hypervisor::kvm::{TdxExitDetails, TdxExitStatus}; use hypervisor::CpuVendor; #[cfg(feature = "kvm")] use hypervisor::HypervisorType; -#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] +#[cfg(feature = "guest_debug")] use hypervisor::StandardRegisters; use hypervisor::{CpuState, HypervisorCpuError, VmExit, VmOps}; use libc::{c_void, siginfo_t}; @@ -2395,9 +2393,9 @@ impl Debuggable for CpuManager { .get_regs(cpu_id as u8) .map_err(DebuggableError::ReadRegs)?; Ok(CoreRegs { - x: gregs.regs.regs, - sp: gregs.regs.sp, - pc: gregs.regs.pc, + x: gregs.get_regs(), + sp: gregs.get_sp(), + pc: gregs.get_pc(), ..Default::default() }) } @@ -2465,9 +2463,9 @@ impl Debuggable for CpuManager { .get_regs(cpu_id as u8) .map_err(DebuggableError::ReadRegs)?; - gregs.regs.regs = regs.x; - gregs.regs.sp = regs.sp; - gregs.regs.pc = regs.pc; + gregs.set_regs(regs.x); + gregs.set_sp(regs.sp); + gregs.set_pc(regs.pc); self.set_regs(cpu_id as u8, &gregs) .map_err(DebuggableError::WriteRegs)?; @@ -2924,8 +2922,8 @@ mod tests { use arch::{aarch64::regs, layout}; use hypervisor::kvm::aarch64::is_system_register; use hypervisor::kvm::kvm_bindings::{ - kvm_regs, kvm_vcpu_init, user_pt_regs, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG, - KVM_REG_ARM_CORE, KVM_REG_SIZE_U64, + kvm_vcpu_init, user_pt_regs, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG, KVM_REG_ARM_CORE, + KVM_REG_SIZE_U64, }; use hypervisor::{arm64_core_reg_id, offset_of}; use std::mem; @@ -2987,7 +2985,7 @@ mod tests { "Failed to get core register: Exec format error (os error 8)" ); - let mut state = kvm_regs::default(); + let mut state = vcpu.create_standard_regs(); let res = vcpu.set_regs(&state); assert!(res.is_err()); assert_eq!( @@ -2999,7 +2997,7 @@ mod tests { let res = vcpu.get_regs(); assert!(res.is_ok()); state = res.unwrap(); - assert_eq!(state.regs.pstate, 0x3C5); + assert_eq!(state.get_pstate(), 0x3C5); assert!(vcpu.set_regs(&state).is_ok()); }