Gentle ping.

On 2026/1/14 9:32, Jinjie Ruan wrote:
> In get_guest_rtc_ns(), "s->base_rtc" is uint64_t, which multiplied by
> "NANOSECONDS_PER_SECOND" may overflow the uint64_t type, which will
> cause the QEMU Linux Virtual Machine's RTC time to jump and in turn
> triggers a kernel Soft Lockup and ultimately leads to a crash.
> 
> Fix it by avoiding adding s->base_rtc in get_guest_rtc_ns_offset(),
> because get_guest_rtc_ns() is used either take the remainder of
> NANOSECONDS_PER_SECOND or take the quotient of NANOSECONDS_PER_SECOND.
> 
> Fixes: 56038ef6234e ("RTC: Update the RTC clock only when reading it")
> Signed-off-by: Jinjie Ruan <[email protected]>
> ---
> v2:
> - Add comment for get_guest_rtc_ns().
> - Update the commit message.
> ---
>  hw/rtc/mc146818rtc.c | 15 +++++++--------
>  1 file changed, 7 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
> index 8631386b9f..36de30649c 100644
> --- a/hw/rtc/mc146818rtc.c
> +++ b/hw/rtc/mc146818rtc.c
> @@ -77,12 +77,13 @@ static inline bool rtc_running(MC146818RtcState *s)
>              (s->cmos_data[RTC_REG_A] & 0x70) <= 0x20);
>  }
>  
> +/*
> + * Note: get_guest_rtc_ns() does not include the "base_rtc" seconds value,
> + * so the caller "must" handle it themselves!!!
> + */
>  static uint64_t get_guest_rtc_ns(MC146818RtcState *s)
>  {
> -    uint64_t guest_clock = qemu_clock_get_ns(rtc_clock);
> -
> -    return s->base_rtc * NANOSECONDS_PER_SECOND +
> -        guest_clock - s->last_update + s->offset;
> +    return qemu_clock_get_ns(rtc_clock) - s->last_update + s->offset;
>  }
>  
>  static void rtc_coalesced_timer_update(MC146818RtcState *s)
> @@ -623,10 +624,8 @@ static void rtc_update_time(MC146818RtcState *s)
>  {
>      struct tm ret;
>      time_t guest_sec;
> -    int64_t guest_nsec;
>  
> -    guest_nsec = get_guest_rtc_ns(s);
> -    guest_sec = guest_nsec / NANOSECONDS_PER_SECOND;
> +    guest_sec = s->base_rtc + get_guest_rtc_ns(s) / NANOSECONDS_PER_SECOND;
>      gmtime_r(&guest_sec, &ret);
>  
>      /* Is SET flag of Register B disabled? */
> @@ -637,7 +636,7 @@ static void rtc_update_time(MC146818RtcState *s)
>  
>  static int update_in_progress(MC146818RtcState *s)
>  {
> -    int64_t guest_nsec;
> +    uint64_t guest_nsec;
>  
>      if (!rtc_running(s)) {
>          return 0;

Reply via email to