xref: /freebsd/sys/dev/vmware/vmci/vmci_queue.h (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
163a93856SMark Peek /*-
2*3eeb7511SMark Peek  * Copyright (c) 2018 VMware, Inc.
363a93856SMark Peek  *
48c302b2eSMark Peek  * SPDX-License-Identifier: (BSD-2-Clause OR GPL-2.0)
563a93856SMark Peek  */
663a93856SMark Peek 
763a93856SMark Peek /* Defines the queue structure and helper functions to enqueue/dequeue items. */
863a93856SMark Peek 
963a93856SMark Peek #ifndef _VMCI_QUEUE_H_
1063a93856SMark Peek #define _VMCI_QUEUE_H_
1163a93856SMark Peek 
1263a93856SMark Peek /*
1363a93856SMark Peek  * vmci_queue
1463a93856SMark Peek  *
1563a93856SMark Peek  * This data type contains the information about a queue.
1663a93856SMark Peek  *
1763a93856SMark Peek  * There are two queues (hence, queue pairs) per transaction model between a
1863a93856SMark Peek  * pair of end points, A & B. One queue is used by end point A to transmit
1963a93856SMark Peek  * commands and responses to B. The other queue is used by B to transmit
2063a93856SMark Peek  * commands and responses.
2163a93856SMark Peek  *
2263a93856SMark Peek  * vmci_queue_kernel_if is a per-OS defined queue structure. It contains
2363a93856SMark Peek  * either a direct pointer to the linear address of the buffer contents or a
2463a93856SMark Peek  * pointer to structures which help the OS locate those data pages.
2563a93856SMark Peek  * See vmci_kernel_if.c for its definition.
2663a93856SMark Peek  */
2763a93856SMark Peek 
2863a93856SMark Peek struct vmci_queue_kernel_if;
2963a93856SMark Peek 
3063a93856SMark Peek struct vmci_queue {
3163a93856SMark Peek 	struct vmci_queue_header	*q_header;
3263a93856SMark Peek 	struct vmci_queue_header	*saved_header;
3363a93856SMark Peek 	struct vmci_queue_kernel_if	*kernel_if;
3463a93856SMark Peek };
3563a93856SMark Peek 
3663a93856SMark Peek #define BUF_TYPE	int
3763a93856SMark Peek 
3863a93856SMark Peek /*
3963a93856SMark Peek  *------------------------------------------------------------------------------
4063a93856SMark Peek  *
4163a93856SMark Peek  * vmci_memcpy{to,from}_queue_func() prototypes. Functions of these types are
4263a93856SMark Peek  * passed around to enqueue and dequeue routines. Note that often the functions
4363a93856SMark Peek  * passed are simply wrappers around memcpy itself.
4463a93856SMark Peek  *
4563a93856SMark Peek  * Note: In order for the memcpy typedefs to be compatible with the VMKernel,
4663a93856SMark Peek  * there's an unused last parameter for the hosted side. In ESX, that parameter
4763a93856SMark Peek  * holds a buffer type.
4863a93856SMark Peek  *
4963a93856SMark Peek  *------------------------------------------------------------------------------
5063a93856SMark Peek  */
5163a93856SMark Peek typedef	int vmci_memcpy_to_queue_func(struct vmci_queue *queue,
5263a93856SMark Peek 	    uint64_t queue_offset, const void *src, size_t src_offset,
5363a93856SMark Peek 	    size_t size, BUF_TYPE buf_type, bool can_block);
5463a93856SMark Peek typedef	int vmci_memcpy_from_queue_func(void *dest, size_t dest_offset,
5563a93856SMark Peek 	    const struct vmci_queue *queue, uint64_t queue_offset, size_t size,
5663a93856SMark Peek 	    BUF_TYPE buf_type, bool can_block);
5763a93856SMark Peek 
5863a93856SMark Peek /*
5963a93856SMark Peek  *------------------------------------------------------------------------------
6063a93856SMark Peek  *
6163a93856SMark Peek  * vmci_memcpy{to,from}_queue_[v]_[local]() prototypes
6263a93856SMark Peek  *
6363a93856SMark Peek  * Note that these routines are NOT SAFE to call on a host end-point until the
6463a93856SMark Peek  * guest end of the queue pair has attached -AND- SetPageStore(). The VMX
6563a93856SMark Peek  * crosstalk device will issue the SetPageStore() on behalf of the guest when
6663a93856SMark Peek  * the guest creates a QueuePair or attaches to one created by the host. So, if
6763a93856SMark Peek  * the guest notifies the host that it's attached then the queue is safe to use.
6863a93856SMark Peek  * Also, if the host registers notification of the connection of the guest, then
6963a93856SMark Peek  * it will only receive that notification when the guest has issued the
7063a93856SMark Peek  * SetPageStore() call and not before (when the guest had attached).
7163a93856SMark Peek  *
7263a93856SMark Peek  *------------------------------------------------------------------------------
7363a93856SMark Peek  */
7463a93856SMark Peek 
7563a93856SMark Peek int	vmci_memcpy_to_queue(struct vmci_queue *queue, uint64_t queue_offset,
7663a93856SMark Peek 	    const void *src, size_t src_offset, size_t size, BUF_TYPE buf_type,
7763a93856SMark Peek 	    bool can_block);
7863a93856SMark Peek int	vmci_memcpy_from_queue(void *dest, size_t dest_offset,
7963a93856SMark Peek 	    const struct vmci_queue *queue, uint64_t queue_offset, size_t size,
8063a93856SMark Peek 	    BUF_TYPE buf_type, bool can_block);
8163a93856SMark Peek int	vmci_memcpy_to_queue_local(struct vmci_queue *queue,
8263a93856SMark Peek 	    uint64_t queue_offset, const void *src, size_t src_offset,
8363a93856SMark Peek 	    size_t size, BUF_TYPE buf_type, bool can_block);
8463a93856SMark Peek int	vmci_memcpy_from_queue_local(void *dest, size_t dest_offset,
8563a93856SMark Peek 	    const struct vmci_queue *queue, uint64_t queue_offset, size_t size,
8663a93856SMark Peek 	    BUF_TYPE buf_type, bool can_block);
8763a93856SMark Peek 
8863a93856SMark Peek int	vmci_memcpy_to_queue_v(struct vmci_queue *queue, uint64_t queue_offset,
8963a93856SMark Peek 	    const void *src, size_t src_offset, size_t size, BUF_TYPE buf_type,
9063a93856SMark Peek 	    bool can_block);
9163a93856SMark Peek int	vmci_memcpy_from_queue_v(void *dest, size_t dest_offset,
9263a93856SMark Peek 	    const struct vmci_queue *queue, uint64_t queue_offset, size_t size,
9363a93856SMark Peek 	    BUF_TYPE buf_type, bool can_block);
9463a93856SMark Peek 
9563a93856SMark Peek static inline int
vmci_memcpy_to_queue_v_local(struct vmci_queue * queue,uint64_t queue_offset,const void * src,size_t src_offset,size_t size,int buf_type,bool can_block)9663a93856SMark Peek vmci_memcpy_to_queue_v_local(struct vmci_queue *queue, uint64_t queue_offset,
9763a93856SMark Peek    const void *src, size_t src_offset, size_t size, int buf_type,
9863a93856SMark Peek    bool can_block)
9963a93856SMark Peek {
10063a93856SMark Peek 
10163a93856SMark Peek 	return (vmci_memcpy_to_queue_v(queue, queue_offset, src, src_offset,
10263a93856SMark Peek 	    size, buf_type, can_block));
10363a93856SMark Peek }
10463a93856SMark Peek 
10563a93856SMark Peek static inline int
vmci_memcpy_from_queue_v_local(void * dest,size_t dest_offset,const struct vmci_queue * queue,uint64_t queue_offset,size_t size,int buf_type,bool can_block)10663a93856SMark Peek vmci_memcpy_from_queue_v_local(void *dest, size_t dest_offset,
10763a93856SMark Peek     const struct vmci_queue *queue, uint64_t queue_offset, size_t size,
10863a93856SMark Peek     int buf_type, bool can_block)
10963a93856SMark Peek {
11063a93856SMark Peek 
11163a93856SMark Peek 	return (vmci_memcpy_from_queue_v(dest, dest_offset, queue, queue_offset,
11263a93856SMark Peek 	    size, buf_type, can_block));
11363a93856SMark Peek }
11463a93856SMark Peek 
11563a93856SMark Peek #endif /* !_VMCI_QUEUE_H_ */
116