From 77ad8b283c8707e19e44691e6afb3f8df37b5754 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 5 Mar 2025 11:24:20 +0000 Subject: [PATCH 1/2] ok.rs: Rename get_values() to get_sev_status() The function is only ever used to read the SEV_STATUS MSR, so rename it and hard-code the function parameters. This helps adding alternative means to read SEV_STATUS. Signed-off-by: Joerg Roedel --- src/ok.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ok.rs b/src/ok.rs index eb82d9e..8d0dce8 100644 --- a/src/ok.rs +++ b/src/ok.rs @@ -10,6 +10,8 @@ use serde::{Deserialize, Serialize}; const SEV_MASK: usize = 1; const ES_MASK: usize = 1 << 1; const SNP_MASK: usize = 1 << 2; +const MSR_SEV_STATUS: u32 = 0xC0010131; + type TestFn = dyn Fn() -> TestResult; struct Test { @@ -72,11 +74,11 @@ impl fmt::Display for TestState { fn collect_tests() -> Vec { // Grab your MSR value one time. - let temp_bitfield = match get_values(0xC0010131, 0) { + let temp_bitfield = match get_sev_status() { Ok(temp_bitfield) => temp_bitfield, Err(e) => { return vec![Test { - name: "Error reading MSR", + name: "Error reading SEV_STATUS", gen_mask: SEV_MASK, run: Box::new(move || TestResult { name: "Error reading MSR".to_string(), @@ -345,8 +347,8 @@ fn emit_skip(tests: &[Test], level: usize, quiet: bool) { } } -fn get_values(reg: u32, cpu: u16) -> Result { - let mut msr = Msr::new(reg, cpu).context("Error Reading MSR")?; +fn get_sev_status() -> Result { + let mut msr = Msr::new(MSR_SEV_STATUS, 0).context("Error Reading MSR")?; let my_bitfield = SevStatus(msr.read()?); Ok(my_bitfield) } From b6cb76bb06b2a6b95c7eb131e7e4924230ab3a7f Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 5 Mar 2025 11:38:39 +0000 Subject: [PATCH 2/2] Grab SEV_STATUS from SYSFS if available Since reading MSRs using the Linux MSR kernel module is generally discouraged and disabled by default in many Linux distributions, add another way of reading the SEV_STATUS value via SYSFS. If that does not work the MSR module is still used as a fall-back. Signed-off-by: Joerg Roedel --- src/ok.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/ok.rs b/src/ok.rs index 8d0dce8..6bf2bf0 100644 --- a/src/ok.rs +++ b/src/ok.rs @@ -1,6 +1,8 @@ use super::*; use std::fmt; +use std::fs::File; +use std::io::{BufRead, BufReader}; use bitfield::bitfield; use colorful::*; @@ -11,6 +13,7 @@ const SEV_MASK: usize = 1; const ES_MASK: usize = 1 << 1; const SNP_MASK: usize = 1 << 2; const MSR_SEV_STATUS: u32 = 0xC0010131; +const SEV_STATUS_SYSFS_FILENAME: &str = "/sys/devices/system/cpu/sev/sev_status"; type TestFn = dyn Fn() -> TestResult; @@ -73,7 +76,7 @@ impl fmt::Display for TestState { } fn collect_tests() -> Vec { - // Grab your MSR value one time. + // Grab SEV_STATUS one time. let temp_bitfield = match get_sev_status() { Ok(temp_bitfield) => temp_bitfield, Err(e) => { @@ -347,12 +350,25 @@ fn emit_skip(tests: &[Test], level: usize, quiet: bool) { } } -fn get_sev_status() -> Result { +fn get_status_sysfs() -> Result { + let status_file = File::open(SEV_STATUS_SYSFS_FILENAME)?; + let mut reader = BufReader::new(status_file); + let mut buffer = String::new(); + + reader.read_line(&mut buffer)?; + Ok(SevStatus(u64::from_str_radix(buffer.trim(), 16)?)) +} + +fn get_status_msr() -> Result { let mut msr = Msr::new(MSR_SEV_STATUS, 0).context("Error Reading MSR")?; let my_bitfield = SevStatus(msr.read()?); Ok(my_bitfield) } +fn get_sev_status() -> Result { + get_status_sysfs().or_else(|_| get_status_msr()) +} + fn run_msr_check(check_bit: u64, sev_feature: &str, optional_field: bool) -> TestResult { let mut status = TestState::Fail; let mut message = "DISABLED".to_string();