1
2
3
4
5
6
7
8#ifndef _VMW_VMCI_DEF_H_
9#define _VMW_VMCI_DEF_H_
10
11#include <linux/atomic.h>
12#include <linux/bits.h>
13
14
15#define VMCI_STATUS_ADDR 0x00
16#define VMCI_CONTROL_ADDR 0x04
17#define VMCI_ICR_ADDR 0x08
18#define VMCI_IMR_ADDR 0x0c
19#define VMCI_DATA_OUT_ADDR 0x10
20#define VMCI_DATA_IN_ADDR 0x14
21#define VMCI_CAPS_ADDR 0x18
22#define VMCI_RESULT_LOW_ADDR 0x1c
23#define VMCI_RESULT_HIGH_ADDR 0x20
24
25
26#define VMCI_MAX_DEVICES 1
27
28
29#define VMCI_STATUS_INT_ON BIT(0)
30
31
32#define VMCI_CONTROL_RESET BIT(0)
33#define VMCI_CONTROL_INT_ENABLE BIT(1)
34#define VMCI_CONTROL_INT_DISABLE BIT(2)
35
36
37#define VMCI_CAPS_HYPERCALL BIT(0)
38#define VMCI_CAPS_GUESTCALL BIT(1)
39#define VMCI_CAPS_DATAGRAM BIT(2)
40#define VMCI_CAPS_NOTIFICATIONS BIT(3)
41#define VMCI_CAPS_PPN64 BIT(4)
42
43
44#define VMCI_ICR_DATAGRAM BIT(0)
45#define VMCI_ICR_NOTIFICATION BIT(1)
46
47
48#define VMCI_IMR_DATAGRAM BIT(0)
49#define VMCI_IMR_NOTIFICATION BIT(1)
50
51
52#define VMCI_MAX_INTRS 2
53
54
55
56
57
58enum {
59 VMCI_INTR_DATAGRAM = 0,
60 VMCI_INTR_NOTIFICATION = 1,
61};
62
63
64
65
66
67#define VMCI_MAX_GUEST_QP_MEMORY (128 * 1024 * 1024)
68
69
70
71
72
73
74#define VMCI_MAX_PINNED_QP_MEMORY (32 * 1024)
75
76
77
78
79
80
81
82
83
84
85enum {
86 VMCI_RESOURCES_QUERY = 0,
87 VMCI_GET_CONTEXT_ID = 1,
88 VMCI_SET_NOTIFY_BITMAP = 2,
89 VMCI_DOORBELL_LINK = 3,
90 VMCI_DOORBELL_UNLINK = 4,
91 VMCI_DOORBELL_NOTIFY = 5,
92
93
94
95
96 VMCI_DATAGRAM_REQUEST_MAP = 6,
97 VMCI_DATAGRAM_REMOVE_MAP = 7,
98 VMCI_EVENT_SUBSCRIBE = 8,
99 VMCI_EVENT_UNSUBSCRIBE = 9,
100 VMCI_QUEUEPAIR_ALLOC = 10,
101 VMCI_QUEUEPAIR_DETACH = 11,
102
103
104
105
106
107 VMCI_HGFS_TRANSPORT = 13,
108 VMCI_UNITY_PBRPC_REGISTER = 14,
109 VMCI_RPC_PRIVILEGED = 15,
110 VMCI_RPC_UNPRIVILEGED = 16,
111 VMCI_RESOURCE_MAX = 17,
112};
113
114
115
116
117
118
119
120
121
122struct vmci_handle {
123 u32 context;
124 u32 resource;
125};
126
127#define vmci_make_handle(_cid, _rid) \
128 (struct vmci_handle){ .context = _cid, .resource = _rid }
129
130static inline bool vmci_handle_is_equal(struct vmci_handle h1,
131 struct vmci_handle h2)
132{
133 return h1.context == h2.context && h1.resource == h2.resource;
134}
135
136#define VMCI_INVALID_ID ~0
137static const struct vmci_handle VMCI_INVALID_HANDLE = {
138 .context = VMCI_INVALID_ID,
139 .resource = VMCI_INVALID_ID
140};
141
142static inline bool vmci_handle_is_invalid(struct vmci_handle h)
143{
144 return vmci_handle_is_equal(h, VMCI_INVALID_HANDLE);
145}
146
147
148
149
150
151#define VMCI_ANON_SRC_CONTEXT_ID VMCI_INVALID_ID
152#define VMCI_ANON_SRC_RESOURCE_ID VMCI_INVALID_ID
153static const struct vmci_handle VMCI_ANON_SRC_HANDLE = {
154 .context = VMCI_ANON_SRC_CONTEXT_ID,
155 .resource = VMCI_ANON_SRC_RESOURCE_ID
156};
157
158
159#define VMCI_RESERVED_CID_LIMIT ((u32) 16)
160
161
162
163
164
165#define VMCI_HYPERVISOR_CONTEXT_ID 0
166
167
168
169
170
171#define VMCI_WELL_KNOWN_CONTEXT_ID 1
172
173
174
175
176#define VMCI_HOST_CONTEXT_ID 2
177
178#define VMCI_CONTEXT_IS_VM(_cid) (VMCI_INVALID_ID != (_cid) && \
179 (_cid) > VMCI_HOST_CONTEXT_ID)
180
181
182
183
184
185#define VMCI_CONTEXT_RESOURCE_ID 0
186
187
188
189
190enum {
191 VMCI_SUCCESS_QUEUEPAIR_ATTACH = 5,
192 VMCI_SUCCESS_QUEUEPAIR_CREATE = 4,
193 VMCI_SUCCESS_LAST_DETACH = 3,
194 VMCI_SUCCESS_ACCESS_GRANTED = 2,
195 VMCI_SUCCESS_ENTRY_DEAD = 1,
196 VMCI_SUCCESS = 0,
197 VMCI_ERROR_INVALID_RESOURCE = (-1),
198 VMCI_ERROR_INVALID_ARGS = (-2),
199 VMCI_ERROR_NO_MEM = (-3),
200 VMCI_ERROR_DATAGRAM_FAILED = (-4),
201 VMCI_ERROR_MORE_DATA = (-5),
202 VMCI_ERROR_NO_MORE_DATAGRAMS = (-6),
203 VMCI_ERROR_NO_ACCESS = (-7),
204 VMCI_ERROR_NO_HANDLE = (-8),
205 VMCI_ERROR_DUPLICATE_ENTRY = (-9),
206 VMCI_ERROR_DST_UNREACHABLE = (-10),
207 VMCI_ERROR_PAYLOAD_TOO_LARGE = (-11),
208 VMCI_ERROR_INVALID_PRIV = (-12),
209 VMCI_ERROR_GENERIC = (-13),
210 VMCI_ERROR_PAGE_ALREADY_SHARED = (-14),
211 VMCI_ERROR_CANNOT_SHARE_PAGE = (-15),
212 VMCI_ERROR_CANNOT_UNSHARE_PAGE = (-16),
213 VMCI_ERROR_NO_PROCESS = (-17),
214 VMCI_ERROR_NO_DATAGRAM = (-18),
215 VMCI_ERROR_NO_RESOURCES = (-19),
216 VMCI_ERROR_UNAVAILABLE = (-20),
217 VMCI_ERROR_NOT_FOUND = (-21),
218 VMCI_ERROR_ALREADY_EXISTS = (-22),
219 VMCI_ERROR_NOT_PAGE_ALIGNED = (-23),
220 VMCI_ERROR_INVALID_SIZE = (-24),
221 VMCI_ERROR_REGION_ALREADY_SHARED = (-25),
222 VMCI_ERROR_TIMEOUT = (-26),
223 VMCI_ERROR_DATAGRAM_INCOMPLETE = (-27),
224 VMCI_ERROR_INCORRECT_IRQL = (-28),
225 VMCI_ERROR_EVENT_UNKNOWN = (-29),
226 VMCI_ERROR_OBSOLETE = (-30),
227 VMCI_ERROR_QUEUEPAIR_MISMATCH = (-31),
228 VMCI_ERROR_QUEUEPAIR_NOTSET = (-32),
229 VMCI_ERROR_QUEUEPAIR_NOTOWNER = (-33),
230 VMCI_ERROR_QUEUEPAIR_NOTATTACHED = (-34),
231 VMCI_ERROR_QUEUEPAIR_NOSPACE = (-35),
232 VMCI_ERROR_QUEUEPAIR_NODATA = (-36),
233 VMCI_ERROR_BUSMEM_INVALIDATION = (-37),
234 VMCI_ERROR_MODULE_NOT_LOADED = (-38),
235 VMCI_ERROR_DEVICE_NOT_FOUND = (-39),
236 VMCI_ERROR_QUEUEPAIR_NOT_READY = (-40),
237 VMCI_ERROR_WOULD_BLOCK = (-41),
238
239
240 VMCI_ERROR_CLIENT_MIN = (-500),
241 VMCI_ERROR_CLIENT_MAX = (-550),
242
243
244 VMCI_SHAREDMEM_ERROR_BAD_CONTEXT = (-1000),
245};
246
247
248enum {
249
250 VMCI_EVENT_CTX_ID_UPDATE = 0,
251
252
253 VMCI_EVENT_CTX_REMOVED = 1,
254
255
256 VMCI_EVENT_QP_RESUMED = 2,
257
258
259 VMCI_EVENT_QP_PEER_ATTACH = 3,
260
261
262 VMCI_EVENT_QP_PEER_DETACH = 4,
263
264
265
266
267
268 VMCI_EVENT_MEM_ACCESS_ON = 5,
269
270
271
272
273
274 VMCI_EVENT_MEM_ACCESS_OFF = 6,
275 VMCI_EVENT_MAX = 7,
276};
277
278
279
280
281
282
283
284
285#define VMCI_EVENT_VALID_VMX(_event) ((_event) == VMCI_EVENT_MEM_ACCESS_ON || \
286 (_event) == VMCI_EVENT_MEM_ACCESS_OFF)
287
288#define VMCI_EVENT_VALID(_event) ((_event) < VMCI_EVENT_MAX && \
289 !VMCI_EVENT_VALID_VMX(_event))
290
291
292#define VMCI_EVENT_HANDLER 0
293
294
295
296
297
298
299enum {
300 VMCI_NO_PRIVILEGE_FLAGS = 0,
301 VMCI_PRIVILEGE_FLAG_RESTRICTED = 1,
302 VMCI_PRIVILEGE_FLAG_TRUSTED = 2,
303 VMCI_PRIVILEGE_ALL_FLAGS = (VMCI_PRIVILEGE_FLAG_RESTRICTED |
304 VMCI_PRIVILEGE_FLAG_TRUSTED),
305 VMCI_DEFAULT_PROC_PRIVILEGE_FLAGS = VMCI_NO_PRIVILEGE_FLAGS,
306 VMCI_LEAST_PRIVILEGE_FLAGS = VMCI_PRIVILEGE_FLAG_RESTRICTED,
307 VMCI_MAX_PRIVILEGE_FLAGS = VMCI_PRIVILEGE_FLAG_TRUSTED,
308};
309
310
311#define VMCI_RESERVED_RESOURCE_ID_MAX 1023
312
313
314
315
316
317
318
319
320
321
322#define VMCI_VERSION_SHIFT_WIDTH 16
323#define VMCI_MAKE_VERSION(_major, _minor) \
324 ((_major) << VMCI_VERSION_SHIFT_WIDTH | (u16) (_minor))
325
326#define VMCI_VERSION_MAJOR(v) ((u32) (v) >> VMCI_VERSION_SHIFT_WIDTH)
327#define VMCI_VERSION_MINOR(v) ((u16) (v))
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352#define VMCI_VERSION VMCI_VERSION_NOVMVM
353#define VMCI_VERSION_NOVMVM VMCI_MAKE_VERSION(11, 0)
354#define VMCI_VERSION_NOTIFY VMCI_MAKE_VERSION(10, 0)
355#define VMCI_VERSION_HOSTQP VMCI_MAKE_VERSION(9, 0)
356#define VMCI_VERSION_PREHOSTQP VMCI_MAKE_VERSION(8, 0)
357#define VMCI_VERSION_PREVERS2 VMCI_MAKE_VERSION(1, 0)
358
359#define VMCI_SOCKETS_MAKE_VERSION(_p) \
360 ((((_p)[0] & 0xFF) << 24) | (((_p)[1] & 0xFF) << 16) | ((_p)[2]))
361
362
363
364
365
366
367
368
369#define IOCTL_VMCI_VERSION _IO(7, 0x9f)
370#define IOCTL_VMCI_INIT_CONTEXT _IO(7, 0xa0)
371#define IOCTL_VMCI_QUEUEPAIR_SETVA _IO(7, 0xa4)
372#define IOCTL_VMCI_NOTIFY_RESOURCE _IO(7, 0xa5)
373#define IOCTL_VMCI_NOTIFICATIONS_RECEIVE _IO(7, 0xa6)
374#define IOCTL_VMCI_VERSION2 _IO(7, 0xa7)
375#define IOCTL_VMCI_QUEUEPAIR_ALLOC _IO(7, 0xa8)
376#define IOCTL_VMCI_QUEUEPAIR_SETPAGEFILE _IO(7, 0xa9)
377#define IOCTL_VMCI_QUEUEPAIR_DETACH _IO(7, 0xaa)
378#define IOCTL_VMCI_DATAGRAM_SEND _IO(7, 0xab)
379#define IOCTL_VMCI_DATAGRAM_RECEIVE _IO(7, 0xac)
380#define IOCTL_VMCI_CTX_ADD_NOTIFICATION _IO(7, 0xaf)
381#define IOCTL_VMCI_CTX_REMOVE_NOTIFICATION _IO(7, 0xb0)
382#define IOCTL_VMCI_CTX_GET_CPT_STATE _IO(7, 0xb1)
383#define IOCTL_VMCI_CTX_SET_CPT_STATE _IO(7, 0xb2)
384#define IOCTL_VMCI_GET_CONTEXT_ID _IO(7, 0xb3)
385#define IOCTL_VMCI_SOCKETS_VERSION _IO(7, 0xb4)
386#define IOCTL_VMCI_SOCKETS_GET_AF_VALUE _IO(7, 0xb8)
387#define IOCTL_VMCI_SOCKETS_GET_LOCAL_CID _IO(7, 0xb9)
388#define IOCTL_VMCI_SET_NOTIFY _IO(7, 0xcb)
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430struct vmci_queue_header {
431
432 struct vmci_handle handle;
433 atomic64_t producer_tail;
434 atomic64_t consumer_head;
435};
436
437
438
439
440
441
442
443
444
445
446
447struct vmci_datagram {
448 struct vmci_handle dst;
449 struct vmci_handle src;
450 u64 payload_size;
451};
452
453
454
455
456
457
458#define VMCI_FLAG_DG_NONE 0
459#define VMCI_FLAG_WELLKNOWN_DG_HND BIT(0)
460#define VMCI_FLAG_ANYCID_DG_HND BIT(1)
461#define VMCI_FLAG_DG_DELAYED_CB BIT(2)
462
463
464
465
466
467#define VMCI_MAX_DG_SIZE (17 * 4096)
468#define VMCI_MAX_DG_PAYLOAD_SIZE (VMCI_MAX_DG_SIZE - \
469 sizeof(struct vmci_datagram))
470#define VMCI_DG_PAYLOAD(_dg) (void *)((char *)(_dg) + \
471 sizeof(struct vmci_datagram))
472#define VMCI_DG_HEADERSIZE sizeof(struct vmci_datagram)
473#define VMCI_DG_SIZE(_dg) (VMCI_DG_HEADERSIZE + (size_t)(_dg)->payload_size)
474#define VMCI_DG_SIZE_ALIGNED(_dg) ((VMCI_DG_SIZE(_dg) + 7) & (~((size_t) 0x7)))
475#define VMCI_MAX_DATAGRAM_QUEUE_SIZE (VMCI_MAX_DG_SIZE * 2)
476
477struct vmci_event_payload_qp {
478 struct vmci_handle handle;
479 u32 peer_id;
480 u32 _pad;
481};
482
483
484enum {
485
486 VMCI_QPFLAG_ATTACH_ONLY = 1 << 0,
487
488
489 VMCI_QPFLAG_LOCAL = 1 << 1,
490
491
492 VMCI_QPFLAG_NONBLOCK = 1 << 2,
493
494
495 VMCI_QPFLAG_PINNED = 1 << 3,
496
497
498 VMCI_QP_ALL_FLAGS = (VMCI_QPFLAG_ATTACH_ONLY | VMCI_QPFLAG_LOCAL |
499 VMCI_QPFLAG_NONBLOCK | VMCI_QPFLAG_PINNED),
500
501
502 VMCI_QP_ASYMM = (VMCI_QPFLAG_NONBLOCK | VMCI_QPFLAG_PINNED),
503 VMCI_QP_ASYMM_PEER = (VMCI_QPFLAG_ATTACH_ONLY | VMCI_QP_ASYMM),
504};
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521#define VMCI_MAX_DATAGRAM_AND_EVENT_QUEUE_SIZE \
522 (VMCI_MAX_DATAGRAM_QUEUE_SIZE + \
523 1024 * (sizeof(struct vmci_datagram) + \
524 sizeof(struct vmci_event_data_max)))
525
526
527
528
529
530
531struct vmci_resource_query_hdr {
532 struct vmci_datagram hdr;
533 u32 num_resources;
534 u32 _padding;
535};
536
537
538
539
540
541struct vmci_resource_query_msg {
542 u32 num_resources;
543 u32 _padding;
544 u32 resources[1];
545};
546
547
548
549
550
551
552
553#define VMCI_RESOURCE_QUERY_MAX_NUM 31
554
555
556#define VMCI_RESOURCE_QUERY_MAX_SIZE \
557 (sizeof(struct vmci_resource_query_hdr) + \
558 sizeof(u32) * VMCI_RESOURCE_QUERY_MAX_NUM)
559
560
561
562
563
564struct vmci_notify_bm_set_msg {
565 struct vmci_datagram hdr;
566 union {
567 u32 bitmap_ppn32;
568 u64 bitmap_ppn64;
569 };
570};
571
572
573
574
575
576
577struct vmci_doorbell_link_msg {
578 struct vmci_datagram hdr;
579 struct vmci_handle handle;
580 u64 notify_idx;
581};
582
583
584
585
586
587
588struct vmci_doorbell_unlink_msg {
589 struct vmci_datagram hdr;
590 struct vmci_handle handle;
591};
592
593
594
595
596
597struct vmci_doorbell_notify_msg {
598 struct vmci_datagram hdr;
599 struct vmci_handle handle;
600};
601
602
603
604
605
606struct vmci_event_data {
607 u32 event;
608 u32 _pad;
609
610};
611
612
613
614
615
616
617struct vmci_event_payld_ctx {
618 u32 context_id;
619 u32 _pad;
620};
621
622struct vmci_event_payld_qp {
623 struct vmci_handle handle;
624 u32 peer_id;
625 u32 _pad;
626};
627
628
629
630
631
632
633
634struct vmci_event_data_max {
635 struct vmci_event_data event_data;
636 union {
637 struct vmci_event_payld_ctx context_payload;
638 struct vmci_event_payld_qp qp_payload;
639 } ev_data_payload;
640};
641
642
643
644
645
646
647struct vmci_event_msg {
648 struct vmci_datagram hdr;
649
650
651 struct vmci_event_data event_data;
652
653
654};
655
656
657struct vmci_event_ctx {
658 struct vmci_event_msg msg;
659 struct vmci_event_payld_ctx payload;
660};
661
662
663struct vmci_event_qp {
664 struct vmci_event_msg msg;
665 struct vmci_event_payld_qp payload;
666};
667
668
669
670
671
672struct vmci_qp_alloc_msg {
673 struct vmci_datagram hdr;
674 struct vmci_handle handle;
675 u32 peer;
676 u32 flags;
677 u64 produce_size;
678 u64 consume_size;
679 u64 num_ppns;
680
681
682};
683
684struct vmci_qp_detach_msg {
685 struct vmci_datagram hdr;
686 struct vmci_handle handle;
687};
688
689
690#define VMCI_FLAG_DELAYED_CB BIT(0)
691
692typedef void (*vmci_callback) (void *client_data);
693
694
695
696
697
698
699
700struct vmci_qp;
701
702
703typedef int (*vmci_datagram_recv_cb) (void *client_data,
704 struct vmci_datagram *msg);
705
706
707typedef void (*vmci_event_cb) (u32 sub_id, const struct vmci_event_data *ed,
708 void *client_data);
709
710
711
712
713
714static inline const void *
715vmci_event_data_const_payload(const struct vmci_event_data *ev_data)
716{
717 return (const char *)ev_data + sizeof(*ev_data);
718}
719
720static inline void *vmci_event_data_payload(struct vmci_event_data *ev_data)
721{
722 return (void *)vmci_event_data_const_payload(ev_data);
723}
724
725
726
727
728
729
730
731
732
733
734
735static inline u64 vmci_q_read_pointer(atomic64_t *var)
736{
737#if defined(CONFIG_X86_32)
738 return atomic_read((atomic_t *)var);
739#else
740 return atomic64_read(var);
741#endif
742}
743
744
745
746
747
748
749
750static inline void vmci_q_set_pointer(atomic64_t *var,
751 u64 new_val)
752{
753#if defined(CONFIG_X86_32)
754 return atomic_set((atomic_t *)var, (u32)new_val);
755#else
756 return atomic64_set(var, new_val);
757#endif
758}
759
760
761
762
763
764static inline void vmci_qp_add_pointer(atomic64_t *var,
765 size_t add,
766 u64 size)
767{
768 u64 new_val = vmci_q_read_pointer(var);
769
770 if (new_val >= size - add)
771 new_val -= size;
772
773 new_val += add;
774
775 vmci_q_set_pointer(var, new_val);
776}
777
778
779
780
781static inline u64
782vmci_q_header_producer_tail(const struct vmci_queue_header *q_header)
783{
784 struct vmci_queue_header *qh = (struct vmci_queue_header *)q_header;
785 return vmci_q_read_pointer(&qh->producer_tail);
786}
787
788
789
790
791static inline u64
792vmci_q_header_consumer_head(const struct vmci_queue_header *q_header)
793{
794 struct vmci_queue_header *qh = (struct vmci_queue_header *)q_header;
795 return vmci_q_read_pointer(&qh->consumer_head);
796}
797
798
799
800
801
802static inline void
803vmci_q_header_add_producer_tail(struct vmci_queue_header *q_header,
804 size_t add,
805 u64 queue_size)
806{
807 vmci_qp_add_pointer(&q_header->producer_tail, add, queue_size);
808}
809
810
811
812
813
814static inline void
815vmci_q_header_add_consumer_head(struct vmci_queue_header *q_header,
816 size_t add,
817 u64 queue_size)
818{
819 vmci_qp_add_pointer(&q_header->consumer_head, add, queue_size);
820}
821
822
823
824
825
826static inline void
827vmci_q_header_get_pointers(const struct vmci_queue_header *produce_q_header,
828 const struct vmci_queue_header *consume_q_header,
829 u64 *producer_tail,
830 u64 *consumer_head)
831{
832 if (producer_tail)
833 *producer_tail = vmci_q_header_producer_tail(produce_q_header);
834
835 if (consumer_head)
836 *consumer_head = vmci_q_header_consumer_head(consume_q_header);
837}
838
839static inline void vmci_q_header_init(struct vmci_queue_header *q_header,
840 const struct vmci_handle handle)
841{
842 q_header->handle = handle;
843 atomic64_set(&q_header->producer_tail, 0);
844 atomic64_set(&q_header->consumer_head, 0);
845}
846
847
848
849
850
851static s64
852vmci_q_header_free_space(const struct vmci_queue_header *produce_q_header,
853 const struct vmci_queue_header *consume_q_header,
854 const u64 produce_q_size)
855{
856 u64 tail;
857 u64 head;
858 u64 free_space;
859
860 tail = vmci_q_header_producer_tail(produce_q_header);
861 head = vmci_q_header_consumer_head(consume_q_header);
862
863 if (tail >= produce_q_size || head >= produce_q_size)
864 return VMCI_ERROR_INVALID_SIZE;
865
866
867
868
869
870
871 if (tail >= head)
872 free_space = produce_q_size - (tail - head) - 1;
873 else
874 free_space = head - tail - 1;
875
876 return free_space;
877}
878
879
880
881
882
883
884
885
886
887
888static inline s64
889vmci_q_header_buf_ready(const struct vmci_queue_header *consume_q_header,
890 const struct vmci_queue_header *produce_q_header,
891 const u64 consume_q_size)
892{
893 s64 free_space;
894
895 free_space = vmci_q_header_free_space(consume_q_header,
896 produce_q_header, consume_q_size);
897 if (free_space < VMCI_SUCCESS)
898 return free_space;
899
900 return consume_q_size - free_space - 1;
901}
902
903
904#endif
905