hypervisor: Implement hypervisor agnostic Register interface

This will help in fixing the build issue for MSHV on ARM64.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
This commit is contained in:
Jinank Jain
2025-01-15 09:49:49 +00:00
committed by Bo Chen
parent c43ae1dc9d
commit 061482340e
5 changed files with 33 additions and 11 deletions

View File

@@ -7,11 +7,11 @@ use kvm_ioctls::DeviceFd;
use crate::arch::aarch64::gic::{Error, Result}; use crate::arch::aarch64::gic::{Error, Result};
use crate::device::HypervisorDeviceError; use crate::device::HypervisorDeviceError;
use crate::kvm::kvm_bindings::{ use crate::kvm::kvm_bindings::{
kvm_device_attr, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG, kvm_device_attr, kvm_one_reg, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS, KVM_REG_ARM64,
KVM_REG_ARM64_SYSREG_OP0_MASK, KVM_REG_ARM64_SYSREG_OP0_SHIFT, KVM_REG_ARM64_SYSREG_OP2_MASK, KVM_REG_ARM64_SYSREG, KVM_REG_ARM64_SYSREG_OP0_MASK, KVM_REG_ARM64_SYSREG_OP0_SHIFT,
KVM_REG_ARM64_SYSREG_OP2_SHIFT, KVM_REG_SIZE_U64, KVM_REG_ARM64_SYSREG_OP2_MASK, KVM_REG_ARM64_SYSREG_OP2_SHIFT, KVM_REG_SIZE_U64,
}; };
use crate::kvm::{Register, VcpuKvmState}; use crate::kvm::VcpuKvmState;
use crate::CpuState; use crate::CpuState;
// Relevant redistributor registers that we want to save/restore. // Relevant redistributor registers that we want to save/restore.
@@ -213,7 +213,7 @@ pub fn construct_gicr_typers(vcpu_states: &[CpuState]) -> Vec<u64> {
let state: VcpuKvmState = state.clone().into(); let state: VcpuKvmState = state.clone().into();
let last = (index == vcpu_states.len() - 1) as u64; let last = (index == vcpu_states.len() - 1) as u64;
// state.sys_regs is a big collection of system registers, including MIPDR_EL1 // state.sys_regs is a big collection of system registers, including MIPDR_EL1
let mpidr: Vec<Register> = state let mpidr: Vec<kvm_one_reg> = state
.sys_regs .sys_regs
.into_iter() .into_iter()
.filter(|reg| reg.id == KVM_ARM64_SYSREG_MPIDR_EL1) .filter(|reg| reg.id == KVM_ARM64_SYSREG_MPIDR_EL1)

View File

@@ -14,7 +14,7 @@ use kvm_bindings::{
kvm_mp_state, kvm_one_reg, kvm_regs, KVM_REG_ARM_COPROC_MASK, KVM_REG_ARM_CORE, kvm_mp_state, kvm_one_reg, kvm_regs, KVM_REG_ARM_COPROC_MASK, KVM_REG_ARM_CORE,
KVM_REG_SIZE_MASK, KVM_REG_SIZE_U32, KVM_REG_SIZE_U64, KVM_REG_SIZE_MASK, KVM_REG_SIZE_U32, KVM_REG_SIZE_U64,
}; };
pub use kvm_bindings::{kvm_one_reg as Register, kvm_vcpu_init as VcpuInit, RegList}; pub use kvm_bindings::{kvm_vcpu_init as VcpuInit, RegList};
pub use kvm_ioctls::{Cap, Kvm}; pub use kvm_ioctls::{Cap, Kvm};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@@ -54,14 +54,14 @@ use crate::{offset_of, riscv64_reg_id};
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub mod x86_64; pub mod x86_64;
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
use aarch64::{RegList, Register}; use aarch64::RegList;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use kvm_bindings::{ use kvm_bindings::{
kvm_enable_cap, kvm_msr_entry, MsrList, KVM_CAP_HYPERV_SYNIC, KVM_CAP_SPLIT_IRQCHIP, kvm_enable_cap, kvm_msr_entry, MsrList, KVM_CAP_HYPERV_SYNIC, KVM_CAP_SPLIT_IRQCHIP,
KVM_GUESTDBG_USE_HW_BP, KVM_GUESTDBG_USE_HW_BP,
}; };
#[cfg(target_arch = "riscv64")] #[cfg(target_arch = "riscv64")]
use riscv64::{RegList, Register}; use riscv64::RegList;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use x86_64::check_required_kvm_extensions; use x86_64::check_required_kvm_extensions;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
@@ -353,6 +353,23 @@ impl From<ClockData> for kvm_clock_data {
} }
} }
impl From<kvm_bindings::kvm_one_reg> for crate::Register {
fn from(s: kvm_bindings::kvm_one_reg) -> Self {
crate::Register::Kvm(s)
}
}
impl From<crate::Register> for kvm_bindings::kvm_one_reg {
fn from(e: crate::Register) -> Self {
match e {
crate::Register::Kvm(e) => e,
/* Needed in case other hypervisors are enabled */
#[allow(unreachable_patterns)]
_ => panic!("Register is not valid"),
}
}
}
#[cfg(not(target_arch = "riscv64"))] #[cfg(not(target_arch = "riscv64"))]
impl From<kvm_bindings::kvm_regs> for crate::StandardRegisters { impl From<kvm_bindings::kvm_regs> for crate::StandardRegisters {
fn from(s: kvm_bindings::kvm_regs) -> Self { fn from(s: kvm_bindings::kvm_regs) -> Self {
@@ -2917,7 +2934,7 @@ impl cpu::Vcpu for KvmVcpu {
// Get systerm register // Get systerm register
// Call KVM_GET_REG_LIST to get all registers available to the guest. // Call KVM_GET_REG_LIST to get all registers available to the guest.
// For ArmV8 there are around 500 registers. // For ArmV8 there are around 500 registers.
let mut sys_regs: Vec<Register> = Vec::new(); let mut sys_regs: Vec<kvm_bindings::kvm_one_reg> = Vec::new();
let mut reg_list = RegList::new(500).unwrap(); let mut reg_list = RegList::new(500).unwrap();
self.fd self.fd
.lock() .lock()
@@ -2970,7 +2987,7 @@ impl cpu::Vcpu for KvmVcpu {
// Get non-core register // Get non-core register
// Call KVM_GET_REG_LIST to get all registers available to the guest. // Call KVM_GET_REG_LIST to get all registers available to the guest.
// For RISC-V 64-bit there are around 200 registers. // For RISC-V 64-bit there are around 200 registers.
let mut sys_regs: Vec<Register> = Vec::new(); let mut sys_regs: Vec<kvm_bindings::kvm_one_reg> = Vec::new();
let mut reg_list = RegList::new(200).unwrap(); let mut reg_list = RegList::new(200).unwrap();
self.fd self.fd
.lock() .lock()

View File

@@ -4,11 +4,11 @@
pub mod aia; pub mod aia;
pub use kvm_bindings::RegList;
use kvm_bindings::{ use kvm_bindings::{
kvm_mp_state, kvm_one_reg, kvm_riscv_core, KVM_REG_RISCV_CORE, KVM_REG_RISCV_TYPE_MASK, kvm_mp_state, kvm_one_reg, kvm_riscv_core, KVM_REG_RISCV_CORE, KVM_REG_RISCV_TYPE_MASK,
KVM_REG_SIZE_MASK, KVM_REG_SIZE_U64, KVM_REG_SIZE_MASK, KVM_REG_SIZE_U64,
}; };
pub use kvm_bindings::{kvm_one_reg as Register, RegList};
pub use kvm_ioctls::{Cap, Kvm}; pub use kvm_ioctls::{Cap, Kvm};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@@ -196,6 +196,11 @@ pub enum IrqRoutingEntry {
Mshv(mshv_bindings::mshv_user_irq_entry), Mshv(mshv_bindings::mshv_user_irq_entry),
} }
pub enum Register {
#[cfg(feature = "kvm")]
Kvm(kvm_bindings::kvm_one_reg),
}
#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum StandardRegisters { pub enum StandardRegisters {
#[cfg(all(feature = "kvm", not(target_arch = "riscv64")))] #[cfg(all(feature = "kvm", not(target_arch = "riscv64")))]