]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
powerpc/bpf: Add support for bpf constant blinding
authorNaveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Fri, 23 Sep 2016 20:35:02 +0000 (02:05 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 4 Oct 2016 09:33:20 +0000 (20:33 +1100)
In line with similar support for other architectures by Daniel Borkmann.

'MOD Default X' from test_bpf without constant blinding:
84 bytes emitted from JIT compiler (pass:3, flen:7)
d0000000058a4688 + <x>:
   0: nop
   4: nop
   8: std     r27,-40(r1)
   c: std     r28,-32(r1)
  10: xor     r8,r8,r8
  14: xor     r28,r28,r28
  18: mr      r27,r3
  1c: li      r8,66
  20: cmpwi   r28,0
  24: bne     0x0000000000000030
  28: li      r8,0
  2c: b       0x0000000000000044
  30: divwu   r9,r8,r28
  34: mullw   r9,r28,r9
  38: subf    r8,r9,r8
  3c: rotlwi  r8,r8,0
  40: li      r8,66
  44: ld      r27,-40(r1)
  48: ld      r28,-32(r1)
  4c: mr      r3,r8
  50: blr

... and with constant blinding:
140 bytes emitted from JIT compiler (pass:3, flen:11)
d00000000bd6ab24 + <x>:
   0: nop
   4: nop
   8: std     r27,-40(r1)
   c: std     r28,-32(r1)
  10: xor     r8,r8,r8
  14: xor     r28,r28,r28
  18: mr      r27,r3
  1c: lis     r2,-22834
  20: ori     r2,r2,36083
  24: rotlwi  r2,r2,0
  28: xori    r2,r2,36017
  2c: xoris   r2,r2,42702
  30: rotlwi  r2,r2,0
  34: mr      r8,r2
  38: rotlwi  r8,r8,0
  3c: cmpwi   r28,0
  40: bne     0x000000000000004c
  44: li      r8,0
  48: b       0x000000000000007c
  4c: divwu   r9,r8,r28
  50: mullw   r9,r28,r9
  54: subf    r8,r9,r8
  58: rotlwi  r8,r8,0
  5c: lis     r2,-17137
  60: ori     r2,r2,39065
  64: rotlwi  r2,r2,0
  68: xori    r2,r2,39131
  6c: xoris   r2,r2,48399
  70: rotlwi  r2,r2,0
  74: mr      r8,r2
  78: rotlwi  r8,r8,0
  7c: ld      r27,-40(r1)
  80: ld      r28,-32(r1)
  84: mr      r3,r8
  88: blr

Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/net/bpf_jit64.h
arch/powerpc/net/bpf_jit_comp64.c

index 038e00bf2b7749605299628ca2824f5d66de7832..62fa7589db2b4edc6e9e28742a4b7e531fd23162 100644 (file)
 #ifndef __ASSEMBLY__
 
 /* BPF register usage */
-#define SKB_HLEN_REG   (MAX_BPF_REG + 0)
-#define SKB_DATA_REG   (MAX_BPF_REG + 1)
-#define TMP_REG_1      (MAX_BPF_REG + 2)
-#define TMP_REG_2      (MAX_BPF_REG + 3)
+#define SKB_HLEN_REG   (MAX_BPF_JIT_REG + 0)
+#define SKB_DATA_REG   (MAX_BPF_JIT_REG + 1)
+#define TMP_REG_1      (MAX_BPF_JIT_REG + 2)
+#define TMP_REG_2      (MAX_BPF_JIT_REG + 3)
 
 /* BPF to ppc register mappings */
 static const int b2p[] = {
@@ -62,6 +62,7 @@ static const int b2p[] = {
        /* frame pointer aka BPF_REG_10 */
        [BPF_REG_FP] = 31,
        /* eBPF jit internal registers */
+       [BPF_REG_AX] = 2,
        [SKB_HLEN_REG] = 25,
        [SKB_DATA_REG] = 26,
        [TMP_REG_1] = 9,
index 3ec29d6fba6077b691ab21bd57b9f29b8301d30a..0fe98a567125aa7c339f5dfa537d278cda223868 100644 (file)
@@ -974,21 +974,37 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
        int pass;
        int flen;
        struct bpf_binary_header *bpf_hdr;
+       struct bpf_prog *org_fp = fp;
+       struct bpf_prog *tmp_fp;
+       bool bpf_blinded = false;
 
        if (!bpf_jit_enable)
-               return fp;
+               return org_fp;
+
+       tmp_fp = bpf_jit_blind_constants(org_fp);
+       if (IS_ERR(tmp_fp))
+               return org_fp;
+
+       if (tmp_fp != org_fp) {
+               bpf_blinded = true;
+               fp = tmp_fp;
+       }
 
        flen = fp->len;
        addrs = kzalloc((flen+1) * sizeof(*addrs), GFP_KERNEL);
-       if (addrs == NULL)
-               return fp;
+       if (addrs == NULL) {
+               fp = org_fp;
+               goto out;
+       }
+
+       memset(&cgctx, 0, sizeof(struct codegen_context));
 
-       cgctx.idx = 0;
-       cgctx.seen = 0;
        /* Scouting faux-generate pass 0 */
-       if (bpf_jit_build_body(fp, 0, &cgctx, addrs))
+       if (bpf_jit_build_body(fp, 0, &cgctx, addrs)) {
                /* We hit something illegal or unsupported. */
+               fp = org_fp;
                goto out;
+       }
 
        /*
         * Pretend to build prologue, given the features we've seen.  This will
@@ -1003,8 +1019,10 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
 
        bpf_hdr = bpf_jit_binary_alloc(alloclen, &image, 4,
                        bpf_jit_fill_ill_insns);
-       if (!bpf_hdr)
+       if (!bpf_hdr) {
+               fp = org_fp;
                goto out;
+       }
 
        code_base = (u32 *)(image + FUNCTION_DESCR_SIZE);
 
@@ -1041,6 +1059,10 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
 
 out:
        kfree(addrs);
+
+       if (bpf_blinded)
+               bpf_jit_prog_release_other(fp, fp == org_fp ? tmp_fp : org_fp);
+
        return fp;
 }