Back to home page

OSCL-LXR

 
 

    


0001 #define BTF_TYPES \
0002     .btf_strings = "\0int\0i\0ctx\0callback\0main\0", \
0003     .btf_types = { \
0004     /* 1: int   */ BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), \
0005     /* 2: int*  */ BTF_PTR_ENC(1), \
0006     /* 3: void* */ BTF_PTR_ENC(0), \
0007     /* 4: int __(void*) */ BTF_FUNC_PROTO_ENC(1, 1), \
0008         BTF_FUNC_PROTO_ARG_ENC(7, 3), \
0009     /* 5: int __(int, int*) */ BTF_FUNC_PROTO_ENC(1, 2), \
0010         BTF_FUNC_PROTO_ARG_ENC(5, 1), \
0011         BTF_FUNC_PROTO_ARG_ENC(7, 2), \
0012     /* 6: main      */ BTF_FUNC_ENC(20, 4), \
0013     /* 7: callback  */ BTF_FUNC_ENC(11, 5), \
0014     BTF_END_RAW \
0015     }
0016 
0017 #define MAIN_TYPE   6
0018 #define CALLBACK_TYPE   7
0019 
0020 /* can't use BPF_CALL_REL, jit_subprogs adjusts IMM & OFF
0021  * fields for pseudo calls
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 /* can't use BPF_FUNC_loop constant,
0028  * do_mix_fixups adjusts the IMM field
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     /* main */
0037     /* force verifier state branching to verify logic on first and
0038      * subsequent bpf_loop insn processing steps
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     /* callback */
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     /* main */
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     /* callback */
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     /* main */
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), /* pick a random callback */
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     /* callback */
0121     BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
0122     BPF_EXIT_INSN(),
0123     /* callback #2 */
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     /* main */
0144 
0145     /* A reference to callback #1 to make verifier count it as a func.
0146      * This reference is overwritten below and callback #1 is dead.
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     /* callback */
0159     BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
0160     BPF_EXIT_INSN(),
0161     /* callback #2 */
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     /* main */
0182     BPF_ST_MEM(BPF_W, BPF_REG_10, -12, 0x77),
0183     /* bpf_loop call #1 */
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     /* bpf_loop call #2 */
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     /* call func and exit */
0198     BPF_CALL_REL(2),
0199     BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
0200     BPF_EXIT_INSN(),
0201     /* func */
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     /* callback */
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     /* offsets are the same as in the first call */
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     /* offsets differ from main because of different offset
0230      * in BPF_ST_MEM instruction
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