xref: /linux/tools/testing/selftests/bpf/verifier/atomic_bounds.c (revision d0034a7a4ac7fae708146ac0059b9c47a1543f0d)
1*37086bfdSBrendan Jackman {
2*37086bfdSBrendan Jackman 	"BPF_ATOMIC bounds propagation, mem->reg",
3*37086bfdSBrendan Jackman 	.insns = {
4*37086bfdSBrendan Jackman 		/* a = 0; */
5*37086bfdSBrendan Jackman 		/*
6*37086bfdSBrendan Jackman 		 * Note this is implemented with two separate instructions,
7*37086bfdSBrendan Jackman 		 * where you might think one would suffice:
8*37086bfdSBrendan Jackman 		 *
9*37086bfdSBrendan Jackman 		 * BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
10*37086bfdSBrendan Jackman 		 *
11*37086bfdSBrendan Jackman 		 * This is because BPF_ST_MEM doesn't seem to set the stack slot
12*37086bfdSBrendan Jackman 		 * type to 0 when storing an immediate.
13*37086bfdSBrendan Jackman 		 */
14*37086bfdSBrendan Jackman 		BPF_MOV64_IMM(BPF_REG_0, 0),
15*37086bfdSBrendan Jackman 		BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
16*37086bfdSBrendan Jackman 		/* b = atomic_fetch_add(&a, 1); */
17*37086bfdSBrendan Jackman 		BPF_MOV64_IMM(BPF_REG_1, 1),
18*37086bfdSBrendan Jackman 		BPF_ATOMIC_OP(BPF_DW, BPF_ADD | BPF_FETCH, BPF_REG_10, BPF_REG_1, -8),
19*37086bfdSBrendan Jackman 		/* Verifier should be able to tell that this infinite loop isn't reachable. */
20*37086bfdSBrendan Jackman 		/* if (b) while (true) continue; */
21*37086bfdSBrendan Jackman 		BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, -1),
22*37086bfdSBrendan Jackman 		BPF_EXIT_INSN(),
23*37086bfdSBrendan Jackman 	},
24*37086bfdSBrendan Jackman 	.result = ACCEPT,
25*37086bfdSBrendan Jackman 	.result_unpriv = REJECT,
26*37086bfdSBrendan Jackman 	.errstr_unpriv = "back-edge",
27*37086bfdSBrendan Jackman },
28