Commit 76096863 authored by Stefano Stabellini's avatar Stefano Stabellini Committed by David Vrabel

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: default avatarStefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
Reviewed-by: default avatarBoris Ostrovsky <boris.ostrovsky@oracle.com>
parent 7d5f6f81
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pvclock_gtod.h> #include <linux/pvclock_gtod.h>
#include <linux/timekeeper_internal.h>
#include <asm/pvclock.h> #include <asm/pvclock.h>
#include <asm/xen/hypervisor.h> #include <asm/xen/hypervisor.h>
...@@ -123,9 +124,13 @@ static int xen_pvclock_gtod_notify(struct notifier_block *nb, ...@@ -123,9 +124,13 @@ static int xen_pvclock_gtod_notify(struct notifier_block *nb,
static struct timespec next_sync; static struct timespec next_sync;
struct xen_platform_op op; struct xen_platform_op op;
struct timespec now; struct timespec64 now;
struct timekeeper *tk = priv;
static bool settime64_supported = true;
int ret;
now = __current_kernel_time(); now.tv_sec = tk->xtime_sec;
now.tv_nsec = (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift);
/* /*
* We only take the expensive HV call when the clock was set * 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,12 +139,28 @@ static int xen_pvclock_gtod_notify(struct notifier_block *nb,
if (!was_set && timespec_compare(&now, &next_sync) < 0) if (!was_set && timespec_compare(&now, &next_sync) < 0)
return NOTIFY_OK; return NOTIFY_OK;
op.cmd = XENPF_settime32; again:
op.u.settime32.secs = now.tv_sec; if (settime64_supported) {
op.u.settime32.nsecs = now.tv_nsec; op.cmd = XENPF_settime64;
op.u.settime32.system_time = xen_clocksource_read(); op.u.settime64.mbz = 0;
op.u.settime64.secs = now.tv_sec;
op.u.settime64.nsecs = now.tv_nsec;
op.u.settime64.system_time = xen_clocksource_read();
} else {
op.cmd = XENPF_settime32;
op.u.settime32.secs = now.tv_sec;
op.u.settime32.nsecs = now.tv_nsec;
op.u.settime32.system_time = xen_clocksource_read();
}
ret = HYPERVISOR_platform_op(&op);
(void)HYPERVISOR_platform_op(&op); if (ret == -ENOSYS && settime64_supported) {
settime64_supported = false;
goto again;
}
if (ret < 0)
return NOTIFY_BAD;
/* /*
* Move the next drift compensation time 11 minutes * Move the next drift compensation time 11 minutes
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment