vmci_context.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225
  1. /*
  2. * VMware VMCI Driver
  3. *
  4. * Copyright (C) 2012 VMware, Inc. All rights reserved.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation version 2 and no later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  13. * for more details.
  14. */
  15. #include <linux/vmw_vmci_defs.h>
  16. #include <linux/vmw_vmci_api.h>
  17. #include <linux/highmem.h>
  18. #include <linux/kernel.h>
  19. #include <linux/module.h>
  20. #include <linux/sched.h>
  21. #include <linux/cred.h>
  22. #include <linux/slab.h>
  23. #include "vmci_queue_pair.h"
  24. #include "vmci_datagram.h"
  25. #include "vmci_doorbell.h"
  26. #include "vmci_context.h"
  27. #include "vmci_driver.h"
  28. #include "vmci_event.h"
  29. /* Use a wide upper bound for the maximum contexts. */
  30. #define VMCI_MAX_CONTEXTS 2000
  31. /*
  32. * List of current VMCI contexts. Contexts can be added by
  33. * vmci_ctx_create() and removed via vmci_ctx_destroy().
  34. * These, along with context lookup, are protected by the
  35. * list structure's lock.
  36. */
  37. static struct {
  38. struct list_head head;
  39. spinlock_t lock; /* Spinlock for context list operations */
  40. } ctx_list = {
  41. .head = LIST_HEAD_INIT(ctx_list.head),
  42. .lock = __SPIN_LOCK_UNLOCKED(ctx_list.lock),
  43. };
  44. /* Used by contexts that did not set up notify flag pointers */
  45. static bool ctx_dummy_notify;
  46. static void ctx_signal_notify(struct vmci_ctx *context)
  47. {
  48. *context->notify = true;
  49. }
  50. static void ctx_clear_notify(struct vmci_ctx *context)
  51. {
  52. *context->notify = false;
  53. }
  54. /*
  55. * If nothing requires the attention of the guest, clears both
  56. * notify flag and call.
  57. */
  58. static void ctx_clear_notify_call(struct vmci_ctx *context)
  59. {
  60. if (context->pending_datagrams == 0 &&
  61. vmci_handle_arr_get_size(context->pending_doorbell_array) == 0)
  62. ctx_clear_notify(context);
  63. }
  64. /*
  65. * Sets the context's notify flag iff datagrams are pending for this
  66. * context. Called from vmci_setup_notify().
  67. */
  68. void vmci_ctx_check_signal_notify(struct vmci_ctx *context)
  69. {
  70. spin_lock(&context->lock);
  71. if (context->pending_datagrams)
  72. ctx_signal_notify(context);
  73. spin_unlock(&context->lock);
  74. }
  75. /*
  76. * Allocates and initializes a VMCI context.
  77. */
  78. struct vmci_ctx *vmci_ctx_create(u32 cid, u32 priv_flags,
  79. uintptr_t event_hnd,
  80. int user_version,
  81. const struct cred *cred)
  82. {
  83. struct vmci_ctx *context;
  84. int error;
  85. if (cid == VMCI_INVALID_ID) {
  86. pr_devel("Invalid context ID for VMCI context\n");
  87. error = -EINVAL;
  88. goto err_out;
  89. }
  90. if (priv_flags & ~VMCI_PRIVILEGE_ALL_FLAGS) {
  91. pr_devel("Invalid flag (flags=0x%x) for VMCI context\n",
  92. priv_flags);
  93. error = -EINVAL;
  94. goto err_out;
  95. }
  96. if (user_version == 0) {
  97. pr_devel("Invalid suer_version %d\n", user_version);
  98. error = -EINVAL;
  99. goto err_out;
  100. }
  101. context = kzalloc(sizeof(*context), GFP_KERNEL);
  102. if (!context) {
  103. pr_warn("Failed to allocate memory for VMCI context\n");
  104. error = -EINVAL;
  105. goto err_out;
  106. }
  107. kref_init(&context->kref);
  108. spin_lock_init(&context->lock);
  109. INIT_LIST_HEAD(&context->list_item);
  110. INIT_LIST_HEAD(&context->datagram_queue);
  111. INIT_LIST_HEAD(&context->notifier_list);
  112. /* Initialize host-specific VMCI context. */
  113. init_waitqueue_head(&context->host_context.wait_queue);
  114. context->queue_pair_array =
  115. vmci_handle_arr_create(0, VMCI_MAX_GUEST_QP_COUNT);
  116. if (!context->queue_pair_array) {
  117. error = -ENOMEM;
  118. goto err_free_ctx;
  119. }
  120. context->doorbell_array =
  121. vmci_handle_arr_create(0, VMCI_MAX_GUEST_DOORBELL_COUNT);
  122. if (!context->doorbell_array) {
  123. error = -ENOMEM;
  124. goto err_free_qp_array;
  125. }
  126. context->pending_doorbell_array =
  127. vmci_handle_arr_create(0, VMCI_MAX_GUEST_DOORBELL_COUNT);
  128. if (!context->pending_doorbell_array) {
  129. error = -ENOMEM;
  130. goto err_free_db_array;
  131. }
  132. context->user_version = user_version;
  133. context->priv_flags = priv_flags;
  134. if (cred)
  135. context->cred = get_cred(cred);
  136. context->notify = &ctx_dummy_notify;
  137. context->notify_page = NULL;
  138. /*
  139. * If we collide with an existing context we generate a new
  140. * and use it instead. The VMX will determine if regeneration
  141. * is okay. Since there isn't 4B - 16 VMs running on a given
  142. * host, the below loop will terminate.
  143. */
  144. spin_lock(&ctx_list.lock);
  145. while (vmci_ctx_exists(cid)) {
  146. /* We reserve the lowest 16 ids for fixed contexts. */
  147. cid = max(cid, VMCI_RESERVED_CID_LIMIT - 1) + 1;
  148. if (cid == VMCI_INVALID_ID)
  149. cid = VMCI_RESERVED_CID_LIMIT;
  150. }
  151. context->cid = cid;
  152. list_add_tail_rcu(&context->list_item, &ctx_list.head);
  153. spin_unlock(&ctx_list.lock);
  154. return context;
  155. err_free_db_array:
  156. vmci_handle_arr_destroy(context->doorbell_array);
  157. err_free_qp_array:
  158. vmci_handle_arr_destroy(context->queue_pair_array);
  159. err_free_ctx:
  160. kfree(context);
  161. err_out:
  162. return ERR_PTR(error);
  163. }
  164. /*
  165. * Destroy VMCI context.
  166. */
  167. void vmci_ctx_destroy(struct vmci_ctx *context)
  168. {
  169. spin_lock(&ctx_list.lock);
  170. list_del_rcu(&context->list_item);
  171. spin_unlock(&ctx_list.lock);
  172. synchronize_rcu();
  173. vmci_ctx_put(context);
  174. }
  175. /*
  176. * Fire notification for all contexts interested in given cid.
  177. */
  178. static int ctx_fire_notification(u32 context_id, u32 priv_flags)
  179. {
  180. u32 i, array_size;
  181. struct vmci_ctx *sub_ctx;
  182. struct vmci_handle_arr *subscriber_array;
  183. struct vmci_handle context_handle =
  184. vmci_make_handle(context_id, VMCI_EVENT_HANDLER);
  185. /*
  186. * We create an array to hold the subscribers we find when
  187. * scanning through all contexts.
  188. */
  189. subscriber_array = vmci_handle_arr_create(0, VMCI_MAX_CONTEXTS);
  190. if (subscriber_array == NULL)
  191. return VMCI_ERROR_NO_MEM;
  192. /*
  193. * Scan all contexts to find who is interested in being
  194. * notified about given contextID.
  195. */
  196. rcu_read_lock();
  197. list_for_each_entry_rcu(sub_ctx, &ctx_list.head, list_item) {
  198. struct vmci_handle_list *node;
  199. /*
  200. * We only deliver notifications of the removal of
  201. * contexts, if the two contexts are allowed to
  202. * interact.
  203. */
  204. if (vmci_deny_interaction(priv_flags, sub_ctx->priv_flags))
  205. continue;
  206. list_for_each_entry_rcu(node, &sub_ctx->notifier_list, node) {
  207. if (!vmci_handle_is_equal(node->handle, context_handle))
  208. continue;
  209. vmci_handle_arr_append_entry(&subscriber_array,
  210. vmci_make_handle(sub_ctx->cid,
  211. VMCI_EVENT_HANDLER));
  212. }
  213. }
  214. rcu_read_unlock();
  215. /* Fire event to all subscribers. */
  216. array_size = vmci_handle_arr_get_size(subscriber_array);
  217. for (i = 0; i < array_size; i++) {
  218. int result;
  219. struct vmci_event_ctx ev;
  220. ev.msg.hdr.dst = vmci_handle_arr_get_entry(subscriber_array, i);
  221. ev.msg.hdr.src = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID,
  222. VMCI_CONTEXT_RESOURCE_ID);
  223. ev.msg.hdr.payload_size = sizeof(ev) - sizeof(ev.msg.hdr);
  224. ev.msg.event_data.event = VMCI_EVENT_CTX_REMOVED;
  225. ev.payload.context_id = context_id;
  226. result = vmci_datagram_dispatch(VMCI_HYPERVISOR_CONTEXT_ID,
  227. &ev.msg.hdr, false);
  228. if (result < VMCI_SUCCESS) {
  229. pr_devel("Failed to enqueue event datagram (type=%d) for context (ID=0x%x)\n",
  230. ev.msg.event_data.event,
  231. ev.msg.hdr.dst.context);
  232. /* We continue to enqueue on next subscriber. */
  233. }
  234. }
  235. vmci_handle_arr_destroy(subscriber_array);
  236. return VMCI_SUCCESS;
  237. }
  238. /*
  239. * Returns the current number of pending datagrams. The call may
  240. * also serve as a synchronization point for the datagram queue,
  241. * as no enqueue operations can occur concurrently.
  242. */
  243. int vmci_ctx_pending_datagrams(u32 cid, u32 *pending)
  244. {
  245. struct vmci_ctx *context;
  246. context = vmci_ctx_get(cid);
  247. if (context == NULL)
  248. return VMCI_ERROR_INVALID_ARGS;
  249. spin_lock(&context->lock);
  250. if (pending)
  251. *pending = context->pending_datagrams;
  252. spin_unlock(&context->lock);
  253. vmci_ctx_put(context);
  254. return VMCI_SUCCESS;
  255. }
  256. /*
  257. * Queues a VMCI datagram for the appropriate target VM context.
  258. */
  259. int vmci_ctx_enqueue_datagram(u32 cid, struct vmci_datagram *dg)
  260. {
  261. struct vmci_datagram_queue_entry *dq_entry;
  262. struct vmci_ctx *context;
  263. struct vmci_handle dg_src;
  264. size_t vmci_dg_size;
  265. vmci_dg_size = VMCI_DG_SIZE(dg);
  266. if (vmci_dg_size > VMCI_MAX_DG_SIZE) {
  267. pr_devel("Datagram too large (bytes=%zu)\n", vmci_dg_size);
  268. return VMCI_ERROR_INVALID_ARGS;
  269. }
  270. /* Get the target VM's VMCI context. */
  271. context = vmci_ctx_get(cid);
  272. if (!context) {
  273. pr_devel("Invalid context (ID=0x%x)\n", cid);
  274. return VMCI_ERROR_INVALID_ARGS;
  275. }
  276. /* Allocate guest call entry and add it to the target VM's queue. */
  277. dq_entry = kmalloc(sizeof(*dq_entry), GFP_KERNEL);
  278. if (dq_entry == NULL) {
  279. pr_warn("Failed to allocate memory for datagram\n");
  280. vmci_ctx_put(context);
  281. return VMCI_ERROR_NO_MEM;
  282. }
  283. dq_entry->dg = dg;
  284. dq_entry->dg_size = vmci_dg_size;
  285. dg_src = dg->src;
  286. INIT_LIST_HEAD(&dq_entry->list_item);
  287. spin_lock(&context->lock);
  288. /*
  289. * We put a higher limit on datagrams from the hypervisor. If
  290. * the pending datagram is not from hypervisor, then we check
  291. * if enqueueing it would exceed the
  292. * VMCI_MAX_DATAGRAM_QUEUE_SIZE limit on the destination. If
  293. * the pending datagram is from hypervisor, we allow it to be
  294. * queued at the destination side provided we don't reach the
  295. * VMCI_MAX_DATAGRAM_AND_EVENT_QUEUE_SIZE limit.
  296. */
  297. if (context->datagram_queue_size + vmci_dg_size >=
  298. VMCI_MAX_DATAGRAM_QUEUE_SIZE &&
  299. (!vmci_handle_is_equal(dg_src,
  300. vmci_make_handle
  301. (VMCI_HYPERVISOR_CONTEXT_ID,
  302. VMCI_CONTEXT_RESOURCE_ID)) ||
  303. context->datagram_queue_size + vmci_dg_size >=
  304. VMCI_MAX_DATAGRAM_AND_EVENT_QUEUE_SIZE)) {
  305. spin_unlock(&context->lock);
  306. vmci_ctx_put(context);
  307. kfree(dq_entry);
  308. pr_devel("Context (ID=0x%x) receive queue is full\n", cid);
  309. return VMCI_ERROR_NO_RESOURCES;
  310. }
  311. list_add(&dq_entry->list_item, &context->datagram_queue);
  312. context->pending_datagrams++;
  313. context->datagram_queue_size += vmci_dg_size;
  314. ctx_signal_notify(context);
  315. wake_up(&context->host_context.wait_queue);
  316. spin_unlock(&context->lock);
  317. vmci_ctx_put(context);
  318. return vmci_dg_size;
  319. }
  320. /*
  321. * Verifies whether a context with the specified context ID exists.
  322. * FIXME: utility is dubious as no decisions can be reliably made
  323. * using this data as context can appear and disappear at any time.
  324. */
  325. bool vmci_ctx_exists(u32 cid)
  326. {
  327. struct vmci_ctx *context;
  328. bool exists = false;
  329. rcu_read_lock();
  330. list_for_each_entry_rcu(context, &ctx_list.head, list_item) {
  331. if (context->cid == cid) {
  332. exists = true;
  333. break;
  334. }
  335. }
  336. rcu_read_unlock();
  337. return exists;
  338. }
  339. /*
  340. * Retrieves VMCI context corresponding to the given cid.
  341. */
  342. struct vmci_ctx *vmci_ctx_get(u32 cid)
  343. {
  344. struct vmci_ctx *c, *context = NULL;
  345. if (cid == VMCI_INVALID_ID)
  346. return NULL;
  347. rcu_read_lock();
  348. list_for_each_entry_rcu(c, &ctx_list.head, list_item) {
  349. if (c->cid == cid) {
  350. /*
  351. * The context owner drops its own reference to the
  352. * context only after removing it from the list and
  353. * waiting for RCU grace period to expire. This
  354. * means that we are not about to increase the
  355. * reference count of something that is in the
  356. * process of being destroyed.
  357. */
  358. context = c;
  359. kref_get(&context->kref);
  360. break;
  361. }
  362. }
  363. rcu_read_unlock();
  364. return context;
  365. }
  366. /*
  367. * Deallocates all parts of a context data structure. This
  368. * function doesn't lock the context, because it assumes that
  369. * the caller was holding the last reference to context.
  370. */
  371. static void ctx_free_ctx(struct kref *kref)
  372. {
  373. struct vmci_ctx *context = container_of(kref, struct vmci_ctx, kref);
  374. struct vmci_datagram_queue_entry *dq_entry, *dq_entry_tmp;
  375. struct vmci_handle temp_handle;
  376. struct vmci_handle_list *notifier, *tmp;
  377. /*
  378. * Fire event to all contexts interested in knowing this
  379. * context is dying.
  380. */
  381. ctx_fire_notification(context->cid, context->priv_flags);
  382. /*
  383. * Cleanup all queue pair resources attached to context. If
  384. * the VM dies without cleaning up, this code will make sure
  385. * that no resources are leaked.
  386. */
  387. temp_handle = vmci_handle_arr_get_entry(context->queue_pair_array, 0);
  388. while (!vmci_handle_is_equal(temp_handle, VMCI_INVALID_HANDLE)) {
  389. if (vmci_qp_broker_detach(temp_handle,
  390. context) < VMCI_SUCCESS) {
  391. /*
  392. * When vmci_qp_broker_detach() succeeds it
  393. * removes the handle from the array. If
  394. * detach fails, we must remove the handle
  395. * ourselves.
  396. */
  397. vmci_handle_arr_remove_entry(context->queue_pair_array,
  398. temp_handle);
  399. }
  400. temp_handle =
  401. vmci_handle_arr_get_entry(context->queue_pair_array, 0);
  402. }
  403. /*
  404. * It is fine to destroy this without locking the callQueue, as
  405. * this is the only thread having a reference to the context.
  406. */
  407. list_for_each_entry_safe(dq_entry, dq_entry_tmp,
  408. &context->datagram_queue, list_item) {
  409. WARN_ON(dq_entry->dg_size != VMCI_DG_SIZE(dq_entry->dg));
  410. list_del(&dq_entry->list_item);
  411. kfree(dq_entry->dg);
  412. kfree(dq_entry);
  413. }
  414. list_for_each_entry_safe(notifier, tmp,
  415. &context->notifier_list, node) {
  416. list_del(&notifier->node);
  417. kfree(notifier);
  418. }
  419. vmci_handle_arr_destroy(context->queue_pair_array);
  420. vmci_handle_arr_destroy(context->doorbell_array);
  421. vmci_handle_arr_destroy(context->pending_doorbell_array);
  422. vmci_ctx_unset_notify(context);
  423. if (context->cred)
  424. put_cred(context->cred);
  425. kfree(context);
  426. }
  427. /*
  428. * Drops reference to VMCI context. If this is the last reference to
  429. * the context it will be deallocated. A context is created with
  430. * a reference count of one, and on destroy, it is removed from
  431. * the context list before its reference count is decremented. Thus,
  432. * if we reach zero, we are sure that nobody else are about to increment
  433. * it (they need the entry in the context list for that), and so there
  434. * is no need for locking.
  435. */
  436. void vmci_ctx_put(struct vmci_ctx *context)
  437. {
  438. kref_put(&context->kref, ctx_free_ctx);
  439. }
  440. /*
  441. * Dequeues the next datagram and returns it to caller.
  442. * The caller passes in a pointer to the max size datagram
  443. * it can handle and the datagram is only unqueued if the
  444. * size is less than max_size. If larger max_size is set to
  445. * the size of the datagram to give the caller a chance to
  446. * set up a larger buffer for the guestcall.
  447. */
  448. int vmci_ctx_dequeue_datagram(struct vmci_ctx *context,
  449. size_t *max_size,
  450. struct vmci_datagram **dg)
  451. {
  452. struct vmci_datagram_queue_entry *dq_entry;
  453. struct list_head *list_item;
  454. int rv;
  455. /* Dequeue the next datagram entry. */
  456. spin_lock(&context->lock);
  457. if (context->pending_datagrams == 0) {
  458. ctx_clear_notify_call(context);
  459. spin_unlock(&context->lock);
  460. pr_devel("No datagrams pending\n");
  461. return VMCI_ERROR_NO_MORE_DATAGRAMS;
  462. }
  463. list_item = context->datagram_queue.next;
  464. dq_entry =
  465. list_entry(list_item, struct vmci_datagram_queue_entry, list_item);
  466. /* Check size of caller's buffer. */
  467. if (*max_size < dq_entry->dg_size) {
  468. *max_size = dq_entry->dg_size;
  469. spin_unlock(&context->lock);
  470. pr_devel("Caller's buffer should be at least (size=%u bytes)\n",
  471. (u32) *max_size);
  472. return VMCI_ERROR_NO_MEM;
  473. }
  474. list_del(list_item);
  475. context->pending_datagrams--;
  476. context->datagram_queue_size -= dq_entry->dg_size;
  477. if (context->pending_datagrams == 0) {
  478. ctx_clear_notify_call(context);
  479. rv = VMCI_SUCCESS;
  480. } else {
  481. /*
  482. * Return the size of the next datagram.
  483. */
  484. struct vmci_datagram_queue_entry *next_entry;
  485. list_item = context->datagram_queue.next;
  486. next_entry =
  487. list_entry(list_item, struct vmci_datagram_queue_entry,
  488. list_item);
  489. /*
  490. * The following size_t -> int truncation is fine as
  491. * the maximum size of a (routable) datagram is 68KB.
  492. */
  493. rv = (int)next_entry->dg_size;
  494. }
  495. spin_unlock(&context->lock);
  496. /* Caller must free datagram. */
  497. *dg = dq_entry->dg;
  498. dq_entry->dg = NULL;
  499. kfree(dq_entry);
  500. return rv;
  501. }
  502. /*
  503. * Reverts actions set up by vmci_setup_notify(). Unmaps and unlocks the
  504. * page mapped/locked by vmci_setup_notify().
  505. */
  506. void vmci_ctx_unset_notify(struct vmci_ctx *context)
  507. {
  508. struct page *notify_page;
  509. spin_lock(&context->lock);
  510. notify_page = context->notify_page;
  511. context->notify = &ctx_dummy_notify;
  512. context->notify_page = NULL;
  513. spin_unlock(&context->lock);
  514. if (notify_page) {
  515. kunmap(notify_page);
  516. put_page(notify_page);
  517. }
  518. }
  519. /*
  520. * Add remote_cid to list of contexts current contexts wants
  521. * notifications from/about.
  522. */
  523. int vmci_ctx_add_notification(u32 context_id, u32 remote_cid)
  524. {
  525. struct vmci_ctx *context;
  526. struct vmci_handle_list *notifier, *n;
  527. int result;
  528. bool exists = false;
  529. context = vmci_ctx_get(context_id);
  530. if (!context)
  531. return VMCI_ERROR_NOT_FOUND;
  532. if (VMCI_CONTEXT_IS_VM(context_id) && VMCI_CONTEXT_IS_VM(remote_cid)) {
  533. pr_devel("Context removed notifications for other VMs not supported (src=0x%x, remote=0x%x)\n",
  534. context_id, remote_cid);
  535. result = VMCI_ERROR_DST_UNREACHABLE;
  536. goto out;
  537. }
  538. if (context->priv_flags & VMCI_PRIVILEGE_FLAG_RESTRICTED) {
  539. result = VMCI_ERROR_NO_ACCESS;
  540. goto out;
  541. }
  542. notifier = kmalloc(sizeof(struct vmci_handle_list), GFP_KERNEL);
  543. if (!notifier) {
  544. result = VMCI_ERROR_NO_MEM;
  545. goto out;
  546. }
  547. INIT_LIST_HEAD(&notifier->node);
  548. notifier->handle = vmci_make_handle(remote_cid, VMCI_EVENT_HANDLER);
  549. spin_lock(&context->lock);
  550. if (context->n_notifiers < VMCI_MAX_CONTEXTS) {
  551. list_for_each_entry(n, &context->notifier_list, node) {
  552. if (vmci_handle_is_equal(n->handle, notifier->handle)) {
  553. exists = true;
  554. break;
  555. }
  556. }
  557. if (exists) {
  558. kfree(notifier);
  559. result = VMCI_ERROR_ALREADY_EXISTS;
  560. } else {
  561. list_add_tail_rcu(&notifier->node,
  562. &context->notifier_list);
  563. context->n_notifiers++;
  564. result = VMCI_SUCCESS;
  565. }
  566. } else {
  567. kfree(notifier);
  568. result = VMCI_ERROR_NO_MEM;
  569. }
  570. spin_unlock(&context->lock);
  571. out:
  572. vmci_ctx_put(context);
  573. return result;
  574. }
  575. /*
  576. * Remove remote_cid from current context's list of contexts it is
  577. * interested in getting notifications from/about.
  578. */
  579. int vmci_ctx_remove_notification(u32 context_id, u32 remote_cid)
  580. {
  581. struct vmci_ctx *context;
  582. struct vmci_handle_list *notifier, *tmp;
  583. struct vmci_handle handle;
  584. bool found = false;
  585. context = vmci_ctx_get(context_id);
  586. if (!context)
  587. return VMCI_ERROR_NOT_FOUND;
  588. handle = vmci_make_handle(remote_cid, VMCI_EVENT_HANDLER);
  589. spin_lock(&context->lock);
  590. list_for_each_entry_safe(notifier, tmp,
  591. &context->notifier_list, node) {
  592. if (vmci_handle_is_equal(notifier->handle, handle)) {
  593. list_del_rcu(&notifier->node);
  594. context->n_notifiers--;
  595. found = true;
  596. break;
  597. }
  598. }
  599. spin_unlock(&context->lock);
  600. if (found) {
  601. synchronize_rcu();
  602. kfree(notifier);
  603. }
  604. vmci_ctx_put(context);
  605. return found ? VMCI_SUCCESS : VMCI_ERROR_NOT_FOUND;
  606. }
  607. static int vmci_ctx_get_chkpt_notifiers(struct vmci_ctx *context,
  608. u32 *buf_size, void **pbuf)
  609. {
  610. u32 *notifiers;
  611. size_t data_size;
  612. struct vmci_handle_list *entry;
  613. int i = 0;
  614. if (context->n_notifiers == 0) {
  615. *buf_size = 0;
  616. *pbuf = NULL;
  617. return VMCI_SUCCESS;
  618. }
  619. data_size = context->n_notifiers * sizeof(*notifiers);
  620. if (*buf_size < data_size) {
  621. *buf_size = data_size;
  622. return VMCI_ERROR_MORE_DATA;
  623. }
  624. notifiers = kmalloc(data_size, GFP_ATOMIC); /* FIXME: want GFP_KERNEL */
  625. if (!notifiers)
  626. return VMCI_ERROR_NO_MEM;
  627. list_for_each_entry(entry, &context->notifier_list, node)
  628. notifiers[i++] = entry->handle.context;
  629. *buf_size = data_size;
  630. *pbuf = notifiers;
  631. return VMCI_SUCCESS;
  632. }
  633. static int vmci_ctx_get_chkpt_doorbells(struct vmci_ctx *context,
  634. u32 *buf_size, void **pbuf)
  635. {
  636. struct dbell_cpt_state *dbells;
  637. u32 i, n_doorbells;
  638. n_doorbells = vmci_handle_arr_get_size(context->doorbell_array);
  639. if (n_doorbells > 0) {
  640. size_t data_size = n_doorbells * sizeof(*dbells);
  641. if (*buf_size < data_size) {
  642. *buf_size = data_size;
  643. return VMCI_ERROR_MORE_DATA;
  644. }
  645. dbells = kzalloc(data_size, GFP_ATOMIC);
  646. if (!dbells)
  647. return VMCI_ERROR_NO_MEM;
  648. for (i = 0; i < n_doorbells; i++)
  649. dbells[i].handle = vmci_handle_arr_get_entry(
  650. context->doorbell_array, i);
  651. *buf_size = data_size;
  652. *pbuf = dbells;
  653. } else {
  654. *buf_size = 0;
  655. *pbuf = NULL;
  656. }
  657. return VMCI_SUCCESS;
  658. }
  659. /*
  660. * Get current context's checkpoint state of given type.
  661. */
  662. int vmci_ctx_get_chkpt_state(u32 context_id,
  663. u32 cpt_type,
  664. u32 *buf_size,
  665. void **pbuf)
  666. {
  667. struct vmci_ctx *context;
  668. int result;
  669. context = vmci_ctx_get(context_id);
  670. if (!context)
  671. return VMCI_ERROR_NOT_FOUND;
  672. spin_lock(&context->lock);
  673. switch (cpt_type) {
  674. case VMCI_NOTIFICATION_CPT_STATE:
  675. result = vmci_ctx_get_chkpt_notifiers(context, buf_size, pbuf);
  676. break;
  677. case VMCI_WELLKNOWN_CPT_STATE:
  678. /*
  679. * For compatibility with VMX'en with VM to VM communication, we
  680. * always return zero wellknown handles.
  681. */
  682. *buf_size = 0;
  683. *pbuf = NULL;
  684. result = VMCI_SUCCESS;
  685. break;
  686. case VMCI_DOORBELL_CPT_STATE:
  687. result = vmci_ctx_get_chkpt_doorbells(context, buf_size, pbuf);
  688. break;
  689. default:
  690. pr_devel("Invalid cpt state (type=%d)\n", cpt_type);
  691. result = VMCI_ERROR_INVALID_ARGS;
  692. break;
  693. }
  694. spin_unlock(&context->lock);
  695. vmci_ctx_put(context);
  696. return result;
  697. }
  698. /*
  699. * Set current context's checkpoint state of given type.
  700. */
  701. int vmci_ctx_set_chkpt_state(u32 context_id,
  702. u32 cpt_type,
  703. u32 buf_size,
  704. void *cpt_buf)
  705. {
  706. u32 i;
  707. u32 current_id;
  708. int result = VMCI_SUCCESS;
  709. u32 num_ids = buf_size / sizeof(u32);
  710. if (cpt_type == VMCI_WELLKNOWN_CPT_STATE && num_ids > 0) {
  711. /*
  712. * We would end up here if VMX with VM to VM communication
  713. * attempts to restore a checkpoint with wellknown handles.
  714. */
  715. pr_warn("Attempt to restore checkpoint with obsolete wellknown handles\n");
  716. return VMCI_ERROR_OBSOLETE;
  717. }
  718. if (cpt_type != VMCI_NOTIFICATION_CPT_STATE) {
  719. pr_devel("Invalid cpt state (type=%d)\n", cpt_type);
  720. return VMCI_ERROR_INVALID_ARGS;
  721. }
  722. for (i = 0; i < num_ids && result == VMCI_SUCCESS; i++) {
  723. current_id = ((u32 *)cpt_buf)[i];
  724. result = vmci_ctx_add_notification(context_id, current_id);
  725. if (result != VMCI_SUCCESS)
  726. break;
  727. }
  728. if (result != VMCI_SUCCESS)
  729. pr_devel("Failed to set cpt state (type=%d) (error=%d)\n",
  730. cpt_type, result);
  731. return result;
  732. }
  733. /*
  734. * Retrieves the specified context's pending notifications in the
  735. * form of a handle array. The handle arrays returned are the
  736. * actual data - not a copy and should not be modified by the
  737. * caller. They must be released using
  738. * vmci_ctx_rcv_notifications_release.
  739. */
  740. int vmci_ctx_rcv_notifications_get(u32 context_id,
  741. struct vmci_handle_arr **db_handle_array,
  742. struct vmci_handle_arr **qp_handle_array)
  743. {
  744. struct vmci_ctx *context;
  745. int result = VMCI_SUCCESS;
  746. context = vmci_ctx_get(context_id);
  747. if (context == NULL)
  748. return VMCI_ERROR_NOT_FOUND;
  749. spin_lock(&context->lock);
  750. *db_handle_array = context->pending_doorbell_array;
  751. context->pending_doorbell_array =
  752. vmci_handle_arr_create(0, VMCI_MAX_GUEST_DOORBELL_COUNT);
  753. if (!context->pending_doorbell_array) {
  754. context->pending_doorbell_array = *db_handle_array;
  755. *db_handle_array = NULL;
  756. result = VMCI_ERROR_NO_MEM;
  757. }
  758. *qp_handle_array = NULL;
  759. spin_unlock(&context->lock);
  760. vmci_ctx_put(context);
  761. return result;
  762. }
  763. /*
  764. * Releases handle arrays with pending notifications previously
  765. * retrieved using vmci_ctx_rcv_notifications_get. If the
  766. * notifications were not successfully handed over to the guest,
  767. * success must be false.
  768. */
  769. void vmci_ctx_rcv_notifications_release(u32 context_id,
  770. struct vmci_handle_arr *db_handle_array,
  771. struct vmci_handle_arr *qp_handle_array,
  772. bool success)
  773. {
  774. struct vmci_ctx *context = vmci_ctx_get(context_id);
  775. spin_lock(&context->lock);
  776. if (!success) {
  777. struct vmci_handle handle;
  778. /*
  779. * New notifications may have been added while we were not
  780. * holding the context lock, so we transfer any new pending
  781. * doorbell notifications to the old array, and reinstate the
  782. * old array.
  783. */
  784. handle = vmci_handle_arr_remove_tail(
  785. context->pending_doorbell_array);
  786. while (!vmci_handle_is_invalid(handle)) {
  787. if (!vmci_handle_arr_has_entry(db_handle_array,
  788. handle)) {
  789. vmci_handle_arr_append_entry(
  790. &db_handle_array, handle);
  791. }
  792. handle = vmci_handle_arr_remove_tail(
  793. context->pending_doorbell_array);
  794. }
  795. vmci_handle_arr_destroy(context->pending_doorbell_array);
  796. context->pending_doorbell_array = db_handle_array;
  797. db_handle_array = NULL;
  798. } else {
  799. ctx_clear_notify_call(context);
  800. }
  801. spin_unlock(&context->lock);
  802. vmci_ctx_put(context);
  803. if (db_handle_array)
  804. vmci_handle_arr_destroy(db_handle_array);
  805. if (qp_handle_array)
  806. vmci_handle_arr_destroy(qp_handle_array);
  807. }
  808. /*
  809. * Registers that a new doorbell handle has been allocated by the
  810. * context. Only doorbell handles registered can be notified.
  811. */
  812. int vmci_ctx_dbell_create(u32 context_id, struct vmci_handle handle)
  813. {
  814. struct vmci_ctx *context;
  815. int result;
  816. if (context_id == VMCI_INVALID_ID || vmci_handle_is_invalid(handle))
  817. return VMCI_ERROR_INVALID_ARGS;
  818. context = vmci_ctx_get(context_id);
  819. if (context == NULL)
  820. return VMCI_ERROR_NOT_FOUND;
  821. spin_lock(&context->lock);
  822. if (!vmci_handle_arr_has_entry(context->doorbell_array, handle))
  823. result = vmci_handle_arr_append_entry(&context->doorbell_array,
  824. handle);
  825. else
  826. result = VMCI_ERROR_DUPLICATE_ENTRY;
  827. spin_unlock(&context->lock);
  828. vmci_ctx_put(context);
  829. return result;
  830. }
  831. /*
  832. * Unregisters a doorbell handle that was previously registered
  833. * with vmci_ctx_dbell_create.
  834. */
  835. int vmci_ctx_dbell_destroy(u32 context_id, struct vmci_handle handle)
  836. {
  837. struct vmci_ctx *context;
  838. struct vmci_handle removed_handle;
  839. if (context_id == VMCI_INVALID_ID || vmci_handle_is_invalid(handle))
  840. return VMCI_ERROR_INVALID_ARGS;
  841. context = vmci_ctx_get(context_id);
  842. if (context == NULL)
  843. return VMCI_ERROR_NOT_FOUND;
  844. spin_lock(&context->lock);
  845. removed_handle =
  846. vmci_handle_arr_remove_entry(context->doorbell_array, handle);
  847. vmci_handle_arr_remove_entry(context->pending_doorbell_array, handle);
  848. spin_unlock(&context->lock);
  849. vmci_ctx_put(context);
  850. return vmci_handle_is_invalid(removed_handle) ?
  851. VMCI_ERROR_NOT_FOUND : VMCI_SUCCESS;
  852. }
  853. /*
  854. * Unregisters all doorbell handles that were previously
  855. * registered with vmci_ctx_dbell_create.
  856. */
  857. int vmci_ctx_dbell_destroy_all(u32 context_id)
  858. {
  859. struct vmci_ctx *context;
  860. struct vmci_handle handle;
  861. if (context_id == VMCI_INVALID_ID)
  862. return VMCI_ERROR_INVALID_ARGS;
  863. context = vmci_ctx_get(context_id);
  864. if (context == NULL)
  865. return VMCI_ERROR_NOT_FOUND;
  866. spin_lock(&context->lock);
  867. do {
  868. struct vmci_handle_arr *arr = context->doorbell_array;
  869. handle = vmci_handle_arr_remove_tail(arr);
  870. } while (!vmci_handle_is_invalid(handle));
  871. do {
  872. struct vmci_handle_arr *arr = context->pending_doorbell_array;
  873. handle = vmci_handle_arr_remove_tail(arr);
  874. } while (!vmci_handle_is_invalid(handle));
  875. spin_unlock(&context->lock);
  876. vmci_ctx_put(context);
  877. return VMCI_SUCCESS;
  878. }
  879. /*
  880. * Registers a notification of a doorbell handle initiated by the
  881. * specified source context. The notification of doorbells are
  882. * subject to the same isolation rules as datagram delivery. To
  883. * allow host side senders of notifications a finer granularity
  884. * of sender rights than those assigned to the sending context
  885. * itself, the host context is required to specify a different
  886. * set of privilege flags that will override the privileges of
  887. * the source context.
  888. */
  889. int vmci_ctx_notify_dbell(u32 src_cid,
  890. struct vmci_handle handle,
  891. u32 src_priv_flags)
  892. {
  893. struct vmci_ctx *dst_context;
  894. int result;
  895. if (vmci_handle_is_invalid(handle))
  896. return VMCI_ERROR_INVALID_ARGS;
  897. /* Get the target VM's VMCI context. */
  898. dst_context = vmci_ctx_get(handle.context);
  899. if (!dst_context) {
  900. pr_devel("Invalid context (ID=0x%x)\n", handle.context);
  901. return VMCI_ERROR_NOT_FOUND;
  902. }
  903. if (src_cid != handle.context) {
  904. u32 dst_priv_flags;
  905. if (VMCI_CONTEXT_IS_VM(src_cid) &&
  906. VMCI_CONTEXT_IS_VM(handle.context)) {
  907. pr_devel("Doorbell notification from VM to VM not supported (src=0x%x, dst=0x%x)\n",
  908. src_cid, handle.context);
  909. result = VMCI_ERROR_DST_UNREACHABLE;
  910. goto out;
  911. }
  912. result = vmci_dbell_get_priv_flags(handle, &dst_priv_flags);
  913. if (result < VMCI_SUCCESS) {
  914. pr_warn("Failed to get privilege flags for destination (handle=0x%x:0x%x)\n",
  915. handle.context, handle.resource);
  916. goto out;
  917. }
  918. if (src_cid != VMCI_HOST_CONTEXT_ID ||
  919. src_priv_flags == VMCI_NO_PRIVILEGE_FLAGS) {
  920. src_priv_flags = vmci_context_get_priv_flags(src_cid);
  921. }
  922. if (vmci_deny_interaction(src_priv_flags, dst_priv_flags)) {
  923. result = VMCI_ERROR_NO_ACCESS;
  924. goto out;
  925. }
  926. }
  927. if (handle.context == VMCI_HOST_CONTEXT_ID) {
  928. result = vmci_dbell_host_context_notify(src_cid, handle);
  929. } else {
  930. spin_lock(&dst_context->lock);
  931. if (!vmci_handle_arr_has_entry(dst_context->doorbell_array,
  932. handle)) {
  933. result = VMCI_ERROR_NOT_FOUND;
  934. } else {
  935. if (!vmci_handle_arr_has_entry(
  936. dst_context->pending_doorbell_array,
  937. handle)) {
  938. result = vmci_handle_arr_append_entry(
  939. &dst_context->pending_doorbell_array,
  940. handle);
  941. if (result == VMCI_SUCCESS) {
  942. ctx_signal_notify(dst_context);
  943. wake_up(&dst_context->host_context.wait_queue);
  944. }
  945. } else {
  946. result = VMCI_SUCCESS;
  947. }
  948. }
  949. spin_unlock(&dst_context->lock);
  950. }
  951. out:
  952. vmci_ctx_put(dst_context);
  953. return result;
  954. }
  955. bool vmci_ctx_supports_host_qp(struct vmci_ctx *context)
  956. {
  957. return context && context->user_version >= VMCI_VERSION_HOSTQP;
  958. }
  959. /*
  960. * Registers that a new queue pair handle has been allocated by
  961. * the context.
  962. */
  963. int vmci_ctx_qp_create(struct vmci_ctx *context, struct vmci_handle handle)
  964. {
  965. int result;
  966. if (context == NULL || vmci_handle_is_invalid(handle))
  967. return VMCI_ERROR_INVALID_ARGS;
  968. if (!vmci_handle_arr_has_entry(context->queue_pair_array, handle))
  969. result = vmci_handle_arr_append_entry(
  970. &context->queue_pair_array, handle);
  971. else
  972. result = VMCI_ERROR_DUPLICATE_ENTRY;
  973. return result;
  974. }
  975. /*
  976. * Unregisters a queue pair handle that was previously registered
  977. * with vmci_ctx_qp_create.
  978. */
  979. int vmci_ctx_qp_destroy(struct vmci_ctx *context, struct vmci_handle handle)
  980. {
  981. struct vmci_handle hndl;
  982. if (context == NULL || vmci_handle_is_invalid(handle))
  983. return VMCI_ERROR_INVALID_ARGS;
  984. hndl = vmci_handle_arr_remove_entry(context->queue_pair_array, handle);
  985. return vmci_handle_is_invalid(hndl) ?
  986. VMCI_ERROR_NOT_FOUND : VMCI_SUCCESS;
  987. }
  988. /*
  989. * Determines whether a given queue pair handle is registered
  990. * with the given context.
  991. */
  992. bool vmci_ctx_qp_exists(struct vmci_ctx *context, struct vmci_handle handle)
  993. {
  994. if (context == NULL || vmci_handle_is_invalid(handle))
  995. return false;
  996. return vmci_handle_arr_has_entry(context->queue_pair_array, handle);
  997. }
  998. /*
  999. * vmci_context_get_priv_flags() - Retrieve privilege flags.
  1000. * @context_id: The context ID of the VMCI context.
  1001. *
  1002. * Retrieves privilege flags of the given VMCI context ID.
  1003. */
  1004. u32 vmci_context_get_priv_flags(u32 context_id)
  1005. {
  1006. if (vmci_host_code_active()) {
  1007. u32 flags;
  1008. struct vmci_ctx *context;
  1009. context = vmci_ctx_get(context_id);
  1010. if (!context)
  1011. return VMCI_LEAST_PRIVILEGE_FLAGS;
  1012. flags = context->priv_flags;
  1013. vmci_ctx_put(context);
  1014. return flags;
  1015. }
  1016. return VMCI_NO_PRIVILEGE_FLAGS;
  1017. }
  1018. EXPORT_SYMBOL_GPL(vmci_context_get_priv_flags);
  1019. /*
  1020. * vmci_is_context_owner() - Determimnes if user is the context owner
  1021. * @context_id: The context ID of the VMCI context.
  1022. * @uid: The host user id (real kernel value).
  1023. *
  1024. * Determines whether a given UID is the owner of given VMCI context.
  1025. */
  1026. bool vmci_is_context_owner(u32 context_id, kuid_t uid)
  1027. {
  1028. bool is_owner = false;
  1029. if (vmci_host_code_active()) {
  1030. struct vmci_ctx *context = vmci_ctx_get(context_id);
  1031. if (context) {
  1032. if (context->cred)
  1033. is_owner = uid_eq(context->cred->uid, uid);
  1034. vmci_ctx_put(context);
  1035. }
  1036. }
  1037. return is_owner;
  1038. }
  1039. EXPORT_SYMBOL_GPL(vmci_is_context_owner);