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

Luigi Leonardi posted 1 patch 3 days, 2 hours ago
backends/igvm.c | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
[PATCH] backends/igvm: supply an empty device tree when the machine has none
Posted by Luigi Leonardi 3 days, 2 hours ago
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>
---
 backends/igvm.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/backends/igvm.c b/backends/igvm.c
index ec7bee428b..e982bab06a 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
@@ -856,7 +859,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;
@@ -866,20 +869,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"
@@ -887,7 +897,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;
 }

---
base-commit: 67166d97a3269285aa68c489f85c9ccdf78495e1
change-id: 20260923-relax_dt-b16edc2ce1f1

Best regards,
-- 
Luigi Leonardi <leonardi@redhat.com>