13 #include <asm/cacheflush.h>
14 #include <linux/netdevice.h>
15 #include <linux/filter.h>
20 #error "Little-endian PPC not supported in BPF compiler"
26 static inline void bpf_flush_icache(
void *
start,
void *
end)
54 for (i =
r_M; i < (
r_M+16); i++) {
85 switch (filter[0].
code) {
119 for (i =
r_M; i < (
r_M+16); i++) {
120 if (ctx->
seen & (1 << (i-
r_M)))
121 PPC_LD(i, 1, -(8*(32-i)));
130 #define CHOOSE_LOAD_FUNC(K, func) \
131 ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
134 static int bpf_jit_build_body(
struct sk_filter *fp,
u32 *image,
141 unsigned int true_cond;
145 unsigned int exit_addr = addrs[flen];
147 for (i = 0; i < flen; i++) {
148 unsigned int K = filter[
i].
k;
154 addrs[
i] = ctx->
idx * 4;
156 switch (filter[i].
code) {
376 queue_mapping) != 2);
389 offsetof(
struct paca_struct, paca_index));
421 goto common_load_ind;
424 goto common_load_ind;
472 if (filter[i].
jt == filter[i].
jf) {
473 if (filter[i].
jt > 0)
478 switch (filter[i].code) {
514 if (filter[i].
jt == 0)
517 addrs[i + 1 + filter[i].jf]);
519 PPC_BCC(true_cond, addrs[i + 1 + filter[i].
jt]);
520 if (filter[i].jf != 0)
521 PPC_JMP(addrs[i + 1 + filter[i].jf]);
529 if (printk_ratelimit())
530 pr_err(
"BPF filter opcode %04x (@%d) unsupported\n",
537 addrs[
i] = ctx->
idx * 4;
544 unsigned int proglen;
545 unsigned int alloclen;
556 addrs = kzalloc((flen+1) *
sizeof(*addrs),
GFP_KERNEL);
614 if (bpf_jit_build_body(fp, 0, &cgctx, addrs))
623 bpf_jit_build_prologue(fp, 0, &cgctx);
624 bpf_jit_build_epilogue(0, &cgctx);
626 proglen = cgctx.
idx * 4;
633 code_base = image + (FUNCTION_DESCR_SIZE/4);
636 for (pass = 1; pass < 3; pass++) {
639 bpf_jit_build_prologue(fp, code_base, &cgctx);
640 bpf_jit_build_body(fp, code_base, &cgctx, addrs);
641 bpf_jit_build_epilogue(code_base, &cgctx);
644 pr_info(
"Pass %d: shrink = %d, seen = 0x%x\n", pass,
645 proglen - (cgctx.
idx * 4), cgctx.
seen);
649 pr_info(
"flen=%d proglen=%u pass=%d image=%p\n",
650 flen, proglen, pass, image);
654 print_hex_dump(
KERN_ERR,
"JIT code: ",
659 bpf_flush_icache(code_base, code_base + (proglen/4));
661 ((
u64 *)image)[0] = (
u64)code_base;
662 ((
u64 *)image)[1] = local_paca->kernel_toc;