diff options
| -rw-r--r-- | backends/igvm.c | 80 | ||||
| -rw-r--r-- | backends/meson.build | 7 | ||||
| -rw-r--r-- | include/system/igvm-internal.h | 3 | ||||
| -rw-r--r-- | target/i386/igvm.c | 5 |
4 files changed, 77 insertions, 18 deletions
diff --git a/backends/igvm.c b/backends/igvm.c index 3f4b97a5d4..80e87fe602 100644 --- a/backends/igvm.c +++ b/backends/igvm.c @@ -26,6 +26,10 @@ #include <igvm/igvm.h> #include <igvm/igvm_defs.h> +#ifdef CONFIG_FDT +#include <libfdt.h> +#endif + #ifndef IGVM_VHT_OPTIONAL_BIT #define IGVM_VHT_OPTIONAL_BIT (1U << 31) #endif @@ -81,7 +85,8 @@ struct QEMU_PACKED sev_id_authentication { #define IGVM_SEV_ID_BLOCK_VERSION 1 QIgvmParameterData* -qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index) +qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index, + Error **errp) { QIgvmParameterData *param_entry; QTAILQ_FOREACH(param_entry, &igvm->parameter_data, next) @@ -90,7 +95,8 @@ qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index) return param_entry; } } - warn_report("IGVM: No parameter area for index %u", parameter_area_index); + error_setg(errp, "IGVM: parameter area index %u not found", + parameter_area_index); return NULL; } @@ -119,6 +125,10 @@ static int qigvm_directive_snp_id_block(QIgvm *ctx, const uint8_t *header_data, static int qigvm_initialization_guest_policy(QIgvm *ctx, const uint8_t *header_data, Error **errp); +#ifdef CONFIG_FDT +static int qigvm_directive_device_tree(QIgvm *ctx, const uint8_t *header_data, + Error **errp); +#endif struct QIGVMHandler { IgvmVariableHeaderType type; @@ -149,6 +159,10 @@ static struct QIGVMHandler handlers[] = { qigvm_initialization_guest_policy }, { IGVM_VHT_MADT, IGVM_HEADER_SECTION_DIRECTIVE, qigvm_directive_madt }, +#ifdef CONFIG_FDT + { IGVM_VHT_DEVICE_TREE, IGVM_HEADER_SECTION_DIRECTIVE, + qigvm_directive_device_tree }, +#endif }; static int qigvm_handler(QIgvm *ctx, IgvmVariableHeaderType raw_type, @@ -528,9 +542,10 @@ static int qigvm_directive_parameter_insert(QIgvm *ctx, return 0; } - param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index); + param_entry = qigvm_find_param_entry(ctx, + param->parameter_area_index, errp); if (param_entry == NULL) { - return 0; + return -1; } region = qigvm_prepare_memory(ctx, param->gpa, param_entry->size, @@ -601,9 +616,10 @@ static int qigvm_directive_memory_map(QIgvm *ctx, const uint8_t *header_data, } /* Find the parameter area that should hold the memory map */ - param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index); + param_entry = qigvm_find_param_entry(ctx, + param->parameter_area_index, errp); if (param_entry == NULL) { - return 0; + return -1; } max_entry_count = param_entry->size / sizeof(IGVM_VHS_MEMORY_MAP_ENTRY); @@ -660,9 +676,10 @@ static int qigvm_directive_vp_count(QIgvm *ctx, const uint8_t *header_data, uint32_t *vp_count; CPUState *cpu; - param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index); + param_entry = qigvm_find_param_entry(ctx, + param->parameter_area_index, errp); if (param_entry == NULL) { - return 0; + return -1; } vp_count = (uint32_t *)(param_entry->data + param->byte_offset); @@ -683,9 +700,10 @@ static int qigvm_directive_environment_info(QIgvm *ctx, QIgvmParameterData *param_entry; IgvmEnvironmentInfo *environmental_state; - param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index); + param_entry = qigvm_find_param_entry(ctx, + param->parameter_area_index, errp); if (param_entry == NULL) { - return 0; + return -1; } environmental_state = @@ -780,6 +798,48 @@ static int qigvm_directive_snp_id_block(QIgvm *ctx, const uint8_t *header_data, return 0; } +#ifdef CONFIG_FDT +static int qigvm_directive_device_tree(QIgvm *ctx, const uint8_t *header_data, + Error **errp) +{ + const IGVM_VHS_PARAMETER *param = (const IGVM_VHS_PARAMETER *)header_data; + g_autofree void *fdt_packed = NULL; + QIgvmParameterData *param_entry; + uint32_t fdt_size; + + param_entry = qigvm_find_param_entry(ctx, + param->parameter_area_index, errp); + if (param_entry == NULL) { + return -1; + } + + if (ctx->machine_state->fdt == NULL) { + error_setg(errp, "IGVM: device tree not available"); + return -1; + } + + fdt_size = fdt_totalsize(ctx->machine_state->fdt); + fdt_packed = g_memdup2(ctx->machine_state->fdt, fdt_size); + + if (fdt_pack(fdt_packed)) { + error_setg(errp, "IGVM: failed to pack device tree"); + return -1; + } + + fdt_size = fdt_totalsize(fdt_packed); + if (fdt_size > param_entry->size) { + error_setg(errp, + "IGVM: device tree size exceeds parameter area" + " defined in IGVM file"); + return -1; + } + + memcpy(param_entry->data, fdt_packed, fdt_size); + + return 0; +} +#endif + static int qigvm_initialization_guest_policy(QIgvm *ctx, const uint8_t *header_data, Error **errp) { diff --git a/backends/meson.build b/backends/meson.build index 60021f45d1..8792c58c36 100644 --- a/backends/meson.build +++ b/backends/meson.build @@ -34,11 +34,8 @@ if have_vhost_user_crypto endif system_ss.add(when: gio, if_true: files('dbus-vmstate.c')) system_ss.add(when: 'CONFIG_SGX', if_true: files('hostmem-epc.c')) -if igvm.found() - system_ss.add(igvm) - system_ss.add(files('igvm-cfg.c'), igvm) - system_ss.add(files('igvm.c'), igvm) -endif + +system_ss.add(when: igvm, if_true: [files('igvm-cfg.c', 'igvm.c'), fdt]) system_ss.add(when: 'CONFIG_SPDM_SOCKET', if_true: files('spdm-socket.c')) diff --git a/include/system/igvm-internal.h b/include/system/igvm-internal.h index 7f131c4d03..7eb3792ed8 100644 --- a/include/system/igvm-internal.h +++ b/include/system/igvm-internal.h @@ -72,6 +72,7 @@ struct QIgvm { IgvmHandle qigvm_file_init(char *filename, Error **errp); QIgvmParameterData* -qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index); +qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index, + Error **errp); #endif diff --git a/target/i386/igvm.c b/target/i386/igvm.c index f41b498b89..ad9bf87761 100644 --- a/target/i386/igvm.c +++ b/target/i386/igvm.c @@ -191,9 +191,10 @@ int qigvm_directive_madt(QIgvm *ctx, const uint8_t *header_data, Error **errp) int result = 0; /* Find the parameter area that should hold the MADT data */ - param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index); + param_entry = qigvm_find_param_entry(ctx, + param->parameter_area_index, errp); if (param_entry == NULL) { - return 0; + return -1; } GArray *madt = acpi_build_madt_standalone(ctx->machine_state); |
