diff options
Diffstat (limited to 'tools/testing/selftests/bpf')
| -rwxr-xr-x | tools/testing/selftests/bpf/tcp_client.py | 3 | ||||
| -rwxr-xr-x | tools/testing/selftests/bpf/tcp_server.py | 5 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/test_btf.c | 553 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/test_libbpf_open.c | 30 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/test_maps.c | 27 | ||||
| -rwxr-xr-x | tools/testing/selftests/bpf/test_offload.py | 135 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/test_progs.c | 14 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/verifier/ctx_sk_msg.c | 1 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/verifier/ctx_skb.c | 1 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/verifier/jmp32.c | 22 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/verifier/jset.c | 2 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/verifier/spill_fill.c | 1 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/verifier/spin_lock.c | 2 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/verifier/value_ptr_arith.c | 4 |
14 files changed, 677 insertions, 123 deletions
diff --git a/tools/testing/selftests/bpf/tcp_client.py b/tools/testing/selftests/bpf/tcp_client.py index 7f8200a8702b..a53ed58528d6 100755 --- a/tools/testing/selftests/bpf/tcp_client.py +++ b/tools/testing/selftests/bpf/tcp_client.py | |||
| @@ -30,12 +30,11 @@ def send(sock, s): | |||
| 30 | 30 | ||
| 31 | 31 | ||
| 32 | serverPort = int(sys.argv[1]) | 32 | serverPort = int(sys.argv[1]) |
| 33 | HostName = socket.gethostname() | ||
| 34 | 33 | ||
| 35 | # create active socket | 34 | # create active socket |
| 36 | sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) | 35 | sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) |
| 37 | try: | 36 | try: |
| 38 | sock.connect((HostName, serverPort)) | 37 | sock.connect(('localhost', serverPort)) |
| 39 | except socket.error as e: | 38 | except socket.error as e: |
| 40 | sys.exit(1) | 39 | sys.exit(1) |
| 41 | 40 | ||
diff --git a/tools/testing/selftests/bpf/tcp_server.py b/tools/testing/selftests/bpf/tcp_server.py index b39903fca4c8..0ca60d193bed 100755 --- a/tools/testing/selftests/bpf/tcp_server.py +++ b/tools/testing/selftests/bpf/tcp_server.py | |||
| @@ -35,13 +35,10 @@ MAX_PORTS = 2 | |||
| 35 | serverPort = SERVER_PORT | 35 | serverPort = SERVER_PORT |
| 36 | serverSocket = None | 36 | serverSocket = None |
| 37 | 37 | ||
| 38 | HostName = socket.gethostname() | ||
| 39 | |||
| 40 | # create passive socket | 38 | # create passive socket |
| 41 | serverSocket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) | 39 | serverSocket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) |
| 42 | host = socket.gethostname() | ||
| 43 | 40 | ||
| 44 | try: serverSocket.bind((host, 0)) | 41 | try: serverSocket.bind(('localhost', 0)) |
| 45 | except socket.error as msg: | 42 | except socket.error as msg: |
| 46 | print('bind fails: ' + str(msg)) | 43 | print('bind fails: ' + str(msg)) |
| 47 | 44 | ||
diff --git a/tools/testing/selftests/bpf/test_btf.c b/tools/testing/selftests/bpf/test_btf.c index 179f1d8ec5bf..447acc34db94 100644 --- a/tools/testing/selftests/bpf/test_btf.c +++ b/tools/testing/selftests/bpf/test_btf.c | |||
| @@ -52,18 +52,10 @@ static int count_result(int err) | |||
| 52 | return err; | 52 | return err; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | #define __printf(a, b) __attribute__((format(printf, a, b))) | 55 | static int __base_pr(enum libbpf_print_level level __attribute__((unused)), |
| 56 | 56 | const char *format, va_list args) | |
| 57 | __printf(1, 2) | ||
| 58 | static int __base_pr(const char *format, ...) | ||
| 59 | { | 57 | { |
| 60 | va_list args; | 58 | return vfprintf(stderr, format, args); |
| 61 | int err; | ||
| 62 | |||
| 63 | va_start(args, format); | ||
| 64 | err = vfprintf(stderr, format, args); | ||
| 65 | va_end(args); | ||
| 66 | return err; | ||
| 67 | } | 59 | } |
| 68 | 60 | ||
| 69 | #define BTF_INFO_ENC(kind, kind_flag, vlen) \ | 61 | #define BTF_INFO_ENC(kind, kind_flag, vlen) \ |
| @@ -78,12 +70,21 @@ static int __base_pr(const char *format, ...) | |||
| 78 | BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), sz), \ | 70 | BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), sz), \ |
| 79 | BTF_INT_ENC(encoding, bits_offset, bits) | 71 | BTF_INT_ENC(encoding, bits_offset, bits) |
| 80 | 72 | ||
| 73 | #define BTF_FWD_ENC(name, kind_flag) \ | ||
| 74 | BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FWD, kind_flag, 0), 0) | ||
| 75 | |||
| 81 | #define BTF_ARRAY_ENC(type, index_type, nr_elems) \ | 76 | #define BTF_ARRAY_ENC(type, index_type, nr_elems) \ |
| 82 | (type), (index_type), (nr_elems) | 77 | (type), (index_type), (nr_elems) |
| 83 | #define BTF_TYPE_ARRAY_ENC(type, index_type, nr_elems) \ | 78 | #define BTF_TYPE_ARRAY_ENC(type, index_type, nr_elems) \ |
| 84 | BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0), \ | 79 | BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0), \ |
| 85 | BTF_ARRAY_ENC(type, index_type, nr_elems) | 80 | BTF_ARRAY_ENC(type, index_type, nr_elems) |
| 86 | 81 | ||
| 82 | #define BTF_STRUCT_ENC(name, nr_elems, sz) \ | ||
| 83 | BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, nr_elems), sz) | ||
| 84 | |||
| 85 | #define BTF_UNION_ENC(name, nr_elems, sz) \ | ||
| 86 | BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_UNION, 0, nr_elems), sz) | ||
| 87 | |||
| 87 | #define BTF_MEMBER_ENC(name, type, bits_offset) \ | 88 | #define BTF_MEMBER_ENC(name, type, bits_offset) \ |
| 88 | (name), (type), (bits_offset) | 89 | (name), (type), (bits_offset) |
| 89 | #define BTF_ENUM_ENC(name, val) (name), (val) | 90 | #define BTF_ENUM_ENC(name, val) (name), (val) |
| @@ -99,6 +100,12 @@ static int __base_pr(const char *format, ...) | |||
| 99 | #define BTF_CONST_ENC(type) \ | 100 | #define BTF_CONST_ENC(type) \ |
| 100 | BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), type) | 101 | BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), type) |
| 101 | 102 | ||
| 103 | #define BTF_VOLATILE_ENC(type) \ | ||
| 104 | BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), type) | ||
| 105 | |||
| 106 | #define BTF_RESTRICT_ENC(type) \ | ||
| 107 | BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_RESTRICT, 0, 0), type) | ||
| 108 | |||
| 102 | #define BTF_FUNC_PROTO_ENC(ret_type, nargs) \ | 109 | #define BTF_FUNC_PROTO_ENC(ret_type, nargs) \ |
| 103 | BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, nargs), ret_type) | 110 | BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, nargs), ret_type) |
| 104 | 111 | ||
| @@ -111,6 +118,10 @@ static int __base_pr(const char *format, ...) | |||
| 111 | #define BTF_END_RAW 0xdeadbeef | 118 | #define BTF_END_RAW 0xdeadbeef |
| 112 | #define NAME_TBD 0xdeadb33f | 119 | #define NAME_TBD 0xdeadb33f |
| 113 | 120 | ||
| 121 | #define NAME_NTH(N) (0xffff0000 | N) | ||
| 122 | #define IS_NAME_NTH(X) ((X & 0xffff0000) == 0xffff0000) | ||
| 123 | #define GET_NAME_NTH_IDX(X) (X & 0x0000ffff) | ||
| 124 | |||
| 114 | #define MAX_NR_RAW_U32 1024 | 125 | #define MAX_NR_RAW_U32 1024 |
| 115 | #define BTF_LOG_BUF_SIZE 65535 | 126 | #define BTF_LOG_BUF_SIZE 65535 |
| 116 | 127 | ||
| @@ -119,12 +130,14 @@ static struct args { | |||
| 119 | unsigned int file_test_num; | 130 | unsigned int file_test_num; |
| 120 | unsigned int get_info_test_num; | 131 | unsigned int get_info_test_num; |
| 121 | unsigned int info_raw_test_num; | 132 | unsigned int info_raw_test_num; |
| 133 | unsigned int dedup_test_num; | ||
| 122 | bool raw_test; | 134 | bool raw_test; |
| 123 | bool file_test; | 135 | bool file_test; |
| 124 | bool get_info_test; | 136 | bool get_info_test; |
| 125 | bool pprint_test; | 137 | bool pprint_test; |
| 126 | bool always_log; | 138 | bool always_log; |
| 127 | bool info_raw_test; | 139 | bool info_raw_test; |
| 140 | bool dedup_test; | ||
| 128 | } args; | 141 | } args; |
| 129 | 142 | ||
| 130 | static char btf_log_buf[BTF_LOG_BUF_SIZE]; | 143 | static char btf_log_buf[BTF_LOG_BUF_SIZE]; |
| @@ -1965,7 +1978,7 @@ static struct btf_raw_test raw_tests[] = { | |||
| 1965 | /* void (*)(int a, unsigned int <bad_name_off>) */ | 1978 | /* void (*)(int a, unsigned int <bad_name_off>) */ |
| 1966 | BTF_FUNC_PROTO_ENC(0, 2), /* [3] */ | 1979 | BTF_FUNC_PROTO_ENC(0, 2), /* [3] */ |
| 1967 | BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), | 1980 | BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), |
| 1968 | BTF_FUNC_PROTO_ARG_ENC(0xffffffff, 2), | 1981 | BTF_FUNC_PROTO_ARG_ENC(0x0fffffff, 2), |
| 1969 | BTF_END_RAW, | 1982 | BTF_END_RAW, |
| 1970 | }, | 1983 | }, |
| 1971 | .str_sec = "\0a", | 1984 | .str_sec = "\0a", |
| @@ -2835,11 +2848,13 @@ static void *btf_raw_create(const struct btf_header *hdr, | |||
| 2835 | const char **ret_next_str) | 2848 | const char **ret_next_str) |
| 2836 | { | 2849 | { |
| 2837 | const char *next_str = str, *end_str = str + str_sec_size; | 2850 | const char *next_str = str, *end_str = str + str_sec_size; |
| 2851 | const char **strs_idx = NULL, **tmp_strs_idx; | ||
| 2852 | int strs_cap = 0, strs_cnt = 0, next_str_idx = 0; | ||
| 2838 | unsigned int size_needed, offset; | 2853 | unsigned int size_needed, offset; |
| 2839 | struct btf_header *ret_hdr; | 2854 | struct btf_header *ret_hdr; |
| 2840 | int i, type_sec_size; | 2855 | int i, type_sec_size, err = 0; |
| 2841 | uint32_t *ret_types; | 2856 | uint32_t *ret_types; |
| 2842 | void *raw_btf; | 2857 | void *raw_btf = NULL; |
| 2843 | 2858 | ||
| 2844 | type_sec_size = get_raw_sec_size(raw_types); | 2859 | type_sec_size = get_raw_sec_size(raw_types); |
| 2845 | if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types")) | 2860 | if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types")) |
| @@ -2854,17 +2869,44 @@ static void *btf_raw_create(const struct btf_header *hdr, | |||
| 2854 | memcpy(raw_btf, hdr, sizeof(*hdr)); | 2869 | memcpy(raw_btf, hdr, sizeof(*hdr)); |
| 2855 | offset = sizeof(*hdr); | 2870 | offset = sizeof(*hdr); |
| 2856 | 2871 | ||
| 2872 | /* Index strings */ | ||
| 2873 | while ((next_str = get_next_str(next_str, end_str))) { | ||
| 2874 | if (strs_cnt == strs_cap) { | ||
| 2875 | strs_cap += max(16, strs_cap / 2); | ||
| 2876 | tmp_strs_idx = realloc(strs_idx, | ||
| 2877 | sizeof(*strs_idx) * strs_cap); | ||
| 2878 | if (CHECK(!tmp_strs_idx, | ||
| 2879 | "Cannot allocate memory for strs_idx")) { | ||
| 2880 | err = -1; | ||
| 2881 | goto done; | ||
| 2882 | } | ||
| 2883 | strs_idx = tmp_strs_idx; | ||
| 2884 | } | ||
| 2885 | strs_idx[strs_cnt++] = next_str; | ||
| 2886 | next_str += strlen(next_str); | ||
| 2887 | } | ||
| 2888 | |||
| 2857 | /* Copy type section */ | 2889 | /* Copy type section */ |
| 2858 | ret_types = raw_btf + offset; | 2890 | ret_types = raw_btf + offset; |
| 2859 | for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) { | 2891 | for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) { |
| 2860 | if (raw_types[i] == NAME_TBD) { | 2892 | if (raw_types[i] == NAME_TBD) { |
| 2861 | next_str = get_next_str(next_str, end_str); | 2893 | if (CHECK(next_str_idx == strs_cnt, |
| 2862 | if (CHECK(!next_str, "Error in getting next_str")) { | 2894 | "Error in getting next_str #%d", |
| 2863 | free(raw_btf); | 2895 | next_str_idx)) { |
| 2864 | return NULL; | 2896 | err = -1; |
| 2897 | goto done; | ||
| 2865 | } | 2898 | } |
| 2866 | ret_types[i] = next_str - str; | 2899 | ret_types[i] = strs_idx[next_str_idx++] - str; |
| 2867 | next_str += strlen(next_str); | 2900 | } else if (IS_NAME_NTH(raw_types[i])) { |
| 2901 | int idx = GET_NAME_NTH_IDX(raw_types[i]); | ||
| 2902 | |||
| 2903 | if (CHECK(idx <= 0 || idx > strs_cnt, | ||
| 2904 | "Error getting string #%d, strs_cnt:%d", | ||
| 2905 | idx, strs_cnt)) { | ||
| 2906 | err = -1; | ||
| 2907 | goto done; | ||
| 2908 | } | ||
| 2909 | ret_types[i] = strs_idx[idx-1] - str; | ||
| 2868 | } else { | 2910 | } else { |
| 2869 | ret_types[i] = raw_types[i]; | 2911 | ret_types[i] = raw_types[i]; |
| 2870 | } | 2912 | } |
| @@ -2881,8 +2923,17 @@ static void *btf_raw_create(const struct btf_header *hdr, | |||
| 2881 | 2923 | ||
| 2882 | *btf_size = size_needed; | 2924 | *btf_size = size_needed; |
| 2883 | if (ret_next_str) | 2925 | if (ret_next_str) |
| 2884 | *ret_next_str = next_str; | 2926 | *ret_next_str = |
| 2927 | next_str_idx < strs_cnt ? strs_idx[next_str_idx] : NULL; | ||
| 2885 | 2928 | ||
| 2929 | done: | ||
| 2930 | if (err) { | ||
| 2931 | if (raw_btf) | ||
| 2932 | free(raw_btf); | ||
| 2933 | if (strs_idx) | ||
| 2934 | free(strs_idx); | ||
| 2935 | return NULL; | ||
| 2936 | } | ||
| 2886 | return raw_btf; | 2937 | return raw_btf; |
| 2887 | } | 2938 | } |
| 2888 | 2939 | ||
| @@ -5551,20 +5602,450 @@ static int test_info_raw(void) | |||
| 5551 | return err; | 5602 | return err; |
| 5552 | } | 5603 | } |
| 5553 | 5604 | ||
| 5605 | struct btf_raw_data { | ||
| 5606 | __u32 raw_types[MAX_NR_RAW_U32]; | ||
| 5607 | const char *str_sec; | ||
| 5608 | __u32 str_sec_size; | ||
| 5609 | }; | ||
| 5610 | |||
| 5611 | struct btf_dedup_test { | ||
| 5612 | const char *descr; | ||
| 5613 | struct btf_raw_data input; | ||
| 5614 | struct btf_raw_data expect; | ||
| 5615 | struct btf_dedup_opts opts; | ||
| 5616 | }; | ||
| 5617 | |||
| 5618 | const struct btf_dedup_test dedup_tests[] = { | ||
| 5619 | |||
| 5620 | { | ||
| 5621 | .descr = "dedup: unused strings filtering", | ||
| 5622 | .input = { | ||
| 5623 | .raw_types = { | ||
| 5624 | BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 4), | ||
| 5625 | BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 64, 8), | ||
| 5626 | BTF_END_RAW, | ||
| 5627 | }, | ||
| 5628 | BTF_STR_SEC("\0unused\0int\0foo\0bar\0long"), | ||
| 5629 | }, | ||
| 5630 | .expect = { | ||
| 5631 | .raw_types = { | ||
| 5632 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), | ||
| 5633 | BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8), | ||
| 5634 | BTF_END_RAW, | ||
| 5635 | }, | ||
| 5636 | BTF_STR_SEC("\0int\0long"), | ||
| 5637 | }, | ||
| 5638 | .opts = { | ||
| 5639 | .dont_resolve_fwds = false, | ||
| 5640 | }, | ||
| 5641 | }, | ||
| 5642 | { | ||
| 5643 | .descr = "dedup: strings deduplication", | ||
| 5644 | .input = { | ||
| 5645 | .raw_types = { | ||
| 5646 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), | ||
| 5647 | BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8), | ||
| 5648 | BTF_TYPE_INT_ENC(NAME_NTH(3), BTF_INT_SIGNED, 0, 32, 4), | ||
| 5649 | BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 64, 8), | ||
| 5650 | BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 32, 4), | ||
| 5651 | BTF_END_RAW, | ||
| 5652 | }, | ||
| 5653 | BTF_STR_SEC("\0int\0long int\0int\0long int\0int"), | ||
| 5654 | }, | ||
| 5655 | .expect = { | ||
| 5656 | .raw_types = { | ||
| 5657 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), | ||
| 5658 | BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8), | ||
| 5659 | BTF_END_RAW, | ||
| 5660 | }, | ||
| 5661 | BTF_STR_SEC("\0int\0long int"), | ||
| 5662 | }, | ||
| 5663 | .opts = { | ||
| 5664 | .dont_resolve_fwds = false, | ||
| 5665 | }, | ||
| 5666 | }, | ||
| 5667 | { | ||
| 5668 | .descr = "dedup: struct example #1", | ||
| 5669 | /* | ||
| 5670 | * struct s { | ||
| 5671 | * struct s *next; | ||
| 5672 | * const int *a; | ||
| 5673 | * int b[16]; | ||
| 5674 | * int c; | ||
| 5675 | * } | ||
| 5676 | */ | ||
| 5677 | .input = { | ||
| 5678 | .raw_types = { | ||
| 5679 | /* int */ | ||
| 5680 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), /* [1] */ | ||
| 5681 | /* int[16] */ | ||
| 5682 | BTF_TYPE_ARRAY_ENC(1, 1, 16), /* [2] */ | ||
| 5683 | /* struct s { */ | ||
| 5684 | BTF_STRUCT_ENC(NAME_NTH(2), 4, 84), /* [3] */ | ||
| 5685 | BTF_MEMBER_ENC(NAME_NTH(3), 4, 0), /* struct s *next; */ | ||
| 5686 | BTF_MEMBER_ENC(NAME_NTH(4), 5, 64), /* const int *a; */ | ||
| 5687 | BTF_MEMBER_ENC(NAME_NTH(5), 2, 128), /* int b[16]; */ | ||
| 5688 | BTF_MEMBER_ENC(NAME_NTH(6), 1, 640), /* int c; */ | ||
| 5689 | /* ptr -> [3] struct s */ | ||
| 5690 | BTF_PTR_ENC(3), /* [4] */ | ||
| 5691 | /* ptr -> [6] const int */ | ||
| 5692 | BTF_PTR_ENC(6), /* [5] */ | ||
| 5693 | /* const -> [1] int */ | ||
| 5694 | BTF_CONST_ENC(1), /* [6] */ | ||
| 5695 | |||
| 5696 | /* full copy of the above */ | ||
| 5697 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), /* [7] */ | ||
| 5698 | BTF_TYPE_ARRAY_ENC(7, 7, 16), /* [8] */ | ||
| 5699 | BTF_STRUCT_ENC(NAME_NTH(2), 4, 84), /* [9] */ | ||
| 5700 | BTF_MEMBER_ENC(NAME_NTH(3), 10, 0), | ||
| 5701 | BTF_MEMBER_ENC(NAME_NTH(4), 11, 64), | ||
| 5702 | BTF_MEMBER_ENC(NAME_NTH(5), 8, 128), | ||
| 5703 | BTF_MEMBER_ENC(NAME_NTH(6), 7, 640), | ||
| 5704 | BTF_PTR_ENC(9), /* [10] */ | ||
| 5705 | BTF_PTR_ENC(12), /* [11] */ | ||
| 5706 | BTF_CONST_ENC(7), /* [12] */ | ||
| 5707 | BTF_END_RAW, | ||
| 5708 | }, | ||
| 5709 | BTF_STR_SEC("\0int\0s\0next\0a\0b\0c\0"), | ||
| 5710 | }, | ||
| 5711 | .expect = { | ||
| 5712 | .raw_types = { | ||
| 5713 | /* int */ | ||
| 5714 | BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 32, 4), /* [1] */ | ||
| 5715 | /* int[16] */ | ||
| 5716 | BTF_TYPE_ARRAY_ENC(1, 1, 16), /* [2] */ | ||
| 5717 | /* struct s { */ | ||
| 5718 | BTF_STRUCT_ENC(NAME_NTH(6), 4, 84), /* [3] */ | ||
| 5719 | BTF_MEMBER_ENC(NAME_NTH(5), 4, 0), /* struct s *next; */ | ||
| 5720 | BTF_MEMBER_ENC(NAME_NTH(1), 5, 64), /* const int *a; */ | ||
| 5721 | BTF_MEMBER_ENC(NAME_NTH(2), 2, 128), /* int b[16]; */ | ||
| 5722 | BTF_MEMBER_ENC(NAME_NTH(3), 1, 640), /* int c; */ | ||
| 5723 | /* ptr -> [3] struct s */ | ||
| 5724 | BTF_PTR_ENC(3), /* [4] */ | ||
| 5725 | /* ptr -> [6] const int */ | ||
| 5726 | BTF_PTR_ENC(6), /* [5] */ | ||
| 5727 | /* const -> [1] int */ | ||
| 5728 | BTF_CONST_ENC(1), /* [6] */ | ||
| 5729 | BTF_END_RAW, | ||
| 5730 | }, | ||
| 5731 | BTF_STR_SEC("\0a\0b\0c\0int\0next\0s"), | ||
| 5732 | }, | ||
| 5733 | .opts = { | ||
| 5734 | .dont_resolve_fwds = false, | ||
| 5735 | }, | ||
| 5736 | }, | ||
| 5737 | { | ||
| 5738 | .descr = "dedup: all possible kinds (no duplicates)", | ||
| 5739 | .input = { | ||
| 5740 | .raw_types = { | ||
| 5741 | BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8), /* [1] int */ | ||
| 5742 | BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4), /* [2] enum */ | ||
| 5743 | BTF_ENUM_ENC(NAME_TBD, 0), | ||
| 5744 | BTF_ENUM_ENC(NAME_TBD, 1), | ||
| 5745 | BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */), /* [3] fwd */ | ||
| 5746 | BTF_TYPE_ARRAY_ENC(2, 1, 7), /* [4] array */ | ||
| 5747 | BTF_STRUCT_ENC(NAME_TBD, 1, 4), /* [5] struct */ | ||
| 5748 | BTF_MEMBER_ENC(NAME_TBD, 1, 0), | ||
| 5749 | BTF_UNION_ENC(NAME_TBD, 1, 4), /* [6] union */ | ||
| 5750 | BTF_MEMBER_ENC(NAME_TBD, 1, 0), | ||
| 5751 | BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [7] typedef */ | ||
| 5752 | BTF_PTR_ENC(0), /* [8] ptr */ | ||
| 5753 | BTF_CONST_ENC(8), /* [9] const */ | ||
| 5754 | BTF_VOLATILE_ENC(8), /* [10] volatile */ | ||
| 5755 | BTF_RESTRICT_ENC(8), /* [11] restrict */ | ||
| 5756 | BTF_FUNC_PROTO_ENC(1, 2), /* [12] func_proto */ | ||
| 5757 | BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), | ||
| 5758 | BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8), | ||
| 5759 | BTF_FUNC_ENC(NAME_TBD, 12), /* [13] func */ | ||
| 5760 | BTF_END_RAW, | ||
| 5761 | }, | ||
| 5762 | BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"), | ||
| 5763 | }, | ||
| 5764 | .expect = { | ||
| 5765 | .raw_types = { | ||
| 5766 | BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8), /* [1] int */ | ||
| 5767 | BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4), /* [2] enum */ | ||
| 5768 | BTF_ENUM_ENC(NAME_TBD, 0), | ||
| 5769 | BTF_ENUM_ENC(NAME_TBD, 1), | ||
| 5770 | BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */), /* [3] fwd */ | ||
| 5771 | BTF_TYPE_ARRAY_ENC(2, 1, 7), /* [4] array */ | ||
| 5772 | BTF_STRUCT_ENC(NAME_TBD, 1, 4), /* [5] struct */ | ||
| 5773 | BTF_MEMBER_ENC(NAME_TBD, 1, 0), | ||
| 5774 | BTF_UNION_ENC(NAME_TBD, 1, 4), /* [6] union */ | ||
| 5775 | BTF_MEMBER_ENC(NAME_TBD, 1, 0), | ||
| 5776 | BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [7] typedef */ | ||
| 5777 | BTF_PTR_ENC(0), /* [8] ptr */ | ||
| 5778 | BTF_CONST_ENC(8), /* [9] const */ | ||
| 5779 | BTF_VOLATILE_ENC(8), /* [10] volatile */ | ||
| 5780 | BTF_RESTRICT_ENC(8), /* [11] restrict */ | ||
| 5781 | BTF_FUNC_PROTO_ENC(1, 2), /* [12] func_proto */ | ||
| 5782 | BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), | ||
| 5783 | BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8), | ||
| 5784 | BTF_FUNC_ENC(NAME_TBD, 12), /* [13] func */ | ||
| 5785 | BTF_END_RAW, | ||
| 5786 | }, | ||
| 5787 | BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"), | ||
| 5788 | }, | ||
| 5789 | .opts = { | ||
| 5790 | .dont_resolve_fwds = false, | ||
| 5791 | }, | ||
| 5792 | }, | ||
| 5793 | { | ||
| 5794 | .descr = "dedup: no int duplicates", | ||
| 5795 | .input = { | ||
| 5796 | .raw_types = { | ||
| 5797 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8), | ||
| 5798 | /* different name */ | ||
| 5799 | BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8), | ||
| 5800 | /* different encoding */ | ||
| 5801 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8), | ||
| 5802 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8), | ||
| 5803 | /* different bit offset */ | ||
| 5804 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8), | ||
| 5805 | /* different bit size */ | ||
| 5806 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8), | ||
| 5807 | /* different byte size */ | ||
| 5808 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), | ||
| 5809 | BTF_END_RAW, | ||
| 5810 | }, | ||
| 5811 | BTF_STR_SEC("\0int\0some other int"), | ||
| 5812 | }, | ||
| 5813 | .expect = { | ||
| 5814 | .raw_types = { | ||
| 5815 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8), | ||
| 5816 | /* different name */ | ||
| 5817 | BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8), | ||
| 5818 | /* different encoding */ | ||
| 5819 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8), | ||
| 5820 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8), | ||
| 5821 | /* different bit offset */ | ||
| 5822 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8), | ||
| 5823 | /* different bit size */ | ||
| 5824 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8), | ||
| 5825 | /* different byte size */ | ||
| 5826 | BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), | ||
| 5827 | BTF_END_RAW, | ||
| 5828 | }, | ||
| 5829 | BTF_STR_SEC("\0int\0some other int"), | ||
| 5830 | }, | ||
| 5831 | .opts = { | ||
| 5832 | .dont_resolve_fwds = false, | ||
| 5833 | }, | ||
| 5834 | }, | ||
| 5835 | |||
| 5836 | }; | ||
| 5837 | |||
| 5838 | static int btf_type_size(const struct btf_type *t) | ||
| 5839 | { | ||
| 5840 | int base_size = sizeof(struct btf_type); | ||
| 5841 | __u16 vlen = BTF_INFO_VLEN(t->info); | ||
| 5842 | __u16 kind = BTF_INFO_KIND(t->info); | ||
| 5843 | |||
| 5844 | switch (kind) { | ||
| 5845 | case BTF_KIND_FWD: | ||
| 5846 | case BTF_KIND_CONST: | ||
| 5847 | case BTF_KIND_VOLATILE: | ||
| 5848 | case BTF_KIND_RESTRICT: | ||
| 5849 | case BTF_KIND_PTR: | ||
| 5850 | case BTF_KIND_TYPEDEF: | ||
| 5851 | case BTF_KIND_FUNC: | ||
| 5852 | return base_size; | ||
| 5853 | case BTF_KIND_INT: | ||
| 5854 | return base_size + sizeof(__u32); | ||
| 5855 | case BTF_KIND_ENUM: | ||
| 5856 | return base_size + vlen * sizeof(struct btf_enum); | ||
| 5857 | case BTF_KIND_ARRAY: | ||
| 5858 | return base_size + sizeof(struct btf_array); | ||
| 5859 | case BTF_KIND_STRUCT: | ||
| 5860 | case BTF_KIND_UNION: | ||
| 5861 | return base_size + vlen * sizeof(struct btf_member); | ||
| 5862 | case BTF_KIND_FUNC_PROTO: | ||
| 5863 | return base_size + vlen * sizeof(struct btf_param); | ||
| 5864 | default: | ||
| 5865 | fprintf(stderr, "Unsupported BTF_KIND:%u\n", kind); | ||
| 5866 | return -EINVAL; | ||
| 5867 | } | ||
| 5868 | } | ||
| 5869 | |||
| 5870 | static void dump_btf_strings(const char *strs, __u32 len) | ||
| 5871 | { | ||
| 5872 | const char *cur = strs; | ||
| 5873 | int i = 0; | ||
| 5874 | |||
| 5875 | while (cur < strs + len) { | ||
| 5876 | fprintf(stderr, "string #%d: '%s'\n", i, cur); | ||
| 5877 | cur += strlen(cur) + 1; | ||
| 5878 | i++; | ||
| 5879 | } | ||
| 5880 | } | ||
| 5881 | |||
| 5882 | static int do_test_dedup(unsigned int test_num) | ||
| 5883 | { | ||
| 5884 | const struct btf_dedup_test *test = &dedup_tests[test_num - 1]; | ||
| 5885 | int err = 0, i; | ||
| 5886 | __u32 test_nr_types, expect_nr_types, test_str_len, expect_str_len; | ||
| 5887 | void *raw_btf; | ||
| 5888 | unsigned int raw_btf_size; | ||
| 5889 | struct btf *test_btf = NULL, *expect_btf = NULL; | ||
| 5890 | const char *ret_test_next_str, *ret_expect_next_str; | ||
| 5891 | const char *test_strs, *expect_strs; | ||
| 5892 | const char *test_str_cur, *test_str_end; | ||
| 5893 | const char *expect_str_cur, *expect_str_end; | ||
| 5894 | |||
| 5895 | fprintf(stderr, "BTF dedup test[%u] (%s):", test_num, test->descr); | ||
| 5896 | |||
| 5897 | raw_btf = btf_raw_create(&hdr_tmpl, test->input.raw_types, | ||
| 5898 | test->input.str_sec, test->input.str_sec_size, | ||
| 5899 | &raw_btf_size, &ret_test_next_str); | ||
| 5900 | if (!raw_btf) | ||
| 5901 | return -1; | ||
| 5902 | test_btf = btf__new((__u8 *)raw_btf, raw_btf_size); | ||
| 5903 | free(raw_btf); | ||
| 5904 | if (CHECK(IS_ERR(test_btf), "invalid test_btf errno:%ld", | ||
| 5905 | PTR_ERR(test_btf))) { | ||
| 5906 | err = -1; | ||
| 5907 | goto done; | ||
| 5908 | } | ||
| 5909 | |||
| 5910 | raw_btf = btf_raw_create(&hdr_tmpl, test->expect.raw_types, | ||
| 5911 | test->expect.str_sec, | ||
| 5912 | test->expect.str_sec_size, | ||
| 5913 | &raw_btf_size, &ret_expect_next_str); | ||
| 5914 | if (!raw_btf) | ||
| 5915 | return -1; | ||
| 5916 | expect_btf = btf__new((__u8 *)raw_btf, raw_btf_size); | ||
| 5917 | free(raw_btf); | ||
| 5918 | if (CHECK(IS_ERR(expect_btf), "invalid expect_btf errno:%ld", | ||
| 5919 | PTR_ERR(expect_btf))) { | ||
| 5920 | err = -1; | ||
| 5921 | goto done; | ||
| 5922 | } | ||
| 5923 | |||
| 5924 | err = btf__dedup(test_btf, NULL, &test->opts); | ||
| 5925 | if (CHECK(err, "btf_dedup failed errno:%d", err)) { | ||
| 5926 | err = -1; | ||
| 5927 | goto done; | ||
| 5928 | } | ||
| 5929 | |||
| 5930 | btf__get_strings(test_btf, &test_strs, &test_str_len); | ||
| 5931 | btf__get_strings(expect_btf, &expect_strs, &expect_str_len); | ||
| 5932 | if (CHECK(test_str_len != expect_str_len, | ||
| 5933 | "test_str_len:%u != expect_str_len:%u", | ||
| 5934 | test_str_len, expect_str_len)) { | ||
| 5935 | fprintf(stderr, "\ntest strings:\n"); | ||
| 5936 | dump_btf_strings(test_strs, test_str_len); | ||
| 5937 | fprintf(stderr, "\nexpected strings:\n"); | ||
| 5938 | dump_btf_strings(expect_strs, expect_str_len); | ||
| 5939 | err = -1; | ||
| 5940 | goto done; | ||
| 5941 | } | ||
| 5942 | |||
| 5943 | test_str_cur = test_strs; | ||
| 5944 | test_str_end = test_strs + test_str_len; | ||
| 5945 | expect_str_cur = expect_strs; | ||
| 5946 | expect_str_end = expect_strs + expect_str_len; | ||
| 5947 | while (test_str_cur < test_str_end && expect_str_cur < expect_str_end) { | ||
| 5948 | size_t test_len, expect_len; | ||
| 5949 | |||
| 5950 | test_len = strlen(test_str_cur); | ||
| 5951 | expect_len = strlen(expect_str_cur); | ||
| 5952 | if (CHECK(test_len != expect_len, | ||
| 5953 | "test_len:%zu != expect_len:%zu " | ||
| 5954 | "(test_str:%s, expect_str:%s)", | ||
| 5955 | test_len, expect_len, test_str_cur, expect_str_cur)) { | ||
| 5956 | err = -1; | ||
| 5957 | goto done; | ||
| 5958 | } | ||
| 5959 | if (CHECK(strcmp(test_str_cur, expect_str_cur), | ||
| 5960 | "test_str:%s != expect_str:%s", | ||
| 5961 | test_str_cur, expect_str_cur)) { | ||
| 5962 | err = -1; | ||
| 5963 | goto done; | ||
| 5964 | } | ||
| 5965 | test_str_cur += test_len + 1; | ||
| 5966 | expect_str_cur += expect_len + 1; | ||
| 5967 | } | ||
| 5968 | if (CHECK(test_str_cur != test_str_end, | ||
| 5969 | "test_str_cur:%p != test_str_end:%p", | ||
| 5970 | test_str_cur, test_str_end)) { | ||
| 5971 | err = -1; | ||
| 5972 | goto done; | ||
| 5973 | } | ||
| 5974 | |||
| 5975 | test_nr_types = btf__get_nr_types(test_btf); | ||
| 5976 | expect_nr_types = btf__get_nr_types(expect_btf); | ||
| 5977 | if (CHECK(test_nr_types != expect_nr_types, | ||
| 5978 | "test_nr_types:%u != expect_nr_types:%u", | ||
| 5979 | test_nr_types, expect_nr_types)) { | ||
| 5980 | err = -1; | ||
| 5981 | goto done; | ||
| 5982 | } | ||
| 5983 | |||
| 5984 | for (i = 1; i <= test_nr_types; i++) { | ||
| 5985 | const struct btf_type *test_type, *expect_type; | ||
| 5986 | int test_size, expect_size; | ||
| 5987 | |||
| 5988 | test_type = btf__type_by_id(test_btf, i); | ||
| 5989 | expect_type = btf__type_by_id(expect_btf, i); | ||
| 5990 | test_size = btf_type_size(test_type); | ||
| 5991 | expect_size = btf_type_size(expect_type); | ||
| 5992 | |||
| 5993 | if (CHECK(test_size != expect_size, | ||
| 5994 | "type #%d: test_size:%d != expect_size:%u", | ||
| 5995 | i, test_size, expect_size)) { | ||
| 5996 | err = -1; | ||
| 5997 | goto done; | ||
| 5998 | } | ||
| 5999 | if (CHECK(memcmp((void *)test_type, | ||
| 6000 | (void *)expect_type, | ||
| 6001 | test_size), | ||
| 6002 | "type #%d: contents differ", i)) { | ||
| 6003 | err = -1; | ||
| 6004 | goto done; | ||
| 6005 | } | ||
| 6006 | } | ||
| 6007 | |||
| 6008 | done: | ||
| 6009 | if (!err) | ||
| 6010 | fprintf(stderr, "OK"); | ||
| 6011 | if (!IS_ERR(test_btf)) | ||
| 6012 | btf__free(test_btf); | ||
| 6013 | if (!IS_ERR(expect_btf)) | ||
| 6014 | btf__free(expect_btf); | ||
| 6015 | |||
| 6016 | return err; | ||
| 6017 | } | ||
| 6018 | |||
| 6019 | static int test_dedup(void) | ||
| 6020 | { | ||
| 6021 | unsigned int i; | ||
| 6022 | int err = 0; | ||
| 6023 | |||
| 6024 | if (args.dedup_test_num) | ||
| 6025 | return count_result(do_test_dedup(args.dedup_test_num)); | ||
| 6026 | |||
| 6027 | for (i = 1; i <= ARRAY_SIZE(dedup_tests); i++) | ||
| 6028 | err |= count_result(do_test_dedup(i)); | ||
| 6029 | |||
| 6030 | return err; | ||
| 6031 | } | ||
| 6032 | |||
| 5554 | static void usage(const char *cmd) | 6033 | static void usage(const char *cmd) |
| 5555 | { | 6034 | { |
| 5556 | fprintf(stderr, "Usage: %s [-l] [[-r btf_raw_test_num (1 - %zu)] |\n" | 6035 | fprintf(stderr, "Usage: %s [-l] [[-r btf_raw_test_num (1 - %zu)] |\n" |
| 5557 | "\t[-g btf_get_info_test_num (1 - %zu)] |\n" | 6036 | "\t[-g btf_get_info_test_num (1 - %zu)] |\n" |
| 5558 | "\t[-f btf_file_test_num (1 - %zu)] |\n" | 6037 | "\t[-f btf_file_test_num (1 - %zu)] |\n" |
| 5559 | "\t[-k btf_prog_info_raw_test_num (1 - %zu)] |\n" | 6038 | "\t[-k btf_prog_info_raw_test_num (1 - %zu)] |\n" |
| 5560 | "\t[-p (pretty print test)]]\n", | 6039 | "\t[-p (pretty print test)] |\n" |
| 6040 | "\t[-d btf_dedup_test_num (1 - %zu)]]\n", | ||
| 5561 | cmd, ARRAY_SIZE(raw_tests), ARRAY_SIZE(get_info_tests), | 6041 | cmd, ARRAY_SIZE(raw_tests), ARRAY_SIZE(get_info_tests), |
| 5562 | ARRAY_SIZE(file_tests), ARRAY_SIZE(info_raw_tests)); | 6042 | ARRAY_SIZE(file_tests), ARRAY_SIZE(info_raw_tests), |
| 6043 | ARRAY_SIZE(dedup_tests)); | ||
| 5563 | } | 6044 | } |
| 5564 | 6045 | ||
| 5565 | static int parse_args(int argc, char **argv) | 6046 | static int parse_args(int argc, char **argv) |
| 5566 | { | 6047 | { |
| 5567 | const char *optstr = "lpk:f:r:g:"; | 6048 | const char *optstr = "hlpk:f:r:g:d:"; |
| 5568 | int opt; | 6049 | int opt; |
| 5569 | 6050 | ||
| 5570 | while ((opt = getopt(argc, argv, optstr)) != -1) { | 6051 | while ((opt = getopt(argc, argv, optstr)) != -1) { |
| @@ -5591,12 +6072,16 @@ static int parse_args(int argc, char **argv) | |||
| 5591 | args.info_raw_test_num = atoi(optarg); | 6072 | args.info_raw_test_num = atoi(optarg); |
| 5592 | args.info_raw_test = true; | 6073 | args.info_raw_test = true; |
| 5593 | break; | 6074 | break; |
| 6075 | case 'd': | ||
| 6076 | args.dedup_test_num = atoi(optarg); | ||
| 6077 | args.dedup_test = true; | ||
| 6078 | break; | ||
| 5594 | case 'h': | 6079 | case 'h': |
| 5595 | usage(argv[0]); | 6080 | usage(argv[0]); |
| 5596 | exit(0); | 6081 | exit(0); |
| 5597 | default: | 6082 | default: |
| 5598 | usage(argv[0]); | 6083 | usage(argv[0]); |
| 5599 | return -1; | 6084 | return -1; |
| 5600 | } | 6085 | } |
| 5601 | } | 6086 | } |
| 5602 | 6087 | ||
| @@ -5632,6 +6117,14 @@ static int parse_args(int argc, char **argv) | |||
| 5632 | return -1; | 6117 | return -1; |
| 5633 | } | 6118 | } |
| 5634 | 6119 | ||
| 6120 | if (args.dedup_test_num && | ||
| 6121 | (args.dedup_test_num < 1 || | ||
| 6122 | args.dedup_test_num > ARRAY_SIZE(dedup_tests))) { | ||
| 6123 | fprintf(stderr, "BTF dedup test number must be [1 - %zu]\n", | ||
| 6124 | ARRAY_SIZE(dedup_tests)); | ||
| 6125 | return -1; | ||
| 6126 | } | ||
| 6127 | |||
| 5635 | return 0; | 6128 | return 0; |
| 5636 | } | 6129 | } |
| 5637 | 6130 | ||
| @@ -5650,7 +6143,7 @@ int main(int argc, char **argv) | |||
| 5650 | return err; | 6143 | return err; |
| 5651 | 6144 | ||
| 5652 | if (args.always_log) | 6145 | if (args.always_log) |
| 5653 | libbpf_set_print(__base_pr, __base_pr, __base_pr); | 6146 | libbpf_set_print(__base_pr); |
| 5654 | 6147 | ||
| 5655 | if (args.raw_test) | 6148 | if (args.raw_test) |
| 5656 | err |= test_raw(); | 6149 | err |= test_raw(); |
| @@ -5667,14 +6160,18 @@ int main(int argc, char **argv) | |||
| 5667 | if (args.info_raw_test) | 6160 | if (args.info_raw_test) |
| 5668 | err |= test_info_raw(); | 6161 | err |= test_info_raw(); |
| 5669 | 6162 | ||
| 6163 | if (args.dedup_test) | ||
| 6164 | err |= test_dedup(); | ||
| 6165 | |||
| 5670 | if (args.raw_test || args.get_info_test || args.file_test || | 6166 | if (args.raw_test || args.get_info_test || args.file_test || |
| 5671 | args.pprint_test || args.info_raw_test) | 6167 | args.pprint_test || args.info_raw_test || args.dedup_test) |
| 5672 | goto done; | 6168 | goto done; |
| 5673 | 6169 | ||
| 5674 | err |= test_raw(); | 6170 | err |= test_raw(); |
| 5675 | err |= test_get_info(); | 6171 | err |= test_get_info(); |
| 5676 | err |= test_file(); | 6172 | err |= test_file(); |
| 5677 | err |= test_info_raw(); | 6173 | err |= test_info_raw(); |
| 6174 | err |= test_dedup(); | ||
| 5678 | 6175 | ||
| 5679 | done: | 6176 | done: |
| 5680 | print_summary(); | 6177 | print_summary(); |
diff --git a/tools/testing/selftests/bpf/test_libbpf_open.c b/tools/testing/selftests/bpf/test_libbpf_open.c index 8fcd1c076add..1909ecf4d999 100644 --- a/tools/testing/selftests/bpf/test_libbpf_open.c +++ b/tools/testing/selftests/bpf/test_libbpf_open.c | |||
| @@ -34,23 +34,16 @@ static void usage(char *argv[]) | |||
| 34 | printf("\n"); | 34 | printf("\n"); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | #define DEFINE_PRINT_FN(name, enabled) \ | 37 | static bool debug = 0; |
| 38 | static int libbpf_##name(const char *fmt, ...) \ | 38 | static int libbpf_debug_print(enum libbpf_print_level level, |
| 39 | { \ | 39 | const char *fmt, va_list args) |
| 40 | va_list args; \ | 40 | { |
| 41 | int ret; \ | 41 | if (level == LIBBPF_DEBUG && !debug) |
| 42 | \ | 42 | return 0; |
| 43 | va_start(args, fmt); \ | 43 | |
| 44 | if (enabled) { \ | 44 | fprintf(stderr, "[%d] ", level); |
| 45 | fprintf(stderr, "[" #name "] "); \ | 45 | return vfprintf(stderr, fmt, args); |
| 46 | ret = vfprintf(stderr, fmt, args); \ | ||
| 47 | } \ | ||
| 48 | va_end(args); \ | ||
| 49 | return ret; \ | ||
| 50 | } | 46 | } |
| 51 | DEFINE_PRINT_FN(warning, 1) | ||
| 52 | DEFINE_PRINT_FN(info, 1) | ||
| 53 | DEFINE_PRINT_FN(debug, 1) | ||
| 54 | 47 | ||
| 55 | #define EXIT_FAIL_LIBBPF EXIT_FAILURE | 48 | #define EXIT_FAIL_LIBBPF EXIT_FAILURE |
| 56 | #define EXIT_FAIL_OPTION 2 | 49 | #define EXIT_FAIL_OPTION 2 |
| @@ -120,15 +113,14 @@ int main(int argc, char **argv) | |||
| 120 | int longindex = 0; | 113 | int longindex = 0; |
| 121 | int opt; | 114 | int opt; |
| 122 | 115 | ||
| 123 | libbpf_set_print(libbpf_warning, libbpf_info, NULL); | 116 | libbpf_set_print(libbpf_debug_print); |
| 124 | 117 | ||
| 125 | /* Parse commands line args */ | 118 | /* Parse commands line args */ |
| 126 | while ((opt = getopt_long(argc, argv, "hDq", | 119 | while ((opt = getopt_long(argc, argv, "hDq", |
| 127 | long_options, &longindex)) != -1) { | 120 | long_options, &longindex)) != -1) { |
| 128 | switch (opt) { | 121 | switch (opt) { |
| 129 | case 'D': | 122 | case 'D': |
| 130 | libbpf_set_print(libbpf_warning, libbpf_info, | 123 | debug = 1; |
| 131 | libbpf_debug); | ||
| 132 | break; | 124 | break; |
| 133 | case 'q': /* Use in scripting mode */ | 125 | case 'q': /* Use in scripting mode */ |
| 134 | verbose = 0; | 126 | verbose = 0; |
diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c index e7798dd97f4b..3c627771f965 100644 --- a/tools/testing/selftests/bpf/test_maps.c +++ b/tools/testing/selftests/bpf/test_maps.c | |||
| @@ -45,7 +45,7 @@ static int map_flags; | |||
| 45 | } \ | 45 | } \ |
| 46 | }) | 46 | }) |
| 47 | 47 | ||
| 48 | static void test_hashmap(int task, void *data) | 48 | static void test_hashmap(unsigned int task, void *data) |
| 49 | { | 49 | { |
| 50 | long long key, next_key, first_key, value; | 50 | long long key, next_key, first_key, value; |
| 51 | int fd; | 51 | int fd; |
| @@ -135,7 +135,7 @@ static void test_hashmap(int task, void *data) | |||
| 135 | close(fd); | 135 | close(fd); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | static void test_hashmap_sizes(int task, void *data) | 138 | static void test_hashmap_sizes(unsigned int task, void *data) |
| 139 | { | 139 | { |
| 140 | int fd, i, j; | 140 | int fd, i, j; |
| 141 | 141 | ||
| @@ -155,7 +155,7 @@ static void test_hashmap_sizes(int task, void *data) | |||
| 155 | } | 155 | } |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | static void test_hashmap_percpu(int task, void *data) | 158 | static void test_hashmap_percpu(unsigned int task, void *data) |
| 159 | { | 159 | { |
| 160 | unsigned int nr_cpus = bpf_num_possible_cpus(); | 160 | unsigned int nr_cpus = bpf_num_possible_cpus(); |
| 161 | BPF_DECLARE_PERCPU(long, value); | 161 | BPF_DECLARE_PERCPU(long, value); |
| @@ -282,7 +282,7 @@ static int helper_fill_hashmap(int max_entries) | |||
| 282 | return fd; | 282 | return fd; |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | static void test_hashmap_walk(int task, void *data) | 285 | static void test_hashmap_walk(unsigned int task, void *data) |
| 286 | { | 286 | { |
| 287 | int fd, i, max_entries = 1000; | 287 | int fd, i, max_entries = 1000; |
| 288 | long long key, value, next_key; | 288 | long long key, value, next_key; |
| @@ -353,7 +353,7 @@ static void test_hashmap_zero_seed(void) | |||
| 353 | close(second); | 353 | close(second); |
| 354 | } | 354 | } |
| 355 | 355 | ||
| 356 | static void test_arraymap(int task, void *data) | 356 | static void test_arraymap(unsigned int task, void *data) |
| 357 | { | 357 | { |
| 358 | int key, next_key, fd; | 358 | int key, next_key, fd; |
| 359 | long long value; | 359 | long long value; |
| @@ -408,7 +408,7 @@ static void test_arraymap(int task, void *data) | |||
| 408 | close(fd); | 408 | close(fd); |
| 409 | } | 409 | } |
| 410 | 410 | ||
| 411 | static void test_arraymap_percpu(int task, void *data) | 411 | static void test_arraymap_percpu(unsigned int task, void *data) |
| 412 | { | 412 | { |
| 413 | unsigned int nr_cpus = bpf_num_possible_cpus(); | 413 | unsigned int nr_cpus = bpf_num_possible_cpus(); |
| 414 | BPF_DECLARE_PERCPU(long, values); | 414 | BPF_DECLARE_PERCPU(long, values); |
| @@ -504,7 +504,7 @@ static void test_arraymap_percpu_many_keys(void) | |||
| 504 | close(fd); | 504 | close(fd); |
| 505 | } | 505 | } |
| 506 | 506 | ||
| 507 | static void test_devmap(int task, void *data) | 507 | static void test_devmap(unsigned int task, void *data) |
| 508 | { | 508 | { |
| 509 | int fd; | 509 | int fd; |
| 510 | __u32 key, value; | 510 | __u32 key, value; |
| @@ -519,7 +519,7 @@ static void test_devmap(int task, void *data) | |||
| 519 | close(fd); | 519 | close(fd); |
| 520 | } | 520 | } |
| 521 | 521 | ||
| 522 | static void test_queuemap(int task, void *data) | 522 | static void test_queuemap(unsigned int task, void *data) |
| 523 | { | 523 | { |
| 524 | const int MAP_SIZE = 32; | 524 | const int MAP_SIZE = 32; |
| 525 | __u32 vals[MAP_SIZE + MAP_SIZE/2], val; | 525 | __u32 vals[MAP_SIZE + MAP_SIZE/2], val; |
| @@ -577,7 +577,7 @@ static void test_queuemap(int task, void *data) | |||
| 577 | close(fd); | 577 | close(fd); |
| 578 | } | 578 | } |
| 579 | 579 | ||
| 580 | static void test_stackmap(int task, void *data) | 580 | static void test_stackmap(unsigned int task, void *data) |
| 581 | { | 581 | { |
| 582 | const int MAP_SIZE = 32; | 582 | const int MAP_SIZE = 32; |
| 583 | __u32 vals[MAP_SIZE + MAP_SIZE/2], val; | 583 | __u32 vals[MAP_SIZE + MAP_SIZE/2], val; |
| @@ -642,7 +642,7 @@ static void test_stackmap(int task, void *data) | |||
| 642 | #define SOCKMAP_PARSE_PROG "./sockmap_parse_prog.o" | 642 | #define SOCKMAP_PARSE_PROG "./sockmap_parse_prog.o" |
| 643 | #define SOCKMAP_VERDICT_PROG "./sockmap_verdict_prog.o" | 643 | #define SOCKMAP_VERDICT_PROG "./sockmap_verdict_prog.o" |
| 644 | #define SOCKMAP_TCP_MSG_PROG "./sockmap_tcp_msg_prog.o" | 644 | #define SOCKMAP_TCP_MSG_PROG "./sockmap_tcp_msg_prog.o" |
| 645 | static void test_sockmap(int tasks, void *data) | 645 | static void test_sockmap(unsigned int tasks, void *data) |
| 646 | { | 646 | { |
| 647 | struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_msg, *bpf_map_break; | 647 | struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_msg, *bpf_map_break; |
| 648 | int map_fd_msg = 0, map_fd_rx = 0, map_fd_tx = 0, map_fd_break; | 648 | int map_fd_msg = 0, map_fd_rx = 0, map_fd_tx = 0, map_fd_break; |
| @@ -1268,10 +1268,11 @@ static void test_map_large(void) | |||
| 1268 | } | 1268 | } |
| 1269 | 1269 | ||
| 1270 | #define run_parallel(N, FN, DATA) \ | 1270 | #define run_parallel(N, FN, DATA) \ |
| 1271 | printf("Fork %d tasks to '" #FN "'\n", N); \ | 1271 | printf("Fork %u tasks to '" #FN "'\n", N); \ |
| 1272 | __run_parallel(N, FN, DATA) | 1272 | __run_parallel(N, FN, DATA) |
| 1273 | 1273 | ||
| 1274 | static void __run_parallel(int tasks, void (*fn)(int task, void *data), | 1274 | static void __run_parallel(unsigned int tasks, |
| 1275 | void (*fn)(unsigned int task, void *data), | ||
| 1275 | void *data) | 1276 | void *data) |
| 1276 | { | 1277 | { |
| 1277 | pid_t pid[tasks]; | 1278 | pid_t pid[tasks]; |
| @@ -1312,7 +1313,7 @@ static void test_map_stress(void) | |||
| 1312 | #define DO_UPDATE 1 | 1313 | #define DO_UPDATE 1 |
| 1313 | #define DO_DELETE 0 | 1314 | #define DO_DELETE 0 |
| 1314 | 1315 | ||
| 1315 | static void test_update_delete(int fn, void *data) | 1316 | static void test_update_delete(unsigned int fn, void *data) |
| 1316 | { | 1317 | { |
| 1317 | int do_update = ((int *)data)[1]; | 1318 | int do_update = ((int *)data)[1]; |
| 1318 | int fd = ((int *)data)[0]; | 1319 | int fd = ((int *)data)[0]; |
diff --git a/tools/testing/selftests/bpf/test_offload.py b/tools/testing/selftests/bpf/test_offload.py index d59642e70f56..84bea3985d64 100755 --- a/tools/testing/selftests/bpf/test_offload.py +++ b/tools/testing/selftests/bpf/test_offload.py | |||
| @@ -23,6 +23,7 @@ import string | |||
| 23 | import struct | 23 | import struct |
| 24 | import subprocess | 24 | import subprocess |
| 25 | import time | 25 | import time |
| 26 | import traceback | ||
| 26 | 27 | ||
| 27 | logfile = None | 28 | logfile = None |
| 28 | log_level = 1 | 29 | log_level = 1 |
| @@ -78,7 +79,9 @@ def fail(cond, msg): | |||
| 78 | if not cond: | 79 | if not cond: |
| 79 | return | 80 | return |
| 80 | print("FAIL: " + msg) | 81 | print("FAIL: " + msg) |
| 81 | log("FAIL: " + msg, "", level=1) | 82 | tb = "".join(traceback.extract_stack().format()) |
| 83 | print(tb) | ||
| 84 | log("FAIL: " + msg, tb, level=1) | ||
| 82 | os.sys.exit(1) | 85 | os.sys.exit(1) |
| 83 | 86 | ||
| 84 | def start_test(msg): | 87 | def start_test(msg): |
| @@ -589,6 +592,15 @@ def check_verifier_log(output, reference): | |||
| 589 | return | 592 | return |
| 590 | fail(True, "Missing or incorrect message from netdevsim in verifier log") | 593 | fail(True, "Missing or incorrect message from netdevsim in verifier log") |
| 591 | 594 | ||
| 595 | def check_multi_basic(two_xdps): | ||
| 596 | fail(two_xdps["mode"] != 4, "Bad mode reported with multiple programs") | ||
| 597 | fail("prog" in two_xdps, "Base program reported in multi program mode") | ||
| 598 | fail(len(two_xdps["attached"]) != 2, | ||
| 599 | "Wrong attached program count with two programs") | ||
| 600 | fail(two_xdps["attached"][0]["prog"]["id"] == | ||
| 601 | two_xdps["attached"][1]["prog"]["id"], | ||
| 602 | "Offloaded and other programs have the same id") | ||
| 603 | |||
| 592 | def test_spurios_extack(sim, obj, skip_hw, needle): | 604 | def test_spurios_extack(sim, obj, skip_hw, needle): |
| 593 | res = sim.cls_bpf_add_filter(obj, prio=1, handle=1, skip_hw=skip_hw, | 605 | res = sim.cls_bpf_add_filter(obj, prio=1, handle=1, skip_hw=skip_hw, |
| 594 | include_stderr=True) | 606 | include_stderr=True) |
| @@ -600,6 +612,67 @@ def test_spurios_extack(sim, obj, skip_hw, needle): | |||
| 600 | include_stderr=True) | 612 | include_stderr=True) |
| 601 | check_no_extack(res, needle) | 613 | check_no_extack(res, needle) |
| 602 | 614 | ||
| 615 | def test_multi_prog(sim, obj, modename, modeid): | ||
| 616 | start_test("Test multi-attachment XDP - %s + offload..." % | ||
| 617 | (modename or "default", )) | ||
| 618 | sim.set_xdp(obj, "offload") | ||
| 619 | xdp = sim.ip_link_show(xdp=True)["xdp"] | ||
| 620 | offloaded = sim.dfs_read("bpf_offloaded_id") | ||
| 621 | fail("prog" not in xdp, "Base program not reported in single program mode") | ||
| 622 | fail(len(xdp["attached"]) != 1, | ||
| 623 | "Wrong attached program count with one program") | ||
| 624 | |||
| 625 | sim.set_xdp(obj, modename) | ||
| 626 | two_xdps = sim.ip_link_show(xdp=True)["xdp"] | ||
| 627 | |||
| 628 | fail(xdp["attached"][0] not in two_xdps["attached"], | ||
| 629 | "Offload program not reported after other activated") | ||
| 630 | check_multi_basic(two_xdps) | ||
| 631 | |||
| 632 | offloaded2 = sim.dfs_read("bpf_offloaded_id") | ||
| 633 | fail(offloaded != offloaded2, | ||
| 634 | "Offload ID changed after loading other program") | ||
| 635 | |||
| 636 | start_test("Test multi-attachment XDP - replace...") | ||
| 637 | ret, _, err = sim.set_xdp(obj, "offload", fail=False, include_stderr=True) | ||
| 638 | fail(ret == 0, "Replaced one of programs without -force") | ||
| 639 | check_extack(err, "XDP program already attached.", args) | ||
| 640 | |||
| 641 | if modename == "" or modename == "drv": | ||
| 642 | othermode = "" if modename == "drv" else "drv" | ||
| 643 | start_test("Test multi-attachment XDP - detach...") | ||
| 644 | ret, _, err = sim.unset_xdp(othermode, force=True, | ||
| 645 | fail=False, include_stderr=True) | ||
| 646 | fail(ret == 0, "Removed program with a bad mode") | ||
| 647 | check_extack(err, "program loaded with different flags.", args) | ||
| 648 | |||
| 649 | sim.unset_xdp("offload") | ||
| 650 | xdp = sim.ip_link_show(xdp=True)["xdp"] | ||
| 651 | offloaded = sim.dfs_read("bpf_offloaded_id") | ||
| 652 | |||
| 653 | fail(xdp["mode"] != modeid, "Bad mode reported after multiple programs") | ||
| 654 | fail("prog" not in xdp, | ||
| 655 | "Base program not reported after multi program mode") | ||
| 656 | fail(xdp["attached"][0] not in two_xdps["attached"], | ||
| 657 | "Offload program not reported after other activated") | ||
| 658 | fail(len(xdp["attached"]) != 1, | ||
| 659 | "Wrong attached program count with remaining programs") | ||
| 660 | fail(offloaded != "0", "Offload ID reported with only other program left") | ||
| 661 | |||
| 662 | start_test("Test multi-attachment XDP - reattach...") | ||
| 663 | sim.set_xdp(obj, "offload") | ||
| 664 | two_xdps = sim.ip_link_show(xdp=True)["xdp"] | ||
| 665 | |||
| 666 | fail(xdp["attached"][0] not in two_xdps["attached"], | ||
| 667 | "Other program not reported after offload activated") | ||
| 668 | check_multi_basic(two_xdps) | ||
| 669 | |||
| 670 | start_test("Test multi-attachment XDP - device remove...") | ||
| 671 | sim.remove() | ||
| 672 | |||
| 673 | sim = NetdevSim() | ||
| 674 | sim.set_ethtool_tc_offloads(True) | ||
| 675 | return sim | ||
| 603 | 676 | ||
| 604 | # Parse command line | 677 | # Parse command line |
| 605 | parser = argparse.ArgumentParser() | 678 | parser = argparse.ArgumentParser() |
| @@ -842,7 +915,9 @@ try: | |||
| 842 | ret, _, err = sim.set_xdp(obj, "generic", force=True, | 915 | ret, _, err = sim.set_xdp(obj, "generic", force=True, |
| 843 | fail=False, include_stderr=True) | 916 | fail=False, include_stderr=True) |
| 844 | fail(ret == 0, "Replaced XDP program with a program in different mode") | 917 | fail(ret == 0, "Replaced XDP program with a program in different mode") |
| 845 | fail(err.count("File exists") != 1, "Replaced driver XDP with generic") | 918 | check_extack(err, |
| 919 | "native and generic XDP can't be active at the same time.", | ||
| 920 | args) | ||
| 846 | ret, _, err = sim.set_xdp(obj, "", force=True, | 921 | ret, _, err = sim.set_xdp(obj, "", force=True, |
| 847 | fail=False, include_stderr=True) | 922 | fail=False, include_stderr=True) |
| 848 | fail(ret == 0, "Replaced XDP program with a program in different mode") | 923 | fail(ret == 0, "Replaced XDP program with a program in different mode") |
| @@ -931,59 +1006,9 @@ try: | |||
| 931 | rm(pin_file) | 1006 | rm(pin_file) |
| 932 | bpftool_prog_list_wait(expected=0) | 1007 | bpftool_prog_list_wait(expected=0) |
| 933 | 1008 | ||
| 934 | start_test("Test multi-attachment XDP - attach...") | 1009 | sim = test_multi_prog(sim, obj, "", 1) |
| 935 | sim.set_xdp(obj, "offload") | 1010 | sim = test_multi_prog(sim, obj, "drv", 1) |
| 936 | xdp = sim.ip_link_show(xdp=True)["xdp"] | 1011 | sim = test_multi_prog(sim, obj, "generic", 2) |
| 937 | offloaded = sim.dfs_read("bpf_offloaded_id") | ||
| 938 | fail("prog" not in xdp, "Base program not reported in single program mode") | ||
| 939 | fail(len(ipl["xdp"]["attached"]) != 1, | ||
| 940 | "Wrong attached program count with one program") | ||
| 941 | |||
| 942 | sim.set_xdp(obj, "") | ||
| 943 | two_xdps = sim.ip_link_show(xdp=True)["xdp"] | ||
| 944 | offloaded2 = sim.dfs_read("bpf_offloaded_id") | ||
| 945 | |||
| 946 | fail(two_xdps["mode"] != 4, "Bad mode reported with multiple programs") | ||
| 947 | fail("prog" in two_xdps, "Base program reported in multi program mode") | ||
| 948 | fail(xdp["attached"][0] not in two_xdps["attached"], | ||
| 949 | "Offload program not reported after driver activated") | ||
| 950 | fail(len(two_xdps["attached"]) != 2, | ||
| 951 | "Wrong attached program count with two programs") | ||
| 952 | fail(two_xdps["attached"][0]["prog"]["id"] == | ||
| 953 | two_xdps["attached"][1]["prog"]["id"], | ||
| 954 | "offloaded and drv programs have the same id") | ||
| 955 | fail(offloaded != offloaded2, | ||
| 956 | "offload ID changed after loading driver program") | ||
| 957 | |||
| 958 | start_test("Test multi-attachment XDP - replace...") | ||
| 959 | ret, _, err = sim.set_xdp(obj, "offload", fail=False, include_stderr=True) | ||
| 960 | fail(err.count("busy") != 1, "Replaced one of programs without -force") | ||
| 961 | |||
| 962 | start_test("Test multi-attachment XDP - detach...") | ||
| 963 | ret, _, err = sim.unset_xdp("drv", force=True, | ||
| 964 | fail=False, include_stderr=True) | ||
| 965 | fail(ret == 0, "Removed program with a bad mode") | ||
| 966 | check_extack(err, "program loaded with different flags.", args) | ||
| 967 | |||
| 968 | sim.unset_xdp("offload") | ||
| 969 | xdp = sim.ip_link_show(xdp=True)["xdp"] | ||
| 970 | offloaded = sim.dfs_read("bpf_offloaded_id") | ||
| 971 | |||
| 972 | fail(xdp["mode"] != 1, "Bad mode reported after multiple programs") | ||
| 973 | fail("prog" not in xdp, | ||
| 974 | "Base program not reported after multi program mode") | ||
| 975 | fail(xdp["attached"][0] not in two_xdps["attached"], | ||
| 976 | "Offload program not reported after driver activated") | ||
| 977 | fail(len(ipl["xdp"]["attached"]) != 1, | ||
| 978 | "Wrong attached program count with remaining programs") | ||
| 979 | fail(offloaded != "0", "offload ID reported with only driver program left") | ||
| 980 | |||
| 981 | start_test("Test multi-attachment XDP - device remove...") | ||
| 982 | sim.set_xdp(obj, "offload") | ||
| 983 | sim.remove() | ||
| 984 | |||
| 985 | sim = NetdevSim() | ||
| 986 | sim.set_ethtool_tc_offloads(True) | ||
| 987 | 1012 | ||
| 988 | start_test("Test mixing of TC and XDP...") | 1013 | start_test("Test mixing of TC and XDP...") |
| 989 | sim.tc_add_ingress() | 1014 | sim.tc_add_ingress() |
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index a08d026ac396..c52bd90fbb34 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <string.h> | 10 | #include <string.h> |
| 11 | #include <assert.h> | 11 | #include <assert.h> |
| 12 | #include <stdlib.h> | 12 | #include <stdlib.h> |
| 13 | #include <stdarg.h> | ||
| 13 | #include <time.h> | 14 | #include <time.h> |
| 14 | 15 | ||
| 15 | #include <linux/types.h> | 16 | #include <linux/types.h> |
| @@ -1783,6 +1784,15 @@ static void test_task_fd_query_tp(void) | |||
| 1783 | "sys_enter_read"); | 1784 | "sys_enter_read"); |
| 1784 | } | 1785 | } |
| 1785 | 1786 | ||
| 1787 | static int libbpf_debug_print(enum libbpf_print_level level, | ||
| 1788 | const char *format, va_list args) | ||
| 1789 | { | ||
| 1790 | if (level == LIBBPF_DEBUG) | ||
| 1791 | return 0; | ||
| 1792 | |||
| 1793 | return vfprintf(stderr, format, args); | ||
| 1794 | } | ||
| 1795 | |||
| 1786 | static void test_reference_tracking() | 1796 | static void test_reference_tracking() |
| 1787 | { | 1797 | { |
| 1788 | const char *file = "./test_sk_lookup_kern.o"; | 1798 | const char *file = "./test_sk_lookup_kern.o"; |
| @@ -1809,9 +1819,9 @@ static void test_reference_tracking() | |||
| 1809 | 1819 | ||
| 1810 | /* Expect verifier failure if test name has 'fail' */ | 1820 | /* Expect verifier failure if test name has 'fail' */ |
| 1811 | if (strstr(title, "fail") != NULL) { | 1821 | if (strstr(title, "fail") != NULL) { |
| 1812 | libbpf_set_print(NULL, NULL, NULL); | 1822 | libbpf_set_print(NULL); |
| 1813 | err = !bpf_program__load(prog, "GPL", 0); | 1823 | err = !bpf_program__load(prog, "GPL", 0); |
| 1814 | libbpf_set_print(printf, printf, NULL); | 1824 | libbpf_set_print(libbpf_debug_print); |
| 1815 | } else { | 1825 | } else { |
| 1816 | err = bpf_program__load(prog, "GPL", 0); | 1826 | err = bpf_program__load(prog, "GPL", 0); |
| 1817 | } | 1827 | } |
diff --git a/tools/testing/selftests/bpf/verifier/ctx_sk_msg.c b/tools/testing/selftests/bpf/verifier/ctx_sk_msg.c index b0195770da6a..c6c69220a569 100644 --- a/tools/testing/selftests/bpf/verifier/ctx_sk_msg.c +++ b/tools/testing/selftests/bpf/verifier/ctx_sk_msg.c | |||
| @@ -100,6 +100,7 @@ | |||
| 100 | .errstr = "invalid bpf_context access", | 100 | .errstr = "invalid bpf_context access", |
| 101 | .result = REJECT, | 101 | .result = REJECT, |
| 102 | .prog_type = BPF_PROG_TYPE_SK_MSG, | 102 | .prog_type = BPF_PROG_TYPE_SK_MSG, |
| 103 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 103 | }, | 104 | }, |
| 104 | { | 105 | { |
| 105 | "invalid read past end of SK_MSG", | 106 | "invalid read past end of SK_MSG", |
diff --git a/tools/testing/selftests/bpf/verifier/ctx_skb.c b/tools/testing/selftests/bpf/verifier/ctx_skb.c index 881f1c7f57a1..c660deb582f1 100644 --- a/tools/testing/selftests/bpf/verifier/ctx_skb.c +++ b/tools/testing/selftests/bpf/verifier/ctx_skb.c | |||
| @@ -687,6 +687,7 @@ | |||
| 687 | }, | 687 | }, |
| 688 | .errstr = "invalid bpf_context access", | 688 | .errstr = "invalid bpf_context access", |
| 689 | .result = REJECT, | 689 | .result = REJECT, |
| 690 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 690 | }, | 691 | }, |
| 691 | { | 692 | { |
| 692 | "check skb->hash half load not permitted, unaligned 3", | 693 | "check skb->hash half load not permitted, unaligned 3", |
diff --git a/tools/testing/selftests/bpf/verifier/jmp32.c b/tools/testing/selftests/bpf/verifier/jmp32.c index ceb39ffa0e88..f0961c58581e 100644 --- a/tools/testing/selftests/bpf/verifier/jmp32.c +++ b/tools/testing/selftests/bpf/verifier/jmp32.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | .data64 = { 1ULL << 63 | 1, } | 27 | .data64 = { 1ULL << 63 | 1, } |
| 28 | }, | 28 | }, |
| 29 | }, | 29 | }, |
| 30 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 30 | }, | 31 | }, |
| 31 | { | 32 | { |
| 32 | "jset32: BPF_X", | 33 | "jset32: BPF_X", |
| @@ -58,6 +59,7 @@ | |||
| 58 | .data64 = { 1ULL << 63 | 1, } | 59 | .data64 = { 1ULL << 63 | 1, } |
| 59 | }, | 60 | }, |
| 60 | }, | 61 | }, |
| 62 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 61 | }, | 63 | }, |
| 62 | { | 64 | { |
| 63 | "jset32: min/max deduction", | 65 | "jset32: min/max deduction", |
| @@ -93,6 +95,7 @@ | |||
| 93 | .data64 = { -1, } | 95 | .data64 = { -1, } |
| 94 | }, | 96 | }, |
| 95 | }, | 97 | }, |
| 98 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 96 | }, | 99 | }, |
| 97 | { | 100 | { |
| 98 | "jeq32: BPF_X", | 101 | "jeq32: BPF_X", |
| @@ -119,6 +122,7 @@ | |||
| 119 | .data64 = { 1ULL << 63 | 1, } | 122 | .data64 = { 1ULL << 63 | 1, } |
| 120 | }, | 123 | }, |
| 121 | }, | 124 | }, |
| 125 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 122 | }, | 126 | }, |
| 123 | { | 127 | { |
| 124 | "jeq32: min/max deduction", | 128 | "jeq32: min/max deduction", |
| @@ -154,6 +158,7 @@ | |||
| 154 | .data64 = { -1, } | 158 | .data64 = { -1, } |
| 155 | }, | 159 | }, |
| 156 | }, | 160 | }, |
| 161 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 157 | }, | 162 | }, |
| 158 | { | 163 | { |
| 159 | "jne32: BPF_X", | 164 | "jne32: BPF_X", |
| @@ -180,6 +185,7 @@ | |||
| 180 | .data64 = { 1ULL << 63 | 2, } | 185 | .data64 = { 1ULL << 63 | 2, } |
| 181 | }, | 186 | }, |
| 182 | }, | 187 | }, |
| 188 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 183 | }, | 189 | }, |
| 184 | { | 190 | { |
| 185 | "jne32: min/max deduction", | 191 | "jne32: min/max deduction", |
| @@ -218,6 +224,7 @@ | |||
| 218 | .data64 = { 0, } | 224 | .data64 = { 0, } |
| 219 | }, | 225 | }, |
| 220 | }, | 226 | }, |
| 227 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 221 | }, | 228 | }, |
| 222 | { | 229 | { |
| 223 | "jge32: BPF_X", | 230 | "jge32: BPF_X", |
| @@ -244,6 +251,7 @@ | |||
| 244 | .data64 = { (UINT_MAX - 1) | 2ULL << 32, } | 251 | .data64 = { (UINT_MAX - 1) | 2ULL << 32, } |
| 245 | }, | 252 | }, |
| 246 | }, | 253 | }, |
| 254 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 247 | }, | 255 | }, |
| 248 | { | 256 | { |
| 249 | "jge32: min/max deduction", | 257 | "jge32: min/max deduction", |
| @@ -284,6 +292,7 @@ | |||
| 284 | .data64 = { 0, } | 292 | .data64 = { 0, } |
| 285 | }, | 293 | }, |
| 286 | }, | 294 | }, |
| 295 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 287 | }, | 296 | }, |
| 288 | { | 297 | { |
| 289 | "jgt32: BPF_X", | 298 | "jgt32: BPF_X", |
| @@ -310,6 +319,7 @@ | |||
| 310 | .data64 = { (UINT_MAX - 1) | 2ULL << 32, } | 319 | .data64 = { (UINT_MAX - 1) | 2ULL << 32, } |
| 311 | }, | 320 | }, |
| 312 | }, | 321 | }, |
| 322 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 313 | }, | 323 | }, |
| 314 | { | 324 | { |
| 315 | "jgt32: min/max deduction", | 325 | "jgt32: min/max deduction", |
| @@ -350,6 +360,7 @@ | |||
| 350 | .data64 = { INT_MAX, } | 360 | .data64 = { INT_MAX, } |
| 351 | }, | 361 | }, |
| 352 | }, | 362 | }, |
| 363 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 353 | }, | 364 | }, |
| 354 | { | 365 | { |
| 355 | "jle32: BPF_X", | 366 | "jle32: BPF_X", |
| @@ -376,6 +387,7 @@ | |||
| 376 | .data64 = { UINT_MAX, } | 387 | .data64 = { UINT_MAX, } |
| 377 | }, | 388 | }, |
| 378 | }, | 389 | }, |
| 390 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 379 | }, | 391 | }, |
| 380 | { | 392 | { |
| 381 | "jle32: min/max deduction", | 393 | "jle32: min/max deduction", |
| @@ -416,6 +428,7 @@ | |||
| 416 | .data64 = { INT_MAX - 1, } | 428 | .data64 = { INT_MAX - 1, } |
| 417 | }, | 429 | }, |
| 418 | }, | 430 | }, |
| 431 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 419 | }, | 432 | }, |
| 420 | { | 433 | { |
| 421 | "jlt32: BPF_X", | 434 | "jlt32: BPF_X", |
| @@ -442,6 +455,7 @@ | |||
| 442 | .data64 = { (INT_MAX - 1) | 3ULL << 32, } | 455 | .data64 = { (INT_MAX - 1) | 3ULL << 32, } |
| 443 | }, | 456 | }, |
| 444 | }, | 457 | }, |
| 458 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 445 | }, | 459 | }, |
| 446 | { | 460 | { |
| 447 | "jlt32: min/max deduction", | 461 | "jlt32: min/max deduction", |
| @@ -482,6 +496,7 @@ | |||
| 482 | .data64 = { -2, } | 496 | .data64 = { -2, } |
| 483 | }, | 497 | }, |
| 484 | }, | 498 | }, |
| 499 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 485 | }, | 500 | }, |
| 486 | { | 501 | { |
| 487 | "jsge32: BPF_X", | 502 | "jsge32: BPF_X", |
| @@ -508,6 +523,7 @@ | |||
| 508 | .data64 = { -2, } | 523 | .data64 = { -2, } |
| 509 | }, | 524 | }, |
| 510 | }, | 525 | }, |
| 526 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 511 | }, | 527 | }, |
| 512 | { | 528 | { |
| 513 | "jsge32: min/max deduction", | 529 | "jsge32: min/max deduction", |
| @@ -548,6 +564,7 @@ | |||
| 548 | .data64 = { 1, } | 564 | .data64 = { 1, } |
| 549 | }, | 565 | }, |
| 550 | }, | 566 | }, |
| 567 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 551 | }, | 568 | }, |
| 552 | { | 569 | { |
| 553 | "jsgt32: BPF_X", | 570 | "jsgt32: BPF_X", |
| @@ -574,6 +591,7 @@ | |||
| 574 | .data64 = { 0x7fffffff, } | 591 | .data64 = { 0x7fffffff, } |
| 575 | }, | 592 | }, |
| 576 | }, | 593 | }, |
| 594 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 577 | }, | 595 | }, |
| 578 | { | 596 | { |
| 579 | "jsgt32: min/max deduction", | 597 | "jsgt32: min/max deduction", |
| @@ -614,6 +632,7 @@ | |||
| 614 | .data64 = { 1, } | 632 | .data64 = { 1, } |
| 615 | }, | 633 | }, |
| 616 | }, | 634 | }, |
| 635 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 617 | }, | 636 | }, |
| 618 | { | 637 | { |
| 619 | "jsle32: BPF_X", | 638 | "jsle32: BPF_X", |
| @@ -640,6 +659,7 @@ | |||
| 640 | .data64 = { 0x7fffffff | 2ULL << 32, } | 659 | .data64 = { 0x7fffffff | 2ULL << 32, } |
| 641 | }, | 660 | }, |
| 642 | }, | 661 | }, |
| 662 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 643 | }, | 663 | }, |
| 644 | { | 664 | { |
| 645 | "jsle32: min/max deduction", | 665 | "jsle32: min/max deduction", |
| @@ -680,6 +700,7 @@ | |||
| 680 | .data64 = { 1, } | 700 | .data64 = { 1, } |
| 681 | }, | 701 | }, |
| 682 | }, | 702 | }, |
| 703 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 683 | }, | 704 | }, |
| 684 | { | 705 | { |
| 685 | "jslt32: BPF_X", | 706 | "jslt32: BPF_X", |
| @@ -706,6 +727,7 @@ | |||
| 706 | .data64 = { 0x7fffffff | 2ULL << 32, } | 727 | .data64 = { 0x7fffffff | 2ULL << 32, } |
| 707 | }, | 728 | }, |
| 708 | }, | 729 | }, |
| 730 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 709 | }, | 731 | }, |
| 710 | { | 732 | { |
| 711 | "jslt32: min/max deduction", | 733 | "jslt32: min/max deduction", |
diff --git a/tools/testing/selftests/bpf/verifier/jset.c b/tools/testing/selftests/bpf/verifier/jset.c index 7e14037acfaf..8dcd4e0383d5 100644 --- a/tools/testing/selftests/bpf/verifier/jset.c +++ b/tools/testing/selftests/bpf/verifier/jset.c | |||
| @@ -53,6 +53,7 @@ | |||
| 53 | .data64 = { ~0ULL, } | 53 | .data64 = { ~0ULL, } |
| 54 | }, | 54 | }, |
| 55 | }, | 55 | }, |
| 56 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 56 | }, | 57 | }, |
| 57 | { | 58 | { |
| 58 | "jset: sign-extend", | 59 | "jset: sign-extend", |
| @@ -70,6 +71,7 @@ | |||
| 70 | .result = ACCEPT, | 71 | .result = ACCEPT, |
| 71 | .retval = 2, | 72 | .retval = 2, |
| 72 | .data = { 1, 0, 0, 0, 0, 0, 0, 1, }, | 73 | .data = { 1, 0, 0, 0, 0, 0, 0, 1, }, |
| 74 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 73 | }, | 75 | }, |
| 74 | { | 76 | { |
| 75 | "jset: known const compare", | 77 | "jset: known const compare", |
diff --git a/tools/testing/selftests/bpf/verifier/spill_fill.c b/tools/testing/selftests/bpf/verifier/spill_fill.c index d58db72fdfe8..45d43bf82f26 100644 --- a/tools/testing/selftests/bpf/verifier/spill_fill.c +++ b/tools/testing/selftests/bpf/verifier/spill_fill.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | .errstr_unpriv = "attempt to corrupt spilled", | 46 | .errstr_unpriv = "attempt to corrupt spilled", |
| 47 | .errstr = "R0 invalid mem access 'inv", | 47 | .errstr = "R0 invalid mem access 'inv", |
| 48 | .result = REJECT, | 48 | .result = REJECT, |
| 49 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 49 | }, | 50 | }, |
| 50 | { | 51 | { |
| 51 | "check corrupted spill/fill, LSB", | 52 | "check corrupted spill/fill, LSB", |
diff --git a/tools/testing/selftests/bpf/verifier/spin_lock.c b/tools/testing/selftests/bpf/verifier/spin_lock.c index d829eef372a4..781621facae4 100644 --- a/tools/testing/selftests/bpf/verifier/spin_lock.c +++ b/tools/testing/selftests/bpf/verifier/spin_lock.c | |||
| @@ -83,6 +83,7 @@ | |||
| 83 | .result_unpriv = REJECT, | 83 | .result_unpriv = REJECT, |
| 84 | .errstr_unpriv = "", | 84 | .errstr_unpriv = "", |
| 85 | .prog_type = BPF_PROG_TYPE_CGROUP_SKB, | 85 | .prog_type = BPF_PROG_TYPE_CGROUP_SKB, |
| 86 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 86 | }, | 87 | }, |
| 87 | { | 88 | { |
| 88 | "spin_lock: test4 direct ld/st", | 89 | "spin_lock: test4 direct ld/st", |
| @@ -112,6 +113,7 @@ | |||
| 112 | .result_unpriv = REJECT, | 113 | .result_unpriv = REJECT, |
| 113 | .errstr_unpriv = "", | 114 | .errstr_unpriv = "", |
| 114 | .prog_type = BPF_PROG_TYPE_CGROUP_SKB, | 115 | .prog_type = BPF_PROG_TYPE_CGROUP_SKB, |
| 116 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 115 | }, | 117 | }, |
| 116 | { | 118 | { |
| 117 | "spin_lock: test5 call within a locked region", | 119 | "spin_lock: test5 call within a locked region", |
diff --git a/tools/testing/selftests/bpf/verifier/value_ptr_arith.c b/tools/testing/selftests/bpf/verifier/value_ptr_arith.c index 9ab5ace83e02..4b721a77bebb 100644 --- a/tools/testing/selftests/bpf/verifier/value_ptr_arith.c +++ b/tools/testing/selftests/bpf/verifier/value_ptr_arith.c | |||
| @@ -512,6 +512,7 @@ | |||
| 512 | .fixup_map_array_48b = { 3 }, | 512 | .fixup_map_array_48b = { 3 }, |
| 513 | .result = ACCEPT, | 513 | .result = ACCEPT, |
| 514 | .retval = 0xabcdef12, | 514 | .retval = 0xabcdef12, |
| 515 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 515 | }, | 516 | }, |
| 516 | { | 517 | { |
| 517 | "map access: unknown scalar += value_ptr, 3", | 518 | "map access: unknown scalar += value_ptr, 3", |
| @@ -537,6 +538,7 @@ | |||
| 537 | .result_unpriv = REJECT, | 538 | .result_unpriv = REJECT, |
| 538 | .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", | 539 | .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", |
| 539 | .retval = 0xabcdef12, | 540 | .retval = 0xabcdef12, |
| 541 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 540 | }, | 542 | }, |
| 541 | { | 543 | { |
| 542 | "map access: unknown scalar += value_ptr, 4", | 544 | "map access: unknown scalar += value_ptr, 4", |
| @@ -559,6 +561,7 @@ | |||
| 559 | .result = REJECT, | 561 | .result = REJECT, |
| 560 | .errstr = "R1 max value is outside of the array range", | 562 | .errstr = "R1 max value is outside of the array range", |
| 561 | .errstr_unpriv = "R1 pointer arithmetic of map value goes out of range", | 563 | .errstr_unpriv = "R1 pointer arithmetic of map value goes out of range", |
| 564 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 562 | }, | 565 | }, |
| 563 | { | 566 | { |
| 564 | "map access: value_ptr += unknown scalar, 1", | 567 | "map access: value_ptr += unknown scalar, 1", |
| @@ -598,6 +601,7 @@ | |||
| 598 | .fixup_map_array_48b = { 3 }, | 601 | .fixup_map_array_48b = { 3 }, |
| 599 | .result = ACCEPT, | 602 | .result = ACCEPT, |
| 600 | .retval = 0xabcdef12, | 603 | .retval = 0xabcdef12, |
| 604 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
| 601 | }, | 605 | }, |
| 602 | { | 606 | { |
| 603 | "map access: value_ptr += unknown scalar, 3", | 607 | "map access: value_ptr += unknown scalar, 3", |
