ppc: bpf: update jit to use compatibility macros
authorDenis Kirjanov <kda@linux-powerpc.org>
Tue, 17 Feb 2015 07:04:40 +0000 (10:04 +0300)
committerDavid S. Miller <davem@davemloft.net>
Fri, 20 Feb 2015 20:19:43 +0000 (15:19 -0500)
Use helpers from the asm-compat.h to wrap up assembly mnemonics

Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
arch/powerpc/net/bpf_jit.h
arch/powerpc/net/bpf_jit_64.S
arch/powerpc/net/bpf_jit_comp.c

index c406aa95b2bc5970b1aa7d3033cc8518faa93089..2d5e71577210471bb9f1f78891407e8235f1977b 100644 (file)
 #ifndef _BPF_JIT_H
 #define _BPF_JIT_H
 
+#ifdef CONFIG_PPC64
+#define BPF_PPC_STACK_R3_OFF   48
 #define BPF_PPC_STACK_LOCALS   32
 #define BPF_PPC_STACK_BASIC    (48+64)
 #define BPF_PPC_STACK_SAVE     (18*8)
 #define BPF_PPC_STACKFRAME     (BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \
                                 BPF_PPC_STACK_SAVE)
 #define BPF_PPC_SLOWPATH_FRAME (48+64)
+#else
+#define BPF_PPC_STACK_R3_OFF   24
+#define BPF_PPC_STACK_LOCALS   16
+#define BPF_PPC_STACK_BASIC    (24+32)
+#define BPF_PPC_STACK_SAVE     (18*4)
+#define BPF_PPC_STACKFRAME     (BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \
+                                BPF_PPC_STACK_SAVE)
+#define BPF_PPC_SLOWPATH_FRAME (24+32)
+#endif
+
+#define REG_SZ         (BITS_PER_LONG/8)
 
 /*
  * Generated code register usage:
@@ -57,7 +70,11 @@ DECLARE_LOAD_FUNC(sk_load_half);
 DECLARE_LOAD_FUNC(sk_load_byte);
 DECLARE_LOAD_FUNC(sk_load_byte_msh);
 
+#ifdef CONFIG_PPC64
 #define FUNCTION_DESCR_SIZE    24
+#else
+#define FUNCTION_DESCR_SIZE    0
+#endif
 
 /*
  * 16-bit immediate helper macros: HA() is for use with sign-extending instrs
@@ -86,7 +103,12 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
 #define PPC_LIS(r, i)          PPC_ADDIS(r, 0, i)
 #define PPC_STD(r, base, i)    EMIT(PPC_INST_STD | ___PPC_RS(r) |            \
                                     ___PPC_RA(base) | ((i) & 0xfffc))
-
+#define PPC_STDU(r, base, i)   EMIT(PPC_INST_STDU | ___PPC_RS(r) |           \
+                                    ___PPC_RA(base) | ((i) & 0xfffc))
+#define PPC_STW(r, base, i)    EMIT(PPC_INST_STW | ___PPC_RS(r) |            \
+                                    ___PPC_RA(base) | ((i) & 0xfffc))
+#define PPC_STWU(r, base, i)   EMIT(PPC_INST_STWU | ___PPC_RS(r) |           \
+                                    ___PPC_RA(base) | ((i) & 0xfffc))
 
 #define PPC_LBZ(r, base, i)    EMIT(PPC_INST_LBZ | ___PPC_RT(r) |            \
                                     ___PPC_RA(base) | IMM_L(i))
@@ -98,6 +120,17 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
                                     ___PPC_RA(base) | IMM_L(i))
 #define PPC_LHBRX(r, base, b)  EMIT(PPC_INST_LHBRX | ___PPC_RT(r) |          \
                                     ___PPC_RA(base) | ___PPC_RB(b))
+
+#ifdef CONFIG_PPC64
+#define PPC_BPF_LL(r, base, i) do { PPC_LD(r, base, i); } while(0)
+#define PPC_BPF_STL(r, base, i) do { PPC_STD(r, base, i); } while(0)
+#define PPC_BPF_STLU(r, base, i) do { PPC_STDU(r, base, i); } while(0)
+#else
+#define PPC_BPF_LL(r, base, i) do { PPC_LWZ(r, base, i); } while(0)
+#define PPC_BPF_STL(r, base, i) do { PPC_STW(r, base, i); } while(0)
+#define PPC_BPF_STLU(r, base, i) do { PPC_STWU(r, base, i); } while(0)
+#endif
+
 /* Convenience helpers for the above with 'far' offsets: */
 #define PPC_LBZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LBZ(r, base, i);   \
                else {  PPC_ADDIS(r, base, IMM_HA(i));                        \
@@ -115,6 +148,12 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
                else {  PPC_ADDIS(r, base, IMM_HA(i));                        \
                        PPC_LHZ(r, r, IMM_L(i)); } } while(0)
 
