13c419715SShung-Hsi Yu // SPDX-License-Identifier: GPL-2.0 23c419715SShung-Hsi Yu /* Copyright (C) 2023 SUSE LLC */ 33c419715SShung-Hsi Yu #include <linux/bpf.h> 43c419715SShung-Hsi Yu #include <bpf/bpf_helpers.h> 53c419715SShung-Hsi Yu #include "bpf_misc.h" 63c419715SShung-Hsi Yu 73c419715SShung-Hsi Yu SEC("?raw_tp") 83c419715SShung-Hsi Yu __success __log_level(2) 93c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 3: (bf) r1 = r10") 103c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 2: (55) if r2 != 0xfffffff8 goto pc+2") 113c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 1: (87) r2 = -r2") 123c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 0: (b7) r2 = 8") bpf_neg(void)133c419715SShung-Hsi Yu__naked int bpf_neg(void) 143c419715SShung-Hsi Yu { 153c419715SShung-Hsi Yu asm volatile ( 163c419715SShung-Hsi Yu "r2 = 8;" 173c419715SShung-Hsi Yu "r2 = -r2;" 183c419715SShung-Hsi Yu "if r2 != -8 goto 1f;" 193c419715SShung-Hsi Yu "r1 = r10;" 203c419715SShung-Hsi Yu "r1 += r2;" 213c419715SShung-Hsi Yu "1:" 223c419715SShung-Hsi Yu "r0 = 0;" 233c419715SShung-Hsi Yu "exit;" 243c419715SShung-Hsi Yu ::: __clobber_all); 253c419715SShung-Hsi Yu } 263c419715SShung-Hsi Yu 273c419715SShung-Hsi Yu SEC("?raw_tp") 283c419715SShung-Hsi Yu __success __log_level(2) 293c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 3: (bf) r1 = r10") 303c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 2: (55) if r2 != 0x0 goto pc+2") 313c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 1: (d4) r2 = le16 r2") 323c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 0: (b7) r2 = 0") bpf_end_to_le(void)333c419715SShung-Hsi Yu__naked int bpf_end_to_le(void) 343c419715SShung-Hsi Yu { 353c419715SShung-Hsi Yu asm volatile ( 363c419715SShung-Hsi Yu "r2 = 0;" 373c419715SShung-Hsi Yu "r2 = le16 r2;" 383c419715SShung-Hsi Yu "if r2 != 0 goto 1f;" 393c419715SShung-Hsi Yu "r1 = r10;" 403c419715SShung-Hsi Yu "r1 += r2;" 413c419715SShung-Hsi Yu "1:" 423c419715SShung-Hsi Yu "r0 = 0;" 433c419715SShung-Hsi Yu "exit;" 443c419715SShung-Hsi Yu ::: __clobber_all); 453c419715SShung-Hsi Yu } 463c419715SShung-Hsi Yu 473c419715SShung-Hsi Yu 483c419715SShung-Hsi Yu SEC("?raw_tp") 493c419715SShung-Hsi Yu __success __log_level(2) 503c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 3: (bf) r1 = r10") 513c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 2: (55) if r2 != 0x0 goto pc+2") 523c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 1: (dc) r2 = be16 r2") 533c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 0: (b7) r2 = 0") bpf_end_to_be(void)543c419715SShung-Hsi Yu__naked int bpf_end_to_be(void) 553c419715SShung-Hsi Yu { 563c419715SShung-Hsi Yu asm volatile ( 573c419715SShung-Hsi Yu "r2 = 0;" 583c419715SShung-Hsi Yu "r2 = be16 r2;" 593c419715SShung-Hsi Yu "if r2 != 0 goto 1f;" 603c419715SShung-Hsi Yu "r1 = r10;" 613c419715SShung-Hsi Yu "r1 += r2;" 623c419715SShung-Hsi Yu "1:" 633c419715SShung-Hsi Yu "r0 = 0;" 643c419715SShung-Hsi Yu "exit;" 653c419715SShung-Hsi Yu ::: __clobber_all); 663c419715SShung-Hsi Yu } 673c419715SShung-Hsi Yu 683c419715SShung-Hsi Yu #if (defined(__TARGET_ARCH_arm64) || defined(__TARGET_ARCH_x86) || \ 693c419715SShung-Hsi Yu (defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64) || \ 703c419715SShung-Hsi Yu defined(__TARGET_ARCH_arm) || defined(__TARGET_ARCH_s390)) && \ 713c419715SShung-Hsi Yu __clang_major__ >= 18 723c419715SShung-Hsi Yu 733c419715SShung-Hsi Yu SEC("?raw_tp") 743c419715SShung-Hsi Yu __success __log_level(2) 753c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 3: (bf) r1 = r10") 763c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 2: (55) if r2 != 0x0 goto pc+2") 773c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 1: (d7) r2 = bswap16 r2") 783c419715SShung-Hsi Yu __msg("mark_precise: frame0: regs=r2 stack= before 0: (b7) r2 = 0") bpf_end_bswap(void)793c419715SShung-Hsi Yu__naked int bpf_end_bswap(void) 803c419715SShung-Hsi Yu { 813c419715SShung-Hsi Yu asm volatile ( 823c419715SShung-Hsi Yu "r2 = 0;" 833c419715SShung-Hsi Yu "r2 = bswap16 r2;" 843c419715SShung-Hsi Yu "if r2 != 0 goto 1f;" 853c419715SShung-Hsi Yu "r1 = r10;" 863c419715SShung-Hsi Yu "r1 += r2;" 873c419715SShung-Hsi Yu "1:" 883c419715SShung-Hsi Yu "r0 = 0;" 893c419715SShung-Hsi Yu "exit;" 903c419715SShung-Hsi Yu ::: __clobber_all); 913c419715SShung-Hsi Yu } 923c419715SShung-Hsi Yu 933c419715SShung-Hsi Yu #endif /* v4 instruction */ 94*62ccdb11SAndrii Nakryiko 95*62ccdb11SAndrii Nakryiko SEC("?raw_tp") 96*62ccdb11SAndrii Nakryiko __success __log_level(2) 97*62ccdb11SAndrii Nakryiko /* 98*62ccdb11SAndrii Nakryiko * Without the bug fix there will be no history between "last_idx 3 first_idx 3" 99*62ccdb11SAndrii Nakryiko * and "parent state regs=" lines. "R0_w=6" parts are here to help anchor 100*62ccdb11SAndrii Nakryiko * expected log messages to the one specific mark_chain_precision operation. 101*62ccdb11SAndrii Nakryiko * 102*62ccdb11SAndrii Nakryiko * This is quite fragile: if verifier checkpointing heuristic changes, this 103*62ccdb11SAndrii Nakryiko * might need adjusting. 104*62ccdb11SAndrii Nakryiko */ 105*62ccdb11SAndrii Nakryiko __msg("2: (07) r0 += 1 ; R0_w=6") 106*62ccdb11SAndrii Nakryiko __msg("3: (35) if r0 >= 0xa goto pc+1") 107*62ccdb11SAndrii Nakryiko __msg("mark_precise: frame0: last_idx 3 first_idx 3 subseq_idx -1") 108*62ccdb11SAndrii Nakryiko __msg("mark_precise: frame0: regs=r0 stack= before 2: (07) r0 += 1") 109*62ccdb11SAndrii Nakryiko __msg("mark_precise: frame0: regs=r0 stack= before 1: (07) r0 += 1") 110*62ccdb11SAndrii Nakryiko __msg("mark_precise: frame0: regs=r0 stack= before 4: (05) goto pc-4") 111*62ccdb11SAndrii Nakryiko __msg("mark_precise: frame0: regs=r0 stack= before 3: (35) if r0 >= 0xa goto pc+1") 112*62ccdb11SAndrii Nakryiko __msg("mark_precise: frame0: parent state regs= stack=: R0_rw=P4") 113*62ccdb11SAndrii Nakryiko __msg("3: R0_w=6") state_loop_first_last_equal(void)114*62ccdb11SAndrii Nakryiko__naked int state_loop_first_last_equal(void) 115*62ccdb11SAndrii Nakryiko { 116*62ccdb11SAndrii Nakryiko asm volatile ( 117*62ccdb11SAndrii Nakryiko "r0 = 0;" 118*62ccdb11SAndrii Nakryiko "l0_%=:" 119*62ccdb11SAndrii Nakryiko "r0 += 1;" 120*62ccdb11SAndrii Nakryiko "r0 += 1;" 121*62ccdb11SAndrii Nakryiko /* every few iterations we'll have a checkpoint here with 122*62ccdb11SAndrii Nakryiko * first_idx == last_idx, potentially confusing precision 123*62ccdb11SAndrii Nakryiko * backtracking logic 124*62ccdb11SAndrii Nakryiko */ 125*62ccdb11SAndrii Nakryiko "if r0 >= 10 goto l1_%=;" /* checkpoint + mark_precise */ 126*62ccdb11SAndrii Nakryiko "goto l0_%=;" 127*62ccdb11SAndrii Nakryiko "l1_%=:" 128*62ccdb11SAndrii Nakryiko "exit;" 129*62ccdb11SAndrii Nakryiko ::: __clobber_common 130*62ccdb11SAndrii Nakryiko ); 131*62ccdb11SAndrii Nakryiko } 132*62ccdb11SAndrii Nakryiko 133*62ccdb11SAndrii Nakryiko char _license[] SEC("license") = "GPL"; 134