1 /* 2 * An implementation of file copy service. 3 * 4 * Copyright (C) 2014, Microsoft, Inc. 5 * 6 * Author : K. Y. Srinivasan <ksrinivasan@novell.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License version 2 as published 10 * by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 15 * NON INFRINGEMENT. See the GNU General Public License for more 16 * details. 17 * 18 */ 19 20 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 21 22 #include <linux/nls.h> 23 #include <linux/workqueue.h> 24 #include <linux/hyperv.h> 25 #include <linux/sched.h> 26 27 #include "hyperv_vmbus.h" 28 #include "hv_utils_transport.h" 29 30 #define WIN8_SRV_MAJOR 1 31 #define WIN8_SRV_MINOR 1 32 #define WIN8_SRV_VERSION (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR) 33 34 #define FCOPY_VER_COUNT 1 35 static const int fcopy_versions[] = { 36 WIN8_SRV_VERSION 37 }; 38 39 #define FW_VER_COUNT 1 40 static const int fw_versions[] = { 41 UTIL_FW_VERSION 42 }; 43 44 /* 45 * Global state maintained for transaction that is being processed. 46 * For a class of integration services, including the "file copy service", 47 * the specified protocol is a "request/response" protocol which means that 48 * there can only be single outstanding transaction from the host at any 49 * given point in time. We use this to simplify memory management in this 50 * driver - we cache and process only one message at a time. 51 * 52 * While the request/response protocol is guaranteed by the host, we further 53 * ensure this by serializing packet processing in this driver - we do not 54 * read additional packets from the VMBUs until the current packet is fully 55 * handled. 56 */ 57 58 static struct { 59 int state; /* hvutil_device_state */ 60 int recv_len; /* number of bytes received. */ 61 struct hv_fcopy_hdr *fcopy_msg; /* current message */ 62 struct vmbus_channel *recv_channel; /* chn we got the request */ 63 u64 recv_req_id; /* request ID. */ 64 } fcopy_transaction; 65 66 static void fcopy_respond_to_host(int error); 67 static void fcopy_send_data(struct work_struct *dummy); 68 static void fcopy_timeout_func(struct work_struct *dummy); 69 static DECLARE_DELAYED_WORK(fcopy_timeout_work, fcopy_timeout_func); 70 static DECLARE_WORK(fcopy_send_work, fcopy_send_data); 71 static const char fcopy_devname[] = "vmbus/hv_fcopy"; 72 static u8 *recv_buffer; 73 static struct hvutil_transport *hvt; 74 static struct completion release_event; 75 /* 76 * This state maintains the version number registered by the daemon. 77 */ 78 static int dm_reg_value; 79 80 static void fcopy_poll_wrapper(void *channel) 81 { 82 /* Transaction is finished, reset the state here to avoid races. */ 83 fcopy_transaction.state = HVUTIL_READY; 84 hv_fcopy_onchannelcallback(channel); 85 } 86 87 static void fcopy_timeout_func(struct work_struct *dummy) 88 { 89 /* 90 * If the timer fires, the user-mode component has not responded; 91 * process the pending transaction. 92 */ 93 fcopy_respond_to_host(HV_E_FAIL); 94 hv_poll_channel(fcopy_transaction.recv_channel, fcopy_poll_wrapper); 95 } 96 97 static void fcopy_register_done(void) 98 { 99 pr_debug("FCP: userspace daemon registered\n"); 100 hv_poll_channel(fcopy_transaction.recv_channel, fcopy_poll_wrapper); 101 } 102 103 static int fcopy_handle_handshake(u32 version) 104 { 105 u32 our_ver = FCOPY_CURRENT_VERSION; 106 107 switch (version) { 108 case FCOPY_VERSION_0: 109 /* Daemon doesn't expect us to reply */ 110 dm_reg_value = version; 111 break; 112 case FCOPY_VERSION_1: 113 /* Daemon expects us to reply with our own version */ 114 if (hvutil_transport_send(hvt, &our_ver, sizeof(our_ver), 115 fcopy_register_done)) 116 return -EFAULT; 117 dm_reg_value = version; 118 break; 119 default: 120 /* 121 * For now we will fail the registration. 122 * If and when we have multiple versions to 123 * deal with, we will be backward compatible. 124 * We will add this code when needed. 125 */ 126 return -EINVAL; 127 } 128 pr_debug("FCP: userspace daemon ver. %d connected\n", version); 129 return 0; 130 } 131 132 static void fcopy_send_data(struct work_struct *dummy) 133 { 134 struct hv_start_fcopy *smsg_out = NULL; 135 int operation = fcopy_transaction.fcopy_msg->operation; 136 struct hv_start_fcopy *smsg_in; 137 void *out_src; 138 int rc, out_len; 139 140 /* 141 * The strings sent from the host are encoded in 142 * in utf16; convert it to utf8 strings. 143 * The host assures us that the utf16 strings will not exceed 144 * the max lengths specified. We will however, reserve room 145 * for the string terminating character - in the utf16s_utf8s() 146 * function we limit the size of the buffer where the converted 147 * string is placed to W_MAX_PATH -1 to guarantee 148 * that the strings can be properly terminated! 149 */ 150 151 switch (operation) { 152 case START_FILE_COPY: 153 out_len = sizeof(struct hv_start_fcopy); 154 smsg_out = kzalloc(sizeof(*smsg_out), GFP_KERNEL); 155 if (!smsg_out) 156 return; 157 158 smsg_out->hdr.operation = operation; 159 smsg_in = (struct hv_start_fcopy *)fcopy_transaction.fcopy_msg; 160 161 utf16s_to_utf8s((wchar_t *)smsg_in->file_name, W_MAX_PATH, 162 UTF16_LITTLE_ENDIAN, 163 (__u8 *)&smsg_out->file_name, W_MAX_PATH - 1); 164 165 utf16s_to_utf8s((wchar_t *)smsg_in->path_name, W_MAX_PATH, 166 UTF16_LITTLE_ENDIAN, 167 (__u8 *)&smsg_out->path_name, W_MAX_PATH - 1); 168 169 smsg_out->copy_flags = smsg_in->copy_flags; 170 smsg_out->file_size = smsg_in->file_size; 171 out_src = smsg_out; 172 break; 173 174 default: 175 out_src = fcopy_transaction.fcopy_msg; 176 out_len = fcopy_transaction.recv_len; 177 break; 178 } 179 180 fcopy_transaction.state = HVUTIL_USERSPACE_REQ; 181 rc = hvutil_transport_send(hvt, out_src, out_len, NULL); 182 if (rc) { 183 pr_debug("FCP: failed to communicate to the daemon: %d\n", rc); 184 if (cancel_delayed_work_sync(&fcopy_timeout_work)) { 185 fcopy_respond_to_host(HV_E_FAIL); 186 fcopy_transaction.state = HVUTIL_READY; 187 } 188 } 189 kfree(smsg_out); 190 191 return; 192 } 193 194 /* 195 * Send a response back to the host. 196 */ 197 198 static void 199 fcopy_respond_to_host(int error) 200 { 201 struct icmsg_hdr *icmsghdr; 202 u32 buf_len; 203 struct vmbus_channel *channel; 204 u64 req_id; 205 206 /* 207 * Copy the global state for completing the transaction. Note that 208 * only one transaction can be active at a time. This is guaranteed 209 * by the file copy protocol implemented by the host. Furthermore, 210 * the "transaction active" state we maintain ensures that there can 211 * only be one active transaction at a time. 212 */ 213 214 buf_len = fcopy_transaction.recv_len; 215 channel = fcopy_transaction.recv_channel; 216 req_id = fcopy_transaction.recv_req_id; 217 218 icmsghdr = (struct icmsg_hdr *) 219 &recv_buffer[sizeof(struct vmbuspipe_hdr)]; 220 221 if (channel->onchannel_callback == NULL) 222 /* 223 * We have raced with util driver being unloaded; 224 * silently return. 225 */ 226 return; 227 228 icmsghdr->status = error; 229 icmsghdr->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; 230 vmbus_sendpacket(channel, recv_buffer, buf_len, req_id, 231 VM_PKT_DATA_INBAND, 0); 232 } 233 234 void hv_fcopy_onchannelcallback(void *context) 235 { 236 struct vmbus_channel *channel = context; 237 u32 recvlen; 238 u64 requestid; 239 struct hv_fcopy_hdr *fcopy_msg; 240 struct icmsg_hdr *icmsghdr; 241 int fcopy_srv_version; 242 243 if (fcopy_transaction.state > HVUTIL_READY) 244 return; 245 246 vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen, 247 &requestid); 248 if (recvlen <= 0) 249 return; 250 251 icmsghdr = (struct icmsg_hdr *)&recv_buffer[ 252 sizeof(struct vmbuspipe_hdr)]; 253 if (icmsghdr->icmsgtype == ICMSGTYPE_NEGOTIATE) { 254 if (vmbus_prep_negotiate_resp(icmsghdr, recv_buffer, 255 fw_versions, FW_VER_COUNT, 256 fcopy_versions, FCOPY_VER_COUNT, 257 NULL, &fcopy_srv_version)) { 258 259 pr_info("FCopy IC version %d.%d\n", 260 fcopy_srv_version >> 16, 261 fcopy_srv_version & 0xFFFF); 262 } 263 } else { 264 fcopy_msg = (struct hv_fcopy_hdr *)&recv_buffer[ 265 sizeof(struct vmbuspipe_hdr) + 266 sizeof(struct icmsg_hdr)]; 267 268 /* 269 * Stash away this global state for completing the 270 * transaction; note transactions are serialized. 271 */ 272 273 fcopy_transaction.recv_len = recvlen; 274 fcopy_transaction.recv_req_id = requestid; 275 fcopy_transaction.fcopy_msg = fcopy_msg; 276 277 if (fcopy_transaction.state < HVUTIL_READY) { 278 /* Userspace is not registered yet */ 279 fcopy_respond_to_host(HV_E_FAIL); 280 return; 281 } 282 fcopy_transaction.state = HVUTIL_HOSTMSG_RECEIVED; 283 284 /* 285 * Send the information to the user-level daemon. 286 */ 287 schedule_work(&fcopy_send_work); 288 schedule_delayed_work(&fcopy_timeout_work, 289 HV_UTIL_TIMEOUT * HZ); 290 return; 291 } 292 icmsghdr->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; 293 vmbus_sendpacket(channel, recv_buffer, recvlen, requestid, 294 VM_PKT_DATA_INBAND, 0); 295 } 296 297 /* Callback when data is received from userspace */ 298 static int fcopy_on_msg(void *msg, int len) 299 { 300 int *val = (int *)msg; 301 302 if (len != sizeof(int)) 303 return -EINVAL; 304 305 if (fcopy_transaction.state == HVUTIL_DEVICE_INIT) 306 return fcopy_handle_handshake(*val); 307 308 if (fcopy_transaction.state != HVUTIL_USERSPACE_REQ) 309 return -EINVAL; 310 311 /* 312 * Complete the transaction by forwarding the result 313 * to the host. But first, cancel the timeout. 314 */ 315 if (cancel_delayed_work_sync(&fcopy_timeout_work)) { 316 fcopy_transaction.state = HVUTIL_USERSPACE_RECV; 317 fcopy_respond_to_host(*val); 318 hv_poll_channel(fcopy_transaction.recv_channel, 319 fcopy_poll_wrapper); 320 } 321 322 return 0; 323 } 324 325 static void fcopy_on_reset(void) 326 { 327 /* 328 * The daemon has exited; reset the state. 329 */ 330 fcopy_transaction.state = HVUTIL_DEVICE_INIT; 331 332 if (cancel_delayed_work_sync(&fcopy_timeout_work)) 333 fcopy_respond_to_host(HV_E_FAIL); 334 complete(&release_event); 335 } 336 337 int hv_fcopy_init(struct hv_util_service *srv) 338 { 339 recv_buffer = srv->recv_buffer; 340 fcopy_transaction.recv_channel = srv->channel; 341 342 init_completion(&release_event); 343 /* 344 * When this driver loads, the user level daemon that 345 * processes the host requests may not yet be running. 346 * Defer processing channel callbacks until the daemon 347 * has registered. 348 */ 349 fcopy_transaction.state = HVUTIL_DEVICE_INIT; 350 351 hvt = hvutil_transport_init(fcopy_devname, 0, 0, 352 fcopy_on_msg, fcopy_on_reset); 353 if (!hvt) 354 return -EFAULT; 355 356 return 0; 357 } 358 359 void hv_fcopy_deinit(void) 360 { 361 fcopy_transaction.state = HVUTIL_DEVICE_DYING; 362 cancel_delayed_work_sync(&fcopy_timeout_work); 363 hvutil_transport_destroy(hvt); 364 wait_for_completion(&release_event); 365 } 366