db_ipc.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* Copyright (C) 2014 Stony Brook University
  2. This file is part of Graphene Library OS.
  3. Graphene Library OS is free software: you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public License
  5. as published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. Graphene Library OS is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. /*
  14. * db_ipc.c
  15. *
  16. * This file contains APIs for physical memory bulk copy across processes.
  17. */
  18. #include "pal_defs.h"
  19. #include "pal_linux_defs.h"
  20. #include "pal.h"
  21. #include "pal_internal.h"
  22. #include "pal_linux.h"
  23. #include "pal_error.h"
  24. #include "pal_debug.h"
  25. #include "pal_security.h"
  26. #include "graphene-ipc.h"
  27. #include "api.h"
  28. int gipc_open (PAL_HANDLE * handle, const char * type, const char * uri,
  29. int access, int share, int create, int options)
  30. {
  31. if (strcmp_static(type, "gipc"))
  32. return -PAL_ERROR_INVAL;
  33. if (!WITHIN_MASK(access, PAL_ACCESS_MASK) ||
  34. !WITHIN_MASK(share, PAL_SHARE_MASK) ||
  35. !WITHIN_MASK(create, PAL_CREATE_MASK) ||
  36. !WITHIN_MASK(options, PAL_OPTION_MASK))
  37. return -PAL_ERROR_INVAL;
  38. int64_t token;
  39. int rv;
  40. int fd = INLINE_SYSCALL(open, 3, GIPC_FILE, O_RDONLY|O_CLOEXEC, 0);
  41. if (IS_ERR(fd))
  42. return -PAL_ERROR_DENIED;
  43. token = atoi(uri);
  44. rv = INLINE_SYSCALL(ioctl, 3, fd, GIPC_JOIN, token);
  45. if (rv < 0) {
  46. INLINE_SYSCALL(close, 1, fd);
  47. return -PAL_ERROR_DENIED;
  48. }
  49. PAL_HANDLE hdl = malloc(HANDLE_SIZE(gipc));
  50. SET_HANDLE_TYPE(hdl, gipc);
  51. hdl->gipc.fd = fd;
  52. hdl->gipc.token = token;
  53. *handle = hdl;
  54. return 0;
  55. }
  56. int gipc_close (PAL_HANDLE handle)
  57. {
  58. int ret = INLINE_SYSCALL(close, 1, handle->gipc.fd);
  59. return (IS_ERR(ret)) ? -PAL_ERROR_BADHANDLE : 0;
  60. }
  61. const char * gipc_getrealpath (PAL_HANDLE handle)
  62. {
  63. __UNUSED(handle);
  64. return GIPC_FILE;
  65. }
  66. struct handle_ops gipc_ops = {
  67. .getrealpath = &gipc_getrealpath,
  68. .open = &gipc_open,
  69. .close = &gipc_close,
  70. };
  71. int _DkCreatePhysicalMemoryChannel (PAL_HANDLE * handle, uint64_t * key)
  72. {
  73. int token = 0;
  74. int fd = INLINE_SYSCALL(open, 3, GIPC_FILE, O_RDONLY|O_CLOEXEC, 0);
  75. if (IS_ERR(fd))
  76. goto err;
  77. PAL_HANDLE hdl = malloc(HANDLE_SIZE(gipc));
  78. SET_HANDLE_TYPE(hdl, gipc);
  79. hdl->gipc.fd = fd;
  80. // ioctl to create a new queue
  81. token = INLINE_SYSCALL(ioctl, 3, fd, GIPC_CREATE, 0);
  82. if (token < 0)
  83. goto err_fd;
  84. *handle = hdl;
  85. *key = token;
  86. return 0;
  87. err_fd:
  88. INLINE_SYSCALL(close, 1, fd);
  89. err:
  90. return -PAL_ERROR_DENIED;
  91. }
  92. int _DkPhysicalMemoryCommit (PAL_HANDLE channel, int entries,
  93. PAL_PTR * addrs, PAL_NUM * sizes)
  94. {
  95. int fd = channel->gipc.fd;
  96. struct gipc_send gs;
  97. gs.addr = __alloca(sizeof(unsigned long) * entries);
  98. gs.len = __alloca(sizeof(unsigned long) * entries);
  99. for (int i = 0 ; i < entries ; i++) {
  100. if (!addrs[i] || !sizes[i] || !IS_ALLOC_ALIGNED_PTR(addrs[i]) ||
  101. !IS_ALLOC_ALIGNED(sizes[i]))
  102. return -PAL_ERROR_INVAL;
  103. gs.addr[i] = (unsigned long) addrs[i];
  104. gs.len[i] = sizes[i];
  105. }
  106. gs.entries = entries;
  107. int ret = INLINE_SYSCALL(ioctl, 3, fd, GIPC_SEND, &gs);
  108. if (IS_ERR(ret))
  109. return -PAL_ERROR_DENIED;
  110. return ret;
  111. }
  112. int _DkPhysicalMemoryMap (PAL_HANDLE channel, int entries,
  113. PAL_PTR * addrs, PAL_NUM * sizes, PAL_FLG * prots)
  114. {
  115. int fd = channel->gipc.fd;
  116. struct gipc_recv gr;
  117. gr.addr = __alloca(sizeof(unsigned long) * entries);
  118. gr.len = __alloca(sizeof(unsigned long) * entries);
  119. gr.prot = __alloca(sizeof(unsigned long) * entries);
  120. for (int i = 0 ; i < entries ; i++) {
  121. if (!sizes[i] || !IS_ALLOC_ALIGNED_PTR(addrs[i]) || !IS_ALLOC_ALIGNED(sizes[i]))
  122. return -PAL_ERROR_INVAL;
  123. gr.addr[i] = (unsigned long) addrs[i];
  124. gr.len[i] = sizes[i];
  125. gr.prot[i] = HOST_PROT(prots[i]);
  126. }
  127. gr.entries = entries;
  128. int ret = INLINE_SYSCALL(ioctl, 3, fd, GIPC_RECV, &gr);
  129. if (IS_ERR(ret))
  130. return -PAL_ERROR_DENIED;
  131. for (int i = 0 ; i < entries ; i++)
  132. addrs[i] = (PAL_PTR) gr.addr[i];
  133. return ret;
  134. }