qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH 0/3] pseries: Fix and extend PAPR RTC implementation
@ 2014-12-11  4:53 David Gibson
  2014-12-11  4:53 ` [Qemu-devel] [RFC PATCH 1/3] pseries: Move sPAPR RTC code into its own file David Gibson
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: David Gibson @ 2014-12-11  4:53 UTC (permalink / raw)
  To: agraf, aik, mdroth; +Cc: qemu-ppc, paulus, qemu-devel

At the moment, the PAPR RTC implementation (actually a paravirt
firmware interface, rather than a normal device) works directly off
host time, and so doesn't respect the options such as clock=vm which
can be specified in the -rtc command line option.

This series is a first cut at addressing this.  Caveats:

  * I haven't yet investigated how clock=vm will interact with
    migration.  I suspect badly.

  * We also use a time stamp when delivering RTAS events in
    spapr_events.c.  For now I haven't changed the code here which
    uses host time (via qemu_get_timedate()).  It's not entirely clear
    which clock these timestamps should be linked to.

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

* [Qemu-devel] [RFC PATCH 1/3] pseries: Move sPAPR RTC code into its own file
  2014-12-11  4:53 [Qemu-devel] [RFC PATCH 0/3] pseries: Fix and extend PAPR RTC implementation David Gibson
@ 2014-12-11  4:53 ` David Gibson
  2014-12-11  4:54 ` [Qemu-devel] [RFC PATCH 2/3] pseries: Add more parameter validation in RTAS time of day functions David Gibson
  2014-12-11  4:54 ` [Qemu-devel] [RFC PATCH 3/3] pseries: Make RTAS time of day functions respect -rtc options David Gibson
  2 siblings, 0 replies; 4+ messages in thread
From: David Gibson @ 2014-12-11  4:53 UTC (permalink / raw)
  To: agraf, aik, mdroth; +Cc: qemu-ppc, paulus, qemu-devel, David Gibson

At the moment the RTAS (firmware/hypervisor) time of day functions are
implemented in spapr_rtas.c along with a bunch of other things.  Since
we're going to be expanding these a bit, move the RTAS RTC related code
out into new file spapr_rtc.c.  Also add its own initialization function,
spapr_rtc_init() called from the main machine init routine.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/Makefile.objs   |  2 +-
 hw/ppc/spapr.c         |  3 ++
 hw/ppc/spapr_rtas.c    | 49 -----------------------------
 hw/ppc/spapr_rtc.c     | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/spapr.h |  1 +
 5 files changed, 88 insertions(+), 50 deletions(-)
 create mode 100644 hw/ppc/spapr_rtc.c

diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 19d9920..437955d 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -3,7 +3,7 @@ obj-y += ppc.o ppc_booke.o
 # IBM pSeries (sPAPR)
 obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o
 obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
-obj-$(CONFIG_PSERIES) += spapr_pci.o
+obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o
 ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
 obj-y += spapr_pci_vfio.o
 endif
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 30de25d..16377a3 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1446,6 +1446,9 @@ static void ppc_spapr_init(MachineState *machine)
     /* Set up EPOW events infrastructure */
     spapr_events_init(spapr);
 
+    /* Set up the RTC RTAS interfaces */
+    spapr_rtc_init();
+
     /* Set up VIO bus */
     spapr->vio_bus = spapr_vio_bus_init();
 
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 2ec2a8e..0f1ae55 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -52,51 +52,6 @@ static void rtas_display_character(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     }
 }
 
