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