@samitouri / QOSamiQemu / commits / 1c4bd8f13c

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] https://github.com/coconut-svsm/svsm/pull/1006 Signed-off-by: Luigi Leonardi <leonardi@redhat.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Message-ID: <20260626-microvm_device_tree-v6-3-9cd13cf057e2@redhat.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

Luigi Leonardi committed Jun 26, 2026 at 12:04 UTC 1c4bd8f13c769598eeee91d69a463fdb099a2c31
2 files changed +55 -1
backends/igvm.c
+54
@@ -26,6 +26,10 @@
26 #include <igvm/igvm.h>
27 #include <igvm/igvm_defs.h>
28
29 +#ifdef CONFIG_FDT
30 +#include <libfdt.h>
31 +#endif
32 +
33 #ifndef IGVM_VHT_OPTIONAL_BIT
34 #define IGVM_VHT_OPTIONAL_BIT (1U << 31)
35 #endif
@@ -121,6 +125,10 @@ static int qigvm_directive_snp_id_block(QIgvm *ctx, const uint8_t *header_data,
125 static int qigvm_initialization_guest_policy(QIgvm *ctx,
126 const uint8_t *header_data,
127 Error **errp);
128 +#ifdef CONFIG_FDT
129 +static int qigvm_directive_device_tree(QIgvm *ctx, const uint8_t *header_data,
130 + Error **errp);
131 +#endif
132
133 struct QIGVMHandler {
134 IgvmVariableHeaderType type;
@@ -151,6 +159,10 @@ static struct QIGVMHandler handlers[] = {
159 qigvm_initialization_guest_policy },
160 { IGVM_VHT_MADT, IGVM_HEADER_SECTION_DIRECTIVE,
161 qigvm_directive_madt },
162 +#ifdef CONFIG_FDT
163 + { IGVM_VHT_DEVICE_TREE, IGVM_HEADER_SECTION_DIRECTIVE,
164 + qigvm_directive_device_tree },
165 +#endif
166 };
167
168 static int qigvm_handler(QIgvm *ctx, IgvmVariableHeaderType raw_type,
@@ -786,6 +798,48 @@ static int qigvm_directive_snp_id_block(QIgvm *ctx, const uint8_t *header_data,
798 return 0;
799 }
800
801 +#ifdef CONFIG_FDT
802 +static int qigvm_directive_device_tree(QIgvm *ctx, const uint8_t *header_data,
803 + Error **errp)
804 +{
805 + const IGVM_VHS_PARAMETER *param = (const IGVM_VHS_PARAMETER *)header_data;
806 + g_autofree void *fdt_packed = NULL;
807 + QIgvmParameterData *param_entry;
808 + uint32_t fdt_size;
809 +
810 + param_entry = qigvm_find_param_entry(ctx,
811 + param->parameter_area_index, errp);
812 + if (param_entry == NULL) {
813 + return -1;
814 + }
815 +
816 + if (ctx->machine_state->fdt == NULL) {
817 + error_setg(errp, "IGVM: device tree not available");
818 + return -1;
819 + }
820 +
821 + fdt_size = fdt_totalsize(ctx->machine_state->fdt);
822 + fdt_packed = g_memdup2(ctx->machine_state->fdt, fdt_size);
823 +
824 + if (fdt_pack(fdt_packed)) {
825 + error_setg(errp, "IGVM: failed to pack device tree");
826 + return -1;
827 + }
828 +
829 + fdt_size = fdt_totalsize(fdt_packed);
830 + if (fdt_size > param_entry->size) {
831 + error_setg(errp,
832 + "IGVM: device tree size exceeds parameter area"
833 + " defined in IGVM file");
834 + return -1;
835 + }
836 +
837 + memcpy(param_entry->data, fdt_packed, fdt_size);
838 +
839 + return 0;
840 +}
841 +#endif
842 +
843 static int qigvm_initialization_guest_policy(QIgvm *ctx,
844 const uint8_t *header_data, Error **errp)
845 {
backends/meson.build
+1 -1
@@ -35,7 +35,7 @@ endif
35 system_ss.add(when: gio, if_true: files('dbus-vmstate.c'))
36 system_ss.add(when: 'CONFIG_SGX', if_true: files('hostmem-epc.c'))
37
38 -system_ss.add(when: igvm, if_true: [files('igvm-cfg.c', 'igvm.c')])
38 +system_ss.add(when: igvm, if_true: [files('igvm-cfg.c', 'igvm.c'), fdt])
39
40 system_ss.add(when: 'CONFIG_SPDM_SOCKET', if_true: files('spdm-socket.c'))
41