aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/net/bpf_jit.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-05-12 09:56:30 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-05-12 09:56:30 -0700
commitac3c4aa248c5b5390c40fad1ceb0a15a53f57a36 (patch)
treea7b09cc6d8a9ec28bfb7d2ab7d280dd8e61bfb5e /arch/mips/net/bpf_jit.c
parent0ba1c1950c320fcfdfe3dbc7470884e4a390083c (diff)
parent3e441845caf1c9591b5b961f34ff1a37d023c9e2 (diff)
downloadlinux-ac3c4aa248c5b5390c40fad1ceb0a15a53f57a36.tar.gz
linux-ac3c4aa248c5b5390c40fad1ceb0a15a53f57a36.tar.bz2
linux-ac3c4aa248c5b5390c40fad1ceb0a15a53f57a36.zip
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from James Hogan: "math-emu: - Add missing clearing of BLTZALL and BGEZALL emulation counters - Fix BC1EQZ and BC1NEZ condition handling - Fix BLEZL and BGTZL identification BPF: - Add JIT support for SKF_AD_HATYPE - Use unsigned access for unsigned SKB fields - Quit clobbering callee saved registers in JIT code - Fix multiple problems in JIT skb access helpers Loongson 3: - Select MIPS_L1_CACHE_SHIFT_6 Octeon: - Remove vestiges of CONFIG_CAVIUM_OCTEON_2ND_KERNEL - Remove unused L2C types and macros. - Remove unused SLI types and macros. - Fix compile error when USB is not enabled. - Octeon: Remove unused PCIERCX types and macros. - Octeon: Clean up platform code. SNI: - Remove recursive include of cpu-feature-overrides.h Sibyte: - Export symbol periph_rev to sb1250-mac network driver. - Fix Kconfig warning. Generic platform: - Enable Root FS on NFS in generic_defconfig SMP-MT: - Use CPU interrupt controller IPI IRQ domain support UASM: - Add support for LHU for uasm. - Remove needless ISA abstraction mm: - Add 48-bit VA space and 4-level page tables for 4K pages. PCI: - Add controllers before the specified head irqchip driver for MIPS CPU: - Replace magic 0x100 with IE_SW0 - Prepare for non-legacy IRQ domains - Introduce IPI IRQ domain support MAINTAINERS: - Update email-id of Rahul Bedarkar NET: - sb1250-mac: Add missing MODULE_LICENSE() CPUFREQ: - Loongson2: drop set_cpus_allowed_ptr() Misc: - Disable Werror when W= is set - Opt into HAVE_COPY_THREAD_TLS - Enable GENERIC_CPU_AUTOPROBE - Use common outgoing-CPU-notification code - Remove dead define of ST_OFF - Remove CONFIG_ARCH_HAS_ILOG2_U{32,64} - Stengthen IPI IRQ domain sanity check - Remove confusing else statement in __do_page_fault() - Don't unnecessarily include kmalloc.h into <asm/cache.h>. - Delete unused definition of SMP_CACHE_SHIFT. - Delete redundant definition of SMP_CACHE_BYTES" * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (39 commits) MIPS: Sibyte: Fix Kconfig warning. MIPS: Sibyte: Export symbol periph_rev to sb1250-mac network driver. NET: sb1250-mac: Add missing MODULE_LICENSE() MAINTAINERS: Update email-id of Rahul Bedarkar MIPS: Remove confusing else statement in __do_page_fault() MIPS: Stengthen IPI IRQ domain sanity check MIPS: smp-mt: Use CPU interrupt controller IPI IRQ domain support irqchip: mips-cpu: Introduce IPI IRQ domain support irqchip: mips-cpu: Prepare for non-legacy IRQ domains irqchip: mips-cpu: Replace magic 0x100 with IE_SW0 MIPS: Remove CONFIG_ARCH_HAS_ILOG2_U{32,64} MIPS: generic: Enable Root FS on NFS in generic_defconfig MIPS: mach-rm: Remove recursive include of cpu-feature-overrides.h MIPS: Opt into HAVE_COPY_THREAD_TLS CPUFREQ: Loongson2: drop set_cpus_allowed_ptr() MIPS: uasm: Remove needless ISA abstraction MIPS: Remove dead define of ST_OFF MIPS: Use common outgoing-CPU-notification code MIPS: math-emu: Fix BC1EQZ and BC1NEZ condition handling MIPS: r2-on-r6-emu: Clear BLTZALL and BGEZALL debugfs counters ...
Diffstat (limited to 'arch/mips/net/bpf_jit.c')
-rw-r--r--arch/mips/net/bpf_jit.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c
index 49a2e2226fee..44b925005dd3 100644
--- a/arch/mips/net/bpf_jit.c
+++ b/arch/mips/net/bpf_jit.c
@@ -365,6 +365,12 @@ static inline void emit_half_load(unsigned int reg, unsigned int base,
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)
{
@@ -526,7 +532,8 @@ static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset)
u32 sflags, tmp_flags;
/* Adjust the stack pointer */
- emit_stack_offset(-align_sp(offset), ctx);
+ if (offset)
+ emit_stack_offset(-align_sp(offset), ctx);
tmp_flags = sflags = ctx->flags >> SEEN_SREG_SFT;
/* sflags is essentially a bitmap */
@@ -578,7 +585,8 @@ static void restore_bpf_jit_regs(struct jit_ctx *ctx,
emit_load_stack_reg(r_ra, r_sp, real_off, ctx);
/* Restore the sp and discard the scrach memory */
- emit_stack_offset(align_sp(offset), ctx);
+ if (offset)
+ emit_stack_offset(align_sp(offset), ctx);
}
static unsigned int get_stack_depth(struct jit_ctx *ctx)
@@ -625,8 +633,14 @@ static void build_prologue(struct jit_ctx *ctx)
if (ctx->flags & SEEN_X)
emit_jit_reg_move(r_X, r_zero, ctx);
- /* Do not leak kernel data to userspace */
- if (bpf_needs_clear_a(&ctx->skf->insns[0]))
+ /*
+ * 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);
}
@@ -1112,6 +1126,8 @@ jmp_cmp:
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 */
@@ -1120,10 +1136,15 @@ jmp_cmp:
emit_bcond(MIPS_COND_EQ, r_s0, r_zero,
b_imm(prog->len, ctx), ctx);
emit_reg_move(r_ret, r_zero, ctx);
- BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
- ifindex) != 4);
- off = offsetof(struct net_device, ifindex);
- emit_load(r_A, r_s0, off, 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;
@@ -1143,7 +1164,7 @@ jmp_cmp:
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
vlan_tci) != 2);
off = offsetof(struct sk_buff, vlan_tci);
- emit_half_load(r_s0, r_skb, off, ctx);
+ emit_half_load_unsigned(r_s0, r_skb, off, ctx);
if (code == (BPF_ANC | SKF_AD_VLAN_TAG)) {
emit_andi(r_A, r_s0, (u16)~VLAN_TAG_PRESENT, ctx);
} else {
@@ -1170,7 +1191,7 @@ jmp_cmp:
BUILD_BUG_ON(offsetof(struct sk_buff,
queue_mapping) > 0xff);
off = offsetof(struct sk_buff, queue_mapping);
- emit_half_load(r_A, r_skb, off, ctx);
+ emit_half_load_unsigned(r_A, r_skb, off, ctx);
break;
default:
pr_debug("%s: Unhandled opcode: 0x%02x\n", __FILE__,