Lines Matching refs:context

30  * These, along with context lookup, are protected by the
35 spinlock_t lock; /* Spinlock for context list operations */
44 static void ctx_signal_notify(struct vmci_ctx *context)
46 *context->notify = true;
49 static void ctx_clear_notify(struct vmci_ctx *context)
51 *context->notify = false;
58 static void ctx_clear_notify_call(struct vmci_ctx *context)
60 if (context->pending_datagrams == 0 &&
61 vmci_handle_arr_get_size(context->pending_doorbell_array) == 0)
62 ctx_clear_notify(context);
66 * Sets the context's notify flag iff datagrams are pending for this
67 * context. Called from vmci_setup_notify().
69 void vmci_ctx_check_signal_notify(struct vmci_ctx *context)
71 spin_lock(&context->lock);
72 if (context->pending_datagrams)
73 ctx_signal_notify(context);
74 spin_unlock(&context->lock);
78 * Allocates and initializes a VMCI context.
85 struct vmci_ctx *context;
89 pr_devel("Invalid context ID for VMCI context\n");
95 pr_devel("Invalid flag (flags=0x%x) for VMCI context\n",
107 context = kzalloc(sizeof(*context), GFP_KERNEL);
108 if (!context) {
109 pr_warn("Failed to allocate memory for VMCI context\n");
114 kref_init(&context->kref);
115 spin_lock_init(&context->lock);
116 INIT_LIST_HEAD(&context->list_item);
117 INIT_LIST_HEAD(&context->datagram_queue);
118 INIT_LIST_HEAD(&context->notifier_list);
120 /* Initialize host-specific VMCI context. */
121 init_waitqueue_head(&context->host_context.wait_queue);
123 context->queue_pair_array =
125 if (!context->queue_pair_array) {
130 context->doorbell_array =
132 if (!context->doorbell_array) {
137 context->pending_doorbell_array =
139 if (!context->pending_doorbell_array) {
144 context->user_version = user_version;
146 context->priv_flags = priv_flags;
149 context->cred = get_cred(cred);
151 context->notify = &ctx_dummy_notify;
152 context->notify_page = NULL;
155 * If we collide with an existing context we generate a new
168 context->cid = cid;
170 list_add_tail_rcu(&context->list_item, &ctx_list.head);
173 return context;
176 vmci_handle_arr_destroy(context->doorbell_array);
178 vmci_handle_arr_destroy(context->queue_pair_array);
180 kfree(context);
186 * Destroy VMCI context.
188 void vmci_ctx_destroy(struct vmci_ctx *context)
191 list_del_rcu(&context->list_item);
195 vmci_ctx_put(context);
260 pr_devel("Failed to enqueue event datagram (type=%d) for context (ID=0x%x)\n",
262 ev.msg.hdr.dst.context);
278 struct vmci_ctx *context;
280 context = vmci_ctx_get(cid);
281 if (context == NULL)
284 spin_lock(&context->lock);
286 *pending = context->pending_datagrams;
287 spin_unlock(&context->lock);
288 vmci_ctx_put(context);
294 * Queues a VMCI datagram for the appropriate target VM context.
299 struct vmci_ctx *context;
309 /* Get the target VM's VMCI context. */
310 context = vmci_ctx_get(cid);
311 if (!context) {
312 pr_devel("Invalid context (ID=0x%x)\n", cid);
320 vmci_ctx_put(context);
328 spin_lock(&context->lock);
339 if (context->datagram_queue_size + vmci_dg_size >=
345 context->datagram_queue_size + vmci_dg_size >=
347 spin_unlock(&context->lock);
348 vmci_ctx_put(context);
354 list_add(&dq_entry->list_item, &context->datagram_queue);
355 context->pending_datagrams++;
356 context->datagram_queue_size += vmci_dg_size;
357 ctx_signal_notify(context);
358 wake_up(&context->host_context.wait_queue);
359 spin_unlock(&context->lock);
360 vmci_ctx_put(context);
366 * Verifies whether a context with the specified context ID exists.
368 * using this data as context can appear and disappear at any time.
372 struct vmci_ctx *context;
377 list_for_each_entry_rcu(context, &ctx_list.head, list_item) {
378 if (context->cid == cid) {
389 * Retrieves VMCI context corresponding to the given cid.
393 struct vmci_ctx *c, *context = NULL;
402 * The context owner drops its own reference to the
403 * context only after removing it from the list and
409 context = c;
410 kref_get(&context->kref);
416 return context;
420 * Deallocates all parts of a context data structure. This
421 * function doesn't lock the context, because it assumes that
422 * the caller was holding the last reference to context.
426 struct vmci_ctx *context = container_of(kref, struct vmci_ctx, kref);
433 * context is dying.
435 ctx_fire_notification(context->cid, context->priv_flags);
438 * Cleanup all queue pair resources attached to context. If
442 temp_handle = vmci_handle_arr_get_entry(context->queue_pair_array, 0);
445 context) < VMCI_SUCCESS) {
452 vmci_handle_arr_remove_entry(context->queue_pair_array,
456 vmci_handle_arr_get_entry(context->queue_pair_array, 0);
461 * this is the only thread having a reference to the context.
464 &context->datagram_queue, list_item) {
472 &context->notifier_list, node) {
477 vmci_handle_arr_destroy(context->queue_pair_array);
478 vmci_handle_arr_destroy(context->doorbell_array);
479 vmci_handle_arr_destroy(context->pending_doorbell_array);
480 vmci_ctx_unset_notify(context);
481 if (context->cred)
482 put_cred(context->cred);
483 kfree(context);
487 * Drops reference to VMCI context. If this is the last reference to
488 * the context it will be deallocated. A context is created with
490 * the context list before its reference count is decremented. Thus,
492 * it (they need the entry in the context list for that), and so there
495 void vmci_ctx_put(struct vmci_ctx *context)
497 kref_put(&context->kref, ctx_free_ctx);
508 int vmci_ctx_dequeue_datagram(struct vmci_ctx *context,
517 spin_lock(&context->lock);
518 if (context->pending_datagrams == 0) {
519 ctx_clear_notify_call(context);
520 spin_unlock(&context->lock);
525 list_item = context->datagram_queue.next;
533 spin_unlock(&context->lock);
540 context->pending_datagrams--;
541 context->datagram_queue_size -= dq_entry->dg_size;
542 if (context->pending_datagrams == 0) {
543 ctx_clear_notify_call(context);
551 list_item = context->datagram_queue.next;
562 spin_unlock(&context->lock);
576 void vmci_ctx_unset_notify(struct vmci_ctx *context)
580 spin_lock(&context->lock);
582 notify_page = context->notify_page;
583 context->notify = &ctx_dummy_notify;
584 context->notify_page = NULL;
586 spin_unlock(&context->lock);
600 struct vmci_ctx *context;
605 context = vmci_ctx_get(context_id);
606 if (!context)
616 if (context->priv_flags & VMCI_PRIVILEGE_FLAG_RESTRICTED) {
630 spin_lock(&context->lock);
632 if (context->n_notifiers < VMCI_MAX_CONTEXTS) {
633 list_for_each_entry(n, &context->notifier_list, node) {
645 &context->notifier_list);
646 context->n_notifiers++;
654 spin_unlock(&context->lock);
657 vmci_ctx_put(context);
662 * Remove remote_cid from current context's list of contexts it is
667 struct vmci_ctx *context;
671 context = vmci_ctx_get(context_id);
672 if (!context)
677 spin_lock(&context->lock);
679 &context->notifier_list, node) {
682 context->n_notifiers--;
687 spin_unlock(&context->lock);
692 vmci_ctx_put(context);
697 static int vmci_ctx_get_chkpt_notifiers(struct vmci_ctx *context,
705 if (context->n_notifiers == 0) {
711 data_size = context->n_notifiers * sizeof(*notifiers);
721 list_for_each_entry(entry, &context->notifier_list, node)
722 notifiers[i++] = entry->handle.context;
729 static int vmci_ctx_get_chkpt_doorbells(struct vmci_ctx *context,
735 n_doorbells = vmci_handle_arr_get_size(context->doorbell_array);
749 context->doorbell_array, i);
762 * Get current context's checkpoint state of given type.
769 struct vmci_ctx *context;
772 context = vmci_ctx_get(context_id);
773 if (!context)
776 spin_lock(&context->lock);
780 result = vmci_ctx_get_chkpt_notifiers(context, buf_size, pbuf);
795 result = vmci_ctx_get_chkpt_doorbells(context, buf_size, pbuf);
804 spin_unlock(&context->lock);
805 vmci_ctx_put(context);
811 * Set current context's checkpoint state of given type.
851 * Retrieves the specified context's pending notifications in the
861 struct vmci_ctx *context;
864 context = vmci_ctx_get(context_id);
865 if (context == NULL)
868 spin_lock(&context->lock);
870 *db_handle_array = context->pending_doorbell_array;
871 context->pending_doorbell_array =
873 if (!context->pending_doorbell_array) {
874 context->pending_doorbell_array = *db_handle_array;
880 spin_unlock(&context->lock);
881 vmci_ctx_put(context);
897 struct vmci_ctx *context = vmci_ctx_get(context_id);
899 spin_lock(&context->lock);
905 * holding the context lock, so we transfer any new pending
911 context->pending_doorbell_array);
919 context->pending_doorbell_array);
921 vmci_handle_arr_destroy(context->pending_doorbell_array);
922 context->pending_doorbell_array = db_handle_array;
925 ctx_clear_notify_call(context);
927 spin_unlock(&context->lock);
928 vmci_ctx_put(context);
939 * context. Only doorbell handles registered can be notified.
943 struct vmci_ctx *context;
949 context = vmci_ctx_get(context_id);
950 if (context == NULL)
953 spin_lock(&context->lock);
954 if (!vmci_handle_arr_has_entry(context->doorbell_array, handle))
955 result = vmci_handle_arr_append_entry(&context->doorbell_array,
960 spin_unlock(&context->lock);
961 vmci_ctx_put(context);
972 struct vmci_ctx *context;
978 context = vmci_ctx_get(context_id);
979 if (context == NULL)
982 spin_lock(&context->lock);
984 vmci_handle_arr_remove_entry(context->doorbell_array, handle);
985 vmci_handle_arr_remove_entry(context->pending_doorbell_array, handle);
986 spin_unlock(&context->lock);
988 vmci_ctx_put(context);
1000 struct vmci_ctx *context;
1006 context = vmci_ctx_get(context_id);
1007 if (context == NULL)
1010 spin_lock(&context->lock);
1012 struct vmci_handle_arr *arr = context->doorbell_array;
1016 struct vmci_handle_arr *arr = context->pending_doorbell_array;
1019 spin_unlock(&context->lock);
1021 vmci_ctx_put(context);
1028 * specified source context. The notification of doorbells are
1031 * of sender rights than those assigned to the sending context
1032 * itself, the host context is required to specify a different
1034 * the source context.
1046 /* Get the target VM's VMCI context. */
1047 dst_context = vmci_ctx_get(handle.context);
1049 pr_devel("Invalid context (ID=0x%x)\n", handle.context);
1053 if (src_cid != handle.context) {
1057 VMCI_CONTEXT_IS_VM(handle.context)) {
1059 src_cid, handle.context);
1067 handle.context, handle.resource);
1082 if (handle.context == VMCI_HOST_CONTEXT_ID) {
1114 bool vmci_ctx_supports_host_qp(struct vmci_ctx *context)
1116 return context && context->user_version >= VMCI_VERSION_HOSTQP;
1121 * the context.
1123 int vmci_ctx_qp_create(struct vmci_ctx *context, struct vmci_handle handle)
1127 if (context == NULL || vmci_handle_is_invalid(handle))
1130 if (!vmci_handle_arr_has_entry(context->queue_pair_array, handle))
1132 &context->queue_pair_array, handle);
1143 int vmci_ctx_qp_destroy(struct vmci_ctx *context, struct vmci_handle handle)
1147 if (context == NULL || vmci_handle_is_invalid(handle))
1150 hndl = vmci_handle_arr_remove_entry(context->queue_pair_array, handle);
1158 * with the given context.
1160 bool vmci_ctx_qp_exists(struct vmci_ctx *context, struct vmci_handle handle)
1162 if (context == NULL || vmci_handle_is_invalid(handle))
1165 return vmci_handle_arr_has_entry(context->queue_pair_array, handle);
1170 * @context_id: The context ID of the VMCI context.
1172 * Retrieves privilege flags of the given VMCI context ID.
1178 struct vmci_ctx *context;
1180 context = vmci_ctx_get(context_id);
1181 if (!context)
1184 flags = context->priv_flags;
1185 vmci_ctx_put(context);
1193 * vmci_is_context_owner() - Determimnes if user is the context owner
1194 * @context_id: The context ID of the VMCI context.
1197 * Determines whether a given UID is the owner of given VMCI context.
1204 struct vmci_ctx *context = vmci_ctx_get(context_id);
1205 if (context) {
1206 if (context->cred)
1207 is_owner = uid_eq(context->cred->uid, uid);
1208 vmci_ctx_put(context);