All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] hw/rtc/mc146818rtc: Fix get_guest_rtc_ns() overflow bug
@ 2026-01-14  1:32 Jinjie Ruan
  2026-03-18  7:03 ` Jinjie Ruan
  2026-05-11  7:06 ` Paolo Bonzini
  0 siblings, 2 replies; 8+ messages in thread
From: Jinjie Ruan @ 2026-01-14  1:32 UTC (permalink / raw)
  To: peter.maydell, mst, pbonzini, qemu-devel; +Cc: ruanjinjie

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 <ruanjinjie@huawei.com>
---
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;
-- 
2.34.1



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

end of thread, other threads:[~2026-05-11 10:27 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-14  1:32 [PATCH v2] hw/rtc/mc146818rtc: Fix get_guest_rtc_ns() overflow bug Jinjie Ruan
2026-03-18  7:03 ` Jinjie Ruan
2026-04-22  3:07   ` Jinjie Ruan
2026-04-30 12:53     ` Peter Maydell
2026-05-11  3:10       ` Jinjie Ruan
2026-05-11  7:06 ` Paolo Bonzini
2026-05-11 10:22   ` Philippe Mathieu-Daudé
2026-05-11 10:27   ` Daniel P. Berrangé

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.