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