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

bpf: add ld64 imm test cases

Add test cases where we combine semi-random imm values, mainly for testing
JITs when they have different encoding options for 64 bit immediates in
order to reduce resulting image size.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Daniel Borkmann and committed by
Alexei Starovoitov
a82d8cd3 56ea6a8b

+142
+80
tools/testing/selftests/bpf/bpf_rand.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __BPF_RAND__ 3 + #define __BPF_RAND__ 4 + 5 + #include <stdint.h> 6 + #include <stdlib.h> 7 + #include <time.h> 8 + 9 + static inline uint64_t bpf_rand_mask(uint64_t mask) 10 + { 11 + return (((uint64_t)(uint32_t)rand()) | 12 + ((uint64_t)(uint32_t)rand() << 32)) & mask; 13 + } 14 + 15 + #define bpf_rand_ux(x, m) \ 16 + static inline uint64_t bpf_rand_u##x(int shift) \ 17 + { \ 18 + return bpf_rand_mask((m)) << shift; \ 19 + } 20 + 21 + bpf_rand_ux( 8, 0xffULL) 22 + bpf_rand_ux(16, 0xffffULL) 23 + bpf_rand_ux(24, 0xffffffULL) 24 + bpf_rand_ux(32, 0xffffffffULL) 25 + bpf_rand_ux(40, 0xffffffffffULL) 26 + bpf_rand_ux(48, 0xffffffffffffULL) 27 + bpf_rand_ux(56, 0xffffffffffffffULL) 28 + bpf_rand_ux(64, 0xffffffffffffffffULL) 29 + 30 + static inline void bpf_semi_rand_init(void) 31 + { 32 + srand(time(NULL)); 33 + } 34 + 35 + static inline uint64_t bpf_semi_rand_get(void) 36 + { 37 + switch (rand() % 39) { 38 + case 0: return 0x000000ff00000000ULL | bpf_rand_u8(0); 39 + case 1: return 0xffffffff00000000ULL | bpf_rand_u16(0); 40 + case 2: return 0x00000000ffff0000ULL | bpf_rand_u16(0); 41 + case 3: return 0x8000000000000000ULL | bpf_rand_u32(0); 42 + case 4: return 0x00000000f0000000ULL | bpf_rand_u32(0); 43 + case 5: return 0x0000000100000000ULL | bpf_rand_u24(0); 44 + case 6: return 0x800ff00000000000ULL | bpf_rand_u32(0); 45 + case 7: return 0x7fffffff00000000ULL | bpf_rand_u32(0); 46 + case 8: return 0xffffffffffffff00ULL ^ bpf_rand_u32(24); 47 + case 9: return 0xffffffffffffff00ULL | bpf_rand_u8(0); 48 + case 10: return 0x0000000010000000ULL | bpf_rand_u32(0); 49 + case 11: return 0xf000000000000000ULL | bpf_rand_u8(0); 50 + case 12: return 0x0000f00000000000ULL | bpf_rand_u8(8); 51 + case 13: return 0x000000000f000000ULL | bpf_rand_u8(16); 52 + case 14: return 0x0000000000000f00ULL | bpf_rand_u8(32); 53 + case 15: return 0x00fff00000000f00ULL | bpf_rand_u8(48); 54 + case 16: return 0x00007fffffffffffULL ^ bpf_rand_u32(1); 55 + case 17: return 0xffff800000000000ULL | bpf_rand_u8(4); 56 + case 18: return 0xffff800000000000ULL | bpf_rand_u8(20); 57 + case 19: return (0xffffffc000000000ULL + 0x80000ULL) | bpf_rand_u32(0); 58 + case 20: return (0xffffffc000000000ULL - 0x04000000ULL) | bpf_rand_u32(0); 59 + case 21: return 0x0000000000000000ULL | bpf_rand_u8(55) | bpf_rand_u32(20); 60 + case 22: return 0xffffffffffffffffULL ^ bpf_rand_u8(3) ^ bpf_rand_u32(40); 61 + case 23: return 0x0000000000000000ULL | bpf_rand_u8(bpf_rand_u8(0) % 64); 62 + case 24: return 0x0000000000000000ULL | bpf_rand_u16(bpf_rand_u8(0) % 64); 63 + case 25: return 0xffffffffffffffffULL ^ bpf_rand_u8(bpf_rand_u8(0) % 64); 64 + case 26: return 0xffffffffffffffffULL ^ bpf_rand_u40(bpf_rand_u8(0) % 64); 65 + case 27: return 0x0000800000000000ULL; 66 + case 28: return 0x8000000000000000ULL; 67 + case 29: return 0x0000000000000000ULL; 68 + case 30: return 0xffffffffffffffffULL; 69 + case 31: return bpf_rand_u16(bpf_rand_u8(0) % 64); 70 + case 32: return bpf_rand_u24(bpf_rand_u8(0) % 64); 71 + case 33: return bpf_rand_u32(bpf_rand_u8(0) % 64); 72 + case 34: return bpf_rand_u40(bpf_rand_u8(0) % 64); 73 + case 35: return bpf_rand_u48(bpf_rand_u8(0) % 64); 74 + case 36: return bpf_rand_u56(bpf_rand_u8(0) % 64); 75 + case 37: return bpf_rand_u64(bpf_rand_u8(0) % 64); 76 + default: return bpf_rand_u64(0); 77 + } 78 + } 79 + 80 + #endif /* __BPF_RAND__ */
+62
tools/testing/selftests/bpf/test_verifier.c
··· 41 41 # endif 42 42 #endif 43 43 #include "bpf_rlimit.h" 44 + #include "bpf_rand.h" 44 45 #include "../../../include/linux/filter.h" 45 46 46 47 #ifndef ARRAY_SIZE ··· 151 150 while (i < len - 1) 152 151 insn[i++] = BPF_LD_ABS(BPF_B, 1); 153 152 insn[i] = BPF_EXIT_INSN(); 153 + } 154 + 155 + static void bpf_fill_rand_ld_dw(struct bpf_test *self) 156 + { 157 + struct bpf_insn *insn = self->insns; 158 + uint64_t res = 0; 159 + int i = 0; 160 + 161 + insn[i++] = BPF_MOV32_IMM(BPF_REG_0, 0); 162 + while (i < self->retval) { 163 + uint64_t val = bpf_semi_rand_get(); 164 + struct bpf_insn tmp[2] = { BPF_LD_IMM64(BPF_REG_1, val) }; 165 + 166 + res ^= val; 167 + insn[i++] = tmp[0]; 168 + insn[i++] = tmp[1]; 169 + insn[i++] = BPF_ALU64_REG(BPF_XOR, BPF_REG_0, BPF_REG_1); 170 + } 171 + insn[i++] = BPF_MOV64_REG(BPF_REG_1, BPF_REG_0); 172 + insn[i++] = BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32); 173 + insn[i++] = BPF_ALU64_REG(BPF_XOR, BPF_REG_0, BPF_REG_1); 174 + insn[i] = BPF_EXIT_INSN(); 175 + res ^= (res >> 32); 176 + self->retval = (uint32_t)res; 154 177 } 155 178 156 179 static struct bpf_test tests[] = { ··· 11999 11974 .result = ACCEPT, 12000 11975 .retval = 10, 12001 11976 }, 11977 + { 11978 + "ld_dw: xor semi-random 64 bit imms, test 1", 11979 + .insns = { }, 11980 + .data = { }, 11981 + .fill_helper = bpf_fill_rand_ld_dw, 11982 + .prog_type = BPF_PROG_TYPE_SCHED_CLS, 11983 + .result = ACCEPT, 11984 + .retval = 4090, 11985 + }, 11986 + { 11987 + "ld_dw: xor semi-random 64 bit imms, test 2", 11988 + .insns = { }, 11989 + .data = { }, 11990 + .fill_helper = bpf_fill_rand_ld_dw, 11991 + .prog_type = BPF_PROG_TYPE_SCHED_CLS, 11992 + .result = ACCEPT, 11993 + .retval = 2047, 11994 + }, 11995 + { 11996 + "ld_dw: xor semi-random 64 bit imms, test 3", 11997 + .insns = { }, 11998 + .data = { }, 11999 + .fill_helper = bpf_fill_rand_ld_dw, 12000 + .prog_type = BPF_PROG_TYPE_SCHED_CLS, 12001 + .result = ACCEPT, 12002 + .retval = 511, 12003 + }, 12004 + { 12005 + "ld_dw: xor semi-random 64 bit imms, test 4", 12006 + .insns = { }, 12007 + .data = { }, 12008 + .fill_helper = bpf_fill_rand_ld_dw, 12009 + .prog_type = BPF_PROG_TYPE_SCHED_CLS, 12010 + .result = ACCEPT, 12011 + .retval = 5, 12012 + }, 12002 12013 }; 12003 12014 12004 12015 static int probe_filter_length(const struct bpf_insn *fp) ··· 12407 12346 return EXIT_FAILURE; 12408 12347 } 12409 12348 12349 + bpf_semi_rand_init(); 12410 12350 return do_test(unpriv, from, to); 12411 12351 }