-static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
-                                 uint32_t token, uint32_t nargs,
-                                 target_ulong args,
-                                 uint32_t nret, target_ulong rets)
-{
-    struct tm tm;
-
-    if (nret != 8) {
-        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
-        return;
-    }
-
-    qemu_get_timedate(&tm, spapr->rtc_offset);
-
-    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
-    rtas_st(rets, 1, tm.tm_year + 1900);
-    rtas_st(rets, 2, tm.tm_mon + 1);
-    rtas_st(rets, 3, tm.tm_mday);
-    rtas_st(rets, 4, tm.tm_hour);
-    rtas_st(rets, 5, tm.tm_min);
-    rtas_st(rets, 6, tm.tm_sec);
-    rtas_st(rets, 7, 0); /* we don't do nanoseconds */
-}
-
-static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
-                                 uint32_t token, uint32_t nargs,
-                                 target_ulong args,
-                                 uint32_t nret, target_ulong rets)
-{
-    struct tm tm;
-
-    tm.tm_year = rtas_ld(args, 0) - 1900;
-    tm.tm_mon = rtas_ld(args, 1) - 1;
-    tm.tm_mday = rtas_ld(args, 2);
-    tm.tm_hour = rtas_ld(args, 3);
-    tm.tm_min = rtas_ld(args, 4);
-    tm.tm_sec = rtas_ld(args, 5);
-
-    /* Just generate a monitor event for the change */
-    qapi_event_send_rtc_change(qemu_timedate_diff(&tm), &error_abort);
-    spapr->rtc_offset = qemu_timedate_diff(&tm);
-
-    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
-}
-
 static void rtas_power_off(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                            uint32_t token, uint32_t nargs, target_ulong args,
                            uint32_t nret, target_ulong rets)
@@ -400,10 +355,6 @@ static void core_rtas_register_types(void)
 {
     spapr_rtas_register(RTAS_DISPLAY_CHARACTER, "display-character",
                         rtas_display_character);
-    spapr_rtas_register(RTAS_GET_TIME_OF_DAY, "get-time-of-day",
-                        rtas_get_time_of_day);
-    spapr_rtas_register(RTAS_SET_TIME_OF_DAY, "set-time-of-day",
-                        rtas_set_time_of_day);
     spapr_rtas_register(RTAS_POWER_OFF, "power-off", rtas_power_off);
     spapr_rtas_register(RTAS_SYSTEM_REBOOT, "system-reboot",
                         rtas_system_reboot);
diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c
new file mode 100644
index 0000000..e290ac0
--- /dev/null
+++ b/hw/ppc/spapr_rtc.c
@@ -0,0 +1,83 @@
+/*
+ * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
+ *
+ * RTAS Real Time Clock
+ *
+ * Copyright (c) 2010-2011 David Gibson, IBM Corporation.
+ * Copyright 2014 David Gibson, Red Hat.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+#include "cpu.h"
+#include "hw/ppc/spapr.h"
+#include "qapi-event.h"
+
+static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+                                 uint32_t token, uint32_t nargs,
+                                 target_ulong args,
+                                 uint32_t nret, target_ulong rets)
+{
+    struct tm tm;
+
+    if (nret != 8) {
+        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+        return;
+    }
+
+    qemu_get_timedate(&tm, spapr->rtc_offset);
+
+    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+    rtas_st(rets, 1, tm.tm_year + 1900);
+    rtas_st(rets, 2, tm.tm_mon + 1);
+    rtas_st(rets, 3, tm.tm_mday);
+    rtas_st(rets, 4, tm.tm_hour);
+    rtas_st(rets, 5, tm.tm_min);
+    rtas_st(rets, 6, tm.tm_sec);
+    rtas_st(rets, 7, 0); /* we don't do nanoseconds */
+}
+
+static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+                                 uint32_t token, uint32_t nargs,
+                                 target_ulong args,
+                                 uint32_t nret, target_ulong rets)
+{
+    struct tm tm;
+
+    tm.tm_year = rtas_ld(args, 0) - 1900;
+    tm.tm_mon = rtas_ld(args, 1) - 1;
+    tm.tm_mday = rtas_ld(args, 2);
+    tm.tm_hour = rtas_ld(args, 3);
+    tm.tm_min = rtas_ld(args, 4);
+    tm.tm_sec = rtas_ld(args, 5);
+
+    /* Just generate a monitor event for the change */
+    qapi_event_send_rtc_change(qemu_timedate_diff(&tm), &error_abort);
+    spapr->rtc_offset = qemu_timedate_diff(&tm);
+
+    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+}
+
+void spapr_rtc_init(void)
+{
+    spapr_rtas_register(RTAS_GET_TIME_OF_DAY, "get-time-of-day",
+                        rtas_get_time_of_day);
+    spapr_rtas_register(RTAS_SET_TIME_OF_DAY, "set-time-of-day",
+                        rtas_set_time_of_day);
+}
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 749daf4..9a468bc 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -479,5 +479,6 @@ int spapr_dma_dt(void *fdt, int node_off, const char *propname,
                  uint32_t liobn, uint64_t window, uint32_t size);
 int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname,
                       sPAPRTCETable *tcet);
