Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Test new enum kflag and enum64 API functions

Add tests to use the new enum kflag and enum64 API functions
in selftest btf_write.

Acked-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/r/20220607062703.3724287-1-yhs@fb.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Yonghong Song and committed by
Alexei Starovoitov
2b730145 d932815a

+114 -37
+22 -3
tools/testing/selftests/bpf/btf_helpers.c
··· 26 26 [BTF_KIND_FLOAT] = "FLOAT", 27 27 [BTF_KIND_DECL_TAG] = "DECL_TAG", 28 28 [BTF_KIND_TYPE_TAG] = "TYPE_TAG", 29 + [BTF_KIND_ENUM64] = "ENUM64", 29 30 }; 30 31 31 32 static const char *btf_kind_str(__u16 kind) 32 33 { 33 - if (kind > BTF_KIND_TYPE_TAG) 34 + if (kind > BTF_KIND_ENUM64) 34 35 return "UNKNOWN"; 35 36 return btf_kind_str_mapping[kind]; 36 37 } ··· 140 139 } 141 140 case BTF_KIND_ENUM: { 142 141 const struct btf_enum *v = btf_enum(t); 142 + const char *fmt_str; 143 143 144 - fprintf(out, " size=%u vlen=%u", t->size, vlen); 144 + fmt_str = btf_kflag(t) ? "\n\t'%s' val=%d" : "\n\t'%s' val=%u"; 145 + fprintf(out, " encoding=%s size=%u vlen=%u", 146 + btf_kflag(t) ? "SIGNED" : "UNSIGNED", t->size, vlen); 145 147 for (i = 0; i < vlen; i++, v++) { 146 - fprintf(out, "\n\t'%s' val=%u", 148 + fprintf(out, fmt_str, 147 149 btf_str(btf, v->name_off), v->val); 150 + } 151 + break; 152 + } 153 + case BTF_KIND_ENUM64: { 154 + const struct btf_enum64 *v = btf_enum64(t); 155 + const char *fmt_str; 156 + 157 + fmt_str = btf_kflag(t) ? "\n\t'%s' val=%lld" : "\n\t'%s' val=%llu"; 158 + 159 + fprintf(out, " encoding=%s size=%u vlen=%u", 160 + btf_kflag(t) ? "SIGNED" : "UNSIGNED", t->size, vlen); 161 + for (i = 0; i < vlen; i++, v++) { 162 + fprintf(out, fmt_str, 163 + btf_str(btf, v->name_off), 164 + ((__u64)v->val_hi32 << 32) | v->val_lo32); 148 165 } 149 166 break; 150 167 }
+92 -34
tools/testing/selftests/bpf/prog_tests/btf_write.c
··· 9 9 const struct btf_var_secinfo *vi; 10 10 const struct btf_type *t; 11 11 const struct btf_member *m; 12 + const struct btf_enum64 *v64; 12 13 const struct btf_enum *v; 13 14 const struct btf_param *p; 14 15 int id, err, str_off; ··· 172 171 ASSERT_STREQ(btf__str_by_offset(btf, v->name_off), "v2", "v2_name"); 173 172 ASSERT_EQ(v->val, 2, "v2_val"); 174 173 ASSERT_STREQ(btf_type_raw_dump(btf, 9), 175 - "[9] ENUM 'e1' size=4 vlen=2\n" 174 + "[9] ENUM 'e1' encoding=UNSIGNED size=4 vlen=2\n" 176 175 "\t'v1' val=1\n" 177 176 "\t'v2' val=2", "raw_dump"); 178 177 ··· 203 202 ASSERT_EQ(btf_vlen(t), 0, "enum_fwd_kind"); 204 203 ASSERT_EQ(t->size, 4, "enum_fwd_sz"); 205 204 ASSERT_STREQ(btf_type_raw_dump(btf, 12), 206 - "[12] ENUM 'enum_fwd' size=4 vlen=0", "raw_dump"); 205 + "[12] ENUM 'enum_fwd' encoding=UNSIGNED size=4 vlen=0", "raw_dump"); 207 206 208 207 /* TYPEDEF */ 209 208 id = btf__add_typedef(btf, "typedef1", 1); ··· 308 307 ASSERT_EQ(t->type, 1, "tag_type"); 309 308 ASSERT_STREQ(btf_type_raw_dump(btf, 20), 310 309 "[20] TYPE_TAG 'tag1' type_id=1", "raw_dump"); 310 + 311 + /* ENUM64 */ 312 + id = btf__add_enum64(btf, "e1", 8, true); 313 + ASSERT_EQ(id, 21, "enum64_id"); 314 + err = btf__add_enum64_value(btf, "v1", -1); 315 + ASSERT_OK(err, "v1_res"); 316 + err = btf__add_enum64_value(btf, "v2", 0x123456789); /* 4886718345 */ 317 + ASSERT_OK(err, "v2_res"); 318 + t = btf__type_by_id(btf, 21); 319 + ASSERT_STREQ(btf__str_by_offset(btf, t->name_off), "e1", "enum64_name"); 320 + ASSERT_EQ(btf_kind(t), BTF_KIND_ENUM64, "enum64_kind"); 321 + ASSERT_EQ(btf_vlen(t), 2, "enum64_vlen"); 322 + ASSERT_EQ(t->size, 8, "enum64_sz"); 323 + v64 = btf_enum64(t) + 0; 324 + ASSERT_STREQ(btf__str_by_offset(btf, v64->name_off), "v1", "v1_name"); 325 + ASSERT_EQ(v64->val_hi32, 0xffffffff, "v1_val"); 326 + ASSERT_EQ(v64->val_lo32, 0xffffffff, "v1_val"); 327 + v64 = btf_enum64(t) + 1; 328 + ASSERT_STREQ(btf__str_by_offset(btf, v64->name_off), "v2", "v2_name"); 329 + ASSERT_EQ(v64->val_hi32, 0x1, "v2_val"); 330 + ASSERT_EQ(v64->val_lo32, 0x23456789, "v2_val"); 331 + ASSERT_STREQ(btf_type_raw_dump(btf, 21), 332 + "[21] ENUM64 'e1' encoding=SIGNED size=8 vlen=2\n" 333 + "\t'v1' val=-1\n" 334 + "\t'v2' val=4886718345", "raw_dump"); 335 + 336 + id = btf__add_enum64(btf, "e1", 8, false); 337 + ASSERT_EQ(id, 22, "enum64_id"); 338 + err = btf__add_enum64_value(btf, "v1", 0xffffffffFFFFFFFF); /* 18446744073709551615 */ 339 + ASSERT_OK(err, "v1_res"); 340 + t = btf__type_by_id(btf, 22); 341 + ASSERT_STREQ(btf__str_by_offset(btf, t->name_off), "e1", "enum64_name"); 342 + ASSERT_EQ(btf_kind(t), BTF_KIND_ENUM64, "enum64_kind"); 343 + ASSERT_EQ(btf_vlen(t), 1, "enum64_vlen"); 344 + ASSERT_EQ(t->size, 8, "enum64_sz"); 345 + v64 = btf_enum64(t) + 0; 346 + ASSERT_STREQ(btf__str_by_offset(btf, v64->name_off), "v1", "v1_name"); 347 + ASSERT_EQ(v64->val_hi32, 0xffffffff, "v1_val"); 348 + ASSERT_EQ(v64->val_lo32, 0xffffffff, "v1_val"); 349 + ASSERT_STREQ(btf_type_raw_dump(btf, 22), 350 + "[22] ENUM64 'e1' encoding=UNSIGNED size=8 vlen=1\n" 351 + "\t'v1' val=18446744073709551615", "raw_dump"); 311 352 } 312 353 313 354 static void test_btf_add() ··· 375 332 "\t'f2' type_id=1 bits_offset=32 bitfield_size=16", 376 333 "[8] UNION 'u1' size=8 vlen=1\n" 377 334 "\t'f1' type_id=1 bits_offset=0 bitfield_size=16", 378 - "[9] ENUM 'e1' size=4 vlen=2\n" 335 + "[9] ENUM 'e1' encoding=UNSIGNED size=4 vlen=2\n" 379 336 "\t'v1' val=1\n" 380 337 "\t'v2' val=2", 381 338 "[10] FWD 'struct_fwd' fwd_kind=struct", 382 339 "[11] FWD 'union_fwd' fwd_kind=union", 383 - "[12] ENUM 'enum_fwd' size=4 vlen=0", 340 + "[12] ENUM 'enum_fwd' encoding=UNSIGNED size=4 vlen=0", 384 341 "[13] TYPEDEF 'typedef1' type_id=1", 385 342 "[14] FUNC 'func1' type_id=15 linkage=global", 386 343 "[15] FUNC_PROTO '(anon)' ret_type_id=1 vlen=2\n" ··· 391 348 "\ttype_id=1 offset=4 size=8", 392 349 "[18] DECL_TAG 'tag1' type_id=16 component_idx=-1", 393 350 "[19] DECL_TAG 'tag2' type_id=14 component_idx=1", 394 - "[20] TYPE_TAG 'tag1' type_id=1"); 351 + "[20] TYPE_TAG 'tag1' type_id=1", 352 + "[21] ENUM64 'e1' encoding=SIGNED size=8 vlen=2\n" 353 + "\t'v1' val=-1\n" 354 + "\t'v2' val=4886718345", 355 + "[22] ENUM64 'e1' encoding=UNSIGNED size=8 vlen=1\n" 356 + "\t'v1' val=18446744073709551615"); 395 357 396 358 btf__free(btf); 397 359 } ··· 418 370 gen_btf(btf2); 419 371 420 372 id = btf__add_btf(btf1, btf2); 421 - if (!ASSERT_EQ(id, 21, "id")) 373 + if (!ASSERT_EQ(id, 23, "id")) 422 374 goto cleanup; 423 375 424 376 VALIDATE_RAW_BTF( ··· 434 386 "\t'f2' type_id=1 bits_offset=32 bitfield_size=16", 435 387 "[8] UNION 'u1' size=8 vlen=1\n" 436 388 "\t'f1' type_id=1 bits_offset=0 bitfield_size=16", 437 - "[9] ENUM 'e1' size=4 vlen=2\n" 389 + "[9] ENUM 'e1' encoding=UNSIGNED size=4 vlen=2\n" 438 390 "\t'v1' val=1\n" 439 391 "\t'v2' val=2", 440 392 "[10] FWD 'struct_fwd' fwd_kind=struct", 441 393 "[11] FWD 'union_fwd' fwd_kind=union", 442 - "[12] ENUM 'enum_fwd' size=4 vlen=0", 394 + "[12] ENUM 'enum_fwd' encoding=UNSIGNED size=4 vlen=0", 443 395 "[13] TYPEDEF 'typedef1' type_id=1", 444 396 "[14] FUNC 'func1' type_id=15 linkage=global", 445 397 "[15] FUNC_PROTO '(anon)' ret_type_id=1 vlen=2\n" ··· 451 403 "[18] DECL_TAG 'tag1' type_id=16 component_idx=-1", 452 404 "[19] DECL_TAG 'tag2' type_id=14 component_idx=1", 453 405 "[20] TYPE_TAG 'tag1' type_id=1", 406 + "[21] ENUM64 'e1' encoding=SIGNED size=8 vlen=2\n" 407 + "\t'v1' val=-1\n" 408 + "\t'v2' val=4886718345", 409 + "[22] ENUM64 'e1' encoding=UNSIGNED size=8 vlen=1\n" 410 + "\t'v1' val=18446744073709551615", 454 411 455 412 /* types appended from the second BTF */ 456 - "[21] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 457 - "[22] PTR '(anon)' type_id=21", 458 - "[23] CONST '(anon)' type_id=25", 459 - "[24] VOLATILE '(anon)' type_id=23", 460 - "[25] RESTRICT '(anon)' type_id=24", 461 - "[26] ARRAY '(anon)' type_id=22 index_type_id=21 nr_elems=10", 462 - "[27] STRUCT 's1' size=8 vlen=2\n" 463 - "\t'f1' type_id=21 bits_offset=0\n" 464 - "\t'f2' type_id=21 bits_offset=32 bitfield_size=16", 465 - "[28] UNION 'u1' size=8 vlen=1\n" 466 - "\t'f1' type_id=21 bits_offset=0 bitfield_size=16", 467 - "[29] ENUM 'e1' size=4 vlen=2\n" 413 + "[23] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 414 + "[24] PTR '(anon)' type_id=23", 415 + "[25] CONST '(anon)' type_id=27", 416 + "[26] VOLATILE '(anon)' type_id=25", 417 + "[27] RESTRICT '(anon)' type_id=26", 418 + "[28] ARRAY '(anon)' type_id=24 index_type_id=23 nr_elems=10", 419 + "[29] STRUCT 's1' size=8 vlen=2\n" 420 + "\t'f1' type_id=23 bits_offset=0\n" 421 + "\t'f2' type_id=23 bits_offset=32 bitfield_size=16", 422 + "[30] UNION 'u1' size=8 vlen=1\n" 423 + "\t'f1' type_id=23 bits_offset=0 bitfield_size=16", 424 + "[31] ENUM 'e1' encoding=UNSIGNED size=4 vlen=2\n" 468 425 "\t'v1' val=1\n" 469 426 "\t'v2' val=2", 470 - "[30] FWD 'struct_fwd' fwd_kind=struct", 471 - "[31] FWD 'union_fwd' fwd_kind=union", 472 - "[32] ENUM 'enum_fwd' size=4 vlen=0", 473 - "[33] TYPEDEF 'typedef1' type_id=21", 474 - "[34] FUNC 'func1' type_id=35 linkage=global", 475 - "[35] FUNC_PROTO '(anon)' ret_type_id=21 vlen=2\n" 476 - "\t'p1' type_id=21\n" 477 - "\t'p2' type_id=22", 478 - "[36] VAR 'var1' type_id=21, linkage=global-alloc", 479 - "[37] DATASEC 'datasec1' size=12 vlen=1\n" 480 - "\ttype_id=21 offset=4 size=8", 481 - "[38] DECL_TAG 'tag1' type_id=36 component_idx=-1", 482 - "[39] DECL_TAG 'tag2' type_id=34 component_idx=1", 483 - "[40] TYPE_TAG 'tag1' type_id=21"); 427 + "[32] FWD 'struct_fwd' fwd_kind=struct", 428 + "[33] FWD 'union_fwd' fwd_kind=union", 429 + "[34] ENUM 'enum_fwd' encoding=UNSIGNED size=4 vlen=0", 430 + "[35] TYPEDEF 'typedef1' type_id=23", 431 + "[36] FUNC 'func1' type_id=37 linkage=global", 432 + "[37] FUNC_PROTO '(anon)' ret_type_id=23 vlen=2\n" 433 + "\t'p1' type_id=23\n" 434 + "\t'p2' type_id=24", 435 + "[38] VAR 'var1' type_id=23, linkage=global-alloc", 436 + "[39] DATASEC 'datasec1' size=12 vlen=1\n" 437 + "\ttype_id=23 offset=4 size=8", 438 + "[40] DECL_TAG 'tag1' type_id=38 component_idx=-1", 439 + "[41] DECL_TAG 'tag2' type_id=36 component_idx=1", 440 + "[42] TYPE_TAG 'tag1' type_id=23", 441 + "[43] ENUM64 'e1' encoding=SIGNED size=8 vlen=2\n" 442 + "\t'v1' val=-1\n" 443 + "\t'v2' val=4886718345", 444 + "[44] ENUM64 'e1' encoding=UNSIGNED size=8 vlen=1\n" 445 + "\t'v1' val=18446744073709551615"); 484 446 485 447 cleanup: 486 448 btf__free(btf1);