diff options
-rw-r--r-- | sys/dev/xen/timer/timer.c | 26 |
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); } /** |