]> Git Repo - linux.git/commitdiff
Merge tag 'mips_5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
authorLinus Torvalds <[email protected]>
Wed, 8 May 2019 23:41:47 +0000 (16:41 -0700)
committerLinus Torvalds <[email protected]>
Wed, 8 May 2019 23:41:47 +0000 (16:41 -0700)
Pull MIPS updates from Paul Burton:

 - A set of memblock initialization improvements thanks to Serge Semin,
   tidying up after our conversion from bootmem to memblock back in
   v4.20.

 - Our eBPF JIT the previously supported only MIPS64r2 through MIPS64r5
   is improved to also support MIPS64r6. Support for MIPS32 systems is
   introduced, with the caveat that it only works for programs that
   don't use 64 bit registers or operations - those will bail out & need
   to be interpreted.

 - Improvements to the allocation & configuration of our exception
   vector that should fix issues seen on some platforms using recent
   versions of U-Boot.

 - Some minor improvements to code generated for jump labels, along with
   enabling them by default for generic kernels.

* tag 'mips_5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: (27 commits)
  mips: Manually call fdt_init_reserved_mem() method
  mips: Make sure dt memory regions are valid
  mips: Perform early low memory test
  mips: Dump memblock regions for debugging
  mips: Add reserve-nomap memory type support
  mips: Use memblock to reserve the __nosave memory range
  mips: Discard post-CMA-init foreach loop
  mips: Reserve memory for the kernel image resources
  MIPS: Remove duplicate EBase configuration
  MIPS: Sync icache for whole exception vector
  MIPS: Always allocate exception vector for MIPSr2+
  MIPS: Use memblock_phys_alloc() for exception vector
  mips: Combine memblock init and memory reservation loops
  mips: Discard rudiments from bootmem_init
  mips: Make sure kernel .bss exists in boot mem pool
  mips: vdso: drop unnecessary cc-ldoption
  Revert "MIPS: ralink: fix cpu clock of mt7621 and add dt clk devices"
  MIPS: generic: Enable CONFIG_JUMP_LABEL
  MIPS: jump_label: Use compact branches for >= r6
  MIPS: jump_label: Remove redundant nops
  ...

1  2 
arch/mips/Kconfig
arch/mips/net/ebpf_jit.c

diff --combined arch/mips/Kconfig
index b9c48b27162dc111aa6fee50d057f2cc4bee368d,fb8a39d53168c98567434b8a63773c0f4adce2e1..ff8cff9fcf545bba8d9026aced13af4a804da07a
@@@ -44,8 -44,7 +44,7 @@@ config MIP
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_TRACEHOOK
        select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT
-       select HAVE_CBPF_JIT if (!64BIT && !CPU_MICROMIPS)
-       select HAVE_EBPF_JIT if (64BIT && !CPU_MICROMIPS)
+       select HAVE_EBPF_JIT if (!CPU_MICROMIPS)
        select HAVE_CONTEXT_TRACKING
        select HAVE_COPY_THREAD_TLS
        select HAVE_C_RECORDMCOUNT
@@@ -276,7 -275,7 +275,7 @@@ config BCM47X
        select BCM47XX_SPROM
        select BCM47XX_SSB if !BCM47XX_BCMA
        help
-        Support for BCM47XX based boards
+         Support for BCM47XX based boards
  
  config BCM63XX
        bool "Broadcom BCM63XX based boards"
        select MIPS_L1_CACHE_SHIFT_4
        select CLKDEV_LOOKUP
        help
-        Support for BCM63XX based boards
+         Support for BCM63XX based boards
  
  config MIPS_COBALT
        bool "Cobalt Server"
@@@ -374,10 -373,10 +373,10 @@@ config MACH_JAZ
        select SYS_SUPPORTS_64BIT_KERNEL
        select SYS_SUPPORTS_100HZ
        help
