forked from Minki/linux
bpf/tests: Add exhaustive test of LD_IMM64 immediate magnitudes
This patch adds a test for the 64-bit immediate load, a two-instruction operation, to verify correctness for all possible magnitudes of the immediate operand. Mainly intended for JIT testing. Signed-off-by: Johan Almbladh <johan.almbladh@anyfinetworks.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20210914091842.4186267-8-johan.almbladh@anyfinetworks.com
This commit is contained in:
parent
a7d2e752e5
commit
2e80761194
@ -1104,6 +1104,60 @@ static int bpf_fill_alu32_mod_reg(struct bpf_test *self)
|
||||
return __bpf_fill_alu32_reg(self, BPF_MOD);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the two-instruction 64-bit immediate load operation for all
|
||||
* power-of-two magnitudes of the immediate operand. For each MSB, a block
|
||||
* of immediate values centered around the power-of-two MSB are tested,
|
||||
* both for positive and negative values. The test is designed to verify
|
||||
* the operation for JITs that emit different code depending on the magnitude
|
||||
* of the immediate value. This is often the case if the native instruction
|
||||
* immediate field width is narrower than 32 bits.
|
||||
*/
|
||||
static int bpf_fill_ld_imm64(struct bpf_test *self)
|
||||
{
|
||||
int block = 64; /* Increase for more tests per MSB position */
|
||||
int len = 3 + 8 * 63 * block * 2;
|
||||
struct bpf_insn *insn;
|
||||
int bit, adj, sign;
|
||||
int i = 0;
|
||||
|
||||
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
||||
if (!insn)
|
||||
return -ENOMEM;
|
||||
|
||||
insn[i++] = BPF_ALU64_IMM(BPF_MOV, R0, 0);
|
||||
|
||||
for (bit = 0; bit <= 62; bit++) {
|
||||
for (adj = -block / 2; adj < block / 2; adj++) {
|
||||
for (sign = -1; sign <= 1; sign += 2) {
|
||||
s64 imm = sign * ((1LL << bit) + adj);
|
||||
|
||||
/* Perform operation */
|
||||
i += __bpf_ld_imm64(&insn[i], R1, imm);
|
||||
|
||||
/* Load reference */
|
||||
insn[i++] = BPF_ALU32_IMM(BPF_MOV, R2, imm);
|
||||
insn[i++] = BPF_ALU32_IMM(BPF_MOV, R3,
|
||||
(u32)(imm >> 32));
|
||||
insn[i++] = BPF_ALU64_IMM(BPF_LSH, R3, 32);
|
||||
insn[i++] = BPF_ALU64_REG(BPF_OR, R2, R3);
|
||||
|
||||
/* Check result */
|
||||
insn[i++] = BPF_JMP_REG(BPF_JEQ, R1, R2, 1);
|
||||
insn[i++] = BPF_EXIT_INSN();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
insn[i++] = BPF_ALU64_IMM(BPF_MOV, R0, 1);
|
||||
insn[i++] = BPF_EXIT_INSN();
|
||||
|
||||
self->u.ptr.insns = insn;
|
||||
self->u.ptr.len = len;
|
||||
BUG_ON(i != len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Exhaustive tests of JMP operations for all combinations of power-of-two
|
||||
@ -10245,6 +10299,15 @@ static struct bpf_test tests[] = {
|
||||
.fill_helper = bpf_fill_alu32_mod_reg,
|
||||
.nr_testruns = NR_PATTERN_RUNS,
|
||||
},
|
||||
/* LD_IMM64 immediate magnitudes */
|
||||
{
|
||||
"LD_IMM64: all immediate value magnitudes",
|
||||
{ },
|
||||
INTERNAL | FLAG_NO_DATA,
|
||||
{ },
|
||||
{ { 0, 1 } },
|
||||
.fill_helper = bpf_fill_ld_imm64,
|
||||
},
|
||||
/* JMP immediate magnitudes */
|
||||
{
|
||||
"JMP_JSET_K: all immediate value magnitudes",
|
||||
|
Loading…
Reference in New Issue
Block a user