summaryrefslogtreecommitdiffstats
path: root/arch/sparc/net/bpf_jit_asm.S
diff options
context:
space:
mode:
authorAlexei Starovoitov2014-09-23 22:50:10 +0200
committerDavid S. Miller2014-09-24 21:04:07 +0200
commit35607b02dbef304fa5037236a3b43c1d8ab2aa52 (patch)
treec219ac28ef9d9691122fb445be7a6dfbcf120a3d /arch/sparc/net/bpf_jit_asm.S
parentMerge tag 'master-2014-09-23' of git://git.kernel.org/pub/scm/linux/kernel/gi... (diff)
downloadkernel-qcow2-linux-35607b02dbef304fa5037236a3b43c1d8ab2aa52.tar.gz
kernel-qcow2-linux-35607b02dbef304fa5037236a3b43c1d8ab2aa52.tar.xz
kernel-qcow2-linux-35607b02dbef304fa5037236a3b43c1d8ab2aa52.zip
sparc: bpf_jit: fix loads from negative offsets
- fix BPF_LD|ABS|IND from negative offsets: make sure to sign extend lower 32 bits in 64-bit register before calling C helpers from JITed code, otherwise 'int k' argument of bpf_internal_load_pointer_neg_helper() function will be added as large unsigned integer, causing packet size check to trigger and abort the program. It's worth noting that JITed code for 'A = A op K' will affect upper 32 bits differently depending whether K is simm13 or not. Since small constants are sign extended, whereas large constants are stored in temp register and zero extended. That is ok and we don't have to pay a penalty of sign extension for every sethi, since all classic BPF instructions have 32-bit semantics and we only need to set correct upper bits when transitioning from JITed code into C. - though instructions 'A &= 0' and 'A *= 0' are odd, JIT compiler should not optimize them out Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/net/bpf_jit_asm.S')
-rw-r--r--arch/sparc/net/bpf_jit_asm.S3
1 files changed, 3 insertions, 0 deletions
diff --git a/arch/sparc/net/bpf_jit_asm.S b/arch/sparc/net/bpf_jit_asm.S
index 9d016c7017f7..8c83f4b8eb15 100644
--- a/arch/sparc/net/bpf_jit_asm.S
+++ b/arch/sparc/net/bpf_jit_asm.S
@@ -6,10 +6,12 @@
#define SAVE_SZ 176
#define SCRATCH_OFF STACK_BIAS + 128
#define BE_PTR(label) be,pn %xcc, label
+#define SIGN_EXTEND(reg) sra reg, 0, reg
#else
#define SAVE_SZ 96
#define SCRATCH_OFF 72
#define BE_PTR(label) be label
+#define SIGN_EXTEND(reg)
#endif
#define SKF_MAX_NEG_OFF (-0x200000) /* SKF_LL_OFF from filter.h */
@@ -135,6 +137,7 @@ bpf_slow_path_byte_msh:
save %sp, -SAVE_SZ, %sp; \
mov %i0, %o0; \
mov r_OFF, %o1; \
+ SIGN_EXTEND(%o1); \
call bpf_internal_load_pointer_neg_helper; \
mov (LEN), %o2; \
mov %o0, r_TMP; \