From nobody Sun Feb 8 04:35:02 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 75781EB64DA for ; Wed, 12 Jul 2023 22:18:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232234AbjGLWSI (ORCPT ); Wed, 12 Jul 2023 18:18:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36060 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232802AbjGLWSC (ORCPT ); Wed, 12 Jul 2023 18:18:02 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9FAF41BEC for ; Wed, 12 Jul 2023 15:17:45 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 26DE86194C for ; Wed, 12 Jul 2023 22:17:45 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 76549C433C7; Wed, 12 Jul 2023 22:17:43 +0000 (UTC) Date: Wed, 12 Jul 2023 18:17:40 -0400 From: Steven Rostedt To: Linus Torvalds Cc: LKML , Masami Hiramatsu , Mark Rutland , Arnd Bergmann , Beau Belgrave , Florent Revest , YueHaibing , Zheng Yejian , Catalin Marinas Subject: [GIT PULL] tracing: Fixes for v6.5-rc1 Message-ID: <20230712181740.7c5fb0c8@gandalf.local.home> X-Mailer: Claws Mail 3.19.1 (GTK+ 2.24.33; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Linus, Tracing fixes and clean ups: - 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. Please pull the latest trace-v6.5-rc1 tree, which can be found at: git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git trace-v6.5-rc1 Tag SHA1: eb30dc43a7f5fb905bcaf40e7b5c581b78f77443 Head SHA1: bec3c25c247c4f88a33d79675a09e1644c9a3114 Arnd Bergmann (1): tracing: arm64: Avoid missing-prototype warnings Beau Belgrave (2): tracing/user_events: Fix struct arg size match check selftests/user_events: Test struct size match cases Florent Revest (2): samples: ftrace: Save required argument registers in sample trampolin= es arm64: ftrace: Add direct call trampoline samples support Steven Rostedt (Google) (1): tracing: Stop FORTIFY_SOURCE complaining about stack trace caller YueHaibing (1): x86/ftrace: Remove unsued extern declaration ftrace_regs_caller_ret() Zheng Yejian (2): ring-buffer: Fix deadloop issue on reading trace_pipe ftrace: Fix possible warning on checking all pages used in ftrace_pro= cess_locs() ---- arch/arm64/Kconfig | 2 ++ arch/arm64/include/asm/ftrace.h | 4 +++ arch/arm64/include/asm/syscall.h | 3 ++ arch/arm64/kernel/syscall.c | 3 -- arch/x86/kernel/ftrace.c | 1 - include/linux/ftrace.h | 9 ++++++ kernel/trace/fgraph.c | 1 + kernel/trace/ftrace.c | 45 ++++++++++++++++++----= ---- kernel/trace/ftrace_internal.h | 5 +-- kernel/trace/ring_buffer.c | 24 ++++++++------ kernel/trace/trace.c | 21 ++++++++++-- kernel/trace/trace_events_user.c | 3 ++ kernel/trace/trace_kprobe_selftest.c | 3 ++ samples/ftrace/ftrace-direct-modify.c | 34 +++++++++++++++++++ samples/ftrace/ftrace-direct-multi-modify.c | 40 +++++++++++++++++++++++ samples/ftrace/ftrace-direct-multi.c | 25 ++++++++++++++ samples/ftrace/ftrace-direct-too.c | 40 +++++++++++++++++++---- samples/ftrace/ftrace-direct.c | 24 ++++++++++++++ tools/testing/selftests/user_events/dyn_test.c | 12 +++++++ 19 files changed, 262 insertions(+), 37 deletions(-) --------------------------- diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 7856c3a3e35a..a2511b30d0f6 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -197,6 +197,8 @@ config ARM64 !CC_OPTIMIZE_FOR_SIZE) select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY \ if DYNAMIC_FTRACE_WITH_ARGS + select HAVE_SAMPLE_FTRACE_DIRECT + select HAVE_SAMPLE_FTRACE_DIRECT_MULTI select HAVE_EFFICIENT_UNALIGNED_ACCESS select HAVE_FAST_GUP select HAVE_FTRACE_MCOUNT_RECORD diff --git a/arch/arm64/include/asm/ftrace.h b/arch/arm64/include/asm/ftrac= e.h index 21ac1c5c71d3..ab158196480c 100644 --- a/arch/arm64/include/asm/ftrace.h +++ b/arch/arm64/include/asm/ftrace.h @@ -211,6 +211,10 @@ static inline unsigned long fgraph_ret_regs_frame_poin= ter(struct fgraph_ret_regs { return ret_regs->fp; } + +void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent, + unsigned long frame_pointer); + #endif /* ifdef CONFIG_FUNCTION_GRAPH_TRACER */ #endif =20 diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/sysc= all.h index 4cfe9b49709b..ab8e14b96f68 100644 --- a/arch/arm64/include/asm/syscall.h +++ b/arch/arm64/include/asm/syscall.h @@ -85,4 +85,7 @@ static inline int syscall_get_arch(struct task_struct *ta= sk) return AUDIT_ARCH_AARCH64; } =20 +int syscall_trace_enter(struct pt_regs *regs); +void syscall_trace_exit(struct pt_regs *regs); + #endif /* __ASM_SYSCALL_H */ diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index 5a668d7f3c1f..b1ae2f2eaf77 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -75,9 +75,6 @@ static inline bool has_syscall_work(unsigned long flags) return unlikely(flags & _TIF_SYSCALL_WORK); } =20 -int syscall_trace_enter(struct pt_regs *regs); -void syscall_trace_exit(struct pt_regs *regs); - static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, const syscall_fn_t syscall_table[]) { diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 01e8f34daf22..12df54ff0e81 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -282,7 +282,6 @@ static inline void tramp_free(void *tramp) { } =20 /* Defined as markers to the end of the ftrace default trampolines */ extern void ftrace_regs_caller_end(void); -extern void ftrace_regs_caller_ret(void); extern void ftrace_caller_end(void); extern void ftrace_caller_op_ptr(void); extern void ftrace_regs_caller_op_ptr(void); diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 8e59bd954153..ce156c7704ee 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -41,6 +41,15 @@ struct ftrace_ops; struct ftrace_regs; struct dyn_ftrace; =20 +char *arch_ftrace_match_adjust(char *str, const char *search); + +#ifdef CONFIG_HAVE_FUNCTION_GRAPH_RETVAL +struct fgraph_ret_regs; +unsigned long ftrace_return_to_handler(struct fgraph_ret_regs *ret_regs); +#else +unsigned long ftrace_return_to_handler(unsigned long frame_pointer); +#endif + #ifdef CONFIG_FUNCTION_TRACER /* * If the arch's mcount caller does not support all of ftrace's diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c index cd2c35b1dd8f..c83c005e654e 100644 --- a/kernel/trace/fgraph.c +++ b/kernel/trace/fgraph.c @@ -15,6 +15,7 @@ #include =20 #include "ftrace_internal.h" +#include "trace.h" =20 #ifdef CONFIG_DYNAMIC_FTRACE #define ASSIGN_OPS_HASH(opsname, val) \ diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 3740aca79fe7..05c0024815bf 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -3305,6 +3305,22 @@ static int ftrace_allocate_records(struct ftrace_pag= e *pg, int count) return cnt; } =20 +static void ftrace_free_pages(struct ftrace_page *pages) +{ + struct ftrace_page *pg =3D pages; + + while (pg) { + if (pg->records) { + free_pages((unsigned long)pg->records, pg->order); + ftrace_number_of_pages -=3D 1 << pg->order; + } + pages =3D pg->next; + kfree(pg); + pg =3D pages; + ftrace_number_of_groups--; + } +} + static struct ftrace_page * ftrace_allocate_pages(unsigned long num_to_init) { @@ -3343,17 +3359,7 @@ ftrace_allocate_pages(unsigned long num_to_init) return start_pg; =20 free_pages: - pg =3D start_pg; - while (pg) { - if (pg->records) { - free_pages((unsigned long)pg->records, pg->order); - ftrace_number_of_pages -=3D 1 << pg->order; - } - start_pg =3D pg->next; - kfree(pg); - pg =3D start_pg; - ftrace_number_of_groups--; - } + ftrace_free_pages(start_pg); pr_info("ftrace: FAILED to allocate memory for functions\n"); return NULL; } @@ -6471,9 +6477,11 @@ static int ftrace_process_locs(struct module *mod, unsigned long *start, unsigned long *end) { + struct ftrace_page *pg_unuse =3D NULL; struct ftrace_page *start_pg; struct ftrace_page *pg; struct dyn_ftrace *rec; + unsigned long skipped =3D 0; unsigned long count; unsigned long *p; unsigned long addr; @@ -6536,8 +6544,10 @@ static int ftrace_process_locs(struct module *mod, * object files to satisfy alignments. * Skip any NULL pointers. */ - if (!addr) + if (!addr) { + skipped++; continue; + } =20 end_offset =3D (pg->index+1) * sizeof(pg->records[0]); if (end_offset > PAGE_SIZE << pg->order) { @@ -6551,8 +6561,10 @@ static int ftrace_process_locs(struct module *mod, rec->ip =3D addr; } =20 - /* We should have used all pages */ - WARN_ON(pg->next); + if (pg->next) { + pg_unuse =3D pg->next; + pg->next =3D NULL; + } =20 /* Assign the last page to ftrace_pages */ ftrace_pages =3D pg; @@ -6574,6 +6586,11 @@ static int ftrace_process_locs(struct module *mod, out: mutex_unlock(&ftrace_lock); =20 + /* We should have used all pages unless we skipped some */ + if (pg_unuse) { + WARN_ON(!skipped); + ftrace_free_pages(pg_unuse); + } return ret; } =20 diff --git a/kernel/trace/ftrace_internal.h b/kernel/trace/ftrace_internal.h index 382775edf690..5012c04f92c0 100644 --- a/kernel/trace/ftrace_internal.h +++ b/kernel/trace/ftrace_internal.h @@ -2,6 +2,9 @@ #ifndef _LINUX_KERNEL_FTRACE_INTERNAL_H #define _LINUX_KERNEL_FTRACE_INTERNAL_H =20 +int __register_ftrace_function(struct ftrace_ops *ops); +int __unregister_ftrace_function(struct ftrace_ops *ops); + #ifdef CONFIG_FUNCTION_TRACER =20 extern struct mutex ftrace_lock; @@ -15,8 +18,6 @@ int ftrace_ops_test(struct ftrace_ops *ops, unsigned long= ip, void *regs); =20 #else /* !CONFIG_DYNAMIC_FTRACE */ =20 -int __register_ftrace_function(struct ftrace_ops *ops); -int __unregister_ftrace_function(struct ftrace_ops *ops); /* Keep as macros so we do not need to define the commands */ # define ftrace_startup(ops, command) \ ({ \ diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 834b361a4a66..14d8001140c8 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -5242,28 +5242,34 @@ unsigned long ring_buffer_size(struct trace_buffer = *buffer, int cpu) } EXPORT_SYMBOL_GPL(ring_buffer_size); =20 +static void rb_clear_buffer_page(struct buffer_page *page) +{ + local_set(&page->write, 0); + local_set(&page->entries, 0); + rb_init_page(page->page); + page->read =3D 0; +} + static void rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) { + struct buffer_page *page; + rb_head_page_deactivate(cpu_buffer); =20 cpu_buffer->head_page =3D list_entry(cpu_buffer->pages, struct buffer_page, list); - local_set(&cpu_buffer->head_page->write, 0); - local_set(&cpu_buffer->head_page->entries, 0); - local_set(&cpu_buffer->head_page->page->commit, 0); - - cpu_buffer->head_page->read =3D 0; + rb_clear_buffer_page(cpu_buffer->head_page); + list_for_each_entry(page, cpu_buffer->pages, list) { + rb_clear_buffer_page(page); + } =20 cpu_buffer->tail_page =3D cpu_buffer->head_page; cpu_buffer->commit_page =3D cpu_buffer->head_page; =20 INIT_LIST_HEAD(&cpu_buffer->reader_page->list); INIT_LIST_HEAD(&cpu_buffer->new_pages); - local_set(&cpu_buffer->reader_page->write, 0); - local_set(&cpu_buffer->reader_page->entries, 0); - local_set(&cpu_buffer->reader_page->page->commit, 0); - cpu_buffer->reader_page->read =3D 0; + rb_clear_buffer_page(cpu_buffer->reader_page); =20 local_set(&cpu_buffer->entries_bytes, 0); local_set(&cpu_buffer->overrun, 0); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 4529e264cb86..20122eeccf97 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -3118,6 +3118,7 @@ static void __ftrace_trace_stack(struct trace_buffer = *buffer, struct ftrace_stack *fstack; struct stack_entry *entry; int stackidx; + void *ptr; =20 /* * Add one, for this function and the call to save_stack_trace() @@ -3161,9 +3162,25 @@ static void __ftrace_trace_stack(struct trace_buffer= *buffer, trace_ctx); if (!event) goto out; - entry =3D ring_buffer_event_data(event); + ptr =3D ring_buffer_event_data(event); + entry =3D ptr; + + /* + * For backward compatibility reasons, the entry->caller is an + * array of 8 slots to store the stack. This is also exported + * to user space. The amount allocated on the ring buffer actually + * holds enough for the stack specified by nr_entries. This will + * go into the location of entry->caller. Due to string fortifiers + * checking the size of the destination of memcpy() it triggers + * when it detects that size is greater than 8. To hide this from + * the fortifiers, we use "ptr" and pointer arithmetic to assign caller. + * + * The below is really just: + * memcpy(&entry->caller, fstack->calls, size); + */ + ptr +=3D offsetof(typeof(*entry), caller); + memcpy(ptr, fstack->calls, size); =20 - memcpy(&entry->caller, fstack->calls, size); entry->size =3D nr_entries; =20 if (!call_filter_check_discard(call, entry, buffer, event)) diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_u= ser.c index 4f5e74bbdab2..33cb6af31f39 100644 --- a/kernel/trace/trace_events_user.c +++ b/kernel/trace/trace_events_user.c @@ -1317,6 +1317,9 @@ static int user_field_set_string(struct ftrace_event_= field *field, pos +=3D snprintf(buf + pos, LEN_OR_ZERO, " "); pos +=3D snprintf(buf + pos, LEN_OR_ZERO, "%s", field->name); =20 + if (str_has_prefix(field->type, "struct ")) + pos +=3D snprintf(buf + pos, LEN_OR_ZERO, " %d", field->size); + if (colon) pos +=3D snprintf(buf + pos, LEN_OR_ZERO, ";"); =20 diff --git a/kernel/trace/trace_kprobe_selftest.c b/kernel/trace/trace_kpro= be_selftest.c index 16548ee4c8c6..3851cd1e6a62 100644 --- a/kernel/trace/trace_kprobe_selftest.c +++ b/kernel/trace/trace_kprobe_selftest.c @@ -1,4 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 + +#include "trace_kprobe_selftest.h" + /* * Function used during the kprobe self test. This function is in a separa= te * compile unit so it can be compile with CC_FLAGS_FTRACE to ensure that it diff --git a/samples/ftrace/ftrace-direct-modify.c b/samples/ftrace/ftrace-= direct-modify.c index 06d889149012..e5ed08098ff3 100644 --- a/samples/ftrace/ftrace-direct-modify.c +++ b/samples/ftrace/ftrace-direct-modify.c @@ -2,7 +2,9 @@ #include #include #include +#ifndef CONFIG_ARM64 #include +#endif =20 extern void my_direct_func1(void); extern void my_direct_func2(void); @@ -96,6 +98,38 @@ asm ( =20 #endif /* CONFIG_S390 */ =20 +#ifdef CONFIG_ARM64 + +asm ( +" .pushsection .text, \"ax\", @progbits\n" +" .type my_tramp1, @function\n" +" .globl my_tramp1\n" +" my_tramp1:" +" bti c\n" +" sub sp, sp, #16\n" +" stp x9, x30, [sp]\n" +" bl my_direct_func1\n" +" ldp x30, x9, [sp]\n" +" add sp, sp, #16\n" +" ret x9\n" +" .size my_tramp1, .-my_tramp1\n" + +" .type my_tramp2, @function\n" +" .globl my_tramp2\n" +" my_tramp2:" +" bti c\n" +" sub sp, sp, #16\n" +" stp x9, x30, [sp]\n" +" bl my_direct_func2\n" +" ldp x30, x9, [sp]\n" +" add sp, sp, #16\n" +" ret x9\n" +" .size my_tramp2, .-my_tramp2\n" +" .popsection\n" +); + +#endif /* CONFIG_ARM64 */ + #ifdef CONFIG_LOONGARCH =20 asm ( diff --git a/samples/ftrace/ftrace-direct-multi-modify.c b/samples/ftrace/f= trace-direct-multi-modify.c index 62f6b681999e..292cff2b3f5d 100644 --- a/samples/ftrace/ftrace-direct-multi-modify.c +++ b/samples/ftrace/ftrace-direct-multi-modify.c @@ -2,7 +2,9 @@ #include #include #include +#ifndef CONFIG_ARM64 #include +#endif =20 extern void my_direct_func1(unsigned long ip); extern void my_direct_func2(unsigned long ip); @@ -103,6 +105,44 @@ asm ( =20 #endif /* CONFIG_S390 */ =20 +#ifdef CONFIG_ARM64 + +asm ( +" .pushsection .text, \"ax\", @progbits\n" +" .type my_tramp1, @function\n" +" .globl my_tramp1\n" +" my_tramp1:" +" bti c\n" +" sub sp, sp, #32\n" +" stp x9, x30, [sp]\n" +" str x0, [sp, #16]\n" +" mov x0, x30\n" +" bl my_direct_func1\n" +" ldp x30, x9, [sp]\n" +" ldr x0, [sp, #16]\n" +" add sp, sp, #32\n" +" ret x9\n" +" .size my_tramp1, .-my_tramp1\n" + +" .type my_tramp2, @function\n" +" .globl my_tramp2\n" +" my_tramp2:" +" bti c\n" +" sub sp, sp, #32\n" +" stp x9, x30, [sp]\n" +" str x0, [sp, #16]\n" +" mov x0, x30\n" +" bl my_direct_func2\n" +" ldp x30, x9, [sp]\n" +" ldr x0, [sp, #16]\n" +" add sp, sp, #32\n" +" ret x9\n" +" .size my_tramp2, .-my_tramp2\n" +" .popsection\n" +); + +#endif /* CONFIG_ARM64 */ + #ifdef CONFIG_LOONGARCH #include =20 diff --git a/samples/ftrace/ftrace-direct-multi.c b/samples/ftrace/ftrace-d= irect-multi.c index 5482cf616b43..b4391e08c913 100644 --- a/samples/ftrace/ftrace-direct-multi.c +++ b/samples/ftrace/ftrace-direct-multi.c @@ -4,7 +4,9 @@ #include /* for handle_mm_fault() */ #include #include +#ifndef CONFIG_ARM64 #include +#endif =20 extern void my_direct_func(unsigned long ip); =20 @@ -66,6 +68,29 @@ asm ( =20 #endif /* CONFIG_S390 */ =20 +#ifdef CONFIG_ARM64 + +asm ( +" .pushsection .text, \"ax\", @progbits\n" +" .type my_tramp, @function\n" +" .globl my_tramp\n" +" my_tramp:" +" bti c\n" +" sub sp, sp, #32\n" +" stp x9, x30, [sp]\n" +" str x0, [sp, #16]\n" +" mov x0, x30\n" +" bl my_direct_func\n" +" ldp x30, x9, [sp]\n" +" ldr x0, [sp, #16]\n" +" add sp, sp, #32\n" +" ret x9\n" +" .size my_tramp, .-my_tramp\n" +" .popsection\n" +); + +#endif /* CONFIG_ARM64 */ + #ifdef CONFIG_LOONGARCH =20 #include diff --git a/samples/ftrace/ftrace-direct-too.c b/samples/ftrace/ftrace-dir= ect-too.c index a05bc2cc2261..e9804c5307c0 100644 --- a/samples/ftrace/ftrace-direct-too.c +++ b/samples/ftrace/ftrace-direct-too.c @@ -3,16 +3,18 @@ =20 #include /* for handle_mm_fault() */ #include +#ifndef CONFIG_ARM64 #include +#endif =20 -extern void my_direct_func(struct vm_area_struct *vma, - unsigned long address, unsigned int flags); +extern void my_direct_func(struct vm_area_struct *vma, unsigned long addre= ss, + unsigned int flags, struct pt_regs *regs); =20 -void my_direct_func(struct vm_area_struct *vma, - unsigned long address, unsigned int flags) +void my_direct_func(struct vm_area_struct *vma, unsigned long address, + unsigned int flags, struct pt_regs *regs) { - trace_printk("handle mm fault vma=3D%p address=3D%lx flags=3D%x\n", - vma, address, flags); + trace_printk("handle mm fault vma=3D%p address=3D%lx flags=3D%x regs=3D%p= \n", + vma, address, flags, regs); } =20 extern void my_tramp(void *); @@ -34,7 +36,9 @@ asm ( " pushq %rdi\n" " pushq %rsi\n" " pushq %rdx\n" +" pushq %rcx\n" " call my_direct_func\n" +" popq %rcx\n" " popq %rdx\n" " popq %rsi\n" " popq %rdi\n" @@ -70,6 +74,30 @@ asm ( =20 #endif /* CONFIG_S390 */ =20 +#ifdef CONFIG_ARM64 + +asm ( +" .pushsection .text, \"ax\", @progbits\n" +" .type my_tramp, @function\n" +" .globl my_tramp\n" +" my_tramp:" +" bti c\n" +" sub sp, sp, #48\n" +" stp x9, x30, [sp]\n" +" stp x0, x1, [sp, #16]\n" +" stp x2, x3, [sp, #32]\n" +" bl my_direct_func\n" +" ldp x30, x9, [sp]\n" +" ldp x0, x1, [sp, #16]\n" +" ldp x2, x3, [sp, #32]\n" +" add sp, sp, #48\n" +" ret x9\n" +" .size my_tramp, .-my_tramp\n" +" .popsection\n" +); + +#endif /* CONFIG_ARM64 */ + #ifdef CONFIG_LOONGARCH =20 asm ( diff --git a/samples/ftrace/ftrace-direct.c b/samples/ftrace/ftrace-direct.c index 06879bbd3399..20f4a7caa810 100644 --- a/samples/ftrace/ftrace-direct.c +++ b/samples/ftrace/ftrace-direct.c @@ -3,7 +3,9 @@ =20 #include /* for wake_up_process() */ #include +#ifndef CONFIG_ARM64 #include +#endif =20 extern void my_direct_func(struct task_struct *p); =20 @@ -63,6 +65,28 @@ asm ( =20 #endif /* CONFIG_S390 */ =20 +#ifdef CONFIG_ARM64 + +asm ( +" .pushsection .text, \"ax\", @progbits\n" +" .type my_tramp, @function\n" +" .globl my_tramp\n" +" my_tramp:" +" bti c\n" +" sub sp, sp, #32\n" +" stp x9, x30, [sp]\n" +" str x0, [sp, #16]\n" +" bl my_direct_func\n" +" ldp x30, x9, [sp]\n" +" ldr x0, [sp, #16]\n" +" add sp, sp, #32\n" +" ret x9\n" +" .size my_tramp, .-my_tramp\n" +" .popsection\n" +); + +#endif /* CONFIG_ARM64 */ + #ifdef CONFIG_LOONGARCH =20 asm ( diff --git a/tools/testing/selftests/user_events/dyn_test.c b/tools/testing= /selftests/user_events/dyn_test.c index d6979a48478f..91a4444ad42b 100644 --- a/tools/testing/selftests/user_events/dyn_test.c +++ b/tools/testing/selftests/user_events/dyn_test.c @@ -217,6 +217,18 @@ TEST_F(user, matching) { /* Types don't match */ TEST_NMATCH("__test_event u64 a; u64 b", "__test_event u32 a; u32 b"); + + /* Struct name and size matches */ + TEST_MATCH("__test_event struct my_struct a 20", + "__test_event struct my_struct a 20"); + + /* Struct name don't match */ + TEST_NMATCH("__test_event struct my_struct a 20", + "__test_event struct my_struct b 20"); + + /* Struct size don't match */ + TEST_NMATCH("__test_event struct my_struct a 20", + "__test_event struct my_struct a 21"); } =20 int main(int argc, char **argv)