+#ifdef CONFIG_PPC64
+#define PPC_LL_OFFS(r, base, i) do { PPC_LD_OFFS(r, base, i); } while(0)
+#else
+#define PPC_LL_OFFS(r, base, i) do { PPC_LWZ_OFFS(r, base, i); } while(0)
+#endif
+
 #define PPC_CMPWI(a, i)                EMIT(PPC_INST_CMPWI | ___PPC_RA(a) | IMM_L(i))
 #define PPC_CMPDI(a, i)                EMIT(PPC_INST_CMPDI | ___PPC_RA(a) | IMM_L(i))
 #define PPC_CMPLWI(a, i)       EMIT(PPC_INST_CMPLWI | ___PPC_RA(a) | IMM_L(i))
@@ -196,6 +235,12 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
                                PPC_ORI(d, d, (uintptr_t)(i) & 0xffff);       \
                } } while (0);
 
+#ifdef CONFIG_PPC64
+#define PPC_FUNC_ADDR(d,i) do { PPC_LI64(d, i); } while(0)
+#else
+#define PPC_FUNC_ADDR(d,i) do { PPC_LI32(d, i); } while(0)
+#endif
+
 #define PPC_LHBRX_OFFS(r, base, i) \
                do { PPC_LI32(r, i); PPC_LHBRX(r, r, base); } while(0)
 #ifdef __LITTLE_ENDIAN__
index 8f87d92171228d470f9274ff4eee27e921dbfbed..8ff5a3b5d1c3d4aab4bab875b5f9165b3b7f0678 100644 (file)
  */
        .globl  sk_load_word
 sk_load_word:
-       cmpdi   r_addr, 0
+       PPC_LCMPI       r_addr, 0
        blt     bpf_slow_path_word_neg
        .globl  sk_load_word_positive_offset
 sk_load_word_positive_offset:
        /* Are we accessing past headlen? */
        subi    r_scratch1, r_HL, 4
-       cmpd    r_scratch1, r_addr
+       PPC_LCMP        r_scratch1, r_addr
        blt     bpf_slow_path_word
        /* Nope, just hitting the header.  cr0 here is eq or gt! */
 #ifdef __LITTLE_ENDIAN__
@@ -52,12 +52,12 @@ sk_load_word_positive_offset:
 
        .globl  sk_load_half
 sk_load_half:
-       cmpdi   r_addr, 0
+       PPC_LCMPI       r_addr, 0
        blt     bpf_slow_path_half_neg
        .globl  sk_load_half_positive_offset
 sk_load_half_positive_offset:
        subi    r_scratch1, r_HL, 2
-       cmpd    r_scratch1, r_addr
+       PPC_LCMP        r_scratch1, r_addr
        blt     bpf_slow_path_half
 #ifdef __LITTLE_ENDIAN__
        lhbrx   r_A, r_D, r_addr
@@ -68,11 +68,11 @@ sk_load_half_positive_offset:
 
        .globl  sk_load_byte
 sk_load_byte:
-       cmpdi   r_addr, 0
+       PPC_LCMPI       r_addr, 0
        blt     bpf_slow_path_byte_neg
        .globl  sk_load_byte_positive_offset
 sk_load_byte_positive_offset:
-       cmpd    r_HL, r_addr
+       PPC_LCMP        r_HL, r_addr
        ble     bpf_slow_path_byte
        lbzx    r_A, r_D, r_addr
        blr
