Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions arch/x86/net/bpf_jit_comp32.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,8 @@ static inline void emit_ia32_to_be_r64(const u8 dst[], s32 val,
* dst = dst (div|mod) src
*/
static inline void emit_ia32_div_mod_r(const u8 op, const u8 dst, const u8 src,
bool dstk, bool sstk, u8 **pprog)
bool dstk, bool sstk, bool is_signed,
u8 **pprog)
{
u8 *prog = *pprog;
int cnt = 0;
Expand All @@ -454,10 +455,17 @@ static inline void emit_ia32_div_mod_r(const u8 op, const u8 dst, const u8 src,
/* mov eax,dst */
EMIT2(0x8B, add_2reg(0xC0, dst, IA32_EAX));

/* xor edx,edx */
EMIT2(0x31, add_2reg(0xC0, IA32_EDX, IA32_EDX));
/* div ecx */
EMIT2(0xF7, add_1reg(0xF0, IA32_ECX));
if (is_signed) {
/* cdq */
EMIT1(0x99);
/* idiv ecx */
EMIT2(0xF7, add_1reg(0xF8, IA32_ECX));
} else {
/* xor edx,edx */
EMIT2(0x31, add_2reg(0xC0, IA32_EDX, IA32_EDX));
/* div ecx */
EMIT2(0xF7, add_1reg(0xF0, IA32_ECX));
}

if (op == BPF_MOD) {
if (dstk)
Expand Down Expand Up @@ -1796,15 +1804,16 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
switch (BPF_SRC(code)) {
case BPF_X:
emit_ia32_div_mod_r(BPF_OP(code), dst_lo,
src_lo, dstk, sstk, &prog);
src_lo, dstk, sstk,
insn->off == 1, &prog);
break;
case BPF_K:
/* mov ecx,imm32*/
EMIT2_off32(0xC7, add_1reg(0xC0, IA32_ECX),
imm32);
emit_ia32_div_mod_r(BPF_OP(code), dst_lo,
IA32_ECX, dstk, false,
&prog);
insn->off == 1, &prog);
break;
}
if (!bpf_prog->aux->verifier_zext)
Expand Down
Loading