1// SPDX-License-Identifier: GPL-2.0 2#include <bpf/btf.h> 3#include <test_btf.h> 4#include <linux/btf.h> 5#include <test_progs.h> 6#include <network_helpers.h> 7 8#include "linked_list.skel.h" 9#include "linked_list_fail.skel.h" 10 11static char log_buf[1024 * 1024]; 12 13static struct { 14 const char *prog_name; 15 const char *err_msg; 16} linked_list_fail_tests[] = { 17#define TEST(test, off) \ 18 { #test "_missing_lock_push_front", \ 19 "bpf_spin_lock at off=" #off " must be held for bpf_list_head" }, \ 20 { #test "_missing_lock_push_back", \ 21 "bpf_spin_lock at off=" #off " must be held for bpf_list_head" }, \ 22 { #test "_missing_lock_pop_front", \ 23 "bpf_spin_lock at off=" #off " must be held for bpf_list_head" }, \ 24 { #test "_missing_lock_pop_back", \ 25 "bpf_spin_lock at off=" #off " must be held for bpf_list_head" }, 26 TEST(kptr, 40) 27 TEST(global, 16) 28 TEST(map, 0) 29 TEST(inner_map, 0) 30#undef TEST 31#define TEST(test, op) \ 32 { #test "_kptr_incorrect_lock_" #op, \ 33 "held lock and object are not in the same allocation\n" \ 34 "bpf_spin_lock at off=40 must be held for bpf_list_head" }, \ 35 { #test "_global_incorrect_lock_" #op, \ 36 "held lock and object are not in the same allocation\n" \ 37 "bpf_spin_lock at off=16 must be held for bpf_list_head" }, \ 38 { #test "_map_incorrect_lock_" #op, \ 39 "held lock and object are not in the same allocation\n" \ 40 "bpf_spin_lock at off=0 must be held for bpf_list_head" }, \ 41 { #test "_inner_map_incorrect_lock_" #op, \ 42 "held lock and object are not in the same allocation\n" \ 43 "bpf_spin_lock at off=0 must be held for bpf_list_head" }, 44 TEST(kptr, push_front) 45 TEST(kptr, push_back) 46 TEST(kptr, pop_front) 47 TEST(kptr, pop_back) 48 TEST(global, push_front) 49 TEST(global, push_back) 50 TEST(global, pop_front) 51 TEST(global, pop_back) 52 TEST(map, push_front) 53 TEST(map, push_back) 54 TEST(map, pop_front) 55 TEST(map, pop_back) 56 TEST(inner_map, push_front) 57 TEST(inner_map, push_back) 58 TEST(inner_map, pop_front) 59 TEST(inner_map, pop_back) 60#undef TEST 61 { "map_compat_kprobe", "tracing progs cannot use bpf_{list_head,rb_root} yet" }, 62 { "map_compat_kretprobe", "tracing progs cannot use bpf_{list_head,rb_root} yet" }, 63 { "map_compat_tp", "tracing progs cannot use bpf_{list_head,rb_root} yet" }, 64 { "map_compat_perf", "tracing progs cannot use bpf_{list_head,rb_root} yet" }, 65 { "map_compat_raw_tp", "tracing progs cannot use bpf_{list_head,rb_root} yet" }, 66 { "map_compat_raw_tp_w", "tracing progs cannot use bpf_{list_head,rb_root} yet" }, 67 { "obj_type_id_oor", "local type ID argument must be in range [0, U32_MAX]" }, 68 { "obj_new_no_composite", "bpf_obj_new/bpf_percpu_obj_new type ID argument must be of a struct" }, 69 { "obj_new_no_struct", "bpf_obj_new/bpf_percpu_obj_new type ID argument must be of a struct" }, 70 { "obj_drop_non_zero_off", "R1 must have zero offset when passed to release func" }, 71 { "new_null_ret", "R0 invalid mem access 'ptr_or_null_'" }, 72 { "obj_new_acq", "Unreleased reference id=" }, 73 { "use_after_drop", "invalid mem access 'scalar'" }, 74 { "ptr_walk_scalar", "type=scalar expected=percpu_ptr_" }, 75 { "direct_read_lock", "direct access to bpf_spin_lock is disallowed" }, 76 { "direct_write_lock", "direct access to bpf_spin_lock is disallowed" }, 77 { "direct_read_head", "direct access to bpf_list_head is disallowed" }, 78 { "direct_write_head", "direct access to bpf_list_head is disallowed" }, 79 { "direct_read_node", "direct access to bpf_list_node is disallowed" }, 80 { "direct_write_node", "direct access to bpf_list_node is disallowed" }, 81 { "use_after_unlock_push_front", "invalid mem access 'scalar'" }, 82 { "use_after_unlock_push_back", "invalid mem access 'scalar'" }, 83 { "double_push_front", "arg#1 expected pointer to allocated object" }, 84 { "double_push_back", "arg#1 expected pointer to allocated object" }, 85 { "no_node_value_type", "bpf_list_node not found at offset=0" }, 86 { "incorrect_value_type", 87 "operation on bpf_list_head expects arg#1 bpf_list_node at offset=48 in struct foo, " 88 "but arg is at offset=0 in struct bar" }, 89 { "incorrect_node_var_off", "variable ptr_ access var_off=(0x0; 0xffffffff) disallowed" }, 90 { "incorrect_node_off1", "bpf_list_node not found at offset=49" }, 91 { "incorrect_node_off2", "arg#1 offset=0, but expected bpf_list_node at offset=48 in struct foo" }, 92 { "no_head_type", "bpf_list_head not found at offset=0" }, 93 { "incorrect_head_var_off1", "R1 doesn't have constant offset" }, 94 { "incorrect_head_var_off2", "variable ptr_ access var_off=(0x0; 0xffffffff) disallowed" }, 95 { "incorrect_head_off1", "bpf_list_head not found at offset=25" }, 96 { "incorrect_head_off2", "bpf_list_head not found at offset=1" }, 97 { "pop_front_off", "off 48 doesn't point to 'struct bpf_spin_lock' that is at 40" }, 98 { "pop_back_off", "off 48 doesn't point to 'struct bpf_spin_lock' that is at 40" }, 99}; 100 101static void test_linked_list_fail_prog(const char *prog_name, const char *err_msg) 102{ 103 LIBBPF_OPTS(bpf_object_open_opts, opts, .kernel_log_buf = log_buf, 104 .kernel_log_size = sizeof(log_buf), 105 .kernel_log_level = 1); 106 struct linked_list_fail *skel; 107 struct bpf_program *prog; 108 int ret; 109 110 skel = linked_list_fail__open_opts(&opts); 111 if (!ASSERT_OK_PTR(skel, "linked_list_fail__open_opts")) 112 return; 113 114 prog = bpf_object__find_program_by_name(skel->obj, prog_name); 115 if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name")) 116 goto end; 117 118 bpf_program__set_autoload(prog, true); 119 120 ret = linked_list_fail__load(skel); 121 if (!ASSERT_ERR(ret, "linked_list_fail__load must fail")) 122 goto end; 123 124 if (!ASSERT_OK_PTR(strstr(log_buf, err_msg), "expected error message")) { 125 fprintf(stderr, "Expected: %s\n", err_msg); 126 fprintf(stderr, "Verifier: %s\n", log_buf); 127 } 128 129end: 130 linked_list_fail__destroy(skel); 131} 132 133static void clear_fields(struct bpf_map *map) 134{ 135 char buf[24]; 136 int key = 0; 137 138 memset(buf, 0xff, sizeof(buf)); 139 ASSERT_OK(bpf_map__update_elem(map, &key, sizeof(key), buf, sizeof(buf), 0), "check_and_free_fields"); 140} 141 142enum { 143 TEST_ALL, 144 PUSH_POP, 145 PUSH_POP_MULT, 146 LIST_IN_LIST, 147}; 148 149static void test_linked_list_success(int mode, bool leave_in_map) 150{ 151 LIBBPF_OPTS(bpf_test_run_opts, opts, 152 .data_in = &pkt_v4, 153 .data_size_in = sizeof(pkt_v4), 154 .repeat = 1, 155 ); 156 struct linked_list *skel; 157 int ret; 158 159 skel = linked_list__open_and_load(); 160 if (!ASSERT_OK_PTR(skel, "linked_list__open_and_load")) 161 return; 162 163 if (mode == LIST_IN_LIST) 164 goto lil; 165 if (mode == PUSH_POP_MULT) 166 goto ppm; 167 168 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.map_list_push_pop), &opts); 169 ASSERT_OK(ret, "map_list_push_pop"); 170 ASSERT_OK(opts.retval, "map_list_push_pop retval"); 171 if (!leave_in_map) 172 clear_fields(skel->maps.array_map); 173 174 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.inner_map_list_push_pop), &opts); 175 ASSERT_OK(ret, "inner_map_list_push_pop"); 176 ASSERT_OK(opts.retval, "inner_map_list_push_pop retval"); 177 if (!leave_in_map) 178 clear_fields(skel->maps.inner_map); 179 180 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.global_list_push_pop), &opts); 181 ASSERT_OK(ret, "global_list_push_pop"); 182 ASSERT_OK(opts.retval, "global_list_push_pop retval"); 183 if (!leave_in_map) 184 clear_fields(skel->maps.bss_A); 185 186 if (mode == PUSH_POP) 187 goto end; 188 189ppm: 190 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.map_list_push_pop_multiple), &opts); 191 ASSERT_OK(ret, "map_list_push_pop_multiple"); 192 ASSERT_OK(opts.retval, "map_list_push_pop_multiple retval"); 193 if (!leave_in_map) 194 clear_fields(skel->maps.array_map); 195 196 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.inner_map_list_push_pop_multiple), &opts); 197 ASSERT_OK(ret, "inner_map_list_push_pop_multiple"); 198 ASSERT_OK(opts.retval, "inner_map_list_push_pop_multiple retval"); 199 if (!leave_in_map) 200 clear_fields(skel->maps.inner_map); 201 202 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.global_list_push_pop_multiple), &opts); 203 ASSERT_OK(ret, "global_list_push_pop_multiple"); 204 ASSERT_OK(opts.retval, "global_list_push_pop_multiple retval"); 205 if (!leave_in_map) 206 clear_fields(skel->maps.bss_A); 207 208 if (mode == PUSH_POP_MULT) 209 goto end; 210 211lil: 212 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.map_list_in_list), &opts); 213 ASSERT_OK(ret, "map_list_in_list"); 214 ASSERT_OK(opts.retval, "map_list_in_list retval"); 215 if (!leave_in_map) 216 clear_fields(skel->maps.array_map); 217 218 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.inner_map_list_in_list), &opts); 219 ASSERT_OK(ret, "inner_map_list_in_list"); 220 ASSERT_OK(opts.retval, "inner_map_list_in_list retval"); 221 if (!leave_in_map) 222 clear_fields(skel->maps.inner_map); 223 224 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.global_list_in_list), &opts); 225 ASSERT_OK(ret, "global_list_in_list"); 226 ASSERT_OK(opts.retval, "global_list_in_list retval"); 227 if (!leave_in_map) 228 clear_fields(skel->maps.bss_A); 229end: 230 linked_list__destroy(skel); 231} 232 233#define SPIN_LOCK 2 234#define LIST_HEAD 3 235#define LIST_NODE 4 236 237static struct btf *init_btf(void) 238{ 239 int id, lid, hid, nid; 240 struct btf *btf; 241 242 btf = btf__new_empty(); 243 if (!ASSERT_OK_PTR(btf, "btf__new_empty")) 244 return NULL; 245 id = btf__add_int(btf, "int", 4, BTF_INT_SIGNED); 246 if (!ASSERT_EQ(id, 1, "btf__add_int")) 247 goto end; 248 lid = btf__add_struct(btf, "bpf_spin_lock", 4); 249 if (!ASSERT_EQ(lid, SPIN_LOCK, "btf__add_struct bpf_spin_lock")) 250 goto end; 251 hid = btf__add_struct(btf, "bpf_list_head", 16); 252 if (!ASSERT_EQ(hid, LIST_HEAD, "btf__add_struct bpf_list_head")) 253 goto end; 254 nid = btf__add_struct(btf, "bpf_list_node", 24); 255 if (!ASSERT_EQ(nid, LIST_NODE, "btf__add_struct bpf_list_node")) 256 goto end; 257 return btf; 258end: 259 btf__free(btf); 260 return NULL; 261} 262 263static void list_and_rb_node_same_struct(bool refcount_field) 264{ 265 int bpf_rb_node_btf_id, bpf_refcount_btf_id = 0, foo_btf_id; 266 struct btf *btf; 267 int id, err; 268 269 btf = init_btf(); 270 if (!ASSERT_OK_PTR(btf, "init_btf")) 271 return; 272 273 bpf_rb_node_btf_id = btf__add_struct(btf, "bpf_rb_node", 32); 274 if (!ASSERT_GT(bpf_rb_node_btf_id, 0, "btf__add_struct bpf_rb_node")) 275 return; 276 277 if (refcount_field) { 278 bpf_refcount_btf_id = btf__add_struct(btf, "bpf_refcount", 4); 279 if (!ASSERT_GT(bpf_refcount_btf_id, 0, "btf__add_struct bpf_refcount")) 280 return; 281 } 282 283 id = btf__add_struct(btf, "bar", refcount_field ? 60 : 56); 284 if (!ASSERT_GT(id, 0, "btf__add_struct bar")) 285 return; 286 err = btf__add_field(btf, "a", LIST_NODE, 0, 0); 287 if (!ASSERT_OK(err, "btf__add_field bar::a")) 288 return; 289 err = btf__add_field(btf, "c", bpf_rb_node_btf_id, 192, 0); 290 if (!ASSERT_OK(err, "btf__add_field bar::c")) 291 return; 292 if (refcount_field) { 293 err = btf__add_field(btf, "ref", bpf_refcount_btf_id, 448, 0); 294 if (!ASSERT_OK(err, "btf__add_field bar::ref")) 295 return; 296 } 297 298 foo_btf_id = btf__add_struct(btf, "foo", 20); 299 if (!ASSERT_GT(foo_btf_id, 0, "btf__add_struct foo")) 300 return; 301 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 302 if (!ASSERT_OK(err, "btf__add_field foo::a")) 303 return; 304 err = btf__add_field(btf, "b", SPIN_LOCK, 128, 0); 305 if (!ASSERT_OK(err, "btf__add_field foo::b")) 306 return; 307 id = btf__add_decl_tag(btf, "contains:bar:a", foo_btf_id, 0); 308 if (!ASSERT_GT(id, 0, "btf__add_decl_tag contains:bar:a")) 309 return; 310 311 err = btf__load_into_kernel(btf); 312 ASSERT_EQ(err, refcount_field ? 0 : -EINVAL, "check btf"); 313 btf__free(btf); 314} 315 316static void test_btf(void) 317{ 318 struct btf *btf = NULL; 319 int id, err; 320 321 while (test__start_subtest("btf: too many locks")) { 322 btf = init_btf(); 323 if (!ASSERT_OK_PTR(btf, "init_btf")) 324 break; 325 id = btf__add_struct(btf, "foo", 24); 326 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 327 break; 328 err = btf__add_field(btf, "a", SPIN_LOCK, 0, 0); 329 if (!ASSERT_OK(err, "btf__add_struct foo::a")) 330 break; 331 err = btf__add_field(btf, "b", SPIN_LOCK, 32, 0); 332 if (!ASSERT_OK(err, "btf__add_struct foo::a")) 333 break; 334 err = btf__add_field(btf, "c", LIST_HEAD, 64, 0); 335 if (!ASSERT_OK(err, "btf__add_struct foo::a")) 336 break; 337 338 err = btf__load_into_kernel(btf); 339 ASSERT_EQ(err, -E2BIG, "check btf"); 340 btf__free(btf); 341 break; 342 } 343 344 while (test__start_subtest("btf: missing lock")) { 345 btf = init_btf(); 346 if (!ASSERT_OK_PTR(btf, "init_btf")) 347 break; 348 id = btf__add_struct(btf, "foo", 16); 349 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 350 break; 351 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 352 if (!ASSERT_OK(err, "btf__add_struct foo::a")) 353 break; 354 id = btf__add_decl_tag(btf, "contains:baz:a", 5, 0); 355 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:baz:a")) 356 break; 357 id = btf__add_struct(btf, "baz", 16); 358 if (!ASSERT_EQ(id, 7, "btf__add_struct baz")) 359 break; 360 err = btf__add_field(btf, "a", LIST_NODE, 0, 0); 361 if (!ASSERT_OK(err, "btf__add_field baz::a")) 362 break; 363 364 err = btf__load_into_kernel(btf); 365 ASSERT_EQ(err, -EINVAL, "check btf"); 366 btf__free(btf); 367 break; 368 } 369 370 while (test__start_subtest("btf: bad offset")) { 371 btf = init_btf(); 372 if (!ASSERT_OK_PTR(btf, "init_btf")) 373 break; 374 id = btf__add_struct(btf, "foo", 36); 375 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 376 break; 377 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 378 if (!ASSERT_OK(err, "btf__add_field foo::a")) 379 break; 380 err = btf__add_field(btf, "b", LIST_NODE, 0, 0); 381 if (!ASSERT_OK(err, "btf__add_field foo::b")) 382 break; 383 err = btf__add_field(btf, "c", SPIN_LOCK, 0, 0); 384 if (!ASSERT_OK(err, "btf__add_field foo::c")) 385 break; 386 id = btf__add_decl_tag(btf, "contains:foo:b", 5, 0); 387 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:foo:b")) 388 break; 389 390 err = btf__load_into_kernel(btf); 391 ASSERT_EQ(err, -EEXIST, "check btf"); 392 btf__free(btf); 393 break; 394 } 395 396 while (test__start_subtest("btf: missing contains:")) { 397 btf = init_btf(); 398 if (!ASSERT_OK_PTR(btf, "init_btf")) 399 break; 400 id = btf__add_struct(btf, "foo", 24); 401 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 402 break; 403 err = btf__add_field(btf, "a", SPIN_LOCK, 0, 0); 404 if (!ASSERT_OK(err, "btf__add_field foo::a")) 405 break; 406 err = btf__add_field(btf, "b", LIST_HEAD, 64, 0); 407 if (!ASSERT_OK(err, "btf__add_field foo::b")) 408 break; 409 410 err = btf__load_into_kernel(btf); 411 ASSERT_EQ(err, -EINVAL, "check btf"); 412 btf__free(btf); 413 break; 414 } 415 416 while (test__start_subtest("btf: missing struct")) { 417 btf = init_btf(); 418 if (!ASSERT_OK_PTR(btf, "init_btf")) 419 break; 420 id = btf__add_struct(btf, "foo", 24); 421 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 422 break; 423 err = btf__add_field(btf, "a", SPIN_LOCK, 0, 0); 424 if (!ASSERT_OK(err, "btf__add_field foo::a")) 425 break; 426 err = btf__add_field(btf, "b", LIST_HEAD, 64, 0); 427 if (!ASSERT_OK(err, "btf__add_field foo::b")) 428 break; 429 id = btf__add_decl_tag(btf, "contains:bar:bar", 5, 1); 430 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:bar")) 431 break; 432 433 err = btf__load_into_kernel(btf); 434 ASSERT_EQ(err, -ENOENT, "check btf"); 435 btf__free(btf); 436 break; 437 } 438 439 while (test__start_subtest("btf: missing node")) { 440 btf = init_btf(); 441 if (!ASSERT_OK_PTR(btf, "init_btf")) 442 break; 443 id = btf__add_struct(btf, "foo", 24); 444 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 445 break; 446 err = btf__add_field(btf, "a", SPIN_LOCK, 0, 0); 447 if (!ASSERT_OK(err, "btf__add_field foo::a")) 448 break; 449 err = btf__add_field(btf, "b", LIST_HEAD, 64, 0); 450 if (!ASSERT_OK(err, "btf__add_field foo::b")) 451 break; 452 id = btf__add_decl_tag(btf, "contains:foo:c", 5, 1); 453 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:foo:c")) 454 break; 455 456 err = btf__load_into_kernel(btf); 457 btf__free(btf); 458 ASSERT_EQ(err, -ENOENT, "check btf"); 459 break; 460 } 461 462 while (test__start_subtest("btf: node incorrect type")) { 463 btf = init_btf(); 464 if (!ASSERT_OK_PTR(btf, "init_btf")) 465 break; 466 id = btf__add_struct(btf, "foo", 20); 467 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 468 break; 469 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 470 if (!ASSERT_OK(err, "btf__add_field foo::a")) 471 break; 472 err = btf__add_field(btf, "b", SPIN_LOCK, 128, 0); 473 if (!ASSERT_OK(err, "btf__add_field foo::b")) 474 break; 475 id = btf__add_decl_tag(btf, "contains:bar:a", 5, 0); 476 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:a")) 477 break; 478 id = btf__add_struct(btf, "bar", 4); 479 if (!ASSERT_EQ(id, 7, "btf__add_struct bar")) 480 break; 481 err = btf__add_field(btf, "a", SPIN_LOCK, 0, 0); 482 if (!ASSERT_OK(err, "btf__add_field bar::a")) 483 break; 484 485 err = btf__load_into_kernel(btf); 486 ASSERT_EQ(err, -EINVAL, "check btf"); 487 btf__free(btf); 488 break; 489 } 490 491 while (test__start_subtest("btf: multiple bpf_list_node with name b")) { 492 btf = init_btf(); 493 if (!ASSERT_OK_PTR(btf, "init_btf")) 494 break; 495 id = btf__add_struct(btf, "foo", 52); 496 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 497 break; 498 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 499 if (!ASSERT_OK(err, "btf__add_field foo::a")) 500 break; 501 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 502 if (!ASSERT_OK(err, "btf__add_field foo::b")) 503 break; 504 err = btf__add_field(btf, "b", LIST_NODE, 256, 0); 505 if (!ASSERT_OK(err, "btf__add_field foo::c")) 506 break; 507 err = btf__add_field(btf, "d", SPIN_LOCK, 384, 0); 508 if (!ASSERT_OK(err, "btf__add_field foo::d")) 509 break; 510 id = btf__add_decl_tag(btf, "contains:foo:b", 5, 0); 511 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:foo:b")) 512 break; 513 514 err = btf__load_into_kernel(btf); 515 ASSERT_EQ(err, -EINVAL, "check btf"); 516 btf__free(btf); 517 break; 518 } 519 520 while (test__start_subtest("btf: owning | owned AA cycle")) { 521 btf = init_btf(); 522 if (!ASSERT_OK_PTR(btf, "init_btf")) 523 break; 524 id = btf__add_struct(btf, "foo", 44); 525 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 526 break; 527 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 528 if (!ASSERT_OK(err, "btf__add_field foo::a")) 529 break; 530 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 531 if (!ASSERT_OK(err, "btf__add_field foo::b")) 532 break; 533 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 534 if (!ASSERT_OK(err, "btf__add_field foo::c")) 535 break; 536 id = btf__add_decl_tag(btf, "contains:foo:b", 5, 0); 537 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:foo:b")) 538 break; 539 540 err = btf__load_into_kernel(btf); 541 ASSERT_EQ(err, -ELOOP, "check btf"); 542 btf__free(btf); 543 break; 544 } 545 546 while (test__start_subtest("btf: owning | owned ABA cycle")) { 547 btf = init_btf(); 548 if (!ASSERT_OK_PTR(btf, "init_btf")) 549 break; 550 id = btf__add_struct(btf, "foo", 44); 551 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 552 break; 553 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 554 if (!ASSERT_OK(err, "btf__add_field foo::a")) 555 break; 556 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 557 if (!ASSERT_OK(err, "btf__add_field foo::b")) 558 break; 559 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 560 if (!ASSERT_OK(err, "btf__add_field foo::c")) 561 break; 562 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0); 563 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b")) 564 break; 565 id = btf__add_struct(btf, "bar", 44); 566 if (!ASSERT_EQ(id, 7, "btf__add_struct bar")) 567 break; 568 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 569 if (!ASSERT_OK(err, "btf__add_field bar::a")) 570 break; 571 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 572 if (!ASSERT_OK(err, "btf__add_field bar::b")) 573 break; 574 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 575 if (!ASSERT_OK(err, "btf__add_field bar::c")) 576 break; 577 id = btf__add_decl_tag(btf, "contains:foo:b", 7, 0); 578 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag contains:foo:b")) 579 break; 580 581 err = btf__load_into_kernel(btf); 582 ASSERT_EQ(err, -ELOOP, "check btf"); 583 btf__free(btf); 584 break; 585 } 586 587 while (test__start_subtest("btf: owning -> owned")) { 588 btf = init_btf(); 589 if (!ASSERT_OK_PTR(btf, "init_btf")) 590 break; 591 id = btf__add_struct(btf, "foo", 28); 592 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 593 break; 594 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 595 if (!ASSERT_OK(err, "btf__add_field foo::a")) 596 break; 597 err = btf__add_field(btf, "b", SPIN_LOCK, 192, 0); 598 if (!ASSERT_OK(err, "btf__add_field foo::b")) 599 break; 600 id = btf__add_decl_tag(btf, "contains:bar:a", 5, 0); 601 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:a")) 602 break; 603 id = btf__add_struct(btf, "bar", 24); 604 if (!ASSERT_EQ(id, 7, "btf__add_struct bar")) 605 break; 606 err = btf__add_field(btf, "a", LIST_NODE, 0, 0); 607 if (!ASSERT_OK(err, "btf__add_field bar::a")) 608 break; 609 610 err = btf__load_into_kernel(btf); 611 ASSERT_EQ(err, 0, "check btf"); 612 btf__free(btf); 613 break; 614 } 615 616 while (test__start_subtest("btf: owning -> owning | owned -> owned")) { 617 btf = init_btf(); 618 if (!ASSERT_OK_PTR(btf, "init_btf")) 619 break; 620 id = btf__add_struct(btf, "foo", 28); 621 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 622 break; 623 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 624 if (!ASSERT_OK(err, "btf__add_field foo::a")) 625 break; 626 err = btf__add_field(btf, "b", SPIN_LOCK, 192, 0); 627 if (!ASSERT_OK(err, "btf__add_field foo::b")) 628 break; 629 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0); 630 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b")) 631 break; 632 id = btf__add_struct(btf, "bar", 44); 633 if (!ASSERT_EQ(id, 7, "btf__add_struct bar")) 634 break; 635 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 636 if (!ASSERT_OK(err, "btf__add_field bar::a")) 637 break; 638 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 639 if (!ASSERT_OK(err, "btf__add_field bar::b")) 640 break; 641 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 642 if (!ASSERT_OK(err, "btf__add_field bar::c")) 643 break; 644 id = btf__add_decl_tag(btf, "contains:baz:a", 7, 0); 645 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag contains:baz:a")) 646 break; 647 id = btf__add_struct(btf, "baz", 24); 648 if (!ASSERT_EQ(id, 9, "btf__add_struct baz")) 649 break; 650 err = btf__add_field(btf, "a", LIST_NODE, 0, 0); 651 if (!ASSERT_OK(err, "btf__add_field baz:a")) 652 break; 653 654 err = btf__load_into_kernel(btf); 655 ASSERT_EQ(err, 0, "check btf"); 656 btf__free(btf); 657 break; 658 } 659 660 while (test__start_subtest("btf: owning | owned -> owning | owned -> owned")) { 661 btf = init_btf(); 662 if (!ASSERT_OK_PTR(btf, "init_btf")) 663 break; 664 id = btf__add_struct(btf, "foo", 44); 665 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 666 break; 667 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 668 if (!ASSERT_OK(err, "btf__add_field foo::a")) 669 break; 670 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 671 if (!ASSERT_OK(err, "btf__add_field foo::b")) 672 break; 673 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 674 if (!ASSERT_OK(err, "btf__add_field foo::c")) 675 break; 676 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0); 677 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b")) 678 break; 679 id = btf__add_struct(btf, "bar", 44); 680 if (!ASSERT_EQ(id, 7, "btf__add_struct bar")) 681 break; 682 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 683 if (!ASSERT_OK(err, "btf__add_field bar:a")) 684 break; 685 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 686 if (!ASSERT_OK(err, "btf__add_field bar:b")) 687 break; 688 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 689 if (!ASSERT_OK(err, "btf__add_field bar:c")) 690 break; 691 id = btf__add_decl_tag(btf, "contains:baz:a", 7, 0); 692 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag contains:baz:a")) 693 break; 694 id = btf__add_struct(btf, "baz", 24); 695 if (!ASSERT_EQ(id, 9, "btf__add_struct baz")) 696 break; 697 err = btf__add_field(btf, "a", LIST_NODE, 0, 0); 698 if (!ASSERT_OK(err, "btf__add_field baz:a")) 699 break; 700 701 err = btf__load_into_kernel(btf); 702 ASSERT_EQ(err, -ELOOP, "check btf"); 703 btf__free(btf); 704 break; 705 } 706 707 while (test__start_subtest("btf: owning -> owning | owned -> owning | owned -> owned")) { 708 btf = init_btf(); 709 if (!ASSERT_OK_PTR(btf, "init_btf")) 710 break; 711 id = btf__add_struct(btf, "foo", 20); 712 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 713 break; 714 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 715 if (!ASSERT_OK(err, "btf__add_field foo::a")) 716 break; 717 err = btf__add_field(btf, "b", SPIN_LOCK, 128, 0); 718 if (!ASSERT_OK(err, "btf__add_field foo::b")) 719 break; 720 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0); 721 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b")) 722 break; 723 id = btf__add_struct(btf, "bar", 44); 724 if (!ASSERT_EQ(id, 7, "btf__add_struct bar")) 725 break; 726 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 727 if (!ASSERT_OK(err, "btf__add_field bar::a")) 728 break; 729 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 730 if (!ASSERT_OK(err, "btf__add_field bar::b")) 731 break; 732 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 733 if (!ASSERT_OK(err, "btf__add_field bar::c")) 734 break; 735 id = btf__add_decl_tag(btf, "contains:baz:b", 7, 0); 736 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag")) 737 break; 738 id = btf__add_struct(btf, "baz", 44); 739 if (!ASSERT_EQ(id, 9, "btf__add_struct baz")) 740 break; 741 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 742 if (!ASSERT_OK(err, "btf__add_field bar::a")) 743 break; 744 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 745 if (!ASSERT_OK(err, "btf__add_field bar::b")) 746 break; 747 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 748 if (!ASSERT_OK(err, "btf__add_field bar::c")) 749 break; 750 id = btf__add_decl_tag(btf, "contains:bam:a", 9, 0); 751 if (!ASSERT_EQ(id, 10, "btf__add_decl_tag contains:bam:a")) 752 break; 753 id = btf__add_struct(btf, "bam", 24); 754 if (!ASSERT_EQ(id, 11, "btf__add_struct bam")) 755 break; 756 err = btf__add_field(btf, "a", LIST_NODE, 0, 0); 757 if (!ASSERT_OK(err, "btf__add_field bam::a")) 758 break; 759 760 err = btf__load_into_kernel(btf); 761 ASSERT_EQ(err, -ELOOP, "check btf"); 762 btf__free(btf); 763 break; 764 } 765 766 while (test__start_subtest("btf: list_node and rb_node in same struct")) { 767 list_and_rb_node_same_struct(true); 768 break; 769 } 770 771 while (test__start_subtest("btf: list_node and rb_node in same struct, no bpf_refcount")) { 772 list_and_rb_node_same_struct(false); 773 break; 774 } 775} 776 777void test_linked_list(void) 778{ 779 int i; 780 781 for (i = 0; i < ARRAY_SIZE(linked_list_fail_tests); i++) { 782 if (!test__start_subtest(linked_list_fail_tests[i].prog_name)) 783 continue; 784 test_linked_list_fail_prog(linked_list_fail_tests[i].prog_name, 785 linked_list_fail_tests[i].err_msg); 786 } 787 test_btf(); 788 test_linked_list_success(PUSH_POP, false); 789 test_linked_list_success(PUSH_POP, true); 790 test_linked_list_success(PUSH_POP_MULT, false); 791 test_linked_list_success(PUSH_POP_MULT, true); 792 test_linked_list_success(LIST_IN_LIST, false); 793 test_linked_list_success(LIST_IN_LIST, true); 794 test_linked_list_success(TEST_ALL, false); 795} 796