-        This a family of machines based on the MIPS R4030 chipset which was
-        used by several vendors to build RISC/os and Windows NT workstations.
-        Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and
-        Olivetti M700-10 workstations.
+         This a family of machines based on the MIPS R4030 chipset which was
+         used by several vendors to build RISC/os and Windows NT workstations.
+         Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and
+         Olivetti M700-10 workstations.
  
  config MACH_INGENIC
        bool "Ingenic SoC based machines"
@@@ -573,14 -572,14 +572,14 @@@ config NXP_STB22
        bool "NXP STB220 board"
        select SOC_PNX833X
        help
-        Support for NXP Semiconductors STB220 Development Board.
+         Support for NXP Semiconductors STB220 Development Board.
  
  config NXP_STB225
        bool "NXP 225 board"
        select SOC_PNX833X
        select SOC_PNX8335
        help
-        Support for NXP Semiconductors STB225 Development Board.
+         Support for NXP Semiconductors STB225 Development Board.
  
  config PMC_MSP
        bool "PMC-Sierra MSP chipsets"
@@@ -722,9 -721,9 +721,9 @@@ config SGI_IP2
        select SYS_SUPPORTS_64BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
        select MIPS_L1_CACHE_SHIFT_7
-       help
-         This is the SGI Indigo2 with R10000 processor.  To compile a Linux
-         kernel that runs on these, say Y here.
+       help
+         This is the SGI Indigo2 with R10000 processor.  To compile a Linux
+         kernel that runs on these, say Y here.
  
  config SGI_IP32
        bool "SGI IP32 (O2)"
@@@ -1037,6 -1036,13 +1036,6 @@@ source "arch/mips/paravirt/Kconfig
  
  endmenu
  
 -config RWSEM_GENERIC_SPINLOCK
 -      bool
 -      default y
 -
 -config RWSEM_XCHGADD_ALGORITHM
 -      bool
 -
  config GENERIC_HWEIGHT
        bool
        default y
@@@ -1168,9 -1174,9 +1167,9 @@@ config HOLES_IN_ZON
  config SYS_SUPPORTS_RELOCATABLE
        bool
        help
-        Selected if the platform supports relocating the kernel.
-        The platform must provide plat_get_fdt() if it selects CONFIG_USE_OF
-        to allow access to command line and entropy sources.
+         Selected if the platform supports relocating the kernel.
+         The platform must provide plat_get_fdt() if it selects CONFIG_USE_OF
+         to allow access to command line and entropy sources.
  
  config MIPS_CBPF_JIT
        def_bool y
@@@ -2113,8 -2119,8 +2112,8 @@@ config MIPS_PGD_C0_CONTEX
  # Set to y for ptrace access to watch registers.
  #
  config HARDWARE_WATCHPOINTS
-        bool
-        default y if CPU_MIPSR1 || CPU_MIPSR2 || CPU_MIPSR6
+       bool
+       default y if CPU_MIPSR1 || CPU_MIPSR2 || CPU_MIPSR6
  
  menu "Kernel type"
  
@@@ -2178,10 -2184,10 +2177,10 @@@ config PAGE_SIZE_4K
        bool "4kB"
        depends on !CPU_LOONGSON2 && !CPU_LOONGSON3
        help
-        This option select the standard 4kB Linux page size.  On some
-        R3000-family processors this is the only available page size.  Using
-        4kB page size will minimize memory consumption and is therefore
-        recommended for low memory systems.
+         This option select the standard 4kB Linux page size.  On some
+         R3000-family processors this is the only available page size.  Using
+         4kB page size will minimize memory consumption and is therefore
+         recommended for low memory systems.
  
  config PAGE_SIZE_8KB
        bool "8kB"
@@@ -2474,7 -2480,6 +2473,6 @@@ config SB1_PASS_2_1_WORKAROUND
        depends on CPU_SB1 && CPU_SB1_PASS_2
        default y
  
  choice
        prompt "SmartMIPS or microMIPS ASE support"
  
