Module Name:    src
Committed By:   bouyer
Date:           Sat Apr 18 15:06:18 UTC 2020

Modified Files:
        src/sys/arch/x86/include [bouyer-xenpvh]: cpu.h cpuvar.h
        src/sys/arch/x86/x86 [bouyer-xenpvh]: cpu.c mainbus.c
        src/sys/arch/xen/include [bouyer-xenpvh]: hypervisor.h xen.h
        src/sys/arch/xen/x86 [bouyer-xenpvh]: cpu.c hypervisor_machdep.c
            xen_ipi.c xen_mainbus.c
        src/sys/arch/xen/xen [bouyer-xenpvh]: evtchn.c hypervisor.c xen_clock.c

Log Message:
Add PVHVM multiprocessor support:
We need the hypervisor to be set up before cpus attaches.
Move hypervisor setup to a new function xen_hvm_init(), called at the
beggining of mainbus_attach(). This function searches the cfdata[] array
to see if the hypervisor device is enabled (so you can disable PV
support with
disable hypervisor
from userconf).
For HVM, ci_cpuid doens't match the virtual CPU index needed by Xen.
Introduce ci_vcpuid to cpu_info. Introduce xen_hvm_init_cpu(), to be
called for each CPU in in its context, which initialize ci_vcpuid and
ci_vcpu, and setup the event callback.
Change Xen code to use ci_vcpuid.

Do not call lapic_calibrate_timer() for VM_GUEST_XENPVHVM, we will use
Xen timers.

Don't call lapic_initclocks() from cpu_hatch(); instead set
x86_cpu_initclock_func to lapic_initclocks() in lapic_calibrate_timer(),
and call *(x86_cpu_initclock_func)() from cpu_hatch().
Also call x86_cpu_initclock_func from cpu_attach() for the boot CPU.
As x86_cpu_initclock_func is called for all CPUs, x86_initclock_func can
be a NOP for lapic timer.

Reorganize Xen code for x86_initclock_func/x86_cpu_initclock_func.
Move x86_cpu_idle_xen() to hypervisor_machdep.c


To generate a diff of this commit:
cvs rdiff -u -r1.117.4.5 -r1.117.4.6 src/sys/arch/x86/include/cpu.h
cvs rdiff -u -r1.51 -r1.51.10.1 src/sys/arch/x86/include/cpuvar.h
cvs rdiff -u -r1.181.4.2 -r1.181.4.3 src/sys/arch/x86/x86/cpu.c
cvs rdiff -u -r1.3.12.2 -r1.3.12.3 src/sys/arch/x86/x86/mainbus.c
cvs rdiff -u -r1.49.10.2 -r1.49.10.3 src/sys/arch/xen/include/hypervisor.h
cvs rdiff -u -r1.44 -r1.44.8.1 src/sys/arch/xen/include/xen.h
cvs rdiff -u -r1.133 -r1.133.4.1 src/sys/arch/xen/x86/cpu.c
cvs rdiff -u -r1.36.8.3 -r1.36.8.4 src/sys/arch/xen/x86/hypervisor_machdep.c
cvs rdiff -u -r1.35.6.3 -r1.35.6.4 src/sys/arch/xen/x86/xen_ipi.c
cvs rdiff -u -r1.6.12.2 -r1.6.12.3 src/sys/arch/xen/x86/xen_mainbus.c
cvs rdiff -u -r1.88.2.4 -r1.88.2.5 src/sys/arch/xen/xen/evtchn.c
cvs rdiff -u -r1.73.2.5 -r1.73.2.6 src/sys/arch/xen/xen/hypervisor.c
cvs rdiff -u -r1.1.2.2 -r1.1.2.3 src/sys/arch/xen/xen/xen_clock.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x86/include/cpu.h
diff -u src/sys/arch/x86/include/cpu.h:1.117.4.5 src/sys/arch/x86/include/cpu.h:1.117.4.6
--- src/sys/arch/x86/include/cpu.h:1.117.4.5	Thu Apr 16 17:44:54 2020
+++ src/sys/arch/x86/include/cpu.h	Sat Apr 18 15:06:18 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.117.4.5 2020/04/16 17:44:54 bouyer Exp $	*/
+/*	$NetBSD: cpu.h,v 1.117.4.6 2020/04/18 15:06:18 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1990 The Regents of the University of California.
@@ -223,6 +223,7 @@ struct cpu_info {
 	uint32_t 	ci_flags __aligned(64);/* general flags */
 	uint32_t 	ci_acpiid;	/* our ACPI/MADT ID */
 	uint32_t 	ci_initapicid;	/* our initial APIC ID */
+	uint32_t 	ci_vcpuid;	/* our CPU id for hypervisor */
 	cpuid_t		ci_cpuid;	/* our CPU ID */
 	struct cpu_info	*ci_next;	/* next cpu */
 
@@ -530,6 +531,7 @@ void	lwp_trampoline(void);
 void	xen_startrtclock(void);
 void	xen_delay(unsigned int);
 void	xen_initclocks(void);
+void	xen_cpu_initclocks(void);
 void	xen_suspendclocks(struct cpu_info *);
 void	xen_resumeclocks(struct cpu_info *);
 #endif /* XEN */

Index: src/sys/arch/x86/include/cpuvar.h
diff -u src/sys/arch/x86/include/cpuvar.h:1.51 src/sys/arch/x86/include/cpuvar.h:1.51.10.1
--- src/sys/arch/x86/include/cpuvar.h:1.51	Mon Feb 11 14:59:32 2019
+++ src/sys/arch/x86/include/cpuvar.h	Sat Apr 18 15:06:18 2020
@@ -1,4 +1,4 @@
-/* 	$NetBSD: cpuvar.h,v 1.51 2019/02/11 14:59:32 cherry Exp $ */
+/* 	$NetBSD: cpuvar.h,v 1.51.10.1 2020/04/18 15:06:18 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2000, 2007 The NetBSD Foundation, Inc.
@@ -99,6 +99,7 @@ struct cpufeature_attach_args {
 #include <sys/kcpuset.h>
 #if defined(_KERNEL_OPT)
 #include "opt_multiprocessor.h"
+#include "opt_xen.h"
 #endif /* defined(_KERNEL_OPT) */
 
 extern int (*x86_ipi)(int, int, int);
