yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
05bba0
From 6fa144cedf0719b284355c9cd13ea6ec9a7c26d4 Mon Sep 17 00:00:00 2001
05bba0
From: Marcelo Tosatti <mtosatti@redhat.com>
05bba0
Date: Fri, 28 Aug 2015 01:07:55 +0200
05bba0
Subject: [PATCH] mc146818rtc: add rtc-reset-reinjection QMP command
05bba0
05bba0
Message-id: <20150828010755.GA11313@amt.cnet>
05bba0
Patchwork-id: 67629
05bba0
O-Subject: [RHEL-7.2 qemu-kvm PATCH] mc146818rtc: add rtc-reset-reinjection QMP command
05bba0
Bugzilla: 1191226
05bba0
RH-Acked-by: Juan Quintela <quintela@redhat.com>
05bba0
RH-Acked-by: Amit Shah <amit.shah@redhat.com>
05bba0
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
05bba0
05bba0
Without this command libvirt refuses to allow guest agent
05bba0
time synchronization to function.
05bba0
05bba0
Upstream commit f2ae8abf1fa003e7ec6ee22cc3871924422a01d0
05bba0
05bba0
It is necessary to reset RTC interrupt reinjection backlog if
05bba0
guest time is synchronized via a different mechanism, such as
05bba0
QGA's guest-set-time command.
05bba0
05bba0
Failing to do so causes both corrections to be applied (summed),
05bba0
resulting in an incorrect guest time.
05bba0
05bba0
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
05bba0
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
05bba0
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
05bba0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
05bba0
---
05bba0
 hw/timer/mc146818rtc.c | 18 ++++++++++++++++++
05bba0
 monitor.c              |  7 +++++++
05bba0
 qapi-schema.json       | 13 +++++++++++++
05bba0
 qmp-commands.hx        | 23 +++++++++++++++++++++++
05bba0
 4 files changed, 61 insertions(+)
05bba0
05bba0
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
05bba0
index 432b16c..083f573 100644
05bba0
--- a/hw/timer/mc146818rtc.c
05bba0
+++ b/hw/timer/mc146818rtc.c
05bba0
@@ -26,6 +26,7 @@
05bba0
 #include "sysemu/sysemu.h"
05bba0
 #include "hw/timer/mc146818rtc.h"
05bba0
 #include "qapi/visitor.h"
05bba0
+#include "qmp-commands.h"
05bba0
 
05bba0
 #ifdef TARGET_I386
05bba0
 #include "hw/i386/apic.h"
05bba0
@@ -85,6 +86,7 @@ typedef struct RTCState {
05bba0
     Notifier clock_reset_notifier;
05bba0
     LostTickPolicy lost_tick_policy;
05bba0
     Notifier suspend_notifier;
05bba0
+    QLIST_ENTRY(RTCState) link;
05bba0
 } RTCState;
05bba0
 
05bba0
 static void rtc_set_time(RTCState *s);
05bba0
@@ -529,6 +531,20 @@ static void rtc_get_time(RTCState *s, struct tm *tm)
05bba0
         rtc_from_bcd(s, s->cmos_data[RTC_CENTURY]) * 100 - 1900;
05bba0
 }
05bba0
 
05bba0
+static QLIST_HEAD(, RTCState) rtc_devices =
05bba0
+    QLIST_HEAD_INITIALIZER(rtc_devices);
05bba0
+
05bba0
+#ifdef TARGET_I386
05bba0
+void qmp_rtc_reset_reinjection(Error **errp)
05bba0
+{
05bba0
+    RTCState *s;
05bba0
+
05bba0
+    QLIST_FOREACH(s, &rtc_devices, link) {
05bba0
+        s->irq_coalesced = 0;
05bba0
+    }
05bba0
+}
05bba0
+#endif
05bba0
+
05bba0
 static void rtc_set_time(RTCState *s)
05bba0
 {
05bba0
     struct tm tm;
05bba0
@@ -889,6 +905,8 @@ ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
05bba0
     } else {
05bba0
         isa_init_irq(isadev, &s->irq, RTC_ISA_IRQ);
05bba0
     }
05bba0
+    QLIST_INSERT_HEAD(&rtc_devices, s, link);
05bba0
+
05bba0
     return isadev;
05bba0
 }
05bba0
 
05bba0
diff --git a/monitor.c b/monitor.c
05bba0
index 798885d..6a1d06e 100644
05bba0
--- a/monitor.c
05bba0
+++ b/monitor.c
05bba0
@@ -4878,3 +4878,10 @@ QemuOptsList qemu_mon_opts = {
05bba0
         { /* end of list */ }
05bba0
     },
05bba0
 };
05bba0
+
05bba0
+#ifndef TARGET_I386
05bba0
+void qmp_rtc_reset_reinjection(Error **errp)
05bba0
+{
05bba0
+    error_set(errp, QERR_FEATURE_DISABLED, "rtc-reset-reinjection");
05bba0
+}
05bba0
+#endif
05bba0
diff --git a/qapi-schema.json b/qapi-schema.json
05bba0
index 8a7cf0b..c8732c1 100644
05bba0
--- a/qapi-schema.json
05bba0
+++ b/qapi-schema.json
05bba0
@@ -4213,3 +4213,16 @@
05bba0
 ##
05bba0
 { 'command': 'query-rx-filter', 'data': { '*name': 'str' },
05bba0
   'returns': ['RxFilterInfo'] }
05bba0
+
05bba0
+##
05bba0
+# @rtc-reset-reinjection
05bba0
+#
05bba0
+# This command will reset the RTC interrupt reinjection backlog.
05bba0
+# Can be used if another mechanism to synchronize guest time
05bba0
+# is in effect, for example QEMU guest agent's guest-set-time
05bba0
+# command.
05bba0
+#
05bba0
+# Since: 2.1
05bba0
+##
05bba0
+{ 'command': 'rtc-reset-reinjection' }
05bba0
+
05bba0
diff --git a/qmp-commands.hx b/qmp-commands.hx
05bba0
index 44dd48e..22a09be 100644
05bba0
--- a/qmp-commands.hx
05bba0
+++ b/qmp-commands.hx
05bba0
@@ -3341,3 +3341,26 @@ Example:
05bba0
    }
05bba0
 
05bba0
 EQMP
05bba0
+
05bba0
+#if defined TARGET_I386
05bba0
+    {
05bba0
+        .name       = "rtc-reset-reinjection",
05bba0
+        .args_type  = "",
05bba0
+        .mhandler.cmd_new = qmp_marshal_input_rtc_reset_reinjection,
05bba0
+    },
05bba0
+#endif
05bba0
+
05bba0
+SQMP
05bba0
+rtc-reset-reinjection
05bba0
+---------------------
05bba0
+
05bba0
+Reset the RTC interrupt reinjection backlog.
05bba0
+
05bba0
+Arguments: None.
05bba0
+
05bba0
+Example:
05bba0
+
05bba0
+-> { "execute": "rtc-reset-reinjection" }
05bba0
+<- { "return": {} }
05bba0
+
05bba0
+EQMP
05bba0
-- 
05bba0
1.8.3.1
05bba0