Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 Aug 2016 18:13:48 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r303965 - user/cperciva/freebsd-update-build/patches/10.3-RELEASE
Message-ID:  <201608111813.u7BIDmtt019722@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Thu Aug 11 18:13:48 2016
New Revision: 303965
URL: https://svnweb.freebsd.org/changeset/base/303965

Log:
  Add a bunch of ENs from Microsoft for the 10.3-RELEASE.

Added:
  user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:10.dhclient
  user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:11.vmbus
  user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:12.hv_storvsc
  user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:13.vmbus
  user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:14.hv_storvsc
  user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:15.vmbus
  user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:16.hv_storvsc

Added: user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:10.dhclient
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:10.dhclient	Thu Aug 11 18:13:48 2016	(r303965)
@@ -0,0 +1,39 @@
+Index: sbin/dhclient/dhclient.c
+===================================================================
+--- sbin/dhclient/dhclient.c	(revision 302284)
++++ sbin/dhclient/dhclient.c	(working copy)
+@@ -2277,6 +2277,17 @@ script_set_env(struct client_state *clie
+ {
+ 	int i, j, namelen;
+ 
++	/* No `` or $() command substitution allowed in environment values! */
++	for (j=0; j < strlen(value); j++)
++		switch (value[j]) {
++		case '`':
++		case '$':
++			warning("illegal character (%c) in value '%s'",
++			    value[j], value);
++			/* Ignore this option */
++			return;
++		}
++
+ 	namelen = strlen(name);
+ 
+ 	for (i = 0; client->scriptEnv[i]; i++)
+@@ -2313,16 +2324,6 @@ script_set_env(struct client_state *clie
+ 	    strlen(value) + 1);
+ 	if (client->scriptEnv[i] == NULL)
+ 		error("script_set_env: no memory for variable assignment");
+-
+-	/* No `` or $() command substitution allowed in environment values! */
+-	for (j=0; j < strlen(value); j++)
+-		switch (value[j]) {
+-		case '`':
+-		case '$':
+-			error("illegal character (%c) in value '%s'", value[j],
+-			    value);
+-			/* not reached */
+-		}
+ 	snprintf(client->scriptEnv[i], strlen(prefix) + strlen(name) +
+ 	    1 + strlen(value) + 1, "%s%s=%s", prefix, name, value);
+ }

Added: user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:11.vmbus
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:11.vmbus	Thu Aug 11 18:13:48 2016	(r303965)
@@ -0,0 +1,218 @@
+--- sys/dev/hyperv/vmbus/hv_channel.c.orig
++++ sys/dev/hyperv/vmbus/hv_channel.c
+@@ -180,12 +180,12 @@
+ 	if (user_data_len)
+ 		memcpy(open_msg->user_data, user_data, user_data_len);
+ 
+-	mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
+ 	TAILQ_INSERT_TAIL(
+ 		&hv_vmbus_g_connection.channel_msg_anchor,
+ 		open_info,
+ 		msg_list_entry);
+-	mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
+ 
+ 	ret = hv_vmbus_post_message(
+ 		open_msg, sizeof(hv_vmbus_channel_open_channel));
+@@ -212,12 +212,12 @@
+ 	}
+ 
+ 	cleanup:
+-	mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
+ 	TAILQ_REMOVE(
+ 		&hv_vmbus_g_connection.channel_msg_anchor,
+ 		open_info,
+ 		msg_list_entry);
+-	mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
+ 	sema_destroy(&open_info->wait_sema);
+ 	free(open_info, M_DEVBUF);
+ 
+@@ -401,13 +401,13 @@
+ 	gpadl_msg->child_rel_id = channel->offer_msg.child_rel_id;
+ 	gpadl_msg->gpadl = next_gpadl_handle;
+ 
+-	mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
+ 	TAILQ_INSERT_TAIL(
+ 		&hv_vmbus_g_connection.channel_msg_anchor,
+ 		msg_info,
+ 		msg_list_entry);
+ 
+-	mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
+ 
+ 	ret = hv_vmbus_post_message(
+ 		gpadl_msg,
+@@ -446,10 +446,10 @@
+ 
+ cleanup:
+ 
+-	mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
+ 	TAILQ_REMOVE(&hv_vmbus_g_connection.channel_msg_anchor,
+ 		msg_info, msg_list_entry);
+-	mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
+ 
+ 	sema_destroy(&msg_info->wait_sema);
+ 	free(msg_info, M_DEVBUF);
+@@ -488,10 +488,10 @@
+ 	msg->child_rel_id = channel->offer_msg.child_rel_id;
+ 	msg->gpadl = gpadl_handle;
+ 
+-	mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
+ 	TAILQ_INSERT_TAIL(&hv_vmbus_g_connection.channel_msg_anchor,
+ 			info, msg_list_entry);
+-	mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
+ 
+ 	ret = hv_vmbus_post_message(msg,
+ 			sizeof(hv_vmbus_channel_gpadl_teardown));
+@@ -504,10 +504,10 @@
+ 	/*
+ 	 * Received a torndown response
+ 	 */
+-	mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
+ 	TAILQ_REMOVE(&hv_vmbus_g_connection.channel_msg_anchor,
+ 			info, msg_list_entry);
+-	mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
+ 	sema_destroy(&info->wait_sema);
+ 	free(info, M_DEVBUF);
+ 
+--- sys/dev/hyperv/vmbus/hv_channel_mgmt.c.orig
++++ sys/dev/hyperv/vmbus/hv_channel_mgmt.c
+@@ -567,7 +567,7 @@
+ 	/*
+ 	 * Find the open msg, copy the result and signal/unblock the wait event
+ 	 */
+-	mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
+ 
+ 	TAILQ_FOREACH(msg_info, &hv_vmbus_g_connection.channel_msg_anchor,
+ 	    msg_list_entry) {
+@@ -585,7 +585,7 @@
+ 		}
+ 	    }
+ 	}
+-	mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
+ 
+ }
+ 
+@@ -609,7 +609,7 @@
+ 	/* Find the establish msg, copy the result and signal/unblock
+ 	 * the wait event
+ 	 */
+-	mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
+ 	TAILQ_FOREACH(msg_info, &hv_vmbus_g_connection.channel_msg_anchor,
+ 		msg_list_entry) {
+ 	    request_header = (hv_vmbus_channel_msg_header*) msg_info->msg;
+@@ -628,7 +628,7 @@
+ 		}
+ 	    }
+ 	}
+-	mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
+ }
+ 
+ /**
+@@ -653,7 +653,7 @@
+ 	 * wait event.
+ 	 */
+ 
+-	mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
+ 
+ 	TAILQ_FOREACH(msg_info, &hv_vmbus_g_connection.channel_msg_anchor,
+ 		msg_list_entry) {
+@@ -673,7 +673,7 @@
+ 		}
+ 	    }
+ 	}
+-    mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++    mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
+ }
+ 
+ /**
+@@ -693,7 +693,7 @@
+ 
+ 	versionResponse = (hv_vmbus_channel_version_response*)hdr;
+ 
+-	mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
+ 	TAILQ_FOREACH(msg_info, &hv_vmbus_g_connection.channel_msg_anchor,
+ 	    msg_list_entry) {
+ 	    requestHeader = (hv_vmbus_channel_msg_header*) msg_info->msg;
+@@ -707,7 +707,7 @@
+ 		sema_post(&msg_info->wait_sema);
+ 	    }
+ 	}
+-    mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++    mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
+ 
+ }
+ 
+--- sys/dev/hyperv/vmbus/hv_connection.c.orig
++++ sys/dev/hyperv/vmbus/hv_connection.c
+@@ -101,26 +101,26 @@
+ 	 * Add to list before we send the request since we may receive the
+ 	 * response before returning from this routine
+ 	 */
+-	mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
+ 
+ 	TAILQ_INSERT_TAIL(
+ 		&hv_vmbus_g_connection.channel_msg_anchor,
+ 		msg_info,
+ 		msg_list_entry);
+ 
+-	mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
+ 
+ 	ret = hv_vmbus_post_message(
+ 		msg,
+ 		sizeof(hv_vmbus_channel_initiate_contact));
+ 
+ 	if (ret != 0) {
+-		mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++		mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
+ 		TAILQ_REMOVE(
+ 			&hv_vmbus_g_connection.channel_msg_anchor,
+ 			msg_info,
+ 			msg_list_entry);
+-		mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++		mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
+ 		return (ret);
+ 	}
+ 
+@@ -129,12 +129,12 @@
+ 	 */
+ 	ret = sema_timedwait(&msg_info->wait_sema, 5 * hz); /* KYS 5 seconds */
+ 
+-	mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
+ 	TAILQ_REMOVE(
+ 		&hv_vmbus_g_connection.channel_msg_anchor,
+ 		msg_info,
+ 		msg_list_entry);
+-	mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
++	mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
+ 
+ 	/**
+ 	 * Check if successful
+@@ -173,7 +173,7 @@
+ 
+ 	TAILQ_INIT(&hv_vmbus_g_connection.channel_msg_anchor);
+ 	mtx_init(&hv_vmbus_g_connection.channel_msg_lock, "vmbus channel msg",
+-		NULL, MTX_SPIN);
++		NULL, MTX_DEF);
+ 
+ 	TAILQ_INIT(&hv_vmbus_g_connection.channel_anchor);
+ 	mtx_init(&hv_vmbus_g_connection.channel_lock, "vmbus channel",

Added: user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:12.hv_storvsc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:12.hv_storvsc	Thu Aug 11 18:13:48 2016	(r303965)
@@ -0,0 +1,205 @@
+--- sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c.orig
++++ sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
+@@ -81,12 +81,6 @@
+ #define BLKVSC_MAX_IO_REQUESTS		STORVSC_MAX_IO_REQUESTS
+ #define STORVSC_MAX_TARGETS		(2)
+ 
+-#define STORVSC_WIN7_MAJOR 4
+-#define STORVSC_WIN7_MINOR 2
+-
+-#define STORVSC_WIN8_MAJOR 5
+-#define STORVSC_WIN8_MINOR 1
+-
+ #define VSTOR_PKT_SIZE	(sizeof(struct vstor_packet) - vmscsi_size_delta)
+ 
+ #define HV_ALIGN(x, a) roundup2(x, a)
+@@ -208,7 +202,7 @@
+  * Sense buffer size changed in win8; have a run-time
+  * variable to track the size we should use.
+  */
+-static int sense_buffer_size;
++static int sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
+ 
+ /*
+  * The size of the vmscsi_request has changed in win8. The
+@@ -218,9 +212,46 @@
+  * Track the correct size we need to apply.
+  */
+ static int vmscsi_size_delta;
++/*
++ * The storage protocol version is determined during the
++ * initial exchange with the host.  It will indicate which
++ * storage functionality is available in the host.
++*/
++static int vmstor_proto_version;
++
++struct vmstor_proto {
++        int proto_version;
++        int sense_buffer_size;
++        int vmscsi_size_delta;
++};
+ 
+-static int storvsc_current_major;
+-static int storvsc_current_minor;
++static const struct vmstor_proto vmstor_proto_list[] = {
++        {
++                VMSTOR_PROTOCOL_VERSION_WIN10,
++                POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
++                0
++        },
++        {
++                VMSTOR_PROTOCOL_VERSION_WIN8_1,
++                POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
++                0
++        },
++        {
++                VMSTOR_PROTOCOL_VERSION_WIN8,
++                POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
++                0
++        },
++        {
++                VMSTOR_PROTOCOL_VERSION_WIN7,
++                PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE,
++                sizeof(struct vmscsi_win8_extension),
++        },
++        {
++                VMSTOR_PROTOCOL_VERSION_WIN6,
++                PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE,
++                sizeof(struct vmscsi_win8_extension),
++        }
++};
+ 
+ /* static functions */
+ static int storvsc_probe(device_t dev);
+@@ -435,7 +466,7 @@
+ static int
+ hv_storvsc_channel_init(struct hv_device *dev)
+ {
+-	int ret = 0;
++	int ret = 0, i;
+ 	struct hv_storvsc_request *request;
+ 	struct vstor_packet *vstor_packet;
+ 	struct storvsc_softc *sc;
+@@ -484,19 +515,20 @@
+ 		goto cleanup;
+ 	}
+ 
+-	/* reuse the packet for version range supported */
++	for (i = 0; i < nitems(vmstor_proto_list); i++) {
++		/* reuse the packet for version range supported */
+ 
+-	memset(vstor_packet, 0, sizeof(struct vstor_packet));
+-	vstor_packet->operation = VSTOR_OPERATION_QUERYPROTOCOLVERSION;
+-	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
++		memset(vstor_packet, 0, sizeof(struct vstor_packet));
++		vstor_packet->operation = VSTOR_OPERATION_QUERYPROTOCOLVERSION;
++		vstor_packet->flags = REQUEST_COMPLETION_FLAG;
+ 
+-	vstor_packet->u.version.major_minor =
+-	    VMSTOR_PROTOCOL_VERSION(storvsc_current_major, storvsc_current_minor);
++		vstor_packet->u.version.major_minor =
++			vmstor_proto_list[i].proto_version;
+ 
+-	/* revision is only significant for Windows guests */
+-	vstor_packet->u.version.revision = 0;
++		/* revision is only significant for Windows guests */
++		vstor_packet->u.version.revision = 0;
+ 
+-	ret = hv_vmbus_channel_send_packet(
++		ret = hv_vmbus_channel_send_packet(
+ 			dev->channel,
+ 			vstor_packet,
+ 			VSTOR_PKT_SIZE,
+@@ -504,20 +536,34 @@
+ 			HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
+ 			HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+ 
+-	if (ret != 0)
+-		goto cleanup;
++		if (ret != 0)
++			goto cleanup;
+ 
+-	/* wait 5 seconds */
+-	ret = sema_timedwait(&request->synch_sema, 5 * hz);
++		/* wait 5 seconds */
++		ret = sema_timedwait(&request->synch_sema, 5 * hz);
+ 
+-	if (ret)
+-		goto cleanup;
++		if (ret)
++			goto cleanup;
+ 
+-	/* TODO: Check returned version */
+-	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO ||
+-		vstor_packet->status != 0)
+-		goto cleanup;
++		if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO) {
++			ret = EINVAL;
++			goto cleanup;	
++		}
++		if (vstor_packet->status == 0) {
++			vmstor_proto_version =
++				vmstor_proto_list[i].proto_version;
++			sense_buffer_size =
++				vmstor_proto_list[i].sense_buffer_size;
++			vmscsi_size_delta =
++				vmstor_proto_list[i].vmscsi_size_delta;
++			break;
++		}
++	}
+ 
++	if (vstor_packet->status != 0) {
++		ret = EINVAL;
++		goto cleanup;
++	}
+ 	/**
+ 	 * Query channel properties
+ 	 */
+@@ -916,19 +962,6 @@
+ 	int ata_disk_enable = 0;
+ 	int ret	= ENXIO;
+ 	
+-	if (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008 ||
+-	    hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7) {
+-		sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
+-		vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
+-		storvsc_current_major = STORVSC_WIN7_MAJOR;
+-		storvsc_current_minor = STORVSC_WIN7_MINOR;
+-	} else {
+-		sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
+-		vmscsi_size_delta = 0;
+-		storvsc_current_major = STORVSC_WIN8_MAJOR;
+-		storvsc_current_minor = STORVSC_WIN8_MINOR;
+-	}
+-	
+ 	switch (storvsc_get_storage_type(dev)) {
+ 	case DRIVER_BLKVSC:
+ 		if(bootverbose)
+@@ -2064,6 +2097,13 @@
+ 		    ((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
+ 		     csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes);
+ 		if (cmd->opcode == INQUIRY &&
++		    /* 
++		     * XXX: Temporary work around disk hot plugin on win2k12r2,
++		     * only filtering the invalid disk on win10 or 2016 server.
++		     * So, the hot plugin on win10 and 2016 server needs
++		     * to be fixed.
++		     */
++		    vmstor_proto_version == VMSTOR_PROTOCOL_VERSION_WIN10 && 
+ 		    is_inquiry_valid(
+ 		    (const struct scsi_inquiry_data *)csio->data_ptr) == 0) {
+ 			ccb->ccb_h.status |= CAM_DEV_NOT_THERE;
+--- sys/dev/hyperv/storvsc/hv_vstorage.h.orig
++++ sys/dev/hyperv/storvsc/hv_vstorage.h
+@@ -41,6 +41,11 @@
+ #define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_) ((((MAJOR_) & 0xff) << 8) | \
+                                                  (((MINOR_) & 0xff)     ))
+ 
++#define VMSTOR_PROTOCOL_VERSION_WIN6       VMSTOR_PROTOCOL_VERSION(2, 0)
++#define VMSTOR_PROTOCOL_VERSION_WIN7       VMSTOR_PROTOCOL_VERSION(4, 2)
++#define VMSTOR_PROTOCOL_VERSION_WIN8       VMSTOR_PROTOCOL_VERSION(5, 1)
++#define VMSTOR_PROTOCOL_VERSION_WIN8_1     VMSTOR_PROTOCOL_VERSION(6, 0)
++#define VMSTOR_PROTOCOL_VERSION_WIN10      VMSTOR_PROTOCOL_VERSION(6, 2)
+ /*
+  * Invalid version.
+  */

Added: user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:13.vmbus
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:13.vmbus	Thu Aug 11 18:13:48 2016	(r303965)
@@ -0,0 +1,155 @@
+--- sys/dev/hyperv/vmbus/hv_hv.c.orig
++++ sys/dev/hyperv/vmbus/hv_hv.c
+@@ -33,6 +33,7 @@
+ __FBSDID("$FreeBSD$");
+ 
+ #include <sys/param.h>
++#include <sys/kernel.h>
+ #include <sys/malloc.h>
+ #include <sys/pcpu.h>
+ #include <sys/timetc.h>
+@@ -50,6 +51,9 @@
+ 
+ static u_int hv_get_timecount(struct timecounter *tc);
+ 
++u_int	hyperv_features;
++u_int	hyperv_recommends;
++
+ /**
+  * Globals
+  */
+@@ -211,8 +215,6 @@
+ 
+ 	hv_vmbus_g_context.hypercall_page = virt_addr;
+ 
+-	tc_init(&hv_timecounter); /* register virtual timecount */
+-
+ 	hv_et_init();
+ 	
+ 	return (0);
+@@ -427,3 +429,93 @@
+ 	wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t);
+ }
+ 
++static bool
++hyperv_identify(void)
++{
++	u_int regs[4];
++	unsigned int maxLeaf;
++	unsigned int op;
++
++	if (vm_guest != VM_GUEST_HV)
++		return (false);
++
++	op = HV_CPU_ID_FUNCTION_HV_VENDOR_AND_MAX_FUNCTION;
++	do_cpuid(op, regs);
++	maxLeaf = regs[0];
++	if (maxLeaf < HV_CPU_ID_FUNCTION_MS_HV_IMPLEMENTATION_LIMITS)
++		return (false);
++
++	op = HV_CPU_ID_FUNCTION_HV_INTERFACE;
++	do_cpuid(op, regs);
++	if (regs[0] != 0x31237648 /* HV#1 */)
++		return (false);
++
++	op = HV_CPU_ID_FUNCTION_MS_HV_FEATURES;
++	do_cpuid(op, regs);
++	if ((regs[0] & HV_FEATURE_MSR_HYPERCALL) == 0) {
++		/*
++		 * Hyper-V w/o Hypercall is impossible; someone
++		 * is faking Hyper-V.
++		 */
++		return (false);
++	}
++	hyperv_features = regs[0];
++
++	op = HV_CPU_ID_FUNCTION_MS_HV_VERSION;
++	do_cpuid(op, regs);
++	printf("Hyper-V Version: %d.%d.%d [SP%d]\n",
++	    regs[1] >> 16, regs[1] & 0xffff, regs[0], regs[2]);
++
++	printf("  Features: 0x%b\n", hyperv_features,
++	    "\020"
++	    "\001VPRUNTIME"
++	    "\002TMREFCNT"
++	    "\003SYNCIC"
++	    "\004SYNCTM"
++	    "\005APIC"
++	    "\006HYERCALL"
++	    "\007VPINDEX"
++	    "\010RESET"
++	    "\011STATS"
++	    "\012REFTSC"
++	    "\013IDLE"
++	    "\014TMFREQ"
++	    "\015DEBUG");
++
++	op = HV_CPU_ID_FUNCTION_MS_HV_ENLIGHTENMENT_INFORMATION;
++	do_cpuid(op, regs);
++	hyperv_recommends = regs[0];
++	if (bootverbose)
++		printf("  Recommends: %08x %08x\n", regs[0], regs[1]);
++
++	op = HV_CPU_ID_FUNCTION_MS_HV_IMPLEMENTATION_LIMITS;
++	do_cpuid(op, regs);
++	if (bootverbose) {
++		printf("  Limits: Vcpu:%d Lcpu:%d Int:%d\n",
++		    regs[0], regs[1], regs[2]);
++	}
++
++	if (maxLeaf >= HV_CPU_ID_FUNCTION_MS_HV_HARDWARE_FEATURE) {
++		op = HV_CPU_ID_FUNCTION_MS_HV_HARDWARE_FEATURE;
++		do_cpuid(op, regs);
++		if (bootverbose) {
++			printf("  HW Features: %08x AMD: %08x\n",
++			    regs[0], regs[3]);
++		}
++	}
++
++	return (true);
++}
++
++static void
++hyperv_init(void *dummy __unused)
++{
++	if (!hyperv_identify())
++		return;
++
++	if (hyperv_features & HV_FEATURE_MSR_TIME_REFCNT) {
++		/* Register virtual timecount */
++		tc_init(&hv_timecounter);
++	}
++}
++SYSINIT(hyperv_initialize, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, hyperv_init, NULL);
+--- sys/dev/hyperv/vmbus/hv_vmbus_priv.h.orig
++++ sys/dev/hyperv/vmbus/hv_vmbus_priv.h
+@@ -471,10 +471,17 @@
+ 	HV_CPU_ID_FUNCTION_MS_HV_VERSION			= 0x40000002,
+ 	HV_CPU_ID_FUNCTION_MS_HV_FEATURES			= 0x40000003,
+ 	HV_CPU_ID_FUNCTION_MS_HV_ENLIGHTENMENT_INFORMATION	= 0x40000004,
+-	HV_CPU_ID_FUNCTION_MS_HV_IMPLEMENTATION_LIMITS		= 0x40000005
+-
++	HV_CPU_ID_FUNCTION_MS_HV_IMPLEMENTATION_LIMITS		= 0x40000005,
++	HV_CPU_ID_FUNCTION_MS_HV_HARDWARE_FEATURE		= 0x40000006
+ } hv_vmbus_cpuid_function;
+ 
++#define	HV_FEATURE_MSR_TIME_REFCNT	(1 << 1)
++#define	HV_FEATURE_MSR_SYNCIC		(1 << 2)
++#define	HV_FEATURE_MSR_STIMER		(1 << 3)
++#define	HV_FEATURE_MSR_APIC		(1 << 4)
++#define	HV_FEATURE_MSR_HYPERCALL	(1 << 5)
++#define	HV_FEATURE_MSR_GUEST_IDLE	(1 << 10)
++
+ /*
+  * Define the format of the SIMP register
+  */
+@@ -628,6 +635,9 @@
+ extern hv_vmbus_context		hv_vmbus_g_context;
+ 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 {

Added: user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:14.hv_storvsc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:14.hv_storvsc	Thu Aug 11 18:13:48 2016	(r303965)
@@ -0,0 +1,50 @@
+--- sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c.orig
++++ sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
+@@ -1273,6 +1273,7 @@
+ }
+ #endif /* HVS_TIMEOUT_TEST */
+ 
++#ifdef notyet
+ /**
+  * @brief timeout handler for requests
+  *
+@@ -1320,6 +1321,7 @@
+ 	storvsc_timeout_test(reqp, MODE_SELECT_10, 1);
+ #endif
+ }
++#endif
+ 
+ /**
+  * @brief StorVSC device poll function
+@@ -1472,6 +1474,7 @@
+ 			return;
+ 		}
+ 
++#ifdef notyet
+ 		if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
+ 			callout_init(&reqp->callout, CALLOUT_MPSAFE);
+ 			callout_reset_sbt(&reqp->callout,
+@@ -1491,6 +1494,7 @@
+ 			}
+ #endif /* HVS_TIMEOUT_TEST */
+ 		}
++#endif
+ 
+ 		if ((res = hv_storvsc_io_request(sc->hs_dev, reqp)) != 0) {
+ 			xpt_print(ccb->ccb_h.path,
+@@ -2039,6 +2043,7 @@
+ 		mtx_unlock(&sc->hs_lock);
+ 	}
+ 
++#ifdef notyet
+ 	/*
+ 	 * callout_drain() will wait for the timer handler to finish
+ 	 * if it is running. So we don't need any lock to synchronize
+@@ -2049,6 +2054,7 @@
+ 	if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
+ 		callout_drain(&reqp->callout);
+ 	}
++#endif
+ 
+ 	ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
+ 	ccb->ccb_h.status &= ~CAM_STATUS_MASK;

Added: user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:15.vmbus
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:15.vmbus	Thu Aug 11 18:13:48 2016	(r303965)
@@ -0,0 +1,68 @@
+--- sys/dev/hyperv/vmbus/hv_connection.c.orig
++++ sys/dev/hyperv/vmbus/hv_connection.c
+@@ -476,31 +476,35 @@
+ /**
+  * Send a msg on the vmbus's message connection
+  */
+-int hv_vmbus_post_message(void *buffer, size_t bufferLen) {
+-	int ret = 0;
++int hv_vmbus_post_message(void *buffer, size_t bufferLen)
++{
+ 	hv_vmbus_connection_id connId;
+-	unsigned retries = 0;
+-
+-	/* NetScaler delays from previous code were consolidated here */
+-	static int delayAmount[] = {100, 100, 100, 500, 500, 5000, 5000, 5000};
+-
+-	/* for(each entry in delayAmount) try to post message,
+-	 *  delay a little bit before retrying
++	sbintime_t time = SBT_1MS;
++	int retries;
++	int ret;
++
++	connId.as_uint32_t = 0;
++	connId.u.id = HV_VMBUS_MESSAGE_CONNECTION_ID;
++
++	/*
++	 * We retry to cope with transient failures caused by host side's
++	 * insufficient resources. 20 times should suffice in practice.
+ 	 */
+-	for (retries = 0;
+-	    retries < sizeof(delayAmount)/sizeof(delayAmount[0]); retries++) {
+-	    connId.as_uint32_t = 0;
+-	    connId.u.id = HV_VMBUS_MESSAGE_CONNECTION_ID;
+-	    ret = hv_vmbus_post_msg_via_msg_ipc(connId, 1, buffer, bufferLen);
+-	    if (ret != HV_STATUS_INSUFFICIENT_BUFFERS)
+-		break;
+-	    /* TODO: KYS We should use a blocking wait call */
+-	    DELAY(delayAmount[retries]);
++	for (retries = 0; retries < 20; retries++) {
++		ret = hv_vmbus_post_msg_via_msg_ipc(connId, 1, buffer,
++						    bufferLen);
++		if (ret == HV_STATUS_SUCCESS)
++			return (0);
++
++		pause_sbt("pstmsg", time, 0, C_HARDCLOCK);
++		if (time < SBT_1S * 2)
++			time *= 2;
+ 	}
+ 
+-	KASSERT(ret == 0, ("Error VMBUS: Message Post Failed\n"));
++	KASSERT(ret == HV_STATUS_SUCCESS,
++		("Error VMBUS: Message Post Failed, ret=%d\n", ret));
+ 
+-	return (ret);
++	return (EAGAIN);
+ }
+ 
+ /**
+--- sys/dev/hyperv/vmbus/hv_vmbus_priv.h.orig
++++ sys/dev/hyperv/vmbus/hv_vmbus_priv.h
+@@ -70,6 +70,7 @@
+  *    You did not supply enough message buffers to send a message.
+  */
+ 
++#define HV_STATUS_SUCCESS                ((uint16_t)0)
+ #define HV_STATUS_INSUFFICIENT_BUFFERS   ((uint16_t)0x0013)
+ 
+ typedef void (*hv_vmbus_channel_callback)(void *context);

Added: user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:16.hv_storvsc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/cperciva/freebsd-update-build/patches/10.3-RELEASE/7-EN-16:16.hv_storvsc	Thu Aug 11 18:13:48 2016	(r303965)
@@ -0,0 +1,165 @@
+--- sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c.orig
++++ sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
+@@ -805,6 +805,13 @@
+ 
+ 	vm_srb = &vstor_packet->u.vm_srb;
+ 
++	/*
++	 * Copy some fields of the host's response into the request structure,
++	 * because the fields will be used later in storvsc_io_done().
++	 */
++	request->vstor_packet.u.vm_srb.scsi_status = vm_srb->scsi_status;
++	request->vstor_packet.u.vm_srb.transfer_len = vm_srb->transfer_len;
++
+ 	if (((vm_srb->scsi_status & 0xFF) == SCSI_STATUS_CHECK_COND) &&
+ 			(vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID)) {
+ 		/* Autosense data available */
+@@ -1939,62 +1946,24 @@
+ }
+ 
+ /*
+- * Modified based on scsi_print_inquiry which is responsible to
+- * print the detail information for scsi_inquiry_data.
+- *
++ * SCSI Inquiry checks qualifier and type.
++ * If qualifier is 011b, means the device server is not capable
++ * of supporting a peripheral device on this logical unit, and
++ * the type should be set to 1Fh.
++ * 
+  * Return 1 if it is valid, 0 otherwise.
+  */
+ static inline int
+ is_inquiry_valid(const struct scsi_inquiry_data *inq_data)
+ {
+ 	uint8_t type;
+-	char vendor[16], product[48], revision[16];
+-
+-	/*
+-	 * Check device type and qualifier
+-	 */
+-	if (!(SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ||
+-	    SID_QUAL(inq_data) == SID_QUAL_LU_CONNECTED))
++	if (SID_QUAL(inq_data) != SID_QUAL_LU_CONNECTED) {
+ 		return (0);
+-
++	}
+ 	type = SID_TYPE(inq_data);
+-	switch (type) {
+-	case T_DIRECT:
+-	case T_SEQUENTIAL:
+-	case T_PRINTER:
+-	case T_PROCESSOR:
+-	case T_WORM:
+-	case T_CDROM:
+-	case T_SCANNER:
+-	case T_OPTICAL:
+-	case T_CHANGER:
+-	case T_COMM:
+-	case T_STORARRAY:
+-	case T_ENCLOSURE:
+-	case T_RBC:
+-	case T_OCRW:
+-	case T_OSD:
+-	case T_ADC:
+-		break;
+-	case T_NODEVICE:
+-	default:
++	if (type == T_NODEVICE) {
+ 		return (0);
+ 	}
+-
+-	/*
+-	 * Check vendor, product, and revision
+-	 */
+-	cam_strvis(vendor, inq_data->vendor, sizeof(inq_data->vendor),
+-	    sizeof(vendor));
+-	cam_strvis(product, inq_data->product, sizeof(inq_data->product),
+-	    sizeof(product));
+-	cam_strvis(revision, inq_data->revision, sizeof(inq_data->revision),
+-	    sizeof(revision));
+-	if (strlen(vendor) == 0  ||
+-	    strlen(product) == 0 ||
+-	    strlen(revision) == 0)
+-		return (0);
+-
+ 	return (1);
+ }
+ 
+@@ -2071,7 +2040,6 @@
+ 	ccb->ccb_h.status &= ~CAM_STATUS_MASK;
+ 	if (vm_srb->scsi_status == SCSI_STATUS_OK) {
+ 		const struct scsi_generic *cmd;
+-
+ 		/*
+ 		 * Check whether the data for INQUIRY cmd is valid or
+ 		 * not.  Windows 10 and Windows 2016 send all zero
+@@ -2080,23 +2048,59 @@
+ 		cmd = (const struct scsi_generic *)
+ 		    ((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
+ 		     csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes);
+-		if (cmd->opcode == INQUIRY &&
+-		    /* 
+-		     * XXX: Temporary work around disk hot plugin on win2k12r2,
+-		     * only filtering the invalid disk on win10 or 2016 server.
+-		     * So, the hot plugin on win10 and 2016 server needs
+-		     * to be fixed.
++		if (cmd->opcode == INQUIRY) {
++		    /*
++		     * The host of Windows 10 or 2016 server will response
++		     * the inquiry request with invalid data for unexisted device:
++			[0x7f 0x0 0x5 0x2 0x1f ... ]
++		     * But on windows 2012 R2, the response is:
++			[0x7f 0x0 0x0 0x0 0x0 ]
++		     * That is why here wants to validate the inquiry response.
++		     * The validation will skip the INQUIRY whose response is short,
++		     * which is less than SHORT_INQUIRY_LENGTH (36).
++		     *
++		     * For more information about INQUIRY, please refer to:
++		     *  ftp://ftp.avc-pioneer.com/Mtfuji_7/Proposal/Jun09/INQUIRY.pdf
+ 		     */
+-		    vmstor_proto_version == VMSTOR_PROTOCOL_VERSION_WIN10 && 
+-		    is_inquiry_valid(
+-		    (const struct scsi_inquiry_data *)csio->data_ptr) == 0) {
++		    const struct scsi_inquiry_data *inq_data =
++			(const struct scsi_inquiry_data *)csio->data_ptr;
++		    uint8_t* resp_buf = (uint8_t*)csio->data_ptr;
++		    /* Get the buffer length reported by host */
++		    int resp_xfer_len = vm_srb->transfer_len;
++		    /* Get the available buffer length */
++		    int resp_buf_len = resp_xfer_len >= 5 ? resp_buf[4] + 5 : 0;
++		    int data_len = (resp_buf_len < resp_xfer_len) ? resp_buf_len : resp_xfer_len;
++		    if (data_len < SHORT_INQUIRY_LENGTH) {
++			ccb->ccb_h.status |= CAM_REQ_CMP;
++			if (bootverbose && data_len >= 5) {
++				mtx_lock(&sc->hs_lock);
++				xpt_print(ccb->ccb_h.path,
++				    "storvsc skips the validation for short inquiry (%d)"
++				    " [%x %x %x %x %x]\n",
++				    data_len,resp_buf[0],resp_buf[1],resp_buf[2],
++				    resp_buf[3],resp_buf[4]);
++				mtx_unlock(&sc->hs_lock);
++			}
++		    } else if (is_inquiry_valid(inq_data) == 0) {
+ 			ccb->ccb_h.status |= CAM_DEV_NOT_THERE;
++			if (bootverbose && data_len >= 5) {
++				mtx_lock(&sc->hs_lock);
++				xpt_print(ccb->ccb_h.path,
++				    "storvsc uninstalled invalid device"
++				    " [%x %x %x %x %x]\n",
++				resp_buf[0],resp_buf[1],resp_buf[2],resp_buf[3],resp_buf[4]);
++				mtx_unlock(&sc->hs_lock);
++			}
++		    } else {
++			ccb->ccb_h.status |= CAM_REQ_CMP;
+ 			if (bootverbose) {
+ 				mtx_lock(&sc->hs_lock);
+ 				xpt_print(ccb->ccb_h.path,
+-				    "storvsc uninstalled device\n");
++				    "storvsc has passed inquiry response (%d) validation\n",
++				    data_len);
+ 				mtx_unlock(&sc->hs_lock);
+ 			}
++		    }
+ 		} else {
+ 			ccb->ccb_h.status |= CAM_REQ_CMP;
+ 		}



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