+void spapr_rtc_init(void);
 
 #endif /* !defined (__HW_SPAPR_H__) */
-- 
2.1.0

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

* [Qemu-devel] [RFC PATCH 2/3] pseries: Add more parameter validation in RTAS time of day functions
  2014-12-11  4:53 [Qemu-devel] [RFC PATCH 0/3] pseries: Fix and extend PAPR RTC implementation David Gibson
  2014-12-11  4:53 ` [Qemu-devel] [RFC PATCH 1/3] pseries: Move sPAPR RTC code into its own file David Gibson
@ 2014-12-11  4:54 ` David Gibson
  2014-12-11  4:54 ` [Qemu-devel] [RFC PATCH 3/3] pseries: Make RTAS time of day functions respect -rtc options David Gibson
  2 siblings, 0 replies; 4+ messages in thread
From: David Gibson @ 2014-12-11  4:54 UTC (permalink / raw)
  To: agraf, aik, mdroth; +Cc: qemu-ppc, paulus, qemu-devel, David Gibson

Currently, the RTAS time of day functions only partially validate the
number of parameters they receive and return.  Because of how the
parameters are used, this is unlikely to lead to a crash, but it's messy.

This patch adds the missing checks.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_rtc.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c
index e290ac0..13eeab8 100644
--- a/hw/ppc/spapr_rtc.c
+++ b/hw/ppc/spapr_rtc.c
@@ -36,7 +36,7 @@ static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 {
     struct tm tm;
 
-    if (nret != 8) {
+    if ((nargs != 0) || (nret != 8)) {
         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
         return;
     }
@@ -60,6 +60,11 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 {
     struct tm tm;
 
+    if ((nargs != 7) || (nret != 1)) {
+        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+        return;
+    }
+
     tm.tm_year = rtas_ld(args, 0) - 1900;
     tm.tm_mon = rtas_ld(args, 1) - 1;
     tm.tm_mday = rtas_ld(args, 2);
-- 
2.1.0

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

* [Qemu-devel] [RFC PATCH 3/3] pseries: Make RTAS time of day functions respect -rtc options
  2014-12-11  4:53 [Qemu-devel] [RFC PATCH 0/3] pseries: Fix and extend PAPR RTC implementation David Gibson
  2014-12-11  4:53 ` [Qemu-devel] [RFC PATCH 1/3] pseries: Move sPAPR RTC code into its own file David Gibson
  2014-12-11  4:54 ` [Qemu-devel] [RFC PATCH 2/3] pseries: Add more parameter validation in RTAS time of day functions David Gibson
@ 2014-12-11  4:54 ` David Gibson
  2 siblings, 0 replies; 4+ messages in thread
From: David Gibson @ 2014-12-11  4:54 UTC (permalink / raw)
  To: agraf, aik, mdroth; +Cc: qemu-ppc, paulus, qemu-devel, David Gibson

In the 'pseries' machine the real time clock is provided by a
paravirtualized firmware interface rather than a device per se; the RTAS
get-time-of-day and set-time-of-day calls.

Out current implementations of those work directly off host time (with
an offset), not respecting options such as clock=vm which can be
specified in the -rtc command line option.

