vma.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. static bool compare_legacy_flags(vm_flags_t legacy_flags, vma_flags_t flags)
  3. {
  4. const unsigned long legacy_val = legacy_flags;
  5. /* The lower word should contain the precise same value. */
  6. const unsigned long flags_lower = flags.__vma_flags[0];
  7. #if NUM_VMA_FLAGS > BITS_PER_LONG
  8. int i;
  9. /* All bits in higher flag values should be zero. */
  10. for (i = 1; i < NUM_VMA_FLAGS / BITS_PER_LONG; i++) {
  11. if (flags.__vma_flags[i] != 0)
  12. return false;
  13. }
  14. #endif
  15. static_assert(sizeof(legacy_flags) == sizeof(unsigned long));
  16. return legacy_val == flags_lower;
  17. }
  18. static bool test_copy_vma(void)
  19. {
  20. vm_flags_t vm_flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
  21. struct mm_struct mm = {};
  22. bool need_locks = false;
  23. VMA_ITERATOR(vmi, &mm, 0);
  24. struct vm_area_struct *vma, *vma_new, *vma_next;
  25. /* Move backwards and do not merge. */
  26. vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, vm_flags);
  27. vma_new = copy_vma(&vma, 0, 0x2000, 0, &need_locks);
  28. ASSERT_NE(vma_new, vma);
  29. ASSERT_EQ(vma_new->vm_start, 0);
  30. ASSERT_EQ(vma_new->vm_end, 0x2000);
  31. ASSERT_EQ(vma_new->vm_pgoff, 0);
  32. vma_assert_attached(vma_new);
  33. cleanup_mm(&mm, &vmi);
  34. /* Move a VMA into position next to another and merge the two. */
  35. vma = alloc_and_link_vma(&mm, 0, 0x2000, 0, vm_flags);
  36. vma_next = alloc_and_link_vma(&mm, 0x6000, 0x8000, 6, vm_flags);
  37. vma_new = copy_vma(&vma, 0x4000, 0x2000, 4, &need_locks);
  38. vma_assert_attached(vma_new);
  39. ASSERT_EQ(vma_new, vma_next);
  40. cleanup_mm(&mm, &vmi);
  41. return true;
  42. }
  43. static bool test_vma_flags_unchanged(void)
  44. {
  45. vma_flags_t flags = EMPTY_VMA_FLAGS;
  46. vm_flags_t legacy_flags = 0;
  47. int bit;
  48. struct vm_area_struct vma;
  49. struct vm_area_desc desc;
  50. vma.flags = EMPTY_VMA_FLAGS;
  51. desc.vma_flags = EMPTY_VMA_FLAGS;
  52. for (bit = 0; bit < BITS_PER_LONG; bit++) {
  53. vma_flags_t mask = mk_vma_flags(bit);
  54. legacy_flags |= (1UL << bit);
  55. /* Individual flags. */
  56. vma_flags_set(&flags, bit);
  57. ASSERT_TRUE(compare_legacy_flags(legacy_flags, flags));
  58. /* Via mask. */
  59. vma_flags_set_mask(&flags, mask);
  60. ASSERT_TRUE(compare_legacy_flags(legacy_flags, flags));
  61. /* Same for VMA. */
  62. vma_set_flags(&vma, bit);
  63. ASSERT_TRUE(compare_legacy_flags(legacy_flags, vma.flags));
  64. vma_set_flags_mask(&vma, mask);
  65. ASSERT_TRUE(compare_legacy_flags(legacy_flags, vma.flags));
  66. /* Same for VMA descriptor. */
  67. vma_desc_set_flags(&desc, bit);
  68. ASSERT_TRUE(compare_legacy_flags(legacy_flags, desc.vma_flags));
  69. vma_desc_set_flags_mask(&desc, mask);
  70. ASSERT_TRUE(compare_legacy_flags(legacy_flags, desc.vma_flags));
  71. }
  72. return true;
  73. }
  74. static bool test_vma_flags_cleared(void)
  75. {
  76. const vma_flags_t empty = EMPTY_VMA_FLAGS;
  77. vma_flags_t flags;
  78. int i;
  79. /* Set all bits high. */
  80. memset(&flags, 1, sizeof(flags));
  81. /* Try to clear. */
  82. vma_flags_clear_all(&flags);
  83. /* Equal to EMPTY_VMA_FLAGS? */
  84. ASSERT_EQ(memcmp(&empty, &flags, sizeof(flags)), 0);
  85. /* Make sure every unsigned long entry in bitmap array zero. */
  86. for (i = 0; i < sizeof(flags) / BITS_PER_LONG; i++) {
  87. const unsigned long val = flags.__vma_flags[i];
  88. ASSERT_EQ(val, 0);
  89. }
  90. return true;
  91. }
  92. /*
  93. * Assert that VMA flag functions that operate at the system word level function
  94. * correctly.
  95. */
  96. static bool test_vma_flags_word(void)
  97. {
  98. vma_flags_t flags = EMPTY_VMA_FLAGS;
  99. const vma_flags_t comparison =
  100. mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT, 64, 65);
  101. /* Set some custom high flags. */
  102. vma_flags_set(&flags, 64, 65);
  103. /* Now overwrite the first word. */
  104. vma_flags_overwrite_word(&flags, VM_READ | VM_WRITE);
  105. /* Ensure they are equal. */
  106. ASSERT_EQ(memcmp(&flags, &comparison, sizeof(flags)), 0);
  107. flags = EMPTY_VMA_FLAGS;
  108. vma_flags_set(&flags, 64, 65);
  109. /* Do the same with the _once() equivalent. */
  110. vma_flags_overwrite_word_once(&flags, VM_READ | VM_WRITE);
  111. ASSERT_EQ(memcmp(&flags, &comparison, sizeof(flags)), 0);
  112. flags = EMPTY_VMA_FLAGS;
  113. vma_flags_set(&flags, 64, 65);
  114. /* Make sure we can set a word without disturbing other bits. */
  115. vma_flags_set(&flags, VMA_WRITE_BIT);
  116. vma_flags_set_word(&flags, VM_READ);
  117. ASSERT_EQ(memcmp(&flags, &comparison, sizeof(flags)), 0);
  118. flags = EMPTY_VMA_FLAGS;
  119. vma_flags_set(&flags, 64, 65);
  120. /* Make sure we can clear a word without disturbing other bits. */
  121. vma_flags_set(&flags, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
  122. vma_flags_clear_word(&flags, VM_EXEC);
  123. ASSERT_EQ(memcmp(&flags, &comparison, sizeof(flags)), 0);
  124. return true;
  125. }
  126. /* Ensure that vma_flags_test() and friends works correctly. */
  127. static bool test_vma_flags_test(void)
  128. {
  129. const vma_flags_t flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
  130. VMA_EXEC_BIT, 64, 65);
  131. struct vm_area_struct vma;
  132. struct vm_area_desc desc;
  133. vma.flags = flags;
  134. desc.vma_flags = flags;
  135. #define do_test(...) \
  136. ASSERT_TRUE(vma_flags_test(&flags, __VA_ARGS__)); \
  137. ASSERT_TRUE(vma_desc_test_flags(&desc, __VA_ARGS__))
  138. #define do_test_all_true(...) \
  139. ASSERT_TRUE(vma_flags_test_all(&flags, __VA_ARGS__)); \
  140. ASSERT_TRUE(vma_test_all_flags(&vma, __VA_ARGS__))
  141. #define do_test_all_false(...) \
  142. ASSERT_FALSE(vma_flags_test_all(&flags, __VA_ARGS__)); \
  143. ASSERT_FALSE(vma_test_all_flags(&vma, __VA_ARGS__))
  144. /*
  145. * Testing for some flags that are present, some that are not - should
  146. * pass. ANY flags matching should work.
  147. */
  148. do_test(VMA_READ_BIT, VMA_MAYREAD_BIT, VMA_SEQ_READ_BIT);
  149. /* However, the ...test_all() variant should NOT pass. */
  150. do_test_all_false(VMA_READ_BIT, VMA_MAYREAD_BIT, VMA_SEQ_READ_BIT);
  151. /* But should pass for flags present. */
  152. do_test_all_true(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64, 65);
  153. /* Also subsets... */
  154. do_test_all_true(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64);
  155. do_test_all_true(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
  156. do_test_all_true(VMA_READ_BIT, VMA_WRITE_BIT);
  157. do_test_all_true(VMA_READ_BIT);
  158. /*
  159. * Check _mask variant. We don't need to test extensively as macro
  160. * helper is the equivalent.
  161. */
  162. ASSERT_TRUE(vma_flags_test_mask(&flags, flags));
  163. ASSERT_TRUE(vma_flags_test_all_mask(&flags, flags));
  164. /* Single bits. */
  165. do_test(VMA_READ_BIT);
  166. do_test(VMA_WRITE_BIT);
  167. do_test(VMA_EXEC_BIT);
  168. #if NUM_VMA_FLAG_BITS > 64
  169. do_test(64);
  170. do_test(65);
  171. #endif
  172. /* Two bits. */
  173. do_test(VMA_READ_BIT, VMA_WRITE_BIT);
  174. do_test(VMA_READ_BIT, VMA_EXEC_BIT);
  175. do_test(VMA_WRITE_BIT, VMA_EXEC_BIT);
  176. /* Ordering shouldn't matter. */
  177. do_test(VMA_WRITE_BIT, VMA_READ_BIT);
  178. do_test(VMA_EXEC_BIT, VMA_READ_BIT);
  179. do_test(VMA_EXEC_BIT, VMA_WRITE_BIT);
  180. #if NUM_VMA_FLAG_BITS > 64
  181. do_test(VMA_READ_BIT, 64);
  182. do_test(VMA_WRITE_BIT, 64);
  183. do_test(64, VMA_READ_BIT);
  184. do_test(64, VMA_WRITE_BIT);
  185. do_test(VMA_READ_BIT, 65);
  186. do_test(VMA_WRITE_BIT, 65);
  187. do_test(65, VMA_READ_BIT);
  188. do_test(65, VMA_WRITE_BIT);
  189. #endif
  190. /* Three bits. */
  191. do_test(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
  192. #if NUM_VMA_FLAG_BITS > 64
  193. /* No need to consider every single permutation. */
  194. do_test(VMA_READ_BIT, VMA_WRITE_BIT, 64);
  195. do_test(VMA_READ_BIT, VMA_WRITE_BIT, 65);
  196. /* Four bits. */
  197. do_test(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64);
  198. do_test(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 65);
  199. /* Five bits. */
  200. do_test(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64, 65);
  201. #endif
  202. #undef do_test
  203. #undef do_test_all_true
  204. #undef do_test_all_false
  205. return true;
  206. }
  207. /* Ensure that vma_flags_clear() and friends works correctly. */
  208. static bool test_vma_flags_clear(void)
  209. {
  210. vma_flags_t flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
  211. VMA_EXEC_BIT, 64, 65);
  212. vma_flags_t mask = mk_vma_flags(VMA_EXEC_BIT, 64);
  213. struct vm_area_struct vma;
  214. struct vm_area_desc desc;
  215. vma.flags = flags;
  216. desc.vma_flags = flags;
  217. /* Cursory check of _mask() variant, as the helper macros imply. */
  218. vma_flags_clear_mask(&flags, mask);
  219. vma_flags_clear_mask(&vma.flags, mask);
  220. vma_desc_clear_flags_mask(&desc, mask);
  221. ASSERT_FALSE(vma_flags_test(&flags, VMA_EXEC_BIT, 64));
  222. ASSERT_FALSE(vma_flags_test(&vma.flags, VMA_EXEC_BIT, 64));
  223. ASSERT_FALSE(vma_desc_test_flags(&desc, VMA_EXEC_BIT, 64));
  224. /* Reset. */
  225. vma_flags_set(&flags, VMA_EXEC_BIT, 64);
  226. vma_set_flags(&vma, VMA_EXEC_BIT, 64);
  227. vma_desc_set_flags(&desc, VMA_EXEC_BIT, 64);
  228. /*
  229. * Clear the flags and assert clear worked, then reset flags back to
  230. * include specified flags.
  231. */
  232. #define do_test_and_reset(...) \
  233. vma_flags_clear(&flags, __VA_ARGS__); \
  234. vma_flags_clear(&vma.flags, __VA_ARGS__); \
  235. vma_desc_clear_flags(&desc, __VA_ARGS__); \
  236. ASSERT_FALSE(vma_flags_test(&flags, __VA_ARGS__)); \
  237. ASSERT_FALSE(vma_flags_test(&vma.flags, __VA_ARGS__)); \
  238. ASSERT_FALSE(vma_desc_test_flags(&desc, __VA_ARGS__)); \
  239. vma_flags_set(&flags, __VA_ARGS__); \
  240. vma_set_flags(&vma, __VA_ARGS__); \
  241. vma_desc_set_flags(&desc, __VA_ARGS__)
  242. /* Single flags. */
  243. do_test_and_reset(VMA_READ_BIT);
  244. do_test_and_reset(VMA_WRITE_BIT);
  245. do_test_and_reset(VMA_EXEC_BIT);
  246. do_test_and_reset(64);
  247. do_test_and_reset(65);
  248. /* Two flags, in different orders. */
  249. do_test_and_reset(VMA_READ_BIT, VMA_WRITE_BIT);
  250. do_test_and_reset(VMA_READ_BIT, VMA_EXEC_BIT);
  251. do_test_and_reset(VMA_READ_BIT, 64);
  252. do_test_and_reset(VMA_READ_BIT, 65);
  253. do_test_and_reset(VMA_WRITE_BIT, VMA_READ_BIT);
  254. do_test_and_reset(VMA_WRITE_BIT, VMA_EXEC_BIT);
  255. do_test_and_reset(VMA_WRITE_BIT, 64);
  256. do_test_and_reset(VMA_WRITE_BIT, 65);
  257. do_test_and_reset(VMA_EXEC_BIT, VMA_READ_BIT);
  258. do_test_and_reset(VMA_EXEC_BIT, VMA_WRITE_BIT);
  259. do_test_and_reset(VMA_EXEC_BIT, 64);
  260. do_test_and_reset(VMA_EXEC_BIT, 65);
  261. do_test_and_reset(64, VMA_READ_BIT);
  262. do_test_and_reset(64, VMA_WRITE_BIT);
  263. do_test_and_reset(64, VMA_EXEC_BIT);
  264. do_test_and_reset(64, 65);
  265. do_test_and_reset(65, VMA_READ_BIT);
  266. do_test_and_reset(65, VMA_WRITE_BIT);
  267. do_test_and_reset(65, VMA_EXEC_BIT);
  268. do_test_and_reset(65, 64);
  269. /* Three flags. */
  270. #undef do_test_some_missing
  271. #undef do_test_and_reset
  272. return true;
  273. }
  274. static void run_vma_tests(int *num_tests, int *num_fail)
  275. {
  276. TEST(copy_vma);
  277. TEST(vma_flags_unchanged);
  278. TEST(vma_flags_cleared);
  279. TEST(vma_flags_word);
  280. TEST(vma_flags_test);
  281. TEST(vma_flags_clear);
  282. }