qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Patch v5 0/6] hw/core/loader: capture Error from load_image_targphys
@ 2025-10-21 10:54 Vishal Chourasia
  2025-10-21 10:54 ` [Patch v5 1/6] hw/core/loader: Use qemu_open() instead of open() in get_image_size() Vishal Chourasia
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Vishal Chourasia @ 2025-10-21 10:54 UTC (permalink / raw)
  To: adityag, harshpb, milesg, npiggin, peter.maydell, alistair23,
	balaton, qemu-devel, qemu-ppc, berrange
  Cc: Vishal Chourasia

Currently, when QEMU fails to load images (kernel, BIOS, initrd) via
load_image_targphys(), the error messages are not descriptive enough
for users to understand why the loading failed. This series adds the
ability to pass Error information through the loader functions to
provide more detailed error reporting.

v5:
- Moved the patch which replaces open() with qemu_open() earlier in the
  series
- Incorporated minor changes in the error messages requested by Balaton
- Moved check for size zero in load_image_targphys_as() into it's
  separate patch 

v4:
- Reject empty files (`size == 0`) with an appropriate error. [1/5]
- Populate error when `rom_add_file_fixed_as()` fails. [1/5]
- Add missing check in hw/ppc/virtex_ml507.c [5/5]
- Fixed checkpatch warnings [5/5]
- Check errp for failures from load_image_targphys/load_image_targphys_as [3,5/5]
- Remove unused variables [5/5]

v3:
- Use qemu_open() instead of open() in get_image_size() (danpb)
- Remove redundant error_setg_file_open() call (danpb)
- Use error_prepend()/error_reportf_err() to preserve underlying
  error details (danpb)

Vishal Chourasia (6):
  hw/core/loader: Use qemu_open() instead of open() in get_image_size()
  hw/core/loader: capture Error from load_image_targphys
  hw/core/loader: add check for zero size in load_image_targphys_as
  hw/core: Pass errp to load_image_targphys_as()
  hw/ppc/spapr: Rename resize_hpt_err to errp
  hw/ppc: Pass errp to load_image_targphys() and report errors

 hw/alpha/dp264.c         |  4 ++--
 hw/arm/armv7m.c          |  2 +-
 hw/arm/boot.c            |  5 +++--
 hw/arm/digic_boards.c    |  2 +-
 hw/arm/highbank.c        |  3 ++-
 hw/arm/raspi.c           |  2 +-
 hw/arm/vexpress.c        |  2 +-
 hw/core/generic-loader.c |  8 +++++---
 hw/core/guest-loader.c   |  7 ++++---
 hw/core/loader.c         | 36 ++++++++++++++++++++++++++++--------
 hw/hppa/machine.c        |  5 +++--
 hw/i386/multiboot.c      |  2 +-
 hw/i386/x86-common.c     |  4 ++--
 hw/ipmi/ipmi_bmc_sim.c   |  2 +-
 hw/loongarch/boot.c      |  5 ++---
 hw/m68k/an5206.c         |  2 +-
 hw/m68k/mcf5208.c        |  4 ++--
 hw/m68k/next-cube.c      |  2 +-
 hw/m68k/q800.c           |  7 ++++---
 hw/m68k/virt.c           |  4 ++--
 hw/microblaze/boot.c     |  5 +++--
 hw/mips/boston.c         |  2 +-
 hw/mips/fuloong2e.c      |  9 +++++----
 hw/mips/jazz.c           |  2 +-
 hw/mips/loongson3_virt.c | 10 ++++++----
 hw/mips/malta.c          |  9 +++++----
 hw/nubus/nubus-device.c  |  2 +-
 hw/openrisc/boot.c       |  5 +++--
 hw/pci/pci.c             |  2 +-
 hw/ppc/amigaone.c        | 15 ++++++++-------
 hw/ppc/e500.c            | 18 ++++++++++--------
 hw/ppc/mac_newworld.c    | 28 ++++++++++++++++++----------
 hw/ppc/mac_oldworld.c    | 28 ++++++++++++++++++----------
 hw/ppc/pegasos2.c        | 18 ++++++++++++------
 hw/ppc/pnv.c             | 30 +++++++++++++++---------------
 hw/ppc/ppc440_bamboo.c   | 10 ++++++----
 hw/ppc/prep.c            | 27 +++++++++++++++++----------
 hw/ppc/sam460ex.c        | 10 ++++++----
 hw/ppc/spapr.c           | 35 ++++++++++++++++++-----------------
 hw/ppc/virtex_ml507.c    | 18 ++++++++++++------
 hw/riscv/boot.c          |  7 ++++---
 hw/rx/rx-gdbsim.c        |  2 +-
 hw/s390x/ipl.c           |  8 +++++---
 hw/sh4/r2d.c             |  8 +++++---
 hw/smbios/smbios.c       |  2 +-
 hw/sparc/leon3.c         |  4 ++--
 hw/sparc/sun4m.c         |  8 +++++---
 hw/sparc64/sun4u.c       |  7 ++++---
 hw/xtensa/xtfpga.c       |  3 ++-
 include/hw/loader.h      |  8 +++++---
 system/device_tree.c     |  2 +-
 51 files changed, 268 insertions(+), 182 deletions(-)

-- 
2.51.0



^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Patch v5 1/6] hw/core/loader: Use qemu_open() instead of open() in get_image_size()
  2025-10-21 10:54 [Patch v5 0/6] hw/core/loader: capture Error from load_image_targphys Vishal Chourasia
@ 2025-10-21 10:54 ` Vishal Chourasia
  2025-10-21 10:54 ` [Patch v5 2/6] hw/core/loader: capture Error from load_image_targphys Vishal Chourasia
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Vishal Chourasia @ 2025-10-21 10:54 UTC (permalink / raw)
  To: adityag, harshpb, milesg, npiggin, peter.maydell, alistair23,
	balaton, qemu-devel, qemu-ppc, berrange
  Cc: Vishal Chourasia

Replace open() with qemu_open() which provides better error handling
via the Error object, automatically sets O_CLOEXEC, and supports FD
passing with /dev/fdset.

Currently pass errp argument as NULL.

Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Vishal Chourasia <vishalc@linux.ibm.com>
---
 hw/core/loader.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/core/loader.c b/hw/core/loader.c
index 477661a025..c9782d67e8 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -74,7 +74,7 @@ int64_t get_image_size(const char *filename)
 {
     int fd;
     int64_t size;
-    fd = open(filename, O_RDONLY | O_BINARY);
+    fd = qemu_open(filename, O_RDONLY | O_BINARY, NULL);
     if (fd < 0)
         return -1;
     size = lseek(fd, 0, SEEK_END);
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Patch v5 2/6] hw/core/loader: capture Error from load_image_targphys
  2025-10-21 10:54 [Patch v5 0/6] hw/core/loader: capture Error from load_image_targphys Vishal Chourasia
  2025-10-21 10:54 ` [Patch v5 1/6] hw/core/loader: Use qemu_open() instead of open() in get_image_size() Vishal Chourasia
@ 2025-10-21 10:54 ` Vishal Chourasia
  2025-10-21 10:54 ` [Patch v5 3/6] hw/core/loader: add check for zero size in load_image_targphys_as Vishal Chourasia
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Vishal Chourasia @ 2025-10-21 10:54 UTC (permalink / raw)
  To: adityag, harshpb, milesg, npiggin, peter.maydell, alistair23,
	balaton, qemu-devel, qemu-ppc, berrange, richard.henderson,
	alistair, alex.bennee, deller, pbonzini, eduardo, minyard,
	gaosong, maobibo, laurent, edgar.iglesias, hpoussin, david,
	chigot, konrad.frederic, atar4qemu, jcmvbkbc
  Cc: Vishal Chourasia

Add Error **errp parameter to load_image_targphys(),
load_image_targphys_as(), and get_image_size() to enable better
error reporting when image loading fails.

Pass NULL for errp in all existing call sites to maintain current
behavior. No functional change intended in this patch.

Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Vishal Chourasia <vishalc@linux.ibm.com>
---
 hw/alpha/dp264.c         |  4 ++--
 hw/arm/armv7m.c          |  2 +-
 hw/arm/boot.c            |  5 +++--
 hw/arm/digic_boards.c    |  2 +-
 hw/arm/highbank.c        |  3 ++-
 hw/arm/raspi.c           |  2 +-
 hw/arm/vexpress.c        |  2 +-
 hw/core/generic-loader.c |  3 ++-
 hw/core/guest-loader.c   |  2 +-
 hw/core/loader.c         | 31 +++++++++++++++++++++++--------
 hw/hppa/machine.c        |  5 +++--
 hw/i386/multiboot.c      |  2 +-
 hw/i386/x86-common.c     |  4 ++--
 hw/ipmi/ipmi_bmc_sim.c   |  2 +-
 hw/loongarch/boot.c      |  5 ++---
 hw/m68k/an5206.c         |  2 +-
 hw/m68k/mcf5208.c        |  4 ++--
 hw/m68k/next-cube.c      |  2 +-
 hw/m68k/q800.c           |  7 ++++---
 hw/m68k/virt.c           |  4 ++--
 hw/microblaze/boot.c     |  5 +++--
 hw/mips/boston.c         |  2 +-
 hw/mips/fuloong2e.c      |  9 +++++----
 hw/mips/jazz.c           |  2 +-
 hw/mips/loongson3_virt.c | 10 ++++++----
 hw/mips/malta.c          |  9 +++++----
 hw/nubus/nubus-device.c  |  2 +-
 hw/openrisc/boot.c       |  5 +++--
 hw/pci/pci.c             |  2 +-
 hw/ppc/amigaone.c        |  4 ++--
 hw/ppc/e500.c            |  5 +++--
 hw/ppc/mac_newworld.c    |  9 ++++++---
 hw/ppc/mac_oldworld.c    |  9 ++++++---
 hw/ppc/pegasos2.c        |  5 +++--
 hw/ppc/pnv.c             |  9 ++++++---
 hw/ppc/ppc440_bamboo.c   |  3 ++-
 hw/ppc/prep.c            |  8 +++++---
 hw/ppc/sam460ex.c        |  3 ++-
 hw/ppc/spapr.c           |  8 ++++----
 hw/ppc/virtex_ml507.c    |  5 +++--
 hw/riscv/boot.c          |  7 ++++---
 hw/rx/rx-gdbsim.c        |  2 +-
 hw/s390x/ipl.c           |  8 +++++---
 hw/sh4/r2d.c             |  8 +++++---
 hw/smbios/smbios.c       |  2 +-
 hw/sparc/leon3.c         |  4 ++--
 hw/sparc/sun4m.c         |  8 +++++---
 hw/sparc64/sun4u.c       |  7 ++++---
 hw/xtensa/xtfpga.c       |  3 ++-
 include/hw/loader.h      |  8 +++++---
 system/device_tree.c     |  2 +-
 51 files changed, 159 insertions(+), 107 deletions(-)

diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index 19562b5967..b6155646ef 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -182,7 +182,7 @@ static void clipper_init(MachineState *machine)
             long initrd_base;
             int64_t initrd_size;
 
