xref: /openbmc/linux/drivers/hv/hv_snapshot.c (revision 8730046c)
1 /*
2  * An implementation of host initiated guest snapshot.
3  *
4  *
5  * Copyright (C) 2013, Microsoft, Inc.
6  * Author : K. Y. Srinivasan <kys@microsoft.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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20 
21 #include <linux/net.h>
22 #include <linux/nls.h>
23 #include <linux/connector.h>
24 #include <linux/workqueue.h>
25 #include <linux/hyperv.h>
26 
27 #include "hyperv_vmbus.h"
28 #include "hv_utils_transport.h"
29 
30 #define VSS_MAJOR  5
31 #define VSS_MINOR  0
32 #define VSS_VERSION    (VSS_MAJOR << 16 | VSS_MINOR)
33 
34 /*
35  * Timeout values are based on expecations from host
36  */
37 #define VSS_FREEZE_TIMEOUT (15 * 60)
38 
39 /*
40  * Global state maintained for transaction that is being processed. For a class
41  * of integration services, including the "VSS service", the specified protocol
42  * is a "request/response" protocol which means that there can only be single
43  * outstanding transaction from the host at any given point in time. We use
44  * this to simplify memory management in this driver - we cache and process
45  * only one message at a time.
46  *
47  * While the request/response protocol is guaranteed by the host, we further
48  * ensure this by serializing packet processing in this driver - we do not
49  * read additional packets from the VMBUs until the current packet is fully
50  * handled.
51  */
52 
53 static struct {
54 	int state;   /* hvutil_device_state */
55 	int recv_len; /* number of bytes received. */
56 	struct vmbus_channel *recv_channel; /* chn we got the request */
57 	u64 recv_req_id; /* request ID. */
58 	struct hv_vss_msg  *msg; /* current message */
59 } vss_transaction;
60 
61 
62 static void vss_respond_to_host(int error);
63 
64 /*
65  * This state maintains the version number registered by the daemon.
66  */
67 static int dm_reg_value;
68 
69 static const char vss_devname[] = "vmbus/hv_vss";
70 static __u8 *recv_buffer;
71 static struct hvutil_transport *hvt;
72 static struct completion release_event;
73 
74 static void vss_timeout_func(struct work_struct *dummy);
75 static void vss_handle_request(struct work_struct *dummy);
76 
77 static DECLARE_DELAYED_WORK(vss_timeout_work, vss_timeout_func);
78 static DECLARE_WORK(vss_handle_request_work, vss_handle_request);
79 
80 static void vss_poll_wrapper(void *channel)
81 {
82 	/* Transaction is finished, reset the state here to avoid races. */
83 	vss_transaction.state = HVUTIL_READY;
84 	hv_vss_onchannelcallback(channel);
85 }
86 
87 /*
88  * Callback when data is received from user mode.
89  */
90 
91 static void vss_timeout_func(struct work_struct *dummy)
92 {
93 	/*
94 	 * Timeout waiting for userspace component to reply happened.
95 	 */
96 	pr_warn("VSS: timeout waiting for daemon to reply\n");
97 	vss_respond_to_host(HV_E_FAIL);
98 
99 	hv_poll_channel(vss_transaction.recv_channel, vss_poll_wrapper);
100 }
101 
102 static void vss_register_done(void)
103 {
104 	hv_poll_channel(vss_transaction.recv_channel, vss_poll_wrapper);
105 	pr_debug("VSS: userspace daemon registered\n");
106 }
107 
108 static int vss_handle_handshake(struct hv_vss_msg *vss_msg)
109 {
110 	u32 our_ver = VSS_OP_REGISTER1;
111 
112 	switch (vss_msg->vss_hdr.operation) {
113 	case VSS_OP_REGISTER:
114 		/* Daemon doesn't expect us to reply */
115 		dm_reg_value = VSS_OP_REGISTER;
116 		break;
117 	case VSS_OP_REGISTER1:
118 		/* Daemon expects us to reply with our own version */
119 		if (hvutil_transport_send(hvt, &our_ver, sizeof(our_ver),
120 					  vss_register_done))
121 			return -EFAULT;
122 		dm_reg_value = VSS_OP_REGISTER1;
123 		break;
124 	default:
125 		return -EINVAL;
126 	}
127 	pr_info("VSS: userspace daemon ver. %d connected\n", dm_reg_value);
128 	return 0;
129 }
130 
131 static int vss_on_msg(void *msg, int len)
132 {
133 	struct hv_vss_msg *vss_msg = (struct hv_vss_msg *)msg;
134 
135 	if (len != sizeof(*vss_msg)) {
136 		pr_debug("VSS: Message size does not match length\n");
137 		return -EINVAL;
138 	}
139 
140 	if (vss_msg->vss_hdr.operation == VSS_OP_REGISTER ||
141 	    vss_msg->vss_hdr.operation == VSS_OP_REGISTER1) {
142 		/*
143 		 * Don't process registration messages if we're in the middle
144 		 * of a transaction processing.
145 		 */
146 		if (vss_transaction.state > HVUTIL_READY) {
147 			pr_debug("VSS: Got unexpected registration request\n");
148 			return -EINVAL;
149 		}
150 
151 		return vss_handle_handshake(vss_msg);
152 	} else if (vss_transaction.state == HVUTIL_USERSPACE_REQ) {
153 		vss_transaction.state = HVUTIL_USERSPACE_RECV;
154 
155 		if (vss_msg->vss_hdr.operation == VSS_OP_HOT_BACKUP)
156 			vss_transaction.msg->vss_cf.flags =
157 				VSS_HBU_NO_AUTO_RECOVERY;
158 
159 		if (cancel_delayed_work_sync(&vss_timeout_work)) {
160 			vss_respond_to_host(vss_msg->error);
161 			/* Transaction is finished, reset the state. */
162 			hv_poll_channel(vss_transaction.recv_channel,
163 					vss_poll_wrapper);
164 		}
165 	} else {
166 		/* This is a spurious call! */
167 		pr_debug("VSS: Transaction not active\n");
168 		return -EINVAL;
169 	}
170 	return 0;
171 }
172 
173 static void vss_send_op(void)
174 {
175 	int op = vss_transaction.msg->vss_hdr.operation;
176 	int rc;
177 	struct hv_vss_msg *vss_msg;
178 
179 	/* The transaction state is wrong. */
180 	if (vss_transaction.state != HVUTIL_HOSTMSG_RECEIVED) {
181 		pr_debug("VSS: Unexpected attempt to send to daemon\n");
182 		return;
183 	}
184 
185 	vss_msg = kzalloc(sizeof(*vss_msg), GFP_KERNEL);
186 	if (!vss_msg)
187 		return;
188 
189 	vss_msg->vss_hdr.operation = op;
190 
191 	vss_transaction.state = HVUTIL_USERSPACE_REQ;
192 
193 	schedule_delayed_work(&vss_timeout_work, op == VSS_OP_FREEZE ?
194 			VSS_FREEZE_TIMEOUT * HZ : HV_UTIL_TIMEOUT * HZ);
195 
196 	rc = hvutil_transport_send(hvt, vss_msg, sizeof(*vss_msg), NULL);
197 	if (rc) {
198 		pr_warn("VSS: failed to communicate to the daemon: %d\n", rc);
199 		if (cancel_delayed_work_sync(&vss_timeout_work)) {
200 			vss_respond_to_host(HV_E_FAIL);
201 			vss_transaction.state = HVUTIL_READY;
202 		}
203 	}
204 
205 	kfree(vss_msg);
206 
207 	return;
208 }
209 
210 static void vss_handle_request(struct work_struct *dummy)
211 {
212 	switch (vss_transaction.msg->vss_hdr.operation) {
213 	/*
214 	 * Initiate a "freeze/thaw" operation in the guest.
215 	 * We respond to the host once the operation is complete.
216 	 *
217 	 * We send the message to the user space daemon and the operation is
218 	 * performed in the daemon.
219 	 */
220 	case VSS_OP_THAW:
221 	case VSS_OP_FREEZE:
222 	case VSS_OP_HOT_BACKUP:
223 		if (vss_transaction.state < HVUTIL_READY) {
224 			/* Userspace is not registered yet */
225 			pr_debug("VSS: Not ready for request.\n");
226 			vss_respond_to_host(HV_E_FAIL);
227 			return;
228 		}
229 
230 		pr_debug("VSS: Received request for op code: %d\n",
231 			vss_transaction.msg->vss_hdr.operation);
232 		vss_transaction.state = HVUTIL_HOSTMSG_RECEIVED;
233 		vss_send_op();
234 		return;
235 	case VSS_OP_GET_DM_INFO:
236 		vss_transaction.msg->dm_info.flags = 0;
237 		break;
238 	default:
239 		break;
240 	}
241 
242 	vss_respond_to_host(0);
243 	hv_poll_channel(vss_transaction.recv_channel, vss_poll_wrapper);
244 }
245 
246 /*
247  * Send a response back to the host.
248  */
249 
250 static void
251 vss_respond_to_host(int error)
252 {
253 	struct icmsg_hdr *icmsghdrp;
254 	u32	buf_len;
255 	struct vmbus_channel *channel;
256 	u64	req_id;
257 
258 	/*
259 	 * Copy the global state for completing the transaction. Note that
260 	 * only one transaction can be active at a time.
261 	 */
262 
263 	buf_len = vss_transaction.recv_len;
264 	channel = vss_transaction.recv_channel;
265 	req_id = vss_transaction.recv_req_id;
266 
267 	icmsghdrp = (struct icmsg_hdr *)
268 			&recv_buffer[sizeof(struct vmbuspipe_hdr)];
269 
270 	if (channel->onchannel_callback == NULL)
271 		/*
272 		 * We have raced with util driver being unloaded;
273 		 * silently return.
274 		 */
275 		return;
276 
277 	icmsghdrp->status = error;
278 
279 	icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE;
280 
281 	vmbus_sendpacket(channel, recv_buffer, buf_len, req_id,
282 				VM_PKT_DATA_INBAND, 0);
283 
284 }
285 
286 /*
287  * This callback is invoked when we get a VSS message from the host.
288  * The host ensures that only one VSS transaction can be active at a time.
289  */
290 
291 void hv_vss_onchannelcallback(void *context)
292 {
293 	struct vmbus_channel *channel = context;
294 	u32 recvlen;
295 	u64 requestid;
296 	struct hv_vss_msg *vss_msg;
297 
298 
299 	struct icmsg_hdr *icmsghdrp;
300 	struct icmsg_negotiate *negop = NULL;
301 
302 	if (vss_transaction.state > HVUTIL_READY)
303 		return;
304 
305 	vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen,
306 			 &requestid);
307 
308 	if (recvlen > 0) {
309 		icmsghdrp = (struct icmsg_hdr *)&recv_buffer[
310 			sizeof(struct vmbuspipe_hdr)];
311 
312 		if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
313 			vmbus_prep_negotiate_resp(icmsghdrp, negop,
314 				 recv_buffer, UTIL_FW_VERSION,
315 				 VSS_VERSION);
316 		} else {
317 			vss_msg = (struct hv_vss_msg *)&recv_buffer[
318 				sizeof(struct vmbuspipe_hdr) +
319 				sizeof(struct icmsg_hdr)];
320 
321 			/*
322 			 * Stash away this global state for completing the
323 			 * transaction; note transactions are serialized.
324 			 */
325 
326 			vss_transaction.recv_len = recvlen;
327 			vss_transaction.recv_req_id = requestid;
328 			vss_transaction.msg = (struct hv_vss_msg *)vss_msg;
329 
330 			schedule_work(&vss_handle_request_work);
331 			return;
332 		}
333 
334 		icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
335 			| ICMSGHDRFLAG_RESPONSE;
336 
337 		vmbus_sendpacket(channel, recv_buffer,
338 				       recvlen, requestid,
339 				       VM_PKT_DATA_INBAND, 0);
340 	}
341 
342 }
343 
344 static void vss_on_reset(void)
345 {
346 	if (cancel_delayed_work_sync(&vss_timeout_work))
347 		vss_respond_to_host(HV_E_FAIL);
348 	vss_transaction.state = HVUTIL_DEVICE_INIT;
349 	complete(&release_event);
350 }
351 
352 int
353 hv_vss_init(struct hv_util_service *srv)
354 {
355 	init_completion(&release_event);
356 	if (vmbus_proto_version < VERSION_WIN8_1) {
357 		pr_warn("Integration service 'Backup (volume snapshot)'"
358 			" not supported on this host version.\n");
359 		return -ENOTSUPP;
360 	}
361 	recv_buffer = srv->recv_buffer;
362 	vss_transaction.recv_channel = srv->channel;
363 
364 	/*
365 	 * When this driver loads, the user level daemon that
366 	 * processes the host requests may not yet be running.
367 	 * Defer processing channel callbacks until the daemon
368 	 * has registered.
369 	 */
370 	vss_transaction.state = HVUTIL_DEVICE_INIT;
371 
372 	hvt = hvutil_transport_init(vss_devname, CN_VSS_IDX, CN_VSS_VAL,
373 				    vss_on_msg, vss_on_reset);
374 	if (!hvt) {
375 		pr_warn("VSS: Failed to initialize transport\n");
376 		return -EFAULT;
377 	}
378 
379 	return 0;
380 }
381 
382 void hv_vss_deinit(void)
383 {
384 	vss_transaction.state = HVUTIL_DEVICE_DYING;
385 	cancel_delayed_work_sync(&vss_timeout_work);
386 	cancel_work_sync(&vss_handle_request_work);
387 	hvutil_transport_destroy(hvt);
388 	wait_for_completion(&release_event);
389 }
390