svn commit: r293870 - in head/sys: dev/hyperv/vmbus x86/x86

Sepherosa Ziehau sephe at FreeBSD.org
Thu Jan 14 02:50:14 UTC 2016


Author: sephe
Date: Thu Jan 14 02:50:13 2016
New Revision: 293870
URL: https://svnweb.freebsd.org/changeset/base/293870

Log:
  hyperv: use x86 generic code to do the hypervisor detection
  
  This is first step to move the generic part of HV code into kernel instead
  of module, so that it is possible to use hypercall to implement some other
  paravirtualization code in the kernel.
  
  Submitted by:		Howard Su <howard0su at gmail.com>
  Reviewed by:		royger, delphij, adrian
  Approved by:		adrian (mentor)
  Sponsored by:		Microsoft OSTC
  Differential Revision:	https://reviews.freebsd.org/D3072

Modified:
  head/sys/dev/hyperv/vmbus/hv_connection.c
  head/sys/dev/hyperv/vmbus/hv_hv.c
  head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
  head/sys/x86/x86/identcpu.c

Modified: head/sys/dev/hyperv/vmbus/hv_connection.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_connection.c	Thu Jan 14 02:32:50 2016	(r293869)
+++ head/sys/dev/hyperv/vmbus/hv_connection.c	Thu Jan 14 02:50:13 2016	(r293870)
@@ -251,7 +251,7 @@ hv_vmbus_connect(void) {
 
 	hv_vmbus_protocal_version = version;
 	if (bootverbose)
-		printf("VMBUS: Portocal Version: %d.%d\n",
+		printf("VMBUS: Protocol Version: %d.%d\n",
 		    version >> 16, version & 0xFFFF);
 
 	sema_destroy(&msg_info->wait_sema);

Modified: head/sys/dev/hyperv/vmbus/hv_hv.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_hv.c	Thu Jan 14 02:32:50 2016	(r293869)
+++ head/sys/dev/hyperv/vmbus/hv_hv.c	Thu Jan 14 02:50:13 2016	(r293870)
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/pcpu.h>
 #include <sys/timetc.h>
 #include <machine/bus.h>
+#include <machine/md_var.h>
 #include <vm/vm.h>
 #include <vm/vm_param.h>
 #include <vm/pmap.h>
@@ -55,12 +56,6 @@ __FBSDID("$FreeBSD$");
 
 static u_int hv_get_timecount(struct timecounter *tc);
 
-static inline void do_cpuid_inline(unsigned int op, unsigned int *eax,
-	unsigned int *ebx, unsigned int *ecx, unsigned int *edx) {
-	__asm__ __volatile__("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx),
-			     "=d" (*edx) : "0" (op), "c" (ecx));
-}
-
 /**
  * Globals
  */
@@ -86,27 +81,10 @@ hv_get_timecount(struct timecounter *tc)
 int
 hv_vmbus_query_hypervisor_presence(void) 
 {
-	u_int regs[4];
-	int hyper_v_detected = 0;
-
-	/*
-	 * When Xen is detected and native Xen PV support is enabled,
-	 * ignore Xen's HyperV emulation.
-	 */
-	if (vm_guest == VM_GUEST_XEN)
+	if (vm_guest != VM_GUEST_HV)
 		return (0);
 
-	do_cpuid(1, regs);
-	if (regs[2] & 0x80000000) { /* if(a hypervisor is detected) */
-		/* make sure this really is Hyper-V */
-		/* we look at the CPUID info */
-		do_cpuid(HV_X64_MSR_GUEST_OS_ID, regs);
-		hyper_v_detected =
-				regs[0] >= HV_X64_CPUID_MIN &&
-				regs[0] <= HV_X64_CPUID_MAX &&
-				!memcmp("Microsoft Hv", &regs[1], 12);
-	}
-	return (hyper_v_detected);
+	return (hv_high >= HV_X64_CPUID_MIN && hv_high <= HV_X64_CPUID_MAX);
 }
 
 /**
@@ -115,10 +93,7 @@ hv_vmbus_query_hypervisor_presence(void)
 static int
 hv_vmbus_get_hypervisor_version(void) 
 {
-	unsigned int eax;
-	unsigned int ebx;
-	unsigned int ecx;
-	unsigned int edx;
+	u_int regs[4];
 	unsigned int maxLeaf;
 	unsigned int op;
 
@@ -127,28 +102,16 @@ hv_vmbus_get_hypervisor_version(void) 
 	 * Viridian is present
 	 * Query id and revision.
 	 */
-	eax = 0;
-	ebx = 0;
-	ecx = 0;
-	edx = 0;
 	op = HV_CPU_ID_FUNCTION_HV_VENDOR_AND_MAX_FUNCTION;
-	do_cpuid_inline(op, &eax, &ebx, &ecx, &edx);
+	do_cpuid(op, regs);
 
-	maxLeaf = eax;
-	eax = 0;
-	ebx = 0;
-	ecx = 0;
-	edx = 0;
+	maxLeaf = regs[0];
 	op = HV_CPU_ID_FUNCTION_HV_INTERFACE;
-	do_cpuid_inline(op, &eax, &ebx, &ecx, &edx);
+	do_cpuid(op, regs);
 
 	if (maxLeaf >= HV_CPU_ID_FUNCTION_MS_HV_VERSION) {
-	    eax = 0;
-	    ebx = 0;
-	    ecx = 0;
-	    edx = 0;
 	    op = HV_CPU_ID_FUNCTION_MS_HV_VERSION;
-	    do_cpuid_inline(op, &eax, &ebx, &ecx, &edx);
+	    do_cpuid(op, regs);
 	}
 	return (maxLeaf);
 }

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Thu Jan 14 02:32:50 2016	(r293869)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Thu Jan 14 02:50:13 2016	(r293870)
@@ -60,13 +60,15 @@ __FBSDID("$FreeBSD$");
 
 #include "hv_vmbus_priv.h"
 
-
-#define VMBUS_IRQ	0x5
+#include <contrib/dev/acpica/include/acpi.h>
+#include "acpi_if.h"
 
 static device_t vmbus_devp;
 static int vmbus_inited;
 static hv_setup_args setup_args; /* only CPU 0 supported at this time */
 
+static char *vmbus_ids[] = { "VMBUS", NULL };
+
 /**
  * @brief Software interrupt thread routine to handle channel messages from
  * the hypervisor.
@@ -350,25 +352,15 @@ hv_vmbus_child_device_unregister(struct 
 	return(ret);
 }
 
-static void
-vmbus_identify(driver_t *driver, device_t parent)
-{
-	if (!hv_vmbus_query_hypervisor_presence())
-		return;
-
-	vm_guest = VM_GUEST_HV;
-
-	BUS_ADD_CHILD(parent, 0, "vmbus", 0);
-}
-
 static int
 vmbus_probe(device_t dev) {
-	if(bootverbose)
-		device_printf(dev, "VMBUS: probe\n");
+	if (ACPI_ID_PROBE(device_get_parent(dev), dev, vmbus_ids) == NULL ||
+	    device_get_unit(dev) != 0)
+		return (ENXIO);
 
 	device_set_desc(dev, "Vmbus Devices");
 
-	return (BUS_PROBE_NOWILDCARD);
+	return (BUS_PROBE_DEFAULT);
 }
 
 #ifdef HYPERV
@@ -723,7 +715,6 @@ vmbus_modevent(module_t mod, int what, v
 
 static device_method_t vmbus_methods[] = {
 	/** Device interface */
-	DEVMETHOD(device_identify, vmbus_identify),
 	DEVMETHOD(device_probe, vmbus_probe),
 	DEVMETHOD(device_attach, vmbus_attach),
 	DEVMETHOD(device_detach, vmbus_detach),
@@ -745,8 +736,9 @@ static driver_t vmbus_driver = { driver_
 
 devclass_t vmbus_devclass;
 
-DRIVER_MODULE(vmbus, nexus, vmbus_driver, vmbus_devclass, vmbus_modevent, 0);
-MODULE_VERSION(vmbus,1);
+DRIVER_MODULE(vmbus, acpi, vmbus_driver, vmbus_devclass, vmbus_modevent, 0);
+MODULE_DEPEND(vmbus, acpi, 1, 1, 1);
+MODULE_VERSION(vmbus, 1);
 
 /* We want to be started after SMP is initialized */
 SYSINIT(vmb_init, SI_SUB_SMP + 1, SI_ORDER_FIRST, vmbus_init, NULL);

Modified: head/sys/x86/x86/identcpu.c
==============================================================================
--- head/sys/x86/x86/identcpu.c	Thu Jan 14 02:32:50 2016	(r293869)
+++ head/sys/x86/x86/identcpu.c	Thu Jan 14 02:50:13 2016	(r293870)
@@ -1294,6 +1294,8 @@ identify_hypervisor(void)
 			hv_vendor[12] = '\0';
 			if (strcmp(hv_vendor, "VMwareVMware") == 0)
 				vm_guest = VM_GUEST_VMWARE;
+			else if (strcmp(hv_vendor, "Microsoft Hv") == 0)
+				vm_guest = VM_GUEST_HV;
 		}
 		return;
 	}


More information about the svn-src-all mailing list