This patch reworks the RTAS RTC code to respect those options, primarily
by basing them on the qemu_clock_get_ns(rtc_clock) function instead of
directly on qemu_get_timedate() (which essentially handles host time, not
virtual rtc time).

As a bonus, this means our get-time-of-day function now also returns
nanoseconds.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_rtc.c | 36 ++++++++++++++++++++++++++++++++----
 1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c
index 13eeab8..58715d2 100644
--- a/hw/ppc/spapr_rtc.c
+++ b/hw/ppc/spapr_rtc.c
@@ -26,6 +26,7 @@
  *
  */
 #include "cpu.h"
+#include "sysemu/sysemu.h"
 #include "hw/ppc/spapr.h"
 #include "qapi-event.h"
 
@@ -35,13 +36,18 @@ static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                                  uint32_t nret, target_ulong rets)
 {
     struct tm tm;
+    int64_t host_ns;
+    time_t guest_s;
 
     if ((nargs != 0) || (nret != 8)) {
         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
         return;
     }
 
-    qemu_get_timedate(&tm, spapr->rtc_offset);
+    host_ns = qemu_clock_get_ns(rtc_clock);
+
+    guest_s = host_ns / 1000000000LL + spapr->rtc_offset;
+    gmtime_r(&guest_s, &tm);
 
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
     rtas_st(rets, 1, tm.tm_year + 1900);
@@ -50,7 +56,7 @@ static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     rtas_st(rets, 4, tm.tm_hour);
     rtas_st(rets, 5, tm.tm_min);
     rtas_st(rets, 6, tm.tm_sec);
-    rtas_st(rets, 7, 0); /* we don't do nanoseconds */
+    rtas_st(rets, 7, host_ns % 1000000000LL);
 }
 
 static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
@@ -59,6 +65,8 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                                  uint32_t nret, target_ulong rets)
 {
     struct tm tm;
+    time_t new_s;
+    int64_t host_ns;
 
     if ((nargs != 7) || (nret != 1)) {
         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
@@ -72,15 +80,35 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     tm.tm_min = rtas_ld(args, 4);
     tm.tm_sec = rtas_ld(args, 5);
 
-    /* Just generate a monitor event for the change */
+    new_s = mktimegm(&tm);
+    if (new_s == -1) {
+        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+        return;
+    }
+
+    /* Generate a monitor event for the change */
     qapi_event_send_rtc_change(qemu_timedate_diff(&tm), &error_abort);
-    spapr->rtc_offset = qemu_timedate_diff(&tm);
+
+    host_ns = qemu_clock_get_ns(rtc_clock);
+
+    spapr->rtc_offset = new_s - host_ns / 1000000000L;
 
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 
 void spapr_rtc_init(void)
 {
+    struct tm tm;
+    time_t host_s;
+    int64_t rtc_ns;
+
+    /* Initialize the RTAS RTC from host time */
+
+    qemu_get_timedate(&tm, 0);
+    host_s = mktimegm(&tm);
+    rtc_ns = qemu_clock_get_ns(rtc_clock);
+    spapr->rtc_offset = host_s - rtc_ns / 1000000000LL;
+
     spapr_rtas_register(RTAS_GET_TIME_OF_DAY, "get-time-of-day",
                         rtas_get_time_of_day);
     spapr_rtas_register(RTAS_SET_TIME_OF_DAY, "set-time-of-day",
-- 
2.1.0

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

end of thread, other threads:[~2014-12-11  4:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-11  4:53 [Qemu-devel] [RFC PATCH 0/3] pseries: Fix and extend PAPR RTC implementation David Gibson
2014-12-11  4:53 ` [Qemu-devel] [RFC PATCH 1/3] pseries: Move sPAPR RTC code into its own file David Gibson
2014-12-11  4:54 ` [Qemu-devel] [RFC PATCH 2/3] pseries: Add more parameter validation in RTAS time of day functions David Gibson
2014-12-11  4:54 ` [Qemu-devel] [RFC PATCH 3/3] pseries: Make RTAS time of day functions respect -rtc options David Gibson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).