xref: /freebsd/sys/dev/vmware/vmci/vmci_queue.h (revision 734e82fe33aa764367791a7d603b383996c6b40b)
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
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
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