From f1a0144e14047df597753db661defa116f72f177 Mon Sep 17 00:00:00 2001 From: Zhuocheng Ding Date: Fri, 11 Sep 2020 09:55:48 +0800 Subject: [PATCH 1/2] Add RTC alarm syncing support to host QEMU This allows QMP clients to implement RTC alarm syncing from guest to host. Tracked-On: OAM-100921 Signed-off-by: Zhuocheng Ding Signed-off-by: Swee Yee Fonn --- ...-mc146818rtc-add-RTC_ALARM-QMP-event.patch | 72 +++++++++++++++++++ ...tc-add-rtc-refresh-timer-QMP-command.patch | 68 ++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 host/qemu/0002-mc146818rtc-add-RTC_ALARM-QMP-event.patch create mode 100644 host/qemu/0003-mc146818rtc-add-rtc-refresh-timer-QMP-command.patch diff --git a/host/qemu/0002-mc146818rtc-add-RTC_ALARM-QMP-event.patch b/host/qemu/0002-mc146818rtc-add-RTC_ALARM-QMP-event.patch new file mode 100644 index 0000000000..00e05c2ab7 --- /dev/null +++ b/host/qemu/0002-mc146818rtc-add-RTC_ALARM-QMP-event.patch @@ -0,0 +1,72 @@ +From 2eb9f2c0850c0e92877b0e8db7e8173bea5f584e Mon Sep 17 00:00:00 2001 +From: Zhuocheng Ding +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 +--- + 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 + diff --git a/host/qemu/0003-mc146818rtc-add-rtc-refresh-timer-QMP-command.patch b/host/qemu/0003-mc146818rtc-add-rtc-refresh-timer-QMP-command.patch new file mode 100644 index 0000000000..63978d3159 --- /dev/null +++ b/host/qemu/0003-mc146818rtc-add-rtc-refresh-timer-QMP-command.patch @@ -0,0 +1,68 @@ +From 3f588e6de9c64225ca7f3d2df4e2e46e72ab8dc9 Mon Sep 17 00:00:00 2001 +From: Zhuocheng Ding +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 +--- + 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 + From 9bb08c79f36d6de52ac451fa656cd6476c3eca8a Mon Sep 17 00:00:00 2001 From: Zhuo Peng Date: Tue, 19 Jan 2021 20:31:56 +0800 Subject: [PATCH 2/2] Add 'mc146818rtc.external_wakeup' option for qemu Add "mc146818rtc.external_wakeup" for qemu. When this option is on, Qemu doesn't keep it's own RTC timer to wake up guest. It will relay on host to send wakeup guest cmd to wakeup guest. Tracked-On: OAM-100922 Signed-off-by: Zhuo Peng Signed-off-by: Swee Yee Fonn --- ...external-wakeup-mode-to-sync-guest-w.patch | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 host/qemu/0010-mc146818rtc-add-external-wakeup-mode-to-sync-guest-w.patch diff --git a/host/qemu/0010-mc146818rtc-add-external-wakeup-mode-to-sync-guest-w.patch b/host/qemu/0010-mc146818rtc-add-external-wakeup-mode-to-sync-guest-w.patch new file mode 100644 index 0000000000..7b788ee86d --- /dev/null +++ b/host/qemu/0010-mc146818rtc-add-external-wakeup-mode-to-sync-guest-w.patch @@ -0,0 +1,72 @@ +From d4f3baf8936d947b4f45f8a2074825ef09da35e9 Mon Sep 17 00:00:00 2001 +From: Zhuocheng Ding +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 +