Skip to content

Commit

Permalink
fw_meta: refactor parse_fw_meta_data() to take a &[u8]
Browse files Browse the repository at this point in the history
Refactor the public function parse_fw_meta_data() so that the caller
can provide an slice containing the firmware metadata. This will help
building a fuzzing harness around this interface

Signed-off-by: Carlos López <[email protected]>
  • Loading branch information
00xc committed Oct 18, 2023
1 parent dde36a0 commit 07b2acb
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 12 deletions.
21 changes: 11 additions & 10 deletions src/fw_meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use crate::address::{Address, PhysAddr};
use crate::cpu::percpu::this_cpu_mut;
use crate::error::SvsmError;
use crate::mm::PerCPUPageMappingGuard;
use crate::mm::SIZE_1G;
use crate::sev::ghcb::PageStateChangeOp;
use crate::sev::{pvalidate, rmp_adjust, PvalidateOp, RMPFlags};
use crate::types::{PageSize, PAGE_SIZE};
Expand Down Expand Up @@ -245,16 +244,18 @@ fn find_table<'a>(uuid: &Uuid, mem: &'a [u8]) -> Option<&'a [u8]> {
None
}

pub fn parse_fw_meta_data() -> Result<SevFWMetaData, SvsmError> {
/// Parse the firmware metadata from the given slice.
pub fn parse_fw_meta_data(mem: &[u8]) -> Result<SevFWMetaData, SvsmError> {
let mut meta_data = SevFWMetaData::new();
// Map meta-data location, it starts at 32 bytes below 4GiB
let pstart = PhysAddr::from((4 * SIZE_1G) - PAGE_SIZE);
let guard = PerCPUPageMappingGuard::create_4k(pstart)?;
let vstart = guard.virt_addr();

// Safety: RawMetaBuffer has a size of one page and it has no invalid
// representations.
let raw_meta = unsafe { &*vstart.as_ptr::<RawMetaBuffer>() };

if mem.len() != size_of::<RawMetaBuffer>() {
return Err(SvsmError::Firmware);
}

// Safety: `RawMetaBuffer` has no invalid representations and is
// `repr(C, packed)`, which means there are no alignment requirements.
// We have also verified that the size of the slice matches.
let raw_meta = unsafe { &*mem.as_ptr().cast::<RawMetaBuffer>() };

// Check the UUID
let raw_uuid = raw_meta.header.uuid;
Expand Down
15 changes: 13 additions & 2 deletions src/svsm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use svsm::mm::alloc::{memory_info, print_memory_info, root_mem_init};
use svsm::mm::memory::init_memory_map;
use svsm::mm::pagetable::paging_init;
use svsm::mm::virtualrange::virt_log_usage;
use svsm::mm::{init_kernel_mapping_info, PerCPUPageMappingGuard};
use svsm::mm::{init_kernel_mapping_info, PerCPUPageMappingGuard, SIZE_1G};
use svsm::requests::{request_loop, update_mappings};
use svsm::serial::SerialPort;
use svsm::serial::SERIAL_PORT;
Expand Down Expand Up @@ -310,6 +310,17 @@ fn mapping_info_init(launch_info: &KernelLaunchInfo) {
);
}

fn map_and_parse_fw_meta() -> Result<SevFWMetaData, SvsmError> {
// Map meta-data location, it starts at 32 bytes below 4GiB
let pstart = PhysAddr::from((4 * SIZE_1G) - PAGE_SIZE);
let guard = PerCPUPageMappingGuard::create_4k(pstart)?;
let vstart = guard.virt_addr().as_ptr::<u8>();
// Safety: we just mapped a page, so the size must hold. The type
// of the slice elements is `u8` so there are no alignment requirements.
let metadata = unsafe { slice::from_raw_parts(vstart, PAGE_SIZE) };
parse_fw_meta_data(metadata)
}

#[no_mangle]
pub extern "C" fn svsm_start(li: &KernelLaunchInfo, vb_addr: usize) {
let launch_info: KernelLaunchInfo = *li;
Expand Down Expand Up @@ -443,7 +454,7 @@ pub extern "C" fn svsm_main() {

start_secondary_cpus(&cpus);

let fw_meta = parse_fw_meta_data()
let fw_meta = map_and_parse_fw_meta()
.unwrap_or_else(|e| panic!("Failed to parse FW SEV meta-data: {:#?}", e));

print_fw_meta(&fw_meta);
Expand Down

0 comments on commit 07b2acb

Please sign in to comment.