From eac636b0ce5cb889aa72628f18169cd58ba3697d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Date: Mon, 2 May 2016 16:15:28 +0000 Subject: [PATCH] xen/time: allow Dom0 to set the host time Dom0 should be able to set the host time. This is implemented by first writing to the RTC (as would be done on bare metal), and then using the XENPF_settime64 hypercall in order to force Xen to update the wallclock shared page of all domains. Sponsored by: Citrix Systems R&D --- sys/dev/xen/timer/timer.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/sys/dev/xen/timer/timer.c b/sys/dev/xen/timer/timer.c index 8bc74007665..8eecc6051d7 100644 --- a/sys/dev/xen/timer/timer.c +++ b/sys/dev/xen/timer/timer.c @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -63,6 +64,8 @@ __FBSDID("$FreeBSD$"); #include +#include + #include "clock_if.h" static devclass_t xentimer_devclass; @@ -211,11 +214,32 @@ xen_fetch_uptime(struct timespec *ts) static int xentimer_settime(device_t dev __unused, struct timespec *ts) { + struct xen_platform_op settime; + int ret; + /* * Don't return EINVAL here; just silently fail if the domain isn't * privileged enough to set the TOD. */ - return (0); + if (!xen_initial_domain()) + return (0); + + /* Set the native RTC. */ + atrtc_set(ts); + + settime.cmd = XENPF_settime64; + settime.u.settime64.mbz = 0; + settime.u.settime64.secs = ts->tv_sec; + settime.u.settime64.nsecs = ts->tv_nsec; + settime.u.settime64.system_time = + xen_fetch_vcpu_time(DPCPU_GET(vcpu_info)); + + ret = HYPERVISOR_platform_op(&settime); + ret = ret != 0 ? xen_translate_error(ret) : 0; + if (ret != 0 && bootverbose) + device_printf(dev, "failed to set Xen PV clock: %d\n", ret); + + return (ret); } /**