File Index
Files and directories
Sign in
FILE

compute_live_registers.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/progs/compute_live_registers.c C
  1// SPDX-License-Identifier: GPL-2.0
  2
  3#include <linux/bpf.h>
  4#include <bpf/bpf_helpers.h>
  5#include "../../../include/linux/filter.h"
  6#include "bpf_arena_common.h"
  7#include "bpf_misc.h"
  8
  9struct {
 10	__uint(type, BPF_MAP_TYPE_ARRAY);
 11	__uint(max_entries, 1);
 12	__type(key, __u32);
 13	__type(value, __u64);
 14} test_map SEC(".maps");
 15
 16struct {
 17	__uint(type, BPF_MAP_TYPE_ARENA);
 18	__uint(map_flags, BPF_F_MMAPABLE);
 19	__uint(max_entries, 1);
 20} arena SEC(".maps");
 21
 22SEC("socket")
 23__log_level(2)
 24__msg(" 0: .......... (b7) r0 = 42")
 25__msg(" 1: 0......... (bf) r1 = r0")
 26__msg(" 2: .1........ (bf) r2 = r1")
 27__msg(" 3: ..2....... (bf) r3 = r2")
 28__msg(" 4: ...3...... (bf) r4 = r3")
 29__msg(" 5: ....4..... (bf) r5 = r4")
 30__msg(" 6: .....5.... (bf) r6 = r5")
 31__msg(" 7: ......6... (bf) r7 = r6")
 32__msg(" 8: .......7.. (bf) r8 = r7")
 33__msg(" 9: ........8. (bf) r9 = r8")
 34__msg("10: .........9 (bf) r0 = r9")
 35__msg("11: 0......... (95) exit")
 36__naked void assign_chain(void)
 37{
 38	asm volatile (
 39		"r0 = 42;"
 40		"r1 = r0;"
 41		"r2 = r1;"
 42		"r3 = r2;"
 43		"r4 = r3;"
 44		"r5 = r4;"
 45		"r6 = r5;"
 46		"r7 = r6;"
 47		"r8 = r7;"
 48		"r9 = r8;"
 49		"r0 = r9;"
 50		"exit;"
 51		::: __clobber_all);
 52}
 53
 54SEC("socket")
 55__log_level(2)
 56__msg("0: .......... (b7) r1 = 7")
 57__msg("1: .1........ (07) r1 += 7")
 58__msg("2: .......... (b7) r2 = 7")
 59__msg("3: ..2....... (b7) r3 = 42")
 60__msg("4: ..23...... (0f) r2 += r3")
 61__msg("5: .......... (b7) r0 = 0")
 62__msg("6: 0......... (95) exit")
 63__naked void arithmetics(void)
 64{
 65	asm volatile (
 66		"r1 = 7;"
 67		"r1 += 7;"
 68		"r2 = 7;"
 69		"r3 = 42;"
 70		"r2 += r3;"
 71		"r0 = 0;"
 72		"exit;"
 73		::: __clobber_all);
 74}
 75
 76#ifdef CAN_USE_BPF_ST
 77SEC("socket")
 78__log_level(2)
 79__msg("  1: .1........ (07) r1 += -8")
 80__msg("  2: .1........ (7a) *(u64 *)(r1 +0) = 7")
 81__msg("  3: .1........ (b7) r2 = 42")
 82__msg("  4: .12....... (7b) *(u64 *)(r1 +0) = r2")
 83__msg("  5: .12....... (7b) *(u64 *)(r1 +0) = r2")
 84__msg("  6: .......... (b7) r0 = 0")
 85__naked void store(void)
 86{
 87	asm volatile (
 88		"r1 = r10;"
 89		"r1 += -8;"
 90		"*(u64 *)(r1 +0) = 7;"
 91		"r2 = 42;"
 92		"*(u64 *)(r1 +0) = r2;"
 93		"*(u64 *)(r1 +0) = r2;"
 94		"r0 = 0;"
 95		"exit;"
 96		::: __clobber_all);
 97}
 98#endif
 99
