summaryrefslogtreecommitdiffstats
path: root/arch/sh/tools
diff options
context:
space:
mode:
authorJinke Han <jinkehan@didiglobal.com>2026-09-08 15:37:42 +0800
committerIngo Molnar <mingo@kernel.org>2026-09-17 09:48:42 +0200
commita5f7a5bb3b7f28ba7e4fa246775b29a0e5537255 (patch)
tree73fef824f9a846cf935869d0dbc5070ef6e2f741 /arch/sh/tools
downloadlinux-stable-a5f7a5bb3b7f28ba7e4fa246775b29a0e5537255.tar.gz
linux-stable-a5f7a5bb3b7f28ba7e4fa246775b29a0e5537255.zip
x86/kprobes: Fix crash when probing CS CALL instructionsgrafted
When using eBPF to probe CS CALL instructions within a function, a crash can be triggered. The eBPF tool probes offset 257 of the __hrtimer_run_queues() function: <__hrtimer_run_queues+249>: nopl 0x0(%rax,%rax,1) <__hrtimer_run_queues+254>: mov %r14,%rdi <__hrtimer_run_queues+257>: cs call <__x86_indirect_thunk_r12> <__hrtimer_run_queues+263>: mov %eax,%r12d <__hrtimer_run_queues+266>: xchg %ax,%ax <__hrtimer_run_queues+268>: mov %r13,%rdi Which triggers this crash: BUG: unable to handle page fault for address: 00000000000f41c9 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page PGD 0 P4D 0 Oops: 0002 [#1] SMP NOPTI CPU: 1 PID: 0 Comm: swapper/1 Kdump: loaded Tainted: P RIP: 0010:__hrtimer_run_queues+0x106/0x230 Note that __hrtimer_run_queues+0x106 is __hrtimer_run_queues+262, which is at the 6th byte of the above CS CALL instruction. Since the CS CALL instruction occupies 6 bytes, the exception occurred in the middle of that call instruction. The root cause is that when using eBPF tools to probe in the middle of a function, a kprobe with INT3 is used as the underlying implementation. During single-step emulation of the original CALL instruction, int3_emulate_call() assumes that the probed CALL instruction is 5 bytes long. However, the actual CS-prefixed CALL instruction occupies 6 bytes, so it constructs an incorrect exception return address. When the CPU returns from the kprobe handler, the next instruction to be executed is at the address of the last byte of that CS CALL instruction. Coincidentally, starting from that address, the CPU fetches and decodes a completely different instruction, which ultimately triggers a kernel crash. Fix the issue by using the actual instruction length obtained from the instruction decoder when constructing the exception return address, rather than relying on the hardcoded CALL_INSN_SIZE macro. [ mingo: Refined the changelog ] Fixes: 6256e668b7af ("x86/kprobes: Use int3 instead of debug trap for single-step") Suggested-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Signed-off-by: Jinke Han <jinkehan@didiglobal.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Acked-by: Yafang Shao <laoar.shao@gmail.com> Acked-by: Borislav Petkov <bp@alien8.de> Cc: Peter Zijlstra <peterz@infradead.org> Link: https://patch.msgid.link/20260908073742.GA10517@didi-ThinkCentre-M920t-N000
Diffstat (limited to 'arch/sh/tools')
-rw-r--r--arch/sh/tools/Makefile16
-rw-r--r--arch/sh/tools/gen-mach-types48
-rw-r--r--arch/sh/tools/mach-types67
3 files changed, 131 insertions, 0 deletions
diff --git a/arch/sh/tools/Makefile b/arch/sh/tools/Makefile
new file mode 100644
index 000000000..e5ba31c79
--- /dev/null
+++ b/arch/sh/tools/Makefile
@@ -0,0 +1,16 @@
+#
+# arch/sh/tools/Makefile
+#
+# Copyright (C) 2003 Paul Mundt
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Shamelessly cloned from ARM.
+#
+
+include/generated/machtypes.h: $(src)/gen-mach-types $(src)/mach-types
+ @echo ' Generating $@'
+ $(Q)mkdir -p $(dir $@)
+ $(Q)LC_ALL=C $(AWK) -f $^ > $@
diff --git a/arch/sh/tools/gen-mach-types b/arch/sh/tools/gen-mach-types
new file mode 100644
index 000000000..6d7c2d8ea
--- /dev/null
+++ b/arch/sh/tools/gen-mach-types
@@ -0,0 +1,48 @@
+#!/bin/awk
+# SPDX-License-Identifier: GPL-2.0
+#
+# Awk script to generate include/generated/machtypes.h
+# Heavily based on arch/arm/tools/gen-mach-types
+#
+BEGIN { nr = 0 }
+/^#/ { next }
+/^[ ]*$/ { next }
+
+NF == 2 {
+ mach[nr] = $1;
+ config[nr] = "CONFIG_"$2;
+ nr++;
+ }
+
+END {
+ printf("/*\n");
+ printf(" * Automagically generated, don't touch.\n");
+ printf(" */\n");
+ printf("#ifndef __ASM_SH_MACHTYPES_H\n");
+ printf("#define __ASM_SH_MACHTYPES_H\n");
+ printf("\n");
+ printf("/*\n");
+ printf(" * We'll use the following MACH_xxx defs for placeholders for the time\n");
+ printf(" * being .. these will all go away once sh_machtype is assigned per-board.\n");
+ printf(" *\n");
+ printf(" * For now we leave things the way they are for backwards compatibility.\n");
+ printf(" */\n");
+ printf("\n");
+ printf("/* Mach types */\n");
+
+ for (i = 0; i < nr; i++) {
+ printf("#ifdef %s\n", config[i]);
+ printf(" #define MACH_%s\t\t1\n", mach[i]);
+ printf("#else\n");
+ printf(" #define MACH_%s\t\t0\n", mach[i]);
+ printf("#endif\n");
+ }
+
+ printf("\n");
+ printf("/* Machtype checks */\n");
+ for (i = 0; i < nr; i++)
+ printf("#define mach_is_%s()\t\t\t(MACH_%s)\n",
+ tolower(mach[i]), mach[i]);
+ printf("\n");
+ printf("#endif /* __ASM_SH_MACHTYPES_H */\n");
+ }
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
new file mode 100644
index 000000000..29e648855
--- /dev/null
+++ b/arch/sh/tools/mach-types
@@ -0,0 +1,67 @@
+#
+# MACH_<xxx> CONFIG_<xxx>
+#
+
+#
+# List of board groups.
+#
+SE SH_SOLUTION_ENGINE
+HIGHLANDER SH_HIGHLANDER
+RTS7751R2D SH_RTS7751R2D
+RSK SH_RSK
+ALPHA_BOARD SH_ALPHA_BOARD
+
+#
+# List of companion chips / MFDs.
+#
+HD64461 HD64461
+
+#
+# List of boards.
+#
+7206SE SH_7206_SOLUTION_ENGINE
+7343SE SH_7343_SOLUTION_ENGINE
+7619SE SH_7619_SOLUTION_ENGINE
+7721SE SH_7721_SOLUTION_ENGINE
+7722SE SH_7722_SOLUTION_ENGINE
+7724SE SH_7724_SOLUTION_ENGINE
+7751SE SH_7751_SOLUTION_ENGINE
+7780SE SH_7780_SOLUTION_ENGINE
+HP6XX SH_HP6XX
+DREAMCAST SH_DREAMCAST
+SNAPGEAR SH_SECUREEDGE5410
+EDOSK7705 SH_EDOSK7705
+EDOSK7760 SH_EDOSK7760
+SDK7786 SH_SDK7786
+SH4202_MICRODEV SH_SH4202_MICRODEV
+SH03 SH_SH03
+LANDISK SH_LANDISK
+R7780RP SH_R7780RP
+R7780MP SH_R7780MP
+R7785RP SH_R7785RP
+TITAN SH_TITAN
+SHMIN SH_SHMIN
+LBOXRE2 SH_LBOX_RE2
+X3PROTO SH_X3PROTO
+MAGICPANELR2 SH_MAGIC_PANEL_R2
+R2D_PLUS RTS7751R2D_PLUS
+R2D_1 RTS7751R2D_1
+SDK7780 SH_SDK7780
+MIGOR SH_MIGOR
+RSK7201 SH_RSK7201
+RSK7203 SH_RSK7203
+RSK7264 SH_RSK7264
+RSK7269 SH_RSK7269
+AP325RXA SH_AP325RXA
+SH2007 SH_SH2007
+SH7757LCR SH_SH7757LCR
+SH7763RDP SH_SH7763RDP
+SH7785LCR SH_SH7785LCR
+SH7785LCR_PT SH_SH7785LCR_PT
+URQUELL SH_URQUELL
+ESPT SH_ESPT
+POLARIS SH_POLARIS
+KFR2R09 SH_KFR2R09
+ECOVEC SH_ECOVEC
+APSH4A3A SH_APSH4A3A
+APSH4AD0A SH_APSH4AD0A