diff options
Diffstat (limited to 'kernel/bpf/trampoline.c')
| -rw-r--r-- | kernel/bpf/trampoline.c | 80 | 
1 files changed, 67 insertions, 13 deletions
| diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index bf0906e1e2b9..d6395215b849 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -864,7 +864,7 @@ static __always_inline u64 notrace bpf_prog_start_time(void)   * [2..MAX_U64] - execute bpf prog and record execution time.   *     This is start time.   */ -u64 notrace __bpf_prog_enter(struct bpf_prog *prog, struct bpf_tramp_run_ctx *run_ctx) +static u64 notrace __bpf_prog_enter_recur(struct bpf_prog *prog, struct bpf_tramp_run_ctx *run_ctx)  	__acquires(RCU)  {  	rcu_read_lock(); @@ -901,7 +901,8 @@ static void notrace update_prog_stats(struct bpf_prog *prog,  	}  } -void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start, struct bpf_tramp_run_ctx *run_ctx) +static void notrace __bpf_prog_exit_recur(struct bpf_prog *prog, u64 start, +					  struct bpf_tramp_run_ctx *run_ctx)  	__releases(RCU)  {  	bpf_reset_run_ctx(run_ctx->saved_run_ctx); @@ -912,8 +913,8 @@ void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start, struct bpf_tramp_  	rcu_read_unlock();  } -u64 notrace __bpf_prog_enter_lsm_cgroup(struct bpf_prog *prog, -					struct bpf_tramp_run_ctx *run_ctx) +static u64 notrace __bpf_prog_enter_lsm_cgroup(struct bpf_prog *prog, +					       struct bpf_tramp_run_ctx *run_ctx)  	__acquires(RCU)  {  	/* Runtime stats are exported via actual BPF_LSM_CGROUP @@ -927,8 +928,8 @@ u64 notrace __bpf_prog_enter_lsm_cgroup(struct bpf_prog *prog,  	return NO_START_TIME;  } -void notrace __bpf_prog_exit_lsm_cgroup(struct bpf_prog *prog, u64 start, -					struct bpf_tramp_run_ctx *run_ctx) +static void notrace __bpf_prog_exit_lsm_cgroup(struct bpf_prog *prog, u64 start, +					       struct bpf_tramp_run_ctx *run_ctx)  	__releases(RCU)  {  	bpf_reset_run_ctx(run_ctx->saved_run_ctx); @@ -937,7 +938,8 @@ void notrace __bpf_prog_exit_lsm_cgroup(struct bpf_prog *prog, u64 start,  	rcu_read_unlock();  } -u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog, struct bpf_tramp_run_ctx *run_ctx) +u64 notrace __bpf_prog_enter_sleepable_recur(struct bpf_prog *prog, +					     struct bpf_tramp_run_ctx *run_ctx)  {  	rcu_read_lock_trace();  	migrate_disable(); @@ -953,8 +955,8 @@ u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog, struct bpf_tramp_r  	return bpf_prog_start_time();  } -void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start, -				       struct bpf_tramp_run_ctx *run_ctx) +void notrace __bpf_prog_exit_sleepable_recur(struct bpf_prog *prog, u64 start, +					     struct bpf_tramp_run_ctx *run_ctx)  {  	bpf_reset_run_ctx(run_ctx->saved_run_ctx); @@ -964,8 +966,30 @@ void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start,  	rcu_read_unlock_trace();  } -u64 notrace __bpf_prog_enter_struct_ops(struct bpf_prog *prog, -					struct bpf_tramp_run_ctx *run_ctx) +static u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog, +					      struct bpf_tramp_run_ctx *run_ctx) +{ +	rcu_read_lock_trace(); +	migrate_disable(); +	might_fault(); + +	run_ctx->saved_run_ctx = bpf_set_run_ctx(&run_ctx->run_ctx); + +	return bpf_prog_start_time(); +} + +static void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start, +					      struct bpf_tramp_run_ctx *run_ctx) +{ +	bpf_reset_run_ctx(run_ctx->saved_run_ctx); + +	update_prog_stats(prog, start); +	migrate_enable(); +	rcu_read_unlock_trace(); +} + +static u64 notrace __bpf_prog_enter(struct bpf_prog *prog, +				    struct bpf_tramp_run_ctx *run_ctx)  	__acquires(RCU)  {  	rcu_read_lock(); @@ -976,8 +1000,8 @@ u64 notrace __bpf_prog_enter_struct_ops(struct bpf_prog *prog,  	return bpf_prog_start_time();  } -void notrace __bpf_prog_exit_struct_ops(struct bpf_prog *prog, u64 start, -					struct bpf_tramp_run_ctx *run_ctx) +static void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start, +				    struct bpf_tramp_run_ctx *run_ctx)  	__releases(RCU)  {  	bpf_reset_run_ctx(run_ctx->saved_run_ctx); @@ -997,6 +1021,36 @@ void notrace __bpf_tramp_exit(struct bpf_tramp_image *tr)  	percpu_ref_put(&tr->pcref);  } +bpf_trampoline_enter_t bpf_trampoline_enter(const struct bpf_prog *prog) +{ +	bool sleepable = prog->aux->sleepable; + +	if (bpf_prog_check_recur(prog)) +		return sleepable ? __bpf_prog_enter_sleepable_recur : +			__bpf_prog_enter_recur; + +	if (resolve_prog_type(prog) == BPF_PROG_TYPE_LSM && +	    prog->expected_attach_type == BPF_LSM_CGROUP) +		return __bpf_prog_enter_lsm_cgroup; + +	return sleepable ? __bpf_prog_enter_sleepable : __bpf_prog_enter; +} + +bpf_trampoline_exit_t bpf_trampoline_exit(const struct bpf_prog *prog) +{ +	bool sleepable = prog->aux->sleepable; + +	if (bpf_prog_check_recur(prog)) +		return sleepable ? __bpf_prog_exit_sleepable_recur : +			__bpf_prog_exit_recur; + +	if (resolve_prog_type(prog) == BPF_PROG_TYPE_LSM && +	    prog->expected_attach_type == BPF_LSM_CGROUP) +		return __bpf_prog_exit_lsm_cgroup; + +	return sleepable ? __bpf_prog_exit_sleepable : __bpf_prog_exit; +} +  int __weak  arch_prepare_bpf_trampoline(struct bpf_tramp_image *tr, void *image, void *image_end,  			    const struct btf_func_model *m, u32 flags, |