s390/bpf: Fix sign extension in branch_ku
Both signed and unsigned variants of BPF_JMP | BPF_K require
sign-extending the immediate. JIT emits cgfi for the signed case,
which is correct, and clgfi for the unsigned case, which is not
correct: clgfi zero-extends the immediate.
s390 does not provide an instruction that does sign-extension and
unsigned comparison at the same time. Therefore, fix by first loading
the sign-extended immediate into work register REG_1 and proceeding
as if it's BPF_X.
Fixes: 4e9b4a6883
("s390/bpf: Use relative long branches")
Reported-by: Seth Forshee <seth.forshee@canonical.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Tested-by: Seth Forshee <seth.forshee@canonical.com>
Link: https://lore.kernel.org/bpf/20200717165326.6786-3-iii@linux.ibm.com
This commit is contained in:
Родитель
2ea4859807
Коммит
7477d43be5
|
@ -1417,21 +1417,10 @@ branch_ks:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
branch_ku:
|
branch_ku:
|
||||||
is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32;
|
/* lgfi %w1,imm (load sign extend imm) */
|
||||||
/* clfi or clgfi %dst,imm */
|
src_reg = REG_1;
|
||||||
EMIT6_IMM(is_jmp32 ? 0xc20f0000 : 0xc20e0000,
|
EMIT6_IMM(0xc0010000, src_reg, imm);
|
||||||
dst_reg, imm);
|
goto branch_xu;
|
||||||
if (!is_first_pass(jit) &&
|
|
||||||
can_use_rel(jit, addrs[i + off + 1])) {
|
|
||||||
/* brc mask,off */
|
|
||||||
EMIT4_PCREL_RIC(0xa7040000,
|
|
||||||
mask >> 12, addrs[i + off + 1]);
|
|
||||||
} else {
|
|
||||||
/* brcl mask,off */
|
|
||||||
EMIT6_PCREL_RILC(0xc0040000,
|
|
||||||
mask >> 12, addrs[i + off + 1]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
branch_xs:
|
branch_xs:
|
||||||
is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32;
|
is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32;
|
||||||
if (!is_first_pass(jit) &&
|
if (!is_first_pass(jit) &&
|
||||||
|
|
Загрузка…
Ссылка в новой задаче