diff --git a/bootlib/src/platform.rs b/bootlib/src/platform.rs index 23dc10bad..ce8efc10a 100644 --- a/bootlib/src/platform.rs +++ b/bootlib/src/platform.rs @@ -5,7 +5,7 @@ // Author: Jon Lange (jlange@microsoft.com) /// Defines the underlying platform type on which the SVSM will run. -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq)] #[repr(C)] pub enum SvsmPlatformType { Native = 0, diff --git a/kernel/src/platform/mod.rs b/kernel/src/platform/mod.rs index 0d7eaad81..46d4bbae1 100644 --- a/kernel/src/platform/mod.rs +++ b/kernel/src/platform/mod.rs @@ -13,6 +13,7 @@ use crate::platform::native::NativePlatform; use crate::platform::snp::SnpPlatform; use crate::platform::tdp::TdpPlatform; use crate::types::PageSize; +use crate::utils; use crate::utils::immut_after_init::ImmutAfterInitCell; use crate::utils::MemoryRegion; @@ -23,6 +24,7 @@ pub mod native; pub mod snp; pub mod tdp; +static SVSM_PLATFORM_TYPE: ImmutAfterInitCell = ImmutAfterInitCell::uninit(); pub static SVSM_PLATFORM: ImmutAfterInitCell = ImmutAfterInitCell::uninit(); #[derive(Clone, Copy, Debug)] @@ -50,6 +52,14 @@ pub enum PageValidateOp { /// This defines a platform abstraction to permit the SVSM to run on different /// underlying architectures. pub trait SvsmPlatform { + /// Halts the system as required by the platform. + fn halt() + where + Self: Sized, + { + utils::halt(); + } + /// Performs basic early initialization of the runtime environment. fn env_setup(&mut self, debug_serial_port: u16, vtom: usize) -> Result<(), SvsmError>; @@ -142,6 +152,7 @@ pub enum SvsmPlatformCell { impl SvsmPlatformCell { pub fn new(platform_type: SvsmPlatformType) -> Self { + assert_eq!(platform_type, *SVSM_PLATFORM_TYPE); match platform_type { SvsmPlatformType::Native => SvsmPlatformCell::Native(NativePlatform::new()), SvsmPlatformType::Snp => SvsmPlatformCell::Snp(SnpPlatform::new()), @@ -165,3 +176,18 @@ impl SvsmPlatformCell { } } } + +pub fn init_platform_type(platform_type: SvsmPlatformType) { + SVSM_PLATFORM_TYPE.init(&platform_type).unwrap(); +} + +pub fn halt() { + // Use a platform-specific halt. However, the SVSM_PLATFORM global may not + // yet be initialized, so go choose the halt implementation based on the + // platform-specific halt instead. + match *SVSM_PLATFORM_TYPE { + SvsmPlatformType::Native => NativePlatform::halt(), + SvsmPlatformType::Snp => SnpPlatform::halt(), + SvsmPlatformType::Tdp => TdpPlatform::halt(), + } +} diff --git a/kernel/src/platform/tdp.rs b/kernel/src/platform/tdp.rs index d0e9c0873..819f69d2f 100644 --- a/kernel/src/platform/tdp.rs +++ b/kernel/src/platform/tdp.rs @@ -16,7 +16,7 @@ use crate::types::PageSize; use crate::utils::immut_after_init::ImmutAfterInitCell; use crate::utils::{zero_mem_region, MemoryRegion}; use tdx_tdcall::tdx::{ - td_accept_memory, tdvmcall_io_read_16, tdvmcall_io_read_32, tdvmcall_io_read_8, + td_accept_memory, tdvmcall_halt, tdvmcall_io_read_16, tdvmcall_io_read_32, tdvmcall_io_read_8, tdvmcall_io_write_16, tdvmcall_io_write_32, tdvmcall_io_write_8, }; @@ -39,6 +39,10 @@ impl Default for TdpPlatform { } impl SvsmPlatform for TdpPlatform { + fn halt() { + tdvmcall_halt(); + } + fn env_setup(&mut self, debug_serial_port: u16, vtom: usize) -> Result<(), SvsmError> { VTOM.init(&vtom).map_err(|_| SvsmError::PlatformInit)?; // Serial console device can be initialized immediately diff --git a/kernel/src/stage2.rs b/kernel/src/stage2.rs index 3520ad39a..96094c532 100755 --- a/kernel/src/stage2.rs +++ b/kernel/src/stage2.rs @@ -33,9 +33,12 @@ use svsm::mm::validate::{ init_valid_bitmap_alloc, valid_bitmap_addr, valid_bitmap_set_valid_range, }; use svsm::mm::{init_kernel_mapping_info, FixedAddressMappingRange, SVSM_PERCPU_BASE}; -use svsm::platform::{PageStateChangeOp, PageValidateOp, SvsmPlatform, SvsmPlatformCell}; +use svsm::platform; +use svsm::platform::{ + init_platform_type, PageStateChangeOp, PageValidateOp, SvsmPlatform, SvsmPlatformCell, +}; use svsm::types::{PageSize, PAGE_SIZE, PAGE_SIZE_2M}; -use svsm::utils::{halt, is_aligned, MemoryRegion}; +use svsm::utils::{is_aligned, MemoryRegion}; extern "C" { static mut pgtable: PageTable; @@ -345,6 +348,7 @@ fn prepare_heap( #[no_mangle] pub extern "C" fn stage2_main(launch_info: &Stage2LaunchInfo) { let platform_type = SvsmPlatformType::from(launch_info.platform_type); + init_platform_type(platform_type); let mut platform_cell = SvsmPlatformCell::new(platform_type); let platform = platform_cell.as_mut_dyn_ref(); @@ -465,6 +469,6 @@ pub extern "C" fn stage2_main(launch_info: &Stage2LaunchInfo) { fn panic(info: &PanicInfo<'_>) -> ! { log::error!("Panic: {}", info); loop { - halt(); + platform::halt(); } } diff --git a/kernel/src/svsm.rs b/kernel/src/svsm.rs index 25690876a..5188c2251 100755 --- a/kernel/src/svsm.rs +++ b/kernel/src/svsm.rs @@ -38,7 +38,8 @@ use svsm::mm::memory::{init_memory_map, write_guest_memory_map}; use svsm::mm::pagetable::paging_init; use svsm::mm::virtualrange::virt_log_usage; use svsm::mm::{init_kernel_mapping_info, FixedAddressMappingRange, PerCPUPageMappingGuard}; -use svsm::platform::{SvsmPlatformCell, SVSM_PLATFORM}; +use svsm::platform; +use svsm::platform::{init_platform_type, SvsmPlatformCell, SVSM_PLATFORM}; use svsm::requests::{request_loop, request_processing_main, update_mappings}; use svsm::sev::utils::{rmp_adjust, RMPFlags}; use svsm::sev::{secrets_page, secrets_page_mut}; @@ -46,7 +47,7 @@ use svsm::svsm_paging::{init_page_table, invalidate_early_boot_memory}; use svsm::task::exec_user; use svsm::task::{create_kernel_task, schedule_init}; use svsm::types::{PageSize, GUEST_VMPL, PAGE_SIZE}; -use svsm::utils::{halt, immut_after_init::ImmutAfterInitCell, zero_mem_region}; +use svsm::utils::{immut_after_init::ImmutAfterInitCell, zero_mem_region}; #[cfg(all(feature = "mstpm", not(test)))] use svsm::vtpm::vtpm_init; @@ -276,6 +277,8 @@ fn init_cpuid_table(addr: VirtAddr) { #[no_mangle] pub extern "C" fn svsm_start(li: &KernelLaunchInfo, vb_addr: usize) { let launch_info: KernelLaunchInfo = *li; + init_platform_type(launch_info.platform_type); + let vb_ptr = core::ptr::NonNull::new(VirtAddr::new(vb_addr).as_mut_ptr::()).unwrap(); mapping_info_init(&launch_info); @@ -483,6 +486,6 @@ fn panic(info: &PanicInfo<'_>) -> ! { loop { debug_break(); - halt(); + platform::halt(); } }