diff options
Diffstat (limited to 'arch/x86/net/bpf_jit_comp.c')
| -rw-r--r-- | arch/x86/net/bpf_jit_comp.c | 14 | 
1 files changed, 10 insertions, 4 deletions
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 26328e800869..4ed75dd81d05 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -359,15 +359,21 @@ void bpf_jit_compile(struct sk_filter *fp)  				EMIT2(0x89, 0xd0);	/* mov %edx,%eax */  				break;  			case BPF_S_ALU_MOD_K: /* A %= K; */ +				if (K == 1) { +					CLEAR_A(); +					break; +				}  				EMIT2(0x31, 0xd2);	/* xor %edx,%edx */  				EMIT1(0xb9);EMIT(K, 4);	/* mov imm32,%ecx */  				EMIT2(0xf7, 0xf1);	/* div %ecx */  				EMIT2(0x89, 0xd0);	/* mov %edx,%eax */  				break; -			case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */ -				EMIT3(0x48, 0x69, 0xc0); /* imul imm32,%rax,%rax */ -				EMIT(K, 4); -				EMIT4(0x48, 0xc1, 0xe8, 0x20); /* shr $0x20,%rax */ +			case BPF_S_ALU_DIV_K: /* A /= K */ +				if (K == 1) +					break; +				EMIT2(0x31, 0xd2);	/* xor %edx,%edx */ +				EMIT1(0xb9);EMIT(K, 4);	/* mov imm32,%ecx */ +				EMIT2(0xf7, 0xf1);	/* div %ecx */  				break;  			case BPF_S_ALU_AND_X:  				seen |= SEEN_XREG;  |