Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Thomas Gleixner:

- Prevent a potential inconistency in the perf user space access which
might lead to evading sanity checks.

- Prevent perf recording function trace entries twice

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/ftrace: Fix double traces of perf on ftrace:function
perf/core: Fix potential double-fetch bug

+22 -13
+1 -1
include/linux/perf_event.h
··· 1201 1201 extern void perf_tp_event(u16 event_type, u64 count, void *record, 1202 1202 int entry_size, struct pt_regs *regs, 1203 1203 struct hlist_head *head, int rctx, 1204 - struct task_struct *task); 1204 + struct task_struct *task, struct perf_event *event); 1205 1205 extern void perf_bp_event(struct perf_event *event, void *data); 1206 1206 1207 1207 #ifndef perf_misc_flags
+2 -2
include/linux/trace_events.h
··· 508 508 static inline void 509 509 perf_trace_buf_submit(void *raw_data, int size, int rctx, u16 type, 510 510 u64 count, struct pt_regs *regs, void *head, 511 - struct task_struct *task) 511 + struct task_struct *task, struct perf_event *event) 512 512 { 513 - perf_tp_event(type, count, raw_data, size, regs, head, rctx, task); 513 + perf_tp_event(type, count, raw_data, size, regs, head, rctx, task, event); 514 514 } 515 515 #endif 516 516
+11 -4
kernel/events/core.c
··· 7906 7906 } 7907 7907 } 7908 7908 perf_tp_event(call->event.type, count, raw_data, size, regs, head, 7909 - rctx, task); 7909 + rctx, task, NULL); 7910 7910 } 7911 7911 EXPORT_SYMBOL_GPL(perf_trace_run_bpf_submit); 7912 7912 7913 7913 void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size, 7914 7914 struct pt_regs *regs, struct hlist_head *head, int rctx, 7915 - struct task_struct *task) 7915 + struct task_struct *task, struct perf_event *event) 7916 7916 { 7917 7917 struct perf_sample_data data; 7918 - struct perf_event *event; 7919 7918 7920 7919 struct perf_raw_record raw = { 7921 7920 .frag = { ··· 7928 7929 7929 7930 perf_trace_buf_update(record, event_type); 7930 7931 7931 - hlist_for_each_entry_rcu(event, head, hlist_entry) { 7932 + /* Use the given event instead of the hlist */ 7933 + if (event) { 7932 7934 if (perf_tp_event_match(event, &data, regs)) 7933 7935 perf_swevent_event(event, count, &data, regs); 7936 + } else { 7937 + hlist_for_each_entry_rcu(event, head, hlist_entry) { 7938 + if (perf_tp_event_match(event, &data, regs)) 7939 + perf_swevent_event(event, count, &data, regs); 7940 + } 7934 7941 } 7935 7942 7936 7943 /* ··· 9615 9610 ret = copy_from_user(attr, uattr, size); 9616 9611 if (ret) 9617 9612 return -EFAULT; 9613 + 9614 + attr->size = size; 9618 9615 9619 9616 if (attr->__reserved_1) 9620 9617 return -EINVAL;
+3 -1
kernel/trace/trace_event_perf.c
··· 306 306 perf_ftrace_function_call(unsigned long ip, unsigned long parent_ip, 307 307 struct ftrace_ops *ops, struct pt_regs *pt_regs) 308 308 { 309 + struct perf_event *event; 309 310 struct ftrace_entry *entry; 310 311 struct hlist_head *head; 311 312 struct pt_regs regs; ··· 330 329 331 330 entry->ip = ip; 332 331 entry->parent_ip = parent_ip; 332 + event = container_of(ops, struct perf_event, ftrace_ops); 333 333 perf_trace_buf_submit(entry, ENTRY_SIZE, rctx, TRACE_FN, 334 - 1, &regs, head, NULL); 334 + 1, &regs, head, NULL, event); 335 335 336 336 #undef ENTRY_SIZE 337 337 }
+2 -2
kernel/trace/trace_kprobe.c
··· 1200 1200 memset(&entry[1], 0, dsize); 1201 1201 store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize); 1202 1202 perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs, 1203 - head, NULL); 1203 + head, NULL, NULL); 1204 1204 } 1205 1205 NOKPROBE_SYMBOL(kprobe_perf_func); 1206 1206 ··· 1236 1236 entry->ret_ip = (unsigned long)ri->ret_addr; 1237 1237 store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize); 1238 1238 perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs, 1239 - head, NULL); 1239 + head, NULL, NULL); 1240 1240 } 1241 1241 NOKPROBE_SYMBOL(kretprobe_perf_func); 1242 1242 #endif /* CONFIG_PERF_EVENTS */
+2 -2
kernel/trace/trace_syscalls.c
··· 596 596 (unsigned long *)&rec->args); 597 597 perf_trace_buf_submit(rec, size, rctx, 598 598 sys_data->enter_event->event.type, 1, regs, 599 - head, NULL); 599 + head, NULL, NULL); 600 600 } 601 601 602 602 static int perf_sysenter_enable(struct trace_event_call *call) ··· 667 667 rec->nr = syscall_nr; 668 668 rec->ret = syscall_get_return_value(current, regs); 669 669 perf_trace_buf_submit(rec, size, rctx, sys_data->exit_event->event.type, 670 - 1, regs, head, NULL); 670 + 1, regs, head, NULL, NULL); 671 671 } 672 672 673 673 static int perf_sysexit_enable(struct trace_event_call *call)
+1 -1
kernel/trace/trace_uprobe.c
··· 1156 1156 } 1157 1157 1158 1158 perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs, 1159 - head, NULL); 1159 + head, NULL, NULL); 1160 1160 out: 1161 1161 preempt_enable(); 1162 1162 }