Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ppc: bpf: update jit to use compatibility macros

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>

authored by

Denis Kirjanov and committed by
David S. Miller
09ca5ab2 693930d6

+98 -51
+46 -1
arch/powerpc/net/bpf_jit.h
··· 10 10 #ifndef _BPF_JIT_H 11 11 #define _BPF_JIT_H 12 12 13 + #ifdef CONFIG_PPC64 14 + #define BPF_PPC_STACK_R3_OFF 48 13 15 #define BPF_PPC_STACK_LOCALS 32 14 16 #define BPF_PPC_STACK_BASIC (48+64) 15 17 #define BPF_PPC_STACK_SAVE (18*8) 16 18 #define BPF_PPC_STACKFRAME (BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \ 17 19 BPF_PPC_STACK_SAVE) 18 20 #define BPF_PPC_SLOWPATH_FRAME (48+64) 21 + #else 22 + #define BPF_PPC_STACK_R3_OFF 24 23 + #define BPF_PPC_STACK_LOCALS 16 24 + #define BPF_PPC_STACK_BASIC (24+32) 25 + #define BPF_PPC_STACK_SAVE (18*4) 26 + #define BPF_PPC_STACKFRAME (BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \ 27 + BPF_PPC_STACK_SAVE) 28 + #define BPF_PPC_SLOWPATH_FRAME (24+32) 29 + #endif 30 + 31 + #define REG_SZ (BITS_PER_LONG/8) 19 32 20 33 /* 21 34 * Generated code register usage: ··· 70 57 DECLARE_LOAD_FUNC(sk_load_byte); 71 58 DECLARE_LOAD_FUNC(sk_load_byte_msh); 72 59 60 + #ifdef CONFIG_PPC64 73 61 #define FUNCTION_DESCR_SIZE 24 62 + #else 63 + #define FUNCTION_DESCR_SIZE 0 64 + #endif 74 65 75 66 /* 76 67 * 16-bit immediate helper macros: HA() is for use with sign-extending instrs ··· 103 86 #define PPC_LIS(r, i) PPC_ADDIS(r, 0, i) 104 87 #define PPC_STD(r, base, i) EMIT(PPC_INST_STD | ___PPC_RS(r) | \ 105 88 ___PPC_RA(base) | ((i) & 0xfffc)) 106 - 89 + #define PPC_STDU(r, base, i) EMIT(PPC_INST_STDU | ___PPC_RS(r) | \ 90 + ___PPC_RA(base) | ((i) & 0xfffc)) 91 + #define PPC_STW(r, base, i) EMIT(PPC_INST_STW | ___PPC_RS(r) | \ 92 + ___PPC_RA(base) | ((i) & 0xfffc)) 93 + #define PPC_STWU(r, base, i) EMIT(PPC_INST_STWU | ___PPC_RS(r) | \ 94 + ___PPC_RA(base) | ((i) & 0xfffc)) 107 95 108 96 #define PPC_LBZ(r, base, i) EMIT(PPC_INST_LBZ | ___PPC_RT(r) | \ 109 97 ___PPC_RA(base) | IMM_L(i)) ··· 120 98 ___PPC_RA(base) | IMM_L(i)) 121 99 #define PPC_LHBRX(r, base, b) EMIT(PPC_INST_LHBRX | ___PPC_RT(r) | \ 122 100 ___PPC_RA(base) | ___PPC_RB(b)) 101 + 102 + #ifdef CONFIG_PPC64 103 + #define PPC_BPF_LL(r, base, i) do { PPC_LD(r, base, i); } while(0) 104 + #define PPC_BPF_STL(r, base, i) do { PPC_STD(r, base, i); } while(0) 105 + #define PPC_BPF_STLU(r, base, i) do { PPC_STDU(r, base, i); } while(0) 106 + #else 107 + #define PPC_BPF_LL(r, base, i) do { PPC_LWZ(r, base, i); } while(0) 108 + #define PPC_BPF_STL(r, base, i) do { PPC_STW(r, base, i); } while(0) 109 + #define PPC_BPF_STLU(r, base, i) do { PPC_STWU(r, base, i); } while(0) 110 + #endif 111 + 123 112 /* Convenience helpers for the above with 'far' offsets: */ 124 113 #define PPC_LBZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LBZ(r, base, i); \ 125 114 else { PPC_ADDIS(r, base, IMM_HA(i)); \ ··· 147 114 #define PPC_LHZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LHZ(r, base, i); \ 148 115 else { PPC_ADDIS(r, base, IMM_HA(i)); \ 149 116 PPC_LHZ(r, r, IMM_L(i)); } } while(0) 117 + 118 + #ifdef CONFIG_PPC64 119 + #define PPC_LL_OFFS(r, base, i) do { PPC_LD_OFFS(r, base, i); } while(0) 120 + #else 121 + #define PPC_LL_OFFS(r, base, i) do { PPC_LWZ_OFFS(r, base, i); } while(0) 122 + #endif 150 123 151 124 #define PPC_CMPWI(a, i) EMIT(PPC_INST_CMPWI | ___PPC_RA(a) | IMM_L(i)) 152 125 #define PPC_CMPDI(a, i) EMIT(PPC_INST_CMPDI | ___PPC_RA(a) | IMM_L(i)) ··· 234 195 if ((uintptr_t)(i) & 0x000000000000ffffULL) \ 235 196 PPC_ORI(d, d, (uintptr_t)(i) & 0xffff); \ 236 197 } } while (0); 198 + 199 + #ifdef CONFIG_PPC64 200 + #define PPC_FUNC_ADDR(d,i) do { PPC_LI64(d, i); } while(0) 201 + #else 202 + #define PPC_FUNC_ADDR(d,i) do { PPC_LI32(d, i); } while(0) 203 + #endif 237 204 238 205 #define PPC_LHBRX_OFFS(r, base, i) \ 239 206 do { PPC_LI32(r, i); PPC_LHBRX(r, r, base); } while(0)
+35 -35
arch/powerpc/net/bpf_jit_64.S
··· 34 34 */ 35 35 .globl sk_load_word 36 36 sk_load_word: 37 - cmpdi r_addr, 0 37 + PPC_LCMPI r_addr, 0 38 38 blt bpf_slow_path_word_neg 39 39 .globl sk_load_word_positive_offset 40 40 sk_load_word_positive_offset: 41 41 /* Are we accessing past headlen? */ 42 42 subi r_scratch1, r_HL, 4 43 - cmpd r_scratch1, r_addr 43 + PPC_LCMP r_scratch1, r_addr 44 44 blt bpf_slow_path_word 45 45 /* Nope, just hitting the header. cr0 here is eq or gt! */ 46 46 #ifdef __LITTLE_ENDIAN__ ··· 52 52 53 53 .globl sk_load_half 54 54 sk_load_half: 55 - cmpdi r_addr, 0 55 + PPC_LCMPI r_addr, 0 56 56 blt bpf_slow_path_half_neg 57 57 .globl sk_load_half_positive_offset 58 58 sk_load_half_positive_offset: 59 59 subi r_scratch1, r_HL, 2 60 - cmpd r_scratch1, r_addr 60 + PPC_LCMP r_scratch1, r_addr 61 61 blt bpf_slow_path_half 62 62 #ifdef __LITTLE_ENDIAN__ 63 63 lhbrx r_A, r_D, r_addr ··· 68 68 69 69 .globl sk_load_byte 70 70 sk_load_byte: 71 - cmpdi r_addr, 0 71 + PPC_LCMPI r_addr, 0 72 72 blt bpf_slow_path_byte_neg 73 73 .globl sk_load_byte_positive_offset 74 74 sk_load_byte_positive_offset: 75 - cmpd r_HL, r_addr 75 + PPC_LCMP r_HL, r_addr 76 76 ble bpf_slow_path_byte 77 77 lbzx r_A, r_D, r_addr 78 78 blr ··· 83 83 */ 84 84 .globl sk_load_byte_msh 85 85 sk_load_byte_msh: 86 - cmpdi r_addr, 0 86 + PPC_LCMPI r_addr, 0 87 87 blt bpf_slow_path_byte_msh_neg 88 88 .globl sk_load_byte_msh_positive_offset 89 89 sk_load_byte_msh_positive_offset: 90 - cmpd r_HL, r_addr 90 + PPC_LCMP r_HL, r_addr 91 91 ble bpf_slow_path_byte_msh 92 92 lbzx r_X, r_D, r_addr 93 93 rlwinm r_X, r_X, 2, 32-4-2, 31-2 ··· 101 101 */ 102 102 #define bpf_slow_path_common(SIZE) \ 103 103 mflr r0; \ 104 - std r0, 16(r1); \ 104 + PPC_STL r0, PPC_LR_STKOFF(r1); \ 105 105 /* R3 goes in parameter space of caller's frame */ \ 106 - std r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ 107 - std r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ 108 - std r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ 109 - addi r5, r1, BPF_PPC_STACK_BASIC+(2*8); \ 110 - stdu r1, -BPF_PPC_SLOWPATH_FRAME(r1); \ 106 + PPC_STL r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1); \ 107 + PPC_STL r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1); \ 108 + PPC_STL r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1); \ 109 + addi r5, r1, BPF_PPC_STACK_BASIC+(2*REG_SZ); \ 110 + PPC_STLU r1, -BPF_PPC_SLOWPATH_FRAME(r1); \ 111 111 /* R3 = r_skb, as passed */ \ 112 112 mr r4, r_addr; \ 113 113 li r6, SIZE; \ ··· 115 115 nop; \ 116 116 /* R3 = 0 on success */ \ 117 117 addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \ 118 - ld r0, 16(r1); \ 119 - ld r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ 120 - ld r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ 118 + PPC_LL r0, PPC_LR_STKOFF(r1); \ 119 + PPC_LL r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1); \ 120 + PPC_LL r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1); \ 121 121 mtlr r0; \ 122 - cmpdi r3, 0; \ 122 + PPC_LCMPI r3, 0; \ 123 123 blt bpf_error; /* cr0 = LT */ \ 124 - ld r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ 124 + PPC_LL r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1); \ 125 125 /* Great success! */ 126 126 127 127 bpf_slow_path_word: 128 128 bpf_slow_path_common(4) 129 129 /* Data value is on stack, and cr0 != LT */ 130 - lwz r_A, BPF_PPC_STACK_BASIC+(2*8)(r1) 130 + lwz r_A, BPF_PPC_STACK_BASIC+(2*REG_SZ)(r1) 131 131 blr 132 132 133 133 bpf_slow_path_half: ··· 154 154 */ 155 155 #define sk_negative_common(SIZE) \ 156 156 mflr r0; \ 157 - std r0, 16(r1); \ 157 + PPC_STL r0, PPC_LR_STKOFF(r1); \ 158 158 /* R3 goes in parameter space of caller's frame */ \ 159 - std r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ 160 - std r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ 161 - std r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ 162 - stdu r1, -BPF_PPC_SLOWPATH_FRAME(r1); \ 159 + PPC_STL r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1); \ 160 + PPC_STL r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1); \ 161 + PPC_STL r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1); \ 162 + PPC_STLU r1, -BPF_PPC_SLOWPATH_FRAME(r1); \ 163 163 /* R3 = r_skb, as passed */ \ 164 164 mr r4, r_addr; \ 165 165 li r5, SIZE; \ ··· 167 167 nop; \ 168 168 /* R3 != 0 on success */ \ 169 169 addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \ 170 - ld r0, 16(r1); \ 171 - ld r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ 172 - ld r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ 170 + PPC_LL r0, PPC_LR_STKOFF(r1); \ 171 + PPC_LL r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1); \ 172 + PPC_LL r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1); \ 173 173 mtlr r0; \ 174 - cmpldi r3, 0; \ 174 + PPC_LCMPLI r3, 0; \ 175 175 beq bpf_error_slow; /* cr0 = EQ */ \ 176 176 mr r_addr, r3; \ 177 - ld r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ 177 + PPC_LL r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1); \ 178 178 /* Great success! */ 179 179 180 180 bpf_slow_path_word_neg: 181 181 lis r_scratch1,-32 /* SKF_LL_OFF */ 182 - cmpd r_addr, r_scratch1 /* addr < SKF_* */ 182 + PPC_LCMP r_addr, r_scratch1 /* addr < SKF_* */ 183 183 blt bpf_error /* cr0 = LT */ 184 184 .globl sk_load_word_negative_offset 185 185 sk_load_word_negative_offset: ··· 189 189 190 190 bpf_slow_path_half_neg: 191 191 lis r_scratch1,-32 /* SKF_LL_OFF */ 192 - cmpd r_addr, r_scratch1 /* addr < SKF_* */ 192 + PPC_LCMP r_addr, r_scratch1 /* addr < SKF_* */ 193 193 blt bpf_error /* cr0 = LT */ 194 194 .globl sk_load_half_negative_offset 195 195 sk_load_half_negative_offset: ··· 199 199 200 200 bpf_slow_path_byte_neg: 201 201 lis r_scratch1,-32 /* SKF_LL_OFF */ 202 - cmpd r_addr, r_scratch1 /* addr < SKF_* */ 202 + PPC_LCMP r_addr, r_scratch1 /* addr < SKF_* */ 203 203 blt bpf_error /* cr0 = LT */ 204 204 .globl sk_load_byte_negative_offset 205 205 sk_load_byte_negative_offset: ··· 209 209 210 210 bpf_slow_path_byte_msh_neg: 211 211 lis r_scratch1,-32 /* SKF_LL_OFF */ 212 - cmpd r_addr, r_scratch1 /* addr < SKF_* */ 212 + PPC_LCMP r_addr, r_scratch1 /* addr < SKF_* */ 213 213 blt bpf_error /* cr0 = LT */ 214 214 .globl sk_load_byte_msh_negative_offset 215 215 sk_load_byte_msh_negative_offset: ··· 221 221 bpf_error_slow: 222 222 /* fabricate a cr0 = lt */ 223 223 li r_scratch1, -1 224 - cmpdi r_scratch1, 0 224 + PPC_LCMPI r_scratch1, 0 225 225 bpf_error: 226 226 /* Entered with cr0 = lt */ 227 227 li r3, 0
+17 -15
arch/powerpc/net/bpf_jit_comp.c
··· 1 - /* bpf_jit_comp.c: BPF JIT compiler for PPC64 1 + /* bpf_jit_comp.c: BPF JIT compiler 2 2 * 3 3 * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation 4 4 * 5 5 * Based on the x86 BPF compiler, by Eric Dumazet (eric.dumazet@gmail.com) 6 + * Ported to ppc32 by Denis Kirjanov <kda@linux-powerpc.org> 6 7 * 7 8 * This program is free software; you can redistribute it and/or 8 9 * modify it under the terms of the GNU General Public License ··· 37 36 if (ctx->seen & SEEN_DATAREF) { 38 37 /* If we call any helpers (for loads), save LR */ 39 38 EMIT(PPC_INST_MFLR | __PPC_RT(R0)); 40 - PPC_STD(0, 1, 16); 39 + PPC_BPF_STL(0, 1, PPC_LR_STKOFF); 41 40 42 41 /* Back up non-volatile regs. */ 43 - PPC_STD(r_D, 1, -(8*(32-r_D))); 44 - PPC_STD(r_HL, 1, -(8*(32-r_HL))); 42 + PPC_BPF_STL(r_D, 1, -(REG_SZ*(32-r_D))); 43 + PPC_BPF_STL(r_HL, 1, -(REG_SZ*(32-r_HL))); 45 44 } 46 45 if (ctx->seen & SEEN_MEM) { 47 46 /* ··· 50 49 */ 51 50 for (i = r_M; i < (r_M+16); i++) { 52 51 if (ctx->seen & (1 << (i-r_M))) 53 - PPC_STD(i, 1, -(8*(32-i))); 52 + PPC_BPF_STL(i, 1, -(REG_SZ*(32-i))); 54 53 } 55 54 } 56 - EMIT(PPC_INST_STDU | __PPC_RS(R1) | __PPC_RA(R1) | 57 - (-BPF_PPC_STACKFRAME & 0xfffc)); 55 + PPC_BPF_STLU(1, 1, -BPF_PPC_STACKFRAME); 58 56 } 59 57 60 58 if (ctx->seen & SEEN_DATAREF) { ··· 67 67 data_len)); 68 68 PPC_LWZ_OFFS(r_HL, r_skb, offsetof(struct sk_buff, len)); 69 69 PPC_SUB(r_HL, r_HL, r_scratch1); 70 - PPC_LD_OFFS(r_D, r_skb, offsetof(struct sk_buff, data)); 70 + PPC_LL_OFFS(r_D, r_skb, offsetof(struct sk_buff, data)); 71 71 } 72 72 73 73 if (ctx->seen & SEEN_XREG) { ··· 99 99 if (ctx->seen & (SEEN_MEM | SEEN_DATAREF)) { 100 100 PPC_ADDI(1, 1, BPF_PPC_STACKFRAME); 101 101 if (ctx->seen & SEEN_DATAREF) { 102 - PPC_LD(0, 1, 16); 102 + PPC_BPF_LL(0, 1, PPC_LR_STKOFF); 103 103 PPC_MTLR(0); 104 - PPC_LD(r_D, 1, -(8*(32-r_D))); 105 - PPC_LD(r_HL, 1, -(8*(32-r_HL))); 104 + PPC_BPF_LL(r_D, 1, -(REG_SZ*(32-r_D))); 105 + PPC_BPF_LL(r_HL, 1, -(REG_SZ*(32-r_HL))); 106 106 } 107 107 if (ctx->seen & SEEN_MEM) { 108 108 /* Restore any saved non-vol registers */ 109 109 for (i = r_M; i < (r_M+16); i++) { 110 110 if (ctx->seen & (1 << (i-r_M))) 111 - PPC_LD(i, 1, -(8*(32-i))); 111 + PPC_BPF_LL(i, 1, -(REG_SZ*(32-i))); 112 112 } 113 113 } 114 114 } ··· 355 355 ifindex) != 4); 356 356 BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, 357 357 type) != 2); 358 - PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, 358 + PPC_LL_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, 359 359 dev)); 360 360 PPC_CMPDI(r_scratch1, 0); 361 361 if (ctx->pc_ret0 != -1) { ··· 437 437 common_load: 438 438 /* Load from [K]. */ 439 439 ctx->seen |= SEEN_DATAREF; 440 - PPC_LI64(r_scratch1, func); 440 + PPC_FUNC_ADDR(r_scratch1, func); 441 441 PPC_MTLR(r_scratch1); 442 442 PPC_LI32(r_addr, K); 443 443 PPC_BLRL(); ··· 463 463 * in the helper functions. 464 464 */ 465 465 ctx->seen |= SEEN_DATAREF | SEEN_XREG; 466 - PPC_LI64(r_scratch1, func); 466 + PPC_FUNC_ADDR(r_scratch1, func); 467 467 PPC_MTLR(r_scratch1); 468 468 PPC_ADDI(r_addr, r_X, IMM_L(K)); 469 469 if (K >= 32768) ··· 685 685 686 686 if (image) { 687 687 bpf_flush_icache(code_base, code_base + (proglen/4)); 688 + #ifdef CONFIG_PPC64 688 689 /* Function descriptor nastiness: Address + TOC */ 689 690 ((u64 *)image)[0] = (u64)code_base; 690 691 ((u64 *)image)[1] = local_paca->kernel_toc; 692 + #endif 691 693 fp->bpf_func = (void *)image; 692 694 fp->jited = true; 693 695 }