Skip to content

Commit ebc27aa

Browse files
committed
Merge tag 'trace-v6.5-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace
Pull tracing fixes from Steven Rostedt: - Fix some missing-prototype warnings - Fix user events struct args (did not include size of struct) When creating a user event, the "struct" keyword is to denote that the size of the field will be passed in. But the parsing failed to handle this case. - Add selftest to struct sizes for user events - Fix sample code for direct trampolines. The sample code for direct trampolines attached to handle_mm_fault(). But the prototype changed and the direct trampoline sample code was not updated. Direct trampolines needs to have the arguments correct otherwise it can fail or crash the system. - Remove unused ftrace_regs_caller_ret() prototype. - Quiet false positive of FORTIFY_SOURCE Due to backward compatibility, the structure used to save stack traces in the kernel had a fixed size of 8. This structure is exported to user space via the tracing format file. A change was made to allow more than 8 functions to be recorded, and user space now uses the size field to know how many functions are actually in the stack. But the structure still has size of 8 (even though it points into the ring buffer that has the required amount allocated to hold a full stack. This was fine until the fortifier noticed that the memcpy(&entry->caller, stack, size) was greater than the 8 functions and would complain at runtime about it. Hide this by using a pointer to the stack location on the ring buffer instead of using the address of the entry structure caller field. - Fix a deadloop in reading trace_pipe that was caused by a mismatch between ring_buffer_empty() returning false which then asked to read the data, but the read code uses rb_num_of_entries() that returned zero, and causing a infinite "retry". - Fix a warning caused by not using all pages allocated to store ftrace functions, where this can happen if the linker inserts a bunch of "NULL" entries, causing the accounting of how many pages needed to be off. - Fix histogram synthetic event crashing when the start event is removed and the end event is still using a variable from it - Fix memory leak in freeing iter->temp in tracing_release_pipe() * tag 'trace-v6.5-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: tracing: Fix memory leak of iter->temp when reading trace_pipe tracing/histograms: Add histograms to hist_vars if they have referenced variables tracing: Stop FORTIFY_SOURCE complaining about stack trace caller ftrace: Fix possible warning on checking all pages used in ftrace_process_locs() ring-buffer: Fix deadloop issue on reading trace_pipe tracing: arm64: Avoid missing-prototype warnings selftests/user_events: Test struct size match cases tracing/user_events: Fix struct arg size match check x86/ftrace: Remove unsued extern declaration ftrace_regs_caller_ret() arm64: ftrace: Add direct call trampoline samples support samples: ftrace: Save required argument registers in sample trampolines
2 parents 1599932 + d5a8218 commit ebc27aa

File tree

20 files changed

+268
-40
lines changed

20 files changed

+268
-40
lines changed

arch/arm64/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ config ARM64
197197
!CC_OPTIMIZE_FOR_SIZE)
198198
select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY \
199199
if DYNAMIC_FTRACE_WITH_ARGS
200+
select HAVE_SAMPLE_FTRACE_DIRECT
201+
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
200202
select HAVE_EFFICIENT_UNALIGNED_ACCESS
201203
select HAVE_FAST_GUP
202204
select HAVE_FTRACE_MCOUNT_RECORD

arch/arm64/include/asm/ftrace.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,10 @@ static inline unsigned long fgraph_ret_regs_frame_pointer(struct fgraph_ret_regs
211211
{
212212
return ret_regs->fp;
213213
}
214+
215+
void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent,
216+
unsigned long frame_pointer);
217+
214218
#endif /* ifdef CONFIG_FUNCTION_GRAPH_TRACER */
215219
#endif
216220

arch/arm64/include/asm/syscall.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,7 @@ static inline int syscall_get_arch(struct task_struct *task)
8585
return AUDIT_ARCH_AARCH64;
8686
}
8787

88+
int syscall_trace_enter(struct pt_regs *regs);
89+
void syscall_trace_exit(struct pt_regs *regs);
90+
8891
#endif /* __ASM_SYSCALL_H */

arch/arm64/kernel/syscall.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,6 @@ static inline bool has_syscall_work(unsigned long flags)
7575
return unlikely(flags & _TIF_SYSCALL_WORK);
7676
}
7777

