diff --git a/backends/igvm.c b/backends/igvm.c index 3e7c0ea41d..b01a19ba46 100644 --- a/backends/igvm.c +++ b/backends/igvm.c @@ -128,6 +128,8 @@ static struct QIGVMHandler handlers[] = { qigvm_directive_snp_id_block }, { IGVM_VHT_GUEST_POLICY, IGVM_HEADER_SECTION_INITIALIZATION, qigvm_initialization_guest_policy }, + { IGVM_VHT_MADT, IGVM_HEADER_SECTION_DIRECTIVE, + qigvm_directive_madt }, }; static int qigvm_handler(QIgvm *ctx, uint32_t type, Error **errp) diff --git a/include/system/igvm-internal.h b/include/system/igvm-internal.h index 1d36519ab0..38004bd908 100644 --- a/include/system/igvm-internal.h +++ b/include/system/igvm-internal.h @@ -74,4 +74,9 @@ IgvmHandle qigvm_file_init(char *filename, Error **errp); QIgvmParameterData* qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index); +/* + * IGVM parameter handlers + */ +int qigvm_directive_madt(QIgvm *ctx, const uint8_t *header_data, Error **errp); + #endif diff --git a/stubs/igvm.c b/stubs/igvm.c index 17cd1e903e..47d5130d9d 100644 --- a/stubs/igvm.c +++ b/stubs/igvm.c @@ -12,6 +12,7 @@ #include "qemu/osdep.h" #include "system/igvm.h" +#include "system/igvm-internal.h" int qigvm_x86_get_mem_map_entry(int index, ConfidentialGuestMemoryMapEntry *entry, @@ -24,3 +25,8 @@ int qigvm_x86_set_vp_context(void *data, int index, Error **errp) { return -1; } + +int qigvm_directive_madt(QIgvm *ctx, const uint8_t *header_data, Error **errp) +{ + return -1; +} diff --git a/target/i386/igvm.c b/target/i386/igvm.c index 457c253b03..f41b498b89 100644 --- a/target/i386/igvm.c +++ b/target/i386/igvm.c @@ -13,7 +13,9 @@ #include "cpu.h" #include "hw/i386/e820_memory_layout.h" +#include "hw/i386/acpi-build.h" #include "system/igvm.h" +#include "system/igvm-internal.h" struct IgvmNativeVpContextX64 { uint64_t rax; @@ -178,3 +180,33 @@ void qigvm_x86_bsp_reset(CPUX86State *env) qigvm_x86_load_context(bsp_context, env); } + +/* + * Process MADT IGVM parameter + */ +int qigvm_directive_madt(QIgvm *ctx, const uint8_t *header_data, Error **errp) +{ + const IGVM_VHS_PARAMETER *param = (const IGVM_VHS_PARAMETER *)header_data; + QIgvmParameterData *param_entry; + int result = 0; + + /* Find the parameter area that should hold the MADT data */ + param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index); + if (param_entry == NULL) { + return 0; + } + + GArray *madt = acpi_build_madt_standalone(ctx->machine_state); + + if (madt->len <= param_entry->size) { + memcpy(param_entry->data, madt->data, madt->len); + } else { + error_setg( + errp, + "IGVM: MADT size exceeds parameter area defined in IGVM file"); + result = -1; + } + + g_array_free(madt, true); + return result; +}