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

bpf, ppc64: remove ld_abs/ld_ind

Since LD_ABS/LD_IND instructions are now removed from the core and
reimplemented through a combination of inlined BPF instructions and
a slow-path helper, we can get rid of the complexity from ppc64 JIT.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Tested-by: Sandipan Das <sandipan@linux.vnet.ibm.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Daniel Borkmann and committed by
Alexei Starovoitov
dbf44daf 4db25cc9

+11 -317
+1 -1
arch/powerpc/net/Makefile
··· 3 3 # Arch-specific network modules 4 4 # 5 5 ifeq ($(CONFIG_PPC64),y) 6 - obj-$(CONFIG_BPF_JIT) += bpf_jit_asm64.o bpf_jit_comp64.o 6 + obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o 7 7 else 8 8 obj-$(CONFIG_BPF_JIT) += bpf_jit_asm.o bpf_jit_comp.o 9 9 endif
+9 -28
arch/powerpc/net/bpf_jit64.h
··· 20 20 * with our redzone usage. 21 21 * 22 22 * [ prev sp ] <------------- 23 - * [ nv gpr save area ] 8*8 | 23 + * [ nv gpr save area ] 6*8 | 24 24 * [ tail_call_cnt ] 8 | 25 25 * [ local_tmp_var ] 8 | 26 26 * fp (r31) --> [ ebpf stack space ] upto 512 | ··· 28 28 * sp (r1) ---> [ stack pointer ] -------------- 29 29 */ 30 30 31 - /* for gpr non volatile registers BPG_REG_6 to 10, plus skb cache registers */ 32 - #define BPF_PPC_STACK_SAVE (8*8) 31 + /* for gpr non volatile registers BPG_REG_6 to 10 */ 32 + #define BPF_PPC_STACK_SAVE (6*8) 33 33 /* for bpf JIT code internal usage */ 34 34 #define BPF_PPC_STACK_LOCALS 16 35 35 /* stack frame excluding BPF stack, ensure this is quadword aligned */ ··· 39 39 #ifndef __ASSEMBLY__ 40 40 41 41 /* BPF register usage */ 42 - #define SKB_HLEN_REG (MAX_BPF_JIT_REG + 0) 43 - #define SKB_DATA_REG (MAX_BPF_JIT_REG + 1) 44 - #define TMP_REG_1 (MAX_BPF_JIT_REG + 2) 45 - #define TMP_REG_2 (MAX_BPF_JIT_REG + 3) 42 + #define TMP_REG_1 (MAX_BPF_JIT_REG + 0) 43 + #define TMP_REG_2 (MAX_BPF_JIT_REG + 1) 46 44 47 45 /* BPF to ppc register mappings */ 48 46 static const int b2p[] = { ··· 61 63 [BPF_REG_FP] = 31, 62 64 /* eBPF jit internal registers */ 63 65 [BPF_REG_AX] = 2, 64 - [SKB_HLEN_REG] = 25, 65 - [SKB_DATA_REG] = 26, 66 66 [TMP_REG_1] = 9, 67 67 [TMP_REG_2] = 10 68 68 }; 69 69 70 - /* PPC NVR range -- update this if we ever use NVRs below r24 */ 71 - #define BPF_PPC_NVR_MIN 24 72 - 73 - /* Assembly helpers */ 74 - #define DECLARE_LOAD_FUNC(func) u64 func(u64 r3, u64 r4); \ 75 - u64 func##_negative_offset(u64 r3, u64 r4); \ 76 - u64 func##_positive_offset(u64 r3, u64 r4); 77 - 78 - DECLARE_LOAD_FUNC(sk_load_word); 79 - DECLARE_LOAD_FUNC(sk_load_half); 80 - DECLARE_LOAD_FUNC(sk_load_byte); 81 - 82 - #define CHOOSE_LOAD_FUNC(imm, func) \ 83 - (imm < 0 ? \ 84 - (imm >= SKF_LL_OFF ? func##_negative_offset : func) : \ 85 - func##_positive_offset) 70 + /* PPC NVR range -- update this if we ever use NVRs below r27 */ 71 + #define BPF_PPC_NVR_MIN 27 86 72 87 73 #define SEEN_FUNC 0x1000 /* might call external helpers */ 88 74 #define SEEN_STACK 0x2000 /* uses BPF stack */ 89 - #define SEEN_SKB 0x4000 /* uses sk_buff */ 90 - #define SEEN_TAILCALL 0x8000 /* uses tail calls */ 75 + #define SEEN_TAILCALL 0x4000 /* uses tail calls */ 91 76 92 77 struct codegen_context { 93 78 /* 94 79 * This is used to track register usage as well 95 80 * as calls to external helpers. 96 81 * - register usage is tracked with corresponding 97 - * bits (r3-r10 and r25-r31) 82 + * bits (r3-r10 and r27-r31) 98 83 * - rest of the bits can be used to track other 99 84 * things -- for now, we use bits 16 to 23 100 85 * encoded in SEEN_* macros above
-180
arch/powerpc/net/bpf_jit_asm64.S
··· 1 - /* 2 - * bpf_jit_asm64.S: Packet/header access helper functions 3 - * for PPC64 BPF compiler. 4 - * 5 - * Copyright 2016, Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> 6 - * IBM Corporation 7 - * 8 - * Based on bpf_jit_asm.S by Matt Evans 9 - * 10 - * This program is free software; you can redistribute it and/or 11 - * modify it under the terms of the GNU General Public License 12 - * as published by the Free Software Foundation; version 2 13 - * of the License. 14 - */ 15 - 16 - #include <asm/ppc_asm.h> 17 - #include <asm/ptrace.h> 18 - #include "bpf_jit64.h" 19 - 20 - /* 21 - * All of these routines are called directly from generated code, 22 - * with the below register usage: 23 - * r27 skb pointer (ctx) 24 - * r25 skb header length 25 - * r26 skb->data pointer 26 - * r4 offset 27 - * 28 - * Result is passed back in: 29 - * r8 data read in host endian format (accumulator) 30 - * 31 - * r9 is used as a temporary register 32 - */ 33 - 34 - #define r_skb r27 35 - #define r_hlen r25 36 - #define r_data r26 37 - #define r_off r4 38 - #define r_val r8 39 - #define r_tmp r9 40 - 41 - _GLOBAL_TOC(sk_load_word) 42 - cmpdi r_off, 0 43 - blt bpf_slow_path_word_neg 44 - b sk_load_word_positive_offset 45 - 46 - _GLOBAL_TOC(sk_load_word_positive_offset) 47 - /* Are we accessing past headlen? */ 48 - subi r_tmp, r_hlen, 4 49 - cmpd r_tmp, r_off 50 - blt bpf_slow_path_word 51 - /* Nope, just hitting the header. cr0 here is eq or gt! */ 52 - LWZX_BE r_val, r_data, r_off 53 - blr /* Return success, cr0 != LT */ 54 - 55 - _GLOBAL_TOC(sk_load_half) 56 - cmpdi r_off, 0 57 - blt bpf_slow_path_half_neg 58 - b sk_load_half_positive_offset 59 - 60 - _GLOBAL_TOC(sk_load_half_positive_offset) 61 - subi r_tmp, r_hlen, 2 62 - cmpd r_tmp, r_off 63 - blt bpf_slow_path_half 64 - LHZX_BE r_val, r_data, r_off 65 - blr 66 - 67 - _GLOBAL_TOC(sk_load_byte) 68 - cmpdi r_off, 0 69 - blt bpf_slow_path_byte_neg 70 - b sk_load_byte_positive_offset 71 - 72 - _GLOBAL_TOC(sk_load_byte_positive_offset) 73 - cmpd r_hlen, r_off 74 - ble bpf_slow_path_byte 75 - lbzx r_val, r_data, r_off 76 - blr 77 - 78 - /* 79 - * Call out to skb_copy_bits: 80 - * Allocate a new stack frame here to remain ABI-compliant in 81 - * stashing LR. 82 - */ 83 - #define bpf_slow_path_common(SIZE) \ 84 - mflr r0; \ 85 - std r0, PPC_LR_STKOFF(r1); \ 86 - stdu r1, -(STACK_FRAME_MIN_SIZE + BPF_PPC_STACK_LOCALS)(r1); \ 87 - mr r3, r_skb; \ 88 - /* r4 = r_off as passed */ \ 89 - addi r5, r1, STACK_FRAME_MIN_SIZE; \ 90 - li r6, SIZE; \ 91 - bl skb_copy_bits; \ 92 - nop; \ 93 - /* save r5 */ \ 94 - addi r5, r1, STACK_FRAME_MIN_SIZE; \ 95 - /* r3 = 0 on success */ \ 96 - addi r1, r1, STACK_FRAME_MIN_SIZE + BPF_PPC_STACK_LOCALS; \ 97 - ld r0, PPC_LR_STKOFF(r1); \ 98 - mtlr r0; \ 99 - cmpdi r3, 0; \ 100 - blt bpf_error; /* cr0 = LT */ 101 - 102 - bpf_slow_path_word: 103 - bpf_slow_path_common(4) 104 - /* Data value is on stack, and cr0 != LT */ 105 - LWZX_BE r_val, 0, r5 106 - blr 107 - 108 - bpf_slow_path_half: 109 - bpf_slow_path_common(2) 110 - LHZX_BE r_val, 0, r5 111 - blr 112 - 113 - bpf_slow_path_byte: 114 - bpf_slow_path_common(1) 115 - lbzx r_val, 0, r5 116 - blr 117 - 118 - /* 119 - * Call out to bpf_internal_load_pointer_neg_helper 120 - */ 121 - #define sk_negative_common(SIZE) \ 122 - mflr r0; \ 123 - std r0, PPC_LR_STKOFF(r1); \ 124 - stdu r1, -STACK_FRAME_MIN_SIZE(r1); \ 125 - mr r3, r_skb; \ 126 - /* r4 = r_off, as passed */ \ 127 - li r5, SIZE; \ 128 - bl bpf_internal_load_pointer_neg_helper; \ 129 - nop; \ 130 - addi r1, r1, STACK_FRAME_MIN_SIZE; \ 131 - ld r0, PPC_LR_STKOFF(r1); \ 132 - mtlr r0; \ 133 - /* R3 != 0 on success */ \ 134 - cmpldi r3, 0; \ 135 - beq bpf_error_slow; /* cr0 = EQ */ 136 - 137 - bpf_slow_path_word_neg: 138 - lis r_tmp, -32 /* SKF_LL_OFF */ 139 - cmpd r_off, r_tmp /* addr < SKF_* */ 140 - blt bpf_error /* cr0 = LT */ 141 - b sk_load_word_negative_offset 142 - 143 - _GLOBAL_TOC(sk_load_word_negative_offset) 144 - sk_negative_common(4) 145 - LWZX_BE r_val, 0, r3 146 - blr 147 - 148 - bpf_slow_path_half_neg: 149 - lis r_tmp, -32 /* SKF_LL_OFF */ 150 - cmpd r_off, r_tmp /* addr < SKF_* */ 151 - blt bpf_error /* cr0 = LT */ 152 - b sk_load_half_negative_offset 153 - 154 - _GLOBAL_TOC(sk_load_half_negative_offset) 155 - sk_negative_common(2) 156 - LHZX_BE r_val, 0, r3 157 - blr 158 - 159 - bpf_slow_path_byte_neg: 160 - lis r_tmp, -32 /* SKF_LL_OFF */ 161 - cmpd r_off, r_tmp /* addr < SKF_* */ 162 - blt bpf_error /* cr0 = LT */ 163 - b sk_load_byte_negative_offset 164 - 165 - _GLOBAL_TOC(sk_load_byte_negative_offset) 166 - sk_negative_common(1) 167 - lbzx r_val, 0, r3 168 - blr 169 - 170 - bpf_error_slow: 171 - /* fabricate a cr0 = lt */ 172 - li r_tmp, -1 173 - cmpdi r_tmp, 0 174 - bpf_error: 175 - /* 176 - * Entered with cr0 = lt 177 - * Generated code will 'blt epilogue', returning 0. 178 - */ 179 - li r_val, 0 180 - blr
+1 -108
arch/powerpc/net/bpf_jit_comp64.c
··· 59 59 * [ prev sp ] <------------- 60 60 * [ ... ] | 61 61 * sp (r1) ---> [ stack pointer ] -------------- 62 - * [ nv gpr save area ] 8*8 62 + * [ nv gpr save area ] 6*8 63 63 * [ tail_call_cnt ] 8 64 64 * [ local_tmp_var ] 8 65 65 * [ unused red zone ] 208 bytes protected ··· 86 86 87 87 pr_err("BPF JIT is asking about unknown registers"); 88 88 BUG(); 89 - } 90 - 91 - static void bpf_jit_emit_skb_loads(u32 *image, struct codegen_context *ctx) 92 - { 93 - /* 94 - * Load skb->len and skb->data_len 95 - * r3 points to skb 96 - */ 97 - PPC_LWZ(b2p[SKB_HLEN_REG], 3, offsetof(struct sk_buff, len)); 98 - PPC_LWZ(b2p[TMP_REG_1], 3, offsetof(struct sk_buff, data_len)); 99 - /* header_len = len - data_len */ 100 - PPC_SUB(b2p[SKB_HLEN_REG], b2p[SKB_HLEN_REG], b2p[TMP_REG_1]); 101 - 102 - /* skb->data pointer */ 103 - PPC_BPF_LL(b2p[SKB_DATA_REG], 3, offsetof(struct sk_buff, data)); 104 89 } 105 90 106 91 static void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx) ··· 130 145 if (bpf_is_seen_register(ctx, i)) 131 146 PPC_BPF_STL(b2p[i], 1, bpf_jit_stack_offsetof(ctx, b2p[i])); 132 147 133 - /* 134 - * Save additional non-volatile regs if we cache skb 135 - * Also, setup skb data 136 - */ 137 - if (ctx->seen & SEEN_SKB) { 138 - PPC_BPF_STL(b2p[SKB_HLEN_REG], 1, 139 - bpf_jit_stack_offsetof(ctx, b2p[SKB_HLEN_REG])); 140 - PPC_BPF_STL(b2p[SKB_DATA_REG], 1, 141 - bpf_jit_stack_offsetof(ctx, b2p[SKB_DATA_REG])); 142 - bpf_jit_emit_skb_loads(image, ctx); 143 - } 144 - 145 148 /* Setup frame pointer to point to the bpf stack area */ 146 149 if (bpf_is_seen_register(ctx, BPF_REG_FP)) 147 150 PPC_ADDI(b2p[BPF_REG_FP], 1, ··· 144 171 for (i = BPF_REG_6; i <= BPF_REG_10; i++) 145 172 if (bpf_is_seen_register(ctx, i)) 146 173 PPC_BPF_LL(b2p[i], 1, bpf_jit_stack_offsetof(ctx, b2p[i])); 147 - 148 - /* Restore non-volatile registers used for skb cache */ 149 - if (ctx->seen & SEEN_SKB) { 150 - PPC_BPF_LL(b2p[SKB_HLEN_REG], 1, 151 - bpf_jit_stack_offsetof(ctx, b2p[SKB_HLEN_REG])); 152 - PPC_BPF_LL(b2p[SKB_DATA_REG], 1, 153 - bpf_jit_stack_offsetof(ctx, b2p[SKB_DATA_REG])); 154 - } 155 174 156 175 /* Tear down our stack frame */ 157 176 if (bpf_has_stack_frame(ctx)) { ··· 718 753 ctx->seen |= SEEN_FUNC; 719 754 func = (u8 *) __bpf_call_base + imm; 720 755 721 - /* Save skb pointer if we need to re-cache skb data */ 722 - if ((ctx->seen & SEEN_SKB) && 723 - bpf_helper_changes_pkt_data(func)) 724 - PPC_BPF_STL(3, 1, bpf_jit_stack_local(ctx)); 725 - 726 756 bpf_jit_emit_func_call(image, ctx, (u64)func); 727 757 728 758 /* move return value from r3 to BPF_REG_0 */ 729 759 PPC_MR(b2p[BPF_REG_0], 3); 730 - 731 - /* refresh skb cache */ 732 - if ((ctx->seen & SEEN_SKB) && 733 - bpf_helper_changes_pkt_data(func)) { 734 - /* reload skb pointer to r3 */ 735 - PPC_BPF_LL(3, 1, bpf_jit_stack_local(ctx)); 736 - bpf_jit_emit_skb_loads(image, ctx); 737 - } 738 760 break; 739 761 740 762 /* ··· 836 884 break; 837 885 } 838 886 PPC_BCC(true_cond, addrs[i + 1 + off]); 839 - break; 840 - 841 - /* 842 - * Loads from packet header/data 843 - * Assume 32-bit input value in imm and X (src_reg) 844 - */ 845 - 846 - /* Absolute loads */ 847 - case BPF_LD | BPF_W | BPF_ABS: 848 - func = (u8 *)CHOOSE_LOAD_FUNC(imm, sk_load_word); 849 - goto common_load_abs; 850 - case BPF_LD | BPF_H | BPF_ABS: 851 - func = (u8 *)CHOOSE_LOAD_FUNC(imm, sk_load_half); 852 - goto common_load_abs; 853 - case BPF_LD | BPF_B | BPF_ABS: 854 - func = (u8 *)CHOOSE_LOAD_FUNC(imm, sk_load_byte); 855 - common_load_abs: 856 - /* 857 - * Load from [imm] 858 - * Load into r4, which can just be passed onto 859 - * skb load helpers as the second parameter 860 - */ 861 - PPC_LI32(4, imm); 862 - goto common_load; 863 - 864 - /* Indirect loads */ 865 - case BPF_LD | BPF_W | BPF_IND: 866 - func = (u8 *)sk_load_word; 867 - goto common_load_ind; 868 - case BPF_LD | BPF_H | BPF_IND: 869 - func = (u8 *)sk_load_half; 870 - goto common_load_ind; 871 - case BPF_LD | BPF_B | BPF_IND: 872 - func = (u8 *)sk_load_byte; 873 - common_load_ind: 874 - /* 875 - * Load from [src_reg + imm] 876 - * Treat src_reg as a 32-bit value 877 - */ 878 - PPC_EXTSW(4, src_reg); 879 - if (imm) { 880 - if (imm >= -32768 && imm < 32768) 881 - PPC_ADDI(4, 4, IMM_L(imm)); 882 - else { 883 - PPC_LI32(b2p[TMP_REG_1], imm); 884 - PPC_ADD(4, 4, b2p[TMP_REG_1]); 885 - } 886 - } 887 - 888 - common_load: 889 - ctx->seen |= SEEN_SKB; 890 - ctx->seen |= SEEN_FUNC; 891 - bpf_jit_emit_func_call(image, ctx, (u64)func); 892 - 893 - /* 894 - * Helper returns 'lt' condition on error, and an 895 - * appropriate return value in BPF_REG_0 896 - */ 897 - PPC_BCC(COND_LT, exit_addr); 898 887 break; 899 888 900 889 /*