Skip to contentSkip to conversation

add QMP command to reset rtc interrupt backlog (v4)

PATCH Superseded [email protected] 4 participants 7 messages Jun 4, 2014 – Jun 17, 2014

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

cover add QMP command to reset rtc interrupt backlog (v4)

v4: fix command name,
correct english (Eric Blake)
add object_property_add_alias (Paolo)

---

It is necessary to reset RTC interrupt backlog if guest time is synchronized via a different mechanism, such as QGA's guest-set-time command.

Failing to do so causes both corrections to be applied (summed), resulting in an incorrect guest time.

#1 lore raw

PATCH 1/3 mc146818rtc: add rtc-reset-reinjection QMP command

It is necessary to reset RTC interrupt reinjection backlog if guest time is synchronized via a different mechanism, such as QGA's guest-set-time command.

Failing to do so causes both corrections to be applied (summed), resulting in an incorrect guest time.

---
 hw/timer/mc146818rtc.c |   22 ++++++++++++++++++++++
 qapi-schema.json       |   12 ++++++++++++
 qmp-commands.hx        |   23 +++++++++++++++++++++++
 3 files changed, 57 insertions(+)
hw/timer/mc146818rtc.c +22 -0
Index: qemu/hw/timer/mc146818rtc.c
===================================================================
@@ -26,6 +26,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/timer/mc146818rtc.h"
 #include "qapi/visitor.h"
+#include "qmp-commands.h"
 
 #ifdef TARGET_I386
 #include "hw/i386/apic.h"
@@ -84,6 +85,9 @@
     Notifier clock_reset_notifier;
     LostTickPolicy lost_tick_policy;
     Notifier suspend_notifier;
+#ifdef TARGET_I386
+    QLIST_ENTRY(RTCState) link;
+#endif
 } RTCState;
 
 static void rtc_set_time(RTCState *s);
@@ -522,6 +526,20 @@
         rtc_from_bcd(s, s->cmos_data[RTC_CENTURY]) * 100 - 1900;
 }
 
+#ifdef TARGET_I386
+static QLIST_HEAD(, RTCState) rtc_devices =
+    QLIST_HEAD_INITIALIZER(rtc_devices);
+
+void qmp_rtc_reset_reinjection(Error **errp)
+{
+    RTCState *s;
+
+    QLIST_FOREACH(s, &rtc_devices, link) {
+        s->irq_coalesced = 0;
+    }
+}
+#endif
+
 static void rtc_set_time(RTCState *s)
 {
     struct tm tm;
@@ -911,6 +929,10 @@
     } else {
         isa_init_irq(isadev, &s->irq, RTC_ISA_IRQ);
     }
+#ifdef TARGET_I386
+    QLIST_INSERT_HEAD(&rtc_devices, s, link);
+#endif
+
     return isadev;
 }
 
qapi-schema.json +12 -0
Index: qemu/qapi-schema.json
===================================================================
@@ -4722,3 +4722,15 @@
               'btn'     : 'InputBtnEvent',
               'rel'     : 'InputMoveEvent',
               'abs'     : 'InputMoveEvent' } }
+
+##
+# @rtc-reset-reinjection
+#
+# This command will reset the RTC interrupt reinjection backlog.
+# Can be used if another mechanism to synchronize guest time
+# is in effect, for example QEMU guest agent's guest-set-time
+# command.
+#
+# Since: 2.1
+##
+{ 'command': 'rtc-reset-reinjection' }
qmp-commands.hx +23 -0
Index: qemu/qmp-commands.hx
===================================================================
@@ -3572,3 +3572,26 @@
                    } } ] }
 
 EQMP
+
+#if defined (TARGET_I386)
+    {
+        .name       = "rtc-reset-reinjection",
+        .args_type  = "",
+        .mhandler.cmd_new = qmp_marshal_input_rtc_reset_reinjection,
+    },
+#endif
+
+SQMP
+rtc-reset-reinjection
+---------------------
+
+Reset the RTC interrupt reinjection backlog.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "rtc-reset-reinjection" }
+<- { "return": {} }
+
+EQMP
#2 lore raw

Re: [Qemu-devel] [patch 1/3] mc146818rtc: add rtc-reset-reinjection QMP command

Quoted 28 lines · On Wed, Jun 04, 2014 at 02:52:01PM -0300, [email protected] wrote:

It is necessary to reset RTC interrupt reinjection backlog if guest time is synchronized via a different mechanism, such as QGA's guest-set-time command.

Failing to do so causes both corrections to be applied (summed), resulting in an incorrect guest time.

---
 hw/timer/mc146818rtc.c |   22 ++++++++++++++++++++++
 qapi-schema.json       |   12 ++++++++++++
 qmp-commands.hx        |   23 +++++++++++++++++++++++
 3 files changed, 57 insertions(+)