78-
int syscall_trace_enter(struct pt_regs *regs);
79-
void syscall_trace_exit(struct pt_regs *regs);
80-
8178
static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
8279
const syscall_fn_t syscall_table[])
8380
{

arch/x86/kernel/ftrace.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,6 @@ static inline void tramp_free(void *tramp) { }
282282

283283
/* Defined as markers to the end of the ftrace default trampolines */
284284
extern void ftrace_regs_caller_end(void);
285-
extern void ftrace_regs_caller_ret(void);
286285
extern void ftrace_caller_end(void);
287286
extern void ftrace_caller_op_ptr(void);
288287
extern void ftrace_regs_caller_op_ptr(void);

include/linux/ftrace.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ struct ftrace_ops;
4141
struct ftrace_regs;
4242
struct dyn_ftrace;
4343

44+
char *arch_ftrace_match_adjust(char *str, const char *search);
45+
46+
#ifdef CONFIG_HAVE_FUNCTION_GRAPH_RETVAL
47+
struct fgraph_ret_regs;
48+
unsigned long ftrace_return_to_handler(struct fgraph_ret_regs *ret_regs);
49+
#else
50+
unsigned long ftrace_return_to_handler(unsigned long frame_pointer);
51+
#endif
52+
4453
#ifdef CONFIG_FUNCTION_TRACER
4554
/*
4655
* If the arch's mcount caller does not support all of ftrace's

kernel/trace/fgraph.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <trace/events/sched.h>
1616

1717
#include "ftrace_internal.h"
18+
#include "trace.h"
1819

1920
#ifdef CONFIG_DYNAMIC_FTRACE
2021
#define ASSIGN_OPS_HASH(opsname, val) \

kernel/trace/ftrace.c

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3305,6 +3305,22 @@ static int ftrace_allocate_records(struct ftrace_page *pg, int count)
33053305
return cnt;
33063306
}
33073307

3308+
static void ftrace_free_pages(struct ftrace_page *pages)
3309+
{
3310+
struct ftrace_page *pg = pages;
3311+
3312+
while (pg) {
3313+
if (pg->records) {
3314+
free_pages((unsigned long)pg->records, pg->order);
3315+
ftrace_number_of_pages -= 1 << pg->order;
3316+
}
3317+
pages = pg->next;
3318+
kfree(pg);
3319+
pg = pages;
3320+
ftrace_number_of_groups--;
3321+
}
3322+
}
3323+
33083324
static struct ftrace_page *
33093325
ftrace_allocate_pages(unsigned long num_to_init)
33103326
{
@@ -3343,17 +3359,7 @@ ftrace_allocate_pages(unsigned long num_to_init)
33433359
return start_pg;
33443360

33453361
free_pages:
3346-
pg = start_pg;
3347-
while (pg) {
3348-
if (pg->records) {
3349-
free_pages((unsigned long)pg->records, pg->order);
3350-
ftrace_number_of_pages -= 1 << pg->order;
3351-
}
3352-
start_pg = pg->next;
3353-
kfree(pg);
3354-
pg = start_pg;
3355-
ftrace_number_of_groups--;
3356-
}
3362+
ftrace_free_pages(start_pg);
33573363
pr_info("ftrace: FAILED to allocate memory for functions\n");
33583364
return NULL;
33593365
}
@@ -6471,9 +6477,11 @@ static int ftrace_process_locs(struct module *mod,
64716477
unsigned long *start,
64726478
unsigned long *end)
64736479
{
6480+
struct ftrace_page *pg_unuse = NULL;
64746481
struct ftrace_page *start_pg;
64756482
struct ftrace_page *pg;
64766483
struct dyn_ftrace *rec;
6484+
unsigned long skipped = 0;
64776485
unsigned long count;
64786486
unsigned long *p;
64796487
unsigned long addr;
@@ -6536,8 +6544,10 @@ static int ftrace_process_locs(struct module *mod,
65366544
* object files to satisfy alignments.
65376545
* Skip any NULL pointers.
65386546
*/
6539-
if (!addr)
6547+
if (!addr) {
6548+
skipped++;
65406549
continue;
6550+
}
65416551

65426552
end_offset = (pg->index+1) * sizeof(pg->records[0]);
65436553
if (end_offset > PAGE_SIZE << pg->order) {
@@ -6551,8 +6561,10 @@ static int ftrace_process_locs(struct module *mod,
65516561
rec->ip = addr;
65526562
}
65536563

6554-
/* We should have used all pages */
6555-
WARN_ON(pg->next);
6564+
if (pg->next) {
6565+
pg_unuse = pg->next;
6566+
pg->next = NULL;
6567+
}
65566568

65576569
/* Assign the last page to ftrace_pages */
65586570
ftrace_pages = pg;
@@ -6574,6 +6586,11 @@ static int ftrace_process_locs(struct module *mod,
65746586
out:
65756587
mutex_unlock(&ftrace_lock);
65766588

6589+
/* We should have used all pages unless we skipped some */
6590+
if (pg_unuse) {
6591+
WARN_ON(!skipped);
6592+
ftrace_free_pages(pg_unuse);
6593+
}
65776594
return ret;
65786595
}
65796596

kernel/trace/ftrace_internal.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
#ifndef _LINUX_KERNEL_FTRACE_INTERNAL_H
33
#define _LINUX_KERNEL_FTRACE_INTERNAL_H
44

5+
int __register_ftrace_function(struct ftrace_ops *ops);
6+
int __unregister_ftrace_function(struct ftrace_ops *ops);
7+
58
#ifdef CONFIG_FUNCTION_TRACER
69

710
extern struct mutex ftrace_lock;
@@ -15,8 +18,6 @@ int ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip, void *regs);
1518

1619
#else /* !CONFIG_DYNAMIC_FTRACE */
1720

18-
int __register_ftrace_function(struct ftrace_ops *ops);
19-
int __unregister_ftrace_function(struct ftrace_ops *ops);
2021
/* Keep as macros so we do not need to define the commands */
2122
# define ftrace_startup(ops, command) \
2223
({ \

kernel/trace/ring_buffer.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5242,28 +5242,34 @@ unsigned long ring_buffer_size(struct trace_buffer *buffer, int cpu)
52425242
}
52435243
EXPORT_SYMBOL_GPL(ring_buffer_size);
52445244

5245+
static void rb_clear_buffer_page(struct buffer_page *page)
5246+
{
5247+
local_set(&page->write, 0);
5248+
local_set(&page->entries, 0);
5249+
rb_init_page(page->page);
5250+
page->read = 0;
5251+
}
5252+
52455253
static void
52465254
rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
52475255
{
5256+
struct buffer_page *page;
5257+
52485258
rb_head_page_deactivate(cpu_buffer);
52495259

52505260
cpu_buffer->head_page
52515261
= list_entry(cpu_buffer->pages, struct buffer_page, list);
5252-
local_set(&cpu_buffer->head_page->write, 0);
5253-
local_set(&cpu_buffer->head_page->entries, 0);
5254-
local_set(&cpu_buffer->head_page->page->commit, 0);
5255-
5256-
cpu_buffer->head_page->read = 0;
5262+
rb_clear_buffer_page(cpu_buffer->head_page);
5263+
list_for_each_entry(page, cpu_buffer->pages, list) {
5264+
rb_clear_buffer_page(page);
5265+
}
52575266

52585267
cpu_buffer->tail_page = cpu_buffer->head_page;
52595268
cpu_buffer->commit_page = cpu_buffer->head_page;
52605269

52615270
INIT_LIST_HEAD(&cpu_buffer->reader_page->list);
52625271
INIT_LIST_HEAD(&cpu_buffer->new_pages);
5263-
local_set(&cpu_buffer->reader_page->write, 0);
5264-
local_set(&cpu_buffer->reader_page->entries, 0);
5265-
local_set(&cpu_buffer->reader_page->page->commit, 0);
5266-
cpu_buffer->reader_page->read = 0;
5272+
rb_clear_buffer_page(cpu_buffer->reader_page);
52675273

52685274
local_set(&cpu_buffer->entries_bytes, 0);
52695275
local_set(&cpu_buffer->overrun, 0);

0 commit comments

Comments
 (0)