1{
2	"regalloc basic",
3	.insns = {
4	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
5	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
6	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
7	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
8	BPF_LD_MAP_FD(BPF_REG_1, 0),
9	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
10	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
11	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
12	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
13	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
14	BPF_JMP_IMM(BPF_JSGT, BPF_REG_0, 20, 4),
15	BPF_JMP_IMM(BPF_JSLT, BPF_REG_2, 0, 3),
16	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
17	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_2),
18	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
19	BPF_EXIT_INSN(),
20	},
21	.fixup_map_hash_48b = { 4 },
22	.result = ACCEPT,
23	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
24},
25{
26	"regalloc negative",
27	.insns = {
28	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
29	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
30	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
31	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
32	BPF_LD_MAP_FD(BPF_REG_1, 0),
33	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
34	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
35	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
36	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
37	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
38	BPF_JMP_IMM(BPF_JSGT, BPF_REG_0, 24, 4),
39	BPF_JMP_IMM(BPF_JSLT, BPF_REG_2, 0, 3),
40	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
41	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_2),
42	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_7, 0),
43	BPF_EXIT_INSN(),
44	},
45	.fixup_map_hash_48b = { 4 },
46	.result = REJECT,
47	.errstr = "invalid access to map value, value_size=48 off=48 size=1",
48	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
49},
50{
51	"regalloc src_reg mark",
52	.insns = {
53	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
54	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
55	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
56	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
57	BPF_LD_MAP_FD(BPF_REG_1, 0),
58	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
59	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
60	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
61	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
62	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
63	BPF_JMP_IMM(BPF_JSGT, BPF_REG_0, 20, 5),
64	BPF_MOV64_IMM(BPF_REG_3, 0),
65	BPF_JMP_REG(BPF_JSGE, BPF_REG_3, BPF_REG_2, 3),
66	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
67	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_2),
68	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
69	BPF_EXIT_INSN(),
70	},
71	.fixup_map_hash_48b = { 4 },
72	.result = ACCEPT,
73	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
74},
75{
76	"regalloc src_reg negative",
77	.insns = {
78	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
79	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
80	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
81	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
82	BPF_LD_MAP_FD(BPF_REG_1, 0),
83	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
84	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
85	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
86	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
87	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
88	BPF_JMP_IMM(BPF_JSGT, BPF_REG_0, 22, 5),
89	BPF_MOV64_IMM(BPF_REG_3, 0),
90	BPF_JMP_REG(BPF_JSGE, BPF_REG_3, BPF_REG_2, 3),
91	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
92	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_2),
93	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
94	BPF_EXIT_INSN(),
95	},
96	.fixup_map_hash_48b = { 4 },
97	.result = REJECT,
98	.errstr = "invalid access to map value, value_size=48 off=44 size=8",
99	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
100},
101{
102	"regalloc and spill",
103	.insns = {
104	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
105	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
106	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
107	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
108	BPF_LD_MAP_FD(BPF_REG_1, 0),
109	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
110	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
111	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
112	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
113	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
114	BPF_JMP_IMM(BPF_JSGT, BPF_REG_0, 20, 7),
115	/* r0 has upper bound that should propagate into r2 */
116	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -8), /* spill r2 */
117	BPF_MOV64_IMM(BPF_REG_0, 0),
118	BPF_MOV64_IMM(BPF_REG_2, 0), /* clear r0 and r2 */
119	BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_10, -8), /* fill r3 */
120	BPF_JMP_REG(BPF_JSGE, BPF_REG_0, BPF_REG_3, 2),
121	/* r3 has lower and upper bounds */
122	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_3),
123	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
124	BPF_EXIT_INSN(),
125	},
126	.fixup_map_hash_48b = { 4 },
127	.result = ACCEPT,
128	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
129},
130{
131	"regalloc and spill negative",
132	.insns = {
133	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
134	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
135	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
136	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
137	BPF_LD_MAP_FD(BPF_REG_1, 0),
138	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
139	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
140	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
141	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
142	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
143	BPF_JMP_IMM(BPF_JSGT, BPF_REG_0, 48, 7),
144	/* r0 has upper bound that should propagate into r2 */
145	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -8), /* spill r2 */
146	BPF_MOV64_IMM(BPF_REG_0, 0),
147	BPF_MOV64_IMM(BPF_REG_2, 0), /* clear r0 and r2 */
148	BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_10, -8), /* fill r3 */
149	BPF_JMP_REG(BPF_JSGE, BPF_REG_0, BPF_REG_3, 2),
150	/* r3 has lower and upper bounds */
151	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_3),
152	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
153	BPF_EXIT_INSN(),
154	},
155	.fixup_map_hash_48b = { 4 },
156	.result = REJECT,
157	.errstr = "invalid access to map value, value_size=48 off=48 size=8",
158	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
159},
160{
161	"regalloc three regs",
162	.insns = {
163	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
164	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
165	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
166	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
167	BPF_LD_MAP_FD(BPF_REG_1, 0),
168	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
169	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
170	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
171	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
172	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
173	BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
174	BPF_JMP_IMM(BPF_JSGT, BPF_REG_0, 12, 5),
175	BPF_JMP_IMM(BPF_JSLT, BPF_REG_2, 0, 4),
176	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
177	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_2),
178	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_4),
179	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
180	BPF_EXIT_INSN(),
181	},
182	.fixup_map_hash_48b = { 4 },
183	.result = ACCEPT,
184	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
185},
186{
187	"regalloc after call",
188	.insns = {
189	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
190	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
191	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
192	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
193	BPF_LD_MAP_FD(BPF_REG_1, 0),
194	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
195	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
196	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
197	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
198	BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
199	BPF_MOV64_REG(BPF_REG_9, BPF_REG_0),
200	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
201	BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 20, 4),
202	BPF_JMP_IMM(BPF_JSLT, BPF_REG_9, 0, 3),
203	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_8),
204	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_9),
205	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
206	BPF_EXIT_INSN(),
207	BPF_MOV64_IMM(BPF_REG_0, 0),
208	BPF_EXIT_INSN(),
209	},
210	.fixup_map_hash_48b = { 4 },
211	.result = ACCEPT,
212	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
213},
214{
215	"regalloc in callee",
216	.insns = {
217	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
218	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
219	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
220	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
221	BPF_LD_MAP_FD(BPF_REG_1, 0),
222	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
223	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
224	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
225	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
226	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
227	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
228	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
229	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
230	BPF_EXIT_INSN(),
231	BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 20, 5),
232	BPF_JMP_IMM(BPF_JSLT, BPF_REG_2, 0, 4),
233	BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_1),
234	BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_2),
235	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
236	BPF_EXIT_INSN(),
237	BPF_MOV64_IMM(BPF_REG_0, 0),
238	BPF_EXIT_INSN(),
239	},
240	.fixup_map_hash_48b = { 4 },
241	.result = ACCEPT,
242	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
243},
244{
245	"regalloc, spill, JEQ",
246	.insns = {
247	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
248	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
249	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
250	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
251	BPF_LD_MAP_FD(BPF_REG_1, 0),
252	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
253	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), /* spill r0 */
254	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 0),
255	/* The verifier will walk the rest twice with r0 == 0 and r0 == map_value */
256	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
257	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
258	BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 20, 0),
259	/* The verifier will walk the rest two more times with r0 == 20 and r0 == unknown */
260	BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_10, -8), /* fill r3 with map_value */
261	BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0, 1), /* skip ldx if map_value == NULL */
262	/* Buggy verifier will think that r3 == 20 here */
263	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), /* read from map_value */
264	BPF_EXIT_INSN(),
265	},
266	.fixup_map_hash_48b = { 4 },
267	.result = ACCEPT,
268	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
269},
270