Index: qemu/hw/timer/mc146818rtc.c
===================================================================

hw/timer/mc146818rtc.c +1 -0
@@ -26,6 +26,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/timer/mc146818rtc.h"
 #include "qapi/visitor.h"
+#include "qmp-commands.h"
 
 #ifdef TARGET_I386
 #include "hw/i386/apic.h"

hw/timer/mc146818rtc.c line 90

Quoted 6 lines
hw/timer/mc146818rtc.c +3 -0
@@ -84,6 +85,9 @@
     Notifier clock_reset_notifier;
     LostTickPolicy lost_tick_policy;
     Notifier suspend_notifier;
+#ifdef TARGET_I386
+    QLIST_ENTRY(RTCState) link;
+#endif

Could we avoid these ifdefs?
I'd rather maintain the link unconditionally,
even if it's unused except on x86.

Quoted 88 lines
hw/timer/mc146818rtc.c +18 -0
 } RTCState;
 
 static void rtc_set_time(RTCState *s);
@@ -522,6 +526,20 @@
         rtc_from_bcd(s, s->cmos_data[RTC_CENTURY]) * 100 - 1900;
 }
 
+#ifdef TARGET_I386
+static QLIST_HEAD(, RTCState) rtc_devices =
+    QLIST_HEAD_INITIALIZER(rtc_devices);
+
+void qmp_rtc_reset_reinjection(Error **errp)
+{
+    RTCState *s;
+
+    QLIST_FOREACH(s, &rtc_devices, link) {
+        s->irq_coalesced = 0;
+    }
+}
+#endif
+
 static void rtc_set_time(RTCState *s)
 {
     struct tm tm;
@@ -911,6 +929,10 @@
     } else {
         isa_init_irq(isadev, &s->irq, RTC_ISA_IRQ);
     }
+#ifdef TARGET_I386
+    QLIST_INSERT_HEAD(&rtc_devices, s, link);
+#endif
+
     return isadev;
 }
 

Index: qemu/qapi-schema.json
===================================================================

qapi-schema.json +12 -0
@@ -4722,3 +4722,15 @@
               'btn'     : 'InputBtnEvent',
               'rel'     : 'InputMoveEvent',
               'abs'     : 'InputMoveEvent' } }
+
+##
+# @rtc-reset-reinjection
+#
+# This command will reset the RTC interrupt reinjection backlog.
+# Can be used if another mechanism to synchronize guest time
+# is in effect, for example QEMU guest agent's guest-set-time
+# command.
+#
+# Since: 2.1
+##
+{ 'command': 'rtc-reset-reinjection' }

Index: qemu/qmp-commands.hx
===================================================================

qmp-commands.hx +23 -0
@@ -3572,3 +3572,26 @@
                    } } ] }
 
 EQMP
+
+#if defined (TARGET_I386)
+    {
+        .name       = "rtc-reset-reinjection",
+        .args_type  = "",
+        .mhandler.cmd_new = qmp_marshal_input_rtc_reset_reinjection,
+    },
+#endif
+
+SQMP
+rtc-reset-reinjection
+---------------------
+
+Reset the RTC interrupt reinjection backlog.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "rtc-reset-reinjection" }
+<- { "return": {} }
+
+EQMP
Reviewed-by on v1 1/3
#3 lore raw

Re: [Qemu-devel] [patch 1/3] mc146818rtc: add rtc-reset-reinjection QMP command

In reply to [email protected]
Quoted 7 lines · On 06/04/2014 11:52 AM, [email protected] wrote:

It is necessary to reset RTC interrupt reinjection backlog if guest time is synchronized via a different mechanism, such as QGA's guest-set-time command.

Failing to do so causes both corrections to be applied (summed), resulting in an incorrect guest time.

Quoted 7 lines
---
 hw/timer/mc146818rtc.c |   22 ++++++++++++++++++++++
 qapi-schema.json       |   12 ++++++++++++
 qmp-commands.hx        |   23 +++++++++++++++++++++++
 3 files changed, 57 insertions(+)
Signature · 2 lines
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org
#4 lore raw

PATCH 2/3 add object_property_add_alias

In reply to [email protected]

Allowing addition of a link without keeping pointer-to-pointer.

---
 include/qom/object.h |   13 +++++++++
 qom/object.c         |   73 +++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 72 insertions(+), 14 deletions(-)
