Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 23 Jun 2016 08:09:45 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r302128 - stable/10/sys/dev/hyperv/vmbus
Message-ID:  <201606230809.u5N89jOX042636@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Thu Jun 23 08:09:44 2016
New Revision: 302128
URL: https://svnweb.freebsd.org/changeset/base/302128

Log:
  MFC 300654,300655,300708
  
  300654
      hyperv/vmbus: Rework SynIC setup and teardown
  
      - Avoid bit fields.
      - Fix SINT setup (preserve required bits).
  
      MFC after:  1 week
      Sponsored by:       Microsoft OSTC
      Differential Revision:      https://reviews.freebsd.org/D6529
  
  300655
      hyperv: Preserve required bits when disable Hypercall
  
      MFC after:  1 week
      Sponsored by:       Microsoft OSTC
      Differential Revision:      https://reviews.freebsd.org/D6530
  
  300708
      hyperv: Rework guest id settings according to Hyper-V spec
  
      MFC after:  1 week
      Sponsored by:       Microsoft OSTC
      Differential Revision:      https://reviews.freebsd.org/D6553

Modified:
  stable/10/sys/dev/hyperv/vmbus/hv_hv.c
  stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
  stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/hyperv/vmbus/hv_hv.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_hv.c	Thu Jun 23 07:53:58 2016	(r302127)
+++ stable/10/sys/dev/hyperv/vmbus/hv_hv.c	Thu Jun 23 08:09:44 2016	(r302128)
@@ -52,34 +52,24 @@ __FBSDID("$FreeBSD$");
 
 #define	HYPERV_INTERFACE		0x31237648	/* HV#1 */
 
-/*
- * The guest OS needs to register the guest ID with the hypervisor.
- * The guest ID is a 64 bit entity and the structure of this ID is
- * specified in the Hyper-V specification:
- *
- * http://msdn.microsoft.com/en-us/library/windows/
- * hardware/ff542653%28v=vs.85%29.aspx
- *
- * While the current guideline does not specify how FreeBSD guest ID(s)
- * need to be generated, our plan is to publish the guidelines for
- * FreeBSD and other guest operating systems that currently are hosted
- * on Hyper-V. The implementation here conforms to this yet
- * unpublished guidelines.
- *
- * Bit(s)
- * 63    - Indicates if the OS is Open Source or not; 1 is Open Source
- * 62:56 - Os Type: FreeBSD is 0x02
- * 55:48 - Distro specific identification
- * 47:16 - FreeBSD kernel version number
- * 15:0  - Distro specific identification
- */
-#define HYPERV_GUESTID_OSS		(0x1ULL << 63)
-#define HYPERV_GUESTID_FREEBSD		(0x02ULL << 56)
-#define HYPERV_GUESTID(id)				\
-	(HYPERV_GUESTID_OSS | HYPERV_GUESTID_FREEBSD |	\
-	 (((uint64_t)(((id) & 0xff0000) >> 16)) << 48) |\
-	 (((uint64_t)__FreeBSD_version) << 16) |	\
-	 ((uint64_t)((id) & 0x00ffff)))
+#define HYPERV_FREEBSD_BUILD		0ULL
+#define HYPERV_FREEBSD_VERSION		((uint64_t)__FreeBSD_version)
+#define HYPERV_FREEBSD_OSID		0ULL
+
+#define MSR_HV_GUESTID_BUILD_FREEBSD	\
+	(HYPERV_FREEBSD_BUILD & MSR_HV_GUESTID_BUILD_MASK)
+#define MSR_HV_GUESTID_VERSION_FREEBSD	\
+	((HYPERV_FREEBSD_VERSION << MSR_HV_GUESTID_VERSION_SHIFT) & \
+	 MSR_HV_GUESTID_VERSION_MASK)
+#define MSR_HV_GUESTID_OSID_FREEBSD	\
+	((HYPERV_FREEBSD_OSID << MSR_HV_GUESTID_OSID_SHIFT) & \
+	 MSR_HV_GUESTID_OSID_MASK)
+
+#define MSR_HV_GUESTID_FREEBSD		\
+	(MSR_HV_GUESTID_BUILD_FREEBSD |	\
+	 MSR_HV_GUESTID_VERSION_FREEBSD | \
+	 MSR_HV_GUESTID_OSID_FREEBSD |	\
+	 MSR_HV_GUESTID_OSTYPE_FREEBSD)
 
 struct hypercall_ctx {
 	void			*hc_addr;
@@ -321,8 +311,8 @@ hyperv_init(void *dummy __unused)
 		return;
 	}
 
