Skip to content

Commit 1d5a21f

Browse files
luigix25joergroedel
authored andcommitted
igvm: add device tree parameter support
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 device tree is packed before copying into the IGVM parameter area to reduce its size, since IGVM files can define tighter memory constraints for parameter areas. Packing is done in the generic IGVM backend rather than in per-architecture device tree setup code, so that each architecture does not need to handle it individually. [1] coconut-svsm/svsm#1006 Signed-off-by: Luigi Leonardi <leonardi@redhat.com>
1 parent 02c0359 commit 1d5a21f

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

backends/igvm.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
#include <igvm/igvm.h>
2727
#include <igvm/igvm_defs.h>
2828

29+
#ifdef CONFIG_FDT
30+
#include <libfdt.h>
31+
#endif
2932

3033
/*
3134
* Some directives are specific to particular confidential computing platforms.
@@ -100,6 +103,10 @@ static int qigvm_directive_snp_id_block(QIgvm *ctx, const uint8_t *header_data,
100103
static int qigvm_initialization_guest_policy(QIgvm *ctx,
101104
const uint8_t *header_data,
102105
Error **errp);
106+
#ifdef CONFIG_FDT
107+
static int qigvm_directive_device_tree(QIgvm *ctx, const uint8_t *header_data,
108+
Error **errp);
109+
#endif
103110

104111
struct QIGVMHandler {
105112
uint32_t type;
@@ -130,6 +137,10 @@ static struct QIGVMHandler handlers[] = {
130137
qigvm_initialization_guest_policy },
131138
{ IGVM_VHT_MADT, IGVM_HEADER_SECTION_DIRECTIVE,
132139
qigvm_directive_madt },
140+
#ifdef CONFIG_FDT
141+
{ IGVM_VHT_DEVICE_TREE, IGVM_HEADER_SECTION_DIRECTIVE,
142+
qigvm_directive_device_tree },
143+
#endif
133144
};
134145

135146
static int qigvm_handler(QIgvm *ctx, uint32_t type, Error **errp)
@@ -791,6 +802,49 @@ static int qigvm_directive_snp_id_block(QIgvm *ctx, const uint8_t *header_data,
791802
return 0;
792803
}
793804

805+
#ifdef CONFIG_FDT
806+
static int qigvm_directive_device_tree(QIgvm *ctx, const uint8_t *header_data,
807+
Error **errp)
808+
{
809+
const IGVM_VHS_PARAMETER *param = (const IGVM_VHS_PARAMETER *)header_data;
810+
g_autofree void *fdt_packed = NULL;
811+
QIgvmParameterData *param_entry;
812+
uint32_t fdt_size;
813+
814+
param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index);
815+
if (param_entry == NULL) {
816+
error_setg(errp, "IGVM: parameter area index %u not found",
817+
param->parameter_area_index);
818+
return -1;
819+
}
820+
821+
if (ctx->machine_state->fdt == NULL) {
822+
error_setg(errp, "IGVM: device tree not available");
823+
return -1;
824+
}
825+
826+
fdt_size = fdt_totalsize(ctx->machine_state->fdt);
827+
fdt_packed = g_memdup2(ctx->machine_state->fdt, fdt_size);
828+
829+
if (fdt_pack(fdt_packed)) {
830+
error_setg(errp, "IGVM: failed to pack device tree");
831+
return -1;
832+
}
833+
834+
fdt_size = fdt_totalsize(fdt_packed);
835+
if (fdt_size > param_entry->size) {
836+
error_setg(errp,
837+
"IGVM: device tree size exceeds parameter area"
838+
" defined in IGVM file");
839+
return -1;
840+
}
841+
842+
memcpy(param_entry->data, fdt_packed, fdt_size);
843+
844+
return 0;
845+
}
846+
#endif
847+
794848
static int qigvm_initialization_guest_policy(QIgvm *ctx,
795849
const uint8_t *header_data, Error **errp)
796850
{

0 commit comments

Comments
 (0)