-            initrd_size = get_image_size(initrd_filename);
+            initrd_size = get_image_size(initrd_filename, NULL);
             if (initrd_size < 0) {
                 error_report("could not load initial ram disk '%s'",
                              initrd_filename);
@@ -192,7 +192,7 @@ static void clipper_init(MachineState *machine)
             /* Put the initrd image as high in memory as possible.  */
             initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
             load_image_targphys(initrd_filename, initrd_base,
-                                ram_size - initrd_base);
+                                ram_size - initrd_base, NULL);
 
             address_space_stq(&address_space_memory, param_offset + 0x100,
                               initrd_base + 0xfffffc0000000000ULL,
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index cea3eb49ee..c4a9c3ac52 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -611,7 +611,7 @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename,
                                  NULL, ELFDATA2LSB, EM_ARM, 1, 0, as);
         if (image_size < 0) {
             image_size = load_image_targphys_as(kernel_filename, mem_base,
-                                                mem_size, as);
+                                                mem_size, as, NULL);
         }
         if (image_size < 0) {
             error_report("Could not load kernel '%s'", kernel_filename);
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index e77d8679d8..b91660208f 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -964,7 +964,8 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
         /* 32-bit ARM */
         entry = info->loader_start + KERNEL_LOAD_ADDR;
         kernel_size = load_image_targphys_as(info->kernel_filename, entry,
-                                             ram_end - KERNEL_LOAD_ADDR, as);
+                                             ram_end - KERNEL_LOAD_ADDR, as,
+                                             NULL);
         is_linux = 1;
         if (kernel_size >= 0) {
             image_low_addr = entry;
@@ -1025,7 +1026,7 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
                                                      info->initrd_start,
                                                      ram_end -
                                                      info->initrd_start,
-                                                     as);
+                                                     as, NULL);
             }
             if (initrd_size < 0) {
                 error_report("could not load initrd '%s'",
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
index 466b8b84c0..de56991bac 100644
--- a/hw/arm/digic_boards.c
+++ b/hw/arm/digic_boards.c
@@ -97,7 +97,7 @@ static void digic_load_rom(DigicState *s, hwaddr addr,
             exit(1);
         }
 
-        rom_size = load_image_targphys(fn, addr, max_size);
+        rom_size = load_image_targphys(fn, addr, max_size, NULL);
         if (rom_size < 0 || rom_size > max_size) {
             error_report("Couldn't load rom image '%s'.", filename);
             exit(1);
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 165c0b741a..ff987467a9 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -235,7 +235,8 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
     if (machine->firmware != NULL) {
         sysboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, machine->firmware);
         if (sysboot_filename != NULL) {
-            if (load_image_targphys(sysboot_filename, 0xfff88000, 0x8000) < 0) {
+            if (load_image_targphys(sysboot_filename, 0xfff88000, 0x8000,
+                                    NULL) < 0) {
                 error_report("Unable to load %s", machine->firmware);
                 exit(1);
             }
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 9d9af63d65..fbf3e09c03 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -230,7 +230,7 @@ static void setup_boot(MachineState *machine, ARMCPU *cpu,
                              ? FIRMWARE_ADDR_2 : FIRMWARE_ADDR_3;
         /* load the firmware image (typically kernel.img) */
         r = load_image_targphys(machine->firmware, firmware_addr,
-                                ram_size - firmware_addr);
+                                ram_size - firmware_addr, NULL);
         if (r < 0) {
             error_report("Failed to load firmware from %s", machine->firmware);
             exit(1);
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index 35f8d05ea1..60cd375fe7 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -578,7 +578,7 @@ static void vexpress_common_init(MachineState *machine)
             exit(1);
         }
         image_size = load_image_targphys(fn, map[VE_NORFLASH0],
-                                         VEXPRESS_FLASH_SIZE);
+                                         VEXPRESS_FLASH_SIZE, NULL);
         g_free(fn);
         if (image_size < 0) {
             error_report("Could not load ROM image '%s'", machine->firmware);
diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
index e72bbde2a2..6689847c33 100644
--- a/hw/core/generic-loader.c
+++ b/hw/core/generic-loader.c
@@ -148,7 +148,8 @@ static void generic_loader_realize(DeviceState *dev, Error **errp)
 
         if (size < 0 || s->force_raw) {
             /* Default to the maximum size being the machine's ram size */
-            size = load_image_targphys_as(s->file, s->addr, current_machine->ram_size, as);
+            size = load_image_targphys_as(s->file, s->addr,
+                    current_machine->ram_size, as, NULL);
         } else {
             s->addr = entry;
         }
diff --git a/hw/core/guest-loader.c b/hw/core/guest-loader.c
index 3db89d7a2e..59f325ad9c 100644
--- a/hw/core/guest-loader.c
+++ b/hw/core/guest-loader.c
@@ -101,7 +101,7 @@ static void guest_loader_realize(DeviceState *dev, Error **errp)
 
     /* Default to the maximum size being the machine's ram size */
     size = load_image_targphys_as(file, s->addr, current_machine->ram_size,
-                                  NULL);
+                                  NULL, NULL);
     if (size < 0) {
         error_setg(errp, "Cannot load specified image %s", file);
         return;
diff --git a/hw/core/loader.c b/hw/core/loader.c
index c9782d67e8..de35e40719 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -48,6 +48,7 @@
 #include "qapi/error.h"
 #include "qapi/qapi-commands-machine.h"
 #include "qapi/type-helpers.h"
+#include "qemu/units.h"
 #include "trace.h"
 #include "hw/hw.h"
 #include "disas/disas.h"
@@ -70,14 +71,18 @@
 static int roms_loaded;
 
 /* return the size or -1 if error */
-int64_t get_image_size(const char *filename)
+int64_t get_image_size(const char *filename, Error **errp)
 {
     int fd;
     int64_t size;
-    fd = qemu_open(filename, O_RDONLY | O_BINARY, NULL);
+    fd = qemu_open(filename, O_RDONLY | O_BINARY, errp);
     if (fd < 0)
         return -1;
     size = lseek(fd, 0, SEEK_END);
+    if (size < 0) {
+        error_setg_errno(errp, errno, "lseek failure: %s", filename);
+        return -1;
+    }
     close(fd);
     return size;
 }
@@ -118,23 +123,33 @@ ssize_t read_targphys(const char *name,
 }
 
 ssize_t load_image_targphys(const char *filename,
-                            hwaddr addr, uint64_t max_sz)
+                            hwaddr addr, uint64_t max_sz, Error **errp)
 {
-    return load_image_targphys_as(filename, addr, max_sz, NULL);
+    return load_image_targphys_as(filename, addr, max_sz, NULL, errp);
 }
 
 /* return the size or -1 if error */
 ssize_t load_image_targphys_as(const char *filename,
-                               hwaddr addr, uint64_t max_sz, AddressSpace *as)
+                               hwaddr addr, uint64_t max_sz, AddressSpace *as,
+                               Error **errp)
 {
+    ERRP_GUARD();
     ssize_t size;
 
-    size = get_image_size(filename);
-    if (size < 0 || size > max_sz) {
+    size = get_image_size(filename, errp);
+    if (*errp) {
+        return -1;
+    }
+
+    if (size > max_sz) {
+        error_setg(errp, "%s exceeds maximum image size (%" PRIu64 " MiB)",
+                   filename, max_sz / MiB);
         return -1;
     }
+
     if (size > 0) {
         if (rom_add_file_fixed_as(filename, addr, -1, as) < 0) {
+            error_setg(errp, "failed to add file as ROM");
             return -1;
         }
     }
@@ -150,7 +165,7 @@ ssize_t load_image_mr(const char *filename, MemoryRegion *mr)
         return -1;
     }
 
-    size = get_image_size(filename);
+    size = get_image_size(filename, NULL);
 
     if (size < 0 || size > memory_region_size(mr)) {
         return -1;
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index cddca69b93..ba894f8b1e 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -495,7 +495,7 @@ static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus,
             ram_addr_t initrd_base;
             int64_t initrd_size;
 
-            initrd_size = get_image_size(initrd_filename);
+            initrd_size = get_image_size(initrd_filename, NULL);
             if (initrd_size < 0) {
                 error_report("could not load initial ram disk '%s'",
                              initrd_filename);
@@ -516,7 +516,8 @@ static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus,
                 exit(1);
             }
 
-            load_image_targphys(initrd_filename, initrd_base, initrd_size);
+            load_image_targphys(initrd_filename, initrd_base, initrd_size,
+                                NULL);
             cpu[0]->env.initrd_base = initrd_base;
             cpu[0]->env.initrd_end  = initrd_base + initrd_size;
         }
diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
index 6e6b96bc34..78690781b7 100644
--- a/hw/i386/multiboot.c
+++ b/hw/i386/multiboot.c
@@ -337,7 +337,7 @@ int load_multiboot(X86MachineState *x86ms,
                 *next_space = '\0';
             }
             mb_debug("multiboot loading module: %s", one_file);
-            mb_mod_length = get_image_size(one_file);
+            mb_mod_length = get_image_size(one_file, NULL);
             if (mb_mod_length < 0) {
                 error_report("Failed to open file '%s'", one_file);
                 exit(1);
diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
index 7512be64d6..6e78f3d07d 100644
--- a/hw/i386/x86-common.c
+++ b/hw/i386/x86-common.c
@@ -924,7 +924,7 @@ void x86_load_linux(X86MachineState *x86ms,
             exit(1);
         }
 
-        dtb_size = get_image_size(dtb_filename);
+        dtb_size = get_image_size(dtb_filename, NULL);
         if (dtb_size <= 0) {
             fprintf(stderr, "qemu: error reading dtb %s: %s\n",
                     dtb_filename, strerror(errno));
@@ -1025,7 +1025,7 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
     bios_name = MACHINE(x86ms)->firmware ?: default_firmware;
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
     if (filename) {
-        bios_size = get_image_size(filename);
+        bios_size = get_image_size(filename, NULL);
     } else {
         bios_size = -1;
     }
diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index 04e1dcd0e7..4604d632b1 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -2211,7 +2211,7 @@ static void ipmi_fru_init(IPMIFru *fru)
         goto out;
     }
 
-    fsize = get_image_size(fru->filename);
+    fsize = get_image_size(fru->filename, NULL);
     if (fsize > 0) {
         size = QEMU_ALIGN_UP(fsize, fru->areasize);
         fru->data = g_malloc0(size);
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index 3dd48cb8aa..8857a04998 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -328,14 +328,13 @@ static int64_t load_kernel_info(struct loongarch_boot_info *info)
     }
 
     if (info->initrd_filename) {
-        ssize_t initrd_size = get_image_size(info->initrd_filename);
-
+        ssize_t initrd_size = get_image_size(info->initrd_filename, NULL);
         if (initrd_size > 0) {
             initrd_offset = ROUND_UP(kernel_high + 4 * kernel_size, 64 * KiB);
             initrd_offset = alloc_initrd_memory(info, initrd_offset,
                                                 initrd_size);
             initrd_size = load_image_targphys(info->initrd_filename,
-                                              initrd_offset, initrd_size);
+                                              initrd_offset, initrd_size, NULL);
         }
 
         if (initrd_size == -1) {
diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
index d97399b882..ff21d7779e 100644
--- a/hw/m68k/an5206.c
+++ b/hw/m68k/an5206.c
@@ -82,7 +82,7 @@ static void an5206_init(MachineState *machine)
     }
     if (kernel_size < 0) {
         kernel_size = load_image_targphys(kernel_filename, KERNEL_LOAD_ADDR,
-                                          ram_size - KERNEL_LOAD_ADDR);
+                                          ram_size - KERNEL_LOAD_ADDR, NULL);
         entry = KERNEL_LOAD_ADDR;
     }
     if (kernel_size < 0) {
diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index 75cc076f78..4a585b231d 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -351,7 +351,7 @@ static void mcf5208evb_init(MachineState *machine)
             error_report("Could not find ROM image '%s'", machine->firmware);
             exit(1);
         }
-        if (load_image_targphys(fn, 0x0, ROM_SIZE) < 8) {
+        if (load_image_targphys(fn, 0x0, ROM_SIZE, NULL) < 8) {
             error_report("Could not load ROM image '%s'", machine->firmware);
             exit(1);
         }
@@ -380,7 +380,7 @@ static void mcf5208evb_init(MachineState *machine)
     }
     if (kernel_size < 0) {
         kernel_size = load_image_targphys(kernel_filename, 0x40000000,
-                                          ram_size);
+                                          ram_size, NULL);
         entry = 0x40000000;
     }
     if (kernel_size < 0) {
diff --git a/hw/m68k/next-cube.c b/hw/m68k/next-cube.c
index 957644b2d1..cfb2b319e5 100644
--- a/hw/m68k/next-cube.c
+++ b/hw/m68k/next-cube.c
@@ -1325,7 +1325,7 @@ static void next_cube_init(MachineState *machine)
     memory_region_init_alias(&m->rom2, NULL, "next.rom2", &m->rom, 0x0,
                              0x20000);
     memory_region_add_subregion(sysmem, 0x0, &m->rom2);
-    if (load_image_targphys(bios_name, 0x01000000, 0x20000) < 8) {
+    if (load_image_targphys(bios_name, 0x01000000, 0x20000, NULL) < 8) {
         if (!qtest_enabled()) {
             error_report("Failed to load firmware '%s'.", bios_name);
         }
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index 793b23f815..b8676feb41 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -629,7 +629,7 @@ static void q800_machine_init(MachineState *machine)
 
         /* load initrd */
         if (initrd_filename) {
-            initrd_size = get_image_size(initrd_filename);
+            initrd_size = get_image_size(initrd_filename, NULL);
             if (initrd_size < 0) {
                 error_report("could not load initial ram disk '%s'",
                              initrd_filename);
@@ -638,7 +638,7 @@ static void q800_machine_init(MachineState *machine)
 
             initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
             load_image_targphys(initrd_filename, initrd_base,
-                                ram_size - initrd_base);
+                                ram_size - initrd_base, NULL);
             BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base,
                       initrd_size);
         } else {
@@ -668,7 +668,8 @@ static void q800_machine_init(MachineState *machine)
 
         /* Load MacROM binary */
         if (filename) {
-            bios_size = load_image_targphys(filename, MACROM_ADDR, MACROM_SIZE);
+            bios_size = load_image_targphys(filename, MACROM_ADDR, MACROM_SIZE,
+                                            NULL);
             g_free(filename);
         } else {
             bios_size = -1;
diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
index 98cfe43c73..3f65d91556 100644
--- a/hw/m68k/virt.c
+++ b/hw/m68k/virt.c
@@ -283,7 +283,7 @@ static void virt_init(MachineState *machine)
 
         /* load initrd */
         if (initrd_filename) {
-            initrd_size = get_image_size(initrd_filename);
+            initrd_size = get_image_size(initrd_filename, NULL);
             if (initrd_size < 0) {
                 error_report("could not load initial ram disk '%s'",
                              initrd_filename);
@@ -292,7 +292,7 @@ static void virt_init(MachineState *machine)
 
             initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
             load_image_targphys(initrd_filename, initrd_base,
-                                ram_size - initrd_base);
+                                ram_size - initrd_base, NULL);
             BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base,
                       initrd_size);
         } else {
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index 4a9c9df318..ec38107f50 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -170,7 +170,7 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, bool is_little_endian,
         /* Not an ELF image nor an u-boot image, try a RAW image.  */
         if (kernel_size < 0) {
             kernel_size = load_image_targphys(kernel_filename, ddr_base,
-                                              ramsize);
+                                              ramsize, NULL);
             boot_info.bootstrap_pc = ddr_base;
             high = (ddr_base + kernel_size + 3) & ~3;
         }
@@ -189,7 +189,8 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, bool is_little_endian,
             if (initrd_size < 0) {
                 initrd_size = load_image_targphys(initrd_filename,
                                                   boot_info.initrd_start,
-                                                  ramsize - initrd_offset);
+                                                  ramsize - initrd_offset,
+                                                  NULL);
             }
             if (initrd_size < 0) {
                 error_report("could not load initrd '%s'",
diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index 149a263bd5..0a3a827b5f 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -778,7 +778,7 @@ static void boston_mach_init(MachineState *machine)
 
     if (machine->firmware) {
         fw_size = load_image_targphys(machine->firmware,
-                                      0x1fc00000, 4 * MiB);
+                                      0x1fc00000, 4 * MiB, NULL);
         if (fw_size == -1) {
             error_report("unable to load firmware image '%s'",
                           machine->firmware);
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 2a8507b8b0..5fe40eee65 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -118,7 +118,7 @@ static uint64_t load_kernel(MIPSCPU *cpu)
     initrd_size = 0;
     initrd_offset = 0;
     if (loaderparams.initrd_filename) {
-        initrd_size = get_image_size(loaderparams.initrd_filename);
+        initrd_size = get_image_size(loaderparams.initrd_filename, NULL);
         if (initrd_size > 0) {
             initrd_offset = ROUND_UP(kernel_high, INITRD_PAGE_SIZE);
             if (initrd_offset + initrd_size > loaderparams.ram_size) {
@@ -127,8 +127,9 @@ static uint64_t load_kernel(MIPSCPU *cpu)
                 exit(1);
             }
             initrd_size = load_image_targphys(loaderparams.initrd_filename,
-                                              initrd_offset,
-                                              loaderparams.ram_size - initrd_offset);
+                                         initrd_offset,
+                                         loaderparams.ram_size - initrd_offset,
+                                         NULL);
         }
         if (initrd_size == (target_ulong) -1) {
             error_report("could not load initial ram disk '%s'",
@@ -264,7 +265,7 @@ static void mips_fuloong2e_init(MachineState *machine)
                                   machine->firmware ?: FULOONG_BIOSNAME);
         if (filename) {
             bios_size = load_image_targphys(filename, 0x1fc00000LL,
-                                            BIOS_SIZE);
+                                            BIOS_SIZE, NULL);
             g_free(filename);
         } else {
             bios_size = -1;
diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c
index 7fb0b97a38..1d6bdc0091 100644
--- a/hw/mips/jazz.c
+++ b/hw/mips/jazz.c
@@ -245,7 +245,7 @@ static void mips_jazz_init(MachineState *machine,
                               machine->firmware ?: bios_name);
     if (filename) {
         bios_size = load_image_targphys(filename, 0xfff00000LL,
-                                        MAGNUM_BIOS_SIZE);
+                                        MAGNUM_BIOS_SIZE, NULL);
         g_free(filename);
     } else {
         bios_size = -1;
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index 672083dec9..77dc895648 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -371,7 +371,7 @@ static uint64_t load_kernel(CPUMIPSState *env)
     initrd_size = 0;
     initrd_offset = 0;
     if (loaderparams.initrd_filename) {
-        initrd_size = get_image_size(loaderparams.initrd_filename);
+        initrd_size = get_image_size(loaderparams.initrd_filename, NULL);
         if (initrd_size > 0) {
             initrd_offset = MAX(loader_memmap[LOADER_INITRD].base,
                                 ROUND_UP(kernel_high, INITRD_PAGE_SIZE));
@@ -383,8 +383,9 @@ static uint64_t load_kernel(CPUMIPSState *env)
             }
 
             initrd_size = load_image_targphys(loaderparams.initrd_filename,
-                                              initrd_offset,
-                                              loaderparams.ram_size - initrd_offset);
+                                        initrd_offset,
+                                        loaderparams.ram_size - initrd_offset,
+                                        NULL);
         }
 
         if (initrd_size == (target_ulong) -1) {
@@ -650,7 +651,8 @@ static void mips_loongson3_virt_init(MachineState *machine)
         if (filename) {
             bios_size = load_image_targphys(filename,
                                             virt_memmap[VIRT_BIOS_ROM].base,
-                                            virt_memmap[VIRT_BIOS_ROM].size);
+                                            virt_memmap[VIRT_BIOS_ROM].size,
+                                            NULL);
             g_free(filename);
         } else {
             bios_size = -1;
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 02da629b5a..806e8d5078 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -892,7 +892,7 @@ static uint64_t load_kernel(void)
     initrd_size = 0;
     initrd_offset = 0;
     if (loaderparams.initrd_filename) {
-        initrd_size = get_image_size(loaderparams.initrd_filename);
+        initrd_size = get_image_size(loaderparams.initrd_filename, NULL);
         if (initrd_size > 0) {
             /*
              * The kernel allocates the bootmap memory in the low memory after
@@ -908,8 +908,9 @@ static uint64_t load_kernel(void)
                 exit(1);
             }
             initrd_size = load_image_targphys(loaderparams.initrd_filename,
-                                              initrd_offset,
-                                              loaderparams.ram_size - initrd_offset);
+                                        initrd_offset,
+                                        loaderparams.ram_size - initrd_offset,
+                                        NULL);
         }
         if (initrd_size == (target_ulong) -1) {
             error_report("could not load initial ram disk '%s'",
@@ -1176,7 +1177,7 @@ void mips_malta_init(MachineState *machine)
                                       machine->firmware ?: bios_name);
             if (filename) {
                 bios_size = load_image_targphys(filename, FLASH_ADDRESS,
-                                                BIOS_SIZE);
+                                                BIOS_SIZE, NULL);
                 g_free(filename);
             } else {
                 bios_size = -1;
diff --git a/hw/nubus/nubus-device.c b/hw/nubus/nubus-device.c
index 7797e61c7f..0d4d6c0d87 100644
--- a/hw/nubus/nubus-device.c
+++ b/hw/nubus/nubus-device.c
@@ -68,7 +68,7 @@ static void nubus_device_realize(DeviceState *dev, Error **errp)
             path = g_strdup(nd->romfile);
         }
 
-        size = get_image_size(path);
+        size = get_image_size(path, NULL);
         if (size < 0) {
             error_setg(errp, "failed to find romfile \"%s\"", nd->romfile);
             g_free(path);
diff --git a/hw/openrisc/boot.c b/hw/openrisc/boot.c
index c81efe8138..db6fea071e 100644
--- a/hw/openrisc/boot.c
+++ b/hw/openrisc/boot.c
@@ -44,7 +44,8 @@ hwaddr openrisc_load_kernel(ram_addr_t ram_size,
         if (kernel_size < 0) {
             kernel_size = load_image_targphys(kernel_filename,
                                               KERNEL_LOAD_ADDR,
-                                              ram_size - KERNEL_LOAD_ADDR);
+                                              ram_size - KERNEL_LOAD_ADDR,
+                                              NULL);
             high_addr = KERNEL_LOAD_ADDR + kernel_size;
         }
 
@@ -74,7 +75,7 @@ hwaddr openrisc_load_initrd(void *fdt, const char *filename,
 
     size = load_ramdisk(filename, start, mem_size - start);
     if (size < 0) {
-        size = load_image_targphys(filename, start, mem_size - start);
+        size = load_image_targphys(filename, start, mem_size - start, NULL);
         if (size < 0) {
             error_report("could not load ramdisk '%s'", filename);
             exit(1);
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index acc03fd470..738b0c41ae 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2557,7 +2557,7 @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom,
             path = g_strdup(pdev->romfile);
         }
 
-        size = get_image_size(path);
+        size = get_image_size(path, NULL);
         if (size < 0) {
             error_setg(errp, "failed to find romfile \"%s\"", pdev->romfile);
             return;
diff --git a/hw/ppc/amigaone.c b/hw/ppc/amigaone.c
index 12279f42bc..5c5acc9872 100644
--- a/hw/ppc/amigaone.c
+++ b/hw/ppc/amigaone.c
@@ -324,7 +324,7 @@ static void amigaone_init(MachineState *machine)
             error_report("Could not find firmware '%s'", machine->firmware);
             exit(1);
         }
-        sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE);
+        sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE, NULL);
         if (sz <= 0 || sz > PROM_SIZE) {
             error_report("Could not load firmware '%s'", filename);
             exit(1);
@@ -413,7 +413,7 @@ static void amigaone_init(MachineState *machine)
         loadaddr = ROUND_UP(loadaddr + 4 * MiB, 4 * KiB);
         loadaddr = MAX(loadaddr, INITRD_MIN_ADDR);
         sz = load_image_targphys(machine->initrd_filename, loadaddr,
-                                 bi->bd_info - loadaddr);
+                                 bi->bd_info - loadaddr, NULL);
         if (sz <= 0) {
             error_report("Could not load initrd '%s'",
                          machine->initrd_filename);
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 723c97fad2..30937a4a92 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -1227,7 +1227,7 @@ void ppce500_init(MachineState *machine)
         kernel_base = cur_base;
         kernel_size = load_image_targphys(machine->kernel_filename,
                                           cur_base,
-                                          machine->ram_size - cur_base);
+                                          machine->ram_size - cur_base, NULL);
         if (kernel_size < 0) {
             error_report("could not load kernel '%s'",
                          machine->kernel_filename);
@@ -1241,7 +1241,8 @@ void ppce500_init(MachineState *machine)
     if (machine->initrd_filename) {
         initrd_base = (cur_base + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK;
         initrd_size = load_image_targphys(machine->initrd_filename, initrd_base,
-                                          machine->ram_size - initrd_base);
+                                          machine->ram_size - initrd_base,
+                                          NULL);
 
         if (initrd_size < 0) {
             error_report("could not load initial ram disk '%s'",
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 0b6e096116..004efc6b97 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -188,7 +188,8 @@ static void ppc_core99_init(MachineState *machine)
 
         if (bios_size <= 0) {
             /* or load binary ROM image */
-            bios_size = load_image_targphys(filename, PROM_BASE, PROM_SIZE);
+            bios_size = load_image_targphys(filename, PROM_BASE, PROM_SIZE,
+                                            NULL);
         }
         g_free(filename);
     }
@@ -210,7 +211,8 @@ static void ppc_core99_init(MachineState *machine)
         if (kernel_size < 0) {
             kernel_size = load_image_targphys(machine->kernel_filename,
                                               kernel_base,
-                                              machine->ram_size - kernel_base);
+                                              machine->ram_size - kernel_base,
+                                              NULL);
         }
         if (kernel_size < 0) {
             error_report("could not load kernel '%s'",
@@ -222,7 +224,8 @@ static void ppc_core99_init(MachineState *machine)
             initrd_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP);
             initrd_size = load_image_targphys(machine->initrd_filename,
                                               initrd_base,
-                                              machine->ram_size - initrd_base);
+                                              machine->ram_size - initrd_base,
+                                              NULL);
             if (initrd_size < 0) {
                 error_report("could not load initial ram disk '%s'",
                              machine->initrd_filename);
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 40ae936ad8..c7e44d49b0 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -143,7 +143,8 @@ static void ppc_heathrow_init(MachineState *machine)
 
         if (bios_size <= 0) {
             /* or if could not load ELF try loading a binary ROM image */
-            bios_size = load_image_targphys(filename, PROM_BASE, PROM_SIZE);
+            bios_size = load_image_targphys(filename, PROM_BASE, PROM_SIZE,
+                                            NULL);
             bios_addr = PROM_BASE;
         }
         g_free(filename);
@@ -166,7 +167,8 @@ static void ppc_heathrow_init(MachineState *machine)
         if (kernel_size < 0) {
             kernel_size = load_image_targphys(machine->kernel_filename,
                                               kernel_base,
-                                              machine->ram_size - kernel_base);
+                                              machine->ram_size - kernel_base,
+                                              NULL);
         }
         if (kernel_size < 0) {
             error_report("could not load kernel '%s'",
@@ -179,7 +181,8 @@ static void ppc_heathrow_init(MachineState *machine)
                                             KERNEL_GAP);
             initrd_size = load_image_targphys(machine->initrd_filename,
                                               initrd_base,
-                                              machine->ram_size - initrd_base);
+                                              machine->ram_size - initrd_base,
+                                              NULL);
             if (initrd_size < 0) {
                 error_report("could not load initial ram disk '%s'",
                              machine->initrd_filename);
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index e15cf96427..1f754df0e2 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -163,7 +163,8 @@ static void pegasos2_init(MachineState *machine)
     sz = load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                   ELFDATA2MSB, PPC_ELF_MACHINE, 0, 0);
     if (sz <= 0) {
-        sz = load_image_targphys(filename, pm->vof ? 0 : PROM_ADDR, PROM_SIZE);
+        sz = load_image_targphys(filename, pm->vof ? 0 : PROM_ADDR, PROM_SIZE,
+                                 NULL);
     }
     if (sz <= 0 || sz > PROM_SIZE) {
         error_report("Could not load firmware '%s'", filename);
@@ -259,7 +260,7 @@ static void pegasos2_init(MachineState *machine)
         pm->initrd_addr = ROUND_UP(pm->initrd_addr, 4);
         pm->initrd_addr = MAX(pm->initrd_addr, INITRD_MIN_ADDR);
         sz = load_image_targphys(machine->initrd_filename, pm->initrd_addr,
-                                 machine->ram_size - pm->initrd_addr);
+                                 machine->ram_size - pm->initrd_addr, NULL);
         if (sz <= 0) {
             error_report("Could not load initrd '%s'",
                          machine->initrd_filename);
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index f0469cdb8b..1c0dadda87 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1068,7 +1068,8 @@ static void pnv_init(MachineState *machine)
         exit(1);
     }
 
-    fw_size = load_image_targphys(fw_filename, pnv->fw_load_addr, FW_MAX_SIZE);
+    fw_size = load_image_targphys(fw_filename, pnv->fw_load_addr, FW_MAX_SIZE,
+                                  NULL);
     if (fw_size < 0) {
         error_report("Could not load OPAL firmware '%s'", fw_filename);
         exit(1);
@@ -1080,7 +1081,8 @@ static void pnv_init(MachineState *machine)
         long kernel_size;
 
         kernel_size = load_image_targphys(machine->kernel_filename,
-                                          KERNEL_LOAD_ADDR, KERNEL_MAX_SIZE);
+                                          KERNEL_LOAD_ADDR, KERNEL_MAX_SIZE,
+                                          NULL);
         if (kernel_size < 0) {
             error_report("Could not load kernel '%s'",
                          machine->kernel_filename);
@@ -1092,7 +1094,8 @@ static void pnv_init(MachineState *machine)
     if (machine->initrd_filename) {
         pnv->initrd_base = INITRD_LOAD_ADDR;
         pnv->initrd_size = load_image_targphys(machine->initrd_filename,
-                                  pnv->initrd_base, INITRD_MAX_SIZE);
+                                               pnv->initrd_base,
+                                               INITRD_MAX_SIZE, NULL);
         if (pnv->initrd_size < 0) {
             error_report("Could not load initial ram disk '%s'",
                          machine->initrd_filename);
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 6fff0d8afb..7c66912c10 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -242,7 +242,8 @@ static void bamboo_init(MachineState *machine)
     /* Load initrd. */
     if (initrd_filename) {
         initrd_size = load_image_targphys(initrd_filename, RAMDISK_ADDR,
-                                          machine->ram_size - RAMDISK_ADDR);
+                                          machine->ram_size - RAMDISK_ADDR,
+                                          NULL);
 
         if (initrd_size < 0) {
             error_report("could not load ram disk '%s' at %x",
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 982e40e53e..edd3da7102 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -280,7 +280,7 @@ static void ibm_40p_init(MachineState *machine)
     bios_size = load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                          ELFDATA2MSB, PPC_ELF_MACHINE, 0, 0);
     if (bios_size < 0) {
-        bios_size = load_image_targphys(filename, BIOS_ADDR, BIOS_SIZE);
+        bios_size = load_image_targphys(filename, BIOS_ADDR, BIOS_SIZE, NULL);
     }
     if (bios_size < 0 || bios_size > BIOS_SIZE) {
         error_report("Could not load bios image '%s'", filename);
@@ -380,7 +380,8 @@ static void ibm_40p_init(MachineState *machine)
         kernel_base = KERNEL_LOAD_ADDR;
         kernel_size = load_image_targphys(machine->kernel_filename,
                                           kernel_base,
-                                          machine->ram_size - kernel_base);
+                                          machine->ram_size - kernel_base,
+                                          NULL);
         if (kernel_size < 0) {
             error_report("could not load kernel '%s'",
                          machine->kernel_filename);
@@ -393,7 +394,8 @@ static void ibm_40p_init(MachineState *machine)
             initrd_base = INITRD_LOAD_ADDR;
             initrd_size = load_image_targphys(machine->initrd_filename,
                                               initrd_base,
-                                              machine->ram_size - initrd_base);
+                                              machine->ram_size - initrd_base,
+                                              NULL);
             if (initrd_size < 0) {
                 error_report("could not load initial ram disk '%s'",
                              machine->initrd_filename);
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index ee31bd8f34..68d3eacbff 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -494,7 +494,8 @@ static void sam460ex_init(MachineState *machine)
     if (machine->initrd_filename) {
         initrd_size = load_image_targphys(machine->initrd_filename,
                                           RAMDISK_ADDR,
-                                          machine->ram_size - RAMDISK_ADDR);
+                                          machine->ram_size - RAMDISK_ADDR,
+                                          NULL);
         if (initrd_size < 0) {
             error_report("could not load ram disk '%s' at %x",
                     machine->initrd_filename, RAMDISK_ADDR);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 97ab6bebd2..d69117d3b4 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2824,7 +2824,7 @@ static void spapr_machine_init(MachineState *machine)
         error_report("Could not find LPAR firmware '%s'", bios_name);
         exit(1);
     }
-    fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
+    fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE, NULL);
     if (fw_size <= 0) {
         error_report("Could not load LPAR firmware '%s'", filename);
         exit(1);
@@ -3087,9 +3087,9 @@ static void spapr_machine_init(MachineState *machine)
             spapr->initrd_base = (spapr->kernel_addr + spapr->kernel_size
                                   + 0x1ffff) & ~0xffff;
             spapr->initrd_size = load_image_targphys(initrd_filename,
-                                                     spapr->initrd_base,
-                                                     load_limit
-                                                     - spapr->initrd_base);
+                                                spapr->initrd_base,
+                                                load_limit - spapr->initrd_base,
+                                                NULL);
             if (spapr->initrd_size < 0) {
                 error_report("could not load initial ram disk '%s'",
                              initrd_filename);
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index c9969ae48a..00d9ab7509 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -253,7 +253,7 @@ static void virtex_init(MachineState *machine)
             /* If we failed loading ELF's try a raw image.  */
             kernel_size = load_image_targphys(kernel_filename,
                                               boot_offset,
-                                              machine->ram_size);
+                                              machine->ram_size, NULL);
             boot_info.bootstrap_pc = boot_offset;
             high = boot_info.bootstrap_pc + kernel_size + 8192;
         }
@@ -264,7 +264,8 @@ static void virtex_init(MachineState *machine)
         if (machine->initrd_filename) {
             initrd_base = high = ROUND_UP(high, 4);
             initrd_size = load_image_targphys(machine->initrd_filename,
-                                              high, machine->ram_size - high);
+                                              high, machine->ram_size - high,
+                                              NULL);
 
             if (initrd_size < 0) {
                 error_report("couldn't load ram disk '%s'",
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 828a867be3..f38078c8c2 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -172,7 +172,8 @@ target_ulong riscv_load_firmware(const char *firmware_filename,
 
     firmware_size = load_image_targphys_as(firmware_filename,
                                            *firmware_load_addr,
-                                           current_machine->ram_size, NULL);
+                                           current_machine->ram_size, NULL,
+                                           NULL);
 
     if (firmware_size > 0) {
         return *firmware_load_addr + firmware_size;
@@ -207,7 +208,7 @@ static void riscv_load_initrd(MachineState *machine, RISCVBootInfo *info)
 
     size = load_ramdisk(filename, start, mem_size - start);
     if (size == -1) {
-        size = load_image_targphys(filename, start, mem_size - start);
+        size = load_image_targphys(filename, start, mem_size - start, NULL);
         if (size == -1) {
             error_report("could not load ramdisk '%s'", filename);
             exit(1);
@@ -262,7 +263,7 @@ void riscv_load_kernel(MachineState *machine,
     }
 
     kernel_size = load_image_targphys_as(kernel_filename, kernel_start_addr,
-                                         current_machine->ram_size, NULL);
+                                         current_machine->ram_size, NULL, NULL);
     if (kernel_size > 0) {
         info->kernel_size = kernel_size;
         info->image_low_addr = kernel_start_addr;
diff --git a/hw/rx/rx-gdbsim.c b/hw/rx/rx-gdbsim.c
index 5b9004e9e1..ed91c63178 100644
--- a/hw/rx/rx-gdbsim.c
+++ b/hw/rx/rx-gdbsim.c
@@ -63,7 +63,7 @@ static void rx_load_image(RXCPU *cpu, const char *filename,
     long kernel_size;
     int i;
 
-    kernel_size = load_image_targphys(filename, start, size);
+    kernel_size = load_image_targphys(filename, start, size, NULL);
     if (kernel_size < 0) {
         fprintf(stderr, "qemu: could not load kernel '%s'\n", filename);
         exit(1);
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 2f082396c7..3843d2a850 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -169,7 +169,7 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
         } else {
             /* Try to load non-ELF file */
             bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START,
-                                            4096);
+                                            4096, NULL);
             ipl->bios_start_addr = ZIPL_IMAGE_START;
         }
         g_free(bios_filename);
@@ -188,7 +188,8 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
                                &pentry, NULL,
                                NULL, NULL, ELFDATA2MSB, EM_S390, 0, 0);
         if (kernel_size < 0) {
-            kernel_size = load_image_targphys(ipl->kernel, 0, ms->ram_size);
+            kernel_size = load_image_targphys(ipl->kernel, 0, ms->ram_size,
+                                              NULL);
             if (kernel_size < 0) {
                 error_setg(errp, "could not load kernel '%s'", ipl->kernel);
                 return;
@@ -247,7 +248,8 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
                 initrd_offset += 0x100000;
             }
             initrd_size = load_image_targphys(ipl->initrd, initrd_offset,
-                                              ms->ram_size - initrd_offset);
+                                              ms->ram_size - initrd_offset,
+                                              NULL);
             if (initrd_size == -1) {
                 error_setg(errp, "could not load initrd '%s'", ipl->initrd);
                 return;
diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index d68c94e82e..010be6d539 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -329,8 +329,9 @@ static void r2d_init(MachineState *machine)
         int kernel_size;
 
         kernel_size = load_image_targphys(kernel_filename,
-                                          SDRAM_BASE + LINUX_LOAD_OFFSET,
-                                          INITRD_LOAD_OFFSET - LINUX_LOAD_OFFSET);
+                                        SDRAM_BASE + LINUX_LOAD_OFFSET,
+                                        INITRD_LOAD_OFFSET - LINUX_LOAD_OFFSET,
+                                        NULL);
         if (kernel_size < 0) {
             error_report("qemu: could not load kernel '%s'", kernel_filename);
             exit(1);
@@ -350,7 +351,8 @@ static void r2d_init(MachineState *machine)
 
         initrd_size = load_image_targphys(initrd_filename,
                                           SDRAM_BASE + INITRD_LOAD_OFFSET,
-                                          SDRAM_SIZE - INITRD_LOAD_OFFSET);
+                                          SDRAM_SIZE - INITRD_LOAD_OFFSET,
+                                          NULL);
 
         if (initrd_size < 0) {
             error_report("qemu: could not load initrd '%s'", initrd_filename);
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 13e21a9c43..7558b2ad83 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -1340,7 +1340,7 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
             return;
         }
 
-        size = get_image_size(val);
+        size = get_image_size(val, NULL);
         if (size == -1 || size < sizeof(struct smbios_structure_header)) {
             error_setg(errp, "Cannot read SMBIOS file %s", val);
             return;
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index 09d2cec488..631c6113b5 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -349,7 +349,7 @@ static void leon3_generic_hw_init(MachineState *machine)
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
 
     if (filename) {
-        bios_size = get_image_size(filename);
+        bios_size = get_image_size(filename, NULL);
     } else {
         bios_size = -1;
     }
@@ -360,7 +360,7 @@ static void leon3_generic_hw_init(MachineState *machine)
     }
 
     if (bios_size > 0) {
-        ret = load_image_targphys(filename, LEON3_PROM_OFFSET, bios_size);
+        ret = load_image_targphys(filename, LEON3_PROM_OFFSET, bios_size, NULL);
         if (ret < 0 || ret > prom_size) {
             error_report("could not load prom '%s'", filename);
             exit(1);
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 8ac7e625ef..53d7ae08ae 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -245,7 +245,8 @@ static unsigned long sun4m_load_kernel(const char *kernel_filename,
         if (kernel_size < 0)
             kernel_size = load_image_targphys(kernel_filename,
                                               KERNEL_LOAD_ADDR,
-                                              RAM_size - KERNEL_LOAD_ADDR);
+                                              RAM_size - KERNEL_LOAD_ADDR,
+                                              NULL);
         if (kernel_size < 0) {
             error_report("could not load kernel '%s'", kernel_filename);
             exit(1);
@@ -256,7 +257,8 @@ static unsigned long sun4m_load_kernel(const char *kernel_filename,
         if (initrd_filename) {
             *initrd_size = load_image_targphys(initrd_filename,
                                                INITRD_LOAD_ADDR,
-                                               RAM_size - INITRD_LOAD_ADDR);
+                                               RAM_size - INITRD_LOAD_ADDR,
+                                               NULL);
             if ((int)*initrd_size < 0) {
                 error_report("could not load initial ram disk '%s'",
                              initrd_filename);
@@ -700,7 +702,7 @@ static void prom_init(hwaddr addr, const char *bios_name)
                        translate_prom_address, &addr, NULL,
                        NULL, NULL, NULL, ELFDATA2MSB, EM_SPARC, 0, 0);
         if (ret < 0 || ret > PROM_SIZE_MAX) {
-            ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
+            ret = load_image_targphys(filename, addr, PROM_SIZE_MAX, NULL);
         }
         g_free(filename);
     } else {
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index e9f9b0a4cb..82c3e7c855 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -182,7 +182,8 @@ static uint64_t sun4u_load_kernel(const char *kernel_filename,
         if (kernel_size < 0) {
             kernel_size = load_image_targphys(kernel_filename,
                                               KERNEL_LOAD_ADDR,
-                                              RAM_size - KERNEL_LOAD_ADDR);
+                                              RAM_size - KERNEL_LOAD_ADDR,
+                                              NULL);
         }
         if (kernel_size < 0) {
             error_report("could not load kernel '%s'", kernel_filename);
@@ -195,7 +196,7 @@ static uint64_t sun4u_load_kernel(const char *kernel_filename,
 
             *initrd_size = load_image_targphys(initrd_filename,
                                                *initrd_addr,
-                                               RAM_size - *initrd_addr);
+                                               RAM_size - *initrd_addr, NULL);
             if ((int)*initrd_size < 0) {
                 error_report("could not load initial ram disk '%s'",
                              initrd_filename);
@@ -437,7 +438,7 @@ static void prom_init(hwaddr addr, const char *bios_name)
         ret = load_elf(filename, NULL, translate_prom_address, &addr,
                        NULL, NULL, NULL, NULL, ELFDATA2MSB, EM_SPARCV9, 0, 0);
         if (ret < 0 || ret > PROM_SIZE_MAX) {
-            ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
+            ret = load_image_targphys(filename, addr, PROM_SIZE_MAX, NULL);
         }
         g_free(filename);
     } else {
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index 55de1a7a07..db3b015549 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -381,7 +381,8 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine)
             if (initrd_size < 0) {
                 initrd_size = load_image_targphys(initrd_filename,
                                                   cur_lowmem,
-                                                  lowmem_end - cur_lowmem);
+                                                  lowmem_end - cur_lowmem,
+                                                  NULL);
             }
             if (initrd_size < 0) {
                 error_report("could not load initrd '%s'", initrd_filename);
diff --git a/include/hw/loader.h b/include/hw/loader.h
index c96b5e141c..d035e72748 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -1,6 +1,7 @@
 #ifndef LOADER_H
 #define LOADER_H
 #include "hw/nvram/fw_cfg.h"
+#include "qemu/typedefs.h"
 
 /* loader.c */
 /**
@@ -10,7 +11,7 @@
  * Returns the size of the image file on success, -1 otherwise.
  * On error, errno is also set as appropriate.
  */
-int64_t get_image_size(const char *filename);
+int64_t get_image_size(const char *filename, Error **errp);
 /**
  * load_image_size: load an image file into specified buffer
  * @filename: Path to the image file
@@ -41,7 +42,8 @@ ssize_t load_image_size(const char *filename, void *addr, size_t size);
  * Returns the size of the loaded image on success, -1 otherwise.
  */
 ssize_t load_image_targphys_as(const char *filename,
-                               hwaddr addr, uint64_t max_sz, AddressSpace *as);
+                               hwaddr addr, uint64_t max_sz, AddressSpace *as,
+                               Error **errp);
 
 /**load_targphys_hex_as:
  * @filename: Path to the .hex file
@@ -61,7 +63,7 @@ ssize_t load_targphys_hex_as(const char *filename, hwaddr *entry,
  * an AddressSpace.
  */
 ssize_t load_image_targphys(const char *filename, hwaddr,
-                            uint64_t max_sz);
+                            uint64_t max_sz, Error **errp);
 
 /**
  * load_image_mr: load an image into a memory region
diff --git a/system/device_tree.c b/system/device_tree.c
index aa3fe9516f..7850b90fa7 100644
--- a/system/device_tree.c
+++ b/system/device_tree.c
@@ -83,7 +83,7 @@ void *load_device_tree(const char *filename_path, int *sizep)
     void *fdt = NULL;
 
     *sizep = 0;
-    dt_size = get_image_size(filename_path);
+    dt_size = get_image_size(filename_path, NULL);
     if (dt_size < 0) {
         error_report("Unable to get size of device tree file '%s'",
                      filename_path);
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Patch v5 3/6] hw/core/loader: add check for zero size in load_image_targphys_as
  2025-10-21 10:54 [Patch v5 0/6] hw/core/loader: capture Error from load_image_targphys Vishal Chourasia
  2025-10-21 10:54 ` [Patch v5 1/6] hw/core/loader: Use qemu_open() instead of open() in get_image_size() Vishal Chourasia
  2025-10-21 10:54 ` [Patch v5 2/6] hw/core/loader: capture Error from load_image_targphys Vishal Chourasia
@ 2025-10-21 10:54 ` Vishal Chourasia
  2025-10-21 10:54 ` [Patch v5 4/6] hw/core: Pass errp to load_image_targphys_as() Vishal Chourasia
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Vishal Chourasia @ 2025-10-21 10:54 UTC (permalink / raw)
  To: adityag, harshpb, milesg, npiggin, peter.maydell, alistair23,
	balaton, qemu-devel, qemu-ppc, berrange
  Cc: Vishal Chourasia

Currently load_image_targphys_as() returns -1 on file open failure or
when max size is exceeded. Add an explicit check for zero-sized files
to catch this error early, since some callers check for size <= 0.

Signed-off-by: Vishal Chourasia <vishalc@linux.ibm.com>
---
 hw/core/loader.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/hw/core/loader.c b/hw/core/loader.c
index de35e40719..e1a30da2ac 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -141,6 +141,11 @@ ssize_t load_image_targphys_as(const char *filename,
         return -1;
     }
 
+    if (size == 0) {
+        error_setg(errp, "empty file");
+        return -1;
+    }
+
     if (size > max_sz) {
         error_setg(errp, "%s exceeds maximum image size (%" PRIu64 " MiB)",
                    filename, max_sz / MiB);
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Patch v5 4/6] hw/core: Pass errp to load_image_targphys_as()
  2025-10-21 10:54 [Patch v5 0/6] hw/core/loader: capture Error from load_image_targphys Vishal Chourasia
                   ` (2 preceding siblings ...)
  2025-10-21 10:54 ` [Patch v5 3/6] hw/core/loader: add check for zero size in load_image_targphys_as Vishal Chourasia
@ 2025-10-21 10:54 ` Vishal Chourasia
  2025-10-21 10:54 ` [Patch v5 5/6] hw/ppc/spapr: Rename resize_hpt_err to errp Vishal Chourasia
  2025-10-21 10:54 ` [Patch v5 6/6] hw/ppc: Pass errp to load_image_targphys() and report errors Vishal Chourasia
  5 siblings, 0 replies; 11+ messages in thread
From: Vishal Chourasia @ 2025-10-21 10:54 UTC (permalink / raw)
  To: adityag, harshpb, milesg, npiggin, peter.maydell, alistair23,
	balaton, qemu-devel, qemu-ppc, berrange
  Cc: Vishal Chourasia

Pass errp to load_image_targphys_as() in generic-loader and
guest-loader to capture detailed error information from the
loader functions.

Use error_prepend() instead of error_setg() to preserve the
underlying error details while adding context about which image
failed to load.

Signed-off-by: Vishal Chourasia <vishalc@linux.ibm.com>
---
 hw/core/generic-loader.c | 7 ++++---
 hw/core/guest-loader.c   | 7 ++++---
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
index 6689847c33..35d4e5f4ea 100644
--- a/hw/core/generic-loader.c
+++ b/hw/core/generic-loader.c
@@ -60,6 +60,7 @@ static void generic_loader_reset(void *opaque)
 
 static void generic_loader_realize(DeviceState *dev, Error **errp)
 {
+    ERRP_GUARD();
     GenericLoaderState *s = GENERIC_LOADER(dev);
     hwaddr entry;
     ssize_t size = 0;
@@ -149,13 +150,13 @@ static void generic_loader_realize(DeviceState *dev, Error **errp)
         if (size < 0 || s->force_raw) {
             /* Default to the maximum size being the machine's ram size */
             size = load_image_targphys_as(s->file, s->addr,
-                    current_machine->ram_size, as, NULL);
+                    current_machine->ram_size, as, errp);
         } else {
             s->addr = entry;
         }
 
-        if (size < 0) {
-            error_setg(errp, "Cannot load specified image %s", s->file);
+        if (*errp) {
+            error_prepend(errp, "Cannot load specified image %s: ", s->file);
             return;
         }
     }
diff --git a/hw/core/guest-loader.c b/hw/core/guest-loader.c
index 59f325ad9c..dcbe8e4520 100644
--- a/hw/core/guest-loader.c
+++ b/hw/core/guest-loader.c
@@ -81,6 +81,7 @@ static void loader_insert_platform_data(GuestLoaderState *s, int size,
 
 static void guest_loader_realize(DeviceState *dev, Error **errp)
 {
+    ERRP_GUARD();
     GuestLoaderState *s = GUEST_LOADER(dev);
     char *file = s->kernel ? s->kernel : s->initrd;
     int size = 0;
@@ -101,9 +102,9 @@ static void guest_loader_realize(DeviceState *dev, Error **errp)
 
     /* Default to the maximum size being the machine's ram size */
     size = load_image_targphys_as(file, s->addr, current_machine->ram_size,
-                                  NULL, NULL);
-    if (size < 0) {
-        error_setg(errp, "Cannot load specified image %s", file);
+                                  NULL, errp);
+    if (*errp) {
+        error_prepend(errp, "Cannot load specified image %s: ", file);
         return;
     }
 
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Patch v5 5/6] hw/ppc/spapr: Rename resize_hpt_err to errp
  2025-10-21 10:54 [Patch v5 0/6] hw/core/loader: capture Error from load_image_targphys Vishal Chourasia
                   ` (3 preceding siblings ...)
  2025-10-21 10:54 ` [Patch v5 4/6] hw/core: Pass errp to load_image_targphys_as() Vishal Chourasia
@ 2025-10-21 10:54 ` Vishal Chourasia
  2025-10-21 12:59   ` Philippe Mathieu-Daudé
  2025-10-21 10:54 ` [Patch v5 6/6] hw/ppc: Pass errp to load_image_targphys() and report errors Vishal Chourasia
  5 siblings, 1 reply; 11+ messages in thread
From: Vishal Chourasia @ 2025-10-21 10:54 UTC (permalink / raw)
  To: adityag, harshpb, milesg, npiggin, peter.maydell, alistair23,
	balaton, qemu-devel, qemu-ppc, berrange
  Cc: Vishal Chourasia

Rename resize_hpt_err to standard errp naming convention.

Signed-off-by: Vishal Chourasia <vishalc@linux.ibm.com>
---
 hw/ppc/spapr.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index d69117d3b4..e51540a5ad 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2817,7 +2817,7 @@ static void spapr_machine_init(MachineState *machine)
     int i;
     MemoryRegion *sysmem = get_system_memory();
     long load_limit, fw_size;
-    Error *resize_hpt_err = NULL;
+    Error *errp = NULL;
     NICInfo *nd;
 
     if (!filename) {
@@ -2845,7 +2845,7 @@ static void spapr_machine_init(MachineState *machine)
     /* Determine capabilities to run with */
     spapr_caps_init(spapr);
 
-    kvmppc_check_papr_resize_hpt(&resize_hpt_err);
+    kvmppc_check_papr_resize_hpt(&errp);
     if (spapr->resize_hpt == SPAPR_RESIZE_HPT_DEFAULT) {
         /*
          * If the user explicitly requested a mode we should either
@@ -2853,10 +2853,10 @@ static void spapr_machine_init(MachineState *machine)
          * it's not set explicitly, we reset our mode to something
          * that works
          */
-        if (resize_hpt_err) {
+        if (errp) {
             spapr->resize_hpt = SPAPR_RESIZE_HPT_DISABLED;
-            error_free(resize_hpt_err);
-            resize_hpt_err = NULL;
+            error_free(errp);
+            errp = NULL;
         } else {
             spapr->resize_hpt = smc->resize_hpt_default;
         }
@@ -2864,14 +2864,14 @@ static void spapr_machine_init(MachineState *machine)
 
     assert(spapr->resize_hpt != SPAPR_RESIZE_HPT_DEFAULT);
 
-    if ((spapr->resize_hpt != SPAPR_RESIZE_HPT_DISABLED) && resize_hpt_err) {
+    if ((spapr->resize_hpt != SPAPR_RESIZE_HPT_DISABLED) && errp) {
         /*
          * User requested HPT resize, but this host can't supply it.  Bail out
          */
-        error_report_err(resize_hpt_err);
+        error_report_err(errp);
         exit(1);
     }
-    error_free(resize_hpt_err);
+    error_free(errp);
 
     spapr->rma_size = spapr_rma_size(spapr, &error_fatal);
 
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Patch v5 6/6] hw/ppc: Pass errp to load_image_targphys() and report errors
  2025-10-21 10:54 [Patch v5 0/6] hw/core/loader: capture Error from load_image_targphys Vishal Chourasia
                   ` (4 preceding siblings ...)
  2025-10-21 10:54 ` [Patch v5 5/6] hw/ppc/spapr: Rename resize_hpt_err to errp Vishal Chourasia
@ 2025-10-21 10:54 ` Vishal Chourasia
  2025-10-21 12:39   ` BALATON Zoltan
  5 siblings, 1 reply; 11+ messages in thread
From: Vishal Chourasia @ 2025-10-21 10:54 UTC (permalink / raw)
  To: adityag, harshpb, milesg, npiggin, peter.maydell, alistair23,
	balaton, qemu-devel, qemu-ppc, berrange, hpoussin
  Cc: Vishal Chourasia

Pass errp to load_image_targphys() calls in ppc machine initialization
to capture detailed error information when loading firmware, kernel,
and initrd images.

Use error_reportf_err() instead of error_report() to print the
underlying error details along with context about which image failed
to load.

Signed-off-by: Vishal Chourasia <vishalc@linux.ibm.com>
---
 hw/ppc/amigaone.c      | 15 ++++++++-------
 hw/ppc/e500.c          | 17 +++++++++--------
 hw/ppc/mac_newworld.c  | 25 +++++++++++++++----------
 hw/ppc/mac_oldworld.c  | 25 +++++++++++++++----------
 hw/ppc/pegasos2.c      | 17 +++++++++++------
 hw/ppc/pnv.c           | 31 ++++++++++++++-----------------
 hw/ppc/ppc440_bamboo.c |  9 +++++----
 hw/ppc/prep.c          | 25 +++++++++++++++----------
 hw/ppc/sam460ex.c      |  9 +++++----
 hw/ppc/spapr.c         | 15 ++++++++-------
 hw/ppc/virtex_ml507.c  | 17 +++++++++++------
 11 files changed, 116 insertions(+), 89 deletions(-)

diff --git a/hw/ppc/amigaone.c b/hw/ppc/amigaone.c
index 5c5acc9872..bd14bed243 100644
--- a/hw/ppc/amigaone.c
+++ b/hw/ppc/amigaone.c
@@ -276,6 +276,7 @@ static void amigaone_init(MachineState *machine)
     DriveInfo *di;
     hwaddr loadaddr;
     struct boot_info *bi = NULL;
+    Error *errp = NULL;
 
     /* init CPU */
     cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
@@ -324,9 +325,9 @@ static void amigaone_init(MachineState *machine)
             error_report("Could not find firmware '%s'", machine->firmware);
             exit(1);
         }
-        sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE, NULL);
-        if (sz <= 0 || sz > PROM_SIZE) {
-            error_report("Could not load firmware '%s'", filename);
+        sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE, &errp);
+        if (errp) {
+            error_reportf_err(errp, "Could not load firmware '%s': ", filename);
             exit(1);
         }
     }
@@ -413,10 +414,10 @@ static void amigaone_init(MachineState *machine)
         loadaddr = ROUND_UP(loadaddr + 4 * MiB, 4 * KiB);
         loadaddr = MAX(loadaddr, INITRD_MIN_ADDR);
         sz = load_image_targphys(machine->initrd_filename, loadaddr,
-                                 bi->bd_info - loadaddr, NULL);
-        if (sz <= 0) {
-            error_report("Could not load initrd '%s'",
-                         machine->initrd_filename);
+                                 bi->bd_info - loadaddr, &errp);
+        if (errp) {
+            error_reportf_err(errp, "Could not load initrd '%s': ",
+                              machine->initrd_filename);
             exit(1);
         }
         bi->initrd_start = loadaddr;
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 30937a4a92..48e238f3a4 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -932,6 +932,7 @@ void ppce500_init(MachineState *machine)
     MemoryRegion *ccsr_addr_space;
     SysBusDevice *s;
     I2CBus *i2c;
+    Error *errp = NULL;
 
     irqs = g_new0(IrqLines, smp_cpus);
     for (i = 0; i < smp_cpus; i++) {
@@ -1227,10 +1228,10 @@ void ppce500_init(MachineState *machine)
         kernel_base = cur_base;
         kernel_size = load_image_targphys(machine->kernel_filename,
                                           cur_base,
-                                          machine->ram_size - cur_base, NULL);
-        if (kernel_size < 0) {
-            error_report("could not load kernel '%s'",
-                         machine->kernel_filename);
+                                          machine->ram_size - cur_base, &errp);
+        if (errp) {
+            error_reportf_err(errp, "could not load kernel '%s': ",
+                              machine->kernel_filename);
             exit(1);
         }
 
@@ -1242,11 +1243,11 @@ void ppce500_init(MachineState *machine)
         initrd_base = (cur_base + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK;
         initrd_size = load_image_targphys(machine->initrd_filename, initrd_base,
                                           machine->ram_size - initrd_base,
-                                          NULL);
+                                          &errp);
 
-        if (initrd_size < 0) {
-            error_report("could not load initial ram disk '%s'",
-                         machine->initrd_filename);
+        if (errp) {
+            error_reportf_err(errp, "could not load initial ram disk '%s': ",
+                              machine->initrd_filename);
             exit(1);
         }
 
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 004efc6b97..b95a394a8d 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -156,6 +156,7 @@ static void ppc_core99_init(MachineState *machine)
     DeviceState *uninorth_internal_dev = NULL, *uninorth_agp_dev = NULL;
     hwaddr nvram_addr = 0xFFF04000;
     uint64_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TBFREQ;
+    Error *errp = NULL;
 
     /* init CPUs */
     for (i = 0; i < machine->smp.cpus; i++) {
@@ -189,12 +190,16 @@ static void ppc_core99_init(MachineState *machine)
         if (bios_size <= 0) {
             /* or load binary ROM image */
             bios_size = load_image_targphys(filename, PROM_BASE, PROM_SIZE,
-                                            NULL);
+                                            &errp);
         }
         g_free(filename);
     }
     if (bios_size < 0 || bios_size > PROM_SIZE) {
-        error_report("could not load PowerPC bios '%s'", bios_name);
+        if (!errp) {
+            error_setg(&errp, ": exceeds maximum file size (%" PRIu64 " MiB)",
+                       PROM_SIZE / MiB);
+        }
+        error_reportf_err(errp, "could not load PowerPC bios '%s'", bios_name);
         exit(1);
     }
 
@@ -212,11 +217,11 @@ static void ppc_core99_init(MachineState *machine)
             kernel_size = load_image_targphys(machine->kernel_filename,
                                               kernel_base,
                                               machine->ram_size - kernel_base,
-                                              NULL);
+                                              &errp);
         }
-        if (kernel_size < 0) {
-            error_report("could not load kernel '%s'",
-                         machine->kernel_filename);
+        if (errp) {
+            error_reportf_err(errp, "could not load kernel '%s': ",
+                              machine->kernel_filename);
             exit(1);
         }
         /* load initrd */
@@ -225,10 +230,10 @@ static void ppc_core99_init(MachineState *machine)
             initrd_size = load_image_targphys(machine->initrd_filename,
                                               initrd_base,
                                               machine->ram_size - initrd_base,
-                                              NULL);
-            if (initrd_size < 0) {
-                error_report("could not load initial ram disk '%s'",
-                             machine->initrd_filename);
+                                              &errp);
+            if (errp) {
+                error_reportf_err(errp, "couldn't load initial ram disk '%s': ",
+                                  machine->initrd_filename);
                 exit(1);
             }
             cmdline_base = TARGET_PAGE_ALIGN(initrd_base + initrd_size);
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index c7e44d49b0..f20497e949 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -108,6 +108,7 @@ static void ppc_heathrow_init(MachineState *machine)
     DriveInfo *dinfo, *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     void *fw_cfg;
     uint64_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TBFREQ;
+    Error *errp = NULL;
 
     /* init CPUs */
     for (i = 0; i < machine->smp.cpus; i++) {
@@ -144,13 +145,17 @@ static void ppc_heathrow_init(MachineState *machine)
         if (bios_size <= 0) {
             /* or if could not load ELF try loading a binary ROM image */
             bios_size = load_image_targphys(filename, PROM_BASE, PROM_SIZE,
-                                            NULL);
+                                            &errp);
             bios_addr = PROM_BASE;
         }
         g_free(filename);
     }
     if (bios_size < 0 || bios_addr - PROM_BASE + bios_size > PROM_SIZE) {
-        error_report("could not load PowerPC bios '%s'", bios_name);
+        if (!errp) {
+            error_setg(&errp, ": exceeds maximum file size (%" PRIu64 " MiB)",
+                       PROM_SIZE / MiB);
+        }
+        error_reportf_err(errp, "could not load PowerPC bios '%s'", bios_name);
         exit(1);
     }
 
@@ -168,11 +173,11 @@ static void ppc_heathrow_init(MachineState *machine)
             kernel_size = load_image_targphys(machine->kernel_filename,
                                               kernel_base,
                                               machine->ram_size - kernel_base,
-                                              NULL);
+                                              &errp);
         }
-        if (kernel_size < 0) {
-            error_report("could not load kernel '%s'",
-                         machine->kernel_filename);
+        if (errp) {
+            error_reportf_err(errp, "could not load kernel '%s': ",
+                              machine->kernel_filename);
             exit(1);
         }
         /* load initrd */
@@ -182,10 +187,10 @@ static void ppc_heathrow_init(MachineState *machine)
             initrd_size = load_image_targphys(machine->initrd_filename,
                                               initrd_base,
                                               machine->ram_size - initrd_base,
-                                              NULL);
-            if (initrd_size < 0) {
-                error_report("could not load initial ram disk '%s'",
-                             machine->initrd_filename);
+                                              &errp);
+            if (errp) {
+                error_reportf_err(errp, "couldn't load initial ram disk '%s': ",
+                                  machine->initrd_filename);
                 exit(1);
             }
             cmdline_base = TARGET_PAGE_ALIGN(initrd_base + initrd_size);
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 1f754df0e2..f1b45c3b2c 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -129,6 +129,7 @@ static void pegasos2_init(MachineState *machine)
     int i;
     ssize_t sz;
     uint8_t *spd_data;
+    Error *errp = NULL;
 
     /* init CPU */
     pm->cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
@@ -164,10 +165,14 @@ static void pegasos2_init(MachineState *machine)
                   ELFDATA2MSB, PPC_ELF_MACHINE, 0, 0);
     if (sz <= 0) {
         sz = load_image_targphys(filename, pm->vof ? 0 : PROM_ADDR, PROM_SIZE,
-                                 NULL);
+                                 &errp);
     }
     if (sz <= 0 || sz > PROM_SIZE) {
-        error_report("Could not load firmware '%s'", filename);
+        if (!errp) {
+            error_setg(&errp, ": exceeds maximum file size (%" PRIu64 " MiB)",
+                       PROM_SIZE / MiB);
+        }
+        error_reportf_err(errp, "Could not load firmware '%s'", filename);
         exit(1);
     }
     g_free(filename);
@@ -260,10 +265,10 @@ static void pegasos2_init(MachineState *machine)
         pm->initrd_addr = ROUND_UP(pm->initrd_addr, 4);
         pm->initrd_addr = MAX(pm->initrd_addr, INITRD_MIN_ADDR);
         sz = load_image_targphys(machine->initrd_filename, pm->initrd_addr,
-                                 machine->ram_size - pm->initrd_addr, NULL);
-        if (sz <= 0) {
-            error_report("Could not load initrd '%s'",
-                         machine->initrd_filename);
+                                 machine->ram_size - pm->initrd_addr, &errp);
+        if (errp) {
+            error_reportf_err(errp, "Could not load initrd '%s': ",
+                              machine->initrd_filename);
             exit(1);
         }
         pm->initrd_size = sz;
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 1c0dadda87..f5224537d3 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1009,12 +1009,12 @@ static void pnv_init(MachineState *machine)
     PnvMachineClass *pmc = PNV_MACHINE_GET_CLASS(machine);
     int max_smt_threads = pmc->max_smt_threads;
     char *fw_filename;
-    long fw_size;
     uint64_t chip_ram_start = 0;
     int i;
     char *chip_typename;
     DriveInfo *pnor;
     DeviceState *dev;
+    Error *errp = NULL;
 
     if (kvm_enabled()) {
         error_report("machine %s does not support the KVM accelerator",
@@ -1068,24 +1068,21 @@ static void pnv_init(MachineState *machine)
         exit(1);
     }
 
-    fw_size = load_image_targphys(fw_filename, pnv->fw_load_addr, FW_MAX_SIZE,
-                                  NULL);
-    if (fw_size < 0) {
-        error_report("Could not load OPAL firmware '%s'", fw_filename);
+    if (load_image_targphys(fw_filename, pnv->fw_load_addr, FW_MAX_SIZE,
+                                  &errp) < 0) {
+        error_reportf_err(errp, "Could not load OPAL firmware '%s': ",
+                          fw_filename);
         exit(1);
     }
     g_free(fw_filename);
 
     /* load kernel */
     if (machine->kernel_filename) {
-        long kernel_size;
-
-        kernel_size = load_image_targphys(machine->kernel_filename,
-                                          KERNEL_LOAD_ADDR, KERNEL_MAX_SIZE,
-                                          NULL);
-        if (kernel_size < 0) {
-            error_report("Could not load kernel '%s'",
-                         machine->kernel_filename);
+        if (load_image_targphys(machine->kernel_filename,
+                                KERNEL_LOAD_ADDR, KERNEL_MAX_SIZE,
+                                &errp) < 0) {
+            error_reportf_err(errp, "Could not load kernel '%s': ",
+                              machine->kernel_filename);
             exit(1);
         }
     }
@@ -1095,10 +1092,10 @@ static void pnv_init(MachineState *machine)
         pnv->initrd_base = INITRD_LOAD_ADDR;
         pnv->initrd_size = load_image_targphys(machine->initrd_filename,
                                                pnv->initrd_base,
-                                               INITRD_MAX_SIZE, NULL);
-        if (pnv->initrd_size < 0) {
-            error_report("Could not load initial ram disk '%s'",
-                         machine->initrd_filename);
+                                               INITRD_MAX_SIZE, &errp);
+        if (errp) {
+            error_reportf_err(errp, "Could not load initial ram disk '%s': ",
+                              machine->initrd_filename);
             exit(1);
         }
     }
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 7c66912c10..64b5d9a4c4 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -141,6 +141,7 @@ static void bamboo_init(MachineState *machine)
     DeviceState *uicdev;
     SysBusDevice *uicsbd;
     int success;
+    Error *errp = NULL;
 
     if (kvm_enabled()) {
         error_report("machine %s does not support the KVM accelerator",
@@ -243,11 +244,11 @@ static void bamboo_init(MachineState *machine)
     if (initrd_filename) {
         initrd_size = load_image_targphys(initrd_filename, RAMDISK_ADDR,
                                           machine->ram_size - RAMDISK_ADDR,
-                                          NULL);
+                                          &errp);
 
-        if (initrd_size < 0) {
-            error_report("could not load ram disk '%s' at %x",
-                         initrd_filename, RAMDISK_ADDR);
+        if (errp) {
+            error_reportf_err(errp, "could not load ram disk '%s' at %x: ",
+                              initrd_filename, RAMDISK_ADDR);
             exit(1);
         }
     }
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index edd3da7102..d25a98dd2b 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -250,6 +250,7 @@ static void ibm_40p_init(MachineState *machine)
     uint32_t kernel_base = 0, initrd_base = 0;
     long kernel_size = 0, initrd_size = 0;
     char boot_device;
+    Error *errp = NULL;
 
     if (kvm_enabled()) {
         error_report("machine %s does not support the KVM accelerator",
@@ -280,10 +281,14 @@ static void ibm_40p_init(MachineState *machine)
     bios_size = load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                          ELFDATA2MSB, PPC_ELF_MACHINE, 0, 0);
     if (bios_size < 0) {
-        bios_size = load_image_targphys(filename, BIOS_ADDR, BIOS_SIZE, NULL);
+        bios_size = load_image_targphys(filename, BIOS_ADDR, BIOS_SIZE, &errp);
     }
     if (bios_size < 0 || bios_size > BIOS_SIZE) {
-        error_report("Could not load bios image '%s'", filename);
+        if (!errp) {
+            error_setg(&errp, ": exceeds maximum file size (%" PRIu64 " MiB)",
+                       BIOS_SIZE / MiB);
+        }
+        error_reportf_err(errp, "Could not load bios image '%s'", filename);
         return;
     }
     g_free(filename);
@@ -381,10 +386,10 @@ static void ibm_40p_init(MachineState *machine)
         kernel_size = load_image_targphys(machine->kernel_filename,
                                           kernel_base,
                                           machine->ram_size - kernel_base,
-                                          NULL);
-        if (kernel_size < 0) {
-            error_report("could not load kernel '%s'",
-                         machine->kernel_filename);
+                                          &errp);
+        if (errp) {
+            error_reportf_err(errp, "could not load kernel '%s': ",
+                              machine->kernel_filename);
             exit(1);
         }
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
@@ -395,10 +400,10 @@ static void ibm_40p_init(MachineState *machine)
             initrd_size = load_image_targphys(machine->initrd_filename,
                                               initrd_base,
                                               machine->ram_size - initrd_base,
-                                              NULL);
-            if (initrd_size < 0) {
-                error_report("could not load initial ram disk '%s'",
-                             machine->initrd_filename);
+                                              &errp);
+            if (errp) {
+                error_reportf_err(errp, "couldn't load initial ram disk '%s': ",
+                                  machine->initrd_filename);
                 exit(1);
             }
             fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base);
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index 68d3eacbff..9102bfb6d1 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -262,6 +262,7 @@ static void sam460ex_init(MachineState *machine)
     struct boot_info *boot_info;
     uint8_t *spd_data;
     int success;
+    Error *errp = NULL;
 
     cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
     env = &cpu->env;
@@ -495,10 +496,10 @@ static void sam460ex_init(MachineState *machine)
         initrd_size = load_image_targphys(machine->initrd_filename,
                                           RAMDISK_ADDR,
                                           machine->ram_size - RAMDISK_ADDR,
-                                          NULL);
-        if (initrd_size < 0) {
-            error_report("could not load ram disk '%s' at %x",
-                    machine->initrd_filename, RAMDISK_ADDR);
+                                          &errp);
+        if (errp) {
+            error_reportf_err(errp, "could not load ram disk '%s' at %x: ",
+                              machine->initrd_filename, RAMDISK_ADDR);
             exit(1);
         }
     }
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index e51540a5ad..18d73868ed 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2824,9 +2824,10 @@ static void spapr_machine_init(MachineState *machine)
         error_report("Could not find LPAR firmware '%s'", bios_name);
         exit(1);
     }
-    fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE, NULL);
-    if (fw_size <= 0) {
-        error_report("Could not load LPAR firmware '%s'", filename);
+    fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE, &errp);
+    if (errp) {
+        error_reportf_err(errp, "Could not load LPAR firmware '%s': ",
+                          filename);
         exit(1);
     }
 
@@ -3089,10 +3090,10 @@ static void spapr_machine_init(MachineState *machine)
             spapr->initrd_size = load_image_targphys(initrd_filename,
                                                 spapr->initrd_base,
                                                 load_limit - spapr->initrd_base,
-                                                NULL);
-            if (spapr->initrd_size < 0) {
-                error_report("could not load initial ram disk '%s'",
-                             initrd_filename);
+                                                &errp);
+            if (errp) {
+                error_reportf_err(errp, "couldn't load initial ram disk '%s': ",
+                                  initrd_filename);
                 exit(1);
             }
         }
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 00d9ab7509..e1b658bcda 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -195,6 +195,7 @@ static void virtex_init(MachineState *machine)
     qemu_irq irq[32], cpu_irq;
     int kernel_size;
     int i;
+    Error *errp = NULL;
 
     /* init CPUs */
     cpu = ppc440_init_xilinx(machine->cpu_type, 400000000);
@@ -253,7 +254,12 @@ static void virtex_init(MachineState *machine)
             /* If we failed loading ELF's try a raw image.  */
             kernel_size = load_image_targphys(kernel_filename,
                                               boot_offset,
-                                              machine->ram_size, NULL);
+                                              machine->ram_size, &errp);
+            if (errp) {
+                error_reportf_err(errp, "couldn't load kernel '%s': ",
+                                  kernel_filename);
+                exit(1);
+            }
             boot_info.bootstrap_pc = boot_offset;
             high = boot_info.bootstrap_pc + kernel_size + 8192;
         }
@@ -265,11 +271,10 @@ static void virtex_init(MachineState *machine)
             initrd_base = high = ROUND_UP(high, 4);
             initrd_size = load_image_targphys(machine->initrd_filename,
                                               high, machine->ram_size - high,
-                                              NULL);
-
-            if (initrd_size < 0) {
-                error_report("couldn't load ram disk '%s'",
-                             machine->initrd_filename);
+                                              &errp);
+            if (errp) {
+                error_reportf_err(errp, "couldn't load ram disk '%s': ",
+                                  machine->initrd_filename);
                 exit(1);
             }
             high = ROUND_UP(high + initrd_size, 4);
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [Patch v5 6/6] hw/ppc: Pass errp to load_image_targphys() and report errors
  2025-10-21 10:54 ` [Patch v5 6/6] hw/ppc: Pass errp to load_image_targphys() and report errors Vishal Chourasia
@ 2025-10-21 12:39   ` BALATON Zoltan
  2025-10-22  9:57     ` Vishal Chourasia
  0 siblings, 1 reply; 11+ messages in thread
From: BALATON Zoltan @ 2025-10-21 12:39 UTC (permalink / raw)
  To: Vishal Chourasia
  Cc: adityag, harshpb, milesg, npiggin, peter.maydell, alistair23,
	qemu-devel, qemu-ppc, berrange, hpoussin

On Tue, 21 Oct 2025, Vishal Chourasia wrote:
> Pass errp to load_image_targphys() calls in ppc machine initialization
> to capture detailed error information when loading firmware, kernel,
> and initrd images.
>
> Use error_reportf_err() instead of error_report() to print the
> underlying error details along with context about which image failed
> to load.
>
> Signed-off-by: Vishal Chourasia <vishalc@linux.ibm.com>
> ---
> hw/ppc/amigaone.c      | 15 ++++++++-------
> hw/ppc/e500.c          | 17 +++++++++--------
> hw/ppc/mac_newworld.c  | 25 +++++++++++++++----------
> hw/ppc/mac_oldworld.c  | 25 +++++++++++++++----------
> hw/ppc/pegasos2.c      | 17 +++++++++++------
> hw/ppc/pnv.c           | 31 ++++++++++++++-----------------
> hw/ppc/ppc440_bamboo.c |  9 +++++----
> hw/ppc/prep.c          | 25 +++++++++++++++----------
> hw/ppc/sam460ex.c      |  9 +++++----
> hw/ppc/spapr.c         | 15 ++++++++-------
> hw/ppc/virtex_ml507.c  | 17 +++++++++++------
> 11 files changed, 116 insertions(+), 89 deletions(-)
>
> diff --git a/hw/ppc/amigaone.c b/hw/ppc/amigaone.c
> index 5c5acc9872..bd14bed243 100644
> --- a/hw/ppc/amigaone.c
> +++ b/hw/ppc/amigaone.c
> @@ -276,6 +276,7 @@ static void amigaone_init(MachineState *machine)
>     DriveInfo *di;
>     hwaddr loadaddr;
>     struct boot_info *bi = NULL;
> +    Error *errp = NULL;
>
>     /* init CPU */
>     cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
> @@ -324,9 +325,9 @@ static void amigaone_init(MachineState *machine)
>             error_report("Could not find firmware '%s'", machine->firmware);
>             exit(1);
>         }
> -        sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE, NULL);
> -        if (sz <= 0 || sz > PROM_SIZE) {
> -            error_report("Could not load firmware '%s'", filename);
> +        sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE, &errp);
> +        if (errp) {
> +            error_reportf_err(errp, "Could not load firmware '%s': ", filename);
>             exit(1);

If all that's done with an errp is checking for error, printing it and 
then exit then isn't that what passing &error_fatal is for? So these 
should all just do that instead of open coding it, don't they? This would 
lose the general local error messages and those would be replaced by the 
more specific ones from the load functions that should be enough. (I'm 
always unsure how to correctly use error and errp so some more expert 
opinion could be useful but otherwise this series does not seem to 
simplify things much.)

If you don't want to convert all these other machines I'm also OK with 
leaving these passing NULL to load_image_targphys for now and keep current 
error handling which can then be converted later so alternatively you can 
drop this patch if you can't finish it before the freeze.

Regards,
BALATON Zoltan


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Patch v5 5/6] hw/ppc/spapr: Rename resize_hpt_err to errp
  2025-10-21 10:54 ` [Patch v5 5/6] hw/ppc/spapr: Rename resize_hpt_err to errp Vishal Chourasia
@ 2025-10-21 12:59   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 11+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-10-21 12:59 UTC (permalink / raw)
  To: Vishal Chourasia, adityag, harshpb, milesg, npiggin,
	peter.maydell, alistair23, balaton, qemu-devel, qemu-ppc,
	berrange

On 21/10/25 12:54, Vishal Chourasia wrote:
> Rename resize_hpt_err to standard errp naming convention.
> 
> Signed-off-by: Vishal Chourasia <vishalc@linux.ibm.com>
> ---
>   hw/ppc/spapr.c | 16 ++++++++--------
>   1 file changed, 8 insertions(+), 8 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Patch v5 6/6] hw/ppc: Pass errp to load_image_targphys() and report errors
  2025-10-21 12:39   ` BALATON Zoltan
@ 2025-10-22  9:57     ` Vishal Chourasia
  2025-10-22 12:06       ` BALATON Zoltan
  0 siblings, 1 reply; 11+ messages in thread
From: Vishal Chourasia @ 2025-10-22  9:57 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: adityag, harshpb, milesg, npiggin, peter.maydell, alistair23,
	qemu-devel, qemu-ppc, berrange, hpoussin


On 21/10/25 18:09, BALATON Zoltan wrote:
> On Tue, 21 Oct 2025, Vishal Chourasia wrote:
>> Pass errp to load_image_targphys() calls in ppc machine initialization
>> to capture detailed error information when loading firmware, kernel,
>> and initrd images.
>>
>> Use error_reportf_err() instead of error_report() to print the
>> underlying error details along with context about which image failed
>> to load.
>>
>> Signed-off-by: Vishal Chourasia <vishalc@linux.ibm.com>
>> ---
>> hw/ppc/amigaone.c      | 15 ++++++++-------
>> hw/ppc/e500.c          | 17 +++++++++--------
>> hw/ppc/mac_newworld.c  | 25 +++++++++++++++----------
>> hw/ppc/mac_oldworld.c  | 25 +++++++++++++++----------
>> hw/ppc/pegasos2.c      | 17 +++++++++++------
>> hw/ppc/pnv.c           | 31 ++++++++++++++-----------------
>> hw/ppc/ppc440_bamboo.c |  9 +++++----
>> hw/ppc/prep.c          | 25 +++++++++++++++----------
>> hw/ppc/sam460ex.c      |  9 +++++----
>> hw/ppc/spapr.c         | 15 ++++++++-------
>> hw/ppc/virtex_ml507.c  | 17 +++++++++++------
>> 11 files changed, 116 insertions(+), 89 deletions(-)
>>
>> diff --git a/hw/ppc/amigaone.c b/hw/ppc/amigaone.c
>> index 5c5acc9872..bd14bed243 100644
>> --- a/hw/ppc/amigaone.c
>> +++ b/hw/ppc/amigaone.c
>> @@ -276,6 +276,7 @@ static void amigaone_init(MachineState *machine)
>>     DriveInfo *di;
>>     hwaddr loadaddr;
>>     struct boot_info *bi = NULL;
>> +    Error *errp = NULL;
>>
>>     /* init CPU */
>>     cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
>> @@ -324,9 +325,9 @@ static void amigaone_init(MachineState *machine)
>>             error_report("Could not find firmware '%s'", 
>> machine->firmware);
>>             exit(1);
>>         }
>> -        sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE, NULL);
>> -        if (sz <= 0 || sz > PROM_SIZE) {
>> -            error_report("Could not load firmware '%s'", filename);
>> +        sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE, 
>> &errp);
>> +        if (errp) {
>> +            error_reportf_err(errp, "Could not load firmware '%s': 
>> ", filename);
>>             exit(1);
>
> If all that's done with an errp is checking for error, printing it and 
> then exit then isn't that what passing &error_fatal is for? So these 
> should all just do that instead of open coding it, don't they? This 
> would lose the general local error messages and those would be 
> replaced by the more specific ones from the load functions that should 
> be enough. (I'm always unsure how to correctly use error and errp so 
> some more expert opinion could be useful but otherwise this series 
> does not seem to simplify things much.)

I am planning to add filename information inside the 
load_image_targphys() so that we won't need additional error reporting 
regarding the file type in the caller.
We can use error_fatal where ever we are just exiting after printing the 
error. However, in some cases, it may proceed for different reasons in 
which case errp would be more appropriate.

> If you don't want to convert all these other machines I'm also OK with 
> leaving these passing NULL to load_image_targphys for now and keep 
> current error handling which can then be converted later so 
> alternatively you can drop this patch if you can't finish it before 
> the freeze. 

I will try to improve at least for the PPC boards and see if that would 
work better.

Thanks,
Vishal

>
> Regards,
> BALATON Zoltan


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Patch v5 6/6] hw/ppc: Pass errp to load_image_targphys() and report errors
  2025-10-22  9:57     ` Vishal Chourasia
@ 2025-10-22 12:06       ` BALATON Zoltan
  0 siblings, 0 replies; 11+ messages in thread
From: BALATON Zoltan @ 2025-10-22 12:06 UTC (permalink / raw)
  To: Vishal Chourasia
  Cc: adityag, harshpb, milesg, npiggin, peter.maydell, alistair23,
	qemu-devel, qemu-ppc, berrange, hpoussin

[-- Attachment #1: Type: text/plain, Size: 3552 bytes --]

On Wed, 22 Oct 2025, Vishal Chourasia wrote:
> On 21/10/25 18:09, BALATON Zoltan wrote:
>> On Tue, 21 Oct 2025, Vishal Chourasia wrote:
>>> Pass errp to load_image_targphys() calls in ppc machine initialization
>>> to capture detailed error information when loading firmware, kernel,
>>> and initrd images.
>>> 
>>> Use error_reportf_err() instead of error_report() to print the
>>> underlying error details along with context about which image failed
>>> to load.
>>> 
>>> Signed-off-by: Vishal Chourasia <vishalc@linux.ibm.com>
>>> ---
>>> hw/ppc/amigaone.c      | 15 ++++++++-------
>>> hw/ppc/e500.c          | 17 +++++++++--------
>>> hw/ppc/mac_newworld.c  | 25 +++++++++++++++----------
>>> hw/ppc/mac_oldworld.c  | 25 +++++++++++++++----------
>>> hw/ppc/pegasos2.c      | 17 +++++++++++------
>>> hw/ppc/pnv.c           | 31 ++++++++++++++-----------------
>>> hw/ppc/ppc440_bamboo.c |  9 +++++----
>>> hw/ppc/prep.c          | 25 +++++++++++++++----------
>>> hw/ppc/sam460ex.c      |  9 +++++----
>>> hw/ppc/spapr.c         | 15 ++++++++-------
>>> hw/ppc/virtex_ml507.c  | 17 +++++++++++------
>>> 11 files changed, 116 insertions(+), 89 deletions(-)
>>> 
>>> diff --git a/hw/ppc/amigaone.c b/hw/ppc/amigaone.c
>>> index 5c5acc9872..bd14bed243 100644
>>> --- a/hw/ppc/amigaone.c
>>> +++ b/hw/ppc/amigaone.c
>>> @@ -276,6 +276,7 @@ static void amigaone_init(MachineState *machine)
>>>     DriveInfo *di;
>>>     hwaddr loadaddr;
>>>     struct boot_info *bi = NULL;
>>> +    Error *errp = NULL;
>>> 
>>>     /* init CPU */
>>>     cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
>>> @@ -324,9 +325,9 @@ static void amigaone_init(MachineState *machine)
>>>             error_report("Could not find firmware '%s'", 
>>> machine->firmware);
>>>             exit(1);
>>>         }
>>> -        sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE, NULL);
>>> -        if (sz <= 0 || sz > PROM_SIZE) {
>>> -            error_report("Could not load firmware '%s'", filename);
>>> +        sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE, &errp);
>>> +        if (errp) {
>>> +            error_reportf_err(errp, "Could not load firmware '%s': ", 
>>> filename);
>>>             exit(1);
>> 
>> If all that's done with an errp is checking for error, printing it and then 
>> exit then isn't that what passing &error_fatal is for? So these should all 
>> just do that instead of open coding it, don't they? This would lose the 
>> general local error messages and those would be replaced by the more 
>> specific ones from the load functions that should be enough. (I'm always 
>> unsure how to correctly use error and errp so some more expert opinion 
>> could be useful but otherwise this series does not seem to simplify things 
>> much.)
>
> I am planning to add filename information inside the load_image_targphys() so 
> that we won't need additional error reporting regarding the file type in the 
> caller.
> We can use error_fatal where ever we are just exiting after printing the 
> error. However, in some cases, it may proceed for different reasons in which 
> case errp would be more appropriate.

Sure, if the caller can do something else than exit it can pass errp and 
then handle the error some other way. But most callers just print the 
error and exit for which error_fatal is a better and usual way and could 
simplify callers.

Regards,
BALATON Zoltan

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2025-10-22 12:07 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-21 10:54 [Patch v5 0/6] hw/core/loader: capture Error from load_image_targphys Vishal Chourasia
2025-10-21 10:54 ` [Patch v5 1/6] hw/core/loader: Use qemu_open() instead of open() in get_image_size() Vishal Chourasia
2025-10-21 10:54 ` [Patch v5 2/6] hw/core/loader: capture Error from load_image_targphys Vishal Chourasia
2025-10-21 10:54 ` [Patch v5 3/6] hw/core/loader: add check for zero size in load_image_targphys_as Vishal Chourasia
2025-10-21 10:54 ` [Patch v5 4/6] hw/core: Pass errp to load_image_targphys_as() Vishal Chourasia
2025-10-21 10:54 ` [Patch v5 5/6] hw/ppc/spapr: Rename resize_hpt_err to errp Vishal Chourasia
2025-10-21 12:59   ` Philippe Mathieu-Daudé
2025-10-21 10:54 ` [Patch v5 6/6] hw/ppc: Pass errp to load_image_targphys() and report errors Vishal Chourasia
2025-10-21 12:39   ` BALATON Zoltan
2025-10-22  9:57     ` Vishal Chourasia
2025-10-22 12:06       ` BALATON Zoltan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).