@@ -83,11 +83,11 @@ sk_load_byte_positive_offset:
  */
        .globl sk_load_byte_msh
 sk_load_byte_msh:
-       cmpdi   r_addr, 0
+       PPC_LCMPI       r_addr, 0
        blt     bpf_slow_path_byte_msh_neg
        .globl sk_load_byte_msh_positive_offset
 sk_load_byte_msh_positive_offset:
-       cmpd    r_HL, r_addr
+       PPC_LCMP        r_HL, r_addr
        ble     bpf_slow_path_byte_msh
        lbzx    r_X, r_D, r_addr
        rlwinm  r_X, r_X, 2, 32-4-2, 31-2
@@ -101,13 +101,13 @@ sk_load_byte_msh_positive_offset:
  */
 #define bpf_slow_path_common(SIZE)                             \
        mflr    r0;                                             \
-       std     r0, 16(r1);                                     \
+       PPC_STL r0, PPC_LR_STKOFF(r1);                                  \
        /* R3 goes in parameter space of caller's frame */      \
-       std     r_skb, (BPF_PPC_STACKFRAME+48)(r1);             \
-       std     r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);           \
-       std     r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);           \
-       addi    r5, r1, BPF_PPC_STACK_BASIC+(2*8);              \
-       stdu    r1, -BPF_PPC_SLOWPATH_FRAME(r1);                \
+       PPC_STL r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1);           \
+       PPC_STL r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1);              \
+       PPC_STL r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1);              \
+       addi    r5, r1, BPF_PPC_STACK_BASIC+(2*REG_SZ);         \
+       PPC_STLU        r1, -BPF_PPC_SLOWPATH_FRAME(r1);                \
        /* R3 = r_skb, as passed */                             \
        mr      r4, r_addr;                                     \
        li      r6, SIZE;                                       \
@@ -115,19 +115,19 @@ sk_load_byte_msh_positive_offset:
        nop;                                                    \
        /* R3 = 0 on success */                                 \
        addi    r1, r1, BPF_PPC_SLOWPATH_FRAME;                 \
-       ld      r0, 16(r1);                                     \
-       ld      r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);           \
-       ld      r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);           \
+       PPC_LL  r0, PPC_LR_STKOFF(r1);                                  \
+       PPC_LL  r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1);              \
+       PPC_LL  r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1);              \
        mtlr    r0;                                             \
-       cmpdi   r3, 0;                                          \
+       PPC_LCMPI       r3, 0;                                          \
        blt     bpf_error;      /* cr0 = LT */                  \
-       ld      r_skb, (BPF_PPC_STACKFRAME+48)(r1);             \
+       PPC_LL  r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1);           \
        /* Great success! */
 
 bpf_slow_path_word:
        bpf_slow_path_common(4)
        /* Data value is on stack, and cr0 != LT */
-       lwz     r_A, BPF_PPC_STACK_BASIC+(2*8)(r1)
+       lwz     r_A, BPF_PPC_STACK_BASIC+(2*REG_SZ)(r1)
        blr
 
 bpf_slow_path_half:
@@ -154,12 +154,12 @@ bpf_slow_path_byte_msh:
  */
 #define sk_negative_common(SIZE)                               \
        mflr    r0;                                             \
-       std     r0, 16(r1);                                     \
+       PPC_STL r0, PPC_LR_STKOFF(r1);                                  \
        /* R3 goes in parameter space of caller's frame */      \
-       std     r_skb, (BPF_PPC_STACKFRAME+48)(r1);             \
-       std     r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);           \
-       std     r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);           \
-       stdu    r1, -BPF_PPC_SLOWPATH_FRAME(r1);                \
+       PPC_STL r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1);           \
+       PPC_STL r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1);              \
+       PPC_STL r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1);              \
+       PPC_STLU        r1, -BPF_PPC_SLOWPATH_FRAME(r1);                \
        /* R3 = r_skb, as passed */                             \
        mr      r4, r_addr;                                     \
        li      r5, SIZE;                                       \
@@ -167,19 +167,19 @@ bpf_slow_path_byte_msh:
        nop;                                                    \
        /* R3 != 0 on success */                                \
        addi    r1, r1, BPF_PPC_SLOWPATH_FRAME;                 \
