Index: sys/arch/xen/xen/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/xen/clock.c,v
retrieving revision 1.64
diff -p -u -r1.64 clock.c
--- sys/arch/xen/xen/clock.c	12 Jun 2016 09:08:09 -0000	1.64
+++ sys/arch/xen/xen/clock.c	29 Oct 2017 13:58:10 -0000
@@ -33,6 +33,7 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/lwp.h>
 #include <sys/time.h>
 #include <sys/timetc.h>
 #include <sys/timevar.h>
@@ -118,22 +119,29 @@ get_time_values_from_xen(struct cpu_info
 	KASSERT(mutex_owned(&tmutex));
 
 	do {
-		shadow->time_version = t->version;
+		if (1 & (shadow->time_version = t->version)) {
+			/* update in progress */
+			SPINLOCK_BACKOFF_HOOK();
+			continue;
+		}
 		xen_rmb();
 		shadow->tsc_stamp = t->tsc_timestamp;
 		shadow->system_time = t->system_time;
 		shadow->freq_mul = t->tsc_to_system_mul;
 		shadow->freq_shift = t->tsc_shift;
 		xen_rmb();
-	} while ((t->version & 1) || (shadow->time_version != t->version));
+	} while (shadow->time_version != t->version);
 	do {
-		tversion = HYPERVISOR_shared_info->wc_version;
+		if (1 & (tversion = HYPERVISOR_shared_info->wc_version)) {
+			/* update in progress */
+			SPINLOCK_BACKOFF_HOOK();
+			continue;
+		}
 		xen_rmb();
 		shadow->ts.tv_sec = HYPERVISOR_shared_info->wc_sec;
 		shadow->ts.tv_nsec = HYPERVISOR_shared_info->wc_nsec;
 		xen_rmb();
-	} while ((HYPERVISOR_shared_info->wc_version & 1) ||
-	    (tversion != HYPERVISOR_shared_info->wc_version));
+	} while (tversion != HYPERVISOR_shared_info->wc_version);
 }
 
 /*
@@ -228,6 +236,7 @@ xen_wall_time(struct timespec *wt)
 {
 	uint64_t nsec;
 
+	int bound = curlwp_bind();
 	struct cpu_info *ci = curcpu();
 	volatile struct shadow *shadow = &ci_shadow[ci->ci_cpuid];
 
@@ -243,6 +252,8 @@ xen_wall_time(struct timespec *wt)
 	} while (!time_values_up_to_date(ci));
 	mutex_exit(&tmutex);
 
+	curlwp_bindx(bound);
+
 	wt->tv_sec += nsec / 1000000000L;
 	wt->tv_nsec = nsec % 1000000000L;
 }
@@ -313,6 +324,7 @@ startrtclock(void)
 void
 xen_delay(unsigned int n)
 {
+	int bound = curlwp_bind();
 	struct cpu_info *ci = curcpu();
 	volatile struct shadow *shadow = &ci_shadow[ci->ci_cpuid];
 
@@ -335,8 +347,6 @@ xen_delay(unsigned int n)
 		cc2 = cpu_counter();
 		while (cc2 < when)
 			cc2 = cpu_counter();
-		
-		return;
 	} else {
 		uint64_t when;
 
@@ -352,6 +362,7 @@ xen_delay(unsigned int n)
 		}
 		mutex_exit(&tmutex);
 	}
+	curlwp_bindx(bound);
 }
 
 #ifdef DOM0OPS
@@ -400,12 +411,15 @@ xen_get_timecount(struct timecounter *tc
 {
 	uint64_t ns;
 
+	int bound = curlwp_bind();
 	struct cpu_info *ci = curcpu();
 
 	mutex_enter(&tmutex);
 	ns = get_vcpu_time(ci) - xen_clock_bias[ci->ci_cpuid];
 	mutex_exit(&tmutex);
 
+	curlwp_bindx(bound);
+
 	return (u_int)ns;
 }
 
@@ -422,6 +436,8 @@ xen_initclocks(void)
 	int err __diagused;
 	static bool tcdone = false;
 
+	/* XXX KASSERT whatever mechanism binds us to a CPU */
+
 	struct cpu_info *ci = curcpu();
 	volatile struct shadow *shadow = &ci_shadow[ci->ci_cpuid];
 
@@ -578,6 +594,7 @@ setstatclockrate(int arg)
 void
 idle_block(void)
 {
+	KASSERT(curlwp->l_pflag & LP_BOUND); /* idle loop thread */
 	KASSERT(curcpu()->ci_ipending == 0);
 	HYPERVISOR_block();
 }