bpf_jit_asm_64.S 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #include <asm/ptrace.h>
  3. #include "bpf_jit_64.h"
  4. #define SAVE_SZ 176
  5. #define SCRATCH_OFF STACK_BIAS + 128
  6. #define BE_PTR(label) be,pn %xcc, label
  7. #define SIGN_EXTEND(reg) sra reg, 0, reg
  8. #define SKF_MAX_NEG_OFF (-0x200000) /* SKF_LL_OFF from filter.h */
  9. .text
  10. .globl bpf_jit_load_word
  11. bpf_jit_load_word:
  12. cmp r_OFF, 0
  13. bl bpf_slow_path_word_neg
  14. nop
  15. .globl bpf_jit_load_word_positive_offset
  16. bpf_jit_load_word_positive_offset:
  17. sub r_HEADLEN, r_OFF, r_TMP
  18. cmp r_TMP, 3
  19. ble bpf_slow_path_word
  20. add r_SKB_DATA, r_OFF, r_TMP
  21. andcc r_TMP, 3, %g0
  22. bne load_word_unaligned
  23. nop
  24. retl
  25. ld [r_TMP], r_RESULT
  26. load_word_unaligned:
  27. ldub [r_TMP + 0x0], r_OFF
  28. ldub [r_TMP + 0x1], r_TMP2
  29. sll r_OFF, 8, r_OFF
  30. or r_OFF, r_TMP2, r_OFF
  31. ldub [r_TMP + 0x2], r_TMP2
  32. sll r_OFF, 8, r_OFF
  33. or r_OFF, r_TMP2, r_OFF
  34. ldub [r_TMP + 0x3], r_TMP2
  35. sll r_OFF, 8, r_OFF
  36. retl
  37. or r_OFF, r_TMP2, r_RESULT
  38. .globl bpf_jit_load_half
  39. bpf_jit_load_half:
  40. cmp r_OFF, 0
  41. bl bpf_slow_path_half_neg
  42. nop
  43. .globl bpf_jit_load_half_positive_offset
  44. bpf_jit_load_half_positive_offset:
  45. sub r_HEADLEN, r_OFF, r_TMP
  46. cmp r_TMP, 1
  47. ble bpf_slow_path_half
  48. add r_SKB_DATA, r_OFF, r_TMP
  49. andcc r_TMP, 1, %g0
  50. bne load_half_unaligned
  51. nop
  52. retl
  53. lduh [r_TMP], r_RESULT
  54. load_half_unaligned:
  55. ldub [r_TMP + 0x0], r_OFF
  56. ldub [r_TMP + 0x1], r_TMP2
  57. sll r_OFF, 8, r_OFF
  58. retl
  59. or r_OFF, r_TMP2, r_RESULT
  60. .globl bpf_jit_load_byte
  61. bpf_jit_load_byte:
  62. cmp r_OFF, 0
  63. bl bpf_slow_path_byte_neg
  64. nop
  65. .globl bpf_jit_load_byte_positive_offset
  66. bpf_jit_load_byte_positive_offset:
  67. cmp r_OFF, r_HEADLEN
  68. bge bpf_slow_path_byte
  69. nop
  70. retl
  71. ldub [r_SKB_DATA + r_OFF], r_RESULT
  72. #define bpf_slow_path_common(LEN) \
  73. save %sp, -SAVE_SZ, %sp; \
  74. mov %i0, %o0; \
  75. mov %i1, %o1; \
  76. add %fp, SCRATCH_OFF, %o2; \
  77. call skb_copy_bits; \
  78. mov (LEN), %o3; \
  79. cmp %o0, 0; \
  80. restore;
  81. bpf_slow_path_word:
  82. bpf_slow_path_common(4)
  83. bl bpf_error
  84. ld [%sp + SCRATCH_OFF], r_RESULT
  85. retl
  86. nop
  87. bpf_slow_path_half:
  88. bpf_slow_path_common(2)
  89. bl bpf_error
  90. lduh [%sp + SCRATCH_OFF], r_RESULT
  91. retl
  92. nop
  93. bpf_slow_path_byte:
  94. bpf_slow_path_common(1)
  95. bl bpf_error
  96. ldub [%sp + SCRATCH_OFF], r_RESULT
  97. retl
  98. nop
  99. #define bpf_negative_common(LEN) \
  100. save %sp, -SAVE_SZ, %sp; \
  101. mov %i0, %o0; \
  102. mov %i1, %o1; \
  103. SIGN_EXTEND(%o1); \
  104. call bpf_internal_load_pointer_neg_helper; \
  105. mov (LEN), %o2; \
  106. mov %o0, r_TMP; \
  107. cmp %o0, 0; \
  108. BE_PTR(bpf_error); \
  109. restore;
  110. bpf_slow_path_word_neg:
  111. sethi %hi(SKF_MAX_NEG_OFF), r_TMP
  112. cmp r_OFF, r_TMP
  113. bl bpf_error
  114. nop
  115. .globl bpf_jit_load_word_negative_offset
  116. bpf_jit_load_word_negative_offset:
  117. bpf_negative_common(4)
  118. andcc r_TMP, 3, %g0
  119. bne load_word_unaligned
  120. nop
  121. retl
  122. ld [r_TMP], r_RESULT
  123. bpf_slow_path_half_neg:
  124. sethi %hi(SKF_MAX_NEG_OFF), r_TMP
  125. cmp r_OFF, r_TMP
  126. bl bpf_error
  127. nop
  128. .globl bpf_jit_load_half_negative_offset
  129. bpf_jit_load_half_negative_offset:
  130. bpf_negative_common(2)
  131. andcc r_TMP, 1, %g0
  132. bne load_half_unaligned
  133. nop
  134. retl
  135. lduh [r_TMP], r_RESULT
  136. bpf_slow_path_byte_neg:
  137. sethi %hi(SKF_MAX_NEG_OFF), r_TMP
  138. cmp r_OFF, r_TMP
  139. bl bpf_error
  140. nop
  141. .globl bpf_jit_load_byte_negative_offset
  142. bpf_jit_load_byte_negative_offset:
  143. bpf_negative_common(1)
  144. retl
  145. ldub [r_TMP], r_RESULT
  146. bpf_error:
  147. /* Make the JIT program itself return zero. */
  148. ret
  149. restore %g0, %g0, %o0