~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm64/net/bpf_jit_comp.c

Version: ~ [ linux-5.17-rc1 ] ~ [ linux-5.16.2 ] ~ [ linux-5.15.16 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.93 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.173 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.225 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.262 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.297 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.299 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * BPF JIT compiler for ARM64
  4  *
  5  * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com>
  6  */
  7 
  8 #define pr_fmt(fmt) "bpf_jit: " fmt
  9 
 10 #include <linux/bpf.h>
 11 #include <linux/filter.h>
 12 #include <linux/printk.h>
 13 #include <linux/slab.h>
 14 
 15 #include <asm/byteorder.h>
 16 #include <asm/cacheflush.h>
 17 #include <asm/debug-monitors.h>
 18 #include <asm/set_memory.h>
 19 
 20 #include "bpf_jit.h"
 21 
 22 #define TMP_REG_1 (MAX_BPF_JIT_REG + 0)
 23 #define TMP_REG_2 (MAX_BPF_JIT_REG + 1)
 24 #define TCALL_CNT (MAX_BPF_JIT_REG + 2)
 25 #define TMP_REG_3 (MAX_BPF_JIT_REG + 3)
 26 
 27 /* Map BPF registers to A64 registers */
 28 static const int bpf2a64[] = {
 29         /* return value from in-kernel function, and exit value from eBPF */
 30         [BPF_REG_0] = A64_R(7),
 31         /* arguments from eBPF program to in-kernel function */
 32         [BPF_REG_1] = A64_R(0),
 33         [BPF_REG_2] = A64_R(1),
 34         [BPF_REG_3] = A64_R(2),
 35         [BPF_REG_4] = A64_R(3),
 36         [BPF_REG_5] = A64_R(4),
 37         /* callee saved registers that in-kernel function will preserve */
 38         [BPF_REG_6] = A64_R(19),
 39         [BPF_REG_7] = A64_R(20),
 40         [BPF_REG_8] = A64_R(21),
 41         [BPF_REG_9] = A64_R(22),
 42         /* read-only frame pointer to access stack */
 43         [BPF_REG_FP] = A64_R(25),
 44         /* temporary registers for internal BPF JIT */
 45         [TMP_REG_1] = A64_R(10),
 46         [TMP_REG_2] = A64_R(11),
 47         [TMP_REG_3] = A64_R(12),
 48         /* tail_call_cnt */
 49         [TCALL_CNT] = A64_R(26),
 50         /* temporary register for blinding constants */
 51         [BPF_REG_AX] = A64_R(9),
 52 };
 53 
 54 struct jit_ctx {
 55         const struct bpf_prog *prog;
 56         int idx;
 57         int epilogue_offset;
 58         int *offset;
 59         __le32 *image;
 60         u32 stack_size;
 61 };
 62 
 63 static inline void emit(const u32 insn, struct jit_ctx *ctx)
 64 {
 65         if (ctx->image != NULL)
 66                 ctx->image[ctx->idx] = cpu_to_le32(insn);
 67 
 68         ctx->idx++;
 69 }
 70 
 71 static inline void emit_a64_mov_i(const int is64, const int reg,
 72                                   const s32 val, struct jit_ctx *ctx)
 73 {
 74         u16 hi = val >> 16;
 75         u16 lo = val & 0xffff;
 76 
 77         if (hi & 0x8000) {
 78                 if (hi == 0xffff) {
 79                         emit(A64_MOVN(is64, reg, (u16)~lo, 0), ctx);
 80                 } else {
 81                         emit(A64_MOVN(is64, reg, (u16)~hi, 16), ctx);
 82                         if (lo != 0xffff)
 83                                 emit(A64_MOVK(is64, reg, lo, 0), ctx);
 84                 }
 85         } else {
 86                 emit(A64_MOVZ(is64, reg, lo, 0), ctx);
 87                 if (hi)
 88                         emit(A64_MOVK(is64, reg, hi, 16), ctx);
 89         }
 90 }
 91 
 92 static int i64_i16_blocks(const u64 val, bool inverse)
 93 {
 94         return (((val >>  0) & 0xffff) != (inverse ? 0xffff : 0x0000)) +
 95                (((val >> 16) & 0xffff) != (inverse ? 0xffff : 0x0000)) +
 96                (((val >> 32) & 0xffff) != (inverse ? 0xffff : 0x0000)) +
 97                (((val >> 48) & 0xffff) != (inverse ? 0xffff : 0x0000));
 98 }
 99 
100 static inline void emit_a64_mov_i64(const int reg, const u64 val,
101                                     struct jit_ctx *ctx)
102 {
103         u64 nrm_tmp = val, rev_tmp = ~val;
104         bool inverse;
105         int shift;
106 
107         if (!(nrm_tmp >> 32))
108                 return emit_a64_mov_i(0, reg, (u32)val, ctx);
109 
110         inverse = i64_i16_blocks(nrm_tmp, true) < i64_i16_blocks(nrm_tmp, false);
111         shift = max(round_down((inverse ? (fls64(rev_tmp) - 1) :
112                                           (fls64(nrm_tmp) - 1)), 16), 0);
113         if (inverse)
114                 emit(A64_MOVN(1, reg, (rev_tmp >> shift) & 0xffff, shift), ctx);
115         else
116                 emit(A64_MOVZ(1, reg, (nrm_tmp >> shift) & 0xffff, shift), ctx);
117         shift -= 16;
118         while (shift >= 0) {
119                 if (((nrm_tmp >> shift) & 0xffff) != (inverse ? 0xffff : 0x0000))
120                         emit(A64_MOVK(1, reg, (nrm_tmp >> shift) & 0xffff, shift), ctx);
121                 shift -= 16;
122         }
123 }
124 
125 /*
126  * Kernel addresses in the vmalloc space use at most 48 bits, and the
127  * remaining bits are guaranteed to be 0x1. So we can compose the address
128  * with a fixed length movn/movk/movk sequence.
129  */
130 static inline void emit_addr_mov_i64(const int reg, const u64 val,
131                                      struct jit_ctx *ctx)
132 {
133         u64 tmp = val;
134         int shift = 0;
135 
136         emit(A64_MOVN(1, reg, ~tmp & 0xffff, shift), ctx);
137         while (shift < 32) {
138                 tmp >>= 16;
139                 shift += 16;
140                 emit(A64_MOVK(1, reg, tmp & 0xffff, shift), ctx);
141         }
142 }
143 
144 static inline int bpf2a64_offset(int bpf_to, int bpf_from,
145                                  const struct jit_ctx *ctx)
146 {
147         int to = ctx->offset[bpf_to];
148         /* -1 to account for the Branch instruction */
149         int from = ctx->offset[bpf_from] - 1;
150 
151         return to - from;
152 }
153 
154 static void jit_fill_hole(void *area, unsigned int size)
155 {
156         __le32 *ptr;
157         /* We are guaranteed to have aligned memory. */
158         for (ptr = area; size >= sizeof(u32); size -= sizeof(u32))
159                 *ptr++ = cpu_to_le32(AARCH64_BREAK_FAULT);
160 }
161 
162 static inline int epilogue_offset(const struct jit_ctx *ctx)
163 {
164         int to = ctx->epilogue_offset;
165         int from = ctx->idx;
166 
167         return to - from;
168 }
169 
170 /* Stack must be multiples of 16B */
171 #define STACK_ALIGN(sz) (((sz) + 15) & ~15)
172 
173 /* Tail call offset to jump into */
174 #define PROLOGUE_OFFSET 7
175 
176 static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
177 {
178         const struct bpf_prog *prog = ctx->prog;
179         const u8 r6 = bpf2a64[BPF_REG_6];
180         const u8 r7 = bpf2a64[BPF_REG_7];
181         const u8 r8 = bpf2a64[BPF_REG_8];
182         const u8 r9 = bpf2a64[BPF_REG_9];
183         const u8 fp = bpf2a64[BPF_REG_FP];
184         const u8 tcc = bpf2a64[TCALL_CNT];
185         const int idx0 = ctx->idx;
186         int cur_offset;
187 
188         /*
189          * BPF prog stack layout
190          *
191          *                         high
192          * original A64_SP =>   0:+-----+ BPF prologue
193          *                        |FP/LR|
194          * current A64_FP =>  -16:+-----+
195          *                        | ... | callee saved registers
196          * BPF fp register => -64:+-----+ <= (BPF_FP)
197          *                        |     |
198          *                        | ... | BPF prog stack
199          *                        |     |
200          *                        +-----+ <= (BPF_FP - prog->aux->stack_depth)
201          *                        |RSVD | padding
202          * current A64_SP =>      +-----+ <= (BPF_FP - ctx->stack_size)
203          *                        |     |
204          *                        | ... | Function call stack
205          *                        |     |
206          *                        +-----+
207          *                          low
208          *
209          */
210 
211         /* Save FP and LR registers to stay align with ARM64 AAPCS */
212         emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx);
213         emit(A64_MOV(1, A64_FP, A64_SP), ctx);
214 
215         /* Save callee-saved registers */
216         emit(A64_PUSH(r6, r7, A64_SP), ctx);
217         emit(A64_PUSH(r8, r9, A64_SP), ctx);
218         emit(A64_PUSH(fp, tcc, A64_SP), ctx);
219 
220         /* Set up BPF prog stack base register */
221         emit(A64_MOV(1, fp, A64_SP), ctx);
222 
223         if (!ebpf_from_cbpf) {
224                 /* Initialize tail_call_cnt */
225                 emit(A64_MOVZ(1, tcc, 0, 0), ctx);
226 
227                 cur_offset = ctx->idx - idx0;
228                 if (cur_offset != PROLOGUE_OFFSET) {
229                         pr_err_once("PROLOGUE_OFFSET = %d, expected %d!\n",
230                                     cur_offset, PROLOGUE_OFFSET);
231                         return -1;
232                 }
233         }
234 
235         ctx->stack_size = STACK_ALIGN(prog->aux->stack_depth);
236 
237         /* Set up function call stack */
238         emit(A64_SUB_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);
239         return 0;
240 }
241 
242 static int out_offset = -1; /* initialized on the first pass of build_body() */
243 static int emit_bpf_tail_call(struct jit_ctx *ctx)
244 {
245         /* bpf_tail_call(void *prog_ctx, struct bpf_array *array, u64 index) */
246         const u8 r2 = bpf2a64[BPF_REG_2];
247         const u8 r3 = bpf2a64[BPF_REG_3];
248 
249         const u8 tmp = bpf2a64[TMP_REG_1];
250         const u8 prg = bpf2a64[TMP_REG_2];
251         const u8 tcc = bpf2a64[TCALL_CNT];
252         const int idx0 = ctx->idx;
253 #define cur_offset (ctx->idx - idx0)
254 #define jmp_offset (out_offset - (cur_offset))
255         size_t off;
256 
257         /* if (index >= array->map.max_entries)
258          *     goto out;
259          */
260         off = offsetof(struct bpf_array, map.max_entries);
261         emit_a64_mov_i64(tmp, off, ctx);
262         emit(A64_LDR32(tmp, r2, tmp), ctx);
263         emit(A64_MOV(0, r3, r3), ctx);
264         emit(A64_CMP(0, r3, tmp), ctx);
265         emit(A64_B_(A64_COND_CS, jmp_offset), ctx);
266 
267         /* if (tail_call_cnt > MAX_TAIL_CALL_CNT)
268          *     goto out;
269          * tail_call_cnt++;
270          */
271         emit_a64_mov_i64(tmp, MAX_TAIL_CALL_CNT, ctx);
272         emit(A64_CMP(1, tcc, tmp), ctx);
273         emit(A64_B_(A64_COND_HI, jmp_offset), ctx);
274         emit(A64_ADD_I(1, tcc, tcc, 1), ctx);
275 
276         /* prog = array->ptrs[index];
277          * if (prog == NULL)
278          *     goto out;
279          */
280         off = offsetof(struct bpf_array, ptrs);
281         emit_a64_mov_i64(tmp, off, ctx);
282         emit(A64_ADD(1, tmp, r2, tmp), ctx);
283         emit(A64_LSL(1, prg, r3, 3), ctx);
284         emit(A64_LDR64(prg, tmp, prg), ctx);
285         emit(A64_CBZ(1, prg, jmp_offset), ctx);
286 
287         /* goto *(prog->bpf_func + prologue_offset); */
288         off = offsetof(struct bpf_prog, bpf_func);
289         emit_a64_mov_i64(tmp, off, ctx);
290         emit(A64_LDR64(tmp, prg, tmp), ctx);
291         emit(A64_ADD_I(1, tmp, tmp, sizeof(u32) * PROLOGUE_OFFSET), ctx);
292         emit(A64_ADD_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);
293         emit(A64_BR(tmp), ctx);
294 
295         /* out: */
296         if (out_offset == -1)
297                 out_offset = cur_offset;
298         if (cur_offset != out_offset) {
299                 pr_err_once("tail_call out_offset = %d, expected %d!\n",
300                             cur_offset, out_offset);
301                 return -1;
302         }
303         return 0;
304 #undef cur_offset
305 #undef jmp_offset
306 }
307 
308 static void build_epilogue(struct jit_ctx *ctx)
309 {
310         const u8 r0 = bpf2a64[BPF_REG_0];
311         const u8 r6 = bpf2a64[BPF_REG_6];
312         const u8 r7 = bpf2a64[BPF_REG_7];
313         const u8 r8 = bpf2a64[BPF_REG_8];
314         const u8 r9 = bpf2a64[BPF_REG_9];
315         const u8 fp = bpf2a64[BPF_REG_FP];
316 
317         /* We're done with BPF stack */
318         emit(A64_ADD_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);
319 
320         /* Restore fs (x25) and x26 */
321         emit(A64_POP(fp, A64_R(26), A64_SP), ctx);
322 
323         /* Restore callee-saved register */
324         emit(A64_POP(r8, r9, A64_SP), ctx);
325         emit(A64_POP(r6, r7, A64_SP), ctx);
326 
327         /* Restore FP/LR registers */
328         emit(A64_POP(A64_FP, A64_LR, A64_SP), ctx);
329 
330         /* Set return value */
331         emit(A64_MOV(1, A64_R(0), r0), ctx);
332 
333         emit(A64_RET(A64_LR), ctx);
334 }
335 
336 /* JITs an eBPF instruction.
337  * Returns:
338  * 0  - successfully JITed an 8-byte eBPF instruction.
339  * >0 - successfully JITed a 16-byte eBPF instruction.
340  * <0 - failed to JIT.
341  */
342 static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
343                       bool extra_pass)
344 {
345         const u8 code = insn->code;
346         const u8 dst = bpf2a64[insn->dst_reg];
347         const u8 src = bpf2a64[insn->src_reg];
348         const u8 tmp = bpf2a64[TMP_REG_1];
349         const u8 tmp2 = bpf2a64[TMP_REG_2];
350         const u8 tmp3 = bpf2a64[TMP_REG_3];
351         const s16 off = insn->off;
352         const s32 imm = insn->imm;
353         const int i = insn - ctx->prog->insnsi;
354         const bool is64 = BPF_CLASS(code) == BPF_ALU64 ||
355                           BPF_CLASS(code) == BPF_JMP;
356         const bool isdw = BPF_SIZE(code) == BPF_DW;
357         u8 jmp_cond, reg;
358         s32 jmp_offset;
359 
360 #define check_imm(bits, imm) do {                               \
361         if ((((imm) > 0) && ((imm) >> (bits))) ||               \
362             (((imm) < 0) && (~(imm) >> (bits)))) {              \
363                 pr_info("[%2d] imm=%d(0x%x) out of range\n",    \
364                         i, imm, imm);                           \
365                 return -EINVAL;                                 \
366         }                                                       \
367 } while (0)
368 #define check_imm19(imm) check_imm(19, imm)
369 #define check_imm26(imm) check_imm(26, imm)
370 
371         switch (code) {
372         /* dst = src */
373         case BPF_ALU | BPF_MOV | BPF_X:
374         case BPF_ALU64 | BPF_MOV | BPF_X:
375                 emit(A64_MOV(is64, dst, src), ctx);
376                 break;
377         /* dst = dst OP src */
378         case BPF_ALU | BPF_ADD | BPF_X:
379         case BPF_ALU64 | BPF_ADD | BPF_X:
380                 emit(A64_ADD(is64, dst, dst, src), ctx);
381                 break;
382         case BPF_ALU | BPF_SUB | BPF_X:
383         case BPF_ALU64 | BPF_SUB | BPF_X:
384                 emit(A64_SUB(is64, dst, dst, src), ctx);
385                 break;
386         case BPF_ALU | BPF_AND | BPF_X:
387         case BPF_ALU64 | BPF_AND | BPF_X:
388                 emit(A64_AND(is64, dst, dst, src), ctx);
389                 break;
390         case BPF_ALU | BPF_OR | BPF_X:
391         case BPF_ALU64 | BPF_OR | BPF_X:
392                 emit(A64_ORR(is64, dst, dst, src), ctx);
393                 break;
394         case BPF_ALU | BPF_XOR | BPF_X:
395         case BPF_ALU64 | BPF_XOR | BPF_X:
396                 emit(A64_EOR(is64, dst, dst, src), ctx);
397                 break;
398         case BPF_ALU | BPF_MUL | BPF_X:
399         case BPF_ALU64 | BPF_MUL | BPF_X:
400                 emit(A64_MUL(is64, dst, dst, src), ctx);
401                 break;
402         case BPF_ALU | BPF_DIV | BPF_X:
403         case BPF_ALU64 | BPF_DIV | BPF_X:
404         case BPF_ALU | BPF_MOD | BPF_X:
405         case BPF_ALU64 | BPF_MOD | BPF_X:
406                 switch (BPF_OP(code)) {
407                 case BPF_DIV:
408                         emit(A64_UDIV(is64, dst, dst, src), ctx);
409                         break;
410                 case BPF_MOD:
411                         emit(A64_UDIV(is64, tmp, dst, src), ctx);
412                         emit(A64_MUL(is64, tmp, tmp, src), ctx);
413                         emit(A64_SUB(is64, dst, dst, tmp), ctx);
414                         break;
415                 }
416                 break;
417         case BPF_ALU | BPF_LSH | BPF_X:
418         case BPF_ALU64 | BPF_LSH | BPF_X:
419                 emit(A64_LSLV(is64, dst, dst, src), ctx);
420                 break;
421         case BPF_ALU | BPF_RSH | BPF_X:
422         case BPF_ALU64 | BPF_RSH | BPF_X:
423                 emit(A64_LSRV(is64, dst, dst, src), ctx);
424                 break;
425         case BPF_ALU | BPF_ARSH | BPF_X:
426         case BPF_ALU64 | BPF_ARSH | BPF_X:
427                 emit(A64_ASRV(is64, dst, dst, src), ctx);
428                 break;
429         /* dst = -dst */
430         case BPF_ALU | BPF_NEG:
431         case BPF_ALU64 | BPF_NEG:
432                 emit(A64_NEG(is64, dst, dst), ctx);
433                 break;
434         /* dst = BSWAP##imm(dst) */
435         case BPF_ALU | BPF_END | BPF_FROM_LE:
436         case BPF_ALU | BPF_END | BPF_FROM_BE:
437 #ifdef CONFIG_CPU_BIG_ENDIAN
438                 if (BPF_SRC(code) == BPF_FROM_BE)
439                         goto emit_bswap_uxt;
440 #else /* !CONFIG_CPU_BIG_ENDIAN */
441                 if (BPF_SRC(code) == BPF_FROM_LE)
442                         goto emit_bswap_uxt;
443 #endif
444                 switch (imm) {
445                 case 16:
446                         emit(A64_REV16(is64, dst, dst), ctx);
447                         /* zero-extend 16 bits into 64 bits */
448                         emit(A64_UXTH(is64, dst, dst), ctx);
449                         break;
450                 case 32:
451                         emit(A64_REV32(is64, dst, dst), ctx);
452                         /* upper 32 bits already cleared */
453                         break;
454                 case 64:
455                         emit(A64_REV64(dst, dst), ctx);
456                         break;
457                 }
458                 break;
459 emit_bswap_uxt:
460                 switch (imm) {
461                 case 16:
462                         /* zero-extend 16 bits into 64 bits */
463                         emit(A64_UXTH(is64, dst, dst), ctx);
464                         break;
465                 case 32:
466                         /* zero-extend 32 bits into 64 bits */
467                         emit(A64_UXTW(is64, dst, dst), ctx);
468                         break;
469                 case 64:
470                         /* nop */
471                         break;
472                 }
473                 break;
474         /* dst = imm */
475         case BPF_ALU | BPF_MOV | BPF_K:
476         case BPF_ALU64 | BPF_MOV | BPF_K:
477                 emit_a64_mov_i(is64, dst, imm, ctx);
478                 break;
479         /* dst = dst OP imm */
480         case BPF_ALU | BPF_ADD | BPF_K:
481         case BPF_ALU64 | BPF_ADD | BPF_K:
482                 emit_a64_mov_i(is64, tmp, imm, ctx);
483                 emit(A64_ADD(is64, dst, dst, tmp), ctx);
484                 break;
485         case BPF_ALU | BPF_SUB | BPF_K:
486         case BPF_ALU64 | BPF_SUB | BPF_K:
487                 emit_a64_mov_i(is64, tmp, imm, ctx);
488                 emit(A64_SUB(is64, dst, dst, tmp), ctx);
489                 break;
490         case BPF_ALU | BPF_AND | BPF_K:
491         case BPF_ALU64 | BPF_AND | BPF_K:
492                 emit_a64_mov_i(is64, tmp, imm, ctx);
493                 emit(A64_AND(is64, dst, dst, tmp), ctx);
494                 break;
495         case BPF_ALU | BPF_OR | BPF_K:
496         case BPF_ALU64 | BPF_OR | BPF_K:
497                 emit_a64_mov_i(is64, tmp, imm, ctx);
498                 emit(A64_ORR(is64, dst, dst, tmp), ctx);
499                 break;
500         case BPF_ALU | BPF_XOR | BPF_K:
501         case BPF_ALU64 | BPF_XOR | BPF_K:
502                 emit_a64_mov_i(is64, tmp, imm, ctx);
503                 emit(A64_EOR(is64, dst, dst, tmp), ctx);
504                 break;
505         case BPF_ALU | BPF_MUL | BPF_K:
506         case BPF_ALU64 | BPF_MUL | BPF_K:
507                 emit_a64_mov_i(is64, tmp, imm, ctx);
508                 emit(A64_MUL(is64, dst, dst, tmp), ctx);
509                 break;
510         case BPF_ALU | BPF_DIV | BPF_K:
511         case BPF_ALU64 | BPF_DIV | BPF_K:
512                 emit_a64_mov_i(is64, tmp, imm, ctx);
513                 emit(A64_UDIV(is64, dst, dst, tmp), ctx);
514                 break;
515         case BPF_ALU | BPF_MOD | BPF_K:
516         case BPF_ALU64 | BPF_MOD | BPF_K:
517                 emit_a64_mov_i(is64, tmp2, imm, ctx);
518                 emit(A64_UDIV(is64, tmp, dst, tmp2), ctx);
519                 emit(A64_MUL(is64, tmp, tmp, tmp2), ctx);
520                 emit(A64_SUB(is64, dst, dst, tmp), ctx);
521                 break;
522         case BPF_ALU | BPF_LSH | BPF_K:
523         case BPF_ALU64 | BPF_LSH | BPF_K:
524                 emit(A64_LSL(is64, dst, dst, imm), ctx);
525                 break;
526         case BPF_ALU | BPF_RSH | BPF_K:
527         case BPF_ALU64 | BPF_RSH | BPF_K:
528                 emit(A64_LSR(is64, dst, dst, imm), ctx);
529                 break;
530         case BPF_ALU | BPF_ARSH | BPF_K:
531         case BPF_ALU64 | BPF_ARSH | BPF_K:
532                 emit(A64_ASR(is64, dst, dst, imm), ctx);
533                 break;
534 
535         /* JUMP off */
536         case BPF_JMP | BPF_JA:
537                 jmp_offset = bpf2a64_offset(i + off, i, ctx);
538                 check_imm26(jmp_offset);
539                 emit(A64_B(jmp_offset), ctx);
540                 break;
541         /* IF (dst COND src) JUMP off */
542         case BPF_JMP | BPF_JEQ | BPF_X:
543         case BPF_JMP | BPF_JGT | BPF_X:
544         case BPF_JMP | BPF_JLT | BPF_X:
545         case BPF_JMP | BPF_JGE | BPF_X:
546         case BPF_JMP | BPF_JLE | BPF_X:
547         case BPF_JMP | BPF_JNE | BPF_X:
548         case BPF_JMP | BPF_JSGT | BPF_X:
549         case BPF_JMP | BPF_JSLT | BPF_X:
550         case BPF_JMP | BPF_JSGE | BPF_X:
551         case BPF_JMP | BPF_JSLE | BPF_X:
552         case BPF_JMP32 | BPF_JEQ | BPF_X:
553         case BPF_JMP32 | BPF_JGT | BPF_X:
554         case BPF_JMP32 | BPF_JLT | BPF_X:
555         case BPF_JMP32 | BPF_JGE | BPF_X:
556         case BPF_JMP32 | BPF_JLE | BPF_X:
557         case BPF_JMP32 | BPF_JNE | BPF_X:
558         case BPF_JMP32 | BPF_JSGT | BPF_X:
559         case BPF_JMP32 | BPF_JSLT | BPF_X:
560         case BPF_JMP32 | BPF_JSGE | BPF_X:
561         case BPF_JMP32 | BPF_JSLE | BPF_X:
562                 emit(A64_CMP(is64, dst, src), ctx);
563 emit_cond_jmp:
564                 jmp_offset = bpf2a64_offset(i + off, i, ctx);
565                 check_imm19(jmp_offset);
566                 switch (BPF_OP(code)) {
567                 case BPF_JEQ:
568                         jmp_cond = A64_COND_EQ;
569                         break;
570                 case BPF_JGT:
571                         jmp_cond = A64_COND_HI;
572                         break;
573                 case BPF_JLT:
574                         jmp_cond = A64_COND_CC;
575                         break;
576                 case BPF_JGE:
577                         jmp_cond = A64_COND_CS;
578                         break;
579                 case BPF_JLE:
580                         jmp_cond = A64_COND_LS;
581                         break;
582                 case BPF_JSET:
583                 case BPF_JNE:
584                         jmp_cond = A64_COND_NE;
585                         break;
586                 case BPF_JSGT:
587                         jmp_cond = A64_COND_GT;
588                         break;
589                 case BPF_JSLT:
590                         jmp_cond = A64_COND_LT;
591                         break;
592                 case BPF_JSGE:
593                         jmp_cond = A64_COND_GE;
594                         break;
595                 case BPF_JSLE:
596                         jmp_cond = A64_COND_LE;
597                         break;
598                 default:
599                         return -EFAULT;
600                 }
601                 emit(A64_B_(jmp_cond, jmp_offset), ctx);
602                 break;
603         case BPF_JMP | BPF_JSET | BPF_X:
604         case BPF_JMP32 | BPF_JSET | BPF_X:
605                 emit(A64_TST(is64, dst, src), ctx);
606                 goto emit_cond_jmp;
607         /* IF (dst COND imm) JUMP off */
608         case BPF_JMP | BPF_JEQ | BPF_K:
609         case BPF_JMP | BPF_JGT | BPF_K:
610         case BPF_JMP | BPF_JLT | BPF_K:
611         case BPF_JMP | BPF_JGE | BPF_K:
612         case BPF_JMP | BPF_JLE | BPF_K:
613         case BPF_JMP | BPF_JNE | BPF_K:
614         case BPF_JMP | BPF_JSGT | BPF_K:
615         case BPF_JMP | BPF_JSLT | BPF_K:
616         case BPF_JMP | BPF_JSGE | BPF_K:
617         case BPF_JMP | BPF_JSLE | BPF_K:
618         case BPF_JMP32 | BPF_JEQ | BPF_K:
619         case BPF_JMP32 | BPF_JGT | BPF_K:
620         case BPF_JMP32 | BPF_JLT | BPF_K:
621         case BPF_JMP32 | BPF_JGE | BPF_K:
622         case BPF_JMP32 | BPF_JLE | BPF_K:
623         case BPF_JMP32 | BPF_JNE | BPF_K:
624         case BPF_JMP32 | BPF_JSGT | BPF_K:
625         case BPF_JMP32 | BPF_JSLT | BPF_K:
626         case BPF_JMP32 | BPF_JSGE | BPF_K:
627         case BPF_JMP32 | BPF_JSLE | BPF_K:
628                 emit_a64_mov_i(is64, tmp, imm, ctx);
629                 emit(A64_CMP(is64, dst, tmp), ctx);
630                 goto emit_cond_jmp;
631         case BPF_JMP | BPF_JSET | BPF_K:
632         case BPF_JMP32 | BPF_JSET | BPF_K:
633                 emit_a64_mov_i(is64, tmp, imm, ctx);
634                 emit(A64_TST(is64, dst, tmp), ctx);
635                 goto emit_cond_jmp;
636         /* function call */
637         case BPF_JMP | BPF_CALL:
638         {
639                 const u8 r0 = bpf2a64[BPF_REG_0];
640                 bool func_addr_fixed;
641                 u64 func_addr;
642                 int ret;
643 
644                 ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass,
645                                             &func_addr, &func_addr_fixed);
646                 if (ret < 0)
647                         return ret;
648                 emit_addr_mov_i64(tmp, func_addr, ctx);
649                 emit(A64_BLR(tmp), ctx);
650                 emit(A64_MOV(1, r0, A64_R(0)), ctx);
651                 break;
652         }
653         /* tail call */
654         case BPF_JMP | BPF_TAIL_CALL:
655                 if (emit_bpf_tail_call(ctx))
656                         return -EFAULT;
657                 break;
658         /* function return */
659         case BPF_JMP | BPF_EXIT:
660                 /* Optimization: when last instruction is EXIT,
661                    simply fallthrough to epilogue. */
662                 if (i == ctx->prog->len - 1)
663                         break;
664                 jmp_offset = epilogue_offset(ctx);
665                 check_imm26(jmp_offset);
666                 emit(A64_B(jmp_offset), ctx);
667                 break;
668 
669         /* dst = imm64 */
670         case BPF_LD | BPF_IMM | BPF_DW:
671         {
672                 const struct bpf_insn insn1 = insn[1];
673                 u64 imm64;
674 
675                 imm64 = (u64)insn1.imm << 32 | (u32)imm;
676                 emit_a64_mov_i64(dst, imm64, ctx);
677 
678                 return 1;
679         }
680 
681         /* LDX: dst = *(size *)(src + off) */
682         case BPF_LDX | BPF_MEM | BPF_W:
683         case BPF_LDX | BPF_MEM | BPF_H:
684         case BPF_LDX | BPF_MEM | BPF_B:
685         case BPF_LDX | BPF_MEM | BPF_DW:
686                 emit_a64_mov_i(1, tmp, off, ctx);
687                 switch (BPF_SIZE(code)) {
688                 case BPF_W:
689                         emit(A64_LDR32(dst, src, tmp), ctx);
690                         break;
691                 case BPF_H:
692                         emit(A64_LDRH(dst, src, tmp), ctx);
693                         break;
694                 case BPF_B:
695                         emit(A64_LDRB(dst, src, tmp), ctx);
696                         break;
697                 case BPF_DW:
698                         emit(A64_LDR64(dst, src, tmp), ctx);
699                         break;
700                 }
701                 break;
702 
703         /* ST: *(size *)(dst + off) = imm */
704         case BPF_ST | BPF_MEM | BPF_W:
705         case BPF_ST | BPF_MEM | BPF_H:
706         case BPF_ST | BPF_MEM | BPF_B:
707         case BPF_ST | BPF_MEM | BPF_DW:
708                 /* Load imm to a register then store it */
709                 emit_a64_mov_i(1, tmp2, off, ctx);
710                 emit_a64_mov_i(1, tmp, imm, ctx);
711                 switch (BPF_SIZE(code)) {
712                 case BPF_W:
713                         emit(A64_STR32(tmp, dst, tmp2), ctx);
714                         break;
715                 case BPF_H:
716                         emit(A64_STRH(tmp, dst, tmp2), ctx);
717                         break;
718                 case BPF_B:
719                         emit(A64_STRB(tmp, dst, tmp2), ctx);
720                         break;
721                 case BPF_DW:
722                         emit(A64_STR64(tmp, dst, tmp2), ctx);
723                         break;
724                 }
725                 break;
726 
727         /* STX: *(size *)(dst + off) = src */
728         case BPF_STX | BPF_MEM | BPF_W:
729         case BPF_STX | BPF_MEM | BPF_H:
730         case BPF_STX | BPF_MEM | BPF_B:
731         case BPF_STX | BPF_MEM | BPF_DW:
732                 emit_a64_mov_i(1, tmp, off, ctx);
733                 switch (BPF_SIZE(code)) {
734                 case BPF_W:
735                         emit(A64_STR32(src, dst, tmp), ctx);
736                         break;
737                 case BPF_H:
738                         emit(A64_STRH(src, dst, tmp), ctx);
739                         break;
740                 case BPF_B:
741                         emit(A64_STRB(src, dst, tmp), ctx);
742                         break;
743                 case BPF_DW:
744                         emit(A64_STR64(src, dst, tmp), ctx);
745                         break;
746                 }
747                 break;
748 
749         /* STX XADD: lock *(u32 *)(dst + off) += src */
750         case BPF_STX | BPF_XADD | BPF_W:
751         /* STX XADD: lock *(u64 *)(dst + off) += src */
752         case BPF_STX | BPF_XADD | BPF_DW:
753                 if (!off) {
754                         reg = dst;
755                 } else {
756                         emit_a64_mov_i(1, tmp, off, ctx);
757                         emit(A64_ADD(1, tmp, tmp, dst), ctx);
758                         reg = tmp;
759                 }
760                 if (cpus_have_cap(ARM64_HAS_LSE_ATOMICS)) {
761                         emit(A64_STADD(isdw, reg, src), ctx);
762                 } else {
763                         emit(A64_LDXR(isdw, tmp2, reg), ctx);
764                         emit(A64_ADD(isdw, tmp2, tmp2, src), ctx);
765                         emit(A64_STXR(isdw, tmp2, reg, tmp3), ctx);
766                         jmp_offset = -3;
767                         check_imm19(jmp_offset);
768                         emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
769                 }
770                 break;
771 
772         default:
773                 pr_err_once("unknown opcode %02x\n", code);
774                 return -EINVAL;
775         }
776 
777         return 0;
778 }
779 
780 static int build_body(struct jit_ctx *ctx, bool extra_pass)
781 {
782         const struct bpf_prog *prog = ctx->prog;
783         int i;
784 
785         for (i = 0; i < prog->len; i++) {
786                 const struct bpf_insn *insn = &prog->insnsi[i];
787                 int ret;
788 
789                 ret = build_insn(insn, ctx, extra_pass);
790                 if (ret > 0) {
791                         i++;
792                         if (ctx->image == NULL)
793                                 ctx->offset[i] = ctx->idx;
794                         continue;
795                 }
796                 if (ctx->image == NULL)
797                         ctx->offset[i] = ctx->idx;
798                 if (ret)
799                         return ret;
800         }
801 
802         return 0;
803 }
804 
805 static int validate_code(struct jit_ctx *ctx)
806 {
807         int i;
808 
809         for (i = 0; i < ctx->idx; i++) {
810                 u32 a64_insn = le32_to_cpu(ctx->image[i]);
811 
812                 if (a64_insn == AARCH64_BREAK_FAULT)
813                         return -1;
814         }
815 
816         return 0;
817 }
818 
819 static inline void bpf_flush_icache(void *start, void *end)
820 {
821         flush_icache_range((unsigned long)start, (unsigned long)end);
822 }
823 
824 struct arm64_jit_data {
825         struct bpf_binary_header *header;
826         u8 *image;
827         struct jit_ctx ctx;
828 };
829 
830 struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
831 {
832         struct bpf_prog *tmp, *orig_prog = prog;
833         struct bpf_binary_header *header;
834         struct arm64_jit_data *jit_data;
835         bool was_classic = bpf_prog_was_classic(prog);
836         bool tmp_blinded = false;
837         bool extra_pass = false;
838         struct jit_ctx ctx;
839         int image_size;
840         u8 *image_ptr;
841 
842         if (!prog->jit_requested)
843                 return orig_prog;
844 
845         tmp = bpf_jit_blind_constants(prog);
846         /* If blinding was requested and we failed during blinding,
847          * we must fall back to the interpreter.
848          */
849         if (IS_ERR(tmp))
850                 return orig_prog;
851         if (tmp != prog) {
852                 tmp_blinded = true;
853                 prog = tmp;
854         }
855 
856         jit_data = prog->aux->jit_data;
857         if (!jit_data) {
858                 jit_data = kzalloc(sizeof(*jit_data), GFP_KERNEL);
859                 if (!jit_data) {
860                         prog = orig_prog;
861                         goto out;
862                 }
863                 prog->aux->jit_data = jit_data;
864         }
865         if (jit_data->ctx.offset) {
866                 ctx = jit_data->ctx;
867                 image_ptr = jit_data->image;
868                 header = jit_data->header;
869                 extra_pass = true;
870                 image_size = sizeof(u32) * ctx.idx;
871                 goto skip_init_ctx;
872         }
873         memset(&ctx, 0, sizeof(ctx));
874         ctx.prog = prog;
875 
876         ctx.offset = kcalloc(prog->len, sizeof(int), GFP_KERNEL);
877         if (ctx.offset == NULL) {
878                 prog = orig_prog;
879                 goto out_off;
880         }
881 
882         /* 1. Initial fake pass to compute ctx->idx. */
883 
884         /* Fake pass to fill in ctx->offset. */
885         if (build_body(&ctx, extra_pass)) {
886                 prog = orig_prog;
887                 goto out_off;
888         }
889 
890         if (build_prologue(&ctx, was_classic)) {
891                 prog = orig_prog;
892                 goto out_off;
893         }
894 
895         ctx.epilogue_offset = ctx.idx;
896         build_epilogue(&ctx);
897 
898         /* Now we know the actual image size. */
899         image_size = sizeof(u32) * ctx.idx;
900         header = bpf_jit_binary_alloc(image_size, &image_ptr,
901                                       sizeof(u32), jit_fill_hole);
902         if (header == NULL) {
903                 prog = orig_prog;
904                 goto out_off;
905         }
906 
907         /* 2. Now, the actual pass. */
908 
909         ctx.image = (__le32 *)image_ptr;
910 skip_init_ctx:
911         ctx.idx = 0;
912 
913         build_prologue(&ctx, was_classic);
914 
915         if (build_body(&ctx, extra_pass)) {
916                 bpf_jit_binary_free(header);
917                 prog = orig_prog;
918                 goto out_off;
919         }
920 
921         build_epilogue(&ctx);
922 
923         /* 3. Extra pass to validate JITed code. */
924         if (validate_code(&ctx)) {
925                 bpf_jit_binary_free(header);
926                 prog = orig_prog;
927                 goto out_off;
928         }
929 
930         /* And we're done. */
931         if (bpf_jit_enable > 1)
932                 bpf_jit_dump(prog->len, image_size, 2, ctx.image);
933 
934         bpf_flush_icache(header, ctx.image + ctx.idx);
935 
936         if (!prog->is_func || extra_pass) {
937                 if (extra_pass && ctx.idx != jit_data->ctx.idx) {
938                         pr_err_once("multi-func JIT bug %d != %d\n",
939                                     ctx.idx, jit_data->ctx.idx);
940                         bpf_jit_binary_free(header);
941                         prog->bpf_func = NULL;
942                         prog->jited = 0;
943                         goto out_off;
944                 }
945                 bpf_jit_binary_lock_ro(header);
946         } else {
947                 jit_data->ctx = ctx;
948                 jit_data->image = image_ptr;
949                 jit_data->header = header;
950         }
951         prog->bpf_func = (void *)ctx.image;
952         prog->jited = 1;
953         prog->jited_len = image_size;
954 
955         if (!prog->is_func || extra_pass) {
956                 bpf_prog_fill_jited_linfo(prog, ctx.offset);
957 out_off:
958                 kfree(ctx.offset);
959                 kfree(jit_data);
960                 prog->aux->jit_data = NULL;
961         }
962 out:
963         if (tmp_blinded)
964                 bpf_jit_prog_release_other(prog, prog == orig_prog ?
965                                            tmp : orig_prog);
966         return prog;
967 }
968 
969 void *bpf_jit_alloc_exec(unsigned long size)
970 {
971         return __vmalloc_node_range(size, PAGE_SIZE, BPF_JIT_REGION_START,
972                                     BPF_JIT_REGION_END, GFP_KERNEL,
973                                     PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
974                                     __builtin_return_address(0));
975 }
976 
977 void bpf_jit_free_exec(void *addr)
978 {
979         return vfree(addr);
980 }
981 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp