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); } /**