Commit ed9e629535 for qemu.org

commit ed9e629535543ef114bdc2f5bd45349dbc0adedf
Author: Luigi Leonardi <leonardi@redhat.com>
Date:   Wed Sep 23 18:20:55 2026 +0200

    backends/igvm: supply an empty device tree when the machine has none

    Commit 1c4bd8f13c ("igvm: add device tree parameter support") added
    handling for the IGVM device tree parameter directive. The handler
    fails when the machine has not built a device tree of its own, so an
    IGVM file carrying that directive cannot be booted on such a machine,
    for example q35.

    An empty tree satisfies the IGVM file's request, so build and supply
    one instead of rejecting the whole file.

    While at it, rename fdt_packed to fdt, which better reflects the
    content of the variable, as it does not always hold a packed fdt.

    Signed-off-by: Luigi Leonardi <leonardi@redhat.com>
    Message-ID: <20260923-relax_dt-v1-1-ff40f2a06acd@redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

diff --git a/backends/igvm.c b/backends/igvm.c
index ef45794744..5a1416fe8e 100644
--- a/backends/igvm.c
+++ b/backends/igvm.c
@@ -29,6 +29,9 @@

 #ifdef CONFIG_FDT
 #include <libfdt.h>
+
+/* Enough for the header, the memory reservation block and an empty root node */
+#define EMPTY_FDT_SIZE 256
 #endif

 #ifndef IGVM_VHT_OPTIONAL_BIT
@@ -871,7 +874,7 @@ 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;
+    g_autofree void *fdt = NULL;
     uint8_t *param_data;
     uint32_t param_size;
     uint32_t fdt_size;
@@ -881,20 +884,27 @@ static int qigvm_directive_device_tree(QIgvm *ctx, const uint8_t *header_data,
         return -1;
     }

-    if (ctx->machine_state->fdt == NULL) {
-        error_setg(errp, "IGVM: device tree not available");
-        return -1;
+    if (ctx->machine_state->fdt) {
+        fdt = g_memdup2(ctx->machine_state->fdt,
+                        fdt_totalsize(ctx->machine_state->fdt));
+    } else {
+        /*
+         * The machine doesn't build a device tree of its own.
+         * Supply an empty tree rather than rejecting the IGVM file.
+         */
+        fdt = g_malloc0(EMPTY_FDT_SIZE);
+        if (fdt_create_empty_tree(fdt, EMPTY_FDT_SIZE)) {
+            error_setg(errp, "IGVM: failed to create an empty device tree");
+            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)) {
+    if (fdt_pack(fdt)) {
         error_setg(errp, "IGVM: failed to pack device tree");
         return -1;
     }

-    fdt_size = fdt_totalsize(fdt_packed);
+    fdt_size = fdt_totalsize(fdt);
     if (fdt_size > param_size) {
         error_setg(errp,
                    "IGVM: device tree size exceeds parameter area"
@@ -902,7 +912,7 @@ static int qigvm_directive_device_tree(QIgvm *ctx, const uint8_t *header_data,
         return -1;
     }

-    memcpy(param_data, fdt_packed, fdt_size);
+    memcpy(param_data, fdt, fdt_size);

     return 0;
 }