100SEC("socket")
101__log_level(2)
102__msg("1: ....4..... (07) r4 += -8")
103__msg("2: ....4..... (79) r5 = *(u64 *)(r4 +0)")
104__msg("3: ....45.... (07) r4 += -8")
105__naked void load(void)
106{
107	asm volatile (
108		"r4 = r10;"
109		"r4 += -8;"
110		"r5 = *(u64 *)(r4 +0);"
111		"r4 += -8;"
112		"r0 = r5;"
113		"exit;"
114		::: __clobber_all);
115}
116
117SEC("socket")
118__log_level(2)
119__msg("0: .1........ (61) r2 = *(u32 *)(r1 +0)")
120__msg("1: ..2....... (d4) r2 = le64 r2")
121__msg("2: ..2....... (bf) r0 = r2")
122__naked void endian(void)
123{
124	asm volatile (
125		"r2 = *(u32 *)(r1 +0);"
126		"r2 = le64 r2;"
127		"r0 = r2;"
128		"exit;"
129		::: __clobber_all);
130}
131
132SEC("socket")
133__log_level(2)
134__msg(" 8: 0......... (b7) r1 = 1")
135__msg(" 9: 01........ (db) r1 = atomic64_fetch_add((u64 *)(r0 +0), r1)")
136__msg("10: 01........ (c3) lock *(u32 *)(r0 +0) += r1")
137__msg("11: 01........ (db) r1 = atomic64_xchg((u64 *)(r0 +0), r1)")
138__msg("12: 01........ (bf) r2 = r0")
139__msg("13: .12....... (bf) r0 = r1")
140__msg("14: 012....... (db) r0 = atomic64_cmpxchg((u64 *)(r2 +0), r0, r1)")
141__naked void atomic(void)
142{
143	asm volatile (
144		"r2 = r10;"
145		"r2 += -8;"
146		"r1 = 0;"
147		"*(u64 *)(r2 +0) = r1;"
148		"r1 = %[test_map] ll;"
149		"call %[bpf_map_lookup_elem];"
150		"if r0 == 0 goto 1f;"
151		"r1 = 1;"
152		"r1 = atomic_fetch_add((u64 *)(r0 +0), r1);"
153		".8byte %[add_nofetch];" /* same as "lock *(u32 *)(r0 +0) += r1;" */
154		"r1 = xchg_64(r0 + 0, r1);"
155		"r2 = r0;"
156		"r0 = r1;"
157		"r0 = cmpxchg_64(r2 + 0, r0, r1);"
158		"1: exit;"
159		:
160		: __imm(bpf_map_lookup_elem),
161		  __imm_addr(test_map),
162		  __imm_insn(add_nofetch, BPF_ATOMIC_OP(BPF_W, BPF_ADD, BPF_REG_0, BPF_REG_1, 0))
163		: __clobber_all);
164}
165
166#ifdef CAN_USE_LOAD_ACQ_STORE_REL
167
168SEC("socket")
169__log_level(2)
170__msg("2: .12....... (db) store_release((u64 *)(r2 -8), r1)")
171__msg("3: .......... (bf) r3 = r10")
172__msg("4: ...3...... (db) r4 = load_acquire((u64 *)(r3 -8))")
173__naked void atomic_load_acq_store_rel(void)
174{
175	asm volatile (
176		"r1 = 42;"
177		"r2 = r10;"
178		".8byte %[store_release_insn];" /* store_release((u64 *)(r2 - 8), r1); */
179		"r3 = r10;"
180		".8byte %[load_acquire_insn];" /* r4 = load_acquire((u64 *)(r3 + 0)); */
181		"r0 = r4;"
182		"exit;"
183		:
184		: __imm_insn(store_release_insn,
185			     BPF_ATOMIC_OP(BPF_DW, BPF_STORE_REL, BPF_REG_2, BPF_REG_1, -8)),
186		  __imm_insn(load_acquire_insn,
187			     BPF_ATOMIC_OP(BPF_DW, BPF_LOAD_ACQ, BPF_REG_4, BPF_REG_3, -8))
188		: __clobber_all);
189}
190
191#endif /* CAN_USE_LOAD_ACQ_STORE_REL */
192
193SEC("socket")
194__log_level(2)
195__msg("4: .12....7.. (85) call bpf_trace_printk#6")
196__msg("5: 0......7.. (0f) r0 += r7")
197__naked void regular_call(void)
198{
199	asm volatile (
200		"r7 = 1;"
201		"r1 = r10;"
202		"r1 += -8;"
203		"r2 = 1;"
204		"call %[bpf_trace_printk];"
205		"r0 += r7;"
206		"exit;"
207		:
208		: __imm(bpf_trace_printk)
209		: __clobber_all);
210}
211
212SEC("socket")
213__log_level(2)
214__msg("2: 012....... (25) if r1 > 0x7 goto pc+1")
215__msg("3: ..2....... (bf) r0 = r2")
216__naked void if1(void)
217{
218	asm volatile (
219		"r0 = 1;"
220		"r2 = 2;"
221		"if r1 > 0x7 goto +1;"
222		"r0 = r2;"
223		"exit;"
224		::: __clobber_all);
225}
226
227SEC("socket")
228__log_level(2)
229__msg("3: 0123...... (2d) if r1 > r3 goto pc+1")
230__msg("4: ..2....... (bf) r0 = r2")
231__naked void if2(void)
232{
233	asm volatile (
234		"r0 = 1;"
235		"r2 = 2;"
236		"r3 = 7;"
237		"if r1 > r3 goto +1;"
238		"r0 = r2;"
239		"exit;"
240		::: __clobber_all);
241}
242
243/* Verifier misses that r2 is alive if jset is not handled properly */
244SEC("socket")
245__log_level(2)
246__msg("2: 012....... (45) if r1 & 0x7 goto pc+1")
247__naked void if3_jset_bug(void)
248{
249	asm volatile (
250		"r0 = 1;"
251		"r2 = 2;"
252		"if r1 & 0x7 goto +1;"
253		"exit;"
254		"r0 = r2;"
255		"exit;"
256		::: __clobber_all);
257}
258
259SEC("socket")
260__log_level(2)
261__msg("0: .......... (b7) r1 = 0")
262__msg("1: .1........ (b7) r2 = 7")
263__msg("2: .12....... (25) if r1 > 0x7 goto pc+4")
264__msg("3: .12....... (07) r1 += 1")
265__msg("4: .12....... (27) r2 *= 2")
266__msg("5: .12....... (05) goto pc+0")
267__msg("6: .12....... (05) goto pc-5")
268__msg("7: .......... (b7) r0 = 0")
269__msg("8: 0......... (95) exit")
270__naked void loop(void)
271{
272	asm volatile (
273		"r1 = 0;"
274		"r2 = 7;"
275		"if r1 > 0x7 goto +4;"
276		"r1 += 1;"
277		"r2 *= 2;"
278		"goto +0;"
279		"goto -5;"
280		"r0 = 0;"
281		"exit;"
282		:
283		: __imm(bpf_trace_printk)
284		: __clobber_all);
285}
286
287#ifdef CAN_USE_GOTOL
288SEC("socket")
289__log_level(2)
290__msg("2: .123...... (25) if r1 > 0x7 goto pc+2")
291__msg("3: ..2....... (bf) r0 = r2")
292__msg("4: 0......... (06) gotol pc+1")
293__msg("5: ...3...... (bf) r0 = r3")
294__msg("6: 0......... (95) exit")
295__naked void gotol(void)
296{
297	asm volatile (
298		"r2 = 42;"
299		"r3 = 24;"
300		"if r1 > 0x7 goto +2;"
301		"r0 = r2;"
302		"gotol +1;"
303		"r0 = r3;"
304		"exit;"
305		:
306		: __imm(bpf_trace_printk)
307		: __clobber_all);
308}
309#endif
310
311SEC("socket")
312__log_level(2)
313__msg("0: .......... (b7) r1 = 1")
314__msg("1: .1........ (e5) may_goto pc+1")
315__msg("2: .......... (05) goto pc-3")
316__msg("3: .1........ (bf) r0 = r1")
317__msg("4: 0......... (95) exit")
318__naked void may_goto(void)
319{
320	asm volatile (
321	"1: r1 = 1;"
322	".8byte %[may_goto];"
323	"goto 1b;"
324	"r0 = r1;"
325	"exit;"
326	:
327	: __imm(bpf_get_smp_processor_id),
328	  __imm_insn(may_goto, BPF_RAW_INSN(BPF_JMP | BPF_JCOND, 0, 0, +1 /* offset */, 0))
329	: __clobber_all);
330}
331
332SEC("socket")
333__log_level(2)
334__msg("1: 0......... (18) r2 = 0x7")
335__msg("3: 0.2....... (0f) r0 += r2")
336__naked void ldimm64(void)
337{
338	asm volatile (
339		"r0 = 0;"
340		"r2 = 0x7 ll;"
341		"r0 += r2;"
342		"exit;"
343		:
344		:: __clobber_all);
345}
346
347/* No rules specific for LD_ABS/LD_IND, default behaviour kicks in */
348SEC("socket")
349__log_level(2)
350__msg("2: 0123456789 (30) r0 = *(u8 *)skb[42]")
351__msg("3: 012.456789 (0f) r7 += r0")
352__msg("4: 012.456789 (b7) r3 = 42")
353__msg("5: 0123456789 (50) r0 = *(u8 *)skb[r3 + 0]")
354__msg("6: 0......7.. (0f) r7 += r0")
355__naked void ldabs(void)
356{
357	asm volatile (
358		"r6 = r1;"
359		"r7 = 0;"
360		"r0 = *(u8 *)skb[42];"
361		"r7 += r0;"
362		"r3 = 42;"
363		".8byte %[ld_ind];" /* same as "r0 = *(u8 *)skb[r3];" */
364		"r7 += r0;"
365		"r0 = r7;"
366		"exit;"
367		:
368		: __imm_insn(ld_ind, BPF_LD_IND(BPF_B, BPF_REG_3, 0))
369		: __clobber_all);
370}
371
372
373#ifdef __BPF_FEATURE_ADDR_SPACE_CAST
374SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
375__log_level(2)
376__msg(" 6: .12345.... (85) call bpf_arena_alloc_pages")
377__msg(" 7: 0......... (bf) r1 = addr_space_cast(r0, 0, 1)")
378__msg(" 8: .1........ (b7) r2 = 42")
379__naked void addr_space_cast(void)
380{
381	asm volatile (
382		"r1 = %[arena] ll;"
383		"r2 = 0;"
384		"r3 = 1;"
385		"r4 = 0;"
386		"r5 = 0;"
387		"call %[bpf_arena_alloc_pages];"
388		"r1 = addr_space_cast(r0, 0, 1);"
389		"r2 = 42;"
390		"*(u64 *)(r1 +0) = r2;"
391		"r0 = 0;"
392		"exit;"
393		:
394		: __imm(bpf_arena_alloc_pages),
395		  __imm_addr(arena)
396		: __clobber_all);
397}
398#endif
399
400static __used __naked int aux1(void)
401{
402	asm volatile (
403		"r0 = r1;"
404		"r0 += r2;"
405		"exit;"
406		::: __clobber_all);
407}
408
409SEC("socket")
410__log_level(2)
411__msg("0: ....45.... (b7) r1 = 1")
412__msg("1: .1..45.... (b7) r2 = 2")
413__msg("2: .12.45.... (b7) r3 = 3")
414/* Conservative liveness for subprog parameters. */
415__msg("3: .12345.... (85) call pc+2")
416__msg("4: .......... (b7) r0 = 0")
417__msg("5: 0......... (95) exit")
418__msg("6: .12....... (bf) r0 = r1")
419__msg("7: 0.2....... (0f) r0 += r2")
420/* Conservative liveness for subprog return value. */
421__msg("8: 0......... (95) exit")
422__naked void subprog1(void)
423{
424	asm volatile (
425		"r1 = 1;"
426		"r2 = 2;"
427		"r3 = 3;"
428		"call aux1;"
429		"r0 = 0;"
430		"exit;"
431		::: __clobber_all);
432}
433
434/* to retain debug info for BTF generation */
435void kfunc_root(void)
436{
437	bpf_arena_alloc_pages(0, 0, 0, 0, 0);
438}
439
440char _license[] SEC("license") = "GPL";
~/ Read-only file preview.