summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2015-10-02 09:48:57 +0200
committerRalf Baechle <ralf@linux-mips.org>2015-10-02 09:48:57 +0200
commit0c5d187828588dd1b36cb93b4481a8db467ef3e8 (patch)
tree899cdb3b4b6e2b99718d7916296bcfbffc853846
parent1e16a8f11669c98a0adf5fb5f8522aebc1f69f71 (diff)
MIPS: BPF: Fix load delay slots.
The entire bpf_jit_asm.S is written in noreorder mode because "we know better" according to a comment. This also prevented the assembler from throwing in the required NOPs for MIPS I processors which have no load-use interlock, thus the load's consumer might end up using the old value of the register from prior to the load. Fixed by putting the assembler in reorder mode for just the affected load instructions. This is not enough for gas to actually try to be clever by looking at the next instruction and inserting a nop only when needed but as the comment said "we know better", so getting gas to unconditionally emit a NOP is just right in this case and prevents adding further ifdefery. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/net/bpf_jit_asm.S4
1 files changed, 4 insertions, 0 deletions
diff --git a/arch/mips/net/bpf_jit_asm.S b/arch/mips/net/bpf_jit_asm.S
index eabb5e0889ee..5d2e0c8d29c0 100644
--- a/arch/mips/net/bpf_jit_asm.S
+++ b/arch/mips/net/bpf_jit_asm.S
@@ -61,7 +61,9 @@ 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 defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
wsbh t0, $r_A
@@ -88,7 +90,9 @@ FEXPORT(sk_load_half_positive)
is_offset_in_header(2, half)
/* Offset within header boundaries */
PTR_ADDU t1, $r_skb_data, offset
+ .set reorder
lh $r_A, 0(t1)
+ .set noreorder
#ifdef CONFIG_CPU_LITTLE_ENDIAN
# if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
wsbh t0, $r_A