capability.c 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513
  1. /*
  2. * Copyright (c) 2023 Agustina Arzille.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. */
  18. #include <kern/capability.h>
  19. #include <kern/cspace.h>
  20. #include <kern/intr.h>
  21. #include <kern/kmem.h>
  22. #include <kern/kmessage.h>
  23. #include <kern/rcu.h>
  24. #include <kern/shell.h>
  25. #include <kern/stream.h>
  26. #include <kern/thread.h>
  27. #include <machine/pmap.h>
  28. #include <vm/map.h>
  29. #include <vm/page.h>
  30. #include <stdio.h>
  31. struct cap_alert
  32. {
  33. union
  34. {
  35. struct
  36. { // Valid for user alerts and when not pending.
  37. int task_id;
  38. int thread_id;
  39. uintptr_t tag;
  40. };
  41. struct hlist_node hnode;
  42. };
  43. struct pqueue_node pnode;
  44. union
  45. {
  46. char payload[CAP_ALERT_SIZE];
  47. struct cap_kern_alert k_alert;
  48. };
  49. };
  50. #define CAP_F(name) OFFSETOF (struct ipc_msg_data, name)
  51. static_assert (CAP_F (caps_recv) - CAP_F (bytes_recv) ==
  52. CAP_F (caps_sent) - CAP_F (bytes_sent) &&
  53. CAP_F (vmes_recv) - CAP_F (bytes_recv) ==
  54. CAP_F (vmes_sent) - CAP_F (bytes_sent),
  55. "invalid layout for struct ipc_msg_data");
  56. #define CAP_VMES_OFF (CAP_F (vmes_recv) - CAP_F (bytes_recv))
  57. #define CAP_CAPS_OFF (CAP_F (caps_recv) - CAP_F (bytes_recv))
  58. // An alert as generated by a kernel event (e.g: a task died).
  59. struct cap_alert_async
  60. {
  61. struct cap_alert base;
  62. struct list xlink;
  63. struct cap_flow *flow;
  64. };
  65. /*
  66. * Landing pads represent the environment on which foreign threads begin
  67. * their execution once a message has been sent.
  68. *
  69. * When a thread initiates message passing, a landing pad is added to
  70. * an internal list. Messaging operations update the iterators and
  71. * metadata that is contained within the "current" landing pad.
  72. */
  73. struct cap_lpad
  74. {
  75. struct cap_base *src;
  76. struct cap_lpad *next;
  77. struct task *task;
  78. size_t size;
  79. uintptr_t ctx[3]; // SP and function arguments.
  80. struct ipc_msg_data mdata;
  81. uint16_t nr_cached_iovs;
  82. uint16_t xflags;
  83. struct cap_iters in_it;
  84. struct cap_iters *cur_in;
  85. struct cap_iters *cur_out;
  86. };
  87. // A thread waiting on 'cap_recv_alert'.
  88. struct cap_receiver
  89. {
  90. struct list lnode;
  91. struct thread *thread;
  92. void *buf;
  93. struct ipc_msg_data mdata;
  94. bool spurious;
  95. };
  96. // A thread waiting for a landing pad to be available.
  97. struct cap_sender
  98. {
  99. struct list lnode;
  100. struct thread *thread;
  101. };
  102. static struct kmem_cache cap_flow_cache;
  103. static struct kmem_cache cap_misc_cache;
  104. static struct kmem_cache cap_lpad_cache;
  105. static struct list cap_intr_handlers[CPU_INTR_TABLE_SIZE];
  106. static struct adaptive_lock cap_intr_lock;
  107. // Priorities for kernel-generated alerts.
  108. #define CAP_ALERT_TASK_PRIO ((THREAD_SCHED_RT_PRIO_MAX + 2) << 1)
  109. #define CAP_ALERT_THREAD_PRIO (CAP_ALERT_TASK_PRIO << 1)
  110. #define CAP_ALERT_INTR_PRIO (CAP_ALERT_THREAD_PRIO << 1)
  111. #define CAP_ALERT_CHANNEL_PRIO (1u)
  112. #define CAP_CHANNEL_SHARED 0x01
  113. #define CAP_FROM_SREF(ptr, type) structof (ptr, type, base.sref)
  114. // Forward declarations.
  115. static void cap_recv_wakeup_fast (struct cap_flow *);
  116. static void cap_intr_rem (uint32_t irq, struct list *link);
  117. static void
  118. cap_base_init (struct cap_base *base, uint32_t type, sref_noref_fn_t noref)
  119. {
  120. assert (type < CAP_TYPE_MAX);
  121. base->tflags = ((uintptr_t)type << (sizeof (uintptr_t) * 8 - 8));
  122. sref_counter_init (&base->sref, 1, NULL, noref);
  123. }
  124. static void
  125. cap_task_fini (struct sref_counter *sref)
  126. {
  127. _Auto tp = CAP_FROM_SREF (sref, struct cap_task);
  128. task_unref (tp->task);
  129. kmem_cache_free (&cap_misc_cache, tp);
  130. }
  131. int
  132. cap_task_create (struct cap_task **outp, struct task *task)
  133. {
  134. struct cap_task *ret = kmem_cache_alloc (&cap_misc_cache);
  135. if (! ret)
  136. return (ENOMEM);
  137. cap_base_init (&ret->base, CAP_TYPE_TASK, cap_task_fini);
  138. task_ref (task);
  139. ret->task = task;
  140. *outp = ret;
  141. return (0);
  142. }
  143. static void
  144. cap_thread_fini (struct sref_counter *sref)
  145. {
  146. _Auto tp = CAP_FROM_SREF (sref, struct cap_thread);
  147. thread_unref (tp->thread);
  148. kmem_cache_free (&cap_misc_cache, tp);
  149. }
  150. int
  151. cap_thread_create (struct cap_thread **outp, struct thread *thread)
  152. {
  153. struct cap_thread *ret = kmem_cache_alloc (&cap_misc_cache);
  154. if (! ret)
  155. return (ENOMEM);
  156. cap_base_init (&ret->base, CAP_TYPE_THREAD, cap_thread_fini);
  157. thread_ref (thread);
  158. ret->thread = thread;
  159. *outp = ret;
  160. return (0);
  161. }
  162. static struct spinlock_guard
  163. cap_flow_guard_make (struct cap_flow *flow)
  164. {
  165. bool save_intr = (flow->base.tflags & CAP_FLOW_HANDLE_INTR) != 0;
  166. return (spinlock_guard_make (&flow->alerts.lock, save_intr));
  167. }
  168. #define cap_flow_guard_lock spinlock_guard_lock
  169. #define cap_flow_guard_fini spinlock_guard_fini
  170. #define cap_alert_type(x) \
  171. _Generic ((x), \
  172. struct pqueue_node *: ((const struct pqueue_node *)(x))->extra, \
  173. struct cap_alert *: ((const struct cap_alert *)(x))->pnode.extra)
  174. static void
  175. cap_alert_init_nodes (struct cap_alert *alert, uint32_t type, uint32_t prio)
  176. {
  177. pqueue_node_init (&alert->pnode, prio);
  178. alert->pnode.extra = type;
  179. hlist_node_init (&alert->hnode);
  180. }
  181. #define CAP_FLOW_GUARD(flow) \
  182. CLEANUP (cap_flow_guard_fini) _Auto __unused UNIQ (cfg) = \
  183. cap_flow_guard_make (flow)
  184. static void
  185. cap_channel_fini (struct sref_counter *sref)
  186. {
  187. _Auto chp = CAP_FROM_SREF (sref, struct cap_channel);
  188. _Auto flow = chp->flow;
  189. if (!pqueue_node_unlinked (&chp->pnode))
  190. {
  191. SPINLOCK_GUARD (&flow->alerts.lock);
  192. pqueue_remove (&flow->alerts.pending, &chp->pnode);
  193. }
  194. cap_base_rel (flow);
  195. kmem_cache_free (&cap_misc_cache, chp);
  196. }
  197. int
  198. cap_channel_create (struct cap_channel **outp, struct cap_flow *flow,
  199. uintptr_t tag)
  200. {
  201. struct cap_channel *ret = kmem_cache_alloc (&cap_misc_cache);
  202. if (! ret)
  203. return (ENOMEM);
  204. cap_base_init (&ret->base, CAP_TYPE_CHANNEL, cap_channel_fini);
  205. pqueue_node_init (&ret->pnode, CAP_ALERT_CHANNEL_PRIO);
  206. ret->pnode.extra = CAP_ALERT_CHAN_CLOSED;
  207. if (flow)
  208. cap_base_acq (flow);
  209. ret->flow = flow;
  210. ret->tag = tag;
  211. ret->vmobj = NULL;
  212. ret->open_count = 0;
  213. *outp = ret;
  214. return (0);
  215. }
  216. static void
  217. cap_task_thread_rem (int id, int type, struct list *link)
  218. {
  219. _Auto kuid = kuid_find (id, type == CAP_ALERT_THREAD_DIED ?
  220. KUID_THREAD : KUID_TASK);
  221. #define cap_unlink_alert(obj, type, unref) \
  222. do \
  223. { \
  224. _Auto ptr = structof (obj, type, kuid); \
  225. spinlock_lock (&ptr->dead_subs.lock); \
  226. list_remove (link); \
  227. spinlock_unlock (&ptr->dead_subs.lock); \
  228. unref (ptr); \
  229. } \
  230. while (0)
  231. if (! kuid)
  232. return;
  233. else if (type == CAP_ALERT_THREAD_DIED)
  234. cap_unlink_alert (kuid, struct thread, thread_unref);
  235. else
  236. cap_unlink_alert (kuid, struct task, task_unref);
  237. #undef cap_unlink_alert
  238. }
  239. static void
  240. cap_alert_free (struct cap_alert *alert)
  241. {
  242. _Auto async = (struct cap_alert_async *)alert;
  243. _Auto k_alert = &alert->k_alert;
  244. int type = cap_alert_type (alert);
  245. if (type == CAP_ALERT_INTR)
  246. cap_intr_rem (k_alert->intr.irq, &async->xlink);
  247. else if (type == CAP_ALERT_THREAD_DIED || type == CAP_ALERT_TASK_DIED)
  248. cap_task_thread_rem (k_alert->any_id, type, &async->xlink);
  249. kmem_cache_free (&cap_misc_cache, alert);
  250. }
  251. static void
  252. cap_flow_fini (struct sref_counter *sref)
  253. {
  254. _Auto flow = CAP_FROM_SREF (sref, struct cap_flow);
  255. struct cap_alert *alert, *tmp;
  256. pqueue_for_each_entry_safe (&flow->alerts.pending, alert, tmp, pnode)
  257. if (cap_alert_type (alert) == CAP_ALERT_USER)
  258. kmem_cache_free (&cap_misc_cache, alert);
  259. hlist_for_each_entry_safe (&flow->alerts.alloc, alert, tmp, hnode)
  260. cap_alert_free (alert);
  261. for (_Auto lpad = flow->lpads.free_list; lpad; )
  262. {
  263. _Auto next = lpad->next;
  264. task_unref (lpad->task);
  265. kmem_cache_free (&cap_lpad_cache, lpad);
  266. lpad = next;
  267. }
  268. kmem_cache_free (&cap_flow_cache, flow);
  269. }
  270. #define CAP_FLOW_VALID_FLAGS \
  271. (CAP_FLOW_HANDLE_INTR | CAP_FLOW_EXT_PAGER | CAP_FLOW_PAGER_FLUSHES)
  272. int
  273. cap_flow_create (struct cap_flow **outp, uint32_t flags,
  274. uintptr_t tag, uintptr_t entry)
  275. {
  276. if (flags & ~CAP_FLOW_VALID_FLAGS)
  277. return (EINVAL);
  278. struct cap_flow *ret = kmem_cache_alloc (&cap_flow_cache);
  279. if (! ret)
  280. return (ENOMEM);
  281. cap_base_init (&ret->base, CAP_TYPE_FLOW, cap_flow_fini);
  282. ret->base.tflags |= flags;
  283. ret->tag = tag;
  284. ret->entry = entry;
  285. spinlock_init (&ret->alerts.lock);
  286. list_init (&ret->alerts.receivers);
  287. hlist_init (&ret->alerts.alloc);
  288. pqueue_init (&ret->alerts.pending);
  289. ret->lpads.free_list = NULL;
  290. list_init (&ret->lpads.waiters);
  291. spinlock_init (&ret->lpads.lock);
  292. *outp = ret;
  293. return (0);
  294. }
  295. int
  296. (cap_get_tag) (const struct cap_base *cap, uintptr_t *tagp)
  297. {
  298. switch (cap_type (cap))
  299. {
  300. case CAP_TYPE_CHANNEL:
  301. *tagp = ((const struct cap_channel *)cap)->tag;
  302. return (0);
  303. case CAP_TYPE_FLOW:
  304. *tagp = ((const struct cap_flow *)cap)->tag;
  305. return (0);
  306. default:
  307. return (EINVAL);
  308. }
  309. }
  310. int
  311. cap_flow_hook (struct cap_channel **outp, struct task *task, int capx)
  312. {
  313. struct cap_base *base = cspace_get (&task->caps, capx);
  314. if (! base)
  315. return (EBADF);
  316. else if (cap_type (base) != CAP_TYPE_FLOW)
  317. {
  318. cap_base_rel (base);
  319. return (EINVAL);
  320. }
  321. _Auto flow = (struct cap_flow *)base;
  322. int ret = cap_channel_create (outp, flow, flow->tag);
  323. cap_base_rel (flow);
  324. return (ret);
  325. }
  326. static void
  327. cap_ipc_msg_data_init (struct ipc_msg_data *data, uintptr_t tag)
  328. {
  329. data->size = sizeof (*data);
  330. data->tag = tag;
  331. data->bytes_recv = data->bytes_sent = 0;
  332. data->flags = 0;
  333. data->vmes_sent = data->caps_sent = 0;
  334. data->vmes_recv = data->caps_recv = 0;
  335. }
  336. /*
  337. * Transfer all 3 iterators between a local and a remote task.
  338. * Updates the metadata if succesful. Returns the number of
  339. * raw bytes transmitted on success; a negative errno value on failure.
  340. */
  341. static ssize_t
  342. cap_transfer_iters (struct task *task, struct cap_iters *r_it,
  343. struct cap_iters *l_it, uint32_t flags, ssize_t *bytesp)
  344. {
  345. ssize_t ret = ipc_iov_iter_copy (task, &r_it->iov, &l_it->iov, flags);
  346. if (ret < 0)
  347. return (ret);
  348. *bytesp += ret;
  349. if (ipc_cap_iter_size (&r_it->cap) && ipc_cap_iter_size (&l_it->cap))
  350. {
  351. int nr_caps = ipc_cap_iter_copy (task, &r_it->cap, &l_it->cap, flags);
  352. if (nr_caps < 0)
  353. return (nr_caps);
  354. *(uint32_t *)((char *)bytesp + CAP_CAPS_OFF) += nr_caps;
  355. }
  356. if (ipc_vme_iter_size (&r_it->vme) && ipc_vme_iter_size (&l_it->vme))
  357. {
  358. int nr_vmes = ipc_vme_iter_copy (task, &r_it->vme, &l_it->vme, flags);
  359. if (nr_vmes < 0)
  360. return (nr_vmes);
  361. *(uint32_t *)((char *)bytesp + CAP_VMES_OFF) += nr_vmes;
  362. }
  363. return (ret);
  364. }
  365. static struct cap_alert*
  366. cap_flow_alloc_alert (struct spinlock_guard *guard, uint32_t flg)
  367. {
  368. cap_flow_guard_fini (guard);
  369. uint32_t alflags = (flg & CAP_ALERT_NONBLOCK) ? 0 : KMEM_ALLOC_SLEEP;
  370. void *ptr = kmem_cache_alloc2 (&cap_misc_cache, alflags);
  371. cap_flow_guard_lock (guard);
  372. return (ptr);
  373. }
  374. static void
  375. cap_receiver_add (struct cap_flow *flow, struct cap_receiver *recv, void *buf)
  376. {
  377. recv->thread = thread_self ();
  378. recv->buf = buf;
  379. recv->spurious = false;
  380. cap_ipc_msg_data_init (&recv->mdata, 0);
  381. list_insert_tail (&flow->alerts.receivers, &recv->lnode);
  382. }
  383. static void
  384. cap_recv_wakeup_fast (struct cap_flow *flow)
  385. {
  386. if (list_empty (&flow->alerts.receivers))
  387. return;
  388. _Auto recv = list_pop (&flow->alerts.receivers, struct cap_receiver, lnode);
  389. recv->spurious = true;
  390. thread_wakeup (recv->thread);
  391. }
  392. static struct pqueue_node*
  393. cap_recv_pop_alert (struct cap_flow *flow, void *buf, uint32_t flags,
  394. struct ipc_msg_data *mdata, int *outp,
  395. struct spinlock_guard *guard)
  396. {
  397. if (!pqueue_empty (&flow->alerts.pending))
  398. return (pqueue_pop (&flow->alerts.pending));
  399. else if (flags & CAP_ALERT_NONBLOCK)
  400. {
  401. cap_flow_guard_fini (guard);
  402. *outp = EAGAIN;
  403. return (NULL);
  404. }
  405. struct cap_receiver recv;
  406. cap_receiver_add (flow, &recv, buf);
  407. do
  408. thread_sleep (&flow->alerts.lock, flow, "flow-alert");
  409. while (pqueue_empty (&flow->alerts.pending));
  410. if (recv.spurious)
  411. return (pqueue_pop (&flow->alerts.pending));
  412. cap_flow_guard_fini (guard);
  413. if (recv.mdata.bytes_recv >= 0 && mdata)
  414. {
  415. recv.mdata.bytes_recv = CAP_ALERT_SIZE;
  416. user_write_struct (mdata, &recv.mdata, sizeof (recv.mdata));
  417. }
  418. *outp = recv.mdata.bytes_recv >= 0 ? 0 : (int)-recv.mdata.bytes_recv;
  419. return (NULL);
  420. }
  421. int
  422. cap_recv_alert (struct cap_flow *flow, void *buf,
  423. uint32_t flags, struct ipc_msg_data *mdata)
  424. {
  425. uint32_t ids[2] = { 0, 0 };
  426. uintptr_t tag = 0;
  427. _Auto guard = cap_flow_guard_make (flow);
  428. int error = 0;
  429. _Auto pnode = cap_recv_pop_alert (flow, buf, flags, mdata, &error, &guard);
  430. if (! pnode)
  431. return (error);
  432. struct cap_alert *entry;
  433. void *payload;
  434. struct cap_kern_alert tmp_alert;
  435. int type = cap_alert_type (pnode);
  436. if (type == CAP_ALERT_CHAN_CLOSED)
  437. {
  438. tmp_alert.type = CAP_ALERT_CHAN_CLOSED;
  439. tag = tmp_alert.tag =
  440. pqueue_entry(pnode, struct cap_channel, pnode)->tag;
  441. payload = &tmp_alert;
  442. entry = NULL;
  443. }
  444. else
  445. {
  446. entry = pqueue_entry (pnode, struct cap_alert, pnode);
  447. payload = entry->payload;
  448. if (type == CAP_ALERT_INTR)
  449. { // Copy into a temp buffer so we may reset the counter.
  450. tmp_alert = entry->k_alert;
  451. entry->k_alert.intr.count = 0;
  452. payload = &tmp_alert;
  453. }
  454. else if (type != CAP_ALERT_USER)
  455. hlist_remove (&entry->hnode);
  456. else
  457. {
  458. ids[0] = entry->task_id;
  459. ids[1] = entry->thread_id;
  460. tag = entry->tag;
  461. }
  462. }
  463. pqueue_inc (&flow->alerts.pending, 1);
  464. cap_flow_guard_fini (&guard);
  465. if (unlikely (user_copy_to (buf, payload, CAP_ALERT_SIZE) != 0))
  466. {
  467. cap_flow_guard_lock (&guard);
  468. pqueue_insert (&flow->alerts.pending, pnode);
  469. if (type == CAP_ALERT_INTR)
  470. entry->k_alert.intr.count += tmp_alert.intr.count;
  471. else if (type != CAP_ALERT_USER && entry)
  472. hlist_insert_head (&flow->alerts.alloc, &entry->hnode);
  473. cap_recv_wakeup_fast (flow);
  474. cap_flow_guard_fini (&guard);
  475. return (EFAULT);
  476. }
  477. else if (mdata)
  478. {
  479. struct ipc_msg_data tmp;
  480. cap_ipc_msg_data_init (&tmp, tag);
  481. tmp.bytes_recv = CAP_ALERT_SIZE;
  482. tmp.task_id = ids[0], tmp.thread_id = ids[1];
  483. user_write_struct (mdata, &tmp, sizeof (tmp));
  484. }
  485. return (0);
  486. }
  487. static void
  488. cap_fill_ids (int *thr_idp, int *task_idp, struct thread *thr)
  489. {
  490. *thr_idp = thread_id (thr);
  491. *task_idp = task_id (thr->task);
  492. }
  493. int
  494. (cap_send_alert) (struct cap_base *cap, const void *buf,
  495. uint32_t flags, uint32_t prio)
  496. {
  497. struct cap_flow *flow;
  498. uintptr_t tag;
  499. switch (cap_type (cap))
  500. {
  501. case CAP_TYPE_CHANNEL:
  502. flow = ((struct cap_channel *)cap)->flow;
  503. tag = ((struct cap_channel *)cap)->tag;
  504. break;
  505. case CAP_TYPE_FLOW:
  506. flow = (struct cap_flow *)cap;
  507. tag = flow->tag;
  508. break;
  509. default:
  510. return (EBADF);
  511. }
  512. /*
  513. * Copy into a temporary buffer, since the code below may otherwise
  514. * generate a page fault while holding a spinlock.
  515. */
  516. char abuf[CAP_ALERT_SIZE] = { 0 };
  517. if (user_copy_from (abuf, buf, CAP_ALERT_SIZE) != 0)
  518. return (EFAULT);
  519. struct cap_receiver *recv;
  520. {
  521. CLEANUP (cap_flow_guard_fini) _Auto guard = cap_flow_guard_make (flow);
  522. if (list_empty (&flow->alerts.receivers))
  523. {
  524. _Auto alert = cap_flow_alloc_alert (&guard, flags);
  525. if (! alert)
  526. return (ENOMEM);
  527. memcpy (alert->payload, abuf, CAP_ALERT_SIZE);
  528. cap_alert_init_nodes (alert, CAP_ALERT_USER, prio);
  529. pqueue_insert (&flow->alerts.pending, &alert->pnode);
  530. cap_fill_ids (&alert->thread_id, &alert->task_id, thread_self ());
  531. alert->tag = tag;
  532. /*
  533. * Allocating an alert temporarily drops the flow lock. Since a
  534. * receiver could have been added in the meantime, we need to
  535. * check again before returning.
  536. */
  537. cap_recv_wakeup_fast (flow);
  538. return (0);
  539. }
  540. recv = list_pop (&flow->alerts.receivers, typeof (*recv), lnode);
  541. }
  542. cap_fill_ids (&recv->mdata.thread_id, &recv->mdata.task_id, thread_self ());
  543. recv->mdata.tag = tag;
  544. ssize_t rv = ipc_bcopy (recv->thread->task, recv->buf, sizeof (abuf),
  545. abuf, sizeof (abuf), IPC_COPY_TO | IPC_CHECK_REMOTE);
  546. thread_wakeup (recv->thread);
  547. recv->mdata.bytes_recv = rv;
  548. return (rv < 0 ? (int)-rv : 0);
  549. }
  550. static void
  551. cap_task_swap (struct task **taskp, struct thread *self)
  552. {
  553. cpu_flags_t flags;
  554. thread_preempt_disable_intr_save (&flags);
  555. struct task *xtask = self->xtask;
  556. self->xtask = *taskp;
  557. *taskp = xtask;
  558. pmap_load (self->xtask->map->pmap);
  559. thread_preempt_enable_intr_restore (flags);
  560. }
  561. static void
  562. cap_flow_push_lpad (struct cap_flow *flow, struct cap_lpad *lpad)
  563. {
  564. while (1)
  565. {
  566. _Auto next = lpad->next = atomic_load_rlx (&flow->lpads.free_list);
  567. if (!atomic_cas_bool_rel (&flow->lpads.free_list, next, lpad))
  568. {
  569. atomic_spin_nop ();
  570. continue;
  571. }
  572. atomic_fence_acq ();
  573. if (!next || !list_empty (&flow->lpads.waiters))
  574. {
  575. SPINLOCK_GUARD (&flow->lpads.lock);
  576. if (list_empty (&flow->lpads.waiters))
  577. return;
  578. _Auto sn = list_first_entry (&flow->lpads.waiters,
  579. struct cap_sender, lnode);
  580. thread_wakeup (sn->thread);
  581. }
  582. return;
  583. }
  584. }
  585. static struct cap_lpad*
  586. cap_lpad_pop_free (struct cap_lpad **ptr)
  587. {
  588. RCU_GUARD ();
  589. while (1)
  590. {
  591. _Auto tmp = atomic_load_rlx (ptr);
  592. if (! tmp)
  593. return (tmp);
  594. else if (atomic_cas_bool_acq (ptr, tmp, tmp->next))
  595. {
  596. tmp->next = NULL;
  597. return (tmp);
  598. }
  599. atomic_spin_nop ();
  600. }
  601. }
  602. static struct cap_lpad*
  603. cap_flow_pop_lpad (struct cap_flow *flow, struct thread *self)
  604. {
  605. _Auto ret = cap_lpad_pop_free (&flow->lpads.free_list);
  606. if (ret)
  607. return (ret);
  608. struct cap_sender sender = { .thread = self };
  609. SPINLOCK_GUARD (&flow->lpads.lock);
  610. list_insert_tail (&flow->lpads.waiters, &sender.lnode);
  611. atomic_fence_rel ();
  612. while ((ret = cap_lpad_pop_free (&flow->lpads.free_list)) == NULL)
  613. thread_sleep (&flow->lpads.lock, flow, "flow-send");
  614. list_remove (&sender.lnode);
  615. return (ret);
  616. }
  617. #define CAP_MSG_MASK (IPC_MSG_TRUNC | IPC_MSG_ERROR | IPC_MSG_KERNEL)
  618. #define CAP_MSG_REQ_PAGES 0x1000
  619. static_assert ((CAP_MSG_REQ_PAGES & CAP_MSG_MASK) == 0,
  620. "CAP_MSG_REQ_PAGES must not intersect message mask");
  621. static ssize_t
  622. cap_sender_impl (struct cap_flow *flow, uintptr_t tag, struct cap_iters *in,
  623. struct cap_iters *out, struct ipc_msg_data *data,
  624. uint32_t xflags, struct cap_base *src)
  625. {
  626. struct thread *self = thread_self ();
  627. _Auto lpad = cap_flow_pop_lpad (flow, self);
  628. uint32_t dirf = IPC_COPY_TO | IPC_CHECK_REMOTE |
  629. ((xflags & IPC_MSG_KERNEL) ? 0 : IPC_CHECK_LOCAL);
  630. cap_ipc_msg_data_init (&lpad->mdata, tag);
  631. ssize_t nb = cap_transfer_iters (lpad->task, &lpad->in_it, in,
  632. dirf, &lpad->mdata.bytes_recv);
  633. lpad->mdata.flags |= (xflags & CAP_MSG_MASK) | (nb < 0 ? IPC_MSG_ERROR : 0);
  634. lpad->cur_in = in;
  635. lpad->cur_out = out;
  636. lpad->xflags = xflags & ~CAP_MSG_MASK;
  637. struct cap_lpad *cur_lpad = self->cur_lpad;
  638. self->cur_lpad = lpad;
  639. cap_fill_ids (&lpad->mdata.thread_id, &lpad->mdata.task_id, self);
  640. lpad->src = src;
  641. // Switch task (also sets the pmap).
  642. cap_task_swap (&lpad->task, self);
  643. user_write_struct ((void *)lpad->ctx[2], &lpad->mdata, sizeof (lpad->mdata));
  644. // Jump to new PC and SP.
  645. uintptr_t prev_stack = *lpad->ctx;
  646. ssize_t ret = cpu_lpad_swap (lpad->ctx, cur_lpad, (void *)flow->entry);
  647. // We're back.
  648. *lpad->ctx = prev_stack;
  649. if (data && user_write_struct (data, &lpad->mdata, sizeof (*data)) != 0)
  650. ret = -EFAULT;
  651. cap_flow_push_lpad (flow, lpad);
  652. self->cur_lpad = cur_lpad;
  653. return (ret);
  654. }
  655. ssize_t
  656. cap_send_iters (struct cap_base *cap, struct cap_iters *in,
  657. struct cap_iters *out, struct ipc_msg_data *data,
  658. uint32_t xflags)
  659. {
  660. struct cap_flow *flow;
  661. uintptr_t tag;
  662. struct ipc_msg_data mdata;
  663. if (! cap)
  664. return (-EBADF);
  665. switch (cap_type (cap))
  666. {
  667. case CAP_TYPE_FLOW:
  668. flow = (struct cap_flow *)cap;
  669. tag = flow->tag;
  670. break;
  671. case CAP_TYPE_CHANNEL:
  672. flow = ((struct cap_channel *)cap)->flow;
  673. tag = ((struct cap_channel *)cap)->tag;
  674. break;
  675. case CAP_TYPE_THREAD:
  676. return (thread_handle_msg (((struct cap_thread *)cap)->thread,
  677. in, out, &mdata));
  678. case CAP_TYPE_TASK:
  679. return (task_handle_msg (((struct cap_task *)cap)->task,
  680. in, out, &mdata));
  681. case CAP_TYPE_KERNEL:
  682. // TODO: Implement.
  683. default:
  684. return (-EINVAL);
  685. }
  686. return (cap_sender_impl (flow, tag, in, out, data, xflags, cap));
  687. }
  688. ssize_t
  689. cap_pull_iters (struct cap_iters *it, struct ipc_msg_data *mdata)
  690. {
  691. struct cap_lpad *lpad = thread_self()->cur_lpad;
  692. if (! lpad)
  693. return (-EINVAL);
  694. struct ipc_msg_data tmp;
  695. cap_ipc_msg_data_init (&tmp, lpad->mdata.tag);
  696. ssize_t ret = cap_transfer_iters (lpad->task, lpad->cur_in, it,
  697. IPC_COPY_FROM | IPC_CHECK_BOTH,
  698. &tmp.bytes_recv);
  699. lpad->mdata.bytes_recv += tmp.bytes_recv;
  700. lpad->mdata.vmes_recv += tmp.vmes_recv;
  701. lpad->mdata.caps_recv += tmp.caps_recv;
  702. if (mdata)
  703. user_write_struct (mdata, &tmp, sizeof (tmp));
  704. return (ret);
  705. }
  706. ssize_t
  707. cap_push_iters (struct cap_iters *it, struct ipc_msg_data *mdata)
  708. {
  709. struct cap_lpad *lpad = thread_self()->cur_lpad;
  710. if (! lpad)
  711. return (-EINVAL);
  712. struct ipc_msg_data tmp;
  713. cap_ipc_msg_data_init (&tmp, lpad->mdata.tag);
  714. ssize_t ret = cap_transfer_iters (lpad->task, lpad->cur_out, it,
  715. IPC_COPY_TO | IPC_CHECK_BOTH,
  716. &tmp.bytes_sent);
  717. lpad->mdata.bytes_sent += tmp.bytes_sent;
  718. lpad->mdata.vmes_sent += tmp.vmes_sent;
  719. lpad->mdata.caps_sent += tmp.caps_sent;
  720. if (mdata)
  721. user_write_struct (mdata, &tmp, sizeof (tmp));
  722. return (ret);
  723. }
  724. static void
  725. cap_mdata_swap (struct ipc_msg_data *mdata)
  726. {
  727. SWAP (&mdata->bytes_sent, &mdata->bytes_recv);
  728. SWAP (&mdata->caps_sent, &mdata->caps_recv);
  729. SWAP (&mdata->vmes_sent, &mdata->vmes_recv);
  730. }
  731. static void
  732. cap_lpad_iters_reset (struct cap_lpad *lpad)
  733. {
  734. #define cap_reset_iter(name) \
  735. ipc_##name##_iter_init (&lpad->in_it.name, lpad->in_it.name.begin, \
  736. lpad->in_it.name.end)
  737. cap_reset_iter (iov);
  738. cap_reset_iter (cap);
  739. cap_reset_iter (vme);
  740. #undef cap_reset_iter
  741. lpad->in_it.iov.cur = lpad->nr_cached_iovs;
  742. lpad->in_it.iov.cache_idx = IPC_IOV_ITER_CACHE_SIZE - lpad->nr_cached_iovs;
  743. }
  744. noreturn static void
  745. cap_lpad_return (struct cap_lpad *lpad, struct thread *self, ssize_t rv)
  746. {
  747. cap_lpad_iters_reset (lpad);
  748. cap_task_swap (&lpad->task, self);
  749. cpu_lpad_return (lpad->ctx[0], rv);
  750. }
  751. ssize_t
  752. cap_reply_iters (struct cap_iters *it, int rv)
  753. {
  754. struct thread *self = thread_self ();
  755. struct cap_lpad *lpad = self->cur_lpad;
  756. ssize_t ret;
  757. if (!lpad || lpad->xflags)
  758. return (-EINVAL);
  759. else if (rv >= 0)
  760. {
  761. ret = cap_transfer_iters (lpad->task, lpad->cur_out, it,
  762. IPC_COPY_TO | IPC_CHECK_BOTH,
  763. &lpad->mdata.bytes_sent);
  764. if (ret > 0)
  765. ret = lpad->mdata.bytes_sent;
  766. cap_mdata_swap (&lpad->mdata);
  767. if (!ipc_iov_iter_empty (&it->iov) ||
  768. ipc_vme_iter_size (&it->vme) ||
  769. ipc_cap_iter_size (&it->cap))
  770. lpad->mdata.flags |= IPC_MSG_TRUNC;
  771. }
  772. else
  773. ret = rv;
  774. cap_lpad_return (lpad, self, ret);
  775. }
  776. static void
  777. cap_lpad_fill_cache (struct cap_lpad *lpad, struct ipc_msg *msg)
  778. {
  779. uint32_t nmax = MIN (msg->iov_cnt, IPC_IOV_ITER_CACHE_SIZE);
  780. _Auto outv = lpad->in_it.iov.cache + IPC_IOV_ITER_CACHE_SIZE;
  781. if (likely (user_copy_from (outv - nmax, msg->iovs,
  782. nmax * sizeof (*outv)) == 0))
  783. {
  784. lpad->in_it.iov.cur += nmax;
  785. lpad->in_it.iov.cache_idx = IPC_IOV_ITER_CACHE_SIZE - nmax;
  786. lpad->nr_cached_iovs = nmax;
  787. }
  788. }
  789. int
  790. cap_flow_add_lpad (struct cap_flow *flow, void *stack, size_t size,
  791. struct ipc_msg *msg, struct ipc_msg_data *mdata,
  792. struct cap_thread_info *info __unused)
  793. {
  794. /*
  795. * TODO: The user check for the stack can't be made here (yet),
  796. * as the tests run with blocks that reside in kernel space.
  797. */
  798. struct cap_lpad *entry = kmem_cache_alloc (&cap_lpad_cache);
  799. if (! entry)
  800. return (ENOMEM);
  801. entry->size = size;
  802. entry->ctx[0] = (uintptr_t)stack;
  803. entry->ctx[1] = (uintptr_t)msg;
  804. entry->ctx[2] = (uintptr_t)mdata;
  805. memset (&entry->mdata, 0, sizeof (entry->mdata));
  806. cap_iters_init_msg (&entry->in_it, msg);
  807. cap_lpad_fill_cache (entry, msg);
  808. task_ref (entry->task = task_self ());
  809. cap_flow_push_lpad (flow, entry);
  810. return (0);
  811. }
  812. int
  813. cap_flow_rem_lpad (struct cap_flow *flow, uintptr_t stack, bool unmap)
  814. {
  815. _Auto self = task_self ();
  816. struct cap_lpad *entry;
  817. {
  818. RCU_GUARD ();
  819. for (_Auto pptr = &flow->lpads.free_list ; ; pptr = &entry->next)
  820. {
  821. entry = atomic_load_rlx (pptr);
  822. if (! entry)
  823. return (ESRCH);
  824. else if (entry->task == self &&
  825. (stack == ~(uintptr_t)0 || stack == *entry->ctx))
  826. {
  827. if (!atomic_cas_bool_acq (pptr, entry, entry->next))
  828. return (ESRCH);
  829. break;
  830. }
  831. }
  832. }
  833. int error = stack != ~(uintptr_t)0 || !unmap ? 0 :
  834. vm_map_remove (vm_map_self (), stack, entry->size);
  835. if (! error)
  836. {
  837. rcu_wait ();
  838. task_unref (entry->task);
  839. kmem_cache_free (&cap_lpad_cache, entry);
  840. }
  841. else
  842. cap_flow_push_lpad (flow, entry);
  843. return (error);
  844. }
  845. static int
  846. cap_handle_intr (void *arg)
  847. {
  848. struct list *list = arg;
  849. assert (list >= &cap_intr_handlers[0] &&
  850. list <= &cap_intr_handlers[ARRAY_SIZE (cap_intr_handlers) - 1]);
  851. RCU_GUARD ();
  852. list_rcu_for_each (list, tmp)
  853. {
  854. _Auto alert = list_entry (tmp, struct cap_alert_async, xlink);
  855. SPINLOCK_GUARD (&alert->flow->alerts.lock);
  856. if (++alert->base.k_alert.intr.count == 1)
  857. {
  858. pqueue_insert (&alert->flow->alerts.pending, &alert->base.pnode);
  859. cap_recv_wakeup_fast (alert->flow);
  860. }
  861. }
  862. return (EAGAIN);
  863. }
  864. static int
  865. cap_intr_add (uint32_t intr, struct list *node)
  866. {
  867. assert (intr >= CPU_EXC_INTR_FIRST &&
  868. intr - CPU_EXC_INTR_FIRST < ARRAY_SIZE (cap_intr_handlers));
  869. struct list *list = &cap_intr_handlers[intr - CPU_EXC_INTR_FIRST];
  870. ADAPTIVE_LOCK_GUARD (&cap_intr_lock);
  871. if (list_empty (list))
  872. {
  873. CPU_INTR_GUARD ();
  874. int error = intr_register (intr, cap_handle_intr, list);
  875. if (error)
  876. return (error);
  877. list_rcu_insert_head (list, node);
  878. return (0);
  879. }
  880. list_rcu_insert_head (list, node);
  881. return (0);
  882. }
  883. static void
  884. cap_intr_rem (uint32_t intr, struct list *node)
  885. {
  886. ADAPTIVE_LOCK_GUARD (&cap_intr_lock);
  887. list_rcu_remove (node);
  888. if (list_empty (&cap_intr_handlers[intr - CPU_EXC_INTR_FIRST]))
  889. intr_unregister (intr, cap_handle_intr);
  890. }
  891. static struct cap_alert_async*
  892. cap_alert_async_find (struct cap_flow *flow, int type, int id)
  893. {
  894. struct cap_alert *tmp;
  895. hlist_for_each_entry (&flow->alerts.alloc, tmp, hnode)
  896. if (cap_alert_type (tmp) == type && tmp->k_alert.any_id == id)
  897. return ((void *)tmp);
  898. return (NULL);
  899. }
  900. int
  901. cap_intr_register (struct cap_flow *flow, uint32_t irq)
  902. {
  903. if (irq < CPU_EXC_INTR_FIRST || irq > CPU_EXC_INTR_LAST)
  904. return (EINVAL);
  905. else if (!(flow->base.tflags & CAP_FLOW_HANDLE_INTR))
  906. return (EPERM);
  907. struct cap_alert_async *ap = kmem_cache_alloc (&cap_misc_cache);
  908. if (! ap)
  909. return (ENOMEM);
  910. cap_alert_init_nodes (&ap->base, CAP_ALERT_INTR, CAP_ALERT_INTR_PRIO);
  911. list_node_init (&ap->xlink);
  912. ap->flow = flow;
  913. ap->base.k_alert.type = CAP_ALERT_INTR;
  914. ap->base.k_alert.intr.irq = irq;
  915. ap->base.k_alert.intr.count = 0;
  916. int error = cap_intr_add (irq, &ap->xlink);
  917. if (error)
  918. {
  919. kmem_cache_free (&cap_misc_cache, ap);
  920. return (error);
  921. }
  922. _Auto guard = cap_flow_guard_make (flow);
  923. if (unlikely (cap_alert_async_find (flow, CAP_ALERT_INTR, irq)))
  924. {
  925. cap_flow_guard_fini (&guard);
  926. cap_intr_rem (irq, &ap->xlink);
  927. rcu_wait ();
  928. kmem_cache_free (&cap_misc_cache, ap);
  929. return (EALREADY);
  930. }
  931. hlist_insert_head (&flow->alerts.alloc, &ap->base.hnode);
  932. cap_flow_guard_fini (&guard);
  933. return (0);
  934. }
  935. static int
  936. cap_unregister_impl (struct cap_flow *flow, int type,
  937. uint32_t id, struct cap_alert_async **outp)
  938. {
  939. CAP_FLOW_GUARD (flow);
  940. _Auto entry = cap_alert_async_find (flow, type, id);
  941. if (! entry)
  942. return (ESRCH);
  943. hlist_remove (&entry->base.hnode);
  944. if (!pqueue_node_unlinked (&entry->base.pnode))
  945. pqueue_remove (&flow->alerts.pending, &entry->base.pnode);
  946. *outp = entry;
  947. return (0);
  948. }
  949. int
  950. cap_intr_unregister (struct cap_flow *flow, uint32_t irq)
  951. {
  952. cpu_flags_t flags;
  953. struct cap_alert_async *entry;
  954. cpu_intr_save (&flags);
  955. int error = cap_unregister_impl (flow, CAP_ALERT_INTR, irq, &entry);
  956. if (! error)
  957. {
  958. cap_intr_rem (irq, &entry->xlink);
  959. cpu_intr_restore (flags);
  960. rcu_wait ();
  961. kmem_cache_free (&cap_misc_cache, entry);
  962. }
  963. else
  964. cpu_intr_restore (flags);
  965. return (error);
  966. }
  967. static int
  968. cap_register_task_thread (struct cap_flow *flow, struct kuid_head *kuid,
  969. uint32_t prio, int type, struct bulletin *outp)
  970. {
  971. struct cap_alert_async *ap = kmem_cache_alloc (&cap_misc_cache);
  972. if (! ap)
  973. return (ENOMEM);
  974. cap_alert_init_nodes (&ap->base, type, prio);
  975. list_node_init (&ap->xlink);
  976. ap->flow = flow;
  977. ap->base.k_alert.type = type;
  978. ap->base.k_alert.any_id = kuid->id;
  979. _Auto guard = cap_flow_guard_make (flow);
  980. if (unlikely (cap_alert_async_find (flow, type, kuid->id)))
  981. {
  982. cap_flow_guard_fini (&guard);
  983. kmem_cache_free (&cap_misc_cache, ap);
  984. return (EALREADY);
  985. }
  986. hlist_insert_head (&flow->alerts.alloc, &ap->base.hnode);
  987. spinlock_lock (&outp->lock);
  988. list_insert_tail (&outp->subs, &ap->xlink);
  989. spinlock_unlock (&outp->lock);
  990. cap_flow_guard_fini (&guard);
  991. return (0);
  992. }
  993. static int
  994. cap_task_thread_unregister (struct cap_flow *flow, int type,
  995. int tid, struct bulletin *outp)
  996. {
  997. struct cap_alert_async *entry;
  998. int error = cap_unregister_impl (flow, type, tid, &entry);
  999. if (error)
  1000. return (error);
  1001. spinlock_lock (&outp->lock);
  1002. list_remove (&entry->xlink);
  1003. spinlock_unlock (&outp->lock);
  1004. kmem_cache_free (&cap_misc_cache, entry);
  1005. return (0);
  1006. }
  1007. int
  1008. cap_thread_register (struct cap_flow *flow, struct thread *thr)
  1009. {
  1010. if (! thr)
  1011. return (EINVAL);
  1012. return (cap_register_task_thread (flow, &thr->kuid, CAP_ALERT_THREAD_PRIO,
  1013. CAP_ALERT_THREAD_DIED, &thr->dead_subs));
  1014. }
  1015. int
  1016. cap_task_register (struct cap_flow *flow, struct task *task)
  1017. {
  1018. if (! task)
  1019. return (EINVAL);
  1020. return (cap_register_task_thread (flow, &task->kuid, CAP_ALERT_TASK_PRIO,
  1021. CAP_ALERT_TASK_DIED, &task->dead_subs));
  1022. }
  1023. int
  1024. cap_thread_unregister (struct cap_flow *flow, struct thread *thr)
  1025. {
  1026. if (! thr)
  1027. return (EINVAL);
  1028. return (cap_task_thread_unregister (flow, CAP_ALERT_THREAD_DIED,
  1029. thread_id (thr), &thr->dead_subs));
  1030. }
  1031. int
  1032. cap_task_unregister (struct cap_flow *flow, struct task *task)
  1033. {
  1034. if (! task)
  1035. return (EINVAL);
  1036. return (cap_task_thread_unregister (flow, CAP_ALERT_TASK_DIED,
  1037. task_id (task), &task->dead_subs));
  1038. }
  1039. void
  1040. cap_notify_dead (struct bulletin *bulletin)
  1041. {
  1042. struct list dead_subs;
  1043. spinlock_lock (&bulletin->lock);
  1044. list_set_head (&dead_subs, &bulletin->subs);
  1045. list_init (&bulletin->subs);
  1046. spinlock_unlock (&bulletin->lock);
  1047. struct cap_alert_async *ap;
  1048. list_for_each_entry (&dead_subs, ap, xlink)
  1049. {
  1050. _Auto flow = ap->flow;
  1051. CAP_FLOW_GUARD (flow);
  1052. if (!pqueue_node_unlinked (&ap->base.pnode))
  1053. continue;
  1054. pqueue_insert (&flow->alerts.pending, &ap->base.pnode);
  1055. cap_recv_wakeup_fast (flow);
  1056. }
  1057. }
  1058. int
  1059. (cap_intern) (struct cap_base *cap, uint32_t flags)
  1060. {
  1061. return (cap ? cspace_add_free (cspace_self (), cap, flags) : -EINVAL);
  1062. }
  1063. ssize_t
  1064. cap_request_pages (struct cap_channel *chp, uint64_t off,
  1065. uint32_t nr_pages, struct vm_page **pages)
  1066. {
  1067. struct kmessage msg;
  1068. msg.type = KMSG_TYPE_PAGE_REQ;
  1069. msg.msg_flags = 0;
  1070. msg.page_req.start = off;
  1071. msg.page_req.end = off + nr_pages * PAGE_SIZE;
  1072. struct cap_iters in, out;
  1073. cap_iters_init_buf (&in, &msg, sizeof (msg));
  1074. cap_iters_init_buf (&out, pages, nr_pages * sizeof (**pages));
  1075. return (cap_send_iters (CAP (chp), &in, &out, NULL,
  1076. IPC_MSG_KERNEL | CAP_MSG_REQ_PAGES));
  1077. }
  1078. ssize_t
  1079. cap_reply_pagereq (const uintptr_t *usrc, uint32_t cnt)
  1080. {
  1081. _Auto self = thread_self ();
  1082. struct cap_lpad *lpad = self->cur_lpad;
  1083. if (!lpad || !(lpad->xflags & CAP_MSG_REQ_PAGES))
  1084. return (-EINVAL);
  1085. uint32_t npg = lpad->cur_out->iov.head.iov_len / sizeof (struct vm_page);
  1086. if (npg < cnt)
  1087. cnt = npg;
  1088. assert (cnt <= VM_MAP_MAX_FRAMES);
  1089. uintptr_t src[VM_MAP_MAX_FRAMES];
  1090. if (user_copy_from (src, usrc, cnt * sizeof (*usrc)) != 0)
  1091. return (-EFAULT);
  1092. struct vm_page **pages = lpad->cur_out->iov.head.iov_base;
  1093. int rv = vm_map_reply_pagereq (src, cnt, pages);
  1094. if (rv < 0)
  1095. return (rv);
  1096. cap_lpad_return (lpad, self, rv);
  1097. }
  1098. static struct vm_object*
  1099. cap_channel_load_vmobj (struct cap_channel *chp)
  1100. {
  1101. RCU_GUARD ();
  1102. _Auto prev = atomic_load_rlx (&chp->vmobj);
  1103. return (!prev || vm_object_tryref (prev) ? prev : NULL);
  1104. }
  1105. struct vm_object*
  1106. cap_channel_get_vmobj (struct cap_channel *chp)
  1107. {
  1108. uint32_t flags = VM_OBJECT_EXTERNAL |
  1109. ((chp->flow->base.tflags & CAP_FLOW_PAGER_FLUSHES) ?
  1110. VM_OBJECT_FLUSHES : 0);
  1111. while (1)
  1112. {
  1113. _Auto prev = cap_channel_load_vmobj (chp);
  1114. if (prev)
  1115. return (prev);
  1116. struct vm_object *obj;
  1117. if (vm_object_create (&obj, flags, chp) != 0)
  1118. // We couldn't create the object but maybe someone else could.
  1119. return (cap_channel_load_vmobj (chp));
  1120. else if (atomic_cas_bool_acq (&chp->vmobj, NULL, obj))
  1121. {
  1122. cap_base_acq (chp);
  1123. return (obj);
  1124. }
  1125. vm_object_destroy (obj);
  1126. }
  1127. }
  1128. void
  1129. cap_channel_put_vmobj (struct cap_channel *chp)
  1130. {
  1131. rcu_read_enter ();
  1132. _Auto prev = atomic_load_rlx (&chp->vmobj);
  1133. if (prev && vm_object_unref_nofree (prev, 1))
  1134. {
  1135. atomic_store_rel (&chp->vmobj, NULL);
  1136. rcu_read_leave ();
  1137. vm_object_destroy (prev);
  1138. }
  1139. else
  1140. rcu_read_leave ();
  1141. }
  1142. void
  1143. cap_channel_close (struct cap_channel *chp)
  1144. {
  1145. uint32_t prev = atomic_sub_acq_rel (&chp->open_count, 1);
  1146. assert (prev != 0);
  1147. if (prev == 1 && chp->flow)
  1148. {
  1149. CAP_FLOW_GUARD (chp->flow);
  1150. pqueue_insert (&chp->flow->alerts.pending, &chp->pnode);
  1151. cap_recv_wakeup_fast (chp->flow);
  1152. }
  1153. }
  1154. static size_t
  1155. cap_get_max (const size_t *args, size_t n)
  1156. {
  1157. size_t ret = *args;
  1158. for (size_t i = 1; i < n; ++i)
  1159. if (args[i] > ret)
  1160. ret = args[i];
  1161. return (ret);
  1162. }
  1163. #define CAP_MAX(...) \
  1164. ({ \
  1165. const size_t args_[] = { __VA_ARGS__ }; \
  1166. cap_get_max (args_, ARRAY_SIZE (args_)); \
  1167. })
  1168. static int __init
  1169. cap_setup (void)
  1170. {
  1171. // Every capability type but flows are allocated from the same cache.
  1172. #define SZ(type) sizeof (struct cap_##type)
  1173. #define AL(type) alignof (struct cap_##type)
  1174. size_t size = CAP_MAX (SZ (task), SZ (thread), SZ (channel),
  1175. SZ (kernel), SZ (alert_async));
  1176. size_t alignment = CAP_MAX (AL (task), AL (thread), AL (channel),
  1177. AL (kernel), AL (alert_async));
  1178. kmem_cache_init (&cap_misc_cache, "cap_misc", size, alignment, NULL, 0);
  1179. kmem_cache_init (&cap_lpad_cache, "cap_lpad",
  1180. sizeof (struct cap_lpad), 0, NULL, 0);
  1181. kmem_cache_init (&cap_flow_cache, "cap_flow",
  1182. sizeof (struct cap_flow), 0, NULL, 0);
  1183. adaptive_lock_init (&cap_intr_lock);
  1184. for (size_t i = 0; i < ARRAY_SIZE (cap_intr_handlers); ++i)
  1185. list_init (&cap_intr_handlers[i]);
  1186. return (0);
  1187. }
  1188. INIT_OP_DEFINE (cap_setup,
  1189. INIT_OP_DEP (intr_setup, true),
  1190. INIT_OP_DEP (kmem_setup, true));
  1191. #ifdef CONFIG_SHELL
  1192. #include <kern/panic.h>
  1193. static void
  1194. cap_shell_info (struct shell *shell, int argc, char **argv)
  1195. {
  1196. _Auto stream = shell->stream;
  1197. if (argc < 2)
  1198. {
  1199. stream_puts (stream, "usage: cap_info task\n");
  1200. return;
  1201. }
  1202. const _Auto task = task_lookup (argv[1]);
  1203. if (! task)
  1204. {
  1205. stream_puts (stream, "cap_info: task not found\n");
  1206. return;
  1207. }
  1208. fmt_xprintf (stream, "capabilities:\nindex\ttype\textra\n");
  1209. ADAPTIVE_LOCK_GUARD (&task->caps.lock);
  1210. struct rdxtree_iter it;
  1211. struct cap_base *cap;
  1212. rdxtree_for_each (&task->caps.tree, &it, cap)
  1213. {
  1214. fmt_xprintf (stream, "%llu\t", it.key);
  1215. switch (cap_type (cap))
  1216. {
  1217. case CAP_TYPE_CHANNEL:
  1218. fmt_xprintf (stream, "channel\t{tag: %lu}\n",
  1219. ((struct cap_channel *)cap)->tag);
  1220. break;
  1221. case CAP_TYPE_FLOW:
  1222. fmt_xprintf (stream, "flow\t{entry: %lu}\n",
  1223. ((struct cap_flow *)cap)->entry);
  1224. break;
  1225. case CAP_TYPE_TASK:
  1226. fmt_xprintf (stream, "task\t{task: %s}\n",
  1227. ((struct cap_task *)cap)->task->name);
  1228. break;
  1229. case CAP_TYPE_THREAD:
  1230. fmt_xprintf (stream, "thread\t{thread: %s}\n",
  1231. ((struct cap_thread *)cap)->thread->name);
  1232. break;
  1233. case CAP_TYPE_KERNEL:
  1234. fmt_xprintf (stream, "kernel\t{kind: %d}\n",
  1235. ((struct cap_kernel *)cap)->kind);
  1236. break;
  1237. default:
  1238. panic ("unknown capability type: %u\n", cap_type (cap));
  1239. }
  1240. }
  1241. task_unref (task);
  1242. }
  1243. static struct shell_cmd cap_shell_cmds[] =
  1244. {
  1245. SHELL_CMD_INITIALIZER ("cap_info", cap_shell_info,
  1246. "cap_info <task_name>",
  1247. "display capabilities of a task"),
  1248. };
  1249. static int __init
  1250. cap_setup_shell (void)
  1251. {
  1252. SHELL_REGISTER_CMDS (cap_shell_cmds, shell_get_main_cmd_set ());
  1253. return (0);
  1254. }
  1255. INIT_OP_DEFINE (cap_setup_shell,
  1256. INIT_OP_DEP (printf_setup, true),
  1257. INIT_OP_DEP (shell_setup, true),
  1258. INIT_OP_DEP (task_setup, true),
  1259. INIT_OP_DEP (cap_setup, true));
  1260. #endif