Re: [PATCH 10/12] hpet: return errors from realize if properties are incorrect

2025-05-29 Thread Zhao Liu
On Mon, May 26, 2025 at 04:24:53PM +0200, Paolo Bonzini wrote:
> Date: Mon, 26 May 2025 16:24:53 +0200
> From: Paolo Bonzini 
> Subject: [PATCH 10/12] hpet: return errors from realize if properties are
>  incorrect
> X-Mailer: git-send-email 2.49.0
> 
> Do not silently adjust num_timers, and fail if intcap is 0.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  hw/timer/hpet.c | 15 ---
>  1 file changed, 8 insertions(+), 7 deletions(-)

Reviewed-by: Zhao Liu 




Re: [PATCH 10/12] hpet: return errors from realize if properties are incorrect

2025-05-27 Thread Markus Armbruster
Paolo Bonzini  writes:

> Do not silently adjust num_timers, and fail if intcap is 0.

A bad habit of ours.

> Signed-off-by: Paolo Bonzini 
> ---
>  hw/timer/hpet.c | 15 ---
>  1 file changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
> index d1b7bc52b7b..d78aba04bcd 100644
> --- a/hw/timer/hpet.c
> +++ b/hw/timer/hpet.c
> @@ -689,8 +689,14 @@ static void hpet_realize(DeviceState *dev, Error **errp)
>  int i;
>  HPETTimer *timer;
>  
> +if (s->num_timers < HPET_MIN_TIMERS || s->num_timers > HPET_MAX_TIMERS) {
> +error_setg(errp, "hpet.num_timers must be between %d and %d",
> +   HPET_MIN_TIMERS, HPET_MAX_TIMERS);
> +return;
> +}
>  if (!s->intcap) {
> -warn_report("Hpet's intcap not initialized");
> +error_setg(errp, "hpet.hpet-intcap not initialized");
> +return;
>  }
>  if (hpet_fw_cfg.count == UINT8_MAX) {
>  /* first instance */
> @@ -698,7 +704,7 @@ static void hpet_realize(DeviceState *dev, Error **errp)
>  }
>  
>  if (hpet_fw_cfg.count == 8) {
> -error_setg(errp, "Only 8 instances of HPET is allowed");
> +error_setg(errp, "Only 8 instances of HPET are allowed");
>  return;
>  }
>  
> @@ -708,11 +714,6 @@ static void hpet_realize(DeviceState *dev, Error **errp)
>  sysbus_init_irq(sbd, &s->irqs[i]);
>  }
>  
> -if (s->num_timers < HPET_MIN_TIMERS) {
> -s->num_timers = HPET_MIN_TIMERS;
> -} else if (s->num_timers > HPET_MAX_TIMERS) {
> -s->num_timers = HPET_MAX_TIMERS;
> -}
>  for (i = 0; i < HPET_MAX_TIMERS; i++) {
>  timer = &s->timer[i];
>  timer->qemu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, hpet_timer, 
> timer);

This device is not user-creatable.  It is only ever created (and
realized) by board code.  Errors should not happen.  If they happen
anyway, it's a board code bug.

The code creating it is pc_basic_device_init():

if (pcms->hpet_enabled) {
qemu_irq rtc_irq;

hpet = qdev_try_new(TYPE_HPET);
if (!hpet) {
error_report("couldn't create HPET device");
exit(1);
}

Could just as well use qdev_new().  Differently confusing error message,
though.

/*
 * For pc-piix-*, hpet's intcap is always IRQ2. For pc-q35-*,
 * use IRQ16~23, IRQ8 and IRQ2.  If the user has already set
 * the property, use whatever mask they specified.
 */
uint8_t compat = object_property_get_uint(OBJECT(hpet),
HPET_INTCAP, NULL);
if (!compat) {
qdev_prop_set_uint32(hpet, HPET_INTCAP, hpet_irqs);
}
sysbus_realize_and_unref(SYS_BUS_DEVICE(hpet), &error_fatal);

If this fails, it's a programming error, i.e. &error_abort is more
appropriate.  Hmm, can the user mess with property values via -global?
If yes, it could be a user error.

[...]
}

I'm rambling.  The patch is fine.

Reviewed-by: Markus Armbruster 




[PATCH 10/12] hpet: return errors from realize if properties are incorrect

2025-05-26 Thread Paolo Bonzini
Do not silently adjust num_timers, and fail if intcap is 0.

Signed-off-by: Paolo Bonzini 
---
 hw/timer/hpet.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
index d1b7bc52b7b..d78aba04bcd 100644
--- a/hw/timer/hpet.c
+++ b/hw/timer/hpet.c
@@ -689,8 +689,14 @@ static void hpet_realize(DeviceState *dev, Error **errp)
 int i;
 HPETTimer *timer;
 
+if (s->num_timers < HPET_MIN_TIMERS || s->num_timers > HPET_MAX_TIMERS) {
+error_setg(errp, "hpet.num_timers must be between %d and %d",
+   HPET_MIN_TIMERS, HPET_MAX_TIMERS);
+return;
+}
 if (!s->intcap) {
-warn_report("Hpet's intcap not initialized");
+error_setg(errp, "hpet.hpet-intcap not initialized");
+return;
 }
 if (hpet_fw_cfg.count == UINT8_MAX) {
 /* first instance */
@@ -698,7 +704,7 @@ static void hpet_realize(DeviceState *dev, Error **errp)
 }
 
 if (hpet_fw_cfg.count == 8) {
-error_setg(errp, "Only 8 instances of HPET is allowed");
+error_setg(errp, "Only 8 instances of HPET are allowed");
 return;
 }
 
@@ -708,11 +714,6 @@ static void hpet_realize(DeviceState *dev, Error **errp)
 sysbus_init_irq(sbd, &s->irqs[i]);
 }
 
-if (s->num_timers < HPET_MIN_TIMERS) {
-s->num_timers = HPET_MIN_TIMERS;
-} else if (s->num_timers > HPET_MAX_TIMERS) {
-s->num_timers = HPET_MAX_TIMERS;
-}
 for (i = 0; i < HPET_MAX_TIMERS; i++) {
 timer = &s->timer[i];
 timer->qemu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, hpet_timer, 
timer);
-- 
2.49.0