diff options
Diffstat (limited to 'arch/x86/net/bpf_jit_comp.c')
| -rw-r--r-- | arch/x86/net/bpf_jit_comp.c | 28 |
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 */ |
