Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Drivers: hv: fcopy: full handshake support

Introduce FCOPY_VERSION_1 to support kernel replying to the negotiation
message with its own version.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Tested-by: Alex Ng <alexng@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Vitaly Kuznetsov and committed by
Greg Kroah-Hartman
a4d1ee5b cd8dc054

+32 -2
+15 -1
drivers/hv/hv_fcopy.c
··· 62 62 static const char fcopy_devname[] = "vmbus/hv_fcopy"; 63 63 static u8 *recv_buffer; 64 64 static struct hvutil_transport *hvt; 65 + /* 66 + * This state maintains the version number registered by the daemon. 67 + */ 68 + static int dm_reg_value; 65 69 66 70 static void fcopy_timeout_func(struct work_struct *dummy) 67 71 { ··· 85 81 86 82 static int fcopy_handle_handshake(u32 version) 87 83 { 84 + u32 our_ver = FCOPY_CURRENT_VERSION; 85 + 88 86 switch (version) { 89 - case FCOPY_CURRENT_VERSION: 87 + case FCOPY_VERSION_0: 88 + /* Daemon doesn't expect us to reply */ 89 + dm_reg_value = version; 90 + break; 91 + case FCOPY_VERSION_1: 92 + /* Daemon expects us to reply with our own version */ 93 + if (hvutil_transport_send(hvt, &our_ver, sizeof(our_ver))) 94 + return -EFAULT; 95 + dm_reg_value = version; 90 96 break; 91 97 default: 92 98 /*
+2 -1
include/uapi/linux/hyperv.h
··· 105 105 */ 106 106 107 107 #define FCOPY_VERSION_0 0 108 - #define FCOPY_CURRENT_VERSION FCOPY_VERSION_0 108 + #define FCOPY_VERSION_1 1 109 + #define FCOPY_CURRENT_VERSION FCOPY_VERSION_1 109 110 #define W_MAX_PATH 260 110 111 111 112 enum hv_fcopy_op {
+15
tools/hv/hv_fcopy_daemon.c
··· 137 137 int version = FCOPY_CURRENT_VERSION; 138 138 char *buffer[4096 * 2]; 139 139 struct hv_fcopy_hdr *in_msg; 140 + int in_handshake = 1; 141 + __u32 kernel_modver; 140 142 141 143 static struct option long_options[] = { 142 144 {"help", no_argument, 0, 'h' }, ··· 193 191 syslog(LOG_ERR, "pread failed: %s", strerror(errno)); 194 192 exit(EXIT_FAILURE); 195 193 } 194 + 195 + if (in_handshake) { 196 + if (len != sizeof(kernel_modver)) { 197 + syslog(LOG_ERR, "invalid version negotiation"); 198 + exit(EXIT_FAILURE); 199 + } 200 + kernel_modver = *(__u32 *)buffer; 201 + in_handshake = 0; 202 + syslog(LOG_INFO, "HV_FCOPY: kernel module version: %d", 203 + kernel_modver); 204 + continue; 205 + } 206 + 196 207 in_msg = (struct hv_fcopy_hdr *)buffer; 197 208 198 209 switch (in_msg->operation) {