Drivers: hv: fcopy: switch to using the hvutil_device_state state machine
[firefly-linux-kernel-4.4.55.git] / drivers / hv / hv_fcopy.c
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/semaphore.h>
23 #include <linux/fs.h>
24 #include <linux/nls.h>
25 #include <linux/workqueue.h>
26 #include <linux/cdev.h>
27 #include <linux/hyperv.h>
28 #include <linux/sched.h>
29 #include <linux/uaccess.h>
30 #include <linux/miscdevice.h>
31
32 #include "hyperv_vmbus.h"
33
34 #define WIN8_SRV_MAJOR          1
35 #define WIN8_SRV_MINOR          1
36 #define WIN8_SRV_VERSION        (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR)
37
38 /*
39  * Global state maintained for transaction that is being processed.
40  * For a class of integration services, including the "file copy service",
41  * the specified protocol is a "request/response" protocol which means that
42  * there can only be single outstanding transaction from the host at any
43  * given point in time. We use this to simplify memory management in this
44  * driver - we cache and process only one message at a time.
45  *
46  * While the request/response protocol is guaranteed by the host, we further
47  * ensure this by serializing packet processing in this driver - we do not
48  * read additional packets from the VMBUs until the current packet is fully
49  * handled.
50  */
51
52 static struct {
53         int state;   /* hvutil_device_state */
54         int recv_len; /* number of bytes received. */
55         struct hv_fcopy_hdr  *fcopy_msg; /* current message */
56         struct hv_start_fcopy  message; /*  sent to daemon */
57         struct vmbus_channel *recv_channel; /* chn we got the request */
58         u64 recv_req_id; /* request ID. */
59         void *fcopy_context; /* for the channel callback */
60         struct semaphore read_sema;
61 } fcopy_transaction;
62
63 static void fcopy_send_data(void);
64 static void fcopy_respond_to_host(int error);
65 static void fcopy_timeout_func(struct work_struct *dummy);
66 static DECLARE_DELAYED_WORK(fcopy_timeout_work, fcopy_timeout_func);
67 static u8 *recv_buffer;
68
69 static void fcopy_timeout_func(struct work_struct *dummy)
70 {
71         /*
72          * If the timer fires, the user-mode component has not responded;
73          * process the pending transaction.
74          */
75         fcopy_respond_to_host(HV_E_FAIL);
76
77         /* Transaction is finished, reset the state. */
78         if (fcopy_transaction.state > HVUTIL_READY)
79                 fcopy_transaction.state = HVUTIL_READY;
80
81         /* In the case the user-space daemon crashes, hangs or is killed, we
82          * need to down the semaphore, otherwise, after the daemon starts next
83          * time, the obsolete data in fcopy_transaction.message or
84          * fcopy_transaction.fcopy_msg will be used immediately.
85          *
86          * NOTE: fcopy_read() happens to get the semaphore (very rare)? We're
87          * still OK, because we've reported the failure to the host.
88          */
89         if (down_trylock(&fcopy_transaction.read_sema))
90                 ;
91
92         hv_poll_channel(fcopy_transaction.fcopy_context,
93                         hv_fcopy_onchannelcallback);
94 }
95
96 static int fcopy_handle_handshake(u32 version)
97 {
98         switch (version) {
99         case FCOPY_CURRENT_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_info("FCP: user-mode registering done. Daemon version: %d\n",
111                 version);
112         fcopy_transaction.state = HVUTIL_READY;
113         hv_poll_channel(fcopy_transaction.fcopy_context,
114                         hv_fcopy_onchannelcallback);
115         return 0;
116 }
117
118 static void fcopy_send_data(void)
119 {
120         struct hv_start_fcopy *smsg_out = &fcopy_transaction.message;
121         int operation = fcopy_transaction.fcopy_msg->operation;
122         struct hv_start_fcopy *smsg_in;
123
124         /*
125          * The  strings sent from the host are encoded in
126          * in utf16; convert it to utf8 strings.
127          * The host assures us that the utf16 strings will not exceed
128          * the max lengths specified. We will however, reserve room
129          * for the string terminating character - in the utf16s_utf8s()
130          * function we limit the size of the buffer where the converted
131          * string is placed to W_MAX_PATH -1 to guarantee
132          * that the strings can be properly terminated!
133          */
134
135         switch (operation) {
136         case START_FILE_COPY:
137                 memset(smsg_out, 0, sizeof(struct hv_start_fcopy));
138                 smsg_out->hdr.operation = operation;
139                 smsg_in = (struct hv_start_fcopy *)fcopy_transaction.fcopy_msg;
140
141                 utf16s_to_utf8s((wchar_t *)smsg_in->file_name, W_MAX_PATH,
142                                 UTF16_LITTLE_ENDIAN,
143                                 (__u8 *)smsg_out->file_name, W_MAX_PATH - 1);
144
145                 utf16s_to_utf8s((wchar_t *)smsg_in->path_name, W_MAX_PATH,
146                                 UTF16_LITTLE_ENDIAN,
147                                 (__u8 *)smsg_out->path_name, W_MAX_PATH - 1);
148
149                 smsg_out->copy_flags = smsg_in->copy_flags;
150                 smsg_out->file_size = smsg_in->file_size;
151                 break;
152
153         default:
154                 break;
155         }
156         up(&fcopy_transaction.read_sema);
157         return;
158 }
159
160 /*
161  * Send a response back to the host.
162  */
163
164 static void
165 fcopy_respond_to_host(int error)
166 {
167         struct icmsg_hdr *icmsghdr;
168         u32 buf_len;
169         struct vmbus_channel *channel;
170         u64 req_id;
171
172         /*
173          * Copy the global state for completing the transaction. Note that
174          * only one transaction can be active at a time. This is guaranteed
175          * by the file copy protocol implemented by the host. Furthermore,
176          * the "transaction active" state we maintain ensures that there can
177          * only be one active transaction at a time.
178          */
179
180         buf_len = fcopy_transaction.recv_len;
181         channel = fcopy_transaction.recv_channel;
182         req_id = fcopy_transaction.recv_req_id;
183
184         icmsghdr = (struct icmsg_hdr *)
185                         &recv_buffer[sizeof(struct vmbuspipe_hdr)];
186
187         if (channel->onchannel_callback == NULL)
188                 /*
189                  * We have raced with util driver being unloaded;
190                  * silently return.
191                  */
192                 return;
193
194         icmsghdr->status = error;
195         icmsghdr->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE;
196         vmbus_sendpacket(channel, recv_buffer, buf_len, req_id,
197                                 VM_PKT_DATA_INBAND, 0);
198 }
199
200 void hv_fcopy_onchannelcallback(void *context)
201 {
202         struct vmbus_channel *channel = context;
203         u32 recvlen;
204         u64 requestid;
205         struct hv_fcopy_hdr *fcopy_msg;
206         struct icmsg_hdr *icmsghdr;
207         struct icmsg_negotiate *negop = NULL;
208         int util_fw_version;
209         int fcopy_srv_version;
210
211         if (fcopy_transaction.state > HVUTIL_READY) {
212                 /*
213                  * We will defer processing this callback once
214                  * the current transaction is complete.
215                  */
216                 fcopy_transaction.fcopy_context = context;
217                 return;
218         }
219         fcopy_transaction.fcopy_context = NULL;
220
221         vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen,
222                          &requestid);
223         if (recvlen <= 0)
224                 return;
225
226         icmsghdr = (struct icmsg_hdr *)&recv_buffer[
227                         sizeof(struct vmbuspipe_hdr)];
228         if (icmsghdr->icmsgtype == ICMSGTYPE_NEGOTIATE) {
229                 util_fw_version = UTIL_FW_VERSION;
230                 fcopy_srv_version = WIN8_SRV_VERSION;
231                 vmbus_prep_negotiate_resp(icmsghdr, negop, recv_buffer,
232                                 util_fw_version, fcopy_srv_version);
233         } else {
234                 fcopy_msg = (struct hv_fcopy_hdr *)&recv_buffer[
235                                 sizeof(struct vmbuspipe_hdr) +
236                                 sizeof(struct icmsg_hdr)];
237
238                 /*
239                  * Stash away this global state for completing the
240                  * transaction; note transactions are serialized.
241                  */
242
243                 fcopy_transaction.recv_len = recvlen;
244                 fcopy_transaction.recv_channel = channel;
245                 fcopy_transaction.recv_req_id = requestid;
246                 fcopy_transaction.fcopy_msg = fcopy_msg;
247
248                 if (fcopy_transaction.state < HVUTIL_READY) {
249                         /* Userspace is not registered yet */
250                         fcopy_respond_to_host(HV_E_FAIL);
251                         return;
252                 }
253                 fcopy_transaction.state = HVUTIL_HOSTMSG_RECEIVED;
254
255                 /*
256                  * Send the information to the user-level daemon.
257                  */
258                 schedule_delayed_work(&fcopy_timeout_work, 5*HZ);
259                 fcopy_send_data();
260                 return;
261         }
262         icmsghdr->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE;
263         vmbus_sendpacket(channel, recv_buffer, recvlen, requestid,
264                         VM_PKT_DATA_INBAND, 0);
265 }
266
267 /*
268  * Create a char device that can support read/write for passing
269  * the payload.
270  */
271
272 static ssize_t fcopy_read(struct file *file, char __user *buf,
273                 size_t count, loff_t *ppos)
274 {
275         void *src;
276         size_t copy_size;
277         int operation;
278
279         /*
280          * Wait until there is something to be read.
281          */
282         if (down_interruptible(&fcopy_transaction.read_sema))
283                 return -EINTR;
284
285         /*
286          * The channel may be rescinded and in this case, we will wakeup the
287          * the thread blocked on the semaphore and we will use the state to
288          * correctly handle this case.
289          */
290         if (fcopy_transaction.state != HVUTIL_HOSTMSG_RECEIVED)
291                 return -ENODEV;
292
293         operation = fcopy_transaction.fcopy_msg->operation;
294
295         if (operation == START_FILE_COPY) {
296                 src = &fcopy_transaction.message;
297                 copy_size = sizeof(struct hv_start_fcopy);
298                 if (count < copy_size)
299                         return 0;
300         } else {
301                 src = fcopy_transaction.fcopy_msg;
302                 copy_size = sizeof(struct hv_do_fcopy);
303                 if (count < copy_size)
304                         return 0;
305         }
306         if (copy_to_user(buf, src, copy_size))
307                 return -EFAULT;
308
309         fcopy_transaction.state = HVUTIL_USERSPACE_REQ;
310
311         return copy_size;
312 }
313
314 static ssize_t fcopy_write(struct file *file, const char __user *buf,
315                         size_t count, loff_t *ppos)
316 {
317         int response = 0;
318
319         if (count != sizeof(int))
320                 return -EINVAL;
321
322         if (copy_from_user(&response, buf, sizeof(int)))
323                 return -EFAULT;
324
325         if (fcopy_transaction.state == HVUTIL_DEVICE_INIT) {
326                 if (fcopy_handle_handshake(response))
327                         return -EINVAL;
328                 return sizeof(int);
329         }
330
331         if (fcopy_transaction.state != HVUTIL_USERSPACE_REQ)
332                 return -EINVAL;
333
334         /*
335          * Complete the transaction by forwarding the result
336          * to the host. But first, cancel the timeout.
337          */
338         if (cancel_delayed_work_sync(&fcopy_timeout_work)) {
339                 fcopy_transaction.state = HVUTIL_USERSPACE_RECV;
340                 fcopy_respond_to_host(response);
341                 fcopy_transaction.state = HVUTIL_READY;
342                 hv_poll_channel(fcopy_transaction.fcopy_context,
343                                 hv_fcopy_onchannelcallback);
344         }
345
346         return sizeof(int);
347 }
348
349 static int fcopy_open(struct inode *inode, struct file *f)
350 {
351         /*
352          * The user level daemon that will open this device is
353          * really an extension of this driver. We can have only
354          * active open at a time.
355          */
356         if (fcopy_transaction.state != HVUTIL_DEVICE_INIT)
357                 return -EBUSY;
358
359         return 0;
360 }
361
362 /* XXX: there are still some tricky corner cases, e.g.,
363  * 1) In a SMP guest, when fcopy_release() runs between
364  * schedule_delayed_work() and fcopy_send_data(), there is
365  * still a chance an obsolete message will be queued.
366  *
367  * 2) When the fcopy daemon is running, if we unload the driver,
368  * we'll notice a kernel oops when we kill the daemon later.
369  */
370 static int fcopy_release(struct inode *inode, struct file *f)
371 {
372         /*
373          * The daemon has exited; reset the state.
374          */
375         fcopy_transaction.state = HVUTIL_DEVICE_INIT;
376
377         if (cancel_delayed_work_sync(&fcopy_timeout_work)) {
378                 /* We haven't up()-ed the semaphore(very rare)? */
379                 if (down_trylock(&fcopy_transaction.read_sema))
380                         ;
381                 fcopy_respond_to_host(HV_E_FAIL);
382         }
383         return 0;
384 }
385
386
387 static const struct file_operations fcopy_fops = {
388         .read           = fcopy_read,
389         .write          = fcopy_write,
390         .release        = fcopy_release,
391         .open           = fcopy_open,
392 };
393
394 static struct miscdevice fcopy_misc = {
395         .minor          = MISC_DYNAMIC_MINOR,
396         .name           = "vmbus/hv_fcopy",
397         .fops           = &fcopy_fops,
398 };
399
400 static int fcopy_dev_init(void)
401 {
402         return misc_register(&fcopy_misc);
403 }
404
405 static void fcopy_dev_deinit(void)
406 {
407
408         /*
409          * Signal the semaphore as the device is
410          * going away.
411          */
412         up(&fcopy_transaction.read_sema);
413         misc_deregister(&fcopy_misc);
414 }
415
416 int hv_fcopy_init(struct hv_util_service *srv)
417 {
418         recv_buffer = srv->recv_buffer;
419
420         /*
421          * When this driver loads, the user level daemon that
422          * processes the host requests may not yet be running.
423          * Defer processing channel callbacks until the daemon
424          * has registered.
425          */
426         fcopy_transaction.state = HVUTIL_DEVICE_INIT;
427         sema_init(&fcopy_transaction.read_sema, 0);
428
429         return fcopy_dev_init();
430 }
431
432 void hv_fcopy_deinit(void)
433 {
434         fcopy_transaction.state = HVUTIL_DEVICE_DYING;
435         cancel_delayed_work_sync(&fcopy_timeout_work);
436         fcopy_dev_deinit();
437 }