-	/* Write guest id */
-	wrmsr(HV_X64_MSR_GUEST_OS_ID, HYPERV_GUESTID(0));
+	/* Set guest id */
+	wrmsr(MSR_HV_GUEST_OS_ID, MSR_HV_GUESTID_FREEBSD);
 
 	if (hyperv_features & HV_FEATURE_MSR_TIME_REFCNT) {
 		/* Register virtual timecount */
@@ -390,11 +380,14 @@ SYSINIT(hypercall_ctor, SI_SUB_DRIVERS, 
 static void
 hypercall_destroy(void *arg __unused)
 {
+	uint64_t hc;
+
 	if (hypercall_context.hc_addr == NULL)
 		return;
 
 	/* Disable Hypercall */
-	wrmsr(MSR_HV_HYPERCALL, 0);
+	hc = rdmsr(MSR_HV_HYPERCALL);
+	wrmsr(MSR_HV_HYPERCALL, (hc & MSR_HV_HYPERCALL_RSVD_MASK));
 	hypercall_memfree();
 
 	if (bootverbose)

Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Thu Jun 23 07:53:58 2016	(r302127)
+++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Thu Jun 23 08:09:44 2016	(r302128)
@@ -61,6 +61,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/vmbus_var.h>
 
 #include <contrib/dev/acpica/include/acpi.h>
@@ -210,100 +211,97 @@ static void
 vmbus_synic_setup(void *xsc)
 {
 	struct vmbus_softc *sc = xsc;
-	int			cpu;
-	hv_vmbus_synic_simp	simp;
-	hv_vmbus_synic_siefp	siefp;
-	hv_vmbus_synic_scontrol sctrl;
-	hv_vmbus_synic_sint	shared_sint;
-
-	cpu = PCPU_GET(cpuid);
+	int cpu = curcpu;
+	uint64_t val, orig;
+	uint32_t sint;
 
 	/*
-	 * Setup the Synic's message page
+	 * Save virtual processor id.
 	 */
-	simp.as_uint64_t = rdmsr(HV_X64_MSR_SIMP);
-	simp.u.simp_enabled = 1;
-	simp.u.base_simp_gpa =
-	    VMBUS_PCPU_GET(sc, message_dma.hv_paddr, cpu) >> PAGE_SHIFT;
-
-	wrmsr(HV_X64_MSR_SIMP, simp.as_uint64_t);
+	VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(MSR_HV_VP_INDEX);
 
 	/*
-	 * Setup the Synic's event page
+	 * Setup the SynIC message.
 	 */
-	siefp.as_uint64_t = rdmsr(HV_X64_MSR_SIEFP);
-	siefp.u.siefp_enabled = 1;
-	siefp.u.base_siefp_gpa =
-	    VMBUS_PCPU_GET(sc, event_flag_dma.hv_paddr, cpu) >> PAGE_SHIFT;
+	orig = rdmsr(MSR_HV_SIMP);
+	val = MSR_HV_SIMP_ENABLE | (orig & MSR_HV_SIMP_RSVD_MASK) |
+	    ((VMBUS_PCPU_GET(sc, message_dma.hv_paddr, cpu) >> PAGE_SHIFT) <<
+	     MSR_HV_SIMP_PGSHIFT);
+	wrmsr(MSR_HV_SIMP, val);
 
-	wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t);
-
-	/*HV_SHARED_SINT_IDT_VECTOR + 0x20; */
-	shared_sint.as_uint64_t = 0;
-	shared_sint.u.vector = sc->vmbus_idtvec;
-	shared_sint.u.masked = FALSE;
-	shared_sint.u.auto_eoi = TRUE;
-
-	wrmsr(HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT,
-	    shared_sint.as_uint64_t);
+	/*
+	 * Setup the SynIC event flags.
+	 */
+	orig = rdmsr(MSR_HV_SIEFP);
+	val = MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK) |
+	    ((VMBUS_PCPU_GET(sc, event_flag_dma.hv_paddr, cpu) >> PAGE_SHIFT) <<
+	     MSR_HV_SIEFP_PGSHIFT);
+	wrmsr(MSR_HV_SIEFP, val);
 
-	wrmsr(HV_X64_MSR_SINT0 + HV_VMBUS_TIMER_SINT,
-	    shared_sint.as_uint64_t);
 
-	/* Enable the global synic bit */
-	sctrl.as_uint64_t = rdmsr(HV_X64_MSR_SCONTROL);
-	sctrl.u.enable = 1;
+	/*
+	 * Configure and unmask SINT for message and event flags.
+	 */
+	sint = MSR_HV_SINT0 + HV_VMBUS_MESSAGE_SINT;
+	orig = rdmsr(sint);
+	val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
+	    (orig & MSR_HV_SINT_RSVD_MASK);
+	wrmsr(sint, val);
 
-	wrmsr(HV_X64_MSR_SCONTROL, sctrl.as_uint64_t);
+	/*
+	 * Configure and unmask SINT for timer.
+	 */
+	sint = MSR_HV_SINT0 + HV_VMBUS_TIMER_SINT;
+	orig = rdmsr(sint);
+	val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
+	    (orig & MSR_HV_SINT_RSVD_MASK);
+	wrmsr(sint, val);
 
 	/*
-	 * Set up the cpuid mapping from Hyper-V to FreeBSD.
-	 * The array is indexed using FreeBSD cpuid.
+	 * All done; enable SynIC.
 	 */
-	VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(HV_X64_MSR_VP_INDEX);
+	orig = rdmsr(MSR_HV_SCONTROL);
+	val = MSR_HV_SCTRL_ENABLE | (orig & MSR_HV_SCTRL_RSVD_MASK);
+	wrmsr(MSR_HV_SCONTROL, val);
 }
 
 static void
 vmbus_synic_teardown(void *arg)
 {
-	hv_vmbus_synic_sint	shared_sint;
-	hv_vmbus_synic_simp	simp;
-	hv_vmbus_synic_siefp	siefp;
-
-	shared_sint.as_uint64_t = rdmsr(
-	    HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT);
-
-	shared_sint.u.masked = 1;
+	uint64_t orig;
+	uint32_t sint;
 
 	/*
-	 * Disable the interrupt 0
+	 * Disable SynIC.
 	 */
-	wrmsr(
-	    HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT,
-	    shared_sint.as_uint64_t);
-
-	shared_sint.as_uint64_t = rdmsr(
-	    HV_X64_MSR_SINT0 + HV_VMBUS_TIMER_SINT);
-
-	shared_sint.u.masked = 1;
+	orig = rdmsr(MSR_HV_SCONTROL);
+	wrmsr(MSR_HV_SCONTROL, (orig & MSR_HV_SCTRL_RSVD_MASK));
 
 	/*
-	 * Disable the interrupt 1
+	 * Mask message and event flags SINT.
 	 */
-	wrmsr(
-	    HV_X64_MSR_SINT0 + HV_VMBUS_TIMER_SINT,
-	    shared_sint.as_uint64_t);
-	simp.as_uint64_t = rdmsr(HV_X64_MSR_SIMP);
-	simp.u.simp_enabled = 0;
-	simp.u.base_simp_gpa = 0;
+	sint = MSR_HV_SINT0 + HV_VMBUS_MESSAGE_SINT;
+	orig = rdmsr(sint);
+	wrmsr(sint, orig | MSR_HV_SINT_MASKED);
 
-	wrmsr(HV_X64_MSR_SIMP, simp.as_uint64_t);
+	/*
+	 * Mask timer SINT.
+	 */
+	sint = MSR_HV_SINT0 + HV_VMBUS_TIMER_SINT;
+	orig = rdmsr(sint);
+	wrmsr(sint, orig | MSR_HV_SINT_MASKED);
 
-	siefp.as_uint64_t = rdmsr(HV_X64_MSR_SIEFP);
-	siefp.u.siefp_enabled = 0;
-	siefp.u.base_siefp_gpa = 0;
+	/*
+	 * Teardown SynIC message.
+	 */
+	orig = rdmsr(MSR_HV_SIMP);
+	wrmsr(MSR_HV_SIMP, (orig & MSR_HV_SIMP_RSVD_MASK));
 
-	wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t);
+	/*
+	 * Teardown SynIC event flags.
+	 */
+	orig = rdmsr(MSR_HV_SIEFP);
+	wrmsr(MSR_HV_SIEFP, (orig & MSR_HV_SIEFP_RSVD_MASK));
 }
 
 static int

