diff --git a/src/fdt.rs b/src/fdt.rs index 0f83c4d9..6891e4a5 100644 --- a/src/fdt.rs +++ b/src/fdt.rs @@ -57,6 +57,22 @@ impl Fdt { Ok(self) } + /// Sets the physical address of the EFI SEV-SNP Confidential Computing Blob (CC Blob). + /// This page contains important information used by an SEV-SNP guest to communicate securely + /// with the firmware. For the purpose of this loader, however, it is just a pointer we need + /// to forward to the OS. + #[cfg(target_os = "uefi")] + pub fn efi_sev_snp_cc_blob(mut self, efi_sev_snp_cc_blob: u64) -> FdtWriterResult { + let cc_blob_node = self.writer.begin_node(&format!( + "hermit,efi_sev_snp_cc_blob@{efi_sev_snp_cc_blob:x}" + ))?; + self.writer + .property_array_u64("reg", &[efi_sev_snp_cc_blob, 1])?; + self.writer.end_node(cc_blob_node)?; + + Ok(self) + } + pub fn memory(mut self, memory: Range) -> FdtWriterResult { let memory_node = self .writer diff --git a/src/os/uefi/mod.rs b/src/os/uefi/mod.rs index 63b59263..98f40181 100644 --- a/src/os/uefi/mod.rs +++ b/src/os/uefi/mod.rs @@ -18,6 +18,7 @@ use uefi::boot::{AllocateType, MemoryType, PAGE_SIZE}; use uefi::fs::{self, FileSystem, Path}; use uefi::prelude::*; use uefi::table::cfg::ConfigTableEntry; +use uefi::{Guid, guid}; pub use self::console::CONSOLE; use crate::fdt::Fdt; @@ -48,6 +49,10 @@ fn main() -> Status { .rsdp(u64::try_from(rsdp.expose_provenance()).unwrap()) .unwrap(); + if let Some(cc_blob) = detect_cc_blob() { + fdt = fdt.efi_sev_snp_cc_blob(cc_blob).unwrap() + }; + if let Some(bootargs) = esp.read_bootargs() { fdt = fdt.bootargs(bootargs).unwrap(); } @@ -186,3 +191,24 @@ impl Esp { inner(&mut self.fs, path.as_ref()) } } + +/// Try to locate an AMD SEV-SNP confidential computing blob, and returns its address if found. +/// This function is only relevant on AMD SEV-SNP guests, and will do mostly nothing otherwise. +fn detect_cc_blob() -> Option { + /// EFI SEV-SNP Confidential Computing Blob configuration table. + /// See . + const CC_BLOB_GUID: Guid = guid!("067b1f5f-cf26-44c5-8554-93d777912d42"); + + system::with_config_table(|config_table| { + config_table + .iter() + .find(|entry| entry.guid == CC_BLOB_GUID) + .map(|entry| { + info!( + "EFI SEV-SNP Confidential Computing Blob found at {:p}", + entry.address + ); + u64::try_from(entry.address.addr()).unwrap() + }) + }) +}