aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/xen/timer
diff options
context:
space:
mode:
authorRoger Pau Monné <royger@FreeBSD.org>2016-05-02 16:15:28 +0000
committerRoger Pau Monné <royger@FreeBSD.org>2016-05-02 16:15:28 +0000
commiteac636b0ce5cb889aa72628f18169cd58ba3697d (patch)
treee6bb1056ac662109e753a9a4803859f4245034b7 /sys/dev/xen/timer
parentf65466eb3a0ef389ed3be9fdfda660848a6bac34 (diff)
downloadsrc-eac636b0ce5cb889aa72628f18169cd58ba3697d.tar.gz
src-eac636b0ce5cb889aa72628f18169cd58ba3697d.zip
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
Notes
Notes: svn path=/head/; revision=298929
Diffstat (limited to 'sys/dev/xen/timer')
-rw-r--r--sys/dev/xen/timer/timer.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/sys/dev/xen/timer/timer.c b/sys/dev/xen/timer/timer.c
index 8bc740076655..8eecc6051d7a 100644
--- a/sys/dev/xen/timer/timer.c
+++ b/sys/dev/xen/timer/timer.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <xen/hypervisor.h>
#include <xen/interface/io/xenbus.h>
#include <xen/interface/vcpu.h>
+#include <xen/error.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
@@ -63,6 +64,8 @@ __FBSDID("$FreeBSD$");
#include <dev/xen/timer/timer.h>
+#include <isa/rtc.h>
+
#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);
}
/**