summaryrefslogtreecommitdiffstats
path: root/drivers/hv/hv_kvp.c
diff options
context:
space:
mode:
authorAlex Ng <alexng@messages.microsoft.com>2017-01-28 12:37:17 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-31 11:05:59 +0100
commita1656454131880980bc3a5313c8bf66ef5990c91 (patch)
treeab70bf0b5d87cfcae805407b550e7afa496520b5 /drivers/hv/hv_kvp.c
parentad6d41253bf91eabb41626683c35a712ba27a20c (diff)
downloadlinux-a1656454131880980bc3a5313c8bf66ef5990c91.tar.gz
linux-a1656454131880980bc3a5313c8bf66ef5990c91.tar.bz2
linux-a1656454131880980bc3a5313c8bf66ef5990c91.zip
Drivers: hv: vmbus: Use all supported IC versions to negotiate
Previously, we were assuming that each IC protocol version was tied to a specific host version. For example, some Windows 10 preview hosts only support v3 TimeSync even though driver assumes v4 is supported by all Windows 10 hosts. The guest will stop trying to negotiate even though older supported versions may still be offered by the host. Make IC version negotiation more robust by going through all versions that are supported by the guest. Fixes: 3da0401b4d0e ("Drivers: hv: utils: Fix the mapping between host version and protocol to use") Reported-by: Rolf Neugebauer <rolf.neugebauer@docker.com> Signed-off-by: Alex Ng <alexng@messages.microsoft.com> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv/hv_kvp.c')
-rw-r--r--drivers/hv/hv_kvp.c41
1 files changed, 17 insertions, 24 deletions
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 3abfc5983c97..2cc670442f6c 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -46,6 +46,19 @@
#define WIN8_SRV_MINOR 0
#define WIN8_SRV_VERSION (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR)
+#define KVP_VER_COUNT 3
+static const int kvp_versions[] = {
+ WIN8_SRV_VERSION,
+ WIN7_SRV_VERSION,
+ WS2008_SRV_VERSION
+};
+
+#define FW_VER_COUNT 2
+static const int fw_versions[] = {
+ UTIL_FW_VERSION,
+ UTIL_WS2K8_FW_VERSION
+};
+
/*
* Global state maintained for transaction that is being processed. For a class
* of integration services, including the "KVP service", the specified protocol
@@ -610,8 +623,6 @@ void hv_kvp_onchannelcallback(void *context)
struct hv_kvp_msg *kvp_msg;
struct icmsg_hdr *icmsghdrp;
- struct icmsg_negotiate *negop = NULL;
- int util_fw_version;
int kvp_srv_version;
static enum {NEGO_NOT_STARTED,
NEGO_IN_PROGRESS,
@@ -640,28 +651,10 @@ void hv_kvp_onchannelcallback(void *context)
sizeof(struct vmbuspipe_hdr)];
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
- /*
- * Based on the host, select appropriate
- * framework and service versions we will
- * negotiate.
- */
- switch (vmbus_proto_version) {
- case (VERSION_WS2008):
- util_fw_version = UTIL_WS2K8_FW_VERSION;
- kvp_srv_version = WS2008_SRV_VERSION;
- break;
- case (VERSION_WIN7):
- util_fw_version = UTIL_FW_VERSION;
- kvp_srv_version = WIN7_SRV_VERSION;
- break;
- default:
- util_fw_version = UTIL_FW_VERSION;
- kvp_srv_version = WIN8_SRV_VERSION;
- }
- vmbus_prep_negotiate_resp(icmsghdrp, negop,
- recv_buffer, util_fw_version,
- kvp_srv_version);
-
+ vmbus_prep_negotiate_resp(icmsghdrp,
+ recv_buffer, fw_versions, FW_VER_COUNT,
+ kvp_versions, KVP_VER_COUNT,
+ NULL, &kvp_srv_version);
} else {
kvp_msg = (struct hv_kvp_msg *)&recv_buffer[
sizeof(struct vmbuspipe_hdr) +