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

Configure Feed

Select the types of activity you want to include in your feed.

powerpc64/bpf: Implement bpf_addr_space_cast instruction

LLVM generates bpf_addr_space_cast instruction while translating
pointers between native (zero) address space and
__attribute__((address_space(N))). The addr_space=0 is reserved as
bpf_arena address space.

rY = addr_space_cast(rX, 0, 1) is processed by the verifier and
converted to normal 32-bit move: wX = wY.

rY = addr_space_cast(rX, 1, 0) : used to convert a bpf arena pointer to
a pointer in the userspace vma. This has to be converted by the JIT.

PPC_RAW_RLDICL_DOT, a variant of PPC_RAW_RLDICL is introduced to set
condition register as well.

Reviewed-by: Hari Bathini <hbathini@linux.ibm.com>
Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20250904100835.1100423-3-skb99@linux.ibm.com

authored by

Saket Kumar Bhaskar and committed by
Madhavan Srinivasan
a2485d06 47c7f3b7

+18
+1
arch/powerpc/include/asm/ppc-opcode.h
··· 571 571 (0x54000001 | ___PPC_RA(d) | ___PPC_RS(a) | __PPC_SH(i) | __PPC_MB(mb) | __PPC_ME(me)) 572 572 #define PPC_RAW_RLWIMI(d, a, i, mb, me) (0x50000000 | ___PPC_RA(d) | ___PPC_RS(a) | __PPC_SH(i) | __PPC_MB(mb) | __PPC_ME(me)) 573 573 #define PPC_RAW_RLDICL(d, a, i, mb) (0x78000000 | ___PPC_RA(d) | ___PPC_RS(a) | __PPC_SH64(i) | __PPC_MB64(mb)) 574 + #define PPC_RAW_RLDICL_DOT(d, a, i, mb) (0x78000000 | ___PPC_RA(d) | ___PPC_RS(a) | __PPC_SH64(i) | __PPC_MB64(mb) | 0x1) 574 575 #define PPC_RAW_RLDICR(d, a, i, me) (0x78000004 | ___PPC_RA(d) | ___PPC_RS(a) | __PPC_SH64(i) | __PPC_ME64(me)) 575 576 576 577 /* slwi = rlwinm Rx, Ry, n, 0, 31-n */
+1
arch/powerpc/net/bpf_jit.h
··· 165 165 unsigned int exentry_idx; 166 166 unsigned int alt_exit_addr; 167 167 u64 arena_vm_start; 168 + u64 user_vm_start; 168 169 }; 169 170 170 171 #define bpf_to_ppc(r) (ctx->b2p[r])
+6
arch/powerpc/net/bpf_jit_comp.c
··· 205 205 /* Make sure that the stack is quadword aligned. */ 206 206 cgctx.stack_size = round_up(fp->aux->stack_depth, 16); 207 207 cgctx.arena_vm_start = bpf_arena_get_kern_vm_start(fp->aux->arena); 208 + cgctx.user_vm_start = bpf_arena_get_user_vm_start(fp->aux->arena); 208 209 209 210 /* Scouting faux-generate pass 0 */ 210 211 if (bpf_jit_build_body(fp, NULL, NULL, &cgctx, addrs, 0, false)) { ··· 438 437 bool bpf_jit_supports_kfunc_call(void) 439 438 { 440 439 return true; 440 + } 441 + 442 + bool bpf_jit_supports_arena(void) 443 + { 444 + return IS_ENABLED(CONFIG_PPC64); 441 445 } 442 446 443 447 bool bpf_jit_supports_far_kfunc_call(void)
+10
arch/powerpc/net/bpf_jit_comp64.c
··· 812 812 */ 813 813 case BPF_ALU | BPF_MOV | BPF_X: /* (u32) dst = src */ 814 814 case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */ 815 + 816 + if (insn_is_cast_user(&insn[i])) { 817 + EMIT(PPC_RAW_RLDICL_DOT(tmp1_reg, src_reg, 0, 32)); 818 + PPC_LI64(dst_reg, (ctx->user_vm_start & 0xffffffff00000000UL)); 819 + PPC_BCC_SHORT(COND_EQ, (ctx->idx + 2) * 4); 820 + EMIT(PPC_RAW_OR(tmp1_reg, dst_reg, tmp1_reg)); 821 + EMIT(PPC_RAW_MR(dst_reg, tmp1_reg)); 822 + break; 823 + } 824 + 815 825 if (imm == 1) { 816 826 /* special mov32 for zext */ 817 827 EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 0, 0, 31));