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