All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/3] wallclock time on arm
@ 2015-11-12 17:45 Stefano Stabellini
  2015-11-12 17:46 ` [PATCH v4 1/3] xen: move wallclock functions from x86 to common Stefano Stabellini
                   ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Stefano Stabellini @ 2015-11-12 17:45 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell, Stefano Stabellini

Hi all,

this small series enables the wallclock time on arm and it consists
mostly in code movement from x86 to common.

Now build tested with XSM_ENABLE=y.


Changes in v4:
- remove spurious change to ticks_to_ns
- move flask_platform_op out of ifdef CONFIG_X86
- move set_to_dummy_if_null out of ifdef CONFIG_X86 for platform_op
- dropped previous ack from Daniel
- add patch "move ticks conversions function declarations"

Changes in v3:
- remove stray blank lines
- move update_domain_wallclock_time() call to arch_domain_create
- move setting time_offset_seconds to domain_vtimer_init
- use spin_trylock(&xenpf_lock) loop in do_platform_op

Changes in v2:
- remove stray blank lines
- remove include <xen/config.h>
- move version_update_* to include/xen/time.h
- introduce ifdef to fix build issue in common/time.c
- define wc_sec and sec as uint64_t
- pass u64 to do_settime
- drop XENPF_settime32
- set time_offset_seconds
- modify xen/xsm/flask/hooks.c



Stefano Stabellini (3):
      xen: move wallclock functions from x86 to common
      arm: export platform_op XENPF_settime64
      xen/arm: move ticks conversions function declarations to the header file

 xen/arch/arm/Makefile             |    1 +
 xen/arch/arm/domain.c             |    2 +
 xen/arch/arm/platform_hypercall.c |   70 +++++++++++++++++++
 xen/arch/arm/time.c               |    5 --
 xen/arch/arm/traps.c              |    1 +
 xen/arch/arm/vtimer.c             |    6 +-
 xen/arch/x86/time.c               |   96 +------------------------
 xen/common/time.c                 |   95 ++++++++++++++++++++++++-
 xen/include/asm-arm/time.h        |    3 +
 xen/include/xen/time.h            |    5 +-
 xen/include/xsm/dummy.h           |   12 ++--
 xen/include/xsm/xsm.h             |   13 ++--
 xen/xsm/dummy.c                   |    2 +-
 xen/xsm/flask/hooks.c             |  140 ++++++++++++++++++-------------------
 14 files changed, 263 insertions(+), 188 deletions(-)
 create mode 100644 xen/arch/arm/platform_hypercall.c

Cheers,

Stefano

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

* [PATCH v4 1/3] xen: move wallclock functions from x86 to common
  2015-11-12 17:45 [PATCH v4 0/3] wallclock time on arm Stefano Stabellini
@ 2015-11-12 17:46 ` Stefano Stabellini
  2015-11-16 13:04   ` Ian Campbell
  2015-11-12 17:46 ` [PATCH v4 2/3] arm: export platform_op XENPF_settime64 Stefano Stabellini
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Stefano Stabellini @ 2015-11-12 17:46 UTC (permalink / raw)
  To: xen-devel; +Cc: andrew.cooper3, Ian.Campbell, JBeulich, Stefano Stabellini

Remove dummy arm implementation of wallclock_time.
Use shared_info() in common code rather than x86-ism to access it, when
possible.

Define the static variable wc_sec, and the local variale sec in
update_domain_wallclock_time, as uint64_t instead of unsigned long, to
avoid size issue on arm.
Take a uint64_t sec paramter in do_settime for the same reason.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
CC: JBeulich@suse.com
CC: andrew.cooper3@citrix.com

---

Changes in v3:
- remove stray blank lines

Changes in v2:
- remove stray blank lines
- remove include <xen/config.h>
- move version_update_* to include/xen/time.h
- introduce ifdef to fix build issue in common/time.c
- define wc_sec and sec as uint64_t
- pass u64 to do_settime
---
 xen/arch/arm/time.c    |    5 ---
 xen/arch/x86/time.c    |   96 +-----------------------------------------------
 xen/common/time.c      |   95 ++++++++++++++++++++++++++++++++++++++++++++++-
 xen/include/xen/time.h |    5 ++-
 4 files changed, 99 insertions(+), 102 deletions(-)

diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
index 5ded30c..6207615 100644
--- a/xen/arch/arm/time.c
+++ b/xen/arch/arm/time.c
@@ -280,11 +280,6 @@ void domain_set_time_offset(struct domain *d, int64_t time_offset_seconds)
     /* XXX update guest visible wallclock time */
 }
 
-struct tm wallclock_time(uint64_t *ns)
-{
-    return (struct tm) { 0 };
-}
-
 /*
  * Local variables:
  * mode: C
diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
index bbb7e6c..0f16db5 100644
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -47,9 +47,6 @@ string_param("clocksource", opt_clocksource);
 unsigned long __read_mostly cpu_khz;  /* CPU clock frequency in kHz. */
 DEFINE_SPINLOCK(rtc_lock);
 unsigned long pit0_ticks;
-static unsigned long wc_sec; /* UTC time at last 'time update'. */
-static unsigned int wc_nsec;
-static DEFINE_SPINLOCK(wc_lock);
 
 struct cpu_time {
     u64 local_tsc_stamp;
@@ -783,10 +780,6 @@ uint64_t tsc_ticks2ns(uint64_t ticks)
     return scale_delta(ticks, &t->tsc_scale);
 }
 
-/* Explicitly OR with 1 just in case version number gets out of sync. */
-#define version_update_begin(v) (((v)+1)|1)
-#define version_update_end(v)   ((v)+1)
-
 static void __update_vcpu_system_time(struct vcpu *v, int force)
 {
     struct cpu_time       *t;
@@ -900,37 +893,6 @@ void force_update_vcpu_system_time(struct vcpu *v)
     __update_vcpu_system_time(v, 1);
 }
 
-void update_domain_wallclock_time(struct domain *d)
-{
-    uint32_t *wc_version;
-    unsigned long sec;
-
-    spin_lock(&wc_lock);
-
-    wc_version = &shared_info(d, wc_version);
-    *wc_version = version_update_begin(*wc_version);
-    wmb();
-
-    sec = wc_sec + d->time_offset_seconds;
-    if ( likely(!has_32bit_shinfo(d)) )
-    {
-        d->shared_info->native.wc_sec    = sec;
-        d->shared_info->native.wc_nsec   = wc_nsec;
-        d->shared_info->native.wc_sec_hi = sec >> 32;
-    }
-    else
-    {
-        d->shared_info->compat.wc_sec         = sec;
-        d->shared_info->compat.wc_nsec        = wc_nsec;
-        d->shared_info->compat.arch.wc_sec_hi = sec >> 32;
-    }
-
-    wmb();
-    *wc_version = version_update_end(*wc_version);
-
-    spin_unlock(&wc_lock);
-}
-
 static void update_domain_rtc(void)
 {
     struct domain *d;
@@ -988,27 +950,6 @@ int cpu_frequency_change(u64 freq)
     return 0;
 }
 
-/* Set clock to <secs,usecs> after 00:00:00 UTC, 1 January, 1970. */
-void do_settime(unsigned long secs, unsigned int nsecs, u64 system_time_base)
-{
-    u64 x;
-    u32 y;
-    struct domain *d;
-
-    x = SECONDS(secs) + nsecs - system_time_base;
-    y = do_div(x, 1000000000);
-
-    spin_lock(&wc_lock);
-    wc_sec  = x;
-    wc_nsec = y;
-    spin_unlock(&wc_lock);
-
-    rcu_read_lock(&domlist_read_lock);
-    for_each_domain ( d )
-        update_domain_wallclock_time(d);
-    rcu_read_unlock(&domlist_read_lock);
-}
-
 /* Per-CPU communication between rendezvous IRQ and softirq handler. */
 struct cpu_calibration {
     u64 local_tsc_stamp;
@@ -1608,25 +1549,6 @@ void send_timer_event(struct vcpu *v)
     send_guest_vcpu_virq(v, VIRQ_TIMER);
 }
 
