|
22 | 22 | #include <linux/sort.h> |
23 | 23 | #include <linux/slab.h> |
24 | 24 | #include <linux/delay.h> |
| 25 | +#include <linux/btf.h> |
25 | 26 |
|
26 | 27 | #include <trace/events/sched.h> |
27 | 28 | #include <trace/syscall.h> |
@@ -2200,6 +2201,61 @@ event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) |
2200 | 2201 | } |
2201 | 2202 | #endif |
2202 | 2203 |
|
| 2204 | +#ifdef CONFIG_BPF_EVENTS |
| 2205 | +static ssize_t |
| 2206 | +event_btf_ids_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) |
| 2207 | +{ |
| 2208 | + struct trace_event_file *file; |
| 2209 | + struct trace_event_call *call; |
| 2210 | + const struct btf_type *t; |
| 2211 | + struct module *mod = NULL; |
| 2212 | + u32 raw_id = 0, tp_id = 0, obj_id = 0; |
| 2213 | + const u32 *ids; |
| 2214 | + struct btf *btf; |
| 2215 | + char buf[128]; |
| 2216 | + int len; |
| 2217 | + |
| 2218 | + /* Module unload could free call->class and ids[] mid-read. */ |
| 2219 | + scoped_guard(mutex, &event_mutex) { |
| 2220 | + file = event_file_file(filp); |
| 2221 | + if (!file) |
| 2222 | + return -ENODEV; |
| 2223 | + |
| 2224 | + call = file->event_call; |
| 2225 | + ids = call->class->btf_ids; |
| 2226 | + if (!ids) |
| 2227 | + return -ENOENT; |
| 2228 | + if (!(call->flags & TRACE_EVENT_FL_DYNAMIC)) |
| 2229 | + mod = (struct module *)call->module; |
| 2230 | + |
| 2231 | + btf = btf_get_module_btf(mod); |
| 2232 | + if (IS_ERR_OR_NULL(btf)) |
| 2233 | + return -ENOENT; |
| 2234 | + |
| 2235 | + /* Module-local ids in ids[] need base+local relocation. */ |
| 2236 | + tp_id = btf_relocate_id(btf, ids[1]); |
| 2237 | + |
| 2238 | + /* |
| 2239 | + * Without FL_TRACEPOINT the dispatcher is shared (e.g. all |
| 2240 | + * per-syscall events fan out from __bpf_trace_sys_enter), so |
| 2241 | + * raw_btf_id has no per-event attach point — report 0. |
| 2242 | + */ |
| 2243 | + if (call->flags & TRACE_EVENT_FL_TRACEPOINT) { |
| 2244 | + t = btf_type_by_id(btf, btf_relocate_id(btf, ids[0])); |
| 2245 | + raw_id = t ? t->type : 0; |
| 2246 | + } |
| 2247 | + obj_id = btf_obj_id(btf); |
| 2248 | + btf_put(btf); |
| 2249 | + } |
| 2250 | + |
| 2251 | + len = scnprintf(buf, sizeof(buf), |
| 2252 | + "btf_obj_id: %u\nraw_btf_id: %u\ntp_btf_id: %u\n", |
| 2253 | + obj_id, raw_id, tp_id); |
| 2254 | + |
| 2255 | + return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); |
| 2256 | +} |
| 2257 | +#endif |
| 2258 | + |
2203 | 2259 | static ssize_t |
2204 | 2260 | event_filter_read(struct file *filp, char __user *ubuf, size_t cnt, |
2205 | 2261 | loff_t *ppos) |
@@ -2700,6 +2756,13 @@ static const struct file_operations ftrace_event_id_fops = { |
2700 | 2756 | }; |
2701 | 2757 | #endif |
2702 | 2758 |
|
| 2759 | +#ifdef CONFIG_BPF_EVENTS |
| 2760 | +static const struct file_operations ftrace_event_btf_ids_fops = { |
| 2761 | + .read = event_btf_ids_read, |
| 2762 | + .llseek = default_llseek, |
| 2763 | +}; |
| 2764 | +#endif |
| 2765 | + |
2703 | 2766 | static const struct file_operations ftrace_event_filter_fops = { |
2704 | 2767 | .open = tracing_open_file_tr, |
2705 | 2768 | .read = event_filter_read, |
@@ -3093,6 +3156,14 @@ static int event_callback(const char *name, umode_t *mode, void **data, |
3093 | 3156 | } |
3094 | 3157 | #endif |
3095 | 3158 |
|
| 3159 | +#ifdef CONFIG_BPF_EVENTS |
| 3160 | + if (call->class->btf_ids && strcmp(name, "btf_ids") == 0) { |
| 3161 | + *mode = TRACE_MODE_READ; |
| 3162 | + *fops = &ftrace_event_btf_ids_fops; |
| 3163 | + return 1; |
| 3164 | + } |
| 3165 | +#endif |
| 3166 | + |
3096 | 3167 | #ifdef CONFIG_HIST_TRIGGERS |
3097 | 3168 | if (strcmp(name, "hist") == 0) { |
3098 | 3169 | *mode = TRACE_MODE_READ; |
@@ -3147,7 +3218,14 @@ event_create_dir(struct eventfs_inode *parent, struct trace_event_file *file) |
3147 | 3218 | .callback = event_callback, |
3148 | 3219 | }, |
3149 | 3220 | #endif |
3150 | | -#define NR_RO_EVENT_ENTRIES (1 + IS_ENABLED(CONFIG_PERF_EVENTS)) |
| 3221 | +#ifdef CONFIG_BPF_EVENTS |
| 3222 | + { |
| 3223 | + .name = "btf_ids", |
| 3224 | + .callback = event_callback, |
| 3225 | + }, |
| 3226 | +#endif |
| 3227 | +#define NR_RO_EVENT_ENTRIES (1 + IS_ENABLED(CONFIG_PERF_EVENTS) + \ |
| 3228 | + IS_ENABLED(CONFIG_BPF_EVENTS)) |
3151 | 3229 | /* Readonly files must be above this line and counted by NR_RO_EVENT_ENTRIES. */ |
3152 | 3230 | { |
3153 | 3231 | .name = "enable", |
|
0 commit comments