aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
}
/**