-/* Return secs after 00:00:00 localtime, 1 January, 1970. */
-unsigned long get_localtime(struct domain *d)
-{
-    return wc_sec + (wc_nsec + NOW()) / 1000000000ULL 
-        + d->time_offset_seconds;
-}
-
-/* Return microsecs after 00:00:00 localtime, 1 January, 1970. */
-uint64_t get_localtime_us(struct domain *d)
-{
-    return (SECONDS(wc_sec + d->time_offset_seconds) + wc_nsec + NOW())
-           / 1000UL;
-}
-
-unsigned long get_sec(void)
-{
-    return wc_sec + (wc_nsec + NOW()) / 1000000000ULL;
-}
-
 /* "cmos_utc_offset" is the difference between UTC time and CMOS time. */
 static long cmos_utc_offset; /* in seconds */
 
@@ -1635,7 +1557,7 @@ int time_suspend(void)
     if ( smp_processor_id() == 0 )
     {
         cmos_utc_offset = -get_cmos_time();
-        cmos_utc_offset += (wc_sec + (wc_nsec + NOW()) / 1000000000ULL);
+        cmos_utc_offset += get_sec();
         kill_timer(&calibration_timer);
 
         /* Sync platform timer stamps. */
@@ -1715,22 +1637,6 @@ int hwdom_pit_access(struct ioreq *ioreq)
     return 0;
 }
 
-struct tm wallclock_time(uint64_t *ns)
-{
-    uint64_t seconds, nsec;
-
-    if ( !wc_sec )
-        return (struct tm) { 0 };
-
-    seconds = NOW() + SECONDS(wc_sec) + wc_nsec;
-    nsec = do_div(seconds, 1000000000);
-
-    if ( ns )
-        *ns = nsec;
-
-    return gmtime(seconds);
-}
-
 /*
  * PV SoftTSC Emulation.
  */
diff --git a/xen/common/time.c b/xen/common/time.c
index 29fdf52..721ada8 100644
--- a/xen/common/time.c
+++ b/xen/common/time.c
@@ -15,8 +15,12 @@
  * along with this program; If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <xen/config.h>
+#include <xen/sched.h>
+#include <xen/shared.h>
+#include <xen/spinlock.h>
 #include <xen/time.h>
+#include <asm/div64.h>
+#include <asm/domain.h>
 
 /* Nonzero if YEAR is a leap year (every 4 years,
    except every 100th isn't, and every 400th is).  */
@@ -34,6 +38,10 @@ const unsigned short int __mon_lengths[2][12] = {
 #define SECS_PER_HOUR (60 * 60)
 #define SECS_PER_DAY  (SECS_PER_HOUR * 24)
 
+static uint64_t wc_sec; /* UTC time at last 'time update'. */
+static unsigned int wc_nsec;
+static DEFINE_SPINLOCK(wc_lock);
+
 struct tm gmtime(unsigned long t)
 {
     struct tm tbuf;
@@ -85,3 +93,88 @@ struct tm gmtime(unsigned long t)
 
     return tbuf;
 }
+
+void update_domain_wallclock_time(struct domain *d)
+{
+    uint32_t *wc_version;
+    uint64_t sec;
+
+    spin_lock(&wc_lock);
+
+    wc_version = &shared_info(d, wc_version);
+    *wc_version = version_update_begin(*wc_version);
+    wmb();
+
+    sec = wc_sec + d->time_offset_seconds;
+    shared_info(d, wc_sec)    = sec;
+    shared_info(d, wc_nsec)   = wc_nsec;
+#ifdef CONFIG_X86
+    if ( likely(!has_32bit_shinfo(d)) )
+        d->shared_info->native.wc_sec_hi = sec >> 32;
+    else
+        d->shared_info->compat.arch.wc_sec_hi = sec >> 32;
+#else
+    shared_info(d, wc_sec_hi) = sec >> 32;
+#endif
+
+    wmb();
+    *wc_version = version_update_end(*wc_version);
+
+    spin_unlock(&wc_lock);
+}
+
+/* Set clock to <secs,usecs> after 00:00:00 UTC, 1 January, 1970. */
+void do_settime(u64 secs, unsigned int nsecs, u64 system_time_base)
+{
+    u64 x;
+    u32 y;
+    struct domain *d;
+
+    x = SECONDS(secs) + nsecs - system_time_base;
+    y = do_div(x, 1000000000);
+
+    spin_lock(&wc_lock);
+    wc_sec  = x;
+    wc_nsec = y;
+    spin_unlock(&wc_lock);
+
+    rcu_read_lock(&domlist_read_lock);
+    for_each_domain ( d )
+        update_domain_wallclock_time(d);
+    rcu_read_unlock(&domlist_read_lock);
+}
+
+/* Return secs after 00:00:00 localtime, 1 January, 1970. */
+unsigned long get_localtime(struct domain *d)
+{
+    return wc_sec + (wc_nsec + NOW()) / 1000000000ULL
+        + d->time_offset_seconds;
+}
+
+/* Return microsecs after 00:00:00 localtime, 1 January, 1970. */
+uint64_t get_localtime_us(struct domain *d)
+{
+    return (SECONDS(wc_sec + d->time_offset_seconds) + wc_nsec + NOW())
+           / 1000UL;
+}
+
+unsigned long get_sec(void)
+{
+    return wc_sec + (wc_nsec + NOW()) / 1000000000ULL;
+}
+
+struct tm wallclock_time(uint64_t *ns)
+{
+    uint64_t seconds, nsec;
+
+    if ( !wc_sec )
+        return (struct tm) { 0 };
+
+    seconds = NOW() + SECONDS(wc_sec) + wc_nsec;
+    nsec = do_div(seconds, 1000000000);
+
+    if ( ns )
+        *ns = nsec;
+
+    return gmtime(seconds);
+}
diff --git a/xen/include/xen/time.h b/xen/include/xen/time.h
index da4e8d7..b742746 100644
--- a/xen/include/xen/time.h
+++ b/xen/include/xen/time.h
@@ -60,11 +60,14 @@ struct tm wallclock_time(uint64_t *ns);
 /* Chosen so (NOW() + delta) wont overflow without an uptime of 200 years */
 #define STIME_DELTA_MAX ((s_time_t)((uint64_t)~0ull>>2))
 
+/* Explicitly OR with 1 just in case version number gets out of sync. */
+#define version_update_begin(v) (((v) + 1) | 1)
+#define version_update_end(v)   ((v) + 1)
 extern void update_vcpu_system_time(struct vcpu *v);
 extern void update_domain_wallclock_time(struct domain *d);
 
 extern void do_settime(
-    unsigned long secs, unsigned int nsecs, u64 system_time_base);
+    u64 secs, unsigned int nsecs, u64 system_time_base);
 
 extern void send_timer_event(struct vcpu *v);
 
-- 
1.7.10.4

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

* [PATCH v4 2/3] arm: export platform_op XENPF_settime64
  2015-11-12 17:45 [PATCH v4 0/3] wallclock time on arm Stefano Stabellini
  2015-11-12 17:46 ` [PATCH v4 1/3] xen: move wallclock functions from x86 to common Stefano Stabellini
@ 2015-11-12 17:46 ` Stefano Stabellini
  2015-11-12 18:49   ` Daniel De Graaf
                     ` (2 more replies)
  2015-11-12 17:46 ` [PATCH v4 3/3] xen/arm: move ticks conversions function declarations to the header file Stefano Stabellini
                   ` (2 subsequent siblings)
  4 siblings, 3 replies; 15+ messages in thread
From: Stefano Stabellini @ 2015-11-12 17:46 UTC (permalink / raw)
  To: xen-devel; +Cc: dgdegra, Ian.Campbell, Stefano Stabellini

Call update_domain_wallclock_time at domain initialization.
Set time_offset_seconds to the number of seconds between physical boot
and domain initialization: it is going to be used to get/set the
wallclock time.
Add time_offset_seconds to system_time when before calling do_settime,
so that system_time actually accounts for all the time in nsec between
machine boot and when the wallclock was set.

Expose xsm_platform_op to ARM.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
CC: dgdegra@tycho.nsa.gov

---

Changes in v4:
- remove spurious change to ticks_to_ns
- move flask_platform_op out of ifdef CONFIG_X86
- move set_to_dummy_if_null out of ifdef CONFIG_X86 for platform_op
- dropped previous ack from Daniel

Changes in v3:
- move update_domain_wallclock_time() call to arch_domain_create
- move setting time_offset_seconds to domain_vtimer_init
- use spin_trylock(&xenpf_lock) loop in do_platform_op

Changes in v2:
- drop XENPF_settime32
- set time_offset_seconds
- modify xen/xsm/flask/hooks.c
---
 xen/arch/arm/Makefile             |    1 +
 xen/arch/arm/domain.c             |    2 +
 xen/arch/arm/platform_hypercall.c |   70 +++++++++++++++++++
 xen/arch/arm/traps.c              |    1 +
 xen/arch/arm/vtimer.c             |    3 +
 xen/include/xsm/dummy.h           |   12 ++--
 xen/include/xsm/xsm.h             |   13 ++--
 xen/xsm/dummy.c                   |    2 +-
 xen/xsm/flask/hooks.c             |  140 ++++++++++++++++++-------------------
 9 files changed, 161 insertions(+), 83 deletions(-)
 create mode 100644 xen/arch/arm/platform_hypercall.c

diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 1ef39f7..240aa29 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -23,6 +23,7 @@ obj-y += percpu.o
 obj-y += guestcopy.o
 obj-y += physdev.o
 obj-y += platform.o
+obj-y += platform_hypercall.o
 obj-y += setup.o
 obj-y += bootfdt.o
 obj-y += time.o
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index b2bfc7d..b17f6cf 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -598,6 +598,8 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
     if ( (rc = domain_vtimer_init(d, config)) != 0 )
         goto fail;
 
+    update_domain_wallclock_time(d);
+
     /*
      * The hardware domain will get a PPI later in
      * arch/arm/domain_build.c  depending on the
diff --git a/xen/arch/arm/platform_hypercall.c b/xen/arch/arm/platform_hypercall.c
new file mode 100644
index 0000000..b708711
--- /dev/null
+++ b/xen/arch/arm/platform_hypercall.c
@@ -0,0 +1,70 @@
+/******************************************************************************
+ * platform_hypercall.c
+ *
+ * Hardware platform operations. Intended for use by domain-0 kernel.
+ *
+ * Copyright (c) 2015, Citrix
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/sched.h>
+#include <xen/guest_access.h>
+#include <xen/spinlock.h>
+#include <public/platform.h>
+#include <xsm/xsm.h>
+#include <asm/current.h>
+#include <asm/event.h>
+
+DEFINE_SPINLOCK(xenpf_lock);
+
+long do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
+{
+    long ret;
+    struct xen_platform_op curop, *op = &curop;
+    struct domain *d;
+
+    if ( copy_from_guest(op, u_xenpf_op, 1) )
+        return -EFAULT;
+
+    if ( op->interface_version != XENPF_INTERFACE_VERSION )
+        return -EACCES;
+
+    d = rcu_lock_current_domain();
+    if ( d == NULL )
+        return -ESRCH;
+
+    ret = xsm_platform_op(XSM_PRIV, op->cmd);
+    if ( ret )
+        return ret;
+
+    /*
+     * Trylock here avoids deadlock with an existing platform critical section
+     * which might (for some current or future reason) want to synchronise
+     * with this vcpu.
+     */
+    while ( !spin_trylock(&xenpf_lock) )
+        if ( hypercall_preempt_check() )
+            return hypercall_create_continuation(
+                __HYPERVISOR_platform_op, "h", u_xenpf_op);
+
+    switch ( op->cmd )
+    {
+    case XENPF_settime64:
+        if ( likely(!op->u.settime64.mbz) )
+            do_settime(op->u.settime64.secs,
+                       op->u.settime64.nsecs,
+                       op->u.settime64.system_time + SECONDS(d->time_offset_seconds));
+        else
+            ret = -EINVAL;
+        break;
+
+    default:
+        ret = -ENOSYS;
+        break;
+    }
+
+    spin_unlock(&xenpf_lock);
+    rcu_unlock_domain(d);
+    return ret;
+}
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 9d2bd6a..c49bd3f 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -1233,6 +1233,7 @@ static arm_hypercall_t arm_hypercall_table[] = {
     HYPERCALL(hvm_op, 2),
     HYPERCALL(grant_table_op, 3),
     HYPERCALL(multicall, 2),
+    HYPERCALL(platform_op, 1),
     HYPERCALL_ARM(vcpu_op, 3),
 };
 
diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c
index 1418092..c8e2a12 100644
--- a/xen/arch/arm/vtimer.c
+++ b/xen/arch/arm/vtimer.c
@@ -22,6 +22,7 @@
 #include <xen/timer.h>
 #include <xen/sched.h>
 #include <xen/perfc.h>
+#include <asm/div64.h>
 #include <asm/irq.h>
 #include <asm/time.h>
 #include <asm/gic.h>
@@ -64,6 +65,8 @@ int domain_vtimer_init(struct domain *d, struct xen_arch_domainconfig *config)
 {
     d->arch.phys_timer_base.offset = NOW();
     d->arch.virt_timer_base.offset = READ_SYSREG64(CNTPCT_EL0);
+    d->time_offset_seconds = ticks_to_ns(d->arch.virt_timer_base.offset - boot_count);
+    do_div(d->time_offset_seconds, 1000000000);
 
     config->clock_frequency = timer_dt_clock_frequency;
 
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index 9fe372c..e43f2a1 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -584,6 +584,12 @@ static XSM_INLINE int xsm_mem_sharing(XSM_DEFAULT_ARG struct domain *d)
 }
 #endif
 
+static XSM_INLINE int xsm_platform_op(XSM_DEFAULT_ARG uint32_t op)
+{
+    XSM_ASSERT_ACTION(XSM_PRIV);
+    return xsm_default_action(action, current->domain, NULL);
+}
+
 #ifdef CONFIG_X86
 static XSM_INLINE int xsm_do_mca(XSM_DEFAULT_VOID)
 {
@@ -639,12 +645,6 @@ static XSM_INLINE int xsm_apic(XSM_DEFAULT_ARG struct domain *d, int cmd)
     return xsm_default_action(action, d, NULL);
 }
 
