Hello Daniel,

Thank you for the review!

On Wed, Oct 15, 2025 at 03:02:27PM +0100, Daniel P. Berrangé wrote:
> On Wed, Oct 15, 2025 at 07:17:17PM +0530, Vishal Chourasia wrote:
> > diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
> > index e72bbde2a2..8cf5aadf1f 100644
> > --- a/hw/core/generic-loader.c
> > +++ b/hw/core/generic-loader.c
> > @@ -148,13 +148,14 @@ 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, errp);
> >          } else {
> >              s->addr = entry;
> >          }
> >  
> > -        if (size < 0) {
> > -            error_setg(errp, "Cannot load specified image %s", s->file);
> > +        if (*errp || size < 0) {
> 
> We should not have to check both *errp and 'size < 0'.
Sure, I will remove the `*errp`

> We must ensure that every code path in 'load_image_targphys_as' that can
> return -1, will *always* fills in 'errp', so that callers can be sure
> that *errp is always non-NULL on failure.
> 

> > +            error_reportf_err(*errp, "Cannot load specified image %s", 
> > s->file);
> 
> This method is propagating the error to the caller in its 'errp'
> parameter, so it is wrong to call error_reportf_err. The latter
> should only be used at the final point in the callstack which
> owns the 'Error' parameter.
> 
> The only change in this method should be to remove the existing
> error_setg call.
Agreed. Removing it altogether.

> > diff --git a/hw/core/guest-loader.c b/hw/core/guest-loader.c
> > index 3db89d7a2e..d4f749fd6e 100644
> > --- a/hw/core/guest-loader.c
> > +++ b/hw/core/guest-loader.c
> > @@ -101,9 +101,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);
> > -    if (size < 0) {
> > -        error_setg(errp, "Cannot load specified image %s", file);
> > +                                  NULL, errp);
> > +    if (*errp || size < 0) {
> > +        error_reportf_err(*errp, "Cannot load specified image %s", file);
> >          return;
> 
> Again must not be calling error_reportf_err nor chcking *errp,
> just remove error_setg().
Will remove.

> >  
> > diff --git a/hw/core/loader.c b/hw/core/loader.c
> > index 477661a025..d8c02786d2 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"
> > @@ -61,23 +62,31 @@
> >  #include "hw/nvram/fw_cfg.h"
> >  #include "system/memory.h"
> >  #include "hw/boards.h"
> > +#include "qapi/error.h"
> >  #include "qemu/cutils.h"
> >  #include "system/runstate.h"
> >  #include "tcg/debuginfo.h"
> >  
> > +#include <errno.h>
> >  #include <zlib.h>
> >  
> >  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 = open(filename, O_RDONLY | O_BINARY);
> > -    if (fd < 0)
> > +    if (fd < 0) {
> > +        error_setg_file_open(errp, errno, filename);
> >          return -1;
> > +    }
> 
> This perhaps ought to be changed to call 'qemu_open' which
> already fills in an Error object, and additionally protects
> the fd with O_CLOEXEC and handles FD passing with /dev/fdset
> 
Make sense, thanks for the suggestion. 

> >      size = lseek(fd, 0, SEEK_END);
> > +    if (size < 0) {
> > +        error_setg_errno(errp, errno, "lseek failure");
> > +        return -1;
> > +    }
> >      close(fd);
> >      return size;
> >  }
> > @@ -118,21 +127,28 @@ 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)
> >  {
> >      ssize_t size;
> >  
> > -    size = get_image_size(filename);
> > -    if (size < 0 || size > max_sz) {
> > +    size = get_image_size(filename, errp);
> > +    if (*errp || size < 0) {
> 
> Must not chck *errp, only 'size < 0'.
Sure. I will modify accordingly.

> 
> >          return -1;
> >      }
> > +
> > +    if (size > max_sz) {
> > +        error_setg(errp, "Exceeds maximum image size (%lu MiB)", max_sz / 
> > MiB);
> > +        return -1;
> > +    }
> > +
> >      if (size > 0) {
> >          if (rom_add_file_fixed_as(filename, addr, -1, as) < 0) {
> >              return -1;
> > @@ -150,7 +166,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;
> 
> 
> I'd suggest that we add the Error parameter in one patch, making every
> caller pass NULL. Then a second patch update the callers to pass a
> non-NULL errp and use error_report_err to print details, ideally  for
> more than just the 1 ppc source file. 

sure.

Planning to make following changes as per your review.

diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
index 8cf5aadf1f..cd636d9d89 100644
--- a/hw/core/generic-loader.c
+++ b/hw/core/generic-loader.c
@@ -154,8 +154,7 @@ static void generic_loader_realize(DeviceState *dev, Error 
**errp)
             s->addr = entry;
         }

-        if (*errp || size < 0) {
-            error_reportf_err(*errp, "Cannot load specified image %s", 
s->file);
+        if (size < 0) {
             return;
         }
     }
diff --git a/hw/core/guest-loader.c b/hw/core/guest-loader.c
index d4f749fd6e..9722474480 100644
--- a/hw/core/guest-loader.c
+++ b/hw/core/guest-loader.c
@@ -102,8 +102,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, errp);
-    if (*errp || size < 0) {
-        error_reportf_err(*errp, "Cannot load specified image %s", file);
+    if (size < 0) {
         return;
     }

diff --git a/hw/core/loader.c b/hw/core/loader.c
index d8c02786d2..68cf982efe 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -77,14 +77,13 @@ int64_t get_image_size(const char *filename, Error **errp)
 {
     int fd;
     int64_t size;
-    fd = open(filename, O_RDONLY | O_BINARY);
+    fd = qemu_open(filename, O_RDONLY | O_BINARY, errp);
     if (fd < 0) {
-        error_setg_file_open(errp, errno, filename);
         return -1;
     }
     size = lseek(fd, 0, SEEK_END);
     if (size < 0) {
-        error_setg_errno(errp, errno, "lseek failure");
+        error_setg_errno(errp, errno, "lseek failure: %s", filename);
         return -1;
     }
     close(fd);
@@ -140,12 +139,12 @@ ssize_t load_image_targphys_as(const char *filename,
     ssize_t size;

     size = get_image_size(filename, errp);
-    if (*errp || size < 0) {
+    if (size < 0) {
         return -1;
     }

     if (size > max_sz) {
-        error_setg(errp, "Exceeds maximum image size (%lu MiB)", max_sz / MiB);
+        error_setg(errp, "%s exceeds maximum image size (%lu MiB)", filename, 
max_sz / MiB);
         return -1;
     }

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index e293d2ef35..16f3802717 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1072,8 +1072,7 @@ static void pnv_init(MachineState *machine)
     fw_size = load_image_targphys(fw_filename, pnv->fw_load_addr, FW_MAX_SIZE,
                                     &errp);
     if (fw_size < 0) {
-        error_reportf_err(errp, "Could not load OPAL firmware '%s': ",
-                fw_filename);
+        error_report_err(errp);
         exit(1);
     }
     g_free(fw_filename);
@@ -1086,8 +1085,7 @@ static void pnv_init(MachineState *machine)
                                           KERNEL_LOAD_ADDR, KERNEL_MAX_SIZE,
                                           &errp);
         if (kernel_size < 0) {
-            error_reportf_err(errp, "Could not load kernel '%s': ",
-                    machine->kernel_filename);
+            error_report_err(errp);
             exit(1);
         }
     }
@@ -1098,8 +1096,7 @@ static void pnv_init(MachineState *machine)
         pnv->initrd_size = load_image_targphys(machine->initrd_filename,
                                   pnv->initrd_base, INITRD_MAX_SIZE, &errp);
         if (pnv->initrd_size < 0) {
-            error_reportf_err(errp, "Could not load initial ram disk '%s': ",
-                    machine->initrd_filename);
+            error_report_err(errp);
             exit(1);
         }
     }


- vishalc


Reply via email to