106164d2b72aa752ce4633184b3e0d97601017135George Zhang/*
206164d2b72aa752ce4633184b3e0d97601017135George Zhang * VMware VMCI Driver
306164d2b72aa752ce4633184b3e0d97601017135George Zhang *
406164d2b72aa752ce4633184b3e0d97601017135George Zhang * Copyright (C) 2012 VMware, Inc. All rights reserved.
506164d2b72aa752ce4633184b3e0d97601017135George Zhang *
606164d2b72aa752ce4633184b3e0d97601017135George Zhang * This program is free software; you can redistribute it and/or modify it
706164d2b72aa752ce4633184b3e0d97601017135George Zhang * under the terms of the GNU General Public License as published by the
806164d2b72aa752ce4633184b3e0d97601017135George Zhang * Free Software Foundation version 2 and no later version.
906164d2b72aa752ce4633184b3e0d97601017135George Zhang *
1006164d2b72aa752ce4633184b3e0d97601017135George Zhang * This program is distributed in the hope that it will be useful, but
1106164d2b72aa752ce4633184b3e0d97601017135George Zhang * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1206164d2b72aa752ce4633184b3e0d97601017135George Zhang * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1306164d2b72aa752ce4633184b3e0d97601017135George Zhang * for more details.
1406164d2b72aa752ce4633184b3e0d97601017135George Zhang */
1506164d2b72aa752ce4633184b3e0d97601017135George Zhang
1606164d2b72aa752ce4633184b3e0d97601017135George Zhang#ifndef _VMCI_QUEUE_PAIR_H_
1706164d2b72aa752ce4633184b3e0d97601017135George Zhang#define _VMCI_QUEUE_PAIR_H_
1806164d2b72aa752ce4633184b3e0d97601017135George Zhang
1906164d2b72aa752ce4633184b3e0d97601017135George Zhang#include <linux/vmw_vmci_defs.h>
2006164d2b72aa752ce4633184b3e0d97601017135George Zhang#include <linux/types.h>
2106164d2b72aa752ce4633184b3e0d97601017135George Zhang
2206164d2b72aa752ce4633184b3e0d97601017135George Zhang#include "vmci_context.h"
2306164d2b72aa752ce4633184b3e0d97601017135George Zhang
2406164d2b72aa752ce4633184b3e0d97601017135George Zhang/* Callback needed for correctly waiting on events. */
2506164d2b72aa752ce4633184b3e0d97601017135George Zhangtypedef int (*vmci_event_release_cb) (void *client_data);
2606164d2b72aa752ce4633184b3e0d97601017135George Zhang
2706164d2b72aa752ce4633184b3e0d97601017135George Zhang/* Guest device port I/O. */
28e6389a13e42d5388ec044ce8da1b3bcfa39598efDmitry Torokhovstruct ppn_set {
2906164d2b72aa752ce4633184b3e0d97601017135George Zhang	u64 num_produce_pages;
3006164d2b72aa752ce4633184b3e0d97601017135George Zhang	u64 num_consume_pages;
3106164d2b72aa752ce4633184b3e0d97601017135George Zhang	u32 *produce_ppns;
3206164d2b72aa752ce4633184b3e0d97601017135George Zhang	u32 *consume_ppns;
3306164d2b72aa752ce4633184b3e0d97601017135George Zhang	bool initialized;
3406164d2b72aa752ce4633184b3e0d97601017135George Zhang};
3506164d2b72aa752ce4633184b3e0d97601017135George Zhang
3606164d2b72aa752ce4633184b3e0d97601017135George Zhang/* VMCIqueue_pairAllocInfo */
3706164d2b72aa752ce4633184b3e0d97601017135George Zhangstruct vmci_qp_alloc_info {
3806164d2b72aa752ce4633184b3e0d97601017135George Zhang	struct vmci_handle handle;
3906164d2b72aa752ce4633184b3e0d97601017135George Zhang	u32 peer;
4006164d2b72aa752ce4633184b3e0d97601017135George Zhang	u32 flags;
4106164d2b72aa752ce4633184b3e0d97601017135George Zhang	u64 produce_size;
4206164d2b72aa752ce4633184b3e0d97601017135George Zhang	u64 consume_size;
4306164d2b72aa752ce4633184b3e0d97601017135George Zhang	u64 ppn_va;	/* Start VA of queue pair PPNs. */
4406164d2b72aa752ce4633184b3e0d97601017135George Zhang	u64 num_ppns;
4506164d2b72aa752ce4633184b3e0d97601017135George Zhang	s32 result;
4606164d2b72aa752ce4633184b3e0d97601017135George Zhang	u32 version;
4706164d2b72aa752ce4633184b3e0d97601017135George Zhang};
4806164d2b72aa752ce4633184b3e0d97601017135George Zhang
4906164d2b72aa752ce4633184b3e0d97601017135George Zhang/* VMCIqueue_pairSetVAInfo */
5006164d2b72aa752ce4633184b3e0d97601017135George Zhangstruct vmci_qp_set_va_info {
5106164d2b72aa752ce4633184b3e0d97601017135George Zhang	struct vmci_handle handle;
5206164d2b72aa752ce4633184b3e0d97601017135George Zhang	u64 va;		/* Start VA of queue pair PPNs. */
5306164d2b72aa752ce4633184b3e0d97601017135George Zhang	u64 num_ppns;
5406164d2b72aa752ce4633184b3e0d97601017135George Zhang	u32 version;
5506164d2b72aa752ce4633184b3e0d97601017135George Zhang	s32 result;
5606164d2b72aa752ce4633184b3e0d97601017135George Zhang};
5706164d2b72aa752ce4633184b3e0d97601017135George Zhang
5806164d2b72aa752ce4633184b3e0d97601017135George Zhang/*
5906164d2b72aa752ce4633184b3e0d97601017135George Zhang * For backwards compatibility, here is a version of the
6006164d2b72aa752ce4633184b3e0d97601017135George Zhang * VMCIqueue_pairPageFileInfo before host support end-points was added.
6106164d2b72aa752ce4633184b3e0d97601017135George Zhang * Note that the current version of that structure requires VMX to
6206164d2b72aa752ce4633184b3e0d97601017135George Zhang * pass down the VA of the mapped file.  Before host support was added
6306164d2b72aa752ce4633184b3e0d97601017135George Zhang * there was nothing of the sort.  So, when the driver sees the ioctl
6406164d2b72aa752ce4633184b3e0d97601017135George Zhang * with a parameter that is the sizeof
6506164d2b72aa752ce4633184b3e0d97601017135George Zhang * VMCIqueue_pairPageFileInfo_NoHostQP then it can infer that the version
6606164d2b72aa752ce4633184b3e0d97601017135George Zhang * of VMX running can't attach to host end points because it doesn't
6706164d2b72aa752ce4633184b3e0d97601017135George Zhang * provide the VA of the mapped files.
6806164d2b72aa752ce4633184b3e0d97601017135George Zhang *
6906164d2b72aa752ce4633184b3e0d97601017135George Zhang * The Linux driver doesn't get an indication of the size of the
7006164d2b72aa752ce4633184b3e0d97601017135George Zhang * structure passed down from user space.  So, to fix a long standing
7106164d2b72aa752ce4633184b3e0d97601017135George Zhang * but unfiled bug, the _pad field has been renamed to version.
7206164d2b72aa752ce4633184b3e0d97601017135George Zhang * Existing versions of VMX always initialize the PageFileInfo
7306164d2b72aa752ce4633184b3e0d97601017135George Zhang * structure so that _pad, er, version is set to 0.
7406164d2b72aa752ce4633184b3e0d97601017135George Zhang *
7506164d2b72aa752ce4633184b3e0d97601017135George Zhang * A version value of 1 indicates that the size of the structure has
7606164d2b72aa752ce4633184b3e0d97601017135George Zhang * been increased to include two UVA's: produce_uva and consume_uva.
7706164d2b72aa752ce4633184b3e0d97601017135George Zhang * These UVA's are of the mmap()'d queue contents backing files.
7806164d2b72aa752ce4633184b3e0d97601017135George Zhang *
7906164d2b72aa752ce4633184b3e0d97601017135George Zhang * In addition, if when VMX is sending down the
8006164d2b72aa752ce4633184b3e0d97601017135George Zhang * VMCIqueue_pairPageFileInfo structure it gets an error then it will
8106164d2b72aa752ce4633184b3e0d97601017135George Zhang * try again with the _NoHostQP version of the file to see if an older
8206164d2b72aa752ce4633184b3e0d97601017135George Zhang * VMCI kernel module is running.
8306164d2b72aa752ce4633184b3e0d97601017135George Zhang */
8406164d2b72aa752ce4633184b3e0d97601017135George Zhang
8506164d2b72aa752ce4633184b3e0d97601017135George Zhang/* VMCIqueue_pairPageFileInfo */
8606164d2b72aa752ce4633184b3e0d97601017135George Zhangstruct vmci_qp_page_file_info {
8706164d2b72aa752ce4633184b3e0d97601017135George Zhang	struct vmci_handle handle;
8806164d2b72aa752ce4633184b3e0d97601017135George Zhang	u64 produce_page_file;	  /* User VA. */
8906164d2b72aa752ce4633184b3e0d97601017135George Zhang	u64 consume_page_file;	  /* User VA. */
9006164d2b72aa752ce4633184b3e0d97601017135George Zhang	u64 produce_page_file_size;  /* Size of the file name array. */
9106164d2b72aa752ce4633184b3e0d97601017135George Zhang	u64 consume_page_file_size;  /* Size of the file name array. */
9206164d2b72aa752ce4633184b3e0d97601017135George Zhang	s32 result;
9306164d2b72aa752ce4633184b3e0d97601017135George Zhang	u32 version;	/* Was _pad. */
9406164d2b72aa752ce4633184b3e0d97601017135George Zhang	u64 produce_va;	/* User VA of the mapped file. */
9506164d2b72aa752ce4633184b3e0d97601017135George Zhang	u64 consume_va;	/* User VA of the mapped file. */
9606164d2b72aa752ce4633184b3e0d97601017135George Zhang};
9706164d2b72aa752ce4633184b3e0d97601017135George Zhang
9806164d2b72aa752ce4633184b3e0d97601017135George Zhang/* vmci queuepair detach info */
9906164d2b72aa752ce4633184b3e0d97601017135George Zhangstruct vmci_qp_dtch_info {
10006164d2b72aa752ce4633184b3e0d97601017135George Zhang	struct vmci_handle handle;
10106164d2b72aa752ce4633184b3e0d97601017135George Zhang	s32 result;
10206164d2b72aa752ce4633184b3e0d97601017135George Zhang	u32 _pad;
10306164d2b72aa752ce4633184b3e0d97601017135George Zhang};
10406164d2b72aa752ce4633184b3e0d97601017135George Zhang
10506164d2b72aa752ce4633184b3e0d97601017135George Zhang/*
10606164d2b72aa752ce4633184b3e0d97601017135George Zhang * struct vmci_qp_page_store describes how the memory of a given queue pair
10706164d2b72aa752ce4633184b3e0d97601017135George Zhang * is backed. When the queue pair is between the host and a guest, the
10806164d2b72aa752ce4633184b3e0d97601017135George Zhang * page store consists of references to the guest pages. On vmkernel,
10906164d2b72aa752ce4633184b3e0d97601017135George Zhang * this is a list of PPNs, and on hosted, it is a user VA where the
11006164d2b72aa752ce4633184b3e0d97601017135George Zhang * queue pair is mapped into the VMX address space.
11106164d2b72aa752ce4633184b3e0d97601017135George Zhang */
11206164d2b72aa752ce4633184b3e0d97601017135George Zhangstruct vmci_qp_page_store {
11306164d2b72aa752ce4633184b3e0d97601017135George Zhang	/* Reference to pages backing the queue pair. */
11406164d2b72aa752ce4633184b3e0d97601017135George Zhang	u64 pages;
11506164d2b72aa752ce4633184b3e0d97601017135George Zhang	/* Length of pageList/virtual addres range (in pages). */
11606164d2b72aa752ce4633184b3e0d97601017135George Zhang	u32 len;
11706164d2b72aa752ce4633184b3e0d97601017135George Zhang};
11806164d2b72aa752ce4633184b3e0d97601017135George Zhang
11906164d2b72aa752ce4633184b3e0d97601017135George Zhang/*
12006164d2b72aa752ce4633184b3e0d97601017135George Zhang * This data type contains the information about a queue.
12106164d2b72aa752ce4633184b3e0d97601017135George Zhang * There are two queues (hence, queue pairs) per transaction model between a
12206164d2b72aa752ce4633184b3e0d97601017135George Zhang * pair of end points, A & B.  One queue is used by end point A to transmit
12306164d2b72aa752ce4633184b3e0d97601017135George Zhang * commands and responses to B.  The other queue is used by B to transmit
12406164d2b72aa752ce4633184b3e0d97601017135George Zhang * commands and responses.
12506164d2b72aa752ce4633184b3e0d97601017135George Zhang *
12606164d2b72aa752ce4633184b3e0d97601017135George Zhang * struct vmci_queue_kern_if is a per-OS defined Queue structure.  It contains
12706164d2b72aa752ce4633184b3e0d97601017135George Zhang * either a direct pointer to the linear address of the buffer contents or a
12806164d2b72aa752ce4633184b3e0d97601017135George Zhang * pointer to structures which help the OS locate those data pages.  See
12906164d2b72aa752ce4633184b3e0d97601017135George Zhang * vmciKernelIf.c for each platform for its definition.
13006164d2b72aa752ce4633184b3e0d97601017135George Zhang */
13106164d2b72aa752ce4633184b3e0d97601017135George Zhangstruct vmci_queue {
13206164d2b72aa752ce4633184b3e0d97601017135George Zhang	struct vmci_queue_header *q_header;
13306164d2b72aa752ce4633184b3e0d97601017135George Zhang	struct vmci_queue_header *saved_header;
13406164d2b72aa752ce4633184b3e0d97601017135George Zhang	struct vmci_queue_kern_if *kernel_if;
13506164d2b72aa752ce4633184b3e0d97601017135George Zhang};
13606164d2b72aa752ce4633184b3e0d97601017135George Zhang
13706164d2b72aa752ce4633184b3e0d97601017135George Zhang/*
13806164d2b72aa752ce4633184b3e0d97601017135George Zhang * Utility function that checks whether the fields of the page
13906164d2b72aa752ce4633184b3e0d97601017135George Zhang * store contain valid values.
14006164d2b72aa752ce4633184b3e0d97601017135George Zhang * Result:
14106164d2b72aa752ce4633184b3e0d97601017135George Zhang * true if the page store is wellformed. false otherwise.
14206164d2b72aa752ce4633184b3e0d97601017135George Zhang */
14306164d2b72aa752ce4633184b3e0d97601017135George Zhangstatic inline bool
14406164d2b72aa752ce4633184b3e0d97601017135George ZhangVMCI_QP_PAGESTORE_IS_WELLFORMED(struct vmci_qp_page_store *page_store)
14506164d2b72aa752ce4633184b3e0d97601017135George Zhang{
14606164d2b72aa752ce4633184b3e0d97601017135George Zhang	return page_store->len >= 2;
14706164d2b72aa752ce4633184b3e0d97601017135George Zhang}
14806164d2b72aa752ce4633184b3e0d97601017135George Zhang
14906164d2b72aa752ce4633184b3e0d97601017135George Zhangvoid vmci_qp_broker_exit(void);
15006164d2b72aa752ce4633184b3e0d97601017135George Zhangint vmci_qp_broker_alloc(struct vmci_handle handle, u32 peer,
15106164d2b72aa752ce4633184b3e0d97601017135George Zhang			 u32 flags, u32 priv_flags,
15206164d2b72aa752ce4633184b3e0d97601017135George Zhang			 u64 produce_size, u64 consume_size,
15306164d2b72aa752ce4633184b3e0d97601017135George Zhang			 struct vmci_qp_page_store *page_store,
15406164d2b72aa752ce4633184b3e0d97601017135George Zhang			 struct vmci_ctx *context);
15506164d2b72aa752ce4633184b3e0d97601017135George Zhangint vmci_qp_broker_set_page_store(struct vmci_handle handle,
15606164d2b72aa752ce4633184b3e0d97601017135George Zhang				  u64 produce_uva, u64 consume_uva,
15706164d2b72aa752ce4633184b3e0d97601017135George Zhang				  struct vmci_ctx *context);
15806164d2b72aa752ce4633184b3e0d97601017135George Zhangint vmci_qp_broker_detach(struct vmci_handle handle, struct vmci_ctx *context);
15906164d2b72aa752ce4633184b3e0d97601017135George Zhang
16006164d2b72aa752ce4633184b3e0d97601017135George Zhangvoid vmci_qp_guest_endpoints_exit(void);
16106164d2b72aa752ce4633184b3e0d97601017135George Zhang
16206164d2b72aa752ce4633184b3e0d97601017135George Zhangint vmci_qp_alloc(struct vmci_handle *handle,
16306164d2b72aa752ce4633184b3e0d97601017135George Zhang		  struct vmci_queue **produce_q, u64 produce_size,
16406164d2b72aa752ce4633184b3e0d97601017135George Zhang		  struct vmci_queue **consume_q, u64 consume_size,
16506164d2b72aa752ce4633184b3e0d97601017135George Zhang		  u32 peer, u32 flags, u32 priv_flags,
16606164d2b72aa752ce4633184b3e0d97601017135George Zhang		  bool guest_endpoint, vmci_event_release_cb wakeup_cb,
16706164d2b72aa752ce4633184b3e0d97601017135George Zhang		  void *client_data);
16806164d2b72aa752ce4633184b3e0d97601017135George Zhangint vmci_qp_broker_map(struct vmci_handle handle,
16906164d2b72aa752ce4633184b3e0d97601017135George Zhang		       struct vmci_ctx *context, u64 guest_mem);
17006164d2b72aa752ce4633184b3e0d97601017135George Zhangint vmci_qp_broker_unmap(struct vmci_handle handle,
17106164d2b72aa752ce4633184b3e0d97601017135George Zhang			 struct vmci_ctx *context, u32 gid);
17206164d2b72aa752ce4633184b3e0d97601017135George Zhang
17306164d2b72aa752ce4633184b3e0d97601017135George Zhang#endif /* _VMCI_QUEUE_PAIR_H_ */
174