|
@@ -45,7 +45,7 @@ struct bpf_jit {
|
|
int labels[1]; /* Labels for local jumps */
|
|
int labels[1]; /* Labels for local jumps */
|
|
};
|
|
};
|
|
|
|
|
|
-#define BPF_SIZE_MAX 4096 /* Max size for program */
|
|
|
|
|
|
+#define BPF_SIZE_MAX 0x7ffff /* Max size for program (20 bit signed displ) */
|
|
|
|
|
|
#define SEEN_SKB 1 /* skb access */
|
|
#define SEEN_SKB 1 /* skb access */
|
|
#define SEEN_MEM 2 /* use mem[] for temporary storage */
|
|
#define SEEN_MEM 2 /* use mem[] for temporary storage */
|
|
@@ -203,15 +203,6 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
|
|
_EMIT6(op1 | __disp, op2); \
|
|
_EMIT6(op1 | __disp, op2); \
|
|
})
|
|
})
|
|
|
|
|
|
-#define EMIT6_DISP(op1, op2, b1, b2, b3, disp) \
|
|
|
|
-({ \
|
|
|
|
- _EMIT6_DISP(op1 | reg(b1, b2) << 16 | \
|
|
|
|
- reg_high(b3) << 8, op2, disp); \
|
|
|
|
- REG_SET_SEEN(b1); \
|
|
|
|
- REG_SET_SEEN(b2); \
|
|
|
|
- REG_SET_SEEN(b3); \
|
|
|
|
-})
|
|
|
|
-
|
|
|
|
#define _EMIT6_DISP_LH(op1, op2, disp) \
|
|
#define _EMIT6_DISP_LH(op1, op2, disp) \
|
|
({ \
|
|
({ \
|
|
u32 _disp = (u32) disp; \
|
|
u32 _disp = (u32) disp; \
|
|
@@ -981,8 +972,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
|
|
REG_SET_SEEN(BPF_REG_5);
|
|
REG_SET_SEEN(BPF_REG_5);
|
|
jit->seen |= SEEN_FUNC;
|
|
jit->seen |= SEEN_FUNC;
|
|
/* lg %w1,<d(imm)>(%l) */
|
|
/* lg %w1,<d(imm)>(%l) */
|
|
- EMIT6_DISP(0xe3000000, 0x0004, REG_W1, REG_0, REG_L,
|
|
|
|
- EMIT_CONST_U64(func));
|
|
|
|
|
|
+ EMIT6_DISP_LH(0xe3000000, 0x0004, REG_W1, REG_0, REG_L,
|
|
|
|
+ EMIT_CONST_U64(func));
|
|
/* basr %r14,%w1 */
|
|
/* basr %r14,%w1 */
|
|
EMIT2(0x0d00, REG_14, REG_W1);
|
|
EMIT2(0x0d00, REG_14, REG_W1);
|
|
/* lgr %b0,%r2: load return value into %b0 */
|
|
/* lgr %b0,%r2: load return value into %b0 */
|