FILE
compute_live_registers.c
File preview with syntax highlighting.
linux-6.19.14/tools/testing/selftests/bpf/progs/compute_live_registers.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.