271 lines · c
1#define BTF_TYPES \2 .btf_strings = "\0int\0i\0ctx\0callback\0main\0", \3 .btf_types = { \4 /* 1: int */ BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), \5 /* 2: int* */ BTF_PTR_ENC(1), \6 /* 3: void* */ BTF_PTR_ENC(0), \7 /* 4: int __(void*) */ BTF_FUNC_PROTO_ENC(1, 1), \8 BTF_FUNC_PROTO_ARG_ENC(7, 3), \9 /* 5: int __(int, int*) */ BTF_FUNC_PROTO_ENC(1, 2), \10 BTF_FUNC_PROTO_ARG_ENC(5, 1), \11 BTF_FUNC_PROTO_ARG_ENC(7, 2), \12 /* 6: main */ BTF_FUNC_ENC(20, 4), \13 /* 7: callback */ BTF_FUNC_ENC(11, 5), \14 BTF_END_RAW \15 }16 17#define MAIN_TYPE 618#define CALLBACK_TYPE 719 20/* can't use BPF_CALL_REL, jit_subprogs adjusts IMM & OFF21 * fields for pseudo calls22 */23#define PSEUDO_CALL_INSN() \24 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_CALL, \25 INSN_OFF_MASK, INSN_IMM_MASK)26 27/* can't use BPF_FUNC_loop constant,28 * do_mix_fixups adjusts the IMM field29 */30#define HELPER_CALL_INSN() \31 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, INSN_OFF_MASK, INSN_IMM_MASK)32 33{34 "inline simple bpf_loop call",35 .insns = {36 /* main */37 /* force verifier state branching to verify logic on first and38 * subsequent bpf_loop insn processing steps39 */40 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),41 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 777, 2),42 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),43 BPF_JMP_IMM(BPF_JA, 0, 0, 1),44 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 2),45 46 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 6),47 BPF_RAW_INSN(0, 0, 0, 0, 0),48 BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),49 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),50 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),51 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),52 BPF_EXIT_INSN(),53 /* callback */54 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),55 BPF_EXIT_INSN(),56 },57 .expected_insns = { PSEUDO_CALL_INSN() },58 .unexpected_insns = { HELPER_CALL_INSN() },59 .prog_type = BPF_PROG_TYPE_TRACEPOINT,60 .flags = F_NEEDS_JIT_ENABLED,61 .result = ACCEPT,62 .runs = 0,63 .func_info = { { 0, MAIN_TYPE }, { 12, CALLBACK_TYPE } },64 .func_info_cnt = 2,65 BTF_TYPES66},67{68 "don't inline bpf_loop call, flags non-zero",69 .insns = {70 /* main */71 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),72 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_0),73 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),74 BPF_ALU64_REG(BPF_MOV, BPF_REG_7, BPF_REG_0),75 BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 9),76 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),77 BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 0),78 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),79 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 7),80 BPF_RAW_INSN(0, 0, 0, 0, 0),81 BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),82 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),83 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),84 BPF_EXIT_INSN(),85 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 1),86 BPF_JMP_IMM(BPF_JA, 0, 0, -10),87 /* callback */88 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),89 BPF_EXIT_INSN(),90 },91 .expected_insns = { HELPER_CALL_INSN() },92 .unexpected_insns = { PSEUDO_CALL_INSN() },93 .prog_type = BPF_PROG_TYPE_TRACEPOINT,94 .flags = F_NEEDS_JIT_ENABLED,95 .result = ACCEPT,96 .runs = 0,97 .func_info = { { 0, MAIN_TYPE }, { 16, CALLBACK_TYPE } },98 .func_info_cnt = 2,99 BTF_TYPES100},101{102 "don't inline bpf_loop call, callback non-constant",103 .insns = {104 /* main */105 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),106 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 777, 4), /* pick a random callback */107 108 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),109 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 10),110 BPF_RAW_INSN(0, 0, 0, 0, 0),111 BPF_JMP_IMM(BPF_JA, 0, 0, 3),112 113 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),114 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 8),115 BPF_RAW_INSN(0, 0, 0, 0, 0),116 117 BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),118 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),119 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),120 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),121 BPF_EXIT_INSN(),122 /* callback */123 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),124 BPF_EXIT_INSN(),125 /* callback #2 */126 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),127 BPF_EXIT_INSN(),128 },129 .expected_insns = { HELPER_CALL_INSN() },130 .unexpected_insns = { PSEUDO_CALL_INSN() },131 .prog_type = BPF_PROG_TYPE_TRACEPOINT,132 .flags = F_NEEDS_JIT_ENABLED,133 .result = ACCEPT,134 .runs = 0,135 .func_info = {136 { 0, MAIN_TYPE },137 { 14, CALLBACK_TYPE },138 { 16, CALLBACK_TYPE }139 },140 .func_info_cnt = 3,141 BTF_TYPES142},143{144 "bpf_loop_inline and a dead func",145 .insns = {146 /* main */147 148 /* A reference to callback #1 to make verifier count it as a func.149 * This reference is overwritten below and callback #1 is dead.150 */151 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 9),152 BPF_RAW_INSN(0, 0, 0, 0, 0),153 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),154 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 8),155 BPF_RAW_INSN(0, 0, 0, 0, 0),156 BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),157 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),158 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),159 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),160 BPF_EXIT_INSN(),161 /* callback */162 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),163 BPF_EXIT_INSN(),164 /* callback #2 */165 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),166 BPF_EXIT_INSN(),167 },168 .expected_insns = { PSEUDO_CALL_INSN() },169 .unexpected_insns = { HELPER_CALL_INSN() },170 .prog_type = BPF_PROG_TYPE_TRACEPOINT,171 .flags = F_NEEDS_JIT_ENABLED,172 .result = ACCEPT,173 .runs = 0,174 .func_info = {175 { 0, MAIN_TYPE },176 { 10, CALLBACK_TYPE },177 { 12, CALLBACK_TYPE }178 },179 .func_info_cnt = 3,180 BTF_TYPES181},182{183 "bpf_loop_inline stack locations for loop vars",184 .insns = {185 /* main */186 BPF_ST_MEM(BPF_W, BPF_REG_10, -12, 0x77),187 /* bpf_loop call #1 */188 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),189 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 22),190 BPF_RAW_INSN(0, 0, 0, 0, 0),191 BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),192 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),193 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),194 /* bpf_loop call #2 */195 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 2),196 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 16),197 BPF_RAW_INSN(0, 0, 0, 0, 0),198 BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),199 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),200 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),201 /* call func and exit */202 BPF_CALL_REL(2),203 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),204 BPF_EXIT_INSN(),205 /* func */206 BPF_ST_MEM(BPF_DW, BPF_REG_10, -32, 0x55),207 BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 2),208 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 6),209 BPF_RAW_INSN(0, 0, 0, 0, 0),210 BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),211 BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),212 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),213 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),214 BPF_EXIT_INSN(),215 /* callback */216 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),217 BPF_EXIT_INSN(),218 },219 .expected_insns = {220 BPF_ST_MEM(BPF_W, BPF_REG_10, -12, 0x77),221 SKIP_INSNS(),222 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -40),223 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_7, -32),224 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_8, -24),225 SKIP_INSNS(),226 /* offsets are the same as in the first call */227 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -40),228 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_7, -32),229 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_8, -24),230 SKIP_INSNS(),231 BPF_ST_MEM(BPF_DW, BPF_REG_10, -32, 0x55),232 SKIP_INSNS(),233 /* offsets differ from main because of different offset234 * in BPF_ST_MEM instruction235 */236 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -56),237 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_7, -48),238 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_8, -40),239 },240 .unexpected_insns = { HELPER_CALL_INSN() },241 .prog_type = BPF_PROG_TYPE_TRACEPOINT,242 .flags = F_NEEDS_JIT_ENABLED,243 .result = ACCEPT,244 .func_info = {245 { 0, MAIN_TYPE },246 { 16, MAIN_TYPE },247 { 25, CALLBACK_TYPE },248 },249 .func_info_cnt = 3,250 BTF_TYPES251},252{253 "inline bpf_loop call in a big program",254 .insns = {},255 .fill_helper = bpf_fill_big_prog_with_loop_1,256 .expected_insns = { PSEUDO_CALL_INSN() },257 .unexpected_insns = { HELPER_CALL_INSN() },258 .result = ACCEPT,259 .prog_type = BPF_PROG_TYPE_TRACEPOINT,260 .flags = F_NEEDS_JIT_ENABLED,261 .func_info = { { 0, MAIN_TYPE }, { 16, CALLBACK_TYPE } },262 .func_info_cnt = 2,263 BTF_TYPES264},265 266#undef HELPER_CALL_INSN267#undef PSEUDO_CALL_INSN268#undef CALLBACK_TYPE269#undef MAIN_TYPE270#undef BTF_TYPES271