@@ -115,7 +116,7 @@ void cpu_init_first(void);
 void x86_cpu_idle_init(void);
 void x86_cpu_idle_halt(void);
 void x86_cpu_idle_mwait(void);
-#ifdef XENPV
+#ifdef XEN
 void x86_cpu_idle_xen(void);
 #endif
 

Index: src/sys/arch/x86/x86/cpu.c
diff -u src/sys/arch/x86/x86/cpu.c:1.181.4.2 src/sys/arch/x86/x86/cpu.c:1.181.4.3
--- src/sys/arch/x86/x86/cpu.c:1.181.4.2	Thu Apr 16 09:45:56 2020
+++ src/sys/arch/x86/x86/cpu.c	Sat Apr 18 15:06:18 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.c,v 1.181.4.2 2020/04/16 09:45:56 bouyer Exp $	*/
+/*	$NetBSD: cpu.c,v 1.181.4.3 2020/04/18 15:06:18 bouyer Exp $	*/
 
 /*
  * Copyright (c) 2000-2012 NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.181.4.2 2020/04/16 09:45:56 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.181.4.3 2020/04/18 15:06:18 bouyer Exp $");
 
 #include "opt_ddb.h"
 #include "opt_mpbios.h"		/* for MPDEBUG */
@@ -89,6 +89,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.18
 
 #include "acpica.h"		/* for NACPICA, for mp_verbose */
 
+#include <x86/machdep.h>
 #include <machine/cpufunc.h>
 #include <machine/cpuvar.h>
 #include <machine/pmap.h>
@@ -130,6 +131,10 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.18
 #endif
 #endif
 
+#ifdef XEN
+#include <xen/hypervisor.h>
+#endif
+
 static int	cpu_match(device_t, cfdata_t, void *);
 static void	cpu_attach(device_t, device_t, void *);
 static void	cpu_defer(device_t);
@@ -442,7 +447,8 @@ cpu_attach(device_t parent, device_t sel
 			/* Enable lapic. */
 			lapic_enable();
 			lapic_set_lvt();
-			lapic_calibrate_timer(ci);
+			if (vm_guest != VM_GUEST_XENPVHVM)
+				lapic_calibrate_timer(ci);
 		}
 #endif
 		/* Make sure DELAY() is initialized. */
