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