1 /*-
2 * Copyright (c) 2018 VMware, Inc.
3 *
4 * SPDX-License-Identifier: (BSD-2-Clause OR GPL-2.0)
5 */
6
7 /* Defines the queue structure and helper functions to enqueue/dequeue items. */
8
9 #ifndef _VMCI_QUEUE_H_
10 #define _VMCI_QUEUE_H_
11
12 /*
13 * vmci_queue
14 *
15 * This data type contains the information about a queue.
16 *
17 * There are two queues (hence, queue pairs) per transaction model between a
18 * pair of end points, A & B. One queue is used by end point A to transmit
19 * commands and responses to B. The other queue is used by B to transmit
20 * commands and responses.
21 *
22 * vmci_queue_kernel_if is a per-OS defined queue structure. It contains
23 * either a direct pointer to the linear address of the buffer contents or a
24 * pointer to structures which help the OS locate those data pages.
25 * See vmci_kernel_if.c for its definition.
26 */
27
28 struct vmci_queue_kernel_if;
29
30 struct vmci_queue {
31 struct vmci_queue_header *q_header;
32 struct vmci_queue_header *saved_header;
33 struct vmci_queue_kernel_if *kernel_if;
34 };
35
36 #define BUF_TYPE int
37
38 /*
39 *------------------------------------------------------------------------------
40 *
41 * vmci_memcpy{to,from}_queue_func() prototypes. Functions of these types are
42 * passed around to enqueue and dequeue routines. Note that often the functions
43 * passed are simply wrappers around memcpy itself.
44 *
45 * Note: In order for the memcpy typedefs to be compatible with the VMKernel,
46 * there's an unused last parameter for the hosted side. In ESX, that parameter
47 * holds a buffer type.
48 *
49 *------------------------------------------------------------------------------
50 */
51 typedef int vmci_memcpy_to_queue_func(struct vmci_queue *queue,
52 uint64_t queue_offset, const void *src, size_t src_offset,
53 size_t size, BUF_TYPE buf_type, bool can_block);
54 typedef int vmci_memcpy_from_queue_func(void *dest, size_t dest_offset,
55 const struct vmci_queue *queue, uint64_t queue_offset, size_t size,
56 BUF_TYPE buf_type, bool can_block);
57
58 /*
59 *------------------------------------------------------------------------------
60 *
61 * vmci_memcpy{to,from}_queue_[v]_[local]() prototypes
62 *
63 * Note that these routines are NOT SAFE to call on a host end-point until the
64 * guest end of the queue pair has attached -AND- SetPageStore(). The VMX
65 * crosstalk device will issue the SetPageStore() on behalf of the guest when
66 * the guest creates a QueuePair or attaches to one created by the host. So, if
67 * the guest notifies the host that it's attached then the queue is safe to use.
68 * Also, if the host registers notification of the connection of the guest, then
69 * it will only receive that notification when the guest has issued the
70 * SetPageStore() call and not before (when the guest had attached).
71 *
72 *------------------------------------------------------------------------------
73 */
74
75 int vmci_memcpy_to_queue(struct vmci_queue *queue, uint64_t queue_offset,
76 const void *src, size_t src_offset, size_t size, BUF_TYPE buf_type,
77 bool can_block);
78 int vmci_memcpy_from_queue(void *dest, size_t dest_offset,
79 const struct vmci_queue *queue, uint64_t queue_offset, size_t size,
80 BUF_TYPE buf_type, bool can_block);
81 int vmci_memcpy_to_queue_local(struct vmci_queue *queue,
82 uint64_t queue_offset, const void *src, size_t src_offset,
83 size_t size, BUF_TYPE buf_type, bool can_block);
84 int vmci_memcpy_from_queue_local(void *dest, size_t dest_offset,
85 const struct vmci_queue *queue, uint64_t queue_offset, size_t size,
86 BUF_TYPE buf_type, bool can_block);
87
88 int vmci_memcpy_to_queue_v(struct vmci_queue *queue, uint64_t queue_offset,
89 const void *src, size_t src_offset, size_t size, BUF_TYPE buf_type,
90 bool can_block);
91 int vmci_memcpy_from_queue_v(void *dest, size_t dest_offset,
92 const struct vmci_queue *queue, uint64_t queue_offset, size_t size,
93 BUF_TYPE buf_type, bool can_block);
94
95 static inline int
vmci_memcpy_to_queue_v_local(struct vmci_queue * queue,uint64_t queue_offset,const void * src,size_t src_offset,size_t size,int buf_type,bool can_block)96 vmci_memcpy_to_queue_v_local(struct vmci_queue *queue, uint64_t queue_offset,
97 const void *src, size_t src_offset, size_t size, int buf_type,
98 bool can_block)
99 {
100
101 return (vmci_memcpy_to_queue_v(queue, queue_offset, src, src_offset,
102 size, buf_type, can_block));
103 }
104
105 static inline int
vmci_memcpy_from_queue_v_local(void * dest,size_t dest_offset,const struct vmci_queue * queue,uint64_t queue_offset,size_t size,int buf_type,bool can_block)106 vmci_memcpy_from_queue_v_local(void *dest, size_t dest_offset,
107 const struct vmci_queue *queue, uint64_t queue_offset, size_t size,
108 int buf_type, bool can_block)
109 {
110
111 return (vmci_memcpy_from_queue_v(dest, dest_offset, queue, queue_offset,
112 size, buf_type, can_block));
113 }
114
115 #endif /* !_VMCI_QUEUE_H_ */
116