@@ -459,6 +465,10 @@ cpu_attach(device_t parent, device_t sel
 		cpu_identify(ci);
 		x86_errata();
 		x86_cpu_idle_init();
+		(*x86_cpu_initclock_func)();
+#ifdef XENPVHVM
+		xen_hvm_init_cpu(ci);
+#endif
 		break;
 
 	case CPU_ROLE_BP:
@@ -466,6 +476,10 @@ cpu_attach(device_t parent, device_t sel
 		cpu_identify(ci);
 		x86_errata();
 		x86_cpu_idle_init();
+#ifdef XENPVHVM
+		xen_hvm_init_cpu(ci);
+#endif
+		(*x86_cpu_initclock_func)();
 		break;
 
 #ifdef MULTIPROCESSOR
@@ -971,7 +985,6 @@ cpu_hatch(void *v)
 #if NLAPIC > 0
 	lapic_enable();
 	lapic_set_lvt();
-	lapic_initclocks();
 #endif
 
 	fpuinit(ci);
@@ -984,6 +997,10 @@ cpu_hatch(void *v)
 	 * above.
 	 */
 	cpu_init(ci);
+#ifdef XENPVHVM
+	xen_hvm_init_cpu(ci);
+#endif
+	(*x86_cpu_initclock_func)();
 	cpu_get_tsc_freq(ci);
 
 	s = splhigh();

Index: src/sys/arch/x86/x86/mainbus.c
diff -u src/sys/arch/x86/x86/mainbus.c:1.3.12.2 src/sys/arch/x86/x86/mainbus.c:1.3.12.3
--- src/sys/arch/x86/x86/mainbus.c:1.3.12.2	Thu Apr 16 08:46:35 2020
+++ src/sys/arch/x86/x86/mainbus.c	Sat Apr 18 15:06:18 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: mainbus.c,v 1.3.12.2 2020/04/16 08:46:35 bouyer Exp $ */
+/* $NetBSD: mainbus.c,v 1.3.12.3 2020/04/18 15:06:18 bouyer Exp $ */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.3.12.2 2020/04/16 08:46:35 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.3.12.3 2020/04/18 15:06:18 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -217,6 +217,10 @@ mainbus_attach(device_t parent, device_t
 	aprint_naive("\n");
 	aprint_normal("\n");
 
+#if defined(XENPVHVM)
+	xen_hvm_init(); /* before attaching CPUs */
+#endif
+
 #if defined(XENPV)
 	if (xendomain_is_dom0()) {
 #endif /* XENPV */
@@ -226,6 +230,10 @@ mainbus_attach(device_t parent, device_t
 	}
 #endif /* XENPV */
 #if defined(XEN)
+	/*
+	 * before isa/pci probe, so that PV devices are not probed again
+	 * as emulated
+	 */
 	xen_mainbus_attach(parent, self, aux);
 #endif
 #if defined(__i386__) && !defined(XENPV)

Index: src/sys/arch/xen/include/hypervisor.h
diff -u src/sys/arch/xen/include/hypervisor.h:1.49.10.2 src/sys/arch/xen/include/hypervisor.h:1.49.10.3
--- src/sys/arch/xen/include/hypervisor.h:1.49.10.2	Thu Apr 16 08:46:35 2020
+++ src/sys/arch/xen/include/hypervisor.h	Sat Apr 18 15:06:18 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: hypervisor.h,v 1.49.10.2 2020/04/16 08:46:35 bouyer Exp $	*/
+/*	$NetBSD: hypervisor.h,v 1.49.10.3 2020/04/18 15:06:18 bouyer Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -58,6 +58,10 @@
 #include "isa.h"
 #include "pci.h"
 
+struct cpu_info;
+
+int xen_hvm_init(void);
+int xen_hvm_init_cpu(struct cpu_info *);
 void xen_mainbus_attach(device_t, device_t, void *);
 
 struct hypervisor_attach_args {

Index: src/sys/arch/xen/include/xen.h
diff -u src/sys/arch/xen/include/xen.h:1.44 src/sys/arch/xen/include/xen.h:1.44.8.1
--- src/sys/arch/xen/include/xen.h:1.44	Thu May  9 17:09:50 2019
+++ src/sys/arch/xen/include/xen.h	Sat Apr 18 15:06:18 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: xen.h,v 1.44 2019/05/09 17:09:50 bouyer Exp $	*/
+/*	$NetBSD: xen.h,v 1.44.8.1 2020/04/18 15:06:18 bouyer Exp $	*/
 
 /*
  *
@@ -70,8 +70,6 @@ void	xenevt_event(int);
 void	xenevt_setipending(int, int);
 void	xenevt_notify(void);
 
-void	idle_block(void);
-
 /* xen_machdep.c */
 void	sysctl_xen_suspend_setup(void);
 

Index: src/sys/arch/xen/x86/cpu.c
diff -u src/sys/arch/xen/x86/cpu.c:1.133 src/sys/arch/xen/x86/cpu.c:1.133.4.1
--- src/sys/arch/xen/x86/cpu.c:1.133	Mon Feb 24 12:20:29 2020
+++ src/sys/arch/xen/x86/cpu.c	Sat Apr 18 15:06:18 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.c,v 1.133 2020/02/24 12:20:29 rin Exp $	*/
+/*	$NetBSD: cpu.c,v 1.133.4.1 2020/04/18 15:06:18 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.133 2020/02/24 12:20:29 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.133.4.1 2020/04/18 15:06:18 bouyer Exp $");
 
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
@@ -317,7 +317,7 @@ static int
 vcpu_is_up(struct cpu_info *ci)
 {
 	KASSERT(ci != NULL);
-	return HYPERVISOR_vcpu_op(VCPUOP_is_up, ci->ci_cpuid, NULL);
+	return HYPERVISOR_vcpu_op(VCPUOP_is_up, ci->ci_vcpuid, NULL);
 }
 
 static void
@@ -390,6 +390,7 @@ cpu_attach_common(device_t parent, devic
 	sc->sc_info = ci;
 	ci->ci_dev = self;
 	ci->ci_cpuid = cpunum;
+	ci->ci_vcpuid = cpunum;
 
 	KASSERT(HYPERVISOR_shared_info != NULL);
 	KASSERT(cpunum < XEN_LEGACY_MAX_VCPUS);
@@ -455,12 +456,14 @@ cpu_attach_common(device_t parent, devic
 		atomic_or_32(&ci->ci_flags, CPUF_SP);
 		cpu_identify(ci);
 		x86_cpu_idle_init();
+		xen_cpu_initclocks();
 		break;
 
 	case CPU_ROLE_BP:
 		atomic_or_32(&ci->ci_flags, CPUF_BSP);
 		cpu_identify(ci);
 		x86_cpu_idle_init();
+		xen_cpu_initclocks();
 		break;
 
 	case CPU_ROLE_AP:
@@ -723,7 +726,7 @@ cpu_hatch(void *v)
 
 	xen_ipi_init();
 
-	xen_initclocks();
+	xen_cpu_initclocks();
 
 #ifdef __x86_64__
 	fpuinit(ci);
@@ -764,7 +767,7 @@ cpu_debug_dump(void)
 		db_printf("%p	%s	%ld	%x	%x	%10p\n",
 		    ci,
 		    ci->ci_dev == NULL ? "BOOT" : device_xname(ci->ci_dev),
-		    (long)ci->ci_cpuid,
+		    (long)ci->ci_vcpuid,
 		    ci->ci_flags, ci->ci_ipis,
 		    ci->ci_curlwp);
 	}
@@ -1011,7 +1014,7 @@ mp_cpu_start(struct cpu_info *ci, vaddr_
 #endif
 
 	/* Initialise the given vcpu to execute cpu_hatch(ci); */
-	if ((hyperror = HYPERVISOR_vcpu_op(VCPUOP_initialise, ci->ci_cpuid, &vcpuctx))) {
+	if ((hyperror = HYPERVISOR_vcpu_op(VCPUOP_initialise, ci->ci_vcpuid, &vcpuctx))) {
 		aprint_error(": context initialisation failed. errno = %d\n", hyperror);
 		return hyperror;
 	}
@@ -1019,12 +1022,12 @@ mp_cpu_start(struct cpu_info *ci, vaddr_
 	/* Start it up */
 
 	/* First bring it down */
-	if ((hyperror = HYPERVISOR_vcpu_op(VCPUOP_down, ci->ci_cpuid, NULL))) {
+	if ((hyperror = HYPERVISOR_vcpu_op(VCPUOP_down, ci->ci_vcpuid, NULL))) {
 		aprint_error(": VCPUOP_down hypervisor command failed. errno = %d\n", hyperror);
 		return hyperror;
 	}
 
-	if ((hyperror = HYPERVISOR_vcpu_op(VCPUOP_up, ci->ci_cpuid, NULL))) {
+	if ((hyperror = HYPERVISOR_vcpu_op(VCPUOP_up, ci->ci_vcpuid, NULL))) {
 		aprint_error(": VCPUOP_up hypervisor command failed. errno = %d\n", hyperror);
 		return hyperror;
 	}
@@ -1086,21 +1089,6 @@ cpu_get_tsc_freq(struct cpu_info *ci)
 	ci->ci_data.cpu_cc_freq = freq;
 }
 
-void
-x86_cpu_idle_xen(void)
-{
-	struct cpu_info *ci = curcpu();
-	
-	KASSERT(ci->ci_ilevel == IPL_NONE);
-
-	x86_disable_intr();
-	if (!__predict_false(ci->ci_want_resched)) {
-		idle_block();
-	} else {
-		x86_enable_intr();
-	}
-}
-
 /*
  * Loads pmap for the current CPU.
  */

Index: src/sys/arch/xen/x86/hypervisor_machdep.c
diff -u src/sys/arch/xen/x86/hypervisor_machdep.c:1.36.8.3 src/sys/arch/xen/x86/hypervisor_machdep.c:1.36.8.4
--- src/sys/arch/xen/x86/hypervisor_machdep.c:1.36.8.3	Thu Apr 16 17:50:52 2020
+++ src/sys/arch/xen/x86/hypervisor_machdep.c	Sat Apr 18 15:06:18 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: hypervisor_machdep.c,v 1.36.8.3 2020/04/16 17:50:52 bouyer Exp $	*/
+/*	$NetBSD: hypervisor_machdep.c,v 1.36.8.4 2020/04/18 15:06:18 bouyer Exp $	*/
 
 /*
  *
@@ -54,7 +54,7 @@
 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hypervisor_machdep.c,v 1.36.8.3 2020/04/16 17:50:52 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hypervisor_machdep.c,v 1.36.8.4 2020/04/18 15:06:18 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -66,6 +66,9 @@ __KERNEL_RCSID(0, "$NetBSD: hypervisor_m
 #include <machine/vmparam.h>
 #include <machine/pmap.h>
 
+#include <x86/machdep.h>
+#include <x86/cpuvar.h>
+
 #include <xen/xen.h>
 #include <xen/intr.h>
 #include <xen/hypervisor.h>
@@ -315,8 +318,8 @@ hypervisor_send_event(struct cpu_info *c
 		hypervisor_force_callback();
 	} else {
 		if (__predict_false(xen_send_ipi(ci, XEN_IPI_HVCB))) {
-			panic("xen_send_ipi(cpu%d, XEN_IPI_HVCB) failed\n",
-			    (int) ci->ci_cpuid);
+			panic("xen_send_ipi(cpu%d id %d, XEN_IPI_HVCB) failed\n",
+			    (int) ci->ci_cpuid, ci->ci_vcpuid);
 		}
 	}
 }
@@ -422,8 +425,8 @@ hypervisor_set_ipending(uint32_t imask, 
 	if (__predict_false(ci != curcpu())) {
 		if (xen_send_ipi(ci, XEN_IPI_HVCB)) {
 			panic("hypervisor_set_ipending: "
-			    "xen_send_ipi(cpu%d, XEN_IPI_HVCB) failed\n",
-			    (int) ci->ci_cpuid);
+			    "xen_send_ipi(cpu%d id %d, XEN_IPI_HVCB) failed\n",
+			    (int) ci->ci_cpuid, ci->ci_vcpuid);
 		}
 	}
 }
@@ -450,6 +453,35 @@ hypervisor_machdep_resume(void)
 #endif
 }
 
+/*
+ * idle_block()
+ *
+ *	Called from the idle loop when we have nothing to do but wait
+ *	for an interrupt.
+ */
+static void
+idle_block(void)
+{
+	KASSERT(curcpu()->ci_ipending == 0);
+	HYPERVISOR_block();
+	KASSERT(curcpu()->ci_ipending == 0);
+}
+
+void
+x86_cpu_idle_xen(void)
+{
+	struct cpu_info *ci = curcpu();
+	
+	KASSERT(ci->ci_ilevel == IPL_NONE);
+
+	x86_disable_intr();
+	if (!__predict_false(ci->ci_want_resched)) {
+		idle_block();
+	} else {
+		x86_enable_intr();
+	}
+}
+
 #ifdef XENPV
 /*
  * Generate the p2m_frame_list_list table,

Index: src/sys/arch/xen/x86/xen_ipi.c
diff -u src/sys/arch/xen/x86/xen_ipi.c:1.35.6.3 src/sys/arch/xen/x86/xen_ipi.c:1.35.6.4
--- src/sys/arch/xen/x86/xen_ipi.c:1.35.6.3	Thu Apr 16 08:46:35 2020
+++ src/sys/arch/xen/x86/xen_ipi.c	Sat Apr 18 15:06:18 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: xen_ipi.c,v 1.35.6.3 2020/04/16 08:46:35 bouyer Exp $ */
+/* $NetBSD: xen_ipi.c,v 1.35.6.4 2020/04/18 15:06:18 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2011, 2019 The NetBSD Foundation, Inc.
@@ -33,10 +33,10 @@
 
 /* 
  * Based on: x86/ipi.c
- * __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.35.6.3 2020/04/16 08:46:35 bouyer Exp $");
+ * __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.35.6.4 2020/04/18 15:06:18 bouyer Exp $");
  */
 
-__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.35.6.3 2020/04/16 08:46:35 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.35.6.4 2020/04/18 15:06:18 bouyer Exp $");
 
 #include "opt_ddb.h"
 
@@ -132,7 +132,7 @@ xen_ipi_init(void)
 
 	ci = curcpu();
 
-	vcpu = ci->ci_cpuid;
+	vcpu = ci->ci_vcpuid;
 	KASSERT(vcpu < XEN_LEGACY_MAX_VCPUS);
 
 	evtchn = bind_vcpu_to_evtch(vcpu);
@@ -231,7 +231,7 @@ xen_ipi_halt(struct cpu_info *ci, struct
 {
 	KASSERT(ci == curcpu());
 	KASSERT(ci != NULL);
-	if (HYPERVISOR_vcpu_op(VCPUOP_down, ci->ci_cpuid, NULL)) {
+	if (HYPERVISOR_vcpu_op(VCPUOP_down, ci->ci_vcpuid, NULL)) {
 		panic("%s shutdown failed.\n", device_xname(ci->ci_dev));
 	}
 

Index: src/sys/arch/xen/x86/xen_mainbus.c
diff -u src/sys/arch/xen/x86/xen_mainbus.c:1.6.12.2 src/sys/arch/xen/x86/xen_mainbus.c:1.6.12.3
--- src/sys/arch/xen/x86/xen_mainbus.c:1.6.12.2	Thu Apr 16 17:46:44 2020
+++ src/sys/arch/xen/x86/xen_mainbus.c	Sat Apr 18 15:06:18 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: xen_mainbus.c,v 1.6.12.2 2020/04/16 17:46:44 bouyer Exp $	*/
+/*	$NetBSD: xen_mainbus.c,v 1.6.12.3 2020/04/18 15:06:18 bouyer Exp $	*/
 /*	NetBSD: mainbus.c,v 1.19 2017/05/23 08:54:39 nonaka Exp 	*/
 /*	NetBSD: mainbus.c,v 1.53 2003/10/27 14:11:47 junyoung Exp 	*/
 
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xen_mainbus.c,v 1.6.12.2 2020/04/16 17:46:44 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_mainbus.c,v 1.6.12.3 2020/04/18 15:06:18 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -131,7 +131,7 @@ xen_mainbus_attach(device_t parent, devi
 			config_found_ia(self, "ipmibus", &mba.mba_ipmi, 0);
 #endif
 	/* FALLTHROUGH */
-	case VM_GUEST_XENHVM:
+	case VM_GUEST_XENPVHVM:
 		mba.mba_haa.haa_busname = "hypervisor";
 		config_found_ia(self, "hypervisorbus",
 		    &mba.mba_haa, xen_mainbus_print);

Index: src/sys/arch/xen/xen/evtchn.c
diff -u src/sys/arch/xen/xen/evtchn.c:1.88.2.4 src/sys/arch/xen/xen/evtchn.c:1.88.2.5
--- src/sys/arch/xen/xen/evtchn.c:1.88.2.4	Thu Apr 16 08:46:36 2020
+++ src/sys/arch/xen/xen/evtchn.c	Sat Apr 18 15:06:18 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: evtchn.c,v 1.88.2.4 2020/04/16 08:46:36 bouyer Exp $	*/
+/*	$NetBSD: evtchn.c,v 1.88.2.5 2020/04/18 15:06:18 bouyer Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -54,7 +54,7 @@
 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: evtchn.c,v 1.88.2.4 2020/04/16 08:46:36 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: evtchn.c,v 1.88.2.5 2020/04/18 15:06:18 bouyer Exp $");
 
 #include "opt_xen.h"
 #include "isa.h"
@@ -564,7 +564,7 @@ bind_virq_to_evtch(int virq)
 	}
 
 	if (virq == VIRQ_TIMER) {
-		evtchn = virq_timer_to_evtch[ci->ci_cpuid];
+		evtchn = virq_timer_to_evtch[ci->ci_vcpuid];
 	} else {
 		evtchn = virq_to_evtch[virq];
 	}
@@ -573,7 +573,7 @@ bind_virq_to_evtch(int virq)
 	if (evtchn == -1) {
 		op.cmd = EVTCHNOP_bind_virq;
 		op.u.bind_virq.virq = virq;
-		op.u.bind_virq.vcpu = ci->ci_cpuid;
+		op.u.bind_virq.vcpu = ci->ci_vcpuid;
 		if (HYPERVISOR_event_channel_op(&op) != 0)
 			panic("Failed to bind virtual IRQ %d\n", virq);
 		evtchn = op.u.bind_virq.port;
@@ -581,7 +581,7 @@ bind_virq_to_evtch(int virq)
 
 	/* Set event channel */
 	if (virq == VIRQ_TIMER) {
-		virq_timer_to_evtch[ci->ci_cpuid] = evtchn;
+		virq_timer_to_evtch[ci->ci_vcpuid] = evtchn;
 	} else {
 		virq_to_evtch[virq] = evtchn;
 	}
@@ -603,7 +603,7 @@ unbind_virq_from_evtch(int virq)
 	struct cpu_info *ci = curcpu();
 
 	if (virq == VIRQ_TIMER) {
-		evtchn = virq_timer_to_evtch[ci->ci_cpuid];
+		evtchn = virq_timer_to_evtch[ci->ci_vcpuid];
 	}
 	else {
 		evtchn = virq_to_evtch[virq];
@@ -623,7 +623,7 @@ unbind_virq_from_evtch(int virq)
 			panic("Failed to unbind virtual IRQ %d\n", virq);
 
 		if (virq == VIRQ_TIMER) {
-			virq_timer_to_evtch[ci->ci_cpuid] = -1;
+			virq_timer_to_evtch[ci->ci_vcpuid] = -1;
 		} else {
 			virq_to_evtch[virq] = -1;
 		}

Index: src/sys/arch/xen/xen/hypervisor.c
diff -u src/sys/arch/xen/xen/hypervisor.c:1.73.2.5 src/sys/arch/xen/xen/hypervisor.c:1.73.2.6
--- src/sys/arch/xen/xen/hypervisor.c:1.73.2.5	Thu Apr 16 20:21:04 2020
+++ src/sys/arch/xen/xen/hypervisor.c	Sat Apr 18 15:06:18 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: hypervisor.c,v 1.73.2.5 2020/04/16 20:21:04 bouyer Exp $ */
+/* $NetBSD: hypervisor.c,v 1.73.2.6 2020/04/18 15:06:18 bouyer Exp $ */
 
 /*
  * Copyright (c) 2005 Manuel Bouyer.
@@ -53,7 +53,7 @@
 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hypervisor.c,v 1.73.2.5 2020/04/16 20:21:04 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hypervisor.c,v 1.73.2.6 2020/04/18 15:06:18 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -73,7 +73,8 @@ __KERNEL_RCSID(0, "$NetBSD: hypervisor.c
 #include <xen/hypervisor.h>
 #include <xen/evtchn.h>
 #include <xen/include/public/version.h>
-#include <x86//pio.h>
+#include <x86/pio.h>
+#include <x86/machdep.h>
 
 #include <sys/cpu.h>
 #include <sys/dirent.h>
@@ -184,11 +185,9 @@ extern struct xenstore_domain_interface 
 volatile shared_info_t *HYPERVISOR_shared_info __read_mostly;
 paddr_t HYPERVISOR_shared_info_pa;
 union start_info_union start_info_union __aligned(PAGE_SIZE);
-#endif
-
-extern void (*delay_func)(unsigned int);
-extern void (*initclock_func)(void);
 
+static int xen_hvm_vec = 0;
+#endif
 
 int xen_version;
 
@@ -205,60 +204,70 @@ enum {
 	XMI_UNPLUG_IDE_EXCEPT_PRI_MASTER = 0x04
 }; 
 
-/*
- * Probe for the hypervisor; always succeeds.
- */
+
+#ifdef XENPVHVM
+
+static bool
+xen_check_hypervisordev(void)
+{
+	extern struct cfdata cfdata[];
+	for (int i = 0; cfdata[i].cf_name != NULL; i++) {
+		if (strcasecmp("hypervisor", cfdata[i].cf_name) == 0) {
+			switch(cfdata[i].cf_fstate) {
+			case FSTATE_NOTFOUND:
+			case FSTATE_FOUND:
+			case FSTATE_STAR:
+				printf("xen_check_hypervisordev: enabled\n");
+				return true;
+			default:
+				printf("xen_check_hypervisordev: disabled\n");
+				return false;
+			}
+		}
+	}
+	printf("xen_check_hypervisordev: notfound\n");
+	return 0;
+}
 int
-hypervisor_match(device_t parent, cfdata_t match, void *aux)
+xen_hvm_init(void)
 {
-	struct hypervisor_attach_args *haa = aux;
-
-	/* Attach path sanity check */
-	if (strncmp(haa->haa_busname, "hypervisor", sizeof("hypervisor")) != 0)
-		return 0;
+	extern vaddr_t hypercall_page;
+	u_int descs[4];
 
-#if defined(XENPVHVM)
 	/*
-	 * The strategy here is to setup hypercall and all PVHVM
-	 * interfaces on match, or fail to match.
-	 * Ideally this should happen under attach, but it's too late
-	 * then and there's no way to bailout.
+	 * We need to setup the HVM interfaces early, so that we can
+	 * properly setup the CPUs later (especially, all CPUs needs to
+	 * run x86_cpuid() locally to get their vcpuid.
 	 *
-	 * If match fails, hypervisor does not attach, and the domain
-	 * can boot with the minimal PC AT ISA configuration just
-	 * enough to attach wd(4) and mount the rootfs.
+	 * if everything goes fine, we switch vm_guest to VM_GUEST_XENPVHVM
 	 */
-	int vec;
-	extern vaddr_t hypercall_page;
 
-	if (vm_guest == VM_GUEST_XENHVM) {
-		aprint_normal("%s: Identified Guest XEN in HVM mode.\n",
-		    haa->haa_busname);
-
-		u_int descs[4];
-		x86_cpuid(XEN_CPUID_LEAF(2), descs);
-
-		/* 
-		 * Given 32 bytes per hypercall stub, and an optimistic number
-		 * of 100 hypercalls ( the current max is 55), there shouldn't
-		 * be any reason to spill over the arbitrary number of 1
-		 * hypercall page. This is what we allocate in locore.S
-		 * anyway. Make sure the allocation matches the registration.
-		 */
+	if (vm_guest != VM_GUEST_XENHVM)
+		return 0;
 
-		KASSERT(descs[0] == 1);
+	/* check if hypervisor was disabled with userconf */
+	if (!xen_check_hypervisordev())
+		return 0;
 
-		/* XXX: vtophys(&hypercall_page) */
-		wrmsr(descs[1], (uintptr_t)&hypercall_page - KERNBASE);
+	aprint_normal("Identified Guest XEN in HVM mode.\n");
 
-	} else {
-		return 0;
-	}
+	x86_cpuid(XEN_CPUID_LEAF(2), descs);
 
-	if (-1 != HYPERVISOR_xen_version(XENVER_version, NULL)) {
-		printf("%s: detected functional hypercall page.\n",
-		    haa->haa_busname);
+	/* 
+	 * Given 32 bytes per hypercall stub, and an optimistic number
+	 * of 100 hypercalls ( the current max is 55), there shouldn't
+	 * be any reason to spill over the arbitrary number of 1
+	 * hypercall page. This is what we allocate in locore.S
+	 * anyway. Make sure the allocation matches the registration.
+	 */
+
+	KASSERT(descs[0] == 1);
 
+	/* XXX: vtophys(&hypercall_page) */
+	wrmsr(descs[1], (uintptr_t)&hypercall_page - KERNBASE);
+
+	if (-1 != HYPERVISOR_xen_version(XENVER_version, NULL)) {
+		printf("Xen HVM: detected functional hypercall page.\n");
 		xen_init_features();
 	}
 
@@ -271,8 +280,8 @@ hypervisor_match(device_t parent, cfdata
 	xen_hvm_param.index = HVM_PARAM_STORE_PFN;
 	
 	if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
-		aprint_error("%s: Unable to obtain xenstore page address\n",
-		    haa->haa_busname);
+		aprint_error(
+		    "Xen HVM: Unable to obtain xenstore page address\n");
 		return 0;
 	}
 
@@ -286,8 +295,8 @@ hypervisor_match(device_t parent, cfdata
 	xen_hvm_param.index = HVM_PARAM_STORE_EVTCHN;
 
 	if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
-		aprint_error("%s: Unable to obtain xenstore event channel\n",
-		    haa->haa_busname);
+		aprint_error(
+		    "Xen HVM: Unable to obtain xenstore event channel\n");
 		return 0;
 	}
 
@@ -297,8 +306,8 @@ hypervisor_match(device_t parent, cfdata
 	xen_hvm_param.index = HVM_PARAM_CONSOLE_PFN;
 	
 	if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
-		aprint_error("%s: Unable to obtain xencons page address\n",
-		    haa->haa_busname);
+		aprint_error(
+		    "Xen HVM: Unable to obtain xencons page address\n");
 		return 0;
 	}
 
@@ -312,8 +321,8 @@ hypervisor_match(device_t parent, cfdata
 	xen_hvm_param.index = HVM_PARAM_CONSOLE_EVTCHN;
 
 	if ( HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
-		aprint_error("%s: Unable to obtain xencons event channel\n",
-		    haa->haa_busname);
+		aprint_error(
+		    "Xen HVM: Unable to obtain xencons event channel\n");
 		return 0;
 	}
 
@@ -328,8 +337,8 @@ hypervisor_match(device_t parent, cfdata
 	};
 
 	if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xmap) < 0) {
-		aprint_error("%s: Unable to register HYPERVISOR_shared_info\n",
-		    haa->haa_busname);
+		aprint_error(
+		    "Xen HVM: Unable to register HYPERVISOR_shared_info\n");
 		return 0;
 	}
 
@@ -337,8 +346,6 @@ hypervisor_match(device_t parent, cfdata
 	pmap_kenter_pa((vaddr_t) HYPERVISOR_shared_info,
 	    HYPERVISOR_shared_info_pa, VM_PROT_READ|VM_PROT_WRITE, 0);
 
-	cpu_info_primary.ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[0];
-
 	/*
 	 * First register callback: here's why
 	 * http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=7b5b8ca7dffde866d851f0b87b994e0b13e5b867
@@ -349,65 +356,121 @@ hypervisor_match(device_t parent, cfdata
 	 * without it.
 	 */
 	if (!xen_feature(XENFEAT_hvm_callback_vector)) {
-		aprint_error("%s: XENFEAT_hvm_callback_vector"
-		    "not available, cannot proceed", haa->haa_busname);
-		
+		aprint_error("Xen HVM: XENFEAT_hvm_callback_vector"
+		    "not available, cannot proceed");
 		return 0;
 	}
 
-	/* Register event callback handler. */
+	/*
+	 * prepare vector.
+	 * We don't really care where it is, as long as it's free
+	 */
+	xen_hvm_vec = idt_vec_alloc(129, 255);
+	idt_vec_set(xen_hvm_vec, &IDTVEC(hypervisor_pvhvm_callback));
 
-	/* We don't really care where it is, as long as it's free */
-	vec = idt_vec_alloc(129, 255);
+	events_default_setup();
 
-	idt_vec_set(vec, &IDTVEC(hypervisor_pvhvm_callback));
+	delay_func = xen_delay;
+	x86_initclock_func = xen_initclocks;
+	x86_cpu_initclock_func = xen_cpu_initclocks;
+	x86_cpu_idle_set(x86_cpu_idle_xen, "xen", true);
+	vm_guest = VM_GUEST_XENPVHVM; /* Be more specific */
+	return 1;
+}
 
-	cpu_init_idt(); /* XXX remove and use only native one below ? */
+int
+xen_hvm_init_cpu(struct cpu_info *ci)
+{
+	u_int32_t descs[4];
+	struct xen_hvm_param xen_hvm_param;
 
-	xen_hvm_param.domid = DOMID_SELF;
-	xen_hvm_param.index = HVM_PARAM_CALLBACK_IRQ;
+	if (vm_guest != VM_GUEST_XENPVHVM)
+		return 0;
 
-	/* val[63:56] = 2, val[7:0] = vec */
-	xen_hvm_param.value = ((int64_t)0x2 << 56) | vec;
+	KASSERT(ci == curcpu());
 
-	if (HYPERVISOR_hvm_op(HVMOP_set_param, &xen_hvm_param) < 0) {
-		aprint_error("%s: Unable to register event callback vector\n",
-		    haa->haa_busname);
+	descs[0] = 0;
+	x86_cpuid(XEN_CPUID_LEAF(4), descs);
+	if (!(descs[0] & XEN_HVM_CPUID_VCPU_ID_PRESENT)) {
+		aprint_error_dev(ci->ci_dev, "Xen HVM: can't get VCPU id\n");
+		vm_guest = VM_GUEST_XENHVM;
 		return 0;
 	}
+	printf("cpu %s ci_acpiid %d vcpuid %d domid %d\n",
+	    device_xname(ci->ci_dev), ci->ci_acpiid, descs[1], descs[2]);
+
+	ci->ci_vcpuid = descs[1];
+	ci->ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[ci->ci_vcpuid];
+
+	/* Register event callback handler. */
 
-	/* Print out value. */
 	xen_hvm_param.domid = DOMID_SELF;
 	xen_hvm_param.index = HVM_PARAM_CALLBACK_IRQ;
-	xen_hvm_param.value = 0;
 
-	if (HYPERVISOR_hvm_op(HVMOP_get_param, &xen_hvm_param) < 0) {
-		printf("%s: Unable to get event callback vector\n",
-		    haa->haa_busname);
+	/* val[63:56] = 2, val[7:0] = vec */
+	xen_hvm_param.value = ((int64_t)0x2 << 56) | xen_hvm_vec;
+
+	if (HYPERVISOR_hvm_op(HVMOP_set_param, &xen_hvm_param) < 0) {
+		aprint_error_dev(ci->ci_dev,
+		    "Xen HVM: Unable to register event callback vector\n");
+		vm_guest = VM_GUEST_XENHVM;
 		return 0;
 	}
 
-	/*
-	 * Afterwards vector callback is done, register VCPU info
-	 * page. Here's why:
-	 * http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=7b5b8ca7dffde866d851f0b87b994e0b13e5b867
-	 * XXX: Ideally this should happen at vcpu attach.
-	 */
-	struct vcpu_register_vcpu_info vrvi;
+	return 1;
+}
 
-	paddr_t vcpu_info_pa = HYPERVISOR_shared_info_pa +
-	    offsetof(struct shared_info, vcpu_info);
-	
-	vrvi.mfn = atop(vcpu_info_pa);
-	vrvi.offset = vcpu_info_pa - trunc_page(vcpu_info_pa);
+#endif /* XENPVHVM */
+
+/*
+ * Probe for the hypervisor; always succeeds.
+ */
+int
+hypervisor_match(device_t parent, cfdata_t match, void *aux)
+{
+	struct hypervisor_attach_args *haa = aux;
 
-	if (HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, curcpu()->ci_cpuid /* VCPU0 */,
-		&vrvi) < 0) {
-		aprint_error("%s: Unable to register vcpu info page\n",
-		    haa->haa_busname);
+	/* Attach path sanity check */
+	if (strncmp(haa->haa_busname, "hypervisor", sizeof("hypervisor")) != 0)
 		return 0;
-	}
 
+
+#ifdef XENPVHVM
+	if (vm_guest != VM_GUEST_XENPVHVM)
+		return 0;
+#endif
+	/* If we got here, it must mean we matched */
+	return 1;
+}
+
+#ifdef MULTIPROCESSOR
+static int
+hypervisor_vcpu_print(void *aux, const char *parent)
+{
+	/* Unconfigured cpus are ignored quietly. */
+	return (QUIET);
+}
+#endif /* MULTIPROCESSOR */
+
+/*
+ * Attach the hypervisor.
+ */
+void
+hypervisor_attach(device_t parent, device_t self, void *aux)
+{
+
+#if NPCI >0
+#ifdef PCI_BUS_FIXUP
+	int pci_maxbus = 0;
+#endif
+#endif /* NPCI */
+	union hypervisor_attach_cookie hac;
+	char xen_extra_version[XEN_EXTRAVERSION_LEN];
+	static char xen_version_string[20];
+	int rc;
+	const struct sysctlnode *node = NULL;
+
+#ifdef XENPVHVM
 	/*
 	 * Set the boot device to xbd0a.
 	 * We claim this is a reasonable default which is picked up
@@ -425,7 +488,7 @@ hypervisor_match(device_t parent, cfdata
 	bi.common.len = sizeof(struct btinfo_rootdevice);
 
 	/* From i386/multiboot.c */
-	/*	$NetBSD: hypervisor.c,v 1.73.2.5 2020/04/16 20:21:04 bouyer Exp $	*/
+	/*	$NetBSD: hypervisor.c,v 1.73.2.6 2020/04/18 15:06:18 bouyer Exp $	*/
 	int i, len;
 	vaddr_t data;
 	extern struct bootinfo	bootinfo;
@@ -448,47 +511,9 @@ hypervisor_match(device_t parent, cfdata
 	if (inw(XEN_MAGIC_IOPORT) == XMI_MAGIC) {
 		outw(XEN_MAGIC_IOPORT, XMI_UNPLUG_IDE_DISKS | XMI_UNPLUG_NICS);
 	} else {
-		aprint_error("%s: Unable to disable emulated devices\n",
-		    haa->haa_busname);
+		aprint_error_dev(self, "Unable to disable emulated devices\n");
 	}
-	events_default_setup();
-	delay_func = xen_delay;
-	initclock_func = xen_initclocks;
-	vm_guest = VM_GUEST_XENPVHVM; /* Be more specific */
-
 #endif /* XENPVHVM */
-
-	/* If we got here, it must mean we matched */
-	return 1;
-}
-
-#ifdef MULTIPROCESSOR
-static int
-hypervisor_vcpu_print(void *aux, const char *parent)
-{
-	/* Unconfigured cpus are ignored quietly. */
-	return (QUIET);
-}
-#endif /* MULTIPROCESSOR */
-
-/*
- * Attach the hypervisor.
- */
-void
-hypervisor_attach(device_t parent, device_t self, void *aux)
-{
-
-#if NPCI >0
-#ifdef PCI_BUS_FIXUP
-	int pci_maxbus = 0;
-#endif
-#endif /* NPCI */
-	union hypervisor_attach_cookie hac;
-	char xen_extra_version[XEN_EXTRAVERSION_LEN];
-	static char xen_version_string[20];
-	int rc;
-	const struct sysctlnode *node = NULL;
-
 	xenkernfs_init();
 
 	xen_version = HYPERVISOR_xen_version(XENVER_version, NULL);

Index: src/sys/arch/xen/xen/xen_clock.c
diff -u src/sys/arch/xen/xen/xen_clock.c:1.1.2.2 src/sys/arch/xen/xen/xen_clock.c:1.1.2.3
--- src/sys/arch/xen/xen/xen_clock.c:1.1.2.2	Thu Apr 16 20:21:44 2020
+++ src/sys/arch/xen/xen/xen_clock.c	Sat Apr 18 15:06:18 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: xen_clock.c,v 1.1.2.2 2020/04/16 20:21:44 bouyer Exp $	*/
+/*	$NetBSD: xen_clock.c,v 1.1.2.3 2020/04/18 15:06:18 bouyer Exp $	*/
 
 /*-
  * Copyright (c) 2017, 2018 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xen_clock.c,v 1.1.2.2 2020/04/16 20:21:44 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_clock.c,v 1.1.2.3 2020/04/18 15:06:18 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -115,20 +115,6 @@ static int	sysctl_xen_timepush(SYSCTLFN_
 #endif
 
 /*
- * idle_block()
- *
- *	Called from the idle loop when we have nothing to do but wait
- *	for an interrupt.
- */
-void
-idle_block(void)
-{
-	KASSERT(curcpu()->ci_ipending == 0);
-	HYPERVISOR_block();
-	KASSERT(curcpu()->ci_ipending == 0);
-}
-
-/*
  * xen_rdtsc()
  *
  *	Read the local pCPU's tsc.
@@ -521,6 +507,11 @@ xen_delay(unsigned n)
 	/* Bind to the CPU so we don't compare tsc on different CPUs.  */
 	bound = curlwp_bind();
 
+	if (curcpu()->ci_vcpu == NULL) {
+		curlwp_bindx(bound);
+		return;
+	}
+
 	/* Short wait (<500us) or long wait?  */
 	if (n < 500000) {
 		/*
@@ -655,7 +646,7 @@ xen_resumeclocks(struct cpu_info *ci)
 	/* Disarm the periodic timer on Xen>=3.1 which is allegedly buggy.  */
 	if (XEN_MAJOR(xen_version) > 3 || XEN_MINOR(xen_version) > 0) {
 		error = HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer,
-		    ci->ci_cpuid, NULL);
+		    ci->ci_vcpuid, NULL);
 		KASSERT(error == 0);
 	}
 
@@ -738,12 +729,12 @@ again:
 }
 
 /*
- * xen_initclocks()
+ * xen_cpu_initclocks()
  *
  *	Initialize the Xen clocks on the current CPU.
  */
 void
-xen_initclocks(void)
+xen_cpu_initclocks(void)
 {
 	struct cpu_info *ci = curcpu();
 
@@ -751,15 +742,6 @@ xen_initclocks(void)
 	if (ci == &cpu_info_primary) {
 		/* Initialize the systemwide Xen timecounter.  */
 		tc_init(&xen_timecounter);
-
-#ifdef DOM0OPS
-		/*
-		 * If this is a privileged dom0, start pushing the wall
-		 * clock time back to the Xen hypervisor.
-		 */
-		if (xendomain_is_privileged())
-			xen_timepush_init();
-#endif
 	}
 
 	/* Attach the event counters.  */
@@ -786,6 +768,24 @@ xen_initclocks(void)
 	xen_resumeclocks(ci);
 }
 
+/*
+ * xen_initclocks()
+ *
+ *	Initialize the Xen global clock
+ */
+void
+xen_initclocks(void)
+{
+#ifdef DOM0OPS
+	/*
+	 * If this is a privileged dom0, start pushing the wall
+	 * clock time back to the Xen hypervisor.
+	 */
+	if (xendomain_is_privileged())
+		xen_timepush_init();
+#endif
+}
+
 #ifdef DOM0OPS
 
 /*

Reply via email to