}
/* ALU result computation used in tests */
-static bool __bpf_alu_result(u64 *res, u64 v1, u64 v2, u8 op)
+enum { F_ALU32 = 1, F_SIGNED = 2 };
+
+static bool __bpf_alu_result(u64 *res, u64 v1, u64 v2, u8 op, u32 flags)
{
+ bool is_signed = flags & F_SIGNED;
+
+ /* Narrow operands for ALU32 */
+ if (flags & F_ALU32) {
+ if (is_signed) {
+ v1 = (u64)(s32)v1;
+ v2 = (u64)(s32)v2;
+ } else {
+ v1 = (u32)v1;
+ v2 = (u32)v2;
+ }
+ }
+
*res = 0;
switch (op) {
case BPF_MOV:
case BPF_DIV:
if (v2 == 0)
return false;
- *res = div64_u64(v1, v2);
+ if (!is_signed) {
+ *res = div64_u64(v1, v2);
+ } else {
+ if ((s64)v2 == -1) /* Handled by verifier */
+ return false;
+ *res = (u64)div64_s64(v1, v2);
+ }
break;
case BPF_MOD:
if (v2 == 0)
return false;
- div64_u64_rem(v1, v2, res);
+ if (!is_signed) {
+ div64_u64_rem(v1, v2, res);
+ } else {
+ if ((s64)v2 == -1)
+ return false;
+ /*
+ * Avoid s64 % s64 which generates __moddi3 on
+ * 32-bit architectures. Use div64_s64 instead.
+ */
+ *res = (u64)((s64)v1 - div64_s64(v1, v2) * (s64)v2);
+ }
break;
}
return true;
/* Test an ALU shift operation for all valid shift values */
static int __bpf_fill_alu_shift(struct bpf_test *self, u8 op,
- u8 mode, bool alu32)
+ u8 mode, u32 flags)
{
static const s64 regs[] = {
0x0123456789abcdefLL, /* dword > 0, word < 0 */
0xfedcba0198765432LL, /* dword < 0, word < 0 */
0x0123458967abcdefLL, /* dword > 0, word > 0 */
};
- int bits = alu32 ? 32 : 64;
+ int bits = (flags & F_ALU32) ? 32 : 64;
int len = (2 + 7 * bits) * ARRAY_SIZE(regs) + 3;
struct bpf_insn *insn;
int imm, k;
/* Perform operation */
insn[i++] = BPF_ALU64_REG(BPF_MOV, R1, R3);
insn[i++] = BPF_ALU64_IMM(BPF_MOV, R2, imm);
- if (alu32) {
+ if (flags & F_ALU32) {
if (mode == BPF_K)
insn[i++] = BPF_ALU32_IMM(op, R1, imm);
else
reg = (s32)reg;
else
reg = (u32)reg;
- __bpf_alu_result(&val, reg, imm, op);
+ __bpf_alu_result(&val, reg, imm, op, 0);
val = (u32)val;
} else {
if (mode == BPF_K)
insn[i++] = BPF_ALU64_IMM(op, R1, imm);
else
insn[i++] = BPF_ALU64_REG(op, R1, R2);
- __bpf_alu_result(&val, reg, imm, op);
+ __bpf_alu_result(&val, reg, imm, op, 0);
}
/*
static int bpf_fill_alu64_lsh_imm(struct bpf_test *self)
{
- return __bpf_fill_alu_shift(self, BPF_LSH, BPF_K, false);
+ return __bpf_fill_alu_shift(self, BPF_LSH, BPF_K, 0);
}
static int bpf_fill_alu64_rsh_imm(struct bpf_test *self)
{
- return __bpf_fill_alu_shift(self, BPF_RSH, BPF_K, false);
+ return __bpf_fill_alu_shift(self, BPF_RSH, BPF_K, 0);
}
static int bpf_fill_alu64_arsh_imm(struct bpf_test *self)
{
- return __bpf_fill_alu_shift(self, BPF_ARSH, BPF_K, false);
+ return __bpf_fill_alu_shift(self, BPF_ARSH, BPF_K, 0);
}
static int bpf_fill_alu64_lsh_reg(struct bpf_test *self)
{
- return __bpf_fill_alu_shift(self, BPF_LSH, BPF_X, false);
+ return __bpf_fill_alu_shift(self, BPF_LSH, BPF_X, 0);
}
static int bpf_fill_alu64_rsh_reg(struct bpf_test *self)
{
- return __bpf_fill_alu_shift(self, BPF_RSH, BPF_X, false);
+ return __bpf_fill_alu_shift(self, BPF_RSH, BPF_X, 0);
}
static int bpf_fill_alu64_arsh_reg(struct bpf_test *self)
{
- return __bpf_fill_alu_shift(self, BPF_ARSH, BPF_X, false);
+ return __bpf_fill_alu_shift(self, BPF_ARSH, BPF_X, 0);
}
static int bpf_fill_alu32_lsh_imm(struct bpf_test *self)
{
- return __bpf_fill_alu_shift(self, BPF_LSH, BPF_K, true);
+ return __bpf_fill_alu_shift(self, BPF_LSH, BPF_K, F_ALU32);
}
static int bpf_fill_alu32_rsh_imm(struct bpf_test *self)
{
- return __bpf_fill_alu_shift(self, BPF_RSH, BPF_K, true);
+ return __bpf_fill_alu_shift(self, BPF_RSH, BPF_K, F_ALU32);
}
static int bpf_fill_alu32_arsh_imm(struct bpf_test *self)
{
- return __bpf_fill_alu_shift(self, BPF_ARSH, BPF_K, true);
+ return __bpf_fill_alu_shift(self, BPF_ARSH, BPF_K, F_ALU32);
}
static int bpf_fill_alu32_lsh_reg(struct bpf_test *self)
{
- return __bpf_fill_alu_shift(self, BPF_LSH, BPF_X, true);
+ return __bpf_fill_alu_shift(self, BPF_LSH, BPF_X, F_ALU32);
}
static int bpf_fill_alu32_rsh_reg(struct bpf_test *self)
{
- return __bpf_fill_alu_shift(self, BPF_RSH, BPF_X, true);
+ return __bpf_fill_alu_shift(self, BPF_RSH, BPF_X, F_ALU32);
}
static int bpf_fill_alu32_arsh_reg(struct bpf_test *self)
{
- return __bpf_fill_alu_shift(self, BPF_ARSH, BPF_X, true);
+ return __bpf_fill_alu_shift(self, BPF_ARSH, BPF_X, F_ALU32);
}
/*
* for the case when the source and destination are the same.
*/
static int __bpf_fill_alu_shift_same_reg(struct bpf_test *self, u8 op,
- bool alu32)
+ u32 flags)
{
- int bits = alu32 ? 32 : 64;
+ int bits = (flags & F_ALU32) ? 32 : 64;
int len = 3 + 6 * bits;
struct bpf_insn *insn;
int i = 0;
/* Perform operation */
insn[i++] = BPF_ALU64_IMM(BPF_MOV, R1, val);
- if (alu32)
+ if (flags & F_ALU32)
insn[i++] = BPF_ALU32_REG(op, R1, R1);
else
insn[i++] = BPF_ALU64_REG(op, R1, R1);
/* Compute the reference result */
- __bpf_alu_result(&res, val, val, op);
- if (alu32)
+ __bpf_alu_result(&res, val, val, op, 0);
+ if (flags & F_ALU32)
res = (u32)res;
i += __bpf_ld_imm64(&insn[i], R2, res);
static int bpf_fill_alu64_lsh_same_reg(struct bpf_test *self)
{
- return __bpf_fill_alu_shift_same_reg(self, BPF_LSH, false);
+ return __bpf_fill_alu_shift_same_reg(self, BPF_LSH, 0);
}
static int bpf_fill_alu64_rsh_same_reg(struct bpf_test *self)
{
- return __bpf_fill_alu_shift_same_reg(self, BPF_RSH, false);
+ return __bpf_fill_alu_shift_same_reg(self, BPF_RSH, 0);
}
static int bpf_fill_alu64_arsh_same_reg(struct bpf_test *self)
{
- return __bpf_fill_alu_shift_same_reg(self, BPF_ARSH, false);
+ return __bpf_fill_alu_shift_same_reg(self, BPF_ARSH, 0);
}
static int bpf_fill_alu32_lsh_same_reg(struct bpf_test *self)
{
- return __bpf_fill_alu_shift_same_reg(self, BPF_LSH, true);
+ return __bpf_fill_alu_shift_same_reg(self, BPF_LSH, F_ALU32);
}
static int bpf_fill_alu32_rsh_same_reg(struct bpf_test *self)
{
- return __bpf_fill_alu_shift_same_reg(self, BPF_RSH, true);
+ return __bpf_fill_alu_shift_same_reg(self, BPF_RSH, F_ALU32);
}
static int bpf_fill_alu32_arsh_same_reg(struct bpf_test *self)
{
- return __bpf_fill_alu_shift_same_reg(self, BPF_ARSH, true);
+ return __bpf_fill_alu_shift_same_reg(self, BPF_ARSH, F_ALU32);
}
/*
static int __bpf_emit_alu64_imm(struct bpf_test *self, void *arg,
struct bpf_insn *insns, s64 dst, s64 imm)
{
- int op = *(int *)arg;
+ int *a = arg;
+ int op = a[0];
+ u32 flags = a[1];
+ s16 off = (flags & F_SIGNED) ? 1 : 0;
int i = 0;
u64 res;
if (!insns)
return 7;
- if (__bpf_alu_result(&res, dst, (s32)imm, op)) {
+ if (__bpf_alu_result(&res, dst, (s32)imm, op, flags)) {
i += __bpf_ld_imm64(&insns[i], R1, dst);
i += __bpf_ld_imm64(&insns[i], R3, res);
- insns[i++] = BPF_ALU64_IMM(op, R1, imm);
+ insns[i++] = BPF_ALU64_IMM_OFF(op, R1, imm, off);
insns[i++] = BPF_JMP_REG(BPF_JEQ, R1, R3, 1);
insns[i++] = BPF_EXIT_INSN();
}
static int __bpf_emit_alu32_imm(struct bpf_test *self, void *arg,
struct bpf_insn *insns, s64 dst, s64 imm)
{
- int op = *(int *)arg;
+ int *a = arg;
+ int op = a[0];
+ u32 flags = a[1];
+ s16 off = (flags & F_SIGNED) ? 1 : 0;
int i = 0;
u64 res;
if (!insns)
return 7;
- if (__bpf_alu_result(&res, (u32)dst, (u32)imm, op)) {
+ if (__bpf_alu_result(&res, dst, (s32)imm, op, flags | F_ALU32)) {
i += __bpf_ld_imm64(&insns[i], R1, dst);
i += __bpf_ld_imm64(&insns[i], R3, (u32)res);
- insns[i++] = BPF_ALU32_IMM(op, R1, imm);
+ insns[i++] = BPF_ALU32_IMM_OFF(op, R1, imm, off);
insns[i++] = BPF_JMP_REG(BPF_JEQ, R1, R3, 1);
insns[i++] = BPF_EXIT_INSN();
}
if (!insns)
return 9;
- if (__bpf_alu_result(&res, dst, src, op)) {
+ if (__bpf_alu_result(&res, dst, src, op, 0)) {
i += __bpf_ld_imm64(&insns[i], R1, dst);
i += __bpf_ld_imm64(&insns[i], R2, src);
i += __bpf_ld_imm64(&insns[i], R3, res);
if (!insns)
return 9;
- if (__bpf_alu_result(&res, (u32)dst, (u32)src, op)) {
+ if (__bpf_alu_result(&res, (u32)dst, (u32)src, op, 0)) {
i += __bpf_ld_imm64(&insns[i], R1, dst);
i += __bpf_ld_imm64(&insns[i], R2, src);
i += __bpf_ld_imm64(&insns[i], R3, (u32)res);
return i;
}
-static int __bpf_fill_alu64_imm(struct bpf_test *self, int op)
+static int __bpf_fill_alu64_imm(struct bpf_test *self, int op, u32 flags)
{
- return __bpf_fill_pattern(self, &op, 64, 32,
+ int arg[2] = {op, flags};
+
+ return __bpf_fill_pattern(self, &arg, 64, 32,
PATTERN_BLOCK1, PATTERN_BLOCK2,
&__bpf_emit_alu64_imm);
}
-static int __bpf_fill_alu32_imm(struct bpf_test *self, int op)
+static int __bpf_fill_alu32_imm(struct bpf_test *self, int op, u32 flags)
{
- return __bpf_fill_pattern(self, &op, 64, 32,
+ int arg[2] = {op, flags};
+
+ return __bpf_fill_pattern(self, &arg, 64, 32,
PATTERN_BLOCK1, PATTERN_BLOCK2,
&__bpf_emit_alu32_imm);
}
/* ALU64 immediate operations */
static int bpf_fill_alu64_mov_imm(struct bpf_test *self)
{
- return __bpf_fill_alu64_imm(self, BPF_MOV);
+ return __bpf_fill_alu64_imm(self, BPF_MOV, 0);
}
static int bpf_fill_alu64_and_imm(struct bpf_test *self)
{
- return __bpf_fill_alu64_imm(self, BPF_AND);
+ return __bpf_fill_alu64_imm(self, BPF_AND, 0);
}
static int bpf_fill_alu64_or_imm(struct bpf_test *self)
{
- return __bpf_fill_alu64_imm(self, BPF_OR);
+ return __bpf_fill_alu64_imm(self, BPF_OR, 0);
}
static int bpf_fill_alu64_xor_imm(struct bpf_test *self)
{
- return __bpf_fill_alu64_imm(self, BPF_XOR);
+ return __bpf_fill_alu64_imm(self, BPF_XOR, 0);
}
static int bpf_fill_alu64_add_imm(struct bpf_test *self)
{
- return __bpf_fill_alu64_imm(self, BPF_ADD);
+ return __bpf_fill_alu64_imm(self, BPF_ADD, 0);
}
static int bpf_fill_alu64_sub_imm(struct bpf_test *self)
{
- return __bpf_fill_alu64_imm(self, BPF_SUB);
+ return __bpf_fill_alu64_imm(self, BPF_SUB, 0);
}
static int bpf_fill_alu64_mul_imm(struct bpf_test *self)
{
- return __bpf_fill_alu64_imm(self, BPF_MUL);
+ return __bpf_fill_alu64_imm(self, BPF_MUL, 0);
}
static int bpf_fill_alu64_div_imm(struct bpf_test *self)
{
- return __bpf_fill_alu64_imm(self, BPF_DIV);
+ return __bpf_fill_alu64_imm(self, BPF_DIV, 0);
}
static int bpf_fill_alu64_mod_imm(struct bpf_test *self)
{
- return __bpf_fill_alu64_imm(self, BPF_MOD);
+ return __bpf_fill_alu64_imm(self, BPF_MOD, 0);
+}
+
+/* Signed ALU64 immediate operations */
+static int bpf_fill_alu64_sdiv_imm(struct bpf_test *self)
+{
+ return __bpf_fill_alu64_imm(self, BPF_DIV, F_SIGNED);
+}
+
+static int bpf_fill_alu64_smod_imm(struct bpf_test *self)
+{
+ return __bpf_fill_alu64_imm(self, BPF_MOD, F_SIGNED);
+}
+
+/* Signed ALU32 immediate operations */
+static int bpf_fill_alu32_sdiv_imm(struct bpf_test *self)
+{
+ return __bpf_fill_alu32_imm(self, BPF_DIV, F_SIGNED);
+}
+
+static int bpf_fill_alu32_smod_imm(struct bpf_test *self)
+{
+ return __bpf_fill_alu32_imm(self, BPF_MOD, F_SIGNED);
}
/* ALU32 immediate operations */
static int bpf_fill_alu32_mov_imm(struct bpf_test *self)
{
- return __bpf_fill_alu32_imm(self, BPF_MOV);
+ return __bpf_fill_alu32_imm(self, BPF_MOV, 0);
}
static int bpf_fill_alu32_and_imm(struct bpf_test *self)
{
- return __bpf_fill_alu32_imm(self, BPF_AND);
+ return __bpf_fill_alu32_imm(self, BPF_AND, 0);
}
static int bpf_fill_alu32_or_imm(struct bpf_test *self)
{
- return __bpf_fill_alu32_imm(self, BPF_OR);
+ return __bpf_fill_alu32_imm(self, BPF_OR, 0);
}
static int bpf_fill_alu32_xor_imm(struct bpf_test *self)
{
- return __bpf_fill_alu32_imm(self, BPF_XOR);
+ return __bpf_fill_alu32_imm(self, BPF_XOR, 0);
}
static int bpf_fill_alu32_add_imm(struct bpf_test *self)
{
- return __bpf_fill_alu32_imm(self, BPF_ADD);
+ return __bpf_fill_alu32_imm(self, BPF_ADD, 0);
}
static int bpf_fill_alu32_sub_imm(struct bpf_test *self)
{
- return __bpf_fill_alu32_imm(self, BPF_SUB);
+ return __bpf_fill_alu32_imm(self, BPF_SUB, 0);
}
static int bpf_fill_alu32_mul_imm(struct bpf_test *self)
{
- return __bpf_fill_alu32_imm(self, BPF_MUL);
+ return __bpf_fill_alu32_imm(self, BPF_MUL, 0);
}
static int bpf_fill_alu32_div_imm(struct bpf_test *self)
{
- return __bpf_fill_alu32_imm(self, BPF_DIV);
+ return __bpf_fill_alu32_imm(self, BPF_DIV, 0);
}
static int bpf_fill_alu32_mod_imm(struct bpf_test *self)
{
- return __bpf_fill_alu32_imm(self, BPF_MOD);
+ return __bpf_fill_alu32_imm(self, BPF_MOD, 0);
}
/* ALU64 register operations */
* Test JITs that implement complex ALU operations as function
* calls, and must re-arrange operands for argument passing.
*/
-static int __bpf_fill_alu_imm_regs(struct bpf_test *self, u8 op, bool alu32)
+static int __bpf_fill_alu_imm_regs(struct bpf_test *self, u8 op,
+ u32 flags)
{
int len = 2 + 10 * 10;
struct bpf_insn *insns;
return -ENOMEM;
/* Operand and result values according to operation */
- if (alu32)
- dst = 0x76543210U;
- else
- dst = 0x7edcba9876543210ULL;
+ if (flags & F_SIGNED) {
+ if (flags & F_ALU32)
+ dst = -76543210;
+ else
+ dst = -7654321076543210LL;
+ } else {
+ if (flags & F_ALU32)
+ dst = 0x76543210U;
+ else
+ dst = 0x7edcba9876543210ULL;
+ }
imm = 0x01234567U;
if (op == BPF_LSH || op == BPF_RSH || op == BPF_ARSH)
imm &= 31;
- __bpf_alu_result(&res, dst, imm, op);
+ __bpf_alu_result(&res, dst, imm, op, flags);
- if (alu32)
+ if (flags & F_ALU32)
res = (u32)res;
/* Check all operand registers */
for (rd = R0; rd <= R9; rd++) {
i += __bpf_ld_imm64(&insns[i], rd, dst);
- if (alu32)
- insns[i++] = BPF_ALU32_IMM(op, rd, imm);
+ s16 off = (flags & F_SIGNED) ? 1 : 0;
+
+ if (flags & F_ALU32)
+ insns[i++] = BPF_ALU32_IMM_OFF(op, rd, imm, off);
else
- insns[i++] = BPF_ALU64_IMM(op, rd, imm);
+ insns[i++] = BPF_ALU64_IMM_OFF(op, rd, imm, off);
insns[i++] = BPF_JMP32_IMM(BPF_JEQ, rd, res, 2);
insns[i++] = BPF_MOV64_IMM(R0, __LINE__);
/* ALU64 K registers */
static int bpf_fill_alu64_mov_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_MOV, false);
+ return __bpf_fill_alu_imm_regs(self, BPF_MOV, 0);
}
static int bpf_fill_alu64_and_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_AND, false);
+ return __bpf_fill_alu_imm_regs(self, BPF_AND, 0);
}
static int bpf_fill_alu64_or_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_OR, false);
+ return __bpf_fill_alu_imm_regs(self, BPF_OR, 0);
}
static int bpf_fill_alu64_xor_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_XOR, false);
+ return __bpf_fill_alu_imm_regs(self, BPF_XOR, 0);
}
static int bpf_fill_alu64_lsh_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_LSH, false);
+ return __bpf_fill_alu_imm_regs(self, BPF_LSH, 0);
}
static int bpf_fill_alu64_rsh_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_RSH, false);
+ return __bpf_fill_alu_imm_regs(self, BPF_RSH, 0);
}
static int bpf_fill_alu64_arsh_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_ARSH, false);
+ return __bpf_fill_alu_imm_regs(self, BPF_ARSH, 0);
}
static int bpf_fill_alu64_add_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_ADD, false);
+ return __bpf_fill_alu_imm_regs(self, BPF_ADD, 0);
}
static int bpf_fill_alu64_sub_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_SUB, false);
+ return __bpf_fill_alu_imm_regs(self, BPF_SUB, 0);
}
static int bpf_fill_alu64_mul_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_MUL, false);
+ return __bpf_fill_alu_imm_regs(self, BPF_MUL, 0);
}
static int bpf_fill_alu64_div_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_DIV, false);
+ return __bpf_fill_alu_imm_regs(self, BPF_DIV, 0);
}
static int bpf_fill_alu64_mod_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_MOD, false);
+ return __bpf_fill_alu_imm_regs(self, BPF_MOD, 0);
+}
+
+/* Signed ALU64 K registers */
+static int bpf_fill_alu64_sdiv_imm_regs(struct bpf_test *self)
+{
+ return __bpf_fill_alu_imm_regs(self, BPF_DIV, F_SIGNED);
+}
+
+static int bpf_fill_alu64_smod_imm_regs(struct bpf_test *self)
+{
+ return __bpf_fill_alu_imm_regs(self, BPF_MOD, F_SIGNED);
}
/* ALU32 K registers */
static int bpf_fill_alu32_mov_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_MOV, true);
+ return __bpf_fill_alu_imm_regs(self, BPF_MOV, F_ALU32);
}
static int bpf_fill_alu32_and_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_AND, true);
+ return __bpf_fill_alu_imm_regs(self, BPF_AND, F_ALU32);
}
static int bpf_fill_alu32_or_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_OR, true);
+ return __bpf_fill_alu_imm_regs(self, BPF_OR, F_ALU32);
}
static int bpf_fill_alu32_xor_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_XOR, true);
+ return __bpf_fill_alu_imm_regs(self, BPF_XOR, F_ALU32);
}
static int bpf_fill_alu32_lsh_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_LSH, true);
+ return __bpf_fill_alu_imm_regs(self, BPF_LSH, F_ALU32);
}
static int bpf_fill_alu32_rsh_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_RSH, true);
+ return __bpf_fill_alu_imm_regs(self, BPF_RSH, F_ALU32);
}
static int bpf_fill_alu32_arsh_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_ARSH, true);
+ return __bpf_fill_alu_imm_regs(self, BPF_ARSH, F_ALU32);
}
static int bpf_fill_alu32_add_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_ADD, true);
+ return __bpf_fill_alu_imm_regs(self, BPF_ADD, F_ALU32);
}
static int bpf_fill_alu32_sub_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_SUB, true);
+ return __bpf_fill_alu_imm_regs(self, BPF_SUB, F_ALU32);
}
static int bpf_fill_alu32_mul_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_MUL, true);
+ return __bpf_fill_alu_imm_regs(self, BPF_MUL, F_ALU32);
}
static int bpf_fill_alu32_div_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_DIV, true);
+ return __bpf_fill_alu_imm_regs(self, BPF_DIV, F_ALU32);
}
static int bpf_fill_alu32_mod_imm_regs(struct bpf_test *self)
{
- return __bpf_fill_alu_imm_regs(self, BPF_MOD, true);
+ return __bpf_fill_alu_imm_regs(self, BPF_MOD, F_ALU32);
+}
+
+/* Signed ALU32 K registers */
+static int bpf_fill_alu32_sdiv_imm_regs(struct bpf_test *self)
+{
+ return __bpf_fill_alu_imm_regs(self, BPF_DIV, F_ALU32 | F_SIGNED);
+}
+
+static int bpf_fill_alu32_smod_imm_regs(struct bpf_test *self)
+{
+ return __bpf_fill_alu_imm_regs(self, BPF_MOD, F_ALU32 | F_SIGNED);
}
/*
if (op == BPF_LSH || op == BPF_RSH || op == BPF_ARSH)
src &= 31;
- __bpf_alu_result(&res, dst, src, op);
- __bpf_alu_result(&same, src, src, op);
+ __bpf_alu_result(&res, dst, src, op, 0);
+ __bpf_alu_result(&same, src, src, op, 0);
if (alu32) {
res = (u32)res;
res = src;
break;
default:
- __bpf_alu_result(&res, dst, src, BPF_OP(op));
+ __bpf_alu_result(&res, dst, src, BPF_OP(op), 0);
}
keep = 0x0123456789abcdefULL;
res = src;
break;
default:
- __bpf_alu_result(&res, (u32)dst, (u32)src, BPF_OP(op));
+ __bpf_alu_result(&res, (u32)dst, (u32)src, BPF_OP(op), 0);
}
keep = 0x0123456789abcdefULL;
res = mem;
break;
default:
- __bpf_alu_result(&res, mem, upd, BPF_OP(op));
+ __bpf_alu_result(&res, mem, upd, BPF_OP(op), 0);
}
/* Test all operand registers */
{ { 0, 1 } },
.fill_helper = bpf_fill_alu64_mod_imm_regs,
},
+ {
+ "ALU64_SDIV_K: registers",
+ { },
+ INTERNAL,
+ { },
+ { { 0, 1 } },
+ .fill_helper = bpf_fill_alu64_sdiv_imm_regs,
+ },
+ {
+ "ALU64_SMOD_K: registers",
+ { },
+ INTERNAL,
+ { },
+ { { 0, 1 } },
+ .fill_helper = bpf_fill_alu64_smod_imm_regs,
+ },
/* ALU32 K registers */
{
"ALU32_MOV_K: registers",
{ { 0, 1 } },
.fill_helper = bpf_fill_alu32_mod_imm_regs,
},
+ {
+ "ALU32_SDIV_K: registers",
+ { },
+ INTERNAL,
+ { },
+ { { 0, 1 } },
+ .fill_helper = bpf_fill_alu32_sdiv_imm_regs,
+ },
+ {
+ "ALU32_SMOD_K: registers",
+ { },
+ INTERNAL,
+ { },
+ { { 0, 1 } },
+ .fill_helper = bpf_fill_alu32_smod_imm_regs,
+ },
/* ALU64 X register combinations */
{
"ALU64_MOV_X: register combinations",
.fill_helper = bpf_fill_alu64_mod_imm,
.nr_testruns = NR_PATTERN_RUNS,
},
+ {
+ "ALU64_SDIV_K: all immediate value magnitudes",
+ { },
+ INTERNAL | FLAG_NO_DATA,
+ { },
+ { { 0, 1 } },
+ .fill_helper = bpf_fill_alu64_sdiv_imm,
+ .nr_testruns = NR_PATTERN_RUNS,
+ },
+ {
+ "ALU64_SMOD_K: all immediate value magnitudes",
+ { },
+ INTERNAL | FLAG_NO_DATA,
+ { },
+ { { 0, 1 } },
+ .fill_helper = bpf_fill_alu64_smod_imm,
+ .nr_testruns = NR_PATTERN_RUNS,
+ },
/* ALU32 immediate magnitudes */
{
"ALU32_MOV_K: all immediate value magnitudes",
.fill_helper = bpf_fill_alu32_mod_imm,
.nr_testruns = NR_PATTERN_RUNS,
},
+ {
+ "ALU32_SDIV_K: all immediate value magnitudes",
+ { },
+ INTERNAL | FLAG_NO_DATA,
+ { },
+ { { 0, 1 } },
+ .fill_helper = bpf_fill_alu32_sdiv_imm,
+ .nr_testruns = NR_PATTERN_RUNS,
+ },
+ {
+ "ALU32_SMOD_K: all immediate value magnitudes",
+ { },
+ INTERNAL | FLAG_NO_DATA,
+ { },
+ { { 0, 1 } },
+ .fill_helper = bpf_fill_alu32_smod_imm,
+ .nr_testruns = NR_PATTERN_RUNS,
+ },
/* ALU64 register magnitudes */
{
"ALU64_MOV_X: all register value magnitudes",