@@@ -2682,16 -2687,16 +2680,16 @@@ config RANDOMIZE_BAS
        bool "Randomize the address of the kernel image"
        depends on RELOCATABLE
        ---help---
-          Randomizes the physical and virtual address at which the
-          kernel image is loaded, as a security feature that
-          deters exploit attempts relying on knowledge of the location
-          of kernel internals.
+         Randomizes the physical and virtual address at which the
+         kernel image is loaded, as a security feature that
+         deters exploit attempts relying on knowledge of the location
+         of kernel internals.
  
-          Entropy is generated using any coprocessor 0 registers available.
+         Entropy is generated using any coprocessor 0 registers available.
  
-          The kernel will be offset by up to RANDOMIZE_BASE_MAX_OFFSET.
+         The kernel will be offset by up to RANDOMIZE_BASE_MAX_OFFSET.
  
-          If unsure, say N.
+         If unsure, say N.
  
  config RANDOMIZE_BASE_MAX_OFFSET
        hex "Maximum kASLR offset" if EXPERT
@@@ -2821,7 -2826,7 +2819,7 @@@ choic
        prompt "Timer frequency"
        default HZ_250
        help
-        Allows the configuration of the timer frequency.
+         Allows the configuration of the timer frequency.
  
        config HZ_24
                bool "24 HZ" if SYS_SUPPORTS_24HZ || SYS_SUPPORTS_ARBIT_HZ
@@@ -3121,10 -3126,10 +3119,10 @@@ config ARCH_MMAP_RND_BITS_MA
        default 15
  
  config ARCH_MMAP_RND_COMPAT_BITS_MIN
-        default 8
+       default 8
  
  config ARCH_MMAP_RND_COMPAT_BITS_MAX
-        default 15
+       default 15
  
  config I8253
        bool
diff --combined arch/mips/net/ebpf_jit.c
index 98bf0c222b5fe84c2086a8707172392323829d57,3548a69c82f790ab7cf41ac5ab2e0326490b2374..dfd5a4b1b779730341e1e373d95951f88a301ad7
@@@ -22,6 -22,7 +22,7 @@@
  #include <asm/byteorder.h>
  #include <asm/cacheflush.h>
  #include <asm/cpu-features.h>
+ #include <asm/isa-rev.h>
  #include <asm/uasm.h>
  
  /* Registers used by JIT */
@@@ -125,15 -126,21 +126,21 @@@ static enum reg_val_type get_reg_val_ty
  }
  
  /* Simply emit the instruction if the JIT memory space has been allocated */
