vmci_context.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226
  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);