ipc.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * Copyright (c) 2022 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. * Definitions for inter-process communication.
  18. */
  19. #ifndef KERN_IPC_H
  20. #define KERN_IPC_H
  21. #include <iovec.h>
  22. #include <stdbool.h>
  23. #include <stdint.h>
  24. #include <kern/types.h>
  25. struct ipc_msg_vme
  26. {
  27. uintptr_t addr;
  28. size_t size;
  29. int prot;
  30. int max_prot;
  31. };
  32. struct ipc_msg_cap
  33. {
  34. int cap;
  35. int flags;
  36. };
  37. #define IPC_IOV_ITER_CACHE_SIZE 8
  38. struct ipc_iov_iter
  39. {
  40. struct iovec cache[IPC_IOV_ITER_CACHE_SIZE];
  41. uint32_t cache_idx;
  42. struct iovec head;
  43. struct iovec *begin;
  44. uint32_t cur;
  45. uint32_t end;
  46. };
  47. struct ipc_cap_iter
  48. {
  49. struct ipc_msg_cap *begin;
  50. uint32_t cur;
  51. uint32_t end;
  52. };
  53. struct ipc_vme_iter
  54. {
  55. struct ipc_msg_vme *begin;
  56. uint32_t cur;
  57. uint32_t end;
  58. };
  59. struct ipc_msg
  60. {
  61. size_t size;
  62. struct iovec *iovs;
  63. uint32_t iov_cnt;
  64. struct ipc_msg_vme *vmes;
  65. uint32_t vme_cnt;
  66. struct ipc_msg_cap *caps;
  67. uint32_t cap_cnt;
  68. };
  69. // Bits for the 'flags' member of a IPC message metadata.
  70. #define IPC_MSG_TRUNC 0x01 // Reply was truncated.
  71. struct ipc_msg_data
  72. {
  73. size_t size;
  74. int task_id;
  75. int thread_id;
  76. uint32_t flags;
  77. uintptr_t tag;
  78. ssize_t bytes_sent;
  79. uint32_t vmes_sent;
  80. uint32_t caps_sent;
  81. ssize_t bytes_recv;
  82. uint32_t vmes_recv;
  83. uint32_t caps_recv;
  84. };
  85. struct task;
  86. // Direction of the binary copy, relative to the remote task.
  87. #define IPC_COPY_FROM 0
  88. #define IPC_COPY_TO 1
  89. /*
  90. * IPC iterator functions.
  91. *
  92. * These come in 3 flavors: iovec, capabilities and VMEs. The former works
  93. * by simply copying data; the other 2 by transfering objects across tasks.
  94. */
  95. static inline void
  96. ipc_cap_iter_init (struct ipc_cap_iter *it,
  97. struct ipc_msg_cap *msg, uint32_t nr_msgs)
  98. {
  99. it->begin = msg;
  100. it->cur = 0, it->end = nr_msgs;
  101. }
  102. static inline int
  103. ipc_cap_iter_size (const struct ipc_cap_iter *it)
  104. {
  105. return ((int)(it->end - it->cur));
  106. }
  107. static inline void
  108. ipc_vme_iter_init (struct ipc_vme_iter *it,
  109. struct ipc_msg_vme *msg, uint32_t nr_msgs)
  110. {
  111. it->begin = msg;
  112. it->cur = 0, it->end = nr_msgs;
  113. }
  114. static inline int
  115. ipc_vme_iter_size (const struct ipc_vme_iter *it)
  116. {
  117. return ((int)(it->end - it->cur));
  118. }
  119. static inline void
  120. ipc_iov_iter_init_buf (struct ipc_iov_iter *it, void *buf, size_t size)
  121. {
  122. it->head = IOVEC (buf, size);
  123. it->cache_idx = IPC_IOV_ITER_CACHE_SIZE;
  124. it->begin = &it->head;
  125. it->cur = it->end = 1;
  126. }
  127. static inline bool
  128. ipc_iov_iter_empty (const struct ipc_iov_iter *it)
  129. {
  130. return (it->cur >= it->end && !it->head.iov_len &&
  131. it->cache_idx >= IPC_IOV_ITER_CACHE_SIZE);
  132. }
  133. static inline void
  134. ipc_iov_iter_init (struct ipc_iov_iter *it, struct iovec *vecs, uint32_t cnt)
  135. {
  136. it->head.iov_len = 0;
  137. it->begin = vecs;
  138. it->cur = 0, it->end = cnt;
  139. it->cache_idx = IPC_IOV_ITER_CACHE_SIZE;
  140. }
  141. // Copy bytes between a local and a remote task.
  142. ssize_t ipc_bcopy (struct task *r_task, void *r_ptr, size_t r_size,
  143. void *l_ptr, size_t l_size, int direction);
  144. // Copy bytes in iterators between a local and a remote task.
  145. ssize_t ipc_iov_iter_copy (struct task *r_task, struct ipc_iov_iter *r_it,
  146. struct ipc_iov_iter *l_it, int direction);
  147. // Transfer capabilities in iterators between a local and a remote task.
  148. int ipc_cap_iter_copy (struct task *r_task, struct ipc_cap_iter *r_it,
  149. struct ipc_cap_iter *l_it, int direction);
  150. // Transfer VMEs in iterators between a local and a remote task.
  151. int ipc_vme_iter_copy (struct task *r_task, struct ipc_vme_iter *r_it,
  152. struct ipc_vme_iter *l_it, int direction);
  153. // Copy bytes in iovecs between a local and a remote task.
  154. static inline ssize_t
  155. ipc_bcopyv (struct task *r_task, struct iovec *r_iov, uint32_t r_niov,
  156. struct iovec *l_iov, uint32_t l_niov, int direction)
  157. {
  158. struct ipc_iov_iter r_it, l_it;
  159. ipc_iov_iter_init (&l_it, l_iov, l_niov);
  160. ipc_iov_iter_init (&r_it, r_iov, r_niov);
  161. return (ipc_iov_iter_copy (r_task, &r_it, &l_it, direction));
  162. }
  163. // Transfer VMEs between a remote and a local task.
  164. static inline int
  165. ipc_copy_vmes (struct task *r_task, struct ipc_msg_vme *r_vmes,
  166. uint32_t r_nvmes, struct ipc_msg_vme *l_vmes,
  167. uint32_t l_nvmes, int direction)
  168. {
  169. struct ipc_vme_iter r_it, l_it;
  170. ipc_vme_iter_init (&r_it, r_vmes, r_nvmes);
  171. ipc_vme_iter_init (&l_it, l_vmes, l_nvmes);
  172. return (ipc_vme_iter_copy (r_task, &r_it, &l_it, direction));
  173. }
  174. // Transfer capabilities between a remote and a local task.
  175. static inline int
  176. ipc_copy_caps (struct task *r_task, struct ipc_msg_cap *r_caps,
  177. uint32_t r_ncaps, struct ipc_msg_cap *l_caps,
  178. uint32_t l_ncaps, int direction)
  179. {
  180. struct ipc_cap_iter r_it, l_it;
  181. ipc_cap_iter_init (&r_it, r_caps, r_ncaps);
  182. ipc_cap_iter_init (&l_it, l_caps, l_ncaps);
  183. return (ipc_cap_iter_copy (r_task, &r_it, &l_it, direction));
  184. }
  185. #endif