diff options
author | George Zhang <georgezhang@vmware.com> | 2013-01-08 18:54:54 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-01-08 19:15:56 -0500 |
commit | 06164d2b72aa752ce4633184b3e0d97601017135 (patch) | |
tree | 51e2ec49ace40729b043978fae3a1e8a5a5411c2 /drivers/misc/vmw_vmci/vmci_queue_pair.h | |
parent | b484b26cc7be6ccf3676deb5e03aed2609ee9a40 (diff) |
VMCI: queue pairs implementation.
VMCI queue pairs allow for bi-directional ordered communication between host and guests.
Signed-off-by: George Zhang <georgezhang@vmware.com>
Acked-by: Andy king <acking@vmware.com>
Acked-by: Dmitry Torokhov <dtor@vmware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/vmw_vmci/vmci_queue_pair.h')
-rw-r--r-- | drivers/misc/vmw_vmci/vmci_queue_pair.h | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.h b/drivers/misc/vmw_vmci/vmci_queue_pair.h new file mode 100644 index 000000000000..8d8d6a1170c3 --- /dev/null +++ b/drivers/misc/vmw_vmci/vmci_queue_pair.h | |||
@@ -0,0 +1,191 @@ | |||
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 | #ifndef _VMCI_QUEUE_PAIR_H_ | ||
17 | #define _VMCI_QUEUE_PAIR_H_ | ||
18 | |||
19 | #include <linux/vmw_vmci_defs.h> | ||
20 | #include <linux/types.h> | ||
21 | |||
22 | #include "vmci_context.h" | ||
23 | |||
24 | /* Callback needed for correctly waiting on events. */ | ||
25 | typedef int (*vmci_event_release_cb) (void *client_data); | ||
26 | |||
27 | /* Guest device port I/O. */ | ||
28 | struct PPNSet { | ||
29 | u64 num_produce_pages; | ||
30 | u64 num_consume_pages; | ||
31 | u32 *produce_ppns; | ||
32 | u32 *consume_ppns; | ||
33 | bool initialized; | ||
34 | }; | ||
35 | |||
36 | /* VMCIqueue_pairAllocInfo */ | ||
37 | struct vmci_qp_alloc_info { | ||
38 | struct vmci_handle handle; | ||
39 | u32 peer; | ||
40 | u32 flags; | ||
41 | u64 produce_size; | ||
42 | u64 consume_size; | ||
43 | u64 ppn_va; /* Start VA of queue pair PPNs. */ | ||
44 | u64 num_ppns; | ||
45 | s32 result; | ||
46 | u32 version; | ||
47 | }; | ||
48 | |||
49 | /* VMCIqueue_pairSetVAInfo */ | ||
50 | struct vmci_qp_set_va_info { | ||
51 | struct vmci_handle handle; | ||
52 | u64 va; /* Start VA of queue pair PPNs. */ | ||
53 | u64 num_ppns; | ||
54 | u32 version; | ||
55 | s32 result; | ||
56 | }; | ||
57 | |||
58 | /* | ||
59 | * For backwards compatibility, here is a version of the | ||
60 | * VMCIqueue_pairPageFileInfo before host support end-points was added. | ||
61 | * Note that the current version of that structure requires VMX to | ||
62 | * pass down the VA of the mapped file. Before host support was added | ||
63 | * there was nothing of the sort. So, when the driver sees the ioctl | ||
64 | * with a parameter that is the sizeof | ||
65 | * VMCIqueue_pairPageFileInfo_NoHostQP then it can infer that the version | ||
66 | * of VMX running can't attach to host end points because it doesn't | ||
67 | * provide the VA of the mapped files. | ||
68 | * | ||
69 | * The Linux driver doesn't get an indication of the size of the | ||
70 | * structure passed down from user space. So, to fix a long standing | ||
71 | * but unfiled bug, the _pad field has been renamed to version. | ||
72 | * Existing versions of VMX always initialize the PageFileInfo | ||
73 | * structure so that _pad, er, version is set to 0. | ||
74 | * | ||
75 | * A version value of 1 indicates that the size of the structure has | ||
76 | * been increased to include two UVA's: produce_uva and consume_uva. | ||
77 | * These UVA's are of the mmap()'d queue contents backing files. | ||
78 | * | ||
79 | * In addition, if when VMX is sending down the | ||
80 | * VMCIqueue_pairPageFileInfo structure it gets an error then it will | ||
81 | * try again with the _NoHostQP version of the file to see if an older | ||
82 | * VMCI kernel module is running. | ||
83 | */ | ||
84 | |||
85 | /* VMCIqueue_pairPageFileInfo */ | ||
86 | struct vmci_qp_page_file_info { | ||
87 | struct vmci_handle handle; | ||
88 | u64 produce_page_file; /* User VA. */ | ||
89 | u64 consume_page_file; /* User VA. */ | ||
90 | u64 produce_page_file_size; /* Size of the file name array. */ | ||
91 | u64 consume_page_file_size; /* Size of the file name array. */ | ||
92 | s32 result; | ||
93 | u32 version; /* Was _pad. */ | ||
94 | u64 produce_va; /* User VA of the mapped file. */ | ||
95 | u64 consume_va; /* User VA of the mapped file. */ | ||
96 | }; | ||
97 | |||
98 | /* vmci queuepair detach info */ | ||
99 | struct vmci_qp_dtch_info { | ||
100 | struct vmci_handle handle; | ||
101 | s32 result; | ||
102 | u32 _pad; | ||
103 | }; | ||
104 | |||
105 | /* | ||
106 | * struct vmci_qp_page_store describes how the memory of a given queue pair | ||
107 | * is backed. When the queue pair is between the host and a guest, the | ||
108 | * page store consists of references to the guest pages. On vmkernel, | ||
109 | * this is a list of PPNs, and on hosted, it is a user VA where the | ||
110 | * queue pair is mapped into the VMX address space. | ||
111 | */ | ||
112 | struct vmci_qp_page_store { | ||
113 | /* Reference to pages backing the queue pair. */ | ||
114 | u64 pages; | ||
115 | /* Length of pageList/virtual addres range (in pages). */ | ||
116 | u32 len; | ||
117 | }; | ||
118 | |||
119 | /* | ||
120 | * This data type contains the information about a queue. | ||
121 | * There are two queues (hence, queue pairs) per transaction model between a | ||
122 | * pair of end points, A & B. One queue is used by end point A to transmit | ||
123 | * commands and responses to B. The other queue is used by B to transmit | ||
124 | * commands and responses. | ||
125 | * | ||
126 | * struct vmci_queue_kern_if is a per-OS defined Queue structure. It contains | ||
127 | * either a direct pointer to the linear address of the buffer contents or a | ||
128 | * pointer to structures which help the OS locate those data pages. See | ||
129 | * vmciKernelIf.c for each platform for its definition. | ||
130 | */ | ||
131 | struct vmci_queue { | ||
132 | struct vmci_queue_header *q_header; | ||
133 | struct vmci_queue_header *saved_header; | ||
134 | struct vmci_queue_kern_if *kernel_if; | ||
135 | }; | ||
136 | |||
137 | /* | ||
138 | * Utility function that checks whether the fields of the page | ||
139 | * store contain valid values. | ||
140 | * Result: | ||
141 | * true if the page store is wellformed. false otherwise. | ||
142 | */ | ||
143 | static inline bool | ||
144 | VMCI_QP_PAGESTORE_IS_WELLFORMED(struct vmci_qp_page_store *page_store) | ||
145 | { | ||
146 | return page_store->len >= 2; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * Helper function to check if the non-blocking flag | ||
151 | * is set for a given queue pair. | ||
152 | */ | ||
153 | static inline bool vmci_can_block(u32 flags) | ||
154 | { | ||
155 | return !(flags & VMCI_QPFLAG_NONBLOCK); | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * Helper function to check if the queue pair is pinned | ||
160 | * into memory. | ||
161 | */ | ||
162 | static inline bool vmci_qp_pinned(u32 flags) | ||
163 | { | ||
164 | return flags & VMCI_QPFLAG_PINNED; | ||
165 | } | ||
166 | |||
167 | void vmci_qp_broker_exit(void); | ||
168 | int vmci_qp_broker_alloc(struct vmci_handle handle, u32 peer, | ||
169 | u32 flags, u32 priv_flags, | ||
170 | u64 produce_size, u64 consume_size, | ||
171 | struct vmci_qp_page_store *page_store, | ||
172 | struct vmci_ctx *context); | ||
173 | int vmci_qp_broker_set_page_store(struct vmci_handle handle, | ||
174 | u64 produce_uva, u64 consume_uva, | ||
175 | struct vmci_ctx *context); | ||
176 | int vmci_qp_broker_detach(struct vmci_handle handle, struct vmci_ctx *context); | ||
177 | |||
178 | void vmci_qp_guest_endpoints_exit(void); | ||
179 | |||
180 | int vmci_qp_alloc(struct vmci_handle *handle, | ||
181 | struct vmci_queue **produce_q, u64 produce_size, | ||
182 | struct vmci_queue **consume_q, u64 consume_size, | ||
183 | u32 peer, u32 flags, u32 priv_flags, | ||
184 | bool guest_endpoint, vmci_event_release_cb wakeup_cb, | ||
185 | void *client_data); | ||
186 | int vmci_qp_broker_map(struct vmci_handle handle, | ||
187 | struct vmci_ctx *context, u64 guest_mem); | ||
188 | int vmci_qp_broker_unmap(struct vmci_handle handle, | ||
189 | struct vmci_ctx *context, u32 gid); | ||
190 | |||
191 | #endif /* _VMCI_QUEUE_PAIR_H_ */ | ||