mirror of
https://github.com/torvalds/linux.git
synced 2026-05-29 17:43:52 +02:00
s390/bpf: Zero-extend bpf prog return values and kfunc arguments
s390x ABI requires callers to zero-extend unsigned arguments and
sign-extend signed arguments, and callees to zero-extend unsigned
return values and sign-extend signed return values.
s390 BPF JIT currently implements only sign extension. Fix this
omission and implement zero extension too.
Fixes: 528eb2cb87 ("s390/bpf: Implement arch_prepare_bpf_trampoline()")
Reported-by: Hari Bathini <hbathini@linux.ibm.com>
Closes: https://lore.kernel.org/bpf/20260312080113.843408-1-hbathini@linux.ibm.com/
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Tested-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Link: https://lore.kernel.org/r/20260313174807.581826-1-iii@linux.ibm.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
bb41fcef5c
commit
202e42e4aa
|
|
@ -830,25 +830,34 @@ static int bpf_jit_probe_post(struct bpf_jit *jit, struct bpf_prog *fp,
|
|||
}
|
||||
|
||||
/*
|
||||
* Sign-extend the register if necessary
|
||||
* Sign- or zero-extend the register if necessary
|
||||
*/
|
||||
static int sign_extend(struct bpf_jit *jit, int r, u8 size, u8 flags)
|
||||
static int sign_zero_extend(struct bpf_jit *jit, int r, u8 size, u8 flags)
|
||||
{
|
||||
if (!(flags & BTF_FMODEL_SIGNED_ARG))
|
||||
return 0;
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
/* lgbr %r,%r */
|
||||
EMIT4(0xb9060000, r, r);
|
||||
if (flags & BTF_FMODEL_SIGNED_ARG)
|
||||
/* lgbr %r,%r */
|
||||
EMIT4(0xb9060000, r, r);
|
||||
else
|
||||
/* llgcr %r,%r */
|
||||
EMIT4(0xb9840000, r, r);
|
||||
return 0;
|
||||
case 2:
|
||||
/* lghr %r,%r */
|
||||
EMIT4(0xb9070000, r, r);
|
||||
if (flags & BTF_FMODEL_SIGNED_ARG)
|
||||
/* lghr %r,%r */
|
||||
EMIT4(0xb9070000, r, r);
|
||||
else
|
||||
/* llghr %r,%r */
|
||||
EMIT4(0xb9850000, r, r);
|
||||
return 0;
|
||||
case 4:
|
||||
/* lgfr %r,%r */
|
||||
EMIT4(0xb9140000, r, r);
|
||||
if (flags & BTF_FMODEL_SIGNED_ARG)
|
||||
/* lgfr %r,%r */
|
||||
EMIT4(0xb9140000, r, r);
|
||||
else
|
||||
/* llgfr %r,%r */
|
||||
EMIT4(0xb9160000, r, r);
|
||||
return 0;
|
||||
case 8:
|
||||
return 0;
|
||||
|
|
@ -1798,9 +1807,9 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
|
|||
return -1;
|
||||
|
||||
for (j = 0; j < m->nr_args; j++) {
|
||||
if (sign_extend(jit, BPF_REG_1 + j,
|
||||
m->arg_size[j],
|
||||
m->arg_flags[j]))
|
||||
if (sign_zero_extend(jit, BPF_REG_1 + j,
|
||||
m->arg_size[j],
|
||||
m->arg_flags[j]))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -2566,7 +2575,7 @@ static int invoke_bpf_prog(struct bpf_tramp_jit *tjit,
|
|||
EMIT6_PCREL_RILB_PTR(0xc0050000, REG_14, p->bpf_func);
|
||||
/* stg %r2,retval_off(%r15) */
|
||||
if (save_ret) {
|
||||
if (sign_extend(jit, REG_2, m->ret_size, m->ret_flags))
|
||||
if (sign_zero_extend(jit, REG_2, m->ret_size, m->ret_flags))
|
||||
return -1;
|
||||
EMIT6_DISP_LH(0xe3000000, 0x0024, REG_2, REG_0, REG_15,
|
||||
tjit->retval_off);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user