aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/net/bpf_jit_comp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/net/bpf_jit_comp.c')
-rw-r--r--arch/x86/net/bpf_jit_comp.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 987514396c1e..99f76103c6b7 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -559,6 +559,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
559 if (is_ereg(dst_reg)) 559 if (is_ereg(dst_reg))
560 EMIT1(0x41); 560 EMIT1(0x41);
561 EMIT3(0xC1, add_1reg(0xC8, dst_reg), 8); 561 EMIT3(0xC1, add_1reg(0xC8, dst_reg), 8);
562
563 /* emit 'movzwl eax, ax' */
564 if (is_ereg(dst_reg))
565 EMIT3(0x45, 0x0F, 0xB7);
566 else
567 EMIT2(0x0F, 0xB7);
568 EMIT1(add_2reg(0xC0, dst_reg, dst_reg));
562 break; 569 break;
563 case 32: 570 case 32:
564 /* emit 'bswap eax' to swap lower 4 bytes */ 571 /* emit 'bswap eax' to swap lower 4 bytes */
@@ -577,6 +584,27 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
577 break; 584 break;
578 585
579 case BPF_ALU | BPF_END | BPF_FROM_LE: 586 case BPF_ALU | BPF_END | BPF_FROM_LE:
587 switch (imm32) {
588 case 16:
589 /* emit 'movzwl eax, ax' to zero extend 16-bit
590 * into 64 bit
591 */
592 if (is_ereg(dst_reg))
593 EMIT3(0x45, 0x0F, 0xB7);
594 else
595 EMIT2(0x0F, 0xB7);
596 EMIT1(add_2reg(0xC0, dst_reg, dst_reg));
597 break;
598 case 32:
599 /* emit 'mov eax, eax' to clear upper 32-bits */
600 if (is_ereg(dst_reg))
601 EMIT1(0x45);
602 EMIT2(0x89, add_2reg(0xC0, dst_reg, dst_reg));
603 break;
604 case 64:
605 /* nop */
606 break;
607 }
580 break; 608 break;
581 609
582 /* ST: *(u8*)(dst_reg + off) = imm */ 610 /* ST: *(u8*)(dst_reg + off) = imm */