Skip to content

Commit

Permalink
kvm: Added KVM MSR Store access
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewjj20 committed May 3, 2024
1 parent 1b7d256 commit 7dc2235
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 39 deletions.
23 changes: 15 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ serde_yaml = "0.8"
enum_dispatch = "0.3.8"

[target.'cfg(target_os = "linux")'.dependencies]
kvm-ioctls = { version = "0.12.0", optional = true }
kvm-bindings = { version = "0.6.0", features = ["fam-wrappers"], optional = true }
kvm-ioctls = { version = "0.17", optional = true }
kvm-bindings = { version = "0.8", features = ["fam-wrappers"], optional = true }

[features]
default = ["use_msr", "kvm"]
Expand Down
52 changes: 51 additions & 1 deletion src/kvm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::msr::{self, MSRValue, MsrStore};

use super::CpuidDB;
use core::arch::x86_64::CpuidResult;
use kvm_bindings::{KVM_CPUID_FLAG_SIGNIFCANT_INDEX, KVM_MAX_CPUID_ENTRIES};
use kvm_bindings::{kvm_msr_entry, Msrs, KVM_CPUID_FLAG_SIGNIFCANT_INDEX, KVM_MAX_CPUID_ENTRIES};
use std::error::Error;

/** Wrap information from kvm
*
Expand Down Expand Up @@ -39,3 +42,50 @@ impl CpuidDB for KvmInfo {
})
}
}

pub struct KvmMsrInfo {
msr_info: kvm_bindings::Msrs,
}

impl KvmMsrInfo {
pub fn new(kvm: &kvm_ioctls::Kvm) -> Result<Self, Box<dyn Error>> {
let msr_features = kvm.get_msr_feature_index_list()?;
let mut msrs = Msrs::from_entries(
&msr_features
.as_slice()
.iter()
.map(|&index| kvm_msr_entry {
index,
..Default::default()
})
.collect::<Vec<_>>(),
)?;
kvm.get_msrs(&mut msrs)?;
Ok(KvmMsrInfo { msr_info: msrs })
}
}

impl MsrStore for KvmMsrInfo {
fn is_empty(&self) -> bool {
false
}
fn get_value<'a>(
&self,
desc: &'a crate::msr::MSRDesc,
) -> std::result::Result<crate::msr::MSRValue<'a>, crate::msr::Error> {
self.msr_info
.as_slice()
.iter()
.find_map(|entry| {
if entry.index == desc.address {
Some(MSRValue {
desc,
value: entry.data,
})
} else {
None
}
})
.ok_or_else(|| msr::Error::NotAvailible {})
}
}
75 changes: 52 additions & 23 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,10 @@ impl Command for Disp {
}
}

#[cfg(feature = "use_msr")]
if !self.skip_msr {
if msr::LINUX_MSR_AVAILIBLE {
#[cfg(all(target_os = "linux"))]
{
match msr::LinuxMsrStore::new() {
Ok(linux_store) => {
println!("MSRS:");
Expand All @@ -91,6 +93,25 @@ impl Command for Disp {
Err(e) => println!("Error checking all msrs: {}", e),
}
}
#[cfg(all(target_os = "linux", feature = "kvm"))]
if !self.skip_kvm {
use cpuinfo::kvm::KvmMsrInfo;
use kvm_ioctls::Kvm;
println!("KVM-MSR:");
if let Err(e) = {
let kvm = Kvm::new()?;
let kvm_msr = KvmMsrInfo::new(&kvm)?;
for msr in &config.msrs {
match kvm_msr.get_value(msr) {
Ok(value) => println!("{}", value),
Err(err) => println!("{} Error : {}", msr, err),
}
}
Ok::<_, Box<dyn Error>>(())
} {
println!("Error Processing KVM-MSR: {}", e);
}
}
}
Ok(())
}
Expand Down Expand Up @@ -120,7 +141,7 @@ fn collect_facts(
})
.collect();

if msr_store.is_empty() {
if !msr_store.is_empty() {
for msr in &config.msrs {
if let Ok(value) = msr_store.get_value(msr) {
let mut facts = value.collect_facts();
Expand All @@ -137,41 +158,49 @@ fn collect_facts(

impl Command for Facts {
fn run(&self, config: &Definition) -> Result<(), Box<dyn std::error::Error>> {
#[cfg(all(target_os = "linux", feature = "kvm"))]
let kvm_option = {
use cpuinfo::kvm::KvmInfo;
use kvm_ioctls::Kvm;
if self.use_kvm {
println!("using kvm");
let kvm = Kvm::new()?;
Some(KvmInfo::new(&kvm)?)
} else {
None
}
};

let (cpuid_source, msr_source): (_, Box<dyn MsrStore>) = {
#[cfg(all(target_os = "linux", feature = "kvm"))]
{
if let Some(kvm_info) = kvm_option {
if self.use_kvm {
use cpuinfo::kvm::KvmInfo;
use kvm::KvmMsrInfo;
use kvm_ioctls::Kvm;
let kvm = Kvm::new()?;
(
kvm_info.into(),
Box::new(msr::EmptyMSR {}) as Box<dyn MsrStore>,
KvmInfo::new(&kvm)?.into(),
Box::new(KvmMsrInfo::new(&kvm)?) as Box<dyn MsrStore>,
)
} else {
(
CpuidType::func(),
Box::new(msr::LinuxMsrStore::new()?) as Box<dyn MsrStore>,
)
let msr = {
#[cfg(feature = "use_msr")]
{
Box::new(msr::LinuxMsrStore::new()?) as Box<dyn MsrStore>
}
#[cfg(not(feature = "use_msr"))]
{
Box::new(msr::EmptyMSR {})
}
};
(CpuidType::func(), msr)
}
}
#[cfg(any(not(target_os = "linux"), not(feature = "kvm")))]
#[cfg(all(target_os = "linux", not(feature = "kvm"), feature = "use_msr"))]
{
(
CpuidType::func(),
Box::new(msr::LinuxMsrStore::new()?) as Box<dyn MsrStore>,
)
}
#[cfg(all(
not(feature = "kvm"),
any(not(target_os = "linux"), not(feature = "use_msr"))
))]
{
(
CpuidType::func(),
Box::new(msr::EmptyMSR {}) as Box<dyn MsrStore>,
)
}
};
println!(
"{}",
Expand Down
5 changes: 0 additions & 5 deletions src/msr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,6 @@ impl MsrStore for EmptyMSR {
}
}

#[cfg(all(target_os = "linux", feature = "use_msr"))]
pub const LINUX_MSR_AVAILIBLE: bool = true;
#[cfg(any(not(target_os = "linux"), not(feature = "use_msr")))]
pub const LINUX_MSR_AVAILIBLE: bool = false;

#[cfg(all(target_os = "linux", feature = "use_msr"))]
pub struct LinuxMsrStore {
msr_device: fs::File,
Expand Down

0 comments on commit 7dc2235

Please sign in to comment.