mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
hypervisor: trim qualified paths
Import the modules used in the crate instead of spelling the full paths at every use site, and drop the now-unnecessary crate-level generated msr_index.rs was trimmed separately. Signed-off-by: Henry Hrvoje Tonkovac <htonkovac@gmail.com> Assisted-by: Claude:Opus-4.8
This commit is contained in:
committed by
Sebastien Boeuf
parent
bb81c6650b
commit
01de980615
@@ -3,13 +3,17 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::any::Any;
|
||||
use std::result;
|
||||
use std::{mem, result};
|
||||
|
||||
use serde::de::Error as SerdeError;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json;
|
||||
use thiserror::Error;
|
||||
|
||||
#[cfg(feature = "kvm")]
|
||||
use crate::kvm::aarch64::gic::Gicv3ItsState;
|
||||
#[cfg(feature = "mshv")]
|
||||
use crate::mshv::aarch64::gic::MshvGicV2MState;
|
||||
use crate::{CpuState, HypervisorDeviceError, HypervisorVmError};
|
||||
|
||||
/// Errors thrown while setting up the VGIC.
|
||||
@@ -42,13 +46,13 @@ pub struct VgicConfig {
|
||||
#[derive(Clone, Serialize)]
|
||||
pub enum GicState {
|
||||
#[cfg(feature = "kvm")]
|
||||
Kvm(crate::kvm::aarch64::gic::Gicv3ItsState),
|
||||
Kvm(Gicv3ItsState),
|
||||
#[cfg(feature = "mshv")]
|
||||
MshvGicV2M(crate::mshv::aarch64::gic::MshvGicV2MState),
|
||||
MshvGicV2M(MshvGicV2MState),
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for GicState {
|
||||
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> result::Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
@@ -57,24 +61,19 @@ impl<'de> Deserialize<'de> for GicState {
|
||||
#[derive(Deserialize)]
|
||||
pub enum GicStateDefaultDeserialize {
|
||||
#[cfg(feature = "kvm")]
|
||||
Kvm(crate::kvm::aarch64::gic::Gicv3ItsState),
|
||||
Kvm(Gicv3ItsState),
|
||||
#[cfg(feature = "mshv")]
|
||||
MshvGicV2M(crate::mshv::aarch64::gic::MshvGicV2MState),
|
||||
MshvGicV2M(MshvGicV2MState),
|
||||
}
|
||||
|
||||
const {
|
||||
assert!(
|
||||
std::mem::size_of::<GicStateDefaultDeserialize>()
|
||||
== std::mem::size_of::<GicState>()
|
||||
);
|
||||
assert!(mem::size_of::<GicStateDefaultDeserialize>() == mem::size_of::<GicState>());
|
||||
};
|
||||
|
||||
let value: serde_json::Value = Deserialize::deserialize(deserializer)?;
|
||||
|
||||
#[cfg(feature = "kvm")]
|
||||
if let Ok(gicv3_its_state) =
|
||||
crate::kvm::aarch64::gic::Gicv3ItsState::deserialize(value.clone())
|
||||
{
|
||||
if let Ok(gicv3_its_state) = Gicv3ItsState::deserialize(value.clone()) {
|
||||
return Ok(GicState::Kvm(gicv3_its_state));
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
use core::fmt::Debug;
|
||||
use std::fmt::{self, Display};
|
||||
use std::result;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -147,4 +148,4 @@ pub trait PlatformEmulator {
|
||||
fn fetch(&self, ip: u64, instruction_bytes: &mut [u8]) -> Result<(), PlatformError>;
|
||||
}
|
||||
|
||||
pub type EmulationResult<S, E> = std::result::Result<S, EmulationError<E>>;
|
||||
pub type EmulationResult<S, E> = result::Result<S, EmulationError<E>>;
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
//
|
||||
|
||||
use core::fmt;
|
||||
use std::mem;
|
||||
use std::os::raw;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -246,7 +248,7 @@ pub struct CpuIdEntry {
|
||||
}
|
||||
|
||||
impl fmt::Display for CpuIdEntry {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"function = 0x{:08x} \
|
||||
@@ -280,13 +282,13 @@ pub struct FpuState {
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct LapicState {
|
||||
#[serde_as(as = "[_; 1024usize]")]
|
||||
pub(crate) regs: [::std::os::raw::c_char; 1024usize],
|
||||
pub(crate) regs: [raw::c_char; 1024usize],
|
||||
}
|
||||
|
||||
impl Default for LapicState {
|
||||
fn default() -> Self {
|
||||
// SAFETY: this is plain old data structure
|
||||
unsafe { ::std::mem::zeroed() }
|
||||
unsafe { mem::zeroed() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,7 +355,7 @@ impl Default for XsaveState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
// SAFETY: this is plain old data structure
|
||||
region: unsafe { std::mem::zeroed() },
|
||||
region: unsafe { mem::zeroed() },
|
||||
extra: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
//
|
||||
//
|
||||
|
||||
#[cfg(feature = "tdx")]
|
||||
use std::io;
|
||||
use std::result;
|
||||
|
||||
#[cfg(feature = "sev_snp")]
|
||||
use igvm::snp_defs::SevVmsa;
|
||||
use thiserror::Error;
|
||||
#[cfg(not(target_arch = "riscv64"))]
|
||||
use {anyhow::anyhow, vm_memory::GuestAddress};
|
||||
@@ -287,7 +293,7 @@ pub enum HypervisorCpuError {
|
||||
///
|
||||
#[cfg(feature = "tdx")]
|
||||
#[error("Failed to initialize TDX")]
|
||||
InitializeTdx(#[source] std::io::Error),
|
||||
InitializeTdx(#[source] io::Error),
|
||||
///
|
||||
/// Unknown TDX VM call
|
||||
///
|
||||
@@ -573,7 +579,7 @@ pub trait Vcpu: Send + Sync {
|
||||
///
|
||||
/// Triggers the running of the current virtual CPU returning an exit reason.
|
||||
///
|
||||
fn run(&mut self) -> std::result::Result<VmExit, HypervisorCpuError>;
|
||||
fn run(&mut self) -> result::Result<VmExit, HypervisorCpuError>;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
///
|
||||
/// Translate guest virtual address to guest physical address
|
||||
@@ -657,7 +663,7 @@ pub trait Vcpu: Send + Sync {
|
||||
unimplemented!()
|
||||
}
|
||||
#[cfg(feature = "sev_snp")]
|
||||
fn setup_sev_snp_regs(&self, _vmsa: igvm::snp_defs::SevVmsa) -> Result<()> {
|
||||
fn setup_sev_snp_regs(&self, _vmsa: SevVmsa) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,15 @@
|
||||
//
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::arch::x86_64;
|
||||
use std::result;
|
||||
use std::sync::Arc;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::arch::x86::CpuIdEntry;
|
||||
use crate::arch::x86::{
|
||||
AmxGuestSupportError, CpuIdEntry, amx_supported, request_guest_amx_support,
|
||||
};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::cpu::CpuVendor;
|
||||
#[cfg(feature = "tdx")]
|
||||
@@ -95,7 +98,7 @@ pub enum HypervisorError {
|
||||
///
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[error("Failed to enable AMX tile state components")]
|
||||
CouldNotEnableAmxStateComponents(#[source] crate::arch::x86::AmxGuestSupportError),
|
||||
CouldNotEnableAmxStateComponents(#[source] AmxGuestSupportError),
|
||||
///
|
||||
/// Failed to retrieve SEV-SNP capabilities
|
||||
///
|
||||
@@ -106,7 +109,7 @@ pub enum HypervisorError {
|
||||
///
|
||||
/// Result type for returning from a function
|
||||
///
|
||||
pub type Result<T> = std::result::Result<T, HypervisorError>;
|
||||
pub type Result<T> = result::Result<T, HypervisorError>;
|
||||
|
||||
///
|
||||
/// Trait to represent a Hypervisor
|
||||
@@ -189,9 +192,7 @@ pub trait Hypervisor: Send + Sync {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn enable_amx_state_components(&self) -> Result<()> {
|
||||
let cpu_vendor = self.get_cpu_vendor();
|
||||
crate::arch::x86::amx_supported(cpu_vendor)
|
||||
.map_err(HypervisorError::CouldNotEnableAmxStateComponents)?;
|
||||
crate::arch::x86::request_guest_amx_support()
|
||||
.map_err(HypervisorError::CouldNotEnableAmxStateComponents)
|
||||
amx_supported(cpu_vendor).map_err(HypervisorError::CouldNotEnableAmxStateComponents)?;
|
||||
request_guest_amx_support().map_err(HypervisorError::CouldNotEnableAmxStateComponents)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,25 +15,36 @@ use std::collections::HashMap;
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||
use std::mem::offset_of;
|
||||
#[cfg(feature = "sev_snp")]
|
||||
use std::num;
|
||||
#[cfg(feature = "sev_snp")]
|
||||
use std::os::fd::FromRawFd;
|
||||
use std::os::fd::OwnedFd;
|
||||
#[cfg(feature = "tdx")]
|
||||
use std::os::raw;
|
||||
#[cfg(any(feature = "sev_snp", feature = "tdx"))]
|
||||
use std::os::unix::io::AsRawFd;
|
||||
#[cfg(feature = "tdx")]
|
||||
use std::os::unix::io::RawFd;
|
||||
#[cfg(feature = "tdx")]
|
||||
use std::ptr;
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||
use std::sync::Mutex;
|
||||
#[cfg(feature = "sev_snp")]
|
||||
use std::sync::OnceLock;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, RwLock};
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use std::{io, result};
|
||||
use std::{fs, io, mem, result};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use anyhow::Context;
|
||||
use anyhow::anyhow;
|
||||
#[cfg(feature = "sev_snp")]
|
||||
use igvm::snp_defs::{SevSelector, SevVmsa};
|
||||
use kvm_bindings::fam_wrappers::KvmIrqRouting;
|
||||
#[cfg(feature = "sev_snp")]
|
||||
use kvm_bindings::kvm_create_guest_memfd;
|
||||
use kvm_ioctls::{NoDatamatch, VcpuFd, VmFd};
|
||||
#[cfg(feature = "sev_snp")]
|
||||
@@ -100,8 +111,6 @@ pub mod aarch64;
|
||||
// riscv64 dependencies
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
pub mod riscv64;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use std::mem;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use kvm_bindings::KVM_X86_DEFAULT_VM;
|
||||
@@ -237,7 +246,7 @@ pub struct SegAccess {
|
||||
}
|
||||
|
||||
#[cfg(feature = "sev_snp")]
|
||||
fn make_segment(sev_selector: igvm::snp_defs::SevSelector) -> Segment {
|
||||
fn make_segment(sev_selector: SevSelector) -> Segment {
|
||||
let flags = SegAccess::from_bits(sev_selector.attrib.into());
|
||||
Segment {
|
||||
base: sev_selector.base,
|
||||
@@ -268,7 +277,7 @@ const TDG_VP_VMCALL_SUCCESS: u64 = 0;
|
||||
const TDG_VP_VMCALL_INVALID_OPERAND: u64 = 0x8000000000000000;
|
||||
|
||||
#[cfg(feature = "tdx")]
|
||||
ioctl_iowr_nr!(KVM_MEMORY_ENCRYPT_OP, KVMIO, 0xba, std::os::raw::c_ulong);
|
||||
ioctl_iowr_nr!(KVM_MEMORY_ENCRYPT_OP, KVMIO, 0xba, raw::c_ulong);
|
||||
|
||||
#[cfg(feature = "tdx")]
|
||||
#[repr(u32)]
|
||||
@@ -629,7 +638,7 @@ pub struct KvmVm {
|
||||
#[cfg(feature = "sev_snp")]
|
||||
sev_fd: Option<x86_64::sev::SevFd>,
|
||||
#[cfg(feature = "sev_snp")]
|
||||
snp_guest_policy: std::sync::OnceLock<u64>,
|
||||
snp_guest_policy: OnceLock<u64>,
|
||||
dirty_log_slots: RwLock<HashMap<u32, KvmDirtyLogSlot>>,
|
||||
memory_slots: Option<Arc<RwLock<HashMap<u32, KvmMemorySlot>>>>,
|
||||
}
|
||||
@@ -1014,7 +1023,7 @@ impl vm::Vm for KvmVm {
|
||||
|
||||
kvm_route.u.msi.data = cfg.data;
|
||||
|
||||
if self.check_extension(crate::kvm::Cap::MsiDevid) {
|
||||
if self.check_extension(Cap::MsiDevid) {
|
||||
// On AArch64, there is limitation on the range of the 'devid',
|
||||
// it cannot be greater than 65536 (the max of u16).
|
||||
//
|
||||
@@ -1065,8 +1074,7 @@ impl vm::Vm for KvmVm {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let irq_routing =
|
||||
kvm_bindings::fam_wrappers::KvmIrqRouting::from_entries(&entries).unwrap();
|
||||
let irq_routing = KvmIrqRouting::from_entries(&entries).unwrap();
|
||||
|
||||
self.fd
|
||||
.set_gsi_routing(&irq_routing)
|
||||
@@ -1100,7 +1108,7 @@ impl vm::Vm for KvmVm {
|
||||
flags |= KVM_MEM_LOG_DIRTY_PAGES;
|
||||
}
|
||||
|
||||
const _: () = assert!(core::mem::size_of::<usize>() <= core::mem::size_of::<u64>());
|
||||
const _: () = assert!(mem::size_of::<usize>() <= mem::size_of::<u64>());
|
||||
|
||||
// Create a per-region guest_memfd when supported.
|
||||
// Each region gets its own fd sized exactly to memory_size
|
||||
@@ -1214,7 +1222,7 @@ impl vm::Vm for KvmVm {
|
||||
flags |= KVM_MEM_LOG_DIRTY_PAGES;
|
||||
}
|
||||
|
||||
const _: () = assert!(core::mem::size_of::<usize>() <= core::mem::size_of::<u64>());
|
||||
const _: () = assert!(mem::size_of::<usize>() <= mem::size_of::<u64>());
|
||||
|
||||
let mut region = kvm_userspace_memory_region2 {
|
||||
slot,
|
||||
@@ -1518,13 +1526,8 @@ impl vm::Vm for KvmVm {
|
||||
///
|
||||
#[cfg(feature = "tdx")]
|
||||
fn tdx_finalize(&self) -> vm::Result<()> {
|
||||
tdx_command(
|
||||
&self.fd.as_raw_fd(),
|
||||
TdxCommand::Finalize,
|
||||
0,
|
||||
std::ptr::null(),
|
||||
)
|
||||
.map_err(vm::HypervisorVmError::FinalizeTdx)
|
||||
tdx_command(&self.fd.as_raw_fd(), TdxCommand::Finalize, 0, ptr::null())
|
||||
.map_err(vm::HypervisorVmError::FinalizeTdx)
|
||||
}
|
||||
|
||||
/// Initialize memory regions for the TDX VM
|
||||
@@ -1573,7 +1576,7 @@ fn tdx_command(
|
||||
command: TdxCommand,
|
||||
flags: u32,
|
||||
data: *const libc::c_void,
|
||||
) -> result::Result<(), io::Error> {
|
||||
) -> io::Result<()> {
|
||||
#[repr(C)]
|
||||
struct TdxIoctlCmd {
|
||||
command: TdxCommand,
|
||||
@@ -1590,13 +1593,8 @@ fn tdx_command(
|
||||
unused: 0,
|
||||
};
|
||||
// SAFETY: FFI call. All input parameters are valid.
|
||||
let ret = unsafe {
|
||||
ioctl_with_val(
|
||||
fd,
|
||||
KVM_MEMORY_ENCRYPT_OP(),
|
||||
&raw const cmd as std::os::raw::c_ulong,
|
||||
)
|
||||
};
|
||||
let ret =
|
||||
unsafe { ioctl_with_val(fd, KVM_MEMORY_ENCRYPT_OP(), &raw const cmd as raw::c_ulong) };
|
||||
|
||||
if ret < 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
@@ -1658,7 +1656,7 @@ impl KvmHypervisor {
|
||||
|
||||
/// Check if the hypervisor is available
|
||||
pub fn is_available() -> hypervisor::Result<bool> {
|
||||
match std::fs::metadata("/dev/kvm") {
|
||||
match fs::metadata("/dev/kvm") {
|
||||
Ok(_) => Ok(true),
|
||||
Err(err) if err.kind() == io::ErrorKind::NotFound => Ok(false),
|
||||
Err(err) => Err(hypervisor::HypervisorError::HypervisorAvailableCheck(
|
||||
@@ -1771,7 +1769,7 @@ impl hypervisor::Hypervisor for KvmHypervisor {
|
||||
let sev_fd = {
|
||||
let sev_snp_enabled = vm_type == KVM_X86_SNP_VM as u64;
|
||||
if sev_snp_enabled {
|
||||
let mask = self.kvm.check_extension_int(crate::kvm::Cap::ExitHypercall);
|
||||
let mask = self.kvm.check_extension_int(Cap::ExitHypercall);
|
||||
let cap = kvm_bindings::kvm_enable_cap {
|
||||
cap: kvm_bindings::KVM_CAP_EXIT_HYPERCALL,
|
||||
args: [mask as _, 0, 0, 0],
|
||||
@@ -1797,7 +1795,7 @@ impl hypervisor::Hypervisor for KvmHypervisor {
|
||||
#[cfg(feature = "sev_snp")]
|
||||
sev_fd,
|
||||
#[cfg(feature = "sev_snp")]
|
||||
snp_guest_policy: std::sync::OnceLock::new(),
|
||||
snp_guest_policy: OnceLock::new(),
|
||||
memory_slots,
|
||||
}))
|
||||
}
|
||||
@@ -2024,7 +2022,7 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off), &mut bytes)
|
||||
.map_err(|e| cpu::HypervisorCpuError::GetAarchCoreRegister(e.into()))?;
|
||||
state.regs.regs[i] = u64::from_le_bytes(bytes);
|
||||
off += std::mem::size_of::<u64>();
|
||||
off += mem::size_of::<u64>();
|
||||
}
|
||||
|
||||
// We are now entering the "Other register" section of the ARMv8-a architecture.
|
||||
@@ -2077,7 +2075,7 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
.get_one_reg(arm64_core_reg_id!(KVM_REG_SIZE_U64, off), &mut bytes)
|
||||
.map_err(|e| cpu::HypervisorCpuError::GetAarchCoreRegister(e.into()))?;
|
||||
state.spsr[i] = u64::from_le_bytes(bytes);
|
||||
off += std::mem::size_of::<u64>();
|
||||
off += mem::size_of::<u64>();
|
||||
}
|
||||
|
||||
Ok(state.into())
|
||||
@@ -2179,7 +2177,7 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
&kvm_regs_state.regs.regs[i].to_le_bytes(),
|
||||
)
|
||||
.map_err(|e| cpu::HypervisorCpuError::SetAarchCoreRegister(e.into()))?;
|
||||
off += std::mem::size_of::<u64>();
|
||||
off += mem::size_of::<u64>();
|
||||
}
|
||||
|
||||
let off = offset_of!(user_pt_regs, sp);
|
||||
@@ -2230,7 +2228,7 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
&kvm_regs_state.spsr[i].to_le_bytes(),
|
||||
)
|
||||
.map_err(|e| cpu::HypervisorCpuError::SetAarchCoreRegister(e.into()))?;
|
||||
off += std::mem::size_of::<u64>();
|
||||
off += mem::size_of::<u64>();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -2770,7 +2768,7 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
kvm_kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PSCI_0_2;
|
||||
if vm
|
||||
.as_any()
|
||||
.downcast_ref::<crate::kvm::KvmVm>()
|
||||
.downcast_ref::<KvmVm>()
|
||||
.unwrap()
|
||||
.check_extension(Cap::ArmPmuV3)
|
||||
{
|
||||
@@ -2780,7 +2778,7 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
if sve_supported
|
||||
&& vm
|
||||
.as_any()
|
||||
.downcast_ref::<crate::kvm::KvmVm>()
|
||||
.downcast_ref::<KvmVm>()
|
||||
.unwrap()
|
||||
.check_extension(Cap::ArmSve)
|
||||
{
|
||||
@@ -3643,7 +3641,7 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
}
|
||||
|
||||
#[cfg(feature = "sev_snp")]
|
||||
fn setup_sev_snp_regs(&self, vmsa: igvm::snp_defs::SevVmsa) -> cpu::Result<()> {
|
||||
fn setup_sev_snp_regs(&self, vmsa: SevVmsa) -> cpu::Result<()> {
|
||||
let mut sregs = self
|
||||
.fd
|
||||
.get_sregs()
|
||||
@@ -3667,7 +3665,7 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
.idtr
|
||||
.limit
|
||||
.try_into()
|
||||
.map_err(|e: std::num::TryFromIntError| {
|
||||
.map_err(|e: num::TryFromIntError| {
|
||||
cpu::HypervisorCpuError::SetSpecialRegs(anyhow!(e))
|
||||
})?;
|
||||
sregs.gdt.base = vmsa.gdtr.base;
|
||||
@@ -3675,7 +3673,7 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
.gdtr
|
||||
.limit
|
||||
.try_into()
|
||||
.map_err(|e: std::num::TryFromIntError| {
|
||||
.map_err(|e: num::TryFromIntError| {
|
||||
cpu::HypervisorCpuError::SetSpecialRegs(anyhow!(e))
|
||||
})?;
|
||||
self.fd
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
use log::error;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
use vmm_sys_util::fam;
|
||||
///
|
||||
/// Export generically-named wrappers of kvm-bindings for Unix-based platforms
|
||||
///
|
||||
@@ -349,7 +350,7 @@ impl From<&xsave2> for XsaveState {
|
||||
}
|
||||
|
||||
impl XsaveState {
|
||||
pub fn to_xsave2(&self) -> Result<xsave2, vmm_sys_util::fam::Error> {
|
||||
pub fn to_xsave2(&self) -> Result<xsave2, fam::Error> {
|
||||
let mut xsave = xsave2::new(self.extra.len())?;
|
||||
// SAFETY: `xsave` was just created via `Xsave::new()` with valid allocated memory.
|
||||
unsafe {
|
||||
|
||||
@@ -7,6 +7,7 @@ use std::fs::OpenOptions;
|
||||
use std::os::fd::{AsRawFd, OwnedFd};
|
||||
use std::os::unix::fs::OpenOptionsExt;
|
||||
use std::path::Path;
|
||||
use std::result;
|
||||
|
||||
use igvm_defs::{IGVM_VHS_SNP_ID_BLOCK, SnpPolicy};
|
||||
use kvm_bindings::kvm_sev_cmd;
|
||||
@@ -15,7 +16,7 @@ use log::{debug, error, info};
|
||||
use vmm_sys_util::errno;
|
||||
use zerocopy::{FromZeros, Immutable, IntoBytes};
|
||||
|
||||
pub(crate) type Result<T> = std::result::Result<T, errno::Error>;
|
||||
pub(crate) type Result<T> = result::Result<T, errno::Error>;
|
||||
|
||||
// KVM SEV command IDs — linux/include/uapi/linux/kvm.h
|
||||
const KVM_SEV_INIT2: u32 = 22;
|
||||
|
||||
@@ -21,9 +21,6 @@
|
||||
//! - riscv64 (experimental)
|
||||
//!
|
||||
|
||||
// TODO: Trim qualified paths in this crate, then drop this expectation.
|
||||
#![expect(clippy::absolute_paths)]
|
||||
|
||||
/// Architecture specific definitions
|
||||
#[macro_use]
|
||||
pub mod arch;
|
||||
@@ -48,9 +45,12 @@ mod cpu;
|
||||
/// Device related module
|
||||
mod device;
|
||||
|
||||
use std::result;
|
||||
use std::sync::Arc;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::time::SystemTime;
|
||||
#[cfg(all(target_arch = "x86_64", feature = "kvm"))]
|
||||
use std::time::UNIX_EPOCH;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use concat_idents::concat_idents;
|
||||
@@ -77,7 +77,7 @@ pub enum HypervisorType {
|
||||
Mshv,
|
||||
}
|
||||
|
||||
pub fn new() -> std::result::Result<Arc<dyn Hypervisor>, HypervisorError> {
|
||||
pub fn new() -> result::Result<Arc<dyn Hypervisor>, HypervisorError> {
|
||||
#[cfg(feature = "kvm")]
|
||||
if kvm::KvmHypervisor::is_available()? {
|
||||
return kvm::KvmHypervisor::new();
|
||||
@@ -202,7 +202,7 @@ impl ClockData {
|
||||
match self {
|
||||
#[cfg(feature = "kvm")]
|
||||
ClockData::Kvm(s) => {
|
||||
if let Ok(time_since_epoch) = realtime.duration_since(std::time::UNIX_EPOCH) {
|
||||
if let Ok(time_since_epoch) = realtime.duration_since(UNIX_EPOCH) {
|
||||
s.realtime = time_since_epoch.as_nanos() as u64;
|
||||
s.flags |= kvm_bindings::KVM_CLOCK_REALTIME;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,10 @@ use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
#[cfg(feature = "sev_snp")]
|
||||
use std::num::NonZeroUsize;
|
||||
#[cfg(feature = "sev_snp")]
|
||||
use std::ptr;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::{fs, io, result};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use anyhow::Context;
|
||||
@@ -38,6 +41,8 @@ use crate::arch::aarch64::regs::{
|
||||
use crate::arch::emulator::PlatformEmulator;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::arch::x86::emulator::Emulator;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::arch::x86::{LapicState, SpecialRegisters};
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use crate::mshv::aarch64::emulator;
|
||||
use crate::mshv::emulator::MshvEmulatorContext;
|
||||
@@ -241,9 +246,9 @@ impl MshvHypervisor {
|
||||
}
|
||||
/// Check if the hypervisor is available
|
||||
pub fn is_available() -> hypervisor::Result<bool> {
|
||||
match std::fs::metadata("/dev/mshv") {
|
||||
match fs::metadata("/dev/mshv") {
|
||||
Ok(_) => Ok(true),
|
||||
Err(err) if err.kind() == std::io::ErrorKind::NotFound => Ok(false),
|
||||
Err(err) if err.kind() == io::ErrorKind::NotFound => Ok(false),
|
||||
Err(err) => Err(hypervisor::HypervisorError::HypervisorAvailableCheck(
|
||||
err.into(),
|
||||
)),
|
||||
@@ -500,7 +505,7 @@ impl cpu::Vcpu for MshvVcpu {
|
||||
///
|
||||
/// Returns the vCPU special registers.
|
||||
///
|
||||
fn get_sregs(&self) -> cpu::Result<crate::arch::x86::SpecialRegisters> {
|
||||
fn get_sregs(&self) -> cpu::Result<SpecialRegisters> {
|
||||
Ok(self
|
||||
.fd
|
||||
.get_sregs()
|
||||
@@ -512,7 +517,7 @@ impl cpu::Vcpu for MshvVcpu {
|
||||
///
|
||||
/// Sets the vCPU special registers.
|
||||
///
|
||||
fn set_sregs(&self, sregs: &crate::arch::x86::SpecialRegisters) -> cpu::Result<()> {
|
||||
fn set_sregs(&self, sregs: &SpecialRegisters) -> cpu::Result<()> {
|
||||
let sregs = (*sregs).into();
|
||||
self.fd
|
||||
.set_sregs(&sregs)
|
||||
@@ -587,7 +592,7 @@ impl cpu::Vcpu for MshvVcpu {
|
||||
}
|
||||
|
||||
#[expect(non_upper_case_globals)]
|
||||
fn run(&mut self) -> std::result::Result<cpu::VmExit, cpu::HypervisorCpuError> {
|
||||
fn run(&mut self) -> result::Result<cpu::VmExit, cpu::HypervisorCpuError> {
|
||||
match self.fd.run() {
|
||||
Ok(x) => match x.header.message_type {
|
||||
hv_message_type_HVMSG_X64_HALT => {
|
||||
@@ -1412,7 +1417,7 @@ impl cpu::Vcpu for MshvVcpu {
|
||||
///
|
||||
/// Returns the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
|
||||
///
|
||||
fn get_lapic(&self) -> cpu::Result<crate::arch::x86::LapicState> {
|
||||
fn get_lapic(&self) -> cpu::Result<LapicState> {
|
||||
Ok(self
|
||||
.fd
|
||||
.get_lapic()
|
||||
@@ -1424,7 +1429,7 @@ impl cpu::Vcpu for MshvVcpu {
|
||||
///
|
||||
/// Sets the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
|
||||
///
|
||||
fn set_lapic(&self, lapic: &crate::arch::x86::LapicState) -> cpu::Result<()> {
|
||||
fn set_lapic(&self, lapic: &LapicState) -> cpu::Result<()> {
|
||||
let lapic: mshv_bindings::LapicState = (*lapic).clone().into();
|
||||
self.fd
|
||||
.set_lapic(&lapic)
|
||||
@@ -1696,7 +1701,7 @@ impl MshvVcpu {
|
||||
/// Clear SW_EXIT_INFO1 register for SEV-SNP guests.
|
||||
///
|
||||
#[cfg(feature = "sev_snp")]
|
||||
fn clear_swexit_info1(&self) -> std::result::Result<cpu::VmExit, cpu::HypervisorCpuError> {
|
||||
fn clear_swexit_info1(&self) -> result::Result<cpu::VmExit, cpu::HypervisorCpuError> {
|
||||
// Clear the SW_EXIT_INFO1 register to indicate no error
|
||||
// Safe to use unwrap, for sev_snp guest we already have the
|
||||
// GHCB pointer wrapped in the option, otherwise this place is not reached.
|
||||
@@ -1898,7 +1903,7 @@ impl vm::Vm for MshvVm {
|
||||
// SAFETY: Safe to call as VCPU has this map already available upon creation
|
||||
let addr = unsafe {
|
||||
libc::mmap(
|
||||
std::ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
HV_PAGE_SIZE,
|
||||
libc::PROT_READ | libc::PROT_WRITE,
|
||||
libc::MAP_SHARED,
|
||||
@@ -1906,7 +1911,7 @@ impl vm::Vm for MshvVm {
|
||||
MSHV_VP_MMAP_OFFSET_GHCB as i64 * libc::sysconf(libc::_SC_PAGE_SIZE),
|
||||
)
|
||||
};
|
||||
if std::ptr::eq(addr, libc::MAP_FAILED) {
|
||||
if ptr::eq(addr, libc::MAP_FAILED) {
|
||||
// No point of continuing, without this mmap VMGEXIT will fail anyway
|
||||
// Return error
|
||||
return Err(vm::HypervisorVmError::MmapToRoot);
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
//
|
||||
|
||||
use std::any::Any;
|
||||
#[cfg(any(feature = "sev_snp", feature = "tdx"))]
|
||||
use std::io;
|
||||
use std::result;
|
||||
use std::sync::Arc;
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||
use std::sync::Mutex;
|
||||
@@ -219,26 +222,26 @@ pub enum HypervisorVmError {
|
||||
/// Error initializing SEV-SNP on the VM
|
||||
///
|
||||
#[error("Failed to initialize SEV-SNP")]
|
||||
InitializeSevSnp(#[source] std::io::Error),
|
||||
InitializeSevSnp(#[source] io::Error),
|
||||
|
||||
#[cfg(feature = "tdx")]
|
||||
///
|
||||
/// Error initializing TDX on the VM
|
||||
///
|
||||
#[error("Failed to initialize TDX")]
|
||||
InitializeTdx(#[source] std::io::Error),
|
||||
InitializeTdx(#[source] io::Error),
|
||||
#[cfg(feature = "tdx")]
|
||||
///
|
||||
/// Error finalizing the TDX configuration on the VM
|
||||
///
|
||||
#[error("Failed to finalize TDX")]
|
||||
FinalizeTdx(#[source] std::io::Error),
|
||||
FinalizeTdx(#[source] io::Error),
|
||||
#[cfg(feature = "tdx")]
|
||||
///
|
||||
/// Error initializing the TDX memory region
|
||||
///
|
||||
#[error("Failed to initialize memory region TDX")]
|
||||
InitMemRegionTdx(#[source] std::io::Error),
|
||||
InitMemRegionTdx(#[source] io::Error),
|
||||
///
|
||||
/// Create Vgic error
|
||||
///
|
||||
@@ -289,7 +292,7 @@ pub enum HypervisorVmError {
|
||||
///
|
||||
/// Result type for returning from a function
|
||||
///
|
||||
pub type Result<T> = std::result::Result<T, HypervisorVmError>;
|
||||
pub type Result<T> = result::Result<T, HypervisorVmError>;
|
||||
|
||||
/// Configuration data for legacy interrupts.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user