bpf_jit.S 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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. * Calling convention :
  14. * rbx : skb pointer (callee saved)
  15. * esi : offset of byte(s) to fetch in skb (can be scratched)
  16. * r10 : copy of skb->data
  17. * r9d : hlen = skb->len - skb->data_len
  18. */
  19. #define SKBDATA %r10
  20. #define SKF_MAX_NEG_OFF $(-0x200000) /* SKF_LL_OFF from filter.h */
  21. #define MAX_BPF_STACK (512 /* from filter.h */ + \
  22. 32 /* space for rbx,r13,r14,r15 */ + \
  23. 8 /* space for skb_copy_bits */)
  24. sk_load_word:
  25. .globl sk_load_word
  26. test %esi,%esi
  27. js bpf_slow_path_word_neg
  28. sk_load_word_positive_offset:
  29. .globl sk_load_word_positive_offset
  30. mov %r9d,%eax # hlen
  31. sub %esi,%eax # hlen - offset
  32. cmp $3,%eax
  33. jle bpf_slow_path_word
  34. mov (SKBDATA,%rsi),%eax
  35. bswap %eax /* ntohl() */
  36. ret
  37. sk_load_half:
  38. .globl sk_load_half
  39. test %esi,%esi
  40. js bpf_slow_path_half_neg
  41. sk_load_half_positive_offset:
  42. .globl sk_load_half_positive_offset
  43. mov %r9d,%eax
  44. sub %esi,%eax # hlen - offset
  45. cmp $1,%eax
  46. jle bpf_slow_path_half
  47. movzwl (SKBDATA,%rsi),%eax
  48. rol $8,%ax # ntohs()
  49. ret
  50. sk_load_byte:
  51. .globl sk_load_byte
  52. test %esi,%esi
  53. js bpf_slow_path_byte_neg
  54. sk_load_byte_positive_offset:
  55. .globl sk_load_byte_positive_offset
  56. cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte */
  57. jle bpf_slow_path_byte
  58. movzbl (SKBDATA,%rsi),%eax
  59. ret
  60. /* rsi contains offset and can be scratched */
  61. #define bpf_slow_path_common(LEN) \
  62. mov %rbx, %rdi; /* arg1 == skb */ \
  63. push %r9; \
  64. push SKBDATA; \
  65. /* rsi already has offset */ \
  66. mov $LEN,%ecx; /* len */ \
  67. lea - MAX_BPF_STACK + 32(%rbp),%rdx; \
  68. call skb_copy_bits; \
  69. test %eax,%eax; \
  70. pop SKBDATA; \
  71. pop %r9;
  72. bpf_slow_path_word:
  73. bpf_slow_path_common(4)
  74. js bpf_error
  75. mov - MAX_BPF_STACK + 32(%rbp),%eax
  76. bswap %eax
  77. ret
  78. bpf_slow_path_half:
  79. bpf_slow_path_common(2)
  80. js bpf_error
  81. mov - MAX_BPF_STACK + 32(%rbp),%ax
  82. rol $8,%ax
  83. movzwl %ax,%eax
  84. ret
  85. bpf_slow_path_byte:
  86. bpf_slow_path_common(1)
  87. js bpf_error
  88. movzbl - MAX_BPF_STACK + 32(%rbp),%eax
  89. ret
  90. #define sk_negative_common(SIZE) \
  91. mov %rbx, %rdi; /* arg1 == skb */ \
  92. push %r9; \
  93. push SKBDATA; \
  94. /* rsi already has offset */ \
  95. mov $SIZE,%edx; /* size */ \
  96. call bpf_internal_load_pointer_neg_helper; \
  97. test %rax,%rax; \
  98. pop SKBDATA; \
  99. pop %r9; \
  100. jz bpf_error
  101. bpf_slow_path_word_neg:
  102. cmp SKF_MAX_NEG_OFF, %esi /* test range */
  103. jl bpf_error /* offset lower -> error */
  104. sk_load_word_negative_offset:
  105. .globl sk_load_word_negative_offset
  106. sk_negative_common(4)
  107. mov (%rax), %eax
  108. bswap %eax
  109. ret
  110. bpf_slow_path_half_neg:
  111. cmp SKF_MAX_NEG_OFF, %esi
  112. jl bpf_error
  113. sk_load_half_negative_offset:
  114. .globl sk_load_half_negative_offset
  115. sk_negative_common(2)
  116. mov (%rax),%ax
  117. rol $8,%ax
  118. movzwl %ax,%eax
  119. ret
  120. bpf_slow_path_byte_neg:
  121. cmp SKF_MAX_NEG_OFF, %esi
  122. jl bpf_error
  123. sk_load_byte_negative_offset:
  124. .globl sk_load_byte_negative_offset
  125. sk_negative_common(1)
  126. movzbl (%rax), %eax
  127. ret
  128. bpf_error:
  129. # force a return 0 from jit handler
  130. xor %eax,%eax
  131. mov - MAX_BPF_STACK(%rbp),%rbx
  132. mov - MAX_BPF_STACK + 8(%rbp),%r13
  133. mov - MAX_BPF_STACK + 16(%rbp),%r14
  134. mov - MAX_BPF_STACK + 24(%rbp),%r15
  135. leaveq
  136. ret