Modified: stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h	Thu Jun 23 07:53:58 2016	(r302127)
+++ stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h	Thu Jun 23 08:09:44 2016	(r302128)
@@ -29,9 +29,48 @@
 #ifndef _HYPERV_REG_H_
 #define _HYPERV_REG_H_
 
+#define MSR_HV_GUEST_OS_ID		0x40000000
+#define MSR_HV_GUESTID_BUILD_MASK	0xffffULL
+#define MSR_HV_GUESTID_VERSION_MASK	0x0000ffffffff0000ULL
+#define MSR_HV_GUESTID_VERSION_SHIFT	16
+#define MSR_HV_GUESTID_OSID_MASK	0x00ff000000000000ULL
+#define MSR_HV_GUESTID_OSID_SHIFT	48
+#define MSR_HV_GUESTID_OSTYPE_MASK	0x7f00000000000000ULL
+#define MSR_HV_GUESTID_OSTYPE_SHIFT	56
+#define MSR_HV_GUESTID_OPENSRC		0x8000000000000000ULL
+#define MSR_HV_GUESTID_OSTYPE_LINUX	\
+	((0x01ULL << MSR_HV_GUESTID_OSTYPE_SHIFT) | MSR_HV_GUESTID_OPENSRC)
+#define MSR_HV_GUESTID_OSTYPE_FREEBSD	\
+	((0x02ULL << MSR_HV_GUESTID_OSTYPE_SHIFT) | MSR_HV_GUESTID_OPENSRC)
+
 #define MSR_HV_HYPERCALL		0x40000001
 #define MSR_HV_HYPERCALL_ENABLE		0x0001ULL
 #define MSR_HV_HYPERCALL_RSVD_MASK	0x0ffeULL
 #define MSR_HV_HYPERCALL_PGSHIFT	12
 
