diff mbox series

[6/6] hw/core/machine.c: Make -machine dumpdtb=file.dtb with no DTB an error

Message ID 20250206151214.2947842-7-peter.maydell@linaro.org
State New
Headers show
Series hw: Centralize handling, improve error messages for -machine dumpdtb | expand

Commit Message

Peter Maydell Feb. 6, 2025, 3:12 p.m. UTC
Currently if the user requests via -machine dumpdtb=file.dtb that we
dump the DTB, but the machine doesn't have a DTB, we silently ignore
the option.  This is confusing to users, and is a legacy of the old
board-specific implementation of the option, where if the execution
codepath didn't go via a call to qemu_fdt_dumpdtb() we would never
handle the option.

Now we handle the option in one place in machine.c, we can provide
the user with a useful message if they asked us to dump a DTB when
none exists.  qmp_dumpdtb() already produces this error; remove the
logic in handle_machine_dumpdtb() that was there specifically to
avoid hitting it.

While we're here, beef up the error message a bit with a hint, and
make it consistent about "an FDT" rather than "a FDT".  (In the
qmp_dumpdtb() case this needs an ERRP_GUARD to make
error_append_hint() work when the caller passes error_fatal.)

Note that the three places where we might report "doesn't have an
FDT" are hit in different situations:

(1) in handle_machine_dumpdtb(), if CONFIG_FDT is not set: this is
because the QEMU binary was built without libfdt at all. The
build system will not let you build with a machine type that
needs an FDT but no libfdt, so here we know both that the machine
doesn't use FDT and that QEMU doesn't have the support:

(2) in the device_tree-stub.c qmp_dumpdtb(): this is used when
we had libfdt at build time but the target architecture didn't
enable any machines which did "select DEVICE_TREE", so here we
know that the machine doesn't use FDT.

(3) in qmp_dumpdtb(), if current_machine->fdt is NULL all we know
is that this machine never set it. That might be because it doesn't
use FDT, or it might be because the user didn't pass an FDT
on the command line and the machine doesn't autogenerate an FDT.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2733
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/core/machine.c         | 6 ++----
 system/device_tree-stub.c | 5 ++++-
 system/device_tree.c      | 7 ++++++-
 3 files changed, 12 insertions(+), 6 deletions(-)

Comments

Richard Henderson Feb. 6, 2025, 8:52 p.m. UTC | #1
On 2/6/25 07:12, Peter Maydell wrote:
> Currently if the user requests via -machine dumpdtb=file.dtb that we
> dump the DTB, but the machine doesn't have a DTB, we silently ignore
> the option.  This is confusing to users, and is a legacy of the old
> board-specific implementation of the option, where if the execution
> codepath didn't go via a call to qemu_fdt_dumpdtb() we would never
> handle the option.
> 
> Now we handle the option in one place in machine.c, we can provide
> the user with a useful message if they asked us to dump a DTB when
> none exists.  qmp_dumpdtb() already produces this error; remove the
> logic in handle_machine_dumpdtb() that was there specifically to
> avoid hitting it.
> 
> While we're here, beef up the error message a bit with a hint, and
> make it consistent about "an FDT" rather than "a FDT".  (In the
> qmp_dumpdtb() case this needs an ERRP_GUARD to make
> error_append_hint() work when the caller passes error_fatal.)
> 
> Note that the three places where we might report "doesn't have an
> FDT" are hit in different situations:
> 
> (1) in handle_machine_dumpdtb(), if CONFIG_FDT is not set: this is
> because the QEMU binary was built without libfdt at all. The
> build system will not let you build with a machine type that
> needs an FDT but no libfdt, so here we know both that the machine
> doesn't use FDT and that QEMU doesn't have the support:
> 
> (2) in the device_tree-stub.c qmp_dumpdtb(): this is used when
> we had libfdt at build time but the target architecture didn't
> enable any machines which did "select DEVICE_TREE", so here we
> know that the machine doesn't use FDT.
> 
> (3) in qmp_dumpdtb(), if current_machine->fdt is NULL all we know
> is that this machine never set it. That might be because it doesn't
> use FDT, or it might be because the user didn't pass an FDT
> on the command line and the machine doesn't autogenerate an FDT.
> 
> Resolves:https://gitlab.com/qemu-project/qemu/-/issues/2733
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
>   hw/core/machine.c         | 6 ++----
>   system/device_tree-stub.c | 5 ++++-
>   system/device_tree.c      | 7 ++++++-
>   3 files changed, 12 insertions(+), 6 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~
diff mbox series

Patch

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 1b740071ac7..f0e45fbad9d 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1701,15 +1701,13 @@  static void handle_machine_dumpdtb(MachineState *ms)
     if (!ms->dumpdtb) {
         return;
     }
-    if (!ms->fdt) {
-        /* Silently ignore dumpdtb option if there is nothing to dump */
-        return;
-    }
 #ifdef CONFIG_FDT
     qmp_dumpdtb(ms->dumpdtb, &error_fatal);
     exit(0);
 #else
     error_report("This machine doesn't have an FDT");
+    error_printf("(this machine type definitely doesn't use FDT, and "
+                 "this QEMU doesn't have FDT support compiled in)\n");
     exit(1);
 #endif
 }
diff --git a/system/device_tree-stub.c b/system/device_tree-stub.c
index bddda6fa37a..428330b0fec 100644
--- a/system/device_tree-stub.c
+++ b/system/device_tree-stub.c
@@ -5,6 +5,9 @@ 
 #ifdef CONFIG_FDT
 void qmp_dumpdtb(const char *filename, Error **errp)
 {
-    error_setg(errp, "This machine doesn't have a FDT");
+    ERRP_GUARD();
+
+    error_setg(errp, "This machine doesn't have an FDT");
+    error_append_hint(errp, "(this machine type definitely doesn't use FDT)\n");
 }
 #endif
diff --git a/system/device_tree.c b/system/device_tree.c
index 56d4ac5650a..0d554240f93 100644
--- a/system/device_tree.c
+++ b/system/device_tree.c
@@ -635,11 +635,16 @@  out:
 
 void qmp_dumpdtb(const char *filename, Error **errp)
 {
+    ERRP_GUARD();
+
     g_autoptr(GError) err = NULL;
     uint32_t size;
 
     if (!current_machine->fdt) {
-        error_setg(errp, "This machine doesn't have a FDT");
+        error_setg(errp, "This machine doesn't have an FDT");
+        error_append_hint(errp,
+                          "(Perhaps it doesn't support FDT at all, or perhaps "
+                          "you need to provide an FDT with the -fdt option?)\n");
         return;
     }