Module Name:    src
Committed By:   bouyer
Date:           Sat Apr 18 20:03:02 UTC 2020

Modified Files:
        src/sys/arch/amd64/amd64 [bouyer-xenpvh]: vector.S
        src/sys/arch/i386/i386 [bouyer-xenpvh]: vector.S
        src/sys/arch/xen/xen [bouyer-xenpvh]: hypervisor.c

Log Message:
If possible, register a per-cpu callback via HVMOP_set_evtchn_upcall_vector.
>From FreeBSD. This requires acking the interrupt in hypervisor_pvhvm_callback.

Don't try to use x86_cpu_idle_xen() for PVHVM, it cause the domU to hang.
FreeBSD doesn't seem to use it either.


To generate a diff of this commit:
cvs rdiff -u -r1.73.6.5 -r1.73.6.6 src/sys/arch/amd64/amd64/vector.S
cvs rdiff -u -r1.85.6.6 -r1.85.6.7 src/sys/arch/i386/i386/vector.S
cvs rdiff -u -r1.73.2.6 -r1.73.2.7 src/sys/arch/xen/xen/hypervisor.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/amd64/amd64/vector.S
diff -u src/sys/arch/amd64/amd64/vector.S:1.73.6.5 src/sys/arch/amd64/amd64/vector.S:1.73.6.6
--- src/sys/arch/amd64/amd64/vector.S:1.73.6.5	Thu Apr 16 17:50:51 2020
+++ src/sys/arch/amd64/amd64/vector.S	Sat Apr 18 20:03:02 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: vector.S,v 1.73.6.5 2020/04/16 17:50:51 bouyer Exp $	*/
+/*	$NetBSD: vector.S,v 1.73.6.6 2020/04/18 20:03:02 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc.
@@ -772,6 +772,14 @@ IDTVEC(hypervisor_pvhvm_callback)
 	incl	CPUVAR(IDEPTH)
 	movq	%rsp,%rdi
 	call	do_hypervisor_callback
+#ifndef XENPV
+	movzbl	_C_LABEL(xenhvm_use_percpu_callback),%edi
+	testl	%edi, %edi
+	jz 1f
+	movq	_C_LABEL(local_apic_va),%rdi
+	movl	$0,LAPIC_EOI(%rdi)
+1:
+#endif
 	jmp 	_C_LABEL(Xdoreti)
 IDTVEC_END(hypervisor_pvhvm_callback)
 	TEXT_USER_END

Index: src/sys/arch/i386/i386/vector.S
diff -u src/sys/arch/i386/i386/vector.S:1.85.6.6 src/sys/arch/i386/i386/vector.S:1.85.6.7
--- src/sys/arch/i386/i386/vector.S:1.85.6.6	Thu Apr 16 17:50:52 2020
+++ src/sys/arch/i386/i386/vector.S	Sat Apr 18 20:03:02 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: vector.S,v 1.85.6.6 2020/04/16 17:50:52 bouyer Exp $	*/
+/*	$NetBSD: vector.S,v 1.85.6.7 2020/04/18 20:03:02 bouyer Exp $	*/
 
 /*
  * Copyright 2002 (c) Wasabi Systems, Inc.
@@ -65,7 +65,7 @@
  */
 
 #include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: vector.S,v 1.85.6.6 2020/04/16 17:50:52 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vector.S,v 1.85.6.7 2020/04/18 20:03:02 bouyer Exp $");
 
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
@@ -1019,6 +1019,14 @@ IDTVEC(hypervisor_pvhvm_callback)	
 	 * Xdoreti needs it too.
 	 */
 	call	do_hypervisor_callback
+#ifndef XENPV
+	movzbl	_C_LABEL(xenhvm_use_percpu_callback),%eax
+	testl	%eax, %eax
+	jz	1f
+	movl	_C_LABEL(local_apic_va),%eax
+	movl	$0, LAPIC_EOI(%eax)
+1:
+#endif
 	jmp	_C_LABEL(Xdoreti)
 IDTVEC_END(hypervisor_pvhvm_callback)
 END(hypervisor_callback)

Index: src/sys/arch/xen/xen/hypervisor.c
diff -u src/sys/arch/xen/xen/hypervisor.c:1.73.2.6 src/sys/arch/xen/xen/hypervisor.c:1.73.2.7
--- src/sys/arch/xen/xen/hypervisor.c:1.73.2.6	Sat Apr 18 15:06:18 2020
+++ src/sys/arch/xen/xen/hypervisor.c	Sat Apr 18 20:03:02 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: hypervisor.c,v 1.73.2.6 2020/04/18 15:06:18 bouyer Exp $ */
+/* $NetBSD: hypervisor.c,v 1.73.2.7 2020/04/18 20:03:02 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.6 2020/04/18 15:06:18 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hypervisor.c,v 1.73.2.7 2020/04/18 20:03:02 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -207,6 +207,8 @@ enum {
 
 #ifdef XENPVHVM
 
+bool xenhvm_use_percpu_callback = 0;
+
 static bool
 xen_check_hypervisordev(void)
 {
@@ -373,7 +375,6 @@ xen_hvm_init(void)
 	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;
 }
@@ -383,6 +384,8 @@ xen_hvm_init_cpu(struct cpu_info *ci)
 {
 	u_int32_t descs[4];
 	struct xen_hvm_param xen_hvm_param;
+	int error;
+	static bool again = 0;
 
 	if (vm_guest != VM_GUEST_XENPVHVM)
 		return 0;
@@ -410,13 +413,43 @@ xen_hvm_init_cpu(struct cpu_info *ci)
 	/* val[63:56] = 2, val[7:0] = vec */
 	xen_hvm_param.value = ((int64_t)0x2 << 56) | xen_hvm_vec;
 
+	/* First try to set up a per-cpu vector. */
+	if (!again || xenhvm_use_percpu_callback) {
+		struct xen_hvm_evtchn_upcall_vector xen_hvm_uvec;
+		xen_hvm_uvec.vcpu = ci->ci_vcpuid;
+		xen_hvm_uvec.vector = xen_hvm_vec;
+
+		xenhvm_use_percpu_callback = 1;
+		error = HYPERVISOR_hvm_op(
+		    HVMOP_set_evtchn_upcall_vector, &xen_hvm_uvec);
+		if (error < 0) {
+			aprint_error_dev(ci->ci_dev,
+			    "failed to set event upcall vector: %d\n", error);
+			if (again)
+				panic("event upcall vector");
+			aprint_error_dev(ci->ci_dev,
+			    "falling back to global vector\n");
+		} else {
+			/*
+			 * From FreeBSD:
+			 * Trick toolstack to think we are enlightened
+			 */
+			aprint_verbose_dev(ci->ci_dev,
+			    "using event upcall vector: %d\n", xen_hvm_vec );
+			xen_hvm_param.value = 1;
+		}
+	}
+
+	if (again)
+		return 1;
+
 	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;
 	}
-
+	again = 1;
 	return 1;
 }
 
@@ -488,7 +521,7 @@ hypervisor_attach(device_t parent, devic
 	bi.common.len = sizeof(struct btinfo_rootdevice);
 
 	/* From i386/multiboot.c */
-	/*	$NetBSD: hypervisor.c,v 1.73.2.6 2020/04/18 15:06:18 bouyer Exp $	*/
+	/*	$NetBSD: hypervisor.c,v 1.73.2.7 2020/04/18 20:03:02 bouyer Exp $	*/
 	int i, len;
 	vaddr_t data;
 	extern struct bootinfo	bootinfo;

Reply via email to