-       ld      r0, 16(r1);                                     \
-       ld      r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);           \
-       ld      r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);           \
+       PPC_LL  r0, PPC_LR_STKOFF(r1);                                  \
+       PPC_LL  r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1);              \
+       PPC_LL  r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1);              \
        mtlr    r0;                                             \
-       cmpldi  r3, 0;                                          \
+       PPC_LCMPLI      r3, 0;                                          \
        beq     bpf_error_slow; /* cr0 = EQ */                  \
        mr      r_addr, r3;                                     \
-       ld      r_skb, (BPF_PPC_STACKFRAME+48)(r1);             \
+       PPC_LL  r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1);           \
        /* Great success! */
 
 bpf_slow_path_word_neg:
        lis     r_scratch1,-32  /* SKF_LL_OFF */
-       cmpd    r_addr, r_scratch1      /* addr < SKF_* */
+       PPC_LCMP        r_addr, r_scratch1      /* addr < SKF_* */
        blt     bpf_error       /* cr0 = LT */
        .globl  sk_load_word_negative_offset
 sk_load_word_negative_offset:
@@ -189,7 +189,7 @@ sk_load_word_negative_offset:
 
 bpf_slow_path_half_neg:
        lis     r_scratch1,-32  /* SKF_LL_OFF */
-       cmpd    r_addr, r_scratch1      /* addr < SKF_* */
+       PPC_LCMP        r_addr, r_scratch1      /* addr < SKF_* */
        blt     bpf_error       /* cr0 = LT */
        .globl  sk_load_half_negative_offset
 sk_load_half_negative_offset:
@@ -199,7 +199,7 @@ sk_load_half_negative_offset:
 
 bpf_slow_path_byte_neg:
        lis     r_scratch1,-32  /* SKF_LL_OFF */
-       cmpd    r_addr, r_scratch1      /* addr < SKF_* */
+       PPC_LCMP        r_addr, r_scratch1      /* addr < SKF_* */
        blt     bpf_error       /* cr0 = LT */
        .globl  sk_load_byte_negative_offset
 sk_load_byte_negative_offset:
@@ -209,7 +209,7 @@ sk_load_byte_negative_offset:
 
 bpf_slow_path_byte_msh_neg:
        lis     r_scratch1,-32  /* SKF_LL_OFF */
-       cmpd    r_addr, r_scratch1      /* addr < SKF_* */
+       PPC_LCMP        r_addr, r_scratch1      /* addr < SKF_* */
        blt     bpf_error       /* cr0 = LT */
        .globl  sk_load_byte_msh_negative_offset
 sk_load_byte_msh_negative_offset:
@@ -221,7 +221,7 @@ sk_load_byte_msh_negative_offset:
 bpf_error_slow:
        /* fabricate a cr0 = lt */
        li      r_scratch1, -1
-       cmpdi   r_scratch1, 0
+       PPC_LCMPI       r_scratch1, 0
 bpf_error:
        /* Entered with cr0 = lt */
        li      r3, 0
index d1916b577f2c9a71c3fb3a5ee419925f070412d0..8b2926850125ba2e1b4b974e439e517afee4dfdd 100644 (file)
@@ -1,8 +1,9 @@
-/* bpf_jit_comp.c: BPF JIT compiler for PPC64
+/* bpf_jit_comp.c: BPF JIT compiler
  *
  * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation
  *
  * Based on the x86 BPF compiler, by Eric Dumazet (eric.dumazet@gmail.com)
+ * Ported to ppc32 by Denis Kirjanov <kda@linux-powerpc.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -36,11 +37,11 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image,
                if (ctx->seen & SEEN_DATAREF) {
                        /* If we call any helpers (for loads), save LR */
                        EMIT(PPC_INST_MFLR | __PPC_RT(R0));
-                       PPC_STD(0, 1, 16);
+                       PPC_BPF_STL(0, 1, PPC_LR_STKOFF);
 
                        /* Back up non-volatile regs. */
-                       PPC_STD(r_D, 1, -(8*(32-r_D)));
-                       PPC_STD(r_HL, 1, -(8*(32-r_HL)));
+                       PPC_BPF_STL(r_D, 1, -(REG_SZ*(32-r_D)));
+                       PPC_BPF_STL(r_HL, 1, -(REG_SZ*(32-r_HL)));
                }
                if (ctx->seen & SEEN_MEM) {
                        /*
@@ -49,11 +50,10 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image,
                         */
                        for (i = r_M; i < (r_M+16); i++) {
                                if (ctx->seen & (1 << (i-r_M)))
-                                       PPC_STD(i, 1, -(8*(32-i)));
+                                       PPC_BPF_STL(i, 1, -(REG_SZ*(32-i)));
                        }
                }
-               EMIT(PPC_INST_STDU | __PPC_RS(R1) | __PPC_RA(R1) |
-                    (-BPF_PPC_STACKFRAME & 0xfffc));
+               PPC_BPF_STLU(1, 1, -BPF_PPC_STACKFRAME);
        }
 
        if (ctx->seen & SEEN_DATAREF) {
@@ -67,7 +67,7 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image,
                                                         data_len));
                PPC_LWZ_OFFS(r_HL, r_skb, offsetof(struct sk_buff, len));
                PPC_SUB(r_HL, r_HL, r_scratch1);
-               PPC_LD_OFFS(r_D, r_skb, offsetof(struct sk_buff, data));
+               PPC_LL_OFFS(r_D, r_skb, offsetof(struct sk_buff, data));
        }
 
        if (ctx->seen & SEEN_XREG) {
@@ -99,16 +99,16 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
        if (ctx->seen & (SEEN_MEM | SEEN_DATAREF)) {
                PPC_ADDI(1, 1, BPF_PPC_STACKFRAME);
                if (ctx->seen & SEEN_DATAREF) {
-                       PPC_LD(0, 1, 16);
+                       PPC_BPF_LL(0, 1, PPC_LR_STKOFF);
                        PPC_MTLR(0);
-                       PPC_LD(r_D, 1, -(8*(32-r_D)));
-                       PPC_LD(r_HL, 1, -(8*(32-r_HL)));
+                       PPC_BPF_LL(r_D, 1, -(REG_SZ*(32-r_D)));
+                       PPC_BPF_LL(r_HL, 1, -(REG_SZ*(32-r_HL)));
                }
                if (ctx->seen & SEEN_MEM) {
                        /* Restore any saved non-vol registers */
                        for (i = r_M; i < (r_M+16); i++) {
                                if (ctx->seen & (1 << (i-r_M)))
-                                       PPC_LD(i, 1, -(8*(32-i)));
+                                       PPC_BPF_LL(i, 1, -(REG_SZ*(32-i)));
                        }
                }
        }
@@ -355,7 +355,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
                                                ifindex) != 4);
                        BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
                                                type) != 2);
-                       PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff,
+                       PPC_LL_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff,
                                                                dev));
                        PPC_CMPDI(r_scratch1, 0);
                        if (ctx->pc_ret0 != -1) {
@@ -437,7 +437,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
                common_load:
                        /* Load from [K]. */
                        ctx->seen |= SEEN_DATAREF;
-                       PPC_LI64(r_scratch1, func);
+                       PPC_FUNC_ADDR(r_scratch1, func);
                        PPC_MTLR(r_scratch1);
                        PPC_LI32(r_addr, K);
                        PPC_BLRL();
@@ -463,7 +463,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
                         * in the helper functions.
                         */
                        ctx->seen |= SEEN_DATAREF | SEEN_XREG;
-                       PPC_LI64(r_scratch1, func);
+                       PPC_FUNC_ADDR(r_scratch1, func);
                        PPC_MTLR(r_scratch1);
                        PPC_ADDI(r_addr, r_X, IMM_L(K));
                        if (K >= 32768)
@@ -685,9 +685,11 @@ void bpf_jit_compile(struct bpf_prog *fp)
 
        if (image) {
                bpf_flush_icache(code_base, code_base + (proglen/4));
+#ifdef CONFIG_PPC64
                /* Function descriptor nastiness: Address + TOC */
                ((u64 *)image)[0] = (u64)code_base;
                ((u64 *)image)[1] = local_paca->kernel_toc;
+#endif
                fp->bpf_func = (void *)image;
                fp->jited = true;
        }