From bd81feb8cdbf0d9df27301c8fabbbd538519e8b3 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 10 Mar 2023 17:07:57 +0100 Subject: scripts: Update the CONFIG_* ignore list in headers_install.sh The file in include/uapi/linux/ have been cleaned in the previous patches, so we can now remove these entries from the CONFIG_* ignore-list. Signed-off-by: Thomas Huth Signed-off-by: Arnd Bergmann --- scripts/headers_install.sh | 4 ---- 1 file changed, 4 deletions(-) (limited to 'scripts') diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh index 4041881746ad..36b56b746fce 100755 --- a/scripts/headers_install.sh +++ b/scripts/headers_install.sh @@ -83,10 +83,6 @@ arch/nios2/include/uapi/asm/swab.h:CONFIG_NIOS2_CI_SWAB_SUPPORT arch/x86/include/uapi/asm/auxvec.h:CONFIG_IA32_EMULATION arch/x86/include/uapi/asm/auxvec.h:CONFIG_X86_64 arch/x86/include/uapi/asm/mman.h:CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS -include/uapi/linux/atmdev.h:CONFIG_COMPAT -include/uapi/linux/eventpoll.h:CONFIG_PM_SLEEP -include/uapi/linux/hw_breakpoint.h:CONFIG_HAVE_MIXED_BREAKPOINTS_REGS -include/uapi/linux/pktcdvd.h:CONFIG_CDROM_PKTCDVD_WCACHE " for c in $configs -- cgit From 3ced71d273f8edf07bf01a831a49ca6b988e06b3 Mon Sep 17 00:00:00 2001 From: Kevin Locke Date: Tue, 21 Mar 2023 15:39:22 -0600 Subject: kbuild: deb-pkg: set version for linux-headers paths As a result of the switch to dh_listpackages, $version is no longer set when install_kernel_headers() is called. This causes files in the linux-headers deb package to be installed to a path with an empty $version (e.g. /usr/src/linux-headers-/scripts/sign-file rather than /usr/src/linux-headers-6.3.0-rc3/scripts/sign-file). To avoid this, while continuing to use the version information from dh_listpackages, pass $version from $package as the second argument of install_kernel_headers(). Fixes: 36862e14e316 ("kbuild: deb-pkg: use dh_listpackages to know enabled packages") Signed-off-by: Kevin Locke Signed-off-by: Masahiro Yamada --- scripts/package/builddeb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/package/builddeb b/scripts/package/builddeb index c5ae57167d7c..7b23f52c70c5 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -162,6 +162,7 @@ install_linux_image_dbg () { install_kernel_headers () { pdir=$1 + version=$2 rm -rf $pdir @@ -229,7 +230,7 @@ do linux-libc-dev) install_libc_headers debian/linux-libc-dev;; linux-headers-*) - install_kernel_headers debian/linux-headers;; + install_kernel_headers debian/linux-headers ${package#linux-headers-};; esac done -- cgit From 1073c15fd39e804ad36ff26a7c7d53b0ab51b184 Mon Sep 17 00:00:00 2001 From: Mirsad Goran Todorovac Date: Wed, 22 Mar 2023 09:51:07 +0100 Subject: scripts: merge_config: Fix typo in variable name. ${WARNOVERRIDE} was misspelled as ${WARNOVVERIDE}, which caused a shell syntax error in certain paths of the script execution. Fixes: 46dff8d7e381 ("scripts: merge_config: Add option to suppress warning on overrides") Signed-off-by: Mirsad Goran Todorovac Reviewed-by: Mark Brown Acked-by: Randy Dunlap Signed-off-by: Masahiro Yamada --- scripts/kconfig/merge_config.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 32620de473ad..902eb429b9db 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -145,7 +145,7 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do NEW_VAL=$(grep -w $CFG $MERGE_FILE) BUILTIN_FLAG=false if [ "$BUILTIN" = "true" ] && [ "${NEW_VAL#CONFIG_*=}" = "m" ] && [ "${PREV_VAL#CONFIG_*=}" = "y" ]; then - ${WARNOVVERIDE} Previous value: $PREV_VAL + ${WARNOVERRIDE} Previous value: $PREV_VAL ${WARNOVERRIDE} New value: $NEW_VAL ${WARNOVERRIDE} -y passed, will not demote y to m ${WARNOVERRIDE} -- cgit From fb27e70f6e408dee5d22b083e7a38a59e6118253 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 22 Mar 2023 19:11:45 +0100 Subject: modpost: Fix processing of CRCs on 32-bit build machines modpost now reads CRCs from .*.cmd files, parsing them using strtol(). This is inconsistent with its parsing of Module.symvers and with their definition as *unsigned* 32-bit values. strtol() clamps values to [LONG_MIN, LONG_MAX], and when building on a 32-bit system this changes all CRCs >= 0x80000000 to be 0x7fffffff. Change extract_crcs_for_object() to use strtoul() instead. Cc: stable@vger.kernel.org Fixes: f292d875d0dc ("modpost: extract symbol versions from *.cmd files") Signed-off-by: Ben Hutchings Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index efff8078e395..9466b6a2abae 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1733,7 +1733,7 @@ static void extract_crcs_for_object(const char *object, struct module *mod) if (!isdigit(*p)) continue; /* skip this line */ - crc = strtol(p, &p, 0); + crc = strtoul(p, &p, 0); if (*p != '\n') continue; /* skip this line */ -- cgit From 644a9cf0d2a8340121fa8107a5fa6f27782bb080 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 5 Mar 2023 20:00:35 -0800 Subject: sh: remove sh5/sh64 last fragments A previous patch removed most of the sh5 (sh64) support from the kernel tree. Now remove the last stragglers. Fixes: 37744feebc08 ("sh: remove sh5 support") Signed-off-by: Randy Dunlap Cc: Geert Uytterhoeven Cc: Arnd Bergmann Cc: Rich Felker Cc: Yoshinori Sato Cc: John Paul Adrian Glaubitz Cc: linux-sh@vger.kernel.org Acked-by: John Paul Adrian Glaubitz Reviewed-by: John Paul Adrian Glaubitz Link: https://lore.kernel.org/r/20230306040037.20350-6-rdunlap@infradead.org Signed-off-by: John Paul Adrian Glaubitz --- Documentation/kbuild/kbuild.rst | 1 - Documentation/scheduler/sched-arch.rst | 2 -- Documentation/translations/zh_CN/scheduler/sched-arch.rst | 2 -- scripts/checkstack.pl | 7 ------- tools/perf/arch/common.c | 2 -- tools/scripts/Makefile.arch | 5 ----- tools/testing/selftests/mm/Makefile | 2 +- tools/testing/selftests/mm/run_vmtests.sh | 2 +- 8 files changed, 2 insertions(+), 21 deletions(-) (limited to 'scripts') diff --git a/Documentation/kbuild/kbuild.rst b/Documentation/kbuild/kbuild.rst index 5202186728b4..e22621f4af0b 100644 --- a/Documentation/kbuild/kbuild.rst +++ b/Documentation/kbuild/kbuild.rst @@ -160,7 +160,6 @@ directory name found in the arch/ directory. But some architectures such as x86 and sparc have aliases. - x86: i386 for 32 bit, x86_64 for 64 bit -- sh: sh for 32 bit, sh64 for 64 bit - sparc: sparc32 for 32 bit, sparc64 for 64 bit CROSS_COMPILE diff --git a/Documentation/scheduler/sched-arch.rst b/Documentation/scheduler/sched-arch.rst index 0eaec669790a..505cd27f9a92 100644 --- a/Documentation/scheduler/sched-arch.rst +++ b/Documentation/scheduler/sched-arch.rst @@ -70,7 +70,5 @@ Possible arch problems I found (and either tried to fix or didn't): ia64 - is safe_halt call racy vs interrupts? (does it sleep?) (See #4a) -sh64 - Is sleeping racy vs interrupts? (See #4a) - sparc - IRQs on at this point(?), change local_irq_save to _disable. - TODO: needs secondary CPUs to disable preempt (See #1) diff --git a/Documentation/translations/zh_CN/scheduler/sched-arch.rst b/Documentation/translations/zh_CN/scheduler/sched-arch.rst index 754a15c6b60f..ce3f39d9b3cb 100644 --- a/Documentation/translations/zh_CN/scheduler/sched-arch.rst +++ b/Documentation/translations/zh_CN/scheduler/sched-arch.rst @@ -70,7 +70,5 @@ arch/x86/kernel/process.c有轮询和睡眠空闲函数的例子。 ia64 - safe_halt的调用与中断相比,是否很荒谬? (它睡眠了吗) (参考 #4a) -sh64 - 睡眠与中断相比,是否很荒谬? (参考 #4a) - sparc - 在这一点上,IRQ是开着的(?),把local_irq_save改为_disable。 - 待办事项: 需要第二个CPU来禁用抢占 (参考 #1) diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index d48dfed6d3db..84f5fb7f1cec 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl @@ -10,7 +10,6 @@ # Mips port by Juan Quintela # IA64 port via Andreas Dilger # Arm port by Holger Schurig -# sh64 port by Paul Mundt # Random bits by Matt Mackall # M68k port by Geert Uytterhoeven and Andreas Schwab # AArch64, PARISC ports by Kyle McMartin @@ -100,12 +99,6 @@ my (@stack, $re, $dre, $sub, $x, $xs, $funcre, $min_stack); # 100092: e3 f0 ff c8 ff 71 lay %r15,-56(%r15) $re = qr/.*(?:lay|ag?hi).*\%r15,-(([0-9]{2}|[3-9])[0-9]{2}) (?:\(\%r15\))?$/ox; - } elsif ($arch =~ /^sh64$/) { - #XXX: we only check for the immediate case presently, - # though we will want to check for the movi/sub - # pair for larger users. -- PFM. - #a00048e0: d4fc40f0 addi.l r15,-240,r15 - $re = qr/.*addi\.l.*r15,-(([0-9]{2}|[3-9])[0-9]{2}),r15/o; } elsif ($arch eq 'sparc' || $arch eq 'sparc64') { # f0019d10: 9d e3 bf 90 save %sp, -112, %sp $re = qr/.*save.*%sp, -(([0-9]{2}|[3-9])[0-9]{2}), %sp/o; diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c index 59dd875fd5e4..cfe63dfab03a 100644 --- a/tools/perf/arch/common.c +++ b/tools/perf/arch/common.c @@ -51,9 +51,7 @@ const char *const s390_triplets[] = { const char *const sh_triplets[] = { "sh-unknown-linux-gnu-", - "sh64-unknown-linux-gnu-", "sh-linux-gnu-", - "sh64-linux-gnu-", NULL }; diff --git a/tools/scripts/Makefile.arch b/tools/scripts/Makefile.arch index 1c72d07cb9fe..f6a50f06dfc4 100644 --- a/tools/scripts/Makefile.arch +++ b/tools/scripts/Makefile.arch @@ -29,11 +29,6 @@ ifeq ($(ARCH),sparc64) SRCARCH := sparc endif -# Additional ARCH settings for sh -ifeq ($(ARCH),sh64) - SRCARCH := sh -endif - # Additional ARCH settings for loongarch ifeq ($(ARCH),loongarch32) SRCARCH := loongarch diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile index c31d952cff68..fc35050b5542 100644 --- a/tools/testing/selftests/mm/Makefile +++ b/tools/testing/selftests/mm/Makefile @@ -90,7 +90,7 @@ endif endif -ifneq (,$(filter $(MACHINE),arm64 ia64 mips64 parisc64 ppc64 riscv64 s390x sh64 sparc64 x86_64)) +ifneq (,$(filter $(MACHINE),arm64 ia64 mips64 parisc64 ppc64 riscv64 s390x sparc64 x86_64)) TEST_GEN_FILES += va_128TBswitch TEST_GEN_FILES += virtual_address_range TEST_GEN_FILES += write_to_hugetlbfs diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh index 8984e0bb58c7..a9d6d52596f2 100644 --- a/tools/testing/selftests/mm/run_vmtests.sh +++ b/tools/testing/selftests/mm/run_vmtests.sh @@ -132,7 +132,7 @@ else fi # filter 64bit architectures -ARCH64STR="arm64 ia64 mips64 parisc64 ppc64 ppc64le riscv64 s390x sh64 sparc64 x86_64" +ARCH64STR="arm64 ia64 mips64 parisc64 ppc64 ppc64le riscv64 s390x sparc64 x86_64" if [ -z "$ARCH" ]; then ARCH=$(uname -m 2>/dev/null | sed -e 's/aarch64.*/arm64/') fi -- cgit From fb799447ae2974a07907906dff5bd4b9e47b7123 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Wed, 1 Mar 2023 07:13:12 -0800 Subject: x86,objtool: Split UNWIND_HINT_EMPTY in two Mark reported that the ORC unwinder incorrectly marks an unwind as reliable when the unwind terminates prematurely in the dark corners of return_to_handler() due to lack of information about the next frame. The problem is UNWIND_HINT_EMPTY is used in two different situations: 1) The end of the kernel stack unwind before hitting user entry, boot code, or fork entry 2) A blind spot in ORC coverage where the unwinder has to bail due to lack of information about the next frame The ORC unwinder has no way to tell the difference between the two. When it encounters an undefined stack state with 'end=1', it blindly marks the stack reliable, which can break the livepatch consistency model. Fix it by splitting UNWIND_HINT_EMPTY into UNWIND_HINT_UNDEFINED and UNWIND_HINT_END_OF_STACK. Reported-by: Mark Rutland Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Acked-by: Steven Rostedt (Google) Acked-by: Peter Zijlstra (Intel) Link: https://lore.kernel.org/r/fd6212c8b450d3564b855e1cb48404d6277b4d9f.1677683419.git.jpoimboe@kernel.org --- Documentation/livepatch/reliable-stacktrace.rst | 2 +- arch/x86/entry/entry_64.S | 12 +++++------ arch/x86/include/asm/orc_types.h | 14 ++++++------- arch/x86/include/asm/unwind_hints.h | 12 +++++++---- arch/x86/kernel/ftrace_64.S | 2 +- arch/x86/kernel/head_64.S | 12 +++++------ arch/x86/kernel/relocate_kernel_64.S | 10 ++++----- arch/x86/kernel/unwind_orc.c | 15 ++++++-------- arch/x86/lib/retpoline.S | 6 +++--- arch/x86/platform/pvh/head.S | 2 +- arch/x86/xen/xen-asm.S | 4 ++-- arch/x86/xen/xen-head.S | 4 ++-- include/linux/objtool.h | 10 ++++----- include/linux/objtool_types.h | 27 ++++++++++++++++--------- scripts/sorttable.h | 2 +- tools/arch/x86/include/asm/orc_types.h | 14 ++++++------- tools/include/linux/objtool_types.h | 27 ++++++++++++++++--------- tools/objtool/check.c | 2 +- tools/objtool/orc_dump.c | 8 ++++++-- tools/objtool/orc_gen.c | 26 ++++++++++++------------ 20 files changed, 116 insertions(+), 95 deletions(-) (limited to 'scripts') diff --git a/Documentation/livepatch/reliable-stacktrace.rst b/Documentation/livepatch/reliable-stacktrace.rst index 67459d2ca2af..d56bb706172f 100644 --- a/Documentation/livepatch/reliable-stacktrace.rst +++ b/Documentation/livepatch/reliable-stacktrace.rst @@ -183,7 +183,7 @@ trampoline or return trampoline. For example, considering the x86_64 .. code-block:: none SYM_CODE_START(return_to_handler) - UNWIND_HINT_EMPTY + UNWIND_HINT_UNDEFINED subq $24, %rsp /* Save the return values */ diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 5b93eb7db0ab..45e135be2a9f 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -205,7 +205,7 @@ syscall_return_via_sysret: */ movq %rsp, %rdi movq PER_CPU_VAR(cpu_tss_rw + TSS_sp0), %rsp - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK pushq RSP-RDI(%rdi) /* RSP */ pushq (%rdi) /* RDI */ @@ -286,7 +286,7 @@ SYM_FUNC_END(__switch_to_asm) .pushsection .text, "ax" __FUNC_ALIGN SYM_CODE_START_NOALIGN(ret_from_fork) - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK ANNOTATE_NOENDBR // copy_thread CALL_DEPTH_ACCOUNT movq %rax, %rdi @@ -303,7 +303,7 @@ SYM_CODE_START_NOALIGN(ret_from_fork) 1: /* kernel thread */ - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK movq %r12, %rdi CALL_NOSPEC rbx /* @@ -643,7 +643,7 @@ SYM_INNER_LABEL(swapgs_restore_regs_and_return_to_usermode, SYM_L_GLOBAL) */ movq %rsp, %rdi movq PER_CPU_VAR(cpu_tss_rw + TSS_sp0), %rsp - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK /* Copy the IRET frame to the trampoline stack. */ pushq 6*8(%rdi) /* SS */ @@ -869,7 +869,7 @@ SYM_CODE_END(exc_xen_hypervisor_callback) */ __FUNC_ALIGN SYM_CODE_START_NOALIGN(xen_failsafe_callback) - UNWIND_HINT_EMPTY + UNWIND_HINT_UNDEFINED ENDBR movl %ds, %ecx cmpw %cx, 0x10(%rsp) @@ -1520,7 +1520,7 @@ SYM_CODE_END(asm_exc_nmi) * MSRs to fully disable 32-bit SYSCALL. */ SYM_CODE_START(ignore_sysret) - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK ENDBR mov $-ENOSYS, %eax sysretl diff --git a/arch/x86/include/asm/orc_types.h b/arch/x86/include/asm/orc_types.h index b4d4ec78589e..46d7e06763c9 100644 --- a/arch/x86/include/asm/orc_types.h +++ b/arch/x86/include/asm/orc_types.h @@ -39,9 +39,11 @@ #define ORC_REG_SP_INDIRECT 9 #define ORC_REG_MAX 15 -#define ORC_TYPE_CALL 0 -#define ORC_TYPE_REGS 1 -#define ORC_TYPE_REGS_PARTIAL 2 +#define ORC_TYPE_UNDEFINED 0 +#define ORC_TYPE_END_OF_STACK 1 +#define ORC_TYPE_CALL 2 +#define ORC_TYPE_REGS 3 +#define ORC_TYPE_REGS_PARTIAL 4 #ifndef __ASSEMBLY__ #include @@ -60,16 +62,14 @@ struct orc_entry { #if defined(__LITTLE_ENDIAN_BITFIELD) unsigned sp_reg:4; unsigned bp_reg:4; - unsigned type:2; + unsigned type:3; unsigned signal:1; - unsigned end:1; #elif defined(__BIG_ENDIAN_BITFIELD) unsigned bp_reg:4; unsigned sp_reg:4; unsigned unused:4; - unsigned end:1; unsigned signal:1; - unsigned type:2; + unsigned type:3; #endif } __packed; diff --git a/arch/x86/include/asm/unwind_hints.h b/arch/x86/include/asm/unwind_hints.h index 4c0f28d665eb..01cb9692b160 100644 --- a/arch/x86/include/asm/unwind_hints.h +++ b/arch/x86/include/asm/unwind_hints.h @@ -7,13 +7,17 @@ #ifdef __ASSEMBLY__ -.macro UNWIND_HINT_EMPTY - UNWIND_HINT type=UNWIND_HINT_TYPE_CALL end=1 +.macro UNWIND_HINT_END_OF_STACK + UNWIND_HINT type=UNWIND_HINT_TYPE_END_OF_STACK +.endm + +.macro UNWIND_HINT_UNDEFINED + UNWIND_HINT type=UNWIND_HINT_TYPE_UNDEFINED .endm .macro UNWIND_HINT_ENTRY VALIDATE_UNRET_BEGIN - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK .endm .macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0 signal=1 @@ -73,7 +77,7 @@ #else #define UNWIND_HINT_FUNC \ - UNWIND_HINT(UNWIND_HINT_TYPE_FUNC, ORC_REG_SP, 8, 0, 0) + UNWIND_HINT(UNWIND_HINT_TYPE_FUNC, ORC_REG_SP, 8, 0) #endif /* __ASSEMBLY__ */ diff --git a/arch/x86/kernel/ftrace_64.S b/arch/x86/kernel/ftrace_64.S index 1265ad519249..0387732e9c3f 100644 --- a/arch/x86/kernel/ftrace_64.S +++ b/arch/x86/kernel/ftrace_64.S @@ -340,7 +340,7 @@ STACK_FRAME_NON_STANDARD_FP(__fentry__) #ifdef CONFIG_FUNCTION_GRAPH_TRACER SYM_CODE_START(return_to_handler) - UNWIND_HINT_EMPTY + UNWIND_HINT_UNDEFINED ANNOTATE_NOENDBR subq $16, %rsp diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index ee3ed15ee1f8..8d8d25c64827 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -42,7 +42,7 @@ L3_START_KERNEL = pud_index(__START_KERNEL_map) __HEAD .code64 SYM_CODE_START_NOALIGN(startup_64) - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK /* * At this point the CPU runs in 64bit mode CS.L = 1 CS.D = 0, * and someone has loaded an identity mapped page table @@ -105,7 +105,7 @@ SYM_CODE_START_NOALIGN(startup_64) lretq .Lon_kernel_cs: - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK /* Sanitize CPU configuration */ call verify_cpu @@ -127,7 +127,7 @@ SYM_CODE_START_NOALIGN(startup_64) SYM_CODE_END(startup_64) SYM_CODE_START(secondary_startup_64) - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK ANNOTATE_NOENDBR /* * At this point the CPU runs in 64bit mode CS.L = 1 CS.D = 0, @@ -156,7 +156,7 @@ SYM_CODE_START(secondary_startup_64) * verify_cpu() above to make sure NX is enabled. */ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL) - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK ANNOTATE_NOENDBR /* @@ -238,7 +238,7 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL) ANNOTATE_RETPOLINE_SAFE jmp *%rax 1: - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK ANNOTATE_NOENDBR // above /* @@ -371,7 +371,7 @@ SYM_CODE_END(secondary_startup_64) */ SYM_CODE_START(start_cpu0) ANNOTATE_NOENDBR - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK movq initial_stack(%rip), %rsp jmp .Ljump_to_C_code SYM_CODE_END(start_cpu0) diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S index 4a73351f87f8..56cab1bb25f5 100644 --- a/arch/x86/kernel/relocate_kernel_64.S +++ b/arch/x86/kernel/relocate_kernel_64.S @@ -43,7 +43,7 @@ .code64 SYM_CODE_START_NOALIGN(relocate_range) SYM_CODE_START_NOALIGN(relocate_kernel) - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK ANNOTATE_NOENDBR /* * %rdi indirection_page @@ -113,7 +113,7 @@ SYM_CODE_START_NOALIGN(relocate_kernel) SYM_CODE_END(relocate_kernel) SYM_CODE_START_LOCAL_NOALIGN(identity_mapped) - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK /* set return address to 0 if not preserving context */ pushq $0 /* store the start address on the stack */ @@ -231,7 +231,7 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_mapped) SYM_CODE_END(identity_mapped) SYM_CODE_START_LOCAL_NOALIGN(virtual_mapped) - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK ANNOTATE_NOENDBR // RET target, above movq RSP(%r8), %rsp movq CR4(%r8), %rax @@ -256,8 +256,8 @@ SYM_CODE_END(virtual_mapped) /* Do the copies */ SYM_CODE_START_LOCAL_NOALIGN(swap_pages) - UNWIND_HINT_EMPTY - movq %rdi, %rcx /* Put the page_list in %rcx */ + UNWIND_HINT_END_OF_STACK + movq %rdi, %rcx /* Put the page_list in %rcx */ xorl %edi, %edi xorl %esi, %esi jmp 1f diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c index 8348ac581de3..3ac50b7298d1 100644 --- a/arch/x86/kernel/unwind_orc.c +++ b/arch/x86/kernel/unwind_orc.c @@ -158,7 +158,6 @@ static struct orc_entry orc_fp_entry = { .sp_offset = 16, .bp_reg = ORC_REG_PREV_SP, .bp_offset = -16, - .end = 0, }; static struct orc_entry *orc_find(unsigned long ip) @@ -250,13 +249,13 @@ static int orc_sort_cmp(const void *_a, const void *_b) return -1; /* - * The "weak" section terminator entries need to always be on the left + * The "weak" section terminator entries need to always be first * to ensure the lookup code skips them in favor of real entries. * These terminator entries exist to handle any gaps created by * whitelisted .o files which didn't get objtool generation. */ orc_a = cur_orc_table + (a - cur_orc_ip_table); - return orc_a->sp_reg == ORC_REG_UNDEFINED && !orc_a->end ? -1 : 1; + return orc_a->type == ORC_TYPE_UNDEFINED ? -1 : 1; } void unwind_module_init(struct module *mod, void *_orc_ip, size_t orc_ip_size, @@ -474,14 +473,12 @@ bool unwind_next_frame(struct unwind_state *state) */ orc = &orc_fp_entry; state->error = true; - } - - /* End-of-stack check for kernel threads: */ - if (orc->sp_reg == ORC_REG_UNDEFINED) { - if (!orc->end) + } else { + if (orc->type == ORC_TYPE_UNDEFINED) goto err; - goto the_end; + if (orc->type == ORC_TYPE_END_OF_STACK) + goto the_end; } state->signal = orc->signal; diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S index 5f61c65322be..27ef53fab6bd 100644 --- a/arch/x86/lib/retpoline.S +++ b/arch/x86/lib/retpoline.S @@ -33,7 +33,7 @@ .align RETPOLINE_THUNK_SIZE SYM_INNER_LABEL(__x86_indirect_thunk_\reg, SYM_L_GLOBAL) - UNWIND_HINT_EMPTY + UNWIND_HINT_UNDEFINED ANNOTATE_NOENDBR ALTERNATIVE_2 __stringify(RETPOLINE \reg), \ @@ -75,7 +75,7 @@ SYM_CODE_END(__x86_indirect_thunk_array) .align RETPOLINE_THUNK_SIZE SYM_INNER_LABEL(__x86_indirect_call_thunk_\reg, SYM_L_GLOBAL) - UNWIND_HINT_EMPTY + UNWIND_HINT_UNDEFINED ANNOTATE_NOENDBR CALL_DEPTH_ACCOUNT @@ -103,7 +103,7 @@ SYM_CODE_END(__x86_indirect_call_thunk_array) .align RETPOLINE_THUNK_SIZE SYM_INNER_LABEL(__x86_indirect_jump_thunk_\reg, SYM_L_GLOBAL) - UNWIND_HINT_EMPTY + UNWIND_HINT_UNDEFINED ANNOTATE_NOENDBR POLINE \reg ANNOTATE_UNRET_SAFE diff --git a/arch/x86/platform/pvh/head.S b/arch/x86/platform/pvh/head.S index 7fe564eaf228..c4365a05ab83 100644 --- a/arch/x86/platform/pvh/head.S +++ b/arch/x86/platform/pvh/head.S @@ -50,7 +50,7 @@ #define PVH_DS_SEL (PVH_GDT_ENTRY_DS * 8) SYM_CODE_START_LOCAL(pvh_start_xen) - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK cld lgdt (_pa(gdt)) diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S index 4a184f6e4e4d..08f1ceb9eb81 100644 --- a/arch/x86/xen/xen-asm.S +++ b/arch/x86/xen/xen-asm.S @@ -165,7 +165,7 @@ xen_pv_trap asm_exc_xen_hypervisor_callback SYM_CODE_START(xen_early_idt_handler_array) i = 0 .rept NUM_EXCEPTION_VECTORS - UNWIND_HINT_EMPTY + UNWIND_HINT_UNDEFINED ENDBR pop %rcx pop %r11 @@ -193,7 +193,7 @@ hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32 * rsp->rax } */ SYM_CODE_START(xen_iret) - UNWIND_HINT_EMPTY + UNWIND_HINT_UNDEFINED ANNOTATE_NOENDBR pushq $0 jmp hypercall_iret diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S index e36ea4268bd2..6eafdd17c242 100644 --- a/arch/x86/xen/xen-head.S +++ b/arch/x86/xen/xen-head.S @@ -45,7 +45,7 @@ SYM_CODE_END(hypercall_page) #ifdef CONFIG_XEN_PV __INIT SYM_CODE_START(startup_xen) - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK ANNOTATE_NOENDBR cld @@ -71,7 +71,7 @@ SYM_CODE_END(startup_xen) #ifdef CONFIG_XEN_PV_SMP .pushsection .text SYM_CODE_START(asm_cpu_bringup_and_idle) - UNWIND_HINT_EMPTY + UNWIND_HINT_END_OF_STACK ENDBR call cpu_bringup_and_idle diff --git a/include/linux/objtool.h b/include/linux/objtool.h index 5aa475118820..03f82c2c2ebf 100644 --- a/include/linux/objtool.h +++ b/include/linux/objtool.h @@ -10,7 +10,7 @@ #ifndef __ASSEMBLY__ -#define UNWIND_HINT(type, sp_reg, sp_offset, signal, end) \ +#define UNWIND_HINT(type, sp_reg, sp_offset, signal) \ "987: \n\t" \ ".pushsection .discard.unwind_hints\n\t" \ /* struct unwind_hint */ \ @@ -19,7 +19,6 @@ ".byte " __stringify(sp_reg) "\n\t" \ ".byte " __stringify(type) "\n\t" \ ".byte " __stringify(signal) "\n\t" \ - ".byte " __stringify(end) "\n\t" \ ".balign 4 \n\t" \ ".popsection\n\t" @@ -91,7 +90,7 @@ * the debuginfo as necessary. It will also warn if it sees any * inconsistencies. */ -.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 end=0 +.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 .Lhere_\@: .pushsection .discard.unwind_hints /* struct unwind_hint */ @@ -100,7 +99,6 @@ .byte \sp_reg .byte \type .byte \signal - .byte \end .balign 4 .popsection .endm @@ -153,14 +151,14 @@ #ifndef __ASSEMBLY__ -#define UNWIND_HINT(type, sp_reg, sp_offset, signal, end) "\n\t" +#define UNWIND_HINT(type, sp_reg, sp_offset, signal) "\n\t" #define STACK_FRAME_NON_STANDARD(func) #define STACK_FRAME_NON_STANDARD_FP(func) #define ANNOTATE_NOENDBR #define ASM_REACHABLE #else #define ANNOTATE_INTRA_FUNCTION_CALL -.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 end=0 +.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 .endm .macro STACK_FRAME_NON_STANDARD func:req .endm diff --git a/include/linux/objtool_types.h b/include/linux/objtool_types.h index 9787ad0f2ef4..453a4f4ef39d 100644 --- a/include/linux/objtool_types.h +++ b/include/linux/objtool_types.h @@ -16,12 +16,18 @@ struct unwind_hint { u8 sp_reg; u8 type; u8 signal; - u8 end; }; #endif /* __ASSEMBLY__ */ /* + * UNWIND_HINT_TYPE_UNDEFINED: A blind spot in ORC coverage which can result in + * a truncated and unreliable stack unwind. + * + * UNWIND_HINT_TYPE_END_OF_STACK: The end of the kernel stack unwind before + * hitting user entry, boot code, or fork entry (when there are no pt_regs + * available). + * * UNWIND_HINT_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP * (the caller's SP right before it made the call). Used for all callable * functions, i.e. all C code and all callable asm functions. @@ -32,17 +38,20 @@ struct unwind_hint { * UNWIND_HINT_TYPE_REGS_PARTIAL: Used in entry code to indicate that * sp_reg+sp_offset points to the iret return frame. * - * UNWIND_HINT_FUNC: Generate the unwind metadata of a callable function. + * UNWIND_HINT_TYPE_FUNC: Generate the unwind metadata of a callable function. * Useful for code which doesn't have an ELF function annotation. * - * UNWIND_HINT_ENTRY: machine entry without stack, SYSCALL/SYSENTER etc. + * UNWIND_HINT_TYPE_{SAVE,RESTORE}: Save the unwind metadata at a certain + * location so that it can be restored later. */ -#define UNWIND_HINT_TYPE_CALL 0 -#define UNWIND_HINT_TYPE_REGS 1 -#define UNWIND_HINT_TYPE_REGS_PARTIAL 2 +#define UNWIND_HINT_TYPE_UNDEFINED 0 +#define UNWIND_HINT_TYPE_END_OF_STACK 1 +#define UNWIND_HINT_TYPE_CALL 2 +#define UNWIND_HINT_TYPE_REGS 3 +#define UNWIND_HINT_TYPE_REGS_PARTIAL 4 /* The below hint types don't have corresponding ORC types */ -#define UNWIND_HINT_TYPE_FUNC 3 -#define UNWIND_HINT_TYPE_SAVE 4 -#define UNWIND_HINT_TYPE_RESTORE 5 +#define UNWIND_HINT_TYPE_FUNC 5 +#define UNWIND_HINT_TYPE_SAVE 6 +#define UNWIND_HINT_TYPE_RESTORE 7 #endif /* _LINUX_OBJTOOL_TYPES_H */ diff --git a/scripts/sorttable.h b/scripts/sorttable.h index deb7c1d3e979..7bd0184380d3 100644 --- a/scripts/sorttable.h +++ b/scripts/sorttable.h @@ -128,7 +128,7 @@ static int orc_sort_cmp(const void *_a, const void *_b) * whitelisted .o files which didn't get objtool generation. */ orc_a = g_orc_table + (a - g_orc_ip_table); - return orc_a->sp_reg == ORC_REG_UNDEFINED && !orc_a->end ? -1 : 1; + return orc_a->type == ORC_TYPE_UNDEFINED ? -1 : 1; } static void *sort_orctable(void *arg) diff --git a/tools/arch/x86/include/asm/orc_types.h b/tools/arch/x86/include/asm/orc_types.h index b4d4ec78589e..46d7e06763c9 100644 --- a/tools/arch/x86/include/asm/orc_types.h +++ b/tools/arch/x86/include/asm/orc_types.h @@ -39,9 +39,11 @@ #define ORC_REG_SP_INDIRECT 9 #define ORC_REG_MAX 15 -#define ORC_TYPE_CALL 0 -#define ORC_TYPE_REGS 1 -#define ORC_TYPE_REGS_PARTIAL 2 +#define ORC_TYPE_UNDEFINED 0 +#define ORC_TYPE_END_OF_STACK 1 +#define ORC_TYPE_CALL 2 +#define ORC_TYPE_REGS 3 +#define ORC_TYPE_REGS_PARTIAL 4 #ifndef __ASSEMBLY__ #include @@ -60,16 +62,14 @@ struct orc_entry { #if defined(__LITTLE_ENDIAN_BITFIELD) unsigned sp_reg:4; unsigned bp_reg:4; - unsigned type:2; + unsigned type:3; unsigned signal:1; - unsigned end:1; #elif defined(__BIG_ENDIAN_BITFIELD) unsigned bp_reg:4; unsigned sp_reg:4; unsigned unused:4; - unsigned end:1; unsigned signal:1; - unsigned type:2; + unsigned type:3; #endif } __packed; diff --git a/tools/include/linux/objtool_types.h b/tools/include/linux/objtool_types.h index 9787ad0f2ef4..453a4f4ef39d 100644 --- a/tools/include/linux/objtool_types.h +++ b/tools/include/linux/objtool_types.h @@ -16,12 +16,18 @@ struct unwind_hint { u8 sp_reg; u8 type; u8 signal; - u8 end; }; #endif /* __ASSEMBLY__ */ /* + * UNWIND_HINT_TYPE_UNDEFINED: A blind spot in ORC coverage which can result in + * a truncated and unreliable stack unwind. + * + * UNWIND_HINT_TYPE_END_OF_STACK: The end of the kernel stack unwind before + * hitting user entry, boot code, or fork entry (when there are no pt_regs + * available). + * * UNWIND_HINT_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP * (the caller's SP right before it made the call). Used for all callable * functions, i.e. all C code and all callable asm functions. @@ -32,17 +38,20 @@ struct unwind_hint { * UNWIND_HINT_TYPE_REGS_PARTIAL: Used in entry code to indicate that * sp_reg+sp_offset points to the iret return frame. * - * UNWIND_HINT_FUNC: Generate the unwind metadata of a callable function. + * UNWIND_HINT_TYPE_FUNC: Generate the unwind metadata of a callable function. * Useful for code which doesn't have an ELF function annotation. * - * UNWIND_HINT_ENTRY: machine entry without stack, SYSCALL/SYSENTER etc. + * UNWIND_HINT_TYPE_{SAVE,RESTORE}: Save the unwind metadata at a certain + * location so that it can be restored later. */ -#define UNWIND_HINT_TYPE_CALL 0 -#define UNWIND_HINT_TYPE_REGS 1 -#define UNWIND_HINT_TYPE_REGS_PARTIAL 2 +#define UNWIND_HINT_TYPE_UNDEFINED 0 +#define UNWIND_HINT_TYPE_END_OF_STACK 1 +#define UNWIND_HINT_TYPE_CALL 2 +#define UNWIND_HINT_TYPE_REGS 3 +#define UNWIND_HINT_TYPE_REGS_PARTIAL 4 /* The below hint types don't have corresponding ORC types */ -#define UNWIND_HINT_TYPE_FUNC 3 -#define UNWIND_HINT_TYPE_SAVE 4 -#define UNWIND_HINT_TYPE_RESTORE 5 +#define UNWIND_HINT_TYPE_FUNC 5 +#define UNWIND_HINT_TYPE_SAVE 6 +#define UNWIND_HINT_TYPE_RESTORE 7 #endif /* _LINUX_OBJTOOL_TYPES_H */ diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 10be80b3fe67..cae6ac6ff246 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2243,6 +2243,7 @@ static void set_func_state(struct cfi_state *state) memcpy(&state->regs, &initial_func_cfi.regs, CFI_NUM_REGS * sizeof(struct cfi_reg)); state->stack_size = initial_func_cfi.cfa.offset; + state->type = UNWIND_HINT_TYPE_CALL; } static int read_unwind_hints(struct objtool_file *file) @@ -2327,7 +2328,6 @@ static int read_unwind_hints(struct objtool_file *file) cfi.cfa.offset = bswap_if_needed(file->elf, hint->sp_offset); cfi.type = hint->type; cfi.signal = hint->signal; - cfi.end = hint->end; insn->cfi = cfi_hash_find_or_add(&cfi); } diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c index 97ecbb8b9034..0e183bb1c720 100644 --- a/tools/objtool/orc_dump.c +++ b/tools/objtool/orc_dump.c @@ -38,6 +38,10 @@ static const char *reg_name(unsigned int reg) static const char *orc_type_name(unsigned int type) { switch (type) { + case ORC_TYPE_UNDEFINED: + return "(und)"; + case ORC_TYPE_END_OF_STACK: + return "end"; case ORC_TYPE_CALL: return "call"; case ORC_TYPE_REGS: @@ -201,6 +205,7 @@ int orc_dump(const char *_objname) printf("%llx:", (unsigned long long)(orc_ip_addr + (i * sizeof(int)) + orc_ip[i])); } + printf("type:%s", orc_type_name(orc[i].type)); printf(" sp:"); @@ -210,8 +215,7 @@ int orc_dump(const char *_objname) print_reg(orc[i].bp_reg, bswap_if_needed(&dummy_elf, orc[i].bp_offset)); - printf(" type:%s signal:%d end:%d\n", - orc_type_name(orc[i].type), orc[i].signal, orc[i].end); + printf(" signal:%d\n", orc[i].signal); } elf_end(elf); diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c index e85bbb996f6c..b327f9ccfe73 100644 --- a/tools/objtool/orc_gen.c +++ b/tools/objtool/orc_gen.c @@ -21,12 +21,22 @@ static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, memset(orc, 0, sizeof(*orc)); if (!cfi) { - orc->end = 0; - orc->sp_reg = ORC_REG_UNDEFINED; + /* + * This is usually either unreachable nops/traps (which don't + * trigger unreachable instruction warnings), or + * STACK_FRAME_NON_STANDARD functions. + */ + orc->type = ORC_TYPE_UNDEFINED; return 0; } switch (cfi->type) { + case UNWIND_HINT_TYPE_UNDEFINED: + orc->type = ORC_TYPE_UNDEFINED; + return 0; + case UNWIND_HINT_TYPE_END_OF_STACK: + orc->type = ORC_TYPE_END_OF_STACK; + return 0; case UNWIND_HINT_TYPE_CALL: orc->type = ORC_TYPE_CALL; break; @@ -42,14 +52,8 @@ static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, return -1; } - orc->end = cfi->end; orc->signal = cfi->signal; - if (cfi->cfa.base == CFI_UNDEFINED) { - orc->sp_reg = ORC_REG_UNDEFINED; - return 0; - } - switch (cfi->cfa.base) { case CFI_SP: orc->sp_reg = ORC_REG_SP; @@ -163,11 +167,7 @@ int orc_create(struct objtool_file *file) struct orc_list_entry *entry; struct list_head orc_list; - struct orc_entry null = { - .sp_reg = ORC_REG_UNDEFINED, - .bp_reg = ORC_REG_UNDEFINED, - .type = ORC_TYPE_CALL, - }; + struct orc_entry null = { .type = ORC_TYPE_UNDEFINED }; /* Build a deduplicated list of ORC entries: */ INIT_LIST_HEAD(&orc_list); -- cgit From a3eebcb61ffb9a26ca77a00ce80050cff0f0ecf3 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 20 Mar 2023 00:52:46 +0000 Subject: dts: add riscv include prefix link The Allwinner D1/D1s SoCs (with a RISC-V core) use an (almost?) identical die as their R528/T113-s siblings with ARM Cortex-A7 cores. To allow sharing the basic SoC .dtsi files across those two architectures as well, introduce a symlink to the RISC-V DT directory. Signed-off-by: Andre Przywara Reviewed-by: Conor Dooley Acked-by: Palmer Dabbelt Link: https://lore.kernel.org/r/20230320005249.13403-2-andre.przywara@arm.com Signed-off-by: Jernej Skrabec --- scripts/dtc/include-prefixes/riscv | 1 + 1 file changed, 1 insertion(+) create mode 120000 scripts/dtc/include-prefixes/riscv (limited to 'scripts') diff --git a/scripts/dtc/include-prefixes/riscv b/scripts/dtc/include-prefixes/riscv new file mode 120000 index 000000000000..202509418938 --- /dev/null +++ b/scripts/dtc/include-prefixes/riscv @@ -0,0 +1 @@ +../../../arch/riscv/boot/dts \ No newline at end of file -- cgit From e5ab9eff46b04c5a04778e40d7092fed3fda52ca Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 23 Mar 2023 21:55:30 +0100 Subject: atomics: Provide atomic_add_negative() variants atomic_add_negative() does not provide the relaxed/acquire/release variants. Provide them in preparation for a new scalable reference count algorithm. Signed-off-by: Thomas Gleixner Signed-off-by: Peter Zijlstra (Intel) Acked-by: Mark Rutland Link: https://lore.kernel.org/r/20230323102800.101763813@linutronix.de --- include/linux/atomic/atomic-arch-fallback.h | 208 ++++++++++++++++++++++++++-- include/linux/atomic/atomic-instrumented.h | 68 ++++++++- include/linux/atomic/atomic-long.h | 38 ++++- scripts/atomic/atomics.tbl | 2 +- scripts/atomic/fallbacks/add_negative | 11 +- 5 files changed, 309 insertions(+), 18 deletions(-) (limited to 'scripts') diff --git a/include/linux/atomic/atomic-arch-fallback.h b/include/linux/atomic/atomic-arch-fallback.h index 77bc5522e61c..4226379a232d 100644 --- a/include/linux/atomic/atomic-arch-fallback.h +++ b/include/linux/atomic/atomic-arch-fallback.h @@ -1208,15 +1208,21 @@ arch_atomic_inc_and_test(atomic_t *v) #define arch_atomic_inc_and_test arch_atomic_inc_and_test #endif +#ifndef arch_atomic_add_negative_relaxed +#ifdef arch_atomic_add_negative +#define arch_atomic_add_negative_acquire arch_atomic_add_negative +#define arch_atomic_add_negative_release arch_atomic_add_negative +#define arch_atomic_add_negative_relaxed arch_atomic_add_negative +#endif /* arch_atomic_add_negative */ + #ifndef arch_atomic_add_negative /** - * arch_atomic_add_negative - add and test if negative + * arch_atomic_add_negative - Add and test if negative * @i: integer value to add * @v: pointer of type atomic_t * - * Atomically adds @i to @v and returns true - * if the result is negative, or false when - * result is greater than or equal to zero. + * Atomically adds @i to @v and returns true if the result is negative, + * or false when the result is greater than or equal to zero. */ static __always_inline bool arch_atomic_add_negative(int i, atomic_t *v) @@ -1226,6 +1232,95 @@ arch_atomic_add_negative(int i, atomic_t *v) #define arch_atomic_add_negative arch_atomic_add_negative #endif +#ifndef arch_atomic_add_negative_acquire +/** + * arch_atomic_add_negative_acquire - Add and test if negative + * @i: integer value to add + * @v: pointer of type atomic_t + * + * Atomically adds @i to @v and returns true if the result is negative, + * or false when the result is greater than or equal to zero. + */ +static __always_inline bool +arch_atomic_add_negative_acquire(int i, atomic_t *v) +{ + return arch_atomic_add_return_acquire(i, v) < 0; +} +#define arch_atomic_add_negative_acquire arch_atomic_add_negative_acquire +#endif + +#ifndef arch_atomic_add_negative_release +/** + * arch_atomic_add_negative_release - Add and test if negative + * @i: integer value to add + * @v: pointer of type atomic_t + * + * Atomically adds @i to @v and returns true if the result is negative, + * or false when the result is greater than or equal to zero. + */ +static __always_inline bool +arch_atomic_add_negative_release(int i, atomic_t *v) +{ + return arch_atomic_add_return_release(i, v) < 0; +} +#define arch_atomic_add_negative_release arch_atomic_add_negative_release +#endif + +#ifndef arch_atomic_add_negative_relaxed +/** + * arch_atomic_add_negative_relaxed - Add and test if negative + * @i: integer value to add + * @v: pointer of type atomic_t + * + * Atomically adds @i to @v and returns true if the result is negative, + * or false when the result is greater than or equal to zero. + */ +static __always_inline bool +arch_atomic_add_negative_relaxed(int i, atomic_t *v) +{ + return arch_atomic_add_return_relaxed(i, v) < 0; +} +#define arch_atomic_add_negative_relaxed arch_atomic_add_negative_relaxed +#endif + +#else /* arch_atomic_add_negative_relaxed */ + +#ifndef arch_atomic_add_negative_acquire +static __always_inline bool +arch_atomic_add_negative_acquire(int i, atomic_t *v) +{ + bool ret = arch_atomic_add_negative_relaxed(i, v); + __atomic_acquire_fence(); + return ret; +} +#define arch_atomic_add_negative_acquire arch_atomic_add_negative_acquire +#endif + +#ifndef arch_atomic_add_negative_release +static __always_inline bool +arch_atomic_add_negative_release(int i, atomic_t *v) +{ + __atomic_release_fence(); + return arch_atomic_add_negative_relaxed(i, v); +} +#define arch_atomic_add_negative_release arch_atomic_add_negative_release +#endif + +#ifndef arch_atomic_add_negative +static __always_inline bool +arch_atomic_add_negative(int i, atomic_t *v) +{ + bool ret; + __atomic_pre_full_fence(); + ret = arch_atomic_add_negative_relaxed(i, v); + __atomic_post_full_fence(); + return ret; +} +#define arch_atomic_add_negative arch_atomic_add_negative +#endif + +#endif /* arch_atomic_add_negative_relaxed */ + #ifndef arch_atomic_fetch_add_unless /** * arch_atomic_fetch_add_unless - add unless the number is already a given value @@ -2329,15 +2424,21 @@ arch_atomic64_inc_and_test(atomic64_t *v) #define arch_atomic64_inc_and_test arch_atomic64_inc_and_test #endif +#ifndef arch_atomic64_add_negative_relaxed +#ifdef arch_atomic64_add_negative +#define arch_atomic64_add_negative_acquire arch_atomic64_add_negative +#define arch_atomic64_add_negative_release arch_atomic64_add_negative +#define arch_atomic64_add_negative_relaxed arch_atomic64_add_negative +#endif /* arch_atomic64_add_negative */ + #ifndef arch_atomic64_add_negative /** - * arch_atomic64_add_negative - add and test if negative + * arch_atomic64_add_negative - Add and test if negative * @i: integer value to add * @v: pointer of type atomic64_t * - * Atomically adds @i to @v and returns true - * if the result is negative, or false when - * result is greater than or equal to zero. + * Atomically adds @i to @v and returns true if the result is negative, + * or false when the result is greater than or equal to zero. */ static __always_inline bool arch_atomic64_add_negative(s64 i, atomic64_t *v) @@ -2347,6 +2448,95 @@ arch_atomic64_add_negative(s64 i, atomic64_t *v) #define arch_atomic64_add_negative arch_atomic64_add_negative #endif +#ifndef arch_atomic64_add_negative_acquire +/** + * arch_atomic64_add_negative_acquire - Add and test if negative + * @i: integer value to add + * @v: pointer of type atomic64_t + * + * Atomically adds @i to @v and returns true if the result is negative, + * or false when the result is greater than or equal to zero. + */ +static __always_inline bool +arch_atomic64_add_negative_acquire(s64 i, atomic64_t *v) +{ + return arch_atomic64_add_return_acquire(i, v) < 0; +} +#define arch_atomic64_add_negative_acquire arch_atomic64_add_negative_acquire +#endif + +#ifndef arch_atomic64_add_negative_release +/** + * arch_atomic64_add_negative_release - Add and test if negative + * @i: integer value to add + * @v: pointer of type atomic64_t + * + * Atomically adds @i to @v and returns true if the result is negative, + * or false when the result is greater than or equal to zero. + */ +static __always_inline bool +arch_atomic64_add_negative_release(s64 i, atomic64_t *v) +{ + return arch_atomic64_add_return_release(i, v) < 0; +} +#define arch_atomic64_add_negative_release arch_atomic64_add_negative_release +#endif + +#ifndef arch_atomic64_add_negative_relaxed +/** + * arch_atomic64_add_negative_relaxed - Add and test if negative + * @i: integer value to add + * @v: pointer of type atomic64_t + * + * Atomically adds @i to @v and returns true if the result is negative, + * or false when the result is greater than or equal to zero. + */ +static __always_inline bool +arch_atomic64_add_negative_relaxed(s64 i, atomic64_t *v) +{ + return arch_atomic64_add_return_relaxed(i, v) < 0; +} +#define arch_atomic64_add_negative_relaxed arch_atomic64_add_negative_relaxed +#endif + +#else /* arch_atomic64_add_negative_relaxed */ + +#ifndef arch_atomic64_add_negative_acquire +static __always_inline bool +arch_atomic64_add_negative_acquire(s64 i, atomic64_t *v) +{ + bool ret = arch_atomic64_add_negative_relaxed(i, v); + __atomic_acquire_fence(); + return ret; +} +#define arch_atomic64_add_negative_acquire arch_atomic64_add_negative_acquire +#endif + +#ifndef arch_atomic64_add_negative_release +static __always_inline bool +arch_atomic64_add_negative_release(s64 i, atomic64_t *v) +{ + __atomic_release_fence(); + return arch_atomic64_add_negative_relaxed(i, v); +} +#define arch_atomic64_add_negative_release arch_atomic64_add_negative_release +#endif + +#ifndef arch_atomic64_add_negative +static __always_inline bool +arch_atomic64_add_negative(s64 i, atomic64_t *v) +{ + bool ret; + __atomic_pre_full_fence(); + ret = arch_atomic64_add_negative_relaxed(i, v); + __atomic_post_full_fence(); + return ret; +} +#define arch_atomic64_add_negative arch_atomic64_add_negative +#endif + +#endif /* arch_atomic64_add_negative_relaxed */ + #ifndef arch_atomic64_fetch_add_unless /** * arch_atomic64_fetch_add_unless - add unless the number is already a given value @@ -2456,4 +2646,4 @@ arch_atomic64_dec_if_positive(atomic64_t *v) #endif #endif /* _LINUX_ATOMIC_FALLBACK_H */ -// b5e87bdd5ede61470c29f7a7e4de781af3770f09 +// 00071fffa021cec66f6290d706d69c91df87bade diff --git a/include/linux/atomic/atomic-instrumented.h b/include/linux/atomic/atomic-instrumented.h index 7a139ec030b0..0496816738ca 100644 --- a/include/linux/atomic/atomic-instrumented.h +++ b/include/linux/atomic/atomic-instrumented.h @@ -592,6 +592,28 @@ atomic_add_negative(int i, atomic_t *v) return arch_atomic_add_negative(i, v); } +static __always_inline bool +atomic_add_negative_acquire(int i, atomic_t *v) +{ + instrument_atomic_read_write(v, sizeof(*v)); + return arch_atomic_add_negative_acquire(i, v); +} + +static __always_inline bool +atomic_add_negative_release(int i, atomic_t *v) +{ + kcsan_release(); + instrument_atomic_read_write(v, sizeof(*v)); + return arch_atomic_add_negative_release(i, v); +} + +static __always_inline bool +atomic_add_negative_relaxed(int i, atomic_t *v) +{ + instrument_atomic_read_write(v, sizeof(*v)); + return arch_atomic_add_negative_relaxed(i, v); +} + static __always_inline int atomic_fetch_add_unless(atomic_t *v, int a, int u) { @@ -1211,6 +1233,28 @@ atomic64_add_negative(s64 i, atomic64_t *v) return arch_atomic64_add_negative(i, v); } +static __always_inline bool +atomic64_add_negative_acquire(s64 i, atomic64_t *v) +{ + instrument_atomic_read_write(v, sizeof(*v)); + return arch_atomic64_add_negative_acquire(i, v); +} + +static __always_inline bool +atomic64_add_negative_release(s64 i, atomic64_t *v) +{ + kcsan_release(); + instrument_atomic_read_write(v, sizeof(*v)); + return arch_atomic64_add_negative_release(i, v); +} + +static __always_inline bool +atomic64_add_negative_relaxed(s64 i, atomic64_t *v) +{ + instrument_atomic_read_write(v, sizeof(*v)); + return arch_atomic64_add_negative_relaxed(i, v); +} + static __always_inline s64 atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u) { @@ -1830,6 +1874,28 @@ atomic_long_add_negative(long i, atomic_long_t *v) return arch_atomic_long_add_negative(i, v); } +static __always_inline bool +atomic_long_add_negative_acquire(long i, atomic_long_t *v) +{ + instrument_atomic_read_write(v, sizeof(*v)); + return arch_atomic_long_add_negative_acquire(i, v); +} + +static __always_inline bool +atomic_long_add_negative_release(long i, atomic_long_t *v) +{ + kcsan_release(); + instrument_atomic_read_write(v, sizeof(*v)); + return arch_atomic_long_add_negative_release(i, v); +} + +static __always_inline bool +atomic_long_add_negative_relaxed(long i, atomic_long_t *v) +{ + instrument_atomic_read_write(v, sizeof(*v)); + return arch_atomic_long_add_negative_relaxed(i, v); +} + static __always_inline long atomic_long_fetch_add_unless(atomic_long_t *v, long a, long u) { @@ -2083,4 +2149,4 @@ atomic_long_dec_if_positive(atomic_long_t *v) }) #endif /* _LINUX_ATOMIC_INSTRUMENTED_H */ -// 764f741eb77a7ad565dc8d99ce2837d5542e8aee +// 1b485de9cbaa4900de59e14ee2084357eaeb1c3a diff --git a/include/linux/atomic/atomic-long.h b/include/linux/atomic/atomic-long.h index 800b8c35992d..2fc51ba66beb 100644 --- a/include/linux/atomic/atomic-long.h +++ b/include/linux/atomic/atomic-long.h @@ -479,6 +479,24 @@ arch_atomic_long_add_negative(long i, atomic_long_t *v) return arch_atomic64_add_negative(i, v); } +static __always_inline bool +arch_atomic_long_add_negative_acquire(long i, atomic_long_t *v) +{ + return arch_atomic64_add_negative_acquire(i, v); +} + +static __always_inline bool +arch_atomic_long_add_negative_release(long i, atomic_long_t *v) +{ + return arch_atomic64_add_negative_release(i, v); +} + +static __always_inline bool +arch_atomic_long_add_negative_relaxed(long i, atomic_long_t *v) +{ + return arch_atomic64_add_negative_relaxed(i, v); +} + static __always_inline long arch_atomic_long_fetch_add_unless(atomic_long_t *v, long a, long u) { @@ -973,6 +991,24 @@ arch_atomic_long_add_negative(long i, atomic_long_t *v) return arch_atomic_add_negative(i, v); } +static __always_inline bool +arch_atomic_long_add_negative_acquire(long i, atomic_long_t *v) +{ + return arch_atomic_add_negative_acquire(i, v); +} + +static __always_inline bool +arch_atomic_long_add_negative_release(long i, atomic_long_t *v) +{ + return arch_atomic_add_negative_release(i, v); +} + +static __always_inline bool +arch_atomic_long_add_negative_relaxed(long i, atomic_long_t *v) +{ + return arch_atomic_add_negative_relaxed(i, v); +} + static __always_inline long arch_atomic_long_fetch_add_unless(atomic_long_t *v, long a, long u) { @@ -1011,4 +1047,4 @@ arch_atomic_long_dec_if_positive(atomic_long_t *v) #endif /* CONFIG_64BIT */ #endif /* _LINUX_ATOMIC_LONG_H */ -// e8f0e08ff072b74d180eabe2ad001282b38c2c88 +// a194c07d7d2f4b0e178d3c118c919775d5d65f50 diff --git a/scripts/atomic/atomics.tbl b/scripts/atomic/atomics.tbl index fbee2f6190d9..85ca8d9b5c27 100644 --- a/scripts/atomic/atomics.tbl +++ b/scripts/atomic/atomics.tbl @@ -33,7 +33,7 @@ try_cmpxchg B v p:old i:new sub_and_test b i v dec_and_test b v inc_and_test b v -add_negative b i v +add_negative B i v add_unless fb v i:a i:u inc_not_zero b v inc_unless_negative b v diff --git a/scripts/atomic/fallbacks/add_negative b/scripts/atomic/fallbacks/add_negative index 15caa2eb2371..e5980abf5904 100755 --- a/scripts/atomic/fallbacks/add_negative +++ b/scripts/atomic/fallbacks/add_negative @@ -1,16 +1,15 @@ cat < Date: Mon, 13 Mar 2023 18:56:30 +0530 Subject: cdx: add the cdx bus driver Introduce AMD CDX bus, which provides a mechanism for scanning and probing CDX devices. These devices are memory mapped on system bus for Application Processors(APUs). CDX devices can be changed dynamically in the Fabric and CDX bus interacts with CDX controller to rescan the bus and rediscover the devices. Signed-off-by: Nipun Gupta Reviewed-by: Pieter Jansen van Vuuren Tested-by: Nikhil Agarwal Link: https://lore.kernel.org/r/20230313132636.31850-2-nipun.gupta@amd.com Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-bus-cdx | 12 + MAINTAINERS | 7 + drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/cdx/Kconfig | 17 ++ drivers/cdx/Makefile | 8 + drivers/cdx/cdx.c | 408 ++++++++++++++++++++++++++++++++ drivers/cdx/cdx.h | 62 +++++ include/linux/cdx/cdx_bus.h | 147 ++++++++++++ include/linux/mod_devicetable.h | 15 ++ scripts/mod/devicetable-offsets.c | 4 + scripts/mod/file2alias.c | 12 + 12 files changed, 695 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-cdx create mode 100644 drivers/cdx/Kconfig create mode 100644 drivers/cdx/Makefile create mode 100644 drivers/cdx/cdx.c create mode 100644 drivers/cdx/cdx.h create mode 100644 include/linux/cdx/cdx_bus.h (limited to 'scripts') diff --git a/Documentation/ABI/testing/sysfs-bus-cdx b/Documentation/ABI/testing/sysfs-bus-cdx new file mode 100644 index 000000000000..43b4e161f226 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-cdx @@ -0,0 +1,12 @@ +What: /sys/bus/cdx/rescan +Date: March 2023 +Contact: nipun.gupta@amd.com +Description: + Writing y/1/on to this file will cause rescan of the bus + and devices on the CDX bus. Any new devices are scanned and + added to the list of Linux devices and any devices removed are + also deleted from Linux. + + For example:: + + # echo 1 > /sys/bus/cdx/rescan diff --git a/MAINTAINERS b/MAINTAINERS index 619c30ec36dc..973cfbd3e3e0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -964,6 +964,13 @@ Q: https://patchwork.kernel.org/project/linux-rdma/list/ F: drivers/infiniband/hw/efa/ F: include/uapi/rdma/efa-abi.h +AMD CDX BUS DRIVER +M: Nipun Gupta +M: Nikhil Agarwal +S: Maintained +F: drivers/cdx/* +F: include/linux/cdx/* + AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER M: Tom Lendacky M: John Allen diff --git a/drivers/Kconfig b/drivers/Kconfig index 968bd0a6fd78..514ae6b24cb2 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -241,4 +241,6 @@ source "drivers/peci/Kconfig" source "drivers/hte/Kconfig" +source "drivers/cdx/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 20b118dca999..7241d80a7b29 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -194,3 +194,4 @@ obj-$(CONFIG_MOST) += most/ obj-$(CONFIG_PECI) += peci/ obj-$(CONFIG_HTE) += hte/ obj-$(CONFIG_DRM_ACCEL) += accel/ +obj-$(CONFIG_CDX_BUS) += cdx/ diff --git a/drivers/cdx/Kconfig b/drivers/cdx/Kconfig new file mode 100644 index 000000000000..1aaee0ec5bd9 --- /dev/null +++ b/drivers/cdx/Kconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# CDX bus configuration +# +# Copyright (C) 2022-2023, Advanced Micro Devices, Inc. +# + +config CDX_BUS + bool "CDX Bus driver" + depends on OF && ARM64 + help + Driver to enable Composable DMA Transfer(CDX) Bus. CDX bus + exposes Fabric devices which uses composable DMA IP to the + APU. CDX bus provides a mechanism for scanning and probing + of CDX devices. CDX devices are memory mapped on system bus + for embedded CPUs. CDX bus uses CDX controller and firmware + to scan these CDX devices. diff --git a/drivers/cdx/Makefile b/drivers/cdx/Makefile new file mode 100644 index 000000000000..c5feb11fc718 --- /dev/null +++ b/drivers/cdx/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for CDX +# +# Copyright (C) 2022-2023, Advanced Micro Devices, Inc. +# + +obj-$(CONFIG_CDX_BUS) += cdx.o diff --git a/drivers/cdx/cdx.c b/drivers/cdx/cdx.c new file mode 100644 index 000000000000..6b162bbb9b25 --- /dev/null +++ b/drivers/cdx/cdx.c @@ -0,0 +1,408 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * CDX bus driver. + * + * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. + */ + +/* + * Architecture Overview + * ===================== + * CDX is a Hardware Architecture designed for AMD FPGA devices. It + * consists of sophisticated mechanism for interaction between FPGA, + * Firmware and the APUs (Application CPUs). + * + * Firmware resides on RPU (Realtime CPUs) which interacts with + * the FPGA program manager and the APUs. The RPU provides memory-mapped + * interface (RPU if) which is used to communicate with APUs. + * + * The diagram below shows an overview of the CDX architecture: + * + * +--------------------------------------+ + * | Application CPUs (APU) | + * | | + * | CDX device drivers| + * | Linux OS | | + * | CDX bus | + * | | | + * | CDX controller | + * | | | + * +-----------------------------|--------+ + * | (discover, config, + * | reset, rescan) + * | + * +------------------------| RPU if |----+ + * | | | + * | V | + * | Realtime CPUs (RPU) | + * | | + * +--------------------------------------+ + * | + * +---------------------|----------------+ + * | FPGA | | + * | +-----------------------+ | + * | | | | | + * | +-------+ +-------+ +-------+ | + * | | dev 1 | | dev 2 | | dev 3 | | + * | +-------+ +-------+ +-------+ | + * +--------------------------------------+ + * + * The RPU firmware extracts the device information from the loaded FPGA + * image and implements a mechanism that allows the APU drivers to + * enumerate such devices (device personality and resource details) via + * a dedicated communication channel. RPU mediates operations such as + * discover, reset and rescan of the FPGA devices for the APU. This is + * done using memory mapped interface provided by the RPU to APU. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "cdx.h" + +/* Default DMA mask for devices on a CDX bus */ +#define CDX_DEFAULT_DMA_MASK (~0ULL) +#define MAX_CDX_CONTROLLERS 16 + +/* CDX controllers registered with the CDX bus */ +static DEFINE_XARRAY_ALLOC(cdx_controllers); + +/** + * cdx_unregister_device - Unregister a CDX device + * @dev: CDX device + * @data: This is always passed as NULL, and is not used in this API, + * but is required here as the bus_for_each_dev() API expects + * the passed function (cdx_unregister_device) to have this + * as an argument. + * + * Return: 0 on success. + */ +static int cdx_unregister_device(struct device *dev, + void *data) +{ + struct cdx_device *cdx_dev = to_cdx_device(dev); + + kfree(cdx_dev->driver_override); + cdx_dev->driver_override = NULL; + /* + * Do not free cdx_dev here as it would be freed in + * cdx_device_release() called from within put_device(). + */ + device_del(&cdx_dev->dev); + put_device(&cdx_dev->dev); + + return 0; +} + +static void cdx_unregister_devices(struct bus_type *bus) +{ + /* Reset all the devices attached to cdx bus */ + bus_for_each_dev(bus, NULL, NULL, cdx_unregister_device); +} + +/** + * cdx_match_one_device - Tell if a CDX device structure has a matching + * CDX device id structure + * @id: single CDX device id structure to match + * @dev: the CDX device structure to match against + * + * Return: matching cdx_device_id structure or NULL if there is no match. + */ +static inline const struct cdx_device_id * +cdx_match_one_device(const struct cdx_device_id *id, + const struct cdx_device *dev) +{ + /* Use vendor ID and device ID for matching */ + if ((id->vendor == CDX_ANY_ID || id->vendor == dev->vendor) && + (id->device == CDX_ANY_ID || id->device == dev->device)) + return id; + return NULL; +} + +/** + * cdx_match_id - See if a CDX device matches a given cdx_id table + * @ids: array of CDX device ID structures to search in + * @dev: the CDX device structure to match against. + * + * Used by a driver to check whether a CDX device is in its list of + * supported devices. Returns the matching cdx_device_id structure or + * NULL if there is no match. + * + * Return: matching cdx_device_id structure or NULL if there is no match. + */ +static inline const struct cdx_device_id * +cdx_match_id(const struct cdx_device_id *ids, struct cdx_device *dev) +{ + if (ids) { + while (ids->vendor || ids->device) { + if (cdx_match_one_device(ids, dev)) + return ids; + ids++; + } + } + return NULL; +} + +/** + * cdx_bus_match - device to driver matching callback + * @dev: the cdx device to match against + * @drv: the device driver to search for matching cdx device + * structures + * + * Return: true on success, false otherwise. + */ +static int cdx_bus_match(struct device *dev, struct device_driver *drv) +{ + struct cdx_device *cdx_dev = to_cdx_device(dev); + struct cdx_driver *cdx_drv = to_cdx_driver(drv); + const struct cdx_device_id *found_id = NULL; + const struct cdx_device_id *ids; + + ids = cdx_drv->match_id_table; + + /* When driver_override is set, only bind to the matching driver */ + if (cdx_dev->driver_override && strcmp(cdx_dev->driver_override, drv->name)) + return false; + + found_id = cdx_match_id(ids, cdx_dev); + if (!found_id) + return false; + + do { + /* + * In case override_only was set, enforce driver_override + * matching. + */ + if (!found_id->override_only) + return true; + if (cdx_dev->driver_override) + return true; + + ids = found_id + 1; + found_id = cdx_match_id(ids, cdx_dev); + } while (found_id); + + return false; +} + +static int cdx_probe(struct device *dev) +{ + struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver); + struct cdx_device *cdx_dev = to_cdx_device(dev); + int error; + + error = cdx_drv->probe(cdx_dev); + if (error) { + dev_err_probe(dev, error, "%s failed\n", __func__); + return error; + } + + return 0; +} + +static void cdx_remove(struct device *dev) +{ + struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver); + struct cdx_device *cdx_dev = to_cdx_device(dev); + + if (cdx_drv && cdx_drv->remove) + cdx_drv->remove(cdx_dev); +} + +static void cdx_shutdown(struct device *dev) +{ + struct cdx_driver *cdx_drv = to_cdx_driver(dev->driver); + struct cdx_device *cdx_dev = to_cdx_device(dev); + + if (cdx_drv && cdx_drv->shutdown) + cdx_drv->shutdown(cdx_dev); +} + +static int cdx_dma_configure(struct device *dev) +{ + struct cdx_device *cdx_dev = to_cdx_device(dev); + u32 input_id = cdx_dev->req_id; + int ret; + + ret = of_dma_configure_id(dev, dev->parent->of_node, 0, &input_id); + if (ret && ret != -EPROBE_DEFER) { + dev_err(dev, "of_dma_configure_id() failed\n"); + return ret; + } + + return 0; +} + +static ssize_t rescan_store(struct bus_type *bus, + const char *buf, size_t count) +{ + struct cdx_controller *cdx; + unsigned long index; + bool val; + + if (kstrtobool(buf, &val) < 0) + return -EINVAL; + + if (!val) + return -EINVAL; + + /* Unregister all the devices on the bus */ + cdx_unregister_devices(&cdx_bus_type); + + /* Rescan all the devices */ + xa_for_each(&cdx_controllers, index, cdx) { + int ret; + + ret = cdx->ops->scan(cdx); + if (ret) + dev_err(cdx->dev, "cdx bus scanning failed\n"); + } + + return count; +} +static BUS_ATTR_WO(rescan); + +static struct attribute *cdx_bus_attrs[] = { + &bus_attr_rescan.attr, + NULL, +}; +ATTRIBUTE_GROUPS(cdx_bus); + +struct bus_type cdx_bus_type = { + .name = "cdx", + .match = cdx_bus_match, + .probe = cdx_probe, + .remove = cdx_remove, + .shutdown = cdx_shutdown, + .dma_configure = cdx_dma_configure, + .bus_groups = cdx_bus_groups, +}; +EXPORT_SYMBOL_GPL(cdx_bus_type); + +int __cdx_driver_register(struct cdx_driver *cdx_driver, + struct module *owner) +{ + int error; + + cdx_driver->driver.owner = owner; + cdx_driver->driver.bus = &cdx_bus_type; + + error = driver_register(&cdx_driver->driver); + if (error) { + pr_err("driver_register() failed for %s: %d\n", + cdx_driver->driver.name, error); + return error; + } + + return 0; +} +EXPORT_SYMBOL_GPL(__cdx_driver_register); + +void cdx_driver_unregister(struct cdx_driver *cdx_driver) +{ + driver_unregister(&cdx_driver->driver); +} +EXPORT_SYMBOL_GPL(cdx_driver_unregister); + +static void cdx_device_release(struct device *dev) +{ + struct cdx_device *cdx_dev = to_cdx_device(dev); + + kfree(cdx_dev); +} + +int cdx_device_add(struct cdx_dev_params *dev_params) +{ + struct cdx_controller *cdx = dev_params->cdx; + struct device *parent = cdx->dev; + struct cdx_device *cdx_dev; + int ret; + + cdx_dev = kzalloc(sizeof(*cdx_dev), GFP_KERNEL); + if (!cdx_dev) + return -ENOMEM; + + /* Populate resource */ + memcpy(cdx_dev->res, dev_params->res, sizeof(struct resource) * + dev_params->res_count); + cdx_dev->res_count = dev_params->res_count; + + /* Populate CDX dev params */ + cdx_dev->req_id = dev_params->req_id; + cdx_dev->vendor = dev_params->vendor; + cdx_dev->device = dev_params->device; + cdx_dev->bus_num = dev_params->bus_num; + cdx_dev->dev_num = dev_params->dev_num; + cdx_dev->cdx = dev_params->cdx; + cdx_dev->dma_mask = CDX_DEFAULT_DMA_MASK; + + /* Initialize generic device */ + device_initialize(&cdx_dev->dev); + cdx_dev->dev.parent = parent; + cdx_dev->dev.bus = &cdx_bus_type; + cdx_dev->dev.dma_mask = &cdx_dev->dma_mask; + cdx_dev->dev.release = cdx_device_release; + + /* Set Name */ + dev_set_name(&cdx_dev->dev, "cdx-%02x:%02x", + ((cdx->id << CDX_CONTROLLER_ID_SHIFT) | (cdx_dev->bus_num & CDX_BUS_NUM_MASK)), + cdx_dev->dev_num); + + ret = device_add(&cdx_dev->dev); + if (ret) { + dev_err(&cdx_dev->dev, + "cdx device add failed: %d", ret); + goto fail; + } + + return 0; +fail: + /* + * Do not free cdx_dev here as it would be freed in + * cdx_device_release() called from put_device(). + */ + put_device(&cdx_dev->dev); + + return ret; +} +EXPORT_SYMBOL_GPL(cdx_device_add); + +int cdx_register_controller(struct cdx_controller *cdx) +{ + int ret; + + ret = xa_alloc(&cdx_controllers, &cdx->id, cdx, + XA_LIMIT(0, MAX_CDX_CONTROLLERS - 1), GFP_KERNEL); + if (ret) { + dev_err(cdx->dev, + "No free index available. Maximum controllers already registered\n"); + cdx->id = (u8)MAX_CDX_CONTROLLERS; + return ret; + } + + /* Scan all the devices */ + cdx->ops->scan(cdx); + + return 0; +} +EXPORT_SYMBOL_GPL(cdx_register_controller); + +void cdx_unregister_controller(struct cdx_controller *cdx) +{ + if (cdx->id >= MAX_CDX_CONTROLLERS) + return; + + device_for_each_child(cdx->dev, NULL, cdx_unregister_device); + xa_erase(&cdx_controllers, cdx->id); +} +EXPORT_SYMBOL_GPL(cdx_unregister_controller); + +static int __init cdx_bus_init(void) +{ + return bus_register(&cdx_bus_type); +} +postcore_initcall(cdx_bus_init); diff --git a/drivers/cdx/cdx.h b/drivers/cdx/cdx.h new file mode 100644 index 000000000000..c436ac7ac86f --- /dev/null +++ b/drivers/cdx/cdx.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Header file for the CDX Bus + * + * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. + */ + +#ifndef _CDX_H_ +#define _CDX_H_ + +#include + +/** + * struct cdx_dev_params - CDX device parameters + * @cdx: CDX controller associated with the device + * @parent: Associated CDX controller + * @vendor: Vendor ID for CDX device + * @device: Device ID for CDX device + * @bus_num: Bus number for this CDX device + * @dev_num: Device number for this device + * @res: array of MMIO region entries + * @res_count: number of valid MMIO regions + * @req_id: Requestor ID associated with CDX device + */ +struct cdx_dev_params { + struct cdx_controller *cdx; + u16 vendor; + u16 device; + u8 bus_num; + u8 dev_num; + struct resource res[MAX_CDX_DEV_RESOURCES]; + u8 res_count; + u32 req_id; +}; + +/** + * cdx_register_controller - Register a CDX controller and its ports + * on the CDX bus. + * @cdx: The CDX controller to register + * + * Return: -errno on failure, 0 on success. + */ +int cdx_register_controller(struct cdx_controller *cdx); + +/** + * cdx_unregister_controller - Unregister a CDX controller + * @cdx: The CDX controller to unregister + */ +void cdx_unregister_controller(struct cdx_controller *cdx); + +/** + * cdx_device_add - Add a CDX device. This function adds a CDX device + * on the CDX bus as per the device parameters provided + * by caller. It also creates and registers an associated + * Linux generic device. + * @dev_params: device parameters associated with the device to be created. + * + * Return: -errno on failure, 0 on success. + */ +int cdx_device_add(struct cdx_dev_params *dev_params); + +#endif /* _CDX_H_ */ diff --git a/include/linux/cdx/cdx_bus.h b/include/linux/cdx/cdx_bus.h new file mode 100644 index 000000000000..d134e0104724 --- /dev/null +++ b/include/linux/cdx/cdx_bus.h @@ -0,0 +1,147 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * CDX bus public interface + * + * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. + * + */ + +#ifndef _CDX_BUS_H_ +#define _CDX_BUS_H_ + +#include +#include +#include + +#define MAX_CDX_DEV_RESOURCES 4 +#define CDX_ANY_ID (0xFFFF) +#define CDX_CONTROLLER_ID_SHIFT 4 +#define CDX_BUS_NUM_MASK 0xF + +/* Forward declaration for CDX controller */ +struct cdx_controller; + +typedef int (*cdx_scan_cb)(struct cdx_controller *cdx); + +/** + * CDX_DEVICE_DRIVER_OVERRIDE - macro used to describe a CDX device with + * override_only flags. + * @vend: the 16 bit CDX Vendor ID + * @dev: the 16 bit CDX Device ID + * @driver_override: the 32 bit CDX Device override_only + * + * This macro is used to create a struct cdx_device_id that matches only a + * driver_override device. + */ +#define CDX_DEVICE_DRIVER_OVERRIDE(vend, dev, driver_override) \ + .vendor = (vend), .device = (dev), .override_only = (driver_override) + +/** + * struct cdx_ops - Callbacks supported by CDX controller. + * @scan: scan the devices on the controller + */ +struct cdx_ops { + cdx_scan_cb scan; +}; + +/** + * struct cdx_controller: CDX controller object + * @dev: Linux device associated with the CDX controller. + * @priv: private data + * @id: Controller ID + * @ops: CDX controller ops + */ +struct cdx_controller { + struct device *dev; + void *priv; + u32 id; + struct cdx_ops *ops; +}; + +/** + * struct cdx_device - CDX device object + * @dev: Linux driver model device object + * @cdx: CDX controller associated with the device + * @vendor: Vendor ID for CDX device + * @device: Device ID for CDX device + * @bus_num: Bus number for this CDX device + * @dev_num: Device number for this device + * @res: array of MMIO region entries + * @res_attr: resource binary attribute + * @res_count: number of valid MMIO regions + * @dma_mask: Default DMA mask + * @flags: CDX device flags + * @req_id: Requestor ID associated with CDX device + * @driver_override: driver name to force a match; do not set directly, + * because core frees it; use driver_set_override() to + * set or clear it. + */ +struct cdx_device { + struct device dev; + struct cdx_controller *cdx; + u16 vendor; + u16 device; + u8 bus_num; + u8 dev_num; + struct resource res[MAX_CDX_DEV_RESOURCES]; + u8 res_count; + u64 dma_mask; + u16 flags; + u32 req_id; + const char *driver_override; +}; + +#define to_cdx_device(_dev) \ + container_of(_dev, struct cdx_device, dev) + +/** + * struct cdx_driver - CDX device driver + * @driver: Generic device driver + * @match_id_table: table of supported device matching Ids + * @probe: Function called when a device is added + * @remove: Function called when a device is removed + * @shutdown: Function called at shutdown time to quiesce the device + * @driver_managed_dma: Device driver doesn't use kernel DMA API for DMA. + * For most device drivers, no need to care about this flag + * as long as all DMAs are handled through the kernel DMA API. + * For some special ones, for example VFIO drivers, they know + * how to manage the DMA themselves and set this flag so that + * the IOMMU layer will allow them to setup and manage their + * own I/O address space. + */ +struct cdx_driver { + struct device_driver driver; + const struct cdx_device_id *match_id_table; + int (*probe)(struct cdx_device *dev); + int (*remove)(struct cdx_device *dev); + void (*shutdown)(struct cdx_device *dev); + bool driver_managed_dma; +}; + +#define to_cdx_driver(_drv) \ + container_of(_drv, struct cdx_driver, driver) + +/* Macro to avoid include chaining to get THIS_MODULE */ +#define cdx_driver_register(drv) \ + __cdx_driver_register(drv, THIS_MODULE) + +/** + * __cdx_driver_register - registers a CDX device driver + * @cdx_driver: CDX driver to register + * @owner: module owner + * + * Return: -errno on failure, 0 on success. + */ +int __must_check __cdx_driver_register(struct cdx_driver *cdx_driver, + struct module *owner); + +/** + * cdx_driver_unregister - unregisters a device driver from the + * CDX bus. + * @cdx_driver: CDX driver to register + */ +void cdx_driver_unregister(struct cdx_driver *cdx_driver); + +extern struct bus_type cdx_bus_type; + +#endif /* _CDX_BUS_H_ */ diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 35203ca3fc37..ccaaeda792c0 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -912,4 +912,19 @@ struct ishtp_device_id { kernel_ulong_t driver_data; }; +/** + * struct cdx_device_id - CDX device identifier + * @vendor: Vendor ID + * @device: Device ID + * @override_only: Match only when dev->driver_override is this driver. + * + * Type of entries in the "device Id" table for CDX devices supported by + * a CDX device driver. + */ +struct cdx_device_id { + __u16 vendor; + __u16 device; + __u32 override_only; +}; + #endif /* LINUX_MOD_DEVICETABLE_H */ diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index c0d3bcb99138..62dc988df84d 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -262,5 +262,9 @@ int main(void) DEVID(ishtp_device_id); DEVID_FIELD(ishtp_device_id, guid); + DEVID(cdx_device_id); + DEVID_FIELD(cdx_device_id, vendor); + DEVID_FIELD(cdx_device_id, device); + return 0; } diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 91c2e7ba5e52..28da34ba4359 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1452,6 +1452,17 @@ static int do_dfl_entry(const char *filename, void *symval, char *alias) return 1; } +/* Looks like: cdx:vNdN */ +static int do_cdx_entry(const char *filename, void *symval, + char *alias) +{ + DEF_FIELD(symval, cdx_device_id, vendor); + DEF_FIELD(symval, cdx_device_id, device); + + sprintf(alias, "cdx:v%08Xd%08Xd", vendor, device); + return 1; +} + /* Does namelen bytes of name exactly match the symbol? */ static bool sym_is(const char *name, unsigned namelen, const char *symbol) { @@ -1531,6 +1542,7 @@ static const struct devtable devtable[] = { {"ssam", SIZE_ssam_device_id, do_ssam_entry}, {"dfl", SIZE_dfl_device_id, do_dfl_entry}, {"ishtp", SIZE_ishtp_device_id, do_ishtp_entry}, + {"cdx", SIZE_cdx_device_id, do_cdx_entry}, }; /* Create MODULE_ALIAS() statements. -- cgit From d1c27c55427e3fe54c1bc22bd4d40fc21ff5406c Mon Sep 17 00:00:00 2001 From: Ross Zwisler Date: Mon, 13 Mar 2023 15:17:44 -0600 Subject: leaking_addresses: also skip canonical ftrace path The canonical location for the tracefs filesystem is at /sys/kernel/tracing. But, from Documentation/trace/ftrace.rst: Before 4.1, all ftrace tracing control files were within the debugfs file system, which is typically located at /sys/kernel/debug/tracing. For backward compatibility, when mounting the debugfs file system, the tracefs file system will be automatically mounted at: /sys/kernel/debug/tracing scripts/leaking_addresses.pl only skipped this older debugfs path, so let's add the canonical path as well. Link: https://lkml.kernel.org/r/20230313211746.1541525-2-zwisler@kernel.org Cc: "Tobin C. Harding" Cc: Andrew Morton Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Paolo Bonzini Cc: Shuah Khan Acked-by: Tycho Andersen Reviewed-by: Steven Rostedt (Google) Signed-off-by: Ross Zwisler Signed-off-by: Steven Rostedt (Google) --- scripts/leaking_addresses.pl | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/leaking_addresses.pl b/scripts/leaking_addresses.pl index 8f636a23bc3f..e695634d153d 100755 --- a/scripts/leaking_addresses.pl +++ b/scripts/leaking_addresses.pl @@ -61,6 +61,7 @@ my @skip_abs = ( '/proc/device-tree', '/proc/1/syscall', '/sys/firmware/devicetree', + '/sys/kernel/tracing/trace_pipe', '/sys/kernel/debug/tracing/trace_pipe', '/sys/kernel/security/apparmor/revision'); -- cgit From 1eacac3255495be7502d406e2ba5444fb5c3607c Mon Sep 17 00:00:00 2001 From: "Joel Fernandes (Google)" Date: Mon, 6 Mar 2023 14:33:58 +0000 Subject: checkpatch: Error out if deprecated RCU API used Single-argument kvfree_rcu() usage is being deprecated [1] [2]. However, till all users are converted, we would like to introduce checkpatch errors for new patches submitted. This patch adds support for the same. Tested with a trial patch. For now, we are only considering usages that don't have compound nesting, for example ignore: kvfree_rcu( (rcu_head_obj), rcu_head_name). This is sufficient as such usages are unlikely. Once all users are converted and we remove the old API, we can also revert this checkpatch patch then. [1] https://lore.kernel.org/rcu/CAEXW_YRhHaVuq+5f+VgCZM=SF+9xO+QXaxe0yE7oA9iCXK-XPg@mail.gmail.com/ [2] https://lore.kernel.org/rcu/CAEXW_YSY=q2_uaE2qo4XSGjzs4+C102YMVJ7kWwuT5LGmJGGew@mail.gmail.com/ Acked-by: Paul E. McKenney Signed-off-by: Joel Fernandes (Google) --- scripts/checkpatch.pl | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index bd44d12965c9..4bfbe3c9fa15 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -6388,6 +6388,15 @@ sub process { } } +# check for soon-to-be-deprecated single-argument k[v]free_rcu() API + if ($line =~ /\bk[v]?free_rcu\s*\([^(]+\)/) { + if ($line =~ /\bk[v]?free_rcu\s*\([^,]+\)/) { + ERROR("DEPRECATED_API", + "Single-argument k[v]free_rcu() API is deprecated, please pass rcu_head object or call k[v]free_rcu_mightsleep()." . $herecurr); + } + } + + # check for unnecessary "Out of Memory" messages if ($line =~ /^\+.*\b$logFunctions\s*\(/ && $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && -- cgit From 5c7548d5a25306dcdb97689479be81cacc8ce596 Mon Sep 17 00:00:00 2001 From: Asahi Lina Date: Fri, 7 Apr 2023 00:25:22 +0200 Subject: scripts: generate_rust_analyzer: Handle sub-modules with no Makefile More complex drivers might want to use modules to organize their Rust code, but those module folders do not need a Makefile. generate_rust_analyzer.py currently crashes on those. Fix it so that a missing Makefile is silently ignored. Link: https://github.com/Rust-for-Linux/linux/pull/883 Signed-off-by: Asahi Lina Signed-off-by: Miguel Ojeda --- scripts/generate_rust_analyzer.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py index ecc7ea9a4dcf..946e250c1b2a 100755 --- a/scripts/generate_rust_analyzer.py +++ b/scripts/generate_rust_analyzer.py @@ -104,7 +104,10 @@ def generate_crates(srctree, objtree, sysroot_src): name = path.name.replace(".rs", "") # Skip those that are not crate roots. - if f"{name}.o" not in open(path.parent / "Makefile").read(): + try: + if f"{name}.o" not in open(path.parent / "Makefile").read(): + continue + except FileNotFoundError: continue logging.info("Adding %s", name) -- cgit From 56fe487062b5561ceabb9f866327cd0b041f3a09 Mon Sep 17 00:00:00 2001 From: Glenn Washburn Date: Sun, 26 Feb 2023 22:05:59 -0600 Subject: scripts/gdb: correct indentation in get_current_task Patch series "scripts/gdb: Support getting current task struct in UML", v3. A running x86 UML kernel reports with architecture "i386:x86-64" as it is a sub-architecture. However, a difference with bare-metal x86 kernels is in how it manages tasks and the current task struct. To identify that the inferior is a UML kernel and not bare-metal, check for the existence of the UML specific symbol "cpu_tasks" which contains the current task struct. This patch (of 3): There is an extra space in a couple blocks in get_current_task. Though python does not care, let's make the spacing consistent. Also, format better an if expression, removing unneeded parenthesis. Link: https://lkml.kernel.org/r/cover.1677469905.git.development@efficientek.com Link: https://lkml.kernel.org/r/2e117b82240de6893f27cb6507242ce455ed7b5b.1677469905.git.development@efficientek.com Signed-off-by: Glenn Washburn Reviewed-by: Jan Kiszka Cc: Anton Ivanov Cc: Johannes Berg Cc: Kieran Bingham Cc: Richard Weinberger Signed-off-by: Andrew Morton --- scripts/gdb/linux/cpus.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py index 9ee99f9fae8d..e8d2a62ff119 100644 --- a/scripts/gdb/linux/cpus.py +++ b/scripts/gdb/linux/cpus.py @@ -163,16 +163,16 @@ def get_current_task(cpu): task_ptr_type = task_type.get_type().pointer() if utils.is_target_arch("x86"): - var_ptr = gdb.parse_and_eval("&pcpu_hot.current_task") - return per_cpu(var_ptr, cpu).dereference() + var_ptr = gdb.parse_and_eval("&pcpu_hot.current_task") + return per_cpu(var_ptr, cpu).dereference() elif utils.is_target_arch("aarch64"): - current_task_addr = gdb.parse_and_eval("$SP_EL0") - if((current_task_addr >> 63) != 0): - current_task = current_task_addr.cast(task_ptr_type) - return current_task.dereference() - else: - raise gdb.GdbError("Sorry, obtaining the current task is not allowed " - "while running in userspace(EL0)") + current_task_addr = gdb.parse_and_eval("$SP_EL0") + if (current_task_addr >> 63) != 0: + current_task = current_task_addr.cast(task_ptr_type) + return current_task.dereference() + else: + raise gdb.GdbError("Sorry, obtaining the current task is not allowed " + "while running in userspace(EL0)") else: raise gdb.GdbError("Sorry, obtaining the current task is not yet " "supported with this arch") -- cgit From 6d51363d53db4f5f11a13509ef28e917b97eb2b3 Mon Sep 17 00:00:00 2001 From: Glenn Washburn Date: Sun, 26 Feb 2023 22:06:00 -0600 Subject: scripts/gdb: support getting current task struct in UML A running x86 UML kernel reports with architecture "i386:x86-64" as it is a sub-architecture. However, a difference with bare-metal x86 kernels is in how it manages tasks and the current task struct. To identify that the inferior is a UML kernel and not bare-metal, check for the existence of the UML specific symbol "cpu_tasks" which contains the current task struct. Link: https://lkml.kernel.org/r/b839d611e2906ccef2725c34d8e353fab35fe75e.1677469905.git.development@efficientek.com Signed-off-by: Glenn Washburn Reviewed-by: Jan Kiszka Cc: Anton Ivanov Cc: Johannes Berg Cc: Kieran Bingham Cc: Richard Weinberger Signed-off-by: Andrew Morton --- scripts/gdb/linux/cpus.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py index e8d2a62ff119..255dc18cb9da 100644 --- a/scripts/gdb/linux/cpus.py +++ b/scripts/gdb/linux/cpus.py @@ -163,8 +163,14 @@ def get_current_task(cpu): task_ptr_type = task_type.get_type().pointer() if utils.is_target_arch("x86"): - var_ptr = gdb.parse_and_eval("&pcpu_hot.current_task") - return per_cpu(var_ptr, cpu).dereference() + if gdb.lookup_global_symbol("cpu_tasks"): + # This is a UML kernel, which stores the current task + # differently than other x86 sub architectures + var_ptr = gdb.parse_and_eval("(struct task_struct *)cpu_tasks[0].task") + return var_ptr.dereference() + else: + var_ptr = gdb.parse_and_eval("&pcpu_hot.current_task") + return per_cpu(var_ptr, cpu).dereference() elif utils.is_target_arch("aarch64"): current_task_addr = gdb.parse_and_eval("$SP_EL0") if (current_task_addr >> 63) != 0: -- cgit From 4b3d049f1c567560191884d4bd8f6e99ab885e20 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 6 Mar 2023 13:32:53 -0800 Subject: scripts/link-vmlinux.sh: fix error message presentation This comes out as Try make KALLSYMS_EXTRA_PASS=1 as a workaround but we want quotes: Try "make KALLSYMS_EXTRA_PASS=1" as a workaround Link: https://lkml.kernel.org/r/202303042034.Cjc7JTd0-lkp@intel.com Cc: kernel test robot Signed-off-by: Andrew Morton --- scripts/link-vmlinux.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 32e573943cf0..0512c313a590 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -291,7 +291,7 @@ fi if is_enabled CONFIG_KALLSYMS; then if ! cmp -s System.map ${kallsyms_vmlinux}.syms; then echo >&2 Inconsistent kallsyms data - echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround + echo >&2 'Try "make KALLSYMS_EXTRA_PASS=1" as a workaround' exit 1 fi fi -- cgit From d99a4158c4483c7f47274937deb142cd8c461b77 Mon Sep 17 00:00:00 2001 From: Gerhard Engleder Date: Wed, 4 Jan 2023 21:15:24 +0100 Subject: checkpatch: ignore ETHTOOL_LINK_MODE_ enum values Since commit 4104a20646 ("checkpatch: ignore generated CamelCase defines and enum values") enum values like ETHTOOL_LINK_MODE_Asym_Pause_BIT are ignored. But there are other enums like ETHTOOL_LINK_MODE_1000baseT_Full_BIT, which are not ignored because of the not matching '1000baseT' substring. Add regex to match all ETHTOOL_LINK_MODE enums. Link: https://lkml.kernel.org/r/20230104201524.28078-1-gerhard@engleder-embedded.com Signed-off-by: Gerhard Engleder Cc: Andy Whitcroft Cc: Dwaipayan Ray Cc: Gerhard Engleder Cc: Joe Perches Cc: Lukas Bulwahn Signed-off-by: Andrew Morton --- scripts/checkpatch.pl | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index bd44d12965c9..c7cd0750b41e 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -5809,6 +5809,8 @@ sub process { $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ && #Ignore Page variants $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && +#Ignore ETHTOOL_LINK_MODE_ variants + $var !~ /^ETHTOOL_LINK_MODE_/ && #Ignore SI style variants like nS, mV and dB #(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE) $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ && -- cgit From 1d7adbc74c009057ed9dc3112f388e91a9c79acc Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 23 Mar 2023 15:52:45 -0700 Subject: scripts/gdb: bail early if there are no clocks Avoid generating an exception if there are no clocks registered: (gdb) lx-clk-summary enable prepare protect clock count count count rate ------------------------------------------------------------------------ Python Exception : No symbol "clk_root_list" in current context. Error occurred in Python: No symbol "clk_root_list" in current context. Link: https://lkml.kernel.org/r/20230323225246.3302977-1-f.fainelli@gmail.com Fixes: d1e9710b63d8 ("scripts/gdb: initial clk support: lx-clk-summary") Signed-off-by: Florian Fainelli Cc: Jan Kiszka Cc: Kieran Bingham Cc: Leonard Crestez Cc: Stephen Boyd Signed-off-by: Andrew Morton --- scripts/gdb/linux/clk.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/gdb/linux/clk.py b/scripts/gdb/linux/clk.py index 061aecfa294e..7a01fdc3e844 100644 --- a/scripts/gdb/linux/clk.py +++ b/scripts/gdb/linux/clk.py @@ -41,6 +41,8 @@ are cached and potentially out of date""" self.show_subtree(child, level + 1) def invoke(self, arg, from_tty): + if utils.gdb_eval_or_none("clk_root_list") is None: + raise gdb.GdbError("No clocks registered") gdb.write(" enable prepare protect \n") gdb.write(" clock count count count rate \n") gdb.write("------------------------------------------------------------------------\n") -- cgit From f19c3c2959e465209ade1a7a699e6cbf4359ce78 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 23 Mar 2023 16:16:57 -0700 Subject: scripts/gdb: bail early if there are no generic PD Avoid generating an exception if there are no generic power domain(s) registered: (gdb) lx-genpd-summary domain status children /device runtime status ---------------------------------------------------------------------- Python Exception : No symbol "gpd_list" in current context. Error occurred in Python: No symbol "gpd_list" in current context. (gdb) quit [f.fainelli@gmail.com: correctly invoke gdb_eval_or_none] Link: https://lkml.kernel.org/r/20230327185746.3856407-1-f.fainelli@gmail.com Link: https://lkml.kernel.org/r/20230323231659.3319941-1-f.fainelli@gmail.com Fixes: 8207d4a88e1e ("scripts/gdb: add lx-genpd-summary command") Signed-off-by: Florian Fainelli Cc: Jan Kiszka Cc: Kieran Bingham Cc: Leonard Crestez Cc: Stephen Boyd Signed-off-by: Andrew Morton --- scripts/gdb/linux/genpd.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/genpd.py b/scripts/gdb/linux/genpd.py index 39cd1abd8559..b53649c0a77a 100644 --- a/scripts/gdb/linux/genpd.py +++ b/scripts/gdb/linux/genpd.py @@ -5,7 +5,7 @@ import gdb import sys -from linux.utils import CachedType +from linux.utils import CachedType, gdb_eval_or_none from linux.lists import list_for_each_entry generic_pm_domain_type = CachedType('struct generic_pm_domain') @@ -70,6 +70,8 @@ Output is similar to /sys/kernel/debug/pm_genpd/pm_genpd_summary''' gdb.write(' %-50s %s\n' % (kobj_path, rtpm_status_str(dev))) def invoke(self, arg, from_tty): + if gdb_eval_or_none("&gpd_list") is None: + raise gdb.GdbError("No power domain(s) registered") gdb.write('domain status children\n'); gdb.write(' /device runtime status\n'); gdb.write('----------------------------------------------------------------------\n'); -- cgit From 3c01a424a37fe625052c68c8620f6aa701f77769 Mon Sep 17 00:00:00 2001 From: Asahi Lina Date: Fri, 24 Feb 2023 17:09:47 +0900 Subject: rust: Enable the new_uninit feature for kernel and driver crates The unstable new_uninit feature enables various library APIs to create uninitialized containers, such as `Box::assume_init()`. This is necessary to build abstractions that directly initialize memory at the target location, instead of doing copies through the stack. Will be used by the DRM scheduler abstraction in the kernel crate, and by field-wise initialization (e.g. using `place!()` or a future replacement macro which may itself live in `kernel`) in driver crates. Link: https://github.com/Rust-for-Linux/linux/issues/879 Link: https://github.com/Rust-for-Linux/linux/issues/2 Link: https://github.com/rust-lang/rust/issues/63291 Signed-off-by: Asahi Lina Reviewed-by: Martin Rodriguez Reboredo Reviewed-by: Gary Guo Reviewed-by: Andreas Hindborg Reviewed-by: Vincenzo Palazzo Link: https://lore.kernel.org/r/20230224-rust-new_uninit-v1-1-c951443d9e26@asahilina.net [ Reworded to use `Link` tags. ] Signed-off-by: Miguel Ojeda --- rust/kernel/lib.rs | 1 + scripts/Makefile.build | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 223564f9f0cc..1118cd3e0b5f 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -17,6 +17,7 @@ #![feature(core_ffi_c)] #![feature(dispatch_from_dyn)] #![feature(generic_associated_types)] +#![feature(new_uninit)] #![feature(receiver_trait)] #![feature(unsize)] diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 76323201232a..1364e3d905fc 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -277,7 +277,7 @@ $(obj)/%.lst: $(src)/%.c FORCE # Compile Rust sources (.rs) # --------------------------------------------------------------------------- -rust_allowed_features := core_ffi_c +rust_allowed_features := core_ffi_c,new_uninit rust_common_cmd = \ RUST_MODFILE=$(modfile) $(RUSTC_OR_CLIPPY) $(rust_flags) \ -- cgit From aa7d233f45b4c549750044c9921f7afcbe50925b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 10 Apr 2023 21:09:07 +0900 Subject: kbuild: give up untracked files for source package builds When the source tree is dirty and contains untracked files, package builds may fail, for example, when a broken symlink exists, a file path contains whitespaces, etc. Since commit 05e96e96a315 ("kbuild: use git-archive for source package creation"), the source tarball only contains committed files because it is created by 'git archive'. scripts/package/gen-diff-patch tries to address the diff from HEAD, but including untracked files by the hand-crafted script introduces more complexity. I wrote a patch [1] to make it work in most cases, but still wonder if this is what we should aim for. To simplify the code, this patch just gives up untracked files. Going forward, it is your responsibility to do 'git add' for what you want in the source package. The script shows a warning just in case you forgot to do so. It should be checked only when building source packages. [1]: https://lore.kernel.org/all/CAK7LNAShbZ56gSh9PrbLnBDYKnjtTkHMoCXeGrhcxMvqXGq9=g@mail.gmail.com/2-0001-kbuild-make-package-builds-more-robust.patch Fixes: 05e96e96a315 ("kbuild: use git-archive for source package creation") Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/Makefile.package | 3 +- scripts/package/gen-diff-patch | 62 +++++++++++-------------- scripts/package/mkdebian | 103 +++++++++++++++++++++++------------------ scripts/package/mkspec | 11 +---- 4 files changed, 90 insertions(+), 89 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.package b/scripts/Makefile.package index 61f72eb8d9be..49aff12cb6ab 100644 --- a/scripts/Makefile.package +++ b/scripts/Makefile.package @@ -94,7 +94,7 @@ binrpm-pkg: $(UTS_MACHINE)-linux -bb $(objtree)/binkernel.spec quiet_cmd_debianize = GEN $@ - cmd_debianize = $(srctree)/scripts/package/mkdebian + cmd_debianize = $(srctree)/scripts/package/mkdebian $(mkdebian-opts) debian: FORCE $(call cmd,debianize) @@ -103,6 +103,7 @@ PHONY += debian-orig debian-orig: private source = $(shell dpkg-parsechangelog -S Source) debian-orig: private version = $(shell dpkg-parsechangelog -S Version | sed 's/-[^-]*$$//') debian-orig: private orig-name = $(source)_$(version).orig.tar.gz +debian-orig: mkdebian-opts = --need-source debian-orig: linux.tar.gz debian $(Q)if [ "$(df --output=target .. 2>/dev/null)" = "$(df --output=target $< 2>/dev/null)" ]; then \ ln -f $< ../$(orig-name); \ diff --git a/scripts/package/gen-diff-patch b/scripts/package/gen-diff-patch index f842ab50a780..8a98b7bb78a0 100755 --- a/scripts/package/gen-diff-patch +++ b/scripts/package/gen-diff-patch @@ -1,44 +1,36 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0-only -diff_patch="${1}" -untracked_patch="${2}" -srctree=$(dirname $0)/../.. +diff_patch=$1 -rm -f ${diff_patch} ${untracked_patch} +mkdir -p "$(dirname "${diff_patch}")" -if ! ${srctree}/scripts/check-git; then - exit -fi - -mkdir -p "$(dirname ${diff_patch})" "$(dirname ${untracked_patch})" +git -C "${srctree:-.}" diff HEAD > "${diff_patch}" -git -C "${srctree}" diff HEAD > "${diff_patch}" - -if [ ! -s "${diff_patch}" ]; then - rm -f "${diff_patch}" +if [ ! -s "${diff_patch}" ] || + [ -z "$(git -C "${srctree:-.}" ls-files --other --exclude-standard | head -n1)" ]; then exit fi -git -C ${srctree} status --porcelain --untracked-files=all | -while read stat path -do - if [ "${stat}" = '??' ]; then - - if ! diff -u /dev/null "${srctree}/${path}" > .tmp_diff && - ! head -n1 .tmp_diff | grep -q "Binary files"; then - { - echo "--- /dev/null" - echo "+++ linux/$path" - cat .tmp_diff | tail -n +3 - } >> ${untracked_patch} - fi - fi -done - -rm -f .tmp_diff - -if [ ! -s "${diff_patch}" ]; then - rm -f "${diff_patch}" - exit -fi +# The source tarball, which is generated by 'git archive', contains everything +# you committed in the repository. If you have local diff ('git diff HEAD'), +# it will go into ${diff_patch}. If untracked files are remaining, the resulting +# source package may not be correct. +# +# Examples: +# - You modified a source file to add #include "new-header.h" +# but forgot to add new-header.h +# - You modified a Makefile to add 'obj-$(CONFIG_FOO) += new-dirver.o' +# but you forgot to add new-driver.c +# +# You need to commit them, or at least stage them by 'git add'. +# +# This script does not take care of untracked files because doing so would +# introduce additional complexity. Instead, print a warning message here if +# untracked files are found. +# If all untracked files are just garbage, you can ignore this warning. +echo >&2 "============================ WARNING ============================" +echo >&2 "Your working tree has diff from HEAD, and also untracked file(s)." +echo >&2 "Please make sure you did 'git add' for all new files you need in" +echo >&2 "the source package." +echo >&2 "=================================================================" diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index e20a2b5be9eb..a4c2c2276223 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -84,7 +84,66 @@ set_debarch() { fi } +# Create debian/source/ if it is a source package build +gen_source () +{ + mkdir -p debian/source + + echo "3.0 (quilt)" > debian/source/format + + { + echo "diff-ignore" + echo "extend-diff-ignore = .*" + } > debian/source/local-options + + # Add .config as a patch + mkdir -p debian/patches + { + echo "Subject: Add .config" + echo "Author: ${maintainer}" + echo + echo "--- /dev/null" + echo "+++ linux/.config" + diff -u /dev/null "${KCONFIG_CONFIG}" | tail -n +3 + } > debian/patches/config.patch + echo config.patch > debian/patches/series + + "${srctree}/scripts/package/gen-diff-patch" debian/patches/diff.patch + if [ -s debian/patches/diff.patch ]; then + sed -i " + 1iSubject: Add local diff + 1iAuthor: ${maintainer} + 1i + " debian/patches/diff.patch + + echo diff.patch >> debian/patches/series + else + rm -f debian/patches/diff.patch + fi +} + rm -rf debian +mkdir debian + +email=${DEBEMAIL-$EMAIL} + +# use email string directly if it contains +if echo "${email}" | grep -q '<.*>'; then + maintainer=${email} +else + # or construct the maintainer string + user=${KBUILD_BUILD_USER-$(id -nu)} + name=${DEBFULLNAME-${user}} + if [ -z "${email}" ]; then + buildhost=${KBUILD_BUILD_HOST-$(hostname -f 2>/dev/null || hostname)} + email="${user}@${buildhost}" + fi + maintainer="${name} <${email}>" +fi + +if [ "$1" = --need-source ]; then + gen_source +fi # Some variables and settings used throughout the script version=$KERNELRELEASE @@ -104,22 +163,6 @@ fi debarch= set_debarch -email=${DEBEMAIL-$EMAIL} - -# use email string directly if it contains -if echo $email | grep -q '<.*>'; then - maintainer=$email -else - # or construct the maintainer string - user=${KBUILD_BUILD_USER-$(id -nu)} - name=${DEBFULLNAME-$user} - if [ -z "$email" ]; then - buildhost=${KBUILD_BUILD_HOST-$(hostname -f 2>/dev/null || hostname)} - email="$user@$buildhost" - fi - maintainer="$name <$email>" -fi - # Try to determine distribution if [ -n "$KDEB_CHANGELOG_DIST" ]; then distribution=$KDEB_CHANGELOG_DIST @@ -132,34 +175,6 @@ else echo >&2 "Install lsb-release or set \$KDEB_CHANGELOG_DIST explicitly" fi -mkdir -p debian/source/ -echo "3.0 (quilt)" > debian/source/format - -{ - echo "diff-ignore" - echo "extend-diff-ignore = .*" -} > debian/source/local-options - -# Add .config as a patch -mkdir -p debian/patches -{ - echo "Subject: Add .config" - echo "Author: ${maintainer}" - echo - echo "--- /dev/null" - echo "+++ linux/.config" - diff -u /dev/null "${KCONFIG_CONFIG}" | tail -n +3 -} > debian/patches/config -echo config > debian/patches/series - -$(dirname $0)/gen-diff-patch debian/patches/diff.patch debian/patches/untracked.patch -if [ -f debian/patches/diff.patch ]; then - echo diff.patch >> debian/patches/series -fi -if [ -f debian/patches/untracked.patch ]; then - echo untracked.patch >> debian/patches/series -fi - echo $debarch > debian/arch extra_build_depends=", $(if_enabled_echo CONFIG_UNWINDER_ORC libelf-dev:native)" extra_build_depends="$extra_build_depends, $(if_enabled_echo CONFIG_SYSTEM_TRUSTED_KEYRING libssl-dev:native)" diff --git a/scripts/package/mkspec b/scripts/package/mkspec index b7d1dc28a5d6..fc8ad3fbc0a9 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -19,8 +19,7 @@ else mkdir -p rpmbuild/SOURCES cp linux.tar.gz rpmbuild/SOURCES cp "${KCONFIG_CONFIG}" rpmbuild/SOURCES/config - $(dirname $0)/gen-diff-patch rpmbuild/SOURCES/diff.patch rpmbuild/SOURCES/untracked.patch - touch rpmbuild/SOURCES/diff.patch rpmbuild/SOURCES/untracked.patch + "${srctree}/scripts/package/gen-diff-patch" rpmbuild/SOURCES/diff.patch fi if grep -q CONFIG_MODULES=y include/config/auto.conf; then @@ -56,7 +55,6 @@ sed -e '/^DEL/d' -e 's/^\t*//' < Date: Tue, 11 Apr 2023 15:47:47 +0100 Subject: bpf: Remove extra whitespace in SPDX tag for syscall/helpers man pages There is an extra whitespace in the SPDX tag, before the license name, in the script for generating man pages for the bpf() syscall and the helpers. It has caused problems in Debian packaging, in the tool that autodetects licenses. Let's clean it up. Fixes: 5cb62b7598f2 ("bpf, docs: Use SPDX license identifier in bpf_doc.py") Signed-off-by: Alejandro Colomar Signed-off-by: Quentin Monnet Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20230411144747.66734-1-quentin@isovalent.com --- scripts/bpf_doc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index 38d51e05c7a2..eaae2ce78381 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -383,7 +383,7 @@ class PrinterRST(Printer): .. Copyright (C) All BPF authors and contributors from 2014 to present. .. See git log include/uapi/linux/bpf.h in kernel tree for details. .. -.. SPDX-License-Identifier: Linux-man-pages-copyleft +.. SPDX-License-Identifier: Linux-man-pages-copyleft .. .. Please do not edit this file. It was generated from the documentation .. located in file include/uapi/linux/bpf.h of the Linux kernel sources -- cgit From 2d19d369c0c6dade11b8e3448c158655dbaa7b77 Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Sat, 8 Apr 2023 12:25:18 +0000 Subject: rust: enable the `pin_macro` feature This feature enables the use of the `pin!` macro for the `stack_pin_init!` macro. This feature is already stabilized in Rust version 1.68. Signed-off-by: Benno Lossin Reviewed-by: Alice Ryhl Reviewed-by: Gary Guo Reviewed-by: Andreas Hindborg Acked-by: Boqun Feng Link: https://lore.kernel.org/r/20230408122429.1103522-2-y86-dev@protonmail.com Signed-off-by: Miguel Ojeda --- rust/kernel/lib.rs | 1 + scripts/Makefile.build | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 1118cd3e0b5f..518559a0767e 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -18,6 +18,7 @@ #![feature(dispatch_from_dyn)] #![feature(generic_associated_types)] #![feature(new_uninit)] +#![feature(pin_macro)] #![feature(receiver_trait)] #![feature(unsize)] diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 1364e3d905fc..da70f68ba9e4 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -277,7 +277,7 @@ $(obj)/%.lst: $(src)/%.c FORCE # Compile Rust sources (.rs) # --------------------------------------------------------------------------- -rust_allowed_features := core_ffi_c,new_uninit +rust_allowed_features := core_ffi_c,new_uninit,pin_macro rust_common_cmd = \ RUST_MODFILE=$(modfile) $(RUSTC_OR_CLIPPY) $(rust_flags) \ -- cgit From 90e53c5e70a69159ec255fec361f7dcf9cf36eae Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Sat, 8 Apr 2023 12:25:45 +0000 Subject: rust: add pin-init API core This API is used to facilitate safe pinned initialization of structs. It replaces cumbersome `unsafe` manual initialization with elegant safe macro invocations. Due to the size of this change it has been split into six commits: 1. This commit introducing the basic public interface: traits and functions to represent and create initializers. 2. Adds the `#[pin_data]`, `pin_init!`, `try_pin_init!`, `init!` and `try_init!` macros along with their internal types. 3. Adds the `InPlaceInit` trait that allows using an initializer to create an object inside of a `Box` and other smart pointers. 4. Adds the `PinnedDrop` trait and adds macro support for it in the `#[pin_data]` macro. 5. Adds the `stack_pin_init!` macro allowing to pin-initialize a struct on the stack. 6. Adds the `Zeroable` trait and `init::zeroed` function to initialize types that have `0x00` in all bytes as a valid bit pattern. -- In this section the problem that the new pin-init API solves is outlined. This message describes the entirety of the API, not just the parts introduced in this commit. For a more granular explanation and additional information on pinning and this issue, view [1]. Pinning is Rust's way of enforcing the address stability of a value. When a value gets pinned it will be impossible for safe code to move it to another location. This is done by wrapping pointers to said object with `Pin

`. This wrapper prevents safe code from creating mutable references to the object, preventing mutable access, which is needed to move the value. `Pin

` provides `unsafe` functions to circumvent this and allow modifications regardless. It is then the programmer's responsibility to uphold the pinning guarantee. Many kernel data structures require a stable address, because there are foreign pointers to them which would get invalidated by moving the structure. Since these data structures are usually embedded in structs to use them, this pinning property propagates to the container struct. Resulting in most structs in both Rust and C code needing to be pinned. So if we want to have a `mutex` field in a Rust struct, this struct also needs to be pinned, because a `mutex` contains a `list_head`. Additionally initializing a `list_head` requires already having the final memory location available, because it is initialized by pointing it to itself. But this presents another challenge in Rust: values have to be initialized at all times. There is the `MaybeUninit` wrapper type, which allows handling uninitialized memory, but this requires using the `unsafe` raw pointers and a casting the type to the initialized variant. This problem gets exacerbated when considering encapsulation and the normal safety requirements of Rust code. The fields of the Rust `Mutex` should not be accessible to normal driver code. After all if anyone can modify the fields, there is no way to ensure the invariants of the `Mutex` are upheld. But if the fields are inaccessible, then initialization of a `Mutex` needs to be somehow achieved via a function or a macro. Because the `Mutex` must be pinned in memory, the function cannot return it by value. It also cannot allocate a `Box` to put the `Mutex` into, because that is an unnecessary allocation and indirection which would hurt performance. The solution in the rust tree (e.g. this commit: [2]) that is replaced by this API is to split this function into two parts: 1. A `new` function that returns a partially initialized `Mutex`, 2. An `init` function that requires the `Mutex` to be pinned and that fully initializes the `Mutex`. Both of these functions have to be marked `unsafe`, since a call to `new` needs to be accompanied with a call to `init`, otherwise using the `Mutex` could result in UB. And because calling `init` twice also is not safe. While `Mutex` initialization cannot fail, other structs might also have to allocate memory, which would result in conditional successful initialization requiring even more manual accommodation work. Combine this with the problem of pin-projections -- the way of accessing fields of a pinned struct -- which also have an `unsafe` API, pinned initialization is riddled with `unsafe` resulting in very poor ergonomics. Not only that, but also having to call two functions possibly multiple lines apart makes it very easy to forget it outright or during refactoring. Here is an example of the current way of initializing a struct with two synchronization primitives (see [3] for the full example): struct SharedState { state_changed: CondVar, inner: Mutex, } impl SharedState { fn try_new() -> Result> { let mut state = Pin::from(UniqueArc::try_new(Self { // SAFETY: `condvar_init!` is called below. state_changed: unsafe { CondVar::new() }, // SAFETY: `mutex_init!` is called below. inner: unsafe { Mutex::new(SharedStateInner { token_count: 0 }) }, })?); // SAFETY: `state_changed` is pinned when `state` is. let pinned = unsafe { state.as_mut().map_unchecked_mut(|s| &mut s.state_changed) }; kernel::condvar_init!(pinned, "SharedState::state_changed"); // SAFETY: `inner` is pinned when `state` is. let pinned = unsafe { state.as_mut().map_unchecked_mut(|s| &mut s.inner) }; kernel::mutex_init!(pinned, "SharedState::inner"); Ok(state.into()) } } The pin-init API of this patch solves this issue by providing a comprehensive solution comprised of macros and traits. Here is the example from above using the pin-init API: #[pin_data] struct SharedState { #[pin] state_changed: CondVar, #[pin] inner: Mutex, } impl SharedState { fn new() -> impl PinInit { pin_init!(Self { state_changed <- new_condvar!("SharedState::state_changed"), inner <- new_mutex!( SharedStateInner { token_count: 0 }, "SharedState::inner", ), }) } } Notably the way the macro is used here requires no `unsafe` and thus comes with the usual Rust promise of safe code not introducing any memory violations. Additionally it is now up to the caller of `new()` to decide the memory location of the `SharedState`. They can choose at the moment `Arc`, `Box` or the stack. -- The API has the following architecture: 1. Initializer traits `PinInit` and `Init` that act like closures. 2. Macros to create these initializer traits safely. 3. Functions to allow manually writing initializers. The initializers (an `impl PinInit`) receive a raw pointer pointing to uninitialized memory and their job is to fully initialize a `T` at that location. If initialization fails, they return an error (`E`) by value. This way of initializing cannot be safely exposed to the user, since it relies upon these properties outside of the control of the trait: - the memory location (slot) needs to be valid memory, - if initialization fails, the slot should not be read from, - the value in the slot should be pinned, so it cannot move and the memory cannot be deallocated until the value is dropped. This is why using an initializer is facilitated by another trait that ensures these requirements. These initializers can be created manually by just supplying a closure that fulfills the same safety requirements as `PinInit`. But this is an `unsafe` operation. To allow safe initializer creation, the `pin_init!` is provided along with three other variants: `try_pin_init!`, `try_init!` and `init!`. These take a modified struct initializer as a parameter and generate a closure that initializes the fields in sequence. The macros take great care in upholding the safety requirements: - A shadowed struct type is used as the return type of the closure instead of `()`. This is to prevent early returns, as these would prevent full initialization. - To ensure every field is only initialized once, a normal struct initializer is placed in unreachable code. The type checker will emit errors if a field is missing or specified multiple times. - When initializing a field fails, the whole initializer will fail and automatically drop fields that have been initialized earlier. - Only the correct initializer type is allowed for unpinned fields. You cannot use a `impl PinInit` to initialize a structurally not pinned field. To ensure the last point, an additional macro `#[pin_data]` is needed. This macro annotates the struct itself and the user specifies structurally pinned and not pinned fields. Because dropping a pinned struct is also not allowed to break the pinning invariants, another macro attribute `#[pinned_drop]` is needed. This macro is introduced in a following commit. These two macros also have mechanisms to ensure the overall safety of the API. Additionally, they utilize a combined proc-macro, declarative macro design: first a proc-macro enables the outer attribute syntax `#[...]` and does some important pre-parsing. Notably this prepares the generics such that the declarative macro can handle them using token trees. Then the actual parsing of the structure and the emission of code is handled by a declarative macro. For pin-projections the crates `pin-project` [4] and `pin-project-lite` [5] had been considered, but were ultimately rejected: - `pin-project` depends on `syn` [6] which is a very big dependency, around 50k lines of code. - `pin-project-lite` is a more reasonable 5k lines of code, but contains a very complex declarative macro to parse generics. On top of that it would require modification that would need to be maintained independently. Link: https://rust-for-linux.com/the-safe-pinned-initialization-problem [1] Link: https://github.com/Rust-for-Linux/linux/tree/0a04dc4ddd671efb87eef54dde0fb38e9074f4be [2] Link: https://github.com/Rust-for-Linux/linux/blob/f509ede33fc10a07eba3da14aa00302bd4b5dddd/samples/rust/rust_miscdev.rs [3] Link: https://crates.io/crates/pin-project [4] Link: https://crates.io/crates/pin-project-lite [5] Link: https://crates.io/crates/syn [6] Co-developed-by: Gary Guo Signed-off-by: Gary Guo Signed-off-by: Benno Lossin Reviewed-by: Alice Ryhl Reviewed-by: Wedson Almeida Filho Reviewed-by: Andreas Hindborg Link: https://lore.kernel.org/r/20230408122429.1103522-7-y86-dev@protonmail.com Signed-off-by: Miguel Ojeda --- rust/kernel/init.rs | 187 +++++++++++++++++++++++++++++++++++++++++ rust/kernel/init/__internal.rs | 33 ++++++++ rust/kernel/lib.rs | 6 ++ scripts/Makefile.build | 2 +- 4 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 rust/kernel/init.rs create mode 100644 rust/kernel/init/__internal.rs (limited to 'scripts') diff --git a/rust/kernel/init.rs b/rust/kernel/init.rs new file mode 100644 index 000000000000..d041f0daf71e --- /dev/null +++ b/rust/kernel/init.rs @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +//! API to safely and fallibly initialize pinned `struct`s using in-place constructors. +//! +//! It also allows in-place initialization of big `struct`s that would otherwise produce a stack +//! overflow. +//! +//! Most `struct`s from the [`sync`] module need to be pinned, because they contain self-referential +//! `struct`s from C. [Pinning][pinning] is Rust's way of ensuring data does not move. +//! +//! # Overview +//! +//! To initialize a `struct` with an in-place constructor you will need two things: +//! - an in-place constructor, +//! - a memory location that can hold your `struct`. +//! +//! To get an in-place constructor there are generally two options: +//! - a custom function/macro returning an in-place constructor provided by someone else, +//! - using the unsafe function [`pin_init_from_closure()`] to manually create an initializer. +//! +//! Aside from pinned initialization, this API also supports in-place construction without pinning, +//! the macros/types/functions are generally named like the pinned variants without the `pin` +//! prefix. +//! +//! [`sync`]: kernel::sync +//! [pinning]: https://doc.rust-lang.org/std/pin/index.html +//! [structurally pinned fields]: +//! https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field +//! [`Arc`]: crate::sync::Arc +//! [`impl PinInit`]: PinInit +//! [`impl PinInit`]: PinInit +//! [`impl Init`]: Init +//! [`Opaque`]: kernel::types::Opaque +//! [`pin_data`]: ::macros::pin_data +//! [`UniqueArc`]: kernel::sync::UniqueArc +//! [`Box`]: alloc::boxed::Box + +use core::{convert::Infallible, marker::PhantomData, mem::MaybeUninit}; + +#[doc(hidden)] +pub mod __internal; + +/// A pin-initializer for the type `T`. +/// +/// To use this initializer, you will need a suitable memory location that can hold a `T`. This can +/// be [`Box`], [`Arc`], [`UniqueArc`]. +/// +/// Also see the [module description](self). +/// +/// # Safety +/// +/// When implementing this type you will need to take great care. Also there are probably very few +/// cases where a manual implementation is necessary. Use [`pin_init_from_closure`] where possible. +/// +/// The [`PinInit::__pinned_init`] function +/// - returns `Ok(())` if it initialized every field of `slot`, +/// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means: +/// - `slot` can be deallocated without UB occurring, +/// - `slot` does not need to be dropped, +/// - `slot` is not partially initialized. +/// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`. +/// +/// [`Arc`]: crate::sync::Arc +/// [`Arc::pin_init`]: crate::sync::Arc::pin_init +/// [`UniqueArc`]: kernel::sync::UniqueArc +/// [`Box`]: alloc::boxed::Box +#[must_use = "An initializer must be used in order to create its value."] +pub unsafe trait PinInit: Sized { + /// Initializes `slot`. + /// + /// # Safety + /// + /// - `slot` is a valid pointer to uninitialized memory. + /// - the caller does not touch `slot` when `Err` is returned, they are only permitted to + /// deallocate. + /// - `slot` will not move until it is dropped, i.e. it will be pinned. + unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E>; +} + +/// An initializer for `T`. +/// +/// To use this initializer, you will need a suitable memory location that can hold a `T`. This can +/// be [`Box`], [`Arc`], [`UniqueArc`]. Because [`PinInit`] is a super trait, you can +/// use every function that takes it as well. +/// +/// Also see the [module description](self). +/// +/// # Safety +/// +/// When implementing this type you will need to take great care. Also there are probably very few +/// cases where a manual implementation is necessary. Use [`init_from_closure`] where possible. +/// +/// The [`Init::__init`] function +/// - returns `Ok(())` if it initialized every field of `slot`, +/// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means: +/// - `slot` can be deallocated without UB occurring, +/// - `slot` does not need to be dropped, +/// - `slot` is not partially initialized. +/// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`. +/// +/// The `__pinned_init` function from the supertrait [`PinInit`] needs to execute the exact same +/// code as `__init`. +/// +/// Contrary to its supertype [`PinInit`] the caller is allowed to +/// move the pointee after initialization. +/// +/// [`Arc`]: crate::sync::Arc +/// [`UniqueArc`]: kernel::sync::UniqueArc +/// [`Box`]: alloc::boxed::Box +#[must_use = "An initializer must be used in order to create its value."] +pub unsafe trait Init: Sized { + /// Initializes `slot`. + /// + /// # Safety + /// + /// - `slot` is a valid pointer to uninitialized memory. + /// - the caller does not touch `slot` when `Err` is returned, they are only permitted to + /// deallocate. + unsafe fn __init(self, slot: *mut T) -> Result<(), E>; +} + +// SAFETY: Every in-place initializer can also be used as a pin-initializer. +unsafe impl PinInit for I +where + I: Init, +{ + unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> { + // SAFETY: `__init` meets the same requirements as `__pinned_init`, except that it does not + // require `slot` to not move after init. + unsafe { self.__init(slot) } + } +} + +/// Creates a new [`PinInit`] from the given closure. +/// +/// # Safety +/// +/// The closure: +/// - returns `Ok(())` if it initialized every field of `slot`, +/// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means: +/// - `slot` can be deallocated without UB occurring, +/// - `slot` does not need to be dropped, +/// - `slot` is not partially initialized. +/// - may assume that the `slot` does not move if `T: !Unpin`, +/// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`. +#[inline] +pub const unsafe fn pin_init_from_closure( + f: impl FnOnce(*mut T) -> Result<(), E>, +) -> impl PinInit { + __internal::InitClosure(f, PhantomData) +} + +/// Creates a new [`Init`] from the given closure. +/// +/// # Safety +/// +/// The closure: +/// - returns `Ok(())` if it initialized every field of `slot`, +/// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means: +/// - `slot` can be deallocated without UB occurring, +/// - `slot` does not need to be dropped, +/// - `slot` is not partially initialized. +/// - the `slot` may move after initialization. +/// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`. +#[inline] +pub const unsafe fn init_from_closure( + f: impl FnOnce(*mut T) -> Result<(), E>, +) -> impl Init { + __internal::InitClosure(f, PhantomData) +} + +/// An initializer that leaves the memory uninitialized. +/// +/// The initializer is a no-op. The `slot` memory is not changed. +#[inline] +pub fn uninit() -> impl Init, E> { + // SAFETY: The memory is allowed to be uninitialized. + unsafe { init_from_closure(|_| Ok(())) } +} + +// SAFETY: Every type can be initialized by-value. +unsafe impl Init for T { + unsafe fn __init(self, slot: *mut T) -> Result<(), Infallible> { + unsafe { slot.write(self) }; + Ok(()) + } +} diff --git a/rust/kernel/init/__internal.rs b/rust/kernel/init/__internal.rs new file mode 100644 index 000000000000..08cbb5333438 --- /dev/null +++ b/rust/kernel/init/__internal.rs @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT + +//! This module contains API-internal items for pin-init. +//! +//! These items must not be used outside of +//! - `kernel/init.rs` +//! - `macros/pin_data.rs` +//! - `macros/pinned_drop.rs` + +use super::*; + +/// See the [nomicon] for what subtyping is. See also [this table]. +/// +/// [nomicon]: https://doc.rust-lang.org/nomicon/subtyping.html +/// [this table]: https://doc.rust-lang.org/nomicon/phantom-data.html#table-of-phantomdata-patterns +type Invariant = PhantomData *mut T>; + +/// This is the module-internal type implementing `PinInit` and `Init`. It is unsafe to create this +/// type, since the closure needs to fulfill the same safety requirement as the +/// `__pinned_init`/`__init` functions. +pub(crate) struct InitClosure(pub(crate) F, pub(crate) Invariant<(E, T)>); + +// SAFETY: While constructing the `InitClosure`, the user promised that it upholds the +// `__init` invariants. +unsafe impl Init for InitClosure +where + F: FnOnce(*mut T) -> Result<(), E>, +{ + #[inline] + unsafe fn __init(self, slot: *mut T) -> Result<(), E> { + (self.0)(slot) + } +} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 518559a0767e..821bd067151c 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -16,6 +16,7 @@ #![feature(coerce_unsized)] #![feature(core_ffi_c)] #![feature(dispatch_from_dyn)] +#![feature(explicit_generic_args_with_impl_trait)] #![feature(generic_associated_types)] #![feature(new_uninit)] #![feature(pin_macro)] @@ -27,11 +28,16 @@ #[cfg(not(CONFIG_RUST))] compile_error!("Missing kernel configuration for conditional compilation"); +#[allow(unused_extern_crates)] +// Allow proc-macros to refer to `::kernel` inside the `kernel` crate (this crate). +extern crate self as kernel; + #[cfg(not(test))] #[cfg(not(testlib))] mod allocator; mod build_assert; pub mod error; +pub mod init; pub mod prelude; pub mod print; mod static_assert; diff --git a/scripts/Makefile.build b/scripts/Makefile.build index da70f68ba9e4..9f94fc83f086 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -277,7 +277,7 @@ $(obj)/%.lst: $(src)/%.c FORCE # Compile Rust sources (.rs) # --------------------------------------------------------------------------- -rust_allowed_features := core_ffi_c,new_uninit,pin_macro +rust_allowed_features := core_ffi_c,explicit_generic_args_with_impl_trait,new_uninit,pin_macro rust_common_cmd = \ RUST_MODFILE=$(modfile) $(RUSTC_OR_CLIPPY) $(rust_flags) \ -- cgit From b4aff7513df323553de714dcf7b54e896577be1f Mon Sep 17 00:00:00 2001 From: Pankaj Raghav Date: Thu, 13 Apr 2023 14:00:55 -0700 Subject: scripts/gdb: use mem instead of core_layout to get the module address commit ac3b43283923 ("module: replace module_layout with module_memory") changed the struct module data structure from module_layout to module_memory. The core_layout member which is used while loading modules are not available anymore leading to the following error while running gdb: (gdb) lx-symbols loading vmlinux Python Exception : There is no member named core_layout. Error occurred in Python: There is no member named core_layout. Replace core_layout with its new counterpart mem[MOD_TEXT]. Fixes: ac3b43283923 ("module: replace module_layout with module_memory") Signed-off-by: Pankaj Raghav Signed-off-by: Luis Chamberlain --- scripts/gdb/linux/constants.py.in | 3 +++ scripts/gdb/linux/modules.py | 4 ++-- scripts/gdb/linux/symbols.py | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in index 2efbec6b6b8d..8085d3693a05 100644 --- a/scripts/gdb/linux/constants.py.in +++ b/scripts/gdb/linux/constants.py.in @@ -54,6 +54,9 @@ LX_VALUE(SB_NODIRATIME) /* linux/htimer.h */ LX_GDBPARSED(hrtimer_resolution) +/* linux/module.h */ +LX_GDBPARSED(MOD_TEXT) + /* linux/mount.h */ LX_VALUE(MNT_NOSUID) LX_VALUE(MNT_NODEV) diff --git a/scripts/gdb/linux/modules.py b/scripts/gdb/linux/modules.py index 441b23239896..261f28640f4c 100644 --- a/scripts/gdb/linux/modules.py +++ b/scripts/gdb/linux/modules.py @@ -13,7 +13,7 @@ import gdb -from linux import cpus, utils, lists +from linux import cpus, utils, lists, constants module_type = utils.CachedType("struct module") @@ -73,7 +73,7 @@ class LxLsmod(gdb.Command): " " if utils.get_long_type().sizeof == 8 else "")) for module in module_list(): - layout = module['core_layout'] + layout = module['mem'][constants.LX_MOD_TEXT] gdb.write("{address} {name:<19} {size:>8} {ref}".format( address=str(layout['base']).split()[0], name=module['name'].string(), diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py index dc07b6d12e30..fdad3f32c747 100644 --- a/scripts/gdb/linux/symbols.py +++ b/scripts/gdb/linux/symbols.py @@ -15,7 +15,7 @@ import gdb import os import re -from linux import modules, utils +from linux import modules, utils, constants if hasattr(gdb, 'Breakpoint'): @@ -109,7 +109,7 @@ lx-symbols command.""" def load_module_symbols(self, module): module_name = module['name'].string() - module_addr = str(module['core_layout']['base']).split()[0] + module_addr = str(module['mem'][constants.LX_MOD_TEXT]['base']).split()[0] module_file = self._get_module_file(module_name) if not module_file and not self.module_files_updated: -- cgit From 87e5b1e8f257023ac5c4d2b8f07716a7f3dcc8ea Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Fri, 31 Mar 2023 17:15:51 +0800 Subject: module: Sync code of is_arm_mapping_symbol() After commit 2e3a10a1551d ("ARM: avoid ARM binutils leaking ELF local symbols") and commit d6b732666a1b ("modpost: fix undefined behavior of is_arm_mapping_symbol()"), many differences of is_arm_mapping_symbol() exist in kernel/module/kallsyms.c and scripts/mod/modpost.c, just sync the code to keep consistent. Signed-off-by: Tiezhu Yang Signed-off-by: Luis Chamberlain --- kernel/module/kallsyms.c | 5 +++-- scripts/mod/modpost.c | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c index 3320586584f1..a9045fe55bcd 100644 --- a/kernel/module/kallsyms.c +++ b/kernel/module/kallsyms.c @@ -251,8 +251,9 @@ static inline int is_arm_mapping_symbol(const char *str) { if (str[0] == '.' && str[1] == 'L') return true; - return str[0] == '$' && strchr("axtd", str[1]) && - (str[2] == '\0' || str[2] == '.'); + return str[0] == '$' && + (str[1] == 'a' || str[1] == 'd' || str[1] == 't' || str[1] == 'x') + && (str[2] == '\0' || str[2] == '.'); } static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, unsigned int symnum) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index efff8078e395..79a27cc5f0b1 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1114,6 +1114,8 @@ static int secref_whitelist(const struct sectioncheck *mismatch, static inline int is_arm_mapping_symbol(const char *str) { + if (str[0] == '.' && str[1] == 'L') + return true; return str[0] == '$' && (str[1] == 'a' || str[1] == 'd' || str[1] == 't' || str[1] == 'x') && (str[2] == '\0' || str[2] == '.'); -- cgit From 987d2e0aaa55de40938435be760aa96428470fd6 Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Fri, 31 Mar 2023 17:15:52 +0800 Subject: module: Move is_arm_mapping_symbol() to module_symbol.h In order to avoid duplicated code, move is_arm_mapping_symbol() to include/linux/module_symbol.h, then remove is_arm_mapping_symbol() in the other places. Signed-off-by: Tiezhu Yang Signed-off-by: Luis Chamberlain --- include/linux/module_symbol.h | 15 +++++++++++++++ kernel/module/kallsyms.c | 14 +------------- scripts/mod/modpost.c | 10 +--------- 3 files changed, 17 insertions(+), 22 deletions(-) create mode 100644 include/linux/module_symbol.h (limited to 'scripts') diff --git a/include/linux/module_symbol.h b/include/linux/module_symbol.h new file mode 100644 index 000000000000..9fa4173d0197 --- /dev/null +++ b/include/linux/module_symbol.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _LINUX_MODULE_SYMBOL_H +#define _LINUX_MODULE_SYMBOL_H + +/* This ignores the intensely annoying "mapping symbols" found in ELF files. */ +static inline int is_arm_mapping_symbol(const char *str) +{ + if (str[0] == '.' && str[1] == 'L') + return true; + return str[0] == '$' && + (str[1] == 'a' || str[1] == 'd' || str[1] == 't' || str[1] == 'x') + && (str[2] == '\0' || str[2] == '.'); +} + +#endif /* _LINUX_MODULE_SYMBOL_H */ diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c index a9045fe55bcd..5de3207f18af 100644 --- a/kernel/module/kallsyms.c +++ b/kernel/module/kallsyms.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -243,19 +244,6 @@ void init_build_id(struct module *mod, const struct load_info *info) } #endif -/* - * This ignores the intensely annoying "mapping symbols" found - * in ARM ELF files: $a, $t and $d. - */ -static inline int is_arm_mapping_symbol(const char *str) -{ - if (str[0] == '.' && str[1] == 'L') - return true; - return str[0] == '$' && - (str[1] == 'a' || str[1] == 'd' || str[1] == 't' || str[1] == 'x') - && (str[2] == '\0' || str[2] == '.'); -} - static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, unsigned int symnum) { return kallsyms->strtab + kallsyms->symtab[symnum].st_name; diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 79a27cc5f0b1..7241db81ffde 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -22,6 +22,7 @@ #include #include "modpost.h" #include "../../include/linux/license.h" +#include "../../include/linux/module_symbol.h" /* Are we using CONFIG_MODVERSIONS? */ static bool modversions; @@ -1112,15 +1113,6 @@ static int secref_whitelist(const struct sectioncheck *mismatch, return 1; } -static inline int is_arm_mapping_symbol(const char *str) -{ - if (str[0] == '.' && str[1] == 'L') - return true; - return str[0] == '$' && - (str[1] == 'a' || str[1] == 'd' || str[1] == 't' || str[1] == 'x') - && (str[2] == '\0' || str[2] == '.'); -} - /* * If there's no name there, ignore it; likewise, ignore it if it's * one of the magic symbols emitted used by current ARM tools. -- cgit From 0a3bf86092c38f7b72c56c6901c78dd302411307 Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Fri, 31 Mar 2023 17:15:53 +0800 Subject: module: Ignore L0 and rename is_arm_mapping_symbol() The L0 symbol is generated when build module on LoongArch, ignore it in modpost and when looking at module symbols, otherwise we can not see the expected call trace. Now is_arm_mapping_symbol() is not only for ARM, in order to reflect the reality, rename is_arm_mapping_symbol() to is_mapping_symbol(). This is related with commit c17a2538704f ("mksysmap: Fix the mismatch of 'L0' symbols in System.map"). (1) Simple test case [loongson@linux hello]$ cat hello.c #include #include #include static void test_func(void) { pr_info("This is a test\n"); dump_stack(); } static int __init hello_init(void) { pr_warn("Hello, world\n"); test_func(); return 0; } static void __exit hello_exit(void) { pr_warn("Goodbye\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL"); [loongson@linux hello]$ cat Makefile obj-m:=hello.o ccflags-y += -g -Og all: make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean (2) Test environment system: LoongArch CLFS 5.5 https://github.com/sunhaiyong1978/CLFS-for-LoongArch/releases/tag/5.0 It needs to update grub to avoid booting error "invalid magic number". kernel: 6.3-rc1 with loongson3_defconfig + CONFIG_DYNAMIC_FTRACE=y (3) Test result Without this patch: [root@linux hello]# insmod hello.ko [root@linux hello]# dmesg ... Hello, world This is a test ... Call Trace: [<9000000000223728>] show_stack+0x68/0x18c [<90000000013374cc>] dump_stack_lvl+0x60/0x88 [] L0\x01+0x20/0x2c [hello] [] L0\x01+0x20/0x30 [hello] [<900000000022097c>] do_one_initcall+0x88/0x288 [<90000000002df890>] do_init_module+0x54/0x200 [<90000000002e1e18>] __do_sys_finit_module+0xc4/0x114 [<90000000013382e8>] do_syscall+0x7c/0x94 [<9000000000221e3c>] handle_syscall+0xbc/0x158 With this patch: [root@linux hello]# insmod hello.ko [root@linux hello]# dmesg ... Hello, world This is a test ... Call Trace: [<9000000000223728>] show_stack+0x68/0x18c [<90000000013374cc>] dump_stack_lvl+0x60/0x88 [] test_func+0x28/0x34 [hello] [] hello_init+0x28/0x38 [hello] [<900000000022097c>] do_one_initcall+0x88/0x288 [<90000000002df890>] do_init_module+0x54/0x200 [<90000000002e1e18>] __do_sys_finit_module+0xc4/0x114 [<90000000013382e8>] do_syscall+0x7c/0x94 [<9000000000221e3c>] handle_syscall+0xbc/0x158 Signed-off-by: Tiezhu Yang Tested-by: Youling Tang # for LoongArch Signed-off-by: Luis Chamberlain --- include/linux/module_symbol.h | 4 +++- kernel/module/kallsyms.c | 2 +- scripts/mod/modpost.c | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/include/linux/module_symbol.h b/include/linux/module_symbol.h index 9fa4173d0197..7ace7ba30203 100644 --- a/include/linux/module_symbol.h +++ b/include/linux/module_symbol.h @@ -3,10 +3,12 @@ #define _LINUX_MODULE_SYMBOL_H /* This ignores the intensely annoying "mapping symbols" found in ELF files. */ -static inline int is_arm_mapping_symbol(const char *str) +static inline int is_mapping_symbol(const char *str) { if (str[0] == '.' && str[1] == 'L') return true; + if (str[0] == 'L' && str[1] == '0') + return true; return str[0] == '$' && (str[1] == 'a' || str[1] == 'd' || str[1] == 't' || str[1] == 'x') && (str[2] == '\0' || str[2] == '.'); diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c index 5de3207f18af..d8e426a9a0cd 100644 --- a/kernel/module/kallsyms.c +++ b/kernel/module/kallsyms.c @@ -289,7 +289,7 @@ static const char *find_kallsyms_symbol(struct module *mod, * and inserted at a whim. */ if (*kallsyms_symbol_name(kallsyms, i) == '\0' || - is_arm_mapping_symbol(kallsyms_symbol_name(kallsyms, i))) + is_mapping_symbol(kallsyms_symbol_name(kallsyms, i))) continue; if (thisval <= addr && thisval > bestval) { diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 7241db81ffde..5cddf7623945 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1115,7 +1115,7 @@ static int secref_whitelist(const struct sectioncheck *mismatch, /* * If there's no name there, ignore it; likewise, ignore it if it's - * one of the magic symbols emitted used by current ARM tools. + * one of the magic symbols emitted used by current tools. * * Otherwise if find_symbols_between() returns those symbols, they'll * fail the whitelist tests and cause lots of false alarms ... fixable @@ -1128,7 +1128,7 @@ static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym) if (!name || !strlen(name)) return 0; - return !is_arm_mapping_symbol(name); + return !is_mapping_symbol(name); } /** -- cgit From 27d000d635ce48b579988e9b3240352a2a0306e0 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Wed, 12 Apr 2023 12:03:16 -0700 Subject: scripts/objdump-func: Support multiple functions Allow specifying multiple functions on the cmdline. Note this removes the secret EXTRA_ARGS feature. While at it, spread out the awk to make it more readable. Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/0bf5f4f5978660985037b24c6db49b114374eb4d.1681325924.git.jpoimboe@kernel.org --- scripts/objdump-func | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/objdump-func b/scripts/objdump-func index 4eb463dd9f52..7b15b873d0e2 100755 --- a/scripts/objdump-func +++ b/scripts/objdump-func @@ -3,7 +3,7 @@ # # Disassemble a single function. # -# usage: objdump-func +# usage: objdump-func [ ...] set -o errexit set -o nounset @@ -13,17 +13,33 @@ OBJDUMP="${CROSS_COMPILE:-}objdump" command -v gawk >/dev/null 2>&1 || die "gawk isn't installed" usage() { - echo "usage: objdump-func " >&2 + echo "usage: objdump-func [ ...]" >&2 exit 1 } [[ $# -lt 2 ]] && usage OBJ=$1; shift -FUNC=$1; shift - -# Secret feature to allow adding extra objdump args at the end -EXTRA_ARGS=$@ - -# Note this also matches compiler-added suffixes like ".cold", etc -${OBJDUMP} -wdr $EXTRA_ARGS $OBJ | gawk -M -v f=$FUNC '/^$/ { P=0; } $0 ~ "<" f "(\\..*)?>:" { P=1; O=strtonum("0x" $1); } { if (P) { o=strtonum("0x" $1); printf("%04x ", o-O); print $0; } }' +FUNCS=("$@") + +${OBJDUMP} -wdr $OBJ | gawk -M -v _funcs="${FUNCS[*]}" ' + BEGIN { split(_funcs, funcs); } + /^$/ { func_match=0; } + /<.*>:/ { + f = gensub(/.*<(.*)>:/, "\\1", 1); + for (i in funcs) { + # match compiler-added suffixes like ".cold", etc + if (f ~ "^" funcs[i] "(\\..*)?") { + func_match = 1; + base = strtonum("0x" $1); + break; + } + } + } + { + if (func_match) { + addr = strtonum("0x" $1); + printf("%04x ", addr - base); + print; + } + }' -- cgit From f6d8283549bc200e2babdd627239ece3547d634c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 7 Apr 2023 19:16:27 +0900 Subject: kbuild: merge cmd_archive_linux and cmd_archive_perf The two commands, cmd_archive_linux and cmd_archive_perf, are similar. Merge them to make it easier to add more changes to the git-archive command. Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor --- scripts/Makefile.package | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.package b/scripts/Makefile.package index 49aff12cb6ab..d80a9b59f784 100644 --- a/scripts/Makefile.package +++ b/scripts/Makefile.package @@ -57,16 +57,17 @@ check-git: false; \ fi +quiet_cmd_archive = ARCHIVE $@ + cmd_archive = git -C $(srctree) archive \ + --output=$$(realpath $@) --prefix=$(basename $@)/ $(archive-args) + # Linux source tarball # --------------------------------------------------------------------------- -quiet_cmd_archive_linux = ARCHIVE $@ - cmd_archive_linux = \ - git -C $(srctree) archive --output=$$(realpath $@) --prefix=$(basename $@)/ $$(cat $<) - targets += linux.tar +linux.tar: archive-args = $$(cat $<) linux.tar: .tmp_HEAD FORCE - $(call if_changed,archive_linux) + $(call if_changed,archive) # rpm-pkg # --------------------------------------------------------------------------- @@ -181,16 +182,14 @@ quiet_cmd_perf_version_file = GEN $@ .tmp_perf/PERF-VERSION-FILE: .tmp_HEAD $(srctree)/tools/perf/util/PERF-VERSION-GEN | .tmp_perf $(call cmd,perf_version_file) -quiet_cmd_archive_perf = ARCHIVE $@ - cmd_archive_perf = \ - git -C $(srctree) archive --output=$$(realpath $@) --prefix=$(basename $@)/ \ - --add-file=$$(realpath $(word 2, $^)) \ +perf-archive-args = --add-file=$$(realpath $(word 2, $^)) \ --add-file=$$(realpath $(word 3, $^)) \ $$(cat $(word 2, $^))^{tree} $$(cat $<) targets += perf-$(KERNELVERSION).tar +perf-$(KERNELVERSION).tar: archive-args = $(perf-archive-args) perf-$(KERNELVERSION).tar: tools/perf/MANIFEST .tmp_perf/HEAD .tmp_perf/PERF-VERSION-FILE FORCE - $(call if_changed,archive_perf) + $(call if_changed,archive) PHONY += perf-tar-src-pkg perf-tar-src-pkg: perf-$(KERNELVERSION).tar -- cgit From f8d94c4e403c89ec6b09ba69f65e4547ba99dd07 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 7 Apr 2023 19:16:28 +0900 Subject: kbuild: do not create intermediate *.tar for source tarballs Since commit 05e96e96a315 ("kbuild: use git-archive for source package creation"), a source tarball is created in two steps; create *.tar file then compress it. I split the compression as a separate rule because I just thought 'git archive' supported only gzip. For other compression algorithms, I could pipe the two commands: $ git archive HEAD | xz > linux.tar.xz I read git-archive(1) carefully, and I realized GIT had provided a more elegant way: $ git -c tar.tar.xz.command=xz archive -o linux.tar.xz HEAD This commit uses 'tar.tar.*.command' configuration to specify the compression backend so we can compress a source tarball on-the-fly. GIT commit 767cf4579f0e ("archive: implement configurable tar filters") is more than a decade old, so it should be available on almost all build environments. Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor --- scripts/Makefile.package | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.package b/scripts/Makefile.package index d80a9b59f784..ed1784be72ce 100644 --- a/scripts/Makefile.package +++ b/scripts/Makefile.package @@ -57,16 +57,23 @@ check-git: false; \ fi +git-config-tar.gz = -c tar.tar.gz.command="$(KGZIP)" +git-config-tar.bz2 = -c tar.tar.bz2.command="$(KBZIP2)" +git-config-tar.xz = -c tar.tar.xz.command="$(XZ)" +git-config-tar.zst = -c tar.tar.zst.command="$(ZSTD)" + quiet_cmd_archive = ARCHIVE $@ - cmd_archive = git -C $(srctree) archive \ + cmd_archive = git -C $(srctree) $(git-config-tar$(suffix $@)) archive \ --output=$$(realpath $@) --prefix=$(basename $@)/ $(archive-args) # Linux source tarball # --------------------------------------------------------------------------- -targets += linux.tar -linux.tar: archive-args = $$(cat $<) -linux.tar: .tmp_HEAD FORCE +linux-tarballs := $(addprefix linux, .tar.gz) + +targets += $(linux-tarballs) +$(linux-tarballs): archive-args = $$(cat $<) +$(linux-tarballs): .tmp_HEAD FORCE $(call if_changed,archive) # rpm-pkg @@ -186,9 +193,12 @@ perf-archive-args = --add-file=$$(realpath $(word 2, $^)) \ --add-file=$$(realpath $(word 3, $^)) \ $$(cat $(word 2, $^))^{tree} $$(cat $<) -targets += perf-$(KERNELVERSION).tar -perf-$(KERNELVERSION).tar: archive-args = $(perf-archive-args) -perf-$(KERNELVERSION).tar: tools/perf/MANIFEST .tmp_perf/HEAD .tmp_perf/PERF-VERSION-FILE FORCE + +perf-tarballs := $(addprefix perf-$(KERNELVERSION), .tar .tar.gz .tar.bz2 .tar.xz .tar.zst) + +targets += $(perf-tarballs) +$(perf-tarballs): archive-args = $(perf-archive-args) +$(perf-tarballs): tools/perf/MANIFEST .tmp_perf/HEAD .tmp_perf/PERF-VERSION-FILE FORCE $(call if_changed,archive) PHONY += perf-tar-src-pkg -- cgit From 3c65a2704cdd2a0cd0766352e587bae4a6268155 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 7 Apr 2023 19:16:29 +0900 Subject: kbuild: do not create intermediate *.tar for tar packages Commit 05e96e96a315 ("kbuild: use git-archive for source package creation") split the compression as a separate step to factor out the common build rules. With the previous commit, we got back to the situation where source tarballs are compressed on-the-fly. There is no reason to keep the separate compression rules. Generate the comressed tar packages directly. Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor --- scripts/Makefile.package | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.package b/scripts/Makefile.package index ed1784be72ce..4d90691505b1 100644 --- a/scripts/Makefile.package +++ b/scripts/Makefile.package @@ -27,21 +27,6 @@ fi ; \ tar -I $(KGZIP) -c $(RCS_TAR_IGNORE) -f $(2).tar.gz \ --transform 's:^:$(2)/:S' $(TAR_CONTENT) $(3) -# tarball compression -# --------------------------------------------------------------------------- - -%.tar.gz: %.tar - $(call cmd,gzip) - -%.tar.bz2: %.tar - $(call cmd,bzip2) - -%.tar.xz: %.tar - $(call cmd,xzmisc) - -%.tar.zst: %.tar - $(call cmd,zstd) - # Git # --------------------------------------------------------------------------- @@ -154,10 +139,17 @@ tar-install: FORCE $(Q)$(MAKE) -f $(srctree)/Makefile +$(Q)$(srctree)/scripts/package/buildtar $@ +compress-tar.gz = -I "$(KGZIP)" +compress-tar.bz2 = -I "$(KBZIP2)" +compress-tar.xz = -I "$(XZ)" +compress-tar.zst = -I "$(ZSTD)" + quiet_cmd_tar = TAR $@ - cmd_tar = cd $<; tar cf ../$@ --owner=root --group=root --sort=name * + cmd_tar = cd $<; tar cf ../$@ $(compress-tar$(suffix $@)) --owner=root --group=root --sort=name * + +dir-tarballs := $(addprefix linux-$(KERNELRELEASE)-$(ARCH), .tar .tar.gz .tar.bz2 .tar.xz .tar.zst) -linux-$(KERNELRELEASE)-$(ARCH).tar: tar-install +$(dir-tarballs): tar-install $(call cmd,tar) PHONY += dir-pkg -- cgit From bea5b74504742f1b51b815bcaf9a70bddbc49ce3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 6 Mar 2023 11:14:51 +0100 Subject: kallsyms: expand symbol name into comment for debugging The assembler output of kallsyms.c is not meant for people to understand, and is generally not helpful when debugging "Inconsistent kallsyms data" warnings. I have previously struggled with these, but found it helpful to list which symbols changed between the first and second pass in the .tmp_vmlinux.kallsyms*.S files. As this file is preprocessed, it's possible to add a C-style multiline comment with the full type/name tuple. Signed-off-by: Arnd Bergmann Signed-off-by: Masahiro Yamada --- scripts/kallsyms.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index a239a87e7bec..ea1e3d3aaa6b 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -525,7 +525,8 @@ static void write_src(void) table[i]->addr); exit(EXIT_FAILURE); } - printf("\t.long\t%#x\n", (int)offset); + expand_symbol(table[i]->sym, table[i]->len, buf); + printf("\t.long\t%#x /* %s */\n", (int)offset, buf); } else if (!symbol_absolute(table[i])) { output_address(table[i]->addr); } else { -- cgit From a7b00a1811c9e562b44f0b283de7f01443123390 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Mar 2023 20:52:36 +0900 Subject: scripts/kallsyms: remove redundant code for omitting U and N The symbol types 'U' and 'N' are already filtered out by the following line in scripts/mksysmap: -e ' [aNUw] ' Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/kallsyms.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index ea1e3d3aaa6b..8148e880f78e 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -178,10 +178,7 @@ static bool is_ignored_symbol(const char *name, char type) return true; } - if (type == 'U' || type == 'u') - return true; - /* exclude debugging symbols */ - if (type == 'N' || type == 'n') + if (type == 'u' || type == 'n') return true; if (toupper(type) == 'A') { -- cgit From e9f76363d0aa2d7c01288d9aad79b7e44855a435 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Mar 2023 20:52:37 +0900 Subject: scripts/mksysmap: remove comments described in nm(1) I do not think we need to repeat what is written in 'man nm'. Signed-off-by: Masahiro Yamada --- scripts/mksysmap | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'scripts') diff --git a/scripts/mksysmap b/scripts/mksysmap index 16a08b8ef2f8..fea65fc3b624 100755 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -9,25 +9,7 @@ ##### # Generate System.map (actual filename passed as second argument) - -# $NM produces the following output: -# f0081e80 T alloc_vfsmnt - -# The second row specify the type of the symbol: -# A = Absolute -# B = Uninitialised data (.bss) -# C = Common symbol -# D = Initialised data -# G = Initialised data for small objects -# I = Indirect reference to another symbol -# N = Debugging symbol -# R = Read only -# S = Uninitialised data for small objects -# T = Text code symbol -# U = Undefined symbol -# V = Weak symbol -# W = Weak symbol -# Corresponding small letters are local symbols +# The following refers to the symbol type as per nm(1). # For System.map filter away: # a - local absolute symbols -- cgit From c4802044a0a7d7dfa82af858c2fa3ae9d76249c4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Mar 2023 20:52:38 +0900 Subject: scripts/mksysmap: use sed with in-line comments It is not feasible to insert comments in a multi-line shell command. Use sed, and move comments close to the code. Signed-off-by: Masahiro Yamada --- scripts/mksysmap | 61 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 24 deletions(-) (limited to 'scripts') diff --git a/scripts/mksysmap b/scripts/mksysmap index fea65fc3b624..41ad4605aeef 100755 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -11,32 +11,45 @@ # Generate System.map (actual filename passed as second argument) # The following refers to the symbol type as per nm(1). -# For System.map filter away: -# a - local absolute symbols -# U - undefined global symbols -# N - debugging symbols -# w - local weak symbols - # readprofile starts reading symbols when _stext is found, and # continue until it finds a symbol which is not either of 'T', 't', # 'W' or 'w'. # -# Ignored prefixes: -# $ - local symbols for ARM, MIPS, etc. -# .L - local labels, .LBB,.Ltmpxxx,.L__unnamed_xx,.LASANPC, etc. -# __crc_ - modversions -# __kstrtab_ - EXPORT_SYMBOL (symbol name) -# __kstrtabns_ - EXPORT_SYMBOL (namespace) + +${NM} -n ${1} | sed >${2} -e " +# --------------------------------------------------------------------------- +# Ignored symbol types # -# Ignored symbols: -# L0 - for LoongArch? - -$NM -n $1 | grep -v \ - -e ' [aNUw] ' \ - -e ' \$' \ - -e ' \.L' \ - -e ' __crc_' \ - -e ' __kstrtab_' \ - -e ' __kstrtabns_' \ - -e ' L0$' \ -> $2 + +# a: local absolute symbols +# N: debugging symbols +# U: undefined global symbols +# w: local weak symbols +/ [aNUw] /d + +# --------------------------------------------------------------------------- +# Ignored prefixes +# (do not forget a space before each pattern) + +# local symbols for ARM, MIPS, etc. +/ \$/d + +# local labels, .LBB, .Ltmpxxx, .L__unnamed_xx, .LASANPC, etc. +/ \.L/d + +# CRC from modversions +/ __crc_/d + +# EXPORT_SYMBOL (symbol name) +/ __kstrtab_/d + +# EXPORT_SYMBOL (namespace) +/ __kstrtabns_/d + +# --------------------------------------------------------------------------- +# Ignored symbols (exact match) +# (do not forget a space before and '$' after each pattern) + +# for LoongArch? +/ L0$/d +" -- cgit From ca09bf48f99bdc08e17da11aeae56b7ea132b7c8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Mar 2023 20:52:39 +0900 Subject: scripts/kallsyms: exclude symbols generated by itself dynamically Drop the symbols generated by scripts/kallsyms itself automatically instead of maintaining the symbol list manually. Pass the kallsyms object from the previous kallsyms step (if it exists) as the third parameter of scripts/mksysmap, which will weed out the generated symbols from the input to the next kallsyms step. Signed-off-by: Masahiro Yamada --- scripts/kallsyms.c | 16 ---------------- scripts/link-vmlinux.sh | 6 +++--- scripts/mksysmap | 11 ++++++++++- 3 files changed, 13 insertions(+), 20 deletions(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 8148e880f78e..0325d0d3ce97 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -104,22 +104,6 @@ static bool is_ignored_symbol(const char *name, char type) { /* Symbol names that exactly match to the following are ignored.*/ static const char * const ignored_symbols[] = { - /* - * Symbols which vary between passes. Passes 1 and 2 must have - * identical symbol lists. The kallsyms_* symbols below are - * only added after pass 1, they would be included in pass 2 - * when --all-symbols is specified so exclude them to get a - * stable symbol list. - */ - "kallsyms_addresses", - "kallsyms_offsets", - "kallsyms_relative_base", - "kallsyms_num_syms", - "kallsyms_names", - "kallsyms_markers", - "kallsyms_token_table", - "kallsyms_token_index", - "kallsyms_seqs_of_names", /* Exclude linker generated symbols which vary between passes */ "_SDA_BASE_", /* ppc */ "_SDA2_BASE_", /* ppc */ diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 32e573943cf0..679eb4653b16 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -174,7 +174,7 @@ kallsyms_step() kallsyms_S=${kallsyms_vmlinux}.S vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o} - mksysmap ${kallsyms_vmlinux} ${kallsyms_vmlinux}.syms + mksysmap ${kallsyms_vmlinux} ${kallsyms_vmlinux}.syms ${kallsymso_prev} kallsyms ${kallsyms_vmlinux}.syms ${kallsyms_S} info AS ${kallsyms_S} @@ -188,7 +188,7 @@ kallsyms_step() mksysmap() { info NM ${2} - ${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2} + ${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2} ${3} } sorttable() @@ -277,7 +277,7 @@ if is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then ${RESOLVE_BTFIDS} vmlinux fi -mksysmap vmlinux System.map +mksysmap vmlinux System.map ${kallsymso} if is_enabled CONFIG_BUILDTIME_TABLE_SORT; then info SORTTAB vmlinux diff --git a/scripts/mksysmap b/scripts/mksysmap index 41ad4605aeef..ff91ec8ecca7 100755 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -4,7 +4,7 @@ # tools to retrieve the actual addresses of symbols in the kernel. # # Usage -# mksysmap vmlinux System.map +# mksysmap vmlinux System.map [exclude] ##### @@ -52,4 +52,13 @@ ${NM} -n ${1} | sed >${2} -e " # for LoongArch? / L0$/d + +# --------------------------------------------------------------------------- +# Ignored kallsyms symbols +# +# If the 3rd parameter exists, symbols from it will be omitted from the output. +# This makes kallsyms have the identical symbol lists in the step 1 and 2. +# Without this, the step2 would get new symbols generated by scripts/kallsyms.c +# when CONFIG_KALLSYMS_ALL is enabled. That might require one more pass. +$(if [ $# -ge 3 ]; then ${NM} ${3} | sed -n '/ U /!s:.* \([^ ]*\)$:/ \1$/d:p'; fi) " -- cgit From 320e7c9d4494f7a6f046871678f582a3392235f8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Mar 2023 20:52:40 +0900 Subject: scripts/kallsyms: move compiler-generated symbol patterns to mksysmap scripts/kallsyms.c maintains compiler-generated symbols, but we end up with something similar in scripts/mksysmap to avoid the "Inconsistent kallsyms data" error. For example, commit c17a2538704f ("mksysmap: Fix the mismatch of 'L0' symbols in System.map"). They were separately maintained prior to commit 94ff2f63d6a3 ("kbuild: reuse mksysmap output for kallsyms"). Now that scripts/kallsyms.c parses the output of scripts/mksysmap, it makes more sense to collect all the ignored patterns to mksysmap. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/kallsyms.c | 60 ------------------------------------------------------ scripts/mksysmap | 43 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 60 deletions(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 0325d0d3ce97..97d514c0fc8f 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -102,66 +102,6 @@ static char *sym_name(const struct sym_entry *s) static bool is_ignored_symbol(const char *name, char type) { - /* Symbol names that exactly match to the following are ignored.*/ - static const char * const ignored_symbols[] = { - /* Exclude linker generated symbols which vary between passes */ - "_SDA_BASE_", /* ppc */ - "_SDA2_BASE_", /* ppc */ - NULL - }; - - /* Symbol names that begin with the following are ignored.*/ - static const char * const ignored_prefixes[] = { - "__efistub_", /* arm64 EFI stub namespace */ - "__kvm_nvhe_$", /* arm64 local symbols in non-VHE KVM namespace */ - "__kvm_nvhe_.L", /* arm64 local symbols in non-VHE KVM namespace */ - "__AArch64ADRPThunk_", /* arm64 lld */ - "__ARMV5PILongThunk_", /* arm lld */ - "__ARMV7PILongThunk_", - "__ThumbV7PILongThunk_", - "__LA25Thunk_", /* mips lld */ - "__microLA25Thunk_", - "__kcfi_typeid_", /* CFI type identifiers */ - NULL - }; - - /* Symbol names that end with the following are ignored.*/ - static const char * const ignored_suffixes[] = { - "_from_arm", /* arm */ - "_from_thumb", /* arm */ - "_veneer", /* arm */ - NULL - }; - - /* Symbol names that contain the following are ignored.*/ - static const char * const ignored_matches[] = { - ".long_branch.", /* ppc stub */ - ".plt_branch.", /* ppc stub */ - NULL - }; - - const char * const *p; - - for (p = ignored_symbols; *p; p++) - if (!strcmp(name, *p)) - return true; - - for (p = ignored_prefixes; *p; p++) - if (!strncmp(name, *p, strlen(*p))) - return true; - - for (p = ignored_suffixes; *p; p++) { - int l = strlen(name) - strlen(*p); - - if (l >= 0 && !strcmp(name + l, *p)) - return true; - } - - for (p = ignored_matches; *p; p++) { - if (strstr(name, *p)) - return true; - } - if (type == 'u' || type == 'n') return true; diff --git a/scripts/mksysmap b/scripts/mksysmap index ff91ec8ecca7..cb3b1fff3eee 100755 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -37,6 +37,28 @@ ${NM} -n ${1} | sed >${2} -e " # local labels, .LBB, .Ltmpxxx, .L__unnamed_xx, .LASANPC, etc. / \.L/d +# arm64 EFI stub namespace +/ __efistub_/d + +# arm64 local symbols in non-VHE KVM namespace +/ __kvm_nvhe_\$/d +/ __kvm_nvhe_\.L/d + +# arm64 lld +/ __AArch64ADRPThunk_/d + +# arm lld +/ __ARMV5PILongThunk_/d +/ __ARMV7PILongThunk_/d +/ __ThumbV7PILongThunk_/d + +# mips lld +/ __LA25Thunk_/d +/ __microLA25Thunk_/d + +# CFI type identifiers +/ __kcfi_typeid_/d + # CRC from modversions / __crc_/d @@ -46,6 +68,15 @@ ${NM} -n ${1} | sed >${2} -e " # EXPORT_SYMBOL (namespace) / __kstrtabns_/d +# --------------------------------------------------------------------------- +# Ignored suffixes +# (do not forget '$' after each pattern) + +# arm +/_from_arm$/d +/_from_thumb$/d +/_veneer$/d + # --------------------------------------------------------------------------- # Ignored symbols (exact match) # (do not forget a space before and '$' after each pattern) @@ -53,6 +84,18 @@ ${NM} -n ${1} | sed >${2} -e " # for LoongArch? / L0$/d +# ppc +/ _SDA_BASE_$/d +/ _SDA2_BASE_$/d + +# --------------------------------------------------------------------------- +# Ignored patterns +# (symbols that contain the pattern are ignored) + +# ppc stub +/\.long_branch\./d +/\.plt_branch\./d + # --------------------------------------------------------------------------- # Ignored kallsyms symbols # -- cgit From 404bad70fcf7cb1a36198581e6904637f3c36846 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Mar 2023 20:52:41 +0900 Subject: scripts/kallsyms: change the output order Currently, this tool outputs symbol data in the following order. (1) kallsyms_addressed / kallsyms_offsets (2) kallsyms_relative_base (3) kallsyms_num_syms (4) kallsyms_names (5) kallsyms_markers (6) kallsyms_seq_of_names (7) kallsyms_token_table (8) kallsyms_token_index This commit changes the order as follows: (1) kallsyms_num_syms (2) kallsyms_names (3) kallsyms_markers (4) kallsyms_token_table (5) kallsyms_token_index (6) kallsyms_addressed / kallsyms_offsets (7) kallsyms_relative_base (8) kallsyms_seq_of_names The motivation is to decrease the number of function calls to expand_symbol() and cleanup_symbol_name(). The compressed names are only required for writing 'kallsyms_names'. If you do this first, we can restore the original symbol names. You do not need to repeat the same operation over again. The actual refactoring will happen in the next commit. Signed-off-by: Masahiro Yamada --- scripts/kallsyms.c | 118 ++++++++++++++++++++++++++--------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 97d514c0fc8f..5996f1e61bcf 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -412,56 +412,6 @@ static void write_src(void) printf("\t.section .rodata, \"a\"\n"); - if (!base_relative) - output_label("kallsyms_addresses"); - else - output_label("kallsyms_offsets"); - - for (i = 0; i < table_cnt; i++) { - if (base_relative) { - /* - * Use the offset relative to the lowest value - * encountered of all relative symbols, and emit - * non-relocatable fixed offsets that will be fixed - * up at runtime. - */ - - long long offset; - int overflow; - - if (!absolute_percpu) { - offset = table[i]->addr - relative_base; - overflow = (offset < 0 || offset > UINT_MAX); - } else if (symbol_absolute(table[i])) { - offset = table[i]->addr; - overflow = (offset < 0 || offset > INT_MAX); - } else { - offset = relative_base - table[i]->addr - 1; - overflow = (offset < INT_MIN || offset >= 0); - } - if (overflow) { - fprintf(stderr, "kallsyms failure: " - "%s symbol value %#llx out of range in relative mode\n", - symbol_absolute(table[i]) ? "absolute" : "relative", - table[i]->addr); - exit(EXIT_FAILURE); - } - expand_symbol(table[i]->sym, table[i]->len, buf); - printf("\t.long\t%#x /* %s */\n", (int)offset, buf); - } else if (!symbol_absolute(table[i])) { - output_address(table[i]->addr); - } else { - printf("\tPTR\t%#llx\n", table[i]->addr); - } - } - printf("\n"); - - if (base_relative) { - output_label("kallsyms_relative_base"); - output_address(relative_base); - printf("\n"); - } - output_label("kallsyms_num_syms"); printf("\t.long\t%u\n", table_cnt); printf("\n"); @@ -521,15 +471,6 @@ static void write_src(void) free(markers); - sort_symbols_by_name(); - output_label("kallsyms_seqs_of_names"); - for (i = 0; i < table_cnt; i++) - printf("\t.byte 0x%02x, 0x%02x, 0x%02x\n", - (unsigned char)(table[i]->seq >> 16), - (unsigned char)(table[i]->seq >> 8), - (unsigned char)(table[i]->seq >> 0)); - printf("\n"); - output_label("kallsyms_token_table"); off = 0; for (i = 0; i < 256; i++) { @@ -544,6 +485,65 @@ static void write_src(void) for (i = 0; i < 256; i++) printf("\t.short\t%d\n", best_idx[i]); printf("\n"); + + if (!base_relative) + output_label("kallsyms_addresses"); + else + output_label("kallsyms_offsets"); + + for (i = 0; i < table_cnt; i++) { + if (base_relative) { + /* + * Use the offset relative to the lowest value + * encountered of all relative symbols, and emit + * non-relocatable fixed offsets that will be fixed + * up at runtime. + */ + + long long offset; + int overflow; + + if (!absolute_percpu) { + offset = table[i]->addr - relative_base; + overflow = (offset < 0 || offset > UINT_MAX); + } else if (symbol_absolute(table[i])) { + offset = table[i]->addr; + overflow = (offset < 0 || offset > INT_MAX); + } else { + offset = relative_base - table[i]->addr - 1; + overflow = (offset < INT_MIN || offset >= 0); + } + if (overflow) { + fprintf(stderr, "kallsyms failure: " + "%s symbol value %#llx out of range in relative mode\n", + symbol_absolute(table[i]) ? "absolute" : "relative", + table[i]->addr); + exit(EXIT_FAILURE); + } + expand_symbol(table[i]->sym, table[i]->len, buf); + printf("\t.long\t%#x /* %s */\n", (int)offset, buf); + } else if (!symbol_absolute(table[i])) { + output_address(table[i]->addr); + } else { + printf("\tPTR\t%#llx\n", table[i]->addr); + } + } + printf("\n"); + + if (base_relative) { + output_label("kallsyms_relative_base"); + output_address(relative_base); + printf("\n"); + } + + sort_symbols_by_name(); + output_label("kallsyms_seqs_of_names"); + for (i = 0; i < table_cnt; i++) + printf("\t.byte 0x%02x, 0x%02x, 0x%02x\n", + (unsigned char)(table[i]->seq >> 16), + (unsigned char)(table[i]->seq >> 8), + (unsigned char)(table[i]->seq >> 0)); + printf("\n"); } -- cgit From dd1553b8a5f2ef4e0aa2537c49ba0c37837b691e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Mar 2023 20:52:42 +0900 Subject: scripts/kallsyms: decrease expand_symbol() / cleanup_symbol_name() calls Currently, expand_symbol() is called many times to get the uncompressed symbol names for sorting, and also for adding comments. With the output order shuffled in the previous commit, the symbol data are now written in the following order: (1) kallsyms_num_syms (2) kallsyms_names <-- need compressed names (3) kallsyms_markers (4) kallsyms_token_table (5) kallsyms_token_index (6) kallsyms_addressed / kallsyms_offsets <-- need uncompressed names (for commenting) (7) kallsyms_relative_base (8) kallsyms_seq_of_names <-- need uncompressed names (for sorting) The compressed names are only needed by (2). Call expand_symbol() between (2) and (3) to restore the original symbol names. This requires just one expand_symbol() call for each symbol. Call cleanup_symbol_name() between (7) and (8) instead of during sorting. It is allowed to overwrite the ->sym field because (8) just outputs the index instead of the name of each symbol. Again, this requires just one cleanup_symbol_name() call for each symbol. This refactoring makes it ~30% faster. [Before] $ time scripts/kallsyms --all-symbols --absolute-percpu --base-relative \ .tmp_vmlinux.kallsyms2.syms >/dev/null real 0m1.027s user 0m1.010s sys 0m0.016s [After] $ time scripts/kallsyms --all-symbols --absolute-percpu --base-relative \ .tmp_vmlinux.kallsyms2.syms >/dev/null real 0m0.717s user 0m0.717s sys 0m0.000s Signed-off-by: Masahiro Yamada --- scripts/kallsyms.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 5996f1e61bcf..937900823fa8 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -335,19 +335,10 @@ static int symbol_absolute(const struct sym_entry *s) return s->percpu_absolute; } -static char * s_name(char *buf) -{ - /* Skip the symbol type */ - return buf + 1; -} - static void cleanup_symbol_name(char *s) { char *p; - if (!lto_clang) - return; - /* * ASCII[.] = 2e * ASCII[0-9] = 30,39 @@ -366,16 +357,10 @@ static void cleanup_symbol_name(char *s) static int compare_names(const void *a, const void *b) { int ret; - char sa_namebuf[KSYM_NAME_LEN]; - char sb_namebuf[KSYM_NAME_LEN]; const struct sym_entry *sa = *(const struct sym_entry **)a; const struct sym_entry *sb = *(const struct sym_entry **)b; - expand_symbol(sa->sym, sa->len, sa_namebuf); - expand_symbol(sb->sym, sb->len, sb_namebuf); - cleanup_symbol_name(s_name(sa_namebuf)); - cleanup_symbol_name(s_name(sb_namebuf)); - ret = strcmp(s_name(sa_namebuf), s_name(sb_namebuf)); + ret = strcmp(sym_name(sa), sym_name(sb)); if (!ret) { if (sa->addr > sb->addr) return 1; @@ -464,6 +449,15 @@ static void write_src(void) } printf("\n"); + /* + * Now that we wrote out the compressed symbol names, restore the + * original names, which are needed in some of the later steps. + */ + for (i = 0; i < table_cnt; i++) { + expand_symbol(table[i]->sym, table[i]->len, buf); + strcpy((char *)table[i]->sym, buf); + } + output_label("kallsyms_markers"); for (i = 0; i < ((table_cnt + 255) >> 8); i++) printf("\t.long\t%u\n", markers[i]); @@ -520,8 +514,7 @@ static void write_src(void) table[i]->addr); exit(EXIT_FAILURE); } - expand_symbol(table[i]->sym, table[i]->len, buf); - printf("\t.long\t%#x /* %s */\n", (int)offset, buf); + printf("\t.long\t%#x /* %s */\n", (int)offset, table[i]->sym); } else if (!symbol_absolute(table[i])) { output_address(table[i]->addr); } else { @@ -536,6 +529,10 @@ static void write_src(void) printf("\n"); } + if (lto_clang) + for (i = 0; i < table_cnt; i++) + cleanup_symbol_name((char *)table[i]->sym); + sort_symbols_by_name(); output_label("kallsyms_seqs_of_names"); for (i = 0; i < table_cnt; i++) -- cgit From 79549da691edd4874c19d99c578a134471817c47 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Mar 2023 20:52:43 +0900 Subject: scripts/kallsyms: update the usage in the comment block Commit 010a0aad39fc ("kallsyms: Correctly sequence symbols when CONFIG_LTO_CLANG=y") added --lto-clang, and updated the usage() function, but not the comment. Update it in the same way. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/kallsyms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 937900823fa8..0d2db41177b2 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -6,7 +6,7 @@ * of the GNU General Public License, incorporated herein by reference. * * Usage: kallsyms [--all-symbols] [--absolute-percpu] - * [--base-relative] in.map > out.S + * [--base-relative] [--lto-clang] in.map > out.S * * Table compression uses all the unused char codes on the symbols and * maps these to the most used substrings (tokens). For instance, it might -- cgit From 491b146d4c13908a23436bd44dc1f01d1a0a99e6 Mon Sep 17 00:00:00 2001 From: Bastian Germann Date: Tue, 14 Mar 2023 01:40:22 +0100 Subject: kbuild: builddeb: Eliminate debian/arch use In the builddeb context, the DEB_HOST_ARCH environment variable is set to the same value as debian/arch's content, so use the variable with dpkg-architecture. This is the last use of the debian/arch file during dpkg-buildpackage time. Signed-off-by: Bastian Germann Signed-off-by: Masahiro Yamada --- scripts/package/builddeb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 7b23f52c70c5..252faaa5561c 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -209,7 +209,7 @@ install_libc_headers () { # move asm headers to /usr/include//asm to match the structure # used by Debian-based distros (to support multi-arch) - host_arch=$(dpkg-architecture -a$(cat debian/arch) -qDEB_HOST_MULTIARCH) + host_arch=$(dpkg-architecture -a$DEB_HOST_ARCH -qDEB_HOST_MULTIARCH) mkdir $pdir/usr/include/$host_arch mv $pdir/usr/include/asm $pdir/usr/include/$host_arch/ } -- cgit From 90fe4c506c855ee90116a96ec25fa39ea8e9f202 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 26 Mar 2023 00:18:15 +0900 Subject: kconfig: menuconfig: remove OLD_NCURSES macro This code has been here for more than 20 years. The bug in the old days no longer matters. Signed-off-by: Masahiro Yamada --- scripts/kconfig/lxdialog/dialog.h | 16 ---------------- scripts/kconfig/lxdialog/menubox.c | 8 -------- scripts/kconfig/lxdialog/textbox.c | 9 --------- 3 files changed, 33 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h index 68b565e3c495..bd2da3a928a7 100644 --- a/scripts/kconfig/lxdialog/dialog.h +++ b/scripts/kconfig/lxdialog/dialog.h @@ -18,22 +18,6 @@ #endif #include -/* - * Colors in ncurses 1.9.9e do not work properly since foreground and - * background colors are OR'd rather than separately masked. This version - * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible - * with standard curses. The simplest fix (to make this work with standard - * curses) uses the wbkgdset() function, not used in the original hack. - * Turn it off if we're building with 1.9.9e, since it just confuses things. - */ -#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE) -#define OLD_NCURSES 1 -#undef wbkgdset -#define wbkgdset(w,p) /*nothing */ -#else -#define OLD_NCURSES 0 -#endif - #define TR(params) _tracef params #define KEY_ESC 27 diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c index 58c2f8afe59b..0e333284e947 100644 --- a/scripts/kconfig/lxdialog/menubox.c +++ b/scripts/kconfig/lxdialog/menubox.c @@ -63,15 +63,7 @@ static void do_print_item(WINDOW * win, const char *item, int line_y, /* Clear 'residue' of last item */ wattrset(win, dlg.menubox.atr); wmove(win, line_y, 0); -#if OLD_NCURSES - { - int i; - for (i = 0; i < menu_width; i++) - waddch(win, ' '); - } -#else wclrtoeol(win); -#endif wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); mvwaddstr(win, line_y, item_x, menu_item); if (hotkey) { diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c index 4e339b12664e..4a6ff9de45b9 100644 --- a/scripts/kconfig/lxdialog/textbox.c +++ b/scripts/kconfig/lxdialog/textbox.c @@ -336,16 +336,7 @@ static void print_line(WINDOW * win, int row, int width) waddnstr(win, line, MIN(strlen(line), width - 2)); /* Clear 'residue' of previous line */ -#if OLD_NCURSES - { - int x = getcurx(win); - int i; - for (i = 0; i < width - x; i++) - waddch(win, ' '); - } -#else wclrtoeol(win); -#endif } /* -- cgit From b84e3687da9436c5438021800ce2d7baa03c2eab Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 26 Mar 2023 00:18:16 +0900 Subject: kconfig: menuconfig: remove unused M_EVENT macro This is not used anywhere. Signed-off-by: Masahiro Yamada --- scripts/kconfig/lxdialog/dialog.h | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h index bd2da3a928a7..347daf25fdc8 100644 --- a/scripts/kconfig/lxdialog/dialog.h +++ b/scripts/kconfig/lxdialog/dialog.h @@ -209,14 +209,3 @@ int dialog_checklist(const char *title, const char *prompt, int height, int width, int list_height); int dialog_inputbox(const char *title, const char *prompt, int height, int width, const char *init); - -/* - * This is the base for fictitious keys, which activate - * the buttons. - * - * Mouse-generated keys are the following: - * -- the first 32 are used as numbers, in addition to '0'-'9' - * -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o') - * -- uppercase chars are used to invoke the button (M_EVENT + 'O') - */ -#define M_EVENT (KEY_MAX+1) -- cgit From fb318e54fea6b8532833faef98c8b7720a30b29d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 26 Mar 2023 00:18:17 +0900 Subject: kconfig: menuconfig: reorder functions to remove forward declarations Define helper functions before the callers so that forward declarations can go away. Signed-off-by: Masahiro Yamada --- scripts/kconfig/lxdialog/textbox.c | 258 +++++++++++++++--------------- scripts/kconfig/mconf.c | 314 ++++++++++++++++++------------------- 2 files changed, 277 insertions(+), 295 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c index 4a6ff9de45b9..bc4d4fb1dc75 100644 --- a/scripts/kconfig/lxdialog/textbox.c +++ b/scripts/kconfig/lxdialog/textbox.c @@ -8,18 +8,136 @@ #include "dialog.h" -static void back_lines(int n); -static void print_page(WINDOW *win, int height, int width, update_text_fn - update_text, void *data); -static void print_line(WINDOW *win, int row, int width); -static char *get_line(void); -static void print_position(WINDOW * win); - static int hscroll; static int begin_reached, end_reached, page_length; static char *buf; static char *page; +/* + * Go back 'n' lines in text. Called by dialog_textbox(). + * 'page' will be updated to point to the desired line in 'buf'. + */ +static void back_lines(int n) +{ + int i; + + begin_reached = 0; + /* Go back 'n' lines */ + for (i = 0; i < n; i++) { + if (*page == '\0') { + if (end_reached) { + end_reached = 0; + continue; + } + } + if (page == buf) { + begin_reached = 1; + return; + } + page--; + do { + if (page == buf) { + begin_reached = 1; + return; + } + page--; + } while (*page != '\n'); + page++; + } +} + +/* + * Return current line of text. Called by dialog_textbox() and print_line(). + * 'page' should point to start of current line before calling, and will be + * updated to point to start of next line. + */ +static char *get_line(void) +{ + int i = 0; + static char line[MAX_LEN + 1]; + + end_reached = 0; + while (*page != '\n') { + if (*page == '\0') { + end_reached = 1; + break; + } else if (i < MAX_LEN) + line[i++] = *(page++); + else { + /* Truncate lines longer than MAX_LEN characters */ + if (i == MAX_LEN) + line[i++] = '\0'; + page++; + } + } + if (i <= MAX_LEN) + line[i] = '\0'; + if (!end_reached) + page++; /* move past '\n' */ + + return line; +} + +/* + * Print a new line of text. + */ +static void print_line(WINDOW *win, int row, int width) +{ + char *line; + + line = get_line(); + line += MIN(strlen(line), hscroll); /* Scroll horizontally */ + wmove(win, row, 0); /* move cursor to correct line */ + waddch(win, ' '); + waddnstr(win, line, MIN(strlen(line), width - 2)); + + /* Clear 'residue' of previous line */ + wclrtoeol(win); +} + +/* + * Print a new page of text. + */ +static void print_page(WINDOW *win, int height, int width, update_text_fn + update_text, void *data) +{ + int i, passed_end = 0; + + if (update_text) { + char *end; + + for (i = 0; i < height; i++) + get_line(); + end = page; + back_lines(height); + update_text(buf, page - buf, end - buf, data); + } + + page_length = 0; + for (i = 0; i < height; i++) { + print_line(win, i, width); + if (!passed_end) + page_length++; + if (end_reached && !passed_end) + passed_end = 1; + } + wnoutrefresh(win); +} + +/* + * Print current position + */ +static void print_position(WINDOW *win) +{ + int percent; + + wattrset(win, dlg.position_indicator.atr); + wbkgdset(win, dlg.position_indicator.atr & A_COLOR); + percent = (page - buf) * 100 / strlen(buf); + wmove(win, getmaxy(win) - 3, getmaxx(win) - 9); + wprintw(win, "(%3d%%)", percent); +} + /* * refresh window content */ @@ -33,7 +151,6 @@ static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw, wrefresh(dialog); } - /* * Display text from a file in a dialog box. * @@ -259,128 +376,3 @@ do_resize: *_hscroll = hscroll; return key; } - -/* - * Go back 'n' lines in text. Called by dialog_textbox(). - * 'page' will be updated to point to the desired line in 'buf'. - */ -static void back_lines(int n) -{ - int i; - - begin_reached = 0; - /* Go back 'n' lines */ - for (i = 0; i < n; i++) { - if (*page == '\0') { - if (end_reached) { - end_reached = 0; - continue; - } - } - if (page == buf) { - begin_reached = 1; - return; - } - page--; - do { - if (page == buf) { - begin_reached = 1; - return; - } - page--; - } while (*page != '\n'); - page++; - } -} - -/* - * Print a new page of text. - */ -static void print_page(WINDOW *win, int height, int width, update_text_fn - update_text, void *data) -{ - int i, passed_end = 0; - - if (update_text) { - char *end; - - for (i = 0; i < height; i++) - get_line(); - end = page; - back_lines(height); - update_text(buf, page - buf, end - buf, data); - } - - page_length = 0; - for (i = 0; i < height; i++) { - print_line(win, i, width); - if (!passed_end) - page_length++; - if (end_reached && !passed_end) - passed_end = 1; - } - wnoutrefresh(win); -} - -/* - * Print a new line of text. - */ -static void print_line(WINDOW * win, int row, int width) -{ - char *line; - - line = get_line(); - line += MIN(strlen(line), hscroll); /* Scroll horizontally */ - wmove(win, row, 0); /* move cursor to correct line */ - waddch(win, ' '); - waddnstr(win, line, MIN(strlen(line), width - 2)); - - /* Clear 'residue' of previous line */ - wclrtoeol(win); -} - -/* - * Return current line of text. Called by dialog_textbox() and print_line(). - * 'page' should point to start of current line before calling, and will be - * updated to point to start of next line. - */ -static char *get_line(void) -{ - int i = 0; - static char line[MAX_LEN + 1]; - - end_reached = 0; - while (*page != '\n') { - if (*page == '\0') { - end_reached = 1; - break; - } else if (i < MAX_LEN) - line[i++] = *(page++); - else { - /* Truncate lines longer than MAX_LEN characters */ - if (i == MAX_LEN) - line[i++] = '\0'; - page++; - } - } - if (i <= MAX_LEN) - line[i] = '\0'; - if (!end_reached) - page++; /* move past '\n' */ - - return line; -} - -/* - * Print current position - */ -static void print_position(WINDOW * win) -{ - int percent; - - wattrset(win, dlg.position_indicator.atr); - wbkgdset(win, dlg.position_indicator.atr & A_COLOR); - percent = (page - buf) * 100 / strlen(buf); - wmove(win, getmaxy(win) - 3, getmaxx(win) - 9); - wprintw(win, "(%3d%%)", percent); -} diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index e67e0db50b2e..53d8834d12fe 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -290,16 +290,6 @@ static int save_and_exit; static int silent; static void conf(struct menu *menu, struct menu *active_menu); -static void conf_choice(struct menu *menu); -static void conf_string(struct menu *menu); -static void conf_load(void); -static void conf_save(void); -static int show_textbox_ext(const char *title, char *text, int r, int c, - int *keys, int *vscroll, int *hscroll, - update_text_fn update_text, void *data); -static void show_textbox(const char *title, const char *text, int r, int c); -static void show_helptext(const char *title, const char *text); -static void show_help(struct menu *menu); static char filename[PATH_MAX+1]; static void set_config_filename(const char *config_filename) @@ -358,6 +348,37 @@ static void reset_subtitle(void) set_dialog_subtitles(subtitles); } +static int show_textbox_ext(const char *title, char *text, int r, int c, int + *keys, int *vscroll, int *hscroll, update_text_fn + update_text, void *data) +{ + dialog_clear(); + return dialog_textbox(title, text, r, c, keys, vscroll, hscroll, + update_text, data); +} + +static void show_textbox(const char *title, const char *text, int r, int c) +{ + show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL, + NULL, NULL); +} + +static void show_helptext(const char *title, const char *text) +{ + show_textbox(title, text, 0, 0); +} + +static void show_help(struct menu *menu) +{ + struct gstr help = str_new(); + + help.max_width = getmaxx(stdscr) - 10; + menu_get_ext_help(menu, &help); + + show_helptext(menu_get_prompt(menu), str_get(&help)); + str_free(&help); +} + struct search_data { struct list_head *head; struct menu **targets; @@ -643,158 +664,6 @@ conf_childs: indent -= doint; } -static void conf(struct menu *menu, struct menu *active_menu) -{ - struct menu *submenu; - const char *prompt = menu_get_prompt(menu); - struct subtitle_part stpart; - struct symbol *sym; - int res; - int s_scroll = 0; - - if (menu != &rootmenu) - stpart.text = menu_get_prompt(menu); - else - stpart.text = NULL; - list_add_tail(&stpart.entries, &trail); - - while (1) { - item_reset(); - current_menu = menu; - build_conf(menu); - if (!child_count) - break; - set_subtitle(); - dialog_clear(); - res = dialog_menu(prompt ? prompt : "Main Menu", - menu_instructions, - active_menu, &s_scroll); - if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) - break; - if (item_count() != 0) { - if (!item_activate_selected()) - continue; - if (!item_tag()) - continue; - } - submenu = item_data(); - active_menu = item_data(); - if (submenu) - sym = submenu->sym; - else - sym = NULL; - - switch (res) { - case 0: - switch (item_tag()) { - case 'm': - if (single_menu_mode) - submenu->data = (void *) (long) !submenu->data; - else - conf(submenu, NULL); - break; - case 't': - if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes) - conf_choice(submenu); - else if (submenu->prompt->type == P_MENU) - conf(submenu, NULL); - break; - case 's': - conf_string(submenu); - break; - } - break; - case 2: - if (sym) - show_help(submenu); - else { - reset_subtitle(); - show_helptext("README", mconf_readme); - } - break; - case 3: - reset_subtitle(); - conf_save(); - break; - case 4: - reset_subtitle(); - conf_load(); - break; - case 5: - if (item_is_tag('t')) { - if (sym_set_tristate_value(sym, yes)) - break; - if (sym_set_tristate_value(sym, mod)) - show_textbox(NULL, setmod_text, 6, 74); - } - break; - case 6: - if (item_is_tag('t')) - sym_set_tristate_value(sym, no); - break; - case 7: - if (item_is_tag('t')) - sym_set_tristate_value(sym, mod); - break; - case 8: - if (item_is_tag('t')) - sym_toggle_tristate_value(sym); - else if (item_is_tag('m')) - conf(submenu, NULL); - break; - case 9: - search_conf(); - break; - case 10: - show_all_options = !show_all_options; - break; - } - } - - list_del(trail.prev); -} - -static int show_textbox_ext(const char *title, char *text, int r, int c, int - *keys, int *vscroll, int *hscroll, update_text_fn - update_text, void *data) -{ - dialog_clear(); - return dialog_textbox(title, text, r, c, keys, vscroll, hscroll, - update_text, data); -} - -static void show_textbox(const char *title, const char *text, int r, int c) -{ - show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL, - NULL, NULL); -} - -static void show_helptext(const char *title, const char *text) -{ - show_textbox(title, text, 0, 0); -} - -static void conf_message_callback(const char *s) -{ - if (save_and_exit) { - if (!silent) - printf("%s", s); - } else { - show_textbox(NULL, s, 6, 60); - } -} - -static void show_help(struct menu *menu) -{ - struct gstr help = str_new(); - - help.max_width = getmaxx(stdscr) - 10; - menu_get_ext_help(menu, &help); - - show_helptext(menu_get_prompt(menu), str_get(&help)); - str_free(&help); -} - static void conf_choice(struct menu *menu) { const char *prompt = menu_get_prompt(menu); @@ -950,6 +819,127 @@ static void conf_save(void) } } +static void conf(struct menu *menu, struct menu *active_menu) +{ + struct menu *submenu; + const char *prompt = menu_get_prompt(menu); + struct subtitle_part stpart; + struct symbol *sym; + int res; + int s_scroll = 0; + + if (menu != &rootmenu) + stpart.text = menu_get_prompt(menu); + else + stpart.text = NULL; + list_add_tail(&stpart.entries, &trail); + + while (1) { + item_reset(); + current_menu = menu; + build_conf(menu); + if (!child_count) + break; + set_subtitle(); + dialog_clear(); + res = dialog_menu(prompt ? prompt : "Main Menu", + menu_instructions, + active_menu, &s_scroll); + if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) + break; + if (item_count() != 0) { + if (!item_activate_selected()) + continue; + if (!item_tag()) + continue; + } + submenu = item_data(); + active_menu = item_data(); + if (submenu) + sym = submenu->sym; + else + sym = NULL; + + switch (res) { + case 0: + switch (item_tag()) { + case 'm': + if (single_menu_mode) + submenu->data = (void *) (long) !submenu->data; + else + conf(submenu, NULL); + break; + case 't': + if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes) + conf_choice(submenu); + else if (submenu->prompt->type == P_MENU) + conf(submenu, NULL); + break; + case 's': + conf_string(submenu); + break; + } + break; + case 2: + if (sym) + show_help(submenu); + else { + reset_subtitle(); + show_helptext("README", mconf_readme); + } + break; + case 3: + reset_subtitle(); + conf_save(); + break; + case 4: + reset_subtitle(); + conf_load(); + break; + case 5: + if (item_is_tag('t')) { + if (sym_set_tristate_value(sym, yes)) + break; + if (sym_set_tristate_value(sym, mod)) + show_textbox(NULL, setmod_text, 6, 74); + } + break; + case 6: + if (item_is_tag('t')) + sym_set_tristate_value(sym, no); + break; + case 7: + if (item_is_tag('t')) + sym_set_tristate_value(sym, mod); + break; + case 8: + if (item_is_tag('t')) + sym_toggle_tristate_value(sym); + else if (item_is_tag('m')) + conf(submenu, NULL); + break; + case 9: + search_conf(); + break; + case 10: + show_all_options = !show_all_options; + break; + } + } + + list_del(trail.prev); +} + +static void conf_message_callback(const char *s) +{ + if (save_and_exit) { + if (!silent) + printf("%s", s); + } else { + show_textbox(NULL, s, 6, 60); + } +} + static int handle_exit(void) { int res; -- cgit From ddc72c9659b5a85a2d135503caf193da0723e813 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 2 Apr 2023 02:01:17 +0900 Subject: kbuild: clang: do not use CROSS_COMPILE for target triple The target triple is overridden by the user-supplied CROSS_COMPILE, but I do not see a good reason to support it. Users can use a new architecture without adding CLANG_TARGET_FLAGS_*, but that would be a rare case. Use the hard-coded and deterministic target triple all the time. Signed-off-by: Masahiro Yamada Acked-by: Nathan Chancellor Reviewed-by: Nick Desaulniers --- scripts/Makefile.clang | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.clang b/scripts/Makefile.clang index 70b354fa1cb4..9076cc939e87 100644 --- a/scripts/Makefile.clang +++ b/scripts/Makefile.clang @@ -13,15 +13,11 @@ CLANG_TARGET_FLAGS_x86 := x86_64-linux-gnu CLANG_TARGET_FLAGS_um := $(CLANG_TARGET_FLAGS_$(SUBARCH)) CLANG_TARGET_FLAGS := $(CLANG_TARGET_FLAGS_$(SRCARCH)) -ifeq ($(CROSS_COMPILE),) ifeq ($(CLANG_TARGET_FLAGS),) -$(error Specify CROSS_COMPILE or add '--target=' option to scripts/Makefile.clang) +$(error add '--target=' option to scripts/Makefile.clang) else CLANG_FLAGS += --target=$(CLANG_TARGET_FLAGS) -endif # CLANG_TARGET_FLAGS -else -CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%)) -endif # CROSS_COMPILE +endif ifeq ($(LLVM_IAS),0) CLANG_FLAGS += -fno-integrated-as -- cgit From ccb2d173b983984bfa35398abed3f8a76c75f788 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 11 Apr 2023 20:09:44 +0000 Subject: Makefile: use -z pack-relative-relocs Commit 27f2a4db76e8 ("Makefile: fix GDB warning with CONFIG_RELR") added --use-android-relr-tags to fix a GDB warning BFD: /android0/linux-next/vmlinux: unknown type [0x13] section `.relr.dyn' The GDB warning has been fixed in version 11.2. The DT_ANDROID_RELR tag was deprecated since DT_RELR was standardized. Thus, --use-android-relr-tags should be removed. While making the change, try -z pack-relative-relocs, which is supported since LLD 15. Keep supporting --pack-dyn-relocs=relr as well for older LLD versions. There is no indication of obsolescence for --pack-dyn-relocs=relr. As of today, GNU ld supports the latter option for x86 and powerpc64 ports and has no intention to support --pack-dyn-relocs=relr. In the absence of the glibc symbol version GLIBC_ABI_DT_RELR, --pack-dyn-relocs=relr and -z pack-relative-relocs are identical in ld.lld. GNU ld and newer versions of LLD report warnings (instead of errors) for unknown -z options. Only errors lead to non-zero exit codes. Therefore, we should test --pack-dyn-relocs=relr before testing -z pack-relative-relocs. Link: https://github.com/ClangBuiltLinux/linux/issues/1057 Link: https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=a619b58721f0a03fd91c27670d3e4c2fb0d88f1e Signed-off-by: Fangrui Song Reviewed-by: Nick Desaulniers Acked-by: Will Deacon Signed-off-by: Masahiro Yamada --- Makefile | 3 ++- scripts/tools-support-relr.sh | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index b5c48e3c935a..3c0ec6dbcfd1 100644 --- a/Makefile +++ b/Makefile @@ -1113,7 +1113,8 @@ LDFLAGS_vmlinux += -X endif ifeq ($(CONFIG_RELR),y) -LDFLAGS_vmlinux += --pack-dyn-relocs=relr --use-android-relr-tags +# ld.lld before 15 did not support -z pack-relative-relocs. +LDFLAGS_vmlinux += $(call ld-option,--pack-dyn-relocs=relr,-z pack-relative-relocs) endif # We never want expected sections to be placed heuristically by the diff --git a/scripts/tools-support-relr.sh b/scripts/tools-support-relr.sh index cb55878bd5b8..4c121946e517 100755 --- a/scripts/tools-support-relr.sh +++ b/scripts/tools-support-relr.sh @@ -7,8 +7,12 @@ trap "rm -f $tmp_file.o $tmp_file $tmp_file.bin" EXIT cat << "END" | $CC -c -x c - -o $tmp_file.o >/dev/null 2>&1 void *p = &p; END -$LD $tmp_file.o -shared -Bsymbolic --pack-dyn-relocs=relr \ - --use-android-relr-tags -o $tmp_file + +# ld.lld before 15 did not support -z pack-relative-relocs. +if ! $LD $tmp_file.o -shared -Bsymbolic --pack-dyn-relocs=relr -o $tmp_file 2>/dev/null; then + $LD $tmp_file.o -shared -Bsymbolic -z pack-relative-relocs -o $tmp_file 2>&1 | + grep -q pack-relative-relocs && exit 1 +fi # Despite printing an error message, GNU nm still exits with exit code 0 if it # sees a relr section. So we need to check that nothing is printed to stderr. -- cgit From 90fd833609c82487a0eca1581becde7ab54d9429 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 18 Apr 2023 14:23:35 +0200 Subject: kasan: remove hwasan-kernel-mem-intrinsic-prefix=1 for clang-14 Some unknown -mllvm options (i.e. those starting with the letter "h") don't cause an error to be returned by clang, so the cc-option helper adds the unknown hwasan-kernel-mem-intrinsic-prefix=1 flag to CFLAGS with compilers that are new enough for hwasan but too old for this option. This causes a rather unreadable build failure: fixdep: error opening file: scripts/mod/.empty.o.d: No such file or directory make[4]: *** [/home/arnd/arm-soc/scripts/Makefile.build:252: scripts/mod/empty.o] Error 2 fixdep: error opening file: scripts/mod/.devicetable-offsets.s.d: No such file or directory make[4]: *** [/home/arnd/arm-soc/scripts/Makefile.build:114: scripts/mod/devicetable-offsets.s] Error 2 Add a version check to only allow this option with clang-15, gcc-13 or later versions. Link: https://lkml.kernel.org/r/20230418122350.1646391-1-arnd@kernel.org Fixes: 51287dcb00cc ("kasan: emit different calls for instrumentable memintrinsics") Link: https://lore.kernel.org/all/CANpmjNMwYosrvqh4ogDO8rgn+SeDHM2b-shD21wTypm_6MMe=g@mail.gmail.com/ Signed-off-by: Arnd Bergmann Reviewed-by: Marco Elver Reviewed-by: Nathan Chancellor Cc: Alexander Potapenko Cc: Andrey Konovalov Cc: Andrey Ryabinin Cc: Dmitry Vyukov Cc: Masahiro Yamada Cc: Michael Ellerman Cc: Nick Desaulniers Cc: Nicolas Schier Cc: Peter Zijlstra Cc: Tom Rix Cc: Vincenzo Frascino Signed-off-by: Andrew Morton --- scripts/Makefile.kasan | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan index c186110ffa20..390658a2d5b7 100644 --- a/scripts/Makefile.kasan +++ b/scripts/Makefile.kasan @@ -69,7 +69,9 @@ CFLAGS_KASAN := -fsanitize=kernel-hwaddress \ $(instrumentation_flags) # Instrument memcpy/memset/memmove calls by using instrumented __hwasan_mem*(). +ifeq ($(call clang-min-version, 150000)$(call gcc-min-version, 130000),y) CFLAGS_KASAN += $(call cc-param,hwasan-kernel-mem-intrinsic-prefix=1) +endif endif # CONFIG_KASAN_SW_TAGS -- cgit From 747cd84f677cedb27db10d4ada777d7ec20431ee Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Tue, 21 Mar 2023 14:18:43 +0800 Subject: scripts/gdb: fix lx-timerlist for struct timequeue_head change commit 511885d7061e ("lib/timerqueue: Rely on rbtree semantics for next timer") changed struct timerqueue_head, and so print_active_timers() should be changed accordingly with its way to interpret the structure. Link: https://lkml.kernel.org/r/TYCP286MB21463BD277330B26DDC18903C6819@TYCP286MB2146.JPNP286.PROD.OUTLOOK.COM Signed-off-by: Peng Liu Reviewed-by: Jan Kiszka Cc: Kieran Bingham Cc: Florian Fainelli Signed-off-by: Andrew Morton --- scripts/gdb/linux/timerlist.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/timerlist.py b/scripts/gdb/linux/timerlist.py index 071d0dd5a634..44e39dc3eb64 100644 --- a/scripts/gdb/linux/timerlist.py +++ b/scripts/gdb/linux/timerlist.py @@ -43,8 +43,7 @@ def print_timer(rb_node, idx): def print_active_timers(base): - curr = base['active']['next']['node'] - curr = curr.address.cast(rbtree.rb_node_type.get_type().pointer()) + curr = base['active']['rb_root']['rb_leftmost'] idx = 0 while curr: yield print_timer(curr, idx) -- cgit From 7362042f3556528e9e9b1eb5ce8d7a3a6331476b Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Tue, 21 Mar 2023 14:19:29 +0800 Subject: scripts/gdb: fix lx-timerlist for Python3 Below incompatibilities between Python2 and Python3 made lx-timerlist fail to run under Python3. o xrange() is replaced by range() in Python3 o bytes and str are different types in Python3 o the return value of Inferior.read_memory() is memoryview object in Python3 akpm: cc stable so that older kernels are properly debuggable under newer Python. Link: https://lkml.kernel.org/r/TYCP286MB2146EE1180A4D5176CBA8AB2C6819@TYCP286MB2146.JPNP286.PROD.OUTLOOK.COM Signed-off-by: Peng Liu Reviewed-by: Jan Kiszka Cc: Florian Fainelli Cc: Kieran Bingham Cc: Signed-off-by: Andrew Morton --- scripts/gdb/linux/timerlist.py | 4 +++- scripts/gdb/linux/utils.py | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/timerlist.py b/scripts/gdb/linux/timerlist.py index 44e39dc3eb64..8281da068c5b 100644 --- a/scripts/gdb/linux/timerlist.py +++ b/scripts/gdb/linux/timerlist.py @@ -72,7 +72,7 @@ def print_cpu(hrtimer_bases, cpu, max_clock_bases): ts = cpus.per_cpu(tick_sched_ptr, cpu) text = "cpu: {}\n".format(cpu) - for i in xrange(max_clock_bases): + for i in range(max_clock_bases): text += " clock {}:\n".format(i) text += print_base(cpu_base['clock_base'][i]) @@ -157,6 +157,8 @@ def pr_cpumask(mask): num_bytes = (nr_cpu_ids + 7) / 8 buf = utils.read_memoryview(inf, bits, num_bytes).tobytes() buf = binascii.b2a_hex(buf) + if type(buf) is not str: + buf=buf.decode() chunks = [] i = num_bytes diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py index 1553f68716cc..7f36aee32ac6 100644 --- a/scripts/gdb/linux/utils.py +++ b/scripts/gdb/linux/utils.py @@ -88,7 +88,10 @@ def get_target_endianness(): def read_memoryview(inf, start, length): - return memoryview(inf.read_memory(start, length)) + m = inf.read_memory(start, length) + if type(m) is memoryview: + return m + return memoryview(m) def read_u16(buffer, offset): -- cgit From 8fc2a304f57cb304231a4b0564d5995b2dd04f63 Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Tue, 21 Mar 2023 14:20:04 +0800 Subject: scripts/gdb: fix lx-timerlist for HRTIMER_MAX_CLOCK_BASES printing HRTIMER_MAX_CLOCK_BASES is of enum type hrtimer_base_type. To print it as an integer, HRTIMER_MAX_CLOCK_BASES should be converted first. Link: https://lkml.kernel.org/r/TYCP286MB214640FF0E7F04AC3926A39EC6819@TYCP286MB2146.JPNP286.PROD.OUTLOOK.COM Signed-off-by: Peng Liu Reviewed-by: Jan Kiszka Cc: Florian Fainelli Cc: Kieran Bingham Signed-off-by: Andrew Morton --- scripts/gdb/linux/timerlist.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/timerlist.py b/scripts/gdb/linux/timerlist.py index 8281da068c5b..249f0e804b24 100644 --- a/scripts/gdb/linux/timerlist.py +++ b/scripts/gdb/linux/timerlist.py @@ -188,7 +188,8 @@ class LxTimerList(gdb.Command): max_clock_bases = gdb.parse_and_eval("HRTIMER_MAX_CLOCK_BASES") text = "Timer List Version: gdb scripts\n" - text += "HRTIMER_MAX_CLOCK_BASES: {}\n".format(max_clock_bases) + text += "HRTIMER_MAX_CLOCK_BASES: {}\n".format( + max_clock_bases.type.fields()[max_clock_bases].enumval) text += "now at {} nsecs\n".format(ktime_get()) for cpu in cpus.each_online_cpu(): -- cgit From c917a872cee480d1fc8461da9be93e27e7977877 Mon Sep 17 00:00:00 2001 From: Matthieu Baerts Date: Mon, 3 Apr 2023 18:23:47 +0200 Subject: checkpatch: don't print the next line if not defined MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When checking if "Reported-by" tag is followed by "Link:", there is no need to print the next line if there is no next line. While at it, also mention in this case that the "Link:" tag should be followed by a URL, similar to the next warning. By doing that, the code is now similar to what is done above when checking if the Co-developed-by tag is properly used. Link: https://lkml.kernel.org/r/20230314-doc-checkpatch-closes-tag-v4-2-d26d1fa66f9f@tessares.net Fixes: d7f1d71e5ef6 ("checkpatch: warn when Reported-by: is not followed by Link:") Signed-off-by: Matthieu Baerts Acked-by: Joe Perches Cc: Andy Whitcroft Cc: Bagas Sanjaya Cc: Daniel Vetter Cc: David Airlie Cc: Dwaipayan Ray Cc: Jonathan Corbet Cc: Kai Wasserbäch Cc: Konstantin Ryabitsev Cc: Linus Torvalds Cc: Lukas Bulwahn Cc: Thorsten Leemhuis Signed-off-by: Andrew Morton --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index c7cd0750b41e..8e22eb45ab2d 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3162,7 +3162,7 @@ sub process { if ($sign_off =~ /^reported(?:|-and-tested)-by:$/i) { if (!defined $lines[$linenr]) { WARN("BAD_REPORTED_BY_LINK", - "Reported-by: should be immediately followed by Link: to the report\n" . $herecurr . $rawlines[$linenr] . "\n"); + "Reported-by: should be immediately followed by Link: with a URL to the report\n" . $herecurr . "\n"); } elsif ($rawlines[$linenr] !~ m{^link:\s*https?://}i) { WARN("BAD_REPORTED_BY_LINK", "Reported-by: should be immediately followed by Link: with a URL to the report\n" . $herecurr . $rawlines[$linenr] . "\n"); -- cgit From f94e40ea272b9847833de1114677eb5ad8b12a0a Mon Sep 17 00:00:00 2001 From: Matthieu Baerts Date: Mon, 3 Apr 2023 18:23:48 +0200 Subject: checkpatch: use a list of "link" tags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following commit will allow the use of a similar "link" tag. Because there is a possibility that other similar tags will be added in the future and to reduce the number of places where the code will be modified to allow this new tag, a list with all these "link" tags is now used. Two variables are created from it: one to search for such tags and one to print all tags in a warning message. Link: https://lkml.kernel.org/r/20230314-doc-checkpatch-closes-tag-v4-3-d26d1fa66f9f@tessares.net Signed-off-by: Matthieu Baerts Suggested-by: Joe Perches Acked-by: Joe Perches Cc: Andy Whitcroft Cc: Bagas Sanjaya Cc: Daniel Vetter Cc: David Airlie Cc: Dwaipayan Ray Cc: Jonathan Corbet Cc: Kai Wasserbäch Cc: Konstantin Ryabitsev Cc: Linus Torvalds Cc: Lukas Bulwahn Cc: Thorsten Leemhuis Signed-off-by: Andrew Morton --- scripts/checkpatch.pl | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 8e22eb45ab2d..209898b8f0b6 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -620,6 +620,22 @@ our $signature_tags = qr{(?xi: Cc: )}; +our @link_tags = qw(Link); + +#Create a search and print patterns for all these strings to be used directly below +our $link_tags_search = ""; +our $link_tags_print = ""; +foreach my $entry (@link_tags) { + if ($link_tags_search ne "") { + $link_tags_search .= '|'; + $link_tags_print .= ' or '; + } + $entry .= ':'; + $link_tags_search .= $entry; + $link_tags_print .= "'$entry'"; +} +$link_tags_search = "(?:${link_tags_search})"; + our $tracing_logging_tags = qr{(?xi: [=-]*> | <[=-]* | @@ -3250,8 +3266,8 @@ sub process { # file delta changes $line =~ /^\s*(?:[\w\.\-\+]*\/)++[\w\.\-\+]+:/ || # filename then : - $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i || - # A Fixes: or Link: line or signature tag line + $line =~ /^\s*(?:Fixes:|$link_tags_search|$signature_tags)/i || + # A Fixes:, link or signature tag line $commit_log_possible_stack_dump)) { WARN("COMMIT_LOG_LONG_LINE", "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); @@ -3266,13 +3282,13 @@ sub process { # Check for odd tags before a URI/URL if ($in_commit_log && - $line =~ /^\s*(\w+):\s*http/ && $1 ne 'Link') { + $line =~ /^\s*(\w+:)\s*http/ && $1 !~ /^$link_tags_search$/) { if ($1 =~ /^v(?:ersion)?\d+/i) { WARN("COMMIT_LOG_VERSIONING", "Patch version information should be after the --- line\n" . $herecurr); } else { WARN("COMMIT_LOG_USE_LINK", - "Unknown link reference '$1:', use 'Link:' instead\n" . $herecurr); + "Unknown link reference '$1', use $link_tags_print instead\n" . $herecurr); } } -- cgit From 44c31888098a590b8ec5ba37009e5a983f7c4b46 Mon Sep 17 00:00:00 2001 From: Matthieu Baerts Date: Mon, 3 Apr 2023 18:23:49 +0200 Subject: checkpatch: allow Closes tags with links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As a follow-up of a previous patch modifying the documentation to allow using the "Closes:" tag, checkpatch.pl is updated accordingly. checkpatch.pl now no longer complain when the "Closes:" tag is used by itself: commit 76f381bb77a0 ("checkpatch: warn when unknown tags are used for links") ... or after the "Reported-by:" tag: commit d7f1d71e5ef6 ("checkpatch: warn when Reported-by: is not followed by Link:") Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/373 Link: https://lkml.kernel.org/r/20230314-doc-checkpatch-closes-tag-v4-4-d26d1fa66f9f@tessares.net Signed-off-by: Matthieu Baerts Acked-by: Joe Perches Cc: Andy Whitcroft Cc: Bagas Sanjaya Cc: Daniel Vetter Cc: David Airlie Cc: Dwaipayan Ray Cc: Jonathan Corbet Cc: Kai Wasserbäch Cc: Konstantin Ryabitsev Cc: Linus Torvalds Cc: Lukas Bulwahn Cc: Thorsten Leemhuis Signed-off-by: Andrew Morton --- scripts/checkpatch.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 209898b8f0b6..922428ee3be5 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -620,7 +620,7 @@ our $signature_tags = qr{(?xi: Cc: )}; -our @link_tags = qw(Link); +our @link_tags = qw(Link Closes); #Create a search and print patterns for all these strings to be used directly below our $link_tags_search = ""; @@ -3174,14 +3174,14 @@ sub process { } } -# check if Reported-by: is followed by a Link: +# check if Reported-by: is followed by a Closes: tag if ($sign_off =~ /^reported(?:|-and-tested)-by:$/i) { if (!defined $lines[$linenr]) { WARN("BAD_REPORTED_BY_LINK", - "Reported-by: should be immediately followed by Link: with a URL to the report\n" . $herecurr . "\n"); - } elsif ($rawlines[$linenr] !~ m{^link:\s*https?://}i) { + "Reported-by: should be immediately followed by Closes: with a URL to the report\n" . $herecurr . "\n"); + } elsif ($rawlines[$linenr] !~ m{^closes:\s*https?://}i) { WARN("BAD_REPORTED_BY_LINK", - "Reported-by: should be immediately followed by Link: with a URL to the report\n" . $herecurr . $rawlines[$linenr] . "\n"); + "Reported-by: should be immediately followed by Closes: with a URL to the report\n" . $herecurr . $rawlines[$linenr] . "\n"); } } } -- cgit From d6ccdd678e459fdcfe675a45c76b3f1a75b9a8e8 Mon Sep 17 00:00:00 2001 From: Matthieu Baerts Date: Mon, 3 Apr 2023 18:23:50 +0200 Subject: checkpatch: check for misuse of the link tags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Link:" and "Closes:" tags have to be used with public URLs. It is difficult to make sure the link is public but at least we can verify the tag is followed by 'http(s)://'. With that, we avoid such a tag that is not allowed [1]: Closes: Now that we check the "link" tags are followed by a URL, we can relax the check linked to "Reported-by being followed by a link tag" to only verify if a "link" tag is present after the "Reported-by" one. Link: https://lore.kernel.org/linux-doc/CAHk-=wh0v1EeDV3v8TzK81nDC40=XuTdY2MCr0xy3m3FiBV3+Q@mail.gmail.com/ [1] Link: https://lkml.kernel.org/r/20230314-doc-checkpatch-closes-tag-v4-5-d26d1fa66f9f@tessares.net Signed-off-by: Matthieu Baerts Acked-by: Joe Perches Cc: Andy Whitcroft Cc: Bagas Sanjaya Cc: Daniel Vetter Cc: David Airlie Cc: Dwaipayan Ray Cc: Jonathan Corbet Cc: Kai Wasserbäch Cc: Konstantin Ryabitsev Cc: Linus Torvalds Cc: Lukas Bulwahn Cc: Thorsten Leemhuis Signed-off-by: Andrew Morton --- scripts/checkpatch.pl | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 922428ee3be5..3e6f5a8614d3 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3179,7 +3179,7 @@ sub process { if (!defined $lines[$linenr]) { WARN("BAD_REPORTED_BY_LINK", "Reported-by: should be immediately followed by Closes: with a URL to the report\n" . $herecurr . "\n"); - } elsif ($rawlines[$linenr] !~ m{^closes:\s*https?://}i) { + } elsif ($rawlines[$linenr] !~ /^closes:\s*/i) { WARN("BAD_REPORTED_BY_LINK", "Reported-by: should be immediately followed by Closes: with a URL to the report\n" . $herecurr . $rawlines[$linenr] . "\n"); } @@ -3292,6 +3292,17 @@ sub process { } } +# Check for misuse of the link tags + if ($in_commit_log && + $line =~ /^\s*(\w+:)\s*(\S+)/) { + my $tag = $1; + my $value = $2; + if ($tag =~ /^$link_tags_search$/ && $value !~ m{^https?://}) { + WARN("COMMIT_LOG_WRONG_LINK", + "'$tag' should be followed by a public http(s) link\n" . $herecurr); + } + } + # Check for lines starting with a # if ($in_commit_log && $line =~ /^#/) { if (WARN("COMMIT_COMMENT_SYMBOL", -- cgit From b7235d6bb516fed6d62d2c9e30e7123b6ce5124c Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Tue, 4 Apr 2023 14:40:49 -0700 Subject: scripts/gdb: add a Radix Tree Parser Linux makes use of the Radix Tree data structure to store pointers indexed by integer values. This structure is utilised across many structures in the kernel including the IRQ descriptor tables, and several filesystems. This module provides a method to lookup values from a structure given its head node. Usage: The function lx_radix_tree_lookup, must be given a symbol of type struct radix_tree_root, and an index into that tree. The object returned is a generic integer value, and must be cast correctly to the type based on the storage in the data structure. For example, to print the irq descriptor in the sparse irq_desc_tree at index 18, try the following: (gdb) print (struct irq_desc)$lx_radix_tree_lookup(irq_desc_tree, 18) This script previously existed under commit e127a73d41ac471d7e3ba950cf128f42d6ee3448 ("scripts/gdb: add a Radix Tree Parser") and was later reverted with b447e02548a3304c47b78b5e2d75a4312a8f17e1i (Revert "scripts/gdb: add a Radix Tree Parser"). This version expects the XArray based radix tree implementation and has been verified using QEMU/x86 on Linux 6.3-rc5. [f.fainelli@gmail.com: revive and update for xarray implementation] [f.fainelli@gmail.com: guard against a NULL node in the while loop] Link: https://lkml.kernel.org/r/20230405222743.1191674-1-f.fainelli@gmail.com Link: https://lkml.kernel.org/r/20230404214049.1016811-1-f.fainelli@gmail.com Signed-off-by: Kieran Bingham Signed-off-by: Florian Fainelli Cc: Jan Kiszka Cc: Kieran Bingham Signed-off-by: Andrew Morton --- scripts/gdb/linux/constants.py.in | 8 ++++ scripts/gdb/linux/radixtree.py | 90 +++++++++++++++++++++++++++++++++++++++ scripts/gdb/vmlinux-gdb.py | 1 + 3 files changed, 99 insertions(+) create mode 100644 scripts/gdb/linux/radixtree.py (limited to 'scripts') diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in index 2efbec6b6b8d..6c886deb0b18 100644 --- a/scripts/gdb/linux/constants.py.in +++ b/scripts/gdb/linux/constants.py.in @@ -17,6 +17,7 @@ #include #include #include +#include #include /* We need to stringify expanded macros so that they can be parsed */ @@ -68,6 +69,13 @@ LX_VALUE(NR_CPUS) /* linux/of_fdt.h> */ LX_VALUE(OF_DT_HEADER) +/* linux/radix-tree.h */ +LX_GDBPARSED(RADIX_TREE_ENTRY_MASK) +LX_GDBPARSED(RADIX_TREE_INTERNAL_NODE) +LX_GDBPARSED(RADIX_TREE_MAP_SIZE) +LX_GDBPARSED(RADIX_TREE_MAP_SHIFT) +LX_GDBPARSED(RADIX_TREE_MAP_MASK) + /* Kernel Configs */ LX_CONFIG(CONFIG_GENERIC_CLOCKEVENTS) LX_CONFIG(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) diff --git a/scripts/gdb/linux/radixtree.py b/scripts/gdb/linux/radixtree.py new file mode 100644 index 000000000000..074543ac763d --- /dev/null +++ b/scripts/gdb/linux/radixtree.py @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Radix Tree Parser +# +# Copyright (c) 2016 Linaro Ltd +# Copyright (c) 2023 Broadcom +# +# Authors: +# Kieran Bingham +# Florian Fainelli + +import gdb + +from linux import utils +from linux import constants + +radix_tree_root_type = utils.CachedType("struct xarray") +radix_tree_node_type = utils.CachedType("struct xa_node") + +def is_internal_node(node): + long_type = utils.get_long_type() + return ((node.cast(long_type) & constants.LX_RADIX_TREE_ENTRY_MASK) == constants.LX_RADIX_TREE_INTERNAL_NODE) + +def entry_to_node(node): + long_type = utils.get_long_type() + node_type = node.type + indirect_ptr = node.cast(long_type) & ~constants.LX_RADIX_TREE_INTERNAL_NODE + return indirect_ptr.cast(radix_tree_node_type.get_type().pointer()) + +def node_maxindex(node): + return (constants.LX_RADIX_TREE_MAP_SIZE << node['shift']) - 1 + +def lookup(root, index): + if root.type == radix_tree_root_type.get_type().pointer(): + node = root.dereference() + elif root.type != radix_tree_root_type.get_type(): + raise gdb.GdbError("must be {} not {}" + .format(radix_tree_root_type.get_type(), root.type)) + + node = root['xa_head'] + if node == 0: + return None + + if not (is_internal_node(node)): + if (index > 0): + return None + return node + + node = entry_to_node(node) + maxindex = node_maxindex(node) + + if (index > maxindex): + return None + + shift = node['shift'] + constants.LX_RADIX_TREE_MAP_SHIFT + + while True: + offset = (index >> node['shift']) & constants.LX_RADIX_TREE_MAP_MASK + slot = node['slots'][offset] + + if slot == 0: + return None + + node = slot.cast(node.type.pointer()).dereference() + if node == 0: + return None + + shift -= constants.LX_RADIX_TREE_MAP_SHIFT + if (shift <= 0): + break + + return node + +class LxRadixTree(gdb.Function): + """ Lookup and return a node from a RadixTree. + +$lx_radix_tree_lookup(root_node [, index]): Return the node at the given index. +If index is omitted, the root node is dereference and returned.""" + + def __init__(self): + super(LxRadixTree, self).__init__("lx_radix_tree_lookup") + + def invoke(self, root, index=0): + result = lookup(root, index) + if result is None: + raise gdb.GdbError("No entry in tree at index {}".format(index)) + + return result + +LxRadixTree() diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py index 3a5b44cd6bfe..4a5056f2c247 100644 --- a/scripts/gdb/vmlinux-gdb.py +++ b/scripts/gdb/vmlinux-gdb.py @@ -38,3 +38,4 @@ else: import linux.genpd import linux.device import linux.mm + import linux.radixtree -- cgit From 8af055ae25bff48f57227f5e3d48a4306f3dd1c4 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 6 Apr 2023 14:52:51 -0700 Subject: scripts/gdb: raise error with reduced debugging information If CONFIG_DEBUG_INFO_REDUCED is enabled in the kernel configuration, we will typically not be able to load vmlinux-gdb.py and will fail with: Traceback (most recent call last): File "/home/fainelli/work/buildroot/output/arm64/build/linux-custom/vmlinux-gdb.py", line 25, in import linux.utils File "/home/fainelli/work/buildroot/output/arm64/build/linux-custom/scripts/gdb/linux/utils.py", line 131, in atomic_long_counter_offset = atomic_long_type.get_type()['counter'].bitpos KeyError: 'counter' Rather be left wondering what is happening only to find out that reduced debug information is the cause, raise an eror. This was not typically a problem until e3c8d33e0d62 ("scripts/gdb: fix 'lx-dmesg' on 32 bits arch") but it has since then. Link: https://lkml.kernel.org/r/20230406215252.1580538-1-f.fainelli@gmail.com Fixes: e3c8d33e0d62 ("scripts/gdb: fix 'lx-dmesg' on 32 bits arch") Signed-off-by: Florian Fainelli Cc: Antonio Borneo Cc: Jan Kiszka Cc: John Ogness Cc: Kieran Bingham Cc: Petr Mladek Signed-off-by: Andrew Morton --- scripts/gdb/linux/constants.py.in | 2 ++ scripts/gdb/vmlinux-gdb.py | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in index 6c886deb0b18..e484e2e7e4d5 100644 --- a/scripts/gdb/linux/constants.py.in +++ b/scripts/gdb/linux/constants.py.in @@ -40,6 +40,8 @@ import gdb +LX_CONFIG(CONFIG_DEBUG_INFO_REDUCED) + /* linux/clk-provider.h */ if IS_BUILTIN(CONFIG_COMMON_CLK): LX_GDBPARSED(CLK_GET_RATE_NOCACHE) diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py index 4a5056f2c247..2f57adcf3dff 100644 --- a/scripts/gdb/vmlinux-gdb.py +++ b/scripts/gdb/vmlinux-gdb.py @@ -22,6 +22,10 @@ except: gdb.write("NOTE: gdb 7.2 or later required for Linux helper scripts to " "work.\n") else: + import linux.constants + if linux.constants.LX_CONFIG_DEBUG_INFO_REDUCED: + raise gdb.GdbError("Reduced debug information will prevent GDB " + "from having complete types.\n") import linux.utils import linux.symbols import linux.modules @@ -32,7 +36,6 @@ else: import linux.lists import linux.rbtree import linux.proc - import linux.constants import linux.timerlist import linux.clk import linux.genpd -- cgit From b0969d7687a7aaa82dcf2d1f245ef699387886da Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 6 Apr 2023 15:04:51 -0700 Subject: scripts/gdb: print interrupts This GDB script prints the interrupts in the system in the same way that /proc/interrupts does. This does include the architecture specific part done by arch_show_interrupts() for x86, ARM, ARM64 and MIPS. Example output from an ARM64 system: (gdb) lx-interruptlist CPU0 CPU1 CPU2 CPU3 10: 3167 1225 1276 2629 GICv2 30 Level arch_timer 13: 0 0 0 0 GICv2 36 Level arm-pmu 14: 0 0 0 0 GICv2 37 Level arm-pmu 15: 0 0 0 0 GICv2 38 Level arm-pmu 16: 0 0 0 0 GICv2 39 Level arm-pmu 28: 0 0 0 0 interrupt-controller@8410640 5 Edge brcmstb-gpio-wake 30: 125 0 0 0 GICv2 128 Level ttyS0 31: 0 0 0 0 interrupt-controller@8416000 0 Level mspi_done 32: 0 0 0 0 interrupt-controller@8410640 3 Edge brcmstb-waketimer 33: 0 0 0 0 interrupt-controller@8418580 8 Edge brcmstb-waketimer-rtc 34: 872 0 0 0 GICv2 230 Level brcm_scmi@0 35: 0 0 0 0 interrupt-controller@8410640 10 Edge 8d0f200.usb-phy 37: 0 0 0 0 GICv2 97 Level PCIe PME 42: 0 0 0 0 GICv2 145 Level xhci-hcd:usb1 43: 94 0 0 0 GICv2 71 Level mmc1 44: 0 0 0 0 GICv2 70 Level mmc0 IPI0: 23 666 154 98 Rescheduling interrupts IPI1: 247 1053 1701 634 Function call interrupts IPI2: 0 0 0 0 CPU stop interrupts IPI3: 0 0 0 0 CPU stop (for crash dump) interrupts IPI4: 0 0 0 0 Timer broadcast interrupts IPI5: 7 9 5 0 IRQ work interrupts IPI6: 0 0 0 0 CPU wake-up interrupts ERR: 0 Link: https://lkml.kernel.org/r/20230406220451.1583239-1-f.fainelli@gmail.com Signed-off-by: Florian Fainelli Cc: Jan Kiszka Cc: Kieran Bingham Signed-off-by: Andrew Morton --- scripts/gdb/linux/constants.py.in | 14 +++ scripts/gdb/linux/interrupts.py | 232 ++++++++++++++++++++++++++++++++++++++ scripts/gdb/vmlinux-gdb.py | 1 + 3 files changed, 247 insertions(+) create mode 100644 scripts/gdb/linux/interrupts.py (limited to 'scripts') diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in index e484e2e7e4d5..36fd2b145853 100644 --- a/scripts/gdb/linux/constants.py.in +++ b/scripts/gdb/linux/constants.py.in @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,10 @@ LX_VALUE(SB_NODIRATIME) /* linux/htimer.h */ LX_GDBPARSED(hrtimer_resolution) +/* linux/irq.h */ +LX_GDBPARSED(IRQD_LEVEL) +LX_GDBPARSED(IRQ_HIDDEN) + /* linux/mount.h */ LX_VALUE(MNT_NOSUID) LX_VALUE(MNT_NODEV) @@ -85,3 +90,12 @@ LX_CONFIG(CONFIG_HIGH_RES_TIMERS) LX_CONFIG(CONFIG_NR_CPUS) LX_CONFIG(CONFIG_OF) LX_CONFIG(CONFIG_TICK_ONESHOT) +LX_CONFIG(CONFIG_GENERIC_IRQ_SHOW_LEVEL) +LX_CONFIG(CONFIG_X86_LOCAL_APIC) +LX_CONFIG(CONFIG_SMP) +LX_CONFIG(CONFIG_X86_THERMAL_VECTOR) +LX_CONFIG(CONFIG_X86_MCE_THRESHOLD) +LX_CONFIG(CONFIG_X86_MCE_AMD) +LX_CONFIG(CONFIG_X86_MCE) +LX_CONFIG(CONFIG_X86_IO_APIC) +LX_CONFIG(CONFIG_HAVE_KVM) diff --git a/scripts/gdb/linux/interrupts.py b/scripts/gdb/linux/interrupts.py new file mode 100644 index 000000000000..ef478e273791 --- /dev/null +++ b/scripts/gdb/linux/interrupts.py @@ -0,0 +1,232 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright 2023 Broadcom + +import gdb + +from linux import constants +from linux import cpus +from linux import utils +from linux import radixtree + +irq_desc_type = utils.CachedType("struct irq_desc") + +def irq_settings_is_hidden(desc): + return desc['status_use_accessors'] & constants.LX_IRQ_HIDDEN + +def irq_desc_is_chained(desc): + return desc['action'] and desc['action'] == gdb.parse_and_eval("&chained_action") + +def irqd_is_level(desc): + return desc['irq_data']['common']['state_use_accessors'] & constants.LX_IRQD_LEVEL + +def show_irq_desc(prec, irq): + text = "" + + desc = radixtree.lookup(gdb.parse_and_eval("&irq_desc_tree"), irq) + if desc is None: + return text + + desc = desc.cast(irq_desc_type.get_type()) + if desc is None: + return text + + if irq_settings_is_hidden(desc): + return text + + any_count = 0 + if desc['kstat_irqs']: + for cpu in cpus.each_online_cpu(): + any_count += cpus.per_cpu(desc['kstat_irqs'], cpu) + + if (desc['action'] == 0 or irq_desc_is_chained(desc)) and any_count == 0: + return text; + + text += "%*d: " % (prec, irq) + for cpu in cpus.each_online_cpu(): + if desc['kstat_irqs']: + count = cpus.per_cpu(desc['kstat_irqs'], cpu) + else: + count = 0 + text += "%10u" % (count) + + name = "None" + if desc['irq_data']['chip']: + chip = desc['irq_data']['chip'] + if chip['name']: + name = chip['name'].string() + else: + name = "-" + + text += " %8s" % (name) + + if desc['irq_data']['domain']: + text += " %*lu" % (prec, desc['irq_data']['hwirq']) + else: + text += " %*s" % (prec, "") + + if constants.LX_CONFIG_GENERIC_IRQ_SHOW_LEVEL: + text += " %-8s" % ("Level" if irqd_is_level(desc) else "Edge") + + if desc['name']: + text += "-%-8s" % (desc['name'].string()) + + """ Some toolchains may not be able to provide information about irqaction """ + try: + gdb.lookup_type("struct irqaction") + action = desc['action'] + if action is not None: + text += " %s" % (action['name'].string()) + while True: + action = action['next'] + if action is not None: + break + if action['name']: + text += ", %s" % (action['name'].string()) + except: + pass + + text += "\n" + + return text + +def show_irq_err_count(prec): + cnt = utils.gdb_eval_or_none("irq_err_count") + text = "" + if cnt is not None: + text += "%*s: %10u\n" % (prec, "ERR", cnt['counter']) + return text + +def x86_show_irqstat(prec, pfx, field, desc): + irq_stat = gdb.parse_and_eval("&irq_stat") + text = "%*s: " % (prec, pfx) + for cpu in cpus.each_online_cpu(): + stat = cpus.per_cpu(irq_stat, cpu) + text += "%10u " % (stat[field]) + text += " %s\n" % (desc) + return text + +def x86_show_mce(prec, var, pfx, desc): + pvar = gdb.parse_and_eval(var) + text = "%*s: " % (prec, pfx) + for cpu in cpus.each_online_cpu(): + text += "%10u " % (cpus.per_cpu(pvar, cpu)) + text += " %s\n" % (desc) + return text + +def x86_show_interupts(prec): + text = x86_show_irqstat(prec, "NMI", '__nmi_count', 'Non-maskable interrupts') + + if constants.LX_CONFIG_X86_LOCAL_APIC: + text += x86_show_irqstat(prec, "LOC", 'apic_timer_irqs', "Local timer interrupts") + text += x86_show_irqstat(prec, "SPU", 'irq_spurious_count', "Spurious interrupts") + text += x86_show_irqstat(prec, "PMI", 'apic_perf_irqs', "Performance monitoring interrupts") + text += x86_show_irqstat(prec, "IWI", 'apic_irq_work_irqs', "IRQ work interrupts") + text += x86_show_irqstat(prec, "RTR", 'icr_read_retry_count', "APIC ICR read retries") + if utils.gdb_eval_or_none("x86_platform_ipi_callback") is not None: + text += x86_show_irqstat(prec, "PLT", 'x86_platform_ipis', "Platform interrupts") + + if constants.LX_CONFIG_SMP: + text += x86_show_irqstat(prec, "RES", 'irq_resched_count', "Rescheduling interrupts") + text += x86_show_irqstat(prec, "CAL", 'irq_call_count', "Function call interrupts") + text += x86_show_irqstat(prec, "TLB", 'irq_tlb_count', "TLB shootdowns") + + if constants.LX_CONFIG_X86_THERMAL_VECTOR: + text += x86_show_irqstat(prec, "TRM", 'irq_thermal_count', "Thermal events interrupts") + + if constants.LX_CONFIG_X86_MCE_THRESHOLD: + text += x86_show_irqstat(prec, "THR", 'irq_threshold_count', "Threshold APIC interrupts") + + if constants.LX_CONFIG_X86_MCE_AMD: + text += x86_show_irqstat(prec, "DFR", 'irq_deferred_error_count', "Deferred Error APIC interrupts") + + if constants.LX_CONFIG_X86_MCE: + text += x86_show_mce(prec, "&mce_exception_count", "MCE", "Machine check exceptions") + text == x86_show_mce(prec, "&mce_poll_count", "MCP", "Machine check polls") + + text += show_irq_err_count(prec) + + if constants.LX_CONFIG_X86_IO_APIC: + cnt = utils.gdb_eval_or_none("irq_mis_count") + if cnt is not None: + text += "%*s: %10u\n" % (prec, "MIS", cnt['counter']) + + if constants.LX_CONFIG_HAVE_KVM: + text += x86_show_irqstat(prec, "PIN", 'kvm_posted_intr_ipis', 'Posted-interrupt notification event') + text += x86_show_irqstat(prec, "NPI", 'kvm_posted_intr_nested_ipis', 'Nested posted-interrupt event') + text += x86_show_irqstat(prec, "PIW", 'kvm_posted_intr_wakeup_ipis', 'Posted-interrupt wakeup event') + + return text + +def arm_common_show_interrupts(prec): + text = "" + nr_ipi = utils.gdb_eval_or_none("nr_ipi") + ipi_desc = utils.gdb_eval_or_none("ipi_desc") + ipi_types = utils.gdb_eval_or_none("ipi_types") + if nr_ipi is None or ipi_desc is None or ipi_types is None: + return text + + if prec >= 4: + sep = " " + else: + sep = "" + + for ipi in range(nr_ipi): + text += "%*s%u:%s" % (prec - 1, "IPI", ipi, sep) + desc = ipi_desc[ipi].cast(irq_desc_type.get_type().pointer()) + if desc == 0: + continue + for cpu in cpus.each_online_cpu(): + text += "%10u" % (cpus.per_cpu(desc['kstat_irqs'], cpu)) + text += " %s" % (ipi_types[ipi].string()) + text += "\n" + return text + +def aarch64_show_interrupts(prec): + text = arm_common_show_interrupts(prec) + text += "%*s: %10lu\n" % (prec, "ERR", gdb.parse_and_eval("irq_err_count")) + return text + +def arch_show_interrupts(prec): + text = "" + if utils.is_target_arch("x86"): + text += x86_show_interupts(prec) + elif utils.is_target_arch("aarch64"): + text += aarch64_show_interrupts(prec) + elif utils.is_target_arch("arm"): + text += arm_common_show_interrupts(prec) + elif utils.is_target_arch("mips"): + text += show_irq_err_count(prec) + else: + raise gdb.GdbError("Unsupported architecture: {}".format(target_arch)) + + return text + +class LxInterruptList(gdb.Command): + """Print /proc/interrupts""" + + def __init__(self): + super(LxInterruptList, self).__init__("lx-interruptlist", gdb.COMMAND_DATA) + + def invoke(self, arg, from_tty): + nr_irqs = gdb.parse_and_eval("nr_irqs") + prec = 3 + j = 1000 + while prec < 10 and j <= nr_irqs: + prec += 1 + j *= 10 + + gdb.write("%*s" % (prec + 8, "")) + for cpu in cpus.each_online_cpu(): + gdb.write("CPU%-8d" % cpu) + gdb.write("\n") + + if utils.gdb_eval_or_none("&irq_desc_tree") is None: + return + + for irq in range(nr_irqs): + gdb.write(show_irq_desc(prec, irq)) + gdb.write(arch_show_interrupts(prec)) + + +LxInterruptList() diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py index 2f57adcf3dff..2a72f91059b5 100644 --- a/scripts/gdb/vmlinux-gdb.py +++ b/scripts/gdb/vmlinux-gdb.py @@ -42,3 +42,4 @@ else: import linux.device import linux.mm import linux.radixtree + import linux.interrupts -- cgit From 29692fc92c5b6a2c7cfe6f588ef68272e3343647 Mon Sep 17 00:00:00 2001 From: Amjad Ouled-Ameur Date: Thu, 6 Apr 2023 15:12:17 -0700 Subject: scripts/gdb: timerlist: convert int chunks to str join() expects strings but integers are given. Convert chunks list to strings before passing it to join() Link: https://lkml.kernel.org/r/20230406221217.1585486-4-f.fainelli@gmail.com Signed-off-by: Amjad Ouled-Ameur Signed-by: Florian Fainelli Tested-by: Florian Fainelli Cc: Jan Kiszka Signed-off-by: Andrew Morton --- scripts/gdb/linux/timerlist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/timerlist.py b/scripts/gdb/linux/timerlist.py index 249f0e804b24..64bc87191003 100644 --- a/scripts/gdb/linux/timerlist.py +++ b/scripts/gdb/linux/timerlist.py @@ -174,7 +174,7 @@ def pr_cpumask(mask): if 0 < extra <= 4: chunks[0] = chunks[0][0] # Cut off the first 0 - return "".join(chunks) + return "".join(str(chunks)) class LxTimerList(gdb.Command): -- cgit From f4efbdaf59e959507a1a931ec4afecdfb09db76e Mon Sep 17 00:00:00 2001 From: Glenn Washburn Date: Tue, 28 Feb 2023 18:53:34 -0600 Subject: scripts/gdb: create linux/vfs.py for VFS related GDB helpers Patch series "GDB VFS utils". I've created a couple GDB convenience functions that I found useful when debugging some VFS issues and figure others might find them useful. For instance, they are useful in setting conditional breakpoints on VFS functions where you only care if the dentry path is a certain value. I took the opportunity to create a new "vfs" python module to give VFS related utilities a home. This patch (of 2): This will allow for more VFS specific GDB helpers to be collected in one place. Move utils.dentry_name into the vfs modules. Also a local variable in proc.py was changed from vfs to mnt to prevent a naming collision with the new vfs module. [akpm@linux-foundation.org: add SPDX-License-Identifier] Link: https://lkml.kernel.org/r/cover.1677631565.git.development@efficientek.com Link: https://lkml.kernel.org/r/7bba4c065a8c2c47f1fc5b03a7278005b04db251.1677631565.git.development@efficientek.com Signed-off-by: Glenn Washburn Cc: Alexander Viro Cc: Antonio Borneo Cc: Jan Kiszka Cc: John Ogness Cc: Kieran Bingham Cc: Petr Mladek Signed-off-by: Andrew Morton --- scripts/gdb/linux/proc.py | 16 +++++++++------- scripts/gdb/linux/utils.py | 8 -------- scripts/gdb/linux/vfs.py | 22 ++++++++++++++++++++++ scripts/gdb/vmlinux-gdb.py | 1 + 4 files changed, 32 insertions(+), 15 deletions(-) create mode 100644 scripts/gdb/linux/vfs.py (limited to 'scripts') diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py index 09cd871925a5..43c687e7a69d 100644 --- a/scripts/gdb/linux/proc.py +++ b/scripts/gdb/linux/proc.py @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # gdb helper commands and functions for Linux kernel debugging # @@ -16,6 +17,7 @@ from linux import constants from linux import utils from linux import tasks from linux import lists +from linux import vfs from struct import * @@ -170,16 +172,16 @@ values of that process namespace""" gdb.write("{:^18} {:^15} {:>9} {} {} options\n".format( "mount", "super_block", "devname", "pathname", "fstype")) - for vfs in lists.list_for_each_entry(namespace['list'], + for mnt in lists.list_for_each_entry(namespace['list'], mount_ptr_type, "mnt_list"): - devname = vfs['mnt_devname'].string() + devname = mnt['mnt_devname'].string() devname = devname if devname else "none" pathname = "" - parent = vfs + parent = mnt while True: mntpoint = parent['mnt_mountpoint'] - pathname = utils.dentry_name(mntpoint) + pathname + pathname = vfs.dentry_name(mntpoint) + pathname if (parent == parent['mnt_parent']): break parent = parent['mnt_parent'] @@ -187,14 +189,14 @@ values of that process namespace""" if (pathname == ""): pathname = "/" - superblock = vfs['mnt']['mnt_sb'] + superblock = mnt['mnt']['mnt_sb'] fstype = superblock['s_type']['name'].string() s_flags = int(superblock['s_flags']) - m_flags = int(vfs['mnt']['mnt_flags']) + m_flags = int(mnt['mnt']['mnt_flags']) rd = "ro" if (s_flags & constants.LX_SB_RDONLY) else "rw" gdb.write("{} {} {} {} {} {}{}{} 0 0\n".format( - vfs.format_string(), superblock.format_string(), devname, + mnt.format_string(), superblock.format_string(), devname, pathname, fstype, rd, info_opts(FS_INFO, s_flags), info_opts(MNT_INFO, m_flags))) diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py index 7f36aee32ac6..9f44df13761e 100644 --- a/scripts/gdb/linux/utils.py +++ b/scripts/gdb/linux/utils.py @@ -196,11 +196,3 @@ def gdb_eval_or_none(expresssion): return gdb.parse_and_eval(expresssion) except gdb.error: return None - - -def dentry_name(d): - parent = d['d_parent'] - if parent == d or parent == 0: - return "" - p = dentry_name(d['d_parent']) + "/" - return p + d['d_iname'].string() diff --git a/scripts/gdb/linux/vfs.py b/scripts/gdb/linux/vfs.py new file mode 100644 index 000000000000..62d4f9ad7d79 --- /dev/null +++ b/scripts/gdb/linux/vfs.py @@ -0,0 +1,22 @@ +# +# gdb helper commands and functions for Linux kernel debugging +# +# VFS tools +# +# Copyright (c) 2023 Glenn Washburn +# Copyright (c) 2016 Linaro Ltd +# +# Authors: +# Glenn Washburn +# Kieran Bingham +# +# This work is licensed under the terms of the GNU GPL version 2. +# + + +def dentry_name(d): + parent = d['d_parent'] + if parent == d or parent == 0: + return "" + p = dentry_name(d['d_parent']) + "/" + return p + d['d_iname'].string() diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py index 2a72f91059b5..2d32308c3f7a 100644 --- a/scripts/gdb/vmlinux-gdb.py +++ b/scripts/gdb/vmlinux-gdb.py @@ -40,6 +40,7 @@ else: import linux.clk import linux.genpd import linux.device + import linux.vfs import linux.mm import linux.radixtree import linux.interrupts -- cgit From 5a10562bdeb58006de4b1cd5f671b7da26b20bb3 Mon Sep 17 00:00:00 2001 From: Glenn Washburn Date: Tue, 28 Feb 2023 18:53:35 -0600 Subject: scripts/gdb: add GDB convenience functions $lx_dentry_name() and $lx_i_dentry() $lx_dentry_name() generates a full VFS path from a given dentry pointer, and $lx_i_dentry() returns the dentry pointer associated with the given inode pointer, if there is one. Link: https://lkml.kernel.org/r/c9a5ad8efbfbd2cc6559e082734eed7628f43a16.1677631565.git.development@efficientek.com Signed-off-by: Glenn Washburn Cc: Alexander Viro Cc: Antonio Borneo Cc: Jan Kiszka Cc: John Ogness Cc: Kieran Bingham Cc: Petr Mladek Signed-off-by: Andrew Morton --- scripts/gdb/linux/vfs.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'scripts') diff --git a/scripts/gdb/linux/vfs.py b/scripts/gdb/linux/vfs.py index 62d4f9ad7d79..c77b9ce75f6d 100644 --- a/scripts/gdb/linux/vfs.py +++ b/scripts/gdb/linux/vfs.py @@ -13,6 +13,9 @@ # This work is licensed under the terms of the GNU GPL version 2. # +import gdb +from linux import utils + def dentry_name(d): parent = d['d_parent'] @@ -20,3 +23,37 @@ def dentry_name(d): return "" p = dentry_name(d['d_parent']) + "/" return p + d['d_iname'].string() + +class DentryName(gdb.Function): + """Return string of the full path of a dentry. + +$lx_dentry_name(PTR): Given PTR to a dentry struct, return a string +of the full path of the dentry.""" + + def __init__(self): + super(DentryName, self).__init__("lx_dentry_name") + + def invoke(self, dentry_ptr): + return dentry_name(dentry_ptr) + +DentryName() + + +dentry_type = utils.CachedType("struct dentry") + +class InodeDentry(gdb.Function): + """Return dentry pointer for inode. + +$lx_i_dentry(PTR): Given PTR to an inode struct, return a pointer to +the associated dentry struct, if there is one.""" + + def __init__(self): + super(InodeDentry, self).__init__("lx_i_dentry") + + def invoke(self, inode_ptr): + d_u = inode_ptr["i_dentry"]["first"] + if d_u == 0: + return "" + return utils.container_of(d_u, dentry_type.get_type().pointer(), "d_u") + +InodeDentry() -- cgit From a04bb4c24a4846232a81047784d5eff2848e45bd Mon Sep 17 00:00:00 2001 From: Dmitry Rokosov Date: Tue, 4 Apr 2023 22:17:15 +0300 Subject: checkpatch: introduce proper bindings license check All headers from 'include/dt-bindings/' must be verified by checkpatch together with Documentation bindings, because all of them are part of the whole DT bindings system. The requirement is dual licensed and matching patterns: * Schemas: /GPL-2\.0(?:-only)? OR BSD-2-Clause/ * Headers: /GPL-2\.0(?:-only)? OR \S+/ Above patterns suggested by Rob at: https://lore.kernel.org/all/CAL_Jsq+-YJsBO+LuPJ=ZQ=eb-monrwzuCppvReH+af7hYZzNaQ@mail.gmail.com The issue was found during patch review: https://lore.kernel.org/all/20230313201259.19998-4-ddrokosov@sberdevices.ru/ Link: https://lkml.kernel.org/r/20230404191715.7319-1-ddrokosov@sberdevices.ru Signed-off-by: Dmitry Rokosov Reviewed-by: Rob Herring Cc: Andy Whitcroft Cc: Dwaipayan Ray Cc: Joe Perches Cc: Krzysztof Kozlowski Cc: Lukas Bulwahn Signed-off-by: Andrew Morton --- scripts/checkpatch.pl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 3e6f5a8614d3..23bb211de4ce 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3763,7 +3763,7 @@ sub process { "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); } if ($realfile =~ m@^Documentation/devicetree/bindings/@ && - not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) { + $spdx_license !~ /GPL-2\.0(?:-only)? OR BSD-2-Clause/) { my $msg_level = \&WARN; $msg_level = \&CHK if ($file); if (&{$msg_level}("SPDX_LICENSE_TAG", @@ -3773,6 +3773,11 @@ sub process { $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/; } } + if ($realfile =~ m@^include/dt-bindings/@ && + $spdx_license !~ /GPL-2\.0(?:-only)? OR \S+/) { + WARN("SPDX_LICENSE_TAG", + "DT binding headers should be licensed (GPL-2.0-only OR .*)\n" . $herecurr); + } } } } -- cgit From 47981b5cc6871d78aee67b6c9ae70aff90ddb97d Mon Sep 17 00:00:00 2001 From: Alexandre Ghiti Date: Wed, 29 Mar 2023 06:53:27 +0200 Subject: powerpc: Move script to check relocations at compile time in scripts/ Relocating kernel at runtime is done very early in the boot process, so it is not convenient to check for relocations there and react in case a relocation was not expected. Powerpc architecture has a script that allows to check at compile time for such unexpected relocations: extract the common logic to scripts/ so that other architectures can take advantage of it. Signed-off-by: Alexandre Ghiti Reviewed-by: Anup Patel Acked-by: Michael Ellerman (powerpc) Link: https://lore.kernel.org/r/20230329045329.64565-5-alexghiti@rivosinc.com Signed-off-by: Palmer Dabbelt --- arch/powerpc/tools/relocs_check.sh | 18 ++---------------- scripts/relocs_check.sh | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 16 deletions(-) create mode 100755 scripts/relocs_check.sh (limited to 'scripts') diff --git a/arch/powerpc/tools/relocs_check.sh b/arch/powerpc/tools/relocs_check.sh index 63792af00417..6b350e75014c 100755 --- a/arch/powerpc/tools/relocs_check.sh +++ b/arch/powerpc/tools/relocs_check.sh @@ -15,21 +15,8 @@ if [ $# -lt 3 ]; then exit 1 fi -# Have Kbuild supply the path to objdump and nm so we handle cross compilation. -objdump="$1" -nm="$2" -vmlinux="$3" - -# Remove from the bad relocations those that match an undefined weak symbol -# which will result in an absolute relocation to 0. -# Weak unresolved symbols are of that form in nm output: -# " w _binary__btf_vmlinux_bin_end" -undef_weak_symbols=$($nm "$vmlinux" | awk '$1 ~ /w/ { print $2 }') - bad_relocs=$( -$objdump -R "$vmlinux" | - # Only look at relocation lines. - grep -E '\ Date: Fri, 10 Feb 2023 16:26:22 +0100 Subject: rust: fix regexp in scripts/is_rust_module.sh nm can use "R" or "r" to show read-only data sections, but scripts/is_rust_module.sh can only recognize "r", so with some versions of binutils it can fail to detect if a module is a Rust module or not. Right now we're using this script only to determine if we need to skip BTF generation (that is disabled globally if CONFIG_RUST is enabled), but it's still nice to fix this script to do the proper job. Moreover, with this patch applied I can also relax the constraint of "RUST depends on !DEBUG_INFO_BTF" and build a kernel with Rust and BTF enabled at the same time (of course BTF generation is still skipped for Rust modules). [ Miguel: The actual reason is likely to be a change on the Rust compiler between 1.61.0 and 1.62.0: echo '#[used] static S: () = ();' | rustup run 1.61.0 rustc --emit=obj --crate-type=lib - && nm rust_out.o echo '#[used] static S: () = ();' | rustup run 1.62.0 rustc --emit=obj --crate-type=lib - && nm rust_out.o Gives: 0000000000000000 r _ZN8rust_out1S17h48027ce0da975467E 0000000000000000 R _ZN8rust_out1S17h58e1f3d9c0e97cefE See https://godbolt.org/z/KE6jneoo4. ] Signed-off-by: Andrea Righi Reviewed-by: Vincenzo Palazzo Reviewed-by: Eric Curtin Reviewed-by: Martin Rodriguez Reboredo Signed-off-by: Miguel Ojeda --- scripts/is_rust_module.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/is_rust_module.sh b/scripts/is_rust_module.sh index 28b3831a7593..464761a7cf7f 100755 --- a/scripts/is_rust_module.sh +++ b/scripts/is_rust_module.sh @@ -13,4 +13,4 @@ set -e # # In the future, checking for the `.comment` section may be another # option, see https://github.com/rust-lang/rust/pull/97550. -${NM} "$*" | grep -qE '^[0-9a-fA-F]+ r _R[^[:space:]]+16___IS_RUST_MODULE[^[:space:]]*$' +${NM} "$*" | grep -qE '^[0-9a-fA-F]+ [Rr] _R[^[:space:]]+16___IS_RUST_MODULE[^[:space:]]*$' -- cgit From 5a43001c01691dcbd396541e6faa2c0077378f48 Mon Sep 17 00:00:00 2001 From: Ekaterina Orlova Date: Fri, 21 Apr 2023 15:35:39 +0100 Subject: ASN.1: Fix check for strdup() success It seems there is a misprint in the check of strdup() return code that can lead to NULL pointer dereference. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 4520c6a49af8 ("X.509: Add simple ASN.1 grammar compiler") Signed-off-by: Ekaterina Orlova Cc: David Woodhouse Cc: James Bottomley Cc: Jarkko Sakkinen Cc: keyrings@vger.kernel.org Cc: linux-kbuild@vger.kernel.org Link: https://lore.kernel.org/r/20230315172130.140-1-vorobushek.ok@gmail.com/ Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- scripts/asn1_compiler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/asn1_compiler.c b/scripts/asn1_compiler.c index 7b6756a8c15d..4c3f645065a4 100644 --- a/scripts/asn1_compiler.c +++ b/scripts/asn1_compiler.c @@ -625,7 +625,7 @@ int main(int argc, char **argv) p = strrchr(argv[1], '/'); p = p ? p + 1 : argv[1]; grammar_name = strdup(p); - if (!p) { + if (!grammar_name) { perror(NULL); exit(1); } -- cgit From 8b824220bd6641976676ae7a1e925db63eb89c4b Mon Sep 17 00:00:00 2001 From: Woody Suwalski Date: Fri, 31 Mar 2023 10:15:40 -0400 Subject: kbuild: deb-pkg: Fix a spell typo in mkdebian script Signed-off-by: Woody Suwalski Signed-off-by: Masahiro Yamada --- scripts/package/mkdebian | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index a4c2c2276223..74b83c9ae0a8 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -190,7 +190,7 @@ EOF # Generate copyright file cat < debian/copyright -This is a packacked upstream version of the Linux kernel. +This is a packaged upstream version of the Linux kernel. The sources may be found at most Linux archive sites, including: https://www.kernel.org/pub/linux/kernel -- cgit From 9cedc5e89a59da72bfecdb76bfaa5a28a273029d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 20 Apr 2023 02:04:24 +0900 Subject: kbuild: use proper prefix for tarballs to fix rpm-pkg build error Since commit f8d94c4e403c ("kbuild: do not create intermediate *.tar for source tarballs"), 'make rpm-pkg' fails because the prefix of the source tarball is 'linux.tar/' instead of 'linux/'. $(basename $@) strips only '.gz' from the filename linux.tar.gz. You need to strip two suffixes from compressed tarballs and one suffix from uncompressed tarballs (for example 'perf-6.3.0.tar' generated by 'make perf-tar-src-pkg'). One tricky fix might be --prefix=$(firstword $(subst .tar, ,$@))/ but I think it is better to hard-code the prefix. Fixes: f8d94c4e403c ("kbuild: do not create intermediate *.tar for source tarballs") Reported-by: Jiwei Sun Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/Makefile.package | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.package b/scripts/Makefile.package index 4d90691505b1..4000ad04c122 100644 --- a/scripts/Makefile.package +++ b/scripts/Makefile.package @@ -49,7 +49,7 @@ git-config-tar.zst = -c tar.tar.zst.command="$(ZSTD)" quiet_cmd_archive = ARCHIVE $@ cmd_archive = git -C $(srctree) $(git-config-tar$(suffix $@)) archive \ - --output=$$(realpath $@) --prefix=$(basename $@)/ $(archive-args) + --output=$$(realpath $@) $(archive-args) # Linux source tarball # --------------------------------------------------------------------------- @@ -57,7 +57,7 @@ quiet_cmd_archive = ARCHIVE $@ linux-tarballs := $(addprefix linux, .tar.gz) targets += $(linux-tarballs) -$(linux-tarballs): archive-args = $$(cat $<) +$(linux-tarballs): archive-args = --prefix=linux/ $$(cat $<) $(linux-tarballs): .tmp_HEAD FORCE $(call if_changed,archive) @@ -189,7 +189,7 @@ perf-archive-args = --add-file=$$(realpath $(word 2, $^)) \ perf-tarballs := $(addprefix perf-$(KERNELVERSION), .tar .tar.gz .tar.bz2 .tar.xz .tar.zst) targets += $(perf-tarballs) -$(perf-tarballs): archive-args = $(perf-archive-args) +$(perf-tarballs): archive-args = --prefix=perf-$(KERNELVERSION)/ $(perf-archive-args) $(perf-tarballs): tools/perf/MANIFEST .tmp_perf/HEAD .tmp_perf/PERF-VERSION-FILE FORCE $(call if_changed,archive) -- cgit From 31f735c65d4f4825c57620f39f2fa27aa01ac172 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 17 Apr 2023 23:25:47 +0900 Subject: kbuild: add srcdeb-pkg target This new target builds only the debian source package. Unify the build rules of deb-pkg, srcdeb-pkg, bindeb-pkg to avoid code duplication. --no-check-builddeps is added to srcdeb-pkg so that build dependencies will not be checked. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/Makefile.package | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.package b/scripts/Makefile.package index 4d90691505b1..d8a36304b26e 100644 --- a/scripts/Makefile.package +++ b/scripts/Makefile.package @@ -5,7 +5,6 @@ include $(srctree)/scripts/Kbuild.include include $(srctree)/scripts/Makefile.lib KERNELPATH := kernel-$(subst -,_,$(KERNELRELEASE)) -KBUILD_PKG_ROOTCMD ?="fakeroot -u" # Include only those top-level files that are needed by make, plus the GPL copy TAR_CONTENT := Documentation LICENSES arch block certs crypto drivers fs \ include init io_uring ipc kernel lib mm net rust \ @@ -86,6 +85,9 @@ binrpm-pkg: +rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \ $(UTS_MACHINE)-linux -bb $(objtree)/binkernel.spec +# deb-pkg srcdeb-pkg bindeb-pkg +# --------------------------------------------------------------------------- + quiet_cmd_debianize = GEN $@ cmd_debianize = $(srctree)/scripts/package/mkdebian $(mkdebian-opts) @@ -104,14 +106,25 @@ debian-orig: linux.tar.gz debian cp $< ../$(orig-name); \ fi -PHONY += deb-pkg -deb-pkg: debian-orig - +dpkg-buildpackage -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch) $(DPKG_FLAGS) \ - --build=source,binary -nc -us -uc +KBUILD_PKG_ROOTCMD ?= 'fakeroot -u' + +PHONY += deb-pkg srcdeb-pkg bindeb-pkg + +deb-pkg: private build-type := source,binary +srcdeb-pkg: private build-type := source +bindeb-pkg: private build-type := binary -PHONY += bindeb-pkg +deb-pkg srcdeb-pkg: debian-orig bindeb-pkg: debian - +dpkg-buildpackage -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch) $(DPKG_FLAGS) -b -nc -uc +deb-pkg srcdeb-pkg bindeb-pkg: + +$(strip dpkg-buildpackage \ + --build=$(build-type) --no-pre-clean --unsigned-changes \ + $(if $(findstring source, $(build-type)), \ + --unsigned-source) \ + $(if $(findstring binary, $(build-type)), \ + -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch), \ + --no-check-builddeps) \ + $(DPKG_FLAGS)) PHONY += intdeb-pkg intdeb-pkg: @@ -208,6 +221,7 @@ help: @echo ' srcrpm-pkg - Build only the source kernel RPM package' @echo ' binrpm-pkg - Build only the binary kernel RPM package' @echo ' deb-pkg - Build both source and binary deb kernel packages' + @echo ' srcdeb-pkg - Build only the source kernel deb package' @echo ' bindeb-pkg - Build only the binary kernel deb package' @echo ' snap-pkg - Build only the binary kernel snap package' @echo ' (will connect to external hosts)' -- cgit From 1a261a6e10e80cd7c69c3f5bdf47cd41f928fd08 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Tue, 25 Apr 2023 00:21:10 +0800 Subject: scripts: Remove ICC-related dead code Intel compiler support has already been completely removed in commit 95207db8166a ("Remove Intel compiler support"). However, it appears that there is still some ICC-related code in scripts/cc-version.sh. There is no harm in leaving the code as it is, but removing the dead code makes the codebase a bit cleaner. Hopefully all ICC-related stuff in the build scripts will be removed after this commit, given the grep output as below: (linux/scripts) $ grep -i -w -R 'icc' cc-version.sh:ICC) cc-version.sh: min_version=$($min_tool_version icc) dtc/include-prefixes/arm64/qcom/sm6350.dtsi:#include Fixes: 95207db8166a ("Remove Intel compiler support") Signed-off-by: Ruihan Li Reviewed-by: Nick Desaulniers Reviewed-by: Nathan Chancellor Signed-off-by: Linus Torvalds --- scripts/cc-version.sh | 4 ---- 1 file changed, 4 deletions(-) (limited to 'scripts') diff --git a/scripts/cc-version.sh b/scripts/cc-version.sh index 0573c92e841d..a7e28b6a514e 100755 --- a/scripts/cc-version.sh +++ b/scripts/cc-version.sh @@ -45,10 +45,6 @@ Clang) version=$2.$3.$4 min_version=$($min_tool_version llvm) ;; -ICC) - version=$(($2 / 100)).$(($2 % 100)).$3 - min_version=$($min_tool_version icc) - ;; *) echo "$orig_args: unknown C compiler" >&2 exit 1 -- cgit From 1d29b4c223811871017542e96ac00ee562a37497 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 17 Apr 2023 23:25:48 +0900 Subject: kbuild: deb-pkg: add KDEB_SOURCE_COMPRESS to specify source compression Add KDEB_SOURCE_COMPRESS to specify the compression for the orig and debian tarballs. (cf. the existing KDEB_COMPRESS is used to specify the compression for binary packages.) Supported algorithms are gzip, bzip2, lzma, and xz, all of which are supported by dpkg-source. The current default is gzip. You can change it via the environment variable, for example, 'KDEB_SOURCE_COMPRESS=xz make deb-pkg'. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/Makefile.package | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.package b/scripts/Makefile.package index d8a36304b26e..b64042f62def 100644 --- a/scripts/Makefile.package +++ b/scripts/Makefile.package @@ -41,19 +41,25 @@ check-git: false; \ fi -git-config-tar.gz = -c tar.tar.gz.command="$(KGZIP)" -git-config-tar.bz2 = -c tar.tar.bz2.command="$(KBZIP2)" -git-config-tar.xz = -c tar.tar.xz.command="$(XZ)" -git-config-tar.zst = -c tar.tar.zst.command="$(ZSTD)" +git-config-tar.gz = -c tar.tar.gz.command="$(KGZIP)" +git-config-tar.bz2 = -c tar.tar.bz2.command="$(KBZIP2)" +git-config-tar.lzma = -c tar.tar.lzma.command="$(LZMA)" +git-config-tar.xz = -c tar.tar.xz.command="$(XZ)" +git-config-tar.zst = -c tar.tar.zst.command="$(ZSTD)" quiet_cmd_archive = ARCHIVE $@ cmd_archive = git -C $(srctree) $(git-config-tar$(suffix $@)) archive \ --output=$$(realpath $@) --prefix=$(basename $@)/ $(archive-args) +suffix-gzip := .gz +suffix-bzip2 := .bz2 +suffix-lzma := .lzma +suffix-xz := .xz + # Linux source tarball # --------------------------------------------------------------------------- -linux-tarballs := $(addprefix linux, .tar.gz) +linux-tarballs := $(addprefix linux, .tar.gz .tar.bz2 .tar.lzma .tar.xz) targets += $(linux-tarballs) $(linux-tarballs): archive-args = $$(cat $<) @@ -88,6 +94,19 @@ binrpm-pkg: # deb-pkg srcdeb-pkg bindeb-pkg # --------------------------------------------------------------------------- +KDEB_SOURCE_COMPRESS ?= gzip + +supported-deb-source-compress := gzip bzip2 lzma xz + +PHONY += linux.tar.unsupported-deb-src-compress +linux.tar.unsupported-deb-src-compress: + @echo "error: KDEB_SOURCE_COMPRESS=$(KDEB_SOURCE_COMPRESS) is not supported. The supported values are: $(supported-deb-source-compress)" >&2 + @false + +debian-orig-suffix := \ + $(strip $(if $(filter $(supported-deb-source-compress), $(KDEB_SOURCE_COMPRESS)), \ + $(suffix-$(KDEB_SOURCE_COMPRESS)),.unsupported-deb-src-compress)) + quiet_cmd_debianize = GEN $@ cmd_debianize = $(srctree)/scripts/package/mkdebian $(mkdebian-opts) @@ -97,9 +116,9 @@ debian: FORCE PHONY += debian-orig debian-orig: private source = $(shell dpkg-parsechangelog -S Source) debian-orig: private version = $(shell dpkg-parsechangelog -S Version | sed 's/-[^-]*$$//') -debian-orig: private orig-name = $(source)_$(version).orig.tar.gz +debian-orig: private orig-name = $(source)_$(version).orig.tar$(debian-orig-suffix) debian-orig: mkdebian-opts = --need-source -debian-orig: linux.tar.gz debian +debian-orig: linux.tar$(debian-orig-suffix) debian $(Q)if [ "$(df --output=target .. 2>/dev/null)" = "$(df --output=target $< 2>/dev/null)" ]; then \ ln -f $< ../$(orig-name); \ else \ @@ -120,7 +139,7 @@ deb-pkg srcdeb-pkg bindeb-pkg: +$(strip dpkg-buildpackage \ --build=$(build-type) --no-pre-clean --unsigned-changes \ $(if $(findstring source, $(build-type)), \ - --unsigned-source) \ + --unsigned-source --compression=$(KDEB_SOURCE_COMPRESS)) \ $(if $(findstring binary, $(build-type)), \ -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch), \ --no-check-builddeps) \ -- cgit From c90b3bbff2a097f4b6861c6d1aac18ed66f15261 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 17 Apr 2023 23:35:35 +0900 Subject: kbuild: rpm-pkg: remove kernel-drm PROVIDES This code was added more than 20 years ago. [1] I checked the kernel spec files in Fedora and OpenSUSE, but did not see 'kernel-drm'. I do not know if there exists a distro that uses it in RPM dependency. Remove this, and let's see if somebody complains about it. [1]: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=6d956df7d6b716b28c910c4f5b360c4d44d96c4d Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor --- scripts/package/mkspec | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/package/mkspec b/scripts/package/mkspec index fc8ad3fbc0a9..8049f0e2c110 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -28,11 +28,6 @@ else M=DEL fi -if grep -q CONFIG_DRM=y include/config/auto.conf; then - PROVIDES=kernel-drm -fi - -PROVIDES="$PROVIDES kernel-$KERNELRELEASE" __KERNELRELEASE=$(echo $KERNELRELEASE | sed -e "s/-/_/g") EXCLUDES="$RCS_TAR_IGNORE --exclude=*vmlinux* --exclude=*.mod \ --exclude=*.o --exclude=*.ko --exclude=*.cmd --exclude=Documentation \ @@ -55,7 +50,7 @@ sed -e '/^DEL/d' -e 's/^\t*//' < Date: Wed, 26 Apr 2023 09:05:27 +0800 Subject: recordmcount: Fix memory leaks in the uwrite function Common realloc mistake: 'file_append' nulled but not freed upon failure Link: https://lkml.kernel.org/r/20230426010527.703093-1-zenghao@kylinos.cn Signed-off-by: Hao Zeng Suggested-by: Steven Rostedt Signed-off-by: Steven Rostedt (Google) --- scripts/recordmcount.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index e30216525325..40ae6b2c7a6d 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -110,6 +110,7 @@ static ssize_t uwrite(void const *const buf, size_t const count) { size_t cnt = count; off_t idx = 0; + void *p = NULL; file_updated = 1; @@ -117,7 +118,10 @@ static ssize_t uwrite(void const *const buf, size_t const count) off_t aoffset = (file_ptr + count) - file_end; if (aoffset > file_append_size) { - file_append = realloc(file_append, aoffset); + p = realloc(file_append, aoffset); + if (!p) + free(file_append); + file_append = p; file_append_size = aoffset; } if (!file_append) { -- cgit From 9892bd72efdc9daa7c07ca9f427ac7e5928c7704 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 25 Apr 2023 20:08:59 +0900 Subject: kbuild: deb-pkg: specify targets in debian/rules as .PHONY If a file with the same name exists, the target is not run. For example, the following command fails. $ make O=build-arch bindeb-pkg [ snip ] sed: can't read modules.order: No such file or directory make[6]: *** [../Makefile:1577: __modinst_pre] Error 2 make[5]: *** [../scripts/Makefile.package:150: intdeb-pkg] Error 2 make[4]: *** [../Makefile:1657: intdeb-pkg] Error 2 make[3]: *** [debian/rules:14: binary-arch] Error 2 dpkg-buildpackage: error: debian/rules binary subprocess returned exit status 2 make[2]: *** [../scripts/Makefile.package:139: bindeb-pkg] Error 2 Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor --- scripts/package/mkdebian | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index a4c2c2276223..b6cb95473548 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -269,6 +269,8 @@ cat < debian/rules srctree ?= . KERNELRELEASE = ${KERNELRELEASE} +.PHONY: clean build build-arch build-indep binary binary-arch binary-indep + build-indep: build-arch: \$(MAKE) -f \$(srctree)/Makefile ARCH=${ARCH} \ -- cgit From e6ce9d741163af0b846637ce6550ae8a671b1588 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Wed, 5 Apr 2023 16:17:06 +0200 Subject: locking/atomic: Add generic try_cmpxchg{,64}_local() support Add generic support for try_cmpxchg{,64}_local() and their falbacks. These provides the generic try_cmpxchg_local family of functions from the arch_ prefixed version, also adding explicit instrumentation. Signed-off-by: Uros Bizjak Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Ingo Molnar Acked-by: Mark Rutland Link: https://lore.kernel.org/r/20230405141710.3551-2-ubizjak@gmail.com Cc: Linus Torvalds --- include/linux/atomic/atomic-arch-fallback.h | 24 +++++++++++++++++++++++- include/linux/atomic/atomic-instrumented.h | 20 +++++++++++++++++++- scripts/atomic/gen-atomic-fallback.sh | 4 ++++ scripts/atomic/gen-atomic-instrumented.sh | 2 +- 4 files changed, 47 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/include/linux/atomic/atomic-arch-fallback.h b/include/linux/atomic/atomic-arch-fallback.h index 4226379a232d..a6e4437c5f36 100644 --- a/include/linux/atomic/atomic-arch-fallback.h +++ b/include/linux/atomic/atomic-arch-fallback.h @@ -217,6 +217,28 @@ #endif /* arch_try_cmpxchg64_relaxed */ +#ifndef arch_try_cmpxchg_local +#define arch_try_cmpxchg_local(_ptr, _oldp, _new) \ +({ \ + typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ + ___r = arch_cmpxchg_local((_ptr), ___o, (_new)); \ + if (unlikely(___r != ___o)) \ + *___op = ___r; \ + likely(___r == ___o); \ +}) +#endif /* arch_try_cmpxchg_local */ + +#ifndef arch_try_cmpxchg64_local +#define arch_try_cmpxchg64_local(_ptr, _oldp, _new) \ +({ \ + typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ + ___r = arch_cmpxchg64_local((_ptr), ___o, (_new)); \ + if (unlikely(___r != ___o)) \ + *___op = ___r; \ + likely(___r == ___o); \ +}) +#endif /* arch_try_cmpxchg64_local */ + #ifndef arch_atomic_read_acquire static __always_inline int arch_atomic_read_acquire(const atomic_t *v) @@ -2646,4 +2668,4 @@ arch_atomic64_dec_if_positive(atomic64_t *v) #endif #endif /* _LINUX_ATOMIC_FALLBACK_H */ -// 00071fffa021cec66f6290d706d69c91df87bade +// ad2e2b4d168dbc60a73922616047a9bfa446af36 diff --git a/include/linux/atomic/atomic-instrumented.h b/include/linux/atomic/atomic-instrumented.h index 0496816738ca..245ba661c493 100644 --- a/include/linux/atomic/atomic-instrumented.h +++ b/include/linux/atomic/atomic-instrumented.h @@ -2132,6 +2132,24 @@ atomic_long_dec_if_positive(atomic_long_t *v) arch_sync_cmpxchg(__ai_ptr, __VA_ARGS__); \ }) +#define try_cmpxchg_local(ptr, oldp, ...) \ +({ \ + typeof(ptr) __ai_ptr = (ptr); \ + typeof(oldp) __ai_oldp = (oldp); \ + instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_write(__ai_oldp, sizeof(*__ai_oldp)); \ + arch_try_cmpxchg_local(__ai_ptr, __ai_oldp, __VA_ARGS__); \ +}) + +#define try_cmpxchg64_local(ptr, oldp, ...) \ +({ \ + typeof(ptr) __ai_ptr = (ptr); \ + typeof(oldp) __ai_oldp = (oldp); \ + instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_write(__ai_oldp, sizeof(*__ai_oldp)); \ + arch_try_cmpxchg64_local(__ai_ptr, __ai_oldp, __VA_ARGS__); \ +}) + #define cmpxchg_double(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ @@ -2149,4 +2167,4 @@ atomic_long_dec_if_positive(atomic_long_t *v) }) #endif /* _LINUX_ATOMIC_INSTRUMENTED_H */ -// 1b485de9cbaa4900de59e14ee2084357eaeb1c3a +// 97fe4d79aa058d2164df824632cbc4f716d2a407 diff --git a/scripts/atomic/gen-atomic-fallback.sh b/scripts/atomic/gen-atomic-fallback.sh index 3a07695e3c89..6e853f0dad8d 100755 --- a/scripts/atomic/gen-atomic-fallback.sh +++ b/scripts/atomic/gen-atomic-fallback.sh @@ -225,6 +225,10 @@ for cmpxchg in "cmpxchg" "cmpxchg64"; do gen_try_cmpxchg_fallbacks "${cmpxchg}" done +for cmpxchg in "cmpxchg_local" "cmpxchg64_local"; do + gen_try_cmpxchg_fallback "${cmpxchg}" "" +done + grep '^[a-z]' "$1" | while read name meta args; do gen_proto "${meta}" "${name}" "atomic" "int" ${args} done diff --git a/scripts/atomic/gen-atomic-instrumented.sh b/scripts/atomic/gen-atomic-instrumented.sh index 77c06526a574..c8165e9431bf 100755 --- a/scripts/atomic/gen-atomic-instrumented.sh +++ b/scripts/atomic/gen-atomic-instrumented.sh @@ -173,7 +173,7 @@ for xchg in "xchg" "cmpxchg" "cmpxchg64" "try_cmpxchg" "try_cmpxchg64"; do done done -for xchg in "cmpxchg_local" "cmpxchg64_local" "sync_cmpxchg"; do +for xchg in "cmpxchg_local" "cmpxchg64_local" "sync_cmpxchg" "try_cmpxchg_local" "try_cmpxchg64_local" ; do gen_xchg "${xchg}" "" "" printf "\n" done -- cgit From ec570320b09f76d52819e60abdccf372658216b6 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Thu, 13 Apr 2023 17:06:44 +0100 Subject: locking/atomic: Correct (cmp)xchg() instrumentation All xchg() and cmpxchg() ops are atomic RMWs, but currently we instrument these with instrument_atomic_write() rather than instrument_atomic_read_write(), missing the read aspect. Similarly, all try_cmpxchg() ops are non-atomic RMWs on *oldp, but we instrument these accesses with instrument_atomic_write() rather than instrument_read_write(), missing the read aspect and erroneously marking these as atomic. Fix the instrumentation for both points. Signed-off-by: Mark Rutland Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Ingo Molnar Link: https://lkml.kernel.org/r/20230413160644.490976-1-mark.rutland@arm.com Cc: Linus Torvalds --- include/linux/atomic/atomic-instrumented.h | 76 +++++++++++++++--------------- scripts/atomic/gen-atomic-instrumented.sh | 6 +-- 2 files changed, 41 insertions(+), 41 deletions(-) (limited to 'scripts') diff --git a/include/linux/atomic/atomic-instrumented.h b/include/linux/atomic/atomic-instrumented.h index 245ba661c493..03a232a1fa57 100644 --- a/include/linux/atomic/atomic-instrumented.h +++ b/include/linux/atomic/atomic-instrumented.h @@ -1948,14 +1948,14 @@ atomic_long_dec_if_positive(atomic_long_t *v) ({ \ typeof(ptr) __ai_ptr = (ptr); \ kcsan_mb(); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ arch_xchg(__ai_ptr, __VA_ARGS__); \ }) #define xchg_acquire(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ arch_xchg_acquire(__ai_ptr, __VA_ARGS__); \ }) @@ -1963,14 +1963,14 @@ atomic_long_dec_if_positive(atomic_long_t *v) ({ \ typeof(ptr) __ai_ptr = (ptr); \ kcsan_release(); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ arch_xchg_release(__ai_ptr, __VA_ARGS__); \ }) #define xchg_relaxed(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ arch_xchg_relaxed(__ai_ptr, __VA_ARGS__); \ }) @@ -1978,14 +1978,14 @@ atomic_long_dec_if_positive(atomic_long_t *v) ({ \ typeof(ptr) __ai_ptr = (ptr); \ kcsan_mb(); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ arch_cmpxchg(__ai_ptr, __VA_ARGS__); \ }) #define cmpxchg_acquire(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ arch_cmpxchg_acquire(__ai_ptr, __VA_ARGS__); \ }) @@ -1993,14 +1993,14 @@ atomic_long_dec_if_positive(atomic_long_t *v) ({ \ typeof(ptr) __ai_ptr = (ptr); \ kcsan_release(); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ arch_cmpxchg_release(__ai_ptr, __VA_ARGS__); \ }) #define cmpxchg_relaxed(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ arch_cmpxchg_relaxed(__ai_ptr, __VA_ARGS__); \ }) @@ -2008,14 +2008,14 @@ atomic_long_dec_if_positive(atomic_long_t *v) ({ \ typeof(ptr) __ai_ptr = (ptr); \ kcsan_mb(); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ arch_cmpxchg64(__ai_ptr, __VA_ARGS__); \ }) #define cmpxchg64_acquire(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ arch_cmpxchg64_acquire(__ai_ptr, __VA_ARGS__); \ }) @@ -2023,14 +2023,14 @@ atomic_long_dec_if_positive(atomic_long_t *v) ({ \ typeof(ptr) __ai_ptr = (ptr); \ kcsan_release(); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ arch_cmpxchg64_release(__ai_ptr, __VA_ARGS__); \ }) #define cmpxchg64_relaxed(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ arch_cmpxchg64_relaxed(__ai_ptr, __VA_ARGS__); \ }) @@ -2039,8 +2039,8 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(ptr) __ai_ptr = (ptr); \ typeof(oldp) __ai_oldp = (oldp); \ kcsan_mb(); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ - instrument_atomic_write(__ai_oldp, sizeof(*__ai_oldp)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ arch_try_cmpxchg(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) @@ -2048,8 +2048,8 @@ atomic_long_dec_if_positive(atomic_long_t *v) ({ \ typeof(ptr) __ai_ptr = (ptr); \ typeof(oldp) __ai_oldp = (oldp); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ - instrument_atomic_write(__ai_oldp, sizeof(*__ai_oldp)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ arch_try_cmpxchg_acquire(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) @@ -2058,8 +2058,8 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(ptr) __ai_ptr = (ptr); \ typeof(oldp) __ai_oldp = (oldp); \ kcsan_release(); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ - instrument_atomic_write(__ai_oldp, sizeof(*__ai_oldp)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ arch_try_cmpxchg_release(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) @@ -2067,8 +2067,8 @@ atomic_long_dec_if_positive(atomic_long_t *v) ({ \ typeof(ptr) __ai_ptr = (ptr); \ typeof(oldp) __ai_oldp = (oldp); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ - instrument_atomic_write(__ai_oldp, sizeof(*__ai_oldp)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ arch_try_cmpxchg_relaxed(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) @@ -2077,8 +2077,8 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(ptr) __ai_ptr = (ptr); \ typeof(oldp) __ai_oldp = (oldp); \ kcsan_mb(); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ - instrument_atomic_write(__ai_oldp, sizeof(*__ai_oldp)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ arch_try_cmpxchg64(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) @@ -2086,8 +2086,8 @@ atomic_long_dec_if_positive(atomic_long_t *v) ({ \ typeof(ptr) __ai_ptr = (ptr); \ typeof(oldp) __ai_oldp = (oldp); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ - instrument_atomic_write(__ai_oldp, sizeof(*__ai_oldp)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ arch_try_cmpxchg64_acquire(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) @@ -2096,8 +2096,8 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(ptr) __ai_ptr = (ptr); \ typeof(oldp) __ai_oldp = (oldp); \ kcsan_release(); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ - instrument_atomic_write(__ai_oldp, sizeof(*__ai_oldp)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ arch_try_cmpxchg64_release(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) @@ -2105,22 +2105,22 @@ atomic_long_dec_if_positive(atomic_long_t *v) ({ \ typeof(ptr) __ai_ptr = (ptr); \ typeof(oldp) __ai_oldp = (oldp); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ - instrument_atomic_write(__ai_oldp, sizeof(*__ai_oldp)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ arch_try_cmpxchg64_relaxed(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) #define cmpxchg_local(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ arch_cmpxchg_local(__ai_ptr, __VA_ARGS__); \ }) #define cmpxchg64_local(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ arch_cmpxchg64_local(__ai_ptr, __VA_ARGS__); \ }) @@ -2128,7 +2128,7 @@ atomic_long_dec_if_positive(atomic_long_t *v) ({ \ typeof(ptr) __ai_ptr = (ptr); \ kcsan_mb(); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ arch_sync_cmpxchg(__ai_ptr, __VA_ARGS__); \ }) @@ -2136,8 +2136,8 @@ atomic_long_dec_if_positive(atomic_long_t *v) ({ \ typeof(ptr) __ai_ptr = (ptr); \ typeof(oldp) __ai_oldp = (oldp); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ - instrument_atomic_write(__ai_oldp, sizeof(*__ai_oldp)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ arch_try_cmpxchg_local(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) @@ -2145,8 +2145,8 @@ atomic_long_dec_if_positive(atomic_long_t *v) ({ \ typeof(ptr) __ai_ptr = (ptr); \ typeof(oldp) __ai_oldp = (oldp); \ - instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr)); \ - instrument_atomic_write(__ai_oldp, sizeof(*__ai_oldp)); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ arch_try_cmpxchg64_local(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) @@ -2154,7 +2154,7 @@ atomic_long_dec_if_positive(atomic_long_t *v) ({ \ typeof(ptr) __ai_ptr = (ptr); \ kcsan_mb(); \ - instrument_atomic_write(__ai_ptr, 2 * sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, 2 * sizeof(*__ai_ptr)); \ arch_cmpxchg_double(__ai_ptr, __VA_ARGS__); \ }) @@ -2162,9 +2162,9 @@ atomic_long_dec_if_positive(atomic_long_t *v) #define cmpxchg_double_local(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ - instrument_atomic_write(__ai_ptr, 2 * sizeof(*__ai_ptr)); \ + instrument_atomic_read_write(__ai_ptr, 2 * sizeof(*__ai_ptr)); \ arch_cmpxchg_double_local(__ai_ptr, __VA_ARGS__); \ }) #endif /* _LINUX_ATOMIC_INSTRUMENTED_H */ -// 97fe4d79aa058d2164df824632cbc4f716d2a407 +// 6b513a42e1a1b5962532a019b7fc91eaa044ad5e diff --git a/scripts/atomic/gen-atomic-instrumented.sh b/scripts/atomic/gen-atomic-instrumented.sh index c8165e9431bf..d9ffd74f73ca 100755 --- a/scripts/atomic/gen-atomic-instrumented.sh +++ b/scripts/atomic/gen-atomic-instrumented.sh @@ -104,8 +104,8 @@ cat < Date: Tue, 2 May 2023 18:30:04 -0700 Subject: sysctl: remove register_sysctl_paths() The deprecation for register_sysctl_paths() is over. We can rejoice as we nuke register_sysctl_paths(). The routine register_sysctl_table() was the only user left of register_sysctl_paths(), so we can now just open code and move the implementation over to what used to be to __register_sysctl_paths(). The old dynamic struct ctl_table_set *set is now the point to sysctl_table_root.default_set. The old dynamic const struct ctl_path *path was being used in the routine register_sysctl_paths() with a static: static const struct ctl_path null_path[] = { {} }; Since this is a null path we can now just simplfy the old routine and remove its use as its always empty. This saves us a total of 230 bytes. $ ./scripts/bloat-o-meter vmlinux.old vmlinux add/remove: 2/7 grow/shrink: 1/1 up/down: 1015/-1245 (-230) Function old new delta register_leaf_sysctl_tables.constprop - 524 +524 register_sysctl_table 22 497 +475 __pfx_register_leaf_sysctl_tables.constprop - 16 +16 null_path 8 - -8 __pfx_register_sysctl_paths 16 - -16 __pfx_register_leaf_sysctl_tables 16 - -16 __pfx___register_sysctl_paths 16 - -16 __register_sysctl_base 29 12 -17 register_sysctl_paths 18 - -18 register_leaf_sysctl_tables 534 - -534 __register_sysctl_paths 620 - -620 Total: Before=21259666, After=21259436, chg -0.00% Signed-off-by: Luis Chamberlain --- fs/proc/proc_sysctl.c | 55 ++++------------------------------------------- include/linux/sysctl.h | 12 ----------- scripts/check-sysctl-docs | 16 -------------- 3 files changed, 4 insertions(+), 79 deletions(-) (limited to 'scripts') diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 81dbb175017e..8038833ff5b0 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -1575,25 +1575,18 @@ out: } /** - * __register_sysctl_paths - register a sysctl table hierarchy - * @set: Sysctl tree to register on - * @path: The path to the directory the sysctl table is in. + * register_sysctl_table - register a sysctl table hierarchy * @table: the top-level table structure * * Register a sysctl table hierarchy. @table should be a filled in ctl_table * array. A completely 0 filled entry terminates the table. * We are slowly deprecating this call so avoid its use. - * - * See __register_sysctl_table for more details. */ -struct ctl_table_header *__register_sysctl_paths( - struct ctl_table_set *set, - const struct ctl_path *path, struct ctl_table *table) +struct ctl_table_header *register_sysctl_table(struct ctl_table *table) { struct ctl_table *ctl_table_arg = table; int nr_subheaders = count_subheaders(table); struct ctl_table_header *header = NULL, **subheaders, **subheader; - const struct ctl_path *component; char *new_path, *pos; pos = new_path = kmalloc(PATH_MAX, GFP_KERNEL); @@ -1601,11 +1594,6 @@ struct ctl_table_header *__register_sysctl_paths( return NULL; pos[0] = '\0'; - for (component = path; component->procname; component++) { - pos = append_path(new_path, pos, component->procname); - if (!pos) - goto out; - } while (table->procname && table->child && !table[1].procname) { pos = append_path(new_path, pos, table->procname); if (!pos) @@ -1613,7 +1601,7 @@ struct ctl_table_header *__register_sysctl_paths( table = table->child; } if (nr_subheaders == 1) { - header = __register_sysctl_table(set, new_path, table); + header = __register_sysctl_table(&sysctl_table_root.default_set, new_path, table); if (header) header->ctl_table_arg = ctl_table_arg; } else { @@ -1627,7 +1615,7 @@ struct ctl_table_header *__register_sysctl_paths( header->ctl_table_arg = ctl_table_arg; if (register_leaf_sysctl_tables(new_path, pos, &subheader, - set, table)) + &sysctl_table_root.default_set, table)) goto err_register_leaves; } @@ -1646,41 +1634,6 @@ err_register_leaves: header = NULL; goto out; } - -/** - * register_sysctl_paths - register a sysctl table hierarchy - * @path: The path to the directory the sysctl table is in. - * @table: the top-level table structure - * - * Register a sysctl table hierarchy. @table should be a filled in ctl_table - * array. A completely 0 filled entry terminates the table. - * We are slowly deprecating this caller so avoid future uses of it. - * - * See __register_sysctl_paths for more details. - */ -struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path, - struct ctl_table *table) -{ - return __register_sysctl_paths(&sysctl_table_root.default_set, - path, table); -} -EXPORT_SYMBOL(register_sysctl_paths); - -/** - * register_sysctl_table - register a sysctl table hierarchy - * @table: the top-level table structure - * - * Register a sysctl table hierarchy. @table should be a filled in ctl_table - * array. A completely 0 filled entry terminates the table. - * - * See register_sysctl_paths for more details. - */ -struct ctl_table_header *register_sysctl_table(struct ctl_table *table) -{ - static const struct ctl_path null_path[] = { {} }; - - return register_sysctl_paths(null_path, table); -} EXPORT_SYMBOL(register_sysctl_table); int __register_sysctl_base(struct ctl_table *base_table) diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 780690dc08cd..3d08277959af 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -221,14 +221,8 @@ extern void retire_sysctl_set(struct ctl_table_set *set); struct ctl_table_header *__register_sysctl_table( struct ctl_table_set *set, const char *path, struct ctl_table *table); -struct ctl_table_header *__register_sysctl_paths( - struct ctl_table_set *set, - const struct ctl_path *path, struct ctl_table *table); struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *table); struct ctl_table_header *register_sysctl_table(struct ctl_table * table); -struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path, - struct ctl_table *table); - void unregister_sysctl_table(struct ctl_table_header * table); extern int sysctl_init_bases(void); @@ -277,12 +271,6 @@ static inline struct ctl_table_header *register_sysctl_mount_point(const char *p return NULL; } -static inline struct ctl_table_header *register_sysctl_paths( - const struct ctl_path *path, struct ctl_table *table) -{ - return NULL; -} - static inline struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *table) { return NULL; diff --git a/scripts/check-sysctl-docs b/scripts/check-sysctl-docs index 8bcb9e26c7bc..edc9a629d79e 100755 --- a/scripts/check-sysctl-docs +++ b/scripts/check-sysctl-docs @@ -156,22 +156,6 @@ curtable && /\.procname[\t ]*=[\t ]*".+"/ { } } -/register_sysctl_paths\(.*\)/ { - match($0, /register_sysctl_paths\(([^)]+), ([^)]+)\)/, tables) - if (debug) print "Attaching table " tables[2] " to path " tables[1] - if (paths[tables[1]] == table) { - for (entry in entries[tables[2]]) { - printentry(entry) - } - } - split(paths[tables[1]], components, "/") - if (length(components) > 1 && components[1] == table) { - # Count the first subdirectory as seen - seen[components[2]]++ - } -} - - END { for (entry in documented) { if (!seen[entry]) { -- cgit