- #define emit_instr(ctx, func, ...)                    \
- do {                                                  \
-       if ((ctx)->target != NULL) {                    \
-               u32 *p = &(ctx)->target[ctx->idx];      \
-               uasm_i_##func(&p, ##__VA_ARGS__);       \
-       }                                               \
-       (ctx)->idx++;                                   \
+ #define emit_instr_long(ctx, func64, func32, ...)             \
+ do {                                                          \
+       if ((ctx)->target != NULL) {                            \
+               u32 *p = &(ctx)->target[ctx->idx];              \
+               if (IS_ENABLED(CONFIG_64BIT))                   \
+                       uasm_i_##func64(&p, ##__VA_ARGS__);     \
+               else                                            \
+                       uasm_i_##func32(&p, ##__VA_ARGS__);     \
+       }                                                       \
+       (ctx)->idx++;                                           \
  } while (0)
  
+ #define emit_instr(ctx, func, ...)                            \
+       emit_instr_long(ctx, func, func, ##__VA_ARGS__)
  static unsigned int j_target(struct jit_ctx *ctx, int target_idx)
  {
        unsigned long target_va, base_va;
@@@ -186,9 -193,8 +193,9 @@@ enum which_ebpf_reg 
   * separate frame pointer, so BPF_REG_10 relative accesses are
   * adjusted to be $sp relative.
   */
 -int ebpf_to_mips_reg(struct jit_ctx *ctx, const struct bpf_insn *insn,
 -                   enum which_ebpf_reg w)
 +static int ebpf_to_mips_reg(struct jit_ctx *ctx,
 +                          const struct bpf_insn *insn,
 +                          enum which_ebpf_reg w)
  {
        int ebpf_reg = (w == src_reg || w == src_reg_no_fp) ?
                insn->src_reg : insn->dst_reg;
@@@ -274,17 -280,17 +281,17 @@@ static int gen_int_prologue(struct jit_
                 * If RA we are doing a function call and may need
                 * extra 8-byte tmp area.
                 */
-               stack_adjust += 16;
+               stack_adjust += 2 * sizeof(long);
        if (ctx->flags & EBPF_SAVE_S0)
-               stack_adjust += 8;
+               stack_adjust += sizeof(long);
        if (ctx->flags & EBPF_SAVE_S1)
-               stack_adjust += 8;
+               stack_adjust += sizeof(long);
        if (ctx->flags & EBPF_SAVE_S2)
-               stack_adjust += 8;
+               stack_adjust += sizeof(long);
        if (ctx->flags & EBPF_SAVE_S3)
-               stack_adjust += 8;
+               stack_adjust += sizeof(long);
        if (ctx->flags & EBPF_SAVE_S4)
-               stack_adjust += 8;
+               stack_adjust += sizeof(long);
  
        BUILD_BUG_ON(MAX_BPF_STACK & 7);
        locals_size = (ctx->flags & EBPF_SEEN_FP) ? MAX_BPF_STACK : 0;
         * On tail call we skip this instruction, and the TCC is
         * passed in $v1 from the caller.
         */
-       emit_instr(ctx, daddiu, MIPS_R_V1, MIPS_R_ZERO, MAX_TAIL_CALL_CNT);
+       emit_instr(ctx, addiu, MIPS_R_V1, MIPS_R_ZERO, MAX_TAIL_CALL_CNT);
        if (stack_adjust)
-               emit_instr(ctx, daddiu, MIPS_R_SP, MIPS_R_SP, -stack_adjust);
+               emit_instr_long(ctx, daddiu, addiu,
+                                       MIPS_R_SP, MIPS_R_SP, -stack_adjust);
        else
                return 0;
  
-       store_offset = stack_adjust - 8;
+       store_offset = stack_adjust - sizeof(long);
  
        if (ctx->flags & EBPF_SAVE_RA) {
-               emit_instr(ctx, sd, MIPS_R_RA, store_offset, MIPS_R_SP);
-               store_offset -= 8;
+               emit_instr_long(ctx, sd, sw,
+                                       MIPS_R_RA, store_offset, MIPS_R_SP);
+               store_offset -= sizeof(long);
        }
        if (ctx->flags & EBPF_SAVE_S0) {
-               emit_instr(ctx, sd, MIPS_R_S0, store_offset, MIPS_R_SP);
-               store_offset -= 8;
+               emit_instr_long(ctx, sd, sw,
+                                       MIPS_R_S0, store_offset, MIPS_R_SP);
+               store_offset -= sizeof(long);
        }
        if (ctx->flags & EBPF_SAVE_S1) {
-               emit_instr(ctx, sd, MIPS_R_S1, store_offset, MIPS_R_SP);
-               store_offset -= 8;
+               emit_instr_long(ctx, sd, sw,
+                                       MIPS_R_S1, store_offset, MIPS_R_SP);
+               store_offset -= sizeof(long);
        }
        if (ctx->flags & EBPF_SAVE_S2) {
-               emit_instr(ctx, sd, MIPS_R_S2, store_offset, MIPS_R_SP);
-               store_offset -= 8;
+               emit_instr_long(ctx, sd, sw,
+                                       MIPS_R_S2, store_offset, MIPS_R_SP);
+               store_offset -= sizeof(long);
        }
        if (ctx->flags & EBPF_SAVE_S3) {
-               emit_instr(ctx, sd, MIPS_R_S3, store_offset, MIPS_R_SP);
-               store_offset -= 8;
+               emit_instr_long(ctx, sd, sw,
+                                       MIPS_R_S3, store_offset, MIPS_R_SP);
+               store_offset -= sizeof(long);
        }
        if (ctx->flags & EBPF_SAVE_S4) {
-               emit_instr(ctx, sd, MIPS_R_S4, store_offset, MIPS_R_SP);
-               store_offset -= 8;
+               emit_instr_long(ctx, sd, sw,
+                                       MIPS_R_S4, store_offset, MIPS_R_SP);
+               store_offset -= sizeof(long);
        }
  
        if ((ctx->flags & EBPF_SEEN_TC) && !(ctx->flags & EBPF_TCC_IN_V1))
-               emit_instr(ctx, daddu, MIPS_R_S4, MIPS_R_V1, MIPS_R_ZERO);
+               emit_instr_long(ctx, daddu, addu,
+                                       MIPS_R_S4, MIPS_R_V1, MIPS_R_ZERO);
  
        return 0;
  }
@@@ -341,7 -355,7 +356,7 @@@ static int build_int_epilogue(struct ji
  {
        const struct bpf_prog *prog = ctx->skf;
        int stack_adjust = ctx->stack_size;
-       int store_offset = stack_adjust - 8;
+       int store_offset = stack_adjust - sizeof(long);
        enum reg_val_type td;
        int r0 = MIPS_R_V0;
  
        }
  
        if (ctx->flags & EBPF_SAVE_RA) {
-               emit_instr(ctx, ld, MIPS_R_RA, store_offset, MIPS_R_SP);
-               store_offset -= 8;
+               emit_instr_long(ctx, ld, lw,
+                                       MIPS_R_RA, store_offset, MIPS_R_SP);
+               store_offset -= sizeof(long);
        }
        if (ctx->flags & EBPF_SAVE_S0) {
-               emit_instr(ctx, ld, MIPS_R_S0, store_offset, MIPS_R_SP);
-               store_offset -= 8;
+               emit_instr_long(ctx, ld, lw,
+                                       MIPS_R_S0, store_offset, MIPS_R_SP);
+               store_offset -= sizeof(long);
        }
        if (ctx->flags & EBPF_SAVE_S1) {
-               emit_instr(ctx, ld, MIPS_R_S1, store_offset, MIPS_R_SP);
-               store_offset -= 8;
+               emit_instr_long(ctx, ld, lw,
+                                       MIPS_R_S1, store_offset, MIPS_R_SP);
+               store_offset -= sizeof(long);
        }
        if (ctx->flags & EBPF_SAVE_S2) {
-               emit_instr(ctx, ld, MIPS_R_S2, store_offset, MIPS_R_SP);
-               store_offset -= 8;
+               emit_instr_long(ctx, ld, lw,
+                               MIPS_R_S2, store_offset, MIPS_R_SP);
+               store_offset -= sizeof(long);
        }
        if (ctx->flags & EBPF_SAVE_S3) {
-               emit_instr(ctx, ld, MIPS_R_S3, store_offset, MIPS_R_SP);
-               store_offset -= 8;
+               emit_instr_long(ctx, ld, lw,
+                                       MIPS_R_S3, store_offset, MIPS_R_SP);
+               store_offset -= sizeof(long);
        }
        if (ctx->flags & EBPF_SAVE_S4) {
-               emit_instr(ctx, ld, MIPS_R_S4, store_offset, MIPS_R_SP);
-               store_offset -= 8;
+               emit_instr_long(ctx, ld, lw,
+                                       MIPS_R_S4, store_offset, MIPS_R_SP);
+               store_offset -= sizeof(long);
        }
        emit_instr(ctx, jr, dest_reg);
  
        if (stack_adjust)
-               emit_instr(ctx, daddiu, MIPS_R_SP, MIPS_R_SP, stack_adjust);
+               emit_instr_long(ctx, daddiu, addiu,
+                                       MIPS_R_SP, MIPS_R_SP, stack_adjust);
        else
                emit_instr(ctx, nop);
  
@@@ -646,6 -667,10 +668,10 @@@ static int build_one_insn(const struct 
        s64 t64s;
        int bpf_op = BPF_OP(insn->code);
  
+       if (IS_ENABLED(CONFIG_32BIT) && ((BPF_CLASS(insn->code) == BPF_ALU64)
+                                               || (bpf_op == BPF_DW)))
+               return -EINVAL;
        switch (insn->code) {
        case BPF_ALU64 | BPF_ADD | BPF_K: /* ALU64_IMM */
        case BPF_ALU64 | BPF_SUB | BPF_K: /* ALU64_IMM */
                if (insn->imm == 1) /* Mult by 1 is a nop */
                        break;
                gen_imm_to_reg(insn, MIPS_R_AT, ctx);
-               emit_instr(ctx, dmultu, MIPS_R_AT, dst);
-               emit_instr(ctx, mflo, dst);
+               if (MIPS_ISA_REV >= 6) {
+                       emit_instr(ctx, dmulu, dst, dst, MIPS_R_AT);
+               } else {
+                       emit_instr(ctx, dmultu, MIPS_R_AT, dst);
+                       emit_instr(ctx, mflo, dst);
+               }
                break;
        case BPF_ALU64 | BPF_NEG | BPF_K: /* ALU64_IMM */
                dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
                if (insn->imm == 1) /* Mult by 1 is a nop */
                        break;
                gen_imm_to_reg(insn, MIPS_R_AT, ctx);
-               emit_instr(ctx, multu, dst, MIPS_R_AT);
-               emit_instr(ctx, mflo, dst);
+               if (MIPS_ISA_REV >= 6) {
+                       emit_instr(ctx, mulu, dst, dst, MIPS_R_AT);
+               } else {
+                       emit_instr(ctx, multu, dst, MIPS_R_AT);
+                       emit_instr(ctx, mflo, dst);
+               }
                break;
        case BPF_ALU | BPF_NEG | BPF_K: /* ALU_IMM */
                dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
                        break;
                }
                gen_imm_to_reg(insn, MIPS_R_AT, ctx);
+               if (MIPS_ISA_REV >= 6) {
+                       if (bpf_op == BPF_DIV)
+                               emit_instr(ctx, divu_r6, dst, dst, MIPS_R_AT);
+                       else
+                               emit_instr(ctx, modu, dst, dst, MIPS_R_AT);
+                       break;
+               }
                emit_instr(ctx, divu, dst, MIPS_R_AT);
                if (bpf_op == BPF_DIV)
                        emit_instr(ctx, mflo, dst);
                        break;
                }
                gen_imm_to_reg(insn, MIPS_R_AT, ctx);
+               if (MIPS_ISA_REV >= 6) {
+                       if (bpf_op == BPF_DIV)
+                               emit_instr(ctx, ddivu_r6, dst, dst, MIPS_R_AT);
+                       else
+                               emit_instr(ctx, modu, dst, dst, MIPS_R_AT);
+                       break;
+               }
                emit_instr(ctx, ddivu, dst, MIPS_R_AT);
                if (bpf_op == BPF_DIV)
                        emit_instr(ctx, mflo, dst);
                        emit_instr(ctx, and, dst, dst, src);
                        break;
                case BPF_MUL:
-                       emit_instr(ctx, dmultu, dst, src);
-                       emit_instr(ctx, mflo, dst);
+                       if (MIPS_ISA_REV >= 6) {
+                               emit_instr(ctx, dmulu, dst, dst, src);
+                       } else {
+                               emit_instr(ctx, dmultu, dst, src);
+                               emit_instr(ctx, mflo, dst);
+                       }
                        break;
                case BPF_DIV:
                case BPF_MOD:
+                       if (MIPS_ISA_REV >= 6) {
+                               if (bpf_op == BPF_DIV)
+                                       emit_instr(ctx, ddivu_r6,
+                                                       dst, dst, src);
+                               else
+                                       emit_instr(ctx, modu, dst, dst, src);
+                               break;
+                       }
                        emit_instr(ctx, ddivu, dst, src);
                        if (bpf_op == BPF_DIV)
                                emit_instr(ctx, mflo, dst);
                        break;
                case BPF_DIV:
                case BPF_MOD:
+                       if (MIPS_ISA_REV >= 6) {
+                               if (bpf_op == BPF_DIV)
+                                       emit_instr(ctx, divu_r6, dst, dst, src);
+                               else
+                                       emit_instr(ctx, modu, dst, dst, src);
+                               break;
+                       }
                        emit_instr(ctx, divu, dst, src);
                        if (bpf_op == BPF_DIV)
                                emit_instr(ctx, mflo, dst);
                        emit_instr(ctx, dsubu, MIPS_R_T8, dst, src);
                        emit_instr(ctx, sltu, MIPS_R_AT, dst, src);
                        /* SP known to be non-zero, movz becomes boolean not */
-                       emit_instr(ctx, movz, MIPS_R_T9, MIPS_R_SP, MIPS_R_T8);
-                       emit_instr(ctx, movn, MIPS_R_T9, MIPS_R_ZERO, MIPS_R_T8);
+                       if (MIPS_ISA_REV >= 6) {
+                               emit_instr(ctx, seleqz, MIPS_R_T9,
+                                               MIPS_R_SP, MIPS_R_T8);
+                       } else {
+                               emit_instr(ctx, movz, MIPS_R_T9,
+                                               MIPS_R_SP, MIPS_R_T8);
+                               emit_instr(ctx, movn, MIPS_R_T9,
+                                               MIPS_R_ZERO, MIPS_R_T8);
+                       }
                        emit_instr(ctx, or, MIPS_R_AT, MIPS_R_T9, MIPS_R_AT);
                        cmp_eq = bpf_op == BPF_JGT;
                        dst = MIPS_R_AT;
@@@ -1235,7 -1308,7 +1309,7 @@@ jeq_common
  
        case BPF_JMP | BPF_CALL:
                ctx->flags |= EBPF_SAVE_RA;
-               t64s = (s64)insn->imm + (s64)__bpf_call_base;
+               t64s = (s64)insn->imm + (long)__bpf_call_base;
                emit_const_to_reg(ctx, MIPS_R_T9, (u64)t64s);
                emit_instr(ctx, jalr, MIPS_R_RA, MIPS_R_T9);
                /* delay slot */
                if (src < 0)
                        return src;
                if (BPF_MODE(insn->code) == BPF_XADD) {
+                       /*
+                        * If mem_off does not fit within the 9 bit ll/sc
+                        * instruction immediate field, use a temp reg.
+                        */
+                       if (MIPS_ISA_REV >= 6 &&
+                           (mem_off >= BIT(8) || mem_off < -BIT(8))) {
+                               emit_instr(ctx, daddiu, MIPS_R_T6,
+                                               dst, mem_off);
+                               mem_off = 0;
+                               dst = MIPS_R_T6;
+                       }
                        switch (BPF_SIZE(insn->code)) {
                        case BPF_W:
                                if (get_reg_val_type(ctx, this_idx, insn->src_reg) == REG_32BIT) {
@@@ -1721,7 -1805,7 +1806,7 @@@ struct bpf_prog *bpf_int_jit_compile(st
        unsigned int image_size;
        u8 *image_ptr;
  
-       if (!prog->jit_requested || !cpu_has_mips64r2)
+       if (!prog->jit_requested || MIPS_ISA_REV < 2)
                return prog;
  
        tmp = bpf_jit_blind_constants(prog);
This page took 0.085517 seconds and 4 git commands to generate.