* [PATCH] trace: fix UBSAN warning in __remove_instance
From: Darrick J. Wong @ 2025-12-16 17:49 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: mathieu.desnoyers, linux-trace-kernel
From: Darrick J. Wong <djwong@kernel.org>
xfs/558 triggers the following UBSAN warning:
------------[ cut here ]------------
UBSAN: shift-out-of-bounds in /storage/home/djwong/cdev/work/linux-xfs/kernel/trace/trace.c:10510:10
shift exponent 32 is too large for 32-bit type 'int'
CPU: 1 UID: 0 PID: 888674 Comm: rmdir Not tainted 6.19.0-rc1-xfsx #rc1 PREEMPT(lazy) dbf607ef4c142c563f76d706e71af9731d7b9c90
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.0-4.module+el8.8.0+21164+ed375313 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x4a/0x70
ubsan_epilogue+0x5/0x2b
__ubsan_handle_shift_out_of_bounds.cold+0x5e/0x113
__remove_instance.part.0.constprop.0.cold+0x18/0x26f
instance_rmdir+0xf3/0x110
tracefs_syscall_rmdir+0x4d/0x90
vfs_rmdir+0x139/0x230
do_rmdir+0x143/0x230
__x64_sys_rmdir+0x1d/0x20
do_syscall_64+0x44/0x230
entry_SYSCALL_64_after_hwframe+0x4b/0x53
RIP: 0033:0x7f7ae8e51f17
Code: f0 ff ff 73 01 c3 48 8b 0d de 2e 0e 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 b8 54 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 01 c3 48 8b 15 b1 2e 0e 00 f7 d8 64 89 02 b8
RSP: 002b:00007ffd90743f08 EFLAGS: 00000246 ORIG_RAX: 0000000000000054
RAX: ffffffffffffffda RBX: 00007ffd907440f8 RCX: 00007f7ae8e51f17
RDX: 00007f7ae8f3c5c0 RSI: 00007ffd90744a21 RDI: 00007ffd90744a21
RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000
R10: 00007f7ae8f35ac0 R11: 0000000000000246 R12: 00007ffd90744a21
R13: 0000000000000001 R14: 00007f7ae8f8b000 R15: 000055e5283e6a98
</TASK>
---[ end trace ]---
whilst tearing down an ftrace instance. TRACE_FLAGS_MAX_SIZE is now 64,
so the mask comparison expression must be typecast to a u64 value to
avoid an overflow. AFAICT, ZEROED_TRACE_FLAGS is already cast to ULL
so this is ok.
Fixes: bbec8e28cac592 ("tracing: Allow tracer to add more than 32 options")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
kernel/trace/trace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index e575956ef9b5a2..6f2148df14d966 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -10507,7 +10507,7 @@ static int __remove_instance(struct trace_array *tr)
/* Disable all the flags that were enabled coming in */
for (i = 0; i < TRACE_FLAGS_MAX_SIZE; i++) {
- if ((1 << i) & ZEROED_TRACE_FLAGS)
+ if ((1ULL << i) & ZEROED_TRACE_FLAGS)
set_tracer_flag(tr, 1ULL << i, 0);
}
^ permalink raw reply related
* Re: [PATCH v2 2/2] mm: vmscan: add PIDs to vmscan tracepoints
From: Steven Rostedt @ 2025-12-16 18:03 UTC (permalink / raw)
To: Thomas Ballasi
Cc: Masami Hiramatsu, Andrew Morton, linux-mm, linux-trace-kernel
In-Reply-To: <20251216140252.11864-3-tballasi@linux.microsoft.com>
On Tue, 16 Dec 2025 06:02:52 -0800
Thomas Ballasi <tballasi@linux.microsoft.com> wrote:
> The changes aims at adding additionnal tracepoints variables to help
> debuggers attribute them to specific processes.
>
> The PID field uses in_task() to reliably detect when we're in process
> context and can safely access current->pid. When not in process
> context (such as in interrupt or in an asynchronous RCU context), the
> field is set to -1 as a sentinel value.
>
> Signed-off-by: Thomas Ballasi <tballasi@linux.microsoft.com>
Is this really needed? The trace events already show if you are in
interrupt context or not.
# tracer: nop
#
# entries-in-buffer/entries-written: 25817/25817 #P:8
#
# _-----=> irqs-off/BH-disabled
# / _----=> need-resched
# | / _---=> hardirq/softirq <<<<------ Shows irq context
# || / _--=> preempt-depth
# ||| / _-=> migrate-disable
# |||| / delay
# TASK-PID CPU# ||||| TIMESTAMP FUNCTION
# | | | ||||| | |
<idle>-0 [002] d..1. 11429.293552: rcu_watching: Startirq 0 1 0x74c
<idle>-0 [000] d.H1. 11429.293564: rcu_utilization: Start scheduler-tick
<idle>-0 [000] d.H1. 11429.293566: rcu_utilization: End scheduler-tick
<idle>-0 [002] dN.1. 11429.293567: rcu_watching: Endirq 1 0 0x74c
<idle>-0 [002] dN.1. 11429.293568: rcu_watching: Start 0 1 0x754
<idle>-0 [000] d.s1. 11429.293577: rcu_watching: --= 3 1 0xdf4
<idle>-0 [002] dN.1. 11429.293579: rcu_utilization: Start context switch
<idle>-0 [002] dN.1. 11429.293580: rcu_utilization: End context switch
rcu_sched-15 [002] d..1. 11429.293589: rcu_grace_period: rcu_sched 132685 start
<idle>-0 [000] dN.1. 11429.293592: rcu_watching: Endirq 1 0 0xdf4
rcu_sched-15 [002] d..1. 11429.293592: rcu_grace_period: rcu_sched 132685 cpustart
rcu_sched-15 [002] d..1. 11429.293592: rcu_grace_period_init: rcu_sched 132685 0 0 7 ff
<idle>-0 [000] dN.1. 11429.293593: rcu_watching: Start 0 1 0xdfc
Thus, you can already tell if you are in interrupt context or not, and you
always get the current pid. The 'H', 'h' or 's' means you are in a
interrupt type context. ('H' for hard interrupt interrupting a softirq, 'h'
for just a hard interrupt, and 's' for a softirq).
What's the point of adding another field to cover the same information
that's already available?
-- Steve
^ permalink raw reply
* Re: [PATCH v2 3/8] tools/rtla: Consolidate -C/--cgroup option parsing
From: Steven Rostedt @ 2025-12-16 18:04 UTC (permalink / raw)
To: Wander Lairson Costa
Cc: Costa Shulyupin, Tomas Glozar, Crystal Wood, John Kacur,
Ivan Pravdin, linux-trace-kernel, linux-kernel
In-Reply-To: <tazkdgebtw7sgrw7cjrntde6hpcqqlbg7spllkquqxsqowj2uo@xegmfpfkgps7>
On Tue, 16 Dec 2025 13:17:00 -0300
Wander Lairson Costa <wander@redhat.com> wrote:
> > break;
> > --
> > 2.52.0
> >
>
> Reviewed-by: Wander Lairson Costa <wander@redhat.com>
Please trim your replies. It's very annoying to scroll down several pages
just to find a reviewed-by tag.
-- Steve
^ permalink raw reply
* Re: [PATCH] tracing: Guard __DECLARE_TRACE() use of __DO_TRACE_CALL() with SRCU-fast
From: Steven Rostedt @ 2025-12-16 18:06 UTC (permalink / raw)
To: LKML, Linux Trace Kernel
Cc: Masami Hiramatsu, Mathieu Desnoyers, Paul E. McKenney,
Sebastian Andrzej Siewior, bpf
In-Reply-To: <20251216120819.3499e00e@gandalf.local.home>
Ignore this one, I sent it out before updating the subject to say "v4" :-p
-- Steve
^ permalink raw reply
* Re: [PATCH v2 1/2] mm: vmscan: add cgroup IDs to vmscan tracepoints
From: Shakeel Butt @ 2025-12-16 18:50 UTC (permalink / raw)
To: Thomas Ballasi
Cc: Steven Rostedt, Masami Hiramatsu, Andrew Morton, linux-mm,
linux-trace-kernel
In-Reply-To: <20251216140252.11864-2-tballasi@linux.microsoft.com>
On Tue, Dec 16, 2025 at 06:02:51AM -0800, Thomas Ballasi wrote:
> Memory reclaim events are currently difficult to attribute to
> specific cgroups, making debugging memory pressure issues
> challenging. This patch adds memory cgroup ID (memcg_id) to key
> vmscan tracepoints to enable better correlation and analysis.
>
> For operations not associated with a specific cgroup, the field
> is defaulted to 0.
>
> Signed-off-by: Thomas Ballasi <tballasi@linux.microsoft.com>
> ---
...
> + __entry->memcg_id = sc->memcg ? mem_cgroup_id(sc->memcg) : 0;
...
> + __entry->memcg_id = sc->memcg ? mem_cgroup_id(sc->memcg) : 0;
...
>
...
> trace_mm_vmscan_memcg_softlimit_reclaim_begin(sc.order,
> - sc.gfp_mask);
> + sc.gfp_mask,
> + mem_cgroup_id(memcg));
>
...
> + trace_mm_vmscan_memcg_softlimit_reclaim_end(sc.nr_reclaimed, mem_cgroup_id(memcg));
...
> + trace_mm_vmscan_memcg_reclaim_begin(0, sc.gfp_mask, mem_cgroup_id(memcg));
...
> + trace_mm_vmscan_memcg_reclaim_end(nr_reclaimed, mem_cgroup_id(memcg));
Please don't use mem_cgroup_id() here as it is an ID internal to memcg.
Use cgroup_id(memcg->css.cgroup) instead which is inode number and is
exposed to the userspace.
^ permalink raw reply
* [PATCH] tracing: Do not register unsupported perf events
From: Steven Rostedt @ 2025-12-16 23:24 UTC (permalink / raw)
To: LKML, Linux Trace Kernel
Cc: Masami Hiramatsu, Mathieu Desnoyers, Ian Rogers,
Arnaldo Carvalho de Melo, Jiri Olsa, Namhyung Kim
From: Steven Rostedt <rostedt@goodmis.org>
Synthetic events currently do not have a function to register perf events.
This leads to calling the tracepoint register functions with a NULL
function pointer which triggers:
------------[ cut here ]------------
WARNING: kernel/tracepoint.c:175 at tracepoint_add_func+0x357/0x370, CPU#2: perf/2272
Modules linked in: kvm_intel kvm irqbypass
CPU: 2 UID: 0 PID: 2272 Comm: perf Not tainted 6.18.0-ftest-11964-ge022764176fc-dirty #323 PREEMPTLAZY
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
RIP: 0010:tracepoint_add_func+0x357/0x370
Code: 28 9c e8 4c 0b f5 ff eb 0f 4c 89 f7 48 c7 c6 80 4d 28 9c e8 ab 89 f4 ff 31 c0 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc cc <0f> 0b 49 c7 c6 ea ff ff ff e9 ee fe ff ff 0f 0b e9 f9 fe ff ff 0f
RSP: 0018:ffffabc0c44d3c40 EFLAGS: 00010246
RAX: 0000000000000001 RBX: ffff9380aa9e4060 RCX: 0000000000000000
RDX: 000000000000000a RSI: ffffffff9e1d4a98 RDI: ffff937fcf5fd6c8
RBP: 0000000000000001 R08: 0000000000000007 R09: ffff937fcf5fc780
R10: 0000000000000003 R11: ffffffff9c193910 R12: 000000000000000a
R13: ffffffff9e1e5888 R14: 0000000000000000 R15: ffffabc0c44d3c78
FS: 00007f6202f5f340(0000) GS:ffff93819f00f000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000055d3162281a8 CR3: 0000000106a56003 CR4: 0000000000172ef0
Call Trace:
<TASK>
tracepoint_probe_register+0x5d/0x90
synth_event_reg+0x3c/0x60
perf_trace_event_init+0x204/0x340
perf_trace_init+0x85/0xd0
perf_tp_event_init+0x2e/0x50
perf_try_init_event+0x6f/0x230
? perf_event_alloc+0x4bb/0xdc0
perf_event_alloc+0x65a/0xdc0
__se_sys_perf_event_open+0x290/0x9f0
do_syscall_64+0x93/0x7b0
? entry_SYSCALL_64_after_hwframe+0x76/0x7e
? trace_hardirqs_off+0x53/0xc0
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Instead, have the code return -ENODEV, which doesn't warn and has perf
error out with:
# perf record -e synthetic:futex_wait
Error:
The sys_perf_event_open() syscall returned with 19 (No such device) for event (synthetic:futex_wait).
"dmesg | grep -i perf" may provide additional information.
Ideally perf should support synthetic events, but for now just fix the
warning. The support can come later.
Cc: stable@vger.kernel.org
Fixes: 4b147936fa509 ("tracing: Add support for 'synthetic' events")
Reported-by: Ian Rogers <irogers@google.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
kernel/trace/trace_events.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index a5a93d243047..754b14ca87a7 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -710,6 +710,8 @@ int trace_event_reg(struct trace_event_call *call,
#ifdef CONFIG_PERF_EVENTS
case TRACE_REG_PERF_REGISTER:
+ if (!call->class->perf_probe)
+ return -ENODEV;
return tracepoint_probe_register(call->tp,
call->class->perf_probe,
call);
--
2.51.0
^ permalink raw reply related
* Re: [PATCH v13 mm-new 07/16] khugepaged: introduce collapse_max_ptes_none helper function
From: Nico Pache @ 2025-12-16 23:26 UTC (permalink / raw)
To: Baolin Wang
Cc: linux-kernel, linux-trace-kernel, linux-mm, linux-doc, david, ziy,
lorenzo.stoakes, Liam.Howlett, ryan.roberts, dev.jain, corbet,
rostedt, mhiramat, mathieu.desnoyers, akpm, baohua, willy, peterx,
wangkefeng.wang, usamaarif642, sunnanyong, vishal.moola,
thomas.hellstrom, yang, kas, aarcange, raquini, anshuman.khandual,
catalin.marinas, tiwai, will, dave.hansen, jack, cl, jglisse,
surenb, zokeefe, hannes, rientjes, mhocko, rdunlap, hughd,
richard.weiyang, lance.yang, vbabka, rppt, jannh, pfalcato
In-Reply-To: <95b1403f-3ddb-43ff-b481-2ecc6ab8352f@linux.alibaba.com>
On Tue, Dec 16, 2025 at 1:12 AM Baolin Wang
<baolin.wang@linux.alibaba.com> wrote:
>
> Hi Nico,
Hi Baolin! Thanks for testing :)
Did you happen to test with the changes I asked Andrew to append to
this commit?
Either way, I think your fixup makes more sense than mine.
Cheers,
-- Nico
>
> On 2025/12/2 01:46, Nico Pache wrote:
> > The current mechanism for determining mTHP collapse scales the
> > khugepaged_max_ptes_none value based on the target order. This
> > introduces an undesirable feedback loop, or "creep", when max_ptes_none
> > is set to a value greater than HPAGE_PMD_NR / 2.
> >
> > With this configuration, a successful collapse to order N will populate
> > enough pages to satisfy the collapse condition on order N+1 on the next
> > scan. This leads to unnecessary work and memory churn.
> >
> > To fix this issue introduce a helper function that will limit mTHP
> > collapse support to two max_ptes_none values, 0 and HPAGE_PMD_NR - 1.
> > This effectively supports two modes:
> >
> > - max_ptes_none=0: never introduce new none-pages for mTHP collapse.
> > - max_ptes_none=511 (on 4k pagesz): Always collapse to the highest
> > available mTHP order.
> >
> > This removes the possiblilty of "creep", while not modifying any uAPI
> > expectations. A warning will be emitted if any non-supported
> > max_ptes_none value is configured with mTHP enabled.
> >
> > The limits can be ignored by passing full_scan=true, this is useful for
> > madvise_collapse (which ignores limits), or in the case of
> > collapse_scan_pmd(), allows the full PMD to be scanned when mTHP
> > collapse is available.
> >
> > Signed-off-by: Nico Pache <npache@redhat.com>
> > ---
> > mm/khugepaged.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 42 insertions(+), 1 deletion(-)
> >
> > diff --git a/mm/khugepaged.c b/mm/khugepaged.c
> > index 8dab49c53128..f425238d5d4f 100644
> > --- a/mm/khugepaged.c
> > +++ b/mm/khugepaged.c
> > @@ -463,6 +463,44 @@ void __khugepaged_enter(struct mm_struct *mm)
> > wake_up_interruptible(&khugepaged_wait);
> > }
> >
> > +/**
> > + * collapse_max_ptes_none - Calculate maximum allowed empty PTEs for collapse
> > + * @order: The folio order being collapsed to
> > + * @full_scan: Whether this is a full scan (ignore limits)
> > + *
> > + * For madvise-triggered collapses (full_scan=true), all limits are bypassed
> > + * and allow up to HPAGE_PMD_NR - 1 empty PTEs.
> > + *
> > + * For PMD-sized collapses (order == HPAGE_PMD_ORDER), use the configured
> > + * khugepaged_max_ptes_none value.
> > + *
> > + * For mTHP collapses, we currently only support khugepaged_max_pte_none values
> > + * of 0 or (HPAGE_PMD_NR - 1). Any other value will emit a warning and no mTHP
> > + * collapse will be attempted
> > + *
> > + * Return: Maximum number of empty PTEs allowed for the collapse operation
> > + */
> > +static unsigned int collapse_max_ptes_none(unsigned int order, bool full_scan)
> > +{
> > + /* ignore max_ptes_none limits */
> > + if (full_scan)
> > + return HPAGE_PMD_NR - 1;
> > +
> > + if (!is_mthp_order(order))
> > + return khugepaged_max_ptes_none;
> > +
> > + /* Zero/non-present collapse disabled. */
> > + if (!khugepaged_max_ptes_none)
> > + return 0;
> > +
> > + if (khugepaged_max_ptes_none == HPAGE_PMD_NR - 1)
> > + return (1 << order) - 1;
> > +
> > + pr_warn_once("mTHP collapse only supports max_ptes_none values of 0 or %d\n",
> > + HPAGE_PMD_NR - 1);
> > + return -EINVAL;
> > +}
> > +
> > void khugepaged_enter_vma(struct vm_area_struct *vma,
> > vm_flags_t vm_flags)
> > {
> > @@ -550,7 +588,10 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
> > pte_t *_pte;
> > int none_or_zero = 0, shared = 0, result = SCAN_FAIL, referenced = 0;
> > const unsigned long nr_pages = 1UL << order;
> > - int max_ptes_none = khugepaged_max_ptes_none >> (HPAGE_PMD_ORDER - order);
> > + int max_ptes_none = collapse_max_ptes_none(order, !cc->is_khugepaged);
> > +
> > + if (max_ptes_none == -EINVAL)
> > + goto out;
>
> After testing your patchset, I hit the following crash. The reason is
> that when 'max_ptes_none' is -EINVAL here, it shouldn't goto out to call
> release_pte_pages(), because the '_pte' hasn't been initialized at this
> point, and there's no need to release folios either.
>
> After applying the fix below, the crash issue is resolved. I'm not sure
> whether Andrew will help fix this or if you will send a new version to
> address this issue.
>
> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
> index 8cffaf59ced8..2e8171a6d7df 100644
> --- a/mm/khugepaged.c
> +++ b/mm/khugepaged.c
> @@ -646,7 +646,7 @@ static int __collapse_huge_page_isolate(struct
> vm_area_struct *vma,
> int max_ptes_none = collapse_max_ptes_none(order,
> !cc->is_khugepaged);
>
> if (max_ptes_none == -EINVAL)
> - goto out;
> + return result;
>
> for (_pte = pte; _pte < pte + nr_pages;
> _pte++, addr += PAGE_SIZE) {
>
> "
> [ 565.319345] Unable to handle kernel paging request at virtual address
> fffffffffffffffa
> .......
> [ 565.319409] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000001f8549a000
> [ 565.319416] [fffffffffffffffa] pgd=0000001f85f2a403,
> p4d=0000001f85f2a403, pud=0000001f85f2b403, pmd=0000000000000000
> [ 565.319427] Internal error: Oops: 0000000096000006 [#1] SMP
> .......
> [ 565.326733] pc : release_pte_pages+0x68/0x178
> [ 565.326960] lr : __collapse_huge_page_isolate+0xc0/0x748
> [ 565.327232] sp : ffff800083593910
> .......
> [ 565.331476] Call trace:
> [ 565.331664] release_pte_pages+0x68/0x178 (P)
> [ 565.331940] __collapse_huge_page_isolate+0xc0/0x748
> [ 565.332249] collapse_huge_page+0x4cc/0xa70
> [ 565.332510] mthp_collapse+0x254/0x2a8
> [ 565.332754] collapse_scan_pmd+0x5a0/0x6d8
> [ 565.333010] collapse_single_pmd+0x214/0x288
> [ 565.333275] collapse_scan_mm_slot.constprop.0+0x2ac/0x460
> [ 565.333617] khugepaged+0x204/0x2c8
> [ 565.333992] kthread+0xf8/0x110
> [ 565.334368] ret_from_fork+0x10/0x20
> "
>
> >
> > for (_pte = pte; _pte < pte + nr_pages;
> > _pte++, addr += PAGE_SIZE) {
>
^ permalink raw reply
* Re: [PATCH v3 4/4] tracing: move tracing declarations from kernel.h to a dedicated header
From: Andrew Morton @ 2025-12-17 0:13 UTC (permalink / raw)
To: Yury Norov (NVIDIA)
Cc: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
Andy Shevchenko, Christophe Leroy, Randy Dunlap, Ingo Molnar,
Jani Nikula, Joonas Lahtinen, David Laight, Petr Pavlu,
Andi Shyti, Rodrigo Vivi, Tvrtko Ursulin, Daniel Gomez,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
linux-kernel, intel-gfx, dri-devel, linux-modules,
linux-trace-kernel
In-Reply-To: <20251205175237.242022-5-yury.norov@gmail.com>
On Fri, 5 Dec 2025 12:52:35 -0500 "Yury Norov (NVIDIA)" <yury.norov@gmail.com> wrote:
> Tracing is a half of the kernel.h in terms of LOCs, although it's
> a self-consistent part. It is intended for quick debugging purposes
> and isn't used by the normal tracing utilities.
>
> Move it to a separate header. If someone needs to just throw a
> trace_printk() in their driver, they will not have to pull all
> the heavy tracing machinery.
>
> This is a pure move, except for removing a few 'extern's.
>
This one blows up my x86_64 allmodconfig, gcc-15.2.0:
In file included from ./include/linux/string.h:386,
from ./include/linux/trace_printk.h:9,
from ./include/linux/kernel.h:34,
from arch/x86/purgatory/purgatory.c:12:
./include/linux/fortify-string.h:626:63: error: expected identifier or '(' before '{' token
626 | p_size_field, q_size_field, op) ({ \
| ^
./include/linux/fortify-string.h:694:27: note: in expansion of macro '__fortify_memcpy_chk'
694 | #define memmove(p, q, s) __fortify_memcpy_chk(p, q, s, \
| ^~~~~~~~~~~~~~~~~~~~
arch/x86/purgatory/../boot/string.h:11:7: note: in expansion of macro 'memmove'
11 | void *memmove(void *dst, const void *src, size_t len);
| ^~~~~~~
./include/linux/fortify-string.h:258:9: error: expected identifier or '(' before '__builtin_choose_expr'
258 | __builtin_choose_expr(__is_constexpr(__builtin_strlen(p)), \
| ^~~~~~~~~~~~~~~~~~~~~
arch/x86/purgatory/../boot/string.h:23:15: note: in expansion of macro 'strlen'
23 | extern size_t strlen(const char *s);
| ^~~~~~
make[4]: *** [scripts/Makefile.build:287: arch/x86/purgatory/purgatory.o] Error 1
make[3]: *** [scripts/Makefile.build:556: arch/x86/purgatory] Error 2
make[2]: *** [scripts/Makefile.build:556: arch/x86] Error 2
make[1]: *** [/usr/src/25/Makefile:2054: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
^ permalink raw reply
* Re: [PATCH v3 4/4] tracing: move tracing declarations from kernel.h to a dedicated header
From: Yury Norov @ 2025-12-17 0:52 UTC (permalink / raw)
To: Andrew Morton
Cc: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
Andy Shevchenko, Christophe Leroy, Randy Dunlap, Ingo Molnar,
Jani Nikula, Joonas Lahtinen, David Laight, Petr Pavlu,
Andi Shyti, Rodrigo Vivi, Tvrtko Ursulin, Daniel Gomez,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
linux-kernel, intel-gfx, dri-devel, linux-modules,
linux-trace-kernel
In-Reply-To: <20251216161316.45b3f19ff0ad482018137189@linux-foundation.org>
On Tue, Dec 16, 2025 at 04:13:16PM -0800, Andrew Morton wrote:
> On Fri, 5 Dec 2025 12:52:35 -0500 "Yury Norov (NVIDIA)" <yury.norov@gmail.com> wrote:
>
> > Tracing is a half of the kernel.h in terms of LOCs, although it's
> > a self-consistent part. It is intended for quick debugging purposes
> > and isn't used by the normal tracing utilities.
> >
> > Move it to a separate header. If someone needs to just throw a
> > trace_printk() in their driver, they will not have to pull all
> > the heavy tracing machinery.
> >
> > This is a pure move, except for removing a few 'extern's.
> >
>
> This one blows up my x86_64 allmodconfig, gcc-15.2.0:
Thanks, Andrew. I'll take a look.
^ permalink raw reply
* Re: [PATCH] ftrace: fix address for jmp mode in t_show
From: Menglong Dong @ 2025-12-17 1:32 UTC (permalink / raw)
To: Menglong Dong, Steven Rostedt
Cc: mhiramat, mark.rutland, mathieu.desnoyers, ast, jiang.biao,
linux-kernel, linux-trace-kernel
In-Reply-To: <20251216112814.71588752@gandalf.local.home>
On 2025/12/17 00:28 Steven Rostedt <rostedt@goodmis.org> write:
> On Tue, 16 Dec 2025 11:45:33 +0800
> Menglong Dong <menglong8.dong@gmail.com> wrote:
>
> > diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> > index bbb37c0f8c6c..d4c41fb76a25 100644
> > --- a/kernel/trace/ftrace.c
> > +++ b/kernel/trace/ftrace.c
> > @@ -4492,8 +4492,12 @@ static int t_show(struct seq_file *m, void *v)
> > unsigned long direct;
> >
> > direct = ftrace_find_rec_direct(rec->ip);
> > - if (direct)
> > - seq_printf(m, "\n\tdirect-->%pS", (void *)direct);
> > + if (direct) {
> > + seq_printf(m, ftrace_is_jmp(direct) ?
> > + "\n\tdirect(jmp)-->%pS" :
> > + "\n\tdirect-->%pS",
> > + (void *)ftrace_jmp_get(direct));
>
> A little cleaner way to do the above:
>
> seq_printf(m, "\n\tdirect%s-->%pS",
> ftrace_is_jmp(direct) ? "(jmp)" : "",
> (void *)ftrace_jmp_get(direct));
Yeah, looks better. I'll send a V2 later.
Thanks!
Menglong Dong
>
>
> -- Steve
>
> > + }
> > }
> > }
>
>
^ permalink raw reply
* Re: [PATCH v13 mm-new 07/16] khugepaged: introduce collapse_max_ptes_none helper function
From: Baolin Wang @ 2025-12-17 1:33 UTC (permalink / raw)
To: Nico Pache
Cc: linux-kernel, linux-trace-kernel, linux-mm, linux-doc, david, ziy,
lorenzo.stoakes, Liam.Howlett, ryan.roberts, dev.jain, corbet,
rostedt, mhiramat, mathieu.desnoyers, akpm, baohua, willy, peterx,
wangkefeng.wang, usamaarif642, sunnanyong, vishal.moola,
thomas.hellstrom, yang, kas, aarcange, raquini, anshuman.khandual,
catalin.marinas, tiwai, will, dave.hansen, jack, cl, jglisse,
surenb, zokeefe, hannes, rientjes, mhocko, rdunlap, hughd,
richard.weiyang, lance.yang, vbabka, rppt, jannh, pfalcato
In-Reply-To: <CAA1CXcCtp2OwTmm-1EYUpOhsey1sv7CRFu8454m16C=k9iaN6g@mail.gmail.com>
On 2025/12/17 07:26, Nico Pache wrote:
> On Tue, Dec 16, 2025 at 1:12 AM Baolin Wang
> <baolin.wang@linux.alibaba.com> wrote:
>>
>> Hi Nico,
>
> Hi Baolin! Thanks for testing :)
>
> Did you happen to test with the changes I asked Andrew to append to
> this commit?
>
> Either way, I think your fixup makes more sense than mine.
Ah, I did not notice your fixup commit earlier, which seems to address
this problem. And as I said, we don't need to call release_pte_pages()
in this case.
>> On 2025/12/2 01:46, Nico Pache wrote:
>>> The current mechanism for determining mTHP collapse scales the
>>> khugepaged_max_ptes_none value based on the target order. This
>>> introduces an undesirable feedback loop, or "creep", when max_ptes_none
>>> is set to a value greater than HPAGE_PMD_NR / 2.
>>>
>>> With this configuration, a successful collapse to order N will populate
>>> enough pages to satisfy the collapse condition on order N+1 on the next
>>> scan. This leads to unnecessary work and memory churn.
>>>
>>> To fix this issue introduce a helper function that will limit mTHP
>>> collapse support to two max_ptes_none values, 0 and HPAGE_PMD_NR - 1.
>>> This effectively supports two modes:
>>>
>>> - max_ptes_none=0: never introduce new none-pages for mTHP collapse.
>>> - max_ptes_none=511 (on 4k pagesz): Always collapse to the highest
>>> available mTHP order.
>>>
>>> This removes the possiblilty of "creep", while not modifying any uAPI
>>> expectations. A warning will be emitted if any non-supported
>>> max_ptes_none value is configured with mTHP enabled.
>>>
>>> The limits can be ignored by passing full_scan=true, this is useful for
>>> madvise_collapse (which ignores limits), or in the case of
>>> collapse_scan_pmd(), allows the full PMD to be scanned when mTHP
>>> collapse is available.
>>>
>>> Signed-off-by: Nico Pache <npache@redhat.com>
>>> ---
>>> mm/khugepaged.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
>>> 1 file changed, 42 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
>>> index 8dab49c53128..f425238d5d4f 100644
>>> --- a/mm/khugepaged.c
>>> +++ b/mm/khugepaged.c
>>> @@ -463,6 +463,44 @@ void __khugepaged_enter(struct mm_struct *mm)
>>> wake_up_interruptible(&khugepaged_wait);
>>> }
>>>
>>> +/**
>>> + * collapse_max_ptes_none - Calculate maximum allowed empty PTEs for collapse
>>> + * @order: The folio order being collapsed to
>>> + * @full_scan: Whether this is a full scan (ignore limits)
>>> + *
>>> + * For madvise-triggered collapses (full_scan=true), all limits are bypassed
>>> + * and allow up to HPAGE_PMD_NR - 1 empty PTEs.
>>> + *
>>> + * For PMD-sized collapses (order == HPAGE_PMD_ORDER), use the configured
>>> + * khugepaged_max_ptes_none value.
>>> + *
>>> + * For mTHP collapses, we currently only support khugepaged_max_pte_none values
>>> + * of 0 or (HPAGE_PMD_NR - 1). Any other value will emit a warning and no mTHP
>>> + * collapse will be attempted
>>> + *
>>> + * Return: Maximum number of empty PTEs allowed for the collapse operation
>>> + */
>>> +static unsigned int collapse_max_ptes_none(unsigned int order, bool full_scan)
>>> +{
>>> + /* ignore max_ptes_none limits */
>>> + if (full_scan)
>>> + return HPAGE_PMD_NR - 1;
>>> +
>>> + if (!is_mthp_order(order))
>>> + return khugepaged_max_ptes_none;
>>> +
>>> + /* Zero/non-present collapse disabled. */
>>> + if (!khugepaged_max_ptes_none)
>>> + return 0;
>>> +
>>> + if (khugepaged_max_ptes_none == HPAGE_PMD_NR - 1)
>>> + return (1 << order) - 1;
>>> +
>>> + pr_warn_once("mTHP collapse only supports max_ptes_none values of 0 or %d\n",
>>> + HPAGE_PMD_NR - 1);
>>> + return -EINVAL;
>>> +}
>>> +
>>> void khugepaged_enter_vma(struct vm_area_struct *vma,
>>> vm_flags_t vm_flags)
>>> {
>>> @@ -550,7 +588,10 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
>>> pte_t *_pte;
>>> int none_or_zero = 0, shared = 0, result = SCAN_FAIL, referenced = 0;
>>> const unsigned long nr_pages = 1UL << order;
>>> - int max_ptes_none = khugepaged_max_ptes_none >> (HPAGE_PMD_ORDER - order);
>>> + int max_ptes_none = collapse_max_ptes_none(order, !cc->is_khugepaged);
>>> +
>>> + if (max_ptes_none == -EINVAL)
>>> + goto out;
>>
>> After testing your patchset, I hit the following crash. The reason is
>> that when 'max_ptes_none' is -EINVAL here, it shouldn't goto out to call
>> release_pte_pages(), because the '_pte' hasn't been initialized at this
>> point, and there's no need to release folios either.
>>
>> After applying the fix below, the crash issue is resolved. I'm not sure
>> whether Andrew will help fix this or if you will send a new version to
>> address this issue.
>>
>> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
>> index 8cffaf59ced8..2e8171a6d7df 100644
>> --- a/mm/khugepaged.c
>> +++ b/mm/khugepaged.c
>> @@ -646,7 +646,7 @@ static int __collapse_huge_page_isolate(struct
>> vm_area_struct *vma,
>> int max_ptes_none = collapse_max_ptes_none(order,
>> !cc->is_khugepaged);
>>
>> if (max_ptes_none == -EINVAL)
>> - goto out;
>> + return result;
>>
>> for (_pte = pte; _pte < pte + nr_pages;
>> _pte++, addr += PAGE_SIZE) {
>>
>> "
>> [ 565.319345] Unable to handle kernel paging request at virtual address
>> fffffffffffffffa
>> .......
>> [ 565.319409] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000001f8549a000
>> [ 565.319416] [fffffffffffffffa] pgd=0000001f85f2a403,
>> p4d=0000001f85f2a403, pud=0000001f85f2b403, pmd=0000000000000000
>> [ 565.319427] Internal error: Oops: 0000000096000006 [#1] SMP
>> .......
>> [ 565.326733] pc : release_pte_pages+0x68/0x178
>> [ 565.326960] lr : __collapse_huge_page_isolate+0xc0/0x748
>> [ 565.327232] sp : ffff800083593910
>> .......
>> [ 565.331476] Call trace:
>> [ 565.331664] release_pte_pages+0x68/0x178 (P)
>> [ 565.331940] __collapse_huge_page_isolate+0xc0/0x748
>> [ 565.332249] collapse_huge_page+0x4cc/0xa70
>> [ 565.332510] mthp_collapse+0x254/0x2a8
>> [ 565.332754] collapse_scan_pmd+0x5a0/0x6d8
>> [ 565.333010] collapse_single_pmd+0x214/0x288
>> [ 565.333275] collapse_scan_mm_slot.constprop.0+0x2ac/0x460
>> [ 565.333617] khugepaged+0x204/0x2c8
>> [ 565.333992] kthread+0xf8/0x110
>> [ 565.334368] ret_from_fork+0x10/0x20
>> "
>>
>>>
>>> for (_pte = pte; _pte < pte + nr_pages;
>>> _pte++, addr += PAGE_SIZE) {
>>
^ permalink raw reply
* Re: [PATCH 1/3] mm/khugepaged: remove unnecessary goto 'skip' label
From: Wei Yang @ 2025-12-17 2:48 UTC (permalink / raw)
To: Shivank Garg
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Zi Yan,
Baolin Wang, Liam R . Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, linux-mm, linux-kernel,
linux-trace-kernel
In-Reply-To: <20251216111139.95438-4-shivankg@amd.com>
On Tue, Dec 16, 2025 at 11:11:38AM +0000, Shivank Garg wrote:
>Replace 'goto skip' with actual logic for better code readability.
>
>No functional change.
>
>Signed-off-by: Shivank Garg <shivankg@amd.com>
>---
> mm/khugepaged.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
>diff --git a/mm/khugepaged.c b/mm/khugepaged.c
>index 6c8c35d3e0c9..107146f012b1 100644
>--- a/mm/khugepaged.c
>+++ b/mm/khugepaged.c
>@@ -2442,14 +2442,15 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages, int *result,
> break;
> }
> if (!thp_vma_allowable_order(vma, vma->vm_flags, TVA_KHUGEPAGED, PMD_ORDER)) {
>-skip:
> progress++;
> continue;
> }
> hstart = round_up(vma->vm_start, HPAGE_PMD_SIZE);
> hend = round_down(vma->vm_end, HPAGE_PMD_SIZE);
>- if (khugepaged_scan.address > hend)
>- goto skip;
>+ if (khugepaged_scan.address > hend) {
>+ progress++;
>+ continue;
>+ }
Hi, Shivank
The change here looks good, while I come up with an question.
The @progress here seems record two things:
* number of pages scaned
* number of vma skipped
While in very rare case, we may miss to count the second case.
For example, we have following vmas in a process:
vma1 vma2
+----------------+------------+
|2M |1M |
+----------------+------------+
Let's assume vma1 is exactly HPAGE_PMD_SIZE and also HPAGE_PMD_SIZE aligned.
But vma2 is only half of HPAGE_PMD_SIZE.
When scan finish vma1 and start on vma2, we would have hstart = hend =
address. So we continue here but would not do real scan, since address == hend.
I am thinking whether this could handle it:
if (khugepaged_scan.address > hend || hend <= hstart) {
progress++;
continue;
}
Do you thinks I am correct on this?
> if (khugepaged_scan.address < hstart)
> khugepaged_scan.address = hstart;
> VM_BUG_ON(khugepaged_scan.address & ~HPAGE_PMD_MASK);
>--
>2.43.0
>
--
Wei Yang
Help you, Help me
^ permalink raw reply
* Re: [PATCH 3/3] mm/khugepaged: make khugepaged_collapse_control static
From: Wei Yang @ 2025-12-17 2:48 UTC (permalink / raw)
To: Shivank Garg
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Zi Yan,
Baolin Wang, Liam R . Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, linux-mm, linux-kernel,
linux-trace-kernel
In-Reply-To: <20251216111139.95438-8-shivankg@amd.com>
On Tue, Dec 16, 2025 at 11:11:42AM +0000, Shivank Garg wrote:
>The global variable 'khugepaged_collapse_control' is not used outside of
>mm/khugepaged.c. Make it static to limit its scope.
>
>Signed-off-by: Shivank Garg <shivankg@amd.com>
Reviewed-by: Wei Yang <richard.weiyang@gmail.com>
>---
> mm/khugepaged.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
>diff --git a/mm/khugepaged.c b/mm/khugepaged.c
>index 65b1b778378a..d130357a2d88 100644
>--- a/mm/khugepaged.c
>+++ b/mm/khugepaged.c
>@@ -829,7 +829,7 @@ static void khugepaged_alloc_sleep(void)
> remove_wait_queue(&khugepaged_wait, &wait);
> }
>
>-struct collapse_control khugepaged_collapse_control = {
>+static struct collapse_control khugepaged_collapse_control = {
> .is_khugepaged = true,
> };
>
>--
>2.43.0
>
--
Wei Yang
Help you, Help me
^ permalink raw reply
* [PATCH v2] ftrace: fix address for jmp mode in t_show
From: Menglong Dong @ 2025-12-17 3:00 UTC (permalink / raw)
To: rostedt
Cc: mhiramat, mark.rutland, mathieu.desnoyers, menglong8.dong, ast,
jiang.biao, linux-kernel, linux-trace-kernel
The address from ftrace_find_rec_direct() is printed directly in t_show().
This can mislead symbol offsets if it has the "jmp" bit in the last bit.
Fix this by printing the address that returned by ftrace_jmp_get().
Fixes: 25e4e3565d45 ("ftrace: Introduce FTRACE_OPS_FL_JMP")
Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
v2:
- make the code a little more cleaner
---
kernel/trace/ftrace.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index bbb37c0f8c6c..b6c5b0e899e0 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -4492,8 +4492,11 @@ static int t_show(struct seq_file *m, void *v)
unsigned long direct;
direct = ftrace_find_rec_direct(rec->ip);
- if (direct)
- seq_printf(m, "\n\tdirect-->%pS", (void *)direct);
+ if (direct) {
+ seq_printf(m, "\n\tdirect%s-->%pS",
+ ftrace_is_jmp(direct) ? "(jmp)" : "",
+ (void *)ftrace_jmp_get(direct));
+ }
}
}
--
2.52.0
^ permalink raw reply related
* Re: [PATCH v3 4/4] tracing: move tracing declarations from kernel.h to a dedicated header
From: Randy Dunlap @ 2025-12-17 5:24 UTC (permalink / raw)
To: Andrew Morton, Yury Norov (NVIDIA)
Cc: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
Andy Shevchenko, Christophe Leroy, Ingo Molnar, Jani Nikula,
Joonas Lahtinen, David Laight, Petr Pavlu, Andi Shyti,
Rodrigo Vivi, Tvrtko Ursulin, Daniel Gomez, Greg Kroah-Hartman,
Rafael J. Wysocki, Danilo Krummrich, linux-kernel, intel-gfx,
dri-devel, linux-modules, linux-trace-kernel, Kees Cook
In-Reply-To: <20251216161316.45b3f19ff0ad482018137189@linux-foundation.org>
[adding Kees]
On 12/16/25 4:13 PM, Andrew Morton wrote:
> On Fri, 5 Dec 2025 12:52:35 -0500 "Yury Norov (NVIDIA)" <yury.norov@gmail.com> wrote:
>
>> Tracing is a half of the kernel.h in terms of LOCs, although it's
>> a self-consistent part. It is intended for quick debugging purposes
>> and isn't used by the normal tracing utilities.
>>
>> Move it to a separate header. If someone needs to just throw a
>> trace_printk() in their driver, they will not have to pull all
>> the heavy tracing machinery.
>>
>> This is a pure move, except for removing a few 'extern's.
>>
Hm, for a pure move, this shouldn't be necessary. Anyway, not using
FORTIFY in purgatory.o fixes this build error.
Or maybe there's a better answer.
---
arch/x86/purgatory/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/purgatory/Makefile
+++ b/arch/x86/purgatory/Makefile
@@ -62,7 +62,7 @@ PURGATORY_CFLAGS_REMOVE += $(CC_FLAGS_C
endif
CFLAGS_REMOVE_purgatory.o += $(PURGATORY_CFLAGS_REMOVE)
-CFLAGS_purgatory.o += $(PURGATORY_CFLAGS)
+CFLAGS_purgatory.o += $(PURGATORY_CFLAGS) -D__NO_FORTIFY
CFLAGS_REMOVE_sha256.o += $(PURGATORY_CFLAGS_REMOVE)
CFLAGS_sha256.o += $(PURGATORY_CFLAGS)
>
> This one blows up my x86_64 allmodconfig, gcc-15.2.0:
>
> In file included from ./include/linux/string.h:386,
> from ./include/linux/trace_printk.h:9,
> from ./include/linux/kernel.h:34,
> from arch/x86/purgatory/purgatory.c:12:
> ./include/linux/fortify-string.h:626:63: error: expected identifier or '(' before '{' token
> 626 | p_size_field, q_size_field, op) ({ \
> | ^
> ./include/linux/fortify-string.h:694:27: note: in expansion of macro '__fortify_memcpy_chk'
> 694 | #define memmove(p, q, s) __fortify_memcpy_chk(p, q, s, \
> | ^~~~~~~~~~~~~~~~~~~~
> arch/x86/purgatory/../boot/string.h:11:7: note: in expansion of macro 'memmove'
> 11 | void *memmove(void *dst, const void *src, size_t len);
> | ^~~~~~~
> ./include/linux/fortify-string.h:258:9: error: expected identifier or '(' before '__builtin_choose_expr'
> 258 | __builtin_choose_expr(__is_constexpr(__builtin_strlen(p)), \
> | ^~~~~~~~~~~~~~~~~~~~~
> arch/x86/purgatory/../boot/string.h:23:15: note: in expansion of macro 'strlen'
> 23 | extern size_t strlen(const char *s);
> | ^~~~~~
> make[4]: *** [scripts/Makefile.build:287: arch/x86/purgatory/purgatory.o] Error 1
> make[3]: *** [scripts/Makefile.build:556: arch/x86/purgatory] Error 2
> make[2]: *** [scripts/Makefile.build:556: arch/x86] Error 2
> make[1]: *** [/usr/src/25/Makefile:2054: .] Error 2
> make: *** [Makefile:248: __sub-make] Error 2
>
--
~Randy
^ permalink raw reply
* [PATCH v4 0/7] Fix the failure issue of the module_attach test case
From: Chenghao Duan @ 2025-12-17 6:14 UTC (permalink / raw)
To: yangtiezhu, rostedt, mhiramat, mark.rutland, hengqi.chen,
chenhuacai
Cc: kernel, zhangtianyang, masahiroy, linux-kernel, loongarch, bpf,
duanchenghao, youling.tang, jianghaoran, vincent.mc.li,
linux-trace-kernel
v4:
My sincere apologies for the misunderstanding in my interpretation of
Tiezhu's reply in the v2 email thread. After the release of v3, Tiezhu
reminded me again of the importance of splitting the patches, and I am
very grateful for this. Below are the changes made for v4.
Split the patch titled "LoongArch: BPF: Enhance trampoline support for
kernel and module tracing" into the following smaller patches by
functionality to facilitate code reading and review, while ensuring the
code logic and modification locations remain unchanged:
"LoongArch: BPF: Enable and fix trampoline-based tracing for module functions"
"LoongArch: BPF: Save return address register ra to t0 before trampoline"
"LoongArch: BPF: Adjust the jump offset of tail calls"
"LoongArch: BPF: Enhance the bpf_arch_text_poke() function"
--------------------------Changelog------------------------------------
v3:
links: https://lore.kernel.org/all/20251216094753.1317231-1-duanchenghao@kylinos.cn/
1. Adjust the position of fixup_exception() in the patch "LoongArch:
Enable exception fixup for specific ADE": move its invocation to within
the code block wrapped by irqentry_enter()/irqentry_exit().
2. Add the relevant test items to the patch commit log.
3. Adjust the sequence of patches
With the exception of the patch "LoongArch: Enable exception fixup for
specific ADE", no source code changes have been made in the other
patches.
v2:
links: https://lore.kernel.org/all/20251212091103.1247753-1-duanchenghao@kylinos.cn/
Referring to Tiezhu's suggestion, split the v1 patch titled
"LoongArch: Modify the jump logic of the trampoline" into three parts:
(1) ftrace code
(2) sample test
(3) bpf code
The code logic and implementation remain unchanged.
v1:
links: https://lore.kernel.org/all/20251209093405.1309253-1-duanchenghao@kylinos.cn/
The following test cases under the tools/testing/selftests/bpf/
directory have passed the test:
./test_progs -t module_attach
./test_progs -t module_fentry_shadow
./test_progs -t subprogs
./test_progs -t subprogs_extable
./test_progs -t tailcalls
./test_progs -t struct_ops -d struct_ops_multi_pages
./test_progs -t fexit_bpf2bpf
./test_progs -t fexit_stress
./test_progs -t module_fentry_shadow
./test_progs -t fentry_test/fentry
./test_progs -t fexit_test/fexit
./test_progs -t fentry_fexit
./test_progs -t modify_return
./test_progs -t fexit_sleep
./test_progs -t test_overhead
./test_progs -t trampoline_count
Chenghao Duan (7):
LoongArch: ftrace: Refactor register restoration in
ftrace_common_return
LoongArch: Enable exception fixup for specific ADE subcode
LoongArch: BPF: Enable and fix trampoline-based tracing for module
functions
LoongArch: BPF: Save return address register ra to t0 before
trampoline
LoongArch: BPF: Adjust the jump offset of tail calls
LoongArch: BPF: Enhance the bpf_arch_text_poke() function
LoongArch: ftrace: Adjust register stack restore order in direct call
trampolines
arch/loongarch/kernel/mcount_dyn.S | 14 +++++---
arch/loongarch/kernel/traps.c | 9 ++++-
arch/loongarch/net/bpf_jit.c | 38 +++++++++++++++------
samples/ftrace/ftrace-direct-modify.c | 8 ++---
samples/ftrace/ftrace-direct-multi-modify.c | 8 ++---
samples/ftrace/ftrace-direct-multi.c | 4 +--
samples/ftrace/ftrace-direct-too.c | 4 +--
samples/ftrace/ftrace-direct.c | 4 +--
8 files changed, 59 insertions(+), 30 deletions(-)
--
2.25.1
^ permalink raw reply
* [PATCH v4 2/7] LoongArch: Enable exception fixup for specific ADE subcode
From: Chenghao Duan @ 2025-12-17 6:14 UTC (permalink / raw)
To: yangtiezhu, rostedt, mhiramat, mark.rutland, hengqi.chen,
chenhuacai
Cc: kernel, zhangtianyang, masahiroy, linux-kernel, loongarch, bpf,
duanchenghao, youling.tang, jianghaoran, vincent.mc.li,
linux-trace-kernel
In-Reply-To: <20251217061435.802204-1-duanchenghao@kylinos.cn>
This patch allows the LoongArch BPF JIT to handle recoverable memory
access errors generated by BPF_PROBE_MEM* instructions.
When a BPF program performs memory access operations, the instructions
it executes may trigger ADEM exceptions. The kernel’s built-in BPF
exception table mechanism (EX_TYPE_BPF) will generate corresponding
exception fixup entries in the JIT compilation phase; however, the
architecture-specific trap handling function needs to proactively call
the common fixup routine to achieve exception recovery.
do_ade(): fix EX_TYPE_BPF memory access exceptions for BPF programs,
ensure safe execution.
Relevant test cases: illegal address access tests in module_attach and
subprogs_extable of selftests/bpf
Signed-off-by: Chenghao Duan <duanchenghao@kylinos.cn>
---
arch/loongarch/kernel/traps.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c
index 004b8ebf0051..201c9a5532f4 100644
--- a/arch/loongarch/kernel/traps.c
+++ b/arch/loongarch/kernel/traps.c
@@ -534,11 +534,18 @@ asmlinkage void noinstr do_fpe(struct pt_regs *regs, unsigned long fcsr)
asmlinkage void noinstr do_ade(struct pt_regs *regs)
{
- irqentry_state_t state = irqentry_enter(regs);
+ irqentry_state_t state;
+ unsigned int esubcode = FIELD_GET(CSR_ESTAT_ESUBCODE, regs->csr_estat);
+
+ state = irqentry_enter(regs);
+
+ if ((esubcode == EXSUBCODE_ADEM) && fixup_exception(regs))
+ goto out;
die_if_kernel("Kernel ade access", regs);
force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)regs->csr_badvaddr);
+out:
irqentry_exit(regs, state);
}
--
2.25.1
^ permalink raw reply related
* [PATCH v4 1/7] LoongArch: ftrace: Refactor register restoration in ftrace_common_return
From: Chenghao Duan @ 2025-12-17 6:14 UTC (permalink / raw)
To: yangtiezhu, rostedt, mhiramat, mark.rutland, hengqi.chen,
chenhuacai
Cc: kernel, zhangtianyang, masahiroy, linux-kernel, loongarch, bpf,
duanchenghao, youling.tang, jianghaoran, vincent.mc.li,
linux-trace-kernel
In-Reply-To: <20251217061435.802204-1-duanchenghao@kylinos.cn>
Refactor the register restoration sequence in the ftrace_common_return
function to clearly distinguish between the logic of normal returns and
direct call returns in function tracing scenarios. The logic is as
follows:
1. In the case of a normal return, the execution flow returns to the
traced function, and ftrace must ensure that the register data is
consistent with the state when the function was entered.
ra = parent return address; t0 = traced function return address.
2. In the case of a direct call return, the execution flow jumps to the
custom trampoline function, and ftrace must ensure that the register
data is consistent with the state when ftrace was entered.
ra = traced function return address; t0 = parent return address.
Fixes: 9cdc3b6a299c ("LoongArch: ftrace: Add direct call support")
Signed-off-by: Chenghao Duan <duanchenghao@kylinos.cn>
---
arch/loongarch/kernel/mcount_dyn.S | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/arch/loongarch/kernel/mcount_dyn.S b/arch/loongarch/kernel/mcount_dyn.S
index d6b474ad1d5e..5729c20e5b8b 100644
--- a/arch/loongarch/kernel/mcount_dyn.S
+++ b/arch/loongarch/kernel/mcount_dyn.S
@@ -94,7 +94,6 @@ SYM_INNER_LABEL(ftrace_graph_call, SYM_L_GLOBAL)
* at the callsite, so there is no need to restore the T series regs.
*/
ftrace_common_return:
- PTR_L ra, sp, PT_R1
PTR_L a0, sp, PT_R4
PTR_L a1, sp, PT_R5
PTR_L a2, sp, PT_R6
@@ -104,12 +103,17 @@ ftrace_common_return:
PTR_L a6, sp, PT_R10
PTR_L a7, sp, PT_R11
PTR_L fp, sp, PT_R22
- PTR_L t0, sp, PT_ERA
PTR_L t1, sp, PT_R13
- PTR_ADDI sp, sp, PT_SIZE
bnez t1, .Ldirect
+
+ PTR_L ra, sp, PT_R1
+ PTR_L t0, sp, PT_ERA
+ PTR_ADDI sp, sp, PT_SIZE
jr t0
.Ldirect:
+ PTR_L t0, sp, PT_R1
+ PTR_L ra, sp, PT_ERA
+ PTR_ADDI sp, sp, PT_SIZE
jr t1
SYM_CODE_END(ftrace_common)
@@ -161,6 +165,8 @@ SYM_CODE_END(return_to_handler)
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
SYM_CODE_START(ftrace_stub_direct_tramp)
UNWIND_HINT_UNDEFINED
- jr t0
+ move t1, ra
+ move ra, t0
+ jr t1
SYM_CODE_END(ftrace_stub_direct_tramp)
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
--
2.25.1
^ permalink raw reply related
* [PATCH v4 4/7] LoongArch: BPF: Save return address register ra to t0 before trampoline
From: Chenghao Duan @ 2025-12-17 6:14 UTC (permalink / raw)
To: yangtiezhu, rostedt, mhiramat, mark.rutland, hengqi.chen,
chenhuacai
Cc: kernel, zhangtianyang, masahiroy, linux-kernel, loongarch, bpf,
duanchenghao, youling.tang, jianghaoran, vincent.mc.li,
linux-trace-kernel
In-Reply-To: <20251217061435.802204-1-duanchenghao@kylinos.cn>
Modify the build_prologue function to ensure the return address
register ra is saved to t0 before entering trampoline operations.
This change ensures accurate return address handling when a BPF
program calls another BPF program, preventing errors in the
BPF-to-BPF call chain.
Signed-off-by: Chenghao Duan <duanchenghao@kylinos.cn>
---
arch/loongarch/net/bpf_jit.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
index 76cd24646bec..c560d1e14b9d 100644
--- a/arch/loongarch/net/bpf_jit.c
+++ b/arch/loongarch/net/bpf_jit.c
@@ -139,6 +139,7 @@ static void build_prologue(struct jit_ctx *ctx)
stack_adjust = round_up(stack_adjust, 16);
stack_adjust += bpf_stack_adjust;
+ move_reg(ctx, LOONGARCH_GPR_T0, LOONGARCH_GPR_RA);
/* Reserve space for the move_imm + jirl instruction */
for (i = 0; i < LOONGARCH_LONG_JUMP_NINSNS; i++)
emit_insn(ctx, nop);
--
2.25.1
^ permalink raw reply related
* [PATCH v4 3/7] LoongArch: BPF: Enable and fix trampoline-based tracing for module functions
From: Chenghao Duan @ 2025-12-17 6:14 UTC (permalink / raw)
To: yangtiezhu, rostedt, mhiramat, mark.rutland, hengqi.chen,
chenhuacai
Cc: kernel, zhangtianyang, masahiroy, linux-kernel, loongarch, bpf,
duanchenghao, youling.tang, jianghaoran, vincent.mc.li,
linux-trace-kernel
In-Reply-To: <20251217061435.802204-1-duanchenghao@kylinos.cn>
Remove the previous restrictions that blocked the tracing of kernel
module functions. Fix the issue that previously caused kernel lockups
when attempting to trace module functions.
Before entering the trampoline code, the return address register ra
shall store the address of the next assembly instruction after the
'bl trampoline' instruction, which is the traced function address, and
the register t0 shall store the parent function return address. Refine
the trampoline return logic to ensure that register data remains
correct when returning to both the traced function and the parent
function.
Before this patch was applied, the module_attach test in selftests/bpf
encountered a deadlock issue. This was caused by an incorrect jump
address after the trampoline execution, which resulted in an infinite
loop within the module function.
Fixes: 677e6123e3d2 ("LoongArch: BPF: Disable trampoline for kernel module function trace")
Signed-off-by: Chenghao Duan <duanchenghao@kylinos.cn>
---
arch/loongarch/net/bpf_jit.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
index 8dc58781b8eb..76cd24646bec 100644
--- a/arch/loongarch/net/bpf_jit.c
+++ b/arch/loongarch/net/bpf_jit.c
@@ -1265,7 +1265,7 @@ static int emit_jump_or_nops(void *target, void *ip, u32 *insns, bool is_call)
return 0;
}
- return emit_jump_and_link(&ctx, is_call ? LOONGARCH_GPR_T0 : LOONGARCH_GPR_ZERO, (u64)target);
+ return emit_jump_and_link(&ctx, is_call ? LOONGARCH_GPR_RA : LOONGARCH_GPR_ZERO, (u64)target);
}
static int emit_call(struct jit_ctx *ctx, u64 addr)
@@ -1622,14 +1622,12 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
/* To traced function */
/* Ftrace jump skips 2 NOP instructions */
- if (is_kernel_text((unsigned long)orig_call))
+ if (is_kernel_text((unsigned long)orig_call) ||
+ is_module_text_address((unsigned long)orig_call))
orig_call += LOONGARCH_FENTRY_NBYTES;
/* Direct jump skips 5 NOP instructions */
else if (is_bpf_text_address((unsigned long)orig_call))
orig_call += LOONGARCH_BPF_FENTRY_NBYTES;
- /* Module tracing not supported - cause kernel lockups */
- else if (is_module_text_address((unsigned long)orig_call))
- return -ENOTSUPP;
if (flags & BPF_TRAMP_F_CALL_ORIG) {
move_addr(ctx, LOONGARCH_GPR_A0, (const u64)im);
@@ -1722,12 +1720,16 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
emit_insn(ctx, ldd, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, 0);
emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, 16);
- if (flags & BPF_TRAMP_F_SKIP_FRAME)
+ if (flags & BPF_TRAMP_F_SKIP_FRAME) {
/* return to parent function */
- emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_RA, 0);
- else
- /* return to traced function */
+ move_reg(ctx, LOONGARCH_GPR_RA, LOONGARCH_GPR_T0);
emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T0, 0);
+ } else {
+ /* return to traced function */
+ move_reg(ctx, LOONGARCH_GPR_T1, LOONGARCH_GPR_RA);
+ move_reg(ctx, LOONGARCH_GPR_RA, LOONGARCH_GPR_T0);
+ emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T1, 0);
+ }
}
ret = ctx->idx;
--
2.25.1
^ permalink raw reply related
* [PATCH v4 5/7] LoongArch: BPF: Adjust the jump offset of tail calls
From: Chenghao Duan @ 2025-12-17 6:14 UTC (permalink / raw)
To: yangtiezhu, rostedt, mhiramat, mark.rutland, hengqi.chen,
chenhuacai
Cc: kernel, zhangtianyang, masahiroy, linux-kernel, loongarch, bpf,
duanchenghao, youling.tang, jianghaoran, vincent.mc.li,
linux-trace-kernel
In-Reply-To: <20251217061435.802204-1-duanchenghao@kylinos.cn>
Call the next bpf prog and skip the first instruction of TCC
initialization.
A total of 7 instructions are skipped:
'move t0, ra' 1 inst
'move_imm + jirl' 5 inst
'addid REG_TCC, zero, 0' 1 inst
Relevant test cases: the tailcalls test item in selftests/bpf
Signed-off-by: Chenghao Duan <duanchenghao@kylinos.cn>
---
arch/loongarch/net/bpf_jit.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
index c560d1e14b9d..3dbabacc8856 100644
--- a/arch/loongarch/net/bpf_jit.c
+++ b/arch/loongarch/net/bpf_jit.c
@@ -239,7 +239,7 @@ static void __build_epilogue(struct jit_ctx *ctx, bool is_tail_call)
* Call the next bpf prog and skip the first instruction
* of TCC initialization.
*/
- emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T3, 6);
+ emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T3, 7);
}
}
--
2.25.1
^ permalink raw reply related
* [PATCH v4 7/7] LoongArch: ftrace: Adjust register stack restore order in direct call trampolines
From: Chenghao Duan @ 2025-12-17 6:14 UTC (permalink / raw)
To: yangtiezhu, rostedt, mhiramat, mark.rutland, hengqi.chen,
chenhuacai
Cc: kernel, zhangtianyang, masahiroy, linux-kernel, loongarch, bpf,
duanchenghao, youling.tang, jianghaoran, vincent.mc.li,
linux-trace-kernel, Youling Tang
In-Reply-To: <20251217061435.802204-1-duanchenghao@kylinos.cn>
Ensure that in the ftrace direct call logic, the CPU register state
(with ra = parent return address) is restored to the correct state
after the execution of the custom trampoline function and before
returning to the traced function. Additionally, guarantee the
correctness of the jump logic for jr t0 (traced function address).
Reported-by: Youling Tang <tangyouling@kylinos.cn>
Signed-off-by: Chenghao Duan <duanchenghao@kylinos.cn>
Acked-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
samples/ftrace/ftrace-direct-modify.c | 8 ++++----
samples/ftrace/ftrace-direct-multi-modify.c | 8 ++++----
samples/ftrace/ftrace-direct-multi.c | 4 ++--
samples/ftrace/ftrace-direct-too.c | 4 ++--
samples/ftrace/ftrace-direct.c | 4 ++--
5 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/samples/ftrace/ftrace-direct-modify.c b/samples/ftrace/ftrace-direct-modify.c
index da3a9f2091f5..1ba1927b548e 100644
--- a/samples/ftrace/ftrace-direct-modify.c
+++ b/samples/ftrace/ftrace-direct-modify.c
@@ -176,8 +176,8 @@ asm (
" st.d $t0, $sp, 0\n"
" st.d $ra, $sp, 8\n"
" bl my_direct_func1\n"
-" ld.d $t0, $sp, 0\n"
-" ld.d $ra, $sp, 8\n"
+" ld.d $ra, $sp, 0\n"
+" ld.d $t0, $sp, 8\n"
" addi.d $sp, $sp, 16\n"
" jr $t0\n"
" .size my_tramp1, .-my_tramp1\n"
@@ -189,8 +189,8 @@ asm (
" st.d $t0, $sp, 0\n"
" st.d $ra, $sp, 8\n"
" bl my_direct_func2\n"
-" ld.d $t0, $sp, 0\n"
-" ld.d $ra, $sp, 8\n"
+" ld.d $ra, $sp, 0\n"
+" ld.d $t0, $sp, 8\n"
" addi.d $sp, $sp, 16\n"
" jr $t0\n"
" .size my_tramp2, .-my_tramp2\n"
diff --git a/samples/ftrace/ftrace-direct-multi-modify.c b/samples/ftrace/ftrace-direct-multi-modify.c
index 8f7986d698d8..7a7822dfeb50 100644
--- a/samples/ftrace/ftrace-direct-multi-modify.c
+++ b/samples/ftrace/ftrace-direct-multi-modify.c
@@ -199,8 +199,8 @@ asm (
" move $a0, $t0\n"
" bl my_direct_func1\n"
" ld.d $a0, $sp, 0\n"
-" ld.d $t0, $sp, 8\n"
-" ld.d $ra, $sp, 16\n"
+" ld.d $ra, $sp, 8\n"
+" ld.d $t0, $sp, 16\n"
" addi.d $sp, $sp, 32\n"
" jr $t0\n"
" .size my_tramp1, .-my_tramp1\n"
@@ -215,8 +215,8 @@ asm (
" move $a0, $t0\n"
" bl my_direct_func2\n"
" ld.d $a0, $sp, 0\n"
-" ld.d $t0, $sp, 8\n"
-" ld.d $ra, $sp, 16\n"
+" ld.d $ra, $sp, 8\n"
+" ld.d $t0, $sp, 16\n"
" addi.d $sp, $sp, 32\n"
" jr $t0\n"
" .size my_tramp2, .-my_tramp2\n"
diff --git a/samples/ftrace/ftrace-direct-multi.c b/samples/ftrace/ftrace-direct-multi.c
index db326c81a27d..3fe6ddaf0b69 100644
--- a/samples/ftrace/ftrace-direct-multi.c
+++ b/samples/ftrace/ftrace-direct-multi.c
@@ -131,8 +131,8 @@ asm (
" move $a0, $t0\n"
" bl my_direct_func\n"
" ld.d $a0, $sp, 0\n"
-" ld.d $t0, $sp, 8\n"
-" ld.d $ra, $sp, 16\n"
+" ld.d $ra, $sp, 8\n"
+" ld.d $t0, $sp, 16\n"
" addi.d $sp, $sp, 32\n"
" jr $t0\n"
" .size my_tramp, .-my_tramp\n"
diff --git a/samples/ftrace/ftrace-direct-too.c b/samples/ftrace/ftrace-direct-too.c
index 3d0fa260332d..bf2411aa6fd7 100644
--- a/samples/ftrace/ftrace-direct-too.c
+++ b/samples/ftrace/ftrace-direct-too.c
@@ -143,8 +143,8 @@ asm (
" ld.d $a0, $sp, 0\n"
" ld.d $a1, $sp, 8\n"
" ld.d $a2, $sp, 16\n"
-" ld.d $t0, $sp, 24\n"
-" ld.d $ra, $sp, 32\n"
+" ld.d $ra, $sp, 24\n"
+" ld.d $t0, $sp, 32\n"
" addi.d $sp, $sp, 48\n"
" jr $t0\n"
" .size my_tramp, .-my_tramp\n"
diff --git a/samples/ftrace/ftrace-direct.c b/samples/ftrace/ftrace-direct.c
index 956834b0d19a..5368c8c39cbb 100644
--- a/samples/ftrace/ftrace-direct.c
+++ b/samples/ftrace/ftrace-direct.c
@@ -124,8 +124,8 @@ asm (
" st.d $ra, $sp, 16\n"
" bl my_direct_func\n"
" ld.d $a0, $sp, 0\n"
-" ld.d $t0, $sp, 8\n"
-" ld.d $ra, $sp, 16\n"
+" ld.d $ra, $sp, 8\n"
+" ld.d $t0, $sp, 16\n"
" addi.d $sp, $sp, 32\n"
" jr $t0\n"
" .size my_tramp, .-my_tramp\n"
--
2.25.1
^ permalink raw reply related
* [PATCH v4 6/7] LoongArch: BPF: Enhance the bpf_arch_text_poke() function
From: Chenghao Duan @ 2025-12-17 6:14 UTC (permalink / raw)
To: yangtiezhu, rostedt, mhiramat, mark.rutland, hengqi.chen,
chenhuacai
Cc: kernel, zhangtianyang, masahiroy, linux-kernel, loongarch, bpf,
duanchenghao, youling.tang, jianghaoran, vincent.mc.li,
linux-trace-kernel
In-Reply-To: <20251217061435.802204-1-duanchenghao@kylinos.cn>
Enhance the bpf_arch_text_poke() function to enable accurate location
of BPF program entry points.
When modifying the entry point of a BPF program, skip the move t0, ra
instruction to ensure the correct logic and copy of the jump address.
Signed-off-by: Chenghao Duan <duanchenghao@kylinos.cn>
---
arch/loongarch/net/bpf_jit.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
index 3dbabacc8856..0c16a1b18e8f 100644
--- a/arch/loongarch/net/bpf_jit.c
+++ b/arch/loongarch/net/bpf_jit.c
@@ -1290,6 +1290,10 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
void *new_addr)
{
int ret;
+ unsigned long size = 0;
+ unsigned long offset = 0;
+ char namebuf[KSYM_NAME_LEN];
+ void *image = NULL;
bool is_call;
u32 old_insns[LOONGARCH_LONG_JUMP_NINSNS] = {[0 ... 4] = INSN_NOP};
u32 new_insns[LOONGARCH_LONG_JUMP_NINSNS] = {[0 ... 4] = INSN_NOP};
@@ -1297,9 +1301,18 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
/* Only poking bpf text is supported. Since kernel function entry
* is set up by ftrace, we rely on ftrace to poke kernel functions.
*/
- if (!is_bpf_text_address((unsigned long)ip))
+ if (!__bpf_address_lookup((unsigned long)ip, &size, &offset, namebuf))
return -ENOTSUPP;
+ image = ip - offset;
+ /* zero offset means we're poking bpf prog entry */
+ if (offset == 0)
+ /* skip to the nop instruction in bpf prog entry:
+ * move t0, ra
+ * nop
+ */
+ ip = image + LOONGARCH_INSN_SIZE;
+
is_call = old_t == BPF_MOD_CALL;
ret = emit_jump_or_nops(old_addr, ip, old_insns, is_call);
if (ret)
--
2.25.1
^ permalink raw reply related
* Re: [PATCH v4 1/7] LoongArch: ftrace: Refactor register restoration in ftrace_common_return
From: bot+bpf-ci @ 2025-12-17 6:55 UTC (permalink / raw)
To: duanchenghao, yangtiezhu, rostedt, mhiramat, mark.rutland,
hengqi.chen, chenhuacai
Cc: kernel, zhangtianyang, masahiroy, linux-kernel, loongarch, bpf,
duanchenghao, youling.tang, jianghaoran, vincent.mc.li,
linux-trace-kernel, ast, andrii, daniel, martin.lau, eddyz87,
yonghong.song, clm, ihor.solodrai
In-Reply-To: <20251217061435.802204-2-duanchenghao@kylinos.cn>
[-- Attachment #1: Type: text/plain, Size: 3096 bytes --]
> diff --git a/arch/loongarch/kernel/mcount_dyn.S b/arch/loongarch/kernel/mcount_dyn.S
> index d6b474ad1d5e..5729c20e5b8b 100644
> --- a/arch/loongarch/kernel/mcount_dyn.S
> +++ b/arch/loongarch/kernel/mcount_dyn.S
> @@ -94,7 +94,6 @@ SYM_INNER_LABEL(ftrace_graph_call, SYM_L_GLOBAL)
> * at the callsite, so there is no need to restore the T series regs.
> */
> ftrace_common_return:
> - PTR_L ra, sp, PT_R1
> PTR_L a0, sp, PT_R4
> PTR_L a1, sp, PT_R5
> PTR_L a2, sp, PT_R6
> @@ -104,12 +103,17 @@ ftrace_common_return:
> PTR_L a6, sp, PT_R10
> PTR_L a7, sp, PT_R11
> PTR_L fp, sp, PT_R22
> - PTR_L t0, sp, PT_ERA
> PTR_L t1, sp, PT_R13
> - PTR_ADDI sp, sp, PT_SIZE
> bnez t1, .Ldirect
> +
> + PTR_L ra, sp, PT_R1
> + PTR_L t0, sp, PT_ERA
> + PTR_ADDI sp, sp, PT_SIZE
> jr t0
> .Ldirect:
> + PTR_L t0, sp, PT_R1
> + PTR_L ra, sp, PT_ERA
^^^^^^^^^^^^^^^^^^^
Does this break existing ftrace direct trampolines?
Before this change, direct trampolines received:
ra = parent return address (from PT_R1)
t0 = traced function address (from PT_ERA)
After this change, direct trampolines receive:
t0 = parent return address (from PT_R1)
ra = traced function address (from PT_ERA)
The sample trampolines in samples/ftrace/ were written for the old
convention. For example, samples/ftrace/ftrace-direct.c does:
my_tramp:
st.d $t0, $sp, 8 # Save what it thinks is traced func addr
st.d $ra, $sp, 16 # Save what it thinks is parent addr
bl my_direct_func
ld.d $t0, $sp, 8 # Restore
ld.d $ra, $sp, 16 # Restore
jr $t0 # Jump to what it thinks is traced function
With the new convention, the sample would save parent address in the
t0 slot, restore it to t0, and then jump to the parent instead of the
traced function, skipping the traced function entirely.
This was fixed later in commit 055e392f3be7 "LoongArch: ftrace: Adjust
register stack restore order in direct call trampolines" which updated
all the samples to match the new convention. However, any out-of-tree
direct trampolines written before this commit would be broken by this
change.
Was this ABI break intentional? The commit message mentions matching
"the state when ftrace was entered" but doesn't explain why breaking
compatibility was necessary. RISC-V uses the opposite convention
(t0 = traced func, ra = parent), which the original LoongArch code
matched.
> + PTR_ADDI sp, sp, PT_SIZE
> jr t1
> SYM_CODE_END(ftrace_common)
[ ... ]
> @@ -161,6 +165,8 @@ SYM_CODE_END(return_to_handler)
> #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
> SYM_CODE_START(ftrace_stub_direct_tramp)
> UNWIND_HINT_UNDEFINED
> - jr t0
> + move t1, ra
> + move ra, t0
> + jr t1
> SYM_CODE_END(ftrace_stub_direct_tramp)
> #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/20293821855
^ permalink raw reply
* Re: [PATCHv5 bpf-next 1/9] ftrace,bpf: Remove FTRACE_OPS_FL_JMP ftrace_ops flag
From: Jiri Olsa @ 2025-12-17 8:40 UTC (permalink / raw)
To: bot+bpf-ci
Cc: rostedt, revest, mark.rutland, bpf, linux-kernel,
linux-trace-kernel, linux-arm-kernel, ast, daniel, andrii,
menglong8.dong, song, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
In-Reply-To: <95c13c0b793604796037ca67c191e1bfce22770dd020107c7179a698c5d49b91@mail.kernel.org>
On Mon, Dec 15, 2025 at 09:31:51PM +0000, bot+bpf-ci@kernel.org wrote:
> > diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
> > index 015dd1049bea..505b7d3f5641 100644
> > --- a/include/linux/ftrace.h
> > +++ b/include/linux/ftrace.h
>
> [ ... ]
>
> > diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
> > index 976d89011b15..b9a358d7a78f 100644
> > --- a/kernel/bpf/trampoline.c
> > +++ b/kernel/bpf/trampoline.c
> > @@ -214,10 +214,15 @@ static int modify_fentry(struct bpf_trampoline *tr, u32 orig_flags,
> > int ret;
> >
> > if (tr->func.ftrace_managed) {
> > + unsigned long addr = (unsigned long) new_addr;
> > +
> > + if (bpf_trampoline_use_jmp(tr->flags))
> > + addr = ftrace_jmp_set(addr);
> > +
> > if (lock_direct_mutex)
> > - ret = modify_ftrace_direct(tr->fops, (long)new_addr);
> > + ret = modify_ftrace_direct(tr->fops, addr);
> > else
> > - ret = modify_ftrace_direct_nolock(tr->fops, (long)new_addr);
> > + ret = modify_ftrace_direct_nolock(tr->fops, addr);
> > } else {
> > ret = bpf_trampoline_update_fentry(tr, orig_flags, old_addr,
> > new_addr);
> > @@ -240,10 +245,15 @@ static int register_fentry(struct bpf_trampoline *tr, void *new_addr)
> > }
> >
> > if (tr->func.ftrace_managed) {
> > + unsigned long addr = (unsigned long) new_addr;
> > +
> > + if (bpf_trampoline_use_jmp(tr->flags))
> > + addr = ftrace_jmp_set(addr);
> > +
> > ret = ftrace_set_filter_ip(tr->fops, (unsigned long)ip, 0, 1);
> > if (ret)
> > return ret;
> > - ret = register_ftrace_direct(tr->fops, (long)new_addr);
> > + ret = register_ftrace_direct(tr->fops, addr);
> > } else {
> > ret = bpf_trampoline_update_fentry(tr, 0, NULL, new_addr);
> > }
>
> After this change, register_ftrace_direct() receives an address with
> the LSB bit already set (via ftrace_jmp_set) and stores it as-is in
> entry->direct. This address then flows through to ftrace_find_rec_direct()
> which returns entry->direct unchanged.
>
> In available_filter_functions_show():
hum, there's no such function.. AFAICS it's t_show called through
ftrace_avail_fops->ftrace_avail_open->show_ftrace_seq_ops
>
> direct = ftrace_find_rec_direct(rec->ip);
> if (direct)
> seq_printf(m, "\n\tdirect-->%pS", (void *)direct);
>
but yep, it's related problem, that Menglong said he will address in
separate patch
thanks,
jirka
> Can the debug output show misleading symbol offsets? When the LSB is
> set, %pS will resolve addresses like "function+0x1" instead of just
> "function". This makes ftrace debug output harder to read for users
> trying to understand direct call attachments.
>
> The fix would be to strip the LSB bit before printing:
> seq_printf(m, "\n\tdirect-->%pS", (void *)ftrace_jmp_get(direct));
>
> [ ... ]
>
> > diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> > index bbb37c0f8c6c..b0dc911411f1 100644
> > --- a/kernel/trace/ftrace.c
> > +++ b/kernel/trace/ftrace.c
> > @@ -6017,15 +6017,8 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
> > if (ftrace_hash_empty(hash))
> > return -EINVAL;
> >
> > - /* This is a "raw" address, and this should never happen. */
> > - if (WARN_ON_ONCE(ftrace_is_jmp(addr)))
> > - return -EINVAL;
> > -
> > mutex_lock(&direct_mutex);
> >
> > - if (ops->flags & FTRACE_OPS_FL_JMP)
> > - addr = ftrace_jmp_set(addr);
> > -
> > /* Make sure requested entries are not already registered.. */
> > size = 1 << hash->size_bits;
> > for (i = 0; i < size; i++) {
>
> [ ... ]
>
> > @@ -6146,13 +6139,6 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
> >
> > lockdep_assert_held_once(&direct_mutex);
> >
> > - /* This is a "raw" address, and this should never happen. */
> > - if (WARN_ON_ONCE(ftrace_is_jmp(addr)))
> > - return -EINVAL;
> > -
> > - if (ops->flags & FTRACE_OPS_FL_JMP)
> > - addr = ftrace_jmp_set(addr);
> > -
> > /* Enable the tmp_ops to have the same functions as the direct ops */
> > ftrace_ops_init(&tmp_ops);
> > tmp_ops.func_hash = ops->func_hash;
>
> [ ... ]
>
>
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
>
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/20247816064
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox