aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Stabellini <stefano.stabellini@eu.citrix.com>2015-11-23 05:42:12 -0500
committerDavid Vrabel <david.vrabel@citrix.com>2015-12-21 09:40:59 -0500
commit760968631323f710ea0824369bbd65f812c82f08 (patch)
tree1c5b3b9f7cf389e3a0e2406f07198d16934411af
parent7d5f6f81ddbb5b532a832cbeb65472541b22a7c2 (diff)
xen/x86: support XENPF_settime64
Try XENPF_settime64 first, if it is not available fall back to XENPF_settime32. No need to call __current_kernel_time() when all the info needed are already passed via the struct timekeeper * argument. Return NOTIFY_BAD in case of errors. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
-rw-r--r--arch/x86/xen/time.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 3bbd377e1657..4b8af45b211a 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -16,6 +16,7 @@
16#include <linux/gfp.h> 16#include <linux/gfp.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/pvclock_gtod.h> 18#include <linux/pvclock_gtod.h>
19#include <linux/timekeeper_internal.h>
19 20
20#include <asm/pvclock.h> 21#include <asm/pvclock.h>
21#include <asm/xen/hypervisor.h> 22#include <asm/xen/hypervisor.h>
@@ -123,9 +124,13 @@ static int xen_pvclock_gtod_notify(struct notifier_block *nb,
123 static struct timespec next_sync; 124 static struct timespec next_sync;
124 125
125 struct xen_platform_op op; 126 struct xen_platform_op op;
126 struct timespec now; 127 struct timespec64 now;
128 struct timekeeper *tk = priv;
129 static bool settime64_supported = true;
130 int ret;
127 131
128 now = __current_kernel_time(); 132 now.tv_sec = tk->xtime_sec;
133 now.tv_nsec = (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift);
129 134
130 /* 135 /*
131 * We only take the expensive HV call when the clock was set 136 * We only take the expensive HV call when the clock was set
@@ -134,12 +139,28 @@ static int xen_pvclock_gtod_notify(struct notifier_block *nb,
134 if (!was_set && timespec_compare(&now, &next_sync) < 0) 139 if (!was_set && timespec_compare(&now, &next_sync) < 0)
135 return NOTIFY_OK; 140 return NOTIFY_OK;
136 141
137 op.cmd = XENPF_settime32; 142again:
138 op.u.settime32.secs = now.tv_sec; 143 if (settime64_supported) {
139 op.u.settime32.nsecs = now.tv_nsec; 144 op.cmd = XENPF_settime64;
140 op.u.settime32.system_time = xen_clocksource_read(); 145 op.u.settime64.mbz = 0;
146 op.u.settime64.secs = now.tv_sec;
147 op.u.settime64.nsecs = now.tv_nsec;
148 op.u.settime64.system_time = xen_clocksource_read();
149 } else {
150 op.cmd = XENPF_settime32;
151 op.u.settime32.secs = now.tv_sec;
152 op.u.settime32.nsecs = now.tv_nsec;
153 op.u.settime32.system_time = xen_clocksource_read();
154 }
155
156 ret = HYPERVISOR_platform_op(&op);
141 157
142 (void)HYPERVISOR_platform_op(&op); 158 if (ret == -ENOSYS && settime64_supported) {
159 settime64_supported = false;
160 goto again;
161 }
162 if (ret < 0)
163 return NOTIFY_BAD;
143 164
144 /* 165 /*
145 * Move the next drift compensation time 11 minutes 166 * Move the next drift compensation time 11 minutes