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