Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Host rtc sync #1362

Open
wants to merge 2 commits into
base: celadon/r/mr0/stable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions host/qemu/0002-mc146818rtc-add-RTC_ALARM-QMP-event.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
From 2eb9f2c0850c0e92877b0e8db7e8173bea5f584e Mon Sep 17 00:00:00 2001
From: Zhuocheng Ding <[email protected]>
Date: Fri, 11 Sep 2020 09:14:30 +0800
Subject: [PATCH] mc146818rtc: add RTC_ALARM QMP event

Emitted whenever the RTC alarm expire time changes.

Tracked-On: OAM-92864
Signed-off-by: Zhuocheng Ding <[email protected]>
---
hw/rtc/mc146818rtc.c | 7 ++++++-
qapi/misc-target.json | 18 ++++++++++++++++++
2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
index 74ae74bc5c..4db9e946d1 100644
--- a/hw/rtc/mc146818rtc.c
+++ b/hw/rtc/mc146818rtc.c
@@ -269,6 +269,7 @@ static void check_update_timer(RTCState *s)
{
uint64_t next_update_time;
uint64_t guest_nsec;
+ uint64_t next_alarm_time;
int next_alarm_sec;

/* From the data sheet: "Holding the dividers in reset prevents
@@ -289,8 +290,12 @@ static void check_update_timer(RTCState *s)
* for in next_update_time.
*/
next_alarm_sec = get_next_alarm(s);
- s->next_alarm_time = next_update_time +
+ next_alarm_time = next_update_time +
(next_alarm_sec - 1) * NANOSECONDS_PER_SECOND;
+ if (s->next_alarm_time != next_alarm_time) {
+ s->next_alarm_time = next_alarm_time;
+ qapi_event_send_rtc_alarm(s->next_alarm_time);
+ }

/* If update_in_progress latched the UIP bit, we must keep the timer
* programmed to the next second, so that UIP is cleared. Otherwise,
diff --git a/qapi/misc-target.json b/qapi/misc-target.json
index a00fd821eb..a92959d436 100644
--- a/qapi/misc-target.json
+++ b/qapi/misc-target.json
@@ -24,6 +24,24 @@
'data': { 'offset': 'int' },
'if': 'defined(TARGET_ALPHA) || defined(TARGET_ARM) || defined(TARGET_HPPA) || defined(TARGET_I386) || defined(TARGET_MIPS) || defined(TARGET_MIPS64) || defined(TARGET_MOXIE) || defined(TARGET_PPC) || defined(TARGET_PPC64) || defined(TARGET_S390X) || defined(TARGET_SH4) || defined(TARGET_SPARC)' }

+##
+# @RTC_ALARM:
+#
+# Emitted when the guest RTC alarm expire time changes.
+#
+# @expire: expire time of guest RTC alarm, measured in host realtime
+#
+# Example:
+#
+# <- { "event": "RTC_ALARM",
+# "data": { "expire": 1593499713567502000 },
+# "timestamp": { "seconds": 1593413313, "microseconds": 568267 } }
+#
+##
+{ 'event': 'RTC_ALARM',
+ 'data': { 'expire': 'int' },
+ 'if': 'defined(TARGET_I386)' }
+
##
# @rtc-reset-reinjection:
#
--
2.25.1

68 changes: 68 additions & 0 deletions host/qemu/0003-mc146818rtc-add-rtc-refresh-timer-QMP-command.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
From 3f588e6de9c64225ca7f3d2df4e2e46e72ab8dc9 Mon Sep 17 00:00:00 2001
From: Zhuocheng Ding <[email protected]>
Date: Fri, 11 Sep 2020 09:32:03 +0800
Subject: [PATCH] mc146818rtc: add rtc-refresh-timer QMP command

If host is suspended for a while, the timers in QEMU will not take the
time during suspension into account. This command will force QEMU to
recheck RTC timers, so that these timers will not be delayed.

Tracked-On: OAM-92864
Signed-off-by: Zhuocheng Ding <[email protected]>
---
hw/rtc/mc146818rtc.c | 6 ++++++
qapi/misc-target.json | 14 ++++++++++++++
2 files changed, 20 insertions(+)

diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
index 4db9e946d1..5ed0f7b100 100644
--- a/hw/rtc/mc146818rtc.c
+++ b/hw/rtc/mc146818rtc.c
@@ -45,6 +45,7 @@

#ifdef TARGET_I386
#include "qapi/qapi-commands-misc-target.h"
+#include "qemu/main-loop.h"
#include "hw/i386/apic.h"
#endif

@@ -119,6 +120,11 @@ void qmp_rtc_reset_reinjection(Error **errp)
}
}

+void qmp_rtc_refresh_timer(Error **errp)
+{
+ qemu_notify_event();
+}
+
static bool rtc_policy_slew_deliver_irq(RTCState *s)
{
apic_reset_irq_delivered();
diff --git a/qapi/misc-target.json b/qapi/misc-target.json
index a92959d436..04bdd52eca 100644
--- a/qapi/misc-target.json
+++ b/qapi/misc-target.json
@@ -61,6 +61,20 @@
{ 'command': 'rtc-reset-reinjection',
'if': 'defined(TARGET_I386)' }

+##
+# @rtc-refresh-timer:
+#
+# This command will refresh the RTC timers, so that the expired timers can
+# trigger their callbacks immediately.
+#
+# Example:
+#
+# -> { "execute": "rtc-refresh-timer" }
+# <- { "return": {} }
+#
+##
+{ 'command': 'rtc-refresh-timer',
+ 'if': 'defined(TARGET_I386)' }

##
# @SevState:
--
2.25.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
From d4f3baf8936d947b4f45f8a2074825ef09da35e9 Mon Sep 17 00:00:00 2001
From: Zhuocheng Ding <[email protected]>
Date: Wed, 13 Jan 2021 11:29:48 +0800
Subject: [PATCH] mc146818rtc: add external wakeup mode to sync guest wakeup
with host

---
hw/rtc/mc146818rtc.c | 14 ++++++++++++--
include/hw/rtc/mc146818rtc.h | 1 +
2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
index 5ed0f7b100..81f7152e27 100644
--- a/hw/rtc/mc146818rtc.c
+++ b/hw/rtc/mc146818rtc.c
@@ -79,6 +79,7 @@ static void rtc_update_time(RTCState *s);
static void rtc_set_cmos(RTCState *s, const struct tm *tm);
static inline int rtc_from_bcd(RTCState *s, int a);
static uint64_t get_next_alarm(RTCState *s);
+static void rtc_update_timer(void *opaque);

static inline bool rtc_running(RTCState *s)
{
@@ -122,7 +123,15 @@ void qmp_rtc_reset_reinjection(Error **errp)

void qmp_rtc_refresh_timer(Error **errp)
{
- qemu_notify_event();
+ RTCState *s;
+
+ QLIST_FOREACH(s, &rtc_devices, link) {
+ if (s->external_wakeup && (s->cmos_data[RTC_REG_B] & REG_B_AIE)) {
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_RTC, NULL);
+ } else if (!s->external_wakeup) {
+ qemu_notify_event();
+ }
+ }
}

static bool rtc_policy_slew_deliver_irq(RTCState *s)
@@ -443,7 +452,7 @@ static void rtc_update_timer(void *opaque)

if (qemu_clock_get_ns(rtc_clock) >= s->next_alarm_time) {
irqs |= REG_C_AF;
- if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
+ if (!s->external_wakeup && (s->cmos_data[RTC_REG_B] & REG_B_AIE)) {
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_RTC, NULL);
}
}
@@ -1005,6 +1014,7 @@ static Property mc146818rtc_properties[] = {
DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980),
DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", RTCState,
lost_tick_policy, LOST_TICK_POLICY_DISCARD),
+ DEFINE_PROP_BOOL("external_wakeup", RTCState, external_wakeup, false),
DEFINE_PROP_END_OF_LIST(),
};

diff --git a/include/hw/rtc/mc146818rtc.h b/include/hw/rtc/mc146818rtc.h
index 10c93a096a..75afc813b1 100644
--- a/include/hw/rtc/mc146818rtc.h
+++ b/include/hw/rtc/mc146818rtc.h
@@ -35,6 +35,7 @@ typedef struct RTCState {
int64_t next_periodic_time;
/* update-ended timer */
QEMUTimer *update_timer;
+ bool external_wakeup;
uint64_t next_alarm_time;
uint16_t irq_reinject_on_ack_count;
uint32_t irq_coalesced;
--
2.17.1

Loading