18c2ecf20Sopenharmony_ci{
28c2ecf20Sopenharmony_ci	"runtime/jit: tail_call within bounds, prog once",
38c2ecf20Sopenharmony_ci	.insns = {
48c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 0),
58c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
68c2ecf20Sopenharmony_ci	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
78c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 1),
88c2ecf20Sopenharmony_ci	BPF_EXIT_INSN(),
98c2ecf20Sopenharmony_ci	},
108c2ecf20Sopenharmony_ci	.fixup_prog1 = { 1 },
118c2ecf20Sopenharmony_ci	.result = ACCEPT,
128c2ecf20Sopenharmony_ci	.retval = 42,
138c2ecf20Sopenharmony_ci},
148c2ecf20Sopenharmony_ci{
158c2ecf20Sopenharmony_ci	"runtime/jit: tail_call within bounds, prog loop",
168c2ecf20Sopenharmony_ci	.insns = {
178c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 1),
188c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
198c2ecf20Sopenharmony_ci	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
208c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 1),
218c2ecf20Sopenharmony_ci	BPF_EXIT_INSN(),
228c2ecf20Sopenharmony_ci	},
238c2ecf20Sopenharmony_ci	.fixup_prog1 = { 1 },
248c2ecf20Sopenharmony_ci	.result = ACCEPT,
258c2ecf20Sopenharmony_ci	.retval = 41,
268c2ecf20Sopenharmony_ci},
278c2ecf20Sopenharmony_ci{
288c2ecf20Sopenharmony_ci	"runtime/jit: tail_call within bounds, no prog",
298c2ecf20Sopenharmony_ci	.insns = {
308c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 3),
318c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
328c2ecf20Sopenharmony_ci	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
338c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 1),
348c2ecf20Sopenharmony_ci	BPF_EXIT_INSN(),
358c2ecf20Sopenharmony_ci	},
368c2ecf20Sopenharmony_ci	.fixup_prog1 = { 1 },
378c2ecf20Sopenharmony_ci	.result = ACCEPT,
388c2ecf20Sopenharmony_ci	.retval = 1,
398c2ecf20Sopenharmony_ci},
408c2ecf20Sopenharmony_ci{
418c2ecf20Sopenharmony_ci	"runtime/jit: tail_call within bounds, key 2",
428c2ecf20Sopenharmony_ci	.insns = {
438c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 2),
448c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
458c2ecf20Sopenharmony_ci	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
468c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 1),
478c2ecf20Sopenharmony_ci	BPF_EXIT_INSN(),
488c2ecf20Sopenharmony_ci	},
498c2ecf20Sopenharmony_ci	.fixup_prog1 = { 1 },
508c2ecf20Sopenharmony_ci	.result = ACCEPT,
518c2ecf20Sopenharmony_ci	.retval = 24,
528c2ecf20Sopenharmony_ci},
538c2ecf20Sopenharmony_ci{
548c2ecf20Sopenharmony_ci	"runtime/jit: tail_call within bounds, key 2 / key 2, first branch",
558c2ecf20Sopenharmony_ci	.insns = {
568c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 13),
578c2ecf20Sopenharmony_ci	BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
588c2ecf20Sopenharmony_ci		    offsetof(struct __sk_buff, cb[0])),
598c2ecf20Sopenharmony_ci	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
608c2ecf20Sopenharmony_ci		    offsetof(struct __sk_buff, cb[0])),
618c2ecf20Sopenharmony_ci	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4),
628c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 2),
638c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
648c2ecf20Sopenharmony_ci	BPF_JMP_IMM(BPF_JA, 0, 0, 3),
658c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 2),
668c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
678c2ecf20Sopenharmony_ci	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
688c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 1),
698c2ecf20Sopenharmony_ci	BPF_EXIT_INSN(),
708c2ecf20Sopenharmony_ci	},
718c2ecf20Sopenharmony_ci	.fixup_prog1 = { 5, 9 },
728c2ecf20Sopenharmony_ci	.result = ACCEPT,
738c2ecf20Sopenharmony_ci	.retval = 24,
748c2ecf20Sopenharmony_ci},
758c2ecf20Sopenharmony_ci{
768c2ecf20Sopenharmony_ci	"runtime/jit: tail_call within bounds, key 2 / key 2, second branch",
778c2ecf20Sopenharmony_ci	.insns = {
788c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 14),
798c2ecf20Sopenharmony_ci	BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
808c2ecf20Sopenharmony_ci		    offsetof(struct __sk_buff, cb[0])),
818c2ecf20Sopenharmony_ci	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
828c2ecf20Sopenharmony_ci		    offsetof(struct __sk_buff, cb[0])),
838c2ecf20Sopenharmony_ci	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4),
848c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 2),
858c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
868c2ecf20Sopenharmony_ci	BPF_JMP_IMM(BPF_JA, 0, 0, 3),
878c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 2),
888c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
898c2ecf20Sopenharmony_ci	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
908c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 1),
918c2ecf20Sopenharmony_ci	BPF_EXIT_INSN(),
928c2ecf20Sopenharmony_ci	},
938c2ecf20Sopenharmony_ci	.fixup_prog1 = { 5, 9 },
948c2ecf20Sopenharmony_ci	.result = ACCEPT,
958c2ecf20Sopenharmony_ci	.retval = 24,
968c2ecf20Sopenharmony_ci},
978c2ecf20Sopenharmony_ci{
988c2ecf20Sopenharmony_ci	"runtime/jit: tail_call within bounds, key 0 / key 2, first branch",
998c2ecf20Sopenharmony_ci	.insns = {
1008c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 13),
1018c2ecf20Sopenharmony_ci	BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1028c2ecf20Sopenharmony_ci		    offsetof(struct __sk_buff, cb[0])),
1038c2ecf20Sopenharmony_ci	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1048c2ecf20Sopenharmony_ci		    offsetof(struct __sk_buff, cb[0])),
1058c2ecf20Sopenharmony_ci	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4),
1068c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 0),
1078c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
1088c2ecf20Sopenharmony_ci	BPF_JMP_IMM(BPF_JA, 0, 0, 3),
1098c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 2),
1108c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
1118c2ecf20Sopenharmony_ci	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
1128c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 1),
1138c2ecf20Sopenharmony_ci	BPF_EXIT_INSN(),
1148c2ecf20Sopenharmony_ci	},
1158c2ecf20Sopenharmony_ci	.fixup_prog1 = { 5, 9 },
1168c2ecf20Sopenharmony_ci	.result = ACCEPT,
1178c2ecf20Sopenharmony_ci	.retval = 24,
1188c2ecf20Sopenharmony_ci},
1198c2ecf20Sopenharmony_ci{
1208c2ecf20Sopenharmony_ci	"runtime/jit: tail_call within bounds, key 0 / key 2, second branch",
1218c2ecf20Sopenharmony_ci	.insns = {
1228c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 14),
1238c2ecf20Sopenharmony_ci	BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1248c2ecf20Sopenharmony_ci		    offsetof(struct __sk_buff, cb[0])),
1258c2ecf20Sopenharmony_ci	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1268c2ecf20Sopenharmony_ci		    offsetof(struct __sk_buff, cb[0])),
1278c2ecf20Sopenharmony_ci	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4),
1288c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 0),
1298c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
1308c2ecf20Sopenharmony_ci	BPF_JMP_IMM(BPF_JA, 0, 0, 3),
1318c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 2),
1328c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
1338c2ecf20Sopenharmony_ci	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
1348c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 1),
1358c2ecf20Sopenharmony_ci	BPF_EXIT_INSN(),
1368c2ecf20Sopenharmony_ci	},
1378c2ecf20Sopenharmony_ci	.fixup_prog1 = { 5, 9 },
1388c2ecf20Sopenharmony_ci	.result = ACCEPT,
1398c2ecf20Sopenharmony_ci	.retval = 42,
1408c2ecf20Sopenharmony_ci},
1418c2ecf20Sopenharmony_ci{
1428c2ecf20Sopenharmony_ci	"runtime/jit: tail_call within bounds, different maps, first branch",
1438c2ecf20Sopenharmony_ci	.insns = {
1448c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 13),
1458c2ecf20Sopenharmony_ci	BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1468c2ecf20Sopenharmony_ci		    offsetof(struct __sk_buff, cb[0])),
1478c2ecf20Sopenharmony_ci	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1488c2ecf20Sopenharmony_ci		    offsetof(struct __sk_buff, cb[0])),
1498c2ecf20Sopenharmony_ci	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4),
1508c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 0),
1518c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
1528c2ecf20Sopenharmony_ci	BPF_JMP_IMM(BPF_JA, 0, 0, 3),
1538c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 0),
1548c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
1558c2ecf20Sopenharmony_ci	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
1568c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 1),
1578c2ecf20Sopenharmony_ci	BPF_EXIT_INSN(),
1588c2ecf20Sopenharmony_ci	},
1598c2ecf20Sopenharmony_ci	.fixup_prog1 = { 5 },
1608c2ecf20Sopenharmony_ci	.fixup_prog2 = { 9 },
1618c2ecf20Sopenharmony_ci	.result_unpriv = REJECT,
1628c2ecf20Sopenharmony_ci	.errstr_unpriv = "tail_call abusing map_ptr",
1638c2ecf20Sopenharmony_ci	.result = ACCEPT,
1648c2ecf20Sopenharmony_ci	.retval = 1,
1658c2ecf20Sopenharmony_ci},
1668c2ecf20Sopenharmony_ci{
1678c2ecf20Sopenharmony_ci	"runtime/jit: tail_call within bounds, different maps, second branch",
1688c2ecf20Sopenharmony_ci	.insns = {
1698c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 14),
1708c2ecf20Sopenharmony_ci	BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1718c2ecf20Sopenharmony_ci		    offsetof(struct __sk_buff, cb[0])),
1728c2ecf20Sopenharmony_ci	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
1738c2ecf20Sopenharmony_ci		    offsetof(struct __sk_buff, cb[0])),
1748c2ecf20Sopenharmony_ci	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4),
1758c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 0),
1768c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
1778c2ecf20Sopenharmony_ci	BPF_JMP_IMM(BPF_JA, 0, 0, 3),
1788c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 0),
1798c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
1808c2ecf20Sopenharmony_ci	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
1818c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 1),
1828c2ecf20Sopenharmony_ci	BPF_EXIT_INSN(),
1838c2ecf20Sopenharmony_ci	},
1848c2ecf20Sopenharmony_ci	.fixup_prog1 = { 5 },
1858c2ecf20Sopenharmony_ci	.fixup_prog2 = { 9 },
1868c2ecf20Sopenharmony_ci	.result_unpriv = REJECT,
1878c2ecf20Sopenharmony_ci	.errstr_unpriv = "tail_call abusing map_ptr",
1888c2ecf20Sopenharmony_ci	.result = ACCEPT,
1898c2ecf20Sopenharmony_ci	.retval = 42,
1908c2ecf20Sopenharmony_ci},
1918c2ecf20Sopenharmony_ci{
1928c2ecf20Sopenharmony_ci	"runtime/jit: tail_call out of bounds",
1938c2ecf20Sopenharmony_ci	.insns = {
1948c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, 256),
1958c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
1968c2ecf20Sopenharmony_ci	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
1978c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 2),
1988c2ecf20Sopenharmony_ci	BPF_EXIT_INSN(),
1998c2ecf20Sopenharmony_ci	},
2008c2ecf20Sopenharmony_ci	.fixup_prog1 = { 1 },
2018c2ecf20Sopenharmony_ci	.result = ACCEPT,
2028c2ecf20Sopenharmony_ci	.retval = 2,
2038c2ecf20Sopenharmony_ci},
2048c2ecf20Sopenharmony_ci{
2058c2ecf20Sopenharmony_ci	"runtime/jit: pass negative index to tail_call",
2068c2ecf20Sopenharmony_ci	.insns = {
2078c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_3, -1),
2088c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
2098c2ecf20Sopenharmony_ci	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
2108c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 2),
2118c2ecf20Sopenharmony_ci	BPF_EXIT_INSN(),
2128c2ecf20Sopenharmony_ci	},
2138c2ecf20Sopenharmony_ci	.fixup_prog1 = { 1 },
2148c2ecf20Sopenharmony_ci	.result = ACCEPT,
2158c2ecf20Sopenharmony_ci	.retval = 2,
2168c2ecf20Sopenharmony_ci},
2178c2ecf20Sopenharmony_ci{
2188c2ecf20Sopenharmony_ci	"runtime/jit: pass > 32bit index to tail_call",
2198c2ecf20Sopenharmony_ci	.insns = {
2208c2ecf20Sopenharmony_ci	BPF_LD_IMM64(BPF_REG_3, 0x100000000ULL),
2218c2ecf20Sopenharmony_ci	BPF_LD_MAP_FD(BPF_REG_2, 0),
2228c2ecf20Sopenharmony_ci	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
2238c2ecf20Sopenharmony_ci	BPF_MOV64_IMM(BPF_REG_0, 2),
2248c2ecf20Sopenharmony_ci	BPF_EXIT_INSN(),
2258c2ecf20Sopenharmony_ci	},
2268c2ecf20Sopenharmony_ci	.fixup_prog1 = { 2 },
2278c2ecf20Sopenharmony_ci	.result = ACCEPT,
2288c2ecf20Sopenharmony_ci	.retval = 42,
2298c2ecf20Sopenharmony_ci	/* Verifier rewrite for unpriv skips tail call here. */
2308c2ecf20Sopenharmony_ci	.retval_unpriv = 2,
2318c2ecf20Sopenharmony_ci},
232