1/* bpf_jit.S : BPF JIT helper functions 2 * 3 * Copyright (C) 2011 Eric Dumazet (eric.dumazet@gmail.com) 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; version 2 8 * of the License. 9 */ 10#include <linux/linkage.h> 11#include <asm/dwarf2.h> 12 13/* 14 * Calling convention : 15 * rdi : skb pointer 16 * esi : offset of byte(s) to fetch in skb (can be scratched) 17 * r8 : copy of skb->data 18 * r9d : hlen = skb->len - skb->data_len 19 */ 20#define SKBDATA %r8 21 22sk_load_word_ind: 23 .globl sk_load_word_ind 24 25 add %ebx,%esi /* offset += X */ 26# test %esi,%esi /* if (offset < 0) goto bpf_error; */ 27 js bpf_error 28 29sk_load_word: 30 .globl sk_load_word 31 32 mov %r9d,%eax # hlen 33 sub %esi,%eax # hlen - offset 34 cmp $3,%eax 35 jle bpf_slow_path_word 36 mov (SKBDATA,%rsi),%eax 37 bswap %eax /* ntohl() */ 38 ret 39 40 41sk_load_half_ind: 42 .globl sk_load_half_ind 43 44 add %ebx,%esi /* offset += X */ 45 js bpf_error 46 47sk_load_half: 48 .globl sk_load_half 49 50 mov %r9d,%eax 51 sub %esi,%eax # hlen - offset 52 cmp $1,%eax 53 jle bpf_slow_path_half 54 movzwl (SKBDATA,%rsi),%eax 55 rol $8,%ax # ntohs() 56 ret 57 58sk_load_byte_ind: 59 .globl sk_load_byte_ind 60 add %ebx,%esi /* offset += X */ 61 js bpf_error 62 63sk_load_byte: 64 .globl sk_load_byte 65 66 cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte */ 67 jle bpf_slow_path_byte 68 movzbl (SKBDATA,%rsi),%eax 69 ret 70 71/** 72 * sk_load_byte_msh - BPF_S_LDX_B_MSH helper 73 * 74 * Implements BPF_S_LDX_B_MSH : ldxb 4*([offset]&0xf) 75 * Must preserve A accumulator (%eax) 76 * Inputs : %esi is the offset value, already known positive 77 */ 78ENTRY(sk_load_byte_msh) 79 CFI_STARTPROC 80 cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte_msh */ 81 jle bpf_slow_path_byte_msh 82 movzbl (SKBDATA,%rsi),%ebx 83 and $15,%bl 84 shl $2,%bl 85 ret 86 CFI_ENDPROC 87ENDPROC(sk_load_byte_msh) 88 89bpf_error: 90# force a return 0 from jit handler 91 xor %eax,%eax 92 mov -8(%rbp),%rbx 93 leaveq 94 ret 95 96/* rsi contains offset and can be scratched */ 97#define bpf_slow_path_common(LEN) \ 98 push %rdi; /* save skb */ \ 99 push %r9; \ 100 push SKBDATA; \ 101/* rsi already has offset */ \ 102 mov $LEN,%ecx; /* len */ \ 103 lea -12(%rbp),%rdx; \ 104 call skb_copy_bits; \ 105 test %eax,%eax; \ 106 pop SKBDATA; \ 107 pop %r9; \ 108 pop %rdi 109 110 111bpf_slow_path_word: 112 bpf_slow_path_common(4) 113 js bpf_error 114 mov -12(%rbp),%eax 115 bswap %eax 116 ret 117 118bpf_slow_path_half: 119 bpf_slow_path_common(2) 120 js bpf_error 121 mov -12(%rbp),%ax 122 rol $8,%ax 123 movzwl %ax,%eax 124 ret 125 126bpf_slow_path_byte: 127 bpf_slow_path_common(1) 128 js bpf_error 129 movzbl -12(%rbp),%eax 130 ret 131 132bpf_slow_path_byte_msh: 133 xchg %eax,%ebx /* dont lose A , X is about to be scratched */ 134 bpf_slow_path_common(1) 135 js bpf_error 136 movzbl -12(%rbp),%eax 137 and $15,%al 138 shl $2,%al 139 xchg %eax,%ebx 140 ret 141