From a4856dab0d7d68b03b4925e8fea183fe788eb7d7 Mon Sep 17 00:00:00 2001 From: Tony Ambardar Date: Wed, 22 Jul 2020 19:40:12 -0700 Subject: [PATCH 01/23] kernel: mips: restore missing MIPS32 cBPF JIT Kernel v5.1 included an eBPF JIT for MIPS32 kernels, but problems were discovered [1] and the changes later reverted in kernel v5.5 with commits: * f8fffebdea75 ("MIPS: BPF: Disable MIPS32 eBPF JIT") * 36366e367ee9 ("MIPS: BPF: Restore MIPS32 cBPF JIT") Only the first of these was backported to LTS kernel 5.4, leaving cBPF programs without a JIT and introducing a performance regression for any such users e.g. libpcap, tcpdump, etc. Restore cBPF performance by backporting the second commit above: * 070-v5.5-MIPS-BPF-Restore-MIPS32-cBPF-JIT.patch [1] https://lore.kernel.org/bpf/20191205182318.2761605-1-paulburton@kernel.org/ Signed-off-by: Tony Ambardar --- ...5.5-MIPS-BPF-Restore-MIPS32-cBPF-JIT.patch | 1663 +++++++++++++++++ 1 file changed, 1663 insertions(+) create mode 100644 target/linux/generic/backport-5.4/070-v5.5-MIPS-BPF-Restore-MIPS32-cBPF-JIT.patch diff --git a/target/linux/generic/backport-5.4/070-v5.5-MIPS-BPF-Restore-MIPS32-cBPF-JIT.patch b/target/linux/generic/backport-5.4/070-v5.5-MIPS-BPF-Restore-MIPS32-cBPF-JIT.patch new file mode 100644 index 0000000000..793c8be24a --- /dev/null +++ b/target/linux/generic/backport-5.4/070-v5.5-MIPS-BPF-Restore-MIPS32-cBPF-JIT.patch @@ -0,0 +1,1663 @@ +From 36366e367ee93ced84fddb8fae6675e12985f5a4 Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Thu, 5 Dec 2019 10:23:18 -0800 +Subject: [PATCH] MIPS: BPF: Restore MIPS32 cBPF JIT + +Commit 716850ab104d ("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 716850ab104d ("MIPS: eBPF: Initial eBPF support for +MIPS32 architecture."). Together with commit f8fffebdea75 ("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: Paul Burton +Fixes: 716850ab104d ("MIPS: eBPF: Initial eBPF support for MIPS32 architecture.") +Cc: Daniel Borkmann +Cc: Hassan Naveed +Cc: Tony Ambardar +Cc: bpf@vger.kernel.org +Cc: netdev@vger.kernel.org +Cc: linux-mips@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +--- + arch/mips/Kconfig | 1 + + arch/mips/net/Makefile | 1 + + arch/mips/net/bpf_jit.c | 1270 +++++++++++++++++++++++++++++++++++ + arch/mips/net/bpf_jit_asm.S | 285 ++++++++ + 4 files changed, 1557 insertions(+) + create mode 100644 arch/mips/net/bpf_jit.c + create mode 100644 arch/mips/net/bpf_jit_asm.S + +diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig +index e5c2d47608fe..33674cdc3aa8 100644 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -46,6 +46,7 @@ config MIPS + select HAVE_ARCH_TRACEHOOK + select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES + select HAVE_ASM_MODVERSIONS ++ select HAVE_CBPF_JIT if !64BIT && !CPU_MICROMIPS + select HAVE_EBPF_JIT if 64BIT && !CPU_MICROMIPS && TARGET_ISA_REV >= 2 + select HAVE_CONTEXT_TRACKING + select HAVE_COPY_THREAD_TLS +diff --git a/arch/mips/net/Makefile b/arch/mips/net/Makefile +index 2d03af7d6b19..d55912349039 100644 +--- a/arch/mips/net/Makefile ++++ b/arch/mips/net/Makefile +@@ -1,4 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0-only + # MIPS networking code + ++obj-$(CONFIG_MIPS_CBPF_JIT) += bpf_jit.o bpf_jit_asm.o + obj-$(CONFIG_MIPS_EBPF_JIT) += ebpf_jit.o +diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c +new file mode 100644 +index 000000000000..3a0e34f4e615 +--- /dev/null ++++ b/arch/mips/net/bpf_jit.c +@@ -0,0 +1,1270 @@ ++/* ++ * Just-In-Time compiler for BPF filters on MIPS ++ * ++ * Copyright (c) 2014 Imagination Technologies Ltd. ++ * Author: Markos Chandras ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; version 2 of the License. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "bpf_jit.h" ++ ++/* ABI ++ * r_skb_hl SKB header length ++ * r_data SKB data pointer ++ * r_off Offset ++ * r_A BPF register A ++ * r_X BPF register X ++ * r_skb *skb ++ * r_M *scratch memory ++ * r_skb_len SKB length ++ * ++ * On entry (*bpf_func)(*skb, *filter) ++ * a0 = MIPS_R_A0 = skb; ++ * a1 = MIPS_R_A1 = filter; ++ * ++ * Stack ++ * ... ++ * M[15] ++ * M[14] ++ * M[13] ++ * ... ++ * M[0] <-- r_M ++ * saved reg k-1 ++ * saved reg k-2 ++ * ... ++ * saved reg 0 <-- r_sp ++ * ++ * ++ * Packet layout ++ * ++ * <--------------------- len ------------------------> ++ * <--skb-len(r_skb_hl)-->< ----- skb->data_len ------> ++ * ---------------------------------------------------- ++ * | skb->data | ++ * ---------------------------------------------------- ++ */ ++ ++#define ptr typeof(unsigned long) ++ ++#define SCRATCH_OFF(k) (4 * (k)) ++ ++/* JIT flags */ ++#define SEEN_CALL (1 << BPF_MEMWORDS) ++#define SEEN_SREG_SFT (BPF_MEMWORDS + 1) ++#define SEEN_SREG_BASE (1 << SEEN_SREG_SFT) ++#define SEEN_SREG(x) (SEEN_SREG_BASE << (x)) ++#define SEEN_OFF SEEN_SREG(2) ++#define SEEN_A SEEN_SREG(3) ++#define SEEN_X SEEN_SREG(4) ++#define SEEN_SKB SEEN_SREG(5) ++#define SEEN_MEM SEEN_SREG(6) ++/* SEEN_SK_DATA also implies skb_hl an skb_len */ ++#define SEEN_SKB_DATA (SEEN_SREG(7) | SEEN_SREG(1) | SEEN_SREG(0)) ++ ++/* Arguments used by JIT */ ++#define ARGS_USED_BY_JIT 2 /* only applicable to 64-bit */ ++ ++#define SBIT(x) (1 << (x)) /* Signed version of BIT() */ ++ ++/** ++ * struct jit_ctx - JIT context ++ * @skf: The sk_filter ++ * @prologue_bytes: Number of bytes for prologue ++ * @idx: Instruction index ++ * @flags: JIT flags ++ * @offsets: Instruction offsets ++ * @target: Memory location for the compiled filter ++ */ ++struct jit_ctx { ++ const struct bpf_prog *skf; ++ unsigned int prologue_bytes; ++ u32 idx; ++ u32 flags; ++ u32 *offsets; ++ u32 *target; ++}; ++ ++ ++static inline int optimize_div(u32 *k) ++{ ++ /* power of 2 divides can be implemented with right shift */ ++ if (!(*k & (*k-1))) { ++ *k = ilog2(*k); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static inline void emit_jit_reg_move(ptr dst, ptr src, struct jit_ctx *ctx); ++ ++/* 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++; \ ++} while (0) ++ ++/* ++ * Similar to emit_instr but it must be used when we need to emit ++ * 32-bit or 64-bit instructions ++ */ ++#define emit_long_instr(ctx, func, ...) \ ++do { \ ++ if ((ctx)->target != NULL) { \ ++ u32 *p = &(ctx)->target[ctx->idx]; \ ++ UASM_i_##func(&p, ##__VA_ARGS__); \ ++ } \ ++ (ctx)->idx++; \ ++} while (0) ++ ++/* Determine if immediate is within the 16-bit signed range */ ++static inline bool is_range16(s32 imm) ++{ ++ return !(imm >= SBIT(15) || imm < -SBIT(15)); ++} ++ ++static inline void emit_addu(unsigned int dst, unsigned int src1, ++ unsigned int src2, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, addu, dst, src1, src2); ++} ++ ++static inline void emit_nop(struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, nop); ++} ++ ++/* Load a u32 immediate to a register */ ++static inline void emit_load_imm(unsigned int dst, u32 imm, struct jit_ctx *ctx) ++{ ++ if (ctx->target != NULL) { ++ /* addiu can only handle s16 */ ++ if (!is_range16(imm)) { ++ u32 *p = &ctx->target[ctx->idx]; ++ uasm_i_lui(&p, r_tmp_imm, (s32)imm >> 16); ++ p = &ctx->target[ctx->idx + 1]; ++ uasm_i_ori(&p, dst, r_tmp_imm, imm & 0xffff); ++ } else { ++ u32 *p = &ctx->target[ctx->idx]; ++ uasm_i_addiu(&p, dst, r_zero, imm); ++ } ++ } ++ ctx->idx++; ++ ++ if (!is_range16(imm)) ++ ctx->idx++; ++} ++ ++static inline void emit_or(unsigned int dst, unsigned int src1, ++ unsigned int src2, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, or, dst, src1, src2); ++} ++ ++static inline void emit_ori(unsigned int dst, unsigned src, u32 imm, ++ struct jit_ctx *ctx) ++{ ++ if (imm >= BIT(16)) { ++ emit_load_imm(r_tmp, imm, ctx); ++ emit_or(dst, src, r_tmp, ctx); ++ } else { ++ emit_instr(ctx, ori, dst, src, imm); ++ } ++} ++ ++static inline void emit_daddiu(unsigned int dst, unsigned int src, ++ int imm, struct jit_ctx *ctx) ++{ ++ /* ++ * Only used for stack, so the imm is relatively small ++ * and it fits in 15-bits ++ */ ++ emit_instr(ctx, daddiu, dst, src, imm); ++} ++ ++static inline void emit_addiu(unsigned int dst, unsigned int src, ++ u32 imm, struct jit_ctx *ctx) ++{ ++ if (!is_range16(imm)) { ++ emit_load_imm(r_tmp, imm, ctx); ++ emit_addu(dst, r_tmp, src, ctx); ++ } else { ++ emit_instr(ctx, addiu, dst, src, imm); ++ } ++} ++ ++static inline void emit_and(unsigned int dst, unsigned int src1, ++ unsigned int src2, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, and, dst, src1, src2); ++} ++ ++static inline void emit_andi(unsigned int dst, unsigned int src, ++ u32 imm, struct jit_ctx *ctx) ++{ ++ /* If imm does not fit in u16 then load it to register */ ++ if (imm >= BIT(16)) { ++ emit_load_imm(r_tmp, imm, ctx); ++ emit_and(dst, src, r_tmp, ctx); ++ } else { ++ emit_instr(ctx, andi, dst, src, imm); ++ } ++} ++ ++static inline void emit_xor(unsigned int dst, unsigned int src1, ++ unsigned int src2, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, xor, dst, src1, src2); ++} ++ ++static inline void emit_xori(ptr dst, ptr src, u32 imm, struct jit_ctx *ctx) ++{ ++ /* If imm does not fit in u16 then load it to register */ ++ if (imm >= BIT(16)) { ++ emit_load_imm(r_tmp, imm, ctx); ++ emit_xor(dst, src, r_tmp, ctx); ++ } else { ++ emit_instr(ctx, xori, dst, src, imm); ++ } ++} ++ ++static inline void emit_stack_offset(int offset, struct jit_ctx *ctx) ++{ ++ emit_long_instr(ctx, ADDIU, r_sp, r_sp, offset); ++} ++ ++static inline void emit_subu(unsigned int dst, unsigned int src1, ++ unsigned int src2, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, subu, dst, src1, src2); ++} ++ ++static inline void emit_neg(unsigned int reg, struct jit_ctx *ctx) ++{ ++ emit_subu(reg, r_zero, reg, ctx); ++} ++ ++static inline void emit_sllv(unsigned int dst, unsigned int src, ++ unsigned int sa, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, sllv, dst, src, sa); ++} ++ ++static inline void emit_sll(unsigned int dst, unsigned int src, ++ unsigned int sa, struct jit_ctx *ctx) ++{ ++ /* sa is 5-bits long */ ++ if (sa >= BIT(5)) ++ /* Shifting >= 32 results in zero */ ++ emit_jit_reg_move(dst, r_zero, ctx); ++ else ++ emit_instr(ctx, sll, dst, src, sa); ++} ++ ++static inline void emit_srlv(unsigned int dst, unsigned int src, ++ unsigned int sa, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, srlv, dst, src, sa); ++} ++ ++static inline void emit_srl(unsigned int dst, unsigned int src, ++ unsigned int sa, struct jit_ctx *ctx) ++{ ++ /* sa is 5-bits long */ ++ if (sa >= BIT(5)) ++ /* Shifting >= 32 results in zero */ ++ emit_jit_reg_move(dst, r_zero, ctx); ++ else ++ emit_instr(ctx, srl, dst, src, sa); ++} ++ ++static inline void emit_slt(unsigned int dst, unsigned int src1, ++ unsigned int src2, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, slt, dst, src1, src2); ++} ++ ++static inline void emit_sltu(unsigned int dst, unsigned int src1, ++ unsigned int src2, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, sltu, dst, src1, src2); ++} ++ ++static inline void emit_sltiu(unsigned dst, unsigned int src, ++ unsigned int imm, struct jit_ctx *ctx) ++{ ++ /* 16 bit immediate */ ++ if (!is_range16((s32)imm)) { ++ emit_load_imm(r_tmp, imm, ctx); ++ emit_sltu(dst, src, r_tmp, ctx); ++ } else { ++ emit_instr(ctx, sltiu, dst, src, imm); ++ } ++ ++} ++ ++/* Store register on the stack */ ++static inline void emit_store_stack_reg(ptr reg, ptr base, ++ unsigned int offset, ++ struct jit_ctx *ctx) ++{ ++ emit_long_instr(ctx, SW, reg, offset, base); ++} ++ ++static inline void emit_store(ptr reg, ptr base, unsigned int offset, ++ struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, sw, reg, offset, base); ++} ++ ++static inline void emit_load_stack_reg(ptr reg, ptr base, ++ unsigned int offset, ++ struct jit_ctx *ctx) ++{ ++ emit_long_instr(ctx, LW, reg, offset, base); ++} ++ ++static inline void emit_load(unsigned int reg, unsigned int base, ++ unsigned int offset, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, lw, reg, offset, base); ++} ++ ++static inline void emit_load_byte(unsigned int reg, unsigned int base, ++ unsigned int offset, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, lb, reg, offset, base); ++} ++ ++static inline void emit_half_load(unsigned int reg, unsigned int base, ++ unsigned int offset, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, lh, reg, offset, base); ++} ++ ++static inline void emit_half_load_unsigned(unsigned int reg, unsigned int base, ++ unsigned int offset, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, lhu, reg, offset, base); ++} ++ ++static inline void emit_mul(unsigned int dst, unsigned int src1, ++ unsigned int src2, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, mul, dst, src1, src2); ++} ++ ++static inline void emit_div(unsigned int dst, unsigned int src, ++ struct jit_ctx *ctx) ++{ ++ if (ctx->target != NULL) { ++ u32 *p = &ctx->target[ctx->idx]; ++ uasm_i_divu(&p, dst, src); ++ p = &ctx->target[ctx->idx + 1]; ++ uasm_i_mflo(&p, dst); ++ } ++ ctx->idx += 2; /* 2 insts */ ++} ++ ++static inline void emit_mod(unsigned int dst, unsigned int src, ++ struct jit_ctx *ctx) ++{ ++ if (ctx->target != NULL) { ++ u32 *p = &ctx->target[ctx->idx]; ++ uasm_i_divu(&p, dst, src); ++ p = &ctx->target[ctx->idx + 1]; ++ uasm_i_mfhi(&p, dst); ++ } ++ ctx->idx += 2; /* 2 insts */ ++} ++ ++static inline void emit_dsll(unsigned int dst, unsigned int src, ++ unsigned int sa, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, dsll, dst, src, sa); ++} ++ ++static inline void emit_dsrl32(unsigned int dst, unsigned int src, ++ unsigned int sa, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, dsrl32, dst, src, sa); ++} ++ ++static inline void emit_wsbh(unsigned int dst, unsigned int src, ++ struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, wsbh, dst, src); ++} ++ ++/* load pointer to register */ ++static inline void emit_load_ptr(unsigned int dst, unsigned int src, ++ int imm, struct jit_ctx *ctx) ++{ ++ /* src contains the base addr of the 32/64-pointer */ ++ emit_long_instr(ctx, LW, dst, imm, src); ++} ++ ++/* load a function pointer to register */ ++static inline void emit_load_func(unsigned int reg, ptr imm, ++ struct jit_ctx *ctx) ++{ ++ if (IS_ENABLED(CONFIG_64BIT)) { ++ /* At this point imm is always 64-bit */ ++ emit_load_imm(r_tmp, (u64)imm >> 32, ctx); ++ emit_dsll(r_tmp_imm, r_tmp, 16, ctx); /* left shift by 16 */ ++ emit_ori(r_tmp, r_tmp_imm, (imm >> 16) & 0xffff, ctx); ++ emit_dsll(r_tmp_imm, r_tmp, 16, ctx); /* left shift by 16 */ ++ emit_ori(reg, r_tmp_imm, imm & 0xffff, ctx); ++ } else { ++ emit_load_imm(reg, imm, ctx); ++ } ++} ++ ++/* Move to real MIPS register */ ++static inline void emit_reg_move(ptr dst, ptr src, struct jit_ctx *ctx) ++{ ++ emit_long_instr(ctx, ADDU, dst, src, r_zero); ++} ++ ++/* Move to JIT (32-bit) register */ ++static inline void emit_jit_reg_move(ptr dst, ptr src, struct jit_ctx *ctx) ++{ ++ emit_addu(dst, src, r_zero, ctx); ++} ++ ++/* Compute the immediate value for PC-relative branches. */ ++static inline u32 b_imm(unsigned int tgt, struct jit_ctx *ctx) ++{ ++ if (ctx->target == NULL) ++ return 0; ++ ++ /* ++ * We want a pc-relative branch. We only do forward branches ++ * so tgt is always after pc. tgt is the instruction offset ++ * we want to jump to. ++ ++ * Branch on MIPS: ++ * I: target_offset <- sign_extend(offset) ++ * I+1: PC += target_offset (delay slot) ++ * ++ * ctx->idx currently points to the branch instruction ++ * but the offset is added to the delay slot so we need ++ * to subtract 4. ++ */ ++ return ctx->offsets[tgt] - ++ (ctx->idx * 4 - ctx->prologue_bytes) - 4; ++} ++ ++static inline void emit_bcond(int cond, unsigned int reg1, unsigned int reg2, ++ unsigned int imm, struct jit_ctx *ctx) ++{ ++ if (ctx->target != NULL) { ++ u32 *p = &ctx->target[ctx->idx]; ++ ++ switch (cond) { ++ case MIPS_COND_EQ: ++ uasm_i_beq(&p, reg1, reg2, imm); ++ break; ++ case MIPS_COND_NE: ++ uasm_i_bne(&p, reg1, reg2, imm); ++ break; ++ case MIPS_COND_ALL: ++ uasm_i_b(&p, imm); ++ break; ++ default: ++ pr_warn("%s: Unhandled branch conditional: %d\n", ++ __func__, cond); ++ } ++ } ++ ctx->idx++; ++} ++ ++static inline void emit_b(unsigned int imm, struct jit_ctx *ctx) ++{ ++ emit_bcond(MIPS_COND_ALL, r_zero, r_zero, imm, ctx); ++} ++ ++static inline void emit_jalr(unsigned int link, unsigned int reg, ++ struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, jalr, link, reg); ++} ++ ++static inline void emit_jr(unsigned int reg, struct jit_ctx *ctx) ++{ ++ emit_instr(ctx, jr, reg); ++} ++ ++static inline u16 align_sp(unsigned int num) ++{ ++ /* Double word alignment for 32-bit, quadword for 64-bit */ ++ unsigned int align = IS_ENABLED(CONFIG_64BIT) ? 16 : 8; ++ num = (num + (align - 1)) & -align; ++ return num; ++} ++ ++static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset) ++{ ++ int i = 0, real_off = 0; ++ u32 sflags, tmp_flags; ++ ++ /* Adjust the stack pointer */ ++ if (offset) ++ emit_stack_offset(-align_sp(offset), ctx); ++ ++ tmp_flags = sflags = ctx->flags >> SEEN_SREG_SFT; ++ /* sflags is essentially a bitmap */ ++ while (tmp_flags) { ++ if ((sflags >> i) & 0x1) { ++ emit_store_stack_reg(MIPS_R_S0 + i, r_sp, real_off, ++ ctx); ++ real_off += SZREG; ++ } ++ i++; ++ tmp_flags >>= 1; ++ } ++ ++ /* save return address */ ++ if (ctx->flags & SEEN_CALL) { ++ emit_store_stack_reg(r_ra, r_sp, real_off, ctx); ++ real_off += SZREG; ++ } ++ ++ /* Setup r_M leaving the alignment gap if necessary */ ++ if (ctx->flags & SEEN_MEM) { ++ if (real_off % (SZREG * 2)) ++ real_off += SZREG; ++ emit_long_instr(ctx, ADDIU, r_M, r_sp, real_off); ++ } ++} ++ ++static void restore_bpf_jit_regs(struct jit_ctx *ctx, ++ unsigned int offset) ++{ ++ int i, real_off = 0; ++ u32 sflags, tmp_flags; ++ ++ tmp_flags = sflags = ctx->flags >> SEEN_SREG_SFT; ++ /* sflags is a bitmap */ ++ i = 0; ++ while (tmp_flags) { ++ if ((sflags >> i) & 0x1) { ++ emit_load_stack_reg(MIPS_R_S0 + i, r_sp, real_off, ++ ctx); ++ real_off += SZREG; ++ } ++ i++; ++ tmp_flags >>= 1; ++ } ++ ++ /* restore return address */ ++ if (ctx->flags & SEEN_CALL) ++ emit_load_stack_reg(r_ra, r_sp, real_off, ctx); ++ ++ /* Restore the sp and discard the scrach memory */ ++ if (offset) ++ emit_stack_offset(align_sp(offset), ctx); ++} ++ ++static unsigned int get_stack_depth(struct jit_ctx *ctx) ++{ ++ int sp_off = 0; ++ ++ ++ /* How may s* regs do we need to preserved? */ ++ sp_off += hweight32(ctx->flags >> SEEN_SREG_SFT) * SZREG; ++ ++ if (ctx->flags & SEEN_MEM) ++ sp_off += 4 * BPF_MEMWORDS; /* BPF_MEMWORDS are 32-bit */ ++ ++ if (ctx->flags & SEEN_CALL) ++ sp_off += SZREG; /* Space for our ra register */ ++ ++ return sp_off; ++} ++ ++static void build_prologue(struct jit_ctx *ctx) ++{ ++ int sp_off; ++ ++ /* Calculate the total offset for the stack pointer */ ++ sp_off = get_stack_depth(ctx); ++ save_bpf_jit_regs(ctx, sp_off); ++ ++ if (ctx->flags & SEEN_SKB) ++ emit_reg_move(r_skb, MIPS_R_A0, ctx); ++ ++ if (ctx->flags & SEEN_SKB_DATA) { ++ /* Load packet length */ ++ emit_load(r_skb_len, r_skb, offsetof(struct sk_buff, len), ++ ctx); ++ emit_load(r_tmp, r_skb, offsetof(struct sk_buff, data_len), ++ ctx); ++ /* Load the data pointer */ ++ emit_load_ptr(r_skb_data, r_skb, ++ offsetof(struct sk_buff, data), ctx); ++ /* Load the header length */ ++ emit_subu(r_skb_hl, r_skb_len, r_tmp, ctx); ++ } ++ ++ if (ctx->flags & SEEN_X) ++ emit_jit_reg_move(r_X, r_zero, ctx); ++ ++ /* ++ * Do not leak kernel data to userspace, we only need to clear ++ * r_A if it is ever used. In fact if it is never used, we ++ * will not save/restore it, so clearing it in this case would ++ * corrupt the state of the caller. ++ */ ++ if (bpf_needs_clear_a(&ctx->skf->insns[0]) && ++ (ctx->flags & SEEN_A)) ++ emit_jit_reg_move(r_A, r_zero, ctx); ++} ++ ++static void build_epilogue(struct jit_ctx *ctx) ++{ ++ unsigned int sp_off; ++ ++ /* Calculate the total offset for the stack pointer */ ++ ++ sp_off = get_stack_depth(ctx); ++ restore_bpf_jit_regs(ctx, sp_off); ++ ++ /* Return */ ++ emit_jr(r_ra, ctx); ++ emit_nop(ctx); ++} ++ ++#define CHOOSE_LOAD_FUNC(K, func) \ ++ ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative : func) : \ ++ func##_positive) ++ ++static int build_body(struct jit_ctx *ctx) ++{ ++ const struct bpf_prog *prog = ctx->skf; ++ const struct sock_filter *inst; ++ unsigned int i, off, condt; ++ u32 k, b_off __maybe_unused; ++ u8 (*sk_load_func)(unsigned long *skb, int offset); ++ ++ for (i = 0; i < prog->len; i++) { ++ u16 code; ++ ++ inst = &(prog->insns[i]); ++ pr_debug("%s: code->0x%02x, jt->0x%x, jf->0x%x, k->0x%x\n", ++ __func__, inst->code, inst->jt, inst->jf, inst->k); ++ k = inst->k; ++ code = bpf_anc_helper(inst); ++ ++ if (ctx->target == NULL) ++ ctx->offsets[i] = ctx->idx * 4; ++ ++ switch (code) { ++ case BPF_LD | BPF_IMM: ++ /* A <- k ==> li r_A, k */ ++ ctx->flags |= SEEN_A; ++ emit_load_imm(r_A, k, ctx); ++ break; ++ case BPF_LD | BPF_W | BPF_LEN: ++ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); ++ /* A <- len ==> lw r_A, offset(skb) */ ++ ctx->flags |= SEEN_SKB | SEEN_A; ++ off = offsetof(struct sk_buff, len); ++ emit_load(r_A, r_skb, off, ctx); ++ break; ++ case BPF_LD | BPF_MEM: ++ /* A <- M[k] ==> lw r_A, offset(M) */ ++ ctx->flags |= SEEN_MEM | SEEN_A; ++ emit_load(r_A, r_M, SCRATCH_OFF(k), ctx); ++ break; ++ case BPF_LD | BPF_W | BPF_ABS: ++ /* A <- P[k:4] */ ++ sk_load_func = CHOOSE_LOAD_FUNC(k, sk_load_word); ++ goto load; ++ case BPF_LD | BPF_H | BPF_ABS: ++ /* A <- P[k:2] */ ++ sk_load_func = CHOOSE_LOAD_FUNC(k, sk_load_half); ++ goto load; ++ case BPF_LD | BPF_B | BPF_ABS: ++ /* A <- P[k:1] */ ++ sk_load_func = CHOOSE_LOAD_FUNC(k, sk_load_byte); ++load: ++ emit_load_imm(r_off, k, ctx); ++load_common: ++ ctx->flags |= SEEN_CALL | SEEN_OFF | ++ SEEN_SKB | SEEN_A | SEEN_SKB_DATA; ++ ++ emit_load_func(r_s0, (ptr)sk_load_func, ctx); ++ emit_reg_move(MIPS_R_A0, r_skb, ctx); ++ emit_jalr(MIPS_R_RA, r_s0, ctx); ++ /* Load second argument to delay slot */ ++ emit_reg_move(MIPS_R_A1, r_off, ctx); ++ /* Check the error value */ ++ emit_bcond(MIPS_COND_EQ, r_ret, 0, b_imm(i + 1, ctx), ++ ctx); ++ /* Load return register on DS for failures */ ++ emit_reg_move(r_ret, r_zero, ctx); ++ /* Return with error */ ++ emit_b(b_imm(prog->len, ctx), ctx); ++ emit_nop(ctx); ++ break; ++ case BPF_LD | BPF_W | BPF_IND: ++ /* A <- P[X + k:4] */ ++ sk_load_func = sk_load_word; ++ goto load_ind; ++ case BPF_LD | BPF_H | BPF_IND: ++ /* A <- P[X + k:2] */ ++ sk_load_func = sk_load_half; ++ goto load_ind; ++ case BPF_LD | BPF_B | BPF_IND: ++ /* A <- P[X + k:1] */ ++ sk_load_func = sk_load_byte; ++load_ind: ++ ctx->flags |= SEEN_OFF | SEEN_X; ++ emit_addiu(r_off, r_X, k, ctx); ++ goto load_common; ++ case BPF_LDX | BPF_IMM: ++ /* X <- k */ ++ ctx->flags |= SEEN_X; ++ emit_load_imm(r_X, k, ctx); ++ break; ++ case BPF_LDX | BPF_MEM: ++ /* X <- M[k] */ ++ ctx->flags |= SEEN_X | SEEN_MEM; ++ emit_load(r_X, r_M, SCRATCH_OFF(k), ctx); ++ break; ++ case BPF_LDX | BPF_W | BPF_LEN: ++ /* X <- len */ ++ ctx->flags |= SEEN_X | SEEN_SKB; ++ off = offsetof(struct sk_buff, len); ++ emit_load(r_X, r_skb, off, ctx); ++ break; ++ case BPF_LDX | BPF_B | BPF_MSH: ++ /* X <- 4 * (P[k:1] & 0xf) */ ++ ctx->flags |= SEEN_X | SEEN_CALL | SEEN_SKB; ++ /* Load offset to a1 */ ++ emit_load_func(r_s0, (ptr)sk_load_byte, ctx); ++ /* ++ * This may emit two instructions so it may not fit ++ * in the delay slot. So use a0 in the delay slot. ++ */ ++ emit_load_imm(MIPS_R_A1, k, ctx); ++ emit_jalr(MIPS_R_RA, r_s0, ctx); ++ emit_reg_move(MIPS_R_A0, r_skb, ctx); /* delay slot */ ++ /* Check the error value */ ++ emit_bcond(MIPS_COND_NE, r_ret, 0, ++ b_imm(prog->len, ctx), ctx); ++ emit_reg_move(r_ret, r_zero, ctx); ++ /* We are good */ ++ /* X <- P[1:K] & 0xf */ ++ emit_andi(r_X, r_A, 0xf, ctx); ++ /* X << 2 */ ++ emit_b(b_imm(i + 1, ctx), ctx); ++ emit_sll(r_X, r_X, 2, ctx); /* delay slot */ ++ break; ++ case BPF_ST: ++ /* M[k] <- A */ ++ ctx->flags |= SEEN_MEM | SEEN_A; ++ emit_store(r_A, r_M, SCRATCH_OFF(k), ctx); ++ break; ++ case BPF_STX: ++ /* M[k] <- X */ ++ ctx->flags |= SEEN_MEM | SEEN_X; ++ emit_store(r_X, r_M, SCRATCH_OFF(k), ctx); ++ break; ++ case BPF_ALU | BPF_ADD | BPF_K: ++ /* A += K */ ++ ctx->flags |= SEEN_A; ++ emit_addiu(r_A, r_A, k, ctx); ++ break; ++ case BPF_ALU | BPF_ADD | BPF_X: ++ /* A += X */ ++ ctx->flags |= SEEN_A | SEEN_X; ++ emit_addu(r_A, r_A, r_X, ctx); ++ break; ++ case BPF_ALU | BPF_SUB | BPF_K: ++ /* A -= K */ ++ ctx->flags |= SEEN_A; ++ emit_addiu(r_A, r_A, -k, ctx); ++ break; ++ case BPF_ALU | BPF_SUB | BPF_X: ++ /* A -= X */ ++ ctx->flags |= SEEN_A | SEEN_X; ++ emit_subu(r_A, r_A, r_X, ctx); ++ break; ++ case BPF_ALU | BPF_MUL | BPF_K: ++ /* A *= K */ ++ /* Load K to scratch register before MUL */ ++ ctx->flags |= SEEN_A; ++ emit_load_imm(r_s0, k, ctx); ++ emit_mul(r_A, r_A, r_s0, ctx); ++ break; ++ case BPF_ALU | BPF_MUL | BPF_X: ++ /* A *= X */ ++ ctx->flags |= SEEN_A | SEEN_X; ++ emit_mul(r_A, r_A, r_X, ctx); ++ break; ++ case BPF_ALU | BPF_DIV | BPF_K: ++ /* A /= k */ ++ if (k == 1) ++ break; ++ if (optimize_div(&k)) { ++ ctx->flags |= SEEN_A; ++ emit_srl(r_A, r_A, k, ctx); ++ break; ++ } ++ ctx->flags |= SEEN_A; ++ emit_load_imm(r_s0, k, ctx); ++ emit_div(r_A, r_s0, ctx); ++ break; ++ case BPF_ALU | BPF_MOD | BPF_K: ++ /* A %= k */ ++ if (k == 1) { ++ ctx->flags |= SEEN_A; ++ emit_jit_reg_move(r_A, r_zero, ctx); ++ } else { ++ ctx->flags |= SEEN_A; ++ emit_load_imm(r_s0, k, ctx); ++ emit_mod(r_A, r_s0, ctx); ++ } ++ break; ++ case BPF_ALU | BPF_DIV | BPF_X: ++ /* A /= X */ ++ ctx->flags |= SEEN_X | SEEN_A; ++ /* Check if r_X is zero */ ++ emit_bcond(MIPS_COND_EQ, r_X, r_zero, ++ b_imm(prog->len, ctx), ctx); ++ emit_load_imm(r_ret, 0, ctx); /* delay slot */ ++ emit_div(r_A, r_X, ctx); ++ break; ++ case BPF_ALU | BPF_MOD | BPF_X: ++ /* A %= X */ ++ ctx->flags |= SEEN_X | SEEN_A; ++ /* Check if r_X is zero */ ++ emit_bcond(MIPS_COND_EQ, r_X, r_zero, ++ b_imm(prog->len, ctx), ctx); ++ emit_load_imm(r_ret, 0, ctx); /* delay slot */ ++ emit_mod(r_A, r_X, ctx); ++ break; ++ case BPF_ALU | BPF_OR | BPF_K: ++ /* A |= K */ ++ ctx->flags |= SEEN_A; ++ emit_ori(r_A, r_A, k, ctx); ++ break; ++ case BPF_ALU | BPF_OR | BPF_X: ++ /* A |= X */ ++ ctx->flags |= SEEN_A; ++ emit_ori(r_A, r_A, r_X, ctx); ++ break; ++ case BPF_ALU | BPF_XOR | BPF_K: ++ /* A ^= k */ ++ ctx->flags |= SEEN_A; ++ emit_xori(r_A, r_A, k, ctx); ++ break; ++ case BPF_ANC | SKF_AD_ALU_XOR_X: ++ case BPF_ALU | BPF_XOR | BPF_X: ++ /* A ^= X */ ++ ctx->flags |= SEEN_A; ++ emit_xor(r_A, r_A, r_X, ctx); ++ break; ++ case BPF_ALU | BPF_AND | BPF_K: ++ /* A &= K */ ++ ctx->flags |= SEEN_A; ++ emit_andi(r_A, r_A, k, ctx); ++ break; ++ case BPF_ALU | BPF_AND | BPF_X: ++ /* A &= X */ ++ ctx->flags |= SEEN_A | SEEN_X; ++ emit_and(r_A, r_A, r_X, ctx); ++ break; ++ case BPF_ALU | BPF_LSH | BPF_K: ++ /* A <<= K */ ++ ctx->flags |= SEEN_A; ++ emit_sll(r_A, r_A, k, ctx); ++ break; ++ case BPF_ALU | BPF_LSH | BPF_X: ++ /* A <<= X */ ++ ctx->flags |= SEEN_A | SEEN_X; ++ emit_sllv(r_A, r_A, r_X, ctx); ++ break; ++ case BPF_ALU | BPF_RSH | BPF_K: ++ /* A >>= K */ ++ ctx->flags |= SEEN_A; ++ emit_srl(r_A, r_A, k, ctx); ++ break; ++ case BPF_ALU | BPF_RSH | BPF_X: ++ ctx->flags |= SEEN_A | SEEN_X; ++ emit_srlv(r_A, r_A, r_X, ctx); ++ break; ++ case BPF_ALU | BPF_NEG: ++ /* A = -A */ ++ ctx->flags |= SEEN_A; ++ emit_neg(r_A, ctx); ++ break; ++ case BPF_JMP | BPF_JA: ++ /* pc += K */ ++ emit_b(b_imm(i + k + 1, ctx), ctx); ++ emit_nop(ctx); ++ break; ++ case BPF_JMP | BPF_JEQ | BPF_K: ++ /* pc += ( A == K ) ? pc->jt : pc->jf */ ++ condt = MIPS_COND_EQ | MIPS_COND_K; ++ goto jmp_cmp; ++ case BPF_JMP | BPF_JEQ | BPF_X: ++ ctx->flags |= SEEN_X; ++ /* pc += ( A == X ) ? pc->jt : pc->jf */ ++ condt = MIPS_COND_EQ | MIPS_COND_X; ++ goto jmp_cmp; ++ case BPF_JMP | BPF_JGE | BPF_K: ++ /* pc += ( A >= K ) ? pc->jt : pc->jf */ ++ condt = MIPS_COND_GE | MIPS_COND_K; ++ goto jmp_cmp; ++ case BPF_JMP | BPF_JGE | BPF_X: ++ ctx->flags |= SEEN_X; ++ /* pc += ( A >= X ) ? pc->jt : pc->jf */ ++ condt = MIPS_COND_GE | MIPS_COND_X; ++ goto jmp_cmp; ++ case BPF_JMP | BPF_JGT | BPF_K: ++ /* pc += ( A > K ) ? pc->jt : pc->jf */ ++ condt = MIPS_COND_GT | MIPS_COND_K; ++ goto jmp_cmp; ++ case BPF_JMP | BPF_JGT | BPF_X: ++ ctx->flags |= SEEN_X; ++ /* pc += ( A > X ) ? pc->jt : pc->jf */ ++ condt = MIPS_COND_GT | MIPS_COND_X; ++jmp_cmp: ++ /* Greater or Equal */ ++ if ((condt & MIPS_COND_GE) || ++ (condt & MIPS_COND_GT)) { ++ if (condt & MIPS_COND_K) { /* K */ ++ ctx->flags |= SEEN_A; ++ emit_sltiu(r_s0, r_A, k, ctx); ++ } else { /* X */ ++ ctx->flags |= SEEN_A | ++ SEEN_X; ++ emit_sltu(r_s0, r_A, r_X, ctx); ++ } ++ /* A < (K|X) ? r_scrach = 1 */ ++ b_off = b_imm(i + inst->jf + 1, ctx); ++ emit_bcond(MIPS_COND_NE, r_s0, r_zero, b_off, ++ ctx); ++ emit_nop(ctx); ++ /* A > (K|X) ? scratch = 0 */ ++ if (condt & MIPS_COND_GT) { ++ /* Checking for equality */ ++ ctx->flags |= SEEN_A | SEEN_X; ++ if (condt & MIPS_COND_K) ++ emit_load_imm(r_s0, k, ctx); ++ else ++ emit_jit_reg_move(r_s0, r_X, ++ ctx); ++ b_off = b_imm(i + inst->jf + 1, ctx); ++ emit_bcond(MIPS_COND_EQ, r_A, r_s0, ++ b_off, ctx); ++ emit_nop(ctx); ++ /* Finally, A > K|X */ ++ b_off = b_imm(i + inst->jt + 1, ctx); ++ emit_b(b_off, ctx); ++ emit_nop(ctx); ++ } else { ++ /* A >= (K|X) so jump */ ++ b_off = b_imm(i + inst->jt + 1, ctx); ++ emit_b(b_off, ctx); ++ emit_nop(ctx); ++ } ++ } else { ++ /* A == K|X */ ++ if (condt & MIPS_COND_K) { /* K */ ++ ctx->flags |= SEEN_A; ++ emit_load_imm(r_s0, k, ctx); ++ /* jump true */ ++ b_off = b_imm(i + inst->jt + 1, ctx); ++ emit_bcond(MIPS_COND_EQ, r_A, r_s0, ++ b_off, ctx); ++ emit_nop(ctx); ++ /* jump false */ ++ b_off = b_imm(i + inst->jf + 1, ++ ctx); ++ emit_bcond(MIPS_COND_NE, r_A, r_s0, ++ b_off, ctx); ++ emit_nop(ctx); ++ } else { /* X */ ++ /* jump true */ ++ ctx->flags |= SEEN_A | SEEN_X; ++ b_off = b_imm(i + inst->jt + 1, ++ ctx); ++ emit_bcond(MIPS_COND_EQ, r_A, r_X, ++ b_off, ctx); ++ emit_nop(ctx); ++ /* jump false */ ++ b_off = b_imm(i + inst->jf + 1, ctx); ++ emit_bcond(MIPS_COND_NE, r_A, r_X, ++ b_off, ctx); ++ emit_nop(ctx); ++ } ++ } ++ break; ++ case BPF_JMP | BPF_JSET | BPF_K: ++ ctx->flags |= SEEN_A; ++ /* pc += (A & K) ? pc -> jt : pc -> jf */ ++ emit_load_imm(r_s1, k, ctx); ++ emit_and(r_s0, r_A, r_s1, ctx); ++ /* jump true */ ++ b_off = b_imm(i + inst->jt + 1, ctx); ++ emit_bcond(MIPS_COND_NE, r_s0, r_zero, b_off, ctx); ++ emit_nop(ctx); ++ /* jump false */ ++ b_off = b_imm(i + inst->jf + 1, ctx); ++ emit_b(b_off, ctx); ++ emit_nop(ctx); ++ break; ++ case BPF_JMP | BPF_JSET | BPF_X: ++ ctx->flags |= SEEN_X | SEEN_A; ++ /* pc += (A & X) ? pc -> jt : pc -> jf */ ++ emit_and(r_s0, r_A, r_X, ctx); ++ /* jump true */ ++ b_off = b_imm(i + inst->jt + 1, ctx); ++ emit_bcond(MIPS_COND_NE, r_s0, r_zero, b_off, ctx); ++ emit_nop(ctx); ++ /* jump false */ ++ b_off = b_imm(i + inst->jf + 1, ctx); ++ emit_b(b_off, ctx); ++ emit_nop(ctx); ++ break; ++ case BPF_RET | BPF_A: ++ ctx->flags |= SEEN_A; ++ if (i != prog->len - 1) ++ /* ++ * If this is not the last instruction ++ * then jump to the epilogue ++ */ ++ emit_b(b_imm(prog->len, ctx), ctx); ++ emit_reg_move(r_ret, r_A, ctx); /* delay slot */ ++ break; ++ case BPF_RET | BPF_K: ++ /* ++ * It can emit two instructions so it does not fit on ++ * the delay slot. ++ */ ++ emit_load_imm(r_ret, k, ctx); ++ if (i != prog->len - 1) { ++ /* ++ * If this is not the last instruction ++ * then jump to the epilogue ++ */ ++ emit_b(b_imm(prog->len, ctx), ctx); ++ emit_nop(ctx); ++ } ++ break; ++ case BPF_MISC | BPF_TAX: ++ /* X = A */ ++ ctx->flags |= SEEN_X | SEEN_A; ++ emit_jit_reg_move(r_X, r_A, ctx); ++ break; ++ case BPF_MISC | BPF_TXA: ++ /* A = X */ ++ ctx->flags |= SEEN_A | SEEN_X; ++ emit_jit_reg_move(r_A, r_X, ctx); ++ break; ++ /* AUX */ ++ case BPF_ANC | SKF_AD_PROTOCOL: ++ /* A = ntohs(skb->protocol */ ++ ctx->flags |= SEEN_SKB | SEEN_OFF | SEEN_A; ++ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, ++ protocol) != 2); ++ off = offsetof(struct sk_buff, protocol); ++ emit_half_load(r_A, r_skb, off, ctx); ++#ifdef CONFIG_CPU_LITTLE_ENDIAN ++ /* This needs little endian fixup */ ++ if (cpu_has_wsbh) { ++ /* R2 and later have the wsbh instruction */ ++ emit_wsbh(r_A, r_A, ctx); ++ } else { ++ /* Get first byte */ ++ emit_andi(r_tmp_imm, r_A, 0xff, ctx); ++ /* Shift it */ ++ emit_sll(r_tmp, r_tmp_imm, 8, ctx); ++ /* Get second byte */ ++ emit_srl(r_tmp_imm, r_A, 8, ctx); ++ emit_andi(r_tmp_imm, r_tmp_imm, 0xff, ctx); ++ /* Put everyting together in r_A */ ++ emit_or(r_A, r_tmp, r_tmp_imm, ctx); ++ } ++#endif ++ break; ++ case BPF_ANC | SKF_AD_CPU: ++ ctx->flags |= SEEN_A | SEEN_OFF; ++ /* A = current_thread_info()->cpu */ ++ BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, ++ cpu) != 4); ++ off = offsetof(struct thread_info, cpu); ++ /* $28/gp points to the thread_info struct */ ++ emit_load(r_A, 28, off, ctx); ++ break; ++ case BPF_ANC | SKF_AD_IFINDEX: ++ /* A = skb->dev->ifindex */ ++ case BPF_ANC | SKF_AD_HATYPE: ++ /* A = skb->dev->type */ ++ ctx->flags |= SEEN_SKB | SEEN_A; ++ off = offsetof(struct sk_buff, dev); ++ /* Load *dev pointer */ ++ emit_load_ptr(r_s0, r_skb, off, ctx); ++ /* error (0) in the delay slot */ ++ emit_bcond(MIPS_COND_EQ, r_s0, r_zero, ++ b_imm(prog->len, ctx), ctx); ++ emit_reg_move(r_ret, r_zero, ctx); ++ if (code == (BPF_ANC | SKF_AD_IFINDEX)) { ++ BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, ifindex) != 4); ++ off = offsetof(struct net_device, ifindex); ++ emit_load(r_A, r_s0, off, ctx); ++ } else { /* (code == (BPF_ANC | SKF_AD_HATYPE) */ ++ BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, type) != 2); ++ off = offsetof(struct net_device, type); ++ emit_half_load_unsigned(r_A, r_s0, off, ctx); ++ } ++ break; ++ case BPF_ANC | SKF_AD_MARK: ++ ctx->flags |= SEEN_SKB | SEEN_A; ++ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); ++ off = offsetof(struct sk_buff, mark); ++ emit_load(r_A, r_skb, off, ctx); ++ break; ++ case BPF_ANC | SKF_AD_RXHASH: ++ ctx->flags |= SEEN_SKB | SEEN_A; ++ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); ++ off = offsetof(struct sk_buff, hash); ++ emit_load(r_A, r_skb, off, ctx); ++ break; ++ case BPF_ANC | SKF_AD_VLAN_TAG: ++ ctx->flags |= SEEN_SKB | SEEN_A; ++ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, ++ vlan_tci) != 2); ++ off = offsetof(struct sk_buff, vlan_tci); ++ emit_half_load_unsigned(r_A, r_skb, off, ctx); ++ break; ++ case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT: ++ ctx->flags |= SEEN_SKB | SEEN_A; ++ emit_load_byte(r_A, r_skb, PKT_VLAN_PRESENT_OFFSET(), ctx); ++ if (PKT_VLAN_PRESENT_BIT) ++ emit_srl(r_A, r_A, PKT_VLAN_PRESENT_BIT, ctx); ++ if (PKT_VLAN_PRESENT_BIT < 7) ++ emit_andi(r_A, r_A, 1, ctx); ++ break; ++ case BPF_ANC | SKF_AD_PKTTYPE: ++ ctx->flags |= SEEN_SKB; ++ ++ emit_load_byte(r_tmp, r_skb, PKT_TYPE_OFFSET(), ctx); ++ /* Keep only the last 3 bits */ ++ emit_andi(r_A, r_tmp, PKT_TYPE_MAX, ctx); ++#ifdef __BIG_ENDIAN_BITFIELD ++ /* Get the actual packet type to the lower 3 bits */ ++ emit_srl(r_A, r_A, 5, ctx); ++#endif ++ break; ++ case BPF_ANC | SKF_AD_QUEUE: ++ ctx->flags |= SEEN_SKB | SEEN_A; ++ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, ++ queue_mapping) != 2); ++ BUILD_BUG_ON(offsetof(struct sk_buff, ++ queue_mapping) > 0xff); ++ off = offsetof(struct sk_buff, queue_mapping); ++ emit_half_load_unsigned(r_A, r_skb, off, ctx); ++ break; ++ default: ++ pr_debug("%s: Unhandled opcode: 0x%02x\n", __FILE__, ++ inst->code); ++ return -1; ++ } ++ } ++ ++ /* compute offsets only during the first pass */ ++ if (ctx->target == NULL) ++ ctx->offsets[i] = ctx->idx * 4; ++ ++ return 0; ++} ++ ++void bpf_jit_compile(struct bpf_prog *fp) ++{ ++ struct jit_ctx ctx; ++ unsigned int alloc_size, tmp_idx; ++ ++ if (!bpf_jit_enable) ++ return; ++ ++ memset(&ctx, 0, sizeof(ctx)); ++ ++ ctx.offsets = kcalloc(fp->len + 1, sizeof(*ctx.offsets), GFP_KERNEL); ++ if (ctx.offsets == NULL) ++ return; ++ ++ ctx.skf = fp; ++ ++ if (build_body(&ctx)) ++ goto out; ++ ++ tmp_idx = ctx.idx; ++ build_prologue(&ctx); ++ ctx.prologue_bytes = (ctx.idx - tmp_idx) * 4; ++ /* just to complete the ctx.idx count */ ++ build_epilogue(&ctx); ++ ++ alloc_size = 4 * ctx.idx; ++ ctx.target = module_alloc(alloc_size); ++ if (ctx.target == NULL) ++ goto out; ++ ++ /* Clean it */ ++ memset(ctx.target, 0, alloc_size); ++ ++ ctx.idx = 0; ++ ++ /* Generate the actual JIT code */ ++ build_prologue(&ctx); ++ build_body(&ctx); ++ build_epilogue(&ctx); ++ ++ /* Update the icache */ ++ flush_icache_range((ptr)ctx.target, (ptr)(ctx.target + ctx.idx)); ++ ++ if (bpf_jit_enable > 1) ++ /* Dump JIT code */ ++ bpf_jit_dump(fp->len, alloc_size, 2, ctx.target); ++ ++ fp->bpf_func = (void *)ctx.target; ++ fp->jited = 1; ++ ++out: ++ kfree(ctx.offsets); ++} ++ ++void bpf_jit_free(struct bpf_prog *fp) ++{ ++ if (fp->jited) ++ module_memfree(fp->bpf_func); ++ ++ bpf_prog_unlock_free(fp); ++} +diff --git a/arch/mips/net/bpf_jit_asm.S b/arch/mips/net/bpf_jit_asm.S +new file mode 100644 +index 000000000000..57154c5883b6 +--- /dev/null ++++ b/arch/mips/net/bpf_jit_asm.S +@@ -0,0 +1,285 @@ ++/* ++ * bpf_jib_asm.S: Packet/header access helper functions for MIPS/MIPS64 BPF ++ * compiler. ++ * ++ * Copyright (C) 2015 Imagination Technologies Ltd. ++ * Author: Markos Chandras ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; version 2 of the License. ++ */ ++ ++#include ++#include ++#include ++#include "bpf_jit.h" ++ ++/* ABI ++ * ++ * r_skb_hl skb header length ++ * r_skb_data skb data ++ * r_off(a1) offset register ++ * r_A BPF register A ++ * r_X PF register X ++ * r_skb(a0) *skb ++ * r_M *scratch memory ++ * r_skb_le skb length ++ * r_s0 Scratch register 0 ++ * r_s1 Scratch register 1 ++ * ++ * On entry: ++ * a0: *skb ++ * a1: offset (imm or imm + X) ++ * ++ * All non-BPF-ABI registers are free for use. On return, we only ++ * care about r_ret. The BPF-ABI registers are assumed to remain ++ * unmodified during the entire filter operation. ++ */ ++ ++#define skb a0 ++#define offset a1 ++#define SKF_LL_OFF (-0x200000) /* Can't include linux/filter.h in assembly */ ++ ++ /* We know better :) so prevent assembler reordering etc */ ++ .set noreorder ++ ++#define is_offset_negative(TYPE) \ ++ /* If offset is negative we have more work to do */ \ ++ slti t0, offset, 0; \ ++ bgtz t0, bpf_slow_path_##TYPE##_neg; \ ++ /* Be careful what follows in DS. */ ++ ++#define is_offset_in_header(SIZE, TYPE) \ ++ /* Reading from header? */ \ ++ addiu $r_s0, $r_skb_hl, -SIZE; \ ++ slt t0, $r_s0, offset; \ ++ bgtz t0, bpf_slow_path_##TYPE; \ ++ ++LEAF(sk_load_word) ++ is_offset_negative(word) ++FEXPORT(sk_load_word_positive) ++ is_offset_in_header(4, word) ++ /* Offset within header boundaries */ ++ PTR_ADDU t1, $r_skb_data, offset ++ .set reorder ++ lw $r_A, 0(t1) ++ .set noreorder ++#ifdef CONFIG_CPU_LITTLE_ENDIAN ++# if MIPS_ISA_REV >= 2 ++ wsbh t0, $r_A ++ rotr $r_A, t0, 16 ++# else ++ sll t0, $r_A, 24 ++ srl t1, $r_A, 24 ++ srl t2, $r_A, 8 ++ or t0, t0, t1 ++ andi t2, t2, 0xff00 ++ andi t1, $r_A, 0xff00 ++ or t0, t0, t2 ++ sll t1, t1, 8 ++ or $r_A, t0, t1 ++# endif ++#endif ++ jr $r_ra ++ move $r_ret, zero ++ END(sk_load_word) ++ ++LEAF(sk_load_half) ++ is_offset_negative(half) ++FEXPORT(sk_load_half_positive) ++ is_offset_in_header(2, half) ++ /* Offset within header boundaries */ ++ PTR_ADDU t1, $r_skb_data, offset ++ lhu $r_A, 0(t1) ++#ifdef CONFIG_CPU_LITTLE_ENDIAN ++# if MIPS_ISA_REV >= 2 ++ wsbh $r_A, $r_A ++# else ++ sll t0, $r_A, 8 ++ srl t1, $r_A, 8 ++ andi t0, t0, 0xff00 ++ or $r_A, t0, t1 ++# endif ++#endif ++ jr $r_ra ++ move $r_ret, zero ++ END(sk_load_half) ++ ++LEAF(sk_load_byte) ++ is_offset_negative(byte) ++FEXPORT(sk_load_byte_positive) ++ is_offset_in_header(1, byte) ++ /* Offset within header boundaries */ ++ PTR_ADDU t1, $r_skb_data, offset ++ lbu $r_A, 0(t1) ++ jr $r_ra ++ move $r_ret, zero ++ END(sk_load_byte) ++ ++/* ++ * call skb_copy_bits: ++ * (prototype in linux/skbuff.h) ++ * ++ * int skb_copy_bits(sk_buff *skb, int offset, void *to, int len) ++ * ++ * o32 mandates we leave 4 spaces for argument registers in case ++ * the callee needs to use them. Even though we don't care about ++ * the argument registers ourselves, we need to allocate that space ++ * to remain ABI compliant since the callee may want to use that space. ++ * We also allocate 2 more spaces for $r_ra and our return register (*to). ++ * ++ * n64 is a bit different. The *caller* will allocate the space to preserve ++ * the arguments. So in 64-bit kernels, we allocate the 4-arg space for no ++ * good reason but it does not matter that much really. ++ * ++ * (void *to) is returned in r_s0 ++ * ++ */ ++#ifdef CONFIG_CPU_LITTLE_ENDIAN ++#define DS_OFFSET(SIZE) (4 * SZREG) ++#else ++#define DS_OFFSET(SIZE) ((4 * SZREG) + (4 - SIZE)) ++#endif ++#define bpf_slow_path_common(SIZE) \ ++ /* Quick check. Are we within reasonable boundaries? */ \ ++ LONG_ADDIU $r_s1, $r_skb_len, -SIZE; \ ++ sltu $r_s0, offset, $r_s1; \ ++ beqz $r_s0, fault; \ ++ /* Load 4th argument in DS */ \ ++ LONG_ADDIU a3, zero, SIZE; \ ++ PTR_ADDIU $r_sp, $r_sp, -(6 * SZREG); \ ++ PTR_LA t0, skb_copy_bits; \ ++ PTR_S $r_ra, (5 * SZREG)($r_sp); \ ++ /* Assign low slot to a2 */ \ ++ PTR_ADDIU a2, $r_sp, DS_OFFSET(SIZE); \ ++ jalr t0; \ ++ /* Reset our destination slot (DS but it's ok) */ \ ++ INT_S zero, (4 * SZREG)($r_sp); \ ++ /* \ ++ * skb_copy_bits returns 0 on success and -EFAULT \ ++ * on error. Our data live in a2. Do not bother with \ ++ * our data if an error has been returned. \ ++ */ \ ++ /* Restore our frame */ \ ++ PTR_L $r_ra, (5 * SZREG)($r_sp); \ ++ INT_L $r_s0, (4 * SZREG)($r_sp); \ ++ bltz v0, fault; \ ++ PTR_ADDIU $r_sp, $r_sp, 6 * SZREG; \ ++ move $r_ret, zero; \ ++ ++NESTED(bpf_slow_path_word, (6 * SZREG), $r_sp) ++ bpf_slow_path_common(4) ++#ifdef CONFIG_CPU_LITTLE_ENDIAN ++# if MIPS_ISA_REV >= 2 ++ wsbh t0, $r_s0 ++ jr $r_ra ++ rotr $r_A, t0, 16 ++# else ++ sll t0, $r_s0, 24 ++ srl t1, $r_s0, 24 ++ srl t2, $r_s0, 8 ++ or t0, t0, t1 ++ andi t2, t2, 0xff00 ++ andi t1, $r_s0, 0xff00 ++ or t0, t0, t2 ++ sll t1, t1, 8 ++ jr $r_ra ++ or $r_A, t0, t1 ++# endif ++#else ++ jr $r_ra ++ move $r_A, $r_s0 ++#endif ++ ++ END(bpf_slow_path_word) ++ ++NESTED(bpf_slow_path_half, (6 * SZREG), $r_sp) ++ bpf_slow_path_common(2) ++#ifdef CONFIG_CPU_LITTLE_ENDIAN ++# if MIPS_ISA_REV >= 2 ++ jr $r_ra ++ wsbh $r_A, $r_s0 ++# else ++ sll t0, $r_s0, 8 ++ andi t1, $r_s0, 0xff00 ++ andi t0, t0, 0xff00 ++ srl t1, t1, 8 ++ jr $r_ra ++ or $r_A, t0, t1 ++# endif ++#else ++ jr $r_ra ++ move $r_A, $r_s0 ++#endif ++ ++ END(bpf_slow_path_half) ++ ++NESTED(bpf_slow_path_byte, (6 * SZREG), $r_sp) ++ bpf_slow_path_common(1) ++ jr $r_ra ++ move $r_A, $r_s0 ++ ++ END(bpf_slow_path_byte) ++ ++/* ++ * Negative entry points ++ */ ++ .macro bpf_is_end_of_data ++ li t0, SKF_LL_OFF ++ /* Reading link layer data? */ ++ slt t1, offset, t0 ++ bgtz t1, fault ++ /* Be careful what follows in DS. */ ++ .endm ++/* ++ * call skb_copy_bits: ++ * (prototype in linux/filter.h) ++ * ++ * void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb, ++ * int k, unsigned int size) ++ * ++ * see above (bpf_slow_path_common) for ABI restrictions ++ */ ++#define bpf_negative_common(SIZE) \ ++ PTR_ADDIU $r_sp, $r_sp, -(6 * SZREG); \ ++ PTR_LA t0, bpf_internal_load_pointer_neg_helper; \ ++ PTR_S $r_ra, (5 * SZREG)($r_sp); \ ++ jalr t0; \ ++ li a2, SIZE; \ ++ PTR_L $r_ra, (5 * SZREG)($r_sp); \ ++ /* Check return pointer */ \ ++ beqz v0, fault; \ ++ PTR_ADDIU $r_sp, $r_sp, 6 * SZREG; \ ++ /* Preserve our pointer */ \ ++ move $r_s0, v0; \ ++ /* Set return value */ \ ++ move $r_ret, zero; \ ++ ++bpf_slow_path_word_neg: ++ bpf_is_end_of_data ++NESTED(sk_load_word_negative, (6 * SZREG), $r_sp) ++ bpf_negative_common(4) ++ jr $r_ra ++ lw $r_A, 0($r_s0) ++ END(sk_load_word_negative) ++ ++bpf_slow_path_half_neg: ++ bpf_is_end_of_data ++NESTED(sk_load_half_negative, (6 * SZREG), $r_sp) ++ bpf_negative_common(2) ++ jr $r_ra ++ lhu $r_A, 0($r_s0) ++ END(sk_load_half_negative) ++ ++bpf_slow_path_byte_neg: ++ bpf_is_end_of_data ++NESTED(sk_load_byte_negative, (6 * SZREG), $r_sp) ++ bpf_negative_common(1) ++ jr $r_ra ++ lbu $r_A, 0($r_s0) ++ END(sk_load_byte_negative) ++ ++fault: ++ jr $r_ra ++ addiu $r_ret, zero, 1 +-- +2.17.1 + From 217877d046414878126e5c8013162e3b7edc774c Mon Sep 17 00:00:00 2001 From: Tony Ambardar Date: Wed, 22 Jul 2020 06:28:06 -0700 Subject: [PATCH 02/23] base-files: mount bpffs at boot Explicitly mount the BPF filesystem if available. This is used for pinning eBPF programs and maps, making them accessible to other eBPF programs or from userspace with the help of libbpf or bpftool. Signed-off-by: Tony Ambardar [daniel@makrotopia.org: bumped PKG_RELEASE] Signed-off-by: Daniel Golle --- package/base-files/Makefile | 2 +- package/base-files/files/etc/init.d/boot | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/package/base-files/Makefile b/package/base-files/Makefile index d32bae8635..7e0d341705 100644 --- a/package/base-files/Makefile +++ b/package/base-files/Makefile @@ -12,7 +12,7 @@ include $(INCLUDE_DIR)/version.mk include $(INCLUDE_DIR)/feeds.mk PKG_NAME:=base-files -PKG_RELEASE:=224 +PKG_RELEASE:=225 PKG_FLAGS:=nonshared PKG_FILE_DEPENDS:=$(PLATFORM_DIR)/ $(GENERIC_PLATFORM_DIR)/base-files/ diff --git a/package/base-files/files/etc/init.d/boot b/package/base-files/files/etc/init.d/boot index 21aecde615..958a67599e 100755 --- a/package/base-files/files/etc/init.d/boot +++ b/package/base-files/files/etc/init.d/boot @@ -35,6 +35,7 @@ boot() { touch /tmp/resolv.conf.d/resolv.conf.auto ln -sf /tmp/resolv.conf.d/resolv.conf.auto /tmp/resolv.conf grep -q debugfs /proc/filesystems && /bin/mount -o noatime -t debugfs debugfs /sys/kernel/debug + grep -q bpf /proc/filesystems && /bin/mount -o nosuid,nodev,noexec,noatime,mode=0700 -t bpf bpffs /sys/fs/bpf [ "$FAILSAFE" = "true" ] && touch /tmp/.failsafe /sbin/kmodloader From 65305cb44869774a7db10c517b871dce5ab46ccb Mon Sep 17 00:00:00 2001 From: Adrian Schmutzler Date: Sat, 13 Jun 2020 00:36:01 +0200 Subject: [PATCH 03/23] kirkwood: use real model names for Linksys devices This replaces the internal device names "Audi" and "Viper" with the real model names, which a user would look for. This makes the Linksys devices on this target consistent with the names recently changed for mvebu based on the same idea. As a consequence, the "viper" device definition is split into two separate definitions with the correct names for both real models. Signed-off-by: Adrian Schmutzler --- package/boot/uboot-envtools/files/kirkwood | 5 +- .../kirkwood/base-files/etc/board.d/01_leds | 5 +- .../base-files/etc/board.d/02_network | 5 +- .../base-files/etc/board.d/05_compat-version | 5 +- .../kirkwood/base-files/etc/init.d/bootcount | 5 +- .../base-files/lib/upgrade/platform.sh | 5 +- .../arch/arm/boot/dts/kirkwood-e4200-v2.dts | 8 ++++ ...d-linksys-audi.dts => kirkwood-ea3500.dts} | 4 +- .../arch/arm/boot/dts/kirkwood-ea4500.dts | 8 ++++ target/linux/kirkwood/image/Makefile | 47 ++++++++++++------- ...4500.patch => 105-linksys-viper-dts.patch} | 0 11 files changed, 66 insertions(+), 31 deletions(-) create mode 100644 target/linux/kirkwood/files-5.4/arch/arm/boot/dts/kirkwood-e4200-v2.dts rename target/linux/kirkwood/files-5.4/arch/arm/boot/dts/{kirkwood-linksys-audi.dts => kirkwood-ea3500.dts} (96%) create mode 100644 target/linux/kirkwood/files-5.4/arch/arm/boot/dts/kirkwood-ea4500.dts rename target/linux/kirkwood/patches-5.4/{105-ea4500.patch => 105-linksys-viper-dts.patch} (100%) diff --git a/package/boot/uboot-envtools/files/kirkwood b/package/boot/uboot-envtools/files/kirkwood index a099c925ea..401df74597 100644 --- a/package/boot/uboot-envtools/files/kirkwood +++ b/package/boot/uboot-envtools/files/kirkwood @@ -17,7 +17,8 @@ checkpoint,l-50|\ cloudengines,pogoe02|\ cloudengines,pogoplugv4|\ iom,ix2-200|\ -linksys,viper|\ +linksys,e4200-v2|\ +linksys,ea4500|\ raidsonic,ib-nas62x0|\ seagate,dockstar|\ zyxel,nsa310b|\ @@ -25,7 +26,7 @@ zyxel,nsa310s|\ zyxel,nsa325) ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x20000" "0x20000" ;; -linksys,audi) +linksys,ea3500) ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x4000" "0x4000" ;; esac diff --git a/target/linux/kirkwood/base-files/etc/board.d/01_leds b/target/linux/kirkwood/base-files/etc/board.d/01_leds index bbe689bbb5..3f7fe71c0a 100755 --- a/target/linux/kirkwood/base-files/etc/board.d/01_leds +++ b/target/linux/kirkwood/base-files/etc/board.d/01_leds @@ -10,10 +10,11 @@ board_config_update board=$(board_name) case "$board" in -"iom,ix2-200") +iom,ix2-200) ucidef_set_led_timer "health" "health" "status:white:rebuild_led" "200" "800" ;; -"linksys,viper") +linksys,e4200-v2|\ +linksys,ea4500) ucidef_set_led_default "pulse" "pulse" "viper:white:pulse" "1" ;; esac diff --git a/target/linux/kirkwood/base-files/etc/board.d/02_network b/target/linux/kirkwood/base-files/etc/board.d/02_network index 658ce13346..a60b87c912 100755 --- a/target/linux/kirkwood/base-files/etc/board.d/02_network +++ b/target/linux/kirkwood/base-files/etc/board.d/02_network @@ -28,8 +28,9 @@ case "$board" in "zyxel,nsa310s") ucidef_set_interface_lan "eth0" "dhcp" ;; -"linksys,audi"|\ -"linksys,viper") +"linksys,e4200-v2"|\ +"linksys,ea3500"|\ +"linksys,ea4500") ucidef_set_interfaces_lan_wan "ethernet1 ethernet2 ethernet3 ethernet4" "internet" ucidef_set_interface_macaddr "wan" $( mtd_get_mac_ascii u_env eth1addr ) ;; diff --git a/target/linux/kirkwood/base-files/etc/board.d/05_compat-version b/target/linux/kirkwood/base-files/etc/board.d/05_compat-version index 8954d69d12..29d1debe58 100755 --- a/target/linux/kirkwood/base-files/etc/board.d/05_compat-version +++ b/target/linux/kirkwood/base-files/etc/board.d/05_compat-version @@ -9,8 +9,9 @@ board_config_update case "$(board_name)" in - linksys,audi|\ - linksys,viper) + linksys,e4200-v2|\ + linksys,ea3500|\ + linksys,ea4500) ucidef_set_compat_version "1.1" ;; esac diff --git a/target/linux/kirkwood/base-files/etc/init.d/bootcount b/target/linux/kirkwood/base-files/etc/init.d/bootcount index 478f3d0134..bbb36eb6ea 100755 --- a/target/linux/kirkwood/base-files/etc/init.d/bootcount +++ b/target/linux/kirkwood/base-files/etc/init.d/bootcount @@ -4,8 +4,9 @@ START=99 boot() { case $(board_name) in - linksys,audi|\ - linksys,viper) + linksys,e4200-v2|\ + linksys,ea3500|\ + linksys,ea4500) mtd resetbc s_env || true ;; esac diff --git a/target/linux/kirkwood/base-files/lib/upgrade/platform.sh b/target/linux/kirkwood/base-files/lib/upgrade/platform.sh index 6d63a0a4b7..8ff1709f2c 100644 --- a/target/linux/kirkwood/base-files/lib/upgrade/platform.sh +++ b/target/linux/kirkwood/base-files/lib/upgrade/platform.sh @@ -11,8 +11,9 @@ platform_do_upgrade() { local board="$(board_name)" case "$board" in - "linksys,audi"|\ - "linksys,viper") + linksys,e4200-v2|\ + linksys,ea3500|\ + linksys,ea4500) platform_do_upgrade_linksys "$1" ;; *) diff --git a/target/linux/kirkwood/files-5.4/arch/arm/boot/dts/kirkwood-e4200-v2.dts b/target/linux/kirkwood/files-5.4/arch/arm/boot/dts/kirkwood-e4200-v2.dts new file mode 100644 index 0000000000..bfd708a677 --- /dev/null +++ b/target/linux/kirkwood/files-5.4/arch/arm/boot/dts/kirkwood-e4200-v2.dts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "kirkwood-linksys-viper.dts" + +/ { + model = "Linksys E4200 v2 (Viper)"; + compatible = "linksys,e4200-v2", "linksys,viper", "marvell,kirkwood-88f6282", "marvell,kirkwood"; +}; diff --git a/target/linux/kirkwood/files-5.4/arch/arm/boot/dts/kirkwood-linksys-audi.dts b/target/linux/kirkwood/files-5.4/arch/arm/boot/dts/kirkwood-ea3500.dts similarity index 96% rename from target/linux/kirkwood/files-5.4/arch/arm/boot/dts/kirkwood-linksys-audi.dts rename to target/linux/kirkwood/files-5.4/arch/arm/boot/dts/kirkwood-ea3500.dts index 90250fefc8..851f316711 100644 --- a/target/linux/kirkwood/files-5.4/arch/arm/boot/dts/kirkwood-linksys-audi.dts +++ b/target/linux/kirkwood/files-5.4/arch/arm/boot/dts/kirkwood-ea3500.dts @@ -15,8 +15,8 @@ #include "kirkwood-6282.dtsi" / { - model = "Linksys Audi (EA3500)"; - compatible = "linksys,audi", "marvell,kirkwood-88f6282", "marvell,kirkwood"; + model = "Linksys EA3500 (Audi)"; + compatible = "linksys,ea3500", "linksys,audi", "marvell,kirkwood-88f6282", "marvell,kirkwood"; memory@0 { device_type = "memory"; diff --git a/target/linux/kirkwood/files-5.4/arch/arm/boot/dts/kirkwood-ea4500.dts b/target/linux/kirkwood/files-5.4/arch/arm/boot/dts/kirkwood-ea4500.dts new file mode 100644 index 0000000000..495cff34a4 --- /dev/null +++ b/target/linux/kirkwood/files-5.4/arch/arm/boot/dts/kirkwood-ea4500.dts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "kirkwood-linksys-viper.dts" + +/ { + model = "Linksys EA4500 (Viper)"; + compatible = "linksys,ea4500", "linksys,viper", "marvell,kirkwood-88f6282", "marvell,kirkwood"; +}; diff --git a/target/linux/kirkwood/image/Makefile b/target/linux/kirkwood/image/Makefile index 6554fc2669..3a600da13c 100644 --- a/target/linux/kirkwood/image/Makefile +++ b/target/linux/kirkwood/image/Makefile @@ -96,34 +96,47 @@ define Device/iom_ix2-200 endef TARGET_DEVICES += iom_ix2-200 -define Device/linksys_audi - $(Device/dsa-migration) +define Device/linksys DEVICE_VENDOR := Linksys - DEVICE_MODEL := EA3500 (Audi) DEVICE_PACKAGES := kmod-mwl8k wpad-basic kmod-gpio-button-hotplug + KERNEL_IN_UBI := + UBINIZE_OPTS := -E 5 + IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi +endef + +define Device/linksys_e4200-v2 + $(Device/linksys) + $(Device/dsa-migration) + DEVICE_MODEL := E4200 + DEVICE_VARIANT := v2 + DEVICE_DTS := kirkwood-e4200-v2 + KERNEL_SIZE := 2688k + SUPPORTED_DEVICES += linksys,viper linksys-viper +endef +TARGET_DEVICES += linksys_e4200-v2 + +define Device/linksys_ea3500 + $(Device/linksys) + $(Device/dsa-migration) + DEVICE_MODEL := EA3500 + DEVICE_DTS := kirkwood-ea3500 PAGESIZE := 512 SUBPAGESIZE := 256 BLOCKSIZE := 16k KERNEL_SIZE := 2624k - KERNEL_IN_UBI := - UBINIZE_OPTS := -E 5 - IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi - BOARD_NAME := linksys-audi + SUPPORTED_DEVICES += linksys,audi linksys-audi endef -TARGET_DEVICES += linksys_audi +TARGET_DEVICES += linksys_ea3500 -define Device/linksys_viper +define Device/linksys_ea4500 + $(Device/linksys) $(Device/dsa-migration) - DEVICE_VENDOR := Linksys - DEVICE_MODEL := E4200v2 / EA4500 (Viper) - DEVICE_PACKAGES := kmod-mwl8k wpad-basic kmod-gpio-button-hotplug + DEVICE_MODEL := EA4500 + DEVICE_DTS := kirkwood-ea4500 KERNEL_SIZE := 2688k - KERNEL_IN_UBI := - UBINIZE_OPTS := -E 5 - IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi - BOARD_NAME := linksys-viper + SUPPORTED_DEVICES += linksys,viper linksys-viper endef -TARGET_DEVICES += linksys_viper +TARGET_DEVICES += linksys_ea4500 define Device/raidsonic_ib-nas62x0 DEVICE_VENDOR := RaidSonic diff --git a/target/linux/kirkwood/patches-5.4/105-ea4500.patch b/target/linux/kirkwood/patches-5.4/105-linksys-viper-dts.patch similarity index 100% rename from target/linux/kirkwood/patches-5.4/105-ea4500.patch rename to target/linux/kirkwood/patches-5.4/105-linksys-viper-dts.patch From caa6ada969ddf63eb753840fe9fa2acc726e5d57 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 31 Jul 2020 18:17:34 +0200 Subject: [PATCH 04/23] apm821xx: disable WNDR4700 5.4 image The compressed image that the buildbots are building is too large for the netgear uboot and it crashes and soft-bricks the device. | Uncompressing Kernel Image ... | LZMA: uncompress or overwrite error 1 - must RESET board to recover The whole target likely needs to be switched zImage which is a major hassle due to powerpc's legacy bootwrapper setup as compared to ARM. So for now, disable the device. Reported-by: Wiktor Stasiak (FS#3258) Signed-off-by: Christian Lamparter --- target/linux/apm821xx/image/nand.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/target/linux/apm821xx/image/nand.mk b/target/linux/apm821xx/image/nand.mk index 29a4be0189..845770b89f 100644 --- a/target/linux/apm821xx/image/nand.mk +++ b/target/linux/apm821xx/image/nand.mk @@ -117,5 +117,6 @@ define Device/netgear_wndr4700 NETGEAR_HW_ID := 29763875+128+256 UBINIZE_OPTS := -E 5 SUPPORTED_DEVICES += wndr4700 + DEFAULT := n endef TARGET_DEVICES += netgear_wndr4700 From 9e02580d52ef6f2ee1eb38ae4e5977bb6002a552 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 17 Jul 2020 17:01:00 +0200 Subject: [PATCH 05/23] gemini: Add swap partition to DNS-313 Sometimes when using the DNS-313 memory usage can peak and with a simple swap partition we can avoid running into the roof and invoking the OOM killer. Set this partition to 128MB (twice the size of the memory of the DNS-313). Signed-off-by: Linus Walleij --- .../linux/gemini/image/dns313_gen_hdd_img.sh | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/target/linux/gemini/image/dns313_gen_hdd_img.sh b/target/linux/gemini/image/dns313_gen_hdd_img.sh index 813852232f..d302ca6348 100755 --- a/target/linux/gemini/image/dns313_gen_hdd_img.sh +++ b/target/linux/gemini/image/dns313_gen_hdd_img.sh @@ -15,14 +15,20 @@ ROOTFSSIZE="$5" head=4 sect=63 -# Create two empty partitions followed by the boot partition with -# the ./boot/zImage and then the rootfs partition. -set $(ptgen -o $OUTPUT -h $head -s $sect -t 83 -n -p 0 -p 0 -p ${BOOTFSSIZE}M -p ${ROOTFSSIZE}M) +# Create one empty partitions followed by the swap partition, then the +# boot partition with the ./boot/zImage and then the rootfs partition. +# The swap partition with type 82 is 128 MB since the DNS-313 has 64 MB of +# memory so we assign twice of that as swap. +# The boot partition must always be the third partition. +# The user should use the first (blank) partition for user data storage, +# this will typically be named /dev/sda1 +set $(ptgen -o $OUTPUT -h $head -s $sect -n -t 83 -p 0 -t 82 -p 128M -t 83 -p ${BOOTFSSIZE}M -t 83 -p ${ROOTFSSIZE}M) -BOOTOFFSET="$(($1 / 512))" -BOOTSIZE="$(($2 / 512))" -ROOTFSOFFSET="$(($3 / 512))" -ROOTFSSIZE="$(($4 / 512))" +# Swapoffset and swapsize will be $1 and $2 +BOOTOFFSET="$(($3 / 512))" +BOOTSIZE="$(($4 / 512))" +ROOTFSOFFSET="$(($5 / 512))" +ROOTFSSIZE="$(($6 / 512))" dd bs=512 if="$BOOTFS" of="$OUTPUT" seek="$BOOTOFFSET" conv=notrunc dd bs=512 if="$ROOTFS" of="$OUTPUT" seek="$ROOTFSOFFSET" conv=notrunc From 8b3e170526cf0f1d9b15a6dd7787789d15e52cd4 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Fri, 31 Jul 2020 19:51:51 +0200 Subject: [PATCH 06/23] hostapd: fix incorrect service name When retrieving the PID for hostapd and wpa_supplicant via ubus the wrong service name is currently used. This leads to the following error in the log: netifd: radio0 (1409): WARNING (wireless_add_process): executable path /usr/sbin/wpad does not match process path (/proc/exe) Fixing the service name retrieves the correct PID and therefore the warning won't occur. Signed-off-by: David Bauer --- package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh | 2 +- package/network/services/hostapd/files/hostapd.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh index 5214704830..864b15e120 100644 --- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh @@ -993,7 +993,7 @@ drv_mac80211_setup() { add_ap=1 ubus wait_for hostapd ubus call hostapd config_add "{\"iface\":\"$primary_ap\", \"config\":\"${hostapd_conf_file}\"}" - local hostapd_pid=$(ubus call service list '{"name": "hostapd"}' | jsonfilter -l 1 -e "@['hostapd'].instances['hostapd'].pid") + local hostapd_pid=$(ubus call service list '{"name": "wpad"}' | jsonfilter -l 1 -e "@['wpad'].instances['hostapd'].pid") wireless_add_process "$hostapd_pid" "/usr/sbin/hostapd" 1 fi ret="$?" diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh index f4e2aa559c..268a41a82b 100644 --- a/package/network/services/hostapd/files/hostapd.sh +++ b/package/network/services/hostapd/files/hostapd.sh @@ -1125,7 +1125,7 @@ wpa_supplicant_run() { [ "$ret" != 0 ] && wireless_setup_vif_failed WPA_SUPPLICANT_FAILED - local supplicant_pid=$(ubus call service list '{"name": "hostapd"}' | jsonfilter -l 1 -e "@['hostapd'].instances['supplicant'].pid") + local supplicant_pid=$(ubus call service list '{"name": "wpad"}' | jsonfilter -l 1 -e "@['wpad'].instances['supplicant'].pid") wireless_add_process "$supplicant_pid" "/usr/sbin/wpa_supplicant" 1 return $ret From 68bf5a96595a8a0983842c8ff0eaa8af290adc51 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Fri, 31 Jul 2020 19:52:03 +0200 Subject: [PATCH 07/23] mac80211: don't kill wireless daemon on teardown Don't kill the wireless daemon on teardown. hostapd as well as wpa_supplicant are managed by procd which would detect the shutdown of either process as a crash loop. Signed-off-by: David Bauer --- package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh index 864b15e120..823c68170a 100644 --- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh @@ -1048,8 +1048,6 @@ list_phy_interfaces() { } drv_mac80211_teardown() { - wireless_process_kill_all - json_select data json_get_vars phy json_select .. From 9950bc92e3082c11bfc669d79fa82069d59a03da Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Fri, 31 Jul 2020 22:48:49 +0100 Subject: [PATCH 08/23] kernel: add menuconfig entry for kernel CONFIG_CGROUP_NET_CLASSID It was removed from target defaults though it didn't exist in the build-systems kernel configuration options. Add it there. Fixes: d1a8217d87 ("kernel: clean-up build-configurable kernel config symbols") Signed-off-by: Daniel Golle --- config/Config-kernel.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/Config-kernel.in b/config/Config-kernel.in index f6464b7574..fa4c8257b2 100644 --- a/config/Config-kernel.in +++ b/config/Config-kernel.in @@ -795,6 +795,10 @@ if KERNEL_CGROUPS bool "legacy Control Group Classifier" default n + config KERNEL_CGROUP_NET_CLASSID + bool "legacy Network classid cgroup" + default n + config KERNEL_CGROUP_NET_PRIO bool "legacy Network priority cgroup" default n From 1bff9f5b78f8a662f4ea6707e176ffb023cab0a3 Mon Sep 17 00:00:00 2001 From: Stijn Tintel Date: Wed, 29 Jul 2020 23:57:41 +0300 Subject: [PATCH 09/23] kernel: add missing config symbol This symbol is exposed on ARM64 with EFI enabled in the kernel config. Currently this happens only on ipq807x, but as there might be new ARM64 targets with EFI in the future it is better to add the symbol to the generic config. Signed-off-by: Stijn Tintel Acked-by: Jo-Philipp Wich --- target/linux/generic/config-4.14 | 1 + target/linux/generic/config-4.19 | 1 + target/linux/generic/config-5.4 | 1 + 3 files changed, 3 insertions(+) diff --git a/target/linux/generic/config-4.14 b/target/linux/generic/config-4.14 index fa6f239bc5..d9b90f304e 100644 --- a/target/linux/generic/config-4.14 +++ b/target/linux/generic/config-4.14 @@ -1009,6 +1009,7 @@ CONFIG_CRYPTO_PCRYPT=y # CONFIG_DEBUG_CREDENTIALS is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_EFI is not set # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set CONFIG_DEBUG_FS=y # CONFIG_DEBUG_GPIO is not set diff --git a/target/linux/generic/config-4.19 b/target/linux/generic/config-4.19 index 016c3bc6aa..a197d82cda 100644 --- a/target/linux/generic/config-4.19 +++ b/target/linux/generic/config-4.19 @@ -1067,6 +1067,7 @@ CONFIG_CRYPTO_PCRYPT=y # CONFIG_DEBUG_CREDENTIALS is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_EFI is not set # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set CONFIG_DEBUG_FS=y # CONFIG_DEBUG_GPIO is not set diff --git a/target/linux/generic/config-5.4 b/target/linux/generic/config-5.4 index 1df08c33d2..22d0594e93 100644 --- a/target/linux/generic/config-5.4 +++ b/target/linux/generic/config-5.4 @@ -1139,6 +1139,7 @@ CONFIG_CRYPTO_PCRYPT=y # CONFIG_DEBUG_CREDENTIALS is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_EFI is not set # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set CONFIG_DEBUG_FS=y # CONFIG_DEBUG_GPIO is not set From 5c3e83fa881a081d0368cf3933b30a38519aaafd Mon Sep 17 00:00:00 2001 From: Stijn Tintel Date: Sat, 1 Aug 2020 16:29:24 +0300 Subject: [PATCH 10/23] kernel: fix missing TRANSPARENT_HUGEPAGE symbols Enabling KERNEL_TRANSPARENT_HUGEPAGE exposes 2 missing symbols: * CONFIG_READ_ONLY_THP_FOR_FS * TRANSPARENT_HUGEPAGE_ALWAYS * TRANSPARENT_HUGEPAGE_MADVISE The first one was added in 5.4, and is marked experimental there so just disable it in the generic config. For the latter two, we should not force the user to use either of them, so add them as build-configurable kernel options. Fixes: d1a8217d87bf ("kernel: clean-up build-configurable kernel config symbols") Signed-off-by: Stijn Tintel --- config/Config-kernel.in | 12 ++++++++++++ target/linux/generic/config-5.4 | 1 + 2 files changed, 13 insertions(+) diff --git a/config/Config-kernel.in b/config/Config-kernel.in index fa4c8257b2..2e80c8f537 100644 --- a/config/Config-kernel.in +++ b/config/Config-kernel.in @@ -360,6 +360,18 @@ config KERNEL_BLK_DEV_BSG config KERNEL_TRANSPARENT_HUGEPAGE bool +choice + prompt "Transparent Hugepage Support sysfs defaults" + depends on KERNEL_TRANSPARENT_HUGEPAGE + default KERNEL_TRANSPARENT_HUGEPAGE_ALWAYS + + config KERNEL_TRANSPARENT_HUGEPAGE_ALWAYS + bool "always" + + config KERNEL_TRANSPARENT_HUGEPAGE_MADVISE + bool "madvise" +endchoice + config KERNEL_HUGETLBFS bool diff --git a/target/linux/generic/config-5.4 b/target/linux/generic/config-5.4 index 22d0594e93..6e49ceefca 100644 --- a/target/linux/generic/config-5.4 +++ b/target/linux/generic/config-5.4 @@ -4211,6 +4211,7 @@ CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3 # CONFIG_RD_LZO is not set # CONFIG_RD_XZ is not set # CONFIG_READABLE_ASM is not set +# CONFIG_READ_ONLY_THP_FOR_FS is not set # CONFIG_REALTEK_PHY is not set # CONFIG_REDWOOD is not set # CONFIG_REED_SOLOMON_TEST is not set From d157ee0c127c81fa70768f708c8fe58f3ca01e5c Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sat, 18 Jul 2020 21:29:57 -0700 Subject: [PATCH 11/23] staging: remove staging exfat driver This will be replaced with the driver found in newer kernels. Signed-off-by: Rosen Penev --- package/kernel/linux/modules/fs.mk | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/package/kernel/linux/modules/fs.mk b/package/kernel/linux/modules/fs.mk index 82f8685111..84dc498365 100644 --- a/package/kernel/linux/modules/fs.mk +++ b/package/kernel/linux/modules/fs.mk @@ -163,30 +163,6 @@ endef $(eval $(call KernelPackage,fs-efivarfs)) -define KernelPackage/fs-exfat - SUBMENU:=$(FS_MENU) - TITLE:=exFAT filesystem support - KCONFIG:= \ - CONFIG_EXFAT_FS \ - CONFIG_EXFAT_DONT_MOUNT_VFAT=y \ - CONFIG_EXFAT_DISCARD=y \ - CONFIG_EXFAT_DELAYED_SYNC=n \ - CONFIG_EXFAT_KERNEL_DEBUG=n \ - CONFIG_EXFAT_DEBUG_MSG=n \ - CONFIG_EXFAT_DEFAULT_CODEPAGE=437 \ - CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" - FILES:=$(LINUX_DIR)/drivers/staging/exfat/exfat.ko - AUTOLOAD:=$(call AutoLoad,30,exfat,1) - DEPENDS:=@!(LINUX_4_14||LINUX_4_19) +kmod-nls-base -endef - -define KernelPackage/fs-exfat/description - Kernel module for exFAT filesystem support -endef - -$(eval $(call KernelPackage,fs-exfat)) - - define KernelPackage/fs-exportfs SUBMENU:=$(FS_MENU) TITLE:=exportfs kernel server support From cd41234d2f63c484eeec619e0fb82ae54fe8979e Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sat, 18 Jul 2020 21:29:58 -0700 Subject: [PATCH 12/23] exfat: add out of tree module >From an email conversation with the person responsible for upstreaming the exFAT driver, it seems the staging one in kernel 5.4 is not so good. Excerpts below. Namjae Jeon: Hm... exfat in 5.4 kernel that we did crap shit long time ago is contributed by someone who we don't know. This version is unstable and low quality code. We have been improving it continuously. and staging version exfat is removed from linux 5.7 kernel. linux exfat oot version is a backport of exfat in linux 5.7 kernel to support lower version kernel, and it is a real. You can see the patch history fro linux-exfat-oot. this version support timezone and boot sector verification feature newly. and better filesystem structure and much clean code quality that reviewed by high profile kernel developers. and add many bug fixes. And this version is officially maintained by me and kernel guys. I would not recommend to use staging exfat version. Signed-off-by: Rosen Penev --- package/kernel/exfat/Makefile | 54 +++++++++++++++++++ .../kernel/exfat/patches/010-fstream.patch | 23 ++++++++ 2 files changed, 77 insertions(+) create mode 100644 package/kernel/exfat/Makefile create mode 100644 package/kernel/exfat/patches/010-fstream.patch diff --git a/package/kernel/exfat/Makefile b/package/kernel/exfat/Makefile new file mode 100644 index 0000000000..539bdfd295 --- /dev/null +++ b/package/kernel/exfat/Makefile @@ -0,0 +1,54 @@ +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=exfat +PKG_VERSION:=5.8.4 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/namjaejeon/linux-exfat-oot/tar.gz/$(PKG_VERSION)? +PKG_HASH:=47162495bdf9a7e02d6142dfcd4364d7325a4cf75a0439926cf9e8a9d959627b + +PKG_MAINTAINER:= +PKG_LICENSE:=GPL-2.0-only + +#PKG_BUILD_PARALLEL:=1 +#PKG_USE_MIPS16:=0 + +# exfat-oot's makefile needs this to know where to build the kernel module +#export KERNELDIR:=$(LINUX_DIR) + +include $(INCLUDE_DIR)/package.mk +#include $(INCLUDE_DIR)/kernel-defaults.mk + +TAR_OPTIONS+= --strip-components 1 +TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS) + +define KernelPackage/fs-exfat + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Filesystems + TITLE:=exFAT kernel module + FILES:=$(PKG_BUILD_DIR)/exfat.ko + AUTOLOAD:=$(call AutoProbe,exfat) +endef + +define KernelPackage/exfat/description + This package provides the kernel module for exfat. +endef + +define Build/Compile + $(KERNEL_MAKE) M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + $(PKG_EXTRA_KCONFIG) \ + CONFIG_EXFAT_FS=m \ + modules +# $(MAKE) -C $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION) M="$(PKG_BUILD_DIR)" modules +endef + +$(eval $(call KernelPackage,fs-exfat)) diff --git a/package/kernel/exfat/patches/010-fstream.patch b/package/kernel/exfat/patches/010-fstream.patch new file mode 100644 index 0000000000..dc1221c611 --- /dev/null +++ b/package/kernel/exfat/patches/010-fstream.patch @@ -0,0 +1,23 @@ +--- a/super.c ++++ b/super.c +@@ -292,14 +292,14 @@ static const struct fs_parameter_spec exfat_param_specs[] = { + #endif + fsparam_flag("discard", Opt_discard), + fsparam_s32("time_offset", Opt_time_offset), +- __fsparam(NULL, "utf8", Opt_utf8, fs_param_deprecated, +- NULL), +- __fsparam(NULL, "debug", Opt_debug, fs_param_deprecated, +- NULL), ++ __fsparam(NULL, "utf8", Opt_utf8, fs_param_deprecated ++ ), ++ __fsparam(NULL, "debug", Opt_debug, fs_param_deprecated ++ ), + __fsparam(fs_param_is_u32, "namecase", Opt_namecase, +- fs_param_deprecated, NULL), ++ fs_param_deprecated), + __fsparam(fs_param_is_u32, "codepage", Opt_codepage, +- fs_param_deprecated, NULL), ++ fs_param_deprecated), + {} + }; + From f2af32c20c7529650858f6804e2bfd35fe706ced Mon Sep 17 00:00:00 2001 From: Rui Salvaterra Date: Fri, 24 Jul 2020 09:02:55 +0100 Subject: [PATCH 13/23] wireguard-tools: allow compiling with MIPS16 instructions The wg utility compiles and runs without issues in MIPS16 mode, despite setting PKG_USE_MIPS16:=0 in the makefile. Let's remove this, allowing for a substantial size reduction of the wg executable. Since wg is a just a configuration utility, it shouldn't be performance-critical, as the crypto heavy-lifting is done on the kernel side. wg sizes for both modes: MIPS32: 64309 bytes MIPS16: 42501 bytes Signed-off-by: Rui Salvaterra --- package/network/utils/wireguard-tools/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/package/network/utils/wireguard-tools/Makefile b/package/network/utils/wireguard-tools/Makefile index 3232060bd1..2137a8b4a1 100644 --- a/package/network/utils/wireguard-tools/Makefile +++ b/package/network/utils/wireguard-tools/Makefile @@ -22,7 +22,6 @@ PKG_LICENSE:=GPL-2.0 PKG_LICENSE_FILES:=COPYING PKG_BUILD_PARALLEL:=1 -PKG_USE_MIPS16:=0 include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/package-defaults.mk From 9565c5726a34da7c9c953d2293b70fdbfef0e0be Mon Sep 17 00:00:00 2001 From: Rui Salvaterra Date: Sun, 26 Jul 2020 20:04:31 +0100 Subject: [PATCH 14/23] uboot-envtools: ath79: add support for the Nanostation M (XM) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tested on an AirGrid M2 (AG‑HP‑2G16). Signed-off-by: Rui Salvaterra --- package/boot/uboot-envtools/files/ath79 | 1 + 1 file changed, 1 insertion(+) diff --git a/package/boot/uboot-envtools/files/ath79 b/package/boot/uboot-envtools/files/ath79 index 5cd64f4ffd..0442e9e485 100644 --- a/package/boot/uboot-envtools/files/ath79 +++ b/package/boot/uboot-envtools/files/ath79 @@ -34,6 +34,7 @@ netgear,wnr612-v2|\ ocedo,koala|\ ocedo,raccoon|\ openmesh,om5p-ac-v2|\ +ubnt,nanostation-m|\ yuncore,a770|\ yuncore,a782|\ yuncore,xd4200) From 48a9d99a218c6d83e3337c56b6cc7592e7ad12ae Mon Sep 17 00:00:00 2001 From: Magnus Kroken Date: Mon, 27 Jul 2020 20:34:49 +0200 Subject: [PATCH 15/23] openvpn: revise sample configuration Update the openvpn sample configurations to use modern options in favor of deprecated ones, suggest more sane default settings and add some warnings. * Add tls_crypt and ncp_disable to the sample configuration * Replace nsCertType with remote_cert_tls in client sample configuration * Comment out "option compress", compression should not be preferred * Advise 2048-bit Diffie-Hellman parameters by default * Add warnings about compression and use of Blowfish (BF-CBC) Signed-off-by: Magnus Kroken --- .../services/openvpn/files/openvpn.config | 83 +++++++++++++++++-- 1 file changed, 75 insertions(+), 8 deletions(-) diff --git a/package/network/services/openvpn/files/openvpn.config b/package/network/services/openvpn/files/openvpn.config index 1fd846f558..3de1881e35 100644 --- a/package/network/services/openvpn/files/openvpn.config +++ b/package/network/services/openvpn/files/openvpn.config @@ -77,10 +77,10 @@ config openvpn sample_server # Diffie hellman parameters. # Generate your own with: - # openssl dhparam -out dh1024.pem 1024 + # openssl dhparam -out dh2048.pem 2048 # Substitute 2048 for 1024 if you are using - # 2048 bit keys. - option dh /etc/openvpn/dh1024.pem + # 1024 bit keys. + option dh /etc/openvpn/dh2048.pem # Configure server mode and supply a VPN subnet # for OpenVPN to draw client addresses from. @@ -228,10 +228,52 @@ config openvpn sample_server # This file is secret: # option tls_auth "/etc/openvpn/ta.key 0" + # For additional privacy, a shared secret key + # can be used for both authentication (as in tls_auth) + # and encryption of the TLS control channel. + # + # Generate a shared secret with: + # openvpn --genkey --secret ta.key + # + # The server and each client must have + # a copy of this key. + # + # tls_auth and tls_crypt should NOT + # be combined, as tls_crypt implies tls_auth. + # Use EITHER tls_crypt, tls_auth, or neither option. +# option tls_crypt "/etc/openvpn/ta.key" + + # Set the minimum required TLS protocol version + # for all connections. + # + # Require at least TLS 1.1 +# option tls_version_min "1.1" + # Require at least TLS 1.2 +# option tls_version_min "1.2" + # Require TLS 1.2, or the highest version supported + # on the system +# option tls_version_min "1.2 'or-highest'" + + # OpenVPN versions 2.4 and later will attempt to + # automatically negotiate the most secure cipher + # between the client and server, regardless of a + # configured "option cipher" (see below). + # Automatic negotiation is recommended. + # + # Uncomment this option to disable this behavior, + # and force all OpenVPN peers to use the configured + # cipher option instead (not recommended). +# option ncp_disable + # Select a cryptographic cipher. # This config item must be copied to # the client config file as well. - # Blowfish (default): + # + # To see all supported ciphers, run: + # openvpn --show-ciphers + # + # Blowfish (default for backwards compatibility, + # but not recommended due to weaknesses): # option cipher BF-CBC # AES: # option cipher AES-128-CBC @@ -241,11 +283,16 @@ config openvpn sample_server # Enable compression on the VPN link. # If you enable it here, you must also # enable it in the client config file. + # + # Compression is not recommended, as compression and + # encryption in combination can weaken the security + # of the connection. + # # LZ4 requires OpenVPN 2.4+ client and server # option compress lz4 # LZO is compatible with most OpenVPN versions # (set "compress lzo" on 2.4+ clients, and "comp-lzo yes" on older clients) - option compress lzo +# option compress lzo # The maximum number of concurrently connected # clients we want to allow. @@ -371,7 +418,7 @@ config openvpn sample_client option key /etc/openvpn/client.key # Verify server certificate by checking - # that the certicate has the nsCertType + # that the certicate has the key usage # field set to "server". This is an # important precaution to protect against # a potential attack discussed here: @@ -381,12 +428,27 @@ config openvpn sample_client # your server certificates with the nsCertType # field set to "server". The build_key_server # script in the easy_rsa folder will do this. -# option ns_cert_type server +# option remote_cert_tls server # If a tls_auth key is used on the server # then every client must also have the key. # option tls_auth "/etc/openvpn/ta.key 1" + # If a tls_crypt key is used on the server + # every client must also have the key. +# option tls_crypt "/etc/openvpn/ta.key" + + # Set the minimum required TLS protocol version + # for all connections. + # + # Require at least TLS 1.1 +# option tls_version_min "1.1" + # Require at least TLS 1.2 +# option tls_version_min "1.2" + # Require TLS 1.2, or the highest version supported + # on the system +# option tls_version_min "1.2 'or-highest'" + # Select a cryptographic cipher. # If the cipher option is used on the server # then you must also specify it here. @@ -395,10 +457,15 @@ config openvpn sample_client # Enable compression on the VPN link. # Don't enable this unless it is also # enabled in the server config file. + # + # Compression is not recommended, as compression and + # encryption in combination can weaken the security + # of the connection. + # # LZ4 requires OpenVPN 2.4+ on server and client # option compress lz4 # LZO is compatible with most OpenVPN versions - option compress lzo +# option compress lzo # Set log file verbosity. option verb 3 From 8a8ef4ed86ed5af9600ad7560102295c7a35b7de Mon Sep 17 00:00:00 2001 From: Adrian Schmutzler Date: Sat, 1 Aug 2020 17:39:33 +0200 Subject: [PATCH 16/23] ath79/mikrotik: create shared device definitions for nor and nand Move the image preparation and nand-utils package selection into common device definitions for NOR/NAND devices. Signed-off-by: Adrian Schmutzler --- target/linux/ath79/image/common-mikrotik.mk | 14 ++++++++++++++ target/linux/ath79/image/mikrotik.mk | 18 +++++------------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/target/linux/ath79/image/common-mikrotik.mk b/target/linux/ath79/image/common-mikrotik.mk index c21800011b..9ac89fdcb1 100644 --- a/target/linux/ath79/image/common-mikrotik.mk +++ b/target/linux/ath79/image/common-mikrotik.mk @@ -4,3 +4,17 @@ define Device/mikrotik KERNEL := kernel-bin | append-dtb | lzma | loader-kernel KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-kernel endef + +define Device/mikrotik_nor + $(Device/mikrotik) + IMAGE/sysupgrade.bin := append-kernel | kernel2minor -s 1024 -e | \ + pad-to $$$$(BLOCKSIZE) | append-rootfs | pad-rootfs | \ + append-metadata | check-size +endef + +define Device/mikrotik_nand + $(Device/mikrotik) + IMAGE/sysupgrade.bin = append-kernel | kernel2minor -s 2048 -e -c | \ + sysupgrade-tar kernel=$$$$@ | append-metadata + DEVICE_PACKAGES := nand-utils +endef diff --git a/target/linux/ath79/image/mikrotik.mk b/target/linux/ath79/image/mikrotik.mk index b0bd05a81c..a3506bd514 100644 --- a/target/linux/ath79/image/mikrotik.mk +++ b/target/linux/ath79/image/mikrotik.mk @@ -1,36 +1,28 @@ include ./common-mikrotik.mk define Device/mikrotik_routerboard-493g - $(Device/mikrotik) + $(Device/mikrotik_nand) SOC := ar7161 DEVICE_MODEL := RouterBOARD 493G - IMAGE/sysupgrade.bin = append-kernel | kernel2minor -s 2048 -e -c | \ - sysupgrade-tar kernel=$$$$@ | append-metadata - DEVICE_PACKAGES += kmod-usb-ohci kmod-usb2 nand-utils + DEVICE_PACKAGES += kmod-usb-ohci kmod-usb2 SUPPORTED_DEVICES += rb-493g endef TARGET_DEVICES += mikrotik_routerboard-493g define Device/mikrotik_routerboard-922uags-5hpacd - $(Device/mikrotik) + $(Device/mikrotik_nand) SOC := qca9558 DEVICE_MODEL := RouterBOARD 922UAGS-5HPacD - IMAGE/sysupgrade.bin = append-kernel | kernel2minor -s 2048 -e -c | \ - sysupgrade-tar kernel=$$$$@ | append-metadata - DEVICE_PACKAGES += kmod-ath10k-ct ath10k-firmware-qca988x-ct \ - kmod-usb2 nand-utils + DEVICE_PACKAGES += kmod-ath10k-ct ath10k-firmware-qca988x-ct kmod-usb2 SUPPORTED_DEVICES += rb-922uags-5hpacd endef TARGET_DEVICES += mikrotik_routerboard-922uags-5hpacd define Device/mikrotik_routerboard-wap-g-5hact2hnd - $(Device/mikrotik) + $(Device/mikrotik_nor) SOC := qca9556 DEVICE_MODEL := RouterBOARD wAP G-5HacT2HnD (wAP AC) IMAGE_SIZE := 16256k - IMAGE/sysupgrade.bin := append-kernel | kernel2minor -s 1024 -e | \ - pad-to $$$$(BLOCKSIZE) | append-rootfs | pad-rootfs | \ - append-metadata | check-size DEVICE_PACKAGES += kmod-ath10k-ct-smallbuffers ath10k-firmware-qca988x-ct SUPPORTED_DEVICES += rb-wapg-5hact2hnd endef From d0113711a31f00c9c95c33e8a5e290425b63bde6 Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Wed, 15 Jul 2020 22:19:37 -1000 Subject: [PATCH 17/23] README: port to 21st century The README is no longer important to only developers but also users. Reflect that by adding valuable information for everyone new to OpenWrt! Sunshine Signed-off-by: Paul Spooren [remove trailing whitespace and empty line at EOF] Signed-off-by: Adrian Schmutzler --- README | 34 --- README.md | 87 ++++++++ logo.svg | 610 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 697 insertions(+), 34 deletions(-) delete mode 100644 README create mode 100644 README.md create mode 100644 logo.svg diff --git a/README b/README deleted file mode 100644 index c867c1fa4d..0000000000 --- a/README +++ /dev/null @@ -1,34 +0,0 @@ - _______ ________ __ - | |.-----.-----.-----.| | | |.----.| |_ - | - || _ | -__| || | | || _|| _| - |_______|| __|_____|__|__||________||__| |____| - |__| W I R E L E S S F R E E D O M - ----------------------------------------------------- - -This is the buildsystem for the OpenWrt Linux distribution. - -To build your own firmware you need a Linux, BSD or MacOSX system (case -sensitive filesystem required). Cygwin is unsupported because of the lack -of a case sensitive file system. - -You need gcc, binutils, bzip2, flex, python3.5+, perl, make, find, grep, diff, -unzip, gawk, getopt, subversion, libz-dev and libc headers installed. - -1. Run "./scripts/feeds update -a" to obtain all the latest package definitions -defined in feeds.conf / feeds.conf.default - -2. Run "./scripts/feeds install -a" to install symlinks for all obtained -packages into package/feeds/ - -3. Run "make menuconfig" to select your preferred configuration for the -toolchain, target system & firmware packages. - -4. Run "make" to build your firmware. This will download all sources, build -the cross-compile toolchain and then cross-compile the Linux kernel & all -chosen applications for your target system. - -Sunshine! - Your OpenWrt Community - http://www.openwrt.org - - diff --git a/README.md b/README.md new file mode 100644 index 0000000000..652fe9cd44 --- /dev/null +++ b/README.md @@ -0,0 +1,87 @@ +![OpenWrt logo](/logo.svg) + +OpenWrt Project is a Linux operating system targeting embedded devices. Instead +of trying to create a single, static firmware, OpenWrt provides a fully +writable filesystem with package management. This frees you from the +application selection and configuration provided by the vendor and allows you +to customize the device through the use of packages to suit any application. +For developers, OpenWrt is the framework to build an application without having +to build a complete firmware around it; for users this means the ability for +full customization, to use the device in ways never envisioned. + +Sunshine! + +## Development + +To build your own firmware you need a GNU/Linux, BSD or MacOSX system (case +sensitive filesystem required). Cygwin is unsupported because of the lack of a +case sensitive file system. + +### Requirements + +You need the following tools to compile OpenWrt, the package names vary between +distributions. A complete list with distribution specific packages is found in +the [Build System Setup](https://openwrt.org/docs/guide-developer/build-system/install-buildsystem) +documentation. + +``` +gcc binutils bzip2 flex python3 perl make find grep diff unzip gawk getopt +subversion libz-dev libc-dev +``` + +### Quickstart + +1. Run `./scripts/feeds update -a` to obtain all the latest package definitions + defined in feeds.conf / feeds.conf.default + +2. Run `./scripts/feeds install -a` to install symlinks for all obtained + packages into package/feeds/ + +3. Run `make menuconfig` to select your preferred configuration for the + toolchain, target system & firmware packages. + +4. Run `make` to build your firmware. This will download all sources, build the + cross-compile toolchain and then cross-compile the GNU/Linux kernel & all chosen + applications for your target system. + +### Related Repositories + +The main repository uses multiple sub-repositories to manage packages of +different categories. All packages are installed via the OpenWrt package +manager called `opkg`. If you're looking to develop the web interface or port +packages to OpenWrt, please find the fitting repository below. + +* [LuCI Web Interface](https://github.com/openwrt/luci): Modern and modular + interface to control the device via a web browser. + +* [OpenWrt Packages](https://github.com/openwrt/packages): Community repository + of ported packages. + +* [OpenWrt Routing](https://github.com/openwrt-routing/packages): Packages + specifically focused on (mesh) routing. + +## Support Information + +For a list of supported devices see the [OpenWrt Hardware Database](https://openwrt.org/supported_devices) + +### Documentation + +* [Quick Start Guide](https://openwrt.org/docs/guide-quick-start/start) +* [User Guide](https://openwrt.org/docs/guide-user/start) +* [Developer Documentation](https://openwrt.org/docs/guide-developer/start) +* [Technical Reference](https://openwrt.org/docs/techref/start) + +### Support Community + +* [Forum](https://forum.openwrt.org): For usage, projects, discussions and hardware advise. +* [Support Chat](https://webchat.freenode.net/#openwrt): Channel `#openwrt` on freenode.net. + +### Developer Community + +* [Bug Reports](https://bugs.openwrt.org): Report bugs in OpenWrt +* [Dev Mailing List](https://lists.openwrt.org/mailman/listinfo/openwrt-devel): Send patches +* [Dev Chat](https://webchat.freenode.net/#openwrt-devel): Channel `#openwrt-devel` on freenode.net. + +## License + +OpenWrt is licensed under GPL-2.0 diff --git a/logo.svg b/logo.svg new file mode 100644 index 0000000000..50628c89b9 --- /dev/null +++ b/logo.svg @@ -0,0 +1,610 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From b99623329c07712c30b5ad2e0f3b3dffe3ed97c2 Mon Sep 17 00:00:00 2001 From: Adrian Schmutzler Date: Sun, 2 Aug 2020 15:51:39 +0200 Subject: [PATCH 18/23] scripts/checkpatch.pl: fix README.md file name after rename checkpatch.pl uses a list of files to detect the root OpenWrt directory. This includes README, which has been renamed to README.md in the previous commit. Update the file name in checkpatch.pl to prevent errors like the following when running the script: Must be run from the top-level dir. of a OpenWrt tree Signed-off-by: Adrian Schmutzler --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 5224ea49c3..24793e19d8 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -391,7 +391,7 @@ sub top_of_openwrt_tree { my ($root) = @_; my @tree_check = ( - "BSDmakefile", "Config.in", "LICENSE", "Makefile", "README", + "BSDmakefile", "Config.in", "LICENSE", "Makefile", "README.md", "feeds.conf.default", "include", "package", "rules.mk", "scripts", "target", "toolchain", "tools" ); From 8d131986552b9b492fd98a02280803a44f3fda20 Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Tue, 28 Jul 2020 23:32:28 -1000 Subject: [PATCH 19/23] LICENSE: use updated GNU copy The current LICENSE file contains some form feed (FF) characters instead of recently popular line feed (LF) characters. Also update to the latest address of the Free Software Foundation. Lastly center some captions, as suggested by the official GNU LICENSE distribution[0]. Historical changes of GPL-2.0 LICENSE file are availalbe[1]. [0]: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt [1]: https://github.com/pombredanne/gpl-history Signed-off-by: Paul Spooren --- LICENSE | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/LICENSE b/LICENSE index d60c31a97a..d159169d10 100644 --- a/LICENSE +++ b/LICENSE @@ -1,12 +1,12 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - Preamble + Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to +the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not @@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. - - GNU GENERAL PUBLIC LICENSE + + GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains @@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions: License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) - + These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in @@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. - + 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is @@ -225,7 +225,7 @@ impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. - + 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License @@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY + NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN @@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it @@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. @@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names: This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General +library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. From 93d37fad86312850450c45b56ff5367c0009ff7a Mon Sep 17 00:00:00 2001 From: Adrian Schmutzler Date: Wed, 29 Jul 2020 21:00:11 +0200 Subject: [PATCH 20/23] build: image: drop unused check-kernel-size recipe The recipe check-kernel-size is not used in the entire tree. Instead, we already check the size of the kernel image in Device/Build/kernel in image.mk via check-size function if KERNEL_SIZE is defined. Therefore, drop the function. Using it would be redundant anyway. Signed-off-by: Adrian Schmutzler --- include/image-commands.mk | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/image-commands.mk b/include/image-commands.mk index 7a370034c8..9281b91990 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -275,13 +275,6 @@ define Build/check-size } endef -define Build/check-kernel-size - @[ $$(($(subst k,* 1024,$(subst m, * 1024k,$(1))))) -ge "$$(stat -c%s $(IMAGE_KERNEL))" ] || { \ - echo "WARNING: Kernel for $@ is too big > $(1)" >&2; \ - rm -f $@; \ - } -endef - define Build/combined-image -sh $(TOPDIR)/scripts/combined-image.sh \ "$(IMAGE_KERNEL)" \ From 43896dc0b005adfb512c027a27781c971440d415 Mon Sep 17 00:00:00 2001 From: Sungbo Eo Date: Sun, 12 Jan 2020 21:33:53 +0900 Subject: [PATCH 21/23] Revert "ar71xx: fix Arduino Yun enabling of level shifters outputs" This reverts commit 077253dd666a30ae5231c3748222d4b5b138593d. The output enable pins should be disabled by default, and only enabled when used. Otherwise unwanted conflicts might occur between MCU and SoC pins. Signed-off-by: Sungbo Eo --- target/linux/ar71xx/files/arch/mips/ath79/mach-arduino-yun.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-arduino-yun.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-arduino-yun.c index e92f68f490..5873248edf 100644 --- a/target/linux/ar71xx/files/arch/mips/ath79/mach-arduino-yun.c +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-arduino-yun.c @@ -141,7 +141,7 @@ static void __init ds_setup(void) // enable OE of level shifter if (gpio_request_one(DS_GPIO_OE, - GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, "OE-1") != 0) + GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, "OE-1") != 0) printk("Error setting GPIO OE\n"); if (gpio_request_one(DS_GPIO_UART_ENA, @@ -150,7 +150,7 @@ static void __init ds_setup(void) // enable OE of level shifter if (gpio_request_one(DS_GPIO_OE2, - GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, "OE-2") != 0) + GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, "OE-2") != 0) printk("Error setting GPIO OE2\n"); } From 58dc1d0637425cfe023192466e6212009332b677 Mon Sep 17 00:00:00 2001 From: Sungbo Eo Date: Sun, 12 Jan 2020 21:35:00 +0900 Subject: [PATCH 22/23] ar71xx: fix sysupgrade for Arduino Yun Commit bb46b635df48 changed its partition scheme, but sysupgrade image validation still uses the old format. This commit fixes it so that force flag is not needed for sysupgrade. Fixes: bb46b635df48 ("ar71xx: move Arduino Yun to generic building code") Signed-off-by: Sungbo Eo --- target/linux/ar71xx/base-files/lib/upgrade/platform.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh index eb812865db..2391a1de8a 100755 --- a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh +++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh @@ -217,6 +217,7 @@ platform_check_image() { archer-c60-v2|\ archer-c7-v4|\ archer-c7-v5|\ + arduino-yun|\ bullet-m|\ bullet-m-xw|\ c-55|\ @@ -346,7 +347,6 @@ platform_check_image() { ap152|\ ap91-5g|\ ap96|\ - arduino-yun|\ bhr-4grv2|\ bxu2000n-2-a1|\ db120|\ From a5e404d1923d135d335e4ece83f87e6e891396e2 Mon Sep 17 00:00:00 2001 From: Sungbo Eo Date: Sun, 12 Jan 2020 21:35:00 +0900 Subject: [PATCH 23/23] ar71xx: enable ethernet LED of Arduino Yun Commit 05d73a2a7379 enabled GPIO on ethernet LED, but proper LED setup was not added then. This commit fixes it by reverting the change on the LED. Fixes: 05d73a2a7379 ("ar71xx: Arduino Yun board 'WLAN RST' button support") Signed-off-by: Sungbo Eo --- target/linux/ar71xx/files/arch/mips/ath79/mach-arduino-yun.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-arduino-yun.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-arduino-yun.c index 5873248edf..8ab07d514b 100644 --- a/target/linux/ar71xx/files/arch/mips/ath79/mach-arduino-yun.c +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-arduino-yun.c @@ -117,8 +117,7 @@ static void __init ds_setup(void) ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | - AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | - AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); + AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN); //Disable the Function for some pins to have GPIO functionality active // GPIO6-7-8 and GPIO11