0001
0002
0003
0004
0005
0006
0007
0008 #ifndef _VMCI_CONTEXT_H_
0009 #define _VMCI_CONTEXT_H_
0010
0011 #include <linux/vmw_vmci_defs.h>
0012 #include <linux/atomic.h>
0013 #include <linux/kref.h>
0014 #include <linux/types.h>
0015 #include <linux/wait.h>
0016
0017 #include "vmci_handle_array.h"
0018 #include "vmci_datagram.h"
0019
0020
0021 enum {
0022 VMCI_NOTIFICATION_CPT_STATE = 1,
0023 VMCI_WELLKNOWN_CPT_STATE = 2,
0024 VMCI_DG_OUT_STATE = 3,
0025 VMCI_DG_IN_STATE = 4,
0026 VMCI_DG_IN_SIZE_STATE = 5,
0027 VMCI_DOORBELL_CPT_STATE = 6,
0028 };
0029
0030
0031 struct vmci_host {
0032 wait_queue_head_t wait_queue;
0033 };
0034
0035 struct vmci_handle_list {
0036 struct list_head node;
0037 struct vmci_handle handle;
0038 };
0039
0040 struct vmci_ctx {
0041 struct list_head list_item;
0042 u32 cid;
0043 struct kref kref;
0044 struct list_head datagram_queue;
0045 u32 pending_datagrams;
0046 size_t datagram_queue_size;
0047
0048
0049
0050
0051
0052 int user_version;
0053 spinlock_t lock;
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 struct vmci_handle_arr *queue_pair_array;
0066
0067
0068 struct vmci_handle_arr *doorbell_array;
0069
0070
0071 struct vmci_handle_arr *pending_doorbell_array;
0072
0073
0074 struct list_head notifier_list;
0075 unsigned int n_notifiers;
0076
0077 struct vmci_host host_context;
0078 u32 priv_flags;
0079
0080 const struct cred *cred;
0081 bool *notify;
0082 struct page *notify_page;
0083 };
0084
0085
0086 struct vmci_ctx_info {
0087 u32 remote_cid;
0088 int result;
0089 };
0090
0091
0092 struct vmci_ctx_chkpt_buf_info {
0093 u64 cpt_buf;
0094 u32 cpt_type;
0095 u32 buf_size;
0096 s32 result;
0097 u32 _pad;
0098 };
0099
0100
0101
0102
0103
0104 struct vmci_ctx_notify_recv_info {
0105 u64 db_handle_buf_uva;
0106 u64 db_handle_buf_size;
0107 u64 qp_handle_buf_uva;
0108 u64 qp_handle_buf_size;
0109 s32 result;
0110 u32 _pad;
0111 };
0112
0113
0114
0115
0116
0117
0118 static inline bool vmci_deny_interaction(u32 part_one, u32 part_two)
0119 {
0120 return ((part_one & VMCI_PRIVILEGE_FLAG_RESTRICTED) &&
0121 !(part_two & VMCI_PRIVILEGE_FLAG_TRUSTED)) ||
0122 ((part_two & VMCI_PRIVILEGE_FLAG_RESTRICTED) &&
0123 !(part_one & VMCI_PRIVILEGE_FLAG_TRUSTED));
0124 }
0125
0126 struct vmci_ctx *vmci_ctx_create(u32 cid, u32 flags,
0127 uintptr_t event_hnd, int version,
0128 const struct cred *cred);
0129 void vmci_ctx_destroy(struct vmci_ctx *context);
0130
0131 bool vmci_ctx_supports_host_qp(struct vmci_ctx *context);
0132 int vmci_ctx_enqueue_datagram(u32 cid, struct vmci_datagram *dg);
0133 int vmci_ctx_dequeue_datagram(struct vmci_ctx *context,
0134 size_t *max_size, struct vmci_datagram **dg);
0135 int vmci_ctx_pending_datagrams(u32 cid, u32 *pending);
0136 struct vmci_ctx *vmci_ctx_get(u32 cid);
0137 void vmci_ctx_put(struct vmci_ctx *context);
0138 bool vmci_ctx_exists(u32 cid);
0139
0140 int vmci_ctx_add_notification(u32 context_id, u32 remote_cid);
0141 int vmci_ctx_remove_notification(u32 context_id, u32 remote_cid);
0142 int vmci_ctx_get_chkpt_state(u32 context_id, u32 cpt_type,
0143 u32 *num_cids, void **cpt_buf_ptr);
0144 int vmci_ctx_set_chkpt_state(u32 context_id, u32 cpt_type,
0145 u32 num_cids, void *cpt_buf);
0146
0147 int vmci_ctx_qp_create(struct vmci_ctx *context, struct vmci_handle handle);
0148 int vmci_ctx_qp_destroy(struct vmci_ctx *context, struct vmci_handle handle);
0149 bool vmci_ctx_qp_exists(struct vmci_ctx *context, struct vmci_handle handle);
0150
0151 void vmci_ctx_check_signal_notify(struct vmci_ctx *context);
0152 void vmci_ctx_unset_notify(struct vmci_ctx *context);
0153
0154 int vmci_ctx_dbell_create(u32 context_id, struct vmci_handle handle);
0155 int vmci_ctx_dbell_destroy(u32 context_id, struct vmci_handle handle);
0156 int vmci_ctx_dbell_destroy_all(u32 context_id);
0157 int vmci_ctx_notify_dbell(u32 cid, struct vmci_handle handle,
0158 u32 src_priv_flags);
0159
0160 int vmci_ctx_rcv_notifications_get(u32 context_id, struct vmci_handle_arr
0161 **db_handle_array, struct vmci_handle_arr
0162 **qp_handle_array);
0163 void vmci_ctx_rcv_notifications_release(u32 context_id, struct vmci_handle_arr
0164 *db_handle_array, struct vmci_handle_arr
0165 *qp_handle_array, bool success);
0166
0167 static inline u32 vmci_ctx_get_id(struct vmci_ctx *context)
0168 {
0169 if (!context)
0170 return VMCI_INVALID_ID;
0171 return context->cid;
0172 }
0173
0174 #endif