Skip to content

Commit

Permalink
panic: use a platform-specific halt routine
Browse files Browse the repository at this point in the history
Not all platforms support HLT as a way to halt execution, and therefore
the panic halt must be performed through a platform-specific routine.
However, at the time of a panic, the global platform object may not yet
be initialized.  Instead, use a more primitive mechanism for choosing a
platform-specific halt routine during panic.

Signed-off-by: Jon Lange <[email protected]>
  • Loading branch information
msft-jlange committed Oct 25, 2024
1 parent 2f07766 commit 4170523
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 8 deletions.
2 changes: 1 addition & 1 deletion bootlib/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Author: Jon Lange ([email protected])

/// 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,
Expand Down
26 changes: 26 additions & 0 deletions kernel/src/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -23,6 +24,7 @@ pub mod native;
pub mod snp;
pub mod tdp;

static SVSM_PLATFORM_TYPE: ImmutAfterInitCell<SvsmPlatformType> = ImmutAfterInitCell::uninit();
pub static SVSM_PLATFORM: ImmutAfterInitCell<SvsmPlatformCell> = ImmutAfterInitCell::uninit();

#[derive(Clone, Copy, Debug)]
Expand Down Expand Up @@ -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>;

Expand Down Expand Up @@ -135,6 +145,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()),
Expand All @@ -158,3 +169,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(),
}
}
6 changes: 5 additions & 1 deletion kernel/src/platform/tdp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand All @@ -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
Expand Down
10 changes: 7 additions & 3 deletions kernel/src/stage2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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();
}
}
9 changes: 6 additions & 3 deletions kernel/src/svsm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,16 @@ 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};
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;

Expand Down Expand Up @@ -275,6 +276,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::<u64>()).unwrap();

mapping_info_init(&launch_info);
Expand Down Expand Up @@ -481,6 +484,6 @@ fn panic(info: &PanicInfo<'_>) -> ! {

loop {
debug_break();
halt();
platform::halt();
}
}

0 comments on commit 4170523

Please sign in to comment.