• Paul Burton's avatar
    MIPS: BPF: Restore MIPS32 cBPF JIT · 36366e36
    Paul Burton authored
    Commit 716850ab ("MIPS: eBPF: Initial eBPF support for MIPS32
    architecture.") enabled our eBPF JIT for MIPS32 kernels, whereas it has
    previously only been availailable for MIPS64. It was my understanding at
    the time that the BPF test suite was passing & JITing a comparable
    number of tests to our cBPF JIT [1], but it turns out that was not the
    case.
    
    The eBPF JIT has a number of problems on MIPS32:
    
    - Most notably various code paths still result in emission of MIPS64
      instructions which will cause reserved instruction exceptions & kernel
      panics when run on MIPS32 CPUs.
    
    - The eBPF JIT doesn't account for differences between the O32 ABI used
      by MIPS32 kernels versus the N64 ABI used by MIPS64 kernels. Notably
      arguments beyond the first 4 are passed on the stack in O32, and this
      is entirely unhandled when JITing a BPF_CALL instruction. Stack space
      must be reserved for arguments even if they all fit in registers, and
      the callee is free to assume that stack space has been reserved for
      its use - with the eBPF JIT this is not the case, so calling any
      function can result in clobbering values on the stack & unpredictable
      behaviour. Function arguments in eBPF are always 64-bit values which
      is also entirely unhandled - the JIT still uses a single (32-bit)
      register per argument. As a result all function arguments are always
      passed incorrectly when JITing a BPF_CALL instruction, leading to
      kernel crashes or strange behavior.
    
    - The JIT attempts to bail our on use of ALU64 instructions or 64-bit
      memory access instructions. The code doing this at the start of
      build_one_insn() incorrectly checks whether BPF_OP() equals BPF_DW,
      when it should really be checking BPF_SIZE() & only doing so when
      BPF_CLASS() is one of BPF_{LD,LDX,ST,STX}. This results in false
      positives that cause more bailouts than intended, and that in turns
      hides some of the problems described above.
    
    - The kernel's cBPF->eBPF translation makes heavy use of 64-bit eBPF
      instructions that the MIPS32 eBPF JIT bails out on, leading to most
      cBPF programs not being JITed at all.
    
    Until these problems are resolved, revert the removal of the cBPF JIT
    performed by commit 716850ab ("MIPS: eBPF: Initial eBPF support for
    MIPS32 architecture."). Together with commit f8fffebd ("MIPS: BPF:
    Disable MIPS32 eBPF JIT") this restores MIPS32 BPF JIT behavior back to
    the same state it was prior to the introduction of the broken eBPF JIT
    support.
    
    [1] https://lore.kernel.org/linux-mips/MWHPR2201MB13583388481F01A422CE7D66D4410@MWHPR2201MB1358.namprd22.prod.outlook.com/Signed-off-by: default avatarPaul Burton <paulburton@kernel.org>
    Fixes: 716850ab ("MIPS: eBPF: Initial eBPF support for MIPS32 architecture.")
    Cc: Daniel Borkmann <daniel@iogearbox.net>
    Cc: Hassan Naveed <hnaveed@wavecomp.com>
    Cc: Tony Ambardar <itugrok@yahoo.com>
    Cc: bpf@vger.kernel.org
    Cc: netdev@vger.kernel.org
    Cc: linux-mips@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    36366e36
Kconfig 82.2 KB