Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 27 May 2016 07:29:31 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r300834 - head/sys/dev/hyperv/vmbus
Message-ID:  <201605270729.u4R7TVRe049678@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Fri May 27 07:29:31 2016
New Revision: 300834
URL: https://svnweb.freebsd.org/changeset/base/300834

Log:
  hyperv: Test features before enabling optional functionalities
  
  MFC after:	1 week
  Sponsored by:	Microsoft OSTC
  Differential Revision:	https://reviews.freebsd.org/D6571

Added:
  head/sys/dev/hyperv/vmbus/hyperv_var.h   (contents, props changed)
Modified:
  head/sys/dev/hyperv/vmbus/hv_et.c
  head/sys/dev/hyperv/vmbus/hv_hv.c
  head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
  head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
  head/sys/dev/hyperv/vmbus/hyperv_reg.h

Modified: head/sys/dev/hyperv/vmbus/hv_et.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_et.c	Fri May 27 07:10:11 2016	(r300833)
+++ head/sys/dev/hyperv/vmbus/hv_et.c	Fri May 27 07:29:31 2016	(r300834)
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/hyperv/vmbus/hv_vmbus_priv.h>
 #include <dev/hyperv/vmbus/hyperv_reg.h>
+#include <dev/hyperv/vmbus/hyperv_var.h>
 
 #define HV_TIMER_FREQUENCY		(10 * 1000 * 1000LL) /* 100ns period */
 #define HV_MAX_DELTA_TICKS		0xffffffffLL
@@ -48,6 +49,16 @@ __FBSDID("$FreeBSD$");
 	((((uint64_t)HV_VMBUS_TIMER_SINT) << MSR_HV_STIMER_CFG_SINT_SHIFT) & \
 	 MSR_HV_STIMER_CFG_SINT_MASK)
 
+/*
+ * Two additionally required features:
+ * - SynIC is needed for interrupt generation.
+ * - Time reference counter is needed to set ABS reference count to
+ *   STIMER0_COUNT.
+ */
+#define CPUID_HV_ET_MASK		(CPUID_HV_MSR_TIME_REFCNT |	\
+					 CPUID_HV_MSR_SYNIC |		\
+					 CPUID_HV_MSR_SYNTIMER)
+
 static struct eventtimer *et;
 
 static inline uint64_t
@@ -104,7 +115,8 @@ hv_et_intr(struct trapframe *frame)
 static void
 hv_et_identify(driver_t *driver, device_t parent)
 {
-	if (device_find_child(parent, "hv_et", -1) != NULL)
+	if (device_find_child(parent, "hv_et", -1) != NULL ||
+	    (hyperv_features & CPUID_HV_ET_MASK) != CPUID_HV_ET_MASK)
 		return;
 
 	device_add_child(parent, "hv_et", -1);

Modified: head/sys/dev/hyperv/vmbus/hv_hv.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_hv.c	Fri May 27 07:10:11 2016	(r300833)
+++ head/sys/dev/hyperv/vmbus/hv_hv.c	Fri May 27 07:29:31 2016	(r300834)
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/hyperv/include/hyperv_busdma.h>
 #include <dev/hyperv/vmbus/hv_vmbus_priv.h>
 #include <dev/hyperv/vmbus/hyperv_reg.h>
+#include <dev/hyperv/vmbus/hyperv_var.h>
 #include <dev/hyperv/vmbus/vmbus_var.h>
 
 #define HV_NANOSECONDS_PER_SEC		1000000000L

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Fri May 27 07:10:11 2016	(r300833)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Fri May 27 07:29:31 2016	(r300834)
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/hyperv/include/hyperv.h>
 #include <dev/hyperv/vmbus/hv_vmbus_priv.h>
 #include <dev/hyperv/vmbus/hyperv_reg.h>
+#include <dev/hyperv/vmbus/hyperv_var.h>
 #include <dev/hyperv/vmbus/vmbus_var.h>
 
 #include <contrib/dev/acpica/include/acpi.h>
@@ -215,10 +216,21 @@ vmbus_synic_setup(void *xsc)
 	uint64_t val, orig;
 	uint32_t sint;
 
-	/*
-	 * Save virtual processor id.
-	 */
-	VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(MSR_HV_VP_INDEX);
+	if (hyperv_features & CPUID_HV_MSR_VP_INDEX) {
+		/*
+		 * Save virtual processor id.
+		 */
+		VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(MSR_HV_VP_INDEX);
+	} else {
+		/*
+		 * XXX
+		 * Virtual processoor id is only used by a pretty broken
+		 * channel selection code from storvsc.  It's nothing
+		 * critical even if CPUID_HV_MSR_VP_INDEX is not set; keep
+		 * moving on.
+		 */
+		VMBUS_PCPU_GET(sc, vcpuid, cpu) = cpu;
+	}
 
 	/*
 	 * Setup the SynIC message.
@@ -557,7 +569,8 @@ static int
 vmbus_probe(device_t dev)
 {
 	if (ACPI_ID_PROBE(device_get_parent(dev), dev, vmbus_ids) == NULL ||
-	    device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV)
+	    device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV ||
+	    (hyperv_features & CPUID_HV_MSR_SYNIC) == 0)
 		return (ENXIO);
 
 	device_set_desc(dev, "Hyper-V Vmbus");

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Fri May 27 07:10:11 2016	(r300833)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Fri May 27 07:29:31 2016	(r300834)
@@ -451,9 +451,6 @@ typedef enum {
 
 extern hv_vmbus_connection	hv_vmbus_g_connection;
 
-extern u_int			hyperv_features;
-extern u_int			hyperv_recommends;
-
 typedef void (*vmbus_msg_handler)(hv_vmbus_channel_msg_header *msg);
 
 typedef struct hv_vmbus_channel_msg_table_entry {

Modified: head/sys/dev/hyperv/vmbus/hyperv_reg.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hyperv_reg.h	Fri May 27 07:10:11 2016	(r300833)
+++ head/sys/dev/hyperv/vmbus/hyperv_reg.h	Fri May 27 07:29:31 2016	(r300834)
@@ -110,7 +110,8 @@
 #define CPUID_HV_MSR_APIC		0x0010	/* MSR_HV_{EOI,ICR,TPR} */
 #define CPUID_HV_MSR_HYPERCALL		0x0020	/* MSR_HV_GUEST_OS_ID
 						 * MSR_HV_HYPERCALL */
-#define	CPUID_HV_MSR_GUEST_IDLE		0x0400	/* MSR_VH_GUEST_IDLE */
+#define CPUID_HV_MSR_VP_INDEX		0x0040	/* MSR_HV_VP_INDEX */
+#define CPUID_HV_MSR_GUEST_IDLE		0x0400	/* MSR_HV_GUEST_IDLE */
 /* ECX: power management features */
 #define CPUPM_HV_CSTATE_MASK		0x000f	/* deepest C-state */
 #define CPUPM_HV_C3_HPET		0x0010	/* C3 requires HPET */

Added: head/sys/dev/hyperv/vmbus/hyperv_var.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/hyperv/vmbus/hyperv_var.h	Fri May 27 07:29:31 2016	(r300834)
@@ -0,0 +1,35 @@
+/*-
+ * Copyright (c) 2016 Microsoft Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _HYPERV_VAR_H_
+#define _HYPERV_VAR_H_
+
+extern u_int	hyperv_features;
+extern u_int	hyperv_recommends;
+
+#endif	/* !_HYPERV_VAR_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605270729.u4R7TVRe049678>