bpf_jit.S 3.4 KB

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