Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Avoid passing out-of-range values to __retval()

Currently, we pass 0x1234567890abcdef to __retval() for the following
two tests:

verifier_load_acquire/load_acquire_64
verifier_store_release/store_release_64

However, the upper 32 bits of that value are being ignored, since
__retval() expects an int. Actually, the tests would still pass even if
I change '__retval(0x1234567890abcdef)' to e.g. '__retval(0x90abcdef)'.

Restructure the tests a bit to test the entire 64-bit values properly.
Do the same to their 8-, 16- and 32-bit variants as well to keep the
style consistent.

Fixes: ff3afe5da998 ("selftests/bpf: Add selftests for load-acquire and store-release instructions")
Acked-by: Björn Töpel <bjorn@kernel.org>
Reviewed-by: Pu Lehui <pulehui@huawei.com>
Tested-by: Björn Töpel <bjorn@rivosinc.com> # QEMU/RVA23
Signed-off-by: Peilin Ye <yepeilin@google.com>
Link: https://lore.kernel.org/r/d67f4c6f6ee0d0388cbce1f4892ec4176ee2d604.1746588351.git.yepeilin@google.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Peilin Ye and committed by
Alexei Starovoitov
6e492ffc 13fdecf3

+52 -20
+28 -12
tools/testing/selftests/bpf/progs/verifier_load_acquire.c
··· 10 10 11 11 SEC("socket") 12 12 __description("load-acquire, 8-bit") 13 - __success __success_unpriv __retval(0x12) 13 + __success __success_unpriv __retval(0) 14 14 __naked void load_acquire_8(void) 15 15 { 16 16 asm volatile ( 17 + "r0 = 0;" 17 18 "w1 = 0x12;" 18 19 "*(u8 *)(r10 - 1) = w1;" 19 - ".8byte %[load_acquire_insn];" // w0 = load_acquire((u8 *)(r10 - 1)); 20 + ".8byte %[load_acquire_insn];" // w2 = load_acquire((u8 *)(r10 - 1)); 21 + "if r2 == r1 goto 1f;" 22 + "r0 = 1;" 23 + "1:" 20 24 "exit;" 21 25 : 22 26 : __imm_insn(load_acquire_insn, 23 - BPF_ATOMIC_OP(BPF_B, BPF_LOAD_ACQ, BPF_REG_0, BPF_REG_10, -1)) 27 + BPF_ATOMIC_OP(BPF_B, BPF_LOAD_ACQ, BPF_REG_2, BPF_REG_10, -1)) 24 28 : __clobber_all); 25 29 } 26 30 27 31 SEC("socket") 28 32 __description("load-acquire, 16-bit") 29 - __success __success_unpriv __retval(0x1234) 33 + __success __success_unpriv __retval(0) 30 34 __naked void load_acquire_16(void) 31 35 { 32 36 asm volatile ( 37 + "r0 = 0;" 33 38 "w1 = 0x1234;" 34 39 "*(u16 *)(r10 - 2) = w1;" 35 - ".8byte %[load_acquire_insn];" // w0 = load_acquire((u16 *)(r10 - 2)); 40 + ".8byte %[load_acquire_insn];" // w2 = load_acquire((u16 *)(r10 - 2)); 41 + "if r2 == r1 goto 1f;" 42 + "r0 = 1;" 43 + "1:" 36 44 "exit;" 37 45 : 38 46 : __imm_insn(load_acquire_insn, 39 - BPF_ATOMIC_OP(BPF_H, BPF_LOAD_ACQ, BPF_REG_0, BPF_REG_10, -2)) 47 + BPF_ATOMIC_OP(BPF_H, BPF_LOAD_ACQ, BPF_REG_2, BPF_REG_10, -2)) 40 48 : __clobber_all); 41 49 } 42 50 43 51 SEC("socket") 44 52 __description("load-acquire, 32-bit") 45 - __success __success_unpriv __retval(0x12345678) 53 + __success __success_unpriv __retval(0) 46 54 __naked void load_acquire_32(void) 47 55 { 48 56 asm volatile ( 57 + "r0 = 0;" 49 58 "w1 = 0x12345678;" 50 59 "*(u32 *)(r10 - 4) = w1;" 51 - ".8byte %[load_acquire_insn];" // w0 = load_acquire((u32 *)(r10 - 4)); 60 + ".8byte %[load_acquire_insn];" // w2 = load_acquire((u32 *)(r10 - 4)); 61 + "if r2 == r1 goto 1f;" 62 + "r0 = 1;" 63 + "1:" 52 64 "exit;" 53 65 : 54 66 : __imm_insn(load_acquire_insn, 55 - BPF_ATOMIC_OP(BPF_W, BPF_LOAD_ACQ, BPF_REG_0, BPF_REG_10, -4)) 67 + BPF_ATOMIC_OP(BPF_W, BPF_LOAD_ACQ, BPF_REG_2, BPF_REG_10, -4)) 56 68 : __clobber_all); 57 69 } 58 70 59 71 SEC("socket") 60 72 __description("load-acquire, 64-bit") 61 - __success __success_unpriv __retval(0x1234567890abcdef) 73 + __success __success_unpriv __retval(0) 62 74 __naked void load_acquire_64(void) 63 75 { 64 76 asm volatile ( 77 + "r0 = 0;" 65 78 "r1 = 0x1234567890abcdef ll;" 66 79 "*(u64 *)(r10 - 8) = r1;" 67 - ".8byte %[load_acquire_insn];" // r0 = load_acquire((u64 *)(r10 - 8)); 80 + ".8byte %[load_acquire_insn];" // r2 = load_acquire((u64 *)(r10 - 8)); 81 + "if r2 == r1 goto 1f;" 82 + "r0 = 1;" 83 + "1:" 68 84 "exit;" 69 85 : 70 86 : __imm_insn(load_acquire_insn, 71 - BPF_ATOMIC_OP(BPF_DW, BPF_LOAD_ACQ, BPF_REG_0, BPF_REG_10, -8)) 87 + BPF_ATOMIC_OP(BPF_DW, BPF_LOAD_ACQ, BPF_REG_2, BPF_REG_10, -8)) 72 88 : __clobber_all); 73 89 } 74 90
+24 -8
tools/testing/selftests/bpf/progs/verifier_store_release.c
··· 10 10 11 11 SEC("socket") 12 12 __description("store-release, 8-bit") 13 - __success __success_unpriv __retval(0x12) 13 + __success __success_unpriv __retval(0) 14 14 __naked void store_release_8(void) 15 15 { 16 16 asm volatile ( 17 + "r0 = 0;" 17 18 "w1 = 0x12;" 18 19 ".8byte %[store_release_insn];" // store_release((u8 *)(r10 - 1), w1); 19 - "w0 = *(u8 *)(r10 - 1);" 20 + "w2 = *(u8 *)(r10 - 1);" 21 + "if r2 == r1 goto 1f;" 22 + "r0 = 1;" 23 + "1:" 20 24 "exit;" 21 25 : 22 26 : __imm_insn(store_release_insn, ··· 30 26 31 27 SEC("socket") 32 28 __description("store-release, 16-bit") 33 - __success __success_unpriv __retval(0x1234) 29 + __success __success_unpriv __retval(0) 34 30 __naked void store_release_16(void) 35 31 { 36 32 asm volatile ( 33 + "r0 = 0;" 37 34 "w1 = 0x1234;" 38 35 ".8byte %[store_release_insn];" // store_release((u16 *)(r10 - 2), w1); 39 - "w0 = *(u16 *)(r10 - 2);" 36 + "w2 = *(u16 *)(r10 - 2);" 37 + "if r2 == r1 goto 1f;" 38 + "r0 = 1;" 39 + "1:" 40 40 "exit;" 41 41 : 42 42 : __imm_insn(store_release_insn, ··· 50 42 51 43 SEC("socket") 52 44 __description("store-release, 32-bit") 53 - __success __success_unpriv __retval(0x12345678) 45 + __success __success_unpriv __retval(0) 54 46 __naked void store_release_32(void) 55 47 { 56 48 asm volatile ( 49 + "r0 = 0;" 57 50 "w1 = 0x12345678;" 58 51 ".8byte %[store_release_insn];" // store_release((u32 *)(r10 - 4), w1); 59 - "w0 = *(u32 *)(r10 - 4);" 52 + "w2 = *(u32 *)(r10 - 4);" 53 + "if r2 == r1 goto 1f;" 54 + "r0 = 1;" 55 + "1:" 60 56 "exit;" 61 57 : 62 58 : __imm_insn(store_release_insn, ··· 70 58 71 59 SEC("socket") 72 60 __description("store-release, 64-bit") 73 - __success __success_unpriv __retval(0x1234567890abcdef) 61 + __success __success_unpriv __retval(0) 74 62 __naked void store_release_64(void) 75 63 { 76 64 asm volatile ( 65 + "r0 = 0;" 77 66 "r1 = 0x1234567890abcdef ll;" 78 67 ".8byte %[store_release_insn];" // store_release((u64 *)(r10 - 8), r1); 79 - "r0 = *(u64 *)(r10 - 8);" 68 + "r2 = *(u64 *)(r10 - 8);" 69 + "if r2 == r1 goto 1f;" 70 + "r0 = 1;" 71 + "1:" 80 72 "exit;" 81 73 : 82 74 : __imm_insn(store_release_insn,