-static XSM_INLINE int xsm_platform_op(XSM_DEFAULT_ARG uint32_t op)
-{
-    XSM_ASSERT_ACTION(XSM_PRIV);
-    return xsm_default_action(action, current->domain, NULL);
-}
-
 static XSM_INLINE int xsm_machine_memory_map(XSM_DEFAULT_VOID)
 {
     XSM_ASSERT_ACTION(XSM_PRIV);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index ba3caed..f48cf60 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -164,6 +164,8 @@ struct xsm_operations {
     int (*mem_sharing) (struct domain *d);
 #endif
 
+    int (*platform_op) (uint32_t cmd);
+
 #ifdef CONFIG_X86
     int (*do_mca) (void);
     int (*shadow_control) (struct domain *d, uint32_t op);
@@ -175,7 +177,6 @@ struct xsm_operations {
     int (*mem_sharing_op) (struct domain *d, struct domain *cd, int op);
     int (*apic) (struct domain *d, int cmd);
     int (*memtype) (uint32_t access);
-    int (*platform_op) (uint32_t cmd);
     int (*machine_memory_map) (void);
     int (*domain_memory_map) (struct domain *d);
 #define XSM_MMU_UPDATE_READ      1
@@ -624,6 +625,11 @@ static inline int xsm_mem_sharing (xsm_default_t def, struct domain *d)
 }
 #endif
 
+static inline int xsm_platform_op (xsm_default_t def, uint32_t op)
+{
+    return xsm_ops->platform_op(op);
+}
+
 #ifdef CONFIG_X86
 static inline int xsm_do_mca(xsm_default_t def)
 {
@@ -675,11 +681,6 @@ static inline int xsm_memtype (xsm_default_t def, uint32_t access)
     return xsm_ops->memtype(access);
 }
 
-static inline int xsm_platform_op (xsm_default_t def, uint32_t op)
-{
-    return xsm_ops->platform_op(op);
-}
-
 static inline int xsm_machine_memory_map(xsm_default_t def)
 {
     return xsm_ops->machine_memory_map();
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index 72eba40..618a96e 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -141,6 +141,7 @@ void xsm_fixup_ops (struct xsm_operations *ops)
     set_to_dummy_if_null(ops, mem_sharing);
 #endif
 
+    set_to_dummy_if_null(ops, platform_op);
 #ifdef CONFIG_X86
     set_to_dummy_if_null(ops, do_mca);
     set_to_dummy_if_null(ops, shadow_control);
@@ -151,7 +152,6 @@ void xsm_fixup_ops (struct xsm_operations *ops)
     set_to_dummy_if_null(ops, hvm_ioreq_server);
     set_to_dummy_if_null(ops, mem_sharing_op);
     set_to_dummy_if_null(ops, apic);
-    set_to_dummy_if_null(ops, platform_op);
     set_to_dummy_if_null(ops, machine_memory_map);
     set_to_dummy_if_null(ops, domain_memory_map);
     set_to_dummy_if_null(ops, mmu_update);
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index fafb1a4..48f5aef 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -1332,6 +1332,75 @@ static int flask_deassign_dtdevice(struct domain *d, const char *dtpath)
 }
 #endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE */
 
+static int flask_platform_op(uint32_t op)
+{
+    switch ( op )
+    {
+#ifdef CONFIG_X86
+    /* These operations have their own XSM hooks */
+    case XENPF_cpu_online:
+    case XENPF_cpu_offline:
+    case XENPF_cpu_hotadd:
+    case XENPF_mem_hotadd:
+        return 0;
+#endif
+
+    case XENPF_settime32:
+    case XENPF_settime64:
+        return domain_has_xen(current->domain, XEN__SETTIME);
+
+    case XENPF_add_memtype:
+        return domain_has_xen(current->domain, XEN__MTRR_ADD);
+
+    case XENPF_del_memtype:
+        return domain_has_xen(current->domain, XEN__MTRR_DEL);
+
+    case XENPF_read_memtype:
+        return domain_has_xen(current->domain, XEN__MTRR_READ);
+
+    case XENPF_microcode_update:
+        return domain_has_xen(current->domain, XEN__MICROCODE);
+
+    case XENPF_platform_quirk:
+        return domain_has_xen(current->domain, XEN__QUIRK);
+
+    case XENPF_firmware_info:
+        return domain_has_xen(current->domain, XEN__FIRMWARE);
+
+    case XENPF_efi_runtime_call:
+        return domain_has_xen(current->domain, XEN__FIRMWARE);
+
+    case XENPF_enter_acpi_sleep:
+        return domain_has_xen(current->domain, XEN__SLEEP);
+
+    case XENPF_change_freq:
+        return domain_has_xen(current->domain, XEN__FREQUENCY);
+
+    case XENPF_getidletime:
+        return domain_has_xen(current->domain, XEN__GETIDLE);
+
+    case XENPF_set_processor_pminfo:
+    case XENPF_core_parking:
+        return domain_has_xen(current->domain, XEN__PM_OP);
+
+    case XENPF_get_cpu_version:
+    case XENPF_get_cpuinfo:
+        return domain_has_xen(current->domain, XEN__GETCPUINFO);
+
+    case XENPF_resource_op:
+        return avc_current_has_perm(SECINITSID_XEN, SECCLASS_XEN2,
+                                    XEN2__RESOURCE_OP, NULL);
+
+    case XENPF_get_symbol:
+        return avc_has_perm(domain_sid(current->domain), SECINITSID_XEN,
+                            SECCLASS_XEN2, XEN2__GET_SYMBOL, NULL);
+
+    default:
+        printk("flask_platform_op: Unknown op %d\n", op);
+        return -EPERM;
+    }
+}
+
 #ifdef CONFIG_X86
 static int flask_do_mca(void)
 {
@@ -1470,75 +1539,6 @@ static int flask_apic(struct domain *d, int cmd)
     return domain_has_xen(d, perm);
 }
 
-static int flask_platform_op(uint32_t op)
-{
-    switch ( op )
-    {
-#ifdef CONFIG_X86
-    /* These operations have their own XSM hooks */
-    case XENPF_cpu_online:
-    case XENPF_cpu_offline:
-    case XENPF_cpu_hotadd:
-    case XENPF_mem_hotadd:
-        return 0;
-#endif
-
-    case XENPF_settime32:
-    case XENPF_settime64:
-        return domain_has_xen(current->domain, XEN__SETTIME);
-
-    case XENPF_add_memtype:
-        return domain_has_xen(current->domain, XEN__MTRR_ADD);
-
-    case XENPF_del_memtype:
-        return domain_has_xen(current->domain, XEN__MTRR_DEL);
-
-    case XENPF_read_memtype:
-        return domain_has_xen(current->domain, XEN__MTRR_READ);
-
-    case XENPF_microcode_update:
-        return domain_has_xen(current->domain, XEN__MICROCODE);
-
-    case XENPF_platform_quirk:
-        return domain_has_xen(current->domain, XEN__QUIRK);
-
-    case XENPF_firmware_info:
-        return domain_has_xen(current->domain, XEN__FIRMWARE);
-
-    case XENPF_efi_runtime_call:
-        return domain_has_xen(current->domain, XEN__FIRMWARE);
-
-    case XENPF_enter_acpi_sleep:
-        return domain_has_xen(current->domain, XEN__SLEEP);
-
-    case XENPF_change_freq:
-        return domain_has_xen(current->domain, XEN__FREQUENCY);
-
-    case XENPF_getidletime:
-        return domain_has_xen(current->domain, XEN__GETIDLE);
-
-    case XENPF_set_processor_pminfo:
-    case XENPF_core_parking:
-        return domain_has_xen(current->domain, XEN__PM_OP);
-
-    case XENPF_get_cpu_version:
-    case XENPF_get_cpuinfo:
-        return domain_has_xen(current->domain, XEN__GETCPUINFO);
-
-    case XENPF_resource_op:
-        return avc_current_has_perm(SECINITSID_XEN, SECCLASS_XEN2,
-                                    XEN2__RESOURCE_OP, NULL);
-
-    case XENPF_get_symbol:
-        return avc_has_perm(domain_sid(current->domain), SECINITSID_XEN,
-                            SECCLASS_XEN2, XEN2__GET_SYMBOL, NULL);
-
-    default:
-        printk("flask_platform_op: Unknown op %d\n", op);
-        return -EPERM;
-    }
-}
-
 static int flask_machine_memory_map(void)
 {
     return avc_current_has_perm(SECINITSID_XEN, SECCLASS_MMU, MMU__MEMORYMAP, NULL);
@@ -1735,6 +1735,7 @@ static struct xsm_operations flask_ops = {
     .deassign_dtdevice = flask_deassign_dtdevice,
 #endif
 
+    .platform_op = flask_platform_op,
 #ifdef CONFIG_X86
     .do_mca = flask_do_mca,
     .shadow_control = flask_shadow_control,
@@ -1745,7 +1746,6 @@ static struct xsm_operations flask_ops = {
     .hvm_ioreq_server = flask_hvm_ioreq_server,
     .mem_sharing_op = flask_mem_sharing_op,
     .apic = flask_apic,
-    .platform_op = flask_platform_op,
     .machine_memory_map = flask_machine_memory_map,
     .domain_memory_map = flask_domain_memory_map,
     .mmu_update = flask_mmu_update,
-- 
1.7.10.4

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

* [PATCH v4 3/3] xen/arm: move ticks conversions function declarations to the header file
  2015-11-12 17:45 [PATCH v4 0/3] wallclock time on arm Stefano Stabellini
  2015-11-12 17:46 ` [PATCH v4 1/3] xen: move wallclock functions from x86 to common Stefano Stabellini
  2015-11-12 17:46 ` [PATCH v4 2/3] arm: export platform_op XENPF_settime64 Stefano Stabellini
@ 2015-11-12 17:46 ` Stefano Stabellini
  2015-11-13 12:00   ` Julien Grall
  2015-11-16 13:08   ` Ian Campbell
  2015-11-16 13:09 ` [PATCH v4 0/3] wallclock time on arm Ian Campbell
  2015-11-25 11:49 ` Ian Campbell
  4 siblings, 2 replies; 15+ messages in thread
From: Stefano Stabellini @ 2015-11-12 17:46 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian.Campbell, Stefano Stabellini

This is just a cleanup, not required at the moment.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/vtimer.c      |    3 ---
 xen/include/asm-arm/time.h |    3 +++
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c
index c8e2a12..629feb4 100644
--- a/xen/arch/arm/vtimer.c
+++ b/xen/arch/arm/vtimer.c
@@ -29,9 +29,6 @@
 #include <asm/vgic.h>
 #include <asm/regs.h>
 
-extern s_time_t ticks_to_ns(uint64_t ticks);
-extern uint64_t ns_to_ticks(s_time_t ns);
-
 /*
  * Check if regs is allowed access, user_gate is tail end of a
  * CNTKCTL_EL1_ bit name which gates user access
diff --git a/xen/include/asm-arm/time.h b/xen/include/asm-arm/time.h
index d755f36..f99d6e8 100644
--- a/xen/include/asm-arm/time.h
+++ b/xen/include/asm-arm/time.h
@@ -37,6 +37,9 @@ extern void __cpuinit init_timer_interrupt(void);
 /* Counter value at boot time */
 extern uint64_t boot_count;
 
+extern s_time_t ticks_to_ns(uint64_t ticks);
+extern uint64_t ns_to_ticks(s_time_t ns);
+
 void preinit_xen_time(void);
 
 #endif /* __ARM_TIME_H__ */
-- 
1.7.10.4

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

* Re: [PATCH v4 2/3] arm: export platform_op XENPF_settime64
  2015-11-12 17:46 ` [PATCH v4 2/3] arm: export platform_op XENPF_settime64 Stefano Stabellini
@ 2015-11-12 18:49   ` Daniel De Graaf
  2015-11-13 11:59   ` Julien Grall
  2015-11-16 13:08   ` Ian Campbell
  2 siblings, 0 replies; 15+ messages in thread
From: Daniel De Graaf @ 2015-11-12 18:49 UTC (permalink / raw)
  To: Stefano Stabellini, xen-devel; +Cc: Ian.Campbell

On 12/11/15 12:46, Stefano Stabellini wrote:
> Call update_domain_wallclock_time at domain initialization.
> Set time_offset_seconds to the number of seconds between physical boot
> and domain initialization: it is going to be used to get/set the
> wallclock time.
> Add time_offset_seconds to system_time when before calling do_settime,
> so that system_time actually accounts for all the time in nsec between
> machine boot and when the wallclock was set.
>
> Expose xsm_platform_op to ARM.
>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> CC: dgdegra@tycho.nsa.gov

Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>

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

* Re: [PATCH v4 2/3] arm: export platform_op XENPF_settime64
  2015-11-12 17:46 ` [PATCH v4 2/3] arm: export platform_op XENPF_settime64 Stefano Stabellini
  2015-11-12 18:49   ` Daniel De Graaf
@ 2015-11-13 11:59   ` Julien Grall
  2015-11-16 13:08   ` Ian Campbell
  2 siblings, 0 replies; 15+ messages in thread
From: Julien Grall @ 2015-11-13 11:59 UTC (permalink / raw)
  To: Stefano Stabellini, xen-devel; +Cc: dgdegra, Ian.Campbell

Hi Stefano,

On 12/11/15 17:46, Stefano Stabellini wrote:
> Call update_domain_wallclock_time at domain initialization.
> Set time_offset_seconds to the number of seconds between physical boot
> and domain initialization: it is going to be used to get/set the
> wallclock time.
> Add time_offset_seconds to system_time when before calling do_settime,
> so that system_time actually accounts for all the time in nsec between
> machine boot and when the wallclock was set.
> 
> Expose xsm_platform_op to ARM.
> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

Reviewed-by: Julien Grall <julien.grall@citrix.com>

Regards,

-- 
Julien Grall

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

* Re: [PATCH v4 3/3] xen/arm: move ticks conversions function declarations to the header file
  2015-11-12 17:46 ` [PATCH v4 3/3] xen/arm: move ticks conversions function declarations to the header file Stefano Stabellini
@ 2015-11-13 12:00   ` Julien Grall
  2015-11-16 13:08   ` Ian Campbell
  1 sibling, 0 replies; 15+ messages in thread
From: Julien Grall @ 2015-11-13 12:00 UTC (permalink / raw)
  To: Stefano Stabellini, xen-devel; +Cc: Ian.Campbell

Hi Stefano,

On 12/11/15 17:46, Stefano Stabellini wrote:
> This is just a cleanup, not required at the moment.
> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

Reviewed-by: Julien Grall <julien.grall@citrix.com>

> ---
>  xen/arch/arm/vtimer.c      |    3 ---
>  xen/include/asm-arm/time.h |    3 +++
>  2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c
> index c8e2a12..629feb4 100644
> --- a/xen/arch/arm/vtimer.c
> +++ b/xen/arch/arm/vtimer.c
> @@ -29,9 +29,6 @@
>  #include <asm/vgic.h>
>  #include <asm/regs.h>
>  
> -extern s_time_t ticks_to_ns(uint64_t ticks);
> -extern uint64_t ns_to_ticks(s_time_t ns);
> -
>  /*
>   * Check if regs is allowed access, user_gate is tail end of a
>   * CNTKCTL_EL1_ bit name which gates user access
> diff --git a/xen/include/asm-arm/time.h b/xen/include/asm-arm/time.h
> index d755f36..f99d6e8 100644
> --- a/xen/include/asm-arm/time.h
> +++ b/xen/include/asm-arm/time.h
> @@ -37,6 +37,9 @@ extern void __cpuinit init_timer_interrupt(void);
>  /* Counter value at boot time */
>  extern uint64_t boot_count;
>  
> +extern s_time_t ticks_to_ns(uint64_t ticks);
> +extern uint64_t ns_to_ticks(s_time_t ns);
> +
>  void preinit_xen_time(void);
>  
>  #endif /* __ARM_TIME_H__ */
> 


-- 
Julien Grall

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

* Re: [PATCH v4 1/3] xen: move wallclock functions from x86 to common
  2015-11-12 17:46 ` [PATCH v4 1/3] xen: move wallclock functions from x86 to common Stefano Stabellini
@ 2015-11-16 13:04   ` Ian Campbell
  0 siblings, 0 replies; 15+ messages in thread
From: Ian Campbell @ 2015-11-16 13:04 UTC (permalink / raw)
  To: Stefano Stabellini, xen-devel; +Cc: andrew.cooper3, Jan Beulich

On Thu, 2015-11-12 at 17:46 +0000, Stefano Stabellini wrote:
> Remove dummy arm implementation of wallclock_time.
> Use shared_info() in common code rather than x86-ism to access it, when
> possible.
> 
> Define the static variable wc_sec, and the local variale sec in

                                                   variable

> update_domain_wallclock_time, as uint64_t instead of unsigned long, to
> avoid size issue on arm.

             issues

> Take a uint64_t sec paramter in do_settime for the same reason.

                      parameter

> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Acked-by: Jan Beulich <jbeulich@suse.com>

Apart from the typos:

Acked-by: Ian Campbell <ian.campbell@citrix.com>

> CC: JBeulich@suse.com
> CC: andrew.cooper3@citrix.com
> 
> ---
> 
> Changes in v3:
> - remove stray blank lines
> 
> Changes in v2:
> - remove stray blank lines
> - remove include <xen/config.h>
> - move version_update_* to include/xen/time.h
> - introduce ifdef to fix build issue in common/time.c
> - define wc_sec and sec as uint64_t
> - pass u64 to do_settime
> ---
>  xen/arch/arm/time.c    |    5 ---
>  xen/arch/x86/time.c    |   96 +-----------------------------------------
> ------
>  xen/common/time.c      |   95
> ++++++++++++++++++++++++++++++++++++++++++++++-
>  xen/include/xen/time.h |    5 ++-
>  4 files changed, 99 insertions(+), 102 deletions(-)
> 
> diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
> index 5ded30c..6207615 100644
> --- a/xen/arch/arm/time.c
> +++ b/xen/arch/arm/time.c
> @@ -280,11 +280,6 @@ void domain_set_time_offset(struct domain *d,
> int64_t time_offset_seconds)
>      /* XXX update guest visible wallclock time */
>  }
>  
> -struct tm wallclock_time(uint64_t *ns)
> -{
> -    return (struct tm) { 0 };
> -}
> -
>  /*
>   * Local variables:
>   * mode: C
> diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
> index bbb7e6c..0f16db5 100644
> --- a/xen/arch/x86/time.c
> +++ b/xen/arch/x86/time.c
> @@ -47,9 +47,6 @@ string_param("clocksource", opt_clocksource);
>  unsigned long __read_mostly cpu_khz;  /* CPU clock frequency in kHz. */
>  DEFINE_SPINLOCK(rtc_lock);
>  unsigned long pit0_ticks;
> -static unsigned long wc_sec; /* UTC time at last 'time update'. */
> -static unsigned int wc_nsec;
> -static DEFINE_SPINLOCK(wc_lock);
>  
>  struct cpu_time {
>      u64 local_tsc_stamp;
> @@ -783,10 +780,6 @@ uint64_t tsc_ticks2ns(uint64_t ticks)
>      return scale_delta(ticks, &t->tsc_scale);
>  }
>  
> -/* Explicitly OR with 1 just in case version number gets out of sync. */
> -#define version_update_begin(v) (((v)+1)|1)
> -#define version_update_end(v)   ((v)+1)
> -
>  static void __update_vcpu_system_time(struct vcpu *v, int force)
>  {
>      struct cpu_time       *t;
> @@ -900,37 +893,6 @@ void force_update_vcpu_system_time(struct vcpu *v)
>      __update_vcpu_system_time(v, 1);
>  }
>  
> -void update_domain_wallclock_time(struct domain *d)
> -{
> -    uint32_t *wc_version;
> -    unsigned long sec;
> -
> -    spin_lock(&wc_lock);
> -
> -    wc_version = &shared_info(d, wc_version);
> -    *wc_version = version_update_begin(*wc_version);
> -    wmb();
> -
> -    sec = wc_sec + d->time_offset_seconds;
> -    if ( likely(!has_32bit_shinfo(d)) )
> -    {
> -        d->shared_info->native.wc_sec    = sec;
> -        d->shared_info->native.wc_nsec   = wc_nsec;
> -        d->shared_info->native.wc_sec_hi = sec >> 32;
> -    }
> -    else
> -    {
> -        d->shared_info->compat.wc_sec         = sec;
> -        d->shared_info->compat.wc_nsec        = wc_nsec;
> -        d->shared_info->compat.arch.wc_sec_hi = sec >> 32;
> -    }
> -
> -    wmb();
> -    *wc_version = version_update_end(*wc_version);
> -
> -    spin_unlock(&wc_lock);
> -}
> -
>  static void update_domain_rtc(void)
>  {
>      struct domain *d;
> @@ -988,27 +950,6 @@ int cpu_frequency_change(u64 freq)
>      return 0;
>  }
>  
> -/* Set clock to <secs,usecs> after 00:00:00 UTC, 1 January, 1970. */
> -void do_settime(unsigned long secs, unsigned int nsecs, u64
> system_time_base)
> -{
> -    u64 x;
> -    u32 y;
> -    struct domain *d;
> -
> -    x = SECONDS(secs) + nsecs - system_time_base;
> -    y = do_div(x, 1000000000);
> -
> -    spin_lock(&wc_lock);
> -    wc_sec  = x;
> -    wc_nsec = y;
> -    spin_unlock(&wc_lock);
> -
> -    rcu_read_lock(&domlist_read_lock);
> -    for_each_domain ( d )
> -        update_domain_wallclock_time(d);
> -    rcu_read_unlock(&domlist_read_lock);
> -}
> -
>  /* Per-CPU communication between rendezvous IRQ and softirq handler. */
>  struct cpu_calibration {
>      u64 local_tsc_stamp;
> @@ -1608,25 +1549,6 @@ void send_timer_event(struct vcpu *v)
>      send_guest_vcpu_virq(v, VIRQ_TIMER);
>  }
>  
> -/* Return secs after 00:00:00 localtime, 1 January, 1970. */
> -unsigned long get_localtime(struct domain *d)
> -{
> -    return wc_sec + (wc_nsec + NOW()) / 1000000000ULL 
> -        + d->time_offset_seconds;
> -}
> -
> -/* Return microsecs after 00:00:00 localtime, 1 January, 1970. */
> -uint64_t get_localtime_us(struct domain *d)
> -{
> -    return (SECONDS(wc_sec + d->time_offset_seconds) + wc_nsec + NOW())
> -           / 1000UL;
> -}
> -
> -unsigned long get_sec(void)
> -{
> -    return wc_sec + (wc_nsec + NOW()) / 1000000000ULL;
> -}
> -
>  /* "cmos_utc_offset" is the difference between UTC time and CMOS time.
> */
>  static long cmos_utc_offset; /* in seconds */
>  
> @@ -1635,7 +1557,7 @@ int time_suspend(void)
>      if ( smp_processor_id() == 0 )
>      {
>          cmos_utc_offset = -get_cmos_time();
> -        cmos_utc_offset += (wc_sec + (wc_nsec + NOW()) / 1000000000ULL);
> +        cmos_utc_offset += get_sec();
>          kill_timer(&calibration_timer);
>  
>          /* Sync platform timer stamps. */
> @@ -1715,22 +1637,6 @@ int hwdom_pit_access(struct ioreq *ioreq)
>      return 0;
>  }
>  
> -struct tm wallclock_time(uint64_t *ns)
> -{
> -    uint64_t seconds, nsec;
> -
> -    if ( !wc_sec )
> -        return (struct tm) { 0 };
> -
> -    seconds = NOW() + SECONDS(wc_sec) + wc_nsec;
> -    nsec = do_div(seconds, 1000000000);
> -
> -    if ( ns )
> -        *ns = nsec;
> -
> -    return gmtime(seconds);
> -}
> -
>  /*
>   * PV SoftTSC Emulation.
>   */
> diff --git a/xen/common/time.c b/xen/common/time.c
> index 29fdf52..721ada8 100644
> --- a/xen/common/time.c
> +++ b/xen/common/time.c
> @@ -15,8 +15,12 @@
>   * along with this program; If not, see <http://www.gnu.org/licenses/>.
>   */
>  
> -#include <xen/config.h>
> +#include <xen/sched.h>
> +#include <xen/shared.h>
> +#include <xen/spinlock.h>
>  #include <xen/time.h>
> +#include <asm/div64.h>
> +#include <asm/domain.h>
>  
>  /* Nonzero if YEAR is a leap year (every 4 years,
>     except every 100th isn't, and every 400th is).  */
> @@ -34,6 +38,10 @@ const unsigned short int __mon_lengths[2][12] = {
>  #define SECS_PER_HOUR (60 * 60)
>  #define SECS_PER_DAY  (SECS_PER_HOUR * 24)
>  
> +static uint64_t wc_sec; /* UTC time at last 'time update'. */
> +static unsigned int wc_nsec;
> +static DEFINE_SPINLOCK(wc_lock);
> +
>  struct tm gmtime(unsigned long t)
>  {
>      struct tm tbuf;
> @@ -85,3 +93,88 @@ struct tm gmtime(unsigned long t)
>  
>      return tbuf;
>  }
> +
> +void update_domain_wallclock_time(struct domain *d)
> +{
> +    uint32_t *wc_version;
> +    uint64_t sec;
> +
> +    spin_lock(&wc_lock);
> +
> +    wc_version = &shared_info(d, wc_version);
> +    *wc_version = version_update_begin(*wc_version);
> +    wmb();
> +
> +    sec = wc_sec + d->time_offset_seconds;
> +    shared_info(d, wc_sec)    = sec;
> +    shared_info(d, wc_nsec)   = wc_nsec;
> +#ifdef CONFIG_X86
> +    if ( likely(!has_32bit_shinfo(d)) )
> +        d->shared_info->native.wc_sec_hi = sec >> 32;
> +    else
> +        d->shared_info->compat.arch.wc_sec_hi = sec >> 32;
> +#else
> +    shared_info(d, wc_sec_hi) = sec >> 32;
> +#endif
> +
> +    wmb();
> +    *wc_version = version_update_end(*wc_version);
> +
> +    spin_unlock(&wc_lock);
> +}
> +
> +/* Set clock to <secs,usecs> after 00:00:00 UTC, 1 January, 1970. */
> +void do_settime(u64 secs, unsigned int nsecs, u64 system_time_base)
> +{
> +    u64 x;
> +    u32 y;
> +    struct domain *d;
> +
> +    x = SECONDS(secs) + nsecs - system_time_base;
> +    y = do_div(x, 1000000000);
> +
> +    spin_lock(&wc_lock);
> +    wc_sec  = x;
> +    wc_nsec = y;
> +    spin_unlock(&wc_lock);
> +
> +    rcu_read_lock(&domlist_read_lock);
> +    for_each_domain ( d )
> +        update_domain_wallclock_time(d);
> +    rcu_read_unlock(&domlist_read_lock);
> +}
> +
> +/* Return secs after 00:00:00 localtime, 1 January, 1970. */
> +unsigned long get_localtime(struct domain *d)
> +{
> +    return wc_sec + (wc_nsec + NOW()) / 1000000000ULL
> +        + d->time_offset_seconds;
> +}
> +
> +/* Return microsecs after 00:00:00 localtime, 1 January, 1970. */
> +uint64_t get_localtime_us(struct domain *d)
> +{
> +    return (SECONDS(wc_sec + d->time_offset_seconds) + wc_nsec + NOW())
> +           / 1000UL;
> +}
> +
> +unsigned long get_sec(void)
> +{
> +    return wc_sec + (wc_nsec + NOW()) / 1000000000ULL;
> +}
> +
> +struct tm wallclock_time(uint64_t *ns)
> +{
> +    uint64_t seconds, nsec;
> +
> +    if ( !wc_sec )
> +        return (struct tm) { 0 };
> +
> +    seconds = NOW() + SECONDS(wc_sec) + wc_nsec;
> +    nsec = do_div(seconds, 1000000000);
> +
> +    if ( ns )
> +        *ns = nsec;
> +
> +    return gmtime(seconds);
> +}
> diff --git a/xen/include/xen/time.h b/xen/include/xen/time.h
> index da4e8d7..b742746 100644
> --- a/xen/include/xen/time.h
> +++ b/xen/include/xen/time.h
> @@ -60,11 +60,14 @@ struct tm wallclock_time(uint64_t *ns);
>  /* Chosen so (NOW() + delta) wont overflow without an uptime of 200
> years */
>  #define STIME_DELTA_MAX ((s_time_t)((uint64_t)~0ull>>2))
>  
> +/* Explicitly OR with 1 just in case version number gets out of sync. */
> +#define version_update_begin(v) (((v) + 1) | 1)
> +#define version_update_end(v)   ((v) + 1)
>  extern void update_vcpu_system_time(struct vcpu *v);
>  extern void update_domain_wallclock_time(struct domain *d);
>  
>  extern void do_settime(
> -    unsigned long secs, unsigned int nsecs, u64 system_time_base);
> +    u64 secs, unsigned int nsecs, u64 system_time_base);
>  
>  extern void send_timer_event(struct vcpu *v);
>  

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

* Re: [PATCH v4 2/3] arm: export platform_op XENPF_settime64
  2015-11-12 17:46 ` [PATCH v4 2/3] arm: export platform_op XENPF_settime64 Stefano Stabellini
  2015-11-12 18:49   ` Daniel De Graaf
  2015-11-13 11:59   ` Julien Grall
@ 2015-11-16 13:08   ` Ian Campbell
  2015-11-24 17:00     ` Daniel De Graaf
  2 siblings, 1 reply; 15+ messages in thread
From: Ian Campbell @ 2015-11-16 13:08 UTC (permalink / raw)
  To: Stefano Stabellini, xen-devel; +Cc: dgdegra

On Thu, 2015-11-12 at 17:46 +0000, Stefano Stabellini wrote:
> Call update_domain_wallclock_time at domain initialization.
> Set time_offset_seconds to the number of seconds between physical boot
> and domain initialization: it is going to be used to get/set the
> wallclock time.
> Add time_offset_seconds to system_time when before calling do_settime,
> so that system_time actually accounts for all the time in nsec between
> machine boot and when the wallclock was set.
> 
> Expose xsm_platform_op to ARM.
> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

Acked-by: Ian Campbell <ian.campbell@citrix.com>

An aside:[...]
@@ -1332,6 +1332,75 @@ static int flask_deassign_dtdevice(struct domain
> *d, const char *dtpath)
>  }
>  #endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE */
>  
> +static int flask_platform_op(uint32_t op)
> +{
> +    switch ( op )
> +    {
> +#ifdef CONFIG_X86
> +    /* These operations have their own XSM hooks */
> +    case XENPF_cpu_online:
> +    case XENPF_cpu_offline:
> +    case XENPF_cpu_hotadd:
> +    case XENPF_mem_hotadd:
> +        return 0;

Should this not then be an error (e.g. fail closed)?

Also, although only implemented today for x86 they don't seem inherently
any more x86 specific than many of the other things below, so maybe the
ifdef could be ditched?


> +#endif
> +
> +    case XENPF_settime32:
> +    case XENPF_settime64:
> +        return domain_has_xen(current->domain, XEN__SETTIME);
> +
> +    case XENPF_add_memtype:
> +        return domain_has_xen(current->domain, XEN__MTRR_ADD);
> +
> +    case XENPF_del_memtype:
> +        return domain_has_xen(current->domain, XEN__MTRR_DEL);
> +
> +    case XENPF_read_memtype:
> +        return domain_has_xen(current->domain, XEN__MTRR_READ);
> +
> +    case XENPF_microcode_update:
> +        return domain_has_xen(current->domain, XEN__MICROCODE);
> +
> +    case XENPF_platform_quirk:
> +        return domain_has_xen(current->domain, XEN__QUIRK);
> +
> +    case XENPF_firmware_info:
> +        return domain_has_xen(current->domain, XEN__FIRMWARE);
> +
> +    case XENPF_efi_runtime_call:
> +        return domain_has_xen(current->domain, XEN__FIRMWARE);
> +
> +    case XENPF_enter_acpi_sleep:
> +        return domain_has_xen(current->domain, XEN__SLEEP);
> +
> +    case XENPF_change_freq:
> +        return domain_has_xen(current->domain, XEN__FREQUENCY);
> +
> +    case XENPF_getidletime:
> +        return domain_has_xen(current->domain, XEN__GETIDLE);
> +
> +    case XENPF_set_processor_pminfo:
> +    case XENPF_core_parking:
> +        return domain_has_xen(current->domain, XEN__PM_OP);
> +
> +    case XENPF_get_cpu_version:
> +    case XENPF_get_cpuinfo:
> +        return domain_has_xen(current->domain, XEN__GETCPUINFO);
> +
> +    case XENPF_resource_op:
> +        return avc_current_has_perm(SECINITSID_XEN, SECCLASS_XEN2,
> +                                    XEN2__RESOURCE_OP, NULL);
> +
> +    case XENPF_get_symbol:
> +        return avc_has_perm(domain_sid(current->domain), SECINITSID_XEN,
> +                            SECCLASS_XEN2, XEN2__GET_SYMBOL, NULL);
> +
> +    default:
> +        printk("flask_platform_op: Unknown op %d\n", op);
> +        return -EPERM;
> +    }
> +}
> +
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

* Re: [PATCH v4 3/3] xen/arm: move ticks conversions function declarations to the header file
  2015-11-12 17:46 ` [PATCH v4 3/3] xen/arm: move ticks conversions function declarations to the header file Stefano Stabellini
  2015-11-13 12:00   ` Julien Grall
@ 2015-11-16 13:08   ` Ian Campbell
  1 sibling, 0 replies; 15+ messages in thread
From: Ian Campbell @ 2015-11-16 13:08 UTC (permalink / raw)
  To: Stefano Stabellini, xen-devel

On Thu, 2015-11-12 at 17:46 +0000, Stefano Stabellini wrote:
> This is just a cleanup, not required at the moment.
> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

Acked-by: Ian Campbell <ian.campbell@citrix.com>

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

* Re: [PATCH v4 0/3] wallclock time on arm
  2015-11-12 17:45 [PATCH v4 0/3] wallclock time on arm Stefano Stabellini
                   ` (2 preceding siblings ...)
  2015-11-12 17:46 ` [PATCH v4 3/3] xen/arm: move ticks conversions function declarations to the header file Stefano Stabellini
@ 2015-11-16 13:09 ` Ian Campbell
  2015-11-20 11:41   ` Stefano Stabellini
  2015-11-25 11:49 ` Ian Campbell
  4 siblings, 1 reply; 15+ messages in thread
From: Ian Campbell @ 2015-11-16 13:09 UTC (permalink / raw)
  To: Stefano Stabellini, xen-devel

On Thu, 2015-11-12 at 17:45 +0000, Stefano Stabellini wrote:
> Hi all,
> 
> this small series enables the wallclock time on arm and it consists
> mostly in code movement from x86 to common.

AFAICT this is all now suitably acked, but I wanted to coordinate with you
on the guest side changes before applying.

Ian.

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

* Re: [PATCH v4 0/3] wallclock time on arm
  2015-11-16 13:09 ` [PATCH v4 0/3] wallclock time on arm Ian Campbell
@ 2015-11-20 11:41   ` Stefano Stabellini
  0 siblings, 0 replies; 15+ messages in thread
From: Stefano Stabellini @ 2015-11-20 11:41 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, Stefano Stabellini

On Mon, 16 Nov 2015, Ian Campbell wrote:
> On Thu, 2015-11-12 at 17:45 +0000, Stefano Stabellini wrote:
> > Hi all,
> > 
> > this small series enables the wallclock time on arm and it consists
> > mostly in code movement from x86 to common.
> 
> AFAICT this is all now suitably acked, but I wanted to coordinate with you
> on the guest side changes before applying.

They can be applied independently from the Linux changes (if the guest
doesn't know how to read the wallclock, it won't).

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

* Re: [PATCH v4 2/3] arm: export platform_op XENPF_settime64
  2015-11-16 13:08   ` Ian Campbell
@ 2015-11-24 17:00     ` Daniel De Graaf
  2015-11-25 10:36       ` Ian Campbell
  0 siblings, 1 reply; 15+ messages in thread
From: Daniel De Graaf @ 2015-11-24 17:00 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini, xen-devel

On 16/11/15 08:08, Ian Campbell wrote:
> On Thu, 2015-11-12 at 17:46 +0000, Stefano Stabellini wrote:
>> Call update_domain_wallclock_time at domain initialization.
>> Set time_offset_seconds to the number of seconds between physical boot
>> and domain initialization: it is going to be used to get/set the
>> wallclock time.
>> Add time_offset_seconds to system_time when before calling do_settime,
>> so that system_time actually accounts for all the time in nsec between
>> machine boot and when the wallclock was set.
>>
>> Expose xsm_platform_op to ARM.
>>
>> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>
> Acked-by: Ian Campbell <ian.campbell@citrix.com>
>
> An aside:[...]
> @@ -1332,6 +1332,75 @@ static int flask_deassign_dtdevice(struct domain
>> *d, const char *dtpath)
>>   }
>>   #endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE */
>>
>> +static int flask_platform_op(uint32_t op)
>> +{
>> +    switch ( op )
>> +    {
>> +#ifdef CONFIG_X86
>> +    /* These operations have their own XSM hooks */
>> +    case XENPF_cpu_online:
>> +    case XENPF_cpu_offline:
>> +    case XENPF_cpu_hotadd:
>> +    case XENPF_mem_hotadd:
>> +        return 0;
>
> Should this not then be an error (e.g. fail closed)?

During the invocation of these operations, two XSM hooks are called: this
one (from above the switch) and the individual hook (inside the switch).
This hook needs to allow access so that the more detailed hook is called.

> Also, although only implemented today for x86 they don't seem inherently
> any more x86 specific than many of the other things below, so maybe the
> ifdef could be ditched?

The #ifdef is there mostly as a failsafe reminder to ensure that the
implementation for other architectures actually calls the same XSM hooks
that the x86 version does.


-- 
Daniel De Graaf
National Security Agency

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

* Re: [PATCH v4 2/3] arm: export platform_op XENPF_settime64
  2015-11-24 17:00     ` Daniel De Graaf
@ 2015-11-25 10:36       ` Ian Campbell
  0 siblings, 0 replies; 15+ messages in thread
From: Ian Campbell @ 2015-11-25 10:36 UTC (permalink / raw)
  To: Daniel De Graaf, Stefano Stabellini, xen-devel

On Tue, 2015-11-24 at 12:00 -0500, Daniel De Graaf wrote:
> On 16/11/15 08:08, Ian Campbell wrote:
> > On Thu, 2015-11-12 at 17:46 +0000, Stefano Stabellini wrote:
> > > Call update_domain_wallclock_time at domain initialization.
> > > Set time_offset_seconds to the number of seconds between physical
> > > boot
> > > and domain initialization: it is going to be used to get/set the
> > > wallclock time.
> > > Add time_offset_seconds to system_time when before calling
> > > do_settime,
> > > so that system_time actually accounts for all the time in nsec
> > > between
> > > machine boot and when the wallclock was set.
> > > 
> > > Expose xsm_platform_op to ARM.
> > > 
> > > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> > 
> > Acked-by: Ian Campbell <ian.campbell@citrix.com>
> > 
> > An aside:[...]
> > @@ -1332,6 +1332,75 @@ static int flask_deassign_dtdevice(struct domain
> > > *d, const char *dtpath)
> > >   }
> > >   #endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE */
> > > 
> > > +static int flask_platform_op(uint32_t op)
> > > +{
> > > +    switch ( op )
> > > +    {
> > > +#ifdef CONFIG_X86
> > > +    /* These operations have their own XSM hooks */
> > > +    case XENPF_cpu_online:
> > > +    case XENPF_cpu_offline:
> > > +    case XENPF_cpu_hotadd:
> > > +    case XENPF_mem_hotadd:
> > > +        return 0;
> > 
> > Should this not then be an error (e.g. fail closed)?
> 
> During the invocation of these operations, two XSM hooks are called: this
> one (from above the switch) and the individual hook (inside the switch).
> This hook needs to allow access so that the more detailed hook is called.

I see, thanks for the explanation.

> > Also, although only implemented today for x86 they don't seem
> > inherently
> > any more x86 specific than many of the other things below, so maybe the
> > ifdef could be ditched?
> 
> The #ifdef is there mostly as a failsafe reminder to ensure that the
> implementation for other architectures actually calls the same XSM hooks
> that the x86 version does.

OK.

Ian.


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

* Re: [PATCH v4 0/3] wallclock time on arm
  2015-11-12 17:45 [PATCH v4 0/3] wallclock time on arm Stefano Stabellini
                   ` (3 preceding siblings ...)
  2015-11-16 13:09 ` [PATCH v4 0/3] wallclock time on arm Ian Campbell
@ 2015-11-25 11:49 ` Ian Campbell
  4 siblings, 0 replies; 15+ messages in thread
From: Ian Campbell @ 2015-11-25 11:49 UTC (permalink / raw)
  To: Stefano Stabellini, xen-devel

On Thu, 2015-11-12 at 17:45 +0000, Stefano Stabellini wrote:
> 
> Stefano Stabellini (3):
>       xen: move wallclock functions from x86 to common
>       arm: export platform_op XENPF_settime64
>       xen/arm: move ticks conversions function declarations to the header file

Applied, thanks.


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

end of thread, other threads:[~2015-11-25 11:49 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-12 17:45 [PATCH v4 0/3] wallclock time on arm Stefano Stabellini
2015-11-12 17:46 ` [PATCH v4 1/3] xen: move wallclock functions from x86 to common Stefano Stabellini
2015-11-16 13:04   ` Ian Campbell
2015-11-12 17:46 ` [PATCH v4 2/3] arm: export platform_op XENPF_settime64 Stefano Stabellini
2015-11-12 18:49   ` Daniel De Graaf
2015-11-13 11:59   ` Julien Grall
2015-11-16 13:08   ` Ian Campbell
2015-11-24 17:00     ` Daniel De Graaf
2015-11-25 10:36       ` Ian Campbell
2015-11-12 17:46 ` [PATCH v4 3/3] xen/arm: move ticks conversions function declarations to the header file Stefano Stabellini
2015-11-13 12:00   ` Julien Grall
2015-11-16 13:08   ` Ian Campbell
2015-11-16 13:09 ` [PATCH v4 0/3] wallclock time on arm Ian Campbell
2015-11-20 11:41   ` Stefano Stabellini
2015-11-25 11:49 ` Ian Campbell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.