bpf_jit.S 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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. * rdi : skb pointer
  15. * esi : offset of byte(s) to fetch in skb (can be scratched)
  16. * r8 : copy of skb->data
  17. * r9d : hlen = skb->len - skb->data_len
  18. */
  19. #define SKBDATA %r8
  20. sk_load_word_ind:
  21. .globl sk_load_word_ind
  22. add %ebx,%esi /* offset += X */
  23. # test %esi,%esi /* if (offset < 0) goto bpf_error; */
  24. js bpf_error
  25. sk_load_word:
  26. .globl sk_load_word
  27. mov %r9d,%eax # hlen
  28. sub %esi,%eax # hlen - offset
  29. cmp $3,%eax
  30. jle bpf_slow_path_word
  31. mov (SKBDATA,%rsi),%eax
  32. bswap %eax /* ntohl() */
  33. ret
  34. sk_load_half_ind:
  35. .globl sk_load_half_ind
  36. add %ebx,%esi /* offset += X */
  37. js bpf_error
  38. sk_load_half:
  39. .globl sk_load_half
  40. mov %r9d,%eax
  41. sub %esi,%eax # hlen - offset
  42. cmp $1,%eax
  43. jle bpf_slow_path_half
  44. movzwl (SKBDATA,%rsi),%eax
  45. rol $8,%ax # ntohs()
  46. ret
  47. sk_load_byte_ind:
  48. .globl sk_load_byte_ind
  49. add %ebx,%esi /* offset += X */
  50. js bpf_error
  51. sk_load_byte:
  52. .globl sk_load_byte
  53. cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte */
  54. jle bpf_slow_path_byte
  55. movzbl (SKBDATA,%rsi),%eax
  56. ret
  57. /**
  58. * sk_load_byte_msh - BPF_S_LDX_B_MSH helper
  59. *
  60. * Implements BPF_S_LDX_B_MSH : ldxb 4*([offset]&0xf)
  61. * Must preserve A accumulator (%eax)
  62. * Inputs : %esi is the offset value, already known positive
  63. */
  64. ENTRY(sk_load_byte_msh)
  65. CFI_STARTPROC
  66. cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte_msh */
  67. jle bpf_slow_path_byte_msh
  68. movzbl (SKBDATA,%rsi),%ebx
  69. and $15,%bl
  70. shl $2,%bl
  71. ret
  72. CFI_ENDPROC
  73. ENDPROC(sk_load_byte_msh)
  74. bpf_error:
  75. # force a return 0 from jit handler
  76. xor %eax,%eax
  77. mov -8(%rbp),%rbx
  78. leaveq
  79. ret
  80. /* rsi contains offset and can be scratched */
  81. #define bpf_slow_path_common(LEN) \
  82. push %rdi; /* save skb */ \
  83. push %r9; \
  84. push SKBDATA; \
  85. /* rsi already has offset */ \
  86. mov $LEN,%ecx; /* len */ \
  87. lea -12(%rbp),%rdx; \
  88. call skb_copy_bits; \
  89. test %eax,%eax; \
  90. pop SKBDATA; \
  91. pop %r9; \
  92. pop %rdi
  93. bpf_slow_path_word:
  94. bpf_slow_path_common(4)
  95. js bpf_error
  96. mov -12(%rbp),%eax
  97. bswap %eax
  98. ret
  99. bpf_slow_path_half:
  100. bpf_slow_path_common(2)
  101. js bpf_error
  102. mov -12(%rbp),%ax
  103. rol $8,%ax
  104. movzwl %ax,%eax
  105. ret
  106. bpf_slow_path_byte:
  107. bpf_slow_path_common(1)
  108. js bpf_error
  109. movzbl -12(%rbp),%eax
  110. ret
  111. bpf_slow_path_byte_msh:
  112. xchg %eax,%ebx /* dont lose A , X is about to be scratched */
  113. bpf_slow_path_common(1)
  114. js bpf_error
  115. movzbl -12(%rbp),%eax
  116. and $15,%al
  117. shl $2,%al
  118. xchg %eax,%ebx
  119. ret