+#define MSR_HV_VP_INDEX			0x40000002
+
+#define MSR_HV_SCONTROL			0x40000080
+#define MSR_HV_SCTRL_ENABLE		0x0001ULL
+#define MSR_HV_SCTRL_RSVD_MASK		0xfffffffffffffffeULL
+
+#define MSR_HV_SIEFP			0x40000082
+#define MSR_HV_SIEFP_ENABLE		0x0001ULL
+#define MSR_HV_SIEFP_RSVD_MASK		0x0ffeULL
+#define MSR_HV_SIEFP_PGSHIFT		12
+
+#define MSR_HV_SIMP			0x40000083
+#define MSR_HV_SIMP_ENABLE		0x0001ULL
+#define MSR_HV_SIMP_RSVD_MASK		0x0ffeULL
+#define MSR_HV_SIMP_PGSHIFT		12
+
+#define MSR_HV_SINT0			0x40000090
+#define MSR_HV_SINT_VECTOR_MASK		0x00ffULL
+#define MSR_HV_SINT_RSVD1_MASK		0xff00ULL
+#define MSR_HV_SINT_MASKED		0x00010000ULL
+#define MSR_HV_SINT_AUTOEOI		0x00020000ULL
+#define MSR_HV_SINT_RSVD2_MASK		0xfffffffffffc0000ULL
+#define MSR_HV_SINT_RSVD_MASK		(MSR_HV_SINT_RSVD1_MASK |	\
+					 MSR_HV_SINT_RSVD2_MASK)
+
 #endif	/* !_HYPERV_REG_H_ */



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