Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

openhcl: use host-provided srat/madt along with other host acpi tables #653

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions openhcl/underhill_core/src/loader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,14 +428,38 @@ pub fn write_uefi_config(
acpi_irq: crate::worker::SYSTEM_IRQ_ACPI,
};

// Build the ACPI tables as specified.
let madt = acpi_builder.build_madt();
let srat = acpi_builder.build_srat();
let (mut madt, mut srat);
if !isolated {
// The host has ACPI table specializations. Use the host-provided SRAT
// and MADT as well.
//
// FUTURE: merge these with any guest topology modifications, or at
// least validate that no such modifications are present.
tracing::info!("using host-provided srat and madt");
madt = igvm_parameters.madt();
srat = igvm_parameters.srat();
} else {
tracing::info!("using generated srat and madt");
madt = None;
srat = None;
}

// Build the ACPI tables as necessary.
let mut madt_buf = Vec::new();
let madt = *madt.get_or_insert_with(|| {
madt_buf = acpi_builder.build_madt();
&madt_buf
});
let mut srat_buf = Vec::new();
let srat = *srat.get_or_insert_with(|| {
srat_buf = acpi_builder.build_srat();
&srat_buf
});

// - Data that comes from the IGVM parameters
{
cfg.add_raw(config::BlobStructureType::Madt, &madt)
.add_raw(config::BlobStructureType::Srat, &srat)
cfg.add_raw(config::BlobStructureType::Madt, madt)
.add_raw(config::BlobStructureType::Srat, srat)
.add_raw(
config::BlobStructureType::MemoryMap,
vtl0_memory_map
Expand Down
64 changes: 31 additions & 33 deletions openhcl/underhill_core/src/loader/vtl2_config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ use bootloader_fdt_parser::ParsedBootDtInfo;
use hvdef::HV_PAGE_SIZE;
use inspect::Inspect;
use loader_defs::paravisor::ParavisorMeasuredVtl2Config;
use loader_defs::paravisor::PARAVISOR_CONFIG_MADT_PAGE_INDEX;
use loader_defs::paravisor::PARAVISOR_CONFIG_PPTT_PAGE_INDEX;
use loader_defs::paravisor::PARAVISOR_CONFIG_SLIT_PAGE_INDEX;
use loader_defs::paravisor::PARAVISOR_CONFIG_SRAT_PAGE_INDEX;
use loader_defs::paravisor::PARAVISOR_MEASURED_VTL2_CONFIG_PAGE_INDEX;
use loader_defs::paravisor::PARAVISOR_RESERVED_VTL2_SNP_CPUID_PAGE_INDEX;
use loader_defs::paravisor::PARAVISOR_RESERVED_VTL2_SNP_CPUID_SIZE_PAGES;
Expand All @@ -31,6 +33,8 @@ use zerocopy::AsBytes;
#[derive(Debug, Inspect)]
pub struct RuntimeParameters {
parsed_openhcl_boot: ParsedBootDtInfo,
madt: Option<Vec<u8>>,
srat: Option<Vec<u8>>,
slit: Option<Vec<u8>>,
pptt: Option<Vec<u8>>,
cvm_cpuid_info: Option<Vec<u8>>,
Expand Down Expand Up @@ -64,6 +68,16 @@ impl RuntimeParameters {
self.pptt.as_deref()
}

/// The VM's ACPI SRAT table provided by the host.
pub fn srat(&self) -> Option<&[u8]> {
self.srat.as_deref()
}

/// The VM's ACPI MADT table provided by the host.
pub fn madt(&self) -> Option<&[u8]> {
self.madt.as_deref()
}

/// The hardware supplied cpuid information for a CVM.
pub fn cvm_cpuid_info(&self) -> Option<&[u8]> {
self.cvm_cpuid_info.as_deref()
Expand Down Expand Up @@ -184,46 +198,28 @@ pub fn read_vtl2_params() -> anyhow::Result<(RuntimeParameters, MeasuredVtl2Info

// For the various ACPI tables, read the header to see how big the table
// is, then read the exact table.

let slit = {
let table = |index| {
let table_header: acpi_spec::Header = mapping
.read_plain((PARAVISOR_CONFIG_SLIT_PAGE_INDEX * HV_PAGE_SIZE) as usize)
.context("failed to read slit header")?;
tracing::trace!(?table_header, "Read SLIT ACPI header");
.read_plain((index * HV_PAGE_SIZE) as usize)
.context("failed to read table header")?;
tracing::trace!(?table_header, "Read ACPI header");

if table_header.length.get() == 0 {
let table = if table_header.length.get() == 0 {
None
} else {
let mut slit: Vec<u8> = vec![0; table_header.length.get() as usize];
let mut table: Vec<u8> = vec![0; table_header.length.get() as usize];
mapping
.read_at(
(PARAVISOR_CONFIG_SLIT_PAGE_INDEX * HV_PAGE_SIZE) as usize,
slit.as_mut_slice(),
)
.context("failed to read slit")?;
Some(slit)
}
.read_at((index * HV_PAGE_SIZE) as usize, table.as_mut_slice())
.context("failed to read table")?;
Some(table)
};
anyhow::Ok(table)
};

let pptt = {
let table_header: acpi_spec::Header = mapping
.read_plain((PARAVISOR_CONFIG_PPTT_PAGE_INDEX * HV_PAGE_SIZE) as usize)
.context("failed to read pptt header")?;
tracing::trace!(?table_header, "Read PPTT ACPI header");

if table_header.length.get() == 0 {
None
} else {
let mut pptt: Vec<u8> = vec![0; table_header.length.get() as usize];
mapping
.read_at(
(PARAVISOR_CONFIG_PPTT_PAGE_INDEX * HV_PAGE_SIZE) as usize,
pptt.as_mut_slice(),
)
.context("failed to read pptt")?;
Some(pptt)
}
};
let slit = table(PARAVISOR_CONFIG_SLIT_PAGE_INDEX)?;
let pptt = table(PARAVISOR_CONFIG_PPTT_PAGE_INDEX)?;
let madt = table(PARAVISOR_CONFIG_MADT_PAGE_INDEX)?;
let srat = table(PARAVISOR_CONFIG_SRAT_PAGE_INDEX)?;

// Read SNP specific information from the reserved region.
let (cvm_cpuid_info, snp_secrets) = {
Expand Down Expand Up @@ -281,6 +277,8 @@ pub fn read_vtl2_params() -> anyhow::Result<(RuntimeParameters, MeasuredVtl2Info
parsed_openhcl_boot,
slit,
pptt,
madt,
srat,
cvm_cpuid_info,
snp_secrets,
};
Expand Down
14 changes: 13 additions & 1 deletion vm/loader/loader_defs/src/paravisor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,19 @@ use zerocopy::FromZeroes;
pub const PARAVISOR_CONFIG_SLIT_SIZE_PAGES: u64 = 20;
/// Size in pages for the PPTT.
pub const PARAVISOR_CONFIG_PPTT_SIZE_PAGES: u64 = 20;
/// Size in pages for the MADT.
pub const PARAVISOR_CONFIG_MADT_SIZE_PAGES: u64 = 20;
/// Size in pages for the SRAT.
pub const PARAVISOR_CONFIG_SRAT_SIZE_PAGES: u64 = 20;
/// Size in pages for the device tree.
pub const PARAVISOR_CONFIG_DEVICE_TREE_SIZE_PAGES: u64 = 64;

/// The maximum size in pages of the unmeasured vtl 2 config region.
pub const PARAVISOR_UNMEASURED_VTL2_CONFIG_REGION_PAGE_COUNT_MAX: u64 =
PARAVISOR_CONFIG_SLIT_SIZE_PAGES
+ PARAVISOR_CONFIG_PPTT_SIZE_PAGES
+ PARAVISOR_CONFIG_MADT_SIZE_PAGES
+ PARAVISOR_CONFIG_SRAT_SIZE_PAGES
+ PARAVISOR_CONFIG_DEVICE_TREE_SIZE_PAGES;

// Page indices for different parameters within the unmeasured vtl 2 config region.
Expand All @@ -35,9 +41,15 @@ pub const PARAVISOR_CONFIG_SLIT_PAGE_INDEX: u64 = 0;
/// The page index to the PPTT.
pub const PARAVISOR_CONFIG_PPTT_PAGE_INDEX: u64 =
PARAVISOR_CONFIG_SLIT_PAGE_INDEX + PARAVISOR_CONFIG_SLIT_SIZE_PAGES;
/// The page index to the MADT.
pub const PARAVISOR_CONFIG_MADT_PAGE_INDEX: u64 =
PARAVISOR_CONFIG_PPTT_PAGE_INDEX + PARAVISOR_CONFIG_PPTT_SIZE_PAGES;
/// The page index to the SRAT.
pub const PARAVISOR_CONFIG_SRAT_PAGE_INDEX: u64 =
PARAVISOR_CONFIG_MADT_PAGE_INDEX + PARAVISOR_CONFIG_MADT_SIZE_PAGES;
/// The page index to the device tree.
pub const PARAVISOR_CONFIG_DEVICE_TREE_PAGE_INDEX: u64 =
PARAVISOR_CONFIG_PPTT_PAGE_INDEX + PARAVISOR_CONFIG_PPTT_SIZE_PAGES;
PARAVISOR_CONFIG_SRAT_PAGE_INDEX + PARAVISOR_CONFIG_SRAT_SIZE_PAGES;
/// Base index for the unmeasured vtl 2 config region
pub const PARAVISOR_UNMEASURED_VTL2_CONFIG_REGION_BASE_INDEX: u64 =
PARAVISOR_CONFIG_SLIT_PAGE_INDEX;
Expand Down
36 changes: 36 additions & 0 deletions vm/loader/src/paravisor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,24 @@ where
)?;
importer.import_parameter(pptt_parameter_area, 0, IgvmParameterType::Pptt)?;

// Madt
let madt_page_base = config_region_page_base + PARAVISOR_CONFIG_MADT_PAGE_INDEX;
let madt_parameter_area = importer.create_parameter_area(
madt_page_base,
PARAVISOR_CONFIG_MADT_SIZE_PAGES as u32,
"underhill-madt",
)?;
importer.import_parameter(madt_parameter_area, 0, IgvmParameterType::Madt)?;

// Srat
let srat_page_base = config_region_page_base + PARAVISOR_CONFIG_SRAT_PAGE_INDEX;
let srat_parameter_area = importer.create_parameter_area(
srat_page_base,
PARAVISOR_CONFIG_SRAT_SIZE_PAGES as u32,
"underhill-srat",
)?;
importer.import_parameter(srat_parameter_area, 0, IgvmParameterType::Srat)?;

// device tree
let dt_page_base = config_region_page_base + PARAVISOR_CONFIG_DEVICE_TREE_PAGE_INDEX;
let dt_parameter_area = importer.create_parameter_area(
Expand Down Expand Up @@ -1273,6 +1291,24 @@ where
)?;
importer.import_parameter(pptt_parameter_area, 0, IgvmParameterType::Pptt)?;

// Madt
let madt_page_base = config_region_page_base + PARAVISOR_CONFIG_MADT_PAGE_INDEX;
let madt_parameter_area = importer.create_parameter_area(
madt_page_base,
PARAVISOR_CONFIG_MADT_SIZE_PAGES as u32,
"underhill-madt",
)?;
importer.import_parameter(madt_parameter_area, 0, IgvmParameterType::Madt)?;

// Srat
let srat_page_base = config_region_page_base + PARAVISOR_CONFIG_SRAT_PAGE_INDEX;
let srat_parameter_area = importer.create_parameter_area(
srat_page_base,
PARAVISOR_CONFIG_SRAT_SIZE_PAGES as u32,
"underhill-srat",
)?;
importer.import_parameter(srat_parameter_area, 0, IgvmParameterType::Srat)?;

// device tree
let dt_page_base = config_region_page_base + PARAVISOR_CONFIG_DEVICE_TREE_PAGE_INDEX;
let dt_parameter_area = importer.create_parameter_area(
Expand Down
Loading