arch/powerpc/net/bpf_jit_comp32.c

Source file repositories/reference/linux-study-clean/arch/powerpc/net/bpf_jit_comp32.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/net/bpf_jit_comp32.c
Extension
.c
Size
44528 bytes
Lines
1424
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (i != TMP_REG) {
				bpf_set_seen_register(ctx, new - 1);
				bpf_clear_seen_register(ctx, old - 1);
			}
			break;
		}
	}
}

void prepare_for_fsession_fentry(u32 *image, struct codegen_context *ctx, int cookie_cnt,
						int cookie_off, int retval_off)
{
	/*
	 * Set session cookies value
	 * Clear cookies field on stack
	 * Ensure retval to be cleared on fentry
	 */
	EMIT(PPC_RAW_LI(bpf_to_ppc(TMP_REG), 0));

	for (int i = 0; i < cookie_cnt; i++) {
		EMIT(PPC_RAW_STW(bpf_to_ppc(TMP_REG), _R1, cookie_off + 4 * i));
		EMIT(PPC_RAW_STW(bpf_to_ppc(TMP_REG), _R1, cookie_off + 4 * i + 4));
	}

	EMIT(PPC_RAW_STW(bpf_to_ppc(TMP_REG), _R1, retval_off));
	EMIT(PPC_RAW_STW(bpf_to_ppc(TMP_REG), _R1, retval_off + 4));
}

void store_func_meta(u32 *image, struct codegen_context *ctx,
					u64 func_meta, int func_meta_off)
{
	/*
	 * Store func_meta to stack: [R1 + func_meta_off] = func_meta
	 * func_meta := argument count in first byte + cookie value
	 */
	/* Store lower word */
	PPC_LI32(bpf_to_ppc(TMP_REG), (u32)func_meta);
	EMIT(PPC_RAW_STW(bpf_to_ppc(TMP_REG), _R1, func_meta_off));

	/* Store upper word */
	PPC_LI32(bpf_to_ppc(TMP_REG), (u32)(func_meta >> 32));
	EMIT(PPC_RAW_STW(bpf_to_ppc(TMP_REG), _R1, func_meta_off + 4));
}

void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx)
{
	int i;

	/* Instruction for trampoline attach */
	EMIT(PPC_RAW_NOP());

	/* Initialize tail_call_cnt, to be skipped if we do tail calls. */
	if (ctx->seen & SEEN_TAILCALL)
		EMIT(PPC_RAW_LI(_R4, 0));
	else
		EMIT(PPC_RAW_NOP());

#define BPF_TAILCALL_PROLOGUE_SIZE	8

	if (bpf_has_stack_frame(ctx))
		EMIT(PPC_RAW_STWU(_R1, _R1, -BPF_PPC_STACKFRAME(ctx)));

	if (ctx->seen & SEEN_TAILCALL)
		EMIT(PPC_RAW_STW(_R4, _R1, bpf_jit_stack_offsetof(ctx, BPF_PPC_TC)));

	/* First arg comes in as a 32 bits pointer. */
	EMIT(PPC_RAW_MR(bpf_to_ppc(BPF_REG_1), _R3));
	EMIT(PPC_RAW_LI(bpf_to_ppc(BPF_REG_1) - 1, 0));

	/*
	 * We need a stack frame, but we don't necessarily need to
	 * save/restore LR unless we call other functions
	 */
	if (ctx->seen & SEEN_FUNC)
		EMIT(PPC_RAW_MFLR(_R0));

	/*
	 * Back up non-volatile regs -- registers r18-r31
	 */
	for (i = BPF_PPC_NVR_MIN; i <= 31; i++)
		if (bpf_is_seen_register(ctx, i))
			EMIT(PPC_RAW_STW(i, _R1, bpf_jit_stack_offsetof(ctx, i)));

	/* Setup frame pointer to point to the bpf stack area */
	if (bpf_is_seen_register(ctx, bpf_to_ppc(BPF_REG_FP))) {
		EMIT(PPC_RAW_LI(bpf_to_ppc(BPF_REG_FP) - 1, 0));
		EMIT(PPC_RAW_ADDI(bpf_to_ppc(BPF_REG_FP), _R1,
				  STACK_FRAME_MIN_SIZE + ctx->stack_size));
	}

Annotation

Implementation Notes