svn commit: r303965 - user/cperciva/freebsd-update-build/patches/10.3-RELEASE
Gleb Smirnoff
glebius at FreeBSD.org
Thu Aug 11 18:13:50 UTC 2016
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;
+ }
More information about the svn-src-user
mailing list