Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.10.11.
  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