On 02/21/2018 01:33 AM, Michael Ellerman wrote: > Mark Lord <ml...@pobox.com> writes: > >> I am using SECCOMP to filter syscalls on a ppc32 platform, >> and noticed that the JIT compiler was failing on the BPF >> even though the interpreter was working fine. >> >> The issue was that the compiler was missing one of the instructions >> used by SECCOMP, so here is a patch to enable JIT for that instruction. >> >> Signed-Off-By: Mark Lord <ml...@pobox.com> > > Thanks. > > What is the failure mode without this patch? I assume when you have the > JIT enabled the seccomp filter fails to load entirely? Or do we have > logic to fall back to the interpreter?
The logic for all JITs is that once a BPF insn cannot be JITed then it falls back to BPF interpreter. Here, since ppc32 is cBPF the path is: cBPF insn -> cBPF JIT -> fail -> migrate cBPF to eBPF -> run in eBPF interpreter. In the case where interpreter is compiled out (CONFIG_BPF_JIT_ALWAYS_ON), then the filter is rejected. > Either way we should probably back port to stable. I assume this has > been broken since we originally added 32-bit support, so: Note that arm32 before it was converted to be an eBPF JIT (eBPF JITs do handle seccomp BPF in any case) was the only cBPF JIT that had it 'JIT-able', so currently, other cBPF ones like sparc32 or mips32 don't translate it either. Meaning, it would be nice to have as feature; I wouldn't necessarily frame it as a bug though (or at least a stable-urgent one, imho, but I leave that to you, of course). > Fixes: eb84bab0fb38 ("ppc: Kconfig: Enable BPF JIT on ppc32") > Cc: sta...@vger.kernel.org # v4.1+ > > cheers > > >> --- old/arch/powerpc/net/bpf_jit_comp.c 2018-02-16 14:07:01.000000000 -0500 >> +++ linux/arch/powerpc/net/bpf_jit_comp.c 2018-02-20 >> 14:41:20.805227494 -0500 >> @@ -329,6 +329,9 @@ static int bpf_jit_build_body(struct bpf >> BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); >> PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, >> len)); >> break; >> + case BPF_LDX | BPF_W | BPF_ABS: /* A = *((u32 >> *)(seccomp_data + K)); */ >> + PPC_LWZ_OFFS(r_A, r_skb, K); >> + break; >> case BPF_LDX | BPF_W | BPF_LEN: /* X = skb->len; */ >> PPC_LWZ_OFFS(r_X, r_skb, offsetof(struct sk_buff, >> len)); >> break; >> -- >> Mark Lord >> Real-Time Remedies Inc. >> ml...@pobox.com