Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions arch/powerpc/net/bpf_jit_comp.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,22 @@ bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
return true;
}

bool bpf_jit_supports_percpu_insn(void)
{
return IS_ENABLED(CONFIG_PPC64);
}

bool bpf_jit_inlines_helper_call(s32 imm)
{
switch (imm) {
case BPF_FUNC_get_smp_processor_id:
case BPF_FUNC_get_current_task:
return true;
default:
return false;
}
}

void *arch_alloc_bpf_trampoline(unsigned int size)
{
return bpf_prog_pack_alloc(size, bpf_jit_fill_ill_insns);
Expand Down
19 changes: 19 additions & 0 deletions arch/powerpc/net/bpf_jit_comp64.c
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,15 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
case BPF_ALU | BPF_MOV | BPF_X: /* (u32) dst = src */
case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */

if (insn_is_mov_percpu_addr(&insn[i])) {
if (IS_ENABLED(CONFIG_SMP)) {
EMIT(PPC_RAW_LD(tmp1_reg, _R13, offsetof(struct paca_struct, data_offset)));
EMIT(PPC_RAW_ADD(dst_reg, src_reg, tmp1_reg));
} else {
EMIT(PPC_RAW_MR(dst_reg, src_reg));
}
}

if (insn_is_cast_user(&insn[i])) {
EMIT(PPC_RAW_RLDICL_DOT(tmp1_reg, src_reg, 0, 32));
PPC_LI64(dst_reg, (ctx->user_vm_start & 0xffffffff00000000UL));
Expand Down Expand Up @@ -1390,6 +1399,16 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
case BPF_JMP | BPF_CALL:
ctx->seen |= SEEN_FUNC;

if (insn[i].src_reg == BPF_REG_0) {
if (imm == BPF_FUNC_get_smp_processor_id) {
EMIT(PPC_RAW_LHZ(insn[i].src_reg, _R13, offsetof(struct paca_struct, paca_index)));
break;
} else if (imm == BPF_FUNC_get_current_task) {
EMIT(PPC_RAW_LD(insn[i].src_reg, _R13, offsetof(struct paca_struct, __current)));
break;
}
}

ret = bpf_jit_get_func_addr(fp, &insn[i], extra_pass,
&func_addr, &func_addr_fixed);
if (ret < 0)
Expand Down
Loading