1
2
3
4
5
6
7
8 #include <asm/ppc_asm.h>
9 #include <asm/asm-compat.h>
10 #include "bpf_jit32.h"
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 .globl sk_load_word
33 sk_load_word:
34 PPC_LCMPI r_addr, 0
35 blt bpf_slow_path_word_neg
36 .globl sk_load_word_positive_offset
37 sk_load_word_positive_offset:
38
39 subi r_scratch1, r_HL, 4
40 PPC_LCMP r_scratch1, r_addr
41 blt bpf_slow_path_word
42
43 #ifdef __LITTLE_ENDIAN__
44 lwbrx r_A, r_D, r_addr
45 #else
46 lwzx r_A, r_D, r_addr
47 #endif
48 blr
49
50 .globl sk_load_half
51 sk_load_half:
52 PPC_LCMPI r_addr, 0
53 blt bpf_slow_path_half_neg
54 .globl sk_load_half_positive_offset
55 sk_load_half_positive_offset:
56 subi r_scratch1, r_HL, 2
57 PPC_LCMP r_scratch1, r_addr
58 blt bpf_slow_path_half
59 #ifdef __LITTLE_ENDIAN__
60 lhbrx r_A, r_D, r_addr
61 #else
62 lhzx r_A, r_D, r_addr
63 #endif
64 blr
65
66 .globl sk_load_byte
67 sk_load_byte:
68 PPC_LCMPI r_addr, 0
69 blt bpf_slow_path_byte_neg
70 .globl sk_load_byte_positive_offset
71 sk_load_byte_positive_offset:
72 PPC_LCMP r_HL, r_addr
73 ble bpf_slow_path_byte
74 lbzx r_A, r_D, r_addr
75 blr
76
77
78
79
80
81 .globl sk_load_byte_msh
82 sk_load_byte_msh:
83 PPC_LCMPI r_addr, 0
84 blt bpf_slow_path_byte_msh_neg
85 .globl sk_load_byte_msh_positive_offset
86 sk_load_byte_msh_positive_offset:
87 PPC_LCMP r_HL, r_addr
88 ble bpf_slow_path_byte_msh
89 lbzx r_X, r_D, r_addr
90 rlwinm r_X, r_X, 2, 32-4-2, 31-2
91 blr
92
93
94
95
96
97
98
99 #define bpf_slow_path_common(SIZE) \
100 mflr r0; \
101 PPC_STL r0, PPC_LR_STKOFF(r1); \
102 \
103 PPC_STL r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1); \
104 PPC_STL r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1); \
105 PPC_STL r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1); \
106 addi r5, r1, BPF_PPC_STACK_BASIC+(2*REG_SZ); \
107 PPC_STLU r1, -BPF_PPC_SLOWPATH_FRAME(r1); \
108 \
109 mr r4, r_addr; \
110 li r6, SIZE; \
111 bl skb_copy_bits; \
112 nop; \
113 \
114 addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \
115 PPC_LL r0, PPC_LR_STKOFF(r1); \
116 PPC_LL r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1); \
117 PPC_LL r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1); \
118 mtlr r0; \
119 PPC_LCMPI r3, 0; \
120 blt bpf_error; \
121 PPC_LL r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1); \
122
123
124 bpf_slow_path_word:
125 bpf_slow_path_common(4)
126
127 lwz r_A, BPF_PPC_STACK_BASIC+(2*REG_SZ)(r1)
128 blr
129
130 bpf_slow_path_half:
131 bpf_slow_path_common(2)
132 lhz r_A, BPF_PPC_STACK_BASIC+(2*8)(r1)
133 blr
134
135 bpf_slow_path_byte:
136 bpf_slow_path_common(1)
137 lbz r_A, BPF_PPC_STACK_BASIC+(2*8)(r1)
138 blr
139
140 bpf_slow_path_byte_msh:
141 bpf_slow_path_common(1)
142 lbz r_X, BPF_PPC_STACK_BASIC+(2*8)(r1)
143 rlwinm r_X, r_X, 2, 32-4-2, 31-2
144 blr
145
146
147
148
149
150
151
152 #define sk_negative_common(SIZE) \
153 mflr r0; \
154 PPC_STL r0, PPC_LR_STKOFF(r1); \
155 \
156 PPC_STL r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1); \
157 PPC_STL r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1); \
158 PPC_STL r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1); \
159 PPC_STLU r1, -BPF_PPC_SLOWPATH_FRAME(r1); \
160 \
161 mr r4, r_addr; \
162 li r5, SIZE; \
163 bl bpf_internal_load_pointer_neg_helper; \
164 nop; \
165 \
166 addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \
167 PPC_LL r0, PPC_LR_STKOFF(r1); \
168 PPC_LL r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1); \
169 PPC_LL r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1); \
170 mtlr r0; \
171 PPC_LCMPLI r3, 0; \
172 beq bpf_error_slow; \
173 mr r_addr, r3; \
174 PPC_LL r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1); \
175
176
177 bpf_slow_path_word_neg:
178 lis r_scratch1,-32
179 PPC_LCMP r_addr, r_scratch1
180 blt bpf_error
181 .globl sk_load_word_negative_offset
182 sk_load_word_negative_offset:
183 sk_negative_common(4)
184 lwz r_A, 0(r_addr)
185 blr
186
187 bpf_slow_path_half_neg:
188 lis r_scratch1,-32
189 PPC_LCMP r_addr, r_scratch1
190 blt bpf_error
191 .globl sk_load_half_negative_offset
192 sk_load_half_negative_offset:
193 sk_negative_common(2)
194 lhz r_A, 0(r_addr)
195 blr
196
197 bpf_slow_path_byte_neg:
198 lis r_scratch1,-32
199 PPC_LCMP r_addr, r_scratch1
200 blt bpf_error
201 .globl sk_load_byte_negative_offset
202 sk_load_byte_negative_offset:
203 sk_negative_common(1)
204 lbz r_A, 0(r_addr)
205 blr
206
207 bpf_slow_path_byte_msh_neg:
208 lis r_scratch1,-32
209 PPC_LCMP r_addr, r_scratch1
210 blt bpf_error
211 .globl sk_load_byte_msh_negative_offset
212 sk_load_byte_msh_negative_offset:
213 sk_negative_common(1)
214 lbz r_X, 0(r_addr)
215 rlwinm r_X, r_X, 2, 32-4-2, 31-2
216 blr
217
218 bpf_error_slow:
219
220 li r_scratch1, -1
221 PPC_LCMPI r_scratch1, 0
222 bpf_error:
223
224 li r3, 0
225
226 blr