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