Skip to content

Commit 9b632b9

Browse files
committed
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 d98d0b7 commit 9b632b9

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

backends/igvm.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include <igvm/igvm.h>
2727
#include <igvm/igvm_defs.h>
28+
#include <libfdt.h>
2829

2930

3031
/*
@@ -100,6 +101,8 @@ static int qigvm_directive_snp_id_block(QIgvm *ctx, const uint8_t *header_data,
100101
static int qigvm_initialization_guest_policy(QIgvm *ctx,
101102
const uint8_t *header_data,
102103
Error **errp);
104+
static int qigvm_directive_device_tree(QIgvm *ctx, const uint8_t *header_data,
105+
Error **errp);
103106

104107
struct QIGVMHandler {
105108
uint32_t type;
@@ -130,6 +133,8 @@ static struct QIGVMHandler handlers[] = {
130133
qigvm_initialization_guest_policy },
131134
{ IGVM_VHT_MADT, IGVM_HEADER_SECTION_DIRECTIVE,
132135
qigvm_directive_madt },
136+
{ IGVM_VHT_DEVICE_TREE, IGVM_HEADER_SECTION_DIRECTIVE,
137+
qigvm_directive_device_tree },
133138
};
134139

135140
static int qigvm_handler(QIgvm *ctx, uint32_t type, Error **errp)
@@ -790,6 +795,48 @@ static int qigvm_directive_snp_id_block(QIgvm *ctx, const uint8_t *header_data,
790795
return 0;
791796
}
792797

798+
static int qigvm_directive_device_tree(QIgvm *ctx, const uint8_t *header_data,
799+
Error **errp)
800+
{
801+
const IGVM_VHS_PARAMETER *param = (const IGVM_VHS_PARAMETER *)header_data;
802+
g_autofree void *fdt_packed = NULL;
803+
QIgvmParameterData *param_entry;
804+
uint32_t fdt_size;
805+
806+
param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index);
807+
if (param_entry == NULL) {
808+
error_setg(errp, "IGVM: parameter area index %u not found",
809+
param->parameter_area_index);
810+
return -1;
811+
}
812+
813+
if (ctx->machine_state->fdt == NULL) {
814+
error_setg(errp, "IGVM: device tree not available");
815+
return -1;
816+
}
817+
818+
fdt_size = fdt_totalsize(ctx->machine_state->fdt);
819+
fdt_packed = g_malloc(fdt_size);
820+
memcpy(fdt_packed, ctx->machine_state->fdt, fdt_size);
821+
822+
if (fdt_pack(fdt_packed)) {
823+
error_setg(errp, "IGVM: failed to pack device tree");
824+
return -1;
825+
}
826+
827+
fdt_size = fdt_totalsize(fdt_packed);
828+
if (fdt_size > param_entry->size) {
829+
error_setg(errp,
830+
"IGVM: device tree size exceeds parameter area"
831+
" defined in IGVM file");
832+
return -1;
833+
}
834+
835+
memcpy(param_entry->data, fdt_packed, fdt_size);
836+
837+
return 0;
838+
}
839+
793840
static int qigvm_initialization_guest_policy(QIgvm *ctx,
794841
const uint8_t *header_data, Error **errp)
795842
{

0 commit comments

Comments
 (0)