From 3af8a24ec9953e032fbb5200dece8d3759623a6e Mon Sep 17 00:00:00 2001 From: Tyler Fanelli Date: Mon, 24 Jul 2023 18:14:23 -0400 Subject: [PATCH 1/9] verify: Fix clippy warning Signed-off-by: Tyler Fanelli --- src/verify.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/verify.rs b/src/verify.rs index df7d0fd..be2d759 100644 --- a/src/verify.rs +++ b/src/verify.rs @@ -51,7 +51,7 @@ mod certificate_chain { pub fn validate_cc(args: Args, quiet: bool) -> Result<()> { let ark_path = find_cert_in_dir(args.certs_dir.clone(), "ark")?; let ask_path = find_cert_in_dir(args.certs_dir.clone(), "ask")?; - let vcek_path = find_cert_in_dir(args.certs_dir.clone(), "vcek")?; + let vcek_path = find_cert_in_dir(args.certs_dir, "vcek")?; // Get a cert chain from directory let cert_chain: Chain = CertPaths { From c685f16d163bcd291a5b1394bae2b1f5eac982ef Mon Sep 17 00:00:00 2001 From: Tyler Fanelli Date: Mon, 24 Jul 2023 21:01:28 -0400 Subject: [PATCH 2/9] Reformat with cargo fmt Signed-off-by: Tyler Fanelli --- src/display.rs | 7 +++---- src/report.rs | 44 ++++++++++++++++++++++---------------------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/display.rs b/src/display.rs index 9573add..924983a 100644 --- a/src/display.rs +++ b/src/display.rs @@ -19,15 +19,14 @@ mod report_display { #[derive(StructOpt)] pub struct Args { - #[structopt( - help = "Path to attestation report to display." - )] + #[structopt(help = "Path to attestation report to display.")] pub att_report_path: PathBuf, } // Print attestation report in console pub fn display_attestation_report(args: Args, quiet: bool) -> Result<()> { - let att_report = report::read_report(args.att_report_path).context("Could not open attestation report")?; + let att_report = report::read_report(args.att_report_path) + .context("Could not open attestation report")?; if !quiet { println!("{}", att_report); diff --git a/src/report.rs b/src/report.rs index 459664f..5c0316d 100644 --- a/src/report.rs +++ b/src/report.rs @@ -27,7 +27,7 @@ pub fn read_report(att_report_path: PathBuf) -> Result [u8; 64] { let mut data = [0u8; 64]; thread_rng().fill_bytes(&mut data); - data + data } // Write data into given file. Split it into 16 byte lines. @@ -79,29 +79,29 @@ pub fn get_report(args: ReportArgs) -> Result<()> { true => { let request_buf = create_random_request(); - // Overwrite data if file already exists - let request_file = if args.request_file.exists() { - std::fs::OpenOptions::new() - .write(true) - .truncate(true) - .open(args.request_file) - .context("Unable to overwrite request file contents")? - } else { - fs::File::create(args.request_file).context("Unable to create request file.")? - }; - write_hex(&mut BufWriter::new(request_file), &request_buf) - .context("Failed to write request data in request file")?; - request_buf - }, + // Overwrite data if file already exists + let request_file = if args.request_file.exists() { + std::fs::OpenOptions::new() + .write(true) + .truncate(true) + .open(args.request_file) + .context("Unable to overwrite request file contents")? + } else { + fs::File::create(args.request_file).context("Unable to create request file.")? + }; + write_hex(&mut BufWriter::new(request_file), &request_buf) + .context("Failed to write request data in request file")?; + request_buf + } false => { let mut request_file = - File::open(args.request_file).context("Could not open the report request file.")?; - let mut request_buf: [u8; 64] = [0; 64]; - request_file - .read(&mut request_buf) - .context("Could not read report request file.")?; - request_buf - } + File::open(args.request_file).context("Could not open the report request file.")?; + let mut request_buf: [u8; 64] = [0; 64]; + request_file + .read(&mut request_buf) + .context("Could not read report request file.")?; + request_buf + } }; // Get attestation report From 92c21b619d870427b097fec7401e04447db6dac7 Mon Sep 17 00:00:00 2001 From: Tyler Fanelli Date: Mon, 24 Jul 2023 18:12:52 -0400 Subject: [PATCH 3/9] hyperv: Detect if in a Hyper-V SEV-SNP guest Signed-off-by: Tyler Fanelli --- src/hyperv/mod.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 3 +++ 2 files changed, 52 insertions(+) create mode 100644 src/hyperv/mod.rs diff --git a/src/hyperv/mod.rs b/src/hyperv/mod.rs new file mode 100644 index 0000000..698d21b --- /dev/null +++ b/src/hyperv/mod.rs @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: Apache-2.0 + +use std::arch::x86_64::__cpuid; + +const CPUID_HYPERV_SIG: &str = "Microsoft Hv"; +const CPUID_HYPERV_VENDOR_AND_MAX_FUNCTIONS: u32 = 0x40000000; +const CPUID_HYPERV_FEATURES: u32 = 0x40000003; +const CPUID_HYPERV_MIN: u32 = 0x40000005; +const CPUID_HYPERV_MAX: u32 = 0x4000ffff; +const CPUID_HYPERV_ISOLATION: u32 = 1 << 22; +const CPUID_HYPERV_CPU_MANAGEMENT: u32 = 1 << 12; +const CPUID_HYPERV_ISOLATION_CONFIG: u32 = 0x4000000C; +const CPUID_HYPERV_ISOLATION_TYPE_MASK: u32 = 0xf; +const CPUID_HYPERV_ISOLATION_TYPE_SNP: u32 = 2; + +pub fn present() -> bool { + let cpuid = unsafe { __cpuid(CPUID_HYPERV_VENDOR_AND_MAX_FUNCTIONS) }; + if cpuid.eax < CPUID_HYPERV_MIN || cpuid.eax > CPUID_HYPERV_MAX { + return false; + } + + let mut sig: Vec = vec![]; + sig.append(&mut cpuid.ebx.to_le_bytes().to_vec()); + sig.append(&mut cpuid.ecx.to_le_bytes().to_vec()); + sig.append(&mut cpuid.edx.to_le_bytes().to_vec()); + + if sig != CPUID_HYPERV_SIG.as_bytes() { + return false; + } + + let cpuid = unsafe { __cpuid(CPUID_HYPERV_FEATURES) }; + + let isolated: bool = (cpuid.ebx & CPUID_HYPERV_ISOLATION) != 0; + let managed: bool = (cpuid.ebx & CPUID_HYPERV_CPU_MANAGEMENT) != 0; + + if !isolated || managed { + return false; + } + + let cpuid = unsafe { __cpuid(CPUID_HYPERV_ISOLATION_CONFIG) }; + let mask = cpuid.ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK; + let snp = CPUID_HYPERV_ISOLATION_TYPE_SNP; + + if mask != snp { + return false; + } + + true +} diff --git a/src/main.rs b/src/main.rs index 20bdf1b..a2a1168 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,8 @@ mod fetch; mod report; mod verify; +mod hyperv; + use certs::CertificatesArgs; use display::DisplayCmd; use fetch::FetchCmd; @@ -51,6 +53,7 @@ fn main() -> Result<()> { env_logger::init(); let snpguest = SnpGuest::from_args(); + let hv = hyperv::present(); let status = match snpguest.cmd { SnpGuestCmd::Report(args) => report::get_report(args), From e7044935801e34fd635e8a34fa755810d5ccf140 Mon Sep 17 00:00:00 2001 From: Tyler Fanelli Date: Mon, 24 Jul 2023 23:28:35 -0400 Subject: [PATCH 4/9] hyperv: Fetch attestation report from Azure vTPM Signed-off-by: Tyler Fanelli --- Cargo.toml | 1 + src/hyperv/mod.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 2 +- src/report.rs | 16 ++++++++++------ 4 files changed, 61 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 024da39..93a11fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,3 +27,4 @@ hex = "0.4" x509-parser = { version="^0.14", features=["verify"] } asn1-rs = "*" rand = "*" +tss-esapi = "7.2" diff --git a/src/hyperv/mod.rs b/src/hyperv/mod.rs index 698d21b..f5f99bc 100644 --- a/src/hyperv/mod.rs +++ b/src/hyperv/mod.rs @@ -1,5 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 +use super::*; + use std::arch::x86_64::__cpuid; const CPUID_HYPERV_SIG: &str = "Microsoft Hv"; @@ -47,3 +49,50 @@ pub fn present() -> bool { true } + +pub mod report { + use super::*; + + use anyhow::Context; + use serde::{Deserialize, Serialize}; + use sev::firmware::guest::AttestationReport; + use tss_esapi::{ + abstraction::nv, + handles::NvIndexTpmHandle, + interface_types::{resource_handles::NvAuth, session_handles::AuthSession}, + tcti_ldr::{DeviceConfig, TctiNameConf}, + }; + + const VTPM_HCL_REPORT_NV_INDEX: u32 = 0x01400001; + + #[repr(C)] + #[derive(Deserialize, Serialize, Debug, Clone, Copy)] + struct Hcl { + rsv1: [u32; 8], + report: AttestationReport, + rsv2: [u32; 5], + } + + pub fn get() -> Result { + let bytes = tpm2_read().context("unable to read attestation report bytes from vTPM")?; + + hcl_report(&bytes) + } + + fn tpm2_read() -> Result> { + let handle = NvIndexTpmHandle::new(VTPM_HCL_REPORT_NV_INDEX) + .context("unable to initialize TPM handle")?; + let mut ctx = tss_esapi::Context::new(TctiNameConf::Device(DeviceConfig::default()))?; + ctx.set_sessions((Some(AuthSession::Password), None, None)); + + nv::read_full(&mut ctx, NvAuth::Owner, handle) + .context("unable to read non-volatile vTPM data") + } + + fn hcl_report(bytes: &[u8]) -> Result { + let hcl: Hcl = + bincode::deserialize(bytes).context("unable to deserialize bytes from vTPM")?; + + Ok(hcl.report) + } +} diff --git a/src/main.rs b/src/main.rs index a2a1168..16773bb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -56,7 +56,7 @@ fn main() -> Result<()> { let hv = hyperv::present(); let status = match snpguest.cmd { - SnpGuestCmd::Report(args) => report::get_report(args), + SnpGuestCmd::Report(args) => report::get_report(args, hv), SnpGuestCmd::Certificates(args) => certs::get_ext_certs(args), SnpGuestCmd::Fetch(subcmd) => fetch::cmd(subcmd), SnpGuestCmd::Verify(subcmd) => verify::cmd(subcmd, snpguest.quiet), diff --git a/src/report.rs b/src/report.rs index 5c0316d..0a5d8f9 100644 --- a/src/report.rs +++ b/src/report.rs @@ -72,9 +72,7 @@ pub struct ReportArgs { } // Request attestation report and write it into a file -pub fn get_report(args: ReportArgs) -> Result<()> { - let mut sev_fw: Firmware = Firmware::open().context("failed to open SEV firmware device.")?; - +pub fn get_report(args: ReportArgs, hv: bool) -> Result<()> { let request_data = match args.random { true => { let request_buf = create_random_request(); @@ -105,9 +103,15 @@ pub fn get_report(args: ReportArgs) -> Result<()> { }; // Get attestation report - let att_report = sev_fw - .get_report(None, Some(request_data), args.vmpl) - .context("Failed to get report.")?; + let att_report = if hv { + hyperv::report::get()? + } else { + let mut sev_fw: Firmware = + Firmware::open().context("failed to open SEV firmware device.")?; + sev_fw + .get_report(None, Some(request_data), args.vmpl) + .context("Failed to get report.")? + }; // Write attestation report into desired file let mut attestation_file = if args.att_report_path.exists() { From b8983b42f1edb47ab6a16f0747fe0e86c2a3c5f3 Mon Sep 17 00:00:00 2001 From: Tyler Fanelli Date: Tue, 25 Jul 2023 13:09:42 -0400 Subject: [PATCH 5/9] hyperv: Check for hypervisor guest + Hyper-V functions Signed-off-by: Tyler Fanelli --- src/hyperv/mod.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/hyperv/mod.rs b/src/hyperv/mod.rs index f5f99bc..d687645 100644 --- a/src/hyperv/mod.rs +++ b/src/hyperv/mod.rs @@ -4,6 +4,11 @@ use super::*; use std::arch::x86_64::__cpuid; +const CPUID_GET_HIGHEST_FUNCTION: u32 = 0x80000000; +const CPUID_PROCESSOR_INFO_AND_FEATURE_BITS: u32 = 0x1; + +const CPUID_FEATURE_HYPERVISOR: u32 = 1 << 31; + const CPUID_HYPERV_SIG: &str = "Microsoft Hv"; const CPUID_HYPERV_VENDOR_AND_MAX_FUNCTIONS: u32 = 0x40000000; const CPUID_HYPERV_FEATURES: u32 = 0x40000003; @@ -16,6 +21,16 @@ const CPUID_HYPERV_ISOLATION_TYPE_MASK: u32 = 0xf; const CPUID_HYPERV_ISOLATION_TYPE_SNP: u32 = 2; pub fn present() -> bool { + let cpuid = unsafe { __cpuid(CPUID_PROCESSOR_INFO_AND_FEATURE_BITS) }; + if (cpuid.ecx & CPUID_FEATURE_HYPERVISOR) == 0 { + return false; + } + + let cpuid = unsafe { __cpuid(CPUID_GET_HIGHEST_FUNCTION) }; + if cpuid.eax < CPUID_HYPERV_VENDOR_AND_MAX_FUNCTIONS { + return false; + } + let cpuid = unsafe { __cpuid(CPUID_HYPERV_VENDOR_AND_MAX_FUNCTIONS) }; if cpuid.eax < CPUID_HYPERV_MIN || cpuid.eax > CPUID_HYPERV_MAX { return false; From c7ad0fe0bd0538d8a47dd2fcdd99b4e398b72fd8 Mon Sep 17 00:00:00 2001 From: Tyler Fanelli Date: Tue, 25 Jul 2023 13:36:22 -0400 Subject: [PATCH 6/9] hyperv: Require VMPL 0 for attestation report Signed-off-by: Tyler Fanelli --- src/hyperv/mod.rs | 7 +++++-- src/report.rs | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/hyperv/mod.rs b/src/hyperv/mod.rs index d687645..ad5db95 100644 --- a/src/hyperv/mod.rs +++ b/src/hyperv/mod.rs @@ -68,7 +68,7 @@ pub fn present() -> bool { pub mod report { use super::*; - use anyhow::Context; + use anyhow::{anyhow, Context}; use serde::{Deserialize, Serialize}; use sev::firmware::guest::AttestationReport; use tss_esapi::{ @@ -88,7 +88,10 @@ pub mod report { rsv2: [u32; 5], } - pub fn get() -> Result { + pub fn get(vmpl: u32) -> Result { + if vmpl > 0 { + return Err(anyhow!("Azure vTPM attestation report requires VMPL 0")); + } let bytes = tpm2_read().context("unable to read attestation report bytes from vTPM")?; hcl_report(&bytes) diff --git a/src/report.rs b/src/report.rs index 0a5d8f9..db41b38 100644 --- a/src/report.rs +++ b/src/report.rs @@ -104,7 +104,7 @@ pub fn get_report(args: ReportArgs, hv: bool) -> Result<()> { // Get attestation report let att_report = if hv { - hyperv::report::get()? + hyperv::report::get(args.vmpl.unwrap_or(0))? } else { let mut sev_fw: Firmware = Firmware::open().context("failed to open SEV firmware device.")?; From 34b0e6b8f5ec606bd64b8b57db3b44815d41f34a Mon Sep 17 00:00:00 2001 From: Tyler Fanelli Date: Sun, 30 Jul 2023 23:47:23 -0400 Subject: [PATCH 7/9] report: Add --platform flag for Hyper-V Currently, with Hyper-V guests, the report_data of an attestation report is generated beforehand by the platform. This indicates that a user cannot write some optional data to be included in the report. With --platform enabled, the pre-generated platform data will be written to the file pointed to by $REQUEST_PATH (or "platform-request-file.txt" if no $REQUEST_PATH is given as input). Signed-off-by: Tyler Fanelli --- src/report.rs | 168 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 101 insertions(+), 67 deletions(-) diff --git a/src/report.rs b/src/report.rs index db41b38..dd38c2b 100644 --- a/src/report.rs +++ b/src/report.rs @@ -3,14 +3,13 @@ use super::*; use std::{ - fs, - fs::File, - io::{BufWriter, Read, Write}, + fs::{self, File, OpenOptions}, + io::{Read, Write}, path::PathBuf, }; +use anyhow::{anyhow, Result}; use rand::{thread_rng, RngCore}; - use sev::firmware::guest::{AttestationReport, Firmware}; // Read a bin-formatted attestation report. @@ -30,22 +29,6 @@ pub fn create_random_request() -> [u8; 64] { data } -// Write data into given file. Split it into 16 byte lines. -pub fn write_hex(file: &mut BufWriter, data: &[u8]) -> Result<()> { - let mut line_counter = 0; - for val in data { - // Make it blocks for easier read - if line_counter.eq(&16) { - writeln!(file).context("Failed to write data to file")?; - line_counter = 0; - } - // Write byte into file - write!(file, "{:02x}", val).context("Failed to write data to file")?; - line_counter += 1; - } - Ok(()) -} - #[derive(StructOpt)] pub struct ReportArgs { #[structopt(help = "File to write the attestation report to.")] @@ -69,63 +52,114 @@ pub struct ReportArgs { help = "Provide file with data for attestation-report request. If provided with random flag, then the random data will be written in the provided path." )] pub request_file: PathBuf, + + #[structopt( + long, + short, + help = "Expect that the 64-byte report data will already be provided by the platform provider." + )] + pub platform: bool, } -// Request attestation report and write it into a file -pub fn get_report(args: ReportArgs, hv: bool) -> Result<()> { - let request_data = match args.random { - true => { - let request_buf = create_random_request(); - - // Overwrite data if file already exists - let request_file = if args.request_file.exists() { - std::fs::OpenOptions::new() - .write(true) - .truncate(true) - .open(args.request_file) - .context("Unable to overwrite request file contents")? - } else { - fs::File::create(args.request_file).context("Unable to create request file.")? - }; - write_hex(&mut BufWriter::new(request_file), &request_buf) - .context("Failed to write request data in request file")?; - request_buf +impl ReportArgs { + pub fn verify(&self, hyperv: bool) -> Result<()> { + if self.random && self.platform { + return Err(anyhow!( + "--random and --platform both enabled (not allowed). Consult man page." + )); } - false => { - let mut request_file = - File::open(args.request_file).context("Could not open the report request file.")?; - let mut request_buf: [u8; 64] = [0; 64]; - request_file - .read(&mut request_buf) - .context("Could not read report request file.")?; - request_buf + + if self.random && hyperv { + return Err(anyhow!( + "--random enabled yet Hyper-V guest detected (not allowed). Consult man page." + )); } - }; - // Get attestation report - let att_report = if hv { - hyperv::report::get(args.vmpl.unwrap_or(0))? + if self.platform && !hyperv { + return Err(anyhow!("--platform enabled yet Hyper-V guest not detected (not allowed). Consult man page.")); + } + + Ok(()) + } +} + +// Request attestation report and write it into a file +pub fn get_report(args: ReportArgs, hv: bool) -> Result<()> { + args.verify(hv)?; + + let data: Option<[u8; 64]> = if args.random { + Some(create_random_request()) + } else if args.platform { + None } else { - let mut sev_fw: Firmware = - Firmware::open().context("failed to open SEV firmware device.")?; - sev_fw - .get_report(None, Some(request_data), args.vmpl) - .context("Failed to get report.")? + /* + * Read from the request file. + */ + let mut bytes = [0u8; 64]; + let mut file = File::open(&args.request_file)?; + file.read_exact(&mut bytes) + .context("unable to read 64 bytes from REQUEST_FILE")?; + + Some(bytes) }; - // Write attestation report into desired file - let mut attestation_file = if args.att_report_path.exists() { - std::fs::OpenOptions::new() - .write(true) - .truncate(true) - .open(args.att_report_path) - .context("Unable to overwrite attestation report file contents")? + let report = if hv { + hyperv::report::get(args.vmpl.unwrap_or(0))? } else { - fs::File::create(args.att_report_path) - .context("Unable to create attestation report file contents")? + let mut fw = Firmware::open().context("unable to open /dev/sev")?; + fw.get_report(None, data, args.vmpl) + .context("unable to fetch attestation report")? }; - bincode::serialize_into(&mut attestation_file, &att_report) - .context("Could not serialize attestation report into file.")?; + /* + * Serialize and write attestation report. + */ + let mut file = OpenOptions::new() + .create(true) + .truncate(true) + .write(true) + .open(&args.att_report_path)?; + + write!(&mut file, "{}", report).context(format!( + "unable to write attestation report to {}", + args.att_report_path.display() + ))?; + + /* + * Write reports report data (only for --random or --platform). + */ + if args.random { + reqdata_write(args.request_file, &report).context("unable to write random request data")?; + } else if args.platform { + reqdata_write(args.request_file, &report) + .context("unable to write platform request data")?; + } + + Ok(()) +} + +fn reqdata_write(name: PathBuf, report: &AttestationReport) -> Result<()> { + let mut file = OpenOptions::new() + .create(true) + .truncate(true) + .write(true) + .open(name) + .context("unable to create or write to request data file")?; + + write_hex(&mut file, &report.report_data).context("unable to write report data to REQUEST_FILE") +} + +pub fn write_hex(file: &mut File, data: &[u8]) -> Result<()> { + let mut line_counter = 0; + for val in data { + // Make it blocks for easier read + if line_counter.eq(&16) { + writeln!(file)?; + line_counter = 0; + } + + write!(file, "{:02x}", val)?; + line_counter += 1; + } Ok(()) } From deea7e3925d61f5b0bd4c89f146ef376b96b8988 Mon Sep 17 00:00:00 2001 From: Tyler Fanelli Date: Mon, 31 Jul 2023 23:02:26 -0400 Subject: [PATCH 8/9] docs: Document report --platform flag Signed-off-by: Tyler Fanelli --- docs/snpguest.1.adoc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/snpguest.1.adoc b/docs/snpguest.1.adoc index 656ca91..fbf368a 100644 --- a/docs/snpguest.1.adoc +++ b/docs/snpguest.1.adoc @@ -26,13 +26,16 @@ GLOBAL OPTIONS COMMANDS -------- *snpguest report*:: - usage: snpguest report $ATT_REPORT_PATH $REQUEST_FILE [-v, --vmpl] $VMPL [-r, --random] + usage: snpguest report $ATT_REPORT_PATH $REQUEST_FILE [-v, --vmpl] $VMPL [-r, --random] [-p, --platform] Requests an attestation report from the host and writes it in a file with the provided request data and vmpl. Will write the contents of the attestation report in binary format into the specified report path. A path for the attestation report must be provided. User can pass 64 bytes of data in any file format into $REQUEST_FILE in order to use that data to request the attestation report. The user can use the --random flag to generate and use random data for request data. + For Microsoft Hyper-V guests, a user can use the --platform flag to use the request data that was pre-generated + from the platform. Currently, for Hyper-V guests, --platform is required, as there is no ability to write + request data for the attestation report. If the user uses the --random flag, then the data will be written into the file they provided in $REQUEST_FILE. VMPL is an optional parameter and it defaults to 1. From 49a6f10c0b217e1d5629f6f51725dd601fa97cba Mon Sep 17 00:00:00 2001 From: Tyler Fanelli Date: Sun, 6 Aug 2023 19:59:40 -0400 Subject: [PATCH 9/9] azure: Use mutable variable instead of consistently recreating Signed-off-by: Tyler Fanelli --- src/hyperv/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hyperv/mod.rs b/src/hyperv/mod.rs index ad5db95..dfecee2 100644 --- a/src/hyperv/mod.rs +++ b/src/hyperv/mod.rs @@ -21,17 +21,17 @@ const CPUID_HYPERV_ISOLATION_TYPE_MASK: u32 = 0xf; const CPUID_HYPERV_ISOLATION_TYPE_SNP: u32 = 2; pub fn present() -> bool { - let cpuid = unsafe { __cpuid(CPUID_PROCESSOR_INFO_AND_FEATURE_BITS) }; + let mut cpuid = unsafe { __cpuid(CPUID_PROCESSOR_INFO_AND_FEATURE_BITS) }; if (cpuid.ecx & CPUID_FEATURE_HYPERVISOR) == 0 { return false; } - let cpuid = unsafe { __cpuid(CPUID_GET_HIGHEST_FUNCTION) }; + cpuid = unsafe { __cpuid(CPUID_GET_HIGHEST_FUNCTION) }; if cpuid.eax < CPUID_HYPERV_VENDOR_AND_MAX_FUNCTIONS { return false; } - let cpuid = unsafe { __cpuid(CPUID_HYPERV_VENDOR_AND_MAX_FUNCTIONS) }; + cpuid = unsafe { __cpuid(CPUID_HYPERV_VENDOR_AND_MAX_FUNCTIONS) }; if cpuid.eax < CPUID_HYPERV_MIN || cpuid.eax > CPUID_HYPERV_MAX { return false; } @@ -45,7 +45,7 @@ pub fn present() -> bool { return false; } - let cpuid = unsafe { __cpuid(CPUID_HYPERV_FEATURES) }; + cpuid = unsafe { __cpuid(CPUID_HYPERV_FEATURES) }; let isolated: bool = (cpuid.ebx & CPUID_HYPERV_ISOLATION) != 0; let managed: bool = (cpuid.ebx & CPUID_HYPERV_CPU_MANAGEMENT) != 0; @@ -54,7 +54,7 @@ pub fn present() -> bool { return false; } - let cpuid = unsafe { __cpuid(CPUID_HYPERV_ISOLATION_CONFIG) }; + cpuid = unsafe { __cpuid(CPUID_HYPERV_ISOLATION_CONFIG) }; let mask = cpuid.ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK; let snp = CPUID_HYPERV_ISOLATION_TYPE_SNP;