• Home
  • Raw
  • Download

Lines Matching full:context

38  * These, along with context lookup, are protected by the
43 spinlock_t lock; /* Spinlock for context list operations */
52 static void ctx_signal_notify(struct vmci_ctx *context) in ctx_signal_notify() argument
54 *context->notify = true; in ctx_signal_notify()
57 static void ctx_clear_notify(struct vmci_ctx *context) in ctx_clear_notify() argument
59 *context->notify = false; in ctx_clear_notify()
66 static void ctx_clear_notify_call(struct vmci_ctx *context) in ctx_clear_notify_call() argument
68 if (context->pending_datagrams == 0 && in ctx_clear_notify_call()
69 vmci_handle_arr_get_size(context->pending_doorbell_array) == 0) in ctx_clear_notify_call()
70 ctx_clear_notify(context); in ctx_clear_notify_call()
74 * Sets the context's notify flag iff datagrams are pending for this
75 * context. Called from vmci_setup_notify().
77 void vmci_ctx_check_signal_notify(struct vmci_ctx *context) in vmci_ctx_check_signal_notify() argument
79 spin_lock(&context->lock); in vmci_ctx_check_signal_notify()
80 if (context->pending_datagrams) in vmci_ctx_check_signal_notify()
81 ctx_signal_notify(context); in vmci_ctx_check_signal_notify()
82 spin_unlock(&context->lock); in vmci_ctx_check_signal_notify()
86 * Allocates and initializes a VMCI context.
93 struct vmci_ctx *context; in vmci_ctx_create() local
97 pr_devel("Invalid context ID for VMCI context\n"); in vmci_ctx_create()
103 pr_devel("Invalid flag (flags=0x%x) for VMCI context\n", in vmci_ctx_create()
115 context = kzalloc(sizeof(*context), GFP_KERNEL); in vmci_ctx_create()
116 if (!context) { in vmci_ctx_create()
117 pr_warn("Failed to allocate memory for VMCI context\n"); in vmci_ctx_create()
122 kref_init(&context->kref); in vmci_ctx_create()
123 spin_lock_init(&context->lock); in vmci_ctx_create()
124 INIT_LIST_HEAD(&context->list_item); in vmci_ctx_create()
125 INIT_LIST_HEAD(&context->datagram_queue); in vmci_ctx_create()
126 INIT_LIST_HEAD(&context->notifier_list); in vmci_ctx_create()
128 /* Initialize host-specific VMCI context. */ in vmci_ctx_create()
129 init_waitqueue_head(&context->host_context.wait_queue); in vmci_ctx_create()
131 context->queue_pair_array = in vmci_ctx_create()
133 if (!context->queue_pair_array) { in vmci_ctx_create()
138 context->doorbell_array = in vmci_ctx_create()
140 if (!context->doorbell_array) { in vmci_ctx_create()
145 context->pending_doorbell_array = in vmci_ctx_create()
147 if (!context->pending_doorbell_array) { in vmci_ctx_create()
152 context->user_version = user_version; in vmci_ctx_create()
154 context->priv_flags = priv_flags; in vmci_ctx_create()
157 context->cred = get_cred(cred); in vmci_ctx_create()
159 context->notify = &ctx_dummy_notify; in vmci_ctx_create()
160 context->notify_page = NULL; in vmci_ctx_create()
163 * If we collide with an existing context we generate a new in vmci_ctx_create()
176 context->cid = cid; in vmci_ctx_create()
178 list_add_tail_rcu(&context->list_item, &ctx_list.head); in vmci_ctx_create()
181 return context; in vmci_ctx_create()
184 vmci_handle_arr_destroy(context->doorbell_array); in vmci_ctx_create()
186 vmci_handle_arr_destroy(context->queue_pair_array); in vmci_ctx_create()
188 kfree(context); in vmci_ctx_create()
194 * Destroy VMCI context.
196 void vmci_ctx_destroy(struct vmci_ctx *context) in vmci_ctx_destroy() argument
199 list_del_rcu(&context->list_item); in vmci_ctx_destroy()
203 vmci_ctx_put(context); in vmci_ctx_destroy()
268 pr_devel("Failed to enqueue event datagram (type=%d) for context (ID=0x%x)\n", in ctx_fire_notification()
270 ev.msg.hdr.dst.context); in ctx_fire_notification()
286 struct vmci_ctx *context; in vmci_ctx_pending_datagrams() local
288 context = vmci_ctx_get(cid); in vmci_ctx_pending_datagrams()
289 if (context == NULL) in vmci_ctx_pending_datagrams()
292 spin_lock(&context->lock); in vmci_ctx_pending_datagrams()
294 *pending = context->pending_datagrams; in vmci_ctx_pending_datagrams()
295 spin_unlock(&context->lock); in vmci_ctx_pending_datagrams()
296 vmci_ctx_put(context); in vmci_ctx_pending_datagrams()
302 * Queues a VMCI datagram for the appropriate target VM context.
307 struct vmci_ctx *context; in vmci_ctx_enqueue_datagram() local
317 /* Get the target VM's VMCI context. */ in vmci_ctx_enqueue_datagram()
318 context = vmci_ctx_get(cid); in vmci_ctx_enqueue_datagram()
319 if (!context) { in vmci_ctx_enqueue_datagram()
320 pr_devel("Invalid context (ID=0x%x)\n", cid); in vmci_ctx_enqueue_datagram()
328 vmci_ctx_put(context); in vmci_ctx_enqueue_datagram()
336 spin_lock(&context->lock); in vmci_ctx_enqueue_datagram()
347 if (context->datagram_queue_size + vmci_dg_size >= in vmci_ctx_enqueue_datagram()
353 context->datagram_queue_size + vmci_dg_size >= in vmci_ctx_enqueue_datagram()
355 spin_unlock(&context->lock); in vmci_ctx_enqueue_datagram()
356 vmci_ctx_put(context); in vmci_ctx_enqueue_datagram()
358 pr_devel("Context (ID=0x%x) receive queue is full\n", cid); in vmci_ctx_enqueue_datagram()
362 list_add(&dq_entry->list_item, &context->datagram_queue); in vmci_ctx_enqueue_datagram()
363 context->pending_datagrams++; in vmci_ctx_enqueue_datagram()
364 context->datagram_queue_size += vmci_dg_size; in vmci_ctx_enqueue_datagram()
365 ctx_signal_notify(context); in vmci_ctx_enqueue_datagram()
366 wake_up(&context->host_context.wait_queue); in vmci_ctx_enqueue_datagram()
367 spin_unlock(&context->lock); in vmci_ctx_enqueue_datagram()
368 vmci_ctx_put(context); in vmci_ctx_enqueue_datagram()
374 * Verifies whether a context with the specified context ID exists.
376 * using this data as context can appear and disappear at any time.
380 struct vmci_ctx *context; in vmci_ctx_exists() local
385 list_for_each_entry_rcu(context, &ctx_list.head, list_item) { in vmci_ctx_exists()
386 if (context->cid == cid) { in vmci_ctx_exists()
397 * Retrieves VMCI context corresponding to the given cid.
401 struct vmci_ctx *c, *context = NULL; in vmci_ctx_get() local
410 * The context owner drops its own reference to the in vmci_ctx_get()
411 * context only after removing it from the list and in vmci_ctx_get()
417 context = c; in vmci_ctx_get()
418 kref_get(&context->kref); in vmci_ctx_get()
424 return context; in vmci_ctx_get()
428 * Deallocates all parts of a context data structure. This
429 * function doesn't lock the context, because it assumes that
430 * the caller was holding the last reference to context.
434 struct vmci_ctx *context = container_of(kref, struct vmci_ctx, kref); in ctx_free_ctx() local
441 * context is dying. in ctx_free_ctx()
443 ctx_fire_notification(context->cid, context->priv_flags); in ctx_free_ctx()
446 * Cleanup all queue pair resources attached to context. If in ctx_free_ctx()
450 temp_handle = vmci_handle_arr_get_entry(context->queue_pair_array, 0); in ctx_free_ctx()
453 context) < VMCI_SUCCESS) { in ctx_free_ctx()
460 vmci_handle_arr_remove_entry(context->queue_pair_array, in ctx_free_ctx()
464 vmci_handle_arr_get_entry(context->queue_pair_array, 0); in ctx_free_ctx()
469 * this is the only thread having a reference to the context. in ctx_free_ctx()
472 &context->datagram_queue, list_item) { in ctx_free_ctx()
480 &context->notifier_list, node) { in ctx_free_ctx()
485 vmci_handle_arr_destroy(context->queue_pair_array); in ctx_free_ctx()
486 vmci_handle_arr_destroy(context->doorbell_array); in ctx_free_ctx()
487 vmci_handle_arr_destroy(context->pending_doorbell_array); in ctx_free_ctx()
488 vmci_ctx_unset_notify(context); in ctx_free_ctx()
489 if (context->cred) in ctx_free_ctx()
490 put_cred(context->cred); in ctx_free_ctx()
491 kfree(context); in ctx_free_ctx()
495 * Drops reference to VMCI context. If this is the last reference to
496 * the context it will be deallocated. A context is created with
498 * the context list before its reference count is decremented. Thus,
500 * it (they need the entry in the context list for that), and so there
503 void vmci_ctx_put(struct vmci_ctx *context) in vmci_ctx_put() argument
505 kref_put(&context->kref, ctx_free_ctx); in vmci_ctx_put()
516 int vmci_ctx_dequeue_datagram(struct vmci_ctx *context, in vmci_ctx_dequeue_datagram() argument
525 spin_lock(&context->lock); in vmci_ctx_dequeue_datagram()
526 if (context->pending_datagrams == 0) { in vmci_ctx_dequeue_datagram()
527 ctx_clear_notify_call(context); in vmci_ctx_dequeue_datagram()
528 spin_unlock(&context->lock); in vmci_ctx_dequeue_datagram()
533 list_item = context->datagram_queue.next; in vmci_ctx_dequeue_datagram()
541 spin_unlock(&context->lock); in vmci_ctx_dequeue_datagram()
548 context->pending_datagrams--; in vmci_ctx_dequeue_datagram()
549 context->datagram_queue_size -= dq_entry->dg_size; in vmci_ctx_dequeue_datagram()
550 if (context->pending_datagrams == 0) { in vmci_ctx_dequeue_datagram()
551 ctx_clear_notify_call(context); in vmci_ctx_dequeue_datagram()
559 list_item = context->datagram_queue.next; in vmci_ctx_dequeue_datagram()
570 spin_unlock(&context->lock); in vmci_ctx_dequeue_datagram()
584 void vmci_ctx_unset_notify(struct vmci_ctx *context) in vmci_ctx_unset_notify() argument
588 spin_lock(&context->lock); in vmci_ctx_unset_notify()
590 notify_page = context->notify_page; in vmci_ctx_unset_notify()
591 context->notify = &ctx_dummy_notify; in vmci_ctx_unset_notify()
592 context->notify_page = NULL; in vmci_ctx_unset_notify()
594 spin_unlock(&context->lock); in vmci_ctx_unset_notify()
608 struct vmci_ctx *context; in vmci_ctx_add_notification() local
613 context = vmci_ctx_get(context_id); in vmci_ctx_add_notification()
614 if (!context) in vmci_ctx_add_notification()
618 pr_devel("Context removed notifications for other VMs not supported (src=0x%x, remote=0x%x)\n", in vmci_ctx_add_notification()
624 if (context->priv_flags & VMCI_PRIVILEGE_FLAG_RESTRICTED) { in vmci_ctx_add_notification()
638 spin_lock(&context->lock); in vmci_ctx_add_notification()
640 if (context->n_notifiers < VMCI_MAX_CONTEXTS) { in vmci_ctx_add_notification()
641 list_for_each_entry(n, &context->notifier_list, node) { in vmci_ctx_add_notification()
653 &context->notifier_list); in vmci_ctx_add_notification()
654 context->n_notifiers++; in vmci_ctx_add_notification()
662 spin_unlock(&context->lock); in vmci_ctx_add_notification()
665 vmci_ctx_put(context); in vmci_ctx_add_notification()
670 * Remove remote_cid from current context's list of contexts it is
675 struct vmci_ctx *context; in vmci_ctx_remove_notification() local
680 context = vmci_ctx_get(context_id); in vmci_ctx_remove_notification()
681 if (!context) in vmci_ctx_remove_notification()
686 spin_lock(&context->lock); in vmci_ctx_remove_notification()
688 &context->notifier_list, node) { in vmci_ctx_remove_notification()
691 context->n_notifiers--; in vmci_ctx_remove_notification()
696 spin_unlock(&context->lock); in vmci_ctx_remove_notification()
703 vmci_ctx_put(context); in vmci_ctx_remove_notification()
708 static int vmci_ctx_get_chkpt_notifiers(struct vmci_ctx *context, in vmci_ctx_get_chkpt_notifiers() argument
716 if (context->n_notifiers == 0) { in vmci_ctx_get_chkpt_notifiers()
722 data_size = context->n_notifiers * sizeof(*notifiers); in vmci_ctx_get_chkpt_notifiers()
732 list_for_each_entry(entry, &context->notifier_list, node) in vmci_ctx_get_chkpt_notifiers()
733 notifiers[i++] = entry->handle.context; in vmci_ctx_get_chkpt_notifiers()
740 static int vmci_ctx_get_chkpt_doorbells(struct vmci_ctx *context, in vmci_ctx_get_chkpt_doorbells() argument
746 n_doorbells = vmci_handle_arr_get_size(context->doorbell_array); in vmci_ctx_get_chkpt_doorbells()
760 context->doorbell_array, i); in vmci_ctx_get_chkpt_doorbells()
773 * Get current context's checkpoint state of given type.
780 struct vmci_ctx *context; in vmci_ctx_get_chkpt_state() local
783 context = vmci_ctx_get(context_id); in vmci_ctx_get_chkpt_state()
784 if (!context) in vmci_ctx_get_chkpt_state()
787 spin_lock(&context->lock); in vmci_ctx_get_chkpt_state()
791 result = vmci_ctx_get_chkpt_notifiers(context, buf_size, pbuf); in vmci_ctx_get_chkpt_state()
806 result = vmci_ctx_get_chkpt_doorbells(context, buf_size, pbuf); in vmci_ctx_get_chkpt_state()
815 spin_unlock(&context->lock); in vmci_ctx_get_chkpt_state()
816 vmci_ctx_put(context); in vmci_ctx_get_chkpt_state()
822 * Set current context's checkpoint state of given type.
862 * Retrieves the specified context's pending notifications in the
872 struct vmci_ctx *context; in vmci_ctx_rcv_notifications_get() local
875 context = vmci_ctx_get(context_id); in vmci_ctx_rcv_notifications_get()
876 if (context == NULL) in vmci_ctx_rcv_notifications_get()
879 spin_lock(&context->lock); in vmci_ctx_rcv_notifications_get()
881 *db_handle_array = context->pending_doorbell_array; in vmci_ctx_rcv_notifications_get()
882 context->pending_doorbell_array = in vmci_ctx_rcv_notifications_get()
884 if (!context->pending_doorbell_array) { in vmci_ctx_rcv_notifications_get()
885 context->pending_doorbell_array = *db_handle_array; in vmci_ctx_rcv_notifications_get()
891 spin_unlock(&context->lock); in vmci_ctx_rcv_notifications_get()
892 vmci_ctx_put(context); in vmci_ctx_rcv_notifications_get()
908 struct vmci_ctx *context = vmci_ctx_get(context_id); in vmci_ctx_rcv_notifications_release() local
910 spin_lock(&context->lock); in vmci_ctx_rcv_notifications_release()
916 * holding the context lock, so we transfer any new pending in vmci_ctx_rcv_notifications_release()
922 context->pending_doorbell_array); in vmci_ctx_rcv_notifications_release()
930 context->pending_doorbell_array); in vmci_ctx_rcv_notifications_release()
932 vmci_handle_arr_destroy(context->pending_doorbell_array); in vmci_ctx_rcv_notifications_release()
933 context->pending_doorbell_array = db_handle_array; in vmci_ctx_rcv_notifications_release()
936 ctx_clear_notify_call(context); in vmci_ctx_rcv_notifications_release()
938 spin_unlock(&context->lock); in vmci_ctx_rcv_notifications_release()
939 vmci_ctx_put(context); in vmci_ctx_rcv_notifications_release()
950 * context. Only doorbell handles registered can be notified.
954 struct vmci_ctx *context; in vmci_ctx_dbell_create() local
960 context = vmci_ctx_get(context_id); in vmci_ctx_dbell_create()
961 if (context == NULL) in vmci_ctx_dbell_create()
964 spin_lock(&context->lock); in vmci_ctx_dbell_create()
965 if (!vmci_handle_arr_has_entry(context->doorbell_array, handle)) in vmci_ctx_dbell_create()
966 result = vmci_handle_arr_append_entry(&context->doorbell_array, in vmci_ctx_dbell_create()
971 spin_unlock(&context->lock); in vmci_ctx_dbell_create()
972 vmci_ctx_put(context); in vmci_ctx_dbell_create()
983 struct vmci_ctx *context; in vmci_ctx_dbell_destroy() local
989 context = vmci_ctx_get(context_id); in vmci_ctx_dbell_destroy()
990 if (context == NULL) in vmci_ctx_dbell_destroy()
993 spin_lock(&context->lock); in vmci_ctx_dbell_destroy()
995 vmci_handle_arr_remove_entry(context->doorbell_array, handle); in vmci_ctx_dbell_destroy()
996 vmci_handle_arr_remove_entry(context->pending_doorbell_array, handle); in vmci_ctx_dbell_destroy()
997 spin_unlock(&context->lock); in vmci_ctx_dbell_destroy()
999 vmci_ctx_put(context); in vmci_ctx_dbell_destroy()
1011 struct vmci_ctx *context; in vmci_ctx_dbell_destroy_all() local
1017 context = vmci_ctx_get(context_id); in vmci_ctx_dbell_destroy_all()
1018 if (context == NULL) in vmci_ctx_dbell_destroy_all()
1021 spin_lock(&context->lock); in vmci_ctx_dbell_destroy_all()
1023 struct vmci_handle_arr *arr = context->doorbell_array; in vmci_ctx_dbell_destroy_all()
1027 struct vmci_handle_arr *arr = context->pending_doorbell_array; in vmci_ctx_dbell_destroy_all()
1030 spin_unlock(&context->lock); in vmci_ctx_dbell_destroy_all()
1032 vmci_ctx_put(context); in vmci_ctx_dbell_destroy_all()
1039 * specified source context. The notification of doorbells are
1042 * of sender rights than those assigned to the sending context
1043 * itself, the host context is required to specify a different
1045 * the source context.
1057 /* Get the target VM's VMCI context. */ in vmci_ctx_notify_dbell()
1058 dst_context = vmci_ctx_get(handle.context); in vmci_ctx_notify_dbell()
1060 pr_devel("Invalid context (ID=0x%x)\n", handle.context); in vmci_ctx_notify_dbell()
1064 if (src_cid != handle.context) { in vmci_ctx_notify_dbell()
1068 VMCI_CONTEXT_IS_VM(handle.context)) { in vmci_ctx_notify_dbell()
1070 src_cid, handle.context); in vmci_ctx_notify_dbell()
1078 handle.context, handle.resource); in vmci_ctx_notify_dbell()
1093 if (handle.context == VMCI_HOST_CONTEXT_ID) { in vmci_ctx_notify_dbell()
1125 bool vmci_ctx_supports_host_qp(struct vmci_ctx *context) in vmci_ctx_supports_host_qp() argument
1127 return context && context->user_version >= VMCI_VERSION_HOSTQP; in vmci_ctx_supports_host_qp()
1132 * the context.
1134 int vmci_ctx_qp_create(struct vmci_ctx *context, struct vmci_handle handle) in vmci_ctx_qp_create() argument
1138 if (context == NULL || vmci_handle_is_invalid(handle)) in vmci_ctx_qp_create()
1141 if (!vmci_handle_arr_has_entry(context->queue_pair_array, handle)) in vmci_ctx_qp_create()
1143 &context->queue_pair_array, handle); in vmci_ctx_qp_create()
1154 int vmci_ctx_qp_destroy(struct vmci_ctx *context, struct vmci_handle handle) in vmci_ctx_qp_destroy() argument
1158 if (context == NULL || vmci_handle_is_invalid(handle)) in vmci_ctx_qp_destroy()
1161 hndl = vmci_handle_arr_remove_entry(context->queue_pair_array, handle); in vmci_ctx_qp_destroy()
1169 * with the given context.
1171 bool vmci_ctx_qp_exists(struct vmci_ctx *context, struct vmci_handle handle) in vmci_ctx_qp_exists() argument
1173 if (context == NULL || vmci_handle_is_invalid(handle)) in vmci_ctx_qp_exists()
1176 return vmci_handle_arr_has_entry(context->queue_pair_array, handle); in vmci_ctx_qp_exists()
1181 * @context_id: The context ID of the VMCI context.
1183 * Retrieves privilege flags of the given VMCI context ID.
1189 struct vmci_ctx *context; in vmci_context_get_priv_flags() local
1191 context = vmci_ctx_get(context_id); in vmci_context_get_priv_flags()
1192 if (!context) in vmci_context_get_priv_flags()
1195 flags = context->priv_flags; in vmci_context_get_priv_flags()
1196 vmci_ctx_put(context); in vmci_context_get_priv_flags()
1204 * vmci_is_context_owner() - Determimnes if user is the context owner
1205 * @context_id: The context ID of the VMCI context.
1208 * Determines whether a given UID is the owner of given VMCI context.
1215 struct vmci_ctx *context = vmci_ctx_get(context_id); in vmci_is_context_owner() local
1216 if (context) { in vmci_is_context_owner()
1217 if (context->cred) in vmci_is_context_owner()
1218 is_owner = uid_eq(context->cred->uid, uid); in vmci_is_context_owner()
1219 vmci_ctx_put(context); in vmci_is_context_owner()