| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* bpf_jit_comp.c: BPF JIT compiler |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation |
|---|
| 4 | 5 | * |
|---|
| 5 | 6 | * Based on the x86 BPF compiler, by Eric Dumazet (eric.dumazet@gmail.com) |
|---|
| 6 | 7 | * Ported to ppc32 by Denis Kirjanov <kda@linux-powerpc.org> |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or |
|---|
| 9 | | - * modify it under the terms of the GNU General Public License |
|---|
| 10 | | - * as published by the Free Software Foundation; version 2 |
|---|
| 11 | | - * of the License. |
|---|
| 12 | 8 | */ |
|---|
| 13 | 9 | #include <linux/moduleloader.h> |
|---|
| 14 | 10 | #include <asm/cacheflush.h> |
|---|
| .. | .. |
|---|
| 65 | 61 | PPC_LWZ_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, |
|---|
| 66 | 62 | data_len)); |
|---|
| 67 | 63 | PPC_LWZ_OFFS(r_HL, r_skb, offsetof(struct sk_buff, len)); |
|---|
| 68 | | - PPC_SUB(r_HL, r_HL, r_scratch1); |
|---|
| 64 | + EMIT(PPC_RAW_SUB(r_HL, r_HL, r_scratch1)); |
|---|
| 69 | 65 | PPC_LL_OFFS(r_D, r_skb, offsetof(struct sk_buff, data)); |
|---|
| 70 | 66 | } |
|---|
| 71 | 67 | |
|---|
| .. | .. |
|---|
| 74 | 70 | * TODO: Could also detect whether first instr. sets X and |
|---|
| 75 | 71 | * avoid this (as below, with A). |
|---|
| 76 | 72 | */ |
|---|
| 77 | | - PPC_LI(r_X, 0); |
|---|
| 73 | + EMIT(PPC_RAW_LI(r_X, 0)); |
|---|
| 78 | 74 | } |
|---|
| 79 | 75 | |
|---|
| 80 | 76 | /* make sure we dont leak kernel information to user */ |
|---|
| 81 | 77 | if (bpf_needs_clear_a(&filter[0])) |
|---|
| 82 | | - PPC_LI(r_A, 0); |
|---|
| 78 | + EMIT(PPC_RAW_LI(r_A, 0)); |
|---|
| 83 | 79 | } |
|---|
| 84 | 80 | |
|---|
| 85 | 81 | static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) |
|---|
| .. | .. |
|---|
| 87 | 83 | int i; |
|---|
| 88 | 84 | |
|---|
| 89 | 85 | if (ctx->seen & (SEEN_MEM | SEEN_DATAREF)) { |
|---|
| 90 | | - PPC_ADDI(1, 1, BPF_PPC_STACKFRAME); |
|---|
| 86 | + EMIT(PPC_RAW_ADDI(1, 1, BPF_PPC_STACKFRAME)); |
|---|
| 91 | 87 | if (ctx->seen & SEEN_DATAREF) { |
|---|
| 92 | 88 | PPC_BPF_LL(0, 1, PPC_LR_STKOFF); |
|---|
| 93 | | - PPC_MTLR(0); |
|---|
| 89 | + EMIT(PPC_RAW_MTLR(0)); |
|---|
| 94 | 90 | PPC_BPF_LL(r_D, 1, -(REG_SZ*(32-r_D))); |
|---|
| 95 | 91 | PPC_BPF_LL(r_HL, 1, -(REG_SZ*(32-r_HL))); |
|---|
| 96 | 92 | } |
|---|
| .. | .. |
|---|
| 104 | 100 | } |
|---|
| 105 | 101 | /* The RETs have left a return value in R3. */ |
|---|
| 106 | 102 | |
|---|
| 107 | | - PPC_BLR(); |
|---|
| 103 | + EMIT(PPC_RAW_BLR()); |
|---|
| 108 | 104 | } |
|---|
| 109 | 105 | |
|---|
| 110 | 106 | #define CHOOSE_LOAD_FUNC(K, func) \ |
|---|
| .. | .. |
|---|
| 138 | 134 | /*** ALU ops ***/ |
|---|
| 139 | 135 | case BPF_ALU | BPF_ADD | BPF_X: /* A += X; */ |
|---|
| 140 | 136 | ctx->seen |= SEEN_XREG; |
|---|
| 141 | | - PPC_ADD(r_A, r_A, r_X); |
|---|
| 137 | + EMIT(PPC_RAW_ADD(r_A, r_A, r_X)); |
|---|
| 142 | 138 | break; |
|---|
| 143 | 139 | case BPF_ALU | BPF_ADD | BPF_K: /* A += K; */ |
|---|
| 144 | 140 | if (!K) |
|---|
| 145 | 141 | break; |
|---|
| 146 | | - PPC_ADDI(r_A, r_A, IMM_L(K)); |
|---|
| 142 | + EMIT(PPC_RAW_ADDI(r_A, r_A, IMM_L(K))); |
|---|
| 147 | 143 | if (K >= 32768) |
|---|
| 148 | | - PPC_ADDIS(r_A, r_A, IMM_HA(K)); |
|---|
| 144 | + EMIT(PPC_RAW_ADDIS(r_A, r_A, IMM_HA(K))); |
|---|
| 149 | 145 | break; |
|---|
| 150 | 146 | case BPF_ALU | BPF_SUB | BPF_X: /* A -= X; */ |
|---|
| 151 | 147 | ctx->seen |= SEEN_XREG; |
|---|
| 152 | | - PPC_SUB(r_A, r_A, r_X); |
|---|
| 148 | + EMIT(PPC_RAW_SUB(r_A, r_A, r_X)); |
|---|
| 153 | 149 | break; |
|---|
| 154 | 150 | case BPF_ALU | BPF_SUB | BPF_K: /* A -= K */ |
|---|
| 155 | 151 | if (!K) |
|---|
| 156 | 152 | break; |
|---|
| 157 | | - PPC_ADDI(r_A, r_A, IMM_L(-K)); |
|---|
| 153 | + EMIT(PPC_RAW_ADDI(r_A, r_A, IMM_L(-K))); |
|---|
| 158 | 154 | if (K >= 32768) |
|---|
| 159 | | - PPC_ADDIS(r_A, r_A, IMM_HA(-K)); |
|---|
| 155 | + EMIT(PPC_RAW_ADDIS(r_A, r_A, IMM_HA(-K))); |
|---|
| 160 | 156 | break; |
|---|
| 161 | 157 | case BPF_ALU | BPF_MUL | BPF_X: /* A *= X; */ |
|---|
| 162 | 158 | ctx->seen |= SEEN_XREG; |
|---|
| 163 | | - PPC_MULW(r_A, r_A, r_X); |
|---|
| 159 | + EMIT(PPC_RAW_MULW(r_A, r_A, r_X)); |
|---|
| 164 | 160 | break; |
|---|
| 165 | 161 | case BPF_ALU | BPF_MUL | BPF_K: /* A *= K */ |
|---|
| 166 | 162 | if (K < 32768) |
|---|
| 167 | | - PPC_MULI(r_A, r_A, K); |
|---|
| 163 | + EMIT(PPC_RAW_MULI(r_A, r_A, K)); |
|---|
| 168 | 164 | else { |
|---|
| 169 | 165 | PPC_LI32(r_scratch1, K); |
|---|
| 170 | | - PPC_MULW(r_A, r_A, r_scratch1); |
|---|
| 166 | + EMIT(PPC_RAW_MULW(r_A, r_A, r_scratch1)); |
|---|
| 171 | 167 | } |
|---|
| 172 | 168 | break; |
|---|
| 173 | 169 | case BPF_ALU | BPF_MOD | BPF_X: /* A %= X; */ |
|---|
| 174 | 170 | case BPF_ALU | BPF_DIV | BPF_X: /* A /= X; */ |
|---|
| 175 | 171 | ctx->seen |= SEEN_XREG; |
|---|
| 176 | | - PPC_CMPWI(r_X, 0); |
|---|
| 172 | + EMIT(PPC_RAW_CMPWI(r_X, 0)); |
|---|
| 177 | 173 | if (ctx->pc_ret0 != -1) { |
|---|
| 178 | 174 | PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]); |
|---|
| 179 | 175 | } else { |
|---|
| 180 | 176 | PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12); |
|---|
| 181 | | - PPC_LI(r_ret, 0); |
|---|
| 177 | + EMIT(PPC_RAW_LI(r_ret, 0)); |
|---|
| 182 | 178 | PPC_JMP(exit_addr); |
|---|
| 183 | 179 | } |
|---|
| 184 | 180 | if (code == (BPF_ALU | BPF_MOD | BPF_X)) { |
|---|
| 185 | | - PPC_DIVWU(r_scratch1, r_A, r_X); |
|---|
| 186 | | - PPC_MULW(r_scratch1, r_X, r_scratch1); |
|---|
| 187 | | - PPC_SUB(r_A, r_A, r_scratch1); |
|---|
| 181 | + EMIT(PPC_RAW_DIVWU(r_scratch1, r_A, r_X)); |
|---|
| 182 | + EMIT(PPC_RAW_MULW(r_scratch1, r_X, r_scratch1)); |
|---|
| 183 | + EMIT(PPC_RAW_SUB(r_A, r_A, r_scratch1)); |
|---|
| 188 | 184 | } else { |
|---|
| 189 | | - PPC_DIVWU(r_A, r_A, r_X); |
|---|
| 185 | + EMIT(PPC_RAW_DIVWU(r_A, r_A, r_X)); |
|---|
| 190 | 186 | } |
|---|
| 191 | 187 | break; |
|---|
| 192 | 188 | case BPF_ALU | BPF_MOD | BPF_K: /* A %= K; */ |
|---|
| 193 | 189 | PPC_LI32(r_scratch2, K); |
|---|
| 194 | | - PPC_DIVWU(r_scratch1, r_A, r_scratch2); |
|---|
| 195 | | - PPC_MULW(r_scratch1, r_scratch2, r_scratch1); |
|---|
| 196 | | - PPC_SUB(r_A, r_A, r_scratch1); |
|---|
| 190 | + EMIT(PPC_RAW_DIVWU(r_scratch1, r_A, r_scratch2)); |
|---|
| 191 | + EMIT(PPC_RAW_MULW(r_scratch1, r_scratch2, r_scratch1)); |
|---|
| 192 | + EMIT(PPC_RAW_SUB(r_A, r_A, r_scratch1)); |
|---|
| 197 | 193 | break; |
|---|
| 198 | 194 | case BPF_ALU | BPF_DIV | BPF_K: /* A /= K */ |
|---|
| 199 | 195 | if (K == 1) |
|---|
| 200 | 196 | break; |
|---|
| 201 | 197 | PPC_LI32(r_scratch1, K); |
|---|
| 202 | | - PPC_DIVWU(r_A, r_A, r_scratch1); |
|---|
| 198 | + EMIT(PPC_RAW_DIVWU(r_A, r_A, r_scratch1)); |
|---|
| 203 | 199 | break; |
|---|
| 204 | 200 | case BPF_ALU | BPF_AND | BPF_X: |
|---|
| 205 | 201 | ctx->seen |= SEEN_XREG; |
|---|
| 206 | | - PPC_AND(r_A, r_A, r_X); |
|---|
| 202 | + EMIT(PPC_RAW_AND(r_A, r_A, r_X)); |
|---|
| 207 | 203 | break; |
|---|
| 208 | 204 | case BPF_ALU | BPF_AND | BPF_K: |
|---|
| 209 | 205 | if (!IMM_H(K)) |
|---|
| 210 | | - PPC_ANDI(r_A, r_A, K); |
|---|
| 206 | + EMIT(PPC_RAW_ANDI(r_A, r_A, K)); |
|---|
| 211 | 207 | else { |
|---|
| 212 | 208 | PPC_LI32(r_scratch1, K); |
|---|
| 213 | | - PPC_AND(r_A, r_A, r_scratch1); |
|---|
| 209 | + EMIT(PPC_RAW_AND(r_A, r_A, r_scratch1)); |
|---|
| 214 | 210 | } |
|---|
| 215 | 211 | break; |
|---|
| 216 | 212 | case BPF_ALU | BPF_OR | BPF_X: |
|---|
| 217 | 213 | ctx->seen |= SEEN_XREG; |
|---|
| 218 | | - PPC_OR(r_A, r_A, r_X); |
|---|
| 214 | + EMIT(PPC_RAW_OR(r_A, r_A, r_X)); |
|---|
| 219 | 215 | break; |
|---|
| 220 | 216 | case BPF_ALU | BPF_OR | BPF_K: |
|---|
| 221 | 217 | if (IMM_L(K)) |
|---|
| 222 | | - PPC_ORI(r_A, r_A, IMM_L(K)); |
|---|
| 218 | + EMIT(PPC_RAW_ORI(r_A, r_A, IMM_L(K))); |
|---|
| 223 | 219 | if (K >= 65536) |
|---|
| 224 | | - PPC_ORIS(r_A, r_A, IMM_H(K)); |
|---|
| 220 | + EMIT(PPC_RAW_ORIS(r_A, r_A, IMM_H(K))); |
|---|
| 225 | 221 | break; |
|---|
| 226 | 222 | case BPF_ANC | SKF_AD_ALU_XOR_X: |
|---|
| 227 | 223 | case BPF_ALU | BPF_XOR | BPF_X: /* A ^= X */ |
|---|
| 228 | 224 | ctx->seen |= SEEN_XREG; |
|---|
| 229 | | - PPC_XOR(r_A, r_A, r_X); |
|---|
| 225 | + EMIT(PPC_RAW_XOR(r_A, r_A, r_X)); |
|---|
| 230 | 226 | break; |
|---|
| 231 | 227 | case BPF_ALU | BPF_XOR | BPF_K: /* A ^= K */ |
|---|
| 232 | 228 | if (IMM_L(K)) |
|---|
| 233 | | - PPC_XORI(r_A, r_A, IMM_L(K)); |
|---|
| 229 | + EMIT(PPC_RAW_XORI(r_A, r_A, IMM_L(K))); |
|---|
| 234 | 230 | if (K >= 65536) |
|---|
| 235 | | - PPC_XORIS(r_A, r_A, IMM_H(K)); |
|---|
| 231 | + EMIT(PPC_RAW_XORIS(r_A, r_A, IMM_H(K))); |
|---|
| 236 | 232 | break; |
|---|
| 237 | 233 | case BPF_ALU | BPF_LSH | BPF_X: /* A <<= X; */ |
|---|
| 238 | 234 | ctx->seen |= SEEN_XREG; |
|---|
| 239 | | - PPC_SLW(r_A, r_A, r_X); |
|---|
| 235 | + EMIT(PPC_RAW_SLW(r_A, r_A, r_X)); |
|---|
| 240 | 236 | break; |
|---|
| 241 | 237 | case BPF_ALU | BPF_LSH | BPF_K: |
|---|
| 242 | 238 | if (K == 0) |
|---|
| 243 | 239 | break; |
|---|
| 244 | 240 | else |
|---|
| 245 | | - PPC_SLWI(r_A, r_A, K); |
|---|
| 241 | + EMIT(PPC_RAW_SLWI(r_A, r_A, K)); |
|---|
| 246 | 242 | break; |
|---|
| 247 | 243 | case BPF_ALU | BPF_RSH | BPF_X: /* A >>= X; */ |
|---|
| 248 | 244 | ctx->seen |= SEEN_XREG; |
|---|
| 249 | | - PPC_SRW(r_A, r_A, r_X); |
|---|
| 245 | + EMIT(PPC_RAW_SRW(r_A, r_A, r_X)); |
|---|
| 250 | 246 | break; |
|---|
| 251 | 247 | case BPF_ALU | BPF_RSH | BPF_K: /* A >>= K; */ |
|---|
| 252 | 248 | if (K == 0) |
|---|
| 253 | 249 | break; |
|---|
| 254 | 250 | else |
|---|
| 255 | | - PPC_SRWI(r_A, r_A, K); |
|---|
| 251 | + EMIT(PPC_RAW_SRWI(r_A, r_A, K)); |
|---|
| 256 | 252 | break; |
|---|
| 257 | 253 | case BPF_ALU | BPF_NEG: |
|---|
| 258 | | - PPC_NEG(r_A, r_A); |
|---|
| 254 | + EMIT(PPC_RAW_NEG(r_A, r_A)); |
|---|
| 259 | 255 | break; |
|---|
| 260 | 256 | case BPF_RET | BPF_K: |
|---|
| 261 | 257 | PPC_LI32(r_ret, K); |
|---|
| .. | .. |
|---|
| 281 | 277 | if (ctx->seen) |
|---|
| 282 | 278 | PPC_JMP(exit_addr); |
|---|
| 283 | 279 | else |
|---|
| 284 | | - PPC_BLR(); |
|---|
| 280 | + EMIT(PPC_RAW_BLR()); |
|---|
| 285 | 281 | } |
|---|
| 286 | 282 | break; |
|---|
| 287 | 283 | case BPF_RET | BPF_A: |
|---|
| 288 | | - PPC_MR(r_ret, r_A); |
|---|
| 284 | + EMIT(PPC_RAW_MR(r_ret, r_A)); |
|---|
| 289 | 285 | if (i != flen - 1) { |
|---|
| 290 | 286 | if (ctx->seen) |
|---|
| 291 | 287 | PPC_JMP(exit_addr); |
|---|
| 292 | 288 | else |
|---|
| 293 | | - PPC_BLR(); |
|---|
| 289 | + EMIT(PPC_RAW_BLR()); |
|---|
| 294 | 290 | } |
|---|
| 295 | 291 | break; |
|---|
| 296 | 292 | case BPF_MISC | BPF_TAX: /* X = A */ |
|---|
| 297 | | - PPC_MR(r_X, r_A); |
|---|
| 293 | + EMIT(PPC_RAW_MR(r_X, r_A)); |
|---|
| 298 | 294 | break; |
|---|
| 299 | 295 | case BPF_MISC | BPF_TXA: /* A = X */ |
|---|
| 300 | 296 | ctx->seen |= SEEN_XREG; |
|---|
| 301 | | - PPC_MR(r_A, r_X); |
|---|
| 297 | + EMIT(PPC_RAW_MR(r_A, r_X)); |
|---|
| 302 | 298 | break; |
|---|
| 303 | 299 | |
|---|
| 304 | 300 | /*** Constant loads/M[] access ***/ |
|---|
| .. | .. |
|---|
| 309 | 305 | PPC_LI32(r_X, K); |
|---|
| 310 | 306 | break; |
|---|
| 311 | 307 | case BPF_LD | BPF_MEM: /* A = mem[K] */ |
|---|
| 312 | | - PPC_MR(r_A, r_M + (K & 0xf)); |
|---|
| 308 | + EMIT(PPC_RAW_MR(r_A, r_M + (K & 0xf))); |
|---|
| 313 | 309 | ctx->seen |= SEEN_MEM | (1<<(K & 0xf)); |
|---|
| 314 | 310 | break; |
|---|
| 315 | 311 | case BPF_LDX | BPF_MEM: /* X = mem[K] */ |
|---|
| 316 | | - PPC_MR(r_X, r_M + (K & 0xf)); |
|---|
| 312 | + EMIT(PPC_RAW_MR(r_X, r_M + (K & 0xf))); |
|---|
| 317 | 313 | ctx->seen |= SEEN_MEM | (1<<(K & 0xf)); |
|---|
| 318 | 314 | break; |
|---|
| 319 | 315 | case BPF_ST: /* mem[K] = A */ |
|---|
| 320 | | - PPC_MR(r_M + (K & 0xf), r_A); |
|---|
| 316 | + EMIT(PPC_RAW_MR(r_M + (K & 0xf), r_A)); |
|---|
| 321 | 317 | ctx->seen |= SEEN_MEM | (1<<(K & 0xf)); |
|---|
| 322 | 318 | break; |
|---|
| 323 | 319 | case BPF_STX: /* mem[K] = X */ |
|---|
| 324 | | - PPC_MR(r_M + (K & 0xf), r_X); |
|---|
| 320 | + EMIT(PPC_RAW_MR(r_M + (K & 0xf), r_X)); |
|---|
| 325 | 321 | ctx->seen |= SEEN_XREG | SEEN_MEM | (1<<(K & 0xf)); |
|---|
| 326 | 322 | break; |
|---|
| 327 | 323 | case BPF_LD | BPF_W | BPF_LEN: /* A = skb->len; */ |
|---|
| 328 | | - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); |
|---|
| 324 | + BUILD_BUG_ON(sizeof_field(struct sk_buff, len) != 4); |
|---|
| 329 | 325 | PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, len)); |
|---|
| 330 | 326 | break; |
|---|
| 331 | 327 | case BPF_LDX | BPF_W | BPF_ABS: /* A = *((u32 *)(seccomp_data + K)); */ |
|---|
| .. | .. |
|---|
| 337 | 333 | |
|---|
| 338 | 334 | /*** Ancillary info loads ***/ |
|---|
| 339 | 335 | case BPF_ANC | SKF_AD_PROTOCOL: /* A = ntohs(skb->protocol); */ |
|---|
| 340 | | - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, |
|---|
| 336 | + BUILD_BUG_ON(sizeof_field(struct sk_buff, |
|---|
| 341 | 337 | protocol) != 2); |
|---|
| 342 | 338 | PPC_NTOHS_OFFS(r_A, r_skb, offsetof(struct sk_buff, |
|---|
| 343 | 339 | protocol)); |
|---|
| 344 | 340 | break; |
|---|
| 345 | 341 | case BPF_ANC | SKF_AD_IFINDEX: |
|---|
| 346 | 342 | case BPF_ANC | SKF_AD_HATYPE: |
|---|
| 347 | | - BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, |
|---|
| 343 | + BUILD_BUG_ON(sizeof_field(struct net_device, |
|---|
| 348 | 344 | ifindex) != 4); |
|---|
| 349 | | - BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, |
|---|
| 345 | + BUILD_BUG_ON(sizeof_field(struct net_device, |
|---|
| 350 | 346 | type) != 2); |
|---|
| 351 | 347 | PPC_LL_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, |
|---|
| 352 | 348 | dev)); |
|---|
| 353 | | - PPC_CMPDI(r_scratch1, 0); |
|---|
| 349 | + EMIT(PPC_RAW_CMPDI(r_scratch1, 0)); |
|---|
| 354 | 350 | if (ctx->pc_ret0 != -1) { |
|---|
| 355 | 351 | PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]); |
|---|
| 356 | 352 | } else { |
|---|
| 357 | 353 | /* Exit, returning 0; first pass hits here. */ |
|---|
| 358 | 354 | PPC_BCC_SHORT(COND_NE, ctx->idx * 4 + 12); |
|---|
| 359 | | - PPC_LI(r_ret, 0); |
|---|
| 355 | + EMIT(PPC_RAW_LI(r_ret, 0)); |
|---|
| 360 | 356 | PPC_JMP(exit_addr); |
|---|
| 361 | 357 | } |
|---|
| 362 | 358 | if (code == (BPF_ANC | SKF_AD_IFINDEX)) { |
|---|
| .. | .. |
|---|
| 369 | 365 | |
|---|
| 370 | 366 | break; |
|---|
| 371 | 367 | case BPF_ANC | SKF_AD_MARK: |
|---|
| 372 | | - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); |
|---|
| 368 | + BUILD_BUG_ON(sizeof_field(struct sk_buff, mark) != 4); |
|---|
| 373 | 369 | PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, |
|---|
| 374 | 370 | mark)); |
|---|
| 375 | 371 | break; |
|---|
| 376 | 372 | case BPF_ANC | SKF_AD_RXHASH: |
|---|
| 377 | | - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); |
|---|
| 373 | + BUILD_BUG_ON(sizeof_field(struct sk_buff, hash) != 4); |
|---|
| 378 | 374 | PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, |
|---|
| 379 | 375 | hash)); |
|---|
| 380 | 376 | break; |
|---|
| 381 | 377 | case BPF_ANC | SKF_AD_VLAN_TAG: |
|---|
| 382 | | - case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT: |
|---|
| 383 | | - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2); |
|---|
| 384 | | - BUILD_BUG_ON(VLAN_TAG_PRESENT != 0x1000); |
|---|
| 378 | + BUILD_BUG_ON(sizeof_field(struct sk_buff, vlan_tci) != 2); |
|---|
| 385 | 379 | |
|---|
| 386 | 380 | PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, |
|---|
| 387 | 381 | vlan_tci)); |
|---|
| 388 | | - if (code == (BPF_ANC | SKF_AD_VLAN_TAG)) { |
|---|
| 389 | | - PPC_ANDI(r_A, r_A, ~VLAN_TAG_PRESENT); |
|---|
| 390 | | - } else { |
|---|
| 391 | | - PPC_ANDI(r_A, r_A, VLAN_TAG_PRESENT); |
|---|
| 392 | | - PPC_SRWI(r_A, r_A, 12); |
|---|
| 393 | | - } |
|---|
| 382 | + break; |
|---|
| 383 | + case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT: |
|---|
| 384 | + PPC_LBZ_OFFS(r_A, r_skb, PKT_VLAN_PRESENT_OFFSET()); |
|---|
| 385 | + if (PKT_VLAN_PRESENT_BIT) |
|---|
| 386 | + EMIT(PPC_RAW_SRWI(r_A, r_A, PKT_VLAN_PRESENT_BIT)); |
|---|
| 387 | + if (PKT_VLAN_PRESENT_BIT < 7) |
|---|
| 388 | + EMIT(PPC_RAW_ANDI(r_A, r_A, 1)); |
|---|
| 394 | 389 | break; |
|---|
| 395 | 390 | case BPF_ANC | SKF_AD_QUEUE: |
|---|
| 396 | | - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, |
|---|
| 391 | + BUILD_BUG_ON(sizeof_field(struct sk_buff, |
|---|
| 397 | 392 | queue_mapping) != 2); |
|---|
| 398 | 393 | PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, |
|---|
| 399 | 394 | queue_mapping)); |
|---|
| 400 | 395 | break; |
|---|
| 401 | 396 | case BPF_ANC | SKF_AD_PKTTYPE: |
|---|
| 402 | 397 | PPC_LBZ_OFFS(r_A, r_skb, PKT_TYPE_OFFSET()); |
|---|
| 403 | | - PPC_ANDI(r_A, r_A, PKT_TYPE_MAX); |
|---|
| 404 | | - PPC_SRWI(r_A, r_A, 5); |
|---|
| 398 | + EMIT(PPC_RAW_ANDI(r_A, r_A, PKT_TYPE_MAX)); |
|---|
| 399 | + EMIT(PPC_RAW_SRWI(r_A, r_A, 5)); |
|---|
| 405 | 400 | break; |
|---|
| 406 | 401 | case BPF_ANC | SKF_AD_CPU: |
|---|
| 407 | 402 | PPC_BPF_LOAD_CPU(r_A); |
|---|
| .. | .. |
|---|
| 419 | 414 | /* Load from [K]. */ |
|---|
| 420 | 415 | ctx->seen |= SEEN_DATAREF; |
|---|
| 421 | 416 | PPC_FUNC_ADDR(r_scratch1, func); |
|---|
| 422 | | - PPC_MTLR(r_scratch1); |
|---|
| 417 | + EMIT(PPC_RAW_MTLR(r_scratch1)); |
|---|
| 423 | 418 | PPC_LI32(r_addr, K); |
|---|
| 424 | | - PPC_BLRL(); |
|---|
| 419 | + EMIT(PPC_RAW_BLRL()); |
|---|
| 425 | 420 | /* |
|---|
| 426 | 421 | * Helper returns 'lt' condition on error, and an |
|---|
| 427 | 422 | * appropriate return value in r3 |
|---|
| .. | .. |
|---|
| 445 | 440 | */ |
|---|
| 446 | 441 | ctx->seen |= SEEN_DATAREF | SEEN_XREG; |
|---|
| 447 | 442 | PPC_FUNC_ADDR(r_scratch1, func); |
|---|
| 448 | | - PPC_MTLR(r_scratch1); |
|---|
| 449 | | - PPC_ADDI(r_addr, r_X, IMM_L(K)); |
|---|
| 443 | + EMIT(PPC_RAW_MTLR(r_scratch1)); |
|---|
| 444 | + EMIT(PPC_RAW_ADDI(r_addr, r_X, IMM_L(K))); |
|---|
| 450 | 445 | if (K >= 32768) |
|---|
| 451 | | - PPC_ADDIS(r_addr, r_addr, IMM_HA(K)); |
|---|
| 452 | | - PPC_BLRL(); |
|---|
| 446 | + EMIT(PPC_RAW_ADDIS(r_addr, r_addr, IMM_HA(K))); |
|---|
| 447 | + EMIT(PPC_RAW_BLRL()); |
|---|
| 453 | 448 | /* If error, cr0.LT set */ |
|---|
| 454 | 449 | PPC_BCC(COND_LT, exit_addr); |
|---|
| 455 | 450 | break; |
|---|
| .. | .. |
|---|
| 480 | 475 | case BPF_JMP | BPF_JSET | BPF_K: |
|---|
| 481 | 476 | case BPF_JMP | BPF_JSET | BPF_X: |
|---|
| 482 | 477 | true_cond = COND_NE; |
|---|
| 483 | | - /* Fall through */ |
|---|
| 484 | 478 | cond_branch: |
|---|
| 485 | 479 | /* same targets, can avoid doing the test :) */ |
|---|
| 486 | 480 | if (filter[i].jt == filter[i].jf) { |
|---|
| .. | .. |
|---|
| 494 | 488 | case BPF_JMP | BPF_JGE | BPF_X: |
|---|
| 495 | 489 | case BPF_JMP | BPF_JEQ | BPF_X: |
|---|
| 496 | 490 | ctx->seen |= SEEN_XREG; |
|---|
| 497 | | - PPC_CMPLW(r_A, r_X); |
|---|
| 491 | + EMIT(PPC_RAW_CMPLW(r_A, r_X)); |
|---|
| 498 | 492 | break; |
|---|
| 499 | 493 | case BPF_JMP | BPF_JSET | BPF_X: |
|---|
| 500 | 494 | ctx->seen |= SEEN_XREG; |
|---|
| 501 | | - PPC_AND_DOT(r_scratch1, r_A, r_X); |
|---|
| 495 | + EMIT(PPC_RAW_AND_DOT(r_scratch1, r_A, r_X)); |
|---|
| 502 | 496 | break; |
|---|
| 503 | 497 | case BPF_JMP | BPF_JEQ | BPF_K: |
|---|
| 504 | 498 | case BPF_JMP | BPF_JGT | BPF_K: |
|---|
| 505 | 499 | case BPF_JMP | BPF_JGE | BPF_K: |
|---|
| 506 | 500 | if (K < 32768) |
|---|
| 507 | | - PPC_CMPLWI(r_A, K); |
|---|
| 501 | + EMIT(PPC_RAW_CMPLWI(r_A, K)); |
|---|
| 508 | 502 | else { |
|---|
| 509 | 503 | PPC_LI32(r_scratch1, K); |
|---|
| 510 | | - PPC_CMPLW(r_A, r_scratch1); |
|---|
| 504 | + EMIT(PPC_RAW_CMPLW(r_A, r_scratch1)); |
|---|
| 511 | 505 | } |
|---|
| 512 | 506 | break; |
|---|
| 513 | 507 | case BPF_JMP | BPF_JSET | BPF_K: |
|---|
| 514 | 508 | if (K < 32768) |
|---|
| 515 | 509 | /* PPC_ANDI is /only/ dot-form */ |
|---|
| 516 | | - PPC_ANDI(r_scratch1, r_A, K); |
|---|
| 510 | + EMIT(PPC_RAW_ANDI(r_scratch1, r_A, K)); |
|---|
| 517 | 511 | else { |
|---|
| 518 | 512 | PPC_LI32(r_scratch1, K); |
|---|
| 519 | | - PPC_AND_DOT(r_scratch1, r_A, |
|---|
| 520 | | - r_scratch1); |
|---|
| 513 | + EMIT(PPC_RAW_AND_DOT(r_scratch1, r_A, |
|---|
| 514 | + r_scratch1)); |
|---|
| 521 | 515 | } |
|---|
| 522 | 516 | break; |
|---|
| 523 | 517 | } |
|---|