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