diff options
Diffstat (limited to 'kernel/trace/bpf_trace.c')
| -rw-r--r-- | kernel/trace/bpf_trace.c | 70 | 
1 files changed, 42 insertions, 28 deletions
| diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index fc2838ac8b78..01e6b3a38871 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -661,7 +661,41 @@ static const struct bpf_func_proto bpf_get_stackid_proto_tp = {  	.arg3_type	= ARG_ANYTHING,  }; -BPF_CALL_3(bpf_perf_prog_read_value_tp, struct bpf_perf_event_data_kern *, ctx, +static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id) +{ +	switch (func_id) { +	case BPF_FUNC_perf_event_output: +		return &bpf_perf_event_output_proto_tp; +	case BPF_FUNC_get_stackid: +		return &bpf_get_stackid_proto_tp; +	default: +		return tracing_func_proto(func_id); +	} +} + +static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type type, +				    struct bpf_insn_access_aux *info) +{ +	if (off < sizeof(void *) || off >= PERF_MAX_TRACE_SIZE) +		return false; +	if (type != BPF_READ) +		return false; +	if (off % size != 0) +		return false; + +	BUILD_BUG_ON(PERF_MAX_TRACE_SIZE % sizeof(__u64)); +	return true; +} + +const struct bpf_verifier_ops tracepoint_verifier_ops = { +	.get_func_proto  = tp_prog_func_proto, +	.is_valid_access = tp_prog_is_valid_access, +}; + +const struct bpf_prog_ops tracepoint_prog_ops = { +}; + +BPF_CALL_3(bpf_perf_prog_read_value, struct bpf_perf_event_data_kern *, ctx,  	   struct bpf_perf_event_value *, buf, u32, size)  {  	int err = -EINVAL; @@ -678,8 +712,8 @@ clear:  	return err;  } -static const struct bpf_func_proto bpf_perf_prog_read_value_proto_tp = { -         .func           = bpf_perf_prog_read_value_tp, +static const struct bpf_func_proto bpf_perf_prog_read_value_proto = { +         .func           = bpf_perf_prog_read_value,           .gpl_only       = true,           .ret_type       = RET_INTEGER,           .arg1_type      = ARG_PTR_TO_CTX, @@ -687,7 +721,7 @@ static const struct bpf_func_proto bpf_perf_prog_read_value_proto_tp = {           .arg3_type      = ARG_CONST_SIZE,  }; -static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id) +static const struct bpf_func_proto *pe_prog_func_proto(enum bpf_func_id func_id)  {  	switch (func_id) {  	case BPF_FUNC_perf_event_output: @@ -695,34 +729,12 @@ static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id)  	case BPF_FUNC_get_stackid:  		return &bpf_get_stackid_proto_tp;  	case BPF_FUNC_perf_prog_read_value: -		return &bpf_perf_prog_read_value_proto_tp; +		return &bpf_perf_prog_read_value_proto;  	default:  		return tracing_func_proto(func_id);  	}  } -static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type type, -				    struct bpf_insn_access_aux *info) -{ -	if (off < sizeof(void *) || off >= PERF_MAX_TRACE_SIZE) -		return false; -	if (type != BPF_READ) -		return false; -	if (off % size != 0) -		return false; - -	BUILD_BUG_ON(PERF_MAX_TRACE_SIZE % sizeof(__u64)); -	return true; -} - -const struct bpf_verifier_ops tracepoint_verifier_ops = { -	.get_func_proto  = tp_prog_func_proto, -	.is_valid_access = tp_prog_is_valid_access, -}; - -const struct bpf_prog_ops tracepoint_prog_ops = { -}; -  static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type,  				    struct bpf_insn_access_aux *info)  { @@ -779,7 +791,7 @@ static u32 pe_prog_convert_ctx_access(enum bpf_access_type type,  }  const struct bpf_verifier_ops perf_event_verifier_ops = { -	.get_func_proto		= tp_prog_func_proto, +	.get_func_proto		= pe_prog_func_proto,  	.is_valid_access	= pe_prog_is_valid_access,  	.convert_ctx_access	= pe_prog_convert_ctx_access,  }; @@ -872,6 +884,8 @@ int perf_event_query_prog_array(struct perf_event *event, void __user *info)  		return -EINVAL;  	if (copy_from_user(&query, uquery, sizeof(query)))  		return -EFAULT; +	if (query.ids_len > BPF_TRACE_MAX_PROGS) +		return -E2BIG;  	mutex_lock(&bpf_event_mutex);  	ret = bpf_prog_array_copy_info(event->tp_event->prog_array, | 

