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