0001 #define BTF_TYPES \
0002 .btf_strings = "\0int\0i\0ctx\0callback\0main\0", \
0003 .btf_types = { \
0004 BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), \
0005 BTF_PTR_ENC(1), \
0006 BTF_PTR_ENC(0), \
0007 BTF_FUNC_PROTO_ENC(1, 1), \
0008 BTF_FUNC_PROTO_ARG_ENC(7, 3), \
0009 BTF_FUNC_PROTO_ENC(1, 2), \
0010 BTF_FUNC_PROTO_ARG_ENC(5, 1), \
0011 BTF_FUNC_PROTO_ARG_ENC(7, 2), \
0012 BTF_FUNC_ENC(20, 4), \
0013 BTF_FUNC_ENC(11, 5), \
0014 BTF_END_RAW \
0015 }
0016
0017 #define MAIN_TYPE 6
0018 #define CALLBACK_TYPE 7
0019
0020
0021
0022
0023 #define PSEUDO_CALL_INSN() \
0024 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_CALL, \
0025 INSN_OFF_MASK, INSN_IMM_MASK)
0026
0027
0028
0029
0030 #define HELPER_CALL_INSN() \
0031 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, INSN_OFF_MASK, INSN_IMM_MASK)
0032
0033 {
0034 "inline simple bpf_loop call",
0035 .insns = {
0036
0037
0038
0039
0040 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),
0041 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 777, 2),
0042 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
0043 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
0044 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 2),
0045
0046 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 6),
0047 BPF_RAW_INSN(0, 0, 0, 0, 0),
0048 BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
0049 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
0050 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
0051 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
0052 BPF_EXIT_INSN(),
0053
0054 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
0055 BPF_EXIT_INSN(),
0056 },
0057 .expected_insns = { PSEUDO_CALL_INSN() },
0058 .unexpected_insns = { HELPER_CALL_INSN() },
0059 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
0060 .result = ACCEPT,
0061 .runs = 0,
0062 .func_info = { { 0, MAIN_TYPE }, { 12, CALLBACK_TYPE } },
0063 .func_info_cnt = 2,
0064 BTF_TYPES
0065 },
0066 {
0067 "don't inline bpf_loop call, flags non-zero",
0068 .insns = {
0069
0070 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),
0071 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_0),
0072 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),
0073 BPF_ALU64_REG(BPF_MOV, BPF_REG_7, BPF_REG_0),
0074 BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 9),
0075 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
0076 BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 0),
0077 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
0078 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 7),
0079 BPF_RAW_INSN(0, 0, 0, 0, 0),
0080 BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
0081 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
0082 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
0083 BPF_EXIT_INSN(),
0084 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 1),
0085 BPF_JMP_IMM(BPF_JA, 0, 0, -10),
0086
0087 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
0088 BPF_EXIT_INSN(),
0089 },
0090 .expected_insns = { HELPER_CALL_INSN() },
0091 .unexpected_insns = { PSEUDO_CALL_INSN() },
0092 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
0093 .result = ACCEPT,
0094 .runs = 0,
0095 .func_info = { { 0, MAIN_TYPE }, { 16, CALLBACK_TYPE } },
0096 .func_info_cnt = 2,
0097 BTF_TYPES
0098 },
0099 {
0100 "don't inline bpf_loop call, callback non-constant",
0101 .insns = {
0102
0103 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),
0104 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 777, 4),
0105
0106 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
0107 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 10),
0108 BPF_RAW_INSN(0, 0, 0, 0, 0),
0109 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
0110
0111 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
0112 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 8),
0113 BPF_RAW_INSN(0, 0, 0, 0, 0),
0114
0115 BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
0116 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
0117 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
0118 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
0119 BPF_EXIT_INSN(),
0120
0121 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
0122 BPF_EXIT_INSN(),
0123
0124 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
0125 BPF_EXIT_INSN(),
0126 },
0127 .expected_insns = { HELPER_CALL_INSN() },
0128 .unexpected_insns = { PSEUDO_CALL_INSN() },
0129 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
0130 .result = ACCEPT,
0131 .runs = 0,
0132 .func_info = {
0133 { 0, MAIN_TYPE },
0134 { 14, CALLBACK_TYPE },
0135 { 16, CALLBACK_TYPE }
0136 },
0137 .func_info_cnt = 3,
0138 BTF_TYPES
0139 },
0140 {
0141 "bpf_loop_inline and a dead func",
0142 .insns = {
0143
0144
0145
0146
0147
0148 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 9),
0149 BPF_RAW_INSN(0, 0, 0, 0, 0),
0150 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
0151 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 8),
0152 BPF_RAW_INSN(0, 0, 0, 0, 0),
0153 BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
0154 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
0155 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
0156 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
0157 BPF_EXIT_INSN(),
0158
0159 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
0160 BPF_EXIT_INSN(),
0161
0162 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
0163 BPF_EXIT_INSN(),
0164 },
0165 .expected_insns = { PSEUDO_CALL_INSN() },
0166 .unexpected_insns = { HELPER_CALL_INSN() },
0167 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
0168 .result = ACCEPT,
0169 .runs = 0,
0170 .func_info = {
0171 { 0, MAIN_TYPE },
0172 { 10, CALLBACK_TYPE },
0173 { 12, CALLBACK_TYPE }
0174 },
0175 .func_info_cnt = 3,
0176 BTF_TYPES
0177 },
0178 {
0179 "bpf_loop_inline stack locations for loop vars",
0180 .insns = {
0181
0182 BPF_ST_MEM(BPF_W, BPF_REG_10, -12, 0x77),
0183
0184 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
0185 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 22),
0186 BPF_RAW_INSN(0, 0, 0, 0, 0),
0187 BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
0188 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
0189 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
0190
0191 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 2),
0192 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 16),
0193 BPF_RAW_INSN(0, 0, 0, 0, 0),
0194 BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
0195 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
0196 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
0197
0198 BPF_CALL_REL(2),
0199 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
0200 BPF_EXIT_INSN(),
0201
0202 BPF_ST_MEM(BPF_DW, BPF_REG_10, -32, 0x55),
0203 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 2),
0204 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 6),
0205 BPF_RAW_INSN(0, 0, 0, 0, 0),
0206 BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
0207 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
0208 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
0209 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
0210 BPF_EXIT_INSN(),
0211
0212 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
0213 BPF_EXIT_INSN(),
0214 },
0215 .expected_insns = {
0216 BPF_ST_MEM(BPF_W, BPF_REG_10, -12, 0x77),
0217 SKIP_INSNS(),
0218 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -40),
0219 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_7, -32),
0220 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_8, -24),
0221 SKIP_INSNS(),
0222
0223 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -40),
0224 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_7, -32),
0225 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_8, -24),
0226 SKIP_INSNS(),
0227 BPF_ST_MEM(BPF_DW, BPF_REG_10, -32, 0x55),
0228 SKIP_INSNS(),
0229
0230
0231
0232 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -56),
0233 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_7, -48),
0234 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_8, -40),
0235 },
0236 .unexpected_insns = { HELPER_CALL_INSN() },
0237 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
0238 .result = ACCEPT,
0239 .func_info = {
0240 { 0, MAIN_TYPE },
0241 { 16, MAIN_TYPE },
0242 { 25, CALLBACK_TYPE },
0243 },
0244 .func_info_cnt = 3,
0245 BTF_TYPES
0246 },
0247 {
0248 "inline bpf_loop call in a big program",
0249 .insns = {},
0250 .fill_helper = bpf_fill_big_prog_with_loop_1,
0251 .expected_insns = { PSEUDO_CALL_INSN() },
0252 .unexpected_insns = { HELPER_CALL_INSN() },
0253 .result = ACCEPT,
0254 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
0255 .func_info = { { 0, MAIN_TYPE }, { 16, CALLBACK_TYPE } },
0256 .func_info_cnt = 2,
0257 BTF_TYPES
0258 },
0259
0260 #undef HELPER_CALL_INSN
0261 #undef PSEUDO_CALL_INSN
0262 #undef CALLBACK_TYPE
0263 #undef MAIN_TYPE
0264 #undef BTF_TYPES