Coconut SVSM, with the upcoming device tree support[1], will use the IGVM device tree parameter to discover virtio-mmio and ISA serial devices instead of relying on the fw_cfg interface, which is QEMU-specific.
The IGVM parameter handler is implemented for the i386 machine target and stubbed for all others. [1] https://github.com/coconut-svsm/svsm/pull/1006 Signed-off-by: Luigi Leonardi <[email protected]> --- backends/igvm.c | 2 ++ include/system/igvm.h | 2 ++ stubs/igvm.c | 6 ++++++ target/i386/igvm.c | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/backends/igvm.c b/backends/igvm.c index c347d0c17e..9c6bee4add 100644 --- a/backends/igvm.c +++ b/backends/igvm.c @@ -130,6 +130,8 @@ static struct QIGVMHandler handlers[] = { qigvm_initialization_guest_policy }, { IGVM_VHT_MADT, IGVM_HEADER_SECTION_DIRECTIVE, qigvm_directive_madt }, + { IGVM_VHT_DEVICE_TREE, IGVM_HEADER_SECTION_DIRECTIVE, + qigvm_directive_device_tree }, }; static int qigvm_handler(QIgvm *ctx, uint32_t type, Error **errp) diff --git a/include/system/igvm.h b/include/system/igvm.h index 64d3542311..d39f3d55f1 100644 --- a/include/system/igvm.h +++ b/include/system/igvm.h @@ -32,5 +32,7 @@ int qigvm_x86_set_vp_context(void *data, int index, * IGVM parameter handlers */ int qigvm_directive_madt(QIgvm *ctx, const uint8_t *header_data, Error **errp); +int qigvm_directive_device_tree(QIgvm *ctx, const uint8_t *header_data, + Error **errp); #endif diff --git a/stubs/igvm.c b/stubs/igvm.c index 9e9f683fc9..b4d533ad24 100644 --- a/stubs/igvm.c +++ b/stubs/igvm.c @@ -29,3 +29,9 @@ int qigvm_directive_madt(QIgvm *ctx, const uint8_t *header_data, Error **errp) { return -1; } + +int qigvm_directive_device_tree(QIgvm *ctx, const uint8_t *header_data, + Error **errp) +{ + return -1; +} diff --git a/target/i386/igvm.c b/target/i386/igvm.c index f41b498b89..13db6e9be0 100644 --- a/target/i386/igvm.c +++ b/target/i386/igvm.c @@ -11,6 +11,8 @@ #include "qemu/osdep.h" +#include <libfdt.h> + #include "cpu.h" #include "hw/i386/e820_memory_layout.h" #include "hw/i386/acpi-build.h" @@ -210,3 +212,37 @@ int qigvm_directive_madt(QIgvm *ctx, const uint8_t *header_data, Error **errp) g_array_free(madt, true); return result; } + +/* + * Process device tree IGVM parameter + */ +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; + QIgvmParameterData *param_entry; + uint32_t fdt_size; + + /* Find the parameter area that should hold the device tree data */ + param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index); + if (param_entry == NULL) { + return 0; + } + + if (ctx->machine_state->fdt == NULL) { + error_setg(errp, "IGVM: device tree not available"); + return -1; + } + + fdt_size = fdt_totalsize(ctx->machine_state->fdt); + 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, ctx->machine_state->fdt, fdt_size); + + return 0; +} -- 2.54.0