include/qom/object.h +13 -0
Index: qemu/include/qom/object.h
===================================================================
@@ -1073,6 +1073,19 @@
 } ObjectPropertyLinkFlags;
 
 /**
+ * object_property_add_alias:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @alias: the alias object
+ * @errp: if an error occurs, a pointer to an area to store the area
+ *
+ * Add a link under obj, named name, pointing to alias.
+ *
+ */
+void object_property_add_alias(Object *obj, const char *name,
+                               Object *alias, Error **errp);
+
+/**
  * object_property_allow_set_link:
  *
  * The default implementation of the object_property_add_link() check()
qom/object.c +59 -14

115 lines not on this page · raw message

#5 lore raw

Re: [Qemu-devel] [patch 2/3] add object_property_add_alias

Il 04/06/2014 19:52, [email protected] ha scritto:

Quoted 38 lines

Allowing addition of a link without keeping pointer-to-pointer.

---
 include/qom/object.h |   13 +++++++++
 qom/object.c         |   73 +++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 72 insertions(+), 14 deletions(-)

Index: qemu/include/qom/object.h
===================================================================

include/qom/object.h +13 -0
@@ -1073,6 +1073,19 @@
 } ObjectPropertyLinkFlags;
 
 /**
+ * object_property_add_alias:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @alias: the alias object
+ * @errp: if an error occurs, a pointer to an area to store the area
+ *
+ * Add a link under obj, named name, pointing to alias.
+ *
+ */
+void object_property_add_alias(Object *obj, const char *name,
+                               Object *alias, Error **errp);
+
+/**
  * object_property_allow_set_link:
  *
  * The default implementation of the object_property_add_link() check()

Index: qemu/qom/object.c
===================================================================

qom/object.c line 1028

Quoted 6 lines
qom/object.c +3 -0
@@ -1023,27 +1023,71 @@
     g_free(type);
 }
 
+typedef struct {
+    Object *child;
+    Object **childp;

These field names are ugly... not your fault, but perhaps

    Object **linkp;
    Object *alias_dest;

would be better. It would also avoid the mistake below:

qom/object.c line 1146

Quoted 9 lines
qom/object.c +1 -1
@@ -1096,7 +1140,7 @@
 {
     Error *local_err = NULL;
     LinkProperty *prop = opaque;
-    Object **child = prop->child;
+    Object **child = prop->childp;
     Object *old_target = *child;
     Object *new_target = NULL;
     char *path = NULL;

This is object_set_link_property. It writes *child but not prop->child, and subsequent calls to object_get_link_property incorrect.

However, since a similar need arose recently in one of Peter Crosthwaite's patches, let's add a generic resolve mechanism. I'll post a short series in a second, as soon as I finish testing it.

Paolo

Quoted 32 lines
qom/object.c +5 -4
@@ -1133,8 +1177,8 @@
 {
     LinkProperty *prop = opaque;
 
-    if ((prop->flags & OBJ_PROP_LINK_UNREF_ON_RELEASE) && *prop->child) {
-        object_unref(*prop->child);
+    if ((prop->flags & OBJ_PROP_LINK_UNREF_ON_RELEASE) && prop->child) {
+        object_unref(prop->child);
     }
     g_free(prop);
 }
@@ -1150,7 +1194,8 @@
     LinkProperty *prop = g_malloc(sizeof(*prop));
     gchar *full_type;
 
-    prop->child = child;
+    prop->childp = child;
+    prop->child = *child;
     prop->check = check;
     prop->flags = flags;
 
@@ -1227,7 +1272,7 @@
 
     if (object_property_is_link(prop)) {
         LinkProperty *lprop = prop->opaque;
-        return *lprop->child;
+        return lprop->child;
     } else if (object_property_is_child(prop)) {
         return prop->opaque;
     } else {
#6 lore raw

PATCH 3/3 mc146818rtc: add "rtc" link to "/machine"

In reply to [email protected]

Add a link to rtc under /machine providing a stable location for management apps to query "date" field.

{"execute":"qom-get","arguments":{"path":"/machine/rtc","property":"date"} }

Suggested by Paolo Bonzini.

---
 hw/timer/mc146818rtc.c |    9 +++++++++
 1 file changed, 9 insertions(+)
hw/timer/mc146818rtc.c +9 -0
Index: qemu/hw/timer/mc146818rtc.c
===================================================================
@@ -911,6 +911,9 @@
 
     object_property_add(OBJECT(s), "date", "struct tm",
                         rtc_get_date, NULL, NULL, s, NULL);
+
+    object_property_add_alias(qdev_get_machine(), "rtc", OBJECT(s),
+                              &error_abort);
 }
 
 ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
@@ -954,11 +957,17 @@
     dc->cannot_instantiate_with_device_add_yet = true;
 }
 
+static void rtc_finalize(Object *obj)
+{
+    object_property_del(qdev_get_machine(), "rtc", NULL);
+}
+
 static const TypeInfo mc146818rtc_info = {
     .name          = TYPE_MC146818_RTC,
     .parent        = TYPE_ISA_DEVICE,
     .instance_size = sizeof(RTCState),
     .class_init    = rtc_class_initfn,
+    .instance_finalize = rtc_finalize,
 };
 
 static void mc146818rtc_register_types(void)