Linux Audio

Check our new training course

Loading...
v6.13.7
  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	6
 18#define CALLBACK_TYPE	7
 19
 20/* can't use BPF_CALL_REL, jit_subprogs adjusts IMM & OFF
 21 * fields for pseudo calls
 22 */
 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 field
 29 */
 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 and
 38	 * subsequent bpf_loop insn processing steps
 39	 */
 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_TYPES
 66},
 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_TYPES
100},
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_TYPES
142},
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_TYPES
181},
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 offset
234	 * in BPF_ST_MEM instruction
235	 */
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_TYPES
251},
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_TYPES
264},
265
266#undef HELPER_CALL_INSN
267#undef PSEUDO_CALL_INSN
268#undef CALLBACK_TYPE
269#undef MAIN_TYPE
270#undef BTF_TYPES
v6.2
  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	6
 18#define CALLBACK_TYPE	7
 19
 20/* can't use BPF_CALL_REL, jit_subprogs adjusts IMM & OFF
 21 * fields for pseudo calls
 22 */
 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 field
 29 */
 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 and
 38	 * subsequent bpf_loop insn processing steps
 39	 */
 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	.result = ACCEPT,
 61	.runs = 0,
 62	.func_info = { { 0, MAIN_TYPE }, { 12, CALLBACK_TYPE } },
 63	.func_info_cnt = 2,
 64	BTF_TYPES
 65},
 66{
 67	"don't inline bpf_loop call, flags non-zero",
 68	.insns = {
 69	/* main */
 70	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),
 71	BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_0),
 72	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),
 73	BPF_ALU64_REG(BPF_MOV, BPF_REG_7, BPF_REG_0),
 74	BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 9),
 75	BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
 76	BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 0),
 77	BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
 78	BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 7),
 79	BPF_RAW_INSN(0, 0, 0, 0, 0),
 80	BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
 81	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
 82	BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
 83	BPF_EXIT_INSN(),
 84	BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 1),
 85	BPF_JMP_IMM(BPF_JA, 0, 0, -10),
 86	/* callback */
 87	BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
 88	BPF_EXIT_INSN(),
 89	},
 90	.expected_insns = { HELPER_CALL_INSN() },
 91	.unexpected_insns = { PSEUDO_CALL_INSN() },
 92	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
 
 93	.result = ACCEPT,
 94	.runs = 0,
 95	.func_info = { { 0, MAIN_TYPE }, { 16, CALLBACK_TYPE } },
 96	.func_info_cnt = 2,
 97	BTF_TYPES
 98},
 99{
100	"don't inline bpf_loop call, callback non-constant",
101	.insns = {
102	/* main */
103	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),
104	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 777, 4), /* pick a random callback */
105
106	BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
107	BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 10),
108	BPF_RAW_INSN(0, 0, 0, 0, 0),
109	BPF_JMP_IMM(BPF_JA, 0, 0, 3),
110
111	BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
112	BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 8),
113	BPF_RAW_INSN(0, 0, 0, 0, 0),
114
115	BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
116	BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
117	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
118	BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
119	BPF_EXIT_INSN(),
120	/* callback */
121	BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
122	BPF_EXIT_INSN(),
123	/* callback #2 */
124	BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
125	BPF_EXIT_INSN(),
126	},
127	.expected_insns = { HELPER_CALL_INSN() },
128	.unexpected_insns = { PSEUDO_CALL_INSN() },
129	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
 
130	.result = ACCEPT,
131	.runs = 0,
132	.func_info = {
133		{ 0, MAIN_TYPE },
134		{ 14, CALLBACK_TYPE },
135		{ 16, CALLBACK_TYPE }
136	},
137	.func_info_cnt = 3,
138	BTF_TYPES
139},
140{
141	"bpf_loop_inline and a dead func",
142	.insns = {
143	/* main */
144
145	/* A reference to callback #1 to make verifier count it as a func.
146	 * This reference is overwritten below and callback #1 is dead.
147	 */
148	BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 9),
149	BPF_RAW_INSN(0, 0, 0, 0, 0),
150	BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
151	BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 8),
152	BPF_RAW_INSN(0, 0, 0, 0, 0),
153	BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
154	BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
155	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
156	BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
157	BPF_EXIT_INSN(),
158	/* callback */
159	BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
160	BPF_EXIT_INSN(),
161	/* callback #2 */
162	BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
163	BPF_EXIT_INSN(),
164	},
165	.expected_insns = { PSEUDO_CALL_INSN() },
166	.unexpected_insns = { HELPER_CALL_INSN() },
167	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
 
168	.result = ACCEPT,
169	.runs = 0,
170	.func_info = {
171		{ 0, MAIN_TYPE },
172		{ 10, CALLBACK_TYPE },
173		{ 12, CALLBACK_TYPE }
174	},
175	.func_info_cnt = 3,
176	BTF_TYPES
177},
178{
179	"bpf_loop_inline stack locations for loop vars",
180	.insns = {
181	/* main */
182	BPF_ST_MEM(BPF_W, BPF_REG_10, -12, 0x77),
183	/* bpf_loop call #1 */
184	BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
185	BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 22),
186	BPF_RAW_INSN(0, 0, 0, 0, 0),
187	BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
188	BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
189	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
190	/* bpf_loop call #2 */
191	BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 2),
192	BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 16),
193	BPF_RAW_INSN(0, 0, 0, 0, 0),
194	BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
195	BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
196	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
197	/* call func and exit */
198	BPF_CALL_REL(2),
199	BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
200	BPF_EXIT_INSN(),
201	/* func */
202	BPF_ST_MEM(BPF_DW, BPF_REG_10, -32, 0x55),
203	BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 2),
204	BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 6),
205	BPF_RAW_INSN(0, 0, 0, 0, 0),
206	BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
207	BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
208	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
209	BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
210	BPF_EXIT_INSN(),
211	/* callback */
212	BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
213	BPF_EXIT_INSN(),
214	},
215	.expected_insns = {
216	BPF_ST_MEM(BPF_W, BPF_REG_10, -12, 0x77),
217	SKIP_INSNS(),
218	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -40),
219	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_7, -32),
220	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_8, -24),
221	SKIP_INSNS(),
222	/* offsets are the same as in the first call */
223	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -40),
224	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_7, -32),
225	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_8, -24),
226	SKIP_INSNS(),
227	BPF_ST_MEM(BPF_DW, BPF_REG_10, -32, 0x55),
228	SKIP_INSNS(),
229	/* offsets differ from main because of different offset
230	 * in BPF_ST_MEM instruction
231	 */
232	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -56),
233	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_7, -48),
234	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_8, -40),
235	},
236	.unexpected_insns = { HELPER_CALL_INSN() },
237	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
 
238	.result = ACCEPT,
239	.func_info = {
240		{ 0, MAIN_TYPE },
241		{ 16, MAIN_TYPE },
242		{ 25, CALLBACK_TYPE },
243	},
244	.func_info_cnt = 3,
245	BTF_TYPES
246},
247{
248	"inline bpf_loop call in a big program",
249	.insns = {},
250	.fill_helper = bpf_fill_big_prog_with_loop_1,
251	.expected_insns = { PSEUDO_CALL_INSN() },
252	.unexpected_insns = { HELPER_CALL_INSN() },
253	.result = ACCEPT,
254	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
 
255	.func_info = { { 0, MAIN_TYPE }, { 16, CALLBACK_TYPE } },
256	.func_info_cnt = 2,
257	BTF_TYPES
258},
259
260#undef HELPER_CALL_INSN
261#undef PSEUDO_CALL_INSN
262#undef CALLBACK_TYPE
263#undef MAIN_TYPE
264#undef BTF_TYPES