1 /*
2  * VMware VMCI Driver
3  *
4  * Copyright (C) 2012 VMware, Inc. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation version 2 and no later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * for more details.
14  */
15 
16 #include <linux/vmw_vmci_defs.h>
17 #include <linux/vmw_vmci_api.h>
18 #include <linux/module.h>
19 #include <linux/sched.h>
20 #include <linux/slab.h>
21 #include <linux/bug.h>
22 
23 #include "vmci_datagram.h"
24 #include "vmci_resource.h"
25 #include "vmci_context.h"
26 #include "vmci_driver.h"
27 #include "vmci_event.h"
28 #include "vmci_route.h"
29 
30 /*
31  * struct datagram_entry describes the datagram entity. It is used for datagram
32  * entities created only on the host.
33  */
34 struct datagram_entry {
35 	struct vmci_resource resource;
36 	u32 flags;
37 	bool run_delayed;
38 	vmci_datagram_recv_cb recv_cb;
39 	void *client_data;
40 	u32 priv_flags;
41 };
42 
43 struct delayed_datagram_info {
44 	struct datagram_entry *entry;
45 	struct work_struct work;
46 	bool in_dg_host_queue;
47 	/* msg and msg_payload must be together. */
48 	struct vmci_datagram msg;
49 	u8 msg_payload[];
50 };
51 
52 /* Number of in-flight host->host datagrams */
53 static atomic_t delayed_dg_host_queue_size = ATOMIC_INIT(0);
54 
55 /*
56  * Create a datagram entry given a handle pointer.
57  */
dg_create_handle(u32 resource_id,u32 flags,u32 priv_flags,vmci_datagram_recv_cb recv_cb,void * client_data,struct vmci_handle * out_handle)58 static int dg_create_handle(u32 resource_id,
59 			    u32 flags,
60 			    u32 priv_flags,
61 			    vmci_datagram_recv_cb recv_cb,
62 			    void *client_data, struct vmci_handle *out_handle)
63 {
64 	int result;
65 	u32 context_id;
66 	struct vmci_handle handle;
67 	struct datagram_entry *entry;
68 
69 	if ((flags & VMCI_FLAG_WELLKNOWN_DG_HND) != 0)
70 		return VMCI_ERROR_INVALID_ARGS;
71 
72 	if ((flags & VMCI_FLAG_ANYCID_DG_HND) != 0) {
73 		context_id = VMCI_INVALID_ID;
74 	} else {
75 		context_id = vmci_get_context_id();
76 		if (context_id == VMCI_INVALID_ID)
77 			return VMCI_ERROR_NO_RESOURCES;
78 	}
79 
80 	handle = vmci_make_handle(context_id, resource_id);
81 
82 	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
83 	if (!entry) {
84 		pr_warn("Failed allocating memory for datagram entry\n");
85 		return VMCI_ERROR_NO_MEM;
86 	}
87 
88 	entry->run_delayed = (flags & VMCI_FLAG_DG_DELAYED_CB) ? true : false;
89 	entry->flags = flags;
90 	entry->recv_cb = recv_cb;
91 	entry->client_data = client_data;
92 	entry->priv_flags = priv_flags;
93 
94 	/* Make datagram resource live. */
95 	result = vmci_resource_add(&entry->resource,
96 				   VMCI_RESOURCE_TYPE_DATAGRAM,
97 				   handle);
98 	if (result != VMCI_SUCCESS) {
99 		pr_warn("Failed to add new resource (handle=0x%x:0x%x), error: %d\n",
100 			handle.context, handle.resource, result);
101 		kfree(entry);
102 		return result;
103 	}
104 
105 	*out_handle = vmci_resource_handle(&entry->resource);
106 	return VMCI_SUCCESS;
107 }
108 
109 /*
110  * Internal utility function with the same purpose as
111  * vmci_datagram_get_priv_flags that also takes a context_id.
112  */
vmci_datagram_get_priv_flags(u32 context_id,struct vmci_handle handle,u32 * priv_flags)113 static int vmci_datagram_get_priv_flags(u32 context_id,
114 					struct vmci_handle handle,
115 					u32 *priv_flags)
116 {
117 	if (context_id == VMCI_INVALID_ID)
118 		return VMCI_ERROR_INVALID_ARGS;
119 
120 	if (context_id == VMCI_HOST_CONTEXT_ID) {
121 		struct datagram_entry *src_entry;
122 		struct vmci_resource *resource;
123 
124 		resource = vmci_resource_by_handle(handle,
125 						   VMCI_RESOURCE_TYPE_DATAGRAM);
126 		if (!resource)
127 			return VMCI_ERROR_INVALID_ARGS;
128 
129 		src_entry = container_of(resource, struct datagram_entry,
130 					 resource);
131 		*priv_flags = src_entry->priv_flags;
132 		vmci_resource_put(resource);
133 	} else if (context_id == VMCI_HYPERVISOR_CONTEXT_ID)
134 		*priv_flags = VMCI_MAX_PRIVILEGE_FLAGS;
135 	else
136 		*priv_flags = vmci_context_get_priv_flags(context_id);
137 
138 	return VMCI_SUCCESS;
139 }
140 
141 /*
142  * Calls the specified callback in a delayed context.
143  */
dg_delayed_dispatch(struct work_struct * work)144 static void dg_delayed_dispatch(struct work_struct *work)
145 {
146 	struct delayed_datagram_info *dg_info =
147 			container_of(work, struct delayed_datagram_info, work);
148 
149 	dg_info->entry->recv_cb(dg_info->entry->client_data, &dg_info->msg);
150 
151 	vmci_resource_put(&dg_info->entry->resource);
152 
153 	if (dg_info->in_dg_host_queue)
154 		atomic_dec(&delayed_dg_host_queue_size);
155 
156 	kfree(dg_info);
157 }
158 
159 /*
160  * Dispatch datagram as a host, to the host, or other vm context. This
161  * function cannot dispatch to hypervisor context handlers. This should
162  * have been handled before we get here by vmci_datagram_dispatch.
163  * Returns number of bytes sent on success, error code otherwise.
164  */
dg_dispatch_as_host(u32 context_id,struct vmci_datagram * dg)165 static int dg_dispatch_as_host(u32 context_id, struct vmci_datagram *dg)
166 {
167 	int retval;
168 	size_t dg_size;
169 	u32 src_priv_flags;
170 
171 	dg_size = VMCI_DG_SIZE(dg);
172 
173 	/* Host cannot send to the hypervisor. */
174 	if (dg->dst.context == VMCI_HYPERVISOR_CONTEXT_ID)
175 		return VMCI_ERROR_DST_UNREACHABLE;
176 
177 	/* Check that source handle matches sending context. */
178 	if (dg->src.context != context_id) {
179 		pr_devel("Sender context (ID=0x%x) is not owner of src datagram entry (handle=0x%x:0x%x)\n",
180 			 context_id, dg->src.context, dg->src.resource);
181 		return VMCI_ERROR_NO_ACCESS;
182 	}
183 
184 	/* Get hold of privileges of sending endpoint. */
185 	retval = vmci_datagram_get_priv_flags(context_id, dg->src,
186 					      &src_priv_flags);
187 	if (retval != VMCI_SUCCESS) {
188 		pr_warn("Couldn't get privileges (handle=0x%x:0x%x)\n",
189 			dg->src.context, dg->src.resource);
190 		return retval;
191 	}
192 
193 	/* Determine if we should route to host or guest destination. */
194 	if (dg->dst.context == VMCI_HOST_CONTEXT_ID) {
195 		/* Route to host datagram entry. */
196 		struct datagram_entry *dst_entry;
197 		struct vmci_resource *resource;
198 
199 		if (dg->src.context == VMCI_HYPERVISOR_CONTEXT_ID &&
200 		    dg->dst.resource == VMCI_EVENT_HANDLER) {
201 			return vmci_event_dispatch(dg);
202 		}
203 
204 		resource = vmci_resource_by_handle(dg->dst,
205 						   VMCI_RESOURCE_TYPE_DATAGRAM);
206 		if (!resource) {
207 			pr_devel("Sending to invalid destination (handle=0x%x:0x%x)\n",
208 				 dg->dst.context, dg->dst.resource);
209 			return VMCI_ERROR_INVALID_RESOURCE;
210 		}
211 		dst_entry = container_of(resource, struct datagram_entry,
212 					 resource);
213 		if (vmci_deny_interaction(src_priv_flags,
214 					  dst_entry->priv_flags)) {
215 			vmci_resource_put(resource);
216 			return VMCI_ERROR_NO_ACCESS;
217 		}
218 
219 		/*
220 		 * If a VMCI datagram destined for the host is also sent by the
221 		 * host, we always run it delayed. This ensures that no locks
222 		 * are held when the datagram callback runs.
223 		 */
224 		if (dst_entry->run_delayed ||
225 		    dg->src.context == VMCI_HOST_CONTEXT_ID) {
226 			struct delayed_datagram_info *dg_info;
227 
228 			if (atomic_add_return(1, &delayed_dg_host_queue_size)
229 			    == VMCI_MAX_DELAYED_DG_HOST_QUEUE_SIZE) {
230 				atomic_dec(&delayed_dg_host_queue_size);
231 				vmci_resource_put(resource);
232 				return VMCI_ERROR_NO_MEM;
233 			}
234 
235 			dg_info = kmalloc(sizeof(*dg_info) +
236 				    (size_t) dg->payload_size, GFP_ATOMIC);
237 			if (!dg_info) {
238 				atomic_dec(&delayed_dg_host_queue_size);
239 				vmci_resource_put(resource);
240 				return VMCI_ERROR_NO_MEM;
241 			}
242 
243 			dg_info->in_dg_host_queue = true;
244 			dg_info->entry = dst_entry;
245 			memcpy(&dg_info->msg, dg, dg_size);
246 
247 			INIT_WORK(&dg_info->work, dg_delayed_dispatch);
248 			schedule_work(&dg_info->work);
249 			retval = VMCI_SUCCESS;
250 
251 		} else {
252 			retval = dst_entry->recv_cb(dst_entry->client_data, dg);
253 			vmci_resource_put(resource);
254 			if (retval < VMCI_SUCCESS)
255 				return retval;
256 		}
257 	} else {
258 		/* Route to destination VM context. */
259 		struct vmci_datagram *new_dg;
260 
261 		if (context_id != dg->dst.context) {
262 			if (vmci_deny_interaction(src_priv_flags,
263 						  vmci_context_get_priv_flags
264 						  (dg->dst.context))) {
265 				return VMCI_ERROR_NO_ACCESS;
266 			} else if (VMCI_CONTEXT_IS_VM(context_id)) {
267 				/*
268 				 * If the sending context is a VM, it
269 				 * cannot reach another VM.
270 				 */
271 
272 				pr_devel("Datagram communication between VMs not supported (src=0x%x, dst=0x%x)\n",
273 					 context_id, dg->dst.context);
274 				return VMCI_ERROR_DST_UNREACHABLE;
275 			}
276 		}
277 
278 		/* We make a copy to enqueue. */
279 		new_dg = kmemdup(dg, dg_size, GFP_KERNEL);
280 		if (new_dg == NULL)
281 			return VMCI_ERROR_NO_MEM;
282 
283 		retval = vmci_ctx_enqueue_datagram(dg->dst.context, new_dg);
284 		if (retval < VMCI_SUCCESS) {
285 			kfree(new_dg);
286 			return retval;
287 		}
288 	}
289 
290 	/*
291 	 * We currently truncate the size to signed 32 bits. This doesn't
292 	 * matter for this handler as it only support 4Kb messages.
293 	 */
294 	return (int)dg_size;
295 }
296 
297 /*
298  * Dispatch datagram as a guest, down through the VMX and potentially to
299  * the host.
300  * Returns number of bytes sent on success, error code otherwise.
301  */
dg_dispatch_as_guest(struct vmci_datagram * dg)302 static int dg_dispatch_as_guest(struct vmci_datagram *dg)
303 {
304 	int retval;
305 	struct vmci_resource *resource;
306 
307 	resource = vmci_resource_by_handle(dg->src,
308 					   VMCI_RESOURCE_TYPE_DATAGRAM);
309 	if (!resource)
310 		return VMCI_ERROR_NO_HANDLE;
311 
312 	retval = vmci_send_datagram(dg);
313 	vmci_resource_put(resource);
314 	return retval;
315 }
316 
317 /*
318  * Dispatch datagram.  This will determine the routing for the datagram
319  * and dispatch it accordingly.
320  * Returns number of bytes sent on success, error code otherwise.
321  */
vmci_datagram_dispatch(u32 context_id,struct vmci_datagram * dg,bool from_guest)322 int vmci_datagram_dispatch(u32 context_id,
323 			   struct vmci_datagram *dg, bool from_guest)
324 {
325 	int retval;
326 	enum vmci_route route;
327 
328 	BUILD_BUG_ON(sizeof(struct vmci_datagram) != 24);
329 
330 	if (dg->payload_size > VMCI_MAX_DG_SIZE ||
331 	    VMCI_DG_SIZE(dg) > VMCI_MAX_DG_SIZE) {
332 		pr_devel("Payload (size=%llu bytes) too big to send\n",
333 			 (unsigned long long)dg->payload_size);
334 		return VMCI_ERROR_INVALID_ARGS;
335 	}
336 
337 	retval = vmci_route(&dg->src, &dg->dst, from_guest, &route);
338 	if (retval < VMCI_SUCCESS) {
339 		pr_devel("Failed to route datagram (src=0x%x, dst=0x%x, err=%d)\n",
340 			 dg->src.context, dg->dst.context, retval);
341 		return retval;
342 	}
343 
344 	if (VMCI_ROUTE_AS_HOST == route) {
345 		if (VMCI_INVALID_ID == context_id)
346 			context_id = VMCI_HOST_CONTEXT_ID;
347 		return dg_dispatch_as_host(context_id, dg);
348 	}
349 
350 	if (VMCI_ROUTE_AS_GUEST == route)
351 		return dg_dispatch_as_guest(dg);
352 
353 	pr_warn("Unknown route (%d) for datagram\n", route);
354 	return VMCI_ERROR_DST_UNREACHABLE;
355 }
356 
357 /*
358  * Invoke the handler for the given datagram.  This is intended to be
359  * called only when acting as a guest and receiving a datagram from the
360  * virtual device.
361  */
vmci_datagram_invoke_guest_handler(struct vmci_datagram * dg)362 int vmci_datagram_invoke_guest_handler(struct vmci_datagram *dg)
363 {
364 	struct vmci_resource *resource;
365 	struct datagram_entry *dst_entry;
366 
367 	resource = vmci_resource_by_handle(dg->dst,
368 					   VMCI_RESOURCE_TYPE_DATAGRAM);
369 	if (!resource) {
370 		pr_devel("destination (handle=0x%x:0x%x) doesn't exist\n",
371 			 dg->dst.context, dg->dst.resource);
372 		return VMCI_ERROR_NO_HANDLE;
373 	}
374 
375 	dst_entry = container_of(resource, struct datagram_entry, resource);
376 	if (dst_entry->run_delayed) {
377 		struct delayed_datagram_info *dg_info;
378 
379 		dg_info = kmalloc(sizeof(*dg_info) + (size_t)dg->payload_size,
380 				  GFP_ATOMIC);
381 		if (!dg_info) {
382 			vmci_resource_put(resource);
383 			return VMCI_ERROR_NO_MEM;
384 		}
385 
386 		dg_info->in_dg_host_queue = false;
387 		dg_info->entry = dst_entry;
388 		memcpy(&dg_info->msg, dg, VMCI_DG_SIZE(dg));
389 
390 		INIT_WORK(&dg_info->work, dg_delayed_dispatch);
391 		schedule_work(&dg_info->work);
392 	} else {
393 		dst_entry->recv_cb(dst_entry->client_data, dg);
394 		vmci_resource_put(resource);
395 	}
396 
397 	return VMCI_SUCCESS;
398 }
399 
400 /*
401  * vmci_datagram_create_handle_priv() - Create host context datagram endpoint
402  * @resource_id:        The resource ID.
403  * @flags:      Datagram Flags.
404  * @priv_flags: Privilege Flags.
405  * @recv_cb:    Callback when receiving datagrams.
406  * @client_data:        Pointer for a datagram_entry struct
407  * @out_handle: vmci_handle that is populated as a result of this function.
408  *
409  * Creates a host context datagram endpoint and returns a handle to it.
410  */
vmci_datagram_create_handle_priv(u32 resource_id,u32 flags,u32 priv_flags,vmci_datagram_recv_cb recv_cb,void * client_data,struct vmci_handle * out_handle)411 int vmci_datagram_create_handle_priv(u32 resource_id,
412 				     u32 flags,
413 				     u32 priv_flags,
414 				     vmci_datagram_recv_cb recv_cb,
415 				     void *client_data,
416 				     struct vmci_handle *out_handle)
417 {
418 	if (out_handle == NULL)
419 		return VMCI_ERROR_INVALID_ARGS;
420 
421 	if (recv_cb == NULL) {
422 		pr_devel("Client callback needed when creating datagram\n");
423 		return VMCI_ERROR_INVALID_ARGS;
424 	}
425 
426 	if (priv_flags & ~VMCI_PRIVILEGE_ALL_FLAGS)
427 		return VMCI_ERROR_INVALID_ARGS;
428 
429 	return dg_create_handle(resource_id, flags, priv_flags, recv_cb,
430 				client_data, out_handle);
431 }
432 EXPORT_SYMBOL_GPL(vmci_datagram_create_handle_priv);
433 
434 /*
435  * vmci_datagram_create_handle() - Create host context datagram endpoint
436  * @resource_id:        Resource ID.
437  * @flags:      Datagram Flags.
438  * @recv_cb:    Callback when receiving datagrams.
439  * @client_ata: Pointer for a datagram_entry struct
440  * @out_handle: vmci_handle that is populated as a result of this function.
441  *
442  * Creates a host context datagram endpoint and returns a handle to
443  * it.  Same as vmci_datagram_create_handle_priv without the priviledge
444  * flags argument.
445  */
vmci_datagram_create_handle(u32 resource_id,u32 flags,vmci_datagram_recv_cb recv_cb,void * client_data,struct vmci_handle * out_handle)446 int vmci_datagram_create_handle(u32 resource_id,
447 				u32 flags,
448 				vmci_datagram_recv_cb recv_cb,
449 				void *client_data,
450 				struct vmci_handle *out_handle)
451 {
452 	return vmci_datagram_create_handle_priv(
453 		resource_id, flags,
454 		VMCI_DEFAULT_PROC_PRIVILEGE_FLAGS,
455 		recv_cb, client_data,
456 		out_handle);
457 }
458 EXPORT_SYMBOL_GPL(vmci_datagram_create_handle);
459 
460 /*
461  * vmci_datagram_destroy_handle() - Destroys datagram handle
462  * @handle:     vmci_handle to be destroyed and reaped.
463  *
464  * Use this function to destroy any datagram handles created by
465  * vmci_datagram_create_handle{,Priv} functions.
466  */
vmci_datagram_destroy_handle(struct vmci_handle handle)467 int vmci_datagram_destroy_handle(struct vmci_handle handle)
468 {
469 	struct datagram_entry *entry;
470 	struct vmci_resource *resource;
471 
472 	resource = vmci_resource_by_handle(handle, VMCI_RESOURCE_TYPE_DATAGRAM);
473 	if (!resource) {
474 		pr_devel("Failed to destroy datagram (handle=0x%x:0x%x)\n",
475 			 handle.context, handle.resource);
476 		return VMCI_ERROR_NOT_FOUND;
477 	}
478 
479 	entry = container_of(resource, struct datagram_entry, resource);
480 
481 	vmci_resource_put(&entry->resource);
482 	vmci_resource_remove(&entry->resource);
483 	kfree(entry);
484 
485 	return VMCI_SUCCESS;
486 }
487 EXPORT_SYMBOL_GPL(vmci_datagram_destroy_handle);
488 
489 /*
490  * vmci_datagram_send() - Send a datagram
491  * @msg:        The datagram to send.
492  *
493  * Sends the provided datagram on its merry way.
494  */
vmci_datagram_send(struct vmci_datagram * msg)495 int vmci_datagram_send(struct vmci_datagram *msg)
496 {
497 	if (msg == NULL)
498 		return VMCI_ERROR_INVALID_ARGS;
499 
500 	return vmci_datagram_dispatch(VMCI_INVALID_ID, msg, false);
501 }
502 EXPORT_SYMBOL_GPL(vmci_datagram_send);
503