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
30struct vmci_queue_kernel_if;
31
32struct 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 */
53typedef	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);
56typedef	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
77int	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);
80int	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);
83int	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);
86int	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
90int	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);
93int	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
97static inline int
98vmci_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
107static inline int
108vmci_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