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