From 71a3cdf80c0d12aadca6f9b0f5a43883649bdbea Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 12 Jan 2022 11:49:53 +0000 Subject: bpf/scripts: Raise an exception if the correct number of helpers are not generated Currently bpf_helper_defs.h and the bpf helpers man page are auto-generated using function documentation present in bpf.h. If the documentation for the helper is missing or doesn't follow a specific format for e.g. if a function is documented as: * long bpf_kallsyms_lookup_name( const char *name, int name_sz, int flags, u64 *res ) instead of * long bpf_kallsyms_lookup_name(const char *name, int name_sz, int flags, u64 *res) (notice the extra space at the start and end of function arguments) then that helper is not dumped in the auto-generated header and results in an invalid call during eBPF runtime, even if all the code specific to the helper is correct. This patch checks the number of functions documented within the header file with those present as part of #define __BPF_FUNC_MAPPER and raises an Exception if they don't match. It is not needed with the currently documented upstream functions, but can help in debugging when developing new helpers when there might be missing or misformatted documentation. Signed-off-by: Usama Arif Signed-off-by: Andrii Nakryiko Reviewed-by: Quentin Monnet Acked-by: Song Liu Link: https://lore.kernel.org/bpf/20220112114953.722380-1-usama.arif@bytedance.com --- scripts/bpf_doc.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index a6403ddf5de7..5cf8ae2e72bd 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -87,6 +87,8 @@ class HeaderParser(object): self.line = '' self.helpers = [] self.commands = [] + self.desc_unique_helpers = set() + self.define_unique_helpers = [] def parse_element(self): proto = self.parse_symbol() @@ -193,19 +195,42 @@ class HeaderParser(object): except NoSyscallCommandFound: break - def parse_helpers(self): + def parse_desc_helpers(self): self.seek_to('* Start of BPF helper function descriptions:', 'Could not find start of eBPF helper descriptions list') while True: try: helper = self.parse_helper() self.helpers.append(helper) + proto = helper.proto_break_down() + self.desc_unique_helpers.add(proto['name']) except NoHelperFound: break + def parse_define_helpers(self): + # Parse the number of FN(...) in #define __BPF_FUNC_MAPPER to compare + # later with the number of unique function names present in description. + # Note: seek_to(..) discards the first line below the target search text, + # resulting in FN(unspec) being skipped and not added to self.define_unique_helpers. + self.seek_to('#define __BPF_FUNC_MAPPER(FN)', + 'Could not find start of eBPF helper definition list') + # Searches for either one or more FN(\w+) defines or a backslash for newline + p = re.compile('\s*(FN\(\w+\))+|\\\\') + fn_defines_str = '' + while True: + capture = p.match(self.line) + if capture: + fn_defines_str += self.line + else: + break + self.line = self.reader.readline() + # Find the number of occurences of FN(\w+) + self.define_unique_helpers = re.findall('FN\(\w+\)', fn_defines_str) + def run(self): self.parse_syscall() - self.parse_helpers() + self.parse_desc_helpers() + self.parse_define_helpers() self.reader.close() ############################################################################### @@ -295,6 +320,25 @@ class PrinterRST(Printer): print('') +def helper_number_check(desc_unique_helpers, define_unique_helpers): + """ + Checks the number of functions documented within the header file + with those present as part of #define __BPF_FUNC_MAPPER and raise an + Exception if they don't match. + """ + nr_desc_unique_helpers = len(desc_unique_helpers) + nr_define_unique_helpers = len(define_unique_helpers) + if nr_desc_unique_helpers != nr_define_unique_helpers: + helper_exception = ''' +The number of unique helpers in description (%d) doesn\'t match the number of unique helpers defined in __BPF_FUNC_MAPPER (%d) +''' % (nr_desc_unique_helpers, nr_define_unique_helpers) + if nr_desc_unique_helpers < nr_define_unique_helpers: + # Function description is parsed until no helper is found (which can be due to + # misformatting). Hence, only print the first missing/misformatted function. + helper_exception += ''' +The description for %s is not present or formatted correctly. +''' % (define_unique_helpers[nr_desc_unique_helpers]) + raise Exception(helper_exception) class PrinterHelpersRST(PrinterRST): """ @@ -305,6 +349,7 @@ class PrinterHelpersRST(PrinterRST): """ def __init__(self, parser): self.elements = parser.helpers + helper_number_check(parser.desc_unique_helpers, parser.define_unique_helpers) def print_header(self): header = '''\ @@ -509,6 +554,7 @@ class PrinterHelpers(Printer): """ def __init__(self, parser): self.elements = parser.helpers + helper_number_check(parser.desc_unique_helpers, parser.define_unique_helpers) type_fwds = [ 'struct bpf_fib_lookup', -- cgit v1.2.3 From f1f3f67fd8ed6f512955bbbc76b04e9dc33ddeb6 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 19 Jan 2022 11:44:41 +0000 Subject: bpf/scripts: Make description and returns section for helpers/syscalls mandatory This enforce a minimal formatting consistency for the documentation. The description and returns missing for a few helpers have also been added. Signed-off-by: Usama Arif Signed-off-by: Andrii Nakryiko Reviewed-by: Quentin Monnet Link: https://lore.kernel.org/bpf/20220119114442.1452088-2-usama.arif@bytedance.com --- scripts/bpf_doc.py | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index 5cf8ae2e72bd..20441e5d2d33 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -92,14 +92,14 @@ class HeaderParser(object): def parse_element(self): proto = self.parse_symbol() - desc = self.parse_desc() - ret = self.parse_ret() + desc = self.parse_desc(proto) + ret = self.parse_ret(proto) return APIElement(proto=proto, desc=desc, ret=ret) def parse_helper(self): proto = self.parse_proto() - desc = self.parse_desc() - ret = self.parse_ret() + desc = self.parse_desc(proto) + ret = self.parse_ret(proto) return Helper(proto=proto, desc=desc, ret=ret) def parse_symbol(self): @@ -129,16 +129,15 @@ class HeaderParser(object): self.line = self.reader.readline() return capture.group(1) - def parse_desc(self): + def parse_desc(self, proto): p = re.compile(' \* ?(?:\t| {5,8})Description$') capture = p.match(self.line) if not capture: - # Helper can have empty description and we might be parsing another - # attribute: return but do not consume. - return '' + raise Exception("No description section found for " + proto) # Description can be several lines, some of them possibly empty, and it # stops when another subsection title is met. desc = '' + desc_present = False while True: self.line = self.reader.readline() if self.line == ' *\n': @@ -147,21 +146,24 @@ class HeaderParser(object): p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)') capture = p.match(self.line) if capture: + desc_present = True desc += capture.group(1) + '\n' else: break + + if not desc_present: + raise Exception("No description found for " + proto) return desc - def parse_ret(self): + def parse_ret(self, proto): p = re.compile(' \* ?(?:\t| {5,8})Return$') capture = p.match(self.line) if not capture: - # Helper can have empty retval and we might be parsing another - # attribute: return but do not consume. - return '' + raise Exception("No return section found for " + proto) # Return value description can be several lines, some of them possibly # empty, and it stops when another subsection title is met. ret = '' + ret_present = False while True: self.line = self.reader.readline() if self.line == ' *\n': @@ -170,9 +172,13 @@ class HeaderParser(object): p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)') capture = p.match(self.line) if capture: + ret_present = True ret += capture.group(1) + '\n' else: break + + if not ret_present: + raise Exception("No return found for " + proto) return ret def seek_to(self, target, help_message): -- cgit v1.2.3 From 0ba3929e5b3d3fda05d3b9c8d0d20a90a084c19e Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Wed, 19 Jan 2022 11:44:42 +0000 Subject: bpf/scripts: Raise an exception if the correct number of sycalls are not generated Currently the syscalls rst and subsequently man page are auto-generated using function documentation present in bpf.h. If the documentation for the syscall is missing or doesn't follow a specific format, then that syscall is not dumped in the auto-generated rst. This patch checks the number of syscalls documented within the header file with those present as part of the enum bpf_cmd and raises an Exception if they don't match. It is not needed with the currently documented upstream syscalls, but can help in debugging when developing new syscalls when there might be missing or misformatted documentation. The function helper_number_check is moved to the Printer parent class and renamed to elem_number_check as all the most derived children classes are using this function now. Signed-off-by: Usama Arif Signed-off-by: Andrii Nakryiko Reviewed-by: Quentin Monnet Link: https://lore.kernel.org/bpf/20220119114442.1452088-3-usama.arif@bytedance.com --- scripts/bpf_doc.py | 86 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 27 deletions(-) (limited to 'scripts') diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index 20441e5d2d33..096625242475 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -89,6 +89,8 @@ class HeaderParser(object): self.commands = [] self.desc_unique_helpers = set() self.define_unique_helpers = [] + self.desc_syscalls = [] + self.enum_syscalls = [] def parse_element(self): proto = self.parse_symbol() @@ -103,7 +105,7 @@ class HeaderParser(object): return Helper(proto=proto, desc=desc, ret=ret) def parse_symbol(self): - p = re.compile(' \* ?(.+)$') + p = re.compile(' \* ?(BPF\w+)$') capture = p.match(self.line) if not capture: raise NoSyscallCommandFound @@ -181,26 +183,55 @@ class HeaderParser(object): raise Exception("No return found for " + proto) return ret - def seek_to(self, target, help_message): + def seek_to(self, target, help_message, discard_lines = 1): self.reader.seek(0) offset = self.reader.read().find(target) if offset == -1: raise Exception(help_message) self.reader.seek(offset) self.reader.readline() - self.reader.readline() + for _ in range(discard_lines): + self.reader.readline() self.line = self.reader.readline() - def parse_syscall(self): + def parse_desc_syscall(self): self.seek_to('* DOC: eBPF Syscall Commands', 'Could not find start of eBPF syscall descriptions list') while True: try: command = self.parse_element() self.commands.append(command) + self.desc_syscalls.append(command.proto) + except NoSyscallCommandFound: break + def parse_enum_syscall(self): + self.seek_to('enum bpf_cmd {', + 'Could not find start of bpf_cmd enum', 0) + # Searches for either one or more BPF\w+ enums + bpf_p = re.compile('\s*(BPF\w+)+') + # Searches for an enum entry assigned to another entry, + # for e.g. BPF_PROG_RUN = BPF_PROG_TEST_RUN, which is + # not documented hence should be skipped in check to + # determine if the right number of syscalls are documented + assign_p = re.compile('\s*(BPF\w+)\s*=\s*(BPF\w+)') + bpf_cmd_str = '' + while True: + capture = assign_p.match(self.line) + if capture: + # Skip line if an enum entry is assigned to another entry + self.line = self.reader.readline() + continue + capture = bpf_p.match(self.line) + if capture: + bpf_cmd_str += self.line + else: + break + self.line = self.reader.readline() + # Find the number of occurences of BPF\w+ + self.enum_syscalls = re.findall('(BPF\w+)+', bpf_cmd_str) + def parse_desc_helpers(self): self.seek_to('* Start of BPF helper function descriptions:', 'Could not find start of eBPF helper descriptions list') @@ -234,7 +265,8 @@ class HeaderParser(object): self.define_unique_helpers = re.findall('FN\(\w+\)', fn_defines_str) def run(self): - self.parse_syscall() + self.parse_desc_syscall() + self.parse_enum_syscall() self.parse_desc_helpers() self.parse_define_helpers() self.reader.close() @@ -266,6 +298,25 @@ class Printer(object): self.print_one(elem) self.print_footer() + def elem_number_check(self, desc_unique_elem, define_unique_elem, type, instance): + """ + Checks the number of helpers/syscalls documented within the header file + description with those defined as part of enum/macro and raise an + Exception if they don't match. + """ + nr_desc_unique_elem = len(desc_unique_elem) + nr_define_unique_elem = len(define_unique_elem) + if nr_desc_unique_elem != nr_define_unique_elem: + exception_msg = ''' +The number of unique %s in description (%d) doesn\'t match the number of unique %s defined in %s (%d) +''' % (type, nr_desc_unique_elem, type, instance, nr_define_unique_elem) + if nr_desc_unique_elem < nr_define_unique_elem: + # Function description is parsed until no helper is found (which can be due to + # misformatting). Hence, only print the first missing/misformatted helper/enum. + exception_msg += ''' +The description for %s is not present or formatted correctly. +''' % (define_unique_elem[nr_desc_unique_elem]) + raise Exception(exception_msg) class PrinterRST(Printer): """ @@ -326,26 +377,6 @@ class PrinterRST(Printer): print('') -def helper_number_check(desc_unique_helpers, define_unique_helpers): - """ - Checks the number of functions documented within the header file - with those present as part of #define __BPF_FUNC_MAPPER and raise an - Exception if they don't match. - """ - nr_desc_unique_helpers = len(desc_unique_helpers) - nr_define_unique_helpers = len(define_unique_helpers) - if nr_desc_unique_helpers != nr_define_unique_helpers: - helper_exception = ''' -The number of unique helpers in description (%d) doesn\'t match the number of unique helpers defined in __BPF_FUNC_MAPPER (%d) -''' % (nr_desc_unique_helpers, nr_define_unique_helpers) - if nr_desc_unique_helpers < nr_define_unique_helpers: - # Function description is parsed until no helper is found (which can be due to - # misformatting). Hence, only print the first missing/misformatted function. - helper_exception += ''' -The description for %s is not present or formatted correctly. -''' % (define_unique_helpers[nr_desc_unique_helpers]) - raise Exception(helper_exception) - class PrinterHelpersRST(PrinterRST): """ A printer for dumping collected information about helpers as a ReStructured @@ -355,7 +386,7 @@ class PrinterHelpersRST(PrinterRST): """ def __init__(self, parser): self.elements = parser.helpers - helper_number_check(parser.desc_unique_helpers, parser.define_unique_helpers) + self.elem_number_check(parser.desc_unique_helpers, parser.define_unique_helpers, 'helper', '__BPF_FUNC_MAPPER') def print_header(self): header = '''\ @@ -529,6 +560,7 @@ class PrinterSyscallRST(PrinterRST): """ def __init__(self, parser): self.elements = parser.commands + self.elem_number_check(parser.desc_syscalls, parser.enum_syscalls, 'syscall', 'bpf_cmd') def print_header(self): header = '''\ @@ -560,7 +592,7 @@ class PrinterHelpers(Printer): """ def __init__(self, parser): self.elements = parser.helpers - helper_number_check(parser.desc_unique_helpers, parser.define_unique_helpers) + self.elem_number_check(parser.desc_unique_helpers, parser.define_unique_helpers, 'helper', '__BPF_FUNC_MAPPER') type_fwds = [ 'struct bpf_fib_lookup', -- cgit v1.2.3 From 613fe169237785a4bb1d06397b52606b2967da53 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 1 Feb 2022 13:56:21 -0700 Subject: kbuild: Add CONFIG_PAHOLE_VERSION There are a few different places where pahole's version is turned into a three digit form with the exact same command. Move this command into scripts/pahole-version.sh to reduce the amount of duplication across the tree. Create CONFIG_PAHOLE_VERSION so the version code can be used in Kconfig to enable and disable configuration options based on the pahole version, which is already done in a couple of places. Signed-off-by: Nathan Chancellor Signed-off-by: Daniel Borkmann Acked-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20220201205624.652313-3-nathan@kernel.org --- MAINTAINERS | 1 + init/Kconfig | 4 ++++ scripts/pahole-version.sh | 13 +++++++++++++ 3 files changed, 18 insertions(+) create mode 100755 scripts/pahole-version.sh (limited to 'scripts') diff --git a/MAINTAINERS b/MAINTAINERS index 0d422452c8ff..d8a66d50f224 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3524,6 +3524,7 @@ F: net/sched/cls_bpf.c F: samples/bpf/ F: scripts/bpf_doc.py F: scripts/pahole-flags.sh +F: scripts/pahole-version.sh F: tools/bpf/ F: tools/lib/bpf/ F: tools/testing/selftests/bpf/ diff --git a/init/Kconfig b/init/Kconfig index e9119bf54b1f..7328d4f25370 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -86,6 +86,10 @@ config CC_HAS_ASM_INLINE config CC_HAS_NO_PROFILE_FN_ATTR def_bool $(success,echo '__attribute__((no_profile_instrument_function)) int x();' | $(CC) -x c - -c -o /dev/null -Werror) +config PAHOLE_VERSION + int + default $(shell,$(srctree)/scripts/pahole-version.sh $(PAHOLE)) + config CONSTRUCTORS bool diff --git a/scripts/pahole-version.sh b/scripts/pahole-version.sh new file mode 100755 index 000000000000..f8a32ab93ad1 --- /dev/null +++ b/scripts/pahole-version.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Usage: $ ./pahole-version.sh pahole +# +# Prints pahole's version in a 3-digit form, such as 119 for v1.19. + +if [ ! -x "$(command -v "$@")" ]; then + echo 0 + exit 1 +fi + +"$@" --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/' -- cgit v1.2.3 From 2d6c9810eb8915c4ddede707b8e167a1d919e1ca Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 1 Feb 2022 13:56:22 -0700 Subject: scripts/pahole-flags.sh: Use pahole-version.sh Use pahole-version.sh to get pahole's version code to reduce the amount of duplication across the tree. Signed-off-by: Nathan Chancellor Signed-off-by: Daniel Borkmann Acked-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20220201205624.652313-4-nathan@kernel.org --- scripts/pahole-flags.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/pahole-flags.sh b/scripts/pahole-flags.sh index e6093adf4c06..c293941612e7 100755 --- a/scripts/pahole-flags.sh +++ b/scripts/pahole-flags.sh @@ -7,7 +7,7 @@ if ! [ -x "$(command -v ${PAHOLE})" ]; then exit 0 fi -pahole_ver=$(${PAHOLE} --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/') +pahole_ver=$($(dirname $0)/pahole-version.sh ${PAHOLE}) if [ "${pahole_ver}" -ge "118" ] && [ "${pahole_ver}" -le "121" ]; then # pahole 1.18 through 1.21 can't handle zero-sized per-CPU vars -- cgit v1.2.3 From 28c9f3f9a01d954d8357bdb68fbe36255997bf14 Mon Sep 17 00:00:00 2001 From: Ding Xiang Date: Fri, 14 Jan 2022 10:40:58 +0800 Subject: spdxcheck.py: Fix a type error remove unused variable "col", otherwise there will be a type error as below: typeerror: not all arguments converted during string formatting Signed-off-by: Ding Xiang Link: https://lore.kernel.org/r/20220114024058.74536-1-dingxiang@cmss.chinamobile.com Signed-off-by: Greg Kroah-Hartman --- scripts/spdxcheck.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/spdxcheck.py b/scripts/spdxcheck.py index ebd06ae642c9..f3be8ed54f6d 100755 --- a/scripts/spdxcheck.py +++ b/scripts/spdxcheck.py @@ -200,7 +200,7 @@ class id_parser(object): tok = pe.tok.value sys.stdout.write('%s: %d:%d %s: %s\n' %(fname, self.curline, col, pe.txt, tok)) else: - sys.stdout.write('%s: %d:0 %s\n' %(fname, self.curline, col, pe.txt)) + sys.stdout.write('%s: %d:0 %s\n' %(fname, self.curline, pe.txt)) self.spdx_errors += 1 def scan_git_tree(tree): -- cgit v1.2.3 From aa21a1bf97be50ce07d796fb6b0b330822515469 Mon Sep 17 00:00:00 2001 From: Jonathan Neuschäfer Date: Sat, 29 Jan 2022 01:50:18 +0100 Subject: scripts/get_abi.pl: Ignore hidden files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit get_abi.pl currently collects every file in Documentation/ABI. This causes a UnicodeDecodeError in Documentation/sphinx/kernel_abi.py, when it finds my Vim swap files (.foo.swp) in the directory. To avoid such issues, ignore hidden files in get_abi.pl. Reviewed-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Neuschäfer Link: https://lore.kernel.org/r/20220129005019.2090996-1-j.neuschaefer@gmx.net Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 6212f58b69c6..47b7eca5b0b7 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -92,6 +92,7 @@ sub parse_abi { my $mode = (stat($file))[2]; return if ($mode & S_IFDIR); return if ($file =~ m,/README,); + return if ($file =~ m,/\.,); my $name = $file; $name =~ s,.*/,,; -- cgit v1.2.3 From a8b309ce9760943486e0585285e0125588a31650 Mon Sep 17 00:00:00 2001 From: Thomas Bracht Laumann Jespersen Date: Mon, 31 Jan 2022 12:20:28 +0100 Subject: scripts/dtc: Call pkg-config POSIXly correct Running with POSIXLY_CORRECT=1 in the environment the scripts/dtc build fails, because pkg-config doesn't output anything when the flags come after the arguments. Fixes: 067c650c456e ("dtc: Use pkg-config to locate libyaml") Signed-off-by: Thomas Bracht Laumann Jespersen Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220131112028.7907-1-t@laumann.xyz --- scripts/dtc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile index 95aaf7431bff..1cba78e1dce6 100644 --- a/scripts/dtc/Makefile +++ b/scripts/dtc/Makefile @@ -29,7 +29,7 @@ dtc-objs += yamltree.o # To include installed in a non-default path HOSTCFLAGS_yamltree.o := $(shell pkg-config --cflags yaml-0.1) # To link libyaml installed in a non-default path -HOSTLDLIBS_dtc := $(shell pkg-config yaml-0.1 --libs) +HOSTLDLIBS_dtc := $(shell pkg-config --libs yaml-0.1) endif # Generated files need one more search path to include headers in source tree -- cgit v1.2.3 From f154066b61dfde618d98fdafc8cadde076c7f222 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sun, 6 Feb 2022 09:20:08 -0800 Subject: gcc-plugins/stackleak: Provide verbose mode In order to compare instrumentation between builds, make the verbose mode of the plugin available during the build. This is rarely needed (behind EXPERT) and very noisy (disabled for COMPILE_TEST). Cc: Alexander Popov Signed-off-by: Kees Cook --- scripts/Makefile.gcc-plugins | 2 ++ security/Kconfig.hardening | 10 ++++++++++ 2 files changed, 12 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 1d16ca1b78c9..f67153b260c0 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -37,6 +37,8 @@ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ += -fplugin-arg-stackleak_plugin-track-min-size=$(CONFIG_STACKLEAK_TRACK_MIN_SIZE) gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ += -fplugin-arg-stackleak_plugin-arch=$(SRCARCH) +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK_VERBOSE) \ + += -fplugin-arg-stackleak_plugin-verbose ifdef CONFIG_GCC_PLUGIN_STACKLEAK DISABLE_STACKLEAK_PLUGIN += -fplugin-arg-stackleak_plugin-disable endif diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening index d051f8ceefdd..ded4d7c0d132 100644 --- a/security/Kconfig.hardening +++ b/security/Kconfig.hardening @@ -174,6 +174,16 @@ config GCC_PLUGIN_STACKLEAK * https://grsecurity.net/ * https://pax.grsecurity.net/ +config GCC_PLUGIN_STACKLEAK_VERBOSE + bool "Report stack depth analysis instrumentation" if EXPERT + depends on GCC_PLUGIN_STACKLEAK + depends on !COMPILE_TEST # too noisy + help + This option will cause a warning to be printed each time the + stackleak plugin finds a function it thinks needs to be + instrumented. This is useful for comparing coverage between + builds. + config STACKLEAK_TRACK_MIN_SIZE int "Minimum stack frame size of functions tracked by STACKLEAK" default 100 -- cgit v1.2.3 From 27e9faf415dbf94af19b9c827842435edbc1fbbc Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sun, 6 Feb 2022 09:08:20 -0800 Subject: gcc-plugins/stackleak: Exactly match strings instead of prefixes Since STRING_CST may not be NUL terminated, strncmp() was used for check for equality. However, this may lead to mismatches for longer section names where the start matches the tested-for string. Test for exact equality by checking for the presences of NUL termination. Cc: Alexander Popov Signed-off-by: Kees Cook --- scripts/gcc-plugins/stackleak_plugin.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c index e9db7dcb3e5f..b04aa8e91a41 100644 --- a/scripts/gcc-plugins/stackleak_plugin.c +++ b/scripts/gcc-plugins/stackleak_plugin.c @@ -429,6 +429,23 @@ static unsigned int stackleak_cleanup_execute(void) return 0; } +/* + * STRING_CST may or may not be NUL terminated: + * https://gcc.gnu.org/onlinedocs/gccint/Constant-expressions.html + */ +static inline bool string_equal(tree node, const char *string, int length) +{ + if (TREE_STRING_LENGTH(node) < length) + return false; + if (TREE_STRING_LENGTH(node) > length + 1) + return false; + if (TREE_STRING_LENGTH(node) == length + 1 && + TREE_STRING_POINTER(node)[length] != '\0') + return false; + return !memcmp(TREE_STRING_POINTER(node), string, length); +} +#define STRING_EQUAL(node, str) string_equal(node, str, strlen(str)) + static bool stackleak_gate(void) { tree section; @@ -438,13 +455,13 @@ static bool stackleak_gate(void) if (section && TREE_VALUE(section)) { section = TREE_VALUE(TREE_VALUE(section)); - if (!strncmp(TREE_STRING_POINTER(section), ".init.text", 10)) + if (STRING_EQUAL(section, ".init.text")) return false; - if (!strncmp(TREE_STRING_POINTER(section), ".devinit.text", 13)) + if (STRING_EQUAL(section, ".devinit.text")) return false; - if (!strncmp(TREE_STRING_POINTER(section), ".cpuinit.text", 13)) + if (STRING_EQUAL(section, ".cpuinit.text")) return false; - if (!strncmp(TREE_STRING_POINTER(section), ".meminit.text", 13)) + if (STRING_EQUAL(section, ".meminit.text")) return false; } -- cgit v1.2.3 From ae978009fc013e3166c9f523f8b17e41a3c0286e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sun, 6 Feb 2022 09:12:50 -0800 Subject: gcc-plugins/stackleak: Ignore .noinstr.text and .entry.text The .noinstr.text section functions may not have "current()" sanely available. Similarly true for .entry.text, though such a check is currently redundant. Add a check for both. In an x86_64 defconfig build, the following functions no longer receive stackleak instrumentation: __do_fast_syscall_32() do_int80_syscall_32() do_machine_check() do_syscall_64() exc_general_protection() fixup_bad_iret() Suggested-by: Peter Zijlstra Cc: Alexander Popov Signed-off-by: Kees Cook --- scripts/gcc-plugins/stackleak_plugin.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'scripts') diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c index b04aa8e91a41..42f0252ee2a4 100644 --- a/scripts/gcc-plugins/stackleak_plugin.c +++ b/scripts/gcc-plugins/stackleak_plugin.c @@ -463,6 +463,10 @@ static bool stackleak_gate(void) return false; if (STRING_EQUAL(section, ".meminit.text")) return false; + if (STRING_EQUAL(section, ".noinstr.text")) + return false; + if (STRING_EQUAL(section, ".entry.text")) + return false; } return track_frame_size >= 0; -- cgit v1.2.3 From 8a4c5b2a6d8ea079fa36034e8167de87ab6f8880 Mon Sep 17 00:00:00 2001 From: Brenda Streiff Date: Fri, 28 Jan 2022 16:01:28 -0600 Subject: kconfig: let 'shell' return enough output for deep path names The 'shell' built-in only returns the first 256 bytes of the command's output. In some cases, 'shell' is used to return a path; by bumping up the buffer size to 4096 this lets us capture up to PATH_MAX. The specific case where I ran into this was due to commit 1e860048c53e ("gcc-plugins: simplify GCC plugin-dev capability test"). After this change, we now use `$(shell,$(CC) -print-file-name=plugin)` to return a path; if the gcc path is particularly long, then the path ends up truncated at the 256 byte mark, which makes the HAVE_GCC_PLUGINS depends test always fail. Signed-off-by: Brenda Streiff Signed-off-by: Masahiro Yamada --- scripts/kconfig/preprocess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c index 0590f86df6e4..748da578b418 100644 --- a/scripts/kconfig/preprocess.c +++ b/scripts/kconfig/preprocess.c @@ -141,7 +141,7 @@ static char *do_lineno(int argc, char *argv[]) static char *do_shell(int argc, char *argv[]) { FILE *p; - char buf[256]; + char buf[4096]; char *cmd; size_t nread; int i; -- cgit v1.2.3 From 1cf5f151d25fcca94689efd91afa0253621fb33a Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 2 Feb 2022 16:05:16 -0700 Subject: Makefile.extrawarn: Move -Wunaligned-access to W=1 -Wunaligned-access is a new warning in clang that is default enabled for arm and arm64 under certain circumstances within the clang frontend (see LLVM commit below). On v5.17-rc2, an ARCH=arm allmodconfig build shows 1284 total/70 unique instances of this warning (most of the instances are in header files), which is quite noisy. To keep a normal build green through CONFIG_WERROR, only show this warning with W=1, which will allow automated build systems to catch new instances of the warning so that the total number can be driven down to zero eventually since catching unaligned accesses at compile time would be generally useful. Cc: stable@vger.kernel.org Link: https://github.com/llvm/llvm-project/commit/35737df4dcd28534bd3090157c224c19b501278a Link: https://github.com/ClangBuiltLinux/linux/issues/1569 Link: https://github.com/ClangBuiltLinux/linux/issues/1576 Signed-off-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Signed-off-by: Masahiro Yamada --- scripts/Makefile.extrawarn | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index d53825503874..8be892887d71 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -51,6 +51,7 @@ KBUILD_CFLAGS += -Wno-sign-compare KBUILD_CFLAGS += -Wno-format-zero-length KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast) KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare +KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access) endif endif -- cgit v1.2.3 From d23a0c3718222a42430fd56359478a6fc7675070 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 8 Feb 2022 15:26:18 +0900 Subject: kconfig: fix missing fclose() on error paths The file is not closed when ferror() fails. Fixes: 00d674cb3536 ("kconfig: refactor conf_write_dep()") Fixes: 57ddd07c4560 ("kconfig: refactor conf_write_autoconf()") Reported-by: Ryan Cai Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 59717be31210..16897cb8cefd 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -979,10 +979,10 @@ static int conf_write_autoconf_cmd(const char *autoconf_name) fprintf(out, "\n$(deps_config): ;\n"); - if (ferror(out)) /* error check for all fprintf() calls */ - return -1; - + ret = ferror(out); /* error check for all fprintf() calls */ fclose(out); + if (ret) + return -1; if (rename(tmp, name)) { perror("rename"); @@ -1093,10 +1093,10 @@ static int __conf_write_autoconf(const char *filename, print_symbol(file, sym); /* check possible errors in conf_write_heading() and print_symbol() */ - if (ferror(file)) - return -1; - + ret = ferror(file); fclose(file); + if (ret) + return -1; if (rename(tmp, filename)) { perror("rename"); -- cgit v1.2.3 From dc1b4df09acdca7a89806b28f235cd6d8dcd3d24 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Mon, 7 Feb 2022 10:19:43 +0000 Subject: atomics: Fix atomic64_{read_acquire,set_release} fallbacks Arnd reports that on 32-bit architectures, the fallbacks for atomic64_read_acquire() and atomic64_set_release() are broken as they use smp_load_acquire() and smp_store_release() respectively, which do not work on types larger than the native word size. Since those contain compiletime_assert_atomic_type(), any attempt to use those fallbacks will result in a build-time error. e.g. with the following added to arch/arm/kernel/setup.c: | void test_atomic64(atomic64_t *v) | { | atomic64_set_release(v, 5); | atomic64_read_acquire(v); | } The compiler will complain as follows: | In file included from : | In function 'arch_atomic64_set_release', | inlined from 'test_atomic64' at ./include/linux/atomic/atomic-instrumented.h:669:2: | ././include/linux/compiler_types.h:346:38: error: call to '__compiletime_assert_9' declared with attribute error: Need native word sized stores/loads for atomicity. | 346 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) | | ^ | ././include/linux/compiler_types.h:327:4: note: in definition of macro '__compiletime_assert' | 327 | prefix ## suffix(); \ | | ^~~~~~ | ././include/linux/compiler_types.h:346:2: note: in expansion of macro '_compiletime_assert' | 346 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) | | ^~~~~~~~~~~~~~~~~~~ | ././include/linux/compiler_types.h:349:2: note: in expansion of macro 'compiletime_assert' | 349 | compiletime_assert(__native_word(t), \ | | ^~~~~~~~~~~~~~~~~~ | ./include/asm-generic/barrier.h:133:2: note: in expansion of macro 'compiletime_assert_atomic_type' | 133 | compiletime_assert_atomic_type(*p); \ | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ./include/asm-generic/barrier.h:164:55: note: in expansion of macro '__smp_store_release' | 164 | #define smp_store_release(p, v) do { kcsan_release(); __smp_store_release(p, v); } while (0) | | ^~~~~~~~~~~~~~~~~~~ | ./include/linux/atomic/atomic-arch-fallback.h:1270:2: note: in expansion of macro 'smp_store_release' | 1270 | smp_store_release(&(v)->counter, i); | | ^~~~~~~~~~~~~~~~~ | make[2]: *** [scripts/Makefile.build:288: arch/arm/kernel/setup.o] Error 1 | make[1]: *** [scripts/Makefile.build:550: arch/arm/kernel] Error 2 | make: *** [Makefile:1831: arch/arm] Error 2 Fix this by only using smp_load_acquire() and smp_store_release() for native atomic types, and otherwise falling back to the regular barriers necessary for acquire/release semantics, as we do in the more generic acquire and release fallbacks. Since the fallback templates are used to generate the atomic64_*() and atomic_*() operations, the __native_word() check is added to both. For the atomic_*() operations, which are always 32-bit, the __native_word() check is redundant but not harmful, as it is always true. For the example above this works as expected on 32-bit, e.g. for arm multi_v7_defconfig: | : | push {r4, r5} | dmb ish | pldw [r0] | mov r2, #5 | mov r3, #0 | ldrexd r4, [r0] | strexd r4, r2, [r0] | teq r4, #0 | bne 484 | ldrexd r2, [r0] | dmb ish | pop {r4, r5} | bx lr ... and also on 64-bit, e.g. for arm64 defconfig: | : | bti c | paciasp | mov x1, #0x5 | stlr x1, [x0] | ldar x0, [x0] | autiasp | ret Reported-by: Arnd Bergmann Signed-off-by: Mark Rutland Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Ard Biesheuvel Reviewed-by: Boqun Feng Link: https://lore.kernel.org/r/20220207101943.439825-1-mark.rutland@arm.com --- include/linux/atomic/atomic-arch-fallback.h | 38 +++++++++++++++++++++++++---- scripts/atomic/fallbacks/read_acquire | 11 ++++++++- scripts/atomic/fallbacks/set_release | 7 +++++- 3 files changed, 49 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/include/linux/atomic/atomic-arch-fallback.h b/include/linux/atomic/atomic-arch-fallback.h index a3dba31df01e..6db58d180866 100644 --- a/include/linux/atomic/atomic-arch-fallback.h +++ b/include/linux/atomic/atomic-arch-fallback.h @@ -151,7 +151,16 @@ static __always_inline int arch_atomic_read_acquire(const atomic_t *v) { - return smp_load_acquire(&(v)->counter); + int ret; + + if (__native_word(atomic_t)) { + ret = smp_load_acquire(&(v)->counter); + } else { + ret = arch_atomic_read(v); + __atomic_acquire_fence(); + } + + return ret; } #define arch_atomic_read_acquire arch_atomic_read_acquire #endif @@ -160,7 +169,12 @@ arch_atomic_read_acquire(const atomic_t *v) static __always_inline void arch_atomic_set_release(atomic_t *v, int i) { - smp_store_release(&(v)->counter, i); + if (__native_word(atomic_t)) { + smp_store_release(&(v)->counter, i); + } else { + __atomic_release_fence(); + arch_atomic_set(v, i); + } } #define arch_atomic_set_release arch_atomic_set_release #endif @@ -1258,7 +1272,16 @@ arch_atomic_dec_if_positive(atomic_t *v) static __always_inline s64 arch_atomic64_read_acquire(const atomic64_t *v) { - return smp_load_acquire(&(v)->counter); + s64 ret; + + if (__native_word(atomic64_t)) { + ret = smp_load_acquire(&(v)->counter); + } else { + ret = arch_atomic64_read(v); + __atomic_acquire_fence(); + } + + return ret; } #define arch_atomic64_read_acquire arch_atomic64_read_acquire #endif @@ -1267,7 +1290,12 @@ arch_atomic64_read_acquire(const atomic64_t *v) static __always_inline void arch_atomic64_set_release(atomic64_t *v, s64 i) { - smp_store_release(&(v)->counter, i); + if (__native_word(atomic64_t)) { + smp_store_release(&(v)->counter, i); + } else { + __atomic_release_fence(); + arch_atomic64_set(v, i); + } } #define arch_atomic64_set_release arch_atomic64_set_release #endif @@ -2358,4 +2386,4 @@ arch_atomic64_dec_if_positive(atomic64_t *v) #endif #endif /* _LINUX_ATOMIC_FALLBACK_H */ -// cca554917d7ea73d5e3e7397dd70c484cad9b2c4 +// 8e2cc06bc0d2c0967d2f8424762bd48555ee40ae diff --git a/scripts/atomic/fallbacks/read_acquire b/scripts/atomic/fallbacks/read_acquire index 803ba7561076..a0ea1d26e6b2 100755 --- a/scripts/atomic/fallbacks/read_acquire +++ b/scripts/atomic/fallbacks/read_acquire @@ -2,6 +2,15 @@ cat <counter); + ${int} ret; + + if (__native_word(${atomic}_t)) { + ret = smp_load_acquire(&(v)->counter); + } else { + ret = arch_${atomic}_read(v); + __atomic_acquire_fence(); + } + + return ret; } EOF diff --git a/scripts/atomic/fallbacks/set_release b/scripts/atomic/fallbacks/set_release index 86ede759f24e..05cdb7f42477 100755 --- a/scripts/atomic/fallbacks/set_release +++ b/scripts/atomic/fallbacks/set_release @@ -2,6 +2,11 @@ cat <counter, i); + if (__native_word(${atomic}_t)) { + smp_store_release(&(v)->counter, i); + } else { + __atomic_release_fence(); + arch_${atomic}_set(v, i); + } } EOF -- cgit v1.2.3 From 1b9e740a81f91ae338b29ed70455719804957b80 Mon Sep 17 00:00:00 2001 From: Jing Leng Date: Fri, 11 Feb 2022 17:27:36 +0800 Subject: kconfig: fix failing to generate auto.conf When the KCONFIG_AUTOCONFIG is specified (e.g. export \ KCONFIG_AUTOCONFIG=output/config/auto.conf), the directory of include/config/ will not be created, so kconfig can't create deps files in it and auto.conf can't be generated. Signed-off-by: Jing Leng Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 16897cb8cefd..d3c3a61308ad 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -994,14 +994,19 @@ static int conf_write_autoconf_cmd(const char *autoconf_name) static int conf_touch_deps(void) { - const char *name; + const char *name, *tmp; struct symbol *sym; int res, i; - strcpy(depfile_path, "include/config/"); - depfile_prefix_len = strlen(depfile_path); - name = conf_get_autoconfig_name(); + tmp = strrchr(name, '/'); + depfile_prefix_len = tmp ? tmp - name + 1 : 0; + if (depfile_prefix_len + 1 > sizeof(depfile_path)) + return -1; + + strncpy(depfile_path, name, depfile_prefix_len); + depfile_path[depfile_prefix_len] = 0; + conf_read_simple(name, S_DEF_AUTO); sym_calc_value(modules_sym); -- cgit v1.2.3 From 818ab43fc56ad978cbb7c0ffdc9a332fd2f23a23 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sun, 30 Jan 2022 09:59:29 -0800 Subject: fortify: Update compile-time tests for Clang 14 Clang 14 introduces support for compiletime_assert(). Update the compile-time warning regex to catch Clang's variant of the warning text in preparation for Clang supporting CONFIG_FORTIFY_SOURCE. Cc: Nick Desaulniers Cc: linux-hardening@vger.kernel.org Cc: llvm@lists.linux.dev Reviewed-by: Nathan Chancellor Link: https://lore.kernel.org/lkml/YfbtQKtpyAM1hHiC@dev-arch.archlinux-ax161 Signed-off-by: Kees Cook --- scripts/test_fortify.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/test_fortify.sh b/scripts/test_fortify.sh index a4da365508f0..c2688ab8281d 100644 --- a/scripts/test_fortify.sh +++ b/scripts/test_fortify.sh @@ -46,8 +46,12 @@ if "$@" -Werror -c "$IN" -o "$OUT".o 2> "$TMP" ; then status="warning: unsafe ${FUNC}() usage lacked '$WANT' symbol in $IN" fi else - # If the build failed, check for the warning in the stderr (gcc). - if ! grep -q -m1 "error: call to .\b${WANT}\b." "$TMP" ; then + # If the build failed, check for the warning in the stderr. + # GCC: + # ./include/linux/fortify-string.h:316:25: error: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror=attribute-warning] + # Clang 14: + # ./include/linux/fortify-string.h:316:4: error: call to __write_overflow_field declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror,-Wattribute-warning] + if ! grep -Eq -m1 "error: call to .?\b${WANT}\b.?" "$TMP" ; then status="warning: unsafe ${FUNC}() usage lacked '$WANT' warning in $IN" fi fi -- cgit v1.2.3 From a5575df58004e8444e5a2a307407c3f1a6ecf175 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 25 Jan 2022 15:40:27 +0900 Subject: kbuild: unify cmd_copy and cmd_shipped cmd_copy and cmd_shipped have similar functionality. The difference is that cmd_copy uses 'cp' while cmd_shipped 'cat'. Unify them into cmd_copy because this macro name is more intuitive. Going forward, cmd_copy will use 'cat' to avoid the permission issue. I also thought of 'cp --no-preserve=mode' but this option is not mentioned in the POSIX spec [1], so I am keeping the 'cat' command. [1]: https://pubs.opengroup.org/onlinepubs/009695299/utilities/cp.html Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Reviewed-by: Gabriel Krisman Bertazi --- arch/microblaze/boot/Makefile | 2 +- arch/microblaze/boot/dts/Makefile | 2 +- fs/unicode/Makefile | 2 +- scripts/Makefile.lib | 12 ++++-------- usr/Makefile | 4 ++-- 5 files changed, 9 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile index cff570a71946..2b42c370d574 100644 --- a/arch/microblaze/boot/Makefile +++ b/arch/microblaze/boot/Makefile @@ -29,7 +29,7 @@ $(obj)/simpleImage.$(DTB).ub: $(obj)/simpleImage.$(DTB) FORCE $(call if_changed,uimage) $(obj)/simpleImage.$(DTB).unstrip: vmlinux FORCE - $(call if_changed,shipped) + $(call if_changed,copy) $(obj)/simpleImage.$(DTB).strip: vmlinux FORCE $(call if_changed,strip) diff --git a/arch/microblaze/boot/dts/Makefile b/arch/microblaze/boot/dts/Makefile index ef00dd30d19a..b84e2cbb20ee 100644 --- a/arch/microblaze/boot/dts/Makefile +++ b/arch/microblaze/boot/dts/Makefile @@ -12,7 +12,7 @@ $(obj)/linked_dtb.o: $(obj)/system.dtb # Generate system.dtb from $(DTB).dtb ifneq ($(DTB),system) $(obj)/system.dtb: $(obj)/$(DTB).dtb - $(call if_changed,shipped) + $(call if_changed,copy) endif endif diff --git a/fs/unicode/Makefile b/fs/unicode/Makefile index 0cc87423de82..0e51c0025a16 100644 --- a/fs/unicode/Makefile +++ b/fs/unicode/Makefile @@ -33,7 +33,7 @@ $(obj)/utf8data.c: $(obj)/mkutf8data $(filter %.txt, $(cmd_utf8data)) FORCE else $(obj)/utf8data.c: $(src)/utf8data.c_shipped FORCE - $(call if_changed,shipped) + $(call if_changed,copy) endif diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 79be57fdd32a..40735a3adb54 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -246,20 +246,16 @@ $(foreach m, $(notdir $1), \ $(addprefix $(obj)/, $(foreach s, $3, $($(m:%$(strip $2)=%$(s))))))) endef -quiet_cmd_copy = COPY $@ - cmd_copy = cp $< $@ - -# Shipped files +# Copy a file # =========================================================================== # 'cp' preserves permissions. If you use it to copy a file in read-only srctree, # the copy would be read-only as well, leading to an error when executing the # rule next time. Use 'cat' instead in order to generate a writable file. - -quiet_cmd_shipped = SHIPPED $@ -cmd_shipped = cat $< > $@ +quiet_cmd_copy = COPY $@ + cmd_copy = cat $< > $@ $(obj)/%: $(src)/%_shipped - $(call cmd,shipped) + $(call cmd,copy) # Commands useful for building a boot image # =========================================================================== diff --git a/usr/Makefile b/usr/Makefile index cc0d2824e100..59d9e8b07a01 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -3,7 +3,7 @@ # kbuild file for usr/ - including initramfs image # -compress-y := shipped +compress-y := copy compress-$(CONFIG_INITRAMFS_COMPRESSION_GZIP) := gzip compress-$(CONFIG_INITRAMFS_COMPRESSION_BZIP2) := bzip2 compress-$(CONFIG_INITRAMFS_COMPRESSION_LZMA) := lzma @@ -37,7 +37,7 @@ endif # .cpio.*, use it directly as an initramfs, and avoid double compression. ifeq ($(words $(subst .cpio.,$(space),$(ramfs-input))),2) cpio-data := $(ramfs-input) -compress-y := shipped +compress-y := copy endif endif -- cgit v1.2.3 From 5c8166419acf468b5bc3e48f928a040485d3e0c2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 11 Feb 2022 14:14:11 +0900 Subject: kbuild: replace $(if A,A,B) with $(or A,B) $(or ...) is available since GNU Make 3.81, and useful to shorten the code in some places. Covert as follows: $(if A,A,B) --> $(or A,B) This patch also converts: $(if A, A, B) --> $(or A, B) Strictly speaking, the latter is not an equivalent conversion because GNU Make keeps spaces after commas; if A is not empty, $(if A, A, B) expands to " A", while $(or A, B) expands to "A". Anyway, preceding spaces are not significant in the code hunks I touched. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- Makefile | 8 ++++---- scripts/Makefile.build | 3 +-- scripts/Makefile.clean | 2 +- scripts/Makefile.lib | 4 ++-- tools/bpf/bpftool/Makefile | 4 ++-- tools/build/Makefile | 2 +- tools/counter/Makefile | 2 +- tools/gpio/Makefile | 2 +- tools/hv/Makefile | 2 +- tools/iio/Makefile | 2 +- tools/lib/api/Makefile | 2 +- tools/lib/bpf/Makefile | 2 +- tools/lib/perf/Makefile | 2 +- tools/lib/subcmd/Makefile | 2 +- tools/objtool/Makefile | 2 +- tools/pci/Makefile | 2 +- tools/perf/Makefile.perf | 4 ++-- tools/power/x86/intel-speed-select/Makefile | 2 +- tools/scripts/utilities.mak | 2 +- tools/spi/Makefile | 6 +++--- tools/tracing/rtla/Makefile | 2 +- tools/usb/Makefile | 2 +- 22 files changed, 30 insertions(+), 31 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 351f043e133a..a82095c69fdd 100644 --- a/Makefile +++ b/Makefile @@ -1240,8 +1240,8 @@ define filechk_version.h echo \#define LINUX_VERSION_SUBLEVEL $(SUBLEVEL) endef -$(version_h): PATCHLEVEL := $(if $(PATCHLEVEL), $(PATCHLEVEL), 0) -$(version_h): SUBLEVEL := $(if $(SUBLEVEL), $(SUBLEVEL), 0) +$(version_h): PATCHLEVEL := $(or $(PATCHLEVEL), 0) +$(version_h): SUBLEVEL := $(or $(SUBLEVEL), 0) $(version_h): FORCE $(call filechk,version.h) @@ -1624,7 +1624,7 @@ help: @$(MAKE) -f $(srctree)/Documentation/Makefile dochelp @echo '' @echo 'Architecture specific targets ($(SRCARCH)):' - @$(if $(archhelp),$(archhelp),\ + @$(or $(archhelp),\ echo ' No architecture specific help defined for $(SRCARCH)') @echo '' @$(if $(boards), \ @@ -1841,7 +1841,7 @@ $(clean-dirs): clean: $(clean-dirs) $(call cmd,rmfiles) - @find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \ + @find $(or $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \ \( -name '*.[aios]' -o -name '*.ko' -o -name '.*.cmd' \ -o -name '*.ko.*' \ -o -name '*.dtb' -o -name '*.dtbo' -o -name '*.dtb.S' -o -name '*.dt.yaml' \ diff --git a/scripts/Makefile.build b/scripts/Makefile.build index a4b89b757287..7e177d0ee02d 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -40,8 +40,7 @@ include $(srctree)/scripts/Makefile.compiler # The filename Kbuild has precedence over Makefile kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) -kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile) -include $(kbuild-file) +include $(or $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Makefile) include $(srctree)/scripts/Makefile.lib diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index fd6175322470..74cb1c5c3658 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -12,7 +12,7 @@ include $(srctree)/scripts/Kbuild.include # The filename Kbuild has precedence over Makefile kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) -include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) +include $(or $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Makefile) # Figure out what we need to build from the various variables # ========================================================================== diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 40735a3adb54..49377d2c2d20 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -111,7 +111,7 @@ subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) modname-multi = $(sort $(foreach m,$(multi-obj-ym),\ $(if $(filter $*.o, $(call suffix-search, $m, .o, -objs -y -m)),$(m:.o=)))) -__modname = $(if $(modname-multi),$(modname-multi),$(basetarget)) +__modname = $(or $(modname-multi),$(basetarget)) modname = $(subst $(space),:,$(__modname)) modfile = $(addprefix $(obj)/,$(__modname)) @@ -434,7 +434,7 @@ MKIMAGE := $(srctree)/scripts/mkuboot.sh # SRCARCH just happens to match slightly more than ARCH (on sparc), so reduces # the number of overrides in arch makefiles UIMAGE_ARCH ?= $(SRCARCH) -UIMAGE_COMPRESSION ?= $(if $(2),$(2),none) +UIMAGE_COMPRESSION ?= $(or $(2),none) UIMAGE_OPTS-y ?= UIMAGE_TYPE ?= kernel UIMAGE_LOADADDR ?= arch_must_set_this diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile index 83369f55df61..ebd21a609910 100644 --- a/tools/bpf/bpftool/Makefile +++ b/tools/bpf/bpftool/Makefile @@ -78,7 +78,7 @@ CFLAGS += -O2 CFLAGS += -W -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers CFLAGS += $(filter-out -Wswitch-enum -Wnested-externs,$(EXTRA_WARNINGS)) CFLAGS += -DPACKAGE='"bpftool"' -D__EXPORTED_HEADERS__ \ - -I$(if $(OUTPUT),$(OUTPUT),.) \ + -I$(or $(OUTPUT),.) \ -I$(LIBBPF_INCLUDE) \ -I$(srctree)/kernel/bpf/ \ -I$(srctree)/tools/include \ @@ -186,7 +186,7 @@ endif $(OUTPUT)%.bpf.o: skeleton/%.bpf.c $(OUTPUT)vmlinux.h $(LIBBPF_BOOTSTRAP) $(QUIET_CLANG)$(CLANG) \ - -I$(if $(OUTPUT),$(OUTPUT),.) \ + -I$(or $(OUTPUT),.) \ -I$(srctree)/tools/include/uapi/ \ -I$(LIBBPF_BOOTSTRAP_INCLUDE) \ -g -O2 -Wall -target bpf -c $< -o $@ diff --git a/tools/build/Makefile b/tools/build/Makefile index 6f11e6fc9ffe..17cdf01e29a0 100644 --- a/tools/build/Makefile +++ b/tools/build/Makefile @@ -36,7 +36,7 @@ TMP_O := $(if $(OUTPUT),$(OUTPUT)feature/,./) clean: $(call QUIET_CLEAN, fixdep) - $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete + $(Q)find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete $(Q)rm -f $(OUTPUT)fixdep $(call QUIET_CLEAN, feature-detect) ifneq ($(wildcard $(TMP_O)),) diff --git a/tools/counter/Makefile b/tools/counter/Makefile index 5ebc195fd9c0..8843f0fa6119 100644 --- a/tools/counter/Makefile +++ b/tools/counter/Makefile @@ -40,7 +40,7 @@ $(OUTPUT)counter_example: $(COUNTER_EXAMPLE) clean: rm -f $(ALL_PROGRAMS) rm -rf $(OUTPUT)include/linux/counter.h - find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete + find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete install: $(ALL_PROGRAMS) install -d -m 755 $(DESTDIR)$(bindir); \ diff --git a/tools/gpio/Makefile b/tools/gpio/Makefile index 440434027557..d29c9c49e251 100644 --- a/tools/gpio/Makefile +++ b/tools/gpio/Makefile @@ -78,7 +78,7 @@ $(OUTPUT)gpio-watch: $(GPIO_WATCH_IN) clean: rm -f $(ALL_PROGRAMS) rm -f $(OUTPUT)include/linux/gpio.h - find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete + find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete install: $(ALL_PROGRAMS) install -d -m 755 $(DESTDIR)$(bindir); \ diff --git a/tools/hv/Makefile b/tools/hv/Makefile index b57143d9459c..fe770e679ae8 100644 --- a/tools/hv/Makefile +++ b/tools/hv/Makefile @@ -47,7 +47,7 @@ $(OUTPUT)hv_fcopy_daemon: $(HV_FCOPY_DAEMON_IN) clean: rm -f $(ALL_PROGRAMS) - find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete + find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete install: $(ALL_PROGRAMS) install -d -m 755 $(DESTDIR)$(sbindir); \ diff --git a/tools/iio/Makefile b/tools/iio/Makefile index 5d12ac4e7f8f..fa720f062229 100644 --- a/tools/iio/Makefile +++ b/tools/iio/Makefile @@ -58,7 +58,7 @@ $(OUTPUT)iio_generic_buffer: $(IIO_GENERIC_BUFFER_IN) clean: rm -f $(ALL_PROGRAMS) rm -rf $(OUTPUT)include/linux/iio - find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete + find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete install: $(ALL_PROGRAMS) install -d -m 755 $(DESTDIR)$(bindir); \ diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index a13e9c7f1fc5..e21e1b40b525 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile @@ -60,7 +60,7 @@ $(LIBFILE): $(API_IN) clean: $(call QUIET_CLEAN, libapi) $(RM) $(LIBFILE); \ - find $(if $(OUTPUT),$(OUTPUT),.) -name \*.o -or -name \*.o.cmd -or -name \*.o.d | xargs $(RM) + find $(or $(OUTPUT),.) -name \*.o -or -name \*.o.cmd -or -name \*.o.d | xargs $(RM) FORCE: diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index f947b61b2107..36b85aea0393 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -60,7 +60,7 @@ ifndef VERBOSE VERBOSE = 0 endif -INCLUDES = -I$(if $(OUTPUT),$(OUTPUT),.) \ +INCLUDES = -I$(or $(OUTPUT),.) \ -I$(srctree)/tools/include -I$(srctree)/tools/include/uapi export prefix libdir src obj diff --git a/tools/lib/perf/Makefile b/tools/lib/perf/Makefile index 08fe6e3c4089..21df023a2103 100644 --- a/tools/lib/perf/Makefile +++ b/tools/lib/perf/Makefile @@ -153,7 +153,7 @@ $(TESTS_STATIC): $(TESTS_IN) $(LIBPERF_A) $(LIBAPI) $(QUIET_LINK)$(CC) -o $@ $^ $(TESTS_SHARED): $(TESTS_IN) $(LIBAPI) - $(QUIET_LINK)$(CC) -o $@ -L$(if $(OUTPUT),$(OUTPUT),.) $^ -lperf + $(QUIET_LINK)$(CC) -o $@ -L$(or $(OUTPUT),.) $^ -lperf make-tests: libs $(TESTS_SHARED) $(TESTS_STATIC) diff --git a/tools/lib/subcmd/Makefile b/tools/lib/subcmd/Makefile index 1c777a72bb39..8f1a09cdfd17 100644 --- a/tools/lib/subcmd/Makefile +++ b/tools/lib/subcmd/Makefile @@ -63,7 +63,7 @@ $(LIBFILE): $(SUBCMD_IN) clean: $(call QUIET_CLEAN, libsubcmd) $(RM) $(LIBFILE); \ - find $(if $(OUTPUT),$(OUTPUT),.) -name \*.o -or -name \*.o.cmd -or -name \*.o.d | xargs $(RM) + find $(or $(OUTPUT),.) -name \*.o -or -name \*.o.cmd -or -name \*.o.d | xargs $(RM) FORCE: diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index 92ce4fce7bc7..0dbd397f319d 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -13,7 +13,7 @@ srctree := $(patsubst %/,%,$(dir $(srctree))) endif SUBCMD_SRCDIR = $(srctree)/tools/lib/subcmd/ -LIBSUBCMD_OUTPUT = $(if $(OUTPUT),$(OUTPUT),$(CURDIR)/) +LIBSUBCMD_OUTPUT = $(or $(OUTPUT),$(CURDIR)/) LIBSUBCMD = $(LIBSUBCMD_OUTPUT)libsubcmd.a OBJTOOL := $(OUTPUT)objtool diff --git a/tools/pci/Makefile b/tools/pci/Makefile index 4b95a5176355..57744778b518 100644 --- a/tools/pci/Makefile +++ b/tools/pci/Makefile @@ -42,7 +42,7 @@ $(OUTPUT)pcitest: $(PCITEST_IN) clean: rm -f $(ALL_PROGRAMS) rm -rf $(OUTPUT)include/ - find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete + find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete install: $(ALL_PROGRAMS) install -d -m 755 $(DESTDIR)$(bindir); \ diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index ac861e42c8f7..8583d18a3739 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -724,7 +724,7 @@ endif # get relative building directory (to $(OUTPUT)) # and '.' if it's $(OUTPUT) itself __build-dir = $(subst $(OUTPUT),,$(dir $@)) -build-dir = $(if $(__build-dir),$(__build-dir),.) +build-dir = $(or $(__build-dir),.) prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioctl_array) \ $(fadvise_advice_array) \ @@ -1090,7 +1090,7 @@ bpf-skel-clean: clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean $(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(OUTPUT)perf-iostat $(LANG_BINDINGS) - $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete + $(Q)find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete $(Q)$(RM) $(OUTPUT).config-detected $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 $(OUTPUT)pmu-events/jevents $(OUTPUT)$(LIBJVMTI).so $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \ diff --git a/tools/power/x86/intel-speed-select/Makefile b/tools/power/x86/intel-speed-select/Makefile index 12c6939dca2a..7eaa517cd403 100644 --- a/tools/power/x86/intel-speed-select/Makefile +++ b/tools/power/x86/intel-speed-select/Makefile @@ -43,7 +43,7 @@ $(OUTPUT)intel-speed-select: $(ISST_IN) clean: rm -f $(ALL_PROGRAMS) rm -rf $(OUTPUT)include/linux/isst_if.h - find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete + find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete install: $(ALL_PROGRAMS) install -d -m 755 $(DESTDIR)$(bindir); \ diff --git a/tools/scripts/utilities.mak b/tools/scripts/utilities.mak index c16ce833079c..172e47273b5d 100644 --- a/tools/scripts/utilities.mak +++ b/tools/scripts/utilities.mak @@ -175,5 +175,5 @@ _ge-abspath = $(if $(is-executable),$(1)) define get-executable-or-default $(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2))) endef -_ge_attempt = $(if $(get-executable),$(get-executable),$(call _gea_err,$(2))) +_ge_attempt = $(or $(get-executable),$(call _gea_err,$(2))) _gea_err = $(if $(1),$(error Please set '$(1)' appropriately)) diff --git a/tools/spi/Makefile b/tools/spi/Makefile index 0aa6dbd31fb8..7fccd245a535 100644 --- a/tools/spi/Makefile +++ b/tools/spi/Makefile @@ -53,9 +53,9 @@ $(OUTPUT)spidev_fdx: $(SPIDEV_FDX_IN) clean: rm -f $(ALL_PROGRAMS) rm -rf $(OUTPUT)include/ - find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete - find $(if $(OUTPUT),$(OUTPUT),.) -name '\.*.o.d' -delete - find $(if $(OUTPUT),$(OUTPUT),.) -name '\.*.o.cmd' -delete + find $(or $(OUTPUT),.) -name '*.o' -delete + find $(or $(OUTPUT),.) -name '\.*.o.d' -delete + find $(or $(OUTPUT),.) -name '\.*.o.cmd' -delete install: $(ALL_PROGRAMS) install -d -m 755 $(DESTDIR)$(bindir); \ diff --git a/tools/tracing/rtla/Makefile b/tools/tracing/rtla/Makefile index 5a1eda617992..11fb417abb42 100644 --- a/tools/tracing/rtla/Makefile +++ b/tools/tracing/rtla/Makefile @@ -46,7 +46,7 @@ DATADIR := /usr/share DOCDIR := $(DATADIR)/doc MANDIR := $(DATADIR)/man LICDIR := $(DATADIR)/licenses -SRCTREE := $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR)) +SRCTREE := $(or $(BUILD_SRC),$(CURDIR)) # If running from the tarball, man pages are stored in the Documentation # dir. If running from the kernel source, man pages are stored in diff --git a/tools/usb/Makefile b/tools/usb/Makefile index 1b128e551b2e..c6235667dd46 100644 --- a/tools/usb/Makefile +++ b/tools/usb/Makefile @@ -38,7 +38,7 @@ $(OUTPUT)ffs-test: $(FFS_TEST_IN) clean: rm -f $(ALL_PROGRAMS) - find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete -o -name '\.*.o.cmd' -delete + find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete -o -name '\.*.o.cmd' -delete install: $(ALL_PROGRAMS) install -d -m 755 $(DESTDIR)$(bindir); \ -- cgit v1.2.3 From 5224f79096170bf7b92cc8fe42a12f44b91e5f62 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 14 Feb 2022 19:11:44 -0600 Subject: treewide: Replace zero-length arrays with flexible-array members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2]. This code was transformed with the help of Coccinelle: (next-20220214$ spatch --jobs $(getconf _NPROCESSORS_ONLN) --sp-file script.cocci --include-headers --dir . > output.patch) @@ identifier S, member, array; type T1, T2; @@ struct S { ... T1 member; T2 array[ - 0 ]; }; UAPI and wireless changes were intentionally excluded from this patch and will be sent out separately. [1] https://en.wikipedia.org/wiki/Flexible_array_member [2] https://www.kernel.org/doc/html/v5.16/process/deprecated.html#zero-length-and-one-element-arrays Link: https://github.com/KSPP/linux/issues/78 Reviewed-by: Kees Cook Signed-off-by: Gustavo A. R. Silva --- arch/alpha/include/asm/hwrpb.h | 2 +- arch/ia64/include/asm/sal.h | 2 +- arch/s390/include/asm/ccwgroup.h | 2 +- arch/s390/include/asm/chsc.h | 2 +- arch/s390/include/asm/eadm.h | 2 +- arch/s390/include/asm/fcx.h | 4 ++-- arch/s390/include/asm/idals.h | 2 +- arch/s390/include/asm/sclp.h | 2 +- arch/s390/include/asm/sysinfo.h | 6 +++--- arch/sh/include/asm/thread_info.h | 2 +- arch/sparc/include/asm/vio.h | 10 +++++----- arch/um/include/shared/net_kern.h | 2 +- arch/x86/include/asm/microcode_amd.h | 2 +- arch/x86/include/asm/microcode_intel.h | 4 ++-- arch/x86/include/asm/pci.h | 2 +- arch/x86/include/asm/pci_x86.h | 2 +- arch/xtensa/include/asm/bootparam.h | 2 +- drivers/crypto/caam/pdb.h | 2 +- drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 2 +- drivers/gpu/drm/nouveau/include/nvfw/hs.h | 2 +- drivers/hwtracing/coresight/coresight-config.h | 2 +- drivers/misc/bcm-vk/bcm_vk.h | 2 +- drivers/misc/habanalabs/include/common/cpucp_if.h | 6 +++--- .../misc/habanalabs/include/gaudi/gaudi_packets.h | 4 ++-- drivers/misc/habanalabs/include/goya/goya_packets.h | 4 ++-- drivers/net/ethernet/freescale/enetc/enetc_hw.h | 2 +- drivers/net/ethernet/i825xx/sun3_82586.h | 2 +- drivers/net/ethernet/marvell/octeontx2/af/npc.h | 6 +++--- drivers/net/ethernet/qlogic/qed/qed_mfw_hsi.h | 2 +- drivers/net/ethernet/ti/davinci_mdio.c | 2 +- drivers/scsi/dpt/dpti_i2o.h | 2 +- drivers/scsi/elx/libefc_sli/sli4.h | 20 ++++++++++---------- drivers/scsi/mpi3mr/mpi3mr.h | 2 +- drivers/scsi/qla2xxx/qla_bsg.h | 4 ++-- drivers/scsi/qla2xxx/qla_def.h | 2 +- drivers/scsi/qla2xxx/qla_edif_bsg.h | 4 ++-- drivers/scsi/qla2xxx/qla_fw.h | 2 +- drivers/scsi/qla4xxx/ql4_fw.h | 2 +- drivers/staging/r8188eu/include/rtw_cmd.h | 10 +++++----- drivers/staging/rtl8712/rtl871x_cmd.h | 8 ++++---- drivers/staging/rtl8723bs/include/ieee80211.h | 2 +- drivers/staging/rtl8723bs/include/rtw_cmd.h | 2 +- .../vc04_services/include/linux/raspberrypi/vchiq.h | 2 +- drivers/visorbus/vbuschannel.h | 2 +- fs/cifs/ntlmssp.h | 2 +- fs/ext4/fast_commit.h | 4 ++-- fs/ksmbd/ksmbd_netlink.h | 2 +- fs/ksmbd/ntlmssp.h | 6 +++--- fs/ksmbd/smb2pdu.h | 8 ++++---- fs/ksmbd/transport_rdma.c | 2 +- fs/ksmbd/xattr.h | 2 +- fs/xfs/scrub/attr.h | 2 +- include/asm-generic/tlb.h | 4 ++-- include/linux/greybus/greybus_manifest.h | 4 ++-- include/linux/greybus/hd.h | 2 +- include/linux/greybus/module.h | 2 +- include/linux/i3c/ccc.h | 6 +++--- include/linux/platform_data/brcmfmac.h | 2 +- include/linux/platform_data/cros_ec_commands.h | 2 +- include/net/bluetooth/mgmt.h | 2 +- include/net/ioam6.h | 2 +- include/sound/sof/channel_map.h | 4 ++-- scripts/dtc/libfdt/fdt.h | 4 ++-- sound/soc/intel/atom/sst-mfld-dsp.h | 4 ++-- sound/soc/intel/skylake/skl-topology.h | 2 +- tools/lib/perf/include/perf/event.h | 2 +- 66 files changed, 111 insertions(+), 111 deletions(-) (limited to 'scripts') diff --git a/arch/alpha/include/asm/hwrpb.h b/arch/alpha/include/asm/hwrpb.h index d8180e527a1e..fc76f36265ad 100644 --- a/arch/alpha/include/asm/hwrpb.h +++ b/arch/alpha/include/asm/hwrpb.h @@ -152,7 +152,7 @@ struct memdesc_struct { unsigned long chksum; unsigned long optional_pa; unsigned long numclusters; - struct memclust_struct cluster[0]; + struct memclust_struct cluster[]; }; struct dsr_struct { diff --git a/arch/ia64/include/asm/sal.h b/arch/ia64/include/asm/sal.h index 78f4f7b40435..22749a201e92 100644 --- a/arch/ia64/include/asm/sal.h +++ b/arch/ia64/include/asm/sal.h @@ -420,7 +420,7 @@ typedef struct sal_log_processor_info { * The rest of this structure consists of variable-length arrays, which can't be * expressed in C. */ - sal_log_mod_error_info_t info[0]; + sal_log_mod_error_info_t info[]; /* * This is what the rest looked like if C supported variable-length arrays: * diff --git a/arch/s390/include/asm/ccwgroup.h b/arch/s390/include/asm/ccwgroup.h index aa995d91cd1d..11d2fb3de4f5 100644 --- a/arch/s390/include/asm/ccwgroup.h +++ b/arch/s390/include/asm/ccwgroup.h @@ -25,7 +25,7 @@ struct ccwgroup_device { unsigned int count; struct device dev; struct work_struct ungroup_work; - struct ccw_device *cdev[0]; + struct ccw_device *cdev[]; }; /** diff --git a/arch/s390/include/asm/chsc.h b/arch/s390/include/asm/chsc.h index ae4d2549cd67..bb48ea380c0d 100644 --- a/arch/s390/include/asm/chsc.h +++ b/arch/s390/include/asm/chsc.h @@ -63,7 +63,7 @@ struct chsc_pnso_area { struct chsc_header response; u32:32; struct chsc_pnso_naihdr naihdr; - struct chsc_pnso_naid_l2 entries[0]; + struct chsc_pnso_naid_l2 entries[]; } __packed __aligned(PAGE_SIZE); #endif /* _ASM_S390_CHSC_H */ diff --git a/arch/s390/include/asm/eadm.h b/arch/s390/include/asm/eadm.h index 445fe4c8184a..06f795855af7 100644 --- a/arch/s390/include/asm/eadm.h +++ b/arch/s390/include/asm/eadm.h @@ -78,7 +78,7 @@ struct aob { struct aob_rq_header { struct scm_device *scmdev; - char data[0]; + char data[]; }; struct scm_device { diff --git a/arch/s390/include/asm/fcx.h b/arch/s390/include/asm/fcx.h index cff0749e9657..b8a028a36173 100644 --- a/arch/s390/include/asm/fcx.h +++ b/arch/s390/include/asm/fcx.h @@ -214,7 +214,7 @@ struct dcw_intrg_data { u32 :32; u64 time; u64 prog_id; - u8 prog_data[0]; + u8 prog_data[]; } __attribute__ ((packed)); #define DCW_FLAGS_CC (1 << (7 - 1)) @@ -241,7 +241,7 @@ struct dcw { u32 :8; u32 cd_count:8; u32 count; - u8 cd[0]; + u8 cd[]; } __attribute__ ((packed)); #define TCCB_FORMAT_DEFAULT 0x7f diff --git a/arch/s390/include/asm/idals.h b/arch/s390/include/asm/idals.h index 6fb7aced104a..40eae2c08d61 100644 --- a/arch/s390/include/asm/idals.h +++ b/arch/s390/include/asm/idals.h @@ -108,7 +108,7 @@ clear_normalized_cda(struct ccw1 * ccw) struct idal_buffer { size_t size; size_t page_order; - void *data[0]; + void *data[]; }; /* diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index c68ea35de498..22b3213c6c9d 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h @@ -112,7 +112,7 @@ struct zpci_report_error_header { * (OpenCrypto Successful Diagnostics Execution) */ u16 length; /* Length of Subsequent Data (up to 4K – SCLP header */ - u8 data[0]; /* Subsequent Data passed verbatim to SCLP ET 24 */ + u8 data[]; /* Subsequent Data passed verbatim to SCLP ET 24 */ } __packed; extern char *sclp_early_sccb; diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h index fe7b3f8f0791..ab1c6316055c 100644 --- a/arch/s390/include/asm/sysinfo.h +++ b/arch/s390/include/asm/sysinfo.h @@ -67,12 +67,12 @@ struct sysinfo_1_2_2 { unsigned short cpus_configured; unsigned short cpus_standby; unsigned short cpus_reserved; - unsigned short adjustment[0]; + unsigned short adjustment[]; }; struct sysinfo_1_2_2_extension { unsigned int alt_capability; - unsigned short alt_adjustment[0]; + unsigned short alt_adjustment[]; }; struct sysinfo_2_2_1 { @@ -181,7 +181,7 @@ struct sysinfo_15_1_x { unsigned char reserved1; unsigned char mnest; unsigned char reserved2[4]; - union topology_entry tle[0]; + union topology_entry tle[]; }; int stsi(void *sysinfo, int fc, int sel1, int sel2); diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index 598d0184ffea..3a2d50d61fc9 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -33,7 +33,7 @@ struct thread_info { mm_segment_t addr_limit; /* thread address space */ unsigned long previous_sp; /* sp of previous stack in case of nested IRQ stacks */ - __u8 supervisor_stack[0]; + __u8 supervisor_stack[]; }; #endif diff --git a/arch/sparc/include/asm/vio.h b/arch/sparc/include/asm/vio.h index 8a1a83bbb6d5..2d7bdf665fd3 100644 --- a/arch/sparc/include/asm/vio.h +++ b/arch/sparc/include/asm/vio.h @@ -70,7 +70,7 @@ struct vio_dring_register { #define VIO_RX_DRING_DATA 0x0004 u16 resv; u32 num_cookies; - struct ldc_trans_cookie cookies[0]; + struct ldc_trans_cookie cookies[]; }; struct vio_dring_unregister { @@ -161,7 +161,7 @@ struct vio_disk_desc { u64 size; u32 ncookies; u32 resv2; - struct ldc_trans_cookie cookies[0]; + struct ldc_trans_cookie cookies[]; }; #define VIO_DISK_VNAME_LEN 8 @@ -200,13 +200,13 @@ struct vio_disk_devid { u16 resv; u16 type; u32 len; - char id[0]; + char id[]; }; struct vio_disk_efi { u64 lba; u64 len; - char data[0]; + char data[]; }; /* VIO net specific structures and defines */ @@ -246,7 +246,7 @@ struct vio_net_desc { struct vio_dring_hdr hdr; u32 size; u32 ncookies; - struct ldc_trans_cookie cookies[0]; + struct ldc_trans_cookie cookies[]; }; struct vio_net_dext { diff --git a/arch/um/include/shared/net_kern.h b/arch/um/include/shared/net_kern.h index 441a8a309329..67b2e9a1f2e5 100644 --- a/arch/um/include/shared/net_kern.h +++ b/arch/um/include/shared/net_kern.h @@ -39,7 +39,7 @@ struct uml_net_private { void (*add_address)(unsigned char *, unsigned char *, void *); void (*delete_address)(unsigned char *, unsigned char *, void *); - char user[0]; + char user[]; }; struct net_kern_info { diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h index 7063b5a43220..ac31f9140d07 100644 --- a/arch/x86/include/asm/microcode_amd.h +++ b/arch/x86/include/asm/microcode_amd.h @@ -38,7 +38,7 @@ struct microcode_header_amd { struct microcode_amd { struct microcode_header_amd hdr; - unsigned int mpb[0]; + unsigned int mpb[]; }; #define PATCH_MAX_SIZE (3 * PAGE_SIZE) diff --git a/arch/x86/include/asm/microcode_intel.h b/arch/x86/include/asm/microcode_intel.h index d85a07d7154f..4c92cea7e4b5 100644 --- a/arch/x86/include/asm/microcode_intel.h +++ b/arch/x86/include/asm/microcode_intel.h @@ -19,7 +19,7 @@ struct microcode_header_intel { struct microcode_intel { struct microcode_header_intel hdr; - unsigned int bits[0]; + unsigned int bits[]; }; /* microcode format is extended from prescott processors */ @@ -33,7 +33,7 @@ struct extended_sigtable { unsigned int count; unsigned int cksum; unsigned int reserved[3]; - struct extended_signature sigs[0]; + struct extended_signature sigs[]; }; #define DEFAULT_UCODE_DATASIZE (2000) diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index d2c76c8d8cfd..f3fd5928bcbb 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -135,7 +135,7 @@ struct pci_setup_rom { unsigned long bus; unsigned long device; unsigned long function; - uint8_t romdata[0]; + uint8_t romdata[]; }; #endif /* _ASM_X86_PCI_H */ diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index 490411dba438..3fb6fc596095 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h @@ -87,7 +87,7 @@ struct irq_routing_table { u32 miniport_data; /* Crap */ u8 rfu[11]; u8 checksum; /* Modulo 256 checksum must give 0 */ - struct irq_info slots[0]; + struct irq_info slots[]; } __attribute__((packed)); extern unsigned int pcibios_irq_mask; diff --git a/arch/xtensa/include/asm/bootparam.h b/arch/xtensa/include/asm/bootparam.h index 892aab399ac8..6333bd1eb9d2 100644 --- a/arch/xtensa/include/asm/bootparam.h +++ b/arch/xtensa/include/asm/bootparam.h @@ -34,7 +34,7 @@ typedef struct bp_tag { unsigned short id; /* tag id */ unsigned short size; /* size of this record excluding the structure*/ - unsigned long data[0]; /* data */ + unsigned long data[]; /* data */ } bp_tag_t; struct bp_meminfo { diff --git a/drivers/crypto/caam/pdb.h b/drivers/crypto/caam/pdb.h index 8ccc22075043..4b1bcf53f7ac 100644 --- a/drivers/crypto/caam/pdb.h +++ b/drivers/crypto/caam/pdb.h @@ -144,7 +144,7 @@ struct ipsec_encap_pdb { }; u32 spi; u32 ip_hdr_len; - u32 ip_hdr[0]; + u32 ip_hdr[]; }; /** diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c index 1a1edae67e4e..3acee0060e23 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c @@ -51,7 +51,7 @@ struct __guc_ads_blob { struct guc_gt_system_info system_info; struct guc_engine_usage engine_usage; /* From here on, location is dynamic! Refer to above diagram. */ - struct guc_mmio_reg regset[0]; + struct guc_mmio_reg regset[]; } __packed; static u32 guc_ads_regset_size(struct intel_guc *guc) diff --git a/drivers/gpu/drm/nouveau/include/nvfw/hs.h b/drivers/gpu/drm/nouveau/include/nvfw/hs.h index 64d0d32200c2..b53bbc4cd130 100644 --- a/drivers/gpu/drm/nouveau/include/nvfw/hs.h +++ b/drivers/gpu/drm/nouveau/include/nvfw/hs.h @@ -23,7 +23,7 @@ struct nvfw_hs_load_header { u32 data_dma_base; u32 data_size; u32 num_apps; - u32 apps[0]; + u32 apps[]; }; const struct nvfw_hs_load_header * diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index 9bd44b940add..2e1670523461 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -231,7 +231,7 @@ struct cscfg_config_csdev { bool enabled; struct list_head node; int nr_feat; - struct cscfg_feature_csdev *feats_csdev[0]; + struct cscfg_feature_csdev *feats_csdev[]; }; /** diff --git a/drivers/misc/bcm-vk/bcm_vk.h b/drivers/misc/bcm-vk/bcm_vk.h index a1338f375589..25d51222eedf 100644 --- a/drivers/misc/bcm-vk/bcm_vk.h +++ b/drivers/misc/bcm-vk/bcm_vk.h @@ -311,7 +311,7 @@ struct bcm_vk_peer_log { u32 wr_idx; u32 buf_size; u32 mask; - char data[0]; + char data[]; }; /* max buf size allowed */ diff --git a/drivers/misc/habanalabs/include/common/cpucp_if.h b/drivers/misc/habanalabs/include/common/cpucp_if.h index 737c39f33f05..f9c4acc9bf5a 100644 --- a/drivers/misc/habanalabs/include/common/cpucp_if.h +++ b/drivers/misc/habanalabs/include/common/cpucp_if.h @@ -540,19 +540,19 @@ struct cpucp_packet { struct cpucp_unmask_irq_arr_packet { struct cpucp_packet cpucp_pkt; __le32 length; - __le32 irqs[0]; + __le32 irqs[]; }; struct cpucp_nic_status_packet { struct cpucp_packet cpucp_pkt; __le32 length; - __le32 data[0]; + __le32 data[]; }; struct cpucp_array_data_packet { struct cpucp_packet cpucp_pkt; __le32 length; - __le32 data[0]; + __le32 data[]; }; enum cpucp_packet_rc { diff --git a/drivers/misc/habanalabs/include/gaudi/gaudi_packets.h b/drivers/misc/habanalabs/include/gaudi/gaudi_packets.h index 6e097ace2e96..66fc083a7c6a 100644 --- a/drivers/misc/habanalabs/include/gaudi/gaudi_packets.h +++ b/drivers/misc/habanalabs/include/gaudi/gaudi_packets.h @@ -54,7 +54,7 @@ struct gaudi_packet { /* The rest of the packet data follows. Use the corresponding * packet_XXX struct to deference the data, based on packet type */ - u8 contents[0]; + u8 contents[]; }; struct packet_nop { @@ -75,7 +75,7 @@ struct packet_wreg32 { struct packet_wreg_bulk { __le32 size64; __le32 ctl; - __le64 values[0]; /* data starts here */ + __le64 values[]; /* data starts here */ }; #define GAUDI_PKT_LONG_CTL_OP_SHIFT 20 diff --git a/drivers/misc/habanalabs/include/goya/goya_packets.h b/drivers/misc/habanalabs/include/goya/goya_packets.h index ef54bad20509..50ce5175b63a 100644 --- a/drivers/misc/habanalabs/include/goya/goya_packets.h +++ b/drivers/misc/habanalabs/include/goya/goya_packets.h @@ -62,7 +62,7 @@ struct goya_packet { /* The rest of the packet data follows. Use the corresponding * packet_XXX struct to deference the data, based on packet type */ - u8 contents[0]; + u8 contents[]; }; struct packet_nop { @@ -86,7 +86,7 @@ struct packet_wreg32 { struct packet_wreg_bulk { __le32 size64; __le32 ctl; - __le64 values[0]; /* data starts here */ + __le64 values[]; /* data starts here */ }; struct packet_msg_long { diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h index 1514e6a4a3ff..ce5b677e8c2f 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h @@ -881,7 +881,7 @@ struct sgcl_data { u32 bth; u32 ct; u32 cte; - struct sgce sgcl[0]; + struct sgce sgcl[]; }; #define ENETC_CBDR_FMI_MR BIT(0) diff --git a/drivers/net/ethernet/i825xx/sun3_82586.h b/drivers/net/ethernet/i825xx/sun3_82586.h index 79aef681ac85..451cb3d26cb5 100644 --- a/drivers/net/ethernet/i825xx/sun3_82586.h +++ b/drivers/net/ethernet/i825xx/sun3_82586.h @@ -250,7 +250,7 @@ struct mcsetup_cmd_struct unsigned short cmd_cmd; unsigned short cmd_link; unsigned short mc_cnt; /* number of bytes in the MC-List */ - unsigned char mc_list[0][6]; /* pointer to 6 bytes entries */ + unsigned char mc_list[][6]; /* pointer to 6 bytes entries */ }; /* diff --git a/drivers/net/ethernet/marvell/octeontx2/af/npc.h b/drivers/net/ethernet/marvell/octeontx2/af/npc.h index 77fd39e2c8db..9b6e587e78b4 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/npc.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/npc.h @@ -455,7 +455,7 @@ struct npc_coalesced_kpu_prfl { u8 name[NPC_NAME_LEN]; /* KPU Profile name */ u64 version; /* KPU firmware/profile version */ u8 num_prfl; /* No of NPC profiles. */ - u16 prfl_sz[0]; + u16 prfl_sz[]; }; struct npc_mcam_kex { @@ -482,7 +482,7 @@ struct npc_kpu_fwdata { * struct npc_kpu_profile_cam[entries]; * struct npc_kpu_profile_action[entries]; */ - u8 data[0]; + u8 data[]; } __packed; struct npc_lt_def { @@ -572,7 +572,7 @@ struct npc_kpu_profile_fwdata { * Custom KPU CAM and ACTION configuration entries. * struct npc_kpu_fwdata kpu[kpus]; */ - u8 data[0]; + u8 data[]; } __packed; struct rvu_npc_mcam_rule { diff --git a/drivers/net/ethernet/qlogic/qed/qed_mfw_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_mfw_hsi.h index b70ee8200e15..6459dd3feb37 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mfw_hsi.h +++ b/drivers/net/ethernet/qlogic/qed/qed_mfw_hsi.h @@ -2470,6 +2470,6 @@ struct nvm_meta_bin_t { u32 version; #define NVM_META_BIN_VERSION 1 u32 num_options; - u32 options[0]; + u32 options[]; }; #endif diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c index a4efd5e35158..fce2626e34fa 100644 --- a/drivers/net/ethernet/ti/davinci_mdio.c +++ b/drivers/net/ethernet/ti/davinci_mdio.c @@ -70,7 +70,7 @@ struct davinci_mdio_regs { #define USERACCESS_DATA (0xffff) u32 physel; - } user[0]; + } user[]; }; static const struct mdio_platform_data default_pdata = { diff --git a/drivers/scsi/dpt/dpti_i2o.h b/drivers/scsi/dpt/dpti_i2o.h index bf0daeeb50a9..e1fbbf55c09d 100644 --- a/drivers/scsi/dpt/dpti_i2o.h +++ b/drivers/scsi/dpt/dpti_i2o.h @@ -123,7 +123,7 @@ struct i2o_sys_tbl u32 change_ind; u32 reserved2; u32 reserved3; - struct i2o_sys_tbl_entry iops[0]; + struct i2o_sys_tbl_entry iops[]; }; /* diff --git a/drivers/scsi/elx/libefc_sli/sli4.h b/drivers/scsi/elx/libefc_sli/sli4.h index ee2a9e65a88d..38af166cc786 100644 --- a/drivers/scsi/elx/libefc_sli/sli4.h +++ b/drivers/scsi/elx/libefc_sli/sli4.h @@ -609,7 +609,7 @@ struct sli4_rqst_cmn_create_cq_v2 { __le16 cqe_count; __le16 rsvd30; __le32 rsvd32; - struct sli4_dmaaddr page_phys_addr[0]; + struct sli4_dmaaddr page_phys_addr[]; }; enum sli4_create_cqset_e { @@ -634,7 +634,7 @@ struct sli4_rqst_cmn_create_cq_set_v0 { __le16 num_cq_req; __le16 dw6w1_flags; __le16 eq_id[16]; - struct sli4_dmaaddr page_phys_addr[0]; + struct sli4_dmaaddr page_phys_addr[]; }; /* CQE count */ @@ -764,7 +764,7 @@ struct sli4_rqst_cmn_create_mq_ext { __le32 dw7_val; __le32 dw8_flags; __le32 rsvd36; - struct sli4_dmaaddr page_phys_addr[0]; + struct sli4_dmaaddr page_phys_addr[]; }; struct sli4_rsp_cmn_create_mq_ext { @@ -802,7 +802,7 @@ struct sli4_rqst_cmn_create_cq_v0 { __le32 dw6_flags; __le32 rsvd28; __le32 rsvd32; - struct sli4_dmaaddr page_phys_addr[0]; + struct sli4_dmaaddr page_phys_addr[]; }; enum sli4_create_rq_e { @@ -887,7 +887,7 @@ struct sli4_rqst_rq_create_v2 { __le16 base_cq_id; __le16 rsvd26; __le32 rsvd42; - struct sli4_dmaaddr page_phys_addr[0]; + struct sli4_dmaaddr page_phys_addr[]; }; struct sli4_rsp_rq_create_v2 { @@ -3168,7 +3168,7 @@ struct sli4_rqst_cmn_read_object { __le32 read_offset; u8 object_name[104]; __le32 host_buffer_descriptor_count; - struct sli4_bde host_buffer_descriptor[0]; + struct sli4_bde host_buffer_descriptor[]; }; #define RSP_COM_READ_OBJ_EOF 0x80000000 @@ -3191,7 +3191,7 @@ struct sli4_rqst_cmn_write_object { __le32 write_offset; u8 object_name[104]; __le32 host_buffer_descriptor_count; - struct sli4_bde host_buffer_descriptor[0]; + struct sli4_bde host_buffer_descriptor[]; }; #define RSP_CHANGE_STATUS 0xff @@ -3217,7 +3217,7 @@ struct sli4_rqst_cmn_read_object_list { __le32 read_offset; u8 object_name[104]; __le32 host_buffer_descriptor_count; - struct sli4_bde host_buffer_descriptor[0]; + struct sli4_bde host_buffer_descriptor[]; }; enum sli4_rqst_set_dump_flags { @@ -3342,7 +3342,7 @@ struct sli4_rspource_descriptor_v1 { u8 descriptor_type; u8 descriptor_length; __le16 rsvd16; - __le32 type_specific[0]; + __le32 type_specific[]; }; enum sli4_pcie_desc_flags { @@ -3474,7 +3474,7 @@ struct sli4_rqst_post_hdr_templates { struct sli4_rqst_hdr hdr; __le16 rpi_offset; __le16 page_count; - struct sli4_dmaaddr page_descriptor[0]; + struct sli4_dmaaddr page_descriptor[]; }; #define SLI4_HDR_TEMPLATE_SIZE 64 diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h index fc4eaf6d1e47..fb7d8775c9f7 100644 --- a/drivers/scsi/mpi3mr/mpi3mr.h +++ b/drivers/scsi/mpi3mr/mpi3mr.h @@ -878,7 +878,7 @@ struct mpi3mr_fwevt { bool process_evt; u32 evt_ctx; struct kref ref_count; - char event_data[0] __aligned(4); + char event_data[] __aligned(4); }; diff --git a/drivers/scsi/qla2xxx/qla_bsg.h b/drivers/scsi/qla2xxx/qla_bsg.h index 0f8a4c7e52a2..6d2b0a7436c1 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.h +++ b/drivers/scsi/qla2xxx/qla_bsg.h @@ -157,7 +157,7 @@ struct qla84_msg_mgmt { uint16_t rsrvd; struct qla84_mgmt_param mgmtp;/* parameters for cmd */ uint32_t len; /* bytes in payload following this struct */ - uint8_t payload[0]; /* payload for cmd */ + uint8_t payload[]; /* payload for cmd */ }; struct qla_bsg_a84_mgmt { @@ -216,7 +216,7 @@ struct qla_image_version { struct qla_image_version_list { uint32_t count; - struct qla_image_version version[0]; + struct qla_image_version version[]; } __packed; struct qla_status_reg { diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 9ebf4a234d9a..b6434c72dee3 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -5410,7 +5410,7 @@ struct ql_vnd_stat_entry { struct ql_vnd_stats { u64 entry_count; /* Num of entries */ u64 rservd; - struct ql_vnd_stat_entry entry[0]; /* Place holder of entries */ + struct ql_vnd_stat_entry entry[]; /* Place holder of entries */ } __packed; struct ql_vnd_host_stats_resp { diff --git a/drivers/scsi/qla2xxx/qla_edif_bsg.h b/drivers/scsi/qla2xxx/qla_edif_bsg.h index 53026d82ebff..5a26c77157da 100644 --- a/drivers/scsi/qla2xxx/qla_edif_bsg.h +++ b/drivers/scsi/qla2xxx/qla_edif_bsg.h @@ -121,7 +121,7 @@ struct app_pinfo { struct app_pinfo_reply { uint8_t port_count; uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; - struct app_pinfo ports[0]; + struct app_pinfo ports[]; } __packed; struct app_sinfo_req { @@ -140,7 +140,7 @@ struct app_sinfo { struct app_stats_reply { uint8_t elem_count; - struct app_sinfo elem[0]; + struct app_sinfo elem[]; } __packed; struct qla_sa_update_frame { diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 073d06e88c58..0bb1d562f0bf 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -1706,7 +1706,7 @@ struct qla_flt_header { __le16 length; __le16 checksum; __le16 unused; - struct qla_flt_region region[0]; + struct qla_flt_region region[]; }; #define FLT_REGION_SIZE 16 diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h index 4e1764df0a73..860ec61b51b9 100644 --- a/drivers/scsi/qla4xxx/ql4_fw.h +++ b/drivers/scsi/qla4xxx/ql4_fw.h @@ -1028,7 +1028,7 @@ struct crash_record { uint8_t out_RISC_reg_dump[256]; /* 80 -17F */ uint8_t in_RISC_reg_dump[256]; /*180 -27F */ - uint8_t in_out_RISC_stack_dump[0]; /*280 - ??? */ + uint8_t in_out_RISC_stack_dump[]; /*280 - ??? */ }; struct conn_event_log_entry { diff --git a/drivers/staging/r8188eu/include/rtw_cmd.h b/drivers/staging/r8188eu/include/rtw_cmd.h index cf0945ae11c1..f8991a0493d0 100644 --- a/drivers/staging/r8188eu/include/rtw_cmd.h +++ b/drivers/staging/r8188eu/include/rtw_cmd.h @@ -73,7 +73,7 @@ struct c2h_evt_hdr { u8 id:4; u8 plen:4; u8 seq; - u8 payload[0]; + u8 payload[]; }; #define c2h_evt_exist(c2h_evt) ((c2h_evt)->id || (c2h_evt)->plen) @@ -662,25 +662,25 @@ struct getcurtxpwrlevel_rspi { struct setprobereqextraie_parm { unsigned char e_id; unsigned char ie_len; - unsigned char ie[0]; + unsigned char ie[]; }; struct setassocreqextraie_parm { unsigned char e_id; unsigned char ie_len; - unsigned char ie[0]; + unsigned char ie[]; }; struct setproberspextraie_parm { unsigned char e_id; unsigned char ie_len; - unsigned char ie[0]; + unsigned char ie[]; }; struct setassocrspextraie_parm { unsigned char e_id; unsigned char ie_len; - unsigned char ie[0]; + unsigned char ie[]; }; struct addBaReq_parm { diff --git a/drivers/staging/rtl8712/rtl871x_cmd.h b/drivers/staging/rtl8712/rtl871x_cmd.h index ddd69c4ae208..95e9ea5b2d98 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.h +++ b/drivers/staging/rtl8712/rtl871x_cmd.h @@ -657,25 +657,25 @@ struct setra_parm { struct setprobereqextraie_parm { unsigned char e_id; unsigned char ie_len; - unsigned char ie[0]; + unsigned char ie[]; }; struct setassocreqextraie_parm { unsigned char e_id; unsigned char ie_len; - unsigned char ie[0]; + unsigned char ie[]; }; struct setproberspextraie_parm { unsigned char e_id; unsigned char ie_len; - unsigned char ie[0]; + unsigned char ie[]; }; struct setassocrspextraie_parm { unsigned char e_id; unsigned char ie_len; - unsigned char ie[0]; + unsigned char ie[]; }; struct addBaReq_parm { diff --git a/drivers/staging/rtl8723bs/include/ieee80211.h b/drivers/staging/rtl8723bs/include/ieee80211.h index c11d7e2d2347..1e627dc0044d 100644 --- a/drivers/staging/rtl8723bs/include/ieee80211.h +++ b/drivers/staging/rtl8723bs/include/ieee80211.h @@ -204,7 +204,7 @@ struct ieee_param { struct ieee_param_ex { u32 cmd; u8 sta_addr[ETH_ALEN]; - u8 data[0]; + u8 data[]; }; struct sta_data { diff --git a/drivers/staging/rtl8723bs/include/rtw_cmd.h b/drivers/staging/rtl8723bs/include/rtw_cmd.h index 28d2d2732374..1bf030cbbbbe 100644 --- a/drivers/staging/rtl8723bs/include/rtw_cmd.h +++ b/drivers/staging/rtl8723bs/include/rtw_cmd.h @@ -94,7 +94,7 @@ struct c2h_evt_hdr { u8 id:4; u8 plen:4; u8 seq; - u8 payload[0]; + u8 payload[]; }; struct c2h_evt_hdr_88xx { diff --git a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h index 81db7fb76d6d..c93f2f3e87bb 100644 --- a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h +++ b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h @@ -45,7 +45,7 @@ struct vchiq_header { /* Size of message data. */ unsigned int size; - char data[0]; /* message */ + char data[]; /* message */ }; struct vchiq_element { diff --git a/drivers/visorbus/vbuschannel.h b/drivers/visorbus/vbuschannel.h index 4aaf6564eb9f..98711fb6d66e 100644 --- a/drivers/visorbus/vbuschannel.h +++ b/drivers/visorbus/vbuschannel.h @@ -89,7 +89,7 @@ struct visor_vbus_channel { struct visor_vbus_headerinfo hdr_info; struct visor_vbus_deviceinfo chp_info; struct visor_vbus_deviceinfo bus_info; - struct visor_vbus_deviceinfo dev_info[0]; + struct visor_vbus_deviceinfo dev_info[]; } __packed; #endif diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h index 298458404252..55758b9ec877 100644 --- a/fs/cifs/ntlmssp.h +++ b/fs/cifs/ntlmssp.h @@ -107,7 +107,7 @@ struct negotiate_message { SECURITY_BUFFER WorkstationName; /* RFC 1001 and ASCII */ struct ntlmssp_version Version; /* SECURITY_BUFFER */ - char DomainString[0]; + char DomainString[]; /* followed by WorkstationString */ } __packed; diff --git a/fs/ext4/fast_commit.h b/fs/ext4/fast_commit.h index 083ad1cb705a..07e8b734c4fd 100644 --- a/fs/ext4/fast_commit.h +++ b/fs/ext4/fast_commit.h @@ -55,13 +55,13 @@ struct ext4_fc_del_range { struct ext4_fc_dentry_info { __le32 fc_parent_ino; __le32 fc_ino; - __u8 fc_dname[0]; + __u8 fc_dname[]; }; /* Value structure for EXT4_FC_TAG_INODE and EXT4_FC_TAG_INODE_PARTIAL. */ struct ext4_fc_inode { __le32 fc_ino; - __u8 fc_raw_inode[0]; + __u8 fc_raw_inode[]; }; /* Value structure for tag EXT4_FC_TAG_TAIL. */ diff --git a/fs/ksmbd/ksmbd_netlink.h b/fs/ksmbd/ksmbd_netlink.h index 71bfb7de4472..ebe6ca08467a 100644 --- a/fs/ksmbd/ksmbd_netlink.h +++ b/fs/ksmbd/ksmbd_netlink.h @@ -241,7 +241,7 @@ struct ksmbd_rpc_command { struct ksmbd_spnego_authen_request { __u32 handle; __u16 spnego_blob_len; /* the length of spnego_blob */ - __u8 spnego_blob[0]; /* + __u8 spnego_blob[]; /* * the GSS token from SecurityBuffer of * SMB2 SESSION SETUP request */ diff --git a/fs/ksmbd/ntlmssp.h b/fs/ksmbd/ntlmssp.h index adaf4c0cbe8f..f13153c18b4e 100644 --- a/fs/ksmbd/ntlmssp.h +++ b/fs/ksmbd/ntlmssp.h @@ -95,7 +95,7 @@ struct security_buffer { struct target_info { __le16 Type; __le16 Length; - __u8 Content[0]; + __u8 Content[]; } __packed; struct negotiate_message { @@ -108,7 +108,7 @@ struct negotiate_message { * struct security_buffer for version info not present since we * do not set the version is present flag */ - char DomainString[0]; + char DomainString[]; /* followed by WorkstationString */ } __packed; @@ -140,7 +140,7 @@ struct authenticate_message { * struct security_buffer for version info not present since we * do not set the version is present flag */ - char UserString[0]; + char UserString[]; } __packed; struct ntlmv2_resp { diff --git a/fs/ksmbd/smb2pdu.h b/fs/ksmbd/smb2pdu.h index 725b800c29c8..d49468426576 100644 --- a/fs/ksmbd/smb2pdu.h +++ b/fs/ksmbd/smb2pdu.h @@ -759,7 +759,7 @@ struct smb2_file_rename_info { /* encoding of request for level 10 */ __u8 Reserved[7]; __u64 RootDirectory; /* MBZ for network operations (why says spec?) */ __le32 FileNameLength; - char FileName[0]; /* New name to be assigned */ + char FileName[]; /* New name to be assigned */ } __packed; /* level 10 Set */ struct smb2_file_link_info { /* encoding of request for level 11 */ @@ -768,7 +768,7 @@ struct smb2_file_link_info { /* encoding of request for level 11 */ __u8 Reserved[7]; __u64 RootDirectory; /* MBZ for network operations (why says spec?) */ __le32 FileNameLength; - char FileName[0]; /* Name to be assigned to new link */ + char FileName[]; /* Name to be assigned to new link */ } __packed; /* level 11 Set */ /* @@ -810,7 +810,7 @@ struct smb2_file_basic_info { /* data block encoding of response to level 18 */ struct smb2_file_alt_name_info { __le32 FileNameLength; - char FileName[0]; + char FileName[]; } __packed; struct smb2_file_stream_info { @@ -818,7 +818,7 @@ struct smb2_file_stream_info { __le32 StreamNameLength; __le64 StreamSize; __le64 StreamAllocationSize; - char StreamName[0]; + char StreamName[]; } __packed; struct smb2_file_eof_info { /* encoding of request for level 10 */ diff --git a/fs/ksmbd/transport_rdma.c b/fs/ksmbd/transport_rdma.c index 3c1ec1ac0b27..9976d39c6ed8 100644 --- a/fs/ksmbd/transport_rdma.c +++ b/fs/ksmbd/transport_rdma.c @@ -211,7 +211,7 @@ struct smb_direct_rdma_rw_msg { struct completion *completion; struct rdma_rw_ctx rw_ctx; struct sg_table sgt; - struct scatterlist sg_list[0]; + struct scatterlist sg_list[]; }; static inline int get_buf_page_count(void *buf, int size) diff --git a/fs/ksmbd/xattr.h b/fs/ksmbd/xattr.h index 8857c01093d9..16499ca5c82d 100644 --- a/fs/ksmbd/xattr.h +++ b/fs/ksmbd/xattr.h @@ -76,7 +76,7 @@ struct xattr_acl_entry { struct xattr_smb_acl { int count; int next; - struct xattr_acl_entry entries[0]; + struct xattr_acl_entry entries[]; }; /* 64bytes hash in xattr_ntacl is computed with sha256 */ diff --git a/fs/xfs/scrub/attr.h b/fs/xfs/scrub/attr.h index 1719e1c4da59..3590e10e3e62 100644 --- a/fs/xfs/scrub/attr.h +++ b/fs/xfs/scrub/attr.h @@ -24,7 +24,7 @@ struct xchk_xattr_buf { * space bitmap follows immediately after; and we have a third buffer * for storing intermediate bitmap results. */ - uint8_t buf[0]; + uint8_t buf[]; }; /* A place to store attribute values. */ diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h index 2c68a545ffa7..fd7feb5c7894 100644 --- a/include/asm-generic/tlb.h +++ b/include/asm-generic/tlb.h @@ -180,7 +180,7 @@ struct mmu_table_batch { struct rcu_head rcu; #endif unsigned int nr; - void *tables[0]; + void *tables[]; }; #define MAX_TABLE_BATCH \ @@ -227,7 +227,7 @@ struct mmu_gather_batch { struct mmu_gather_batch *next; unsigned int nr; unsigned int max; - struct page *pages[0]; + struct page *pages[]; }; #define MAX_GATHER_BATCH \ diff --git a/include/linux/greybus/greybus_manifest.h b/include/linux/greybus/greybus_manifest.h index 6e62fe478712..bef9eb2093e9 100644 --- a/include/linux/greybus/greybus_manifest.h +++ b/include/linux/greybus/greybus_manifest.h @@ -100,7 +100,7 @@ enum { struct greybus_descriptor_string { __u8 length; __u8 id; - __u8 string[0]; + __u8 string[]; } __packed; /* @@ -175,7 +175,7 @@ struct greybus_manifest_header { struct greybus_manifest { struct greybus_manifest_header header; - struct greybus_descriptor descriptors[0]; + struct greybus_descriptor descriptors[]; } __packed; #endif /* __GREYBUS_MANIFEST_H */ diff --git a/include/linux/greybus/hd.h b/include/linux/greybus/hd.h index d3faf0c1a569..718e2857054e 100644 --- a/include/linux/greybus/hd.h +++ b/include/linux/greybus/hd.h @@ -58,7 +58,7 @@ struct gb_host_device { struct gb_svc *svc; /* Private data for the host driver */ - unsigned long hd_priv[0] __aligned(sizeof(s64)); + unsigned long hd_priv[] __aligned(sizeof(s64)); }; #define to_gb_host_device(d) container_of(d, struct gb_host_device, dev) diff --git a/include/linux/greybus/module.h b/include/linux/greybus/module.h index 47b839af145d..3efe2133acfd 100644 --- a/include/linux/greybus/module.h +++ b/include/linux/greybus/module.h @@ -23,7 +23,7 @@ struct gb_module { bool disconnected; - struct gb_interface *interfaces[0]; + struct gb_interface *interfaces[]; }; #define to_gb_module(d) container_of(d, struct gb_module, dev) diff --git a/include/linux/i3c/ccc.h b/include/linux/i3c/ccc.h index 73b0982cc519..ad59a4ae60d1 100644 --- a/include/linux/i3c/ccc.h +++ b/include/linux/i3c/ccc.h @@ -132,7 +132,7 @@ struct i3c_ccc_dev_desc { struct i3c_ccc_defslvs { u8 count; struct i3c_ccc_dev_desc master; - struct i3c_ccc_dev_desc slaves[0]; + struct i3c_ccc_dev_desc slaves[]; } __packed; /** @@ -240,7 +240,7 @@ struct i3c_ccc_bridged_slave_desc { */ struct i3c_ccc_setbrgtgt { u8 count; - struct i3c_ccc_bridged_slave_desc bslaves[0]; + struct i3c_ccc_bridged_slave_desc bslaves[]; } __packed; /** @@ -318,7 +318,7 @@ enum i3c_ccc_setxtime_subcmd { */ struct i3c_ccc_setxtime { u8 subcmd; - u8 data[0]; + u8 data[]; } __packed; #define I3C_CCC_GETXTIME_SYNC_MODE BIT(0) diff --git a/include/linux/platform_data/brcmfmac.h b/include/linux/platform_data/brcmfmac.h index 2b5676ff35be..f922a192fe58 100644 --- a/include/linux/platform_data/brcmfmac.h +++ b/include/linux/platform_data/brcmfmac.h @@ -178,7 +178,7 @@ struct brcmfmac_platform_data { void (*power_off)(void); char *fw_alternative_path; int device_count; - struct brcmfmac_pd_device devices[0]; + struct brcmfmac_pd_device devices[]; }; diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h index 271bd87bff0a..728735aed980 100644 --- a/include/linux/platform_data/cros_ec_commands.h +++ b/include/linux/platform_data/cros_ec_commands.h @@ -5644,7 +5644,7 @@ struct ec_response_typec_discovery { uint8_t svid_count; /* Number of SVIDs partner sent */ uint16_t reserved; uint32_t discovery_vdo[6]; /* Max VDOs allowed after VDM header is 6 */ - struct svid_mode_info svids[0]; + struct svid_mode_info svids[]; } __ec_align1; /* USB Type-C commands for AP-controlled device policy. */ diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 107b25deae68..9607ec289fd0 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -696,7 +696,7 @@ struct mgmt_cp_set_blocked_keys { #define MGMT_READ_CONTROLLER_CAP_SIZE 0 struct mgmt_rp_read_controller_cap { __le16 cap_len; - __u8 cap[0]; + __u8 cap[]; } __packed; #define MGMT_OP_READ_EXP_FEATURES_INFO 0x0049 diff --git a/include/net/ioam6.h b/include/net/ioam6.h index 3f45ba37a2c6..781d2d8b2f29 100644 --- a/include/net/ioam6.h +++ b/include/net/ioam6.h @@ -35,7 +35,7 @@ struct ioam6_schema { int len; __be32 hdr; - u8 data[0]; + u8 data[]; }; struct ioam6_pernet_data { diff --git a/include/sound/sof/channel_map.h b/include/sound/sof/channel_map.h index fd3a30fcf756..d363f0ca6979 100644 --- a/include/sound/sof/channel_map.h +++ b/include/sound/sof/channel_map.h @@ -39,7 +39,7 @@ struct sof_ipc_channel_map { uint32_t ext_id; uint32_t ch_mask; uint32_t reserved; - int32_t ch_coeffs[0]; + int32_t ch_coeffs[]; } __packed; /** @@ -55,7 +55,7 @@ struct sof_ipc_stream_map { struct sof_ipc_cmd_hdr hdr; uint32_t num_ch_map; uint32_t reserved[3]; - struct sof_ipc_channel_map ch_map[0]; + struct sof_ipc_channel_map ch_map[]; } __packed; #endif /* __IPC_CHANNEL_MAP_H__ */ diff --git a/scripts/dtc/libfdt/fdt.h b/scripts/dtc/libfdt/fdt.h index f2e68807f277..0c91aa7f67b5 100644 --- a/scripts/dtc/libfdt/fdt.h +++ b/scripts/dtc/libfdt/fdt.h @@ -35,14 +35,14 @@ struct fdt_reserve_entry { struct fdt_node_header { fdt32_t tag; - char name[0]; + char name[]; }; struct fdt_property { fdt32_t tag; fdt32_t len; fdt32_t nameoff; - char data[0]; + char data[]; }; #endif /* !__ASSEMBLY */ diff --git a/sound/soc/intel/atom/sst-mfld-dsp.h b/sound/soc/intel/atom/sst-mfld-dsp.h index 8d9e29b16e57..c8f0816edb53 100644 --- a/sound/soc/intel/atom/sst-mfld-dsp.h +++ b/sound/soc/intel/atom/sst-mfld-dsp.h @@ -427,7 +427,7 @@ struct snd_sst_drop_response { struct snd_sst_async_msg { u32 msg_id; /* Async msg id */ - u32 payload[0]; + u32 payload[]; }; struct snd_sst_async_err_msg { @@ -514,7 +514,7 @@ struct snd_sst_bytes_v2 { u8 pipe_id; u8 rsvd; u16 len; - char bytes[0]; + char bytes[]; }; #define MAX_VTSV_FILES 2 diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index 22963634fbea..a5bccf2fcd88 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -164,7 +164,7 @@ struct skl_base_cfg_ext { u8 reserved[8]; u32 priv_param_length; /* Input pin formats followed by output ones. */ - struct skl_pin_format pins_fmt[0]; + struct skl_pin_format pins_fmt[]; } __packed; struct skl_algo_cfg { diff --git a/tools/lib/perf/include/perf/event.h b/tools/lib/perf/include/perf/event.h index 75ee385fb078..e7758707cadd 100644 --- a/tools/lib/perf/include/perf/event.h +++ b/tools/lib/perf/include/perf/event.h @@ -240,7 +240,7 @@ struct id_index_entry { struct perf_record_id_index { struct perf_event_header header; __u64 nr; - struct id_index_entry entries[0]; + struct id_index_entry entries[]; }; struct perf_record_auxtrace_info { -- cgit v1.2.3 From 868653f421cd37e8ec3880da19f0aac93f5c46cc Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 13 Feb 2022 01:18:37 +0900 Subject: kconfig: add fflush() before ferror() check As David Laight pointed out, there is not much point in calling ferror() unless you call fflush() first. Reported-by: David Laight Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index d3c3a61308ad..94dcec2cc803 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -979,6 +979,7 @@ static int conf_write_autoconf_cmd(const char *autoconf_name) fprintf(out, "\n$(deps_config): ;\n"); + fflush(out); ret = ferror(out); /* error check for all fprintf() calls */ fclose(out); if (ret) @@ -1097,6 +1098,7 @@ static int __conf_write_autoconf(const char *filename, if ((sym->flags & SYMBOL_WRITE) && sym->name) print_symbol(file, sym); + fflush(file); /* check possible errors in conf_write_heading() and print_symbol() */ ret = ferror(file); fclose(file); -- cgit v1.2.3 From a7d4f58e99dd3f6067606115ce147c15c17b6e93 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 14 Feb 2022 12:19:18 +0900 Subject: kconfig: fix missing '# end of' for empty menu Currently, "# end of ..." is inserted when the menu goes back to its parent. Hence, an empty menu: menu "Foo" endmenu ... ends up with unbalanced menu comments, like this: # # Foo # Let's close the menu comments properly: # # Foo # # end of Foo Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 94dcec2cc803..901835a56e89 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -903,19 +903,20 @@ next: menu = menu->list; continue; } - if (menu->next) + +end_check: + if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu && + menu->prompt->type == P_MENU) { + fprintf(out, "# end of %s\n", menu_get_prompt(menu)); + need_newline = true; + } + + if (menu->next) { menu = menu->next; - else while ((menu = menu->parent)) { - if (!menu->sym && menu_is_visible(menu) && - menu != &rootmenu) { - str = menu_get_prompt(menu); - fprintf(out, "# end of %s\n", str); - need_newline = true; - } - if (menu->next) { - menu = menu->next; - break; - } + } else { + menu = menu->parent; + if (menu) + goto end_check; } } fclose(out); -- cgit v1.2.3 From d4c858643263cfde13f7d937eaff95c2ed87cdf1 Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Tue, 1 Feb 2022 09:32:57 +0800 Subject: kallsyms: ignore all local labels prefixed by '.L' The llvm compiler can generate lots of local labels ('.LBB', '.Ltmpxxx', '.L__unnamed_xx', etc.). These symbols usually are useless for debugging. And they might overlap with handwritten symbols. Before this change, a dumpstack shows a local symbol for epc: [ 0.040341][ T0] Hardware name: riscv-virtio,qemu (DT) [ 0.040376][ T0] epc : .LBB6_14+0x22/0x6a [ 0.040452][ T0] ra : restore_all+0x12/0x6e The simple solution is that we can ignore all local labels prefixed by '.L'. For handwritten symbols which need to be preserved should drop the '.L' prefix. After this change, the C defined symbol is shown so we can locate the problematical code immediately: [ 0.035795][ T0] Hardware name: riscv-virtio,qemu (DT) [ 0.036332][ T0] epc : trace_hardirqs_on+0x54/0x13c [ 0.036567][ T0] ra : restore_all+0x12/0x6e Signed-off-by: Changbin Du Reviewed-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Signed-off-by: Masahiro Yamada --- 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 54ad86d13784..8caabddf817c 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -108,7 +108,7 @@ static bool is_ignored_symbol(const char *name, char type) /* Symbol names that begin with the following are ignored.*/ static const char * const ignored_prefixes[] = { "$", /* local symbols for ARM, MIPS, etc. */ - ".LASANPC", /* s390 kasan local symbols */ + ".L", /* local labels, .LBB,.Ltmpxxx,.L__unnamed_xx,.LASANPC, etc. */ "__crc_", /* modversions */ "__efistub_", /* arm64 EFI stub namespace */ "__kvm_nvhe_", /* arm64 non-VHE KVM namespace */ -- cgit v1.2.3 From b4f72786429cc57383ff41e02407726313ca178d Mon Sep 17 00:00:00 2001 From: Kui-Feng Lee Date: Thu, 17 Feb 2022 09:54:27 -0800 Subject: scripts/pahole-flags.sh: Parse DWARF and generate BTF with multithreading. Pass a "-j" argument to pahole if possible to reduce the time of generating BTF info. Since v1.22, pahole can parse DWARF and generate BTF with multithreading to speed up the conversion. It will reduce the overall build time of the kernel for seconds. v3 fixes whitespaces and improves the commit description. v2 checks the version of pahole to enable multithreading only if possible. [v2] https://lore.kernel.org/bpf/20220216193431.2691015-1-kuifeng@fb.com/ [v1] https://lore.kernel.org/bpf/20220216004616.2079689-1-kuifeng@fb.com/ Signed-off-by: Kui-Feng Lee Signed-off-by: Andrii Nakryiko Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20220217175427.649713-1-kuifeng@fb.com --- scripts/pahole-flags.sh | 3 +++ 1 file changed, 3 insertions(+) (limited to 'scripts') diff --git a/scripts/pahole-flags.sh b/scripts/pahole-flags.sh index c293941612e7..0d99ef17e4a5 100755 --- a/scripts/pahole-flags.sh +++ b/scripts/pahole-flags.sh @@ -16,5 +16,8 @@ fi if [ "${pahole_ver}" -ge "121" ]; then extra_paholeopt="${extra_paholeopt} --btf_gen_floats" fi +if [ "${pahole_ver}" -ge "122" ]; then + extra_paholeopt="${extra_paholeopt} -j" +fi echo ${extra_paholeopt} -- cgit v1.2.3 From a5cdaea525c32e7def563ba07d9fef9bc6edffab Mon Sep 17 00:00:00 2001 From: Tomasz Warniełło Date: Fri, 18 Feb 2022 19:16:18 +0100 Subject: scripts: kernel-doc: Add the basic POD sections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The NAME section provides the doc title, while SYNOPSIS contains the basic syntax and usage description, which will be printed in the help document and in the error output produced on wrong script usage. The rationale is to give users simple and succinct enlightment, at the same time structuring the script internally for the maintainers. In the synopsis, Rst-only options are grouped around rst, and the rest is arranged as in the OPTIONS subsections (yet to be translated into POD, check at the end of the series). The third of the basic sections, DESCRIPTION, is added separately. Signed-off-by: Tomasz Warniełło Tested-by: Randy Dunlap Acked-by: Randy Dunlap Disliked-by: Akira Yokosawa Link: https://lore.kernel.org/r/20220218181628.1411551-2-tomasz.warniello@gmail.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 3106b7536b89..c8fbf1d3d5aa 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -16,6 +16,31 @@ use strict; ## This software falls under the GNU General Public License. ## ## Please read the COPYING file for more information ## +=head1 NAME + +kernel-doc - Print formatted kernel documentation to stdout + +=head1 SYNOPSIS + + kernel-doc [-h] [-v] [-Werror] + [ -man | + -rst [-sphinx-version VERSION] [-enable-lineno] | + -none + ] + [ + -export | + -internal | + [-function NAME] ... | + [-nosymbol NAME] ... + ] + [-no-doc-sections] + [-export-file FILE] ... + FILE ... + +Run `kernel-doc -h` for details. + +=cut + # 18/01/2001 - Cleanups # Functions prototyped as foo(void) same as foo() # Stop eval'ing where we don't need to. -- cgit v1.2.3 From 43caf1a6823dc7c156cf38a6c71881c1e90cd3c2 Mon Sep 17 00:00:00 2001 From: Tomasz Warniełło Date: Fri, 18 Feb 2022 19:16:19 +0100 Subject: scripts: kernel-doc: Relink argument parsing error handling to pod2usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The former usage function is substituted, although not as the -h and -help parameter handler yet. Purpose: Use Pod::Usage to handle documentation printing in an integrated way. Signed-off-by: Tomasz Warniełło Tested-by: Randy Dunlap Acked-by: Randy Dunlap Disliked-by: Akira Yokosawa Link: https://lore.kernel.org/r/20220218181628.1411551-3-tomasz.warniello@gmail.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index c8fbf1d3d5aa..e7f7251771bb 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -16,6 +16,8 @@ use strict; ## This software falls under the GNU General Public License. ## ## Please read the COPYING file for more information ## +use Pod::Usage qw/pod2usage/; + =head1 NAME kernel-doc - Print formatted kernel documentation to stdout @@ -298,7 +300,13 @@ my $blankline_rst = "\n"; # read arguments if ($#ARGV == -1) { - usage(); + pod2usage( + -message => "No arguments!\n", + -exitval => 1, + -verbose => 99, + -sections => 'SYNOPSIS', + -output => \*STDERR, + ); } my $kernelversion; @@ -518,8 +526,14 @@ while ($ARGV[0] =~ m/^--?(.*)/) { die "Sphinx version should either major.minor or major.minor.patch format\n"; } } else { - # Unknown argument - usage(); + # Unknown argument + pod2usage( + -message => "Argument unknown!\n", + -exitval => 1, + -verbose => 99, + -sections => 'SYNOPSIS', + -output => \*STDERR, + ); } } -- cgit v1.2.3 From f1583922bf9383ce0079dfdded959dfc5585dc5b Mon Sep 17 00:00:00 2001 From: Tomasz Warniełło Date: Fri, 18 Feb 2022 19:16:20 +0100 Subject: scripts: kernel-doc: Translate the DESCRIPTION section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Transition the description section into POD. This is one of the standard documentation sections. This adjustment makes the section available for POD and makes it look better. Notes: - an article addition - paragraphing correction Signed-off-by: Tomasz Warniełło Tested-by: Randy Dunlap Acked-by: Randy Dunlap Disliked-by: Akira Yokosawa Link: https://lore.kernel.org/r/20220218181628.1411551-4-tomasz.warniello@gmail.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index e7f7251771bb..e4203f13fa93 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -41,6 +41,15 @@ kernel-doc - Print formatted kernel documentation to stdout Run `kernel-doc -h` for details. +=head1 DESCRIPTION + +Read C language source or header FILEs, extract embedded documentation comments, +and print formatted documentation to standard output. + +The documentation comments are identified by the "/**" opening comment mark. + +See Documentation/doc-guide/kernel-doc.rst for the documentation comment syntax. + =cut # 18/01/2001 - Cleanups @@ -72,12 +81,6 @@ sub usage { my $message = <<"EOF"; Usage: $0 [OPTION ...] FILE ... -Read C language source or header FILEs, extract embedded documentation comments, -and print formatted documentation to standard output. - -The documentation comments are identified by "/**" opening comment mark. See -Documentation/doc-guide/kernel-doc.rst for the documentation comment syntax. - Output format selection (mutually exclusive): -man Output troff manual page format. This is the default. -rst Output reStructuredText format. -- cgit v1.2.3 From 2875f78708219feadf0956dcf9e936ec25fb7a8b Mon Sep 17 00:00:00 2001 From: Tomasz Warniełło Date: Fri, 18 Feb 2022 19:16:21 +0100 Subject: scripts: kernel-doc: Translate the "Output format selection" subsection of OPTIONS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Another step in the direction of a uniform POD documentation, which will make users happier. Options land at the end of the script, not to clutter the file top. The default output format is corrected to rst. That's what it is now. A POD delimiting comment is added to the script head, which improves the script logical structure. Signed-off-by: Tomasz Warniełło Tested-by: Randy Dunlap Acked-by: Randy Dunlap Disliked-by: Akira Yokosawa Link: https://lore.kernel.org/r/20220218181628.1411551-5-tomasz.warniello@gmail.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index e4203f13fa93..18eca172c4b5 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -52,6 +52,8 @@ See Documentation/doc-guide/kernel-doc.rst for the documentation comment syntax. =cut +# more perldoc at the end of the file + # 18/01/2001 - Cleanups # Functions prototyped as foo(void) same as foo() # Stop eval'ing where we don't need to. @@ -81,11 +83,6 @@ sub usage { my $message = <<"EOF"; Usage: $0 [OPTION ...] FILE ... -Output format selection (mutually exclusive): - -man Output troff manual page format. This is the default. - -rst Output reStructuredText format. - -none Do not output documentation, only warnings. - Output format selection modifier (affects only ReST output): -sphinx-version Use the ReST C domain dialect compatible with an @@ -2563,3 +2560,27 @@ if ($Werror && $warnings) { } else { exit($output_mode eq "none" ? 0 : $errors) } + +__END__ + +=head1 OPTIONS + +=head2 Output format selection (mutually exclusive): + +=over 8 + +=item -man + +Output troff manual page format. + +=item -rst + +Output reStructuredText format. This is the default. + +=item -none + +Do not output documentation, only warnings. + +=back + +=cut -- cgit v1.2.3 From dd803b04b0a0af16e43c2af1a3e67d7ce8e1f899 Mon Sep 17 00:00:00 2001 From: Tomasz Warniełło Date: Fri, 18 Feb 2022 19:16:22 +0100 Subject: scripts: kernel-doc: Translate the "Output format selection modifier" subsection of OPTIONS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aim: unified POD, user more happy This section is renamed to "Output format modifiers" to make it simple. To make it even more simple, a subsection is added: "reStructuredText only". Other notes: - paragraphing correction - article correction Signed-off-by: Tomasz Warniełło Tested-by: Randy Dunlap Acked-by: Randy Dunlap Disliked-by: Akira Yokosawa Link: https://lore.kernel.org/r/20220218181628.1411551-6-tomasz.warniello@gmail.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 18eca172c4b5..b926faa16b00 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -83,13 +83,6 @@ sub usage { my $message = <<"EOF"; Usage: $0 [OPTION ...] FILE ... -Output format selection modifier (affects only ReST output): - - -sphinx-version Use the ReST C domain dialect compatible with an - specific Sphinx Version. - If not specified, kernel-doc will auto-detect using - the sphinx-build version found on PATH. - Output selection (mutually exclusive): -export Only output documentation for symbols that have been exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() @@ -2583,4 +2576,19 @@ Do not output documentation, only warnings. =back +=head2 Output format modifiers + +=head3 reStructuredText only + +=over 8 + +=item -sphinx-version VERSION + +Use the ReST C domain dialect compatible with a specific Sphinx Version. + +If not specified, kernel-doc will auto-detect using the sphinx-build version +found on PATH. + +=back + =cut -- cgit v1.2.3 From 9c77f108f43ae08e560f54c817d4aeb4857dc783 Mon Sep 17 00:00:00 2001 From: Tomasz Warniełło Date: Fri, 18 Feb 2022 19:16:23 +0100 Subject: scripts: kernel-doc: Translate the "Output selection" subsection of OPTIONS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aim: unified POD, user more satisfied, script better structured The plurals in -function and -nosymbol are corrected to singulars. That's how the script works now. I think this describes the syntax better. The plurar suggests multiple FILE arguments might be possible. So this seems more coherent. Other notes: - paragraphing correction - article correction Signed-off-by: Tomasz Warniełło Tested-by: Randy Dunlap Acked-by: Randy Dunlap Disliked-by: Akira Yokosawa Link: https://lore.kernel.org/r/20220218181628.1411551-7-tomasz.warniello@gmail.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index b926faa16b00..e49cdb307a35 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -83,19 +83,6 @@ sub usage { my $message = <<"EOF"; Usage: $0 [OPTION ...] FILE ... -Output selection (mutually exclusive): - -export Only output documentation for symbols that have been - exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() - in any input FILE or -export-file FILE. - -internal Only output documentation for symbols that have NOT been - exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() - in any input FILE or -export-file FILE. - -function NAME Only output documentation for the given function(s) - or DOC: section title(s). All other functions and DOC: - sections are ignored. May be specified multiple times. - -nosymbol NAME Exclude the specified symbols from the output - documentation. May be specified multiple times. - Output selection modifiers: -no-doc-sections Do not output DOC: sections. -enable-lineno Enable output of #define LINENO lines. Only works with @@ -2591,4 +2578,33 @@ found on PATH. =back +=head2 Output selection (mutually exclusive): + +=over 8 + +=item -export + +Only output documentation for the symbols that have been exported using +EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() in any input FILE or -export-file FILE. + +=item -internal + +Only output documentation for the symbols that have NOT been exported using +EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() in any input FILE or -export-file FILE. + +=item -function NAME + +Only output documentation for the given function or DOC: section title. +All other functions and DOC: sections are ignored. + +May be specified multiple times. + +=item -nosymbol NAME + +Exclude the specified symbol from the output documentation. + +May be specified multiple times. + +=back + =cut -- cgit v1.2.3 From c15de5a19a2881205f6f893869584c99cbe4fae4 Mon Sep 17 00:00:00 2001 From: Tomasz Warniełło Date: Fri, 18 Feb 2022 19:16:24 +0100 Subject: scripts: kernel-doc: Translate the "Output selection modifiers" subsection of OPTIONS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aim: unified POD, user more satisfied, script better structured A subsection "reStructuredText only" is added for -enable-lineno. Other notes: - paragraphing correction Signed-off-by: Tomasz Warniełło Tested-by: Randy Dunlap Acked-by: Randy Dunlap Disliked-by: Akira Yokosawa Link: https://lore.kernel.org/r/20220218181628.1411551-8-tomasz.warniello@gmail.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index e49cdb307a35..210e7e3b501b 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -83,14 +83,6 @@ sub usage { my $message = <<"EOF"; Usage: $0 [OPTION ...] FILE ... -Output selection modifiers: - -no-doc-sections Do not output DOC: sections. - -enable-lineno Enable output of #define LINENO lines. Only works with - reStructuredText format. - -export-file FILE Specify an additional FILE in which to look for - EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL(). To be used with - -export or -internal. May be specified multiple times. - Other parameters: -v Verbose output, more warnings and other information. -h Print this help. @@ -2607,4 +2599,33 @@ May be specified multiple times. =back +=head2 Output selection modifiers: + +=over 8 + +=item -no-doc-sections + +Do not output DOC: sections. + +=item -export-file FILE + +Specify an additional FILE in which to look for EXPORT_SYMBOL() and +EXPORT_SYMBOL_GPL(). + +To be used with -export or -internal. + +May be specified multiple times. + +=back + +=head3 reStructuredText only + +=over 8 + +=item -enable-lineno + +Enable output of #define LINENO lines. + +=back + =cut -- cgit v1.2.3 From 834cf6b9039e6f6ebd73cc4da51cc8bc802ca777 Mon Sep 17 00:00:00 2001 From: Tomasz Warniełło Date: Fri, 18 Feb 2022 19:16:25 +0100 Subject: scripts: kernel-doc: Translate the "Other parameters" subsection of OPTIONS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aim: unified POD, user more satisfied, script better structured Notes: - The -help token is added. - The entries are sorted alphbetically. Signed-off-by: Tomasz Warniełło Tested-by: Randy Dunlap Acked-by: Randy Dunlap Disliked-by: Akira Yokosawa Link: https://lore.kernel.org/r/20220218181628.1411551-9-tomasz.warniello@gmail.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 210e7e3b501b..4a26a74318e6 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -83,11 +83,6 @@ sub usage { my $message = <<"EOF"; Usage: $0 [OPTION ...] FILE ... -Other parameters: - -v Verbose output, more warnings and other information. - -h Print this help. - -Werror Treat warnings as errors. - EOF print $message; exit 1; @@ -2628,4 +2623,22 @@ Enable output of #define LINENO lines. =back +=head2 Other parameters: + +=over 8 + +=item -h, -help + +Print this help. + +=item -v + +Verbose output, more warnings and other information. + +=item -Werror + +Treat warnings as errors. + +=back + =cut -- cgit v1.2.3 From 252b47da9fd9eeebbdaed448aea71010261d7dc4 Mon Sep 17 00:00:00 2001 From: Tomasz Warniełło Date: Fri, 18 Feb 2022 19:16:26 +0100 Subject: scripts: kernel-doc: Replace the usage function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aim: unified POD, user more satisfied, script better structured You can see the results with: $ scripts/kernel-doc -help Signed-off-by: Tomasz Warniełło Tested-by: Randy Dunlap Acked-by: Randy Dunlap Disliked-by: Akira Yokosawa Link: https://lore.kernel.org/r/20220218181628.1411551-10-tomasz.warniello@gmail.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 4a26a74318e6..d7ca4877eeda 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -79,15 +79,6 @@ See Documentation/doc-guide/kernel-doc.rst for the documentation comment syntax. # 25/07/2012 - Added support for HTML5 # -- Dan Luedtke -sub usage { - my $message = <<"EOF"; -Usage: $0 [OPTION ...] FILE ... - -EOF - print $message; - exit 1; -} - # # format of comments. # In the following table, (...)? signifies optional structure. @@ -468,7 +459,7 @@ while ($ARGV[0] =~ m/^--?(.*)/) { } elsif ($cmd eq "Werror") { $Werror = 1; } elsif (($cmd eq "h") || ($cmd eq "help")) { - usage(); + pod2usage(-exitval => 0, -verbose => 2); } elsif ($cmd eq 'no-doc-sections') { $no_doc_sections = 1; } elsif ($cmd eq 'enable-lineno') { -- cgit v1.2.3 From 258092a89085ed9536da00f27d8ddbe083c9ea0a Mon Sep 17 00:00:00 2001 From: Tomasz Warniełło Date: Fri, 18 Feb 2022 19:16:27 +0100 Subject: scripts: kernel-doc: Drop obsolete comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What for? To improve the script maintainability. 1. License As stated by Jonathan Corbet in the reply to my version 1, the SPDX line is enough. 2. The to-do list comment As suggested by Jonathan Corbet in reply to my version 3, this section doesn't need to be transitioned. And so it is removed for clarity. 3. The historical changelog comments As suggested by Jonathan Corbet in a reply to v3, this section can go. I wanted to keep it, but since it doesn't contain copyright notices, let's just have it clean and simple. 4. The "format of comments" comment block As suggested by Jani Nikula in a reply to my first version of this transformation, Documentation/doc-guide/kernel-doc.rst can serve as the information hub for comment formatting. The section DESCRIPTION already points there, so the original comment block can just be removed. Suggested-by: Jonathan Corbet Suggested-by: Jani Nikula Signed-off-by: Tomasz Warniełło Tested-by: Randy Dunlap Acked-by: Randy Dunlap Disliked-by: Akira Yokosawa Link: https://lore.kernel.org/r/20220218181628.1411551-11-tomasz.warniello@gmail.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 143 ----------------------------------------------------- 1 file changed, 143 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index d7ca4877eeda..a5a397e22ea7 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -12,9 +12,6 @@ use strict; ## ## ## #define enhancements by Armin Kuster ## ## Copyright (c) 2000 MontaVista Software, Inc. ## -## ## -## This software falls under the GNU General Public License. ## -## Please read the COPYING file for more information ## use Pod::Usage qw/pod2usage/; @@ -54,146 +51,6 @@ See Documentation/doc-guide/kernel-doc.rst for the documentation comment syntax. # more perldoc at the end of the file -# 18/01/2001 - Cleanups -# Functions prototyped as foo(void) same as foo() -# Stop eval'ing where we don't need to. -# -- huggie@earth.li - -# 27/06/2001 - Allowed whitespace after initial "/**" and -# allowed comments before function declarations. -# -- Christian Kreibich - -# Still to do: -# - add perldoc documentation -# - Look more closely at some of the scarier bits :) - -# 26/05/2001 - Support for separate source and object trees. -# Return error code. -# Keith Owens - -# 23/09/2001 - Added support for typedefs, structs, enums and unions -# Support for Context section; can be terminated using empty line -# Small fixes (like spaces vs. \s in regex) -# -- Tim Jansen - -# 25/07/2012 - Added support for HTML5 -# -- Dan Luedtke - -# -# format of comments. -# In the following table, (...)? signifies optional structure. -# (...)* signifies 0 or more structure elements -# /** -# * function_name(:)? (- short description)? -# (* @parameterx: (description of parameter x)?)* -# (* a blank line)? -# * (Description:)? (Description of function)? -# * (section header: (section description)? )* -# (*)?*/ -# -# So .. the trivial example would be: -# -# /** -# * my_function -# */ -# -# If the Description: header tag is omitted, then there must be a blank line -# after the last parameter specification. -# e.g. -# /** -# * my_function - does my stuff -# * @my_arg: its mine damnit -# * -# * Does my stuff explained. -# */ -# -# or, could also use: -# /** -# * my_function - does my stuff -# * @my_arg: its mine damnit -# * Description: Does my stuff explained. -# */ -# etc. -# -# Besides functions you can also write documentation for structs, unions, -# enums and typedefs. Instead of the function name you must write the name -# of the declaration; the struct/union/enum/typedef must always precede -# the name. Nesting of declarations is not supported. -# Use the argument mechanism to document members or constants. -# e.g. -# /** -# * struct my_struct - short description -# * @a: first member -# * @b: second member -# * -# * Longer description -# */ -# struct my_struct { -# int a; -# int b; -# /* private: */ -# int c; -# }; -# -# All descriptions can be multiline, except the short function description. -# -# For really longs structs, you can also describe arguments inside the -# body of the struct. -# eg. -# /** -# * struct my_struct - short description -# * @a: first member -# * @b: second member -# * -# * Longer description -# */ -# struct my_struct { -# int a; -# int b; -# /** -# * @c: This is longer description of C -# * -# * You can use paragraphs to describe arguments -# * using this method. -# */ -# int c; -# }; -# -# This should be use only for struct/enum members. -# -# You can also add additional sections. When documenting kernel functions you -# should document the "Context:" of the function, e.g. whether the functions -# can be called form interrupts. Unlike other sections you can end it with an -# empty line. -# A non-void function should have a "Return:" section describing the return -# value(s). -# Example-sections should contain the string EXAMPLE so that they are marked -# appropriately in DocBook. -# -# Example: -# /** -# * user_function - function that can only be called in user context -# * @a: some argument -# * Context: !in_interrupt() -# * -# * Some description -# * Example: -# * user_function(22); -# */ -# ... -# -# -# All descriptive text is further processed, scanning for the following special -# patterns, which are highlighted appropriately. -# -# 'funcname()' - function -# '$ENVVAR' - environmental variable -# '&struct_name' - name of a structure (up to two words including 'struct') -# '&struct_name.member' - name of a structure member -# '@parameter' - name of a parameter -# '%CONST' - name of a constant. -# '``LITERAL``' - literal string without any spaces on it. - ## init lots of data my $errors = 0; -- cgit v1.2.3 From 2b306ecaf57b2b5004dcb671a46ef24a1c369db2 Mon Sep 17 00:00:00 2001 From: Tomasz Warniełło Date: Fri, 18 Feb 2022 19:16:28 +0100 Subject: scripts: kernel-doc: Refresh the copyright lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I wanted to clean up these lines, but in the end decided not to touch the old ones and just add my own about POD. I'll leave the cleanup for lawyers. Signed-off-by: Tomasz Warniełło Tested-by: Randy Dunlap Acked-by: Randy Dunlap Disliked-by: Akira Yokosawa Link: https://lore.kernel.org/r/20220218181628.1411551-12-tomasz.warniello@gmail.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index a5a397e22ea7..f06f68f3c3d9 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -12,6 +12,8 @@ use strict; ## ## ## #define enhancements by Armin Kuster ## ## Copyright (c) 2000 MontaVista Software, Inc. ## +# +# Copyright (C) 2022 Tomasz Warniełło (POD) use Pod::Usage qw/pod2usage/; -- cgit v1.2.3 From e334f873eb4e1638dd0b45200d2d8838a13b0cac Mon Sep 17 00:00:00 2001 From: Akira Yokosawa Date: Thu, 24 Feb 2022 22:02:46 +0900 Subject: docs: scripts/kernel-doc: Detect absence of FILE arg Currently, when there is no FILE argument following a switch such as -man, -rst, or -none, kernel-doc exits with a warning from perl (long msg folded): Use of uninitialized value $ARGV[0] in pattern match (m//) at ./scripts/kernel-doc line 438. , which is unhelpful. Improve the behavior by adding a check at the bottom of parsing loop. If the argument is absent, display help text and exit with the code of 1 (via usage()). Signed-off-by: Akira Yokosawa Cc: Randy Dunlap Link: https://lore.kernel.org/r/7b136049-a3ba-0eb5-8717-364d773ff914@gmail.com [jc: reworked to fix conflict with pod patches] Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index f06f68f3c3d9..9c084a2ba3b0 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -343,14 +343,23 @@ while ($ARGV[0] =~ m/^--?(.*)/) { die "Sphinx version should either major.minor or major.minor.patch format\n"; } } else { - # Unknown argument - pod2usage( - -message => "Argument unknown!\n", - -exitval => 1, - -verbose => 99, - -sections => 'SYNOPSIS', - -output => \*STDERR, - ); + # Unknown argument + pod2usage( + -message => "Argument unknown!\n", + -exitval => 1, + -verbose => 99, + -sections => 'SYNOPSIS', + -output => \*STDERR, + ); + } + if ($#ARGV < 0){ + pod2usage( + -message => "FILE argument missing\n", + -exitval => 1, + -verbose => 99, + -sections => 'SYNOPSIS', + -output => \*STDERR, + ); } } -- cgit v1.2.3 From 8e4296c286ed7a3b69e619d5069493bdcc9a2b25 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Tue, 1 Feb 2022 12:14:13 -0600 Subject: of: unittest: add program to process EXPECT messages If unittest detects a problem it will print a warning or error message to the console. Unittest also triggers warning and error messages from other kernel code as a result of intentionally bad unittest data. This has led to confusion as to whether the triggered messages are an expected result of a test or whether there is a real problem that is independent of unittest. EXPECT messages were added to unittest to report each triggered message that is expected, resulting in verbose console output. scripts/dtc/of_unittest is a new program that processes the EXPECT messages to determine whether the triggered messages occurred and also removes the excess verbosity of the EXPECT messages. More information is available from 'scripts/dtc/of_unittest_expect --help'. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220201181413.2719955-1-frowand.list@gmail.com --- Documentation/devicetree/of_unittest.rst | 27 +- scripts/dtc/of_unittest_expect | 408 +++++++++++++++++++++++++++++++ 2 files changed, 432 insertions(+), 3 deletions(-) create mode 100755 scripts/dtc/of_unittest_expect (limited to 'scripts') diff --git a/Documentation/devicetree/of_unittest.rst b/Documentation/devicetree/of_unittest.rst index 2afe41a37148..8864b52d1195 100644 --- a/Documentation/devicetree/of_unittest.rst +++ b/Documentation/devicetree/of_unittest.rst @@ -24,7 +24,28 @@ from the unflattened device tree data structure. This interface is used by most of the device drivers in various use cases. -2. Test-data +2. Verbose Output (EXPECT) +========================== + +If unittest detects a problem it will print a warning or error message to +the console. Unittest also triggers warning and error messages from other +kernel code as a result of intentionally bad unittest data. This has led +to confusion as to whether the triggered messages are an expected result +of a test or whether there is a real problem that is independent of unittest. + +'EXPECT \ : text' (begin) and 'EXPECT / : text' (end) messages have been +added to unittest to report that a warning or error is expected. The +begin is printed before triggering the warning or error, and the end is +printed after triggering the warning or error. + +The EXPECT messages result in very noisy console messages that are difficult +to read. The script scripts/dtc/of_unittest_expect was created to filter +this verbosity and highlight mismatches between triggered warnings and +errors vs expected warnings and errors. More information is available +from 'scripts/dtc/of_unittest_expect --help'. + + +3. Test-data ============ The Device Tree Source file (drivers/of/unittest-data/testcases.dts) contains @@ -56,7 +77,7 @@ The assembly file is compiled into an object file (testcases.dtb.o), and is linked into the kernel image. -2.1. Adding the test data +3.1. Adding the test data ------------------------- Un-flattened device tree structure: @@ -191,7 +212,7 @@ properties are updated to the live tree's node by calling the function update_node_properties(). -2.2. Removing the test data +3.2. Removing the test data --------------------------- Once the test case execution is complete, selftest_data_remove is called in diff --git a/scripts/dtc/of_unittest_expect b/scripts/dtc/of_unittest_expect new file mode 100755 index 000000000000..96b12d9ea606 --- /dev/null +++ b/scripts/dtc/of_unittest_expect @@ -0,0 +1,408 @@ +#!/usr/bin/perl +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright 2020, 2022 Sony Corporation +# +# Author: Frank Rowand + +# This program is meant to be an aid to reading the verbose output of +# on the console log that results from executing the Linux kernel +# devicetree unittest (drivers/of/unitest.c). + +$VUFX = "220201a"; + +use strict 'refs'; +use strict subs; + +use Getopt::Long; +use Text::Wrap; + +# strip off everything before final "/" +(undef, $script_name) = split(/^.*\//, $0); + +# following /usr/include/sysexits.h +$EX_OK=0; +$EX_USAGE=64; + + +#______________________________________________________________________________ +sub compare { + my ($expect, $got) = @_; + my $expect_next; + my $expect_next_lit; + my $got_next; + my $type; + + while ($expect) { + + ($expect_next, $type) = split(/<>/, $type); + $expect =~ s/^.*?>>//; # '?' is non-greedy, minimal match + + # literal, ignore all metacharacters when used in a regex + $expect_next_lit = quotemeta($expect_next); + + $got_next = $got; + $got_next =~ s/^($expect_next_lit).*/\1/; + $got =~ s/^$expect_next_lit//; + + if ($expect_next ne $got_next) { + return 0; + } + + if ($type eq "int") { + if ($got =~ /^[+-]*[0-9]+/) { + $got =~ s/^[+-]*[0-9]+//; + } else { + return 0; + } + } elsif ($type eq "hex") { + if ($got =~ /^(0x)*[0-9a-f]+/) { + $got =~ s/^(0x)*[0-9a-f]+//; + } else { + return 0; + } + } elsif ($type eq "") { + if ($expect_next ne $got_next) { + return 0; + } else { + return 1; + } + } else { + $internal_err++; + print "** ERROR: special pattern not recognized: <<$type>>, CONSOLE_LOG line: $.\n"; + return 0; + } + + } + + # should not get here + $internal_err++; + print "** ERROR: $script_name internal error, at end of compare(), CONSOLE_LOG line: $.\n"; + + return 0; +} + + +#______________________________________________________________________________ +sub usage { + +# ***** when editing, be careful to not put tabs in the string printed: + + print STDERR +" +usage: + + $script_name CONSOLE_LOG + + -h print program usage + --help print program usage + --hide-expect suppress output of EXPECTed lines + --line-num report line number of CONSOLE_LOG + --no-expect-stats do not report EXPECT statistics + --no-strip-ts do not strip leading console timestamps + --verbose do not suppress EXPECT begin and end lines + --version print program version and exit + + + Process a console log for EXPECTed test related messages to either + highlight expected devicetree unittest related messages or suppress + the messages. Leading console timestamps will be stripped. + + Various unittests may trigger kernel messages from outside the + unittest code. The unittest annotates that it expects the message + to occur with an 'EXPECT \\ : text' (begin) before triggering the + message, and an 'EXPECT / : text' (end) after triggering the message. + + If an expected message does not occur, that will be reported. + + For each expected message, the 'EXPECT \\ : text' (begin) and + 'EXPECT / : text' (end), 'text' will contain the message text. + + If 'EXPECT \\' (begin) and 'EXPECT /' (end) lines do not contain + matching 'text', that will be reported. + + If EXPECT lines are nested, 'EXPECT /' (end) lines must be in the + reverse order of the corresponding 'EXPECT \\' (begin) lines. + + 'EXPECT \\ : text' (begin) and 'EXPECT / : text' (end) lines can + contain special patterns in 'text': + + <> matches: [+-]*[0-9]+ + <> matches: (0x)*[0-9a-f]+ + + 'EXPECT \\' (begin) and 'EXPECT /' (end) lines are suppressed. + + A prefix is added to every line of output: + + 'ok ' Line matches an enclosing EXPECT begin/end pair + + '** ' Line reports $script_name warning or error + + '-> ' Line reports start or end of the unittests + + '>> ' Line reports a unittest test FAIL + + ' ' Lines that are not otherwise prefixed + + Issues detected in CONSOLE_LOG are reported to STDOUT, not to STDERR. + + Known Issues: + + --line-num causes the CONSOLE_LOG line number to be printed in 4 columns. + If CONSOLE_LOG contains more than 9999 lines then more columns will be + used to report the line number for lines greater than 9999 (eg for + lines 10000 - 99999, 5 columns will be used). +"; + + return {}; +} + +#______________________________________________________________________________ +#______________________________________________________________________________ + +if (!GetOptions( + "h" => \$help, + "help" => \$help, + "hide-expect" => \$hide_expect, + "line-num" => \$print_line_num, + "no-expect-stats" => \$no_expect_stats, + "no-strip-ts" => \$no_strip_ts, + "verbose" => \$verbose, + "version" => \$version, + )) { + print STDERR "\n"; + print STDERR "ERROR processing command line options\n"; + print STDERR "\n"; + print STDERR "For help, type '$script_name --help'\n"; + print STDERR "\n"; + + exit $EX_OK; +} + + +if ($no_strip_ts) { + $strip_ts = 1; + $no_strip_ts = 0; +} else { + $strip_ts = 0; + $no_strip_ts = 1; +} + + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +if ($help){ + + &usage; + + exit $EX_OK; +} + + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +if ($version) { + print STDERR "\n$script_name $VUFX\n\n"; + print STDERR "\n"; + + exit $EX_OK; +} + + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +if ($#ARGV != 0) { + + # Limit input files to exactly one. + # + # 'while ($line = ) {' in the code below supports multiple file + # names on the command line, but the EXPECT statistics are reported + # once for all input - it is not an expected use case to generate one + # set of statistics for multiple input files. + + print STDERR "\n"; + print STDERR "Required arguments: CONSOLE_LOG\n"; + print STDERR "\n"; + + exit $EX_USAGE; +} + + +#______________________________________________________________________________ + +# Patterns to match 'EXPECT \ : ' (begin) and 'EXPECT / : ' (end) +# +# $exp_* are used as regex match patterns, +# so '\\\\' in $exp_begin matches a single '\' +# quotemeta() does not do the right thing in this case +# +# $pr_fmt is the prefix that unittest prints for every message + +$pr_fmt = "### dt-test ### "; +$exp_begin = "${pr_fmt}EXPECT \\\\ : "; +$exp_end = "${pr_fmt}EXPECT / : "; + + +$line_num = ""; +$timestamp = ""; + +LINE: +while ($line = ) { + + chomp $line; + + $prefix = " "; ## 2 characters + + + if ($strip_ts) { + + $timestamp = $line; + + if ($timestamp =~ /^\[\s*[0-9]+\.[0-9]*\] /) { + ($timestamp, $null) = split(/]/, $line); + $timestamp = $timestamp . "] "; + + } else { + $timestamp = ""; + } + } + + $line =~ s/^\[\s*[0-9]+\.[0-9]*\] //; + + + # ----- find EXPECT begin + + if ($line =~ /^\s*$exp_begin/) { + $data = $line; + $data =~ s/^\s*$exp_begin//; + push @begin, $data; + + if ($verbose) { + if ($print_line_num) { + $line_num = sprintf("%4s ", $.); + } + printf "%s %s%s%s\n", $prefix, $line_num, $timestamp, $line; + } + + next LINE; + } + + + # ----- find EXPECT end + + if ($line =~ /^\s*$exp_end/) { + $data = $line; + $data =~ s/^\s*$exp_end//; + + if ($verbose) { + if ($print_line_num) { + $line_num = sprintf("%4s ", $.); + } + printf "%s %s%s%s\n", $prefix, $line_num, $timestamp, $line; + } + + $found = 0; + $no_begin = 0; + if (@found_or_begin > 0) { + $begin = pop @found_or_begin; + if (compare($data, $begin)) { + $found = 1; + } + } elsif (@begin > 0) { + $begin = pop @begin; + } else { + $no_begin = 1; + } + + if ($no_begin) { + + $expect_missing_begin++; + print "** ERROR: EXPECT end without any EXPECT begin:\n"; + print " end ---> $line\n"; + + } elsif (! $found) { + + if ($print_line_num) { + $line_num = sprintf("%4s ", $.); + } + + $expect_not_found++; + printf "** %s%s$script_name WARNING - not found ---> %s\n", + $line_num, $timestamp, $data; + + } elsif (! compare($data, $begin)) { + + $expect_missing_end++; + print "** ERROR: EXPECT end does not match EXPECT begin:\n"; + print " begin -> $begin\n"; + print " end ---> $line\n"; + + } else { + + $expect_found++; + + } + + next LINE; + } + + + # ----- not an EXPECT line + + if (($line =~ /^${pr_fmt}start of unittest - you will see error messages$/) || + ($line =~ /^${pr_fmt}end of unittest - [0-9]+ passed, [0-9]+ failed$/ ) ) { + $prefix = "->"; # 2 characters + } elsif ($line =~ /^${pr_fmt}FAIL /) { + $unittest_fail++; + $prefix = ">>"; # 2 characters + } + + $found = 0; + foreach $begin (@begin) { + if (compare($begin, $line)) { + $found = 1; + last; + } + } + + if ($found) { + $begin = shift @begin; + while (! compare($begin, $line)) { + push @found_or_begin, $begin; + $begin = shift @begin; + } + push @found_or_begin, $line; + + if ($hide_expect) { + $suppress_line = 1; + next LINE; + } + $prefix = "ok"; # 2 characters + } + + + if ($print_line_num) { + $line_num = sprintf("%4s ", $.); + } + + printf "%s %s%s%s\n", $prefix, $line_num, $timestamp, $line; +} + +if (! $no_expect_stats) { + print "\n"; + print "** EXPECT statistics:\n"; + print "**\n"; + printf "** EXPECT found : %4i\n", $expect_found; + printf "** EXPECT not found : %4i\n", $expect_not_found; + printf "** missing EXPECT begin : %4i\n", $expect_missing_begin; + printf "** missing EXPECT end : %4i\n", $expect_missing_end; + printf "** unittest FAIL : %4i\n", $unittest_fail; + printf "** internal error : %4i\n", $internal_err; +} + +if (@begin) { + print "** ERROR: EXPECT begin without any EXPECT end:\n"; + print " This list may be misleading.\n"; + foreach $begin (@begin) { + print " begin ---> $begin\n"; + } +} -- cgit v1.2.3 From aec499c75cf8e0b599be4d559e6922b613085f8f Mon Sep 17 00:00:00 2001 From: Alan Kao Date: Wed, 2 Mar 2022 15:42:45 +0800 Subject: nds32: Remove the architecture The nds32 architecture, also known as AndeStar V3, is a custom 32-bit RISC target designed by Andes Technologies. Support was added to the kernel in 2016 as the replacement RISC-V based V5 processors were already announced, and maintained by (current or former) Andes employees. As explained by Alan Kao, new customers are now all using RISC-V, and all known nds32 users are already on longterm stable kernels provided by Andes, with no development work going into mainline support any more. While the port is still in a reasonably good shape, it only gets worse over time without active maintainers, so it seems best to remove it before it becomes unusable. As always, if it turns out that there are mainline users after all, and they volunteer to maintain the port in the future, the removal can be reverted. Link: https://lore.kernel.org/linux-mm/YhdWNLUhk+x9RAzU@yamatobi.andestech.com/ Link: https://lore.kernel.org/lkml/20220302065213.82702-1-alankao@andestech.com/ Link: https://www.andestech.com/en/products-solutions/andestar-architecture/ Signed-off-by: Alan Kao [arnd: rewrite changelog to provide more background] Signed-off-by: Arnd Bergmann --- .../interrupt-controller/andestech,ativic32.txt | 19 - .../devicetree/bindings/nds32/andestech-boards | 40 - Documentation/devicetree/bindings/nds32/atl2c.txt | 28 - Documentation/devicetree/bindings/nds32/cpus.txt | 38 - .../devicetree/bindings/perf/nds32v3-pmu.txt | 17 - .../bindings/timer/andestech,atcpit100-timer.txt | 33 - .../features/core/cBPF-JIT/arch-support.txt | 1 - .../features/core/eBPF-JIT/arch-support.txt | 1 - .../core/generic-idle-thread/arch-support.txt | 1 - .../features/core/jump-labels/arch-support.txt | 1 - .../core/thread-info-in-task/arch-support.txt | 1 - .../features/core/tracehook/arch-support.txt | 1 - .../features/debug/KASAN/arch-support.txt | 1 - .../debug/debug-vm-pgtable/arch-support.txt | 1 - .../debug/gcov-profile-all/arch-support.txt | 1 - Documentation/features/debug/kcov/arch-support.txt | 1 - Documentation/features/debug/kgdb/arch-support.txt | 1 - .../features/debug/kmemleak/arch-support.txt | 1 - .../debug/kprobes-on-ftrace/arch-support.txt | 1 - .../features/debug/kprobes/arch-support.txt | 1 - .../features/debug/kretprobes/arch-support.txt | 1 - .../features/debug/optprobes/arch-support.txt | 1 - .../features/debug/stackprotector/arch-support.txt | 1 - .../features/debug/uprobes/arch-support.txt | 1 - .../debug/user-ret-profiler/arch-support.txt | 1 - .../features/io/dma-contiguous/arch-support.txt | 1 - .../locking/cmpxchg-local/arch-support.txt | 1 - .../features/locking/lockdep/arch-support.txt | 1 - .../locking/queued-rwlocks/arch-support.txt | 1 - .../locking/queued-spinlocks/arch-support.txt | 1 - .../features/perf/kprobes-event/arch-support.txt | 1 - .../features/perf/perf-regs/arch-support.txt | 1 - .../features/perf/perf-stackdump/arch-support.txt | 1 - .../sched/membarrier-sync-core/arch-support.txt | 1 - .../features/sched/numa-balancing/arch-support.txt | 1 - .../seccomp/seccomp-filter/arch-support.txt | 1 - .../time/arch-tick-broadcast/arch-support.txt | 1 - .../features/time/clockevents/arch-support.txt | 1 - .../time/context-tracking/arch-support.txt | 1 - .../features/time/irq-time-acct/arch-support.txt | 1 - .../features/time/virt-cpuacct/arch-support.txt | 1 - .../features/vm/ELF-ASLR/arch-support.txt | 1 - .../features/vm/PG_uncached/arch-support.txt | 1 - Documentation/features/vm/THP/arch-support.txt | 1 - Documentation/features/vm/TLB/arch-support.txt | 1 - .../features/vm/huge-vmap/arch-support.txt | 1 - .../features/vm/ioremap_prot/arch-support.txt | 1 - .../features/vm/pte_special/arch-support.txt | 1 - MAINTAINERS | 12 - arch/nds32/Kbuild | 4 - arch/nds32/Kconfig | 101 -- arch/nds32/Kconfig.cpu | 218 --- arch/nds32/Kconfig.debug | 2 - arch/nds32/Makefile | 63 - arch/nds32/boot/.gitignore | 2 - arch/nds32/boot/Makefile | 16 - arch/nds32/boot/dts/Makefile | 2 - arch/nds32/boot/dts/ae3xx.dts | 90 -- arch/nds32/configs/defconfig | 104 -- arch/nds32/include/asm/Kbuild | 8 - arch/nds32/include/asm/assembler.h | 39 - arch/nds32/include/asm/barrier.h | 15 - arch/nds32/include/asm/bitfield.h | 985 ------------- arch/nds32/include/asm/cache.h | 12 - arch/nds32/include/asm/cache_info.h | 13 - arch/nds32/include/asm/cacheflush.h | 53 - arch/nds32/include/asm/current.h | 12 - arch/nds32/include/asm/delay.h | 39 - arch/nds32/include/asm/elf.h | 180 --- arch/nds32/include/asm/fixmap.h | 29 - arch/nds32/include/asm/fpu.h | 126 -- arch/nds32/include/asm/fpuemu.h | 44 - arch/nds32/include/asm/ftrace.h | 46 - arch/nds32/include/asm/futex.h | 101 -- arch/nds32/include/asm/highmem.h | 65 - arch/nds32/include/asm/io.h | 84 -- arch/nds32/include/asm/irqflags.h | 41 - arch/nds32/include/asm/l2_cache.h | 137 -- arch/nds32/include/asm/linkage.h | 11 - arch/nds32/include/asm/memory.h | 91 -- arch/nds32/include/asm/mmu.h | 12 - arch/nds32/include/asm/mmu_context.h | 62 - arch/nds32/include/asm/nds32.h | 82 -- arch/nds32/include/asm/nds32_fpu_inst.h | 109 -- arch/nds32/include/asm/page.h | 64 - arch/nds32/include/asm/perf_event.h | 16 - arch/nds32/include/asm/pgalloc.h | 62 - arch/nds32/include/asm/pgtable.h | 377 ----- arch/nds32/include/asm/pmu.h | 386 ----- arch/nds32/include/asm/proc-fns.h | 44 - arch/nds32/include/asm/processor.h | 104 -- arch/nds32/include/asm/ptrace.h | 77 - arch/nds32/include/asm/sfp-machine.h | 158 --- arch/nds32/include/asm/shmparam.h | 19 - arch/nds32/include/asm/stacktrace.h | 39 - arch/nds32/include/asm/string.h | 17 - arch/nds32/include/asm/suspend.h | 11 - arch/nds32/include/asm/swab.h | 35 - arch/nds32/include/asm/syscall.h | 142 -- arch/nds32/include/asm/syscalls.h | 14 - arch/nds32/include/asm/thread_info.h | 72 - arch/nds32/include/asm/tlb.h | 11 - arch/nds32/include/asm/tlbflush.h | 46 - arch/nds32/include/asm/uaccess.h | 282 ---- arch/nds32/include/asm/unistd.h | 6 - arch/nds32/include/asm/vdso.h | 24 - arch/nds32/include/asm/vdso_datapage.h | 37 - arch/nds32/include/asm/vdso_timer_info.h | 14 - arch/nds32/include/asm/vermagic.h | 9 - arch/nds32/include/asm/vmalloc.h | 4 - arch/nds32/include/uapi/asm/Kbuild | 2 - arch/nds32/include/uapi/asm/auxvec.h | 19 - arch/nds32/include/uapi/asm/byteorder.h | 13 - arch/nds32/include/uapi/asm/cachectl.h | 14 - arch/nds32/include/uapi/asm/fp_udfiex_crtl.h | 16 - arch/nds32/include/uapi/asm/param.h | 11 - arch/nds32/include/uapi/asm/ptrace.h | 25 - arch/nds32/include/uapi/asm/sigcontext.h | 84 -- arch/nds32/include/uapi/asm/unistd.h | 16 - arch/nds32/kernel/.gitignore | 2 - arch/nds32/kernel/Makefile | 33 - arch/nds32/kernel/asm-offsets.c | 28 - arch/nds32/kernel/atl2c.c | 65 - arch/nds32/kernel/cacheinfo.c | 49 - arch/nds32/kernel/devtree.c | 19 - arch/nds32/kernel/dma.c | 82 -- arch/nds32/kernel/ex-entry.S | 177 --- arch/nds32/kernel/ex-exit.S | 193 --- arch/nds32/kernel/ex-scall.S | 100 -- arch/nds32/kernel/fpu.c | 266 ---- arch/nds32/kernel/ftrace.c | 278 ---- arch/nds32/kernel/head.S | 197 --- arch/nds32/kernel/irq.c | 9 - arch/nds32/kernel/module.c | 278 ---- arch/nds32/kernel/nds32_ksyms.c | 25 - arch/nds32/kernel/perf_event_cpu.c | 1500 -------------------- arch/nds32/kernel/pm.c | 80 -- arch/nds32/kernel/process.c | 256 ---- arch/nds32/kernel/ptrace.c | 118 -- arch/nds32/kernel/setup.c | 369 ----- arch/nds32/kernel/signal.c | 384 ----- arch/nds32/kernel/sleep.S | 131 -- arch/nds32/kernel/stacktrace.c | 53 - arch/nds32/kernel/sys_nds32.c | 84 -- arch/nds32/kernel/syscall_table.c | 17 - arch/nds32/kernel/time.c | 11 - arch/nds32/kernel/traps.c | 354 ----- arch/nds32/kernel/vdso.c | 231 --- arch/nds32/kernel/vdso/.gitignore | 2 - arch/nds32/kernel/vdso/Makefile | 79 -- arch/nds32/kernel/vdso/datapage.S | 21 - arch/nds32/kernel/vdso/gen_vdso_offsets.sh | 15 - arch/nds32/kernel/vdso/gettimeofday.c | 269 ---- arch/nds32/kernel/vdso/note.S | 11 - arch/nds32/kernel/vdso/sigreturn.S | 19 - arch/nds32/kernel/vdso/vdso.S | 18 - arch/nds32/kernel/vdso/vdso.lds.S | 75 - arch/nds32/kernel/vmlinux.lds.S | 70 - arch/nds32/lib/Makefile | 4 - arch/nds32/lib/clear_user.S | 42 - arch/nds32/lib/copy_from_user.S | 45 - arch/nds32/lib/copy_page.S | 40 - arch/nds32/lib/copy_template.S | 69 - arch/nds32/lib/copy_to_user.S | 45 - arch/nds32/lib/memcpy.S | 30 - arch/nds32/lib/memmove.S | 70 - arch/nds32/lib/memset.S | 33 - arch/nds32/lib/memzero.S | 18 - arch/nds32/math-emu/Makefile | 10 - arch/nds32/math-emu/faddd.c | 24 - arch/nds32/math-emu/fadds.c | 24 - arch/nds32/math-emu/fcmpd.c | 24 - arch/nds32/math-emu/fcmps.c | 24 - arch/nds32/math-emu/fd2s.c | 22 - arch/nds32/math-emu/fd2si.c | 30 - arch/nds32/math-emu/fd2siz.c | 30 - arch/nds32/math-emu/fd2ui.c | 30 - arch/nds32/math-emu/fd2uiz.c | 30 - arch/nds32/math-emu/fdivd.c | 27 - arch/nds32/math-emu/fdivs.c | 26 - arch/nds32/math-emu/fmuld.c | 23 - arch/nds32/math-emu/fmuls.c | 23 - arch/nds32/math-emu/fnegd.c | 21 - arch/nds32/math-emu/fnegs.c | 21 - arch/nds32/math-emu/fpuemu.c | 406 ------ arch/nds32/math-emu/fs2d.c | 23 - arch/nds32/math-emu/fs2si.c | 29 - arch/nds32/math-emu/fs2siz.c | 29 - arch/nds32/math-emu/fs2ui.c | 29 - arch/nds32/math-emu/fs2uiz.c | 30 - arch/nds32/math-emu/fsi2d.c | 22 - arch/nds32/math-emu/fsi2s.c | 22 - arch/nds32/math-emu/fsqrtd.c | 21 - arch/nds32/math-emu/fsqrts.c | 21 - arch/nds32/math-emu/fsubd.c | 27 - arch/nds32/math-emu/fsubs.c | 27 - arch/nds32/math-emu/fui2d.c | 22 - arch/nds32/math-emu/fui2s.c | 22 - arch/nds32/mm/Makefile | 10 - arch/nds32/mm/alignment.c | 575 -------- arch/nds32/mm/cacheflush.c | 338 ----- arch/nds32/mm/extable.c | 16 - arch/nds32/mm/fault.c | 396 ------ arch/nds32/mm/init.c | 263 ---- arch/nds32/mm/mm-nds32.c | 96 -- arch/nds32/mm/mmap.c | 73 - arch/nds32/mm/proc.c | 536 ------- arch/nds32/mm/tlb.c | 50 - drivers/clocksource/Kconfig | 9 - drivers/clocksource/Makefile | 1 - drivers/clocksource/timer-atcpit100.c | 266 ---- drivers/irqchip/Makefile | 1 - drivers/irqchip/irq-ativic32.c | 156 -- drivers/net/ethernet/faraday/Kconfig | 12 +- drivers/video/console/Kconfig | 2 +- scripts/recordmcount.pl | 3 - tools/include/asm/barrier.h | 2 - tools/perf/arch/nds32/Build | 1 - tools/perf/arch/nds32/util/Build | 1 - tools/perf/arch/nds32/util/header.c | 29 - tools/testing/selftests/vDSO/vdso_config.h | 4 - 221 files changed, 6 insertions(+), 15814 deletions(-) delete mode 100644 Documentation/devicetree/bindings/interrupt-controller/andestech,ativic32.txt delete mode 100644 Documentation/devicetree/bindings/nds32/andestech-boards delete mode 100644 Documentation/devicetree/bindings/nds32/atl2c.txt delete mode 100644 Documentation/devicetree/bindings/nds32/cpus.txt delete mode 100644 Documentation/devicetree/bindings/perf/nds32v3-pmu.txt delete mode 100644 Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt delete mode 100644 arch/nds32/Kbuild delete mode 100644 arch/nds32/Kconfig delete mode 100644 arch/nds32/Kconfig.cpu delete mode 100644 arch/nds32/Kconfig.debug delete mode 100644 arch/nds32/Makefile delete mode 100644 arch/nds32/boot/.gitignore delete mode 100644 arch/nds32/boot/Makefile delete mode 100644 arch/nds32/boot/dts/Makefile delete mode 100644 arch/nds32/boot/dts/ae3xx.dts delete mode 100644 arch/nds32/configs/defconfig delete mode 100644 arch/nds32/include/asm/Kbuild delete mode 100644 arch/nds32/include/asm/assembler.h delete mode 100644 arch/nds32/include/asm/barrier.h delete mode 100644 arch/nds32/include/asm/bitfield.h delete mode 100644 arch/nds32/include/asm/cache.h delete mode 100644 arch/nds32/include/asm/cache_info.h delete mode 100644 arch/nds32/include/asm/cacheflush.h delete mode 100644 arch/nds32/include/asm/current.h delete mode 100644 arch/nds32/include/asm/delay.h delete mode 100644 arch/nds32/include/asm/elf.h delete mode 100644 arch/nds32/include/asm/fixmap.h delete mode 100644 arch/nds32/include/asm/fpu.h delete mode 100644 arch/nds32/include/asm/fpuemu.h delete mode 100644 arch/nds32/include/asm/ftrace.h delete mode 100644 arch/nds32/include/asm/futex.h delete mode 100644 arch/nds32/include/asm/highmem.h delete mode 100644 arch/nds32/include/asm/io.h delete mode 100644 arch/nds32/include/asm/irqflags.h delete mode 100644 arch/nds32/include/asm/l2_cache.h delete mode 100644 arch/nds32/include/asm/linkage.h delete mode 100644 arch/nds32/include/asm/memory.h delete mode 100644 arch/nds32/include/asm/mmu.h delete mode 100644 arch/nds32/include/asm/mmu_context.h delete mode 100644 arch/nds32/include/asm/nds32.h delete mode 100644 arch/nds32/include/asm/nds32_fpu_inst.h delete mode 100644 arch/nds32/include/asm/page.h delete mode 100644 arch/nds32/include/asm/perf_event.h delete mode 100644 arch/nds32/include/asm/pgalloc.h delete mode 100644 arch/nds32/include/asm/pgtable.h delete mode 100644 arch/nds32/include/asm/pmu.h delete mode 100644 arch/nds32/include/asm/proc-fns.h delete mode 100644 arch/nds32/include/asm/processor.h delete mode 100644 arch/nds32/include/asm/ptrace.h delete mode 100644 arch/nds32/include/asm/sfp-machine.h delete mode 100644 arch/nds32/include/asm/shmparam.h delete mode 100644 arch/nds32/include/asm/stacktrace.h delete mode 100644 arch/nds32/include/asm/string.h delete mode 100644 arch/nds32/include/asm/suspend.h delete mode 100644 arch/nds32/include/asm/swab.h delete mode 100644 arch/nds32/include/asm/syscall.h delete mode 100644 arch/nds32/include/asm/syscalls.h delete mode 100644 arch/nds32/include/asm/thread_info.h delete mode 100644 arch/nds32/include/asm/tlb.h delete mode 100644 arch/nds32/include/asm/tlbflush.h delete mode 100644 arch/nds32/include/asm/uaccess.h delete mode 100644 arch/nds32/include/asm/unistd.h delete mode 100644 arch/nds32/include/asm/vdso.h delete mode 100644 arch/nds32/include/asm/vdso_datapage.h delete mode 100644 arch/nds32/include/asm/vdso_timer_info.h delete mode 100644 arch/nds32/include/asm/vermagic.h delete mode 100644 arch/nds32/include/asm/vmalloc.h delete mode 100644 arch/nds32/include/uapi/asm/Kbuild delete mode 100644 arch/nds32/include/uapi/asm/auxvec.h delete mode 100644 arch/nds32/include/uapi/asm/byteorder.h delete mode 100644 arch/nds32/include/uapi/asm/cachectl.h delete mode 100644 arch/nds32/include/uapi/asm/fp_udfiex_crtl.h delete mode 100644 arch/nds32/include/uapi/asm/param.h delete mode 100644 arch/nds32/include/uapi/asm/ptrace.h delete mode 100644 arch/nds32/include/uapi/asm/sigcontext.h delete mode 100644 arch/nds32/include/uapi/asm/unistd.h delete mode 100644 arch/nds32/kernel/.gitignore delete mode 100644 arch/nds32/kernel/Makefile delete mode 100644 arch/nds32/kernel/asm-offsets.c delete mode 100644 arch/nds32/kernel/atl2c.c delete mode 100644 arch/nds32/kernel/cacheinfo.c delete mode 100644 arch/nds32/kernel/devtree.c delete mode 100644 arch/nds32/kernel/dma.c delete mode 100644 arch/nds32/kernel/ex-entry.S delete mode 100644 arch/nds32/kernel/ex-exit.S delete mode 100644 arch/nds32/kernel/ex-scall.S delete mode 100644 arch/nds32/kernel/fpu.c delete mode 100644 arch/nds32/kernel/ftrace.c delete mode 100644 arch/nds32/kernel/head.S delete mode 100644 arch/nds32/kernel/irq.c delete mode 100644 arch/nds32/kernel/module.c delete mode 100644 arch/nds32/kernel/nds32_ksyms.c delete mode 100644 arch/nds32/kernel/perf_event_cpu.c delete mode 100644 arch/nds32/kernel/pm.c delete mode 100644 arch/nds32/kernel/process.c delete mode 100644 arch/nds32/kernel/ptrace.c delete mode 100644 arch/nds32/kernel/setup.c delete mode 100644 arch/nds32/kernel/signal.c delete mode 100644 arch/nds32/kernel/sleep.S delete mode 100644 arch/nds32/kernel/stacktrace.c delete mode 100644 arch/nds32/kernel/sys_nds32.c delete mode 100644 arch/nds32/kernel/syscall_table.c delete mode 100644 arch/nds32/kernel/time.c delete mode 100644 arch/nds32/kernel/traps.c delete mode 100644 arch/nds32/kernel/vdso.c delete mode 100644 arch/nds32/kernel/vdso/.gitignore delete mode 100644 arch/nds32/kernel/vdso/Makefile delete mode 100644 arch/nds32/kernel/vdso/datapage.S delete mode 100755 arch/nds32/kernel/vdso/gen_vdso_offsets.sh delete mode 100644 arch/nds32/kernel/vdso/gettimeofday.c delete mode 100644 arch/nds32/kernel/vdso/note.S delete mode 100644 arch/nds32/kernel/vdso/sigreturn.S delete mode 100644 arch/nds32/kernel/vdso/vdso.S delete mode 100644 arch/nds32/kernel/vdso/vdso.lds.S delete mode 100644 arch/nds32/kernel/vmlinux.lds.S delete mode 100644 arch/nds32/lib/Makefile delete mode 100644 arch/nds32/lib/clear_user.S delete mode 100644 arch/nds32/lib/copy_from_user.S delete mode 100644 arch/nds32/lib/copy_page.S delete mode 100644 arch/nds32/lib/copy_template.S delete mode 100644 arch/nds32/lib/copy_to_user.S delete mode 100644 arch/nds32/lib/memcpy.S delete mode 100644 arch/nds32/lib/memmove.S delete mode 100644 arch/nds32/lib/memset.S delete mode 100644 arch/nds32/lib/memzero.S delete mode 100644 arch/nds32/math-emu/Makefile delete mode 100644 arch/nds32/math-emu/faddd.c delete mode 100644 arch/nds32/math-emu/fadds.c delete mode 100644 arch/nds32/math-emu/fcmpd.c delete mode 100644 arch/nds32/math-emu/fcmps.c delete mode 100644 arch/nds32/math-emu/fd2s.c delete mode 100644 arch/nds32/math-emu/fd2si.c delete mode 100644 arch/nds32/math-emu/fd2siz.c delete mode 100644 arch/nds32/math-emu/fd2ui.c delete mode 100644 arch/nds32/math-emu/fd2uiz.c delete mode 100644 arch/nds32/math-emu/fdivd.c delete mode 100644 arch/nds32/math-emu/fdivs.c delete mode 100644 arch/nds32/math-emu/fmuld.c delete mode 100644 arch/nds32/math-emu/fmuls.c delete mode 100644 arch/nds32/math-emu/fnegd.c delete mode 100644 arch/nds32/math-emu/fnegs.c delete mode 100644 arch/nds32/math-emu/fpuemu.c delete mode 100644 arch/nds32/math-emu/fs2d.c delete mode 100644 arch/nds32/math-emu/fs2si.c delete mode 100644 arch/nds32/math-emu/fs2siz.c delete mode 100644 arch/nds32/math-emu/fs2ui.c delete mode 100644 arch/nds32/math-emu/fs2uiz.c delete mode 100644 arch/nds32/math-emu/fsi2d.c delete mode 100644 arch/nds32/math-emu/fsi2s.c delete mode 100644 arch/nds32/math-emu/fsqrtd.c delete mode 100644 arch/nds32/math-emu/fsqrts.c delete mode 100644 arch/nds32/math-emu/fsubd.c delete mode 100644 arch/nds32/math-emu/fsubs.c delete mode 100644 arch/nds32/math-emu/fui2d.c delete mode 100644 arch/nds32/math-emu/fui2s.c delete mode 100644 arch/nds32/mm/Makefile delete mode 100644 arch/nds32/mm/alignment.c delete mode 100644 arch/nds32/mm/cacheflush.c delete mode 100644 arch/nds32/mm/extable.c delete mode 100644 arch/nds32/mm/fault.c delete mode 100644 arch/nds32/mm/init.c delete mode 100644 arch/nds32/mm/mm-nds32.c delete mode 100644 arch/nds32/mm/mmap.c delete mode 100644 arch/nds32/mm/proc.c delete mode 100644 arch/nds32/mm/tlb.c delete mode 100644 drivers/clocksource/timer-atcpit100.c delete mode 100644 drivers/irqchip/irq-ativic32.c delete mode 100644 tools/perf/arch/nds32/Build delete mode 100644 tools/perf/arch/nds32/util/Build delete mode 100644 tools/perf/arch/nds32/util/header.c (limited to 'scripts') diff --git a/Documentation/devicetree/bindings/interrupt-controller/andestech,ativic32.txt b/Documentation/devicetree/bindings/interrupt-controller/andestech,ativic32.txt deleted file mode 100644 index f4b4193d830e..000000000000 --- a/Documentation/devicetree/bindings/interrupt-controller/andestech,ativic32.txt +++ /dev/null @@ -1,19 +0,0 @@ -* Andestech Internal Vector Interrupt Controller - -The Internal Vector Interrupt Controller (IVIC) is a basic interrupt controller -suitable for a simpler SoC platform not requiring a more sophisticated and -bigger External Vector Interrupt Controller. - - -Main node required properties: - -- compatible : should at least contain "andestech,ativic32". -- interrupt-controller : Identifies the node as an interrupt controller -- #interrupt-cells: 1 cells and refer to interrupt-controller/interrupts - -Examples: - intc: interrupt-controller { - compatible = "andestech,ativic32"; - #interrupt-cells = <1>; - interrupt-controller; - }; diff --git a/Documentation/devicetree/bindings/nds32/andestech-boards b/Documentation/devicetree/bindings/nds32/andestech-boards deleted file mode 100644 index f5d75693e3c7..000000000000 --- a/Documentation/devicetree/bindings/nds32/andestech-boards +++ /dev/null @@ -1,40 +0,0 @@ -Andestech(nds32) AE3XX Platform ------------------------------------------------------------------------------ -The AE3XX prototype demonstrates the AE3XX example platform on the FPGA. It -is composed of one Andestech(nds32) processor and AE3XX. - -Required properties (in root node): -- compatible = "andestech,ae3xx"; - -Example: -/dts-v1/; -/ { - compatible = "andestech,ae3xx"; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&intc>; -}; - -Andestech(nds32) AG101P Platform ------------------------------------------------------------------------------ -AG101P is a generic SoC Platform IP that works with any of Andestech(nds32) -processors to provide a cost-effective and high performance solution for -majority of embedded systems in variety of application domains. Users may -simply attach their IP on one of the system buses together with certain glue -logics to complete a SoC solution for a specific application. With -comprehensive simulation and design environments, users may evaluate the -system performance of their applications and track bugs of their designs -efficiently. The optional hardware development platform further provides real -system environment for early prototyping and software/hardware co-development. - -Required properties (in root node): - compatible = "andestech,ag101p"; - -Example: -/dts-v1/; -/ { - compatible = "andestech,ag101p"; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&intc>; -}; diff --git a/Documentation/devicetree/bindings/nds32/atl2c.txt b/Documentation/devicetree/bindings/nds32/atl2c.txt deleted file mode 100644 index da8ab8e7ae9b..000000000000 --- a/Documentation/devicetree/bindings/nds32/atl2c.txt +++ /dev/null @@ -1,28 +0,0 @@ -* Andestech L2 cache Controller - -The level-2 cache controller plays an important role in reducing memory latency -for high performance systems, such as thoese designs with AndesCore processors. -Level-2 cache controller in general enhances overall system performance -signigicantly and the system power consumption might be reduced as well by -reducing DRAM accesses. - -This binding specifies what properties must be available in the device tree -representation of an Andestech L2 cache controller. - -Required properties: - - compatible: - Usage: required - Value type: - Definition: "andestech,atl2c" - - reg : Physical base address and size of cache controller's memory mapped - - cache-unified : Specifies the cache is a unified cache. - - cache-level : Should be set to 2 for a level 2 cache. - -* Example - - cache-controller@e0500000 { - compatible = "andestech,atl2c"; - reg = <0xe0500000 0x1000>; - cache-unified; - cache-level = <2>; - }; diff --git a/Documentation/devicetree/bindings/nds32/cpus.txt b/Documentation/devicetree/bindings/nds32/cpus.txt deleted file mode 100644 index 6f9e311b6589..000000000000 --- a/Documentation/devicetree/bindings/nds32/cpus.txt +++ /dev/null @@ -1,38 +0,0 @@ -* Andestech Processor Binding - -This binding specifies what properties must be available in the device tree -representation of a Andestech Processor Core, which is the root node in the -tree. - -Required properties: - - - compatible: - Usage: required - Value type: - Definition: Should be "andestech,", "andestech,nds32v3" as fallback. - Must contain "andestech,nds32v3" as the most generic value, in addition to - one of the following identifiers for a particular CPU core: - "andestech,n13" - "andestech,n15" - "andestech,d15" - "andestech,n10" - "andestech,d10" - - device_type - Usage: required - Value type: - Definition: must be "cpu" - - reg: Contains CPU index. - - clock-frequency: Contains the clock frequency for CPU, in Hz. - -* Examples - -/ { - cpus { - cpu@0 { - device_type = "cpu"; - compatible = "andestech,n13", "andestech,nds32v3"; - reg = <0x0>; - clock-frequency = <60000000> - }; - }; -}; diff --git a/Documentation/devicetree/bindings/perf/nds32v3-pmu.txt b/Documentation/devicetree/bindings/perf/nds32v3-pmu.txt deleted file mode 100644 index 1bd15785b4ae..000000000000 --- a/Documentation/devicetree/bindings/perf/nds32v3-pmu.txt +++ /dev/null @@ -1,17 +0,0 @@ -* NDS32 Performance Monitor Units - -NDS32 core have a PMU for counting cpu and cache events like cache misses. -The NDS32 PMU representation in the device tree should be done as under: - -Required properties: - -- compatible : - "andestech,nds32v3-pmu" - -- interrupts : The interrupt number for NDS32 PMU is 13. - -Example: -pmu{ - compatible = "andestech,nds32v3-pmu"; - interrupts = <13>; -} diff --git a/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt deleted file mode 100644 index 4c9ea5989e35..000000000000 --- a/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt +++ /dev/null @@ -1,33 +0,0 @@ -Andestech ATCPIT100 timer ------------------------------------------------------------------- -ATCPIT100 is a generic IP block from Andes Technology, embedded in -Andestech AE3XX platforms and other designs. - -This timer is a set of compact multi-function timers, which can be -used as pulse width modulators (PWM) as well as simple timers. - -It supports up to 4 PIT channels. Each PIT channel is a -multi-function timer and provide the following usage scenarios: -One 32-bit timer -Two 16-bit timers -Four 8-bit timers -One 16-bit PWM -One 16-bit timer and one 8-bit PWM -Two 8-bit timer and one 8-bit PWM - -Required properties: -- compatible : Should be "andestech,atcpit100" -- reg : Address and length of the register set -- interrupts : Reference to the timer interrupt -- clocks : a clock to provide the tick rate for "andestech,atcpit100" -- clock-names : should be "PCLK" for the peripheral clock source. - -Examples: - -timer0: timer@f0400000 { - compatible = "andestech,atcpit100"; - reg = <0xf0400000 0x1000>; - interrupts = <2>; - clocks = <&apb>; - clock-names = "PCLK"; -}; diff --git a/Documentation/features/core/cBPF-JIT/arch-support.txt b/Documentation/features/core/cBPF-JIT/arch-support.txt index e59b5215402d..77bd6974dd6d 100644 --- a/Documentation/features/core/cBPF-JIT/arch-support.txt +++ b/Documentation/features/core/cBPF-JIT/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/core/eBPF-JIT/arch-support.txt b/Documentation/features/core/eBPF-JIT/arch-support.txt index dcbd8679f514..d5ab547b2be6 100644 --- a/Documentation/features/core/eBPF-JIT/arch-support.txt +++ b/Documentation/features/core/eBPF-JIT/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/core/generic-idle-thread/arch-support.txt b/Documentation/features/core/generic-idle-thread/arch-support.txt index 4efcba7b5239..ddb3762ca7f5 100644 --- a/Documentation/features/core/generic-idle-thread/arch-support.txt +++ b/Documentation/features/core/generic-idle-thread/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | ok | | parisc: | ok | diff --git a/Documentation/features/core/jump-labels/arch-support.txt b/Documentation/features/core/jump-labels/arch-support.txt index 0c801d1bd2da..d5380ef68713 100644 --- a/Documentation/features/core/jump-labels/arch-support.txt +++ b/Documentation/features/core/jump-labels/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | ok | diff --git a/Documentation/features/core/thread-info-in-task/arch-support.txt b/Documentation/features/core/thread-info-in-task/arch-support.txt index bc74d8beea72..0654ba3a42ff 100644 --- a/Documentation/features/core/thread-info-in-task/arch-support.txt +++ b/Documentation/features/core/thread-info-in-task/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | - | nds32: | ok | | nios2: | TODO | | openrisc: | TODO | | parisc: | ok | diff --git a/Documentation/features/core/tracehook/arch-support.txt b/Documentation/features/core/tracehook/arch-support.txt index af34308fce7f..8e95dc0c7b90 100644 --- a/Documentation/features/core/tracehook/arch-support.txt +++ b/Documentation/features/core/tracehook/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | ok | | nios2: | ok | | openrisc: | ok | | parisc: | ok | diff --git a/Documentation/features/debug/KASAN/arch-support.txt b/Documentation/features/debug/KASAN/arch-support.txt index c244ac7eee26..407ca1d91242 100644 --- a/Documentation/features/debug/KASAN/arch-support.txt +++ b/Documentation/features/debug/KASAN/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/debug/debug-vm-pgtable/arch-support.txt b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt index fa83403b4aec..83eafe1a7f68 100644 --- a/Documentation/features/debug/debug-vm-pgtable/arch-support.txt +++ b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/debug/gcov-profile-all/arch-support.txt b/Documentation/features/debug/gcov-profile-all/arch-support.txt index b39c1a5de3f3..49e0dda11227 100644 --- a/Documentation/features/debug/gcov-profile-all/arch-support.txt +++ b/Documentation/features/debug/gcov-profile-all/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | ok | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/debug/kcov/arch-support.txt b/Documentation/features/debug/kcov/arch-support.txt index 7e44013cc320..3d34b724ddae 100644 --- a/Documentation/features/debug/kcov/arch-support.txt +++ b/Documentation/features/debug/kcov/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/debug/kgdb/arch-support.txt b/Documentation/features/debug/kgdb/arch-support.txt index 2cb0576f9180..7aa073d908c5 100644 --- a/Documentation/features/debug/kgdb/arch-support.txt +++ b/Documentation/features/debug/kgdb/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | ok | | mips: | ok | - | nds32: | TODO | | nios2: | ok | | openrisc: | TODO | | parisc: | ok | diff --git a/Documentation/features/debug/kmemleak/arch-support.txt b/Documentation/features/debug/kmemleak/arch-support.txt index e9ac415f8aec..5c784ff9768a 100644 --- a/Documentation/features/debug/kmemleak/arch-support.txt +++ b/Documentation/features/debug/kmemleak/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | ok | | mips: | ok | - | nds32: | ok | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt b/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt index 96156e8802a7..a1f6e98c6b1f 100644 --- a/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt +++ b/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | ok | diff --git a/Documentation/features/debug/kprobes/arch-support.txt b/Documentation/features/debug/kprobes/arch-support.txt index ee95ed61909a..e7e7015175e7 100644 --- a/Documentation/features/debug/kprobes/arch-support.txt +++ b/Documentation/features/debug/kprobes/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | ok | diff --git a/Documentation/features/debug/kretprobes/arch-support.txt b/Documentation/features/debug/kretprobes/arch-support.txt index 612cb97d47b8..838eb53a6fa5 100644 --- a/Documentation/features/debug/kretprobes/arch-support.txt +++ b/Documentation/features/debug/kretprobes/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | ok | diff --git a/Documentation/features/debug/optprobes/arch-support.txt b/Documentation/features/debug/optprobes/arch-support.txt index d6ff141a6122..6358b00b1723 100644 --- a/Documentation/features/debug/optprobes/arch-support.txt +++ b/Documentation/features/debug/optprobes/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/debug/stackprotector/arch-support.txt b/Documentation/features/debug/stackprotector/arch-support.txt index ad4de22a71ab..f6cdf781305f 100644 --- a/Documentation/features/debug/stackprotector/arch-support.txt +++ b/Documentation/features/debug/stackprotector/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/debug/uprobes/arch-support.txt b/Documentation/features/debug/uprobes/arch-support.txt index 8bd5548a4485..0b871e797d24 100644 --- a/Documentation/features/debug/uprobes/arch-support.txt +++ b/Documentation/features/debug/uprobes/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/debug/user-ret-profiler/arch-support.txt b/Documentation/features/debug/user-ret-profiler/arch-support.txt index 2a3fe812a5fa..a2feda7adff1 100644 --- a/Documentation/features/debug/user-ret-profiler/arch-support.txt +++ b/Documentation/features/debug/user-ret-profiler/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/io/dma-contiguous/arch-support.txt b/Documentation/features/io/dma-contiguous/arch-support.txt index bece89586efa..9b407f26d45e 100644 --- a/Documentation/features/io/dma-contiguous/arch-support.txt +++ b/Documentation/features/io/dma-contiguous/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | ok | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/locking/cmpxchg-local/arch-support.txt b/Documentation/features/locking/cmpxchg-local/arch-support.txt index 52bdda004f5c..090520b0e02d 100644 --- a/Documentation/features/locking/cmpxchg-local/arch-support.txt +++ b/Documentation/features/locking/cmpxchg-local/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/locking/lockdep/arch-support.txt b/Documentation/features/locking/lockdep/arch-support.txt index a8cd163c8b7e..6d840b103537 100644 --- a/Documentation/features/locking/lockdep/arch-support.txt +++ b/Documentation/features/locking/lockdep/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | ok | | mips: | ok | - | nds32: | ok | | nios2: | TODO | | openrisc: | ok | | parisc: | TODO | diff --git a/Documentation/features/locking/queued-rwlocks/arch-support.txt b/Documentation/features/locking/queued-rwlocks/arch-support.txt index 8c85949752b3..de586be05d64 100644 --- a/Documentation/features/locking/queued-rwlocks/arch-support.txt +++ b/Documentation/features/locking/queued-rwlocks/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | ok | | parisc: | TODO | diff --git a/Documentation/features/locking/queued-spinlocks/arch-support.txt b/Documentation/features/locking/queued-spinlocks/arch-support.txt index 5f4e1b3841af..29d0c8b7b1c5 100644 --- a/Documentation/features/locking/queued-spinlocks/arch-support.txt +++ b/Documentation/features/locking/queued-spinlocks/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | ok | | parisc: | TODO | diff --git a/Documentation/features/perf/kprobes-event/arch-support.txt b/Documentation/features/perf/kprobes-event/arch-support.txt index 78f3fe080f0e..881a8a50e41e 100644 --- a/Documentation/features/perf/kprobes-event/arch-support.txt +++ b/Documentation/features/perf/kprobes-event/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | ok | | nios2: | TODO | | openrisc: | TODO | | parisc: | ok | diff --git a/Documentation/features/perf/perf-regs/arch-support.txt b/Documentation/features/perf/perf-regs/arch-support.txt index 5bf3b1854a1f..7639a796a8e1 100644 --- a/Documentation/features/perf/perf-regs/arch-support.txt +++ b/Documentation/features/perf/perf-regs/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/perf/perf-stackdump/arch-support.txt b/Documentation/features/perf/perf-stackdump/arch-support.txt index d88659bb4fc1..df1a4c679a45 100644 --- a/Documentation/features/perf/perf-stackdump/arch-support.txt +++ b/Documentation/features/perf/perf-stackdump/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/sched/membarrier-sync-core/arch-support.txt b/Documentation/features/sched/membarrier-sync-core/arch-support.txt index 883d33b265d6..51b7afc937f1 100644 --- a/Documentation/features/sched/membarrier-sync-core/arch-support.txt +++ b/Documentation/features/sched/membarrier-sync-core/arch-support.txt @@ -40,7 +40,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/sched/numa-balancing/arch-support.txt b/Documentation/features/sched/numa-balancing/arch-support.txt index 9affb7c2c500..d0e308135434 100644 --- a/Documentation/features/sched/numa-balancing/arch-support.txt +++ b/Documentation/features/sched/numa-balancing/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | .. | | microblaze: | .. | | mips: | TODO | - | nds32: | TODO | | nios2: | .. | | openrisc: | .. | | parisc: | .. | diff --git a/Documentation/features/seccomp/seccomp-filter/arch-support.txt b/Documentation/features/seccomp/seccomp-filter/arch-support.txt index 26eec58ab819..05613c5ff560 100644 --- a/Documentation/features/seccomp/seccomp-filter/arch-support.txt +++ b/Documentation/features/seccomp/seccomp-filter/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | ok | diff --git a/Documentation/features/time/arch-tick-broadcast/arch-support.txt b/Documentation/features/time/arch-tick-broadcast/arch-support.txt index 8dcaab070c7b..b4c96ebab7e3 100644 --- a/Documentation/features/time/arch-tick-broadcast/arch-support.txt +++ b/Documentation/features/time/arch-tick-broadcast/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/time/clockevents/arch-support.txt b/Documentation/features/time/clockevents/arch-support.txt index 9a81cb03b1fd..3f6976052e2a 100644 --- a/Documentation/features/time/clockevents/arch-support.txt +++ b/Documentation/features/time/clockevents/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | ok | | mips: | ok | - | nds32: | ok | | nios2: | ok | | openrisc: | ok | | parisc: | TODO | diff --git a/Documentation/features/time/context-tracking/arch-support.txt b/Documentation/features/time/context-tracking/arch-support.txt index 4ed116c2ec39..bb1c1801553e 100644 --- a/Documentation/features/time/context-tracking/arch-support.txt +++ b/Documentation/features/time/context-tracking/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/time/irq-time-acct/arch-support.txt b/Documentation/features/time/irq-time-acct/arch-support.txt index bc30c15557c7..3cea25b80c8c 100644 --- a/Documentation/features/time/irq-time-acct/arch-support.txt +++ b/Documentation/features/time/irq-time-acct/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | .. | diff --git a/Documentation/features/time/virt-cpuacct/arch-support.txt b/Documentation/features/time/virt-cpuacct/arch-support.txt index 050de43bbbb9..5163a60a1c1e 100644 --- a/Documentation/features/time/virt-cpuacct/arch-support.txt +++ b/Documentation/features/time/virt-cpuacct/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | ok | diff --git a/Documentation/features/vm/ELF-ASLR/arch-support.txt b/Documentation/features/vm/ELF-ASLR/arch-support.txt index 2949c99fbb2f..73ec761f1e27 100644 --- a/Documentation/features/vm/ELF-ASLR/arch-support.txt +++ b/Documentation/features/vm/ELF-ASLR/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | ok | diff --git a/Documentation/features/vm/PG_uncached/arch-support.txt b/Documentation/features/vm/PG_uncached/arch-support.txt index 6cde38458596..9066a90b38d9 100644 --- a/Documentation/features/vm/PG_uncached/arch-support.txt +++ b/Documentation/features/vm/PG_uncached/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/vm/THP/arch-support.txt b/Documentation/features/vm/THP/arch-support.txt index 7dbd6967b37e..f717ab792e5a 100644 --- a/Documentation/features/vm/THP/arch-support.txt +++ b/Documentation/features/vm/THP/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | .. | | microblaze: | .. | | mips: | ok | - | nds32: | TODO | | nios2: | .. | | openrisc: | .. | | parisc: | TODO | diff --git a/Documentation/features/vm/TLB/arch-support.txt b/Documentation/features/vm/TLB/arch-support.txt index e1c3a4c4d107..6fa76a37f299 100644 --- a/Documentation/features/vm/TLB/arch-support.txt +++ b/Documentation/features/vm/TLB/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | .. | | microblaze: | .. | | mips: | TODO | - | nds32: | TODO | | nios2: | .. | | openrisc: | .. | | parisc: | TODO | diff --git a/Documentation/features/vm/huge-vmap/arch-support.txt b/Documentation/features/vm/huge-vmap/arch-support.txt index bc53905a0306..6e1792ee37fe 100644 --- a/Documentation/features/vm/huge-vmap/arch-support.txt +++ b/Documentation/features/vm/huge-vmap/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/vm/ioremap_prot/arch-support.txt b/Documentation/features/vm/ioremap_prot/arch-support.txt index 9a0c8783b84d..a6dcbe5f47b6 100644 --- a/Documentation/features/vm/ioremap_prot/arch-support.txt +++ b/Documentation/features/vm/ioremap_prot/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/Documentation/features/vm/pte_special/arch-support.txt b/Documentation/features/vm/pte_special/arch-support.txt index 40b969f3a6bb..376477749c42 100644 --- a/Documentation/features/vm/pte_special/arch-support.txt +++ b/Documentation/features/vm/pte_special/arch-support.txt @@ -17,7 +17,6 @@ | m68k: | TODO | | microblaze: | TODO | | mips: | ok | - | nds32: | TODO | | nios2: | TODO | | openrisc: | TODO | | parisc: | TODO | diff --git a/MAINTAINERS b/MAINTAINERS index 69a2935daf6c..d24a03cb0426 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1229,18 +1229,6 @@ S: Supported F: drivers/clk/analogbits/* F: include/linux/clk/analogbits* -ANDES ARCHITECTURE -M: Nick Hu -M: Greentime Hu -M: Vincent Chen -S: Supported -T: git https://git.kernel.org/pub/scm/linux/kernel/git/greentime/linux.git -F: Documentation/devicetree/bindings/interrupt-controller/andestech,ativic32.txt -F: Documentation/devicetree/bindings/nds32/ -F: arch/nds32/ -N: nds32 -K: nds32 - ANDROID CONFIG FRAGMENTS M: Rob Herring S: Supported diff --git a/arch/nds32/Kbuild b/arch/nds32/Kbuild deleted file mode 100644 index 4e39f7abdeb6..000000000000 --- a/arch/nds32/Kbuild +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -# for cleaning -subdir- += boot diff --git a/arch/nds32/Kconfig b/arch/nds32/Kconfig deleted file mode 100644 index 013249430fa3..000000000000 --- a/arch/nds32/Kconfig +++ /dev/null @@ -1,101 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# For a description of the syntax of this configuration file, -# see Documentation/kbuild/kconfig-language.rst. -# - -config NDS32 - def_bool y - select ARCH_32BIT_OFF_T - select ARCH_HAS_DMA_PREP_COHERENT - select ARCH_HAS_SYNC_DMA_FOR_CPU - select ARCH_HAS_SYNC_DMA_FOR_DEVICE - select ARCH_WANT_FRAME_POINTERS if FTRACE - select CLKSRC_MMIO - select CLONE_BACKWARDS - select COMMON_CLK - select DMA_DIRECT_REMAP - select GENERIC_ATOMIC64 - select GENERIC_CPU_DEVICES - select GENERIC_IRQ_CHIP - select GENERIC_IRQ_SHOW - select GENERIC_IOREMAP - select GENERIC_LIB_ASHLDI3 - select GENERIC_LIB_ASHRDI3 - select GENERIC_LIB_CMPDI2 - select GENERIC_LIB_LSHRDI3 - select GENERIC_LIB_MULDI3 - select GENERIC_LIB_UCMPDI2 - select GENERIC_TIME_VSYSCALL - select HAVE_ARCH_TRACEHOOK - select HAVE_DEBUG_KMEMLEAK - select HAVE_EXIT_THREAD - select HAVE_REGS_AND_STACK_ACCESS_API - select HAVE_PERF_EVENTS - select IRQ_DOMAIN - select LOCKDEP_SUPPORT - select MODULES_USE_ELF_RELA - select OF - select OF_EARLY_FLATTREE - select NO_IOPORT_MAP - select RTC_LIB - select THREAD_INFO_IN_TASK - select HAVE_FUNCTION_TRACER - select HAVE_FUNCTION_GRAPH_TRACER - select HAVE_FTRACE_MCOUNT_RECORD - select HAVE_DYNAMIC_FTRACE - select TRACE_IRQFLAGS_SUPPORT - help - Andes(nds32) Linux support. - -config GENERIC_CALIBRATE_DELAY - def_bool y - -config GENERIC_CSUM - def_bool y - -config GENERIC_HWEIGHT - def_bool y - -config GENERIC_LOCKBREAK - def_bool y - depends on PREEMPTION - -config STACKTRACE_SUPPORT - def_bool y - -config FIX_EARLYCON_MEM - def_bool y - -config PGTABLE_LEVELS - default 2 - -menu "System Type" -source "arch/nds32/Kconfig.cpu" -config NR_CPUS - int - default 1 - -config MMU - def_bool y - -config NDS32_BUILTIN_DTB - string "Builtin DTB" - default "" - help - User can use it to specify the dts of the SoC -endmenu - -menu "Kernel Features" -source "kernel/Kconfig.hz" -endmenu - -menu "Power management options" -config SYS_SUPPORTS_APM_EMULATION - bool - -config ARCH_SUSPEND_POSSIBLE - def_bool y - -source "kernel/power/Kconfig" -endmenu diff --git a/arch/nds32/Kconfig.cpu b/arch/nds32/Kconfig.cpu deleted file mode 100644 index c10759952485..000000000000 --- a/arch/nds32/Kconfig.cpu +++ /dev/null @@ -1,218 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -comment "Processor Features" - -config CPU_BIG_ENDIAN - def_bool !CPU_LITTLE_ENDIAN - -config CPU_LITTLE_ENDIAN - bool "Little endian" - default y - -config FPU - bool "FPU support" - default n - help - If FPU ISA is used in user space, this configuration shall be Y to - enable required support in kernel such as fpu context switch and - fpu exception handler. - - If no FPU ISA is used in user space, say N. - -config LAZY_FPU - bool "lazy FPU support" - depends on FPU - default y - help - Say Y here to enable the lazy FPU scheme. The lazy FPU scheme can - enhance system performance by reducing the context switch - frequency of the FPU register. - - For normal case, say Y. - -config SUPPORT_DENORMAL_ARITHMETIC - bool "Denormal arithmetic support" - depends on FPU - default n - help - Say Y here to enable arithmetic of denormalized number. Enabling - this feature can enhance the precision for tininess number. - However, performance loss in float point calculations is - possibly significant due to additional FPU exception. - - If the calculated tolerance for tininess number is not critical, - say N to prevent performance loss. - -config HWZOL - bool "hardware zero overhead loop support" - depends on CPU_D10 || CPU_D15 - default n - help - A set of Zero-Overhead Loop mechanism is provided to reduce the - instruction fetch and execution overhead of loop-control instructions. - It will save 3 registers($LB, $LC, $LE) for context saving if say Y. - You don't need to save these registers if you can make sure your user - program doesn't use these registers. - - If unsure, say N. - -config CPU_CACHE_ALIASING - bool "Aliasing cache" - depends on CPU_N10 || CPU_D10 || CPU_N13 || CPU_V3 - default y - help - If this CPU is using VIPT data cache and its cache way size is larger - than page size, say Y. If it is using PIPT data cache, say N. - - If unsure, say Y. - -choice - prompt "minimum CPU type" - default CPU_V3 - help - The data cache of N15/D15 is implemented as PIPT and it will not cause - the cache aliasing issue. The rest cpus(N13, N10 and D10) are - implemented as VIPT data cache. It may cause the cache aliasing issue - if its cache way size is larger than page size. You can specify the - CPU type directly or choose CPU_V3 if unsure. - - A kernel built for N10 is able to run on N15, D15, N13, N10 or D10. - A kernel built for N15 is able to run on N15 or D15. - A kernel built for D10 is able to run on D10 or D15. - A kernel built for D15 is able to run on D15. - A kernel built for N13 is able to run on N15, N13 or D15. - -config CPU_N15 - bool "AndesCore N15" -config CPU_N13 - bool "AndesCore N13" - select CPU_CACHE_ALIASING if ANDES_PAGE_SIZE_4KB -config CPU_N10 - bool "AndesCore N10" - select CPU_CACHE_ALIASING -config CPU_D15 - bool "AndesCore D15" -config CPU_D10 - bool "AndesCore D10" - select CPU_CACHE_ALIASING -config CPU_V3 - bool "AndesCore v3 compatible" - select CPU_CACHE_ALIASING -endchoice -choice - prompt "Paging -- page size " - default ANDES_PAGE_SIZE_4KB -config ANDES_PAGE_SIZE_4KB - bool "use 4KB page size" -config ANDES_PAGE_SIZE_8KB - bool "use 8KB page size" -endchoice - -config CPU_ICACHE_DISABLE - bool "Disable I-Cache" - help - Say Y here to disable the processor instruction cache. Unless - you have a reason not to or are unsure, say N. - -config CPU_DCACHE_DISABLE - bool "Disable D-Cache" - help - Say Y here to disable the processor data cache. Unless - you have a reason not to or are unsure, say N. - -config CPU_DCACHE_WRITETHROUGH - bool "Force write through D-cache" - depends on !CPU_DCACHE_DISABLE - help - Say Y here to use the data cache in writethrough mode. Unless you - specifically require this or are unsure, say N. - -config WBNA - bool "WBNA" - default n - help - Say Y here to enable write-back memory with no-write-allocation policy. - -config ALIGNMENT_TRAP - bool "Kernel support unaligned access handling by sw" - depends on PROC_FS - default n - help - Andes processors cannot load/store information which is not - naturally aligned on the bus, i.e., a 4 byte load must start at an - address divisible by 4. On 32-bit Andes processors, these non-aligned - load/store instructions will be emulated in software if you say Y - here, which has a severe performance impact. With an IP-only - configuration it is safe to say N, otherwise say Y. - -config HW_SUPPORT_UNALIGNMENT_ACCESS - bool "Kernel support unaligned access handling by hw" - depends on !ALIGNMENT_TRAP - default n - help - Andes processors load/store world/half-word instructions can access - unaligned memory locations without generating the Data Alignment - Check exceptions. With an IP-only configuration it is safe to say N, - otherwise say Y. - -config HIGHMEM - bool "High Memory Support" - depends on MMU && !CPU_CACHE_ALIASING - select KMAP_LOCAL - help - The address space of Andes processors is only 4 Gigabytes large - and it has to accommodate user address space, kernel address - space as well as some memory mapped IO. That means that, if you - have a large amount of physical memory and/or IO, not all of the - memory can be "permanently mapped" by the kernel. The physical - memory that is not permanently mapped is called "high memory". - - Depending on the selected kernel/user memory split, minimum - vmalloc space and actual amount of RAM, you may not need this - option which should result in a slightly faster kernel. - - If unsure, say N. - -config CACHE_L2 - bool "Support L2 cache" - default y - help - Say Y here to enable L2 cache if your SoC are integrated with L2CC. - If unsure, say N. - -config HW_PRE - bool "Enable hardware prefetcher" - default y - help - Say Y here to enable hardware prefetcher feature. - Only when CPU_VER.REV >= 0x09 can support. - -menu "Memory configuration" - -choice - prompt "Memory split" - depends on MMU - default VMSPLIT_3G_OPT - help - Select the desired split between kernel and user memory. - - If you are not absolutely sure what you are doing, leave this - option alone! - - config VMSPLIT_3G - bool "3G/1G user/kernel split" - config VMSPLIT_3G_OPT - bool "3G/1G user/kernel split (for full 1G low memory)" - config VMSPLIT_2G - bool "2G/2G user/kernel split" - config VMSPLIT_1G - bool "1G/3G user/kernel split" -endchoice - -config PAGE_OFFSET - hex - default 0x40000000 if VMSPLIT_1G - default 0x80000000 if VMSPLIT_2G - default 0xB0000000 if VMSPLIT_3G_OPT - default 0xC0000000 - -endmenu diff --git a/arch/nds32/Kconfig.debug b/arch/nds32/Kconfig.debug deleted file mode 100644 index 295942fe3fd5..000000000000 --- a/arch/nds32/Kconfig.debug +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# dummy file, do not delete diff --git a/arch/nds32/Makefile b/arch/nds32/Makefile deleted file mode 100644 index b33d5d81b6ae..000000000000 --- a/arch/nds32/Makefile +++ /dev/null @@ -1,63 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -LDFLAGS_vmlinux := --no-undefined -X -OBJCOPYFLAGS := -O binary -R .note -R .note.gnu.build-id -R .comment -S - -ifdef CONFIG_FUNCTION_TRACER -arch-y += -malways-save-lp -mno-relax -endif - -# Avoid generating FPU instructions -arch-y += -mno-ext-fpu-sp -mno-ext-fpu-dp -mfloat-abi=soft - -# Enable -KBUILD_CFLAGS += -isystem $(shell $(CC) -print-file-name=include) -KBUILD_CFLAGS += $(call cc-option, -mno-sched-prolog-epilog) -KBUILD_CFLAGS += -mcmodel=large - -KBUILD_CFLAGS +=$(arch-y) $(tune-y) -KBUILD_AFLAGS +=$(arch-y) $(tune-y) - -#Default value -head-y := arch/nds32/kernel/head.o -textaddr-y := $(CONFIG_PAGE_OFFSET)+0xc000 - -TEXTADDR := $(textaddr-y) - -export TEXTADDR - - -# If we have a machine-specific directory, then include it in the build. -core-y += arch/nds32/kernel/ arch/nds32/mm/ -core-$(CONFIG_FPU) += arch/nds32/math-emu/ -libs-y += arch/nds32/lib/ - -ifdef CONFIG_CPU_LITTLE_ENDIAN -KBUILD_CFLAGS += $(call cc-option, -EL) -KBUILD_AFLAGS += $(call cc-option, -EL) -KBUILD_LDFLAGS += $(call cc-option, -EL) -CHECKFLAGS += -D__NDS32_EL__ -else -KBUILD_CFLAGS += $(call cc-option, -EB) -KBUILD_AFLAGS += $(call cc-option, -EB) -KBUILD_LDFLAGS += $(call cc-option, -EB) -CHECKFLAGS += -D__NDS32_EB__ -endif - -boot := arch/nds32/boot -core-y += $(boot)/dts/ - -Image: vmlinux - $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ - - -PHONY += vdso_install -vdso_install: - $(Q)$(MAKE) $(build)=arch/nds32/kernel/vdso $@ - -prepare: vdso_prepare -vdso_prepare: prepare0 - $(Q)$(MAKE) $(build)=arch/nds32/kernel/vdso include/generated/vdso-offsets.h - -define archhelp - echo ' Image - kernel image (arch/$(ARCH)/boot/Image)' -endef diff --git a/arch/nds32/boot/.gitignore b/arch/nds32/boot/.gitignore deleted file mode 100644 index 9182a3a1ea0a..000000000000 --- a/arch/nds32/boot/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -/Image diff --git a/arch/nds32/boot/Makefile b/arch/nds32/boot/Makefile deleted file mode 100644 index c4cc0c2689f7..000000000000 --- a/arch/nds32/boot/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -targets := Image Image.gz - -$(obj)/Image: vmlinux FORCE - $(call if_changed,objcopy) - -$(obj)/Image.gz: $(obj)/Image FORCE - $(call if_changed,gzip) - -install: $(obj)/Image - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ - $(obj)/Image System.map "$(INSTALL_PATH)" - -zinstall: $(obj)/Image.gz - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ - $(obj)/Image.gz System.map "$(INSTALL_PATH)" diff --git a/arch/nds32/boot/dts/Makefile b/arch/nds32/boot/dts/Makefile deleted file mode 100644 index 4fc69562eae8..000000000000 --- a/arch/nds32/boot/dts/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_OF) += $(addsuffix .dtb.o, $(CONFIG_NDS32_BUILTIN_DTB)) diff --git a/arch/nds32/boot/dts/ae3xx.dts b/arch/nds32/boot/dts/ae3xx.dts deleted file mode 100644 index 16a9f54a805e..000000000000 --- a/arch/nds32/boot/dts/ae3xx.dts +++ /dev/null @@ -1,90 +0,0 @@ -/dts-v1/; -/ { - compatible = "andestech,ae3xx"; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&intc>; - - chosen { - stdout-path = &serial0; - }; - - memory@0 { - device_type = "memory"; - reg = <0x00000000 0x40000000>; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - cpu@0 { - device_type = "cpu"; - compatible = "andestech,n13", "andestech,nds32v3"; - reg = <0>; - clock-frequency = <60000000>; - next-level-cache = <&L2>; - }; - }; - - intc: interrupt-controller { - compatible = "andestech,ativic32"; - #interrupt-cells = <1>; - interrupt-controller; - }; - - clock: clk { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <30000000>; - }; - - apb { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - serial0: serial@f0300000 { - compatible = "andestech,uart16550", "ns16550a"; - reg = <0xf0300000 0x1000>; - interrupts = <8>; - clock-frequency = <14745600>; - reg-shift = <2>; - reg-offset = <32>; - no-loopback-test = <1>; - }; - - timer0: timer@f0400000 { - compatible = "andestech,atcpit100"; - reg = <0xf0400000 0x1000>; - interrupts = <2>; - clocks = <&clock>; - clock-names = "PCLK"; - }; - }; - - ahb { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - L2: cache-controller@e0500000 { - compatible = "andestech,atl2c"; - reg = <0xe0500000 0x1000>; - cache-unified; - cache-level = <2>; - }; - - mac0: ethernet@e0100000 { - compatible = "andestech,atmac100"; - reg = <0xe0100000 0x1000>; - interrupts = <18>; - }; - }; - - pmu { - compatible = "andestech,nds32v3-pmu"; - interrupts= <13>; - }; -}; diff --git a/arch/nds32/configs/defconfig b/arch/nds32/configs/defconfig deleted file mode 100644 index f9a89cf00aa6..000000000000 --- a/arch/nds32/configs/defconfig +++ /dev/null @@ -1,104 +0,0 @@ -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_USER_NS=y -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_KALLSYMS_ALL=y -CONFIG_PROFILING=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_CACHE_L2 is not set -CONFIG_PREEMPT=y -# CONFIG_COMPACTION is not set -CONFIG_HZ_100=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_DIAG is not set -# CONFIG_IPV6 is not set -# CONFIG_BLK_DEV is not set -CONFIG_NETDEVICES=y -# CONFIG_NET_CADENCE is not set -# CONFIG_NET_VENDOR_BROADCOM is not set -CONFIG_FTMAC100=y -# CONFIG_NET_VENDOR_INTEL is not set -# CONFIG_NET_VENDOR_MARVELL is not set -# CONFIG_NET_VENDOR_MICREL is not set -# CONFIG_NET_VENDOR_NATSEMI is not set -# CONFIG_NET_VENDOR_SEEQ is not set -# CONFIG_NET_VENDOR_STMICRO is not set -# CONFIG_NET_VENDOR_WIZNET is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -# CONFIG_SERIO is not set -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=3 -CONFIG_SERIAL_8250_RUNTIME_UARTS=3 -CONFIG_SERIAL_OF_PLATFORM=y -# CONFIG_HW_RANDOM is not set -# CONFIG_HWMON is not set -# CONFIG_HID_A4TECH is not set -# CONFIG_HID_APPLE is not set -# CONFIG_HID_BELKIN is not set -# CONFIG_HID_CHERRY is not set -# CONFIG_HID_CHICONY is not set -# CONFIG_HID_CYPRESS is not set -# CONFIG_HID_EZKEY is not set -# CONFIG_HID_ITE is not set -# CONFIG_HID_KENSINGTON is not set -# CONFIG_HID_LOGITECH is not set -# CONFIG_HID_MICROSOFT is not set -# CONFIG_HID_MONTEREY is not set -# CONFIG_USB_SUPPORT is not set -CONFIG_GENERIC_PHY=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -CONFIG_FS_ENCRYPTION=y -CONFIG_FUSE_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_CONFIGFS_FS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3_ACL=y -CONFIG_NFS_V4=y -CONFIG_NFS_V4_1=y -CONFIG_NFS_USE_LEGACY_DNS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ISO8859_1=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_INFO_DWARF4=y -CONFIG_GDB_SCRIPTS=y -CONFIG_READABLE_ASM=y -CONFIG_HEADERS_INSTALL=y -CONFIG_HEADERS_CHECK=y -CONFIG_DEBUG_SECTION_MISMATCH=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y -CONFIG_PANIC_ON_OOPS=y -# CONFIG_SCHED_DEBUG is not set -# CONFIG_DEBUG_PREEMPT is not set -CONFIG_STACKTRACE=y -CONFIG_RCU_CPU_STALL_TIMEOUT=300 -# CONFIG_CRYPTO_HW is not set diff --git a/arch/nds32/include/asm/Kbuild b/arch/nds32/include/asm/Kbuild deleted file mode 100644 index 82a4453c9c2d..000000000000 --- a/arch/nds32/include/asm/Kbuild +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -generic-y += asm-offsets.h -generic-y += cmpxchg.h -generic-y += export.h -generic-y += gpio.h -generic-y += kvm_para.h -generic-y += parport.h -generic-y += user.h diff --git a/arch/nds32/include/asm/assembler.h b/arch/nds32/include/asm/assembler.h deleted file mode 100644 index 5e7c56926049..000000000000 --- a/arch/nds32/include/asm/assembler.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __NDS32_ASSEMBLER_H__ -#define __NDS32_ASSEMBLER_H__ - -.macro gie_disable - setgie.d - dsb -.endm - -.macro gie_enable - setgie.e - dsb -.endm - -.macro gie_save oldpsw - mfsr \oldpsw, $ir0 - setgie.d - dsb -.endm - -.macro gie_restore oldpsw - andi \oldpsw, \oldpsw, #0x1 - beqz \oldpsw, 7001f - setgie.e - dsb -7001: -.endm - - -#define USER(insn, reg, addr, opr) \ -9999: insn reg, addr, opr; \ - .section __ex_table,"a"; \ - .align 3; \ - .long 9999b, 9001f; \ - .previous - -#endif /* __NDS32_ASSEMBLER_H__ */ diff --git a/arch/nds32/include/asm/barrier.h b/arch/nds32/include/asm/barrier.h deleted file mode 100644 index 16413172fd50..000000000000 --- a/arch/nds32/include/asm/barrier.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __NDS32_ASM_BARRIER_H -#define __NDS32_ASM_BARRIER_H - -#ifndef __ASSEMBLY__ -#define mb() asm volatile("msync all":::"memory") -#define rmb() asm volatile("msync all":::"memory") -#define wmb() asm volatile("msync store":::"memory") -#include - -#endif /* __ASSEMBLY__ */ - -#endif /* __NDS32_ASM_BARRIER_H */ diff --git a/arch/nds32/include/asm/bitfield.h b/arch/nds32/include/asm/bitfield.h deleted file mode 100644 index b02a58e71f80..000000000000 --- a/arch/nds32/include/asm/bitfield.h +++ /dev/null @@ -1,985 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __NDS32_BITFIELD_H__ -#define __NDS32_BITFIELD_H__ -/****************************************************************************** - * cr0: CPU_VER (CPU Version Register) - *****************************************************************************/ -#define CPU_VER_offCFGID 0 /* Minor configuration */ -#define CPU_VER_offREV 16 /* Revision of the CPU version */ -#define CPU_VER_offCPUID 24 /* Major CPU versions */ - -#define CPU_VER_mskCFGID ( 0xFFFF << CPU_VER_offCFGID ) -#define CPU_VER_mskREV ( 0xFF << CPU_VER_offREV ) -#define CPU_VER_mskCPUID ( 0xFF << CPU_VER_offCPUID ) - -/****************************************************************************** - * cr1: ICM_CFG (Instruction Cache/Memory Configuration Register) - *****************************************************************************/ -#define ICM_CFG_offISET 0 /* I-cache sets (# of cache lines) per way */ -#define ICM_CFG_offIWAY 3 /* I-cache ways */ -#define ICM_CFG_offISZ 6 /* I-cache line size */ -#define ICM_CFG_offILCK 9 /* I-cache locking support */ -#define ICM_CFG_offILMB 10 /* On-chip ILM banks */ -#define ICM_CFG_offBSAV 13 /* ILM base register alignment version */ -/* bit 15:31 reserved */ - -#define ICM_CFG_mskISET ( 0x7 << ICM_CFG_offISET ) -#define ICM_CFG_mskIWAY ( 0x7 << ICM_CFG_offIWAY ) -#define ICM_CFG_mskISZ ( 0x7 << ICM_CFG_offISZ ) -#define ICM_CFG_mskILCK ( 0x1 << ICM_CFG_offILCK ) -#define ICM_CFG_mskILMB ( 0x7 << ICM_CFG_offILMB ) -#define ICM_CFG_mskBSAV ( 0x3 << ICM_CFG_offBSAV ) - -/****************************************************************************** - * cr2: DCM_CFG (Data Cache/Memory Configuration Register) - *****************************************************************************/ -#define DCM_CFG_offDSET 0 /* D-cache sets (# of cache lines) per way */ -#define DCM_CFG_offDWAY 3 /* D-cache ways */ -#define DCM_CFG_offDSZ 6 /* D-cache line size */ -#define DCM_CFG_offDLCK 9 /* D-cache locking support */ -#define DCM_CFG_offDLMB 10 /* On-chip DLM banks */ -#define DCM_CFG_offBSAV 13 /* DLM base register alignment version */ -/* bit 15:31 reserved */ - -#define DCM_CFG_mskDSET ( 0x7 << DCM_CFG_offDSET ) -#define DCM_CFG_mskDWAY ( 0x7 << DCM_CFG_offDWAY ) -#define DCM_CFG_mskDSZ ( 0x7 << DCM_CFG_offDSZ ) -#define DCM_CFG_mskDLCK ( 0x1 << DCM_CFG_offDLCK ) -#define DCM_CFG_mskDLMB ( 0x7 << DCM_CFG_offDLMB ) -#define DCM_CFG_mskBSAV ( 0x3 << DCM_CFG_offBSAV ) - -/****************************************************************************** - * cr3: MMU_CFG (MMU Configuration Register) - *****************************************************************************/ -#define MMU_CFG_offMMPS 0 /* Memory management protection scheme */ -#define MMU_CFG_offMMPV 2 /* Memory management protection version number */ -#define MMU_CFG_offFATB 7 /* Fully-associative or non-fully-associative TLB */ - -#define MMU_CFG_offTBW 8 /* TLB ways(non-associative) TBS */ -#define MMU_CFG_offTBS 11 /* TLB sets per way(non-associative) TBS */ -/* bit 14:14 reserved */ - -#define MMU_CFG_offEP8MIN4 15 /* 8KB page supported while minimum page is 4KB */ -#define MMU_CFG_offfEPSZ 16 /* Extra page size supported */ -#define MMU_CFG_offTLBLCK 24 /* TLB locking support */ -#define MMU_CFG_offHPTWK 25 /* Hardware Page Table Walker implemented */ -#define MMU_CFG_offDE 26 /* Default endian */ -#define MMU_CFG_offNTPT 27 /* Partitions for non-translated attributes */ -#define MMU_CFG_offIVTB 28 /* Invisible TLB */ -#define MMU_CFG_offVLPT 29 /* VLPT for fast TLB fill handling implemented */ -#define MMU_CFG_offNTME 30 /* Non-translated VA to PA mapping */ -/* bit 31 reserved */ - -#define MMU_CFG_mskMMPS ( 0x3 << MMU_CFG_offMMPS ) -#define MMU_CFG_mskMMPV ( 0x1F << MMU_CFG_offMMPV ) -#define MMU_CFG_mskFATB ( 0x1 << MMU_CFG_offFATB ) -#define MMU_CFG_mskTBW ( 0x7 << MMU_CFG_offTBW ) -#define MMU_CFG_mskTBS ( 0x7 << MMU_CFG_offTBS ) -#define MMU_CFG_mskEP8MIN4 ( 0x1 << MMU_CFG_offEP8MIN4 ) -#define MMU_CFG_mskfEPSZ ( 0xFF << MMU_CFG_offfEPSZ ) -#define MMU_CFG_mskTLBLCK ( 0x1 << MMU_CFG_offTLBLCK ) -#define MMU_CFG_mskHPTWK ( 0x1 << MMU_CFG_offHPTWK ) -#define MMU_CFG_mskDE ( 0x1 << MMU_CFG_offDE ) -#define MMU_CFG_mskNTPT ( 0x1 << MMU_CFG_offNTPT ) -#define MMU_CFG_mskIVTB ( 0x1 << MMU_CFG_offIVTB ) -#define MMU_CFG_mskVLPT ( 0x1 << MMU_CFG_offVLPT ) -#define MMU_CFG_mskNTME ( 0x1 << MMU_CFG_offNTME ) - -/****************************************************************************** - * cr4: MSC_CFG (Misc Configuration Register) - *****************************************************************************/ -#define MSC_CFG_offEDM 0 -#define MSC_CFG_offLMDMA 1 -#define MSC_CFG_offPFM 2 -#define MSC_CFG_offHSMP 3 -#define MSC_CFG_offTRACE 4 -#define MSC_CFG_offDIV 5 -#define MSC_CFG_offMAC 6 -#define MSC_CFG_offAUDIO 7 -#define MSC_CFG_offL2C 9 -#define MSC_CFG_offRDREG 10 -#define MSC_CFG_offADR24 11 -#define MSC_CFG_offINTLC 12 -#define MSC_CFG_offBASEV 13 -#define MSC_CFG_offNOD 16 -/* bit 13:31 reserved */ - -#define MSC_CFG_mskEDM ( 0x1 << MSC_CFG_offEDM ) -#define MSC_CFG_mskLMDMA ( 0x1 << MSC_CFG_offLMDMA ) -#define MSC_CFG_mskPFM ( 0x1 << MSC_CFG_offPFM ) -#define MSC_CFG_mskHSMP ( 0x1 << MSC_CFG_offHSMP ) -#define MSC_CFG_mskTRACE ( 0x1 << MSC_CFG_offTRACE ) -#define MSC_CFG_mskDIV ( 0x1 << MSC_CFG_offDIV ) -#define MSC_CFG_mskMAC ( 0x1 << MSC_CFG_offMAC ) -#define MSC_CFG_mskAUDIO ( 0x3 << MSC_CFG_offAUDIO ) -#define MSC_CFG_mskL2C ( 0x1 << MSC_CFG_offL2C ) -#define MSC_CFG_mskRDREG ( 0x1 << MSC_CFG_offRDREG ) -#define MSC_CFG_mskADR24 ( 0x1 << MSC_CFG_offADR24 ) -#define MSC_CFG_mskINTLC ( 0x1 << MSC_CFG_offINTLC ) -#define MSC_CFG_mskBASEV ( 0x7 << MSC_CFG_offBASEV ) -#define MSC_CFG_mskNOD ( 0x1 << MSC_CFG_offNOD ) - -/****************************************************************************** - * cr5: CORE_CFG (Core Identification Register) - *****************************************************************************/ -#define CORE_ID_offCOREID 0 -/* bit 4:31 reserved */ - -#define CORE_ID_mskCOREID ( 0xF << CORE_ID_offCOREID ) - -/****************************************************************************** - * cr6: FUCOP_EXIST (FPU and Coprocessor Existence Configuration Register) - *****************************************************************************/ -#define FUCOP_EXIST_offCP0EX 0 -#define FUCOP_EXIST_offCP1EX 1 -#define FUCOP_EXIST_offCP2EX 2 -#define FUCOP_EXIST_offCP3EX 3 -#define FUCOP_EXIST_offCP0ISFPU 31 - -#define FUCOP_EXIST_mskCP0EX ( 0x1 << FUCOP_EXIST_offCP0EX ) -#define FUCOP_EXIST_mskCP1EX ( 0x1 << FUCOP_EXIST_offCP1EX ) -#define FUCOP_EXIST_mskCP2EX ( 0x1 << FUCOP_EXIST_offCP2EX ) -#define FUCOP_EXIST_mskCP3EX ( 0x1 << FUCOP_EXIST_offCP3EX ) -#define FUCOP_EXIST_mskCP0ISFPU ( 0x1 << FUCOP_EXIST_offCP0ISFPU ) - -/****************************************************************************** - * ir0: PSW (Processor Status Word Register) - * ir1: IPSW (Interruption PSW Register) - * ir2: P_IPSW (Previous IPSW Register) - *****************************************************************************/ -#define PSW_offGIE 0 /* Global Interrupt Enable */ -#define PSW_offINTL 1 /* Interruption Stack Level */ -#define PSW_offPOM 3 /* Processor Operation Mode, User/Superuser */ -#define PSW_offBE 5 /* Endianness for data memory access, 1:MSB, 0:LSB */ -#define PSW_offIT 6 /* Enable instruction address translation */ -#define PSW_offDT 7 /* Enable data address translation */ -#define PSW_offIME 8 /* Instruction Machine Error flag */ -#define PSW_offDME 9 /* Data Machine Error flag */ -#define PSW_offDEX 10 /* Debug Exception */ -#define PSW_offHSS 11 /* Hardware Single Stepping */ -#define PSW_offDRBE 12 /* Device Register Endian Mode */ -#define PSW_offAEN 13 /* Audio ISA special feature */ -#define PSW_offWBNA 14 /* Write Back Non-Allocate */ -#define PSW_offIFCON 15 /* IFC On */ -#define PSW_offCPL 16 /* Current Priority Level */ -/* bit 19:31 reserved */ - -#define PSW_mskGIE ( 0x1 << PSW_offGIE ) -#define PSW_mskINTL ( 0x3 << PSW_offINTL ) -#define PSW_mskPOM ( 0x3 << PSW_offPOM ) -#define PSW_mskBE ( 0x1 << PSW_offBE ) -#define PSW_mskIT ( 0x1 << PSW_offIT ) -#define PSW_mskDT ( 0x1 << PSW_offDT ) -#define PSW_mskIME ( 0x1 << PSW_offIME ) -#define PSW_mskDME ( 0x1 << PSW_offDME ) -#define PSW_mskDEX ( 0x1 << PSW_offDEX ) -#define PSW_mskHSS ( 0x1 << PSW_offHSS ) -#define PSW_mskDRBE ( 0x1 << PSW_offDRBE ) -#define PSW_mskAEN ( 0x1 << PSW_offAEN ) -#define PSW_mskWBNA ( 0x1 << PSW_offWBNA ) -#define PSW_mskIFCON ( 0x1 << PSW_offIFCON ) -#define PSW_mskCPL ( 0x7 << PSW_offCPL ) - -#define PSW_SYSTEM ( 1 << PSW_offPOM ) -#define PSW_INTL_1 ( 1 << PSW_offINTL ) -#define PSW_CPL_NO ( 0 << PSW_offCPL ) -#define PSW_CPL_ANY ( 7 << PSW_offCPL ) - -#define PSW_clr (PSW_mskGIE|PSW_mskINTL|PSW_mskPOM|PSW_mskIT|PSW_mskDT|PSW_mskIME|PSW_mskWBNA) -#ifdef __NDS32_EB__ -#ifdef CONFIG_WBNA -#define PSW_init (PSW_mskWBNA|(1< - -#define PG_dcache_dirty PG_arch_1 - -void flush_icache_range(unsigned long start, unsigned long end); -#define flush_icache_range flush_icache_range - -void flush_icache_page(struct vm_area_struct *vma, struct page *page); -#define flush_icache_page flush_icache_page - -#ifdef CONFIG_CPU_CACHE_ALIASING -void flush_cache_mm(struct mm_struct *mm); -void flush_cache_dup_mm(struct mm_struct *mm); -void flush_cache_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end); -void flush_cache_page(struct vm_area_struct *vma, - unsigned long addr, unsigned long pfn); -void flush_cache_kmaps(void); -void flush_cache_vmap(unsigned long start, unsigned long end); -void flush_cache_vunmap(unsigned long start, unsigned long end); - -#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 -void flush_dcache_page(struct page *page); -void copy_to_user_page(struct vm_area_struct *vma, struct page *page, - unsigned long vaddr, void *dst, void *src, int len); -void copy_from_user_page(struct vm_area_struct *vma, struct page *page, - unsigned long vaddr, void *dst, void *src, int len); - -#define ARCH_HAS_FLUSH_ANON_PAGE -void flush_anon_page(struct vm_area_struct *vma, - struct page *page, unsigned long vaddr); - -#define ARCH_IMPLEMENTS_FLUSH_KERNEL_VMAP_RANGE 1 -void flush_kernel_vmap_range(void *addr, int size); -void invalidate_kernel_vmap_range(void *addr, int size); -#define flush_dcache_mmap_lock(mapping) xa_lock_irq(&(mapping)->i_pages) -#define flush_dcache_mmap_unlock(mapping) xa_unlock_irq(&(mapping)->i_pages) - -#else -void flush_icache_user_page(struct vm_area_struct *vma, struct page *page, - unsigned long addr, int len); -#define flush_icache_user_page flush_icache_user_page - -#include -#endif - -#endif /* __NDS32_CACHEFLUSH_H__ */ diff --git a/arch/nds32/include/asm/current.h b/arch/nds32/include/asm/current.h deleted file mode 100644 index 65d30096142b..000000000000 --- a/arch/nds32/include/asm/current.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef _ASM_NDS32_CURRENT_H -#define _ASM_NDS32_CURRENT_H - -#ifndef __ASSEMBLY__ -register struct task_struct *current asm("$r25"); -#endif /* __ASSEMBLY__ */ -#define tsk $r25 - -#endif /* _ASM_NDS32_CURRENT_H */ diff --git a/arch/nds32/include/asm/delay.h b/arch/nds32/include/asm/delay.h deleted file mode 100644 index 56ea3894f8f8..000000000000 --- a/arch/nds32/include/asm/delay.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __NDS32_DELAY_H__ -#define __NDS32_DELAY_H__ - -#include - -/* There is no clocksource cycle counter in the CPU. */ -static inline void __delay(unsigned long loops) -{ - __asm__ __volatile__(".align 2\n" - "1:\n" - "\taddi\t%0, %0, -1\n" - "\tbgtz\t%0, 1b\n" - :"=r"(loops) - :"0"(loops)); -} - -static inline void __udelay(unsigned long usecs, unsigned long lpj) -{ - usecs *= (unsigned long)(((0x8000000000000000ULL / (500000 / HZ)) + - 0x80000000ULL) >> 32); - usecs = (unsigned long)(((unsigned long long)usecs * lpj) >> 32); - __delay(usecs); -} - -#define udelay(usecs) __udelay((usecs), loops_per_jiffy) - -/* make sure "usecs *= ..." in udelay do not overflow. */ -#if HZ >= 1000 -#define MAX_UDELAY_MS 1 -#elif HZ <= 200 -#define MAX_UDELAY_MS 5 -#else -#define MAX_UDELAY_MS (1000 / HZ) -#endif - -#endif diff --git a/arch/nds32/include/asm/elf.h b/arch/nds32/include/asm/elf.h deleted file mode 100644 index 1853dc89b8ac..000000000000 --- a/arch/nds32/include/asm/elf.h +++ /dev/null @@ -1,180 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __ASMNDS32_ELF_H -#define __ASMNDS32_ELF_H - -/* - * ELF register definitions.. - */ - -#include -#include -#include - -typedef unsigned long elf_greg_t; -typedef unsigned long elf_freg_t[3]; - -extern unsigned int elf_hwcap; - -#define R_NDS32_NONE 0 -#define R_NDS32_16_RELA 19 -#define R_NDS32_32_RELA 20 -#define R_NDS32_9_PCREL_RELA 22 -#define R_NDS32_15_PCREL_RELA 23 -#define R_NDS32_17_PCREL_RELA 24 -#define R_NDS32_25_PCREL_RELA 25 -#define R_NDS32_HI20_RELA 26 -#define R_NDS32_LO12S3_RELA 27 -#define R_NDS32_LO12S2_RELA 28 -#define R_NDS32_LO12S1_RELA 29 -#define R_NDS32_LO12S0_RELA 30 -#define R_NDS32_SDA15S3_RELA 31 -#define R_NDS32_SDA15S2_RELA 32 -#define R_NDS32_SDA15S1_RELA 33 -#define R_NDS32_SDA15S0_RELA 34 -#define R_NDS32_GOT20 37 -#define R_NDS32_25_PLTREL 38 -#define R_NDS32_COPY 39 -#define R_NDS32_GLOB_DAT 40 -#define R_NDS32_JMP_SLOT 41 -#define R_NDS32_RELATIVE 42 -#define R_NDS32_GOTOFF 43 -#define R_NDS32_GOTPC20 44 -#define R_NDS32_GOT_HI20 45 -#define R_NDS32_GOT_LO12 46 -#define R_NDS32_GOTPC_HI20 47 -#define R_NDS32_GOTPC_LO12 48 -#define R_NDS32_GOTOFF_HI20 49 -#define R_NDS32_GOTOFF_LO12 50 -#define R_NDS32_INSN16 51 -#define R_NDS32_LABEL 52 -#define R_NDS32_LONGCALL1 53 -#define R_NDS32_LONGCALL2 54 -#define R_NDS32_LONGCALL3 55 -#define R_NDS32_LONGJUMP1 56 -#define R_NDS32_LONGJUMP2 57 -#define R_NDS32_LONGJUMP3 58 -#define R_NDS32_LOADSTORE 59 -#define R_NDS32_9_FIXED_RELA 60 -#define R_NDS32_15_FIXED_RELA 61 -#define R_NDS32_17_FIXED_RELA 62 -#define R_NDS32_25_FIXED_RELA 63 -#define R_NDS32_PLTREL_HI20 64 -#define R_NDS32_PLTREL_LO12 65 -#define R_NDS32_PLT_GOTREL_HI20 66 -#define R_NDS32_PLT_GOTREL_LO12 67 -#define R_NDS32_LO12S0_ORI_RELA 72 -#define R_NDS32_DWARF2_OP1_RELA 77 -#define R_NDS32_DWARF2_OP2_RELA 78 -#define R_NDS32_DWARF2_LEB_RELA 79 -#define R_NDS32_WORD_9_PCREL_RELA 94 -#define R_NDS32_LONGCALL4 107 -#define R_NDS32_RELA_NOP_MIX 192 -#define R_NDS32_RELA_NOP_MAX 255 - -#define ELF_NGREG (sizeof (struct user_pt_regs) / sizeof(elf_greg_t)) -#define ELF_CORE_COPY_REGS(dest, regs) \ - *(struct user_pt_regs *)&(dest) = (regs)->user_regs; - -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -/* Core file format: The core file is written in such a way that gdb - can understand it and provide useful information to the user (under - linux we use the 'trad-core' bfd). There are quite a number of - obstacles to being able to view the contents of the floating point - registers, and until these are solved you will not be able to view the - contents of them. Actually, you can read in the core file and look at - the contents of the user struct to find out what the floating point - registers contain. - The actual file contents are as follows: - UPAGE: 1 page consisting of a user struct that tells gdb what is present - in the file. Directly after this is a copy of the task_struct, which - is currently not used by gdb, but it may come in useful at some point. - All of the registers are stored as part of the upage. The upage should - always be only one page. - DATA: The data area is stored. We use current->end_text to - current->brk to pick up all of the user variables, plus any memory - that may have been malloced. No attempt is made to determine if a page - is demand-zero or if a page is totally unused, we just cover the entire - range. All of the addresses are rounded in such a way that an integral - number of pages is written. - STACK: We need the stack information in order to get a meaningful - backtrace. We need to write the data from (esp) to - current->start_stack, so we round each of these off in order to be able - to write an integer number of pages. - The minimum core file size is 3 pages, or 12288 bytes. -*/ - -struct user_fp { - unsigned long long fd_regs[32]; - unsigned long fpcsr; -}; - -typedef struct user_fp elf_fpregset_t; - -struct elf32_hdr; -#define elf_check_arch(x) ((x)->e_machine == EM_NDS32) - -/* - * These are used to set parameters in the core dumps. - */ -#define ELF_CLASS ELFCLASS32 -#ifdef __NDS32_EB__ -#define ELF_DATA ELFDATA2MSB -#else -#define ELF_DATA ELFDATA2LSB -#endif -#define ELF_ARCH EM_NDS32 -#define ELF_EXEC_PAGESIZE PAGE_SIZE - -/* This is the location that an ET_DYN program is loaded if exec'ed. Typical - use of this is to invoke "./ld.so someprog" to test out a new version of - the loader. We need to make sure that it is out of the way of the program - that it will "exec", and that there is sufficient room for the brk. */ - -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) - -/* When the program starts, a1 contains a pointer to a function to be - registered with atexit, as per the SVR4 ABI. A value of 0 means we - have no such handler. */ -#define ELF_PLAT_INIT(_r, load_addr) (_r)->uregs[0] = 0 - -/* This yields a mask that user programs can use to figure out what - instruction set this cpu supports. */ - -#define ELF_HWCAP (elf_hwcap) - -#ifdef __KERNEL__ - -#define ELF_PLATFORM (NULL) - -/* Old NetWinder binaries were compiled in such a way that the iBCS - heuristic always trips on them. Until these binaries become uncommon - enough not to care, don't trust the `ibcs' flag here. In any case - there is no other ELF system currently supported by iBCS. - @@ Could print a warning message to encourage users to upgrade. */ -#define SET_PERSONALITY(ex) set_personality(PER_LINUX) - -#endif - - -#if IS_ENABLED(CONFIG_FPU) -#define FPU_AUX_ENT NEW_AUX_ENT(AT_FPUCW, FPCSR_INIT) -#else -#define FPU_AUX_ENT NEW_AUX_ENT(AT_IGNORE, 0) -#endif - -#define ARCH_DLINFO \ -do { \ - /* Optional FPU initialization */ \ - FPU_AUX_ENT; \ - \ - NEW_AUX_ENT(AT_SYSINFO_EHDR, \ - (elf_addr_t)current->mm->context.vdso); \ -} while (0) -#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 -struct linux_binprm; -int arch_setup_additional_pages(struct linux_binprm *, int); - -#endif diff --git a/arch/nds32/include/asm/fixmap.h b/arch/nds32/include/asm/fixmap.h deleted file mode 100644 index 2fa09a2de428..000000000000 --- a/arch/nds32/include/asm/fixmap.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __ASM_NDS32_FIXMAP_H -#define __ASM_NDS32_FIXMAP_H - -#ifdef CONFIG_HIGHMEM -#include -#include -#endif - -enum fixed_addresses { - FIX_HOLE, - FIX_KMAP_RESERVED, - FIX_KMAP_BEGIN, -#ifdef CONFIG_HIGHMEM - FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1, -#endif - FIX_EARLYCON_MEM_BASE, - __end_of_fixed_addresses -}; -#define FIXADDR_TOP ((unsigned long) (-(16 * PAGE_SIZE))) -#define FIXADDR_SIZE ((__end_of_fixed_addresses) << PAGE_SHIFT) -#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) -#define FIXMAP_PAGE_IO __pgprot(PAGE_DEVICE) -void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot); - -#include -#endif /* __ASM_NDS32_FIXMAP_H */ diff --git a/arch/nds32/include/asm/fpu.h b/arch/nds32/include/asm/fpu.h deleted file mode 100644 index 8294ed4aaa2c..000000000000 --- a/arch/nds32/include/asm/fpu.h +++ /dev/null @@ -1,126 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2005-2018 Andes Technology Corporation */ - -#ifndef __ASM_NDS32_FPU_H -#define __ASM_NDS32_FPU_H - -#if IS_ENABLED(CONFIG_FPU) -#ifndef __ASSEMBLY__ -#include -#include -#include - -extern bool has_fpu; - -extern void save_fpu(struct task_struct *__tsk); -extern void load_fpu(const struct fpu_struct *fpregs); -extern bool do_fpu_exception(unsigned int subtype, struct pt_regs *regs); -extern int do_fpuemu(struct pt_regs *regs, struct fpu_struct *fpu); - -#define test_tsk_fpu(regs) (regs->fucop_ctl & FUCOP_CTL_mskCP0EN) - -/* - * Initially load the FPU with signalling NANS. This bit pattern - * has the property that no matter whether considered as single or as - * double precision, it still represents a signalling NAN. - */ - -#define sNAN64 0xFFFFFFFFFFFFFFFFULL -#define sNAN32 0xFFFFFFFFUL - -#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC) -/* - * Denormalized number is unsupported by nds32 FPU. Hence the operation - * is treated as underflow cases when the final result is a denormalized - * number. To enhance precision, underflow exception trap should be - * enabled by default and kerenl will re-execute it by fpu emulator - * when getting underflow exception. - */ -#define FPCSR_INIT (FPCSR_mskUDFE | FPCSR_mskIEXE) -#else -#define FPCSR_INIT 0x0UL -#endif - -extern const struct fpu_struct init_fpuregs; - -static inline void disable_ptreg_fpu(struct pt_regs *regs) -{ - regs->fucop_ctl &= ~FUCOP_CTL_mskCP0EN; -} - -static inline void enable_ptreg_fpu(struct pt_regs *regs) -{ - regs->fucop_ctl |= FUCOP_CTL_mskCP0EN; -} - -static inline void enable_fpu(void) -{ - unsigned long fucop_ctl; - - fucop_ctl = __nds32__mfsr(NDS32_SR_FUCOP_CTL) | FUCOP_CTL_mskCP0EN; - __nds32__mtsr(fucop_ctl, NDS32_SR_FUCOP_CTL); - __nds32__isb(); -} - -static inline void disable_fpu(void) -{ - unsigned long fucop_ctl; - - fucop_ctl = __nds32__mfsr(NDS32_SR_FUCOP_CTL) & ~FUCOP_CTL_mskCP0EN; - __nds32__mtsr(fucop_ctl, NDS32_SR_FUCOP_CTL); - __nds32__isb(); -} - -static inline void lose_fpu(void) -{ - preempt_disable(); -#if IS_ENABLED(CONFIG_LAZY_FPU) - if (last_task_used_math == current) { - last_task_used_math = NULL; -#else - if (test_tsk_fpu(task_pt_regs(current))) { -#endif - save_fpu(current); - } - disable_ptreg_fpu(task_pt_regs(current)); - preempt_enable(); -} - -static inline void own_fpu(void) -{ - preempt_disable(); -#if IS_ENABLED(CONFIG_LAZY_FPU) - if (last_task_used_math != current) { - if (last_task_used_math != NULL) - save_fpu(last_task_used_math); - load_fpu(¤t->thread.fpu); - last_task_used_math = current; - } -#else - if (!test_tsk_fpu(task_pt_regs(current))) { - load_fpu(¤t->thread.fpu); - } -#endif - enable_ptreg_fpu(task_pt_regs(current)); - preempt_enable(); -} - -#if !IS_ENABLED(CONFIG_LAZY_FPU) -static inline void unlazy_fpu(struct task_struct *tsk) -{ - preempt_disable(); - if (test_tsk_fpu(task_pt_regs(tsk))) - save_fpu(tsk); - preempt_enable(); -} -#endif /* !CONFIG_LAZY_FPU */ -static inline void clear_fpu(struct pt_regs *regs) -{ - preempt_disable(); - if (test_tsk_fpu(regs)) - disable_ptreg_fpu(regs); - preempt_enable(); -} -#endif /* CONFIG_FPU */ -#endif /* __ASSEMBLY__ */ -#endif /* __ASM_NDS32_FPU_H */ diff --git a/arch/nds32/include/asm/fpuemu.h b/arch/nds32/include/asm/fpuemu.h deleted file mode 100644 index 63e7ef5f7969..000000000000 --- a/arch/nds32/include/asm/fpuemu.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2005-2018 Andes Technology Corporation */ - -#ifndef __ARCH_NDS32_FPUEMU_H -#define __ARCH_NDS32_FPUEMU_H - -/* - * single precision - */ - -void fadds(void *ft, void *fa, void *fb); -void fsubs(void *ft, void *fa, void *fb); -void fmuls(void *ft, void *fa, void *fb); -void fdivs(void *ft, void *fa, void *fb); -void fs2d(void *ft, void *fa); -void fs2si(void *ft, void *fa); -void fs2si_z(void *ft, void *fa); -void fs2ui(void *ft, void *fa); -void fs2ui_z(void *ft, void *fa); -void fsi2s(void *ft, void *fa); -void fui2s(void *ft, void *fa); -void fsqrts(void *ft, void *fa); -void fnegs(void *ft, void *fa); -int fcmps(void *ft, void *fa, void *fb, int cop); - -/* - * double precision - */ -void faddd(void *ft, void *fa, void *fb); -void fsubd(void *ft, void *fa, void *fb); -void fmuld(void *ft, void *fa, void *fb); -void fdivd(void *ft, void *fa, void *fb); -void fsqrtd(void *ft, void *fa); -void fd2s(void *ft, void *fa); -void fd2si(void *ft, void *fa); -void fd2si_z(void *ft, void *fa); -void fd2ui(void *ft, void *fa); -void fd2ui_z(void *ft, void *fa); -void fsi2d(void *ft, void *fa); -void fui2d(void *ft, void *fa); -void fnegd(void *ft, void *fa); -int fcmpd(void *ft, void *fa, void *fb, int cop); - -#endif /* __ARCH_NDS32_FPUEMU_H */ diff --git a/arch/nds32/include/asm/ftrace.h b/arch/nds32/include/asm/ftrace.h deleted file mode 100644 index 2f96cc96aa35..000000000000 --- a/arch/nds32/include/asm/ftrace.h +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -#ifndef __ASM_NDS32_FTRACE_H -#define __ASM_NDS32_FTRACE_H - -#ifdef CONFIG_FUNCTION_TRACER - -#define HAVE_FUNCTION_GRAPH_FP_TEST - -#define MCOUNT_ADDR ((unsigned long)(_mcount)) -/* mcount call is composed of three instructions: - * sethi + ori + jral - */ -#define MCOUNT_INSN_SIZE 12 - -extern void _mcount(unsigned long parent_ip); - -#ifdef CONFIG_DYNAMIC_FTRACE - -#define FTRACE_ADDR ((unsigned long)_ftrace_caller) - -#ifdef __NDS32_EL__ -#define INSN_NOP 0x09000040 -#define INSN_SIZE(insn) (((insn & 0x00000080) == 0) ? 4 : 2) -#define IS_SETHI(insn) ((insn & 0x000000fe) == 0x00000046) -#define ENDIAN_CONVERT(insn) be32_to_cpu(insn) -#else /* __NDS32_EB__ */ -#define INSN_NOP 0x40000009 -#define INSN_SIZE(insn) (((insn & 0x80000000) == 0) ? 4 : 2) -#define IS_SETHI(insn) ((insn & 0xfe000000) == 0x46000000) -#define ENDIAN_CONVERT(insn) (insn) -#endif - -extern void _ftrace_caller(unsigned long parent_ip); -static inline unsigned long ftrace_call_adjust(unsigned long addr) -{ - return addr; -} -struct dyn_arch_ftrace { -}; - -#endif /* CONFIG_DYNAMIC_FTRACE */ - -#endif /* CONFIG_FUNCTION_TRACER */ - -#endif /* __ASM_NDS32_FTRACE_H */ diff --git a/arch/nds32/include/asm/futex.h b/arch/nds32/include/asm/futex.h deleted file mode 100644 index 4223f473bd36..000000000000 --- a/arch/nds32/include/asm/futex.h +++ /dev/null @@ -1,101 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __NDS32_FUTEX_H__ -#define __NDS32_FUTEX_H__ - -#include -#include -#include - -#define __futex_atomic_ex_table(err_reg) \ - " .pushsection __ex_table,\"a\"\n" \ - " .align 3\n" \ - " .long 1b, 4f\n" \ - " .long 2b, 4f\n" \ - " .popsection\n" \ - " .pushsection .fixup,\"ax\"\n" \ - "4: move %0, " err_reg "\n" \ - " b 3b\n" \ - " .popsection" - -#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \ - smp_mb(); \ - asm volatile( \ - " movi $ta, #0\n" \ - "1: llw %1, [%2+$ta]\n" \ - " " insn "\n" \ - "2: scw %0, [%2+$ta]\n" \ - " beqz %0, 1b\n" \ - " movi %0, #0\n" \ - "3:\n" \ - __futex_atomic_ex_table("%4") \ - : "=&r" (ret), "=&r" (oldval) \ - : "r" (uaddr), "r" (oparg), "i" (-EFAULT) \ - : "cc", "memory") -static inline int -futex_atomic_cmpxchg_inatomic(u32 * uval, u32 __user * uaddr, - u32 oldval, u32 newval) -{ - int ret = 0; - u32 val, tmp, flags; - - if (!access_ok(uaddr, sizeof(u32))) - return -EFAULT; - - smp_mb(); - asm volatile (" movi $ta, #0\n" - "1: llw %1, [%6 + $ta]\n" - " sub %3, %1, %4\n" - " cmovz %2, %5, %3\n" - " cmovn %2, %1, %3\n" - "2: scw %2, [%6 + $ta]\n" - " beqz %2, 1b\n" - "3:\n " __futex_atomic_ex_table("%7") - :"+&r"(ret), "=&r"(val), "=&r"(tmp), "=&r"(flags) - :"r"(oldval), "r"(newval), "r"(uaddr), "i"(-EFAULT) - :"$ta", "memory"); - smp_mb(); - - *uval = val; - return ret; -} - -static inline int -arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) -{ - int oldval = 0, ret; - - if (!access_ok(uaddr, sizeof(u32))) - return -EFAULT; - switch (op) { - case FUTEX_OP_SET: - __futex_atomic_op("move %0, %3", ret, oldval, tmp, uaddr, - oparg); - break; - case FUTEX_OP_ADD: - __futex_atomic_op("add %0, %1, %3", ret, oldval, tmp, uaddr, - oparg); - break; - case FUTEX_OP_OR: - __futex_atomic_op("or %0, %1, %3", ret, oldval, tmp, uaddr, - oparg); - break; - case FUTEX_OP_ANDN: - __futex_atomic_op("and %0, %1, %3", ret, oldval, tmp, uaddr, - ~oparg); - break; - case FUTEX_OP_XOR: - __futex_atomic_op("xor %0, %1, %3", ret, oldval, tmp, uaddr, - oparg); - break; - default: - ret = -ENOSYS; - } - - if (!ret) - *oval = oldval; - - return ret; -} -#endif /* __NDS32_FUTEX_H__ */ diff --git a/arch/nds32/include/asm/highmem.h b/arch/nds32/include/asm/highmem.h deleted file mode 100644 index 16159a8716f2..000000000000 --- a/arch/nds32/include/asm/highmem.h +++ /dev/null @@ -1,65 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef _ASM_HIGHMEM_H -#define _ASM_HIGHMEM_H - -#include -#include - -/* - * Right now we initialize only a single pte table. It can be extended - * easily, subsequent pte tables have to be allocated in one physical - * chunk of RAM. - */ -/* - * Ordering is (from lower to higher memory addresses): - * - * high_memory - * Persistent kmap area - * PKMAP_BASE - * fixed_addresses - * FIXADDR_START - * FIXADDR_TOP - * Vmalloc area - * VMALLOC_START - * VMALLOC_END - */ -#define PKMAP_BASE ((FIXADDR_START - PGDIR_SIZE) & (PGDIR_MASK)) -#define LAST_PKMAP PTRS_PER_PTE -#define LAST_PKMAP_MASK (LAST_PKMAP - 1) -#define PKMAP_NR(virt) (((virt) - (PKMAP_BASE)) >> PAGE_SHIFT) -#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) - -static inline void flush_cache_kmaps(void) -{ - cpu_dcache_wbinval_all(); -} - -/* declarations for highmem.c */ -extern unsigned long highstart_pfn, highend_pfn; - -extern pte_t *pkmap_page_table; - -extern void kmap_init(void); - -/* - * FIXME: The below looks broken vs. a kmap_atomic() in task context which - * is interupted and another kmap_atomic() happens in interrupt context. - * But what do I know about nds32. -- tglx - */ -#define arch_kmap_local_post_map(vaddr, pteval) \ - do { \ - __nds32__tlbop_inv(vaddr); \ - __nds32__mtsr_dsb(vaddr, NDS32_SR_TLB_VPN); \ - __nds32__tlbop_rwr(pteval); \ - __nds32__isb(); \ - } while (0) - -#define arch_kmap_local_pre_unmap(vaddr) \ - do { \ - __nds32__tlbop_inv(vaddr); \ - __nds32__isb(); \ - } while (0) - -#endif diff --git a/arch/nds32/include/asm/io.h b/arch/nds32/include/asm/io.h deleted file mode 100644 index e57378d04006..000000000000 --- a/arch/nds32/include/asm/io.h +++ /dev/null @@ -1,84 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __ASM_NDS32_IO_H -#define __ASM_NDS32_IO_H - -#include - -#define __raw_writeb __raw_writeb -static inline void __raw_writeb(u8 val, volatile void __iomem *addr) -{ - asm volatile("sbi %0, [%1]" : : "r" (val), "r" (addr)); -} - -#define __raw_writew __raw_writew -static inline void __raw_writew(u16 val, volatile void __iomem *addr) -{ - asm volatile("shi %0, [%1]" : : "r" (val), "r" (addr)); -} - -#define __raw_writel __raw_writel -static inline void __raw_writel(u32 val, volatile void __iomem *addr) -{ - asm volatile("swi %0, [%1]" : : "r" (val), "r" (addr)); -} - -#define __raw_readb __raw_readb -static inline u8 __raw_readb(const volatile void __iomem *addr) -{ - u8 val; - - asm volatile("lbi %0, [%1]" : "=r" (val) : "r" (addr)); - return val; -} - -#define __raw_readw __raw_readw -static inline u16 __raw_readw(const volatile void __iomem *addr) -{ - u16 val; - - asm volatile("lhi %0, [%1]" : "=r" (val) : "r" (addr)); - return val; -} - -#define __raw_readl __raw_readl -static inline u32 __raw_readl(const volatile void __iomem *addr) -{ - u32 val; - - asm volatile("lwi %0, [%1]" : "=r" (val) : "r" (addr)); - return val; -} - -#define __iormb() rmb() -#define __iowmb() wmb() - -/* - * {read,write}{b,w,l,q}_relaxed() are like the regular version, but - * are not guaranteed to provide ordering against spinlocks or memory - * accesses. - */ - -#define readb_relaxed(c) ({ u8 __v = __raw_readb(c); __v; }) -#define readw_relaxed(c) ({ u16 __v = le16_to_cpu((__force __le16)__raw_readw(c)); __v; }) -#define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32)__raw_readl(c)); __v; }) -#define writeb_relaxed(v,c) ((void)__raw_writeb((v),(c))) -#define writew_relaxed(v,c) ((void)__raw_writew((__force u16)cpu_to_le16(v),(c))) -#define writel_relaxed(v,c) ((void)__raw_writel((__force u32)cpu_to_le32(v),(c))) - -/* - * {read,write}{b,w,l,q}() access little endian memory and return result in - * native endianness. - */ -#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) -#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) -#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) - -#define writeb(v,c) ({ __iowmb(); writeb_relaxed((v),(c)); }) -#define writew(v,c) ({ __iowmb(); writew_relaxed((v),(c)); }) -#define writel(v,c) ({ __iowmb(); writel_relaxed((v),(c)); }) - -#include - -#endif /* __ASM_NDS32_IO_H */ diff --git a/arch/nds32/include/asm/irqflags.h b/arch/nds32/include/asm/irqflags.h deleted file mode 100644 index 51ef800bb301..000000000000 --- a/arch/nds32/include/asm/irqflags.h +++ /dev/null @@ -1,41 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include - -#define arch_local_irq_disable() \ - GIE_DISABLE(); - -#define arch_local_irq_enable() \ - GIE_ENABLE(); -static inline unsigned long arch_local_irq_save(void) -{ - unsigned long flags; - flags = __nds32__mfsr(NDS32_SR_PSW) & PSW_mskGIE; - GIE_DISABLE(); - return flags; -} - -static inline unsigned long arch_local_save_flags(void) -{ - unsigned long flags; - flags = __nds32__mfsr(NDS32_SR_PSW) & PSW_mskGIE; - return flags; -} - -static inline void arch_local_irq_restore(unsigned long flags) -{ - if(flags) - GIE_ENABLE(); -} - -static inline int arch_irqs_disabled_flags(unsigned long flags) -{ - return !flags; -} - -static inline int arch_irqs_disabled(void) -{ - return arch_irqs_disabled_flags(arch_local_save_flags()); -} diff --git a/arch/nds32/include/asm/l2_cache.h b/arch/nds32/include/asm/l2_cache.h deleted file mode 100644 index 3ea48e19e6de..000000000000 --- a/arch/nds32/include/asm/l2_cache.h +++ /dev/null @@ -1,137 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef L2_CACHE_H -#define L2_CACHE_H - -/* CCTL_CMD_OP */ -#define L2_CA_CONF_OFF 0x0 -#define L2_IF_CONF_OFF 0x4 -#define L2CC_SETUP_OFF 0x8 -#define L2CC_PROT_OFF 0xC -#define L2CC_CTRL_OFF 0x10 -#define L2_INT_EN_OFF 0x20 -#define L2_STA_OFF 0x24 -#define RDERR_ADDR_OFF 0x28 -#define WRERR_ADDR_OFF 0x2c -#define EVDPTERR_ADDR_OFF 0x30 -#define IMPL3ERR_ADDR_OFF 0x34 -#define L2_CNT0_CTRL_OFF 0x40 -#define L2_EVNT_CNT0_OFF 0x44 -#define L2_CNT1_CTRL_OFF 0x48 -#define L2_EVNT_CNT1_OFF 0x4c -#define L2_CCTL_CMD_OFF 0x60 -#define L2_CCTL_STATUS_OFF 0x64 -#define L2_LINE_TAG_OFF 0x68 -#define L2_LINE_DPT_OFF 0x70 - -#define CCTL_CMD_L2_IX_INVAL 0x0 -#define CCTL_CMD_L2_PA_INVAL 0x1 -#define CCTL_CMD_L2_IX_WB 0x2 -#define CCTL_CMD_L2_PA_WB 0x3 -#define CCTL_CMD_L2_PA_WBINVAL 0x5 -#define CCTL_CMD_L2_SYNC 0xa - -/* CCTL_CMD_TYPE */ -#define CCTL_SINGLE_CMD 0 -#define CCTL_BLOCK_CMD 0x10 -#define CCTL_ALL_CMD 0x10 - -/****************************************************************************** - * L2_CA_CONF (Cache architecture configuration) - *****************************************************************************/ -#define L2_CA_CONF_offL2SET 0 -#define L2_CA_CONF_offL2WAY 4 -#define L2_CA_CONF_offL2CLSZ 8 -#define L2_CA_CONF_offL2DW 11 -#define L2_CA_CONF_offL2PT 14 -#define L2_CA_CONF_offL2VER 16 - -#define L2_CA_CONF_mskL2SET (0xFUL << L2_CA_CONF_offL2SET) -#define L2_CA_CONF_mskL2WAY (0xFUL << L2_CA_CONF_offL2WAY) -#define L2_CA_CONF_mskL2CLSZ (0x7UL << L2_CA_CONF_offL2CLSZ) -#define L2_CA_CONF_mskL2DW (0x7UL << L2_CA_CONF_offL2DW) -#define L2_CA_CONF_mskL2PT (0x3UL << L2_CA_CONF_offL2PT) -#define L2_CA_CONF_mskL2VER (0xFFFFUL << L2_CA_CONF_offL2VER) - -/****************************************************************************** - * L2CC_SETUP (L2CC Setup register) - *****************************************************************************/ -#define L2CC_SETUP_offPART 0 -#define L2CC_SETUP_mskPART (0x3UL << L2CC_SETUP_offPART) -#define L2CC_SETUP_offDDLATC 4 -#define L2CC_SETUP_mskDDLATC (0x3UL << L2CC_SETUP_offDDLATC) -#define L2CC_SETUP_offTDLATC 8 -#define L2CC_SETUP_mskTDLATC (0x3UL << L2CC_SETUP_offTDLATC) - -/****************************************************************************** - * L2CC_PROT (L2CC Protect register) - *****************************************************************************/ -#define L2CC_PROT_offMRWEN 31 -#define L2CC_PROT_mskMRWEN (0x1UL << L2CC_PROT_offMRWEN) - -/****************************************************************************** - * L2_CCTL_STATUS_Mn (The L2CCTL command working status for Master n) - *****************************************************************************/ -#define L2CC_CTRL_offEN 31 -#define L2CC_CTRL_mskEN (0x1UL << L2CC_CTRL_offEN) - -/****************************************************************************** - * L2_CCTL_STATUS_Mn (The L2CCTL command working status for Master n) - *****************************************************************************/ -#define L2_CCTL_STATUS_offCMD_COMP 31 -#define L2_CCTL_STATUS_mskCMD_COMP (0x1 << L2_CCTL_STATUS_offCMD_COMP) - -extern void __iomem *atl2c_base; -#include -#include -#include - -#define L2C_R_REG(offset) readl(atl2c_base + offset) -#define L2C_W_REG(offset, value) writel(value, atl2c_base + offset) - -#define L2_CMD_RDY() \ - do{;}while((L2C_R_REG(L2_CCTL_STATUS_OFF) & L2_CCTL_STATUS_mskCMD_COMP) == 0) - -static inline unsigned long L2_CACHE_SET(void) -{ - return 64 << ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2SET) >> - L2_CA_CONF_offL2SET); -} - -static inline unsigned long L2_CACHE_WAY(void) -{ - return 1 + - ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2WAY) >> - L2_CA_CONF_offL2WAY); -} - -static inline unsigned long L2_CACHE_LINE_SIZE(void) -{ - - return 4 << ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2CLSZ) >> - L2_CA_CONF_offL2CLSZ); -} - -static inline unsigned long GET_L2CC_CTRL_CPU(unsigned long cpu) -{ - if (cpu == smp_processor_id()) - return L2C_R_REG(L2CC_CTRL_OFF); - return L2C_R_REG(L2CC_CTRL_OFF + (cpu << 8)); -} - -static inline void SET_L2CC_CTRL_CPU(unsigned long cpu, unsigned long val) -{ - if (cpu == smp_processor_id()) - L2C_W_REG(L2CC_CTRL_OFF, val); - else - L2C_W_REG(L2CC_CTRL_OFF + (cpu << 8), val); -} - -static inline unsigned long GET_L2CC_STATUS_CPU(unsigned long cpu) -{ - if (cpu == smp_processor_id()) - return L2C_R_REG(L2_CCTL_STATUS_OFF); - return L2C_R_REG(L2_CCTL_STATUS_OFF + (cpu << 8)); -} -#endif diff --git a/arch/nds32/include/asm/linkage.h b/arch/nds32/include/asm/linkage.h deleted file mode 100644 index a696469abb70..000000000000 --- a/arch/nds32/include/asm/linkage.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __ASM_LINKAGE_H -#define __ASM_LINKAGE_H - -/* This file is required by include/linux/linkage.h */ -#define __ALIGN .align 2 -#define __ALIGN_STR ".align 2" - -#endif diff --git a/arch/nds32/include/asm/memory.h b/arch/nds32/include/asm/memory.h deleted file mode 100644 index 62faafbc28e4..000000000000 --- a/arch/nds32/include/asm/memory.h +++ /dev/null @@ -1,91 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __ASM_NDS32_MEMORY_H -#define __ASM_NDS32_MEMORY_H - -#include -#include - -#ifndef __ASSEMBLY__ -#include -#endif - -#ifndef PHYS_OFFSET -#define PHYS_OFFSET (0x0) -#endif - -/* - * TASK_SIZE - the maximum size of a user space task. - * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area - */ -#define TASK_SIZE ((CONFIG_PAGE_OFFSET) - (SZ_32M)) -#define TASK_UNMAPPED_BASE ALIGN(TASK_SIZE / 3, SZ_32M) -#define PAGE_OFFSET (CONFIG_PAGE_OFFSET) - -/* - * Physical vs virtual RAM address space conversion. These are - * private definitions which should NOT be used outside memory.h - * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. - */ -#ifndef __virt_to_phys -#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET) -#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET) -#endif - -/* - * The module space lives between the addresses given by TASK_SIZE - * and PAGE_OFFSET - it must be within 32MB of the kernel text. - */ -#define MODULES_END (PAGE_OFFSET) -#define MODULES_VADDR (MODULES_END - SZ_32M) - -#if TASK_SIZE > MODULES_VADDR -#error Top of user space clashes with start of module space -#endif - -#ifndef __ASSEMBLY__ - -/* - * PFNs are used to describe any physical page; this means - * PFN 0 == physical address 0. - * - * This is the PFN of the first RAM page in the kernel - * direct-mapped view. We assume this is the first page - * of RAM in the mem_map as well. - */ -#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT) - -/* - * Drivers should NOT use these either. - */ -#define __pa(x) __virt_to_phys((unsigned long)(x)) -#define __va(x) ((void *)__phys_to_virt((unsigned long)(x))) - -/* - * Conversion between a struct page and a physical address. - * - * Note: when converting an unknown physical address to a - * struct page, the resulting pointer must be validated - * using VALID_PAGE(). It must return an invalid struct page - * for any physical address not corresponding to a system - * RAM address. - * - * pfn_valid(pfn) indicates whether a PFN number is valid - * - * virt_to_page(k) convert a _valid_ virtual address to struct page * - * virt_addr_valid(k) indicates whether a virtual address is valid - */ -#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET -#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr)) - -#define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)) -#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) - -#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) - -#endif - -#include - -#endif diff --git a/arch/nds32/include/asm/mmu.h b/arch/nds32/include/asm/mmu.h deleted file mode 100644 index 89d63afee455..000000000000 --- a/arch/nds32/include/asm/mmu.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __NDS32_MMU_H -#define __NDS32_MMU_H - -typedef struct { - unsigned int id; - void *vdso; -} mm_context_t; - -#endif diff --git a/arch/nds32/include/asm/mmu_context.h b/arch/nds32/include/asm/mmu_context.h deleted file mode 100644 index c651bc8cacdc..000000000000 --- a/arch/nds32/include/asm/mmu_context.h +++ /dev/null @@ -1,62 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __ASM_NDS32_MMU_CONTEXT_H -#define __ASM_NDS32_MMU_CONTEXT_H - -#include -#include -#include -#include - -#define init_new_context init_new_context -static inline int -init_new_context(struct task_struct *tsk, struct mm_struct *mm) -{ - mm->context.id = 0; - return 0; -} - -#define CID_BITS 9 -extern spinlock_t cid_lock; -extern unsigned int cpu_last_cid; - -static inline void __new_context(struct mm_struct *mm) -{ - unsigned int cid; - unsigned long flags; - - spin_lock_irqsave(&cid_lock, flags); - cid = cpu_last_cid; - cpu_last_cid += 1 << TLB_MISC_offCID; - if (cpu_last_cid == 0) - cpu_last_cid = 1 << TLB_MISC_offCID << CID_BITS; - - if ((cid & TLB_MISC_mskCID) == 0) - flush_tlb_all(); - spin_unlock_irqrestore(&cid_lock, flags); - - mm->context.id = cid; -} - -static inline void check_context(struct mm_struct *mm) -{ - if (unlikely - ((mm->context.id ^ cpu_last_cid) >> TLB_MISC_offCID >> CID_BITS)) - __new_context(mm); -} - -static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, - struct task_struct *tsk) -{ - unsigned int cpu = smp_processor_id(); - - if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) { - check_context(next); - cpu_switch_mm(next); - } -} - -#include - -#endif diff --git a/arch/nds32/include/asm/nds32.h b/arch/nds32/include/asm/nds32.h deleted file mode 100644 index 4994f6a9e0a0..000000000000 --- a/arch/nds32/include/asm/nds32.h +++ /dev/null @@ -1,82 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef _ASM_NDS32_NDS32_H_ -#define _ASM_NDS32_NDS32_H_ - -#include -#include - -#ifndef __ASSEMBLY__ -#include -#include -#include - -#ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE -#define FP_OFFSET (-3) -#else -#define FP_OFFSET (-2) -#endif -#define LP_OFFSET (-1) - -extern void __init early_trap_init(void); -static inline void GIE_ENABLE(void) -{ - mb(); - __nds32__gie_en(); -} - -static inline void GIE_DISABLE(void) -{ - mb(); - __nds32__gie_dis(); -} - -static inline unsigned long CACHE_SET(unsigned char cache) -{ - - if (cache == ICACHE) - return 64 << ((__nds32__mfsr(NDS32_SR_ICM_CFG) & ICM_CFG_mskISET) >> - ICM_CFG_offISET); - else - return 64 << ((__nds32__mfsr(NDS32_SR_DCM_CFG) & DCM_CFG_mskDSET) >> - DCM_CFG_offDSET); -} - -static inline unsigned long CACHE_WAY(unsigned char cache) -{ - - if (cache == ICACHE) - return 1 + - ((__nds32__mfsr(NDS32_SR_ICM_CFG) & ICM_CFG_mskIWAY) >> ICM_CFG_offIWAY); - else - return 1 + - ((__nds32__mfsr(NDS32_SR_DCM_CFG) & DCM_CFG_mskDWAY) >> DCM_CFG_offDWAY); -} - -static inline unsigned long CACHE_LINE_SIZE(unsigned char cache) -{ - - if (cache == ICACHE) - return 8 << - (((__nds32__mfsr(NDS32_SR_ICM_CFG) & ICM_CFG_mskISZ) >> ICM_CFG_offISZ) - 1); - else - return 8 << - (((__nds32__mfsr(NDS32_SR_DCM_CFG) & DCM_CFG_mskDSZ) >> DCM_CFG_offDSZ) - 1); -} - -#endif /* __ASSEMBLY__ */ - -#define IVB_BASE PHYS_OFFSET /* in user space for intr/exc/trap/break table base, 64KB aligned - * We defined at the start of the physical memory */ - -/* dispatched sub-entry exception handler numbering */ -#define RD_PROT 0 /* read protrection */ -#define WRT_PROT 1 /* write protection */ -#define NOEXEC 2 /* non executable */ -#define PAGE_MODIFY 3 /* page modified */ -#define ACC_BIT 4 /* access bit */ -#define RESVED_PTE 5 /* reserved PTE attribute */ -/* reserved 6 ~ 16 */ - -#endif /* _ASM_NDS32_NDS32_H_ */ diff --git a/arch/nds32/include/asm/nds32_fpu_inst.h b/arch/nds32/include/asm/nds32_fpu_inst.h deleted file mode 100644 index 1e4b86a90a48..000000000000 --- a/arch/nds32/include/asm/nds32_fpu_inst.h +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2005-2018 Andes Technology Corporation */ - -#ifndef __NDS32_FPU_INST_H -#define __NDS32_FPU_INST_H - -#define cop0_op 0x35 - -/* - * COP0 field of opcodes. - */ -#define fs1_op 0x0 -#define fs2_op 0x4 -#define fd1_op 0x8 -#define fd2_op 0xc - -/* - * FS1 opcode. - */ -enum fs1 { - fadds_op, fsubs_op, fcpynss_op, fcpyss_op, - fmadds_op, fmsubs_op, fcmovns_op, fcmovzs_op, - fnmadds_op, fnmsubs_op, - fmuls_op = 0xc, fdivs_op, - fs1_f2op_op = 0xf -}; - -/* - * FS1/F2OP opcode. - */ -enum fs1_f2 { - fs2d_op, fsqrts_op, - fui2s_op = 0x8, fsi2s_op = 0xc, - fs2ui_op = 0x10, fs2ui_z_op = 0x14, - fs2si_op = 0x18, fs2si_z_op = 0x1c -}; - -/* - * FS2 opcode. - */ -enum fs2 { - fcmpeqs_op, fcmpeqs_e_op, fcmplts_op, fcmplts_e_op, - fcmples_op, fcmples_e_op, fcmpuns_op, fcmpuns_e_op -}; - -/* - * FD1 opcode. - */ -enum fd1 { - faddd_op, fsubd_op, fcpynsd_op, fcpysd_op, - fmaddd_op, fmsubd_op, fcmovnd_op, fcmovzd_op, - fnmaddd_op, fnmsubd_op, - fmuld_op = 0xc, fdivd_op, fd1_f2op_op = 0xf -}; - -/* - * FD1/F2OP opcode. - */ -enum fd1_f2 { - fd2s_op, fsqrtd_op, - fui2d_op = 0x8, fsi2d_op = 0xc, - fd2ui_op = 0x10, fd2ui_z_op = 0x14, - fd2si_op = 0x18, fd2si_z_op = 0x1c -}; - -/* - * FD2 opcode. - */ -enum fd2 { - fcmpeqd_op, fcmpeqd_e_op, fcmpltd_op, fcmpltd_e_op, - fcmpled_op, fcmpled_e_op, fcmpund_op, fcmpund_e_op -}; - -#define NDS32Insn(x) x - -#define I_OPCODE_off 25 -#define NDS32Insn_OPCODE(x) (NDS32Insn(x) >> I_OPCODE_off) - -#define I_OPCODE_offRt 20 -#define I_OPCODE_mskRt (0x1fUL << I_OPCODE_offRt) -#define NDS32Insn_OPCODE_Rt(x) \ - ((NDS32Insn(x) & I_OPCODE_mskRt) >> I_OPCODE_offRt) - -#define I_OPCODE_offRa 15 -#define I_OPCODE_mskRa (0x1fUL << I_OPCODE_offRa) -#define NDS32Insn_OPCODE_Ra(x) \ - ((NDS32Insn(x) & I_OPCODE_mskRa) >> I_OPCODE_offRa) - -#define I_OPCODE_offRb 10 -#define I_OPCODE_mskRb (0x1fUL << I_OPCODE_offRb) -#define NDS32Insn_OPCODE_Rb(x) \ - ((NDS32Insn(x) & I_OPCODE_mskRb) >> I_OPCODE_offRb) - -#define I_OPCODE_offbit1014 10 -#define I_OPCODE_mskbit1014 (0x1fUL << I_OPCODE_offbit1014) -#define NDS32Insn_OPCODE_BIT1014(x) \ - ((NDS32Insn(x) & I_OPCODE_mskbit1014) >> I_OPCODE_offbit1014) - -#define I_OPCODE_offbit69 6 -#define I_OPCODE_mskbit69 (0xfUL << I_OPCODE_offbit69) -#define NDS32Insn_OPCODE_BIT69(x) \ - ((NDS32Insn(x) & I_OPCODE_mskbit69) >> I_OPCODE_offbit69) - -#define I_OPCODE_offCOP0 0 -#define I_OPCODE_mskCOP0 (0x3fUL << I_OPCODE_offCOP0) -#define NDS32Insn_OPCODE_COP0(x) \ - ((NDS32Insn(x) & I_OPCODE_mskCOP0) >> I_OPCODE_offCOP0) - -#endif /* __NDS32_FPU_INST_H */ diff --git a/arch/nds32/include/asm/page.h b/arch/nds32/include/asm/page.h deleted file mode 100644 index add33a7f02c8..000000000000 --- a/arch/nds32/include/asm/page.h +++ /dev/null @@ -1,64 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2005-2017 Andes Technology Corporation - */ - -#ifndef _ASMNDS32_PAGE_H -#define _ASMNDS32_PAGE_H - -#ifdef CONFIG_ANDES_PAGE_SIZE_4KB -#define PAGE_SHIFT 12 -#endif -#ifdef CONFIG_ANDES_PAGE_SIZE_8KB -#define PAGE_SHIFT 13 -#endif -#include -#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) - -#ifdef __KERNEL__ - -#ifndef __ASSEMBLY__ - -struct page; -struct vm_area_struct; -#ifdef CONFIG_CPU_CACHE_ALIASING -extern void copy_user_highpage(struct page *to, struct page *from, - unsigned long vaddr, struct vm_area_struct *vma); -extern void clear_user_highpage(struct page *page, unsigned long vaddr); - -void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, - struct page *to); -void clear_user_page(void *addr, unsigned long vaddr, struct page *page); -#define __HAVE_ARCH_COPY_USER_HIGHPAGE -#define clear_user_highpage clear_user_highpage -#else -#define clear_user_page(page, vaddr, pg) clear_page(page) -#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) -#endif - -void clear_page(void *page); -void copy_page(void *to, void *from); - -typedef unsigned long pte_t; -typedef unsigned long pgd_t; -typedef unsigned long pgprot_t; - -#define pte_val(x) (x) -#define pgd_val(x) (x) -#define pgprot_val(x) (x) - -#define __pte(x) (x) -#define __pgd(x) (x) -#define __pgprot(x) (x) - -typedef struct page *pgtable_t; - -#include -#include - -#endif /* !__ASSEMBLY__ */ - -#endif /* __KERNEL__ */ - -#endif diff --git a/arch/nds32/include/asm/perf_event.h b/arch/nds32/include/asm/perf_event.h deleted file mode 100644 index fcdff02acc14..000000000000 --- a/arch/nds32/include/asm/perf_event.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2008-2018 Andes Technology Corporation */ - -#ifndef __ASM_PERF_EVENT_H -#define __ASM_PERF_EVENT_H - -/* - * This file is request by Perf, - * please refer to tools/perf/design.txt for more details - */ -struct pt_regs; -unsigned long perf_instruction_pointer(struct pt_regs *regs); -unsigned long perf_misc_flags(struct pt_regs *regs); -#define perf_misc_flags(regs) perf_misc_flags(regs) - -#endif diff --git a/arch/nds32/include/asm/pgalloc.h b/arch/nds32/include/asm/pgalloc.h deleted file mode 100644 index a08e1ebca70e..000000000000 --- a/arch/nds32/include/asm/pgalloc.h +++ /dev/null @@ -1,62 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef _ASMNDS32_PGALLOC_H -#define _ASMNDS32_PGALLOC_H - -#include -#include -#include -#include - -#define __HAVE_ARCH_PTE_ALLOC_ONE -#include /* for pte_{alloc,free}_one */ - -extern pgd_t *pgd_alloc(struct mm_struct *mm); -extern void pgd_free(struct mm_struct *mm, pgd_t * pgd); - -static inline pgtable_t pte_alloc_one(struct mm_struct *mm) -{ - pgtable_t pte; - - pte = __pte_alloc_one(mm, GFP_PGTABLE_USER); - if (pte) - cpu_dcache_wb_page((unsigned long)page_address(pte)); - - return pte; -} - -/* - * Populate the pmdp entry with a pointer to the pte. This pmd is part - * of the mm address space. - * - * Ensure that we always set both PMD entries. - */ -static inline void -pmd_populate_kernel(struct mm_struct *mm, pmd_t * pmdp, pte_t * ptep) -{ - unsigned long pte_ptr = (unsigned long)ptep; - unsigned long pmdval; - - BUG_ON(mm != &init_mm); - - /* - * The pmd must be loaded with the physical - * address of the PTE table - */ - pmdval = __pa(pte_ptr) | _PAGE_KERNEL_TABLE; - set_pmd(pmdp, __pmd(pmdval)); -} - -static inline void -pmd_populate(struct mm_struct *mm, pmd_t * pmdp, pgtable_t ptep) -{ - unsigned long pmdval; - - BUG_ON(mm == &init_mm); - - pmdval = page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE; - set_pmd(pmdp, __pmd(pmdval)); -} - -#endif diff --git a/arch/nds32/include/asm/pgtable.h b/arch/nds32/include/asm/pgtable.h deleted file mode 100644 index 419f984eef70..000000000000 --- a/arch/nds32/include/asm/pgtable.h +++ /dev/null @@ -1,377 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef _ASMNDS32_PGTABLE_H -#define _ASMNDS32_PGTABLE_H - -#include -#include - -#include -#include -#ifndef __ASSEMBLY__ -#include -#include -#endif - -#ifdef CONFIG_ANDES_PAGE_SIZE_4KB -#define PGDIR_SHIFT 22 -#define PTRS_PER_PGD 1024 -#define PTRS_PER_PTE 1024 -#endif - -#ifdef CONFIG_ANDES_PAGE_SIZE_8KB -#define PGDIR_SHIFT 24 -#define PTRS_PER_PGD 256 -#define PTRS_PER_PTE 2048 -#endif - -#ifndef __ASSEMBLY__ -extern void __pte_error(const char *file, int line, unsigned long val); -extern void __pgd_error(const char *file, int line, unsigned long val); - -#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte)) -#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd)) -#endif /* !__ASSEMBLY__ */ - -#define PMD_SIZE (1UL << PMD_SHIFT) -#define PMD_MASK (~(PMD_SIZE-1)) -#define PGDIR_SIZE (1UL << PGDIR_SHIFT) -#define PGDIR_MASK (~(PGDIR_SIZE-1)) - -/* - * This is the lowest virtual address we can permit any user space - * mapping to be mapped at. This is particularly important for - * non-high vector CPUs. - */ -#define FIRST_USER_ADDRESS 0x8000 - -#ifdef CONFIG_HIGHMEM -#define CONSISTENT_BASE ((PKMAP_BASE) - (SZ_2M)) -#define CONSISTENT_END (PKMAP_BASE) -#else -#define CONSISTENT_BASE (FIXADDR_START - SZ_2M) -#define CONSISTENT_END (FIXADDR_START) -#endif -#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT) - -#ifdef CONFIG_HIGHMEM -#ifndef __ASSEMBLY__ -#include -#endif -#endif - -#define VMALLOC_RESERVE SZ_128M -#define VMALLOC_END (CONSISTENT_BASE - PAGE_SIZE) -#define VMALLOC_START ((VMALLOC_END) - VMALLOC_RESERVE) -#define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#define MAXMEM __pa(VMALLOC_START) -#define MAXMEM_PFN PFN_DOWN(MAXMEM) - -#define FIRST_USER_PGD_NR 0 -#define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) + FIRST_USER_PGD_NR) - -/* L2 PTE */ -#define _PAGE_V (1UL << 0) - -#define _PAGE_M_XKRW (0UL << 1) -#define _PAGE_M_UR_KR (1UL << 1) -#define _PAGE_M_UR_KRW (2UL << 1) -#define _PAGE_M_URW_KRW (3UL << 1) -#define _PAGE_M_KR (5UL << 1) -#define _PAGE_M_KRW (7UL << 1) - -#define _PAGE_D (1UL << 4) -#define _PAGE_E (1UL << 5) -#define _PAGE_A (1UL << 6) -#define _PAGE_G (1UL << 7) - -#define _PAGE_C_DEV (0UL << 8) -#define _PAGE_C_DEV_WB (1UL << 8) -#define _PAGE_C_MEM (2UL << 8) -#define _PAGE_C_MEM_SHRD_WB (4UL << 8) -#define _PAGE_C_MEM_SHRD_WT (5UL << 8) -#define _PAGE_C_MEM_WB (6UL << 8) -#define _PAGE_C_MEM_WT (7UL << 8) - -#define _PAGE_L (1UL << 11) - -#define _HAVE_PAGE_L (_PAGE_L) -#define _PAGE_FILE (1UL << 1) -#define _PAGE_YOUNG 0 -#define _PAGE_M_MASK _PAGE_M_KRW -#define _PAGE_C_MASK _PAGE_C_MEM_WT - -#ifdef CONFIG_SMP -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH -#define _PAGE_CACHE_SHRD _PAGE_C_MEM_SHRD_WT -#else -#define _PAGE_CACHE_SHRD _PAGE_C_MEM_SHRD_WB -#endif -#else -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH -#define _PAGE_CACHE_SHRD _PAGE_C_MEM_WT -#else -#define _PAGE_CACHE_SHRD _PAGE_C_MEM_WB -#endif -#endif - -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH -#define _PAGE_CACHE _PAGE_C_MEM_WT -#else -#define _PAGE_CACHE _PAGE_C_MEM_WB -#endif - -#define _PAGE_IOREMAP \ - (_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_G | _PAGE_C_DEV) - -/* - * + Level 1 descriptor (PMD) - */ -#define PMD_TYPE_TABLE 0 - -#ifndef __ASSEMBLY__ - -#define _PAGE_USER_TABLE PMD_TYPE_TABLE -#define _PAGE_KERNEL_TABLE PMD_TYPE_TABLE - -#define PAGE_EXEC __pgprot(_PAGE_V | _PAGE_M_XKRW | _PAGE_E) -#define PAGE_NONE __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_A) -#define PAGE_READ __pgprot(_PAGE_V | _PAGE_M_UR_KR) -#define PAGE_RDWR __pgprot(_PAGE_V | _PAGE_M_URW_KRW | _PAGE_D) -#define PAGE_COPY __pgprot(_PAGE_V | _PAGE_M_UR_KR) - -#define PAGE_UXKRWX_V1 __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) -#define PAGE_UXKRWX_V2 __pgprot(_PAGE_V | _PAGE_M_XKRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) -#define PAGE_URXKRWX_V2 __pgprot(_PAGE_V | _PAGE_M_UR_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) -#define PAGE_CACHE_L1 __pgprot(_HAVE_PAGE_L | _PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE) -#define PAGE_MEMORY __pgprot(_HAVE_PAGE_L | _PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) -#define PAGE_KERNEL __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) -#define PAGE_SHARED __pgprot(_PAGE_V | _PAGE_M_URW_KRW | _PAGE_D | _PAGE_CACHE_SHRD) -#define PAGE_DEVICE __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_G | _PAGE_C_DEV) -#endif /* __ASSEMBLY__ */ - -/* xwr */ -#define __P000 (PAGE_NONE | _PAGE_CACHE_SHRD) -#define __P001 (PAGE_READ | _PAGE_CACHE_SHRD) -#define __P010 (PAGE_COPY | _PAGE_CACHE_SHRD) -#define __P011 (PAGE_COPY | _PAGE_CACHE_SHRD) -#define __P100 (PAGE_EXEC | _PAGE_CACHE_SHRD) -#define __P101 (PAGE_READ | _PAGE_E | _PAGE_CACHE_SHRD) -#define __P110 (PAGE_COPY | _PAGE_E | _PAGE_CACHE_SHRD) -#define __P111 (PAGE_COPY | _PAGE_E | _PAGE_CACHE_SHRD) - -#define __S000 (PAGE_NONE | _PAGE_CACHE_SHRD) -#define __S001 (PAGE_READ | _PAGE_CACHE_SHRD) -#define __S010 (PAGE_RDWR | _PAGE_CACHE_SHRD) -#define __S011 (PAGE_RDWR | _PAGE_CACHE_SHRD) -#define __S100 (PAGE_EXEC | _PAGE_CACHE_SHRD) -#define __S101 (PAGE_READ | _PAGE_E | _PAGE_CACHE_SHRD) -#define __S110 (PAGE_RDWR | _PAGE_E | _PAGE_CACHE_SHRD) -#define __S111 (PAGE_RDWR | _PAGE_E | _PAGE_CACHE_SHRD) - -#ifndef __ASSEMBLY__ -/* - * ZERO_PAGE is a global shared page that is always zero: used - * for zero-mapped memory areas etc.. - */ -extern struct page *empty_zero_page; -extern void paging_init(void); -#define ZERO_PAGE(vaddr) (empty_zero_page) - -#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) -#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))) - -#define pte_none(pte) !(pte_val(pte)) -#define pte_clear(mm,addr,ptep) set_pte_at((mm),(addr),(ptep), __pte(0)) -#define pte_page(pte) (pfn_to_page(pte_pfn(pte))) - -static unsigned long pmd_page_vaddr(pmd_t pmd) -{ - return ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)); -} - -#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) -/* - * Set a level 1 translation table entry, and clean it out of - * any caches such that the MMUs can load it correctly. - */ -static inline void set_pmd(pmd_t * pmdp, pmd_t pmd) -{ - - *pmdp = pmd; -#if !defined(CONFIG_CPU_DCACHE_DISABLE) && !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) - __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (pmdp):"memory"); - __nds32__msync_all(); - __nds32__dsb(); -#endif -} - -/* - * Set a PTE and flush it out - */ -static inline void set_pte(pte_t * ptep, pte_t pte) -{ - - *ptep = pte; -#if !defined(CONFIG_CPU_DCACHE_DISABLE) && !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) - __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (ptep):"memory"); - __nds32__msync_all(); - __nds32__dsb(); -#endif -} - -/* - * The following only work if pte_present() is true. - * Undefined behaviour if not.. - */ - -/* - * pte_write: this page is writeable for user mode - * pte_read: this page is readable for user mode - * pte_kernel_write: this page is writeable for kernel mode - * - * We don't have pte_kernel_read because kernel always can read. - * - * */ - -#define pte_present(pte) (pte_val(pte) & _PAGE_V) -#define pte_write(pte) ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW) -#define pte_read(pte) (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KR) || \ - ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KRW) || \ - ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW)) -#define pte_kernel_write(pte) (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW) || \ - ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KRW) || \ - ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_KRW) || \ - (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_XKRW) && pte_exec(pte))) -#define pte_exec(pte) (pte_val(pte) & _PAGE_E) -#define pte_dirty(pte) (pte_val(pte) & _PAGE_D) -#define pte_young(pte) (pte_val(pte) & _PAGE_YOUNG) - -/* - * The following only works if pte_present() is not true. - */ -#define pte_file(pte) (pte_val(pte) & _PAGE_FILE) -#define pte_to_pgoff(x) (pte_val(x) >> 2) -#define pgoff_to_pte(x) __pte(((x) << 2) | _PAGE_FILE) - -#define PTE_FILE_MAX_BITS 29 - -#define PTE_BIT_FUNC(fn,op) \ -static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } - -static inline pte_t pte_wrprotect(pte_t pte) -{ - pte_val(pte) = pte_val(pte) & ~_PAGE_M_MASK; - pte_val(pte) = pte_val(pte) | _PAGE_M_UR_KR; - return pte; -} - -static inline pte_t pte_mkwrite(pte_t pte) -{ - pte_val(pte) = pte_val(pte) & ~_PAGE_M_MASK; - pte_val(pte) = pte_val(pte) | _PAGE_M_URW_KRW; - return pte; -} - -PTE_BIT_FUNC(exprotect, &=~_PAGE_E); -PTE_BIT_FUNC(mkexec, |=_PAGE_E); -PTE_BIT_FUNC(mkclean, &=~_PAGE_D); -PTE_BIT_FUNC(mkdirty, |=_PAGE_D); -PTE_BIT_FUNC(mkold, &=~_PAGE_YOUNG); -PTE_BIT_FUNC(mkyoung, |=_PAGE_YOUNG); - -/* - * Mark the prot value as uncacheable and unbufferable. - */ -#define pgprot_noncached(prot) __pgprot((pgprot_val(prot)&~_PAGE_C_MASK) | _PAGE_C_DEV) -#define pgprot_writecombine(prot) __pgprot((pgprot_val(prot)&~_PAGE_C_MASK) | _PAGE_C_DEV_WB) - -#define pmd_none(pmd) (pmd_val(pmd)&0x1) -#define pmd_present(pmd) (!pmd_none(pmd)) -#define pmd_bad(pmd) pmd_none(pmd) - -#define copy_pmd(pmdpd,pmdps) set_pmd((pmdpd), *(pmdps)) -#define pmd_clear(pmdp) set_pmd((pmdp), __pmd(1)) - -static inline pmd_t __mk_pmd(pte_t * ptep, unsigned long prot) -{ - unsigned long ptr = (unsigned long)ptep; - pmd_t pmd; - - /* - * The pmd must be loaded with the physical - * address of the PTE table - */ - - pmd_val(pmd) = __virt_to_phys(ptr) | prot; - return pmd; -} - -#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd))) - -/* - * Permanent address of a page. We never have highmem, so this is trivial. - */ -#define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT)) - -/* - * Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. - */ -#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot) - -/* - * The "pgd_xxx()" functions here are trivial for a folded two-level - * setup: the pgd is never bad, and a pmd always exists (as it's folded - * into the pgd entry) - */ -#define pgd_none(pgd) (0) -#define pgd_bad(pgd) (0) -#define pgd_present(pgd) (1) -#define pgd_clear(pgdp) do { } while (0) - -#define page_pte_prot(page,prot) mk_pte(page, prot) -#define page_pte(page) mk_pte(page, __pgprot(0)) -/* - * L1PTE = $mr1 + ((virt >> PMD_SHIFT) << 2); - * L2PTE = (((virt >> PAGE_SHIFT) & (PTRS_PER_PTE -1 )) << 2); - * PPN = (phys & 0xfffff000); - * -*/ - -static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ - const unsigned long mask = 0xfff; - pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); - return pte; -} - -extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; - -/* Encode and decode a swap entry. - * - * We support up to 32GB of swap on 4k machines - */ -#define __swp_type(x) (((x).val >> 2) & 0x7f) -#define __swp_offset(x) ((x).val >> 9) -#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 9) }) -#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) -#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val }) - -/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ -#define kern_addr_valid(addr) (1) - -/* - * We provide our own arch_get_unmapped_area to cope with VIPT caches. - */ -#define HAVE_ARCH_UNMAPPED_AREA - -/* - * remap a physical address `phys' of size `size' with page protection `prot' - * into virtual address `from' - */ - -#endif /* !__ASSEMBLY__ */ - -#endif /* _ASMNDS32_PGTABLE_H */ diff --git a/arch/nds32/include/asm/pmu.h b/arch/nds32/include/asm/pmu.h deleted file mode 100644 index e1ac0b0b8bcf..000000000000 --- a/arch/nds32/include/asm/pmu.h +++ /dev/null @@ -1,386 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2008-2018 Andes Technology Corporation */ - -#ifndef __ASM_PMU_H -#define __ASM_PMU_H - -#include -#include -#include -#include - -/* Has special meaning for perf core implementation */ -#define HW_OP_UNSUPPORTED 0x0 -#define C(_x) PERF_COUNT_HW_CACHE_##_x -#define CACHE_OP_UNSUPPORTED 0x0 - -/* Enough for both software and hardware defined events */ -#define SOFTWARE_EVENT_MASK 0xFF - -#define PFM_OFFSET_MAGIC_0 2 /* DO NOT START FROM 0 */ -#define PFM_OFFSET_MAGIC_1 (PFM_OFFSET_MAGIC_0 + 36) -#define PFM_OFFSET_MAGIC_2 (PFM_OFFSET_MAGIC_1 + 36) - -enum { PFMC0, PFMC1, PFMC2, MAX_COUNTERS }; - -u32 PFM_CTL_OVF[3] = { PFM_CTL_mskOVF0, PFM_CTL_mskOVF1, - PFM_CTL_mskOVF2 }; -u32 PFM_CTL_EN[3] = { PFM_CTL_mskEN0, PFM_CTL_mskEN1, - PFM_CTL_mskEN2 }; -u32 PFM_CTL_OFFSEL[3] = { PFM_CTL_offSEL0, PFM_CTL_offSEL1, - PFM_CTL_offSEL2 }; -u32 PFM_CTL_IE[3] = { PFM_CTL_mskIE0, PFM_CTL_mskIE1, PFM_CTL_mskIE2 }; -u32 PFM_CTL_KS[3] = { PFM_CTL_mskKS0, PFM_CTL_mskKS1, PFM_CTL_mskKS2 }; -u32 PFM_CTL_KU[3] = { PFM_CTL_mskKU0, PFM_CTL_mskKU1, PFM_CTL_mskKU2 }; -u32 PFM_CTL_SEL[3] = { PFM_CTL_mskSEL0, PFM_CTL_mskSEL1, PFM_CTL_mskSEL2 }; -/* - * Perf Events' indices - */ -#define NDS32_IDX_CYCLE_COUNTER 0 -#define NDS32_IDX_COUNTER0 1 -#define NDS32_IDX_COUNTER1 2 - -/* The events for a given PMU register set. */ -struct pmu_hw_events { - /* - * The events that are active on the PMU for the given index. - */ - struct perf_event *events[MAX_COUNTERS]; - - /* - * A 1 bit for an index indicates that the counter is being used for - * an event. A 0 means that the counter can be used. - */ - unsigned long used_mask[BITS_TO_LONGS(MAX_COUNTERS)]; - - /* - * Hardware lock to serialize accesses to PMU registers. Needed for the - * read/modify/write sequences. - */ - raw_spinlock_t pmu_lock; -}; - -struct nds32_pmu { - struct pmu pmu; - cpumask_t active_irqs; - char *name; - irqreturn_t (*handle_irq)(int irq_num, void *dev); - void (*enable)(struct perf_event *event); - void (*disable)(struct perf_event *event); - int (*get_event_idx)(struct pmu_hw_events *hw_events, - struct perf_event *event); - int (*set_event_filter)(struct hw_perf_event *evt, - struct perf_event_attr *attr); - u32 (*read_counter)(struct perf_event *event); - void (*write_counter)(struct perf_event *event, u32 val); - void (*start)(struct nds32_pmu *nds32_pmu); - void (*stop)(struct nds32_pmu *nds32_pmu); - void (*reset)(void *data); - int (*request_irq)(struct nds32_pmu *nds32_pmu, irq_handler_t handler); - void (*free_irq)(struct nds32_pmu *nds32_pmu); - int (*map_event)(struct perf_event *event); - int num_events; - atomic_t active_events; - u64 max_period; - struct platform_device *plat_device; - struct pmu_hw_events *(*get_hw_events)(void); -}; - -#define to_nds32_pmu(p) (container_of(p, struct nds32_pmu, pmu)) - -int nds32_pmu_register(struct nds32_pmu *nds32_pmu, int type); - -u64 nds32_pmu_event_update(struct perf_event *event); - -int nds32_pmu_event_set_period(struct perf_event *event); - -/* - * Common NDS32 SPAv3 event types - * - * Note: An implementation may not be able to count all of these events - * but the encodings are considered to be `reserved' in the case that - * they are not available. - * - * SEL_TOTAL_CYCLES will add an offset is due to ZERO is defined as - * NOT_SUPPORTED EVENT mapping in generic perf code. - * You will need to deal it in the event writing implementation. - */ -enum spav3_counter_0_perf_types { - SPAV3_0_SEL_BASE = -1 + PFM_OFFSET_MAGIC_0, /* counting symbol */ - SPAV3_0_SEL_TOTAL_CYCLES = 0 + PFM_OFFSET_MAGIC_0, - SPAV3_0_SEL_COMPLETED_INSTRUCTION = 1 + PFM_OFFSET_MAGIC_0, - SPAV3_0_SEL_LAST /* counting symbol */ -}; - -enum spav3_counter_1_perf_types { - SPAV3_1_SEL_BASE = -1 + PFM_OFFSET_MAGIC_1, /* counting symbol */ - SPAV3_1_SEL_TOTAL_CYCLES = 0 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_COMPLETED_INSTRUCTION = 1 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_CONDITIONAL_BRANCH = 2 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_TAKEN_CONDITIONAL_BRANCH = 3 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_PREFETCH_INSTRUCTION = 4 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_RET_INST = 5 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_JR_INST = 6 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_JAL_JRAL_INST = 7 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_NOP_INST = 8 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_SCW_INST = 9 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_ISB_DSB_INST = 10 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_CCTL_INST = 11 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_TAKEN_INTERRUPTS = 12 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_LOADS_COMPLETED = 13 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_UITLB_ACCESS = 14 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_UDTLB_ACCESS = 15 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_MTLB_ACCESS = 16 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_CODE_CACHE_ACCESS = 17 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_DATA_DEPENDENCY_STALL_CYCLES = 18 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_DATA_CACHE_MISS_STALL_CYCLES = 19 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_DATA_CACHE_ACCESS = 20 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_DATA_CACHE_MISS = 21 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_LOAD_DATA_CACHE_ACCESS = 22 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_STORE_DATA_CACHE_ACCESS = 23 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_ILM_ACCESS = 24 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_LSU_BIU_CYCLES = 25 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_HPTWK_BIU_CYCLES = 26 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_DMA_BIU_CYCLES = 27 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_CODE_CACHE_FILL_BIU_CYCLES = 28 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_LEGAL_UNALIGN_DCACHE_ACCESS = 29 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_PUSH25 = 30 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_SYSCALLS_INST = 31 + PFM_OFFSET_MAGIC_1, - SPAV3_1_SEL_LAST /* counting symbol */ -}; - -enum spav3_counter_2_perf_types { - SPAV3_2_SEL_BASE = -1 + PFM_OFFSET_MAGIC_2, /* counting symbol */ - SPAV3_2_SEL_TOTAL_CYCLES = 0 + PFM_OFFSET_MAGIC_2, - SPAV3_2_SEL_COMPLETED_INSTRUCTION = 1 + PFM_OFFSET_MAGIC_2, - SPAV3_2_SEL_CONDITIONAL_BRANCH_MISPREDICT = 2 + PFM_OFFSET_MAGIC_2, - SPAV3_2_SEL_TAKEN_CONDITIONAL_BRANCH_MISPREDICT = - 3 + PFM_OFFSET_MAGIC_2, - SPAV3_2_SEL_PREFETCH_INSTRUCTION_CACHE_HIT = 4 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_RET_MISPREDICT = 5 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_IMMEDIATE_J_INST = 6 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_MULTIPLY_INST = 7 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_16_BIT_INST = 8 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_FAILED_SCW_INST = 9 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_LD_AFTER_ST_CONFLICT_REPLAYS = 10 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_TAKEN_EXCEPTIONS = 12 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_STORES_COMPLETED = 13 + PFM_OFFSET_MAGIC_2, - SPAV3_2_SEL_UITLB_MISS = 14 + PFM_OFFSET_MAGIC_2, - SPAV3_2_SEL_UDTLB_MISS = 15 + PFM_OFFSET_MAGIC_2, - SPAV3_2_SEL_MTLB_MISS = 16 + PFM_OFFSET_MAGIC_2, - SPAV3_2_SEL_CODE_CACHE_MISS = 17 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_EMPTY_INST_QUEUE_STALL_CYCLES = 18 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_DATA_WRITE_BACK = 19 + PFM_OFFSET_MAGIC_2, - SPAV3_2_SEL_DATA_CACHE_MISS = 21 + PFM_OFFSET_MAGIC_2, - SPAV3_2_SEL_LOAD_DATA_CACHE_MISS = 22 + PFM_OFFSET_MAGIC_2, - SPAV3_2_SEL_STORE_DATA_CACHE_MISS = 23 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_DLM_ACCESS = 24 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_LSU_BIU_REQUEST = 25 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_HPTWK_BIU_REQUEST = 26 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_DMA_BIU_REQUEST = 27 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_CODE_CACHE_FILL_BIU_REQUEST = 28 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_EXTERNAL_EVENTS = 29 + PFM_OFFSET_MAGIC_2, - SPAV3_1_SEL_POP25 = 30 + PFM_OFFSET_MAGIC_2, - SPAV3_2_SEL_LAST /* counting symbol */ -}; - -/* Get converted event counter index */ -static inline int get_converted_event_idx(unsigned long event) -{ - int idx; - - if ((event) > SPAV3_0_SEL_BASE && event < SPAV3_0_SEL_LAST) { - idx = 0; - } else if ((event) > SPAV3_1_SEL_BASE && event < SPAV3_1_SEL_LAST) { - idx = 1; - } else if ((event) > SPAV3_2_SEL_BASE && event < SPAV3_2_SEL_LAST) { - idx = 2; - } else { - pr_err("GET_CONVERTED_EVENT_IDX PFM counter range error\n"); - return -EPERM; - } - - return idx; -} - -/* Get converted hardware event number */ -static inline u32 get_converted_evet_hw_num(u32 event) -{ - if (event > SPAV3_0_SEL_BASE && event < SPAV3_0_SEL_LAST) - event -= PFM_OFFSET_MAGIC_0; - else if (event > SPAV3_1_SEL_BASE && event < SPAV3_1_SEL_LAST) - event -= PFM_OFFSET_MAGIC_1; - else if (event > SPAV3_2_SEL_BASE && event < SPAV3_2_SEL_LAST) - event -= PFM_OFFSET_MAGIC_2; - else if (event != 0) - pr_err("GET_CONVERTED_EVENT_HW_NUM PFM counter range error\n"); - - return event; -} - -/* - * NDS32 HW events mapping - * - * The hardware events that we support. We do support cache operations but - * we have harvard caches and no way to combine instruction and data - * accesses/misses in hardware. - */ -static const unsigned int nds32_pfm_perf_map[PERF_COUNT_HW_MAX] = { - [PERF_COUNT_HW_CPU_CYCLES] = SPAV3_0_SEL_TOTAL_CYCLES, - [PERF_COUNT_HW_INSTRUCTIONS] = SPAV3_1_SEL_COMPLETED_INSTRUCTION, - [PERF_COUNT_HW_CACHE_REFERENCES] = SPAV3_1_SEL_DATA_CACHE_ACCESS, - [PERF_COUNT_HW_CACHE_MISSES] = SPAV3_2_SEL_DATA_CACHE_MISS, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_BRANCH_MISSES] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_REF_CPU_CYCLES] = HW_OP_UNSUPPORTED -}; - -static const unsigned int nds32_pfm_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] - [PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_COUNT_HW_CACHE_RESULT_MAX] = { - [C(L1D)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = - SPAV3_1_SEL_LOAD_DATA_CACHE_ACCESS, - [C(RESULT_MISS)] = - SPAV3_2_SEL_LOAD_DATA_CACHE_MISS, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = - SPAV3_1_SEL_STORE_DATA_CACHE_ACCESS, - [C(RESULT_MISS)] = - SPAV3_2_SEL_STORE_DATA_CACHE_MISS, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = - CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = - CACHE_OP_UNSUPPORTED, - }, - }, - [C(L1I)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = - SPAV3_1_SEL_CODE_CACHE_ACCESS, - [C(RESULT_MISS)] = - SPAV3_2_SEL_CODE_CACHE_MISS, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = - SPAV3_1_SEL_CODE_CACHE_ACCESS, - [C(RESULT_MISS)] = - SPAV3_2_SEL_CODE_CACHE_MISS, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = - CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, - }, - }, - /* TODO: L2CC */ - [C(LL)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = - CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, - }, - }, - /* NDS32 PMU does not support TLB read/write hit/miss, - * However, it can count access/miss, which mixed with read and write. - * Therefore, only READ counter will use it. - * We do as possible as we can. - */ - [C(DTLB)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = - SPAV3_1_SEL_UDTLB_ACCESS, - [C(RESULT_MISS)] = - SPAV3_2_SEL_UDTLB_MISS, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = - CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = - CACHE_OP_UNSUPPORTED, - }, - }, - [C(ITLB)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = - SPAV3_1_SEL_UITLB_ACCESS, - [C(RESULT_MISS)] = - SPAV3_2_SEL_UITLB_MISS, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = - CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = - CACHE_OP_UNSUPPORTED, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = - CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = - CACHE_OP_UNSUPPORTED, - }, - }, - [C(BPU)] = { /* What is BPU? */ - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = - CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = - CACHE_OP_UNSUPPORTED, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = - CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = - CACHE_OP_UNSUPPORTED, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = - CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = - CACHE_OP_UNSUPPORTED, - }, - }, - [C(NODE)] = { /* What is NODE? */ - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = - CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = - CACHE_OP_UNSUPPORTED, - }, - }, -}; - -int nds32_pmu_map_event(struct perf_event *event, - const unsigned int (*event_map)[PERF_COUNT_HW_MAX], - const unsigned int (*cache_map)[PERF_COUNT_HW_CACHE_MAX] - [PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_COUNT_HW_CACHE_RESULT_MAX], u32 raw_event_mask); - -#endif /* __ASM_PMU_H */ diff --git a/arch/nds32/include/asm/proc-fns.h b/arch/nds32/include/asm/proc-fns.h deleted file mode 100644 index 27c617fa77af..000000000000 --- a/arch/nds32/include/asm/proc-fns.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __NDS32_PROCFNS_H__ -#define __NDS32_PROCFNS_H__ - -#ifdef __KERNEL__ -#include - -struct mm_struct; -struct vm_area_struct; -extern void cpu_proc_init(void); -extern void cpu_proc_fin(void); -extern void cpu_do_idle(void); -extern void cpu_reset(unsigned long reset); -extern void cpu_switch_mm(struct mm_struct *mm); - -extern void cpu_dcache_inval_all(void); -extern void cpu_dcache_wbinval_all(void); -extern void cpu_dcache_inval_page(unsigned long page); -extern void cpu_dcache_wb_page(unsigned long page); -extern void cpu_dcache_wbinval_page(unsigned long page); -extern void cpu_dcache_inval_range(unsigned long start, unsigned long end); -extern void cpu_dcache_wb_range(unsigned long start, unsigned long end); -extern void cpu_dcache_wbinval_range(unsigned long start, unsigned long end); - -extern void cpu_icache_inval_all(void); -extern void cpu_icache_inval_page(unsigned long page); -extern void cpu_icache_inval_range(unsigned long start, unsigned long end); - -extern void cpu_cache_wbinval_page(unsigned long page, int flushi); -extern void cpu_cache_wbinval_range(unsigned long start, - unsigned long end, int flushi); -extern void cpu_cache_wbinval_range_check(struct vm_area_struct *vma, - unsigned long start, - unsigned long end, bool flushi, - bool wbd); - -extern void cpu_dma_wb_range(unsigned long start, unsigned long end); -extern void cpu_dma_inval_range(unsigned long start, unsigned long end); -extern void cpu_dma_wbinval_range(unsigned long start, unsigned long end); - -#endif /* __KERNEL__ */ -#endif /* __NDS32_PROCFNS_H__ */ diff --git a/arch/nds32/include/asm/processor.h b/arch/nds32/include/asm/processor.h deleted file mode 100644 index e6bfc74972bb..000000000000 --- a/arch/nds32/include/asm/processor.h +++ /dev/null @@ -1,104 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __ASM_NDS32_PROCESSOR_H -#define __ASM_NDS32_PROCESSOR_H - -#ifdef __KERNEL__ - -#include -#include -#include - -#define KERNEL_STACK_SIZE PAGE_SIZE -#define STACK_TOP TASK_SIZE -#define STACK_TOP_MAX TASK_SIZE - -struct cpu_context { - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long r11; - unsigned long r12; - unsigned long r13; - unsigned long r14; - unsigned long fp; - unsigned long pc; - unsigned long sp; -}; - -struct thread_struct { - struct cpu_context cpu_context; /* cpu context */ - /* fault info */ - unsigned long address; - unsigned long trap_no; - unsigned long error_code; - - struct fpu_struct fpu; -}; - -#define INIT_THREAD { } - -#ifdef __NDS32_EB__ -#define PSW_DE PSW_mskBE -#else -#define PSW_DE 0x0 -#endif - -#ifdef CONFIG_WBNA -#define PSW_valWBNA PSW_mskWBNA -#else -#define PSW_valWBNA 0x0 -#endif - -#ifdef CONFIG_HWZOL -#define PSW_valINIT (PSW_CPL_ANY | PSW_mskAEN | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | PSW_mskGIE) -#else -#define PSW_valINIT (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | PSW_mskGIE) -#endif - -#define start_thread(regs,pc,stack) \ -({ \ - memzero(regs, sizeof(struct pt_regs)); \ - forget_syscall(regs); \ - regs->ipsw = PSW_valINIT; \ - regs->ir0 = (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | PSW_SYSTEM | PSW_INTL_1); \ - regs->ipc = pc; \ - regs->sp = stack; \ -}) - -/* Forward declaration, a strange C thing */ -struct task_struct; - -/* Free all resources held by a thread. */ -#define release_thread(thread) do { } while(0) -#if IS_ENABLED(CONFIG_FPU) -#if !IS_ENABLED(CONFIG_UNLAZU_FPU) -extern struct task_struct *last_task_used_math; -#endif -#endif - -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy(tsk) do { } while (0) - -unsigned long __get_wchan(struct task_struct *p); - -#define cpu_relax() barrier() - -#define task_pt_regs(task) \ - ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \ - - 8) - 1) - -/* - * Create a new kernel thread - */ -extern int kernel_thread(int (*fn) (void *), void *arg, unsigned long flags); - -#define KSTK_EIP(tsk) instruction_pointer(task_pt_regs(tsk)) -#define KSTK_ESP(tsk) user_stack_pointer(task_pt_regs(tsk)) - -#endif - -#endif /* __ASM_NDS32_PROCESSOR_H */ diff --git a/arch/nds32/include/asm/ptrace.h b/arch/nds32/include/asm/ptrace.h deleted file mode 100644 index 919ee223620c..000000000000 --- a/arch/nds32/include/asm/ptrace.h +++ /dev/null @@ -1,77 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __ASM_NDS32_PTRACE_H -#define __ASM_NDS32_PTRACE_H - -#include - -/* - * If pt_regs.syscallno == NO_SYSCALL, then the thread is not executing - * a syscall -- i.e., its most recent entry into the kernel from - * userspace was not via syscall, or otherwise a tracer cancelled the - * syscall. - * - * This must have the value -1, for ABI compatibility with ptrace etc. - */ -#define NO_SYSCALL (-1) -#ifndef __ASSEMBLY__ -#include - -struct pt_regs { - union { - struct user_pt_regs user_regs; - struct { - long uregs[26]; - long fp; - long gp; - long lp; - long sp; - long ipc; -#if defined(CONFIG_HWZOL) - long lb; - long le; - long lc; -#else - long dummy[3]; -#endif - long syscallno; - }; - }; - long orig_r0; - long ir0; - long ipsw; - long pipsw; - long pipc; - long pp0; - long pp1; - long fucop_ctl; - long osp; -}; - -static inline bool in_syscall(struct pt_regs const *regs) -{ - return regs->syscallno != NO_SYSCALL; -} - -static inline void forget_syscall(struct pt_regs *regs) -{ - regs->syscallno = NO_SYSCALL; -} -static inline unsigned long regs_return_value(struct pt_regs *regs) -{ - return regs->uregs[0]; -} -extern void show_regs(struct pt_regs *); -/* Avoid circular header include via sched.h */ -struct task_struct; - -#define arch_has_single_step() (1) -#define user_mode(regs) (((regs)->ipsw & PSW_mskPOM) == 0) -#define interrupts_enabled(regs) (!!((regs)->ipsw & PSW_mskGIE)) -#define user_stack_pointer(regs) ((regs)->sp) -#define instruction_pointer(regs) ((regs)->ipc) -#define profile_pc(regs) instruction_pointer(regs) - -#endif /* __ASSEMBLY__ */ -#endif diff --git a/arch/nds32/include/asm/sfp-machine.h b/arch/nds32/include/asm/sfp-machine.h deleted file mode 100644 index b1a5caa332b5..000000000000 --- a/arch/nds32/include/asm/sfp-machine.h +++ /dev/null @@ -1,158 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2005-2018 Andes Technology Corporation */ - -#include - -#define _FP_W_TYPE_SIZE 32 -#define _FP_W_TYPE unsigned long -#define _FP_WS_TYPE signed long -#define _FP_I_TYPE long - -#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) -#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) -#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) - -#define _FP_MUL_MEAT_S(R, X, Y) \ - _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S, R, X, Y, umul_ppmm) -#define _FP_MUL_MEAT_D(R, X, Y) \ - _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D, R, X, Y, umul_ppmm) -#define _FP_MUL_MEAT_Q(R, X, Y) \ - _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q, R, X, Y, umul_ppmm) - -#define _FP_MUL_MEAT_DW_S(R, X, Y) \ - _FP_MUL_MEAT_DW_1_wide(_FP_WFRACBITS_S, R, X, Y, umul_ppmm) -#define _FP_MUL_MEAT_DW_D(R, X, Y) \ - _FP_MUL_MEAT_DW_2_wide(_FP_WFRACBITS_D, R, X, Y, umul_ppmm) - -#define _FP_DIV_MEAT_S(R, X, Y) _FP_DIV_MEAT_1_udiv_norm(S, R, X, Y) -#define _FP_DIV_MEAT_D(R, X, Y) _FP_DIV_MEAT_2_udiv(D, R, X, Y) - -#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1) -#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1 -#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1 -#define _FP_NANSIGN_S 0 -#define _FP_NANSIGN_D 0 -#define _FP_NANSIGN_Q 0 - -#define _FP_KEEPNANFRACP 1 -#define _FP_QNANNEGATEDP 0 - -#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ -do { \ - if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \ - && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) { \ - R##_s = Y##_s; \ - _FP_FRAC_COPY_##wc(R, Y); \ - } else { \ - R##_s = X##_s; \ - _FP_FRAC_COPY_##wc(R, X); \ - } \ - R##_c = FP_CLS_NAN; \ -} while (0) - -#define __FPU_FPCSR (current->thread.fpu.fpcsr) - -/* Obtain the current rounding mode. */ -#define FP_ROUNDMODE \ -({ \ - __FPU_FPCSR & FPCSR_mskRM; \ -}) - -#define FP_RND_NEAREST 0 -#define FP_RND_PINF 1 -#define FP_RND_MINF 2 -#define FP_RND_ZERO 3 - -#define FP_EX_INVALID FPCSR_mskIVO -#define FP_EX_DIVZERO FPCSR_mskDBZ -#define FP_EX_OVERFLOW FPCSR_mskOVF -#define FP_EX_UNDERFLOW FPCSR_mskUDF -#define FP_EX_INEXACT FPCSR_mskIEX - -#define SF_CEQ 2 -#define SF_CLT 1 -#define SF_CGT 3 -#define SF_CUN 4 - -#include - -#ifdef __BIG_ENDIAN__ -#define __BYTE_ORDER __BIG_ENDIAN -#define __LITTLE_ENDIAN 0 -#else -#define __BYTE_ORDER __LITTLE_ENDIAN -#define __BIG_ENDIAN 0 -#endif - -#define abort() do { } while (0) -#define umul_ppmm(w1, w0, u, v) \ -do { \ - UWtype __x0, __x1, __x2, __x3; \ - UHWtype __ul, __vl, __uh, __vh; \ - \ - __ul = __ll_lowpart(u); \ - __uh = __ll_highpart(u); \ - __vl = __ll_lowpart(v); \ - __vh = __ll_highpart(v); \ - \ - __x0 = (UWtype) __ul * __vl; \ - __x1 = (UWtype) __ul * __vh; \ - __x2 = (UWtype) __uh * __vl; \ - __x3 = (UWtype) __uh * __vh; \ - \ - __x1 += __ll_highpart(__x0); \ - __x1 += __x2; \ - if (__x1 < __x2) \ - __x3 += __ll_B; \ - \ - (w1) = __x3 + __ll_highpart(__x1); \ - (w0) = __ll_lowpart(__x1) * __ll_B + __ll_lowpart(__x0); \ -} while (0) - -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -do { \ - UWtype __x; \ - __x = (al) + (bl); \ - (sh) = (ah) + (bh) + (__x < (al)); \ - (sl) = __x; \ -} while (0) - -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -do { \ - UWtype __x; \ - __x = (al) - (bl); \ - (sh) = (ah) - (bh) - (__x > (al)); \ - (sl) = __x; \ -} while (0) - -#define udiv_qrnnd(q, r, n1, n0, d) \ -do { \ - UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \ - __d1 = __ll_highpart(d); \ - __d0 = __ll_lowpart(d); \ - \ - __r1 = (n1) % __d1; \ - __q1 = (n1) / __d1; \ - __m = (UWtype) __q1 * __d0; \ - __r1 = __r1 * __ll_B | __ll_highpart(n0); \ - if (__r1 < __m) { \ - __q1--, __r1 += (d); \ - if (__r1 >= (d)) \ - if (__r1 < __m) \ - __q1--, __r1 += (d); \ - } \ - __r1 -= __m; \ - __r0 = __r1 % __d1; \ - __q0 = __r1 / __d1; \ - __m = (UWtype) __q0 * __d0; \ - __r0 = __r0 * __ll_B | __ll_lowpart(n0); \ - if (__r0 < __m) { \ - __q0--, __r0 += (d); \ - if (__r0 >= (d)) \ - if (__r0 < __m) \ - __q0--, __r0 += (d); \ - } \ - __r0 -= __m; \ - (q) = (UWtype) __q1 * __ll_B | __q0; \ - (r) = __r0; \ -} while (0) diff --git a/arch/nds32/include/asm/shmparam.h b/arch/nds32/include/asm/shmparam.h deleted file mode 100644 index 3aeee946973d..000000000000 --- a/arch/nds32/include/asm/shmparam.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef _ASMNDS32_SHMPARAM_H -#define _ASMNDS32_SHMPARAM_H - -/* - * This should be the size of the virtually indexed cache/ways, - * whichever is greater since the cache aliases every size/ways - * bytes. - */ -#define SHMLBA (4 * SZ_8K) /* attach addr a multiple of this */ - -/* - * Enforce SHMLBA in shmat - */ -#define __ARCH_FORCE_SHMLBA - -#endif /* _ASMNDS32_SHMPARAM_H */ diff --git a/arch/nds32/include/asm/stacktrace.h b/arch/nds32/include/asm/stacktrace.h deleted file mode 100644 index 6bf7c777bda4..000000000000 --- a/arch/nds32/include/asm/stacktrace.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2008-2018 Andes Technology Corporation */ - -#ifndef __ASM_STACKTRACE_H -#define __ASM_STACKTRACE_H - -/* Kernel callchain */ -struct stackframe { - unsigned long fp; - unsigned long sp; - unsigned long lp; -}; - -/* - * struct frame_tail: User callchain - * IMPORTANT: - * This struct is used for call-stack walking, - * the order and types matters. - * Do not use array, it only stores sizeof(pointer) - * - * The details can refer to arch/arm/kernel/perf_event.c - */ -struct frame_tail { - unsigned long stack_fp; - unsigned long stack_lp; -}; - -/* For User callchain with optimize for size */ -struct frame_tail_opt_size { - unsigned long stack_r6; - unsigned long stack_fp; - unsigned long stack_gp; - unsigned long stack_lp; -}; - -extern void -get_real_ret_addr(unsigned long *addr, struct task_struct *tsk, int *graph); - -#endif /* __ASM_STACKTRACE_H */ diff --git a/arch/nds32/include/asm/string.h b/arch/nds32/include/asm/string.h deleted file mode 100644 index cae8fe16de98..000000000000 --- a/arch/nds32/include/asm/string.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __ASM_NDS32_STRING_H -#define __ASM_NDS32_STRING_H - -#define __HAVE_ARCH_MEMCPY -extern void *memcpy(void *, const void *, __kernel_size_t); - -#define __HAVE_ARCH_MEMMOVE -extern void *memmove(void *, const void *, __kernel_size_t); - -#define __HAVE_ARCH_MEMSET -extern void *memset(void *, int, __kernel_size_t); - -extern void *memzero(void *ptr, __kernel_size_t n); -#endif diff --git a/arch/nds32/include/asm/suspend.h b/arch/nds32/include/asm/suspend.h deleted file mode 100644 index 6ed2418af1ac..000000000000 --- a/arch/nds32/include/asm/suspend.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2008-2017 Andes Technology Corporation - -#ifndef __ASM_NDS32_SUSPEND_H -#define __ASM_NDS32_SUSPEND_H - -extern void suspend2ram(void); -extern void cpu_resume(void); -extern unsigned long wake_mask; - -#endif diff --git a/arch/nds32/include/asm/swab.h b/arch/nds32/include/asm/swab.h deleted file mode 100644 index 362a466f2976..000000000000 --- a/arch/nds32/include/asm/swab.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __NDS32_SWAB_H__ -#define __NDS32_SWAB_H__ - -#include -#include - -static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) -{ - __asm__("wsbh %0, %0\n\t" /* word swap byte within halfword */ - "rotri %0, %0, #16\n" - :"=r"(x) - :"0"(x)); - return x; -} - -static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x) -{ - __asm__("wsbh %0, %0\n" /* word swap byte within halfword */ - :"=r"(x) - :"0"(x)); - return x; -} - -#define __arch_swab32(x) ___arch__swab32(x) -#define __arch_swab16(x) ___arch__swab16(x) - -#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) -#define __BYTEORDER_HAS_U64__ -#define __SWAB_64_THRU_32__ -#endif - -#endif /* __NDS32_SWAB_H__ */ diff --git a/arch/nds32/include/asm/syscall.h b/arch/nds32/include/asm/syscall.h deleted file mode 100644 index 90aa56c94af1..000000000000 --- a/arch/nds32/include/asm/syscall.h +++ /dev/null @@ -1,142 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved. -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef _ASM_NDS32_SYSCALL_H -#define _ASM_NDS32_SYSCALL_H 1 - -#include -#include -struct task_struct; -struct pt_regs; - -/** - * syscall_get_nr - find what system call a task is executing - * @task: task of interest, must be blocked - * @regs: task_pt_regs() of @task - * - * If @task is executing a system call or is at system call - * tracing about to attempt one, returns the system call number. - * If @task is not executing a system call, i.e. it's blocked - * inside the kernel for a fault or signal, returns -1. - * - * Note this returns int even on 64-bit machines. Only 32 bits of - * system call number can be meaningful. If the actual arch value - * is 64 bits, this truncates to 32 bits so 0xffffffff means -1. - * - * It's only valid to call this when @task is known to be blocked. - */ -static inline int -syscall_get_nr(struct task_struct *task, struct pt_regs *regs) -{ - return regs->syscallno; -} - -/** - * syscall_rollback - roll back registers after an aborted system call - * @task: task of interest, must be in system call exit tracing - * @regs: task_pt_regs() of @task - * - * It's only valid to call this when @task is stopped for system - * call exit tracing (due to TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT), - * after tracehook_report_syscall_entry() returned nonzero to prevent - * the system call from taking place. - * - * This rolls back the register state in @regs so it's as if the - * system call instruction was a no-op. The registers containing - * the system call number and arguments are as they were before the - * system call instruction. This may not be the same as what the - * register state looked like at system call entry tracing. - */ -static inline void -syscall_rollback(struct task_struct *task, struct pt_regs *regs) -{ - regs->uregs[0] = regs->orig_r0; -} - -/** - * syscall_get_error - check result of traced system call - * @task: task of interest, must be blocked - * @regs: task_pt_regs() of @task - * - * Returns 0 if the system call succeeded, or -ERRORCODE if it failed. - * - * It's only valid to call this when @task is stopped for tracing on exit - * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. - */ -static inline long -syscall_get_error(struct task_struct *task, struct pt_regs *regs) -{ - unsigned long error = regs->uregs[0]; - return IS_ERR_VALUE(error) ? error : 0; -} - -/** - * syscall_get_return_value - get the return value of a traced system call - * @task: task of interest, must be blocked - * @regs: task_pt_regs() of @task - * - * Returns the return value of the successful system call. - * This value is meaningless if syscall_get_error() returned nonzero. - * - * It's only valid to call this when @task is stopped for tracing on exit - * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. - */ -static inline long -syscall_get_return_value(struct task_struct *task, struct pt_regs *regs) -{ - return regs->uregs[0]; -} - -/** - * syscall_set_return_value - change the return value of a traced system call - * @task: task of interest, must be blocked - * @regs: task_pt_regs() of @task - * @error: negative error code, or zero to indicate success - * @val: user return value if @error is zero - * - * This changes the results of the system call that user mode will see. - * If @error is zero, the user sees a successful system call with a - * return value of @val. If @error is nonzero, it's a negated errno - * code; the user sees a failed system call with this errno code. - * - * It's only valid to call this when @task is stopped for tracing on exit - * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. - */ -static inline void -syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, - int error, long val) -{ - regs->uregs[0] = (long)error ? error : val; -} - -/** - * syscall_get_arguments - extract system call parameter values - * @task: task of interest, must be blocked - * @regs: task_pt_regs() of @task - * @args: array filled with argument values - * - * Fetches 6 arguments to the system call (from 0 through 5). The first - * argument is stored in @args[0], and so on. - * - * It's only valid to call this when @task is stopped for tracing on - * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. - */ -#define SYSCALL_MAX_ARGS 6 -static inline void -syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, - unsigned long *args) -{ - args[0] = regs->orig_r0; - args++; - memcpy(args, ®s->uregs[0] + 1, 5 * sizeof(args[0])); -} - -static inline int -syscall_get_arch(struct task_struct *task) -{ - return IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) - ? AUDIT_ARCH_NDS32BE : AUDIT_ARCH_NDS32; -} - -#endif /* _ASM_NDS32_SYSCALL_H */ diff --git a/arch/nds32/include/asm/syscalls.h b/arch/nds32/include/asm/syscalls.h deleted file mode 100644 index 4e7216082a67..000000000000 --- a/arch/nds32/include/asm/syscalls.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __ASM_NDS32_SYSCALLS_H -#define __ASM_NDS32_SYSCALLS_H - -asmlinkage long sys_cacheflush(unsigned long addr, unsigned long len, unsigned int op); -asmlinkage long sys_fadvise64_64_wrapper(int fd, int advice, loff_t offset, loff_t len); -asmlinkage long sys_rt_sigreturn_wrapper(void); -asmlinkage long sys_fp_udfiex_crtl(int cmd, int act); - -#include - -#endif /* __ASM_NDS32_SYSCALLS_H */ diff --git a/arch/nds32/include/asm/thread_info.h b/arch/nds32/include/asm/thread_info.h deleted file mode 100644 index bd8f81cf2ce5..000000000000 --- a/arch/nds32/include/asm/thread_info.h +++ /dev/null @@ -1,72 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __ASM_NDS32_THREAD_INFO_H -#define __ASM_NDS32_THREAD_INFO_H - -#ifdef __KERNEL__ - -#define THREAD_SIZE_ORDER (1) -#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) - -#ifndef __ASSEMBLY__ - -struct task_struct; - -#include -#include - -/* - * low level task data that entry.S needs immediate access to. - * __switch_to() assumes cpu_context follows immediately after cpu_domain. - */ -struct thread_info { - unsigned long flags; /* low level flags */ - __s32 preempt_count; /* 0 => preemptable, <0 => bug */ -}; -#define INIT_THREAD_INFO(tsk) \ -{ \ - .preempt_count = INIT_PREEMPT_COUNT, \ -} -#define thread_saved_pc(tsk) ((unsigned long)(tsk->thread.cpu_context.pc)) -#define thread_saved_fp(tsk) ((unsigned long)(tsk->thread.cpu_context.fp)) -#endif - -/* - * thread information flags: - * TIF_SYSCALL_TRACE - syscall trace active - * TIF_SIGPENDING - signal pending - * TIF_NEED_RESCHED - rescheduling necessary - * TIF_NOTIFY_RESUME - callback before returning to user - * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED - */ -#define TIF_SIGPENDING 1 -#define TIF_NEED_RESCHED 2 -#define TIF_SINGLESTEP 3 -#define TIF_NOTIFY_RESUME 4 /* callback before returning to user */ -#define TIF_NOTIFY_SIGNAL 5 /* signal notifications exist */ -#define TIF_SYSCALL_TRACE 8 -#define TIF_POLLING_NRFLAG 17 -#define TIF_MEMDIE 18 -#define TIF_FREEZE 19 -#define TIF_RESTORE_SIGMASK 20 - -#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) -#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) -#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) -#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL) -#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) -#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) -#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) -#define _TIF_FREEZE (1 << TIF_FREEZE) -#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) - -/* - * Change these and you break ASM code in entry-common.S - */ -#define _TIF_WORK_MASK 0x000000ff -#define _TIF_WORK_SYSCALL_ENTRY (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP) -#define _TIF_WORK_SYSCALL_LEAVE (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP) - -#endif /* __KERNEL__ */ -#endif /* __ASM_NDS32_THREAD_INFO_H */ diff --git a/arch/nds32/include/asm/tlb.h b/arch/nds32/include/asm/tlb.h deleted file mode 100644 index 672603804a3b..000000000000 --- a/arch/nds32/include/asm/tlb.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __ASMNDS32_TLB_H -#define __ASMNDS32_TLB_H - -#include - -#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte) - -#endif diff --git a/arch/nds32/include/asm/tlbflush.h b/arch/nds32/include/asm/tlbflush.h deleted file mode 100644 index 97155366ea01..000000000000 --- a/arch/nds32/include/asm/tlbflush.h +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef _ASMNDS32_TLBFLUSH_H -#define _ASMNDS32_TLBFLUSH_H - -#include -#include -#include - -static inline void local_flush_tlb_all(void) -{ - __nds32__tlbop_flua(); - __nds32__isb(); -} - -static inline void local_flush_tlb_mm(struct mm_struct *mm) -{ - __nds32__tlbop_flua(); - __nds32__isb(); -} - -static inline void local_flush_tlb_kernel_range(unsigned long start, - unsigned long end) -{ - while (start < end) { - __nds32__tlbop_inv(start); - __nds32__isb(); - start += PAGE_SIZE; - } -} - -void local_flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end); -void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long addr); - -#define flush_tlb_all local_flush_tlb_all -#define flush_tlb_mm local_flush_tlb_mm -#define flush_tlb_range local_flush_tlb_range -#define flush_tlb_page local_flush_tlb_page -#define flush_tlb_kernel_range local_flush_tlb_kernel_range - -void update_mmu_cache(struct vm_area_struct *vma, - unsigned long address, pte_t * pte); - -#endif diff --git a/arch/nds32/include/asm/uaccess.h b/arch/nds32/include/asm/uaccess.h deleted file mode 100644 index 377548d4451a..000000000000 --- a/arch/nds32/include/asm/uaccess.h +++ /dev/null @@ -1,282 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef _ASMANDES_UACCESS_H -#define _ASMANDES_UACCESS_H - -/* - * User space memory access functions - */ -#include -#include -#include -#include -#include - -#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t" - -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry { - unsigned long insn, fixup; -}; - -extern int fixup_exception(struct pt_regs *regs); - -/* - * Single-value transfer routines. They automatically use the right - * size if we just have the right pointer type. Note that the functions - * which read from user space (*get_*) need to take care not to leak - * kernel data even if the calling code is buggy and fails to check - * the return value. This means zeroing out the destination variable - * or buffer on error. Normally this is done out of line by the - * fixup code, but there are a few places where it intrudes on the - * main code path. When we only write to user space, there is no - * problem. - * - * The "__xxx" versions of the user access functions do not verify the - * address space - it must have been done previously with a separate - * "access_ok()" call. - * - * The "xxx_error" versions set the third argument to EFAULT if an - * error occurs, and leave it unchanged on success. Note that these - * versions are void (ie, don't return a value as such). - */ - -#define get_user(x, ptr) \ -({ \ - long __gu_err = 0; \ - __get_user_check((x), (ptr), __gu_err); \ - __gu_err; \ -}) - -#define __get_user_error(x, ptr, err) \ -({ \ - __get_user_check((x), (ptr), (err)); \ - (void)0; \ -}) - -#define __get_user(x, ptr) \ -({ \ - long __gu_err = 0; \ - const __typeof__(*(ptr)) __user *__p = (ptr); \ - __get_user_err((x), __p, (__gu_err)); \ - __gu_err; \ -}) - -#define __get_user_check(x, ptr, err) \ -({ \ - const __typeof__(*(ptr)) __user *__p = (ptr); \ - might_fault(); \ - if (access_ok(__p, sizeof(*__p))) { \ - __get_user_err((x), __p, (err)); \ - } else { \ - (x) = 0; (err) = -EFAULT; \ - } \ -}) - -#define __get_user_err(x, ptr, err) \ -do { \ - unsigned long __gu_val; \ - __chk_user_ptr(ptr); \ - switch (sizeof(*(ptr))) { \ - case 1: \ - __get_user_asm("lbi", __gu_val, (ptr), (err)); \ - break; \ - case 2: \ - __get_user_asm("lhi", __gu_val, (ptr), (err)); \ - break; \ - case 4: \ - __get_user_asm("lwi", __gu_val, (ptr), (err)); \ - break; \ - case 8: \ - __get_user_asm_dword(__gu_val, (ptr), (err)); \ - break; \ - default: \ - BUILD_BUG(); \ - break; \ - } \ - (x) = (__force __typeof__(*(ptr)))__gu_val; \ -} while (0) - -#define __get_user_asm(inst, x, addr, err) \ - __asm__ __volatile__ ( \ - "1: "inst" %1,[%2]\n" \ - "2:\n" \ - " .section .fixup,\"ax\"\n" \ - " .align 2\n" \ - "3: move %0, %3\n" \ - " move %1, #0\n" \ - " b 2b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 3\n" \ - " .long 1b, 3b\n" \ - " .previous" \ - : "+r" (err), "=&r" (x) \ - : "r" (addr), "i" (-EFAULT) \ - : "cc") - -#ifdef __NDS32_EB__ -#define __gu_reg_oper0 "%H1" -#define __gu_reg_oper1 "%L1" -#else -#define __gu_reg_oper0 "%L1" -#define __gu_reg_oper1 "%H1" -#endif - -#define __get_user_asm_dword(x, addr, err) \ - __asm__ __volatile__ ( \ - "\n1:\tlwi " __gu_reg_oper0 ",[%2]\n" \ - "\n2:\tlwi " __gu_reg_oper1 ",[%2+4]\n" \ - "3:\n" \ - " .section .fixup,\"ax\"\n" \ - " .align 2\n" \ - "4: move %0, %3\n" \ - " b 3b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 3\n" \ - " .long 1b, 4b\n" \ - " .long 2b, 4b\n" \ - " .previous" \ - : "+r"(err), "=&r"(x) \ - : "r"(addr), "i"(-EFAULT) \ - : "cc") - -#define put_user(x, ptr) \ -({ \ - long __pu_err = 0; \ - __put_user_check((x), (ptr), __pu_err); \ - __pu_err; \ -}) - -#define __put_user(x, ptr) \ -({ \ - long __pu_err = 0; \ - __typeof__(*(ptr)) __user *__p = (ptr); \ - __put_user_err((x), __p, __pu_err); \ - __pu_err; \ -}) - -#define __put_user_error(x, ptr, err) \ -({ \ - __put_user_err((x), (ptr), (err)); \ - (void)0; \ -}) - -#define __put_user_check(x, ptr, err) \ -({ \ - __typeof__(*(ptr)) __user *__p = (ptr); \ - might_fault(); \ - if (access_ok(__p, sizeof(*__p))) { \ - __put_user_err((x), __p, (err)); \ - } else { \ - (err) = -EFAULT; \ - } \ -}) - -#define __put_user_err(x, ptr, err) \ -do { \ - __typeof__(*(ptr)) __pu_val = (x); \ - __chk_user_ptr(ptr); \ - switch (sizeof(*(ptr))) { \ - case 1: \ - __put_user_asm("sbi", __pu_val, (ptr), (err)); \ - break; \ - case 2: \ - __put_user_asm("shi", __pu_val, (ptr), (err)); \ - break; \ - case 4: \ - __put_user_asm("swi", __pu_val, (ptr), (err)); \ - break; \ - case 8: \ - __put_user_asm_dword(__pu_val, (ptr), (err)); \ - break; \ - default: \ - BUILD_BUG(); \ - break; \ - } \ -} while (0) - -#define __put_user_asm(inst, x, addr, err) \ - __asm__ __volatile__ ( \ - "1: "inst" %1,[%2]\n" \ - "2:\n" \ - " .section .fixup,\"ax\"\n" \ - " .align 2\n" \ - "3: move %0, %3\n" \ - " b 2b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 3\n" \ - " .long 1b, 3b\n" \ - " .previous" \ - : "+r" (err) \ - : "r" (x), "r" (addr), "i" (-EFAULT) \ - : "cc") - -#ifdef __NDS32_EB__ -#define __pu_reg_oper0 "%H2" -#define __pu_reg_oper1 "%L2" -#else -#define __pu_reg_oper0 "%L2" -#define __pu_reg_oper1 "%H2" -#endif - -#define __put_user_asm_dword(x, addr, err) \ - __asm__ __volatile__ ( \ - "\n1:\tswi " __pu_reg_oper0 ",[%1]\n" \ - "\n2:\tswi " __pu_reg_oper1 ",[%1+4]\n" \ - "3:\n" \ - " .section .fixup,\"ax\"\n" \ - " .align 2\n" \ - "4: move %0, %3\n" \ - " b 3b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 3\n" \ - " .long 1b, 4b\n" \ - " .long 2b, 4b\n" \ - " .previous" \ - : "+r"(err) \ - : "r"(addr), "r"(x), "i"(-EFAULT) \ - : "cc") - -extern unsigned long __arch_clear_user(void __user * addr, unsigned long n); -extern long strncpy_from_user(char *dest, const char __user * src, long count); -extern __must_check long strnlen_user(const char __user * str, long n); -extern unsigned long __arch_copy_from_user(void *to, const void __user * from, - unsigned long n); -extern unsigned long __arch_copy_to_user(void __user * to, const void *from, - unsigned long n); - -#define raw_copy_from_user __arch_copy_from_user -#define raw_copy_to_user __arch_copy_to_user - -#define INLINE_COPY_FROM_USER -#define INLINE_COPY_TO_USER -static inline unsigned long clear_user(void __user * to, unsigned long n) -{ - if (access_ok(to, n)) - n = __arch_clear_user(to, n); - return n; -} - -static inline unsigned long __clear_user(void __user * to, unsigned long n) -{ - return __arch_clear_user(to, n); -} - -#endif /* _ASMNDS32_UACCESS_H */ diff --git a/arch/nds32/include/asm/unistd.h b/arch/nds32/include/asm/unistd.h deleted file mode 100644 index bf5e2d440913..000000000000 --- a/arch/nds32/include/asm/unistd.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#define __ARCH_WANT_SYS_CLONE - -#include diff --git a/arch/nds32/include/asm/vdso.h b/arch/nds32/include/asm/vdso.h deleted file mode 100644 index 89b113ffc3dc..000000000000 --- a/arch/nds32/include/asm/vdso.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2005-2017 Andes Technology Corporation - */ - -#ifndef __ASM_VDSO_H -#define __ASM_VDSO_H - -#ifdef __KERNEL__ - -#ifndef __ASSEMBLY__ - -#include - -#define VDSO_SYMBOL(base, name) \ -({ \ - (unsigned long)(vdso_offset_##name + (unsigned long)(base)); \ -}) - -#endif /* !__ASSEMBLY__ */ - -#endif /* __KERNEL__ */ - -#endif /* __ASM_VDSO_H */ diff --git a/arch/nds32/include/asm/vdso_datapage.h b/arch/nds32/include/asm/vdso_datapage.h deleted file mode 100644 index 74c68802021e..000000000000 --- a/arch/nds32/include/asm/vdso_datapage.h +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2012 ARM Limited -// Copyright (C) 2005-2017 Andes Technology Corporation -#ifndef __ASM_VDSO_DATAPAGE_H -#define __ASM_VDSO_DATAPAGE_H - -#ifdef __KERNEL__ - -#ifndef __ASSEMBLY__ - -struct vdso_data { - bool cycle_count_down; /* timer cyclye counter is decrease with time */ - u32 cycle_count_offset; /* offset of timer cycle counter register */ - u32 seq_count; /* sequence count - odd during updates */ - u32 xtime_coarse_sec; /* coarse time */ - u32 xtime_coarse_nsec; - - u32 wtm_clock_sec; /* wall to monotonic offset */ - u32 wtm_clock_nsec; - u32 xtime_clock_sec; /* CLOCK_REALTIME - seconds */ - u32 cs_mult; /* clocksource multiplier */ - u32 cs_shift; /* Cycle to nanosecond divisor (power of two) */ - u32 hrtimer_res; /* hrtimer resolution */ - - u64 cs_cycle_last; /* last cycle value */ - u64 cs_mask; /* clocksource mask */ - - u64 xtime_clock_nsec; /* CLOCK_REALTIME sub-ns base */ - u32 tz_minuteswest; /* timezone info for gettimeofday(2) */ - u32 tz_dsttime; -}; - -#endif /* !__ASSEMBLY__ */ - -#endif /* __KERNEL__ */ - -#endif /* __ASM_VDSO_DATAPAGE_H */ diff --git a/arch/nds32/include/asm/vdso_timer_info.h b/arch/nds32/include/asm/vdso_timer_info.h deleted file mode 100644 index 328439ce37db..000000000000 --- a/arch/nds32/include/asm/vdso_timer_info.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -extern struct timer_info_t timer_info; -#define EMPTY_VALUE ~(0UL) -#define EMPTY_TIMER_MAPPING EMPTY_VALUE -#define EMPTY_REG_OFFSET EMPTY_VALUE - -struct timer_info_t -{ - bool cycle_count_down; - unsigned long mapping_base; - unsigned long cycle_count_reg_offset; -}; diff --git a/arch/nds32/include/asm/vermagic.h b/arch/nds32/include/asm/vermagic.h deleted file mode 100644 index f772e7ba33f1..000000000000 --- a/arch/nds32/include/asm/vermagic.h +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef _ASM_VERMAGIC_H -#define _ASM_VERMAGIC_H - -#define MODULE_ARCH_VERMAGIC "NDS32v3" - -#endif /* _ASM_VERMAGIC_H */ diff --git a/arch/nds32/include/asm/vmalloc.h b/arch/nds32/include/asm/vmalloc.h deleted file mode 100644 index caeed3898419..000000000000 --- a/arch/nds32/include/asm/vmalloc.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef _ASM_NDS32_VMALLOC_H -#define _ASM_NDS32_VMALLOC_H - -#endif /* _ASM_NDS32_VMALLOC_H */ diff --git a/arch/nds32/include/uapi/asm/Kbuild b/arch/nds32/include/uapi/asm/Kbuild deleted file mode 100644 index e78470141932..000000000000 --- a/arch/nds32/include/uapi/asm/Kbuild +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -generic-y += ucontext.h diff --git a/arch/nds32/include/uapi/asm/auxvec.h b/arch/nds32/include/uapi/asm/auxvec.h deleted file mode 100644 index bc0b92ab8c15..000000000000 --- a/arch/nds32/include/uapi/asm/auxvec.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __ASM_AUXVEC_H -#define __ASM_AUXVEC_H - -/* - * This entry gives some information about the FPU initialization - * performed by the kernel. - */ -#define AT_FPUCW 18 /* Used FPU control word. */ - - -/* VDSO location */ -#define AT_SYSINFO_EHDR 33 - -#define AT_VECTOR_SIZE_ARCH 1 - -#endif diff --git a/arch/nds32/include/uapi/asm/byteorder.h b/arch/nds32/include/uapi/asm/byteorder.h deleted file mode 100644 index c264ef12c49c..000000000000 --- a/arch/nds32/include/uapi/asm/byteorder.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __NDS32_BYTEORDER_H__ -#define __NDS32_BYTEORDER_H__ - -#ifdef __NDS32_EB__ -#include -#else -#include -#endif - -#endif /* __NDS32_BYTEORDER_H__ */ diff --git a/arch/nds32/include/uapi/asm/cachectl.h b/arch/nds32/include/uapi/asm/cachectl.h deleted file mode 100644 index 31b9b439d819..000000000000 --- a/arch/nds32/include/uapi/asm/cachectl.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -// Copyright (C) 1994, 1995, 1996 by Ralf Baechle -// Copyright (C) 2005-2017 Andes Technology Corporation -#ifndef _ASM_CACHECTL -#define _ASM_CACHECTL - -/* - * Options for cacheflush system call - */ -#define ICACHE 0 /* flush instruction cache */ -#define DCACHE 1 /* writeback and flush data cache */ -#define BCACHE 2 /* flush instruction cache + writeback and flush data cache */ - -#endif /* _ASM_CACHECTL */ diff --git a/arch/nds32/include/uapi/asm/fp_udfiex_crtl.h b/arch/nds32/include/uapi/asm/fp_udfiex_crtl.h deleted file mode 100644 index f17396db16ec..000000000000 --- a/arch/nds32/include/uapi/asm/fp_udfiex_crtl.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -/* Copyright (C) 2005-2019 Andes Technology Corporation */ -#ifndef _FP_UDF_IEX_CRTL_H -#define _FP_UDF_IEX_CRTL_H - -/* - * The cmd list of sys_fp_udfiex_crtl() - */ -/* Disable UDF or IEX trap based on the content of parameter act */ -#define DISABLE_UDF_IEX_TRAP 0 -/* Enable UDF or IEX trap based on the content of parameter act */ -#define ENABLE_UDF_IEX_TRAP 1 -/* Get current status of UDF and IEX trap */ -#define GET_UDF_IEX_TRAP 2 - -#endif /* _FP_UDF_IEX_CRTL_H */ diff --git a/arch/nds32/include/uapi/asm/param.h b/arch/nds32/include/uapi/asm/param.h deleted file mode 100644 index 48d00328d328..000000000000 --- a/arch/nds32/include/uapi/asm/param.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __ASM_NDS32_PARAM_H -#define __ASM_NDS32_PARAM_H - -#define EXEC_PAGESIZE 8192 - -#include - -#endif /* __ASM_NDS32_PARAM_H */ diff --git a/arch/nds32/include/uapi/asm/ptrace.h b/arch/nds32/include/uapi/asm/ptrace.h deleted file mode 100644 index d76217c7c010..000000000000 --- a/arch/nds32/include/uapi/asm/ptrace.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef __UAPI_ASM_NDS32_PTRACE_H -#define __UAPI_ASM_NDS32_PTRACE_H - -#ifndef __ASSEMBLY__ - -/* - * User structures for general purpose register. - */ -struct user_pt_regs { - long uregs[26]; - long fp; - long gp; - long lp; - long sp; - long ipc; - long lb; - long le; - long lc; - long syscallno; -}; -#endif -#endif diff --git a/arch/nds32/include/uapi/asm/sigcontext.h b/arch/nds32/include/uapi/asm/sigcontext.h deleted file mode 100644 index 6c1e6648878f..000000000000 --- a/arch/nds32/include/uapi/asm/sigcontext.h +++ /dev/null @@ -1,84 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#ifndef _ASMNDS32_SIGCONTEXT_H -#define _ASMNDS32_SIGCONTEXT_H - -/* - * Signal context structure - contains all info to do with the state - * before the signal handler was invoked. Note: only add new entries - * to the end of the structure. - */ -struct fpu_struct { - unsigned long long fd_regs[32]; - unsigned long fpcsr; - /* - * When CONFIG_SUPPORT_DENORMAL_ARITHMETIC is defined, kernel prevents - * hardware from treating the denormalized output as an underflow case - * and rounding it to a normal number. Hence kernel enables the UDF and - * IEX trap in the fpcsr register to step in the calculation. - * However, the UDF and IEX trap enable bit in $fpcsr also lose - * their use. - * - * UDF_IEX_trap replaces the feature of UDF and IEX trap enable bit in - * $fpcsr to control the trap of underflow and inexact. The bit filed - * of UDF_IEX_trap is the same as $fpcsr, 10th bit is used to enable UDF - * exception trapping and 11th bit is used to enable IEX exception - * trapping. - * - * UDF_IEX_trap is only modified through fp_udfiex_crtl syscall. - * Therefore, UDF_IEX_trap needn't be saved and restored in each - * context switch. - */ - unsigned long UDF_IEX_trap; -}; - -struct zol_struct { - unsigned long nds32_lc; /* $LC */ - unsigned long nds32_le; /* $LE */ - unsigned long nds32_lb; /* $LB */ -}; - -struct sigcontext { - unsigned long trap_no; - unsigned long error_code; - unsigned long oldmask; - unsigned long nds32_r0; - unsigned long nds32_r1; - unsigned long nds32_r2; - unsigned long nds32_r3; - unsigned long nds32_r4; - unsigned long nds32_r5; - unsigned long nds32_r6; - unsigned long nds32_r7; - unsigned long nds32_r8; - unsigned long nds32_r9; - unsigned long nds32_r10; - unsigned long nds32_r11; - unsigned long nds32_r12; - unsigned long nds32_r13; - unsigned long nds32_r14; - unsigned long nds32_r15; - unsigned long nds32_r16; - unsigned long nds32_r17; - unsigned long nds32_r18; - unsigned long nds32_r19; - unsigned long nds32_r20; - unsigned long nds32_r21; - unsigned long nds32_r22; - unsigned long nds32_r23; - unsigned long nds32_r24; - unsigned long nds32_r25; - unsigned long nds32_fp; /* $r28 */ - unsigned long nds32_gp; /* $r29 */ - unsigned long nds32_lp; /* $r30 */ - unsigned long nds32_sp; /* $r31 */ - unsigned long nds32_ipc; - unsigned long fault_address; - unsigned long used_math_flag; - /* FPU Registers */ - struct fpu_struct fpu; - struct zol_struct zol; -}; - -#endif diff --git a/arch/nds32/include/uapi/asm/unistd.h b/arch/nds32/include/uapi/asm/unistd.h deleted file mode 100644 index 410795e280fe..000000000000 --- a/arch/nds32/include/uapi/asm/unistd.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -// Copyright (C) 2005-2017 Andes Technology Corporation - -#define __ARCH_WANT_STAT64 -#define __ARCH_WANT_SYNC_FILE_RANGE2 -#define __ARCH_WANT_SET_GET_RLIMIT -#define __ARCH_WANT_TIME32_SYSCALLS - -/* Use the standard ABI for syscalls */ -#include - -/* Additional NDS32 specific syscalls. */ -#define __NR_cacheflush (__NR_arch_specific_syscall) -#define __NR_fp_udfiex_crtl (__NR_arch_specific_syscall + 1) -__SYSCALL(__NR_cacheflush, sys_cacheflush) -__SYSCALL(__NR_fp_udfiex_crtl, sys_fp_udfiex_crtl) diff --git a/arch/nds32/kernel/.gitignore b/arch/nds32/kernel/.gitignore deleted file mode 100644 index bbb90f92d051..000000000000 --- a/arch/nds32/kernel/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -vmlinux.lds diff --git a/arch/nds32/kernel/Makefile b/arch/nds32/kernel/Makefile deleted file mode 100644 index 394df3f6442c..000000000000 --- a/arch/nds32/kernel/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Makefile for the linux kernel. -# - -CPPFLAGS_vmlinux.lds := -DTEXTADDR=$(TEXTADDR) -AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) -# Object file lists. - -obj-y := ex-entry.o ex-exit.o ex-scall.o irq.o \ - process.o ptrace.o setup.o signal.o \ - sys_nds32.o time.o traps.o cacheinfo.o \ - dma.o syscall_table.o vdso.o - -obj-$(CONFIG_MODULES) += nds32_ksyms.o module.o -obj-$(CONFIG_STACKTRACE) += stacktrace.o -obj-$(CONFIG_FPU) += fpu.o -obj-$(CONFIG_OF) += devtree.o -obj-$(CONFIG_CACHE_L2) += atl2c.o -obj-$(CONFIG_PERF_EVENTS) += perf_event_cpu.o -obj-$(CONFIG_PM) += pm.o sleep.o -extra-y := head.o vmlinux.lds - -CFLAGS_fpu.o += -mext-fpu-sp -mext-fpu-dp - - -obj-y += vdso/ - -obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o - -ifdef CONFIG_FUNCTION_TRACER -CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE) -endif diff --git a/arch/nds32/kernel/asm-offsets.c b/arch/nds32/kernel/asm-offsets.c deleted file mode 100644 index 3541d5981de7..000000000000 --- a/arch/nds32/kernel/asm-offsets.c +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include - -int main(void) -{ - DEFINE(TSK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags)); - DEFINE(TSK_TI_PREEMPT, - offsetof(struct task_struct, thread_info.preempt_count)); - DEFINE(THREAD_CPU_CONTEXT, - offsetof(struct task_struct, thread.cpu_context)); - DEFINE(OSP_OFFSET, offsetof(struct pt_regs, osp)); - DEFINE(SP_OFFSET, offsetof(struct pt_regs, sp)); - DEFINE(FUCOP_CTL_OFFSET, offsetof(struct pt_regs, fucop_ctl)); - DEFINE(IPSW_OFFSET, offsetof(struct pt_regs, ipsw)); - DEFINE(SYSCALLNO_OFFSET, offsetof(struct pt_regs, syscallno)); - DEFINE(IPC_OFFSET, offsetof(struct pt_regs, ipc)); - DEFINE(R0_OFFSET, offsetof(struct pt_regs, uregs[0])); - DEFINE(R15_OFFSET, offsetof(struct pt_regs, uregs[15])); - DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); - DEFINE(CLOCK_COARSE_RES, LOW_RES_NSEC); - return 0; -} diff --git a/arch/nds32/kernel/atl2c.c b/arch/nds32/kernel/atl2c.c deleted file mode 100644 index 0c5386e72098..000000000000 --- a/arch/nds32/kernel/atl2c.c +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include - -void __iomem *atl2c_base; -static const struct of_device_id atl2c_ids[] __initconst = { - {.compatible = "andestech,atl2c",}, - {} -}; - -static int __init atl2c_of_init(void) -{ - struct device_node *np; - struct resource res; - unsigned long tmp = 0; - unsigned long l2set, l2way, l2clsz; - - if (!(__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskL2C)) - return -ENODEV; - - np = of_find_matching_node(NULL, atl2c_ids); - if (!np) - return -ENODEV; - - if (of_address_to_resource(np, 0, &res)) - return -ENODEV; - - atl2c_base = ioremap(res.start, resource_size(&res)); - if (!atl2c_base) - return -ENOMEM; - - l2set = - 64 << ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2SET) >> - L2_CA_CONF_offL2SET); - l2way = - 1 + - ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2WAY) >> - L2_CA_CONF_offL2WAY); - l2clsz = - 4 << ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2CLSZ) >> - L2_CA_CONF_offL2CLSZ); - pr_info("L2:%luKB/%luS/%luW/%luB\n", - l2set * l2way * l2clsz / 1024, l2set, l2way, l2clsz); - - tmp = L2C_R_REG(L2CC_PROT_OFF); - tmp &= ~L2CC_PROT_mskMRWEN; - L2C_W_REG(L2CC_PROT_OFF, tmp); - - tmp = L2C_R_REG(L2CC_SETUP_OFF); - tmp &= ~L2CC_SETUP_mskPART; - L2C_W_REG(L2CC_SETUP_OFF, tmp); - - tmp = L2C_R_REG(L2CC_CTRL_OFF); - tmp |= L2CC_CTRL_mskEN; - L2C_W_REG(L2CC_CTRL_OFF, tmp); - - return 0; -} - -subsys_initcall(atl2c_of_init); diff --git a/arch/nds32/kernel/cacheinfo.c b/arch/nds32/kernel/cacheinfo.c deleted file mode 100644 index aab98e447feb..000000000000 --- a/arch/nds32/kernel/cacheinfo.c +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include - -static void ci_leaf_init(struct cacheinfo *this_leaf, - enum cache_type type, unsigned int level) -{ - char cache_type = (type & CACHE_TYPE_INST ? ICACHE : DCACHE); - - this_leaf->level = level; - this_leaf->type = type; - this_leaf->coherency_line_size = CACHE_LINE_SIZE(cache_type); - this_leaf->number_of_sets = CACHE_SET(cache_type); - this_leaf->ways_of_associativity = CACHE_WAY(cache_type); - this_leaf->size = this_leaf->number_of_sets * - this_leaf->coherency_line_size * this_leaf->ways_of_associativity; -#if defined(CONFIG_CPU_DCACHE_WRITETHROUGH) - this_leaf->attributes = CACHE_WRITE_THROUGH; -#else - this_leaf->attributes = CACHE_WRITE_BACK; -#endif -} - -int init_cache_level(unsigned int cpu) -{ - struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); - - /* Only 1 level and I/D cache seperate. */ - this_cpu_ci->num_levels = 1; - this_cpu_ci->num_leaves = 2; - return 0; -} - -int populate_cache_leaves(unsigned int cpu) -{ - unsigned int level, idx; - struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); - struct cacheinfo *this_leaf = this_cpu_ci->info_list; - - for (idx = 0, level = 1; level <= this_cpu_ci->num_levels && - idx < this_cpu_ci->num_leaves; idx++, level++) { - ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level); - ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level); - } - return 0; -} diff --git a/arch/nds32/kernel/devtree.c b/arch/nds32/kernel/devtree.c deleted file mode 100644 index bdce0fe5af9f..000000000000 --- a/arch/nds32/kernel/devtree.c +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include - -void __init early_init_devtree(void *params) -{ - if (!params || !early_init_dt_scan(params)) { - pr_crit("\n" - "Error: invalid device tree blob at (virtual address 0x%p)\n" - "\nPlease check your bootloader.", params); - - BUG_ON(1); - } - - dump_stack_set_arch_desc("%s (DT)", of_flat_dt_get_machine_name()); -} diff --git a/arch/nds32/kernel/dma.c b/arch/nds32/kernel/dma.c deleted file mode 100644 index 2ac8e6c82a61..000000000000 --- a/arch/nds32/kernel/dma.c +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include -#include - -static inline void cache_op(phys_addr_t paddr, size_t size, - void (*fn)(unsigned long start, unsigned long end)) -{ - struct page *page = pfn_to_page(paddr >> PAGE_SHIFT); - unsigned offset = paddr & ~PAGE_MASK; - size_t left = size; - unsigned long start; - - do { - size_t len = left; - - if (PageHighMem(page)) { - void *addr; - - if (offset + len > PAGE_SIZE) { - if (offset >= PAGE_SIZE) { - page += offset >> PAGE_SHIFT; - offset &= ~PAGE_MASK; - } - len = PAGE_SIZE - offset; - } - - addr = kmap_atomic(page); - start = (unsigned long)(addr + offset); - fn(start, start + len); - kunmap_atomic(addr); - } else { - start = (unsigned long)phys_to_virt(paddr); - fn(start, start + size); - } - offset = 0; - page++; - left -= len; - } while (left); -} - -void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, - enum dma_data_direction dir) -{ - switch (dir) { - case DMA_FROM_DEVICE: - break; - case DMA_TO_DEVICE: - case DMA_BIDIRECTIONAL: - cache_op(paddr, size, cpu_dma_wb_range); - break; - default: - BUG(); - } -} - -void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, - enum dma_data_direction dir) -{ - switch (dir) { - case DMA_TO_DEVICE: - break; - case DMA_FROM_DEVICE: - case DMA_BIDIRECTIONAL: - cache_op(paddr, size, cpu_dma_inval_range); - break; - default: - BUG(); - } -} - -void arch_dma_prep_coherent(struct page *page, size_t size) -{ - cache_op(page_to_phys(page), size, cpu_dma_wbinval_range); -} diff --git a/arch/nds32/kernel/ex-entry.S b/arch/nds32/kernel/ex-entry.S deleted file mode 100644 index 107d98a1d1b8..000000000000 --- a/arch/nds32/kernel/ex-entry.S +++ /dev/null @@ -1,177 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_HWZOL - .macro push_zol - mfusr $r14, $LB - mfusr $r15, $LE - mfusr $r16, $LC - .endm -#endif - .macro skip_save_fucop_ctl -#if defined(CONFIG_FPU) -skip_fucop_ctl: - smw.adm $p0, [$sp], $p0, #0x1 - j fucop_ctl_done -#endif - .endm - - .macro save_user_regs -#if defined(CONFIG_FPU) - sethi $p0, hi20(has_fpu) - lbsi $p0, [$p0+lo12(has_fpu)] - beqz $p0, skip_fucop_ctl - mfsr $p0, $FUCOP_CTL - smw.adm $p0, [$sp], $p0, #0x1 - bclr $p0, $p0, #FUCOP_CTL_offCP0EN - mtsr $p0, $FUCOP_CTL -fucop_ctl_done: - /* move $SP to the bottom of pt_regs */ - addi $sp, $sp, -FUCOP_CTL_OFFSET -#else - smw.adm $sp, [$sp], $sp, #0x1 - /* move $SP to the bottom of pt_regs */ - addi $sp, $sp, -OSP_OFFSET -#endif - - /* push $r0 ~ $r25 */ - smw.bim $r0, [$sp], $r25 - /* push $fp, $gp, $lp */ - smw.bim $sp, [$sp], $sp, #0xe - - mfsr $r12, $SP_USR - mfsr $r13, $IPC -#ifdef CONFIG_HWZOL - push_zol -#endif - movi $r17, -1 - move $r18, $r0 - mfsr $r19, $PSW - mfsr $r20, $IPSW - mfsr $r21, $P_IPSW - mfsr $r22, $P_IPC - mfsr $r23, $P_P0 - mfsr $r24, $P_P1 - smw.bim $r12, [$sp], $r24, #0 - addi $sp, $sp, -FUCOP_CTL_OFFSET - - /* Initialize kernel space $fp */ - andi $p0, $r20, #PSW_mskPOM - movi $p1, #0x0 - cmovz $fp, $p1, $p0 - - andi $r16, $r19, #PSW_mskINTL - slti $r17, $r16, #4 - bnez $r17, 1f - addi $r17, $r19, #-2 - mtsr $r17, $PSW - isb -1: - /* If it was superuser mode, we don't need to update $r25 */ - bnez $p0, 2f - la $p0, __entry_task - lw $r25, [$p0] -2: - .endm - - .text - -/* - * Exception Vector - */ -exception_handlers: - .long unhandled_exceptions !Reset/NMI - .long unhandled_exceptions !TLB fill - .long do_page_fault !PTE not present - .long do_dispatch_tlb_misc !TLB misc - .long unhandled_exceptions !TLB VLPT - .long unhandled_exceptions !Machine Error - .long do_debug_trap !Debug related - .long do_dispatch_general !General exception - .long eh_syscall !Syscall - .long asm_do_IRQ !IRQ - - skip_save_fucop_ctl -common_exception_handler: - save_user_regs - mfsr $p0, $ITYPE - andi $p0, $p0, #ITYPE_mskVECTOR - srli $p0, $p0, #ITYPE_offVECTOR - andi $p1, $p0, #NDS32_VECTOR_mskNONEXCEPTION - bnez $p1, 1f - sethi $lp, hi20(ret_from_exception) - ori $lp, $lp, lo12(ret_from_exception) - sethi $p1, hi20(exception_handlers) - ori $p1, $p1, lo12(exception_handlers) - lw $p1, [$p1+$p0<<2] - move $r0, $p0 - mfsr $r1, $EVA - mfsr $r2, $ITYPE - move $r3, $sp - mfsr $r4, $OIPC - /* enable gie if it is enabled in IPSW. */ - mfsr $r21, $PSW - andi $r20, $r20, #PSW_mskGIE /* r20 is $IPSW*/ - or $r21, $r21, $r20 - mtsr $r21, $PSW - dsb - jr $p1 - /* syscall */ -1: - addi $p1, $p0, #-NDS32_VECTOR_offEXCEPTION - bnez $p1, 2f - sethi $lp, hi20(ret_from_exception) - ori $lp, $lp, lo12(ret_from_exception) - sethi $p1, hi20(exception_handlers) - ori $p1, $p1, lo12(exception_handlers) - lwi $p1, [$p1+#NDS32_VECTOR_offEXCEPTION<<2] - jr $p1 - - /* interrupt */ -2: -#ifdef CONFIG_TRACE_IRQFLAGS - jal __trace_hardirqs_off -#endif - move $r0, $sp - sethi $lp, hi20(ret_from_intr) - ori $lp, $lp, lo12(ret_from_intr) - sethi $p0, hi20(exception_handlers) - ori $p0, $p0, lo12(exception_handlers) - lwi $p0, [$p0+#NDS32_VECTOR_offINTERRUPT<<2] - jr $p0 - - .macro EXCEPTION_VECTOR_DEBUG - .align 4 - mfsr $p0, $EDM_CTL - andi $p0, $p0, EDM_CTL_mskV3_EDM_MODE - tnez $p0, SWID_RAISE_INTERRUPT_LEVEL - .endm - - .macro EXCEPTION_VECTOR - .align 4 - sethi $p0, hi20(common_exception_handler) - ori $p0, $p0, lo12(common_exception_handler) - jral.ton $p0, $p0 - .endm - - .section ".text.init", #alloc, #execinstr - .global exception_vector -exception_vector: -.rept 6 - EXCEPTION_VECTOR -.endr - EXCEPTION_VECTOR_DEBUG -.rept 121 - EXCEPTION_VECTOR -.endr - .align 4 - .global exception_vector_end -exception_vector_end: diff --git a/arch/nds32/kernel/ex-exit.S b/arch/nds32/kernel/ex-exit.S deleted file mode 100644 index b30699911b81..000000000000 --- a/arch/nds32/kernel/ex-exit.S +++ /dev/null @@ -1,193 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include -#include - - - -#ifdef CONFIG_HWZOL - .macro pop_zol - mtusr $r14, $LB - mtusr $r15, $LE - mtusr $r16, $LC - .endm -#endif - - .macro restore_user_regs_first - setgie.d - isb -#if defined(CONFIG_FPU) - addi $sp, $sp, OSP_OFFSET - lmw.adm $r12, [$sp], $r25, #0x0 - sethi $p0, hi20(has_fpu) - lbsi $p0, [$p0+lo12(has_fpu)] - beqz $p0, 2f - mtsr $r25, $FUCOP_CTL -2: -#else - addi $sp, $sp, FUCOP_CTL_OFFSET - lmw.adm $r12, [$sp], $r24, #0x0 -#endif - mtsr $r12, $SP_USR - mtsr $r13, $IPC -#ifdef CONFIG_HWZOL - pop_zol -#endif - mtsr $r19, $PSW - mtsr $r20, $IPSW - mtsr $r21, $P_IPSW - mtsr $r22, $P_IPC - mtsr $r23, $P_P0 - mtsr $r24, $P_P1 - lmw.adm $sp, [$sp], $sp, #0xe - .endm - - .macro restore_user_regs_last - pop $p0 - cmovn $sp, $p0, $p0 - - iret - nop - - .endm - - .macro restore_user_regs - restore_user_regs_first - lmw.adm $r0, [$sp], $r25, #0x0 - addi $sp, $sp, OSP_OFFSET - restore_user_regs_last - .endm - - .macro fast_restore_user_regs - restore_user_regs_first - lmw.adm $r1, [$sp], $r25, #0x0 - addi $sp, $sp, OSP_OFFSET-4 - restore_user_regs_last - .endm - -#ifdef CONFIG_PREEMPTION - .macro preempt_stop - .endm -#else - .macro preempt_stop - setgie.d - isb - .endm -#define resume_kernel no_work_pending -#endif - -ENTRY(ret_from_exception) - preempt_stop -ENTRY(ret_from_intr) - -/* - * judge Kernel or user mode - * - */ - lwi $p0, [$sp+(#IPSW_OFFSET)] ! Check if in nested interrupt - andi $p0, $p0, #PSW_mskINTL - bnez $p0, resume_kernel ! done with iret - j resume_userspace - - -/* - * This is the fast syscall return path. We do as little as - * possible here, and this includes saving $r0 back into the SVC - * stack. - * fixed: tsk - $r25, syscall # - $r7, syscall table pointer - $r8 - */ -ENTRY(ret_fast_syscall) - gie_disable - lwi $r1, [tsk+#TSK_TI_FLAGS] - andi $p1, $r1, #_TIF_WORK_MASK - bnez $p1, fast_work_pending - fast_restore_user_regs ! iret - -/* - * Ok, we need to do extra processing, - * enter the slow path returning from syscall, while pending work. - */ -fast_work_pending: - swi $r0, [$sp+(#R0_OFFSET)] ! what is different from ret_from_exception -work_pending: - andi $p1, $r1, #_TIF_NEED_RESCHED - bnez $p1, work_resched - - andi $p1, $r1, #_TIF_SIGPENDING|#_TIF_NOTIFY_RESUME|#_TIF_NOTIFY_SIGNAL - beqz $p1, no_work_pending - - move $r0, $sp ! 'regs' - gie_enable - bal do_notify_resume - b ret_slow_syscall -work_resched: - bal schedule ! path, return to user mode - -/* - * "slow" syscall return path. - */ -ENTRY(resume_userspace) -ENTRY(ret_slow_syscall) - gie_disable - lwi $p0, [$sp+(#IPSW_OFFSET)] ! Check if in nested interrupt - andi $p0, $p0, #PSW_mskINTL - bnez $p0, no_work_pending ! done with iret - lwi $r1, [tsk+#TSK_TI_FLAGS] - andi $p1, $r1, #_TIF_WORK_MASK - bnez $p1, work_pending ! handle work_resched, sig_pend - -no_work_pending: -#ifdef CONFIG_TRACE_IRQFLAGS - lwi $p0, [$sp+(#IPSW_OFFSET)] - andi $p0, $p0, #0x1 - la $r10, __trace_hardirqs_off - la $r9, __trace_hardirqs_on - cmovz $r9, $p0, $r10 - jral $r9 -#endif - restore_user_regs ! return from iret - - -/* - * preemptive kernel - */ -#ifdef CONFIG_PREEMPTION -resume_kernel: - gie_disable - lwi $t0, [tsk+#TSK_TI_PREEMPT] - bnez $t0, no_work_pending - - lwi $t0, [tsk+#TSK_TI_FLAGS] - andi $p1, $t0, #_TIF_NEED_RESCHED - beqz $p1, no_work_pending - - lwi $t0, [$sp+(#IPSW_OFFSET)] ! Interrupts off? - andi $t0, $t0, #1 - beqz $t0, no_work_pending - - jal preempt_schedule_irq - b no_work_pending -#endif - -/* - * This is how we return from a fork. - */ -ENTRY(ret_from_fork) - bal schedule_tail - beqz $r6, 1f ! r6 stores fn for kernel thread - move $r0, $r7 ! prepare kernel thread arg - jral $r6 -1: - lwi $r1, [tsk+#TSK_TI_FLAGS] ! check for syscall tracing - andi $p1, $r1, #_TIF_WORK_SYSCALL_LEAVE ! are we tracing syscalls? - beqz $p1, ret_slow_syscall - move $r0, $sp - bal syscall_trace_leave - b ret_slow_syscall diff --git a/arch/nds32/kernel/ex-scall.S b/arch/nds32/kernel/ex-scall.S deleted file mode 100644 index 270050f1b7b1..000000000000 --- a/arch/nds32/kernel/ex-scall.S +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include - -/* - * $r0 = previous task_struct, - * $r1 = next task_struct, - * previous and next are guaranteed not to be the same. - */ - -ENTRY(__switch_to) - - la $p0, __entry_task - sw $r1, [$p0] - addi $p1, $r0, #THREAD_CPU_CONTEXT - smw.bi $r6, [$p1], $r14, #0xb ! push r6~r14, fp, lp, sp - move $r25, $r1 -#if defined(CONFIG_FPU) - call _switch_fpu -#endif - addi $r1, $r25, #THREAD_CPU_CONTEXT - lmw.bi $r6, [$r1], $r14, #0xb ! pop r6~r14, fp, lp, sp - ret - - -#define tbl $r8 - -/* - * $r7 will be writen as syscall nr - */ - .macro get_scno - lwi $r7, [$sp + R15_OFFSET] - swi $r7, [$sp + SYSCALLNO_OFFSET] - .endm - - .macro updateipc - addi $r17, $r13, #4 ! $r13 is $IPC - swi $r17, [$sp + IPC_OFFSET] - .endm - -ENTRY(eh_syscall) - updateipc - - get_scno - gie_enable - - lwi $p0, [tsk+#TSK_TI_FLAGS] ! check for syscall tracing - - andi $p1, $p0, #_TIF_WORK_SYSCALL_ENTRY ! are we tracing syscalls? - bnez $p1, __sys_trace - - la $lp, ret_fast_syscall ! return address -jmp_systbl: - addi $p1, $r7, #-__NR_syscalls ! syscall number of syscall instruction is guarded by addembler - bgez $p1, _SCNO_EXCEED ! call sys_* routine - la tbl, sys_call_table ! load syscall table pointer - slli $p1, $r7, #2 - add $p1, tbl, $p1 - lwi $p1, [$p1] - jr $p1 ! no return - -_SCNO_EXCEED: - ori $r0, $r7, #0 - ori $r1, $sp, #0 - b bad_syscall - -/* - * This is the really slow path. We're going to be doing - * context switches, and waiting for our parent to respond. - */ -__sys_trace: - move $r0, $sp - bal syscall_trace_enter - move $r7, $r0 - la $lp, __sys_trace_return ! return address - - addi $p1, $r7, #1 - beqz $p1, ret_slow_syscall ! fatal signal is pending - - addi $p1, $sp, #R0_OFFSET ! pointer to regs - lmw.bi $r0, [$p1], $r5 ! have to reload $r0 - $r5 - b jmp_systbl - -__sys_trace_return: - swi $r0, [$sp+#R0_OFFSET] ! T: save returned $r0 - move $r0, $sp ! set pt_regs for syscall_trace_leave - bal syscall_trace_leave - b ret_slow_syscall - -ENTRY(sys_rt_sigreturn_wrapper) - addi $r0, $sp, #0 - b sys_rt_sigreturn -ENDPROC(sys_rt_sigreturn_wrapper) diff --git a/arch/nds32/kernel/fpu.c b/arch/nds32/kernel/fpu.c deleted file mode 100644 index 701c09a668de..000000000000 --- a/arch/nds32/kernel/fpu.c +++ /dev/null @@ -1,266 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include -#include - -const struct fpu_struct init_fpuregs = { - .fd_regs = {[0 ... 31] = sNAN64}, - .fpcsr = FPCSR_INIT, -#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC) - .UDF_IEX_trap = 0 -#endif -}; - -void save_fpu(struct task_struct *tsk) -{ - unsigned int fpcfg, fpcsr; - - enable_fpu(); - fpcfg = ((__nds32__fmfcfg() & FPCFG_mskFREG) >> FPCFG_offFREG); - switch (fpcfg) { - case SP32_DP32_reg: - asm volatile ("fsdi $fd31, [%0+0xf8]\n\t" - "fsdi $fd30, [%0+0xf0]\n\t" - "fsdi $fd29, [%0+0xe8]\n\t" - "fsdi $fd28, [%0+0xe0]\n\t" - "fsdi $fd27, [%0+0xd8]\n\t" - "fsdi $fd26, [%0+0xd0]\n\t" - "fsdi $fd25, [%0+0xc8]\n\t" - "fsdi $fd24, [%0+0xc0]\n\t" - "fsdi $fd23, [%0+0xb8]\n\t" - "fsdi $fd22, [%0+0xb0]\n\t" - "fsdi $fd21, [%0+0xa8]\n\t" - "fsdi $fd20, [%0+0xa0]\n\t" - "fsdi $fd19, [%0+0x98]\n\t" - "fsdi $fd18, [%0+0x90]\n\t" - "fsdi $fd17, [%0+0x88]\n\t" - "fsdi $fd16, [%0+0x80]\n\t" - : /* no output */ - : "r" (&tsk->thread.fpu) - : "memory"); - fallthrough; - case SP32_DP16_reg: - asm volatile ("fsdi $fd15, [%0+0x78]\n\t" - "fsdi $fd14, [%0+0x70]\n\t" - "fsdi $fd13, [%0+0x68]\n\t" - "fsdi $fd12, [%0+0x60]\n\t" - "fsdi $fd11, [%0+0x58]\n\t" - "fsdi $fd10, [%0+0x50]\n\t" - "fsdi $fd9, [%0+0x48]\n\t" - "fsdi $fd8, [%0+0x40]\n\t" - : /* no output */ - : "r" (&tsk->thread.fpu) - : "memory"); - fallthrough; - case SP16_DP8_reg: - asm volatile ("fsdi $fd7, [%0+0x38]\n\t" - "fsdi $fd6, [%0+0x30]\n\t" - "fsdi $fd5, [%0+0x28]\n\t" - "fsdi $fd4, [%0+0x20]\n\t" - : /* no output */ - : "r" (&tsk->thread.fpu) - : "memory"); - fallthrough; - case SP8_DP4_reg: - asm volatile ("fsdi $fd3, [%1+0x18]\n\t" - "fsdi $fd2, [%1+0x10]\n\t" - "fsdi $fd1, [%1+0x8]\n\t" - "fsdi $fd0, [%1+0x0]\n\t" - "fmfcsr %0\n\t" - "swi %0, [%1+0x100]\n\t" - : "=&r" (fpcsr) - : "r"(&tsk->thread.fpu) - : "memory"); - } - disable_fpu(); -} - -void load_fpu(const struct fpu_struct *fpregs) -{ - unsigned int fpcfg, fpcsr; - - enable_fpu(); - fpcfg = ((__nds32__fmfcfg() & FPCFG_mskFREG) >> FPCFG_offFREG); - switch (fpcfg) { - case SP32_DP32_reg: - asm volatile ("fldi $fd31, [%0+0xf8]\n\t" - "fldi $fd30, [%0+0xf0]\n\t" - "fldi $fd29, [%0+0xe8]\n\t" - "fldi $fd28, [%0+0xe0]\n\t" - "fldi $fd27, [%0+0xd8]\n\t" - "fldi $fd26, [%0+0xd0]\n\t" - "fldi $fd25, [%0+0xc8]\n\t" - "fldi $fd24, [%0+0xc0]\n\t" - "fldi $fd23, [%0+0xb8]\n\t" - "fldi $fd22, [%0+0xb0]\n\t" - "fldi $fd21, [%0+0xa8]\n\t" - "fldi $fd20, [%0+0xa0]\n\t" - "fldi $fd19, [%0+0x98]\n\t" - "fldi $fd18, [%0+0x90]\n\t" - "fldi $fd17, [%0+0x88]\n\t" - "fldi $fd16, [%0+0x80]\n\t" - : /* no output */ - : "r" (fpregs)); - fallthrough; - case SP32_DP16_reg: - asm volatile ("fldi $fd15, [%0+0x78]\n\t" - "fldi $fd14, [%0+0x70]\n\t" - "fldi $fd13, [%0+0x68]\n\t" - "fldi $fd12, [%0+0x60]\n\t" - "fldi $fd11, [%0+0x58]\n\t" - "fldi $fd10, [%0+0x50]\n\t" - "fldi $fd9, [%0+0x48]\n\t" - "fldi $fd8, [%0+0x40]\n\t" - : /* no output */ - : "r" (fpregs)); - fallthrough; - case SP16_DP8_reg: - asm volatile ("fldi $fd7, [%0+0x38]\n\t" - "fldi $fd6, [%0+0x30]\n\t" - "fldi $fd5, [%0+0x28]\n\t" - "fldi $fd4, [%0+0x20]\n\t" - : /* no output */ - : "r" (fpregs)); - fallthrough; - case SP8_DP4_reg: - asm volatile ("fldi $fd3, [%1+0x18]\n\t" - "fldi $fd2, [%1+0x10]\n\t" - "fldi $fd1, [%1+0x8]\n\t" - "fldi $fd0, [%1+0x0]\n\t" - "lwi %0, [%1+0x100]\n\t" - "fmtcsr %0\n\t":"=&r" (fpcsr) - : "r"(fpregs)); - } - disable_fpu(); -} -void store_fpu_for_suspend(void) -{ -#ifdef CONFIG_LAZY_FPU - if (last_task_used_math != NULL) - save_fpu(last_task_used_math); - last_task_used_math = NULL; -#else - if (!used_math()) - return; - unlazy_fpu(current); -#endif - clear_fpu(task_pt_regs(current)); -} -inline void do_fpu_context_switch(struct pt_regs *regs) -{ - /* Enable to use FPU. */ - - if (!user_mode(regs)) { - pr_err("BUG: FPU is used in kernel mode.\n"); - BUG(); - return; - } - - enable_ptreg_fpu(regs); -#ifdef CONFIG_LAZY_FPU //Lazy FPU is used - if (last_task_used_math == current) - return; - if (last_task_used_math != NULL) - /* Other processes fpu state, save away */ - save_fpu(last_task_used_math); - last_task_used_math = current; -#endif - if (used_math()) { - load_fpu(¤t->thread.fpu); - } else { - /* First time FPU user. */ - load_fpu(&init_fpuregs); -#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC) - current->thread.fpu.UDF_IEX_trap = init_fpuregs.UDF_IEX_trap; -#endif - set_used_math(); - } - -} - -inline void fill_sigfpe_signo(unsigned int fpcsr, int *signo) -{ - if (fpcsr & FPCSR_mskOVFT) - *signo = FPE_FLTOVF; -#ifndef CONFIG_SUPPORT_DENORMAL_ARITHMETIC - else if (fpcsr & FPCSR_mskUDFT) - *signo = FPE_FLTUND; -#endif - else if (fpcsr & FPCSR_mskIVOT) - *signo = FPE_FLTINV; - else if (fpcsr & FPCSR_mskDBZT) - *signo = FPE_FLTDIV; - else if (fpcsr & FPCSR_mskIEXT) - *signo = FPE_FLTRES; -} - -inline void handle_fpu_exception(struct pt_regs *regs) -{ - unsigned int fpcsr; - int si_code = 0, si_signo = SIGFPE; -#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC) - unsigned long redo_except = FPCSR_mskDNIT|FPCSR_mskUDFT|FPCSR_mskIEXT; -#else - unsigned long redo_except = FPCSR_mskDNIT; -#endif - - lose_fpu(); - fpcsr = current->thread.fpu.fpcsr; - - if (fpcsr & redo_except) { - si_signo = do_fpuemu(regs, ¤t->thread.fpu); - fpcsr = current->thread.fpu.fpcsr; - if (!si_signo) { - current->thread.fpu.fpcsr &= ~(redo_except); - goto done; - } - } else if (fpcsr & FPCSR_mskRIT) { - if (!user_mode(regs)) - make_task_dead(SIGILL); - si_signo = SIGILL; - } - - switch (si_signo) { - case SIGFPE: - fill_sigfpe_signo(fpcsr, &si_code); - break; - case SIGILL: - show_regs(regs); - si_code = ILL_COPROC; - break; - case SIGBUS: - si_code = BUS_ADRERR; - break; - default: - break; - } - - force_sig_fault(si_signo, si_code, - (void __user *)instruction_pointer(regs)); -done: - own_fpu(); -} - -bool do_fpu_exception(unsigned int subtype, struct pt_regs *regs) -{ - int done = true; - /* Coprocessor disabled exception */ - if (subtype == FPU_DISABLE_EXCEPTION) { - preempt_disable(); - do_fpu_context_switch(regs); - preempt_enable(); - } - /* Coprocessor exception such as underflow and overflow */ - else if (subtype == FPU_EXCEPTION) - handle_fpu_exception(regs); - else - done = false; - return done; -} diff --git a/arch/nds32/kernel/ftrace.c b/arch/nds32/kernel/ftrace.c deleted file mode 100644 index 711bc8cd186d..000000000000 --- a/arch/nds32/kernel/ftrace.c +++ /dev/null @@ -1,278 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -#include -#include -#include - -#ifndef CONFIG_DYNAMIC_FTRACE -extern void (*ftrace_trace_function)(unsigned long, unsigned long, - struct ftrace_ops*, struct ftrace_regs*); -extern void ftrace_graph_caller(void); - -noinline void __naked ftrace_stub(unsigned long ip, unsigned long parent_ip, - struct ftrace_ops *op, struct ftrace_regs *fregs) -{ - __asm__ (""); /* avoid to optimize as pure function */ -} - -noinline void _mcount(unsigned long parent_ip) -{ - /* save all state by the compiler prologue */ - - unsigned long ip = (unsigned long)__builtin_return_address(0); - - if (ftrace_trace_function != ftrace_stub) - ftrace_trace_function(ip - MCOUNT_INSN_SIZE, parent_ip, - NULL, NULL); - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - if (ftrace_graph_return != (trace_func_graph_ret_t)ftrace_stub - || ftrace_graph_entry != ftrace_graph_entry_stub) - ftrace_graph_caller(); -#endif - - /* restore all state by the compiler epilogue */ -} -EXPORT_SYMBOL(_mcount); - -#else /* CONFIG_DYNAMIC_FTRACE */ - -noinline void __naked ftrace_stub(unsigned long ip, unsigned long parent_ip, - struct ftrace_ops *op, struct ftrace_regs *fregs) -{ - __asm__ (""); /* avoid to optimize as pure function */ -} - -noinline void __naked _mcount(unsigned long parent_ip) -{ - __asm__ (""); /* avoid to optimize as pure function */ -} -EXPORT_SYMBOL(_mcount); - -#define XSTR(s) STR(s) -#define STR(s) #s -void _ftrace_caller(unsigned long parent_ip) -{ - /* save all state needed by the compiler prologue */ - - /* - * prepare arguments for real tracing function - * first arg : __builtin_return_address(0) - MCOUNT_INSN_SIZE - * second arg : parent_ip - */ - __asm__ __volatile__ ( - "move $r1, %0 \n\t" - "addi $r0, %1, #-" XSTR(MCOUNT_INSN_SIZE) "\n\t" - : - : "r" (parent_ip), "r" (__builtin_return_address(0))); - - /* a placeholder for the call to a real tracing function */ - __asm__ __volatile__ ( - "ftrace_call: \n\t" - "nop \n\t" - "nop \n\t" - "nop \n\t"); - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - /* a placeholder for the call to ftrace_graph_caller */ - __asm__ __volatile__ ( - "ftrace_graph_call: \n\t" - "nop \n\t" - "nop \n\t" - "nop \n\t"); -#endif - /* restore all state needed by the compiler epilogue */ -} - -static unsigned long gen_sethi_insn(unsigned long addr) -{ - unsigned long opcode = 0x46000000; - unsigned long imm = addr >> 12; - unsigned long rt_num = 0xf << 20; - - return ENDIAN_CONVERT(opcode | rt_num | imm); -} - -static unsigned long gen_ori_insn(unsigned long addr) -{ - unsigned long opcode = 0x58000000; - unsigned long imm = addr & 0x0000fff; - unsigned long rt_num = 0xf << 20; - unsigned long ra_num = 0xf << 15; - - return ENDIAN_CONVERT(opcode | rt_num | ra_num | imm); -} - -static unsigned long gen_jral_insn(unsigned long addr) -{ - unsigned long opcode = 0x4a000001; - unsigned long rt_num = 0x1e << 20; - unsigned long rb_num = 0xf << 10; - - return ENDIAN_CONVERT(opcode | rt_num | rb_num); -} - -static void ftrace_gen_call_insn(unsigned long *call_insns, - unsigned long addr) -{ - call_insns[0] = gen_sethi_insn(addr); /* sethi $r15, imm20u */ - call_insns[1] = gen_ori_insn(addr); /* ori $r15, $r15, imm15u */ - call_insns[2] = gen_jral_insn(addr); /* jral $lp, $r15 */ -} - -static int __ftrace_modify_code(unsigned long pc, unsigned long *old_insn, - unsigned long *new_insn, bool validate) -{ - unsigned long orig_insn[3]; - - if (validate) { - if (copy_from_kernel_nofault(orig_insn, (void *)pc, - MCOUNT_INSN_SIZE)) - return -EFAULT; - if (memcmp(orig_insn, old_insn, MCOUNT_INSN_SIZE)) - return -EINVAL; - } - - if (copy_to_kernel_nofault((void *)pc, new_insn, MCOUNT_INSN_SIZE)) - return -EPERM; - - return 0; -} - -static int ftrace_modify_code(unsigned long pc, unsigned long *old_insn, - unsigned long *new_insn, bool validate) -{ - int ret; - - ret = __ftrace_modify_code(pc, old_insn, new_insn, validate); - if (ret) - return ret; - - flush_icache_range(pc, pc + MCOUNT_INSN_SIZE); - - return ret; -} - -int ftrace_update_ftrace_func(ftrace_func_t func) -{ - unsigned long pc = (unsigned long)&ftrace_call; - unsigned long old_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP}; - unsigned long new_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP}; - - if (func != ftrace_stub) - ftrace_gen_call_insn(new_insn, (unsigned long)func); - - return ftrace_modify_code(pc, old_insn, new_insn, false); -} - -int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) -{ - unsigned long pc = rec->ip; - unsigned long nop_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP}; - unsigned long call_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP}; - - ftrace_gen_call_insn(call_insn, addr); - - return ftrace_modify_code(pc, nop_insn, call_insn, true); -} - -int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, - unsigned long addr) -{ - unsigned long pc = rec->ip; - unsigned long nop_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP}; - unsigned long call_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP}; - - ftrace_gen_call_insn(call_insn, addr); - - return ftrace_modify_code(pc, call_insn, nop_insn, true); -} -#endif /* CONFIG_DYNAMIC_FTRACE */ - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER -void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, - unsigned long frame_pointer) -{ - unsigned long return_hooker = (unsigned long)&return_to_handler; - unsigned long old; - - if (unlikely(atomic_read(¤t->tracing_graph_pause))) - return; - - old = *parent; - - if (!function_graph_enter(old, self_addr, frame_pointer, NULL)) - *parent = return_hooker; -} - -noinline void ftrace_graph_caller(void) -{ - unsigned long *parent_ip = - (unsigned long *)(__builtin_frame_address(2) - 4); - - unsigned long selfpc = - (unsigned long)(__builtin_return_address(1) - MCOUNT_INSN_SIZE); - - unsigned long frame_pointer = - (unsigned long)__builtin_frame_address(3); - - prepare_ftrace_return(parent_ip, selfpc, frame_pointer); -} - -extern unsigned long ftrace_return_to_handler(unsigned long frame_pointer); -void __naked return_to_handler(void) -{ - __asm__ __volatile__ ( - /* save state needed by the ABI */ - "smw.adm $r0,[$sp],$r1,#0x0 \n\t" - - /* get original return address */ - "move $r0, $fp \n\t" - "bal ftrace_return_to_handler\n\t" - "move $lp, $r0 \n\t" - - /* restore state needed by the ABI */ - "lmw.bim $r0,[$sp],$r1,#0x0 \n\t"); -} - -#ifdef CONFIG_DYNAMIC_FTRACE -extern unsigned long ftrace_graph_call; - -static int ftrace_modify_graph_caller(bool enable) -{ - unsigned long pc = (unsigned long)&ftrace_graph_call; - unsigned long nop_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP}; - unsigned long call_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP}; - - ftrace_gen_call_insn(call_insn, (unsigned long)ftrace_graph_caller); - - if (enable) - return ftrace_modify_code(pc, nop_insn, call_insn, true); - else - return ftrace_modify_code(pc, call_insn, nop_insn, true); -} - -int ftrace_enable_ftrace_graph_caller(void) -{ - return ftrace_modify_graph_caller(true); -} - -int ftrace_disable_ftrace_graph_caller(void) -{ - return ftrace_modify_graph_caller(false); -} -#endif /* CONFIG_DYNAMIC_FTRACE */ - -#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ - - -#ifdef CONFIG_TRACE_IRQFLAGS -noinline void __trace_hardirqs_off(void) -{ - trace_hardirqs_off(); -} -noinline void __trace_hardirqs_on(void) -{ - trace_hardirqs_on(); -} -#endif /* CONFIG_TRACE_IRQFLAGS */ diff --git a/arch/nds32/kernel/head.S b/arch/nds32/kernel/head.S deleted file mode 100644 index 7347f00451a9..000000000000 --- a/arch/nds32/kernel/head.S +++ /dev/null @@ -1,197 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_CPU_BIG_ENDIAN -#define OF_DT_MAGIC 0xd00dfeed -#else -#define OF_DT_MAGIC 0xedfe0dd0 -#endif - - .globl swapper_pg_dir - .equ swapper_pg_dir, TEXTADDR - 0x4000 - -/* - * Kernel startup entry point. - */ - .section ".head.text", "ax" - .type _stext, %function -ENTRY(_stext) - setgie.d ! Disable interrupt - isb -/* - * Disable I/D-cache and enable it at a proper time - */ - mfsr $r0, $mr8 - li $r1, #~(CACHE_CTL_mskIC_EN|CACHE_CTL_mskDC_EN) - and $r0, $r0, $r1 - mtsr $r0, $mr8 - -/* - * Process device tree blob - */ - andi $r0,$r2,#0x3 - li $r10, 0 - bne $r0, $r10, _nodtb - lwi $r0, [$r2] - li $r1, OF_DT_MAGIC - bne $r0, $r1, _nodtb - move $r10, $r2 -_nodtb: - -/* - * Create a temporary mapping area for booting, before start_kernel - */ - sethi $r4, hi20(swapper_pg_dir) - li $p0, (PAGE_OFFSET - PHYS_OFFSET) - sub $r4, $r4, $p0 - tlbop FlushAll ! invalidate TLB\n" - isb - mtsr $r4, $L1_PPTB ! load page table pointer\n" - -#ifdef CONFIG_CPU_DCACHE_DISABLE - #define MMU_CTL_NTCC MMU_CTL_CACHEABLE_NON -#else - #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH - #define MMU_CTL_NTCC MMU_CTL_CACHEABLE_WT - #else - #define MMU_CTL_NTCC MMU_CTL_CACHEABLE_WB - #endif -#endif - -/* set NTC cacheability, mutliple page size in use */ - mfsr $r3, $MMU_CTL -#if CONFIG_MEMORY_START >= 0xc0000000 - ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC3) -#elif CONFIG_MEMORY_START >= 0x80000000 - ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC2) -#elif CONFIG_MEMORY_START >= 0x40000000 - ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC1) -#else - ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC0) -#endif - -#ifdef CONFIG_ANDES_PAGE_SIZE_4KB - ori $r3, $r3, #(MMU_CTL_mskMPZIU) -#else - ori $r3, $r3, #(MMU_CTL_mskMPZIU|MMU_CTL_D8KB) -#endif -#ifdef CONFIG_HW_SUPPORT_UNALIGNMENT_ACCESS - li $r0, #MMU_CTL_UNA - or $r3, $r3, $r0 -#endif - mtsr $r3, $MMU_CTL - isb - -/* set page size and size of kernel image */ - mfsr $r0, $MMU_CFG - srli $r3, $r0, MMU_CFG_offfEPSZ - zeb $r3, $r3 - bnez $r3, _extra_page_size_support -#ifdef CONFIG_ANDES_PAGE_SIZE_4KB - li $r5, #SZ_4K ! Use 4KB page size -#else - li $r5, #SZ_8K ! Use 8KB page size - li $r3, #1 -#endif - mtsr $r3, $TLB_MISC - b _image_size_check - -_extra_page_size_support: ! Use epzs pages size - clz $r6, $r3 - subri $r2, $r6, #31 - li $r3, #1 - sll $r3, $r3, $r2 - /* MMU_CFG.EPSZ value -> meaning */ - mul $r5, $r3, $r3 - slli $r5, $r5, #14 - /* MMU_CFG.EPSZ -> TLB_MISC.ACC_PSZ */ - addi $r3, $r2, #0x2 - mtsr $r3, $TLB_MISC - -_image_size_check: - /* calculate the image maximum size accepted by TLB config */ - andi $r6, $r0, MMU_CFG_mskTBW - andi $r0, $r0, MMU_CFG_mskTBS - srli $r6, $r6, MMU_CFG_offTBW - srli $r0, $r0, MMU_CFG_offTBS - addi $r6, $r6, #0x1 ! MMU_CFG.TBW value -> meaning - addi $r0, $r0, #0x2 ! MMU_CFG.TBS value -> meaning - sll $r0, $r6, $r0 ! entries = k-way * n-set - mul $r6, $r0, $r5 ! max size = entries * page size - /* check kernel image size */ - la $r3, (_end - PAGE_OFFSET) - bgt $r3, $r6, __error - - li $r2, #(PHYS_OFFSET + TLB_DATA_kernel_text_attr) - li $r3, PAGE_OFFSET - add $r6, $r6, $r3 - -_tlb: - mtsr $r3, $TLB_VPN - dsb - tlbop $r2, RWR - isb - add $r3, $r3, $r5 - add $r2, $r2, $r5 - bgt $r6, $r3, _tlb - mfsr $r3, $TLB_MISC ! setup access page size - li $r2, #~0xf - and $r3, $r3, $r2 -#ifdef CONFIG_ANDES_PAGE_SIZE_8KB - ori $r3, $r3, #0x1 -#endif - mtsr $r3, $TLB_MISC - - mfsr $r0, $MISC_CTL ! Enable BTB, RTP, shadow sp, and HW_PRE - ori $r0, $r0, #MISC_init - mtsr $r0, $MISC_CTL - - mfsr $p1, $PSW - li $r15, #~PSW_clr ! clear WBNA|DME|IME|DT|IT|POM|INTL|GIE - and $p1, $p1, $r15 - ori $p1, $p1, #PSW_init - mtsr $p1, $IPSW ! when iret, it will automatically enable MMU - la $lp, __mmap_switched - mtsr $lp, $IPC - iret - nop - - .type __switch_data, %object -__switch_data: - .long __bss_start ! $r6 - .long _end ! $r7 - .long __atags_pointer ! $atag_pointer - .long init_task ! $r9, move to $r25 - .long init_thread_union + THREAD_SIZE ! $sp - - -/* - * The following fragment of code is executed with the MMU on in MMU mode, - * and uses absolute addresses; this is not position independent. - */ - .align - .type __mmap_switched, %function -__mmap_switched: - la $r3, __switch_data - lmw.bim $r6, [$r3], $r9, #0b0001 - move $r25, $r9 - move $fp, #0 ! Clear BSS (and zero $fp) - beq $r7, $r6, _RRT -1: swi.bi $fp, [$r6], #4 - bne $r7, $r6, 1b - swi $r10, [$r8] - -_RRT: - b start_kernel - -__error: - b __error diff --git a/arch/nds32/kernel/irq.c b/arch/nds32/kernel/irq.c deleted file mode 100644 index 6ff5a672be27..000000000000 --- a/arch/nds32/kernel/irq.c +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include - -void __init init_IRQ(void) -{ - irqchip_init(); -} diff --git a/arch/nds32/kernel/module.c b/arch/nds32/kernel/module.c deleted file mode 100644 index 3897fd14a21d..000000000000 --- a/arch/nds32/kernel/module.c +++ /dev/null @@ -1,278 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include - -void *module_alloc(unsigned long size) -{ - return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, - GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE, - __builtin_return_address(0)); -} - -void module_free(struct module *module, void *region) -{ - vfree(region); -} - -int module_frob_arch_sections(Elf_Ehdr * hdr, - Elf_Shdr * sechdrs, - char *secstrings, struct module *mod) -{ - return 0; -} - -void do_reloc16(unsigned int val, unsigned int *loc, unsigned int val_mask, - unsigned int val_shift, unsigned int loc_mask, - unsigned int partial_in_place, unsigned int swap) -{ - unsigned int tmp = 0, tmp2 = 0; - - __asm__ __volatile__("\tlhi.bi\t%0, [%2], 0\n" - "\tbeqz\t%3, 1f\n" - "\twsbh\t%0, %1\n" - "1:\n":"=r"(tmp):"0"(tmp), "r"(loc), "r"(swap) - ); - - tmp2 = tmp & loc_mask; - if (partial_in_place) { - tmp &= (~loc_mask); - tmp = - tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask); - } else { - tmp = tmp2 | ((val & val_mask) >> val_shift); - } - - __asm__ __volatile__("\tbeqz\t%3, 2f\n" - "\twsbh\t%0, %1\n" - "2:\n" - "\tshi.bi\t%0, [%2], 0\n":"=r"(tmp):"0"(tmp), - "r"(loc), "r"(swap) - ); -} - -void do_reloc32(unsigned int val, unsigned int *loc, unsigned int val_mask, - unsigned int val_shift, unsigned int loc_mask, - unsigned int partial_in_place, unsigned int swap) -{ - unsigned int tmp = 0, tmp2 = 0; - - __asm__ __volatile__("\tlmw.bi\t%0, [%2], %0, 0\n" - "\tbeqz\t%3, 1f\n" - "\twsbh\t%0, %1\n" - "\trotri\t%0, %1, 16\n" - "1:\n":"=r"(tmp):"0"(tmp), "r"(loc), "r"(swap) - ); - - tmp2 = tmp & loc_mask; - if (partial_in_place) { - tmp &= (~loc_mask); - tmp = - tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask); - } else { - tmp = tmp2 | ((val & val_mask) >> val_shift); - } - - __asm__ __volatile__("\tbeqz\t%3, 2f\n" - "\twsbh\t%0, %1\n" - "\trotri\t%0, %1, 16\n" - "2:\n" - "\tsmw.bi\t%0, [%2], %0, 0\n":"=r"(tmp):"0"(tmp), - "r"(loc), "r"(swap) - ); -} - -static inline int exceed_limit(int offset, unsigned int val_mask, - struct module *module, Elf32_Rela * rel, - unsigned int relindex, unsigned int reloc_order) -{ - int abs_off = offset < 0 ? ~offset : offset; - - if (abs_off & (~val_mask)) { - pr_err("\n%s: relocation type %d out of range.\n" - "please rebuild the kernel module with gcc option \"-Wa,-mno-small-text\".\n", - module->name, ELF32_R_TYPE(rel->r_info)); - pr_err("section %d reloc %d offset 0x%x relative 0x%x.\n", - relindex, reloc_order, rel->r_offset, offset); - return true; - } - return false; -} - -#ifdef __NDS32_EL__ -#define NEED_SWAP 1 -#else -#define NEED_SWAP 0 -#endif - -int -apply_relocate_add(Elf32_Shdr * sechdrs, const char *strtab, - unsigned int symindex, unsigned int relindex, - struct module *module) -{ - Elf32_Shdr *symsec = sechdrs + symindex; - Elf32_Shdr *relsec = sechdrs + relindex; - Elf32_Shdr *dstsec = sechdrs + relsec->sh_info; - Elf32_Rela *rel = (void *)relsec->sh_addr; - unsigned int i; - - for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rela); i++, rel++) { - Elf32_Addr *loc; - Elf32_Sym *sym; - Elf32_Addr v; - s32 offset; - - offset = ELF32_R_SYM(rel->r_info); - if (offset < 0 - || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { - pr_err("%s: bad relocation\n", module->name); - pr_err("section %d reloc %d\n", relindex, i); - return -ENOEXEC; - } - - sym = ((Elf32_Sym *) symsec->sh_addr) + offset; - - if (rel->r_offset < 0 - || rel->r_offset > dstsec->sh_size - sizeof(u16)) { - pr_err("%s: out of bounds relocation\n", module->name); - pr_err("section %d reloc %d offset 0x%0x size %d\n", - relindex, i, rel->r_offset, dstsec->sh_size); - return -ENOEXEC; - } - - loc = (Elf32_Addr *) (dstsec->sh_addr + rel->r_offset); - v = sym->st_value + rel->r_addend; - - switch (ELF32_R_TYPE(rel->r_info)) { - case R_NDS32_NONE: - case R_NDS32_INSN16: - case R_NDS32_LABEL: - case R_NDS32_LONGCALL1: - case R_NDS32_LONGCALL2: - case R_NDS32_LONGCALL3: - case R_NDS32_LONGCALL4: - case R_NDS32_LONGJUMP1: - case R_NDS32_LONGJUMP2: - case R_NDS32_LONGJUMP3: - case R_NDS32_9_FIXED_RELA: - case R_NDS32_15_FIXED_RELA: - case R_NDS32_17_FIXED_RELA: - case R_NDS32_25_FIXED_RELA: - case R_NDS32_LOADSTORE: - case R_NDS32_DWARF2_OP1_RELA: - case R_NDS32_DWARF2_OP2_RELA: - case R_NDS32_DWARF2_LEB_RELA: - case R_NDS32_RELA_NOP_MIX ... R_NDS32_RELA_NOP_MAX: - break; - - case R_NDS32_32_RELA: - do_reloc32(v, loc, 0xffffffff, 0, 0, 0, 0); - break; - - case R_NDS32_HI20_RELA: - do_reloc32(v, loc, 0xfffff000, 12, 0xfff00000, 0, - NEED_SWAP); - break; - - case R_NDS32_LO12S3_RELA: - do_reloc32(v, loc, 0x00000fff, 3, 0xfffff000, 0, - NEED_SWAP); - break; - - case R_NDS32_LO12S2_RELA: - do_reloc32(v, loc, 0x00000fff, 2, 0xfffff000, 0, - NEED_SWAP); - break; - - case R_NDS32_LO12S1_RELA: - do_reloc32(v, loc, 0x00000fff, 1, 0xfffff000, 0, - NEED_SWAP); - break; - - case R_NDS32_LO12S0_RELA: - case R_NDS32_LO12S0_ORI_RELA: - do_reloc32(v, loc, 0x00000fff, 0, 0xfffff000, 0, - NEED_SWAP); - break; - - case R_NDS32_9_PCREL_RELA: - if (exceed_limit - ((v - (Elf32_Addr) loc), 0x000000ff, module, rel, - relindex, i)) - return -ENOEXEC; - do_reloc16(v - (Elf32_Addr) loc, loc, 0x000001ff, 1, - 0xffffff00, 0, NEED_SWAP); - break; - - case R_NDS32_15_PCREL_RELA: - if (exceed_limit - ((v - (Elf32_Addr) loc), 0x00003fff, module, rel, - relindex, i)) - return -ENOEXEC; - do_reloc32(v - (Elf32_Addr) loc, loc, 0x00007fff, 1, - 0xffffc000, 0, NEED_SWAP); - break; - - case R_NDS32_17_PCREL_RELA: - if (exceed_limit - ((v - (Elf32_Addr) loc), 0x0000ffff, module, rel, - relindex, i)) - return -ENOEXEC; - do_reloc32(v - (Elf32_Addr) loc, loc, 0x0001ffff, 1, - 0xffff0000, 0, NEED_SWAP); - break; - - case R_NDS32_25_PCREL_RELA: - if (exceed_limit - ((v - (Elf32_Addr) loc), 0x00ffffff, module, rel, - relindex, i)) - return -ENOEXEC; - do_reloc32(v - (Elf32_Addr) loc, loc, 0x01ffffff, 1, - 0xff000000, 0, NEED_SWAP); - break; - case R_NDS32_WORD_9_PCREL_RELA: - if (exceed_limit - ((v - (Elf32_Addr) loc), 0x000000ff, module, rel, - relindex, i)) - return -ENOEXEC; - do_reloc32(v - (Elf32_Addr) loc, loc, 0x000001ff, 1, - 0xffffff00, 0, NEED_SWAP); - break; - - case R_NDS32_SDA15S3_RELA: - case R_NDS32_SDA15S2_RELA: - case R_NDS32_SDA15S1_RELA: - case R_NDS32_SDA15S0_RELA: - pr_err("%s: unsupported relocation type %d.\n", - module->name, ELF32_R_TYPE(rel->r_info)); - pr_err - ("Small data section access doesn't work in the kernel space; " - "please rebuild the kernel module with gcc option -mcmodel=large.\n"); - pr_err("section %d reloc %d offset 0x%x size %d\n", - relindex, i, rel->r_offset, dstsec->sh_size); - break; - - default: - pr_err("%s: unsupported relocation type %d.\n", - module->name, ELF32_R_TYPE(rel->r_info)); - pr_err("section %d reloc %d offset 0x%x size %d\n", - relindex, i, rel->r_offset, dstsec->sh_size); - } - } - return 0; -} - -int -module_finalize(const Elf32_Ehdr * hdr, const Elf_Shdr * sechdrs, - struct module *module) -{ - return 0; -} - -void module_arch_cleanup(struct module *mod) -{ -} diff --git a/arch/nds32/kernel/nds32_ksyms.c b/arch/nds32/kernel/nds32_ksyms.c deleted file mode 100644 index 20719e42ae36..000000000000 --- a/arch/nds32/kernel/nds32_ksyms.c +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* mem functions */ -EXPORT_SYMBOL(memset); -EXPORT_SYMBOL(memcpy); -EXPORT_SYMBOL(memmove); -EXPORT_SYMBOL(memzero); - -/* user mem (segment) */ -EXPORT_SYMBOL(__arch_copy_from_user); -EXPORT_SYMBOL(__arch_copy_to_user); -EXPORT_SYMBOL(__arch_clear_user); diff --git a/arch/nds32/kernel/perf_event_cpu.c b/arch/nds32/kernel/perf_event_cpu.c deleted file mode 100644 index a78a879e7ef1..000000000000 --- a/arch/nds32/kernel/perf_event_cpu.c +++ /dev/null @@ -1,1500 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2008-2017 Andes Technology Corporation - * - * Reference ARMv7: Jean Pihet - * 2010 (c) MontaVista Software, LLC. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -/* Set at runtime when we know what CPU type we are. */ -static struct nds32_pmu *cpu_pmu; - -static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events); -static void nds32_pmu_start(struct nds32_pmu *cpu_pmu); -static void nds32_pmu_stop(struct nds32_pmu *cpu_pmu); -static struct platform_device_id cpu_pmu_plat_device_ids[] = { - {.name = "nds32-pfm"}, - {}, -}; - -static int nds32_pmu_map_cache_event(const unsigned int (*cache_map) - [PERF_COUNT_HW_CACHE_MAX] - [PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_COUNT_HW_CACHE_RESULT_MAX], u64 config) -{ - unsigned int cache_type, cache_op, cache_result, ret; - - cache_type = (config >> 0) & 0xff; - if (cache_type >= PERF_COUNT_HW_CACHE_MAX) - return -EINVAL; - - cache_op = (config >> 8) & 0xff; - if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX) - return -EINVAL; - - cache_result = (config >> 16) & 0xff; - if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) - return -EINVAL; - - ret = (int)(*cache_map)[cache_type][cache_op][cache_result]; - - if (ret == CACHE_OP_UNSUPPORTED) - return -ENOENT; - - return ret; -} - -static int -nds32_pmu_map_hw_event(const unsigned int (*event_map)[PERF_COUNT_HW_MAX], - u64 config) -{ - int mapping; - - if (config >= PERF_COUNT_HW_MAX) - return -ENOENT; - - mapping = (*event_map)[config]; - return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping; -} - -static int nds32_pmu_map_raw_event(u32 raw_event_mask, u64 config) -{ - int ev_type = (int)(config & raw_event_mask); - int idx = config >> 8; - - switch (idx) { - case 0: - ev_type = PFM_OFFSET_MAGIC_0 + ev_type; - if (ev_type >= SPAV3_0_SEL_LAST || ev_type <= SPAV3_0_SEL_BASE) - return -ENOENT; - break; - case 1: - ev_type = PFM_OFFSET_MAGIC_1 + ev_type; - if (ev_type >= SPAV3_1_SEL_LAST || ev_type <= SPAV3_1_SEL_BASE) - return -ENOENT; - break; - case 2: - ev_type = PFM_OFFSET_MAGIC_2 + ev_type; - if (ev_type >= SPAV3_2_SEL_LAST || ev_type <= SPAV3_2_SEL_BASE) - return -ENOENT; - break; - default: - return -ENOENT; - } - - return ev_type; -} - -int -nds32_pmu_map_event(struct perf_event *event, - const unsigned int (*event_map)[PERF_COUNT_HW_MAX], - const unsigned int (*cache_map) - [PERF_COUNT_HW_CACHE_MAX] - [PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_COUNT_HW_CACHE_RESULT_MAX], u32 raw_event_mask) -{ - u64 config = event->attr.config; - - switch (event->attr.type) { - case PERF_TYPE_HARDWARE: - return nds32_pmu_map_hw_event(event_map, config); - case PERF_TYPE_HW_CACHE: - return nds32_pmu_map_cache_event(cache_map, config); - case PERF_TYPE_RAW: - return nds32_pmu_map_raw_event(raw_event_mask, config); - } - - return -ENOENT; -} - -static int nds32_spav3_map_event(struct perf_event *event) -{ - return nds32_pmu_map_event(event, &nds32_pfm_perf_map, - &nds32_pfm_perf_cache_map, SOFTWARE_EVENT_MASK); -} - -static inline u32 nds32_pfm_getreset_flags(void) -{ - /* Read overflow status */ - u32 val = __nds32__mfsr(NDS32_SR_PFM_CTL); - u32 old_val = val; - - /* Write overflow bit to clear status, and others keep it 0 */ - u32 ov_flag = PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]; - - __nds32__mtsr(val | ov_flag, NDS32_SR_PFM_CTL); - - return old_val; -} - -static inline int nds32_pfm_has_overflowed(u32 pfm) -{ - u32 ov_flag = PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]; - - return pfm & ov_flag; -} - -static inline int nds32_pfm_counter_has_overflowed(u32 pfm, int idx) -{ - u32 mask = 0; - - switch (idx) { - case 0: - mask = PFM_CTL_OVF[0]; - break; - case 1: - mask = PFM_CTL_OVF[1]; - break; - case 2: - mask = PFM_CTL_OVF[2]; - break; - default: - pr_err("%s index wrong\n", __func__); - break; - } - return pfm & mask; -} - -/* - * Set the next IRQ period, based on the hwc->period_left value. - * To be called with the event disabled in hw: - */ -int nds32_pmu_event_set_period(struct perf_event *event) -{ - struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu); - struct hw_perf_event *hwc = &event->hw; - s64 left = local64_read(&hwc->period_left); - s64 period = hwc->sample_period; - int ret = 0; - - /* The period may have been changed by PERF_EVENT_IOC_PERIOD */ - if (unlikely(period != hwc->last_period)) - left = period - (hwc->last_period - left); - - if (unlikely(left <= -period)) { - left = period; - local64_set(&hwc->period_left, left); - hwc->last_period = period; - ret = 1; - } - - if (unlikely(left <= 0)) { - left += period; - local64_set(&hwc->period_left, left); - hwc->last_period = period; - ret = 1; - } - - if (left > (s64)nds32_pmu->max_period) - left = nds32_pmu->max_period; - - /* - * The hw event starts counting from this event offset, - * mark it to be able to extract future "deltas": - */ - local64_set(&hwc->prev_count, (u64)(-left)); - - nds32_pmu->write_counter(event, (u64)(-left) & nds32_pmu->max_period); - - perf_event_update_userpage(event); - - return ret; -} - -static irqreturn_t nds32_pmu_handle_irq(int irq_num, void *dev) -{ - u32 pfm; - struct perf_sample_data data; - struct nds32_pmu *cpu_pmu = (struct nds32_pmu *)dev; - struct pmu_hw_events *cpuc = cpu_pmu->get_hw_events(); - struct pt_regs *regs; - int idx; - /* - * Get and reset the IRQ flags - */ - pfm = nds32_pfm_getreset_flags(); - - /* - * Did an overflow occur? - */ - if (!nds32_pfm_has_overflowed(pfm)) - return IRQ_NONE; - - /* - * Handle the counter(s) overflow(s) - */ - regs = get_irq_regs(); - - nds32_pmu_stop(cpu_pmu); - for (idx = 0; idx < cpu_pmu->num_events; ++idx) { - struct perf_event *event = cpuc->events[idx]; - struct hw_perf_event *hwc; - - /* Ignore if we don't have an event. */ - if (!event) - continue; - - /* - * We have a single interrupt for all counters. Check that - * each counter has overflowed before we process it. - */ - if (!nds32_pfm_counter_has_overflowed(pfm, idx)) - continue; - - hwc = &event->hw; - nds32_pmu_event_update(event); - perf_sample_data_init(&data, 0, hwc->last_period); - if (!nds32_pmu_event_set_period(event)) - continue; - - if (perf_event_overflow(event, &data, regs)) - cpu_pmu->disable(event); - } - nds32_pmu_start(cpu_pmu); - /* - * Handle the pending perf events. - * - * Note: this call *must* be run with interrupts disabled. For - * platforms that can have the PMU interrupts raised as an NMI, this - * will not work. - */ - irq_work_run(); - - return IRQ_HANDLED; -} - -static inline int nds32_pfm_counter_valid(struct nds32_pmu *cpu_pmu, int idx) -{ - return ((idx >= 0) && (idx < cpu_pmu->num_events)); -} - -static inline int nds32_pfm_disable_counter(int idx) -{ - unsigned int val = __nds32__mfsr(NDS32_SR_PFM_CTL); - u32 mask = 0; - - mask = PFM_CTL_EN[idx]; - val &= ~mask; - val &= ~(PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]); - __nds32__mtsr_isb(val, NDS32_SR_PFM_CTL); - return idx; -} - -/* - * Add an event filter to a given event. - */ -static int nds32_pmu_set_event_filter(struct hw_perf_event *event, - struct perf_event_attr *attr) -{ - unsigned long config_base = 0; - int idx = event->idx; - unsigned long no_kernel_tracing = 0; - unsigned long no_user_tracing = 0; - /* If index is -1, do not do anything */ - if (idx == -1) - return 0; - - no_kernel_tracing = PFM_CTL_KS[idx]; - no_user_tracing = PFM_CTL_KU[idx]; - /* - * Default: enable both kernel and user mode tracing. - */ - if (attr->exclude_user) - config_base |= no_user_tracing; - - if (attr->exclude_kernel) - config_base |= no_kernel_tracing; - - /* - * Install the filter into config_base as this is used to - * construct the event type. - */ - event->config_base |= config_base; - return 0; -} - -static inline void nds32_pfm_write_evtsel(int idx, u32 evnum) -{ - u32 offset = 0; - u32 ori_val = __nds32__mfsr(NDS32_SR_PFM_CTL); - u32 ev_mask = 0; - u32 no_kernel_mask = 0; - u32 no_user_mask = 0; - u32 val; - - offset = PFM_CTL_OFFSEL[idx]; - /* Clear previous mode selection, and write new one */ - no_kernel_mask = PFM_CTL_KS[idx]; - no_user_mask = PFM_CTL_KU[idx]; - ori_val &= ~no_kernel_mask; - ori_val &= ~no_user_mask; - if (evnum & no_kernel_mask) - ori_val |= no_kernel_mask; - - if (evnum & no_user_mask) - ori_val |= no_user_mask; - - /* Clear previous event selection */ - ev_mask = PFM_CTL_SEL[idx]; - ori_val &= ~ev_mask; - evnum &= SOFTWARE_EVENT_MASK; - - /* undo the linear mapping */ - evnum = get_converted_evet_hw_num(evnum); - val = ori_val | (evnum << offset); - val &= ~(PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]); - __nds32__mtsr_isb(val, NDS32_SR_PFM_CTL); -} - -static inline int nds32_pfm_enable_counter(int idx) -{ - unsigned int val = __nds32__mfsr(NDS32_SR_PFM_CTL); - u32 mask = 0; - - mask = PFM_CTL_EN[idx]; - val |= mask; - val &= ~(PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]); - __nds32__mtsr_isb(val, NDS32_SR_PFM_CTL); - return idx; -} - -static inline int nds32_pfm_enable_intens(int idx) -{ - unsigned int val = __nds32__mfsr(NDS32_SR_PFM_CTL); - u32 mask = 0; - - mask = PFM_CTL_IE[idx]; - val |= mask; - val &= ~(PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]); - __nds32__mtsr_isb(val, NDS32_SR_PFM_CTL); - return idx; -} - -static inline int nds32_pfm_disable_intens(int idx) -{ - unsigned int val = __nds32__mfsr(NDS32_SR_PFM_CTL); - u32 mask = 0; - - mask = PFM_CTL_IE[idx]; - val &= ~mask; - val &= ~(PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]); - __nds32__mtsr_isb(val, NDS32_SR_PFM_CTL); - return idx; -} - -static int event_requires_mode_exclusion(struct perf_event_attr *attr) -{ - /* Other modes NDS32 does not support */ - return attr->exclude_user || attr->exclude_kernel; -} - -static void nds32_pmu_enable_event(struct perf_event *event) -{ - unsigned long flags; - unsigned int evnum = 0; - struct hw_perf_event *hwc = &event->hw; - struct nds32_pmu *cpu_pmu = to_nds32_pmu(event->pmu); - struct pmu_hw_events *events = cpu_pmu->get_hw_events(); - int idx = hwc->idx; - - if (!nds32_pfm_counter_valid(cpu_pmu, idx)) { - pr_err("CPU enabling wrong pfm counter IRQ enable\n"); - return; - } - - /* - * Enable counter and interrupt, and set the counter to count - * the event that we're interested in. - */ - raw_spin_lock_irqsave(&events->pmu_lock, flags); - - /* - * Disable counter - */ - nds32_pfm_disable_counter(idx); - - /* - * Check whether we need to exclude the counter from certain modes. - */ - if ((!cpu_pmu->set_event_filter || - cpu_pmu->set_event_filter(hwc, &event->attr)) && - event_requires_mode_exclusion(&event->attr)) { - pr_notice - ("NDS32 performance counters do not support mode exclusion\n"); - hwc->config_base = 0; - } - /* Write event */ - evnum = hwc->config_base; - nds32_pfm_write_evtsel(idx, evnum); - - /* - * Enable interrupt for this counter - */ - nds32_pfm_enable_intens(idx); - - /* - * Enable counter - */ - nds32_pfm_enable_counter(idx); - - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); -} - -static void nds32_pmu_disable_event(struct perf_event *event) -{ - unsigned long flags; - struct hw_perf_event *hwc = &event->hw; - struct nds32_pmu *cpu_pmu = to_nds32_pmu(event->pmu); - struct pmu_hw_events *events = cpu_pmu->get_hw_events(); - int idx = hwc->idx; - - if (!nds32_pfm_counter_valid(cpu_pmu, idx)) { - pr_err("CPU disabling wrong pfm counter IRQ enable %d\n", idx); - return; - } - - /* - * Disable counter and interrupt - */ - raw_spin_lock_irqsave(&events->pmu_lock, flags); - - /* - * Disable counter - */ - nds32_pfm_disable_counter(idx); - - /* - * Disable interrupt for this counter - */ - nds32_pfm_disable_intens(idx); - - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); -} - -static inline u32 nds32_pmu_read_counter(struct perf_event *event) -{ - struct nds32_pmu *cpu_pmu = to_nds32_pmu(event->pmu); - struct hw_perf_event *hwc = &event->hw; - int idx = hwc->idx; - u32 count = 0; - - if (!nds32_pfm_counter_valid(cpu_pmu, idx)) { - pr_err("CPU reading wrong counter %d\n", idx); - } else { - switch (idx) { - case PFMC0: - count = __nds32__mfsr(NDS32_SR_PFMC0); - break; - case PFMC1: - count = __nds32__mfsr(NDS32_SR_PFMC1); - break; - case PFMC2: - count = __nds32__mfsr(NDS32_SR_PFMC2); - break; - default: - pr_err - ("%s: CPU has no performance counters %d\n", - __func__, idx); - } - } - return count; -} - -static inline void nds32_pmu_write_counter(struct perf_event *event, u32 value) -{ - struct nds32_pmu *cpu_pmu = to_nds32_pmu(event->pmu); - struct hw_perf_event *hwc = &event->hw; - int idx = hwc->idx; - - if (!nds32_pfm_counter_valid(cpu_pmu, idx)) { - pr_err("CPU writing wrong counter %d\n", idx); - } else { - switch (idx) { - case PFMC0: - __nds32__mtsr_isb(value, NDS32_SR_PFMC0); - break; - case PFMC1: - __nds32__mtsr_isb(value, NDS32_SR_PFMC1); - break; - case PFMC2: - __nds32__mtsr_isb(value, NDS32_SR_PFMC2); - break; - default: - pr_err - ("%s: CPU has no performance counters %d\n", - __func__, idx); - } - } -} - -static int nds32_pmu_get_event_idx(struct pmu_hw_events *cpuc, - struct perf_event *event) -{ - int idx; - struct hw_perf_event *hwc = &event->hw; - /* - * Current implementation maps cycles, instruction count and cache-miss - * to specific counter. - * However, multiple of the 3 counters are able to count these events. - * - * - * SOFTWARE_EVENT_MASK mask for getting event num , - * This is defined by Jia-Rung, you can change the polocies. - * However, do not exceed 8 bits. This is hardware specific. - * The last number is SPAv3_2_SEL_LAST. - */ - unsigned long evtype = hwc->config_base & SOFTWARE_EVENT_MASK; - - idx = get_converted_event_idx(evtype); - /* - * Try to get the counter for correpsonding event - */ - if (evtype == SPAV3_0_SEL_TOTAL_CYCLES) { - if (!test_and_set_bit(idx, cpuc->used_mask)) - return idx; - if (!test_and_set_bit(NDS32_IDX_COUNTER0, cpuc->used_mask)) - return NDS32_IDX_COUNTER0; - if (!test_and_set_bit(NDS32_IDX_COUNTER1, cpuc->used_mask)) - return NDS32_IDX_COUNTER1; - } else if (evtype == SPAV3_1_SEL_COMPLETED_INSTRUCTION) { - if (!test_and_set_bit(idx, cpuc->used_mask)) - return idx; - else if (!test_and_set_bit(NDS32_IDX_COUNTER1, cpuc->used_mask)) - return NDS32_IDX_COUNTER1; - else if (!test_and_set_bit - (NDS32_IDX_CYCLE_COUNTER, cpuc->used_mask)) - return NDS32_IDX_CYCLE_COUNTER; - } else { - if (!test_and_set_bit(idx, cpuc->used_mask)) - return idx; - } - return -EAGAIN; -} - -static void nds32_pmu_start(struct nds32_pmu *cpu_pmu) -{ - unsigned long flags; - unsigned int val; - struct pmu_hw_events *events = cpu_pmu->get_hw_events(); - - raw_spin_lock_irqsave(&events->pmu_lock, flags); - - /* Enable all counters , NDS PFM has 3 counters */ - val = __nds32__mfsr(NDS32_SR_PFM_CTL); - val |= (PFM_CTL_EN[0] | PFM_CTL_EN[1] | PFM_CTL_EN[2]); - val &= ~(PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]); - __nds32__mtsr_isb(val, NDS32_SR_PFM_CTL); - - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); -} - -static void nds32_pmu_stop(struct nds32_pmu *cpu_pmu) -{ - unsigned long flags; - unsigned int val; - struct pmu_hw_events *events = cpu_pmu->get_hw_events(); - - raw_spin_lock_irqsave(&events->pmu_lock, flags); - - /* Disable all counters , NDS PFM has 3 counters */ - val = __nds32__mfsr(NDS32_SR_PFM_CTL); - val &= ~(PFM_CTL_EN[0] | PFM_CTL_EN[1] | PFM_CTL_EN[2]); - val &= ~(PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]); - __nds32__mtsr_isb(val, NDS32_SR_PFM_CTL); - - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); -} - -static void nds32_pmu_reset(void *info) -{ - u32 val = 0; - - val |= (PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]); - __nds32__mtsr(val, NDS32_SR_PFM_CTL); - __nds32__mtsr(0, NDS32_SR_PFM_CTL); - __nds32__mtsr(0, NDS32_SR_PFMC0); - __nds32__mtsr(0, NDS32_SR_PFMC1); - __nds32__mtsr(0, NDS32_SR_PFMC2); -} - -static void nds32_pmu_init(struct nds32_pmu *cpu_pmu) -{ - cpu_pmu->handle_irq = nds32_pmu_handle_irq; - cpu_pmu->enable = nds32_pmu_enable_event; - cpu_pmu->disable = nds32_pmu_disable_event; - cpu_pmu->read_counter = nds32_pmu_read_counter; - cpu_pmu->write_counter = nds32_pmu_write_counter; - cpu_pmu->get_event_idx = nds32_pmu_get_event_idx; - cpu_pmu->start = nds32_pmu_start; - cpu_pmu->stop = nds32_pmu_stop; - cpu_pmu->reset = nds32_pmu_reset; - cpu_pmu->max_period = 0xFFFFFFFF; /* Maximum counts */ -}; - -static u32 nds32_read_num_pfm_events(void) -{ - /* NDS32 SPAv3 PMU support 3 counter */ - return 3; -} - -static int device_pmu_init(struct nds32_pmu *cpu_pmu) -{ - nds32_pmu_init(cpu_pmu); - /* - * This name should be devive-specific name, whatever you like :) - * I think "PMU" will be a good generic name. - */ - cpu_pmu->name = "nds32v3-pmu"; - cpu_pmu->map_event = nds32_spav3_map_event; - cpu_pmu->num_events = nds32_read_num_pfm_events(); - cpu_pmu->set_event_filter = nds32_pmu_set_event_filter; - return 0; -} - -/* - * CPU PMU identification and probing. - */ -static int probe_current_pmu(struct nds32_pmu *pmu) -{ - int ret; - - get_cpu(); - ret = -ENODEV; - /* - * If ther are various CPU types with its own PMU, initialize with - * - * the corresponding one - */ - device_pmu_init(pmu); - put_cpu(); - return ret; -} - -static void nds32_pmu_enable(struct pmu *pmu) -{ - struct nds32_pmu *nds32_pmu = to_nds32_pmu(pmu); - struct pmu_hw_events *hw_events = nds32_pmu->get_hw_events(); - int enabled = bitmap_weight(hw_events->used_mask, - nds32_pmu->num_events); - - if (enabled) - nds32_pmu->start(nds32_pmu); -} - -static void nds32_pmu_disable(struct pmu *pmu) -{ - struct nds32_pmu *nds32_pmu = to_nds32_pmu(pmu); - - nds32_pmu->stop(nds32_pmu); -} - -static void nds32_pmu_release_hardware(struct nds32_pmu *nds32_pmu) -{ - nds32_pmu->free_irq(nds32_pmu); - pm_runtime_put_sync(&nds32_pmu->plat_device->dev); -} - -static irqreturn_t nds32_pmu_dispatch_irq(int irq, void *dev) -{ - struct nds32_pmu *nds32_pmu = (struct nds32_pmu *)dev; - int ret; - u64 start_clock, finish_clock; - - start_clock = local_clock(); - ret = nds32_pmu->handle_irq(irq, dev); - finish_clock = local_clock(); - - perf_sample_event_took(finish_clock - start_clock); - return ret; -} - -static int nds32_pmu_reserve_hardware(struct nds32_pmu *nds32_pmu) -{ - int err; - struct platform_device *pmu_device = nds32_pmu->plat_device; - - if (!pmu_device) - return -ENODEV; - - pm_runtime_get_sync(&pmu_device->dev); - err = nds32_pmu->request_irq(nds32_pmu, nds32_pmu_dispatch_irq); - if (err) { - nds32_pmu_release_hardware(nds32_pmu); - return err; - } - - return 0; -} - -static int -validate_event(struct pmu *pmu, struct pmu_hw_events *hw_events, - struct perf_event *event) -{ - struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu); - - if (is_software_event(event)) - return 1; - - if (event->pmu != pmu) - return 0; - - if (event->state < PERF_EVENT_STATE_OFF) - return 1; - - if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec) - return 1; - - return nds32_pmu->get_event_idx(hw_events, event) >= 0; -} - -static int validate_group(struct perf_event *event) -{ - struct perf_event *sibling, *leader = event->group_leader; - struct pmu_hw_events fake_pmu; - DECLARE_BITMAP(fake_used_mask, MAX_COUNTERS); - /* - * Initialize the fake PMU. We only need to populate the - * used_mask for the purposes of validation. - */ - memset(fake_used_mask, 0, sizeof(fake_used_mask)); - - if (!validate_event(event->pmu, &fake_pmu, leader)) - return -EINVAL; - - for_each_sibling_event(sibling, leader) { - if (!validate_event(event->pmu, &fake_pmu, sibling)) - return -EINVAL; - } - - if (!validate_event(event->pmu, &fake_pmu, event)) - return -EINVAL; - - return 0; -} - -static int __hw_perf_event_init(struct perf_event *event) -{ - struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu); - struct hw_perf_event *hwc = &event->hw; - int mapping; - - mapping = nds32_pmu->map_event(event); - - if (mapping < 0) { - pr_debug("event %x:%llx not supported\n", event->attr.type, - event->attr.config); - return mapping; - } - - /* - * We don't assign an index until we actually place the event onto - * hardware. Use -1 to signify that we haven't decided where to put it - * yet. For SMP systems, each core has it's own PMU so we can't do any - * clever allocation or constraints checking at this point. - */ - hwc->idx = -1; - hwc->config_base = 0; - hwc->config = 0; - hwc->event_base = 0; - - /* - * Check whether we need to exclude the counter from certain modes. - */ - if ((!nds32_pmu->set_event_filter || - nds32_pmu->set_event_filter(hwc, &event->attr)) && - event_requires_mode_exclusion(&event->attr)) { - pr_debug - ("NDS performance counters do not support mode exclusion\n"); - return -EOPNOTSUPP; - } - - /* - * Store the event encoding into the config_base field. - */ - hwc->config_base |= (unsigned long)mapping; - - if (!hwc->sample_period) { - /* - * For non-sampling runs, limit the sample_period to half - * of the counter width. That way, the new counter value - * is far less likely to overtake the previous one unless - * you have some serious IRQ latency issues. - */ - hwc->sample_period = nds32_pmu->max_period >> 1; - hwc->last_period = hwc->sample_period; - local64_set(&hwc->period_left, hwc->sample_period); - } - - if (event->group_leader != event) { - if (validate_group(event) != 0) - return -EINVAL; - } - - return 0; -} - -static int nds32_pmu_event_init(struct perf_event *event) -{ - struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu); - int err = 0; - atomic_t *active_events = &nds32_pmu->active_events; - - /* does not support taken branch sampling */ - if (has_branch_stack(event)) - return -EOPNOTSUPP; - - if (nds32_pmu->map_event(event) == -ENOENT) - return -ENOENT; - - if (!atomic_inc_not_zero(active_events)) { - if (atomic_read(active_events) == 0) { - /* Register irq handler */ - err = nds32_pmu_reserve_hardware(nds32_pmu); - } - - if (!err) - atomic_inc(active_events); - } - - if (err) - return err; - - err = __hw_perf_event_init(event); - - return err; -} - -static void nds32_start(struct perf_event *event, int flags) -{ - struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu); - struct hw_perf_event *hwc = &event->hw; - /* - * NDS pmu always has to reprogram the period, so ignore - * PERF_EF_RELOAD, see the comment below. - */ - if (flags & PERF_EF_RELOAD) - WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE)); - - hwc->state = 0; - /* Set the period for the event. */ - nds32_pmu_event_set_period(event); - - nds32_pmu->enable(event); -} - -static int nds32_pmu_add(struct perf_event *event, int flags) -{ - struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu); - struct pmu_hw_events *hw_events = nds32_pmu->get_hw_events(); - struct hw_perf_event *hwc = &event->hw; - int idx; - int err = 0; - - perf_pmu_disable(event->pmu); - - /* If we don't have a space for the counter then finish early. */ - idx = nds32_pmu->get_event_idx(hw_events, event); - if (idx < 0) { - err = idx; - goto out; - } - - /* - * If there is an event in the counter we are going to use then make - * sure it is disabled. - */ - event->hw.idx = idx; - nds32_pmu->disable(event); - hw_events->events[idx] = event; - - hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE; - if (flags & PERF_EF_START) - nds32_start(event, PERF_EF_RELOAD); - - /* Propagate our changes to the userspace mapping. */ - perf_event_update_userpage(event); - -out: - perf_pmu_enable(event->pmu); - return err; -} - -u64 nds32_pmu_event_update(struct perf_event *event) -{ - struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu); - struct hw_perf_event *hwc = &event->hw; - u64 delta, prev_raw_count, new_raw_count; - -again: - prev_raw_count = local64_read(&hwc->prev_count); - new_raw_count = nds32_pmu->read_counter(event); - - if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, - new_raw_count) != prev_raw_count) { - goto again; - } - /* - * Whether overflow or not, "unsigned substraction" - * will always get their delta - */ - delta = (new_raw_count - prev_raw_count) & nds32_pmu->max_period; - - local64_add(delta, &event->count); - local64_sub(delta, &hwc->period_left); - - return new_raw_count; -} - -static void nds32_stop(struct perf_event *event, int flags) -{ - struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu); - struct hw_perf_event *hwc = &event->hw; - /* - * NDS pmu always has to update the counter, so ignore - * PERF_EF_UPDATE, see comments in nds32_start(). - */ - if (!(hwc->state & PERF_HES_STOPPED)) { - nds32_pmu->disable(event); - nds32_pmu_event_update(event); - hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; - } -} - -static void nds32_pmu_del(struct perf_event *event, int flags) -{ - struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu); - struct pmu_hw_events *hw_events = nds32_pmu->get_hw_events(); - struct hw_perf_event *hwc = &event->hw; - int idx = hwc->idx; - - nds32_stop(event, PERF_EF_UPDATE); - hw_events->events[idx] = NULL; - clear_bit(idx, hw_events->used_mask); - - perf_event_update_userpage(event); -} - -static void nds32_pmu_read(struct perf_event *event) -{ - nds32_pmu_event_update(event); -} - -/* Please refer to SPAv3 for more hardware specific details */ -PMU_FORMAT_ATTR(event, "config:0-63"); - -static struct attribute *nds32_arch_formats_attr[] = { - &format_attr_event.attr, - NULL, -}; - -static struct attribute_group nds32_pmu_format_group = { - .name = "format", - .attrs = nds32_arch_formats_attr, -}; - -static ssize_t nds32_pmu_cpumask_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static DEVICE_ATTR(cpus, 0444, nds32_pmu_cpumask_show, NULL); - -static struct attribute *nds32_pmu_common_attrs[] = { - &dev_attr_cpus.attr, - NULL, -}; - -static struct attribute_group nds32_pmu_common_group = { - .attrs = nds32_pmu_common_attrs, -}; - -static const struct attribute_group *nds32_pmu_attr_groups[] = { - &nds32_pmu_format_group, - &nds32_pmu_common_group, - NULL, -}; - -static void nds32_init(struct nds32_pmu *nds32_pmu) -{ - atomic_set(&nds32_pmu->active_events, 0); - - nds32_pmu->pmu = (struct pmu) { - .pmu_enable = nds32_pmu_enable, - .pmu_disable = nds32_pmu_disable, - .attr_groups = nds32_pmu_attr_groups, - .event_init = nds32_pmu_event_init, - .add = nds32_pmu_add, - .del = nds32_pmu_del, - .start = nds32_start, - .stop = nds32_stop, - .read = nds32_pmu_read, - }; -} - -int nds32_pmu_register(struct nds32_pmu *nds32_pmu, int type) -{ - nds32_init(nds32_pmu); - pm_runtime_enable(&nds32_pmu->plat_device->dev); - pr_info("enabled with %s PMU driver, %d counters available\n", - nds32_pmu->name, nds32_pmu->num_events); - return perf_pmu_register(&nds32_pmu->pmu, nds32_pmu->name, type); -} - -static struct pmu_hw_events *cpu_pmu_get_cpu_events(void) -{ - return this_cpu_ptr(&cpu_hw_events); -} - -static int cpu_pmu_request_irq(struct nds32_pmu *cpu_pmu, irq_handler_t handler) -{ - int err, irq, irqs; - struct platform_device *pmu_device = cpu_pmu->plat_device; - - if (!pmu_device) - return -ENODEV; - - irqs = min(pmu_device->num_resources, num_possible_cpus()); - if (irqs < 1) { - pr_err("no irqs for PMUs defined\n"); - return -ENODEV; - } - - irq = platform_get_irq(pmu_device, 0); - err = request_irq(irq, handler, IRQF_NOBALANCING, "nds32-pfm", - cpu_pmu); - if (err) { - pr_err("unable to request IRQ%d for NDS PMU counters\n", - irq); - return err; - } - return 0; -} - -static void cpu_pmu_free_irq(struct nds32_pmu *cpu_pmu) -{ - int irq; - struct platform_device *pmu_device = cpu_pmu->plat_device; - - irq = platform_get_irq(pmu_device, 0); - if (irq >= 0) - free_irq(irq, cpu_pmu); -} - -static void cpu_pmu_init(struct nds32_pmu *cpu_pmu) -{ - int cpu; - struct pmu_hw_events *events = &per_cpu(cpu_hw_events, cpu); - - raw_spin_lock_init(&events->pmu_lock); - - cpu_pmu->get_hw_events = cpu_pmu_get_cpu_events; - cpu_pmu->request_irq = cpu_pmu_request_irq; - cpu_pmu->free_irq = cpu_pmu_free_irq; - - /* Ensure the PMU has sane values out of reset. */ - if (cpu_pmu->reset) - on_each_cpu(cpu_pmu->reset, cpu_pmu, 1); -} - -static const struct of_device_id cpu_pmu_of_device_ids[] = { - {.compatible = "andestech,nds32v3-pmu", - .data = device_pmu_init}, - {}, -}; - -static int cpu_pmu_device_probe(struct platform_device *pdev) -{ - const struct of_device_id *of_id; - int (*init_fn)(struct nds32_pmu *nds32_pmu); - struct device_node *node = pdev->dev.of_node; - struct nds32_pmu *pmu; - int ret = -ENODEV; - - if (cpu_pmu) { - pr_notice("[perf] attempt to register multiple PMU devices!\n"); - return -ENOSPC; - } - - pmu = kzalloc(sizeof(*pmu), GFP_KERNEL); - if (!pmu) - return -ENOMEM; - - of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node); - if (node && of_id) { - init_fn = of_id->data; - ret = init_fn(pmu); - } else { - ret = probe_current_pmu(pmu); - } - - if (ret) { - pr_notice("[perf] failed to probe PMU!\n"); - goto out_free; - } - - cpu_pmu = pmu; - cpu_pmu->plat_device = pdev; - cpu_pmu_init(cpu_pmu); - ret = nds32_pmu_register(cpu_pmu, PERF_TYPE_RAW); - - if (!ret) - return 0; - -out_free: - pr_notice("[perf] failed to register PMU devices!\n"); - kfree(pmu); - return ret; -} - -static struct platform_driver cpu_pmu_driver = { - .driver = { - .name = "nds32-pfm", - .of_match_table = cpu_pmu_of_device_ids, - }, - .probe = cpu_pmu_device_probe, - .id_table = cpu_pmu_plat_device_ids, -}; - -static int __init register_pmu_driver(void) -{ - int err = 0; - - err = platform_driver_register(&cpu_pmu_driver); - if (err) - pr_notice("[perf] PMU initialization failed\n"); - else - pr_notice("[perf] PMU initialization done\n"); - - return err; -} - -device_initcall(register_pmu_driver); - -/* - * References: arch/nds32/kernel/traps.c:__dump() - * You will need to know the NDS ABI first. - */ -static int unwind_frame_kernel(struct stackframe *frame) -{ - int graph = 0; -#ifdef CONFIG_FRAME_POINTER - /* 0x3 means misalignment */ - if (!kstack_end((void *)frame->fp) && - !((unsigned long)frame->fp & 0x3) && - ((unsigned long)frame->fp >= TASK_SIZE)) { - /* - * The array index is based on the ABI, the below graph - * illustrate the reasons. - * Function call procedure: "smw" and "lmw" will always - * update SP and FP for you automatically. - * - * Stack Relative Address - * | | 0 - * ---- - * |LP| <-- SP(before smw) <-- FP(after smw) -1 - * ---- - * |FP| -2 - * ---- - * | | <-- SP(after smw) -3 - */ - frame->lp = ((unsigned long *)frame->fp)[-1]; - frame->fp = ((unsigned long *)frame->fp)[FP_OFFSET]; - /* make sure CONFIG_FUNCTION_GRAPH_TRACER is turned on */ - if (__kernel_text_address(frame->lp)) - frame->lp = ftrace_graph_ret_addr - (NULL, &graph, frame->lp, NULL); - - return 0; - } else { - return -EPERM; - } -#else - /* - * You can refer to arch/nds32/kernel/traps.c:__dump() - * Treat "sp" as "fp", but the "sp" is one frame ahead of "fp". - * And, the "sp" is not always correct. - * - * Stack Relative Address - * | | 0 - * ---- - * |LP| <-- SP(before smw) -1 - * ---- - * | | <-- SP(after smw) -2 - * ---- - */ - if (!kstack_end((void *)frame->sp)) { - frame->lp = ((unsigned long *)frame->sp)[1]; - /* TODO: How to deal with the value in first - * "sp" is not correct? - */ - if (__kernel_text_address(frame->lp)) - frame->lp = ftrace_graph_ret_addr - (tsk, &graph, frame->lp, NULL); - - frame->sp = ((unsigned long *)frame->sp) + 1; - - return 0; - } else { - return -EPERM; - } -#endif -} - -static void notrace -walk_stackframe(struct stackframe *frame, - int (*fn_record)(struct stackframe *, void *), - void *data) -{ - while (1) { - int ret; - - if (fn_record(frame, data)) - break; - - ret = unwind_frame_kernel(frame); - if (ret < 0) - break; - } -} - -/* - * Gets called by walk_stackframe() for every stackframe. This will be called - * whist unwinding the stackframe and is like a subroutine return so we use - * the PC. - */ -static int callchain_trace(struct stackframe *fr, void *data) -{ - struct perf_callchain_entry_ctx *entry = data; - - perf_callchain_store(entry, fr->lp); - return 0; -} - -/* - * Get the return address for a single stackframe and return a pointer to the - * next frame tail. - */ -static unsigned long -user_backtrace(struct perf_callchain_entry_ctx *entry, unsigned long fp) -{ - struct frame_tail buftail; - unsigned long lp = 0; - unsigned long *user_frame_tail = - (unsigned long *)(fp - (unsigned long)sizeof(buftail)); - - /* Check accessibility of one struct frame_tail beyond */ - if (!access_ok(user_frame_tail, sizeof(buftail))) - return 0; - if (__copy_from_user_inatomic - (&buftail, user_frame_tail, sizeof(buftail))) - return 0; - - /* - * Refer to unwind_frame_kernel() for more illurstration - */ - lp = buftail.stack_lp; /* ((unsigned long *)fp)[-1] */ - fp = buftail.stack_fp; /* ((unsigned long *)fp)[FP_OFFSET] */ - perf_callchain_store(entry, lp); - return fp; -} - -static unsigned long -user_backtrace_opt_size(struct perf_callchain_entry_ctx *entry, - unsigned long fp) -{ - struct frame_tail_opt_size buftail; - unsigned long lp = 0; - - unsigned long *user_frame_tail = - (unsigned long *)(fp - (unsigned long)sizeof(buftail)); - - /* Check accessibility of one struct frame_tail beyond */ - if (!access_ok(user_frame_tail, sizeof(buftail))) - return 0; - if (__copy_from_user_inatomic - (&buftail, user_frame_tail, sizeof(buftail))) - return 0; - - /* - * Refer to unwind_frame_kernel() for more illurstration - */ - lp = buftail.stack_lp; /* ((unsigned long *)fp)[-1] */ - fp = buftail.stack_fp; /* ((unsigned long *)fp)[FP_OFFSET] */ - - perf_callchain_store(entry, lp); - return fp; -} - -/* - * This will be called when the target is in user mode - * This function will only be called when we use - * "PERF_SAMPLE_CALLCHAIN" in - * kernel/events/core.c:perf_prepare_sample() - * - * How to trigger perf_callchain_[user/kernel] : - * $ perf record -e cpu-clock --call-graph fp ./program - * $ perf report --call-graph - */ -unsigned long leaf_fp; -void -perf_callchain_user(struct perf_callchain_entry_ctx *entry, - struct pt_regs *regs) -{ - unsigned long fp = 0; - unsigned long gp = 0; - unsigned long lp = 0; - unsigned long sp = 0; - unsigned long *user_frame_tail; - - leaf_fp = 0; - - perf_callchain_store(entry, regs->ipc); - fp = regs->fp; - gp = regs->gp; - lp = regs->lp; - sp = regs->sp; - if (entry->nr < PERF_MAX_STACK_DEPTH && - (unsigned long)fp && !((unsigned long)fp & 0x7) && fp > sp) { - user_frame_tail = - (unsigned long *)(fp - (unsigned long)sizeof(fp)); - - if (!access_ok(user_frame_tail, sizeof(fp))) - return; - - if (__copy_from_user_inatomic - (&leaf_fp, user_frame_tail, sizeof(fp))) - return; - - if (leaf_fp == lp) { - /* - * Maybe this is non leaf function - * with optimize for size, - * or maybe this is the function - * with optimize for size - */ - struct frame_tail buftail; - - user_frame_tail = - (unsigned long *)(fp - - (unsigned long)sizeof(buftail)); - - if (!access_ok(user_frame_tail, sizeof(buftail))) - return; - - if (__copy_from_user_inatomic - (&buftail, user_frame_tail, sizeof(buftail))) - return; - - if (buftail.stack_fp == gp) { - /* non leaf function with optimize - * for size condition - */ - struct frame_tail_opt_size buftail_opt_size; - - user_frame_tail = - (unsigned long *)(fp - (unsigned long) - sizeof(buftail_opt_size)); - - if (!access_ok(user_frame_tail, - sizeof(buftail_opt_size))) - return; - - if (__copy_from_user_inatomic - (&buftail_opt_size, user_frame_tail, - sizeof(buftail_opt_size))) - return; - - perf_callchain_store(entry, lp); - fp = buftail_opt_size.stack_fp; - - while ((entry->nr < PERF_MAX_STACK_DEPTH) && - (unsigned long)fp && - !((unsigned long)fp & 0x7) && - fp > sp) { - sp = fp; - fp = user_backtrace_opt_size(entry, fp); - } - - } else { - /* this is the function - * without optimize for size - */ - fp = buftail.stack_fp; - perf_callchain_store(entry, lp); - while ((entry->nr < PERF_MAX_STACK_DEPTH) && - (unsigned long)fp && - !((unsigned long)fp & 0x7) && - fp > sp) { - sp = fp; - fp = user_backtrace(entry, fp); - } - } - } else { - /* this is leaf function */ - fp = leaf_fp; - perf_callchain_store(entry, lp); - - /* previous function callcahin */ - while ((entry->nr < PERF_MAX_STACK_DEPTH) && - (unsigned long)fp && - !((unsigned long)fp & 0x7) && fp > sp) { - sp = fp; - fp = user_backtrace(entry, fp); - } - } - return; - } -} - -/* This will be called when the target is in kernel mode */ -void -perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, - struct pt_regs *regs) -{ - struct stackframe fr; - - fr.fp = regs->fp; - fr.lp = regs->lp; - fr.sp = regs->sp; - walk_stackframe(&fr, callchain_trace, entry); -} - -unsigned long perf_instruction_pointer(struct pt_regs *regs) -{ - return instruction_pointer(regs); -} - -unsigned long perf_misc_flags(struct pt_regs *regs) -{ - int misc = 0; - - if (user_mode(regs)) - misc |= PERF_RECORD_MISC_USER; - else - misc |= PERF_RECORD_MISC_KERNEL; - - return misc; -} diff --git a/arch/nds32/kernel/pm.c b/arch/nds32/kernel/pm.c deleted file mode 100644 index e25700e125d8..000000000000 --- a/arch/nds32/kernel/pm.c +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2008-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include - -unsigned int resume_addr; -unsigned int *phy_addr_sp_tmp; - -static void nds32_suspend2ram(void) -{ - pgd_t *pgdv; - p4d_t *p4dv; - pud_t *pudv; - pmd_t *pmdv; - pte_t *ptev; - - pgdv = (pgd_t *)__va((__nds32__mfsr(NDS32_SR_L1_PPTB) & - L1_PPTB_mskBASE)) + pgd_index((unsigned int)cpu_resume); - - p4dv = p4d_offset(pgdv, (unsigned int)cpu_resume); - pudv = pud_offset(p4dv, (unsigned int)cpu_resume); - pmdv = pmd_offset(pudv, (unsigned int)cpu_resume); - ptev = pte_offset_map(pmdv, (unsigned int)cpu_resume); - - resume_addr = ((*ptev) & TLB_DATA_mskPPN) - | ((unsigned int)cpu_resume & 0x00000fff); - - suspend2ram(); -} - -static void nds32_suspend_cpu(void) -{ - while (!(__nds32__mfsr(NDS32_SR_INT_PEND) & wake_mask)) - __asm__ volatile ("standby no_wake_grant\n\t"); -} - -static int nds32_pm_valid(suspend_state_t state) -{ - switch (state) { - case PM_SUSPEND_ON: - case PM_SUSPEND_STANDBY: - case PM_SUSPEND_MEM: - return 1; - default: - return 0; - } -} - -static int nds32_pm_enter(suspend_state_t state) -{ - pr_debug("%s:state:%d\n", __func__, state); - switch (state) { - case PM_SUSPEND_STANDBY: - nds32_suspend_cpu(); - return 0; - case PM_SUSPEND_MEM: - nds32_suspend2ram(); - return 0; - default: - return -EINVAL; - } -} - -static const struct platform_suspend_ops nds32_pm_ops = { - .valid = nds32_pm_valid, - .enter = nds32_pm_enter, -}; - -static int __init nds32_pm_init(void) -{ - pr_debug("Enter %s\n", __func__); - suspend_set_ops(&nds32_pm_ops); - return 0; -} -late_initcall(nds32_pm_init); diff --git a/arch/nds32/kernel/process.c b/arch/nds32/kernel/process.c deleted file mode 100644 index d35c1f63fa11..000000000000 --- a/arch/nds32/kernel/process.c +++ /dev/null @@ -1,256 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if IS_ENABLED(CONFIG_LAZY_FPU) -struct task_struct *last_task_used_math; -#endif - -extern void setup_mm_for_reboot(char mode); - -extern inline void arch_reset(char mode) -{ - if (mode == 's') { - /* Use cpu handler, jump to 0 */ - cpu_reset(0); - } -} - -void (*pm_power_off) (void); -EXPORT_SYMBOL(pm_power_off); - -static char reboot_mode_nds32 = 'h'; - -int __init reboot_setup(char *str) -{ - reboot_mode_nds32 = str[0]; - return 1; -} - -static int cpub_pwroff(void) -{ - return 0; -} - -__setup("reboot=", reboot_setup); - -void machine_halt(void) -{ - cpub_pwroff(); -} - -EXPORT_SYMBOL(machine_halt); - -void machine_power_off(void) -{ - if (pm_power_off) - pm_power_off(); -} - -EXPORT_SYMBOL(machine_power_off); - -void machine_restart(char *cmd) -{ - /* - * Clean and disable cache, and turn off interrupts - */ - cpu_proc_fin(); - - /* - * Tell the mm system that we are going to reboot - - * we may need it to insert some 1:1 mappings so that - * soft boot works. - */ - setup_mm_for_reboot(reboot_mode_nds32); - - /* Execute kernel restart handler call chain */ - do_kernel_restart(cmd); - - /* - * Now call the architecture specific reboot code. - */ - arch_reset(reboot_mode_nds32); - - /* - * Whoops - the architecture was unable to reboot. - * Tell the user! - */ - mdelay(1000); - pr_info("Reboot failed -- System halted\n"); - while (1) ; -} - -EXPORT_SYMBOL(machine_restart); - -void show_regs(struct pt_regs *regs) -{ - printk("PC is at %pS\n", (void *)instruction_pointer(regs)); - printk("LP is at %pS\n", (void *)regs->lp); - pr_info("pc : [<%08lx>] lp : [<%08lx>] %s\n" - "sp : %08lx fp : %08lx gp : %08lx\n", - instruction_pointer(regs), - regs->lp, print_tainted(), regs->sp, regs->fp, regs->gp); - pr_info("r25: %08lx r24: %08lx\n", regs->uregs[25], regs->uregs[24]); - - pr_info("r23: %08lx r22: %08lx r21: %08lx r20: %08lx\n", - regs->uregs[23], regs->uregs[22], - regs->uregs[21], regs->uregs[20]); - pr_info("r19: %08lx r18: %08lx r17: %08lx r16: %08lx\n", - regs->uregs[19], regs->uregs[18], - regs->uregs[17], regs->uregs[16]); - pr_info("r15: %08lx r14: %08lx r13: %08lx r12: %08lx\n", - regs->uregs[15], regs->uregs[14], - regs->uregs[13], regs->uregs[12]); - pr_info("r11: %08lx r10: %08lx r9 : %08lx r8 : %08lx\n", - regs->uregs[11], regs->uregs[10], - regs->uregs[9], regs->uregs[8]); - pr_info("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", - regs->uregs[7], regs->uregs[6], regs->uregs[5], regs->uregs[4]); - pr_info("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", - regs->uregs[3], regs->uregs[2], regs->uregs[1], regs->uregs[0]); - pr_info(" IRQs o%s Segment user\n", - interrupts_enabled(regs) ? "n" : "ff"); -} - -EXPORT_SYMBOL(show_regs); - -void exit_thread(struct task_struct *tsk) -{ -#if defined(CONFIG_FPU) && defined(CONFIG_LAZY_FPU) - if (last_task_used_math == tsk) - last_task_used_math = NULL; -#endif -} - -void flush_thread(void) -{ -#if defined(CONFIG_FPU) - clear_fpu(task_pt_regs(current)); - clear_used_math(); -# ifdef CONFIG_LAZY_FPU - if (last_task_used_math == current) - last_task_used_math = NULL; -# endif -#endif -} - -DEFINE_PER_CPU(struct task_struct *, __entry_task); - -asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); -int copy_thread(unsigned long clone_flags, unsigned long stack_start, - unsigned long stk_sz, struct task_struct *p, unsigned long tls) -{ - struct pt_regs *childregs = task_pt_regs(p); - - memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context)); - - if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) { - memset(childregs, 0, sizeof(struct pt_regs)); - /* kernel thread fn */ - p->thread.cpu_context.r6 = stack_start; - /* kernel thread argument */ - p->thread.cpu_context.r7 = stk_sz; - } else { - *childregs = *current_pt_regs(); - if (stack_start) - childregs->sp = stack_start; - /* child get zero as ret. */ - childregs->uregs[0] = 0; - childregs->osp = 0; - if (clone_flags & CLONE_SETTLS) - childregs->uregs[25] = tls; - } - /* cpu context switching */ - p->thread.cpu_context.pc = (unsigned long)ret_from_fork; - p->thread.cpu_context.sp = (unsigned long)childregs; - -#if IS_ENABLED(CONFIG_FPU) - if (used_math()) { -# if !IS_ENABLED(CONFIG_LAZY_FPU) - unlazy_fpu(current); -# else - preempt_disable(); - if (last_task_used_math == current) - save_fpu(current); - preempt_enable(); -# endif - p->thread.fpu = current->thread.fpu; - clear_fpu(task_pt_regs(p)); - set_stopped_child_used_math(p); - } -#endif - -#ifdef CONFIG_HWZOL - childregs->lb = 0; - childregs->le = 0; - childregs->lc = 0; -#endif - - return 0; -} - -#if IS_ENABLED(CONFIG_FPU) -struct task_struct *_switch_fpu(struct task_struct *prev, struct task_struct *next) -{ -#if !IS_ENABLED(CONFIG_LAZY_FPU) - unlazy_fpu(prev); -#endif - if (!(next->flags & PF_KTHREAD)) - clear_fpu(task_pt_regs(next)); - return prev; -} -#endif - -/* - * fill in the fpe structure for a core dump... - */ -int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpu) -{ - int fpvalid = 0; -#if IS_ENABLED(CONFIG_FPU) - struct task_struct *tsk = current; - - fpvalid = tsk_used_math(tsk); - if (fpvalid) { - lose_fpu(); - memcpy(fpu, &tsk->thread.fpu, sizeof(*fpu)); - } -#endif - return fpvalid; -} - -EXPORT_SYMBOL(dump_fpu); - -unsigned long __get_wchan(struct task_struct *p) -{ - unsigned long fp, lr; - unsigned long stack_start, stack_end; - int count = 0; - - if (IS_ENABLED(CONFIG_FRAME_POINTER)) { - stack_start = (unsigned long)end_of_stack(p); - stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE; - - fp = thread_saved_fp(p); - do { - if (fp < stack_start || fp > stack_end) - return 0; - lr = ((unsigned long *)fp)[0]; - if (!in_sched_functions(lr)) - return lr; - fp = *(unsigned long *)(fp + 4); - } while (count++ < 16); - } - return 0; -} diff --git a/arch/nds32/kernel/ptrace.c b/arch/nds32/kernel/ptrace.c deleted file mode 100644 index d0eda870fbc2..000000000000 --- a/arch/nds32/kernel/ptrace.c +++ /dev/null @@ -1,118 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include - -enum nds32_regset { - REGSET_GPR, -}; - -static int gpr_get(struct task_struct *target, - const struct user_regset *regset, - struct membuf to) -{ - return membuf_write(&to, &task_pt_regs(target)->user_regs, - sizeof(struct user_pt_regs)); -} - -static int gpr_set(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user * ubuf) -{ - int err; - struct user_pt_regs newregs = task_pt_regs(target)->user_regs; - - err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newregs, 0, -1); - if (err) - return err; - - task_pt_regs(target)->user_regs = newregs; - return 0; -} - -static const struct user_regset nds32_regsets[] = { - [REGSET_GPR] = { - .core_note_type = NT_PRSTATUS, - .n = sizeof(struct user_pt_regs) / sizeof(u32), - .size = sizeof(elf_greg_t), - .align = sizeof(elf_greg_t), - .regset_get = gpr_get, - .set = gpr_set} -}; - -static const struct user_regset_view nds32_user_view = { - .name = "nds32", - .e_machine = EM_NDS32, - .regsets = nds32_regsets, - .n = ARRAY_SIZE(nds32_regsets) -}; - -const struct user_regset_view *task_user_regset_view(struct task_struct *task) -{ - return &nds32_user_view; -} - -void ptrace_disable(struct task_struct *child) -{ - user_disable_single_step(child); -} - -/* do_ptrace() - * - * Provide ptrace defined service. - */ -long arch_ptrace(struct task_struct *child, long request, unsigned long addr, - unsigned long data) -{ - int ret = -EIO; - - switch (request) { - default: - ret = ptrace_request(child, request, addr, data); - break; - } - - return ret; -} - -void user_enable_single_step(struct task_struct *child) -{ - struct pt_regs *regs; - regs = task_pt_regs(child); - regs->ipsw |= PSW_mskHSS; - set_tsk_thread_flag(child, TIF_SINGLESTEP); -} - -void user_disable_single_step(struct task_struct *child) -{ - struct pt_regs *regs; - regs = task_pt_regs(child); - regs->ipsw &= ~PSW_mskHSS; - clear_tsk_thread_flag(child, TIF_SINGLESTEP); -} - -/* sys_trace() - * - * syscall trace handler. - */ - -asmlinkage int syscall_trace_enter(struct pt_regs *regs) -{ - if (test_thread_flag(TIF_SYSCALL_TRACE)) { - if (tracehook_report_syscall_entry(regs)) - forget_syscall(regs); - } - return regs->syscallno; -} - -asmlinkage void syscall_trace_leave(struct pt_regs *regs) -{ - int step = test_thread_flag(TIF_SINGLESTEP); - if (step || test_thread_flag(TIF_SYSCALL_TRACE)) - tracehook_report_syscall_exit(regs, step); - -} diff --git a/arch/nds32/kernel/setup.c b/arch/nds32/kernel/setup.c deleted file mode 100644 index b3d34d646652..000000000000 --- a/arch/nds32/kernel/setup.c +++ /dev/null @@ -1,369 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define HWCAP_MFUSR_PC 0x000001 -#define HWCAP_EXT 0x000002 -#define HWCAP_EXT2 0x000004 -#define HWCAP_FPU 0x000008 -#define HWCAP_AUDIO 0x000010 -#define HWCAP_BASE16 0x000020 -#define HWCAP_STRING 0x000040 -#define HWCAP_REDUCED_REGS 0x000080 -#define HWCAP_VIDEO 0x000100 -#define HWCAP_ENCRYPT 0x000200 -#define HWCAP_EDM 0x000400 -#define HWCAP_LMDMA 0x000800 -#define HWCAP_PFM 0x001000 -#define HWCAP_HSMP 0x002000 -#define HWCAP_TRACE 0x004000 -#define HWCAP_DIV 0x008000 -#define HWCAP_MAC 0x010000 -#define HWCAP_L2C 0x020000 -#define HWCAP_FPU_DP 0x040000 -#define HWCAP_V2 0x080000 -#define HWCAP_DX_REGS 0x100000 -#define HWCAP_HWPRE 0x200000 - -unsigned long cpu_id, cpu_rev, cpu_cfgid; -bool has_fpu = false; -char cpu_series; -char *endianness = NULL; - -unsigned int __atags_pointer __initdata; -unsigned int elf_hwcap; -EXPORT_SYMBOL(elf_hwcap); - -/* - * The following string table, must sync with HWCAP_xx bitmask, - * which is defined above - */ -static const char *hwcap_str[] = { - "mfusr_pc", - "perf1", - "perf2", - "fpu", - "audio", - "16b", - "string", - "reduced_regs", - "video", - "encrypt", - "edm", - "lmdma", - "pfm", - "hsmp", - "trace", - "div", - "mac", - "l2c", - "fpu_dp", - "v2", - "dx_regs", - "hw_pre", - NULL, -}; - -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH -#define WRITE_METHOD "write through" -#else -#define WRITE_METHOD "write back" -#endif - -struct cache_info L1_cache_info[2]; -static void __init dump_cpu_info(int cpu) -{ - int i, p = 0; - char str[sizeof(hwcap_str) + 16]; - - for (i = 0; hwcap_str[i]; i++) { - if (elf_hwcap & (1 << i)) { - sprintf(str + p, "%s ", hwcap_str[i]); - p += strlen(hwcap_str[i]) + 1; - } - } - - pr_info("CPU%d Features: %s\n", cpu, str); - - L1_cache_info[ICACHE].ways = CACHE_WAY(ICACHE); - L1_cache_info[ICACHE].line_size = CACHE_LINE_SIZE(ICACHE); - L1_cache_info[ICACHE].sets = CACHE_SET(ICACHE); - L1_cache_info[ICACHE].size = - L1_cache_info[ICACHE].ways * L1_cache_info[ICACHE].line_size * - L1_cache_info[ICACHE].sets / 1024; - pr_info("L1I:%dKB/%dS/%dW/%dB\n", L1_cache_info[ICACHE].size, - L1_cache_info[ICACHE].sets, L1_cache_info[ICACHE].ways, - L1_cache_info[ICACHE].line_size); - L1_cache_info[DCACHE].ways = CACHE_WAY(DCACHE); - L1_cache_info[DCACHE].line_size = CACHE_LINE_SIZE(DCACHE); - L1_cache_info[DCACHE].sets = CACHE_SET(DCACHE); - L1_cache_info[DCACHE].size = - L1_cache_info[DCACHE].ways * L1_cache_info[DCACHE].line_size * - L1_cache_info[DCACHE].sets / 1024; - pr_info("L1D:%dKB/%dS/%dW/%dB\n", L1_cache_info[DCACHE].size, - L1_cache_info[DCACHE].sets, L1_cache_info[DCACHE].ways, - L1_cache_info[DCACHE].line_size); - pr_info("L1 D-Cache is %s\n", WRITE_METHOD); - if (L1_cache_info[DCACHE].size != L1_CACHE_BYTES) - pr_crit - ("The cache line size(%d) of this processor is not the same as L1_CACHE_BYTES(%d).\n", - L1_cache_info[DCACHE].size, L1_CACHE_BYTES); -#ifdef CONFIG_CPU_CACHE_ALIASING - { - int aliasing_num; - aliasing_num = - L1_cache_info[ICACHE].size * 1024 / PAGE_SIZE / - L1_cache_info[ICACHE].ways; - L1_cache_info[ICACHE].aliasing_num = aliasing_num; - L1_cache_info[ICACHE].aliasing_mask = - (aliasing_num - 1) << PAGE_SHIFT; - aliasing_num = - L1_cache_info[DCACHE].size * 1024 / PAGE_SIZE / - L1_cache_info[DCACHE].ways; - L1_cache_info[DCACHE].aliasing_num = aliasing_num; - L1_cache_info[DCACHE].aliasing_mask = - (aliasing_num - 1) << PAGE_SHIFT; - } -#endif -#ifdef CONFIG_FPU - /* Disable fpu and enable when it is used. */ - if (has_fpu) - disable_fpu(); -#endif -} - -static void __init setup_cpuinfo(void) -{ - unsigned long tmp = 0, cpu_name; - - cpu_dcache_inval_all(); - cpu_icache_inval_all(); - __nds32__isb(); - - cpu_id = (__nds32__mfsr(NDS32_SR_CPU_VER) & CPU_VER_mskCPUID) >> CPU_VER_offCPUID; - cpu_name = ((cpu_id) & 0xf0) >> 4; - cpu_series = cpu_name ? cpu_name - 10 + 'A' : 'N'; - cpu_id = cpu_id & 0xf; - cpu_rev = (__nds32__mfsr(NDS32_SR_CPU_VER) & CPU_VER_mskREV) >> CPU_VER_offREV; - cpu_cfgid = (__nds32__mfsr(NDS32_SR_CPU_VER) & CPU_VER_mskCFGID) >> CPU_VER_offCFGID; - - pr_info("CPU:%c%ld, CPU_VER 0x%08x(id %lu, rev %lu, cfg %lu)\n", - cpu_series, cpu_id, __nds32__mfsr(NDS32_SR_CPU_VER), cpu_id, cpu_rev, cpu_cfgid); - - elf_hwcap |= HWCAP_MFUSR_PC; - - if (((__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskBASEV) >> MSC_CFG_offBASEV) == 0) { - if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskDIV) - elf_hwcap |= HWCAP_DIV; - - if ((__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskMAC) - || (cpu_id == 12 && cpu_rev < 4)) - elf_hwcap |= HWCAP_MAC; - } else { - elf_hwcap |= HWCAP_V2; - elf_hwcap |= HWCAP_DIV; - elf_hwcap |= HWCAP_MAC; - } - - if (cpu_cfgid & 0x0001) - elf_hwcap |= HWCAP_EXT; - - if (cpu_cfgid & 0x0002) - elf_hwcap |= HWCAP_BASE16; - - if (cpu_cfgid & 0x0004) - elf_hwcap |= HWCAP_EXT2; - - if (cpu_cfgid & 0x0008) { - elf_hwcap |= HWCAP_FPU; - has_fpu = true; - } - if (cpu_cfgid & 0x0010) - elf_hwcap |= HWCAP_STRING; - - if (__nds32__mfsr(NDS32_SR_MMU_CFG) & MMU_CFG_mskDE) - endianness = "MSB"; - else - endianness = "LSB"; - - if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskEDM) - elf_hwcap |= HWCAP_EDM; - - if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskLMDMA) - elf_hwcap |= HWCAP_LMDMA; - - if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskPFM) - elf_hwcap |= HWCAP_PFM; - - if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskHSMP) - elf_hwcap |= HWCAP_HSMP; - - if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskTRACE) - elf_hwcap |= HWCAP_TRACE; - - if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskAUDIO) - elf_hwcap |= HWCAP_AUDIO; - - if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskL2C) - elf_hwcap |= HWCAP_L2C; - -#ifdef CONFIG_HW_PRE - if (__nds32__mfsr(NDS32_SR_MISC_CTL) & MISC_CTL_makHWPRE_EN) - elf_hwcap |= HWCAP_HWPRE; -#endif - - tmp = __nds32__mfsr(NDS32_SR_CACHE_CTL); - if (!IS_ENABLED(CONFIG_CPU_DCACHE_DISABLE)) - tmp |= CACHE_CTL_mskDC_EN; - - if (!IS_ENABLED(CONFIG_CPU_ICACHE_DISABLE)) - tmp |= CACHE_CTL_mskIC_EN; - __nds32__mtsr_isb(tmp, NDS32_SR_CACHE_CTL); - - dump_cpu_info(smp_processor_id()); -} - -static void __init setup_memory(void) -{ - unsigned long ram_start_pfn; - unsigned long free_ram_start_pfn; - phys_addr_t memory_start, memory_end; - - memory_end = memory_start = 0; - - /* Find main memory where is the kernel */ - memory_start = memblock_start_of_DRAM(); - memory_end = memblock_end_of_DRAM(); - - if (!memory_end) { - panic("No memory!"); - } - - ram_start_pfn = PFN_UP(memblock_start_of_DRAM()); - /* free_ram_start_pfn is first page after kernel */ - free_ram_start_pfn = PFN_UP(__pa(&_end)); - max_pfn = PFN_DOWN(memblock_end_of_DRAM()); - /* it could update max_pfn */ - if (max_pfn - ram_start_pfn <= MAXMEM_PFN) - max_low_pfn = max_pfn; - else { - max_low_pfn = MAXMEM_PFN + ram_start_pfn; - if (!IS_ENABLED(CONFIG_HIGHMEM)) - max_pfn = MAXMEM_PFN + ram_start_pfn; - } - /* high_memory is related with VMALLOC */ - high_memory = (void *)__va(max_low_pfn * PAGE_SIZE); - min_low_pfn = free_ram_start_pfn; - - /* - * initialize the boot-time allocator (with low memory only). - * - * This makes the memory from the end of the kernel to the end of - * RAM usable. - */ - memblock_set_bottom_up(true); - memblock_reserve(PFN_PHYS(ram_start_pfn), PFN_PHYS(free_ram_start_pfn - ram_start_pfn)); - - early_init_fdt_reserve_self(); - early_init_fdt_scan_reserved_mem(); - - memblock_dump_all(); -} - -void __init setup_arch(char **cmdline_p) -{ - early_init_devtree(__atags_pointer ? \ - phys_to_virt(__atags_pointer) : __dtb_start); - - setup_cpuinfo(); - - setup_initial_init_mm(_stext, _etext, _edata, _end); - - /* setup bootmem allocator */ - setup_memory(); - - /* paging_init() sets up the MMU and marks all pages as reserved */ - paging_init(); - - /* invalidate all TLB entries because the new mapping is created */ - __nds32__tlbop_flua(); - - /* use generic way to parse */ - parse_early_param(); - - unflatten_and_copy_device_tree(); - - *cmdline_p = boot_command_line; - early_trap_init(); -} - -static int c_show(struct seq_file *m, void *v) -{ - int i; - - seq_printf(m, "Processor\t: %c%ld (id %lu, rev %lu, cfg %lu)\n", - cpu_series, cpu_id, cpu_id, cpu_rev, cpu_cfgid); - - seq_printf(m, "L1I\t\t: %luKB/%luS/%luW/%luB\n", - CACHE_SET(ICACHE) * CACHE_WAY(ICACHE) * - CACHE_LINE_SIZE(ICACHE) / 1024, CACHE_SET(ICACHE), - CACHE_WAY(ICACHE), CACHE_LINE_SIZE(ICACHE)); - - seq_printf(m, "L1D\t\t: %luKB/%luS/%luW/%luB\n", - CACHE_SET(DCACHE) * CACHE_WAY(DCACHE) * - CACHE_LINE_SIZE(DCACHE) / 1024, CACHE_SET(DCACHE), - CACHE_WAY(DCACHE), CACHE_LINE_SIZE(DCACHE)); - - seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", - loops_per_jiffy / (500000 / HZ), - (loops_per_jiffy / (5000 / HZ)) % 100); - - /* dump out the processor features */ - seq_puts(m, "Features\t: "); - - for (i = 0; hwcap_str[i]; i++) - if (elf_hwcap & (1 << i)) - seq_printf(m, "%s ", hwcap_str[i]); - - seq_puts(m, "\n\n"); - - return 0; -} - -static void *c_start(struct seq_file *m, loff_t * pos) -{ - return *pos < 1 ? (void *)1 : NULL; -} - -static void *c_next(struct seq_file *m, void *v, loff_t * pos) -{ - ++*pos; - return NULL; -} - -static void c_stop(struct seq_file *m, void *v) -{ -} - -struct seq_operations cpuinfo_op = { - .start = c_start, - .next = c_next, - .stop = c_stop, - .show = c_show -}; diff --git a/arch/nds32/kernel/signal.c b/arch/nds32/kernel/signal.c deleted file mode 100644 index 7e3ca430a223..000000000000 --- a/arch/nds32/kernel/signal.c +++ /dev/null @@ -1,384 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -struct rt_sigframe { - struct siginfo info; - struct ucontext uc; -}; -#if IS_ENABLED(CONFIG_FPU) -static inline int restore_sigcontext_fpu(struct pt_regs *regs, - struct sigcontext __user *sc) -{ - struct task_struct *tsk = current; - unsigned long used_math_flag; - int ret = 0; - - clear_used_math(); - __get_user_error(used_math_flag, &sc->used_math_flag, ret); - - if (!used_math_flag) - return 0; - set_used_math(); - -#if IS_ENABLED(CONFIG_LAZY_FPU) - preempt_disable(); - if (current == last_task_used_math) { - last_task_used_math = NULL; - disable_ptreg_fpu(regs); - } - preempt_enable(); -#else - clear_fpu(regs); -#endif - - return __copy_from_user(&tsk->thread.fpu, &sc->fpu, - sizeof(struct fpu_struct)); -} - -static inline int setup_sigcontext_fpu(struct pt_regs *regs, - struct sigcontext __user *sc) -{ - struct task_struct *tsk = current; - int ret = 0; - - __put_user_error(used_math(), &sc->used_math_flag, ret); - - if (!used_math()) - return ret; - - preempt_disable(); -#if IS_ENABLED(CONFIG_LAZY_FPU) - if (last_task_used_math == tsk) - save_fpu(last_task_used_math); -#else - unlazy_fpu(tsk); -#endif - ret = __copy_to_user(&sc->fpu, &tsk->thread.fpu, - sizeof(struct fpu_struct)); - preempt_enable(); - return ret; -} -#endif - -static int restore_sigframe(struct pt_regs *regs, - struct rt_sigframe __user * sf) -{ - sigset_t set; - int err; - - err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); - if (err == 0) { - set_current_blocked(&set); - } - - __get_user_error(regs->uregs[0], &sf->uc.uc_mcontext.nds32_r0, err); - __get_user_error(regs->uregs[1], &sf->uc.uc_mcontext.nds32_r1, err); - __get_user_error(regs->uregs[2], &sf->uc.uc_mcontext.nds32_r2, err); - __get_user_error(regs->uregs[3], &sf->uc.uc_mcontext.nds32_r3, err); - __get_user_error(regs->uregs[4], &sf->uc.uc_mcontext.nds32_r4, err); - __get_user_error(regs->uregs[5], &sf->uc.uc_mcontext.nds32_r5, err); - __get_user_error(regs->uregs[6], &sf->uc.uc_mcontext.nds32_r6, err); - __get_user_error(regs->uregs[7], &sf->uc.uc_mcontext.nds32_r7, err); - __get_user_error(regs->uregs[8], &sf->uc.uc_mcontext.nds32_r8, err); - __get_user_error(regs->uregs[9], &sf->uc.uc_mcontext.nds32_r9, err); - __get_user_error(regs->uregs[10], &sf->uc.uc_mcontext.nds32_r10, err); - __get_user_error(regs->uregs[11], &sf->uc.uc_mcontext.nds32_r11, err); - __get_user_error(regs->uregs[12], &sf->uc.uc_mcontext.nds32_r12, err); - __get_user_error(regs->uregs[13], &sf->uc.uc_mcontext.nds32_r13, err); - __get_user_error(regs->uregs[14], &sf->uc.uc_mcontext.nds32_r14, err); - __get_user_error(regs->uregs[15], &sf->uc.uc_mcontext.nds32_r15, err); - __get_user_error(regs->uregs[16], &sf->uc.uc_mcontext.nds32_r16, err); - __get_user_error(regs->uregs[17], &sf->uc.uc_mcontext.nds32_r17, err); - __get_user_error(regs->uregs[18], &sf->uc.uc_mcontext.nds32_r18, err); - __get_user_error(regs->uregs[19], &sf->uc.uc_mcontext.nds32_r19, err); - __get_user_error(regs->uregs[20], &sf->uc.uc_mcontext.nds32_r20, err); - __get_user_error(regs->uregs[21], &sf->uc.uc_mcontext.nds32_r21, err); - __get_user_error(regs->uregs[22], &sf->uc.uc_mcontext.nds32_r22, err); - __get_user_error(regs->uregs[23], &sf->uc.uc_mcontext.nds32_r23, err); - __get_user_error(regs->uregs[24], &sf->uc.uc_mcontext.nds32_r24, err); - __get_user_error(regs->uregs[25], &sf->uc.uc_mcontext.nds32_r25, err); - - __get_user_error(regs->fp, &sf->uc.uc_mcontext.nds32_fp, err); - __get_user_error(regs->gp, &sf->uc.uc_mcontext.nds32_gp, err); - __get_user_error(regs->lp, &sf->uc.uc_mcontext.nds32_lp, err); - __get_user_error(regs->sp, &sf->uc.uc_mcontext.nds32_sp, err); - __get_user_error(regs->ipc, &sf->uc.uc_mcontext.nds32_ipc, err); -#if defined(CONFIG_HWZOL) - __get_user_error(regs->lc, &sf->uc.uc_mcontext.zol.nds32_lc, err); - __get_user_error(regs->le, &sf->uc.uc_mcontext.zol.nds32_le, err); - __get_user_error(regs->lb, &sf->uc.uc_mcontext.zol.nds32_lb, err); -#endif -#if IS_ENABLED(CONFIG_FPU) - err |= restore_sigcontext_fpu(regs, &sf->uc.uc_mcontext); -#endif - /* - * Avoid sys_rt_sigreturn() restarting. - */ - forget_syscall(regs); - return err; -} - -asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) -{ - struct rt_sigframe __user *frame; - - /* Always make any pending restarted system calls return -EINTR */ - current->restart_block.fn = do_no_restart_syscall; - - /* - * Since we stacked the signal on a 64-bit boundary, - * then 'sp' should be two-word aligned here. If it's - * not, then the user is trying to mess with us. - */ - if (regs->sp & 7) - goto badframe; - - frame = (struct rt_sigframe __user *)regs->sp; - - if (!access_ok(frame, sizeof(*frame))) - goto badframe; - - if (restore_sigframe(regs, frame)) - goto badframe; - - if (restore_altstack(&frame->uc.uc_stack)) - goto badframe; - - return regs->uregs[0]; - -badframe: - force_sig(SIGSEGV); - return 0; -} - -static int -setup_sigframe(struct rt_sigframe __user * sf, struct pt_regs *regs, - sigset_t * set) -{ - int err = 0; - - __put_user_error(regs->uregs[0], &sf->uc.uc_mcontext.nds32_r0, err); - __put_user_error(regs->uregs[1], &sf->uc.uc_mcontext.nds32_r1, err); - __put_user_error(regs->uregs[2], &sf->uc.uc_mcontext.nds32_r2, err); - __put_user_error(regs->uregs[3], &sf->uc.uc_mcontext.nds32_r3, err); - __put_user_error(regs->uregs[4], &sf->uc.uc_mcontext.nds32_r4, err); - __put_user_error(regs->uregs[5], &sf->uc.uc_mcontext.nds32_r5, err); - __put_user_error(regs->uregs[6], &sf->uc.uc_mcontext.nds32_r6, err); - __put_user_error(regs->uregs[7], &sf->uc.uc_mcontext.nds32_r7, err); - __put_user_error(regs->uregs[8], &sf->uc.uc_mcontext.nds32_r8, err); - __put_user_error(regs->uregs[9], &sf->uc.uc_mcontext.nds32_r9, err); - __put_user_error(regs->uregs[10], &sf->uc.uc_mcontext.nds32_r10, err); - __put_user_error(regs->uregs[11], &sf->uc.uc_mcontext.nds32_r11, err); - __put_user_error(regs->uregs[12], &sf->uc.uc_mcontext.nds32_r12, err); - __put_user_error(regs->uregs[13], &sf->uc.uc_mcontext.nds32_r13, err); - __put_user_error(regs->uregs[14], &sf->uc.uc_mcontext.nds32_r14, err); - __put_user_error(regs->uregs[15], &sf->uc.uc_mcontext.nds32_r15, err); - __put_user_error(regs->uregs[16], &sf->uc.uc_mcontext.nds32_r16, err); - __put_user_error(regs->uregs[17], &sf->uc.uc_mcontext.nds32_r17, err); - __put_user_error(regs->uregs[18], &sf->uc.uc_mcontext.nds32_r18, err); - __put_user_error(regs->uregs[19], &sf->uc.uc_mcontext.nds32_r19, err); - __put_user_error(regs->uregs[20], &sf->uc.uc_mcontext.nds32_r20, err); - - __put_user_error(regs->uregs[21], &sf->uc.uc_mcontext.nds32_r21, err); - __put_user_error(regs->uregs[22], &sf->uc.uc_mcontext.nds32_r22, err); - __put_user_error(regs->uregs[23], &sf->uc.uc_mcontext.nds32_r23, err); - __put_user_error(regs->uregs[24], &sf->uc.uc_mcontext.nds32_r24, err); - __put_user_error(regs->uregs[25], &sf->uc.uc_mcontext.nds32_r25, err); - __put_user_error(regs->fp, &sf->uc.uc_mcontext.nds32_fp, err); - __put_user_error(regs->gp, &sf->uc.uc_mcontext.nds32_gp, err); - __put_user_error(regs->lp, &sf->uc.uc_mcontext.nds32_lp, err); - __put_user_error(regs->sp, &sf->uc.uc_mcontext.nds32_sp, err); - __put_user_error(regs->ipc, &sf->uc.uc_mcontext.nds32_ipc, err); -#if defined(CONFIG_HWZOL) - __put_user_error(regs->lc, &sf->uc.uc_mcontext.zol.nds32_lc, err); - __put_user_error(regs->le, &sf->uc.uc_mcontext.zol.nds32_le, err); - __put_user_error(regs->lb, &sf->uc.uc_mcontext.zol.nds32_lb, err); -#endif -#if IS_ENABLED(CONFIG_FPU) - err |= setup_sigcontext_fpu(regs, &sf->uc.uc_mcontext); -#endif - - __put_user_error(current->thread.trap_no, &sf->uc.uc_mcontext.trap_no, - err); - __put_user_error(current->thread.error_code, - &sf->uc.uc_mcontext.error_code, err); - __put_user_error(current->thread.address, - &sf->uc.uc_mcontext.fault_address, err); - __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err); - - err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); - - return err; -} - -static inline void __user *get_sigframe(struct ksignal *ksig, - struct pt_regs *regs, int framesize) -{ - unsigned long sp; - - /* Default to using normal stack */ - sp = regs->sp; - - /* - * If we are on the alternate signal stack and would overflow it, don't. - * Return an always-bogus address instead so we will die with SIGSEGV. - */ - if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) - return (void __user __force *)(-1UL); - - /* This is the X/Open sanctioned signal stack switching. */ - sp = (sigsp(sp, ksig) - framesize); - - /* - * nds32 mandates 8-byte alignment - */ - sp &= ~0x7UL; - - return (void __user *)sp; -} - -static int -setup_return(struct pt_regs *regs, struct ksignal *ksig, void __user * frame) -{ - unsigned long handler = (unsigned long)ksig->ka.sa.sa_handler; - unsigned long retcode; - - retcode = VDSO_SYMBOL(current->mm->context.vdso, rt_sigtramp); - regs->uregs[0] = ksig->sig; - regs->sp = (unsigned long)frame; - regs->lp = retcode; - regs->ipc = handler; - - return 0; -} - -static int -setup_rt_frame(struct ksignal *ksig, sigset_t * set, struct pt_regs *regs) -{ - struct rt_sigframe __user *frame = - get_sigframe(ksig, regs, sizeof(*frame)); - int err = 0; - - if (!access_ok(frame, sizeof(*frame))) - return -EFAULT; - - __put_user_error(0, &frame->uc.uc_flags, err); - __put_user_error(NULL, &frame->uc.uc_link, err); - - err |= __save_altstack(&frame->uc.uc_stack, regs->sp); - err |= setup_sigframe(frame, regs, set); - if (err == 0) { - setup_return(regs, ksig, frame); - if (ksig->ka.sa.sa_flags & SA_SIGINFO) { - err |= copy_siginfo_to_user(&frame->info, &ksig->info); - regs->uregs[1] = (unsigned long)&frame->info; - regs->uregs[2] = (unsigned long)&frame->uc; - } - } - return err; -} - -/* - * OK, we're invoking a handler - */ -static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) -{ - int ret; - sigset_t *oldset = sigmask_to_save(); - - if (in_syscall(regs)) { - /* Avoid additional syscall restarting via ret_slow_syscall. */ - forget_syscall(regs); - - switch (regs->uregs[0]) { - case -ERESTART_RESTARTBLOCK: - case -ERESTARTNOHAND: - regs->uregs[0] = -EINTR; - break; - case -ERESTARTSYS: - if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { - regs->uregs[0] = -EINTR; - break; - } - fallthrough; - case -ERESTARTNOINTR: - regs->uregs[0] = regs->orig_r0; - regs->ipc -= 4; - break; - } - } - /* - * Set up the stack frame - */ - ret = setup_rt_frame(ksig, oldset, regs); - - signal_setup_done(ret, ksig, 0); -} - -/* - * Note that 'init' is a special process: it doesn't get signals it doesn't - * want to handle. Thus you cannot kill init even with a SIGKILL even by - * mistake. - * - * Note that we go through the signals twice: once to check the signals that - * the kernel can handle, and then we build all the user-level signal handling - * stack-frames in one go after that. - */ -static void do_signal(struct pt_regs *regs) -{ - struct ksignal ksig; - - if (get_signal(&ksig)) { - handle_signal(&ksig, regs); - return; - } - - /* - * If we were from a system call, check for system call restarting... - */ - if (in_syscall(regs)) { - /* Restart the system call - no handlers present */ - - /* Avoid additional syscall restarting via ret_slow_syscall. */ - forget_syscall(regs); - - switch (regs->uregs[0]) { - case -ERESTART_RESTARTBLOCK: - regs->uregs[15] = __NR_restart_syscall; - fallthrough; - case -ERESTARTNOHAND: - case -ERESTARTSYS: - case -ERESTARTNOINTR: - regs->uregs[0] = regs->orig_r0; - regs->ipc -= 0x4; - break; - } - } - restore_saved_sigmask(); -} - -asmlinkage void -do_notify_resume(struct pt_regs *regs, unsigned int thread_flags) -{ - if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) - do_signal(regs); - - if (thread_flags & _TIF_NOTIFY_RESUME) - tracehook_notify_resume(regs); -} diff --git a/arch/nds32/kernel/sleep.S b/arch/nds32/kernel/sleep.S deleted file mode 100644 index ca4e61f3656f..000000000000 --- a/arch/nds32/kernel/sleep.S +++ /dev/null @@ -1,131 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2017 Andes Technology Corporation */ - -#include - -.data -.global sp_tmp -sp_tmp: -.long - -.text -.globl suspend2ram -.globl cpu_resume - -suspend2ram: - pushm $r0, $r31 -#if defined(CONFIG_HWZOL) - mfusr $r0, $lc - mfusr $r1, $le - mfusr $r2, $lb -#endif - mfsr $r3, $mr0 - mfsr $r4, $mr1 - mfsr $r5, $mr4 - mfsr $r6, $mr6 - mfsr $r7, $mr7 - mfsr $r8, $mr8 - mfsr $r9, $ir0 - mfsr $r10, $ir1 - mfsr $r11, $ir2 - mfsr $r12, $ir3 - mfsr $r13, $ir9 - mfsr $r14, $ir10 - mfsr $r15, $ir12 - mfsr $r16, $ir13 - mfsr $r17, $ir14 - mfsr $r18, $ir15 - pushm $r0, $r19 -#if defined(CONFIG_FPU) - jal store_fpu_for_suspend -#endif - tlbop FlushAll - isb - - // transfer $sp from va to pa - sethi $r0, hi20(PAGE_OFFSET) - ori $r0, $r0, lo12(PAGE_OFFSET) - movi $r2, PHYS_OFFSET - sub $r1, $sp, $r0 - add $r2, $r1, $r2 - - // store pa($sp) to sp_tmp - sethi $r1, hi20(sp_tmp) - swi $r2, [$r1 + lo12(sp_tmp)] - - pushm $r16, $r25 - pushm $r29, $r30 -#ifdef CONFIG_CACHE_L2 - jal dcache_wb_all_level -#else - jal cpu_dcache_wb_all -#endif - popm $r29, $r30 - popm $r16, $r25 - - // get wake_mask and loop in standby - la $r1, wake_mask - lwi $r1, [$r1] -self_loop: - standby wake_grant - mfsr $r2, $ir15 - and $r2, $r1, $r2 - beqz $r2, self_loop - - // set ipc to resume address - la $r1, resume_addr - lwi $r1, [$r1] - mtsr $r1, $ipc - isb - - // reset psw, turn off the address translation - li $r2, 0x7000a - mtsr $r2, $ipsw - isb - - iret -cpu_resume: - // translate the address of sp_tmp variable to pa - la $r1, sp_tmp - sethi $r0, hi20(PAGE_OFFSET) - ori $r0, $r0, lo12(PAGE_OFFSET) - movi $r2, PHYS_OFFSET - sub $r1, $r1, $r0 - add $r1, $r1, $r2 - - // access the sp_tmp to get stack pointer - lwi $sp, [$r1] - - popm $r0, $r19 -#if defined(CONFIG_HWZOL) - mtusr $r0, $lb - mtusr $r1, $lc - mtusr $r2, $le -#endif - mtsr $r3, $mr0 - mtsr $r4, $mr1 - mtsr $r5, $mr4 - mtsr $r6, $mr6 - mtsr $r7, $mr7 - mtsr $r8, $mr8 - // set original psw to ipsw - mtsr $r9, $ir1 - - mtsr $r11, $ir2 - mtsr $r12, $ir3 - - // set ipc to RR - la $r13, RR - mtsr $r13, $ir9 - - mtsr $r14, $ir10 - mtsr $r15, $ir12 - mtsr $r16, $ir13 - mtsr $r17, $ir14 - mtsr $r18, $ir15 - popm $r0, $r31 - - isb - iret -RR: - ret diff --git a/arch/nds32/kernel/stacktrace.c b/arch/nds32/kernel/stacktrace.c deleted file mode 100644 index d974c0c1c65f..000000000000 --- a/arch/nds32/kernel/stacktrace.c +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include - -void save_stack_trace(struct stack_trace *trace) -{ - save_stack_trace_tsk(current, trace); -} -EXPORT_SYMBOL_GPL(save_stack_trace); - -void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) -{ - unsigned long *fpn; - int skip = trace->skip; - int savesched; - int graph_idx = 0; - - if (tsk == current) { - __asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(fpn)); - savesched = 1; - } else { - fpn = (unsigned long *)thread_saved_fp(tsk); - savesched = 0; - } - - while (!kstack_end(fpn) && !((unsigned long)fpn & 0x3) - && (fpn >= (unsigned long *)TASK_SIZE)) { - unsigned long lpp, fpp; - - lpp = fpn[LP_OFFSET]; - fpp = fpn[FP_OFFSET]; - if (!__kernel_text_address(lpp)) - break; - else - lpp = ftrace_graph_ret_addr(tsk, &graph_idx, lpp, NULL); - - if (savesched || !in_sched_functions(lpp)) { - if (skip) { - skip--; - } else { - trace->entries[trace->nr_entries++] = lpp; - if (trace->nr_entries >= trace->max_entries) - break; - } - } - fpn = (unsigned long *)fpp; - } -} -EXPORT_SYMBOL_GPL(save_stack_trace_tsk); diff --git a/arch/nds32/kernel/sys_nds32.c b/arch/nds32/kernel/sys_nds32.c deleted file mode 100644 index cb2d1e219bb3..000000000000 --- a/arch/nds32/kernel/sys_nds32.c +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include - -#include -#include -#include -#include - -SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, - unsigned long, prot, unsigned long, flags, - unsigned long, fd, unsigned long, pgoff) -{ - if (pgoff & (~PAGE_MASK >> 12)) - return -EINVAL; - - return sys_mmap_pgoff(addr, len, prot, flags, fd, - pgoff >> (PAGE_SHIFT - 12)); -} - -SYSCALL_DEFINE4(fadvise64_64_wrapper,int, fd, int, advice, loff_t, offset, - loff_t, len) -{ - return sys_fadvise64_64(fd, offset, len, advice); -} - -SYSCALL_DEFINE3(cacheflush, unsigned int, start, unsigned int, end, int, cache) -{ - struct vm_area_struct *vma; - bool flushi = true, wbd = true; - - vma = find_vma(current->mm, start); - if (!vma) - return -EFAULT; - switch (cache) { - case ICACHE: - wbd = false; - break; - case DCACHE: - flushi = false; - break; - case BCACHE: - break; - default: - return -EINVAL; - } - cpu_cache_wbinval_range_check(vma, start, end, flushi, wbd); - - return 0; -} - -SYSCALL_DEFINE2(fp_udfiex_crtl, unsigned int, cmd, unsigned int, act) -{ -#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC) - int old_udf_iex; - - if (!used_math()) { - load_fpu(&init_fpuregs); - current->thread.fpu.UDF_IEX_trap = init_fpuregs.UDF_IEX_trap; - set_used_math(); - } - - old_udf_iex = current->thread.fpu.UDF_IEX_trap; - act &= (FPCSR_mskUDFE | FPCSR_mskIEXE); - - switch (cmd) { - case DISABLE_UDF_IEX_TRAP: - current->thread.fpu.UDF_IEX_trap &= ~act; - break; - case ENABLE_UDF_IEX_TRAP: - current->thread.fpu.UDF_IEX_trap |= act; - break; - case GET_UDF_IEX_TRAP: - break; - default: - return -EINVAL; - } - return old_udf_iex; -#else - return -ENOTSUPP; -#endif -} diff --git a/arch/nds32/kernel/syscall_table.c b/arch/nds32/kernel/syscall_table.c deleted file mode 100644 index 7879c061b87f..000000000000 --- a/arch/nds32/kernel/syscall_table.c +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include - -#undef __SYSCALL -#define __SYSCALL(nr, call) [nr] = (call), - -#define sys_rt_sigreturn sys_rt_sigreturn_wrapper -#define sys_fadvise64_64 sys_fadvise64_64_wrapper -void *sys_call_table[__NR_syscalls] __aligned(8192) = { - [0 ... __NR_syscalls - 1] = sys_ni_syscall, -#include -}; diff --git a/arch/nds32/kernel/time.c b/arch/nds32/kernel/time.c deleted file mode 100644 index 574a3d0a8539..000000000000 --- a/arch/nds32/kernel/time.c +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include - -void __init time_init(void) -{ - of_clk_init(NULL); - timer_probe(); -} diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c deleted file mode 100644 index c0a8f3344fb9..000000000000 --- a/arch/nds32/kernel/traps.c +++ /dev/null @@ -1,354 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -extern void show_pte(struct mm_struct *mm, unsigned long addr); - -/* - * Dump out the contents of some memory nicely... - */ -void dump_mem(const char *lvl, unsigned long bottom, unsigned long top) -{ - unsigned long first; - int i; - - pr_emerg("%s(0x%08lx to 0x%08lx)\n", lvl, bottom, top); - - for (first = bottom & ~31; first < top; first += 32) { - unsigned long p; - char str[sizeof(" 12345678") * 8 + 1]; - - memset(str, ' ', sizeof(str)); - str[sizeof(str) - 1] = '\0'; - - for (p = first, i = 0; i < 8 && p < top; i++, p += 4) { - if (p >= bottom && p < top) { - unsigned long val; - - if (get_kernel_nofault(val, - (unsigned long *)p) == 0) - sprintf(str + i * 9, " %08lx", val); - else - sprintf(str + i * 9, " ????????"); - } - } - pr_emerg("%s%04lx:%s\n", lvl, first & 0xffff, str); - } -} - -EXPORT_SYMBOL(dump_mem); - -#define LOOP_TIMES (100) -static void __dump(struct task_struct *tsk, unsigned long *base_reg, - const char *loglvl) -{ - unsigned long ret_addr; - int cnt = LOOP_TIMES, graph = 0; - printk("%sCall Trace:\n", loglvl); - if (!IS_ENABLED(CONFIG_FRAME_POINTER)) { - while (!kstack_end(base_reg)) { - ret_addr = *base_reg++; - if (__kernel_text_address(ret_addr)) { - ret_addr = ftrace_graph_ret_addr( - tsk, &graph, ret_addr, NULL); - print_ip_sym(loglvl, ret_addr); - } - if (--cnt < 0) - break; - } - } else { - while (!kstack_end((void *)base_reg) && - !((unsigned long)base_reg & 0x3) && - ((unsigned long)base_reg >= TASK_SIZE)) { - unsigned long next_fp; - ret_addr = base_reg[LP_OFFSET]; - next_fp = base_reg[FP_OFFSET]; - if (__kernel_text_address(ret_addr)) { - - ret_addr = ftrace_graph_ret_addr( - tsk, &graph, ret_addr, NULL); - print_ip_sym(loglvl, ret_addr); - } - if (--cnt < 0) - break; - base_reg = (unsigned long *)next_fp; - } - } - printk("%s\n", loglvl); -} - -void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl) -{ - unsigned long *base_reg; - - if (!tsk) - tsk = current; - if (!IS_ENABLED(CONFIG_FRAME_POINTER)) { - if (tsk != current) - base_reg = (unsigned long *)(tsk->thread.cpu_context.sp); - else - __asm__ __volatile__("\tori\t%0, $sp, #0\n":"=r"(base_reg)); - } else { - if (tsk != current) - base_reg = (unsigned long *)(tsk->thread.cpu_context.fp); - else - __asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(base_reg)); - } - __dump(tsk, base_reg, loglvl); - barrier(); -} - -DEFINE_SPINLOCK(die_lock); - -/* - * This function is protected against re-entrancy. - */ -void __noreturn die(const char *str, struct pt_regs *regs, int err) -{ - struct task_struct *tsk = current; - static int die_counter; - - console_verbose(); - spin_lock_irq(&die_lock); - bust_spinlocks(1); - - pr_emerg("Internal error: %s: %x [#%d]\n", str, err, ++die_counter); - print_modules(); - pr_emerg("CPU: %i\n", smp_processor_id()); - show_regs(regs); - pr_emerg("Process %s (pid: %d, stack limit = 0x%p)\n", - tsk->comm, tsk->pid, end_of_stack(tsk)); - - if (!user_mode(regs) || in_interrupt()) { - dump_mem("Stack: ", regs->sp, (regs->sp + PAGE_SIZE) & PAGE_MASK); - dump_stack(); - } - - bust_spinlocks(0); - spin_unlock_irq(&die_lock); - make_task_dead(SIGSEGV); -} - -EXPORT_SYMBOL(die); - -void die_if_kernel(const char *str, struct pt_regs *regs, int err) -{ - if (user_mode(regs)) - return; - - die(str, regs, err); -} - -int bad_syscall(int n, struct pt_regs *regs) -{ - if (current->personality != PER_LINUX) { - send_sig(SIGSEGV, current, 1); - return regs->uregs[0]; - } - - force_sig_fault(SIGILL, ILL_ILLTRP, - (void __user *)instruction_pointer(regs) - 4); - die_if_kernel("Oops - bad syscall", regs, n); - return regs->uregs[0]; -} - -void __pte_error(const char *file, int line, unsigned long val) -{ - pr_emerg("%s:%d: bad pte %08lx.\n", file, line, val); -} - -void __pmd_error(const char *file, int line, unsigned long val) -{ - pr_emerg("%s:%d: bad pmd %08lx.\n", file, line, val); -} - -void __pgd_error(const char *file, int line, unsigned long val) -{ - pr_emerg("%s:%d: bad pgd %08lx.\n", file, line, val); -} - -extern char *exception_vector, *exception_vector_end; -void __init early_trap_init(void) -{ - unsigned long ivb = 0; - unsigned long base = PAGE_OFFSET; - - memcpy((unsigned long *)base, (unsigned long *)&exception_vector, - ((unsigned long)&exception_vector_end - - (unsigned long)&exception_vector)); - ivb = __nds32__mfsr(NDS32_SR_IVB); - /* Check platform support. */ - if (((ivb & IVB_mskNIVIC) >> IVB_offNIVIC) < 2) - panic - ("IVIC mode is not allowed on the platform with interrupt controller\n"); - __nds32__mtsr((ivb & ~IVB_mskESZ) | (IVB_valESZ16 << IVB_offESZ) | - IVB_BASE, NDS32_SR_IVB); - __nds32__mtsr(INT_MASK_INITAIAL_VAL, NDS32_SR_INT_MASK); - - /* - * 0x800 = 128 vectors * 16byte. - * It should be enough to flush a page. - */ - cpu_cache_wbinval_page(base, true); -} - -static void send_sigtrap(struct pt_regs *regs, int error_code, int si_code) -{ - struct task_struct *tsk = current; - - tsk->thread.trap_no = ENTRY_DEBUG_RELATED; - tsk->thread.error_code = error_code; - - force_sig_fault(SIGTRAP, si_code, - (void __user *)instruction_pointer(regs)); -} - -void do_debug_trap(unsigned long entry, unsigned long addr, - unsigned long type, struct pt_regs *regs) -{ - if (notify_die(DIE_OOPS, "Oops", regs, addr, type, SIGTRAP) - == NOTIFY_STOP) - return; - - if (user_mode(regs)) { - /* trap_signal */ - send_sigtrap(regs, 0, TRAP_BRKPT); - } else { - /* kernel_trap */ - if (!fixup_exception(regs)) - die("unexpected kernel_trap", regs, 0); - } -} - -void unhandled_interruption(struct pt_regs *regs) -{ - pr_emerg("unhandled_interruption\n"); - show_regs(regs); - if (!user_mode(regs)) - make_task_dead(SIGKILL); - force_sig(SIGKILL); -} - -void unhandled_exceptions(unsigned long entry, unsigned long addr, - unsigned long type, struct pt_regs *regs) -{ - pr_emerg("Unhandled Exception: entry: %lx addr:%lx itype:%lx\n", entry, - addr, type); - show_regs(regs); - if (!user_mode(regs)) - make_task_dead(SIGKILL); - force_sig(SIGKILL); -} - -extern int do_page_fault(unsigned long entry, unsigned long addr, - unsigned int error_code, struct pt_regs *regs); - -/* - * 2:DEF dispatch for TLB MISC exception handler -*/ - -void do_dispatch_tlb_misc(unsigned long entry, unsigned long addr, - unsigned long type, struct pt_regs *regs) -{ - type = type & (ITYPE_mskINST | ITYPE_mskETYPE); - if ((type & ITYPE_mskETYPE) < 5) { - /* Permission exceptions */ - do_page_fault(entry, addr, type, regs); - } else - unhandled_exceptions(entry, addr, type, regs); -} - -void do_revinsn(struct pt_regs *regs) -{ - pr_emerg("Reserved Instruction\n"); - show_regs(regs); - if (!user_mode(regs)) - make_task_dead(SIGILL); - force_sig(SIGILL); -} - -#ifdef CONFIG_ALIGNMENT_TRAP -extern int unalign_access_mode; -extern int do_unaligned_access(unsigned long addr, struct pt_regs *regs); -#endif -void do_dispatch_general(unsigned long entry, unsigned long addr, - unsigned long itype, struct pt_regs *regs, - unsigned long oipc) -{ - unsigned int swid = itype >> ITYPE_offSWID; - unsigned long type = itype & (ITYPE_mskINST | ITYPE_mskETYPE); - if (type == ETYPE_ALIGNMENT_CHECK) { -#ifdef CONFIG_ALIGNMENT_TRAP - /* Alignment check */ - if (user_mode(regs) && unalign_access_mode) { - int ret; - ret = do_unaligned_access(addr, regs); - - if (ret == 0) - return; - - if (ret == -EFAULT) - pr_emerg - ("Unhandled unaligned access exception\n"); - } -#endif - do_page_fault(entry, addr, type, regs); - } else if (type == ETYPE_RESERVED_INSTRUCTION) { - /* Reserved instruction */ - do_revinsn(regs); - } else if (type == ETYPE_COPROCESSOR) { - /* Coprocessor */ -#if IS_ENABLED(CONFIG_FPU) - unsigned int fucop_exist = __nds32__mfsr(NDS32_SR_FUCOP_EXIST); - unsigned int cpid = ((itype & ITYPE_mskCPID) >> ITYPE_offCPID); - - if ((cpid == FPU_CPID) && - (fucop_exist & FUCOP_EXIST_mskCP0ISFPU)) { - unsigned int subtype = (itype & ITYPE_mskSTYPE); - - if (true == do_fpu_exception(subtype, regs)) - return; - } -#endif - unhandled_exceptions(entry, addr, type, regs); - } else if (type == ETYPE_TRAP && swid == SWID_RAISE_INTERRUPT_LEVEL) { - /* trap, used on v3 EDM target debugging workaround */ - /* - * DIPC(OIPC) is passed as parameter before - * interrupt is enabled, so the DIPC will not be corrupted - * even though interrupts are coming in - */ - /* - * 1. update ipc - * 2. update pt_regs ipc with oipc - * 3. update pt_regs ipsw (clear DEX) - */ - __asm__ volatile ("mtsr %0, $IPC\n\t"::"r" (oipc)); - regs->ipc = oipc; - if (regs->pipsw & PSW_mskDEX) { - pr_emerg - ("Nested Debug exception is possibly happened\n"); - pr_emerg("ipc:%08x pipc:%08x\n", - (unsigned int)regs->ipc, - (unsigned int)regs->pipc); - } - do_debug_trap(entry, addr, itype, regs); - regs->ipsw &= ~PSW_mskDEX; - } else - unhandled_exceptions(entry, addr, type, regs); -} diff --git a/arch/nds32/kernel/vdso.c b/arch/nds32/kernel/vdso.c deleted file mode 100644 index e16009a07971..000000000000 --- a/arch/nds32/kernel/vdso.c +++ /dev/null @@ -1,231 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2012 ARM Limited -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -extern struct cache_info L1_cache_info[2]; -extern char vdso_start[], vdso_end[]; -static unsigned long vdso_pages __ro_after_init; -static unsigned long timer_mapping_base; - -struct timer_info_t timer_info = { - .cycle_count_down = true, - .mapping_base = EMPTY_TIMER_MAPPING, - .cycle_count_reg_offset = EMPTY_REG_OFFSET -}; -/* - * The vDSO data page. - */ -static struct page *no_pages[] = { NULL }; - -static union { - struct vdso_data data; - u8 page[PAGE_SIZE]; -} vdso_data_store __page_aligned_data; -struct vdso_data *vdso_data = &vdso_data_store.data; -static struct vm_special_mapping vdso_spec[2] __ro_after_init = { - { - .name = "[vvar]", - .pages = no_pages, - }, - { - .name = "[vdso]", - }, -}; - -static void get_timer_node_info(void) -{ - timer_mapping_base = timer_info.mapping_base; - vdso_data->cycle_count_offset = - timer_info.cycle_count_reg_offset; - vdso_data->cycle_count_down = - timer_info.cycle_count_down; -} - -static int __init vdso_init(void) -{ - int i; - struct page **vdso_pagelist; - - if (memcmp(vdso_start, "\177ELF", 4)) { - pr_err("vDSO is not a valid ELF object!\n"); - return -EINVAL; - } - /* Creat a timer io mapping to get clock cycles counter */ - get_timer_node_info(); - - vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT; - pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n", - vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data); - - /* Allocate the vDSO pagelist */ - vdso_pagelist = kcalloc(vdso_pages, sizeof(struct page *), GFP_KERNEL); - if (vdso_pagelist == NULL) - return -ENOMEM; - - for (i = 0; i < vdso_pages; i++) - vdso_pagelist[i] = virt_to_page(vdso_start + i * PAGE_SIZE); - vdso_spec[1].pages = &vdso_pagelist[0]; - - return 0; -} - -arch_initcall(vdso_init); - -unsigned long inline vdso_random_addr(unsigned long vdso_mapping_len) -{ - unsigned long start = current->mm->mmap_base, end, offset, addr; - start = PAGE_ALIGN(start); - - /* Round the lowest possible end address up to a PMD boundary. */ - end = (start + vdso_mapping_len + PMD_SIZE - 1) & PMD_MASK; - if (end >= TASK_SIZE) - end = TASK_SIZE; - end -= vdso_mapping_len; - - if (end > start) { - offset = get_random_int() % (((end - start) >> PAGE_SHIFT) + 1); - addr = start + (offset << PAGE_SHIFT); - } else { - addr = start; - } - return addr; -} - -int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) -{ - struct mm_struct *mm = current->mm; - unsigned long vdso_base, vdso_text_len, vdso_mapping_len; - struct vm_area_struct *vma; - unsigned long addr = 0; - pgprot_t prot; - int ret, vvar_page_num = 2; - - vdso_text_len = vdso_pages << PAGE_SHIFT; - - if(timer_mapping_base == EMPTY_VALUE) - vvar_page_num = 1; - /* Be sure to map the data page */ - vdso_mapping_len = vdso_text_len + vvar_page_num * PAGE_SIZE; -#ifdef CONFIG_CPU_CACHE_ALIASING - vdso_mapping_len += L1_cache_info[DCACHE].aliasing_num - 1; -#endif - - if (mmap_write_lock_killable(mm)) - return -EINTR; - - addr = vdso_random_addr(vdso_mapping_len); - vdso_base = get_unmapped_area(NULL, addr, vdso_mapping_len, 0, 0); - if (IS_ERR_VALUE(vdso_base)) { - ret = vdso_base; - goto up_fail; - } - -#ifdef CONFIG_CPU_CACHE_ALIASING - { - unsigned int aliasing_mask = - L1_cache_info[DCACHE].aliasing_mask; - unsigned int page_colour_ofs; - page_colour_ofs = ((unsigned int)vdso_data & aliasing_mask) - - (vdso_base & aliasing_mask); - vdso_base += page_colour_ofs & aliasing_mask; - } -#endif - - vma = _install_special_mapping(mm, vdso_base, vvar_page_num * PAGE_SIZE, - VM_READ | VM_MAYREAD, &vdso_spec[0]); - if (IS_ERR(vma)) { - ret = PTR_ERR(vma); - goto up_fail; - } - - /*Map vdata to user space */ - ret = io_remap_pfn_range(vma, vdso_base, - virt_to_phys(vdso_data) >> PAGE_SHIFT, - PAGE_SIZE, vma->vm_page_prot); - if (ret) - goto up_fail; - - /*Map timer to user space */ - vdso_base += PAGE_SIZE; - prot = __pgprot(_PAGE_V | _PAGE_M_UR_KR | _PAGE_D | _PAGE_C_DEV); - ret = io_remap_pfn_range(vma, vdso_base, timer_mapping_base >> PAGE_SHIFT, - PAGE_SIZE, prot); - if (ret) - goto up_fail; - - /*Map vdso to user space */ - vdso_base += PAGE_SIZE; - mm->context.vdso = (void *)vdso_base; - vma = _install_special_mapping(mm, vdso_base, vdso_text_len, - VM_READ | VM_EXEC | - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC, - &vdso_spec[1]); - if (IS_ERR(vma)) { - ret = PTR_ERR(vma); - goto up_fail; - } - - mmap_write_unlock(mm); - return 0; - -up_fail: - mm->context.vdso = NULL; - mmap_write_unlock(mm); - return ret; -} - -static void vdso_write_begin(struct vdso_data *vdata) -{ - ++vdso_data->seq_count; - smp_wmb(); /* Pairs with smp_rmb in vdso_read_retry */ -} - -static void vdso_write_end(struct vdso_data *vdata) -{ - smp_wmb(); /* Pairs with smp_rmb in vdso_read_begin */ - ++vdso_data->seq_count; -} - -void update_vsyscall(struct timekeeper *tk) -{ - vdso_write_begin(vdso_data); - vdso_data->cs_mask = tk->tkr_mono.mask; - vdso_data->cs_mult = tk->tkr_mono.mult; - vdso_data->cs_shift = tk->tkr_mono.shift; - vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last; - vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec; - vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec; - vdso_data->xtime_clock_sec = tk->xtime_sec; - vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec; - vdso_data->xtime_coarse_sec = tk->xtime_sec; - vdso_data->xtime_coarse_nsec = tk->tkr_mono.xtime_nsec >> - tk->tkr_mono.shift; - vdso_data->hrtimer_res = hrtimer_resolution; - vdso_write_end(vdso_data); -} - -void update_vsyscall_tz(void) -{ - vdso_data->tz_minuteswest = sys_tz.tz_minuteswest; - vdso_data->tz_dsttime = sys_tz.tz_dsttime; -} diff --git a/arch/nds32/kernel/vdso/.gitignore b/arch/nds32/kernel/vdso/.gitignore deleted file mode 100644 index 652e31d82582..000000000000 --- a/arch/nds32/kernel/vdso/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -vdso.lds diff --git a/arch/nds32/kernel/vdso/Makefile b/arch/nds32/kernel/vdso/Makefile deleted file mode 100644 index 55df25ef0057..000000000000 --- a/arch/nds32/kernel/vdso/Makefile +++ /dev/null @@ -1,79 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Building a vDSO image for AArch64. -# -# Author: Will Deacon -# Heavily based on the vDSO Makefiles for other archs. -# - -obj-vdso := note.o datapage.o sigreturn.o gettimeofday.o - -# Build rules -targets := $(obj-vdso) vdso.so vdso.so.dbg -obj-vdso := $(addprefix $(obj)/, $(obj-vdso)) - -ccflags-y := -shared -fno-common -fno-builtin -nostdlib -fPIC -Wl,-shared -g \ - -Wl,-soname=linux-vdso.so.1 -Wl,--hash-style=sysv - -# Disable gcov profiling for VDSO code -GCOV_PROFILE := n - - -obj-y += vdso.o -targets += vdso.lds -CPPFLAGS_vdso.lds += -P -C -U$(ARCH) - -# Force dependency -$(obj)/vdso.o : $(obj)/vdso.so - -# Link rule for the .so file, .lds has to be first -$(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE - $(call if_changed,vdsold) - - -# Strip rule for the .so file -$(obj)/%.so: OBJCOPYFLAGS := -S -$(obj)/%.so: $(obj)/%.so.dbg FORCE - $(call if_changed,objcopy) - -# Generate VDSO offsets using helper script -gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh -quiet_cmd_vdsosym = VDSOSYM $@ - cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ - -include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE - $(call if_changed,vdsosym) - - - -# Assembly rules for the .S files - -sigreturn.o : sigreturn.S - $(call if_changed_dep,vdsoas) - -note.o : note.S - $(call if_changed_dep,vdsoas) - -datapage.o : datapage.S - $(call if_changed_dep,vdsoas) - -gettimeofday.o : gettimeofday.c FORCE - $(call if_changed_dep,vdsocc) - -# Actual build commands -quiet_cmd_vdsold = VDSOL $@ - cmd_vdsold = $(CC) $(c_flags) -Wl,-n -Wl,-T $(real-prereqs) -o $@ -quiet_cmd_vdsoas = VDSOA $@ - cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $< -quiet_cmd_vdsocc = VDSOA $@ - cmd_vdsocc = $(CC) $(c_flags) -c -o $@ $< - -# Install commands for the unstripped file -quiet_cmd_vdso_install = INSTALL $@ - cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ - -vdso.so: $(obj)/vdso.so.dbg - @mkdir -p $(MODLIB)/vdso - $(call cmd,vdso_install) - -vdso_install: vdso.so diff --git a/arch/nds32/kernel/vdso/datapage.S b/arch/nds32/kernel/vdso/datapage.S deleted file mode 100644 index 4a62c3cab1c8..000000000000 --- a/arch/nds32/kernel/vdso/datapage.S +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include - -ENTRY(__get_timerpage) - sethi $r0, hi20(. + PAGE_SIZE + 8) - ori $r0, $r0, lo12(. + PAGE_SIZE + 4) - mfusr $r1, $pc - sub $r0, $r1, $r0 - ret -ENDPROC(__get_timerpage) - -ENTRY(__get_datapage) - sethi $r0, hi20(. + 2*PAGE_SIZE + 8) - ori $r0, $r0, lo12(. + 2*PAGE_SIZE + 4) - mfusr $r1, $pc - sub $r0, $r1, $r0 - ret -ENDPROC(__get_datapage) diff --git a/arch/nds32/kernel/vdso/gen_vdso_offsets.sh b/arch/nds32/kernel/vdso/gen_vdso_offsets.sh deleted file mode 100755 index 01924ff071ad..000000000000 --- a/arch/nds32/kernel/vdso/gen_vdso_offsets.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -# -# Match symbols in the DSO that look like VDSO_*; produce a header file -# of constant offsets into the shared object. -# -# Doing this inside the Makefile will break the $(filter-out) function, -# causing Kbuild to rebuild the vdso-offsets header file every time. -# -# Author: Will Deacon -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define X(x) #x -#define Y(x) X(x) - -extern struct vdso_data *__get_datapage(void); -extern struct vdso_data *__get_timerpage(void); - -static notrace unsigned int __vdso_read_begin(const struct vdso_data *vdata) -{ - u32 seq; -repeat: - seq = READ_ONCE(vdata->seq_count); - if (seq & 1) { - cpu_relax(); - goto repeat; - } - return seq; -} - -static notrace unsigned int vdso_read_begin(const struct vdso_data *vdata) -{ - unsigned int seq; - - seq = __vdso_read_begin(vdata); - - smp_rmb(); /* Pairs with smp_wmb in vdso_write_end */ - return seq; -} - -static notrace int vdso_read_retry(const struct vdso_data *vdata, u32 start) -{ - smp_rmb(); /* Pairs with smp_wmb in vdso_write_begin */ - return vdata->seq_count != start; -} - -static notrace long clock_gettime_fallback(clockid_t _clkid, - struct __kernel_old_timespec *_ts) -{ - register struct __kernel_old_timespec *ts asm("$r1") = _ts; - register clockid_t clkid asm("$r0") = _clkid; - register long ret asm("$r0"); - - asm volatile ("movi $r15, %3\n" - "syscall 0x0\n" - :"=r" (ret) - :"r"(clkid), "r"(ts), "i"(__NR_clock_gettime) - :"$r15", "memory"); - - return ret; -} - -static notrace int do_realtime_coarse(struct __kernel_old_timespec *ts, - struct vdso_data *vdata) -{ - u32 seq; - - do { - seq = vdso_read_begin(vdata); - - ts->tv_sec = vdata->xtime_coarse_sec; - ts->tv_nsec = vdata->xtime_coarse_nsec; - - } while (vdso_read_retry(vdata, seq)); - return 0; -} - -static notrace int do_monotonic_coarse(struct __kernel_old_timespec *ts, - struct vdso_data *vdata) -{ - u32 seq; - u64 ns; - - do { - seq = vdso_read_begin(vdata); - - ts->tv_sec = vdata->xtime_coarse_sec + vdata->wtm_clock_sec; - ns = vdata->xtime_coarse_nsec + vdata->wtm_clock_nsec; - - } while (vdso_read_retry(vdata, seq)); - - ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); - ts->tv_nsec = ns; - - return 0; -} - -static notrace inline u64 vgetsns(struct vdso_data *vdso) -{ - u32 cycle_now; - u32 cycle_delta; - u32 *timer_cycle_base; - - timer_cycle_base = - (u32 *) ((char *)__get_timerpage() + vdso->cycle_count_offset); - cycle_now = readl_relaxed(timer_cycle_base); - if (true == vdso->cycle_count_down) - cycle_now = ~(*timer_cycle_base); - cycle_delta = cycle_now - (u32) vdso->cs_cycle_last; - return ((u64) cycle_delta & vdso->cs_mask) * vdso->cs_mult; -} - -static notrace int do_realtime(struct __kernel_old_timespec *ts, struct vdso_data *vdata) -{ - unsigned count; - u64 ns; - do { - count = vdso_read_begin(vdata); - ts->tv_sec = vdata->xtime_clock_sec; - ns = vdata->xtime_clock_nsec; - ns += vgetsns(vdata); - ns >>= vdata->cs_shift; - } while (vdso_read_retry(vdata, count)); - - ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); - ts->tv_nsec = ns; - - return 0; -} - -static notrace int do_monotonic(struct __kernel_old_timespec *ts, struct vdso_data *vdata) -{ - u64 ns; - u32 seq; - - do { - seq = vdso_read_begin(vdata); - - ts->tv_sec = vdata->xtime_clock_sec; - ns = vdata->xtime_clock_nsec; - ns += vgetsns(vdata); - ns >>= vdata->cs_shift; - - ts->tv_sec += vdata->wtm_clock_sec; - ns += vdata->wtm_clock_nsec; - - } while (vdso_read_retry(vdata, seq)); - - ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); - ts->tv_nsec = ns; - - return 0; -} - -notrace int __vdso_clock_gettime(clockid_t clkid, struct __kernel_old_timespec *ts) -{ - struct vdso_data *vdata; - int ret = -1; - - vdata = __get_datapage(); - if (vdata->cycle_count_offset == EMPTY_REG_OFFSET) - return clock_gettime_fallback(clkid, ts); - - switch (clkid) { - case CLOCK_REALTIME_COARSE: - ret = do_realtime_coarse(ts, vdata); - break; - case CLOCK_MONOTONIC_COARSE: - ret = do_monotonic_coarse(ts, vdata); - break; - case CLOCK_REALTIME: - ret = do_realtime(ts, vdata); - break; - case CLOCK_MONOTONIC: - ret = do_monotonic(ts, vdata); - break; - default: - break; - } - - if (ret) - ret = clock_gettime_fallback(clkid, ts); - - return ret; -} - -static notrace int clock_getres_fallback(clockid_t _clk_id, - struct __kernel_old_timespec *_res) -{ - register clockid_t clk_id asm("$r0") = _clk_id; - register struct __kernel_old_timespec *res asm("$r1") = _res; - register int ret asm("$r0"); - - asm volatile ("movi $r15, %3\n" - "syscall 0x0\n" - :"=r" (ret) - :"r"(clk_id), "r"(res), "i"(__NR_clock_getres) - :"$r15", "memory"); - - return ret; -} - -notrace int __vdso_clock_getres(clockid_t clk_id, struct __kernel_old_timespec *res) -{ - struct vdso_data *vdata = __get_datapage(); - - if (res == NULL) - return 0; - switch (clk_id) { - case CLOCK_REALTIME: - case CLOCK_MONOTONIC: - case CLOCK_MONOTONIC_RAW: - res->tv_sec = 0; - res->tv_nsec = vdata->hrtimer_res; - break; - case CLOCK_REALTIME_COARSE: - case CLOCK_MONOTONIC_COARSE: - res->tv_sec = 0; - res->tv_nsec = CLOCK_COARSE_RES; - break; - default: - return clock_getres_fallback(clk_id, res); - } - return 0; -} - -static notrace inline int gettimeofday_fallback(struct __kernel_old_timeval *_tv, - struct timezone *_tz) -{ - register struct __kernel_old_timeval *tv asm("$r0") = _tv; - register struct timezone *tz asm("$r1") = _tz; - register int ret asm("$r0"); - - asm volatile ("movi $r15, %3\n" - "syscall 0x0\n" - :"=r" (ret) - :"r"(tv), "r"(tz), "i"(__NR_gettimeofday) - :"$r15", "memory"); - - return ret; -} - -notrace int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz) -{ - struct __kernel_old_timespec ts; - struct vdso_data *vdata; - int ret; - - vdata = __get_datapage(); - - if (vdata->cycle_count_offset == EMPTY_REG_OFFSET) - return gettimeofday_fallback(tv, tz); - - ret = do_realtime(&ts, vdata); - - if (tv) { - tv->tv_sec = ts.tv_sec; - tv->tv_usec = ts.tv_nsec / 1000; - } - if (tz) { - tz->tz_minuteswest = vdata->tz_minuteswest; - tz->tz_dsttime = vdata->tz_dsttime; - } - - return ret; -} diff --git a/arch/nds32/kernel/vdso/note.S b/arch/nds32/kernel/vdso/note.S deleted file mode 100644 index 0aeaa19b05f0..000000000000 --- a/arch/nds32/kernel/vdso/note.S +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2012 ARM Limited -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include - -ELFNOTE_START(Linux, 0, "a") - .long LINUX_VERSION_CODE -ELFNOTE_END diff --git a/arch/nds32/kernel/vdso/sigreturn.S b/arch/nds32/kernel/vdso/sigreturn.S deleted file mode 100644 index 67e4d1d1612a..000000000000 --- a/arch/nds32/kernel/vdso/sigreturn.S +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2012 ARM Limited -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include - - .text - -ENTRY(__kernel_rt_sigreturn) - .cfi_startproc - movi $r15, __NR_rt_sigreturn - /* - * The SWID of syscall should be __NR_rt_sigreturn to synchronize - * the unwinding scheme in gcc - */ - syscall __NR_rt_sigreturn - .cfi_endproc -ENDPROC(__kernel_rt_sigreturn) diff --git a/arch/nds32/kernel/vdso/vdso.S b/arch/nds32/kernel/vdso/vdso.S deleted file mode 100644 index 16737c11e55b..000000000000 --- a/arch/nds32/kernel/vdso/vdso.S +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2012 ARM Limited -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include - - .globl vdso_start, vdso_end - .section .rodata - .balign PAGE_SIZE -vdso_start: - .incbin "arch/nds32/kernel/vdso/vdso.so" - .balign PAGE_SIZE -vdso_end: - - .previous diff --git a/arch/nds32/kernel/vdso/vdso.lds.S b/arch/nds32/kernel/vdso/vdso.lds.S deleted file mode 100644 index 1f2b16004594..000000000000 --- a/arch/nds32/kernel/vdso/vdso.lds.S +++ /dev/null @@ -1,75 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0 - * Copyright (C) 2005-2017 Andes Technology Corporation - */ - - -#include -#include -#include - -OUTPUT_ARCH(nds32) - -SECTIONS -{ - . = SIZEOF_HEADERS; - - .hash : { *(.hash) } :text - .gnu.hash : { *(.gnu.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - - .note : { *(.note.*) } :text :note - - - .text : { *(.text*) } :text - - .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr - .eh_frame : { KEEP (*(.eh_frame)) } :text - - .dynamic : { *(.dynamic) } :text :dynamic - - .rodata : { *(.rodata*) } :text - - - /DISCARD/ : { - *(.note.GNU-stack) - *(.data .data.* .gnu.linkonce.d.* .sdata*) - *(.bss .sbss .dynbss .dynsbss) - } -} - -/* - * We must supply the ELF program headers explicitly to get just one - * PT_LOAD segment, and set the flags explicitly to make segments read-only. - */ -PHDRS -{ - text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ - dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ - note PT_NOTE FLAGS(4); /* PF_R */ - eh_frame_hdr PT_GNU_EH_FRAME; -} - -/* - * This controls what symbols we export from the DSO. - */ -VERSION -{ - LINUX_4 { - global: - __kernel_rt_sigreturn; - __vdso_gettimeofday; - __vdso_clock_getres; - __vdso_clock_gettime; - local: *; - }; -} - -/* - * Make the rt_sigreturn code visible to the kernel. - */ -VDSO_rt_sigtramp = __kernel_rt_sigreturn; diff --git a/arch/nds32/kernel/vmlinux.lds.S b/arch/nds32/kernel/vmlinux.lds.S deleted file mode 100644 index 6a91b965fb1e..000000000000 --- a/arch/nds32/kernel/vmlinux.lds.S +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include - -#define LOAD_OFFSET (PAGE_OFFSET - PHYS_OFFSET) -#include - -OUTPUT_ARCH(nds32) -ENTRY(_stext_lma) -jiffies = jiffies_64; - -#if defined(CONFIG_GCOV_KERNEL) -#define NDS32_EXIT_KEEP(x) x -#else -#define NDS32_EXIT_KEEP(x) -#endif - -SECTIONS -{ - _stext_lma = TEXTADDR - LOAD_OFFSET; - . = TEXTADDR; - __init_begin = .; - HEAD_TEXT_SECTION - .exit.text : { - NDS32_EXIT_KEEP(EXIT_TEXT) - } - INIT_TEXT_SECTION(PAGE_SIZE) - INIT_DATA_SECTION(16) - .exit.data : { - NDS32_EXIT_KEEP(EXIT_DATA) - } - PERCPU_SECTION(L1_CACHE_BYTES) - __init_end = .; - - . = ALIGN(PAGE_SIZE); - _stext = .; - /* Real text segment */ - .text : AT(ADDR(.text) - LOAD_OFFSET) { - _text = .; /* Text and read-only data */ - TEXT_TEXT - SCHED_TEXT - CPUIDLE_TEXT - LOCK_TEXT - KPROBES_TEXT - IRQENTRY_TEXT - SOFTIRQENTRY_TEXT - *(.fixup) - } - - _etext = .; /* End of text and rodata section */ - - _sdata = .; - RO_DATA(PAGE_SIZE) - RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) - _edata = .; - - EXCEPTION_TABLE(16) - BSS_SECTION(4, 4, 4) - _end = .; - - STABS_DEBUG - DWARF_DEBUG - ELF_DETAILS - - DISCARDS -} diff --git a/arch/nds32/lib/Makefile b/arch/nds32/lib/Makefile deleted file mode 100644 index dddbc15d6b37..000000000000 --- a/arch/nds32/lib/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -lib-y := copy_page.o memcpy.o memmove.o \ - memset.o memzero.o \ - copy_from_user.o copy_to_user.o clear_user.o diff --git a/arch/nds32/lib/clear_user.S b/arch/nds32/lib/clear_user.S deleted file mode 100644 index 805dfcd25bf8..000000000000 --- a/arch/nds32/lib/clear_user.S +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include - -/* Prototype: int __arch_clear_user(void *addr, size_t sz) - * Purpose : clear some user memory - * Params : addr - user memory address to clear - * : sz - number of bytes to clear - * Returns : number of bytes NOT cleared - */ - .text - .align 5 -ENTRY(__arch_clear_user) - add $r5, $r0, $r1 - beqz $r1, clear_exit - xor $p1, $p1, $p1 ! Use $p1=0 to clear mem - srli $p0, $r1, #2 ! $p0 = number of word to clear - andi $r1, $r1, #3 ! Bytes less than a word to copy - beqz $p0, byte_clear ! Only less than a word to clear -word_clear: -USER( smw.bim,$p1, [$r0], $p1) ! Clear the word - addi $p0, $p0, #-1 ! Decrease word count - bnez $p0, word_clear ! Continue looping to clear all words - beqz $r1, clear_exit ! No left bytes to copy -byte_clear: -USER( sbi.bi, $p1, [$r0], #1) ! Clear the byte - addi $r1, $r1, #-1 ! Decrease byte count - bnez $r1, byte_clear ! Continue looping to clear all left bytes -clear_exit: - move $r0, $r1 ! Set return value - ret - - .section .fixup,"ax" - .align 0 -9001: - sub $r0, $r5, $r0 ! Bytes left to copy - ret - .previous -ENDPROC(__arch_clear_user) diff --git a/arch/nds32/lib/copy_from_user.S b/arch/nds32/lib/copy_from_user.S deleted file mode 100644 index ad1857b20067..000000000000 --- a/arch/nds32/lib/copy_from_user.S +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include - -.macro lbi1 dst, addr, adj -USER( lbi.bi, \dst, [\addr], \adj) -.endm - -.macro sbi1 src, addr, adj -sbi.bi \src, [\addr], \adj -.endm - -.macro lmw1 start_reg, addr, end_reg -USER( lmw.bim, \start_reg, [\addr], \end_reg) -.endm - -.macro smw1 start_reg, addr, end_reg -smw.bim \start_reg, [\addr], \end_reg -.endm - - -/* Prototype: int __arch_copy_from_user(void *to, const char *from, size_t n) - * Purpose : copy a block from user memory to kernel memory - * Params : to - kernel memory - * : from - user memory - * : n - number of bytes to copy - * Returns : Number of bytes NOT copied. - */ - -.text -ENTRY(__arch_copy_from_user) - add $r5, $r0, $r2 -#include "copy_template.S" - move $r0, $r2 - ret -.section .fixup,"ax" -.align 2 -9001: - sub $r0, $r5, $r0 - ret -.previous -ENDPROC(__arch_copy_from_user) diff --git a/arch/nds32/lib/copy_page.S b/arch/nds32/lib/copy_page.S deleted file mode 100644 index f8701ed161a8..000000000000 --- a/arch/nds32/lib/copy_page.S +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include - - .text -ENTRY(copy_page) - pushm $r2, $r10 - movi $r2, PAGE_SIZE >> 5 -.Lcopy_loop: - lmw.bim $r3, [$r1], $r10 - smw.bim $r3, [$r0], $r10 - subi45 $r2, #1 - bnez38 $r2, .Lcopy_loop - popm $r2, $r10 - ret -ENDPROC(copy_page) -EXPORT_SYMBOL(copy_page) - -ENTRY(clear_page) - pushm $r1, $r9 - movi $r1, PAGE_SIZE >> 5 - movi55 $r2, #0 - movi55 $r3, #0 - movi55 $r4, #0 - movi55 $r5, #0 - movi55 $r6, #0 - movi55 $r7, #0 - movi55 $r8, #0 - movi55 $r9, #0 -.Lclear_loop: - smw.bim $r2, [$r0], $r9 - subi45 $r1, #1 - bnez38 $r1, .Lclear_loop - popm $r1, $r9 - ret -ENDPROC(clear_page) -EXPORT_SYMBOL(clear_page) diff --git a/arch/nds32/lib/copy_template.S b/arch/nds32/lib/copy_template.S deleted file mode 100644 index 3a9a2de468c2..000000000000 --- a/arch/nds32/lib/copy_template.S +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - - - beq $r1, $r0, quit_memcpy - beqz $r2, quit_memcpy - srli $r3, $r2, #5 ! check if len < cache-line size 32 - beqz $r3, word_copy_entry - andi $r4, $r0, #0x3 ! check byte-align - beqz $r4, unalign_word_copy_entry - - addi $r4, $r4,#-4 - abs $r4, $r4 ! check how many un-align byte to copy - sub $r2, $r2, $r4 ! update $R2 - -unalign_byte_copy: - lbi1 $r3, $r1, #1 - addi $r4, $r4, #-1 - sbi1 $r3, $r0, #1 - bnez $r4, unalign_byte_copy - beqz $r2, quit_memcpy - -unalign_word_copy_entry: - andi $r3, $r0, 0x1f ! check cache-line unaligncount - beqz $r3, cache_copy - - addi $r3, $r3, #-32 - abs $r3, $r3 - sub $r2, $r2, $r3 ! update $R2 - -unalign_word_copy: - lmw1 $r4, $r1, $r4 - addi $r3, $r3, #-4 - smw1 $r4, $r0, $r4 - bnez $r3, unalign_word_copy - beqz $r2, quit_memcpy - - addi $r3, $r2, #-32 ! to check $r2< cache_line , than go to word_copy - bltz $r3, word_copy_entry -cache_copy: - srli $r3, $r2, #5 - beqz $r3, word_copy_entry -3: - lmw1 $r17, $r1, $r24 - addi $r3, $r3, #-1 - smw1 $r17, $r0, $r24 - bnez $r3, 3b - -word_copy_entry: - andi $r2, $r2, #31 - - beqz $r2, quit_memcpy -5: - srli $r3, $r2, #2 - beqz $r3, byte_copy -word_copy: - lmw1 $r4, $r1, $r4 - addi $r3, $r3, #-1 - smw1 $r4, $r0, $r4 - bnez $r3, word_copy - andi $r2, $r2, #3 - beqz $r2, quit_memcpy -byte_copy: - lbi1 $r3, $r1, #1 - addi $r2, $r2, #-1 - - sbi1 $r3, $r0, #1 - bnez $r2, byte_copy -quit_memcpy: diff --git a/arch/nds32/lib/copy_to_user.S b/arch/nds32/lib/copy_to_user.S deleted file mode 100644 index 3230044dcfb8..000000000000 --- a/arch/nds32/lib/copy_to_user.S +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include - -.macro lbi1 dst, addr, adj -lbi.bi \dst, [\addr], \adj -.endm - -.macro sbi1 src, addr, adj -USER( sbi.bi, \src, [\addr], \adj) -.endm - -.macro lmw1 start_reg, addr, end_reg -lmw.bim \start_reg, [\addr], \end_reg -.endm - -.macro smw1 start_reg, addr, end_reg -USER( smw.bim, \start_reg, [\addr], \end_reg) -.endm - - -/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n) - * Purpose : copy a block to user memory from kernel memory - * Params : to - user memory - * : from - kernel memory - * : n - number of bytes to copy - * Returns : Number of bytes NOT copied. - */ - -.text -ENTRY(__arch_copy_to_user) - add $r5, $r0, $r2 -#include "copy_template.S" - move $r0, $r2 - ret -.section .fixup,"ax" -.align 2 -9001: - sub $r0, $r5, $r0 - ret -.previous -ENDPROC(__arch_copy_to_user) diff --git a/arch/nds32/lib/memcpy.S b/arch/nds32/lib/memcpy.S deleted file mode 100644 index a2345ea721e4..000000000000 --- a/arch/nds32/lib/memcpy.S +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include - - -.macro lbi1 dst, addr, adj -lbi.bi \dst, [\addr], \adj -.endm - -.macro sbi1 src, addr, adj -sbi.bi \src, [\addr], \adj -.endm - -.macro lmw1 start_reg, addr, end_reg -lmw.bim \start_reg, [\addr], \end_reg -.endm - -.macro smw1 start_reg, addr, end_reg -smw.bim \start_reg, [\addr], \end_reg -.endm - -.text -ENTRY(memcpy) - move $r5, $r0 -#include "copy_template.S" - move $r0, $r5 - ret - -ENDPROC(memcpy) diff --git a/arch/nds32/lib/memmove.S b/arch/nds32/lib/memmove.S deleted file mode 100644 index c823aada2271..000000000000 --- a/arch/nds32/lib/memmove.S +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include - -/* - void *memmove(void *dst, const void *src, int n); - - dst: $r0 - src: $r1 - n : $r2 - ret: $r0 - pointer to the memory area dst. -*/ - .text - -ENTRY(memmove) - move $r5, $r0 ! Set return value = det - beq $r0, $r1, exit_memcpy ! Exit when det = src - beqz $r2, exit_memcpy ! Exit when n = 0 - pushm $t0, $t1 ! Save reg - srli $p1, $r2, #2 ! $p1 is how many words to copy - - ! Avoid data lost when memory overlap - ! Copy data reversely when src < dst - slt $p0, $r0, $r1 ! check if $r0 < $r1 - beqz $p0, do_reverse ! branch if dst > src - - ! No reverse, dst < src - andi $r2, $r2, #3 ! How many bytes are less than a word - li $t0, #1 ! Determining copy direction in byte_cpy - beqz $p1, byte_cpy ! When n is less than a word - -word_cpy: - lmw.bim $p0, [$r1], $p0 ! Read a word from src - addi $p1, $p1, #-1 ! How many words left to copy - smw.bim $p0, [$r0], $p0 ! Copy the word to det - bnez $p1, word_cpy ! If remained words > 0 - beqz $r2, end_memcpy ! No left bytes to copy - b byte_cpy - -do_reverse: - add $r0, $r0, $r2 ! Start with the end of $r0 - add $r1, $r1, $r2 ! Start with the end of $r1 - andi $r2, $r2, #3 ! How many bytes are less than a word - li $t0, #-1 ! Determining copy direction in byte_cpy - beqz $p1, reverse_byte_cpy ! When n is less than a word - -reverse_word_cpy: - lmw.adm $p0, [$r1], $p0 ! Read a word from src - addi $p1, $p1, #-1 ! How many words left to copy - smw.adm $p0, [$r0], $p0 ! Copy the word to det - bnez $p1, reverse_word_cpy ! If remained words > 0 - beqz $r2, end_memcpy ! No left bytes to copy - -reverse_byte_cpy: - addi $r0, $r0, #-1 - addi $r1, $r1, #-1 -byte_cpy: ! Less than 4 bytes to copy now - lb.bi $p0, [$r1], $t0 ! Read a byte from src - addi $r2, $r2, #-1 ! How many bytes left to copy - sb.bi $p0, [$r0], $t0 ! copy the byte to det - bnez $r2, byte_cpy ! If remained bytes > 0 - -end_memcpy: - popm $t0, $t1 -exit_memcpy: - move $r0, $r5 - ret - -ENDPROC(memmove) diff --git a/arch/nds32/lib/memset.S b/arch/nds32/lib/memset.S deleted file mode 100644 index 193cb6ce21a9..000000000000 --- a/arch/nds32/lib/memset.S +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include - - .text -ENTRY(memset) - move $r5, $r0 ! Return value - beqz $r2, end_memset ! Exit when len = 0 - srli $p1, $r2, 2 ! $p1 is how many words to copy - andi $r2, $r2, 3 ! How many bytes are less than a word - beqz $p1, byte_set ! When n is less than a word - - ! set $r1 from ??????ab to abababab - andi $r1, $r1, #0x00ff ! $r1 = 000000ab - slli $p0, $r1, #8 ! $p0 = 0000ab00 - or $r1, $r1, $p0 ! $r1 = 0000abab - slli $p0, $r1, #16 ! $p0 = abab0000 - or $r1, $r1, $p0 ! $r1 = abababab -word_set: - addi $p1, $p1, #-1 ! How many words left to copy - smw.bim $r1, [$r0], $r1 ! Copy the word to det - bnez $p1, word_set ! Still words to set, continue looping - beqz $r2, end_memset ! No left byte to set -byte_set: ! Less than 4 bytes left to set - addi $r2, $r2, #-1 ! Decrease len by 1 - sbi.bi $r1, [$r0], #1 ! Set data of the next byte to $r1 - bnez $r2, byte_set ! Still bytes left to set -end_memset: - move $r0, $r5 - ret - -ENDPROC(memset) diff --git a/arch/nds32/lib/memzero.S b/arch/nds32/lib/memzero.S deleted file mode 100644 index f055972c9343..000000000000 --- a/arch/nds32/lib/memzero.S +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include - - .text -ENTRY(memzero) - beqz $r1, 1f - push $lp - move $r2, $r1 - move $r1, #0 - push $r0 - bal memset - pop $r0 - pop $lp -1: - ret -ENDPROC(memzero) diff --git a/arch/nds32/math-emu/Makefile b/arch/nds32/math-emu/Makefile deleted file mode 100644 index 3bed7e5d5d05..000000000000 --- a/arch/nds32/math-emu/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Makefile for the Linux/nds32 kernel FPU emulation. -# - -obj-y := fpuemu.o \ - fdivd.o fmuld.o fsubd.o faddd.o fs2d.o fsqrtd.o fcmpd.o fnegs.o \ - fd2si.o fd2ui.o fd2siz.o fd2uiz.o fsi2d.o fui2d.o \ - fdivs.o fmuls.o fsubs.o fadds.o fd2s.o fsqrts.o fcmps.o fnegd.o \ - fs2si.o fs2ui.o fs2siz.o fs2uiz.o fsi2s.o fui2s.o diff --git a/arch/nds32/math-emu/faddd.c b/arch/nds32/math-emu/faddd.c deleted file mode 100644 index f7fd4e3c3904..000000000000 --- a/arch/nds32/math-emu/faddd.c +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation -#include - -#include -#include -#include -void faddd(void *ft, void *fa, void *fb) -{ - FP_DECL_D(A); - FP_DECL_D(B); - FP_DECL_D(R); - FP_DECL_EX; - - FP_UNPACK_DP(A, fa); - FP_UNPACK_DP(B, fb); - - FP_ADD_D(R, A, B); - - FP_PACK_DP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; - -} diff --git a/arch/nds32/math-emu/fadds.c b/arch/nds32/math-emu/fadds.c deleted file mode 100644 index f5af6ca8cca5..000000000000 --- a/arch/nds32/math-emu/fadds.c +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation -#include - -#include -#include -#include -void fadds(void *ft, void *fa, void *fb) -{ - FP_DECL_S(A); - FP_DECL_S(B); - FP_DECL_S(R); - FP_DECL_EX; - - FP_UNPACK_SP(A, fa); - FP_UNPACK_SP(B, fb); - - FP_ADD_S(R, A, B); - - FP_PACK_SP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; - -} diff --git a/arch/nds32/math-emu/fcmpd.c b/arch/nds32/math-emu/fcmpd.c deleted file mode 100644 index 0ea225abe880..000000000000 --- a/arch/nds32/math-emu/fcmpd.c +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation -#include -#include -#include -int fcmpd(void *ft, void *fa, void *fb, int cmpop) -{ - FP_DECL_D(A); - FP_DECL_D(B); - FP_DECL_EX; - long cmp; - - FP_UNPACK_DP(A, fa); - FP_UNPACK_DP(B, fb); - - FP_CMP_D(cmp, A, B, SF_CUN); - cmp += 2; - if (cmp == SF_CGT) - *(long *)ft = 0; - else - *(long *)ft = (cmp & cmpop) ? 1 : 0; - - return 0; -} diff --git a/arch/nds32/math-emu/fcmps.c b/arch/nds32/math-emu/fcmps.c deleted file mode 100644 index 681480758213..000000000000 --- a/arch/nds32/math-emu/fcmps.c +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation -#include -#include -#include -int fcmps(void *ft, void *fa, void *fb, int cmpop) -{ - FP_DECL_S(A); - FP_DECL_S(B); - FP_DECL_EX; - long cmp; - - FP_UNPACK_SP(A, fa); - FP_UNPACK_SP(B, fb); - - FP_CMP_S(cmp, A, B, SF_CUN); - cmp += 2; - if (cmp == SF_CGT) - *(int *)ft = 0x0; - else - *(int *)ft = (cmp & cmpop) ? 0x1 : 0x0; - - return 0; -} diff --git a/arch/nds32/math-emu/fd2s.c b/arch/nds32/math-emu/fd2s.c deleted file mode 100644 index 1328371e8170..000000000000 --- a/arch/nds32/math-emu/fd2s.c +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation -#include - -#include -#include -#include -#include -void fd2s(void *ft, void *fa) -{ - FP_DECL_D(A); - FP_DECL_S(R); - FP_DECL_EX; - - FP_UNPACK_DP(A, fa); - - FP_CONV(S, D, 1, 2, R, A); - - FP_PACK_SP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; -} diff --git a/arch/nds32/math-emu/fd2si.c b/arch/nds32/math-emu/fd2si.c deleted file mode 100644 index fae3e16a0a10..000000000000 --- a/arch/nds32/math-emu/fd2si.c +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2019 Andes Technology Corporation -#include - -#include -#include -#include - -void fd2si(void *ft, void *fa) -{ - int r; - - FP_DECL_D(A); - FP_DECL_EX; - - FP_UNPACK_DP(A, fa); - - if (A_c == FP_CLS_INF) { - *(int *)ft = (A_s == 0) ? 0x7fffffff : 0x80000000; - __FPU_FPCSR |= FP_EX_INVALID; - } else if (A_c == FP_CLS_NAN) { - *(int *)ft = 0xffffffff; - __FPU_FPCSR |= FP_EX_INVALID; - } else { - FP_TO_INT_ROUND_D(r, A, 32, 1); - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; - *(int *)ft = r; - } - -} diff --git a/arch/nds32/math-emu/fd2siz.c b/arch/nds32/math-emu/fd2siz.c deleted file mode 100644 index 92fe6774f112..000000000000 --- a/arch/nds32/math-emu/fd2siz.c +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2019 Andes Technology Corporation -#include - -#include -#include -#include - -void fd2si_z(void *ft, void *fa) -{ - int r; - - FP_DECL_D(A); - FP_DECL_EX; - - FP_UNPACK_DP(A, fa); - - if (A_c == FP_CLS_INF) { - *(int *)ft = (A_s == 0) ? 0x7fffffff : 0x80000000; - __FPU_FPCSR |= FP_EX_INVALID; - } else if (A_c == FP_CLS_NAN) { - *(int *)ft = 0xffffffff; - __FPU_FPCSR |= FP_EX_INVALID; - } else { - FP_TO_INT_D(r, A, 32, 1); - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; - *(int *)ft = r; - } - -} diff --git a/arch/nds32/math-emu/fd2ui.c b/arch/nds32/math-emu/fd2ui.c deleted file mode 100644 index a0423b699aa4..000000000000 --- a/arch/nds32/math-emu/fd2ui.c +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2019 Andes Technology Corporation -#include - -#include -#include -#include - -void fd2ui(void *ft, void *fa) -{ - unsigned int r; - - FP_DECL_D(A); - FP_DECL_EX; - - FP_UNPACK_DP(A, fa); - - if (A_c == FP_CLS_INF) { - *(unsigned int *)ft = (A_s == 0) ? 0xffffffff : 0x00000000; - __FPU_FPCSR |= FP_EX_INVALID; - } else if (A_c == FP_CLS_NAN) { - *(unsigned int *)ft = 0xffffffff; - __FPU_FPCSR |= FP_EX_INVALID; - } else { - FP_TO_INT_ROUND_D(r, A, 32, 0); - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; - *(unsigned int *)ft = r; - } - -} diff --git a/arch/nds32/math-emu/fd2uiz.c b/arch/nds32/math-emu/fd2uiz.c deleted file mode 100644 index 8ae17cfce90d..000000000000 --- a/arch/nds32/math-emu/fd2uiz.c +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2019 Andes Technology Corporation -#include - -#include -#include -#include - -void fd2ui_z(void *ft, void *fa) -{ - unsigned int r; - - FP_DECL_D(A); - FP_DECL_EX; - - FP_UNPACK_DP(A, fa); - - if (A_c == FP_CLS_INF) { - *(unsigned int *)ft = (A_s == 0) ? 0xffffffff : 0x00000000; - __FPU_FPCSR |= FP_EX_INVALID; - } else if (A_c == FP_CLS_NAN) { - *(unsigned int *)ft = 0xffffffff; - __FPU_FPCSR |= FP_EX_INVALID; - } else { - FP_TO_INT_D(r, A, 32, 0); - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; - *(unsigned int *)ft = r; - } - -} diff --git a/arch/nds32/math-emu/fdivd.c b/arch/nds32/math-emu/fdivd.c deleted file mode 100644 index 458e7e98b08e..000000000000 --- a/arch/nds32/math-emu/fdivd.c +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation - -#include -#include -#include -#include - -void fdivd(void *ft, void *fa, void *fb) -{ - FP_DECL_D(A); - FP_DECL_D(B); - FP_DECL_D(R); - FP_DECL_EX; - - FP_UNPACK_DP(A, fa); - FP_UNPACK_DP(B, fb); - - if (B_c == FP_CLS_ZERO && A_c != FP_CLS_ZERO) - FP_SET_EXCEPTION(FP_EX_DIVZERO); - - FP_DIV_D(R, A, B); - - FP_PACK_DP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; -} diff --git a/arch/nds32/math-emu/fdivs.c b/arch/nds32/math-emu/fdivs.c deleted file mode 100644 index c7d202159ce2..000000000000 --- a/arch/nds32/math-emu/fdivs.c +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation -#include - -#include -#include -#include -void fdivs(void *ft, void *fa, void *fb) -{ - FP_DECL_S(A); - FP_DECL_S(B); - FP_DECL_S(R); - FP_DECL_EX; - - FP_UNPACK_SP(A, fa); - FP_UNPACK_SP(B, fb); - - if (B_c == FP_CLS_ZERO && A_c != FP_CLS_ZERO) - FP_SET_EXCEPTION(FP_EX_DIVZERO); - - FP_DIV_S(R, A, B); - - FP_PACK_SP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; -} diff --git a/arch/nds32/math-emu/fmuld.c b/arch/nds32/math-emu/fmuld.c deleted file mode 100644 index f3c77a45ddc2..000000000000 --- a/arch/nds32/math-emu/fmuld.c +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation -#include - -#include -#include -#include -void fmuld(void *ft, void *fa, void *fb) -{ - FP_DECL_D(A); - FP_DECL_D(B); - FP_DECL_D(R); - FP_DECL_EX; - - FP_UNPACK_DP(A, fa); - FP_UNPACK_DP(B, fb); - - FP_MUL_D(R, A, B); - - FP_PACK_DP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; -} diff --git a/arch/nds32/math-emu/fmuls.c b/arch/nds32/math-emu/fmuls.c deleted file mode 100644 index cf150df938f9..000000000000 --- a/arch/nds32/math-emu/fmuls.c +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation -#include - -#include -#include -#include -void fmuls(void *ft, void *fa, void *fb) -{ - FP_DECL_S(A); - FP_DECL_S(B); - FP_DECL_S(R); - FP_DECL_EX; - - FP_UNPACK_SP(A, fa); - FP_UNPACK_SP(B, fb); - - FP_MUL_S(R, A, B); - - FP_PACK_SP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; -} diff --git a/arch/nds32/math-emu/fnegd.c b/arch/nds32/math-emu/fnegd.c deleted file mode 100644 index de7ea6a0873e..000000000000 --- a/arch/nds32/math-emu/fnegd.c +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation -#include - -#include -#include -#include -void fnegd(void *ft, void *fa) -{ - FP_DECL_D(A); - FP_DECL_D(R); - FP_DECL_EX; - - FP_UNPACK_DP(A, fa); - - FP_NEG_D(R, A); - - FP_PACK_DP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; -} diff --git a/arch/nds32/math-emu/fnegs.c b/arch/nds32/math-emu/fnegs.c deleted file mode 100644 index 07270b326a77..000000000000 --- a/arch/nds32/math-emu/fnegs.c +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation -#include - -#include -#include -#include -void fnegs(void *ft, void *fa) -{ - FP_DECL_S(A); - FP_DECL_S(R); - FP_DECL_EX; - - FP_UNPACK_SP(A, fa); - - FP_NEG_S(R, A); - - FP_PACK_SP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; -} diff --git a/arch/nds32/math-emu/fpuemu.c b/arch/nds32/math-emu/fpuemu.c deleted file mode 100644 index 46558a15c0dc..000000000000 --- a/arch/nds32/math-emu/fpuemu.c +++ /dev/null @@ -1,406 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation - -#include -#include -#include -#include -#include - -#define DPFROMREG(dp, x) (dp = (void *)((unsigned long *)fpu_reg + 2*x)) -#ifdef __NDS32_EL__ -#define SPFROMREG(sp, x)\ - ((sp) = (void *)((unsigned long *)fpu_reg + (x^1))) -#else -#define SPFROMREG(sp, x) ((sp) = (void *)((unsigned long *)fpu_reg + x)) -#endif - -#define DEF3OP(name, p, f1, f2) \ -void fpemu_##name##p(void *ft, void *fa, void *fb) \ -{ \ - f1(fa, fa, fb); \ - f2(ft, ft, fa); \ -} - -#define DEF3OPNEG(name, p, f1, f2, f3) \ -void fpemu_##name##p(void *ft, void *fa, void *fb) \ -{ \ - f1(fa, fa, fb); \ - f2(ft, ft, fa); \ - f3(ft, ft); \ -} -DEF3OP(fmadd, s, fmuls, fadds); -DEF3OP(fmsub, s, fmuls, fsubs); -DEF3OP(fmadd, d, fmuld, faddd); -DEF3OP(fmsub, d, fmuld, fsubd); -DEF3OPNEG(fnmadd, s, fmuls, fadds, fnegs); -DEF3OPNEG(fnmsub, s, fmuls, fsubs, fnegs); -DEF3OPNEG(fnmadd, d, fmuld, faddd, fnegd); -DEF3OPNEG(fnmsub, d, fmuld, fsubd, fnegd); - -static const unsigned char cmptab[8] = { - SF_CEQ, - SF_CEQ, - SF_CLT, - SF_CLT, - SF_CLT | SF_CEQ, - SF_CLT | SF_CEQ, - SF_CUN, - SF_CUN -}; - -enum ARGTYPE { - S1S = 1, - S2S, - S1D, - CS, - D1D, - D2D, - D1S, - CD -}; -union func_t { - void (*t)(void *ft, void *fa, void *fb); - void (*b)(void *ft, void *fa); -}; -/* - * Emulate a single FPU arithmetic instruction. - */ -static int fpu_emu(struct fpu_struct *fpu_reg, unsigned long insn) -{ - int rfmt; /* resulting format */ - union func_t func; - int ftype = 0; - - switch (rfmt = NDS32Insn_OPCODE_COP0(insn)) { - case fs1_op:{ - switch (NDS32Insn_OPCODE_BIT69(insn)) { - case fadds_op: - func.t = fadds; - ftype = S2S; - break; - case fsubs_op: - func.t = fsubs; - ftype = S2S; - break; - case fmadds_op: - func.t = fpemu_fmadds; - ftype = S2S; - break; - case fmsubs_op: - func.t = fpemu_fmsubs; - ftype = S2S; - break; - case fnmadds_op: - func.t = fpemu_fnmadds; - ftype = S2S; - break; - case fnmsubs_op: - func.t = fpemu_fnmsubs; - ftype = S2S; - break; - case fmuls_op: - func.t = fmuls; - ftype = S2S; - break; - case fdivs_op: - func.t = fdivs; - ftype = S2S; - break; - case fs1_f2op_op: - switch (NDS32Insn_OPCODE_BIT1014(insn)) { - case fs2d_op: - func.b = fs2d; - ftype = S1D; - break; - case fs2si_op: - func.b = fs2si; - ftype = S1S; - break; - case fs2si_z_op: - func.b = fs2si_z; - ftype = S1S; - break; - case fs2ui_op: - func.b = fs2ui; - ftype = S1S; - break; - case fs2ui_z_op: - func.b = fs2ui_z; - ftype = S1S; - break; - case fsi2s_op: - func.b = fsi2s; - ftype = S1S; - break; - case fui2s_op: - func.b = fui2s; - ftype = S1S; - break; - case fsqrts_op: - func.b = fsqrts; - ftype = S1S; - break; - default: - return SIGILL; - } - break; - default: - return SIGILL; - } - break; - } - case fs2_op: - switch (NDS32Insn_OPCODE_BIT69(insn)) { - case fcmpeqs_op: - case fcmpeqs_e_op: - case fcmplts_op: - case fcmplts_e_op: - case fcmples_op: - case fcmples_e_op: - case fcmpuns_op: - case fcmpuns_e_op: - ftype = CS; - break; - default: - return SIGILL; - } - break; - case fd1_op:{ - switch (NDS32Insn_OPCODE_BIT69(insn)) { - case faddd_op: - func.t = faddd; - ftype = D2D; - break; - case fsubd_op: - func.t = fsubd; - ftype = D2D; - break; - case fmaddd_op: - func.t = fpemu_fmaddd; - ftype = D2D; - break; - case fmsubd_op: - func.t = fpemu_fmsubd; - ftype = D2D; - break; - case fnmaddd_op: - func.t = fpemu_fnmaddd; - ftype = D2D; - break; - case fnmsubd_op: - func.t = fpemu_fnmsubd; - ftype = D2D; - break; - case fmuld_op: - func.t = fmuld; - ftype = D2D; - break; - case fdivd_op: - func.t = fdivd; - ftype = D2D; - break; - case fd1_f2op_op: - switch (NDS32Insn_OPCODE_BIT1014(insn)) { - case fd2s_op: - func.b = fd2s; - ftype = D1S; - break; - case fd2si_op: - func.b = fd2si; - ftype = D1S; - break; - case fd2si_z_op: - func.b = fd2si_z; - ftype = D1S; - break; - case fd2ui_op: - func.b = fd2ui; - ftype = D1S; - break; - case fd2ui_z_op: - func.b = fd2ui_z; - ftype = D1S; - break; - case fsi2d_op: - func.b = fsi2d; - ftype = D1S; - break; - case fui2d_op: - func.b = fui2d; - ftype = D1S; - break; - case fsqrtd_op: - func.b = fsqrtd; - ftype = D1D; - break; - default: - return SIGILL; - } - break; - default: - return SIGILL; - - } - break; - } - - case fd2_op: - switch (NDS32Insn_OPCODE_BIT69(insn)) { - case fcmpeqd_op: - case fcmpeqd_e_op: - case fcmpltd_op: - case fcmpltd_e_op: - case fcmpled_op: - case fcmpled_e_op: - case fcmpund_op: - case fcmpund_e_op: - ftype = CD; - break; - default: - return SIGILL; - } - break; - - default: - return SIGILL; - } - - switch (ftype) { - case S1S:{ - void *ft, *fa; - - SPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn)); - SPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn)); - func.b(ft, fa); - break; - } - case S2S:{ - void *ft, *fa, *fb; - - SPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn)); - SPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn)); - SPFROMREG(fb, NDS32Insn_OPCODE_Rb(insn)); - func.t(ft, fa, fb); - break; - } - case S1D:{ - void *ft, *fa; - - DPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn)); - SPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn)); - func.b(ft, fa); - break; - } - case CS:{ - unsigned int cmpop = NDS32Insn_OPCODE_BIT69(insn); - void *ft, *fa, *fb; - - SPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn)); - SPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn)); - SPFROMREG(fb, NDS32Insn_OPCODE_Rb(insn)); - if (cmpop < 0x8) { - cmpop = cmptab[cmpop]; - fcmps(ft, fa, fb, cmpop); - } else - return SIGILL; - break; - } - case D1D:{ - void *ft, *fa; - - DPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn)); - DPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn)); - func.b(ft, fa); - break; - } - case D2D:{ - void *ft, *fa, *fb; - - DPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn)); - DPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn)); - DPFROMREG(fb, NDS32Insn_OPCODE_Rb(insn)); - func.t(ft, fa, fb); - break; - } - case D1S:{ - void *ft, *fa; - - SPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn)); - DPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn)); - func.b(ft, fa); - break; - } - case CD:{ - unsigned int cmpop = NDS32Insn_OPCODE_BIT69(insn); - void *ft, *fa, *fb; - - SPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn)); - DPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn)); - DPFROMREG(fb, NDS32Insn_OPCODE_Rb(insn)); - if (cmpop < 0x8) { - cmpop = cmptab[cmpop]; - fcmpd(ft, fa, fb, cmpop); - } else - return SIGILL; - break; - } - default: - return SIGILL; - } - - /* - * If an exception is required, generate a tidy SIGFPE exception. - */ -#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC) - if (((fpu_reg->fpcsr << 5) & fpu_reg->fpcsr & FPCSR_mskALLE_NO_UDF_IEXE) - || ((fpu_reg->fpcsr << 5) & (fpu_reg->UDF_IEX_trap))) { -#else - if ((fpu_reg->fpcsr << 5) & fpu_reg->fpcsr & FPCSR_mskALLE) { -#endif - return SIGFPE; - } - return 0; -} - -int do_fpuemu(struct pt_regs *regs, struct fpu_struct *fpu) -{ - unsigned long insn = 0, addr = regs->ipc; - unsigned long emulpc, contpc; - unsigned char *pc = (void *)&insn; - char c; - int i = 0, ret; - - for (i = 0; i < 4; i++) { - if (__get_user(c, (unsigned char *)addr++)) - return SIGBUS; - *pc++ = c; - } - - insn = be32_to_cpu(insn); - - emulpc = regs->ipc; - contpc = regs->ipc + 4; - - if (NDS32Insn_OPCODE(insn) != cop0_op) - return SIGILL; - - switch (NDS32Insn_OPCODE_COP0(insn)) { - case fs1_op: - case fs2_op: - case fd1_op: - case fd2_op: - { - /* a real fpu computation instruction */ - ret = fpu_emu(fpu, insn); - if (!ret) - regs->ipc = contpc; - } - break; - - default: - return SIGILL; - } - - return ret; -} diff --git a/arch/nds32/math-emu/fs2d.c b/arch/nds32/math-emu/fs2d.c deleted file mode 100644 index 0e8db9035631..000000000000 --- a/arch/nds32/math-emu/fs2d.c +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation - -#include -#include -#include -#include -#include - -void fs2d(void *ft, void *fa) -{ - FP_DECL_S(A); - FP_DECL_D(R); - FP_DECL_EX; - - FP_UNPACK_SP(A, fa); - - FP_CONV(D, S, 2, 1, R, A); - - FP_PACK_DP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; -} diff --git a/arch/nds32/math-emu/fs2si.c b/arch/nds32/math-emu/fs2si.c deleted file mode 100644 index b4931d60980e..000000000000 --- a/arch/nds32/math-emu/fs2si.c +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2019 Andes Technology Corporation -#include - -#include -#include -#include - -void fs2si(void *ft, void *fa) -{ - int r; - - FP_DECL_S(A); - FP_DECL_EX; - - FP_UNPACK_SP(A, fa); - - if (A_c == FP_CLS_INF) { - *(int *)ft = (A_s == 0) ? 0x7fffffff : 0x80000000; - __FPU_FPCSR |= FP_EX_INVALID; - } else if (A_c == FP_CLS_NAN) { - *(int *)ft = 0xffffffff; - __FPU_FPCSR |= FP_EX_INVALID; - } else { - FP_TO_INT_ROUND_S(r, A, 32, 1); - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; - *(int *)ft = r; - } -} diff --git a/arch/nds32/math-emu/fs2siz.c b/arch/nds32/math-emu/fs2siz.c deleted file mode 100644 index 1c2b99ce3e38..000000000000 --- a/arch/nds32/math-emu/fs2siz.c +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2019 Andes Technology Corporation -#include - -#include -#include -#include - -void fs2si_z(void *ft, void *fa) -{ - int r; - - FP_DECL_S(A); - FP_DECL_EX; - - FP_UNPACK_SP(A, fa); - - if (A_c == FP_CLS_INF) { - *(int *)ft = (A_s == 0) ? 0x7fffffff : 0x80000000; - __FPU_FPCSR |= FP_EX_INVALID; - } else if (A_c == FP_CLS_NAN) { - *(int *)ft = 0xffffffff; - __FPU_FPCSR |= FP_EX_INVALID; - } else { - FP_TO_INT_S(r, A, 32, 1); - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; - *(int *)ft = r; - } -} diff --git a/arch/nds32/math-emu/fs2ui.c b/arch/nds32/math-emu/fs2ui.c deleted file mode 100644 index c337f0384d06..000000000000 --- a/arch/nds32/math-emu/fs2ui.c +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2019 Andes Technology Corporation -#include - -#include -#include -#include - -void fs2ui(void *ft, void *fa) -{ - unsigned int r; - - FP_DECL_S(A); - FP_DECL_EX; - - FP_UNPACK_SP(A, fa); - - if (A_c == FP_CLS_INF) { - *(unsigned int *)ft = (A_s == 0) ? 0xffffffff : 0x00000000; - __FPU_FPCSR |= FP_EX_INVALID; - } else if (A_c == FP_CLS_NAN) { - *(unsigned int *)ft = 0xffffffff; - __FPU_FPCSR |= FP_EX_INVALID; - } else { - FP_TO_INT_ROUND_S(r, A, 32, 0); - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; - *(unsigned int *)ft = r; - } -} diff --git a/arch/nds32/math-emu/fs2uiz.c b/arch/nds32/math-emu/fs2uiz.c deleted file mode 100644 index 22c5e4768044..000000000000 --- a/arch/nds32/math-emu/fs2uiz.c +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2019 Andes Technology Corporation -#include - -#include -#include -#include - -void fs2ui_z(void *ft, void *fa) -{ - unsigned int r; - - FP_DECL_S(A); - FP_DECL_EX; - - FP_UNPACK_SP(A, fa); - - if (A_c == FP_CLS_INF) { - *(unsigned int *)ft = (A_s == 0) ? 0xffffffff : 0x00000000; - __FPU_FPCSR |= FP_EX_INVALID; - } else if (A_c == FP_CLS_NAN) { - *(unsigned int *)ft = 0xffffffff; - __FPU_FPCSR |= FP_EX_INVALID; - } else { - FP_TO_INT_S(r, A, 32, 0); - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; - *(unsigned int *)ft = r; - } - -} diff --git a/arch/nds32/math-emu/fsi2d.c b/arch/nds32/math-emu/fsi2d.c deleted file mode 100644 index 6b04cec0c5c5..000000000000 --- a/arch/nds32/math-emu/fsi2d.c +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2019 Andes Technology Corporation -#include - -#include -#include -#include - -void fsi2d(void *ft, void *fa) -{ - int a = *(int *)fa; - - FP_DECL_D(R); - FP_DECL_EX; - - FP_FROM_INT_D(R, a, 32, int); - - FP_PACK_DP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; - -} diff --git a/arch/nds32/math-emu/fsi2s.c b/arch/nds32/math-emu/fsi2s.c deleted file mode 100644 index 689864a5df90..000000000000 --- a/arch/nds32/math-emu/fsi2s.c +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2019 Andes Technology Corporation -#include - -#include -#include -#include - -void fsi2s(void *ft, void *fa) -{ - int a = *(int *)fa; - - FP_DECL_S(R); - FP_DECL_EX; - - FP_FROM_INT_S(R, a, 32, int); - - FP_PACK_SP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; - -} diff --git a/arch/nds32/math-emu/fsqrtd.c b/arch/nds32/math-emu/fsqrtd.c deleted file mode 100644 index c3a8dbd81d4e..000000000000 --- a/arch/nds32/math-emu/fsqrtd.c +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation - -#include -#include -#include -#include -void fsqrtd(void *ft, void *fa) -{ - FP_DECL_D(A); - FP_DECL_D(R); - FP_DECL_EX; - - FP_UNPACK_DP(A, fa); - - FP_SQRT_D(R, A); - - FP_PACK_DP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; -} diff --git a/arch/nds32/math-emu/fsqrts.c b/arch/nds32/math-emu/fsqrts.c deleted file mode 100644 index 4c6f94b27328..000000000000 --- a/arch/nds32/math-emu/fsqrts.c +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation - -#include -#include -#include -#include -void fsqrts(void *ft, void *fa) -{ - FP_DECL_S(A); - FP_DECL_S(R); - FP_DECL_EX; - - FP_UNPACK_SP(A, fa); - - FP_SQRT_S(R, A); - - FP_PACK_SP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; -} diff --git a/arch/nds32/math-emu/fsubd.c b/arch/nds32/math-emu/fsubd.c deleted file mode 100644 index 81b6a0d02a1f..000000000000 --- a/arch/nds32/math-emu/fsubd.c +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation -#include - -#include -#include -#include -void fsubd(void *ft, void *fa, void *fb) -{ - - FP_DECL_D(A); - FP_DECL_D(B); - FP_DECL_D(R); - FP_DECL_EX; - - FP_UNPACK_DP(A, fa); - FP_UNPACK_DP(B, fb); - - if (B_c != FP_CLS_NAN) - B_s ^= 1; - - FP_ADD_D(R, A, B); - - FP_PACK_DP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; -} diff --git a/arch/nds32/math-emu/fsubs.c b/arch/nds32/math-emu/fsubs.c deleted file mode 100644 index 61ddd9708465..000000000000 --- a/arch/nds32/math-emu/fsubs.c +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2018 Andes Technology Corporation -#include - -#include -#include -#include -void fsubs(void *ft, void *fa, void *fb) -{ - - FP_DECL_S(A); - FP_DECL_S(B); - FP_DECL_S(R); - FP_DECL_EX; - - FP_UNPACK_SP(A, fa); - FP_UNPACK_SP(B, fb); - - if (B_c != FP_CLS_NAN) - B_s ^= 1; - - FP_ADD_S(R, A, B); - - FP_PACK_SP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; -} diff --git a/arch/nds32/math-emu/fui2d.c b/arch/nds32/math-emu/fui2d.c deleted file mode 100644 index 9689d33a8d50..000000000000 --- a/arch/nds32/math-emu/fui2d.c +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2019 Andes Technology Corporation -#include - -#include -#include -#include - -void fui2d(void *ft, void *fa) -{ - unsigned int a = *(unsigned int *)fa; - - FP_DECL_D(R); - FP_DECL_EX; - - FP_FROM_INT_D(R, a, 32, int); - - FP_PACK_DP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; - -} diff --git a/arch/nds32/math-emu/fui2s.c b/arch/nds32/math-emu/fui2s.c deleted file mode 100644 index f70f0762547d..000000000000 --- a/arch/nds32/math-emu/fui2s.c +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2019 Andes Technology Corporation -#include - -#include -#include -#include - -void fui2s(void *ft, void *fa) -{ - unsigned int a = *(unsigned int *)fa; - - FP_DECL_S(R); - FP_DECL_EX; - - FP_FROM_INT_S(R, a, 32, int); - - FP_PACK_SP(ft, R); - - __FPU_FPCSR |= FP_CUR_EXCEPTIONS; - -} diff --git a/arch/nds32/mm/Makefile b/arch/nds32/mm/Makefile deleted file mode 100644 index 14fb2e8eb036..000000000000 --- a/arch/nds32/mm/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-y := extable.o tlb.o fault.o init.o mmap.o \ - mm-nds32.o cacheflush.o proc.o - -obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o - -ifdef CONFIG_FUNCTION_TRACER -CFLAGS_REMOVE_proc.o = $(CC_FLAGS_FTRACE) -endif -CFLAGS_proc.o += -fomit-frame-pointer diff --git a/arch/nds32/mm/alignment.c b/arch/nds32/mm/alignment.c deleted file mode 100644 index 9c2c0a454da8..000000000000 --- a/arch/nds32/mm/alignment.c +++ /dev/null @@ -1,575 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include - -#define DEBUG(enable, tagged, ...) \ - do{ \ - if (enable) { \ - if (tagged) \ - pr_warn("[ %30s() ] ", __func__); \ - pr_warn(__VA_ARGS__); \ - } \ - } while (0) - -#define RT(inst) (((inst) >> 20) & 0x1FUL) -#define RA(inst) (((inst) >> 15) & 0x1FUL) -#define RB(inst) (((inst) >> 10) & 0x1FUL) -#define SV(inst) (((inst) >> 8) & 0x3UL) -#define IMM(inst) (((inst) >> 0) & 0x7FFFUL) - -#define RA3(inst) (((inst) >> 3) & 0x7UL) -#define RT3(inst) (((inst) >> 6) & 0x7UL) -#define IMM3U(inst) (((inst) >> 0) & 0x7UL) - -#define RA5(inst) (((inst) >> 0) & 0x1FUL) -#define RT4(inst) (((inst) >> 5) & 0xFUL) - -#define GET_IMMSVAL(imm_value) \ - (((imm_value >> 14) & 0x1) ? (imm_value - 0x8000) : imm_value) - -#define __get8_data(val,addr,err) \ - __asm__( \ - "1: lbi.bi %1, [%2], #1\n" \ - "2:\n" \ - " .pushsection .text.fixup,\"ax\"\n" \ - " .align 2\n" \ - "3: movi %0, #1\n" \ - " j 2b\n" \ - " .popsection\n" \ - " .pushsection __ex_table,\"a\"\n" \ - " .align 3\n" \ - " .long 1b, 3b\n" \ - " .popsection\n" \ - : "=r" (err), "=&r" (val), "=r" (addr) \ - : "0" (err), "2" (addr)) - -#define get16_data(addr, val_ptr) \ - do { \ - unsigned int err = 0, v, a = addr; \ - __get8_data(v,a,err); \ - *val_ptr = v << 0; \ - __get8_data(v,a,err); \ - *val_ptr |= v << 8; \ - if (err) \ - goto fault; \ - *val_ptr = le16_to_cpu(*val_ptr); \ - } while(0) - -#define get32_data(addr, val_ptr) \ - do { \ - unsigned int err = 0, v, a = addr; \ - __get8_data(v,a,err); \ - *val_ptr = v << 0; \ - __get8_data(v,a,err); \ - *val_ptr |= v << 8; \ - __get8_data(v,a,err); \ - *val_ptr |= v << 16; \ - __get8_data(v,a,err); \ - *val_ptr |= v << 24; \ - if (err) \ - goto fault; \ - *val_ptr = le32_to_cpu(*val_ptr); \ - } while(0) - -#define get_data(addr, val_ptr, len) \ - if (len == 2) \ - get16_data(addr, val_ptr); \ - else \ - get32_data(addr, val_ptr); - -#define set16_data(addr, val) \ - do { \ - unsigned int err = 0, *ptr = addr ; \ - val = le32_to_cpu(val); \ - __asm__( \ - "1: sbi.bi %2, [%1], #1\n" \ - " srli %2, %2, #8\n" \ - "2: sbi %2, [%1]\n" \ - "3:\n" \ - " .pushsection .text.fixup,\"ax\"\n" \ - " .align 2\n" \ - "4: movi %0, #1\n" \ - " j 3b\n" \ - " .popsection\n" \ - " .pushsection __ex_table,\"a\"\n" \ - " .align 3\n" \ - " .long 1b, 4b\n" \ - " .long 2b, 4b\n" \ - " .popsection\n" \ - : "=r" (err), "+r" (ptr), "+r" (val) \ - : "0" (err) \ - ); \ - if (err) \ - goto fault; \ - } while(0) - -#define set32_data(addr, val) \ - do { \ - unsigned int err = 0, *ptr = addr ; \ - val = le32_to_cpu(val); \ - __asm__( \ - "1: sbi.bi %2, [%1], #1\n" \ - " srli %2, %2, #8\n" \ - "2: sbi.bi %2, [%1], #1\n" \ - " srli %2, %2, #8\n" \ - "3: sbi.bi %2, [%1], #1\n" \ - " srli %2, %2, #8\n" \ - "4: sbi %2, [%1]\n" \ - "5:\n" \ - " .pushsection .text.fixup,\"ax\"\n" \ - " .align 2\n" \ - "6: movi %0, #1\n" \ - " j 5b\n" \ - " .popsection\n" \ - " .pushsection __ex_table,\"a\"\n" \ - " .align 3\n" \ - " .long 1b, 6b\n" \ - " .long 2b, 6b\n" \ - " .long 3b, 6b\n" \ - " .long 4b, 6b\n" \ - " .popsection\n" \ - : "=r" (err), "+r" (ptr), "+r" (val) \ - : "0" (err) \ - ); \ - if (err) \ - goto fault; \ - } while(0) -#define set_data(addr, val, len) \ - if (len == 2) \ - set16_data(addr, val); \ - else \ - set32_data(addr, val); -#define NDS32_16BIT_INSTRUCTION 0x80000000 - -extern pte_t va_present(struct mm_struct *mm, unsigned long addr); -extern pte_t va_kernel_present(unsigned long addr); -extern int va_readable(struct pt_regs *regs, unsigned long addr); -extern int va_writable(struct pt_regs *regs, unsigned long addr); - -int unalign_access_mode = 0, unalign_access_debug = 0; - -static inline unsigned long *idx_to_addr(struct pt_regs *regs, int idx) -{ - /* this should be consistent with ptrace.h */ - if (idx >= 0 && idx <= 25) /* R0-R25 */ - return ®s->uregs[0] + idx; - else if (idx >= 28 && idx <= 30) /* FP, GP, LP */ - return ®s->fp + (idx - 28); - else if (idx == 31) /* SP */ - return ®s->sp; - else - return NULL; /* cause a segfault */ -} - -static inline unsigned long get_inst(unsigned long addr) -{ - return be32_to_cpu(get_unaligned((u32 *) addr)); -} - -static inline unsigned long sign_extend(unsigned long val, int len) -{ - unsigned long ret = 0; - unsigned char *s, *t; - int i = 0; - - val = cpu_to_le32(val); - - s = (void *)&val; - t = (void *)&ret; - - while (i++ < len) - *t++ = *s++; - - if (((*(t - 1)) & 0x80) && (i < 4)) { - - while (i++ <= 4) - *t++ = 0xff; - } - - return le32_to_cpu(ret); -} - -static inline int do_16(unsigned long inst, struct pt_regs *regs) -{ - int imm, regular, load, len, addr_mode, idx_mode; - unsigned long unaligned_addr, target_val, source_idx, target_idx, - shift = 0; - switch ((inst >> 9) & 0x3F) { - - case 0x12: /* LHI333 */ - imm = 1; - regular = 1; - load = 1; - len = 2; - addr_mode = 3; - idx_mode = 3; - break; - case 0x10: /* LWI333 */ - imm = 1; - regular = 1; - load = 1; - len = 4; - addr_mode = 3; - idx_mode = 3; - break; - case 0x11: /* LWI333.bi */ - imm = 1; - regular = 0; - load = 1; - len = 4; - addr_mode = 3; - idx_mode = 3; - break; - case 0x1A: /* LWI450 */ - imm = 0; - regular = 1; - load = 1; - len = 4; - addr_mode = 5; - idx_mode = 4; - break; - case 0x16: /* SHI333 */ - imm = 1; - regular = 1; - load = 0; - len = 2; - addr_mode = 3; - idx_mode = 3; - break; - case 0x14: /* SWI333 */ - imm = 1; - regular = 1; - load = 0; - len = 4; - addr_mode = 3; - idx_mode = 3; - break; - case 0x15: /* SWI333.bi */ - imm = 1; - regular = 0; - load = 0; - len = 4; - addr_mode = 3; - idx_mode = 3; - break; - case 0x1B: /* SWI450 */ - imm = 0; - regular = 1; - load = 0; - len = 4; - addr_mode = 5; - idx_mode = 4; - break; - - default: - return -EFAULT; - } - - if (addr_mode == 3) { - unaligned_addr = *idx_to_addr(regs, RA3(inst)); - source_idx = RA3(inst); - } else { - unaligned_addr = *idx_to_addr(regs, RA5(inst)); - source_idx = RA5(inst); - } - - if (idx_mode == 3) - target_idx = RT3(inst); - else - target_idx = RT4(inst); - - if (imm) - shift = IMM3U(inst) * len; - - if (regular) - unaligned_addr += shift; - - if (load) { - if (!access_ok((void *)unaligned_addr, len)) - return -EACCES; - - get_data(unaligned_addr, &target_val, len); - *idx_to_addr(regs, target_idx) = target_val; - } else { - if (!access_ok((void *)unaligned_addr, len)) - return -EACCES; - target_val = *idx_to_addr(regs, target_idx); - set_data((void *)unaligned_addr, target_val, len); - } - - if (!regular) - *idx_to_addr(regs, source_idx) = unaligned_addr + shift; - regs->ipc += 2; - - return 0; -fault: - return -EACCES; -} - -static inline int do_32(unsigned long inst, struct pt_regs *regs) -{ - int imm, regular, load, len, sign_ext; - unsigned long unaligned_addr, target_val, shift; - - unaligned_addr = *idx_to_addr(regs, RA(inst)); - - switch ((inst >> 25) << 1) { - - case 0x02: /* LHI */ - imm = 1; - regular = 1; - load = 1; - len = 2; - sign_ext = 0; - break; - case 0x0A: /* LHI.bi */ - imm = 1; - regular = 0; - load = 1; - len = 2; - sign_ext = 0; - break; - case 0x22: /* LHSI */ - imm = 1; - regular = 1; - load = 1; - len = 2; - sign_ext = 1; - break; - case 0x2A: /* LHSI.bi */ - imm = 1; - regular = 0; - load = 1; - len = 2; - sign_ext = 1; - break; - case 0x04: /* LWI */ - imm = 1; - regular = 1; - load = 1; - len = 4; - sign_ext = 0; - break; - case 0x0C: /* LWI.bi */ - imm = 1; - regular = 0; - load = 1; - len = 4; - sign_ext = 0; - break; - case 0x12: /* SHI */ - imm = 1; - regular = 1; - load = 0; - len = 2; - sign_ext = 0; - break; - case 0x1A: /* SHI.bi */ - imm = 1; - regular = 0; - load = 0; - len = 2; - sign_ext = 0; - break; - case 0x14: /* SWI */ - imm = 1; - regular = 1; - load = 0; - len = 4; - sign_ext = 0; - break; - case 0x1C: /* SWI.bi */ - imm = 1; - regular = 0; - load = 0; - len = 4; - sign_ext = 0; - break; - - default: - switch (inst & 0xff) { - - case 0x01: /* LH */ - imm = 0; - regular = 1; - load = 1; - len = 2; - sign_ext = 0; - break; - case 0x05: /* LH.bi */ - imm = 0; - regular = 0; - load = 1; - len = 2; - sign_ext = 0; - break; - case 0x11: /* LHS */ - imm = 0; - regular = 1; - load = 1; - len = 2; - sign_ext = 1; - break; - case 0x15: /* LHS.bi */ - imm = 0; - regular = 0; - load = 1; - len = 2; - sign_ext = 1; - break; - case 0x02: /* LW */ - imm = 0; - regular = 1; - load = 1; - len = 4; - sign_ext = 0; - break; - case 0x06: /* LW.bi */ - imm = 0; - regular = 0; - load = 1; - len = 4; - sign_ext = 0; - break; - case 0x09: /* SH */ - imm = 0; - regular = 1; - load = 0; - len = 2; - sign_ext = 0; - break; - case 0x0D: /* SH.bi */ - imm = 0; - regular = 0; - load = 0; - len = 2; - sign_ext = 0; - break; - case 0x0A: /* SW */ - imm = 0; - regular = 1; - load = 0; - len = 4; - sign_ext = 0; - break; - case 0x0E: /* SW.bi */ - imm = 0; - regular = 0; - load = 0; - len = 4; - sign_ext = 0; - break; - - default: - return -EFAULT; - } - } - - if (imm) - shift = GET_IMMSVAL(IMM(inst)) * len; - else - shift = *idx_to_addr(regs, RB(inst)) << SV(inst); - - if (regular) - unaligned_addr += shift; - - if (load) { - - if (!access_ok((void *)unaligned_addr, len)) - return -EACCES; - - get_data(unaligned_addr, &target_val, len); - - if (sign_ext) - *idx_to_addr(regs, RT(inst)) = - sign_extend(target_val, len); - else - *idx_to_addr(regs, RT(inst)) = target_val; - } else { - - if (!access_ok((void *)unaligned_addr, len)) - return -EACCES; - - target_val = *idx_to_addr(regs, RT(inst)); - set_data((void *)unaligned_addr, target_val, len); - } - - if (!regular) - *idx_to_addr(regs, RA(inst)) = unaligned_addr + shift; - - regs->ipc += 4; - - return 0; -fault: - return -EACCES; -} - -int do_unaligned_access(unsigned long addr, struct pt_regs *regs) -{ - unsigned long inst; - int ret = -EFAULT; - - inst = get_inst(regs->ipc); - - DEBUG((unalign_access_debug > 0), 1, - "Faulting addr: 0x%08lx, pc: 0x%08lx [inst: 0x%08lx ]\n", addr, - regs->ipc, inst); - - if (inst & NDS32_16BIT_INSTRUCTION) - ret = do_16((inst >> 16) & 0xffff, regs); - else - ret = do_32(inst, regs); - - return ret; -} - -#ifdef CONFIG_PROC_FS - -static struct ctl_table alignment_tbl[3] = { - { - .procname = "enable", - .data = &unalign_access_mode, - .maxlen = sizeof(unalign_access_mode), - .mode = 0666, - .proc_handler = &proc_dointvec - } - , - { - .procname = "debug_info", - .data = &unalign_access_debug, - .maxlen = sizeof(unalign_access_debug), - .mode = 0644, - .proc_handler = &proc_dointvec - } - , - {} -}; - -static struct ctl_table nds32_sysctl_table[2] = { - { - .procname = "unaligned_access", - .mode = 0555, - .child = alignment_tbl}, - {} -}; - -static struct ctl_path nds32_path[2] = { - {.procname = "nds32"}, - {} -}; - -/* - * Initialize nds32 alignment-correction interface - */ -static int __init nds32_sysctl_init(void) -{ - register_sysctl_paths(nds32_path, nds32_sysctl_table); - return 0; -} - -__initcall(nds32_sysctl_init); -#endif /* CONFIG_PROC_FS */ diff --git a/arch/nds32/mm/cacheflush.c b/arch/nds32/mm/cacheflush.c deleted file mode 100644 index 07aac65d1cab..000000000000 --- a/arch/nds32/mm/cacheflush.c +++ /dev/null @@ -1,338 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern struct cache_info L1_cache_info[2]; - -void flush_icache_range(unsigned long start, unsigned long end) -{ - unsigned long line_size, flags; - line_size = L1_cache_info[DCACHE].line_size; - start = start & ~(line_size - 1); - end = (end + line_size - 1) & ~(line_size - 1); - local_irq_save(flags); - cpu_cache_wbinval_range(start, end, 1); - local_irq_restore(flags); -} -EXPORT_SYMBOL(flush_icache_range); - -void flush_icache_page(struct vm_area_struct *vma, struct page *page) -{ - unsigned long flags; - unsigned long kaddr; - local_irq_save(flags); - kaddr = (unsigned long)kmap_atomic(page); - cpu_cache_wbinval_page(kaddr, vma->vm_flags & VM_EXEC); - kunmap_atomic((void *)kaddr); - local_irq_restore(flags); -} - -void flush_icache_user_page(struct vm_area_struct *vma, struct page *page, - unsigned long addr, int len) -{ - unsigned long kaddr; - kaddr = (unsigned long)kmap_atomic(page) + (addr & ~PAGE_MASK); - flush_icache_range(kaddr, kaddr + len); - kunmap_atomic((void *)kaddr); -} - -void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, - pte_t * pte) -{ - struct page *page; - unsigned long pfn = pte_pfn(*pte); - unsigned long flags; - - if (!pfn_valid(pfn)) - return; - - if (vma->vm_mm == current->active_mm) { - local_irq_save(flags); - __nds32__mtsr_dsb(addr, NDS32_SR_TLB_VPN); - __nds32__tlbop_rwr(*pte); - __nds32__isb(); - local_irq_restore(flags); - } - page = pfn_to_page(pfn); - - if ((test_and_clear_bit(PG_dcache_dirty, &page->flags)) || - (vma->vm_flags & VM_EXEC)) { - unsigned long kaddr; - local_irq_save(flags); - kaddr = (unsigned long)kmap_atomic(page); - cpu_cache_wbinval_page(kaddr, vma->vm_flags & VM_EXEC); - kunmap_atomic((void *)kaddr); - local_irq_restore(flags); - } -} -#ifdef CONFIG_CPU_CACHE_ALIASING -extern pte_t va_present(struct mm_struct *mm, unsigned long addr); - -static inline unsigned long aliasing(unsigned long addr, unsigned long page) -{ - return ((addr & PAGE_MASK) ^ page) & (SHMLBA - 1); -} - -static inline unsigned long kremap0(unsigned long uaddr, unsigned long pa) -{ - unsigned long kaddr, pte; - -#define BASE_ADDR0 0xffffc000 - kaddr = BASE_ADDR0 | (uaddr & L1_cache_info[DCACHE].aliasing_mask); - pte = (pa | PAGE_KERNEL); - __nds32__mtsr_dsb(kaddr, NDS32_SR_TLB_VPN); - __nds32__tlbop_rwlk(pte); - __nds32__isb(); - return kaddr; -} - -static inline void kunmap01(unsigned long kaddr) -{ - __nds32__tlbop_unlk(kaddr); - __nds32__tlbop_inv(kaddr); - __nds32__isb(); -} - -static inline unsigned long kremap1(unsigned long uaddr, unsigned long pa) -{ - unsigned long kaddr, pte; - -#define BASE_ADDR1 0xffff8000 - kaddr = BASE_ADDR1 | (uaddr & L1_cache_info[DCACHE].aliasing_mask); - pte = (pa | PAGE_KERNEL); - __nds32__mtsr_dsb(kaddr, NDS32_SR_TLB_VPN); - __nds32__tlbop_rwlk(pte); - __nds32__isb(); - return kaddr; -} - -void flush_cache_mm(struct mm_struct *mm) -{ - unsigned long flags; - - local_irq_save(flags); - cpu_dcache_wbinval_all(); - cpu_icache_inval_all(); - local_irq_restore(flags); -} - -void flush_cache_dup_mm(struct mm_struct *mm) -{ -} - -void flush_cache_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ - unsigned long flags; - - if ((end - start) > 8 * PAGE_SIZE) { - cpu_dcache_wbinval_all(); - if (vma->vm_flags & VM_EXEC) - cpu_icache_inval_all(); - return; - } - local_irq_save(flags); - while (start < end) { - if (va_present(vma->vm_mm, start)) - cpu_cache_wbinval_page(start, vma->vm_flags & VM_EXEC); - start += PAGE_SIZE; - } - local_irq_restore(flags); - return; -} - -void flush_cache_page(struct vm_area_struct *vma, - unsigned long addr, unsigned long pfn) -{ - unsigned long vto, flags; - - local_irq_save(flags); - vto = kremap0(addr, pfn << PAGE_SHIFT); - cpu_cache_wbinval_page(vto, vma->vm_flags & VM_EXEC); - kunmap01(vto); - local_irq_restore(flags); -} - -void flush_cache_vmap(unsigned long start, unsigned long end) -{ - cpu_dcache_wbinval_all(); - cpu_icache_inval_all(); -} - -void flush_cache_vunmap(unsigned long start, unsigned long end) -{ - cpu_dcache_wbinval_all(); - cpu_icache_inval_all(); -} - -void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, - struct page *to) -{ - cpu_dcache_wbinval_page((unsigned long)vaddr); - cpu_icache_inval_page((unsigned long)vaddr); - copy_page(vto, vfrom); - cpu_dcache_wbinval_page((unsigned long)vto); - cpu_icache_inval_page((unsigned long)vto); -} - -void clear_user_page(void *addr, unsigned long vaddr, struct page *page) -{ - cpu_dcache_wbinval_page((unsigned long)vaddr); - cpu_icache_inval_page((unsigned long)vaddr); - clear_page(addr); - cpu_dcache_wbinval_page((unsigned long)addr); - cpu_icache_inval_page((unsigned long)addr); -} - -void copy_user_highpage(struct page *to, struct page *from, - unsigned long vaddr, struct vm_area_struct *vma) -{ - unsigned long vto, vfrom, flags, kto, kfrom, pfrom, pto; - kto = ((unsigned long)page_address(to) & PAGE_MASK); - kfrom = ((unsigned long)page_address(from) & PAGE_MASK); - pto = page_to_phys(to); - pfrom = page_to_phys(from); - - local_irq_save(flags); - if (aliasing(vaddr, (unsigned long)kfrom)) - cpu_dcache_wb_page((unsigned long)kfrom); - vto = kremap0(vaddr, pto); - vfrom = kremap1(vaddr, pfrom); - copy_page((void *)vto, (void *)vfrom); - kunmap01(vfrom); - kunmap01(vto); - local_irq_restore(flags); -} - -EXPORT_SYMBOL(copy_user_highpage); - -void clear_user_highpage(struct page *page, unsigned long vaddr) -{ - unsigned long vto, flags, kto; - - kto = ((unsigned long)page_address(page) & PAGE_MASK); - - local_irq_save(flags); - if (aliasing(kto, vaddr) && kto != 0) { - cpu_dcache_inval_page(kto); - cpu_icache_inval_page(kto); - } - vto = kremap0(vaddr, page_to_phys(page)); - clear_page((void *)vto); - kunmap01(vto); - local_irq_restore(flags); -} - -EXPORT_SYMBOL(clear_user_highpage); - -void flush_dcache_page(struct page *page) -{ - struct address_space *mapping; - - mapping = page_mapping_file(page); - if (mapping && !mapping_mapped(mapping)) - set_bit(PG_dcache_dirty, &page->flags); - else { - unsigned long kaddr, flags; - - kaddr = (unsigned long)page_address(page); - local_irq_save(flags); - cpu_dcache_wbinval_page(kaddr); - if (mapping) { - unsigned long vaddr, kto; - - vaddr = page->index << PAGE_SHIFT; - if (aliasing(vaddr, kaddr)) { - kto = kremap0(vaddr, page_to_phys(page)); - cpu_dcache_wbinval_page(kto); - kunmap01(kto); - } - } - local_irq_restore(flags); - } -} -EXPORT_SYMBOL(flush_dcache_page); - -void copy_to_user_page(struct vm_area_struct *vma, struct page *page, - unsigned long vaddr, void *dst, void *src, int len) -{ - unsigned long line_size, start, end, vto, flags; - - local_irq_save(flags); - vto = kremap0(vaddr, page_to_phys(page)); - dst = (void *)(vto | (vaddr & (PAGE_SIZE - 1))); - memcpy(dst, src, len); - if (vma->vm_flags & VM_EXEC) { - line_size = L1_cache_info[DCACHE].line_size; - start = (unsigned long)dst & ~(line_size - 1); - end = - ((unsigned long)dst + len + line_size - 1) & ~(line_size - - 1); - cpu_cache_wbinval_range(start, end, 1); - } - kunmap01(vto); - local_irq_restore(flags); -} - -void copy_from_user_page(struct vm_area_struct *vma, struct page *page, - unsigned long vaddr, void *dst, void *src, int len) -{ - unsigned long vto, flags; - - local_irq_save(flags); - vto = kremap0(vaddr, page_to_phys(page)); - src = (void *)(vto | (vaddr & (PAGE_SIZE - 1))); - memcpy(dst, src, len); - kunmap01(vto); - local_irq_restore(flags); -} - -void flush_anon_page(struct vm_area_struct *vma, - struct page *page, unsigned long vaddr) -{ - unsigned long kaddr, flags, ktmp; - if (!PageAnon(page)) - return; - - if (vma->vm_mm != current->active_mm) - return; - - local_irq_save(flags); - if (vma->vm_flags & VM_EXEC) - cpu_icache_inval_page(vaddr & PAGE_MASK); - kaddr = (unsigned long)page_address(page); - if (aliasing(vaddr, kaddr)) { - ktmp = kremap0(vaddr, page_to_phys(page)); - cpu_dcache_wbinval_page(ktmp); - kunmap01(ktmp); - } - local_irq_restore(flags); -} - -void flush_kernel_vmap_range(void *addr, int size) -{ - unsigned long flags; - local_irq_save(flags); - cpu_dcache_wb_range((unsigned long)addr, (unsigned long)addr + size); - local_irq_restore(flags); -} -EXPORT_SYMBOL(flush_kernel_vmap_range); - -void invalidate_kernel_vmap_range(void *addr, int size) -{ - unsigned long flags; - local_irq_save(flags); - cpu_dcache_inval_range((unsigned long)addr, (unsigned long)addr + size); - local_irq_restore(flags); -} -EXPORT_SYMBOL(invalidate_kernel_vmap_range); -#endif diff --git a/arch/nds32/mm/extable.c b/arch/nds32/mm/extable.c deleted file mode 100644 index db7f0a7c8966..000000000000 --- a/arch/nds32/mm/extable.c +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include - -int fixup_exception(struct pt_regs *regs) -{ - const struct exception_table_entry *fixup; - - fixup = search_exception_tables(instruction_pointer(regs)); - if (fixup) - regs->ipc = fixup->fixup; - - return fixup != NULL; -} diff --git a/arch/nds32/mm/fault.c b/arch/nds32/mm/fault.c deleted file mode 100644 index 636977a1c8b9..000000000000 --- a/arch/nds32/mm/fault.c +++ /dev/null @@ -1,396 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -extern void __noreturn die(const char *str, struct pt_regs *regs, long err); - -/* - * This is useful to dump out the page tables associated with - * 'addr' in mm 'mm'. - */ -void show_pte(struct mm_struct *mm, unsigned long addr) -{ - pgd_t *pgd; - if (!mm) - mm = &init_mm; - - pr_alert("pgd = %p\n", mm->pgd); - pgd = pgd_offset(mm, addr); - pr_alert("[%08lx] *pgd=%08lx", addr, pgd_val(*pgd)); - - do { - p4d_t *p4d; - pud_t *pud; - pmd_t *pmd; - - if (pgd_none(*pgd)) - break; - - if (pgd_bad(*pgd)) { - pr_alert("(bad)"); - break; - } - - p4d = p4d_offset(pgd, addr); - pud = pud_offset(p4d, addr); - pmd = pmd_offset(pud, addr); -#if PTRS_PER_PMD != 1 - pr_alert(", *pmd=%08lx", pmd_val(*pmd)); -#endif - - if (pmd_none(*pmd)) - break; - - if (pmd_bad(*pmd)) { - pr_alert("(bad)"); - break; - } - - if (IS_ENABLED(CONFIG_HIGHMEM)) - { - pte_t *pte; - /* We must not map this if we have highmem enabled */ - pte = pte_offset_map(pmd, addr); - pr_alert(", *pte=%08lx", pte_val(*pte)); - pte_unmap(pte); - } - } while (0); - - pr_alert("\n"); -} - -void do_page_fault(unsigned long entry, unsigned long addr, - unsigned int error_code, struct pt_regs *regs) -{ - struct task_struct *tsk; - struct mm_struct *mm; - struct vm_area_struct *vma; - int si_code; - vm_fault_t fault; - unsigned int mask = VM_ACCESS_FLAGS; - unsigned int flags = FAULT_FLAG_DEFAULT; - - error_code = error_code & (ITYPE_mskINST | ITYPE_mskETYPE); - tsk = current; - mm = tsk->mm; - si_code = SEGV_MAPERR; - /* - * We fault-in kernel-space virtual memory on-demand. The - * 'reference' page table is init_mm.pgd. - * - * NOTE! We MUST NOT take any locks for this case. We may - * be in an interrupt or a critical region, and should - * only copy the information from the master page table, - * nothing more. - */ - if (addr >= TASK_SIZE) { - if (user_mode(regs)) - goto bad_area_nosemaphore; - - if (addr >= TASK_SIZE && addr < VMALLOC_END - && (entry == ENTRY_PTE_NOT_PRESENT)) - goto vmalloc_fault; - else - goto no_context; - } - - /* Send a signal to the task for handling the unalignment access. */ - if (entry == ENTRY_GENERAL_EXCPETION - && error_code == ETYPE_ALIGNMENT_CHECK) { - if (user_mode(regs)) - goto bad_area_nosemaphore; - else - goto no_context; - } - - /* - * If we're in an interrupt or have no user - * context, we must not take the fault.. - */ - if (unlikely(faulthandler_disabled() || !mm)) - goto no_context; - - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr); - - /* - * As per x86, we may deadlock here. However, since the kernel only - * validly references user space from well defined areas of the code, - * we can bug out early if this is from code which shouldn't. - */ - if (unlikely(!mmap_read_trylock(mm))) { - if (!user_mode(regs) && - !search_exception_tables(instruction_pointer(regs))) - goto no_context; -retry: - mmap_read_lock(mm); - } else { - /* - * The above down_read_trylock() might have succeeded in which - * case, we'll have missed the might_sleep() from down_read(). - */ - might_sleep(); - if (IS_ENABLED(CONFIG_DEBUG_VM)) { - if (!user_mode(regs) && - !search_exception_tables(instruction_pointer(regs))) - goto no_context; - } - } - - vma = find_vma(mm, addr); - - if (unlikely(!vma)) - goto bad_area; - - if (vma->vm_start <= addr) - goto good_area; - - if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) - goto bad_area; - - if (unlikely(expand_stack(vma, addr))) - goto bad_area; - - /* - * Ok, we have a good vm_area for this memory access, so - * we can handle it.. - */ - -good_area: - si_code = SEGV_ACCERR; - - /* first do some preliminary protection checks */ - if (entry == ENTRY_PTE_NOT_PRESENT) { - if (error_code & ITYPE_mskINST) - mask = VM_EXEC; - else { - mask = VM_READ | VM_WRITE; - } - } else if (entry == ENTRY_TLB_MISC) { - switch (error_code & ITYPE_mskETYPE) { - case RD_PROT: - mask = VM_READ; - break; - case WRT_PROT: - mask = VM_WRITE; - flags |= FAULT_FLAG_WRITE; - break; - case NOEXEC: - mask = VM_EXEC; - break; - case PAGE_MODIFY: - mask = VM_WRITE; - flags |= FAULT_FLAG_WRITE; - break; - case ACC_BIT: - BUG(); - default: - break; - } - - } - if (!(vma->vm_flags & mask)) - goto bad_area; - - /* - * If for any reason at all we couldn't handle the fault, - * make sure we exit gracefully rather than endlessly redo - * the fault. - */ - - fault = handle_mm_fault(vma, addr, flags, regs); - - /* - * If we need to retry but a fatal signal is pending, handle the - * signal first. We do not need to release the mmap_lock because it - * would already be released in __lock_page_or_retry in mm/filemap.c. - */ - if (fault_signal_pending(fault, regs)) { - if (!user_mode(regs)) - goto no_context; - return; - } - - if (unlikely(fault & VM_FAULT_ERROR)) { - if (fault & VM_FAULT_OOM) - goto out_of_memory; - else if (fault & VM_FAULT_SIGBUS) - goto do_sigbus; - else - goto bad_area; - } - - if (fault & VM_FAULT_RETRY) { - flags |= FAULT_FLAG_TRIED; - - /* No need to mmap_read_unlock(mm) as we would - * have already released it in __lock_page_or_retry - * in mm/filemap.c. - */ - goto retry; - } - - mmap_read_unlock(mm); - return; - - /* - * Something tried to access memory that isn't in our memory map.. - * Fix it, but check if it's kernel or user first.. - */ -bad_area: - mmap_read_unlock(mm); - -bad_area_nosemaphore: - - /* User mode accesses just cause a SIGSEGV */ - - if (user_mode(regs)) { - tsk->thread.address = addr; - tsk->thread.error_code = error_code; - tsk->thread.trap_no = entry; - force_sig_fault(SIGSEGV, si_code, (void __user *)addr); - return; - } - -no_context: - - /* Are we prepared to handle this kernel fault? - * - * (The kernel has valid exception-points in the source - * when it acesses user-memory. When it fails in one - * of those points, we find it in a table and do a jump - * to some fixup code that loads an appropriate error - * code) - */ - - { - const struct exception_table_entry *entry; - - if ((entry = - search_exception_tables(instruction_pointer(regs))) != - NULL) { - /* Adjust the instruction pointer in the stackframe */ - instruction_pointer(regs) = entry->fixup; - return; - } - } - - /* - * Oops. The kernel tried to access some bad page. We'll have to - * terminate things with extreme prejudice. - */ - - bust_spinlocks(1); - pr_alert("Unable to handle kernel %s at virtual address %08lx\n", - (addr < PAGE_SIZE) ? "NULL pointer dereference" : - "paging request", addr); - - show_pte(mm, addr); - die("Oops", regs, error_code); - - /* - * We ran out of memory, or some other thing happened to us that made - * us unable to handle the page fault gracefully. - */ - -out_of_memory: - mmap_read_unlock(mm); - if (!user_mode(regs)) - goto no_context; - pagefault_out_of_memory(); - return; - -do_sigbus: - mmap_read_unlock(mm); - - /* Kernel mode? Handle exceptions or die */ - if (!user_mode(regs)) - goto no_context; - - /* - * Send a sigbus - */ - tsk->thread.address = addr; - tsk->thread.error_code = error_code; - tsk->thread.trap_no = entry; - force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)addr); - - return; - -vmalloc_fault: - { - /* - * Synchronize this task's top level page-table - * with the 'reference' page table. - * - * Use current_pgd instead of tsk->active_mm->pgd - * since the latter might be unavailable if this - * code is executed in a misfortunately run irq - * (like inside schedule() between switch_mm and - * switch_to...). - */ - - unsigned int index = pgd_index(addr); - pgd_t *pgd, *pgd_k; - p4d_t *p4d, *p4d_k; - pud_t *pud, *pud_k; - pmd_t *pmd, *pmd_k; - pte_t *pte_k; - - pgd = (pgd_t *) __va(__nds32__mfsr(NDS32_SR_L1_PPTB)) + index; - pgd_k = init_mm.pgd + index; - - if (!pgd_present(*pgd_k)) - goto no_context; - - p4d = p4d_offset(pgd, addr); - p4d_k = p4d_offset(pgd_k, addr); - if (!p4d_present(*p4d_k)) - goto no_context; - - pud = pud_offset(p4d, addr); - pud_k = pud_offset(p4d_k, addr); - if (!pud_present(*pud_k)) - goto no_context; - - pmd = pmd_offset(pud, addr); - pmd_k = pmd_offset(pud_k, addr); - if (!pmd_present(*pmd_k)) - goto no_context; - - if (!pmd_present(*pmd)) - set_pmd(pmd, *pmd_k); - else - BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k)); - - /* - * Since the vmalloc area is global, we don't - * need to copy individual PTE's, it is enough to - * copy the pgd pointer into the pte page of the - * root task. If that is there, we'll find our pte if - * it exists. - */ - - /* Make sure the actual PTE exists as well to - * catch kernel vmalloc-area accesses to non-mapped - * addres. If we don't do this, this will just - * silently loop forever. - */ - - pte_k = pte_offset_kernel(pmd_k, addr); - if (!pte_present(*pte_k)) - goto no_context; - - return; - } -} diff --git a/arch/nds32/mm/init.c b/arch/nds32/mm/init.c deleted file mode 100644 index f63f839738c4..000000000000 --- a/arch/nds32/mm/init.c +++ /dev/null @@ -1,263 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 1995-2005 Russell King -// Copyright (C) 2012 ARM Ltd. -// Copyright (C) 2013-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); -DEFINE_SPINLOCK(anon_alias_lock); -extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; - -/* - * empty_zero_page is a special page that is used for - * zero-initialized data and COW. - */ -struct page *empty_zero_page; -EXPORT_SYMBOL(empty_zero_page); - -static void __init zone_sizes_init(void) -{ - unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 }; - - max_zone_pfn[ZONE_NORMAL] = max_low_pfn; -#ifdef CONFIG_HIGHMEM - max_zone_pfn[ZONE_HIGHMEM] = max_pfn; -#endif - free_area_init(max_zone_pfn); - -} - -/* - * Map all physical memory under high_memory into kernel's address space. - * - * This is explicitly coded for two-level page tables, so if you need - * something else then this needs to change. - */ -static void __init map_ram(void) -{ - unsigned long v, p, e; - pgd_t *pge; - p4d_t *p4e; - pud_t *pue; - pmd_t *pme; - pte_t *pte; - /* These mark extents of read-only kernel pages... - * ...from vmlinux.lds.S - */ - - p = (u32) memblock_start_of_DRAM() & PAGE_MASK; - e = min((u32) memblock_end_of_DRAM(), (u32) __pa(high_memory)); - - v = (u32) __va(p); - pge = pgd_offset_k(v); - - while (p < e) { - int j; - p4e = p4d_offset(pge, v); - pue = pud_offset(p4e, v); - pme = pmd_offset(pue, v); - - if ((u32) pue != (u32) pge || (u32) pme != (u32) pge) { - panic("%s: Kernel hardcoded for " - "two-level page tables", __func__); - } - - /* Alloc one page for holding PTE's... */ - pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE); - if (!pte) - panic("%s: Failed to allocate %lu bytes align=0x%lx\n", - __func__, PAGE_SIZE, PAGE_SIZE); - set_pmd(pme, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE)); - - /* Fill the newly allocated page with PTE'S */ - for (j = 0; p < e && j < PTRS_PER_PTE; - v += PAGE_SIZE, p += PAGE_SIZE, j++, pte++) { - /* Create mapping between p and v. */ - /* TODO: more fine grant for page access permission */ - set_pte(pte, __pte(p + pgprot_val(PAGE_KERNEL))); - } - - pge++; - } -} -static pmd_t *fixmap_pmd_p; -static void __init fixedrange_init(void) -{ - unsigned long vaddr; - pmd_t *pmd; -#ifdef CONFIG_HIGHMEM - pte_t *pte; -#endif /* CONFIG_HIGHMEM */ - - /* - * Fixed mappings: - */ - vaddr = __fix_to_virt(__end_of_fixed_addresses - 1); - pmd = pmd_off_k(vaddr); - fixmap_pmd_p = memblock_alloc(PAGE_SIZE, PAGE_SIZE); - if (!fixmap_pmd_p) - panic("%s: Failed to allocate %lu bytes align=0x%lx\n", - __func__, PAGE_SIZE, PAGE_SIZE); - set_pmd(pmd, __pmd(__pa(fixmap_pmd_p) + _PAGE_KERNEL_TABLE)); - -#ifdef CONFIG_HIGHMEM - /* - * Permanent kmaps: - */ - vaddr = PKMAP_BASE; - - pmd = pmd_off_k(vaddr); - pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE); - if (!pte) - panic("%s: Failed to allocate %lu bytes align=0x%lx\n", - __func__, PAGE_SIZE, PAGE_SIZE); - set_pmd(pmd, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE)); - pkmap_page_table = pte; -#endif /* CONFIG_HIGHMEM */ -} - -/* - * paging_init() sets up the page tables, initialises the zone memory - * maps, and sets up the zero page, bad page and bad page tables. - */ -void __init paging_init(void) -{ - int i; - void *zero_page; - - pr_info("Setting up paging and PTEs.\n"); - /* clear out the init_mm.pgd that will contain the kernel's mappings */ - for (i = 0; i < PTRS_PER_PGD; i++) - swapper_pg_dir[i] = __pgd(1); - - map_ram(); - - fixedrange_init(); - - /* allocate space for empty_zero_page */ - zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE); - if (!zero_page) - panic("%s: Failed to allocate %lu bytes align=0x%lx\n", - __func__, PAGE_SIZE, PAGE_SIZE); - zone_sizes_init(); - - empty_zero_page = virt_to_page(zero_page); - flush_dcache_page(empty_zero_page); -} - -static inline void __init free_highmem(void) -{ -#ifdef CONFIG_HIGHMEM - unsigned long pfn; - for (pfn = PFN_UP(__pa(high_memory)); pfn < max_pfn; pfn++) { - phys_addr_t paddr = (phys_addr_t) pfn << PAGE_SHIFT; - if (!memblock_is_reserved(paddr)) - free_highmem_page(pfn_to_page(pfn)); - } -#endif -} - -static void __init set_max_mapnr_init(void) -{ - max_mapnr = max_pfn; -} - -/* - * mem_init() marks the free areas in the mem_map and tells us how much - * memory is free. This is done after various parts of the system have - * claimed their memory after the kernel image. - */ -void __init mem_init(void) -{ - phys_addr_t memory_start = memblock_start_of_DRAM(); - BUG_ON(!mem_map); - set_max_mapnr_init(); - - free_highmem(); - - /* this will put all low memory onto the freelists */ - memblock_free_all(); - - pr_info("virtual kernel memory layout:\n" - " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n" -#ifdef CONFIG_HIGHMEM - " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n" -#endif - " consist : 0x%08lx - 0x%08lx (%4ld MB)\n" - " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n" - " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n" - " .init : 0x%08lx - 0x%08lx (%4ld kB)\n" - " .data : 0x%08lx - 0x%08lx (%4ld kB)\n" - " .text : 0x%08lx - 0x%08lx (%4ld kB)\n", - FIXADDR_START, FIXADDR_TOP, (FIXADDR_TOP - FIXADDR_START) >> 10, -#ifdef CONFIG_HIGHMEM - PKMAP_BASE, PKMAP_BASE + LAST_PKMAP * PAGE_SIZE, - (LAST_PKMAP * PAGE_SIZE) >> 10, -#endif - CONSISTENT_BASE, CONSISTENT_END, - ((CONSISTENT_END) - (CONSISTENT_BASE)) >> 20, VMALLOC_START, - (unsigned long)VMALLOC_END, (VMALLOC_END - VMALLOC_START) >> 20, - (unsigned long)__va(memory_start), (unsigned long)high_memory, - ((unsigned long)high_memory - - (unsigned long)__va(memory_start)) >> 20, - (unsigned long)&__init_begin, (unsigned long)&__init_end, - ((unsigned long)&__init_end - - (unsigned long)&__init_begin) >> 10, (unsigned long)&_etext, - (unsigned long)&_edata, - ((unsigned long)&_edata - (unsigned long)&_etext) >> 10, - (unsigned long)&_text, (unsigned long)&_etext, - ((unsigned long)&_etext - (unsigned long)&_text) >> 10); - - /* - * Check boundaries twice: Some fundamental inconsistencies can - * be detected at build time already. - */ -#ifdef CONFIG_HIGHMEM - BUILD_BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > FIXADDR_START); - BUILD_BUG_ON((CONSISTENT_END) > PKMAP_BASE); -#endif - BUILD_BUG_ON(VMALLOC_END > CONSISTENT_BASE); - BUILD_BUG_ON(VMALLOC_START >= VMALLOC_END); - -#ifdef CONFIG_HIGHMEM - BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > FIXADDR_START); - BUG_ON(CONSISTENT_END > PKMAP_BASE); -#endif - BUG_ON(VMALLOC_END > CONSISTENT_BASE); - BUG_ON(VMALLOC_START >= VMALLOC_END); - BUG_ON((unsigned long)high_memory > VMALLOC_START); - - return; -} - -void __set_fixmap(enum fixed_addresses idx, - phys_addr_t phys, pgprot_t flags) -{ - unsigned long addr = __fix_to_virt(idx); - pte_t *pte; - - BUG_ON(idx <= FIX_HOLE || idx >= __end_of_fixed_addresses); - - pte = (pte_t *)&fixmap_pmd_p[pte_index(addr)]; - - if (pgprot_val(flags)) { - set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags)); - } else { - pte_clear(&init_mm, addr, pte); - flush_tlb_kernel_range(addr, addr + PAGE_SIZE); - } -} diff --git a/arch/nds32/mm/mm-nds32.c b/arch/nds32/mm/mm-nds32.c deleted file mode 100644 index f2778f2b39f6..000000000000 --- a/arch/nds32/mm/mm-nds32.c +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include - -#define __HAVE_ARCH_PGD_FREE -#include - -#define FIRST_KERNEL_PGD_NR (USER_PTRS_PER_PGD) - -/* - * need to get a page for level 1 - */ - -pgd_t *pgd_alloc(struct mm_struct *mm) -{ - pgd_t *new_pgd, *init_pgd; - int i; - - new_pgd = (pgd_t *) __get_free_pages(GFP_KERNEL, 0); - if (!new_pgd) - return NULL; - for (i = 0; i < PTRS_PER_PGD; i++) { - (*new_pgd) = 1; - new_pgd++; - } - new_pgd -= PTRS_PER_PGD; - - init_pgd = pgd_offset_k(0); - - memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, - (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); - - cpu_dcache_wb_range((unsigned long)new_pgd, - (unsigned long)new_pgd + - PTRS_PER_PGD * sizeof(pgd_t)); - inc_lruvec_page_state(virt_to_page((unsigned long *)new_pgd), - NR_PAGETABLE); - - return new_pgd; -} - -void pgd_free(struct mm_struct *mm, pgd_t * pgd) -{ - pmd_t *pmd; - struct page *pte; - - if (!pgd) - return; - - pmd = (pmd_t *) pgd; - if (pmd_none(*pmd)) - goto free; - if (pmd_bad(*pmd)) { - pmd_ERROR(*pmd); - pmd_clear(pmd); - goto free; - } - - pte = pmd_page(*pmd); - pmd_clear(pmd); - dec_lruvec_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE); - pte_free(mm, pte); - mm_dec_nr_ptes(mm); - pmd_free(mm, pmd); -free: - free_pages((unsigned long)pgd, 0); -} - -/* - * In order to soft-boot, we need to insert a 1:1 mapping in place of - * the user-mode pages. This will then ensure that we have predictable - * results when turning the mmu off - */ -void setup_mm_for_reboot(char mode) -{ - unsigned long pmdval; - pgd_t *pgd; - p4d_t *p4d; - pud_t *pud; - pmd_t *pmd; - int i; - - if (current->mm && current->mm->pgd) - pgd = current->mm->pgd; - else - pgd = init_mm.pgd; - - for (i = 0; i < USER_PTRS_PER_PGD; i++) { - pmdval = (i << PGDIR_SHIFT); - p4d = p4d_offset(pgd, i << PGDIR_SHIFT); - pud = pud_offset(p4d, i << PGDIR_SHIFT); - pmd = pmd_offset(pud + i, i << PGDIR_SHIFT); - set_pmd(pmd, __pmd(pmdval)); - } -} diff --git a/arch/nds32/mm/mmap.c b/arch/nds32/mm/mmap.c deleted file mode 100644 index 1bdf5e7d1b43..000000000000 --- a/arch/nds32/mm/mmap.c +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include - -#define COLOUR_ALIGN(addr,pgoff) \ - ((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \ - (((pgoff)<mm; - struct vm_area_struct *vma; - int do_align = 0; - struct vm_unmapped_area_info info; - int aliasing = 0; - if(IS_ENABLED(CONFIG_CPU_CACHE_ALIASING)) - aliasing = 1; - - /* - * We only need to do colour alignment if either the I or D - * caches alias. - */ - if (aliasing) - do_align = filp || (flags & MAP_SHARED); - - /* - * We enforce the MAP_FIXED case. - */ - if (flags & MAP_FIXED) { - if (aliasing && flags & MAP_SHARED && - (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)) - return -EINVAL; - return addr; - } - - if (len > TASK_SIZE) - return -ENOMEM; - - if (addr) { - if (do_align) - addr = COLOUR_ALIGN(addr, pgoff); - else - addr = PAGE_ALIGN(addr); - - vma = find_vma(mm, addr); - if (TASK_SIZE - len >= addr && - (!vma || addr + len <= vm_start_gap(vma))) - return addr; - } - - info.flags = 0; - info.length = len; - info.low_limit = mm->mmap_base; - info.high_limit = TASK_SIZE; - info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0; - info.align_offset = pgoff << PAGE_SHIFT; - return vm_unmapped_area(&info); -} diff --git a/arch/nds32/mm/proc.c b/arch/nds32/mm/proc.c deleted file mode 100644 index 848c845f5f33..000000000000 --- a/arch/nds32/mm/proc.c +++ /dev/null @@ -1,536 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -extern struct cache_info L1_cache_info[2]; - -int va_kernel_present(unsigned long addr) -{ - pmd_t *pmd; - pte_t *ptep, pte; - - pmd = pmd_off_k(addr); - if (!pmd_none(*pmd)) { - ptep = pte_offset_map(pmd, addr); - pte = *ptep; - if (pte_present(pte)) - return pte; - } - return 0; -} - -pte_t va_present(struct mm_struct * mm, unsigned long addr) -{ - pgd_t *pgd; - p4d_t *p4d; - pud_t *pud; - pmd_t *pmd; - pte_t *ptep, pte; - - pgd = pgd_offset(mm, addr); - if (!pgd_none(*pgd)) { - p4d = p4d_offset(pgd, addr); - if (!p4d_none(*p4d)) { - pud = pud_offset(p4d, addr); - if (!pud_none(*pud)) { - pmd = pmd_offset(pud, addr); - if (!pmd_none(*pmd)) { - ptep = pte_offset_map(pmd, addr); - pte = *ptep; - if (pte_present(pte)) - return pte; - } - } - } - } - return 0; - -} - -int va_readable(struct pt_regs *regs, unsigned long addr) -{ - struct mm_struct *mm = current->mm; - pte_t pte; - int ret = 0; - - if (user_mode(regs)) { - /* user mode */ - pte = va_present(mm, addr); - if (!pte && pte_read(pte)) - ret = 1; - } else { - /* superuser mode is always readable, so we can only - * check it is present or not*/ - return (! !va_kernel_present(addr)); - } - return ret; -} - -int va_writable(struct pt_regs *regs, unsigned long addr) -{ - struct mm_struct *mm = current->mm; - pte_t pte; - int ret = 0; - - if (user_mode(regs)) { - /* user mode */ - pte = va_present(mm, addr); - if (!pte && pte_write(pte)) - ret = 1; - } else { - /* superuser mode */ - pte = va_kernel_present(addr); - if (!pte && pte_kernel_write(pte)) - ret = 1; - } - return ret; -} - -/* - * All - */ -void cpu_icache_inval_all(void) -{ - unsigned long end, line_size; - - line_size = L1_cache_info[ICACHE].line_size; - end = - line_size * L1_cache_info[ICACHE].ways * L1_cache_info[ICACHE].sets; - - do { - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end)); - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end)); - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end)); - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end)); - } while (end > 0); - __nds32__isb(); -} - -void cpu_dcache_inval_all(void) -{ - __nds32__cctl_l1d_invalall(); -} - -#ifdef CONFIG_CACHE_L2 -void dcache_wb_all_level(void) -{ - unsigned long flags, cmd; - local_irq_save(flags); - __nds32__cctl_l1d_wball_alvl(); - /* Section 1: Ensure the section 2 & 3 program code execution after */ - __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RWD,0); - - /* Section 2: Confirm the writeback all level is done in CPU and L2C */ - cmd = CCTL_CMD_L2_SYNC; - L2_CMD_RDY(); - L2C_W_REG(L2_CCTL_CMD_OFF, cmd); - L2_CMD_RDY(); - - /* Section 3: Writeback whole L2 cache */ - cmd = CCTL_ALL_CMD | CCTL_CMD_L2_IX_WB; - L2_CMD_RDY(); - L2C_W_REG(L2_CCTL_CMD_OFF, cmd); - L2_CMD_RDY(); - __nds32__msync_all(); - local_irq_restore(flags); -} -EXPORT_SYMBOL(dcache_wb_all_level); -#endif - -void cpu_dcache_wb_all(void) -{ - __nds32__cctl_l1d_wball_one_lvl(); - __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RWD,0); -} - -void cpu_dcache_wbinval_all(void) -{ -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - unsigned long flags; - local_irq_save(flags); -#endif - cpu_dcache_wb_all(); - cpu_dcache_inval_all(); -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - local_irq_restore(flags); -#endif -} - -/* - * Page - */ -void cpu_icache_inval_page(unsigned long start) -{ - unsigned long line_size, end; - - line_size = L1_cache_info[ICACHE].line_size; - end = start + PAGE_SIZE; - - do { - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end)); - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end)); - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end)); - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end)); - } while (end != start); - __nds32__isb(); -} - -void cpu_dcache_inval_page(unsigned long start) -{ - unsigned long line_size, end; - - line_size = L1_cache_info[DCACHE].line_size; - end = start + PAGE_SIZE; - - do { - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); - } while (end != start); -} - -void cpu_dcache_wb_page(unsigned long start) -{ -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - unsigned long line_size, end; - - line_size = L1_cache_info[DCACHE].line_size; - end = start + PAGE_SIZE; - - do { - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); - end -= line_size; - __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); - } while (end != start); - __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RWD,0); -#endif -} - -void cpu_dcache_wbinval_page(unsigned long start) -{ - unsigned long line_size, end; - - line_size = L1_cache_info[DCACHE].line_size; - end = start + PAGE_SIZE; - - do { - end -= line_size; -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); -#endif - __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); - end -= line_size; -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); -#endif - __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); - end -= line_size; -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); -#endif - __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); - end -= line_size; -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); -#endif - __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); - } while (end != start); - __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RWD,0); -} - -void cpu_cache_wbinval_page(unsigned long page, int flushi) -{ - cpu_dcache_wbinval_page(page); - if (flushi) - cpu_icache_inval_page(page); -} - -/* - * Range - */ -void cpu_icache_inval_range(unsigned long start, unsigned long end) -{ - unsigned long line_size; - - line_size = L1_cache_info[ICACHE].line_size; - - while (end > start) { - __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (start)); - start += line_size; - } - __nds32__isb(); -} - -void cpu_dcache_inval_range(unsigned long start, unsigned long end) -{ - unsigned long line_size; - - line_size = L1_cache_info[DCACHE].line_size; - - while (end > start) { - __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (start)); - start += line_size; - } -} - -void cpu_dcache_wb_range(unsigned long start, unsigned long end) -{ -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - unsigned long line_size; - - line_size = L1_cache_info[DCACHE].line_size; - - while (end > start) { - __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (start)); - start += line_size; - } - __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RWD,0); -#endif -} - -void cpu_dcache_wbinval_range(unsigned long start, unsigned long end) -{ - unsigned long line_size; - - line_size = L1_cache_info[DCACHE].line_size; - - while (end > start) { -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (start)); -#endif - __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (start)); - start += line_size; - } - __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RWD,0); -} - -void cpu_cache_wbinval_range(unsigned long start, unsigned long end, int flushi) -{ - unsigned long line_size, align_start, align_end; - - line_size = L1_cache_info[DCACHE].line_size; - align_start = start & ~(line_size - 1); - align_end = (end + line_size - 1) & ~(line_size - 1); - cpu_dcache_wbinval_range(align_start, align_end); - - if (flushi) { - line_size = L1_cache_info[ICACHE].line_size; - align_start = start & ~(line_size - 1); - align_end = (end + line_size - 1) & ~(line_size - 1); - cpu_icache_inval_range(align_start, align_end); - } -} - -void cpu_cache_wbinval_range_check(struct vm_area_struct *vma, - unsigned long start, unsigned long end, - bool flushi, bool wbd) -{ - unsigned long line_size, t_start, t_end; - - if (!flushi && !wbd) - return; - line_size = L1_cache_info[DCACHE].line_size; - start = start & ~(line_size - 1); - end = (end + line_size - 1) & ~(line_size - 1); - - if ((end - start) > (8 * PAGE_SIZE)) { - if (wbd) - cpu_dcache_wbinval_all(); - if (flushi) - cpu_icache_inval_all(); - return; - } - - t_start = (start + PAGE_SIZE) & PAGE_MASK; - t_end = ((end - 1) & PAGE_MASK); - - if ((start & PAGE_MASK) == t_end) { - if (va_present(vma->vm_mm, start)) { - if (wbd) - cpu_dcache_wbinval_range(start, end); - if (flushi) - cpu_icache_inval_range(start, end); - } - return; - } - - if (va_present(vma->vm_mm, start)) { - if (wbd) - cpu_dcache_wbinval_range(start, t_start); - if (flushi) - cpu_icache_inval_range(start, t_start); - } - - if (va_present(vma->vm_mm, end - 1)) { - if (wbd) - cpu_dcache_wbinval_range(t_end, end); - if (flushi) - cpu_icache_inval_range(t_end, end); - } - - while (t_start < t_end) { - if (va_present(vma->vm_mm, t_start)) { - if (wbd) - cpu_dcache_wbinval_page(t_start); - if (flushi) - cpu_icache_inval_page(t_start); - } - t_start += PAGE_SIZE; - } -} - -#ifdef CONFIG_CACHE_L2 -static inline void cpu_l2cache_op(unsigned long start, unsigned long end, unsigned long op) -{ - if (atl2c_base) { - unsigned long p_start = __pa(start); - unsigned long p_end = __pa(end); - unsigned long cmd; - unsigned long line_size; - /* TODO Can Use PAGE Mode to optimize if range large than PAGE_SIZE */ - line_size = L2_CACHE_LINE_SIZE(); - p_start = p_start & (~(line_size - 1)); - p_end = (p_end + line_size - 1) & (~(line_size - 1)); - cmd = - (p_start & ~(line_size - 1)) | op | - CCTL_SINGLE_CMD; - do { - L2_CMD_RDY(); - L2C_W_REG(L2_CCTL_CMD_OFF, cmd); - cmd += line_size; - p_start += line_size; - } while (p_end > p_start); - cmd = CCTL_CMD_L2_SYNC; - L2_CMD_RDY(); - L2C_W_REG(L2_CCTL_CMD_OFF, cmd); - L2_CMD_RDY(); - } -} -#else -#define cpu_l2cache_op(start,end,op) do { } while (0) -#endif -/* - * DMA - */ -void cpu_dma_wb_range(unsigned long start, unsigned long end) -{ - unsigned long line_size; - unsigned long flags; - line_size = L1_cache_info[DCACHE].line_size; - start = start & (~(line_size - 1)); - end = (end + line_size - 1) & (~(line_size - 1)); - if (unlikely(start == end)) - return; - - local_irq_save(flags); - cpu_dcache_wb_range(start, end); - cpu_l2cache_op(start, end, CCTL_CMD_L2_PA_WB); - __nds32__msync_all(); - local_irq_restore(flags); -} - -void cpu_dma_inval_range(unsigned long start, unsigned long end) -{ - unsigned long line_size; - unsigned long old_start = start; - unsigned long old_end = end; - unsigned long flags; - line_size = L1_cache_info[DCACHE].line_size; - start = start & (~(line_size - 1)); - end = (end + line_size - 1) & (~(line_size - 1)); - if (unlikely(start == end)) - return; - local_irq_save(flags); - if (start != old_start) { - cpu_dcache_wbinval_range(start, start + line_size); - cpu_l2cache_op(start, start + line_size, CCTL_CMD_L2_PA_WBINVAL); - } - if (end != old_end) { - cpu_dcache_wbinval_range(end - line_size, end); - cpu_l2cache_op(end - line_size, end, CCTL_CMD_L2_PA_WBINVAL); - } - cpu_dcache_inval_range(start, end); - cpu_l2cache_op(start, end, CCTL_CMD_L2_PA_INVAL); - __nds32__msync_all(); - local_irq_restore(flags); - -} - -void cpu_dma_wbinval_range(unsigned long start, unsigned long end) -{ - unsigned long line_size; - unsigned long flags; - line_size = L1_cache_info[DCACHE].line_size; - start = start & (~(line_size - 1)); - end = (end + line_size - 1) & (~(line_size - 1)); - if (unlikely(start == end)) - return; - - local_irq_save(flags); - cpu_dcache_wbinval_range(start, end); - cpu_l2cache_op(start, end, CCTL_CMD_L2_PA_WBINVAL); - __nds32__msync_all(); - local_irq_restore(flags); -} - -void cpu_proc_init(void) -{ -} - -void cpu_proc_fin(void) -{ -} - -void cpu_do_idle(void) -{ - __nds32__standby_no_wake_grant(); -} - -void cpu_reset(unsigned long reset) -{ - u32 tmp; - GIE_DISABLE(); - tmp = __nds32__mfsr(NDS32_SR_CACHE_CTL); - tmp &= ~(CACHE_CTL_mskIC_EN | CACHE_CTL_mskDC_EN); - __nds32__mtsr_isb(tmp, NDS32_SR_CACHE_CTL); - cpu_dcache_wbinval_all(); - cpu_icache_inval_all(); - - __asm__ __volatile__("jr.toff %0\n\t"::"r"(reset)); -} - -void cpu_switch_mm(struct mm_struct *mm) -{ - unsigned long cid; - cid = __nds32__mfsr(NDS32_SR_TLB_MISC); - cid = (cid & ~TLB_MISC_mskCID) | mm->context.id; - __nds32__mtsr_dsb(cid, NDS32_SR_TLB_MISC); - __nds32__mtsr_isb(__pa(mm->pgd), NDS32_SR_L1_PPTB); -} diff --git a/arch/nds32/mm/tlb.c b/arch/nds32/mm/tlb.c deleted file mode 100644 index dd41f5e0712f..000000000000 --- a/arch/nds32/mm/tlb.c +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include - -unsigned int cpu_last_cid = { TLB_MISC_mskCID + (2 << TLB_MISC_offCID) }; - -DEFINE_SPINLOCK(cid_lock); - -void local_flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ - unsigned long flags, ocid, ncid; - - if ((end - start) > 0x400000) { - __nds32__tlbop_flua(); - __nds32__isb(); - return; - } - - spin_lock_irqsave(&cid_lock, flags); - ocid = __nds32__mfsr(NDS32_SR_TLB_MISC); - ncid = (ocid & ~TLB_MISC_mskCID) | vma->vm_mm->context.id; - __nds32__mtsr_dsb(ncid, NDS32_SR_TLB_MISC); - while (start < end) { - __nds32__tlbop_inv(start); - __nds32__isb(); - start += PAGE_SIZE; - } - __nds32__mtsr_dsb(ocid, NDS32_SR_TLB_MISC); - spin_unlock_irqrestore(&cid_lock, flags); -} - -void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) -{ - unsigned long flags, ocid, ncid; - - spin_lock_irqsave(&cid_lock, flags); - ocid = __nds32__mfsr(NDS32_SR_TLB_MISC); - ncid = (ocid & ~TLB_MISC_mskCID) | vma->vm_mm->context.id; - __nds32__mtsr_dsb(ncid, NDS32_SR_TLB_MISC); - __nds32__tlbop_inv(addr); - __nds32__isb(); - __nds32__mtsr_dsb(ocid, NDS32_SR_TLB_MISC); - spin_unlock_irqrestore(&cid_lock, flags); -} diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index cfb8ea0df3b1..ae95d06a4a8f 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -617,15 +617,6 @@ config CLKSRC_ST_LPC Enable this option to use the Low Power controller timer as clocksource. -config ATCPIT100_TIMER - bool "ATCPIT100 timer driver" - depends on NDS32 || COMPILE_TEST - depends on HAS_IOMEM - select TIMER_OF - default NDS32 - help - This option enables support for the Andestech ATCPIT100 timers. - config RISCV_TIMER bool "Timer for the RISC-V platform" if COMPILE_TEST depends on GENERIC_SCHED_CLOCK && RISCV && RISCV_SBI diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index fa5f624eadb6..9c85ee2bb373 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -81,7 +81,6 @@ obj-$(CONFIG_INGENIC_SYSOST) += ingenic-sysost.o obj-$(CONFIG_INGENIC_TIMER) += ingenic-timer.o obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o obj-$(CONFIG_X86_NUMACHIP) += numachip.o -obj-$(CONFIG_ATCPIT100_TIMER) += timer-atcpit100.o obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o obj-$(CONFIG_CLINT_TIMER) += timer-clint.o obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o diff --git a/drivers/clocksource/timer-atcpit100.c b/drivers/clocksource/timer-atcpit100.c deleted file mode 100644 index b4bd2f5b801d..000000000000 --- a/drivers/clocksource/timer-atcpit100.c +++ /dev/null @@ -1,266 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation -/* - * Andestech ATCPIT100 Timer Device Driver Implementation - * Rick Chen, Andes Technology Corporation - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "timer-of.h" -#ifdef CONFIG_NDS32 -#include -#endif - -/* - * Definition of register offsets - */ - -/* ID and Revision Register */ -#define ID_REV 0x0 - -/* Configuration Register */ -#define CFG 0x10 - -/* Interrupt Enable Register */ -#define INT_EN 0x14 -#define CH_INT_EN(c, i) ((1<event_handler(evt); - - return IRQ_HANDLED; -} - -static struct timer_of to = { - .flags = TIMER_OF_IRQ | TIMER_OF_CLOCK | TIMER_OF_BASE, - - .clkevt = { - .name = "atcpit100_tick", - .rating = 300, - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .set_state_shutdown = atcpit100_clkevt_shutdown, - .set_state_periodic = atcpit100_clkevt_set_periodic, - .set_state_oneshot = atcpit100_clkevt_set_oneshot, - .tick_resume = atcpit100_clkevt_shutdown, - .set_next_event = atcpit100_clkevt_next_event, - .cpumask = cpu_possible_mask, - }, - - .of_irq = { - .handler = atcpit100_timer_interrupt, - .flags = IRQF_TIMER | IRQF_IRQPOLL, - }, - - /* - * FIXME: we currently only support clocking using PCLK - * and using EXTCLK is not supported in the driver. - */ - .of_clk = { - .name = "PCLK", - } -}; - -static u64 notrace atcpit100_timer_sched_read(void) -{ - return ~readl(timer_of_base(&to) + CH1_CNT); -} - -#ifdef CONFIG_NDS32 -static void fill_vdso_need_info(struct device_node *node) -{ - struct resource timer_res; - of_address_to_resource(node, 0, &timer_res); - timer_info.mapping_base = (unsigned long)timer_res.start; - timer_info.cycle_count_down = true; - timer_info.cycle_count_reg_offset = CH1_CNT; -} -#endif - -static int __init atcpit100_timer_init(struct device_node *node) -{ - int ret; - u32 val; - void __iomem *base; - - ret = timer_of_init(node, &to); - if (ret) - return ret; - - base = timer_of_base(&to); - - sched_clock_register(atcpit100_timer_sched_read, 32, - timer_of_rate(&to)); - - ret = clocksource_mmio_init(base + CH1_CNT, - node->name, timer_of_rate(&to), 300, 32, - clocksource_mmio_readl_down); - - if (ret) { - pr_err("Failed to register clocksource\n"); - return ret; - } - - /* clear channel 0 timer0 interrupt */ - atcpit100_timer_clear_interrupt(base); - - clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), - TIMER_SYNC_TICKS, 0xffffffff); - atcpit100_ch0_tmr0_en(base); - atcpit100_ch1_tmr0_en(base); - atcpit100_clocksource_start(base); - atcpit100_clkevt_time_start(base); - - /* Enable channel 0 timer0 interrupt */ - val = readl(base + INT_EN); - writel(val | CH0INT0EN, base + INT_EN); - -#ifdef CONFIG_NDS32 - fill_vdso_need_info(node); -#endif - - return ret; -} - -TIMER_OF_DECLARE(atcpit100, "andestech,atcpit100", atcpit100_timer_init); diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index c1f611cbfbf8..c6161b0b0cb6 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -92,7 +92,6 @@ obj-$(CONFIG_IRQ_UNIPHIER_AIDET) += irq-uniphier-aidet.o obj-$(CONFIG_ARCH_SYNQUACER) += irq-sni-exiu.o obj-$(CONFIG_MESON_IRQ_GPIO) += irq-meson-gpio.o obj-$(CONFIG_GOLDFISH_PIC) += irq-goldfish-pic.o -obj-$(CONFIG_NDS32) += irq-ativic32.o obj-$(CONFIG_QCOM_PDC) += qcom-pdc.o obj-$(CONFIG_CSKY_MPINTC) += irq-csky-mpintc.o obj-$(CONFIG_CSKY_APB_INTC) += irq-csky-apb-intc.o diff --git a/drivers/irqchip/irq-ativic32.c b/drivers/irqchip/irq-ativic32.c deleted file mode 100644 index 223dd2f97d28..000000000000 --- a/drivers/irqchip/irq-ativic32.c +++ /dev/null @@ -1,156 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -unsigned long wake_mask; - -static void ativic32_ack_irq(struct irq_data *data) -{ - __nds32__mtsr_dsb(BIT(data->hwirq), NDS32_SR_INT_PEND2); -} - -static void ativic32_mask_irq(struct irq_data *data) -{ - unsigned long int_mask2 = __nds32__mfsr(NDS32_SR_INT_MASK2); - __nds32__mtsr_dsb(int_mask2 & (~(BIT(data->hwirq))), NDS32_SR_INT_MASK2); -} - -static void ativic32_unmask_irq(struct irq_data *data) -{ - unsigned long int_mask2 = __nds32__mfsr(NDS32_SR_INT_MASK2); - __nds32__mtsr_dsb(int_mask2 | (BIT(data->hwirq)), NDS32_SR_INT_MASK2); -} - -static int nointc_set_wake(struct irq_data *data, unsigned int on) -{ - unsigned long int_mask = __nds32__mfsr(NDS32_SR_INT_MASK); - static unsigned long irq_orig_bit; - u32 bit = 1 << data->hwirq; - - if (on) { - if (int_mask & bit) - __assign_bit(data->hwirq, &irq_orig_bit, true); - else - __assign_bit(data->hwirq, &irq_orig_bit, false); - - __assign_bit(data->hwirq, &int_mask, true); - __assign_bit(data->hwirq, &wake_mask, true); - - } else { - if (!(irq_orig_bit & bit)) - __assign_bit(data->hwirq, &int_mask, false); - - __assign_bit(data->hwirq, &wake_mask, false); - __assign_bit(data->hwirq, &irq_orig_bit, false); - } - - __nds32__mtsr_dsb(int_mask, NDS32_SR_INT_MASK); - - return 0; -} - -static struct irq_chip ativic32_chip = { - .name = "ativic32", - .irq_ack = ativic32_ack_irq, - .irq_mask = ativic32_mask_irq, - .irq_unmask = ativic32_unmask_irq, - .irq_set_wake = nointc_set_wake, -}; - -static unsigned int __initdata nivic_map[6] = { 6, 2, 10, 16, 24, 32 }; - -static struct irq_domain *root_domain; -static int ativic32_irq_domain_map(struct irq_domain *id, unsigned int virq, - irq_hw_number_t hw) -{ - - unsigned long int_trigger_type; - u32 type; - struct irq_data *irq_data; - int_trigger_type = __nds32__mfsr(NDS32_SR_INT_TRIGGER); - irq_data = irq_get_irq_data(virq); - if (!irq_data) - return -EINVAL; - - if (int_trigger_type & (BIT(hw))) { - irq_set_chip_and_handler(virq, &ativic32_chip, handle_edge_irq); - type = IRQ_TYPE_EDGE_RISING; - } else { - irq_set_chip_and_handler(virq, &ativic32_chip, handle_level_irq); - type = IRQ_TYPE_LEVEL_HIGH; - } - - irqd_set_trigger_type(irq_data, type); - return 0; -} - -static const struct irq_domain_ops ativic32_ops = { - .map = ativic32_irq_domain_map, - .xlate = irq_domain_xlate_onecell -}; - -static irq_hw_number_t get_intr_src(void) -{ - return ((__nds32__mfsr(NDS32_SR_ITYPE) & ITYPE_mskVECTOR) >> ITYPE_offVECTOR) - - NDS32_VECTOR_offINTERRUPT; -} - -static void ativic32_handle_irq(struct pt_regs *regs) -{ - irq_hw_number_t hwirq = get_intr_src(); - generic_handle_domain_irq(root_domain, hwirq); -} - -/* - * TODO: convert nds32 to GENERIC_IRQ_MULTI_HANDLER so that this entry logic - * can live in arch code. - */ -asmlinkage void asm_do_IRQ(struct pt_regs *regs) -{ - struct pt_regs *old_regs; - - irq_enter(); - old_regs = set_irq_regs(regs); - ativic32_handle_irq(regs); - set_irq_regs(old_regs); - irq_exit(); -} - -int __init ativic32_init_irq(struct device_node *node, struct device_node *parent) -{ - unsigned long int_vec_base, nivic, nr_ints; - - if (WARN(parent, "non-root ativic32 are not supported")) - return -EINVAL; - - int_vec_base = __nds32__mfsr(NDS32_SR_IVB); - - if (((int_vec_base & IVB_mskIVIC_VER) >> IVB_offIVIC_VER) == 0) - panic("Unable to use atcivic32 for this cpu.\n"); - - nivic = (int_vec_base & IVB_mskNIVIC) >> IVB_offNIVIC; - if (nivic >= ARRAY_SIZE(nivic_map)) - panic("The number of input for ativic32 is not supported.\n"); - - nr_ints = nivic_map[nivic]; - - root_domain = irq_domain_add_linear(node, nr_ints, - &ativic32_ops, NULL); - - if (!root_domain) - panic("%s: unable to create IRQ domain\n", node->full_name); - - return 0; -} -IRQCHIP_DECLARE(ativic32, "andestech,ativic32", ativic32_init_irq); diff --git a/drivers/net/ethernet/faraday/Kconfig b/drivers/net/ethernet/faraday/Kconfig index 3d1e9a302148..c699bd6bcbb9 100644 --- a/drivers/net/ethernet/faraday/Kconfig +++ b/drivers/net/ethernet/faraday/Kconfig @@ -6,7 +6,7 @@ config NET_VENDOR_FARADAY bool "Faraday devices" default y - depends on ARM || NDS32 || COMPILE_TEST + depends on ARM || COMPILE_TEST help If you have a network (Ethernet) card belonging to this class, say Y. @@ -19,24 +19,22 @@ if NET_VENDOR_FARADAY config FTMAC100 tristate "Faraday FTMAC100 10/100 Ethernet support" - depends on ARM || NDS32 || COMPILE_TEST + depends on ARM || COMPILE_TEST depends on !64BIT || BROKEN select MII help This driver supports the FTMAC100 10/100 Ethernet controller - from Faraday. It is used on Faraday A320, Andes AG101 and some - other ARM/NDS32 SoC's. + from Faraday. It is used on Faraday A320 and some other ARM SoC's. config FTGMAC100 tristate "Faraday FTGMAC100 Gigabit Ethernet support" - depends on ARM || NDS32 || COMPILE_TEST + depends on ARM || COMPILE_TEST depends on !64BIT || BROKEN select PHYLIB select MDIO_ASPEED if MACH_ASPEED_G6 select CRC32 help This driver supports the FTGMAC100 Gigabit Ethernet controller - from Faraday. It is used on Faraday A369, Andes AG102 and some - other ARM/NDS32 SoC's. + from Faraday. It is used on Faraday A369 and some other ARM SoC's. endif # NET_VENDOR_FARADAY diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index fcc46380e7c9..40c50fa2dd70 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -9,7 +9,7 @@ config VGA_CONSOLE bool "VGA text console" if EXPERT || !X86 depends on !4xx && !PPC_8xx && !SPARC && !M68K && !PARISC && !SUPERH && \ (!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) && \ - !ARM64 && !ARC && !MICROBLAZE && !OPENRISC && !NDS32 && !S390 && !UML + !ARM64 && !ARC && !MICROBLAZE && !OPENRISC && !S390 && !UML default y help Saying Y here will allow you to use Linux in text mode through a diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 3ccb2c70add4..6a4645a57976 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -362,9 +362,6 @@ if ($arch eq "x86_64") { $mcount_regex = "^\\s*([0-9a-fA-F]+):\\sR_RISCV_CALL(_PLT)?\\s_?mcount\$"; $type = ".quad"; $alignment = 2; -} elsif ($arch eq "nds32") { - $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_NDS32_HI20_RELA\\s+_mcount\$"; - $alignment = 2; } elsif ($arch eq "csky") { $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_CKCORE_PCREL_JSR_IMM26BY2\\s+_mcount\$"; $alignment = 2; diff --git a/tools/include/asm/barrier.h b/tools/include/asm/barrier.h index dc696c151e1c..8d378c57cb01 100644 --- a/tools/include/asm/barrier.h +++ b/tools/include/asm/barrier.h @@ -24,8 +24,6 @@ #include "../../arch/ia64/include/asm/barrier.h" #elif defined(__xtensa__) #include "../../arch/xtensa/include/asm/barrier.h" -#elif defined(__nds32__) -#include "../../arch/nds32/include/asm/barrier.h" #else #include #endif diff --git a/tools/perf/arch/nds32/Build b/tools/perf/arch/nds32/Build deleted file mode 100644 index e4e5f33c84d8..000000000000 --- a/tools/perf/arch/nds32/Build +++ /dev/null @@ -1 +0,0 @@ -perf-y += util/ diff --git a/tools/perf/arch/nds32/util/Build b/tools/perf/arch/nds32/util/Build deleted file mode 100644 index d0bc205fe49a..000000000000 --- a/tools/perf/arch/nds32/util/Build +++ /dev/null @@ -1 +0,0 @@ -perf-y += header.o diff --git a/tools/perf/arch/nds32/util/header.c b/tools/perf/arch/nds32/util/header.c deleted file mode 100644 index ef9dbdbe7968..000000000000 --- a/tools/perf/arch/nds32/util/header.c +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2005-2017 Andes Technology Corporation - -#include -#include -#include -#include "header.h" - -#define STR_LEN 1024 - -char *get_cpuid_str(struct perf_pmu *pmu) -{ - /* In nds32, we only have one cpu */ - char *buf = NULL; - struct cpu_map *cpus; - const char *sysfs = sysfs__mountpoint(); - - if (!sysfs || !pmu || !pmu->cpus) - return NULL; - - buf = malloc(STR_LEN); - if (!buf) - return NULL; - - cpus = cpu_map__get(pmu->cpus); - sprintf(buf, "0x%x", cpus->nr - 1); - cpu_map__put(cpus); - return buf; -} diff --git a/tools/testing/selftests/vDSO/vdso_config.h b/tools/testing/selftests/vDSO/vdso_config.h index 6188b16827d1..cdfed403ba13 100644 --- a/tools/testing/selftests/vDSO/vdso_config.h +++ b/tools/testing/selftests/vDSO/vdso_config.h @@ -53,10 +53,6 @@ #if __riscv_xlen == 32 #define VDSO_32BIT 1 #endif -#else /* nds32 */ -#define VDSO_VERSION 4 -#define VDSO_NAMES 1 -#define VDSO_32BIT 1 #endif static const char *versions[6] = { -- cgit v1.2.3 From 3d66718cd62d45f3210f047248eab9e76d227e47 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 28 Feb 2022 14:52:42 +0100 Subject: s390/extable: convert to relative table with data Follow arm64, riscv, and x86 and change extable layout to common "relative table with data". This allows to get rid of s390 specific code in sorttable.c. The main difference to before is that extable entries do not contain a relative function pointer anymore. Instead data and type fields are added. The type field is used to indicate which exception handler needs to be called, while the data field is currently unused. Acked-by: Alexander Gordeev Signed-off-by: Heiko Carstens Signed-off-by: Vasily Gorbik --- arch/s390/include/asm/asm-extable.h | 15 ++++++++----- arch/s390/include/asm/extable.h | 36 +++++++++++++++---------------- arch/s390/mm/extable.c | 21 ++++++++++++------ arch/s390/net/bpf_jit_comp.c | 5 ++--- scripts/sorttable.c | 43 +------------------------------------ 5 files changed, 46 insertions(+), 74 deletions(-) (limited to 'scripts') diff --git a/arch/s390/include/asm/asm-extable.h b/arch/s390/include/asm/asm-extable.h index 620390f17f0c..61484a5f1209 100644 --- a/arch/s390/include/asm/asm-extable.h +++ b/arch/s390/include/asm/asm-extable.h @@ -5,17 +5,22 @@ #include #include -#define __EX_TABLE(_section, _fault, _target) \ +#define EX_TYPE_NONE 0 +#define EX_TYPE_FIXUP 1 +#define EX_TYPE_BPF 2 + +#define __EX_TABLE(_section, _fault, _target, _type) \ stringify_in_c(.section _section,"a";) \ - stringify_in_c(.align 8;) \ + stringify_in_c(.align 4;) \ stringify_in_c(.long (_fault) - .;) \ stringify_in_c(.long (_target) - .;) \ - stringify_in_c(.quad 0;) \ + stringify_in_c(.short (_type);) \ + stringify_in_c(.short 0;) \ stringify_in_c(.previous) #define EX_TABLE(_fault, _target) \ - __EX_TABLE(__ex_table, _fault, _target) + __EX_TABLE(__ex_table, _fault, _target, EX_TYPE_FIXUP) #define EX_TABLE_AMODE31(_fault, _target) \ - __EX_TABLE(.amode31.ex_table, _fault, _target) + __EX_TABLE(.amode31.ex_table, _fault, _target, EX_TYPE_FIXUP) #endif /* __ASM_EXTABLE_H */ diff --git a/arch/s390/include/asm/extable.h b/arch/s390/include/asm/extable.h index d39d7159832a..af6ba52743e9 100644 --- a/arch/s390/include/asm/extable.h +++ b/arch/s390/include/asm/extable.h @@ -25,7 +25,7 @@ struct exception_table_entry { int insn, fixup; - long handler; + short type, data; }; extern struct exception_table_entry *__start_amode31_ex_table; @@ -38,17 +38,6 @@ static inline unsigned long extable_fixup(const struct exception_table_entry *x) return (unsigned long)&x->fixup + x->fixup; } -typedef bool (*ex_handler_t)(const struct exception_table_entry *, - struct pt_regs *); - -static inline ex_handler_t -ex_fixup_handler(const struct exception_table_entry *x) -{ - if (likely(!x->handler)) - return NULL; - return (ex_handler_t)((unsigned long)&x->handler + x->handler); -} - #define ARCH_HAS_RELATIVE_EXTABLE static inline void swap_ex_entry_fixup(struct exception_table_entry *a, @@ -58,15 +47,26 @@ static inline void swap_ex_entry_fixup(struct exception_table_entry *a, { a->fixup = b->fixup + delta; b->fixup = tmp.fixup - delta; - a->handler = b->handler; - if (a->handler) - a->handler += delta; - b->handler = tmp.handler; - if (b->handler) - b->handler -= delta; + a->type = b->type; + b->type = tmp.type; + a->data = b->data; + b->data = tmp.data; } #define swap_ex_entry_fixup swap_ex_entry_fixup +#ifdef CONFIG_BPF_JIT + +bool ex_handler_bpf(const struct exception_table_entry *ex, struct pt_regs *regs); + +#else /* !CONFIG_BPF_JIT */ + +static inline bool ex_handler_bpf(const struct exception_table_entry *ex, struct pt_regs *regs) +{ + return false; +} + +#endif /* CONFIG_BPF_JIT */ + bool fixup_exception(struct pt_regs *regs); #endif diff --git a/arch/s390/mm/extable.c b/arch/s390/mm/extable.c index d6ca75570dcf..ac6b736ac883 100644 --- a/arch/s390/mm/extable.c +++ b/arch/s390/mm/extable.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include +#include #include const struct exception_table_entry *s390_search_extables(unsigned long addr) @@ -15,17 +17,24 @@ const struct exception_table_entry *s390_search_extables(unsigned long addr) return search_extable(__start_amode31_ex_table, num, addr); } +static bool ex_handler_fixup(const struct exception_table_entry *ex, struct pt_regs *regs) +{ + regs->psw.addr = extable_fixup(ex); + return true; +} + bool fixup_exception(struct pt_regs *regs) { const struct exception_table_entry *ex; - ex_handler_t handler; ex = s390_search_extables(instruction_pointer(regs)); if (!ex) return false; - handler = ex_fixup_handler(ex); - if (unlikely(handler)) - return handler(ex, regs); - regs->psw.addr = extable_fixup(ex); - return true; + switch (ex->type) { + case EX_TYPE_FIXUP: + return ex_handler_fixup(ex, regs); + case EX_TYPE_BPF: + return ex_handler_bpf(ex, regs); + } + panic("invalid exception table entry"); } diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index f884d1b9ca79..a1a3a10c514c 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -622,8 +622,7 @@ static int get_probe_mem_regno(const u8 *insn) return insn[1] >> 4; } -static bool ex_handler_bpf(const struct exception_table_entry *x, - struct pt_regs *regs) +bool ex_handler_bpf(const struct exception_table_entry *x, struct pt_regs *regs) { int regno; u8 *insn; @@ -678,7 +677,7 @@ static int bpf_jit_probe_mem(struct bpf_jit *jit, struct bpf_prog *fp, /* JIT bug - landing pad and extable must be close. */ return -1; ex->fixup = delta; - ex->handler = (u8 *)ex_handler_bpf - (u8 *)&ex->handler; + ex->type = EX_TYPE_BPF; jit->excnt++; } return 0; diff --git a/scripts/sorttable.c b/scripts/sorttable.c index 3a8ea5ed553d..d00504c5f530 100644 --- a/scripts/sorttable.c +++ b/scripts/sorttable.c @@ -261,45 +261,6 @@ static void sort_relative_table_with_data(char *extab_image, int image_size) } } -static void s390_sort_relative_table(char *extab_image, int image_size) -{ - int i; - - for (i = 0; i < image_size; i += 16) { - char *loc = extab_image + i; - uint64_t handler; - - w(r((uint32_t *)loc) + i, (uint32_t *)loc); - w(r((uint32_t *)(loc + 4)) + (i + 4), (uint32_t *)(loc + 4)); - /* - * 0 is a special self-relative handler value, which means that - * handler should be ignored. It is safe, because it means that - * handler field points to itself, which should never happen. - * When creating extable-relative values, keep it as 0, since - * this should never occur either: it would mean that handler - * field points to the first extable entry. - */ - handler = r8((uint64_t *)(loc + 8)); - if (handler) - handler += i + 8; - w8(handler, (uint64_t *)(loc + 8)); - } - - qsort(extab_image, image_size / 16, 16, compare_relative_table); - - for (i = 0; i < image_size; i += 16) { - char *loc = extab_image + i; - uint64_t handler; - - w(r((uint32_t *)loc) - i, (uint32_t *)loc); - w(r((uint32_t *)(loc + 4)) - (i + 4), (uint32_t *)(loc + 4)); - handler = r8((uint64_t *)(loc + 8)); - if (handler) - handler -= i + 8; - w8(handler, (uint64_t *)(loc + 8)); - } -} - static int do_file(char const *const fname, void *addr) { int rc = -1; @@ -340,12 +301,10 @@ static int do_file(char const *const fname, void *addr) case EM_386: case EM_AARCH64: case EM_RISCV: + case EM_S390: case EM_X86_64: custom_sort = sort_relative_table_with_data; break; - case EM_S390: - custom_sort = s390_sort_relative_table; - break; case EM_PARISC: case EM_PPC: case EM_PPC64: -- cgit v1.2.3 From 1d2ad084800edad81cdc955304272742b10721c7 Mon Sep 17 00:00:00 2001 From: Vasily Gorbik Date: Sun, 6 Mar 2022 20:56:07 +0100 Subject: s390/nospec: add an option to use thunk-extern Currently with -mindirect-branch=thunk and -mfunction-return=thunk compiler options expoline thunks are put into individual COMDAT group sections. s390 is the only architecture which has group sections and it has implications for kpatch and objtool tools support. Using -mindirect-branch=thunk-extern and -mfunction-return=thunk-extern is an alternative, which comes with a need to generate all required expoline thunks manually. Unfortunately modules area is too far away from the kernel image, and expolines from the kernel image cannon be used. But since all new distributions (except Debian) build kernels for machine generations newer than z10, where "exrl" instruction is available, that leaves only 16 expolines thunks possible. Provide an option to build the kernel with -mindirect-branch=thunk-extern and -mfunction-return=thunk-extern for z10 or newer. This also requires to postlink expoline thunks into all modules explicitly. Currently modules already contain most expolines anyhow. Unfortunately -mindirect-branch=thunk-extern and -mfunction-return=thunk-extern options support is broken in gcc <= 11.2. Additional compile test is required to verify proper gcc support. Acked-by: Ilya Leoshkevich Co-developed-by: Sumanth Korikkar Signed-off-by: Sumanth Korikkar Signed-off-by: Vasily Gorbik --- arch/s390/Kconfig | 15 +++++++++++++++ arch/s390/Makefile | 14 +++++++++----- arch/s390/include/asm/nospec-insn.h | 10 ++++++++++ arch/s390/lib/Makefile | 1 + arch/s390/lib/expoline.S | 12 ++++++++++++ arch/s390/tools/gcc-thunk-extern.sh | 24 ++++++++++++++++++++++++ scripts/mod/modpost.c | 5 +++++ 7 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 arch/s390/lib/expoline.S create mode 100755 arch/s390/tools/gcc-thunk-extern.sh (limited to 'scripts') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index a492376d6e3f..115b8cddefee 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -585,6 +585,7 @@ config KERNEL_NOBP config EXPOLINE def_bool n + depends on $(cc-option,-mindirect-branch=thunk) prompt "Avoid speculative indirect branches in the kernel" help Compile the kernel with the expoline compiler options to guard @@ -595,6 +596,20 @@ config EXPOLINE If unsure, say N. +config EXPOLINE_EXTERN + def_bool n + depends on EXPOLINE + depends on HAVE_MARCH_Z10_FEATURES + depends on CC_IS_GCC && GCC_VERSION >= 110200 + depends on $(success,$(srctree)/arch/s390/tools/gcc-thunk-extern.sh $(CC)) + prompt "Generate expolines as extern functions." + help + This option is required for some tooling like kpatch. The kernel is + compiled with -mindirect-branch=thunk-extern and requires a newer + compiler. + + If unsure, say N. + choice prompt "Expoline default" depends on EXPOLINE diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 2edf25b44c4b..bd75128b7d79 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -81,14 +81,18 @@ ifneq ($(call cc-option,-mstack-size=8192 -mstack-guard=128),) endif ifdef CONFIG_EXPOLINE - ifneq ($(call cc-option,$(CC_FLAGS_MARCH) -mindirect-branch=thunk),) + ifdef CONFIG_EXPOLINE_EXTERN + KBUILD_LDFLAGS_MODULE += arch/s390/lib/expoline.o + CC_FLAGS_EXPOLINE := -mindirect-branch=thunk-extern + CC_FLAGS_EXPOLINE += -mfunction-return=thunk-extern + else CC_FLAGS_EXPOLINE := -mindirect-branch=thunk CC_FLAGS_EXPOLINE += -mfunction-return=thunk - CC_FLAGS_EXPOLINE += -mindirect-branch-table - export CC_FLAGS_EXPOLINE - cflags-y += $(CC_FLAGS_EXPOLINE) -DCC_USING_EXPOLINE - aflags-y += -DCC_USING_EXPOLINE endif + CC_FLAGS_EXPOLINE += -mindirect-branch-table + export CC_FLAGS_EXPOLINE + cflags-y += $(CC_FLAGS_EXPOLINE) -DCC_USING_EXPOLINE + aflags-y += -DCC_USING_EXPOLINE endif ifdef CONFIG_FUNCTION_TRACER diff --git a/arch/s390/include/asm/nospec-insn.h b/arch/s390/include/asm/nospec-insn.h index 4397eae15e34..bbb5c4d84db9 100644 --- a/arch/s390/include/asm/nospec-insn.h +++ b/arch/s390/include/asm/nospec-insn.h @@ -18,7 +18,11 @@ _LC_BR_R1 = __LC_BR_R1 * the various thunks are merged into a single copy. */ .macro __THUNK_PROLOG_NAME name +#ifdef CONFIG_EXPOLINE_EXTERN + .pushsection .text,"ax",@progbits +#else .pushsection .text.\name,"axG",@progbits,\name,comdat +#endif .globl \name .hidden \name .type \name,@function @@ -115,7 +119,13 @@ _LC_BR_R1 = __LC_BR_R1 555: br \reg .endm +#ifdef CONFIG_EXPOLINE_EXTERN + .macro GEN_BR_THUNK reg,ruse=%r1 + .endm + .macro GEN_BR_THUNK_EXTERN reg,ruse=%r1 +#else .macro GEN_BR_THUNK reg,ruse=%r1 +#endif __DECODE_RR __THUNK_PROLOG_BR,\reg,\ruse __THUNK_EX_BR \reg,\ruse __THUNK_EPILOG diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile index 69feb8ed3312..5d415b3db6d1 100644 --- a/arch/s390/lib/Makefile +++ b/arch/s390/lib/Makefile @@ -7,6 +7,7 @@ lib-y += delay.o string.o uaccess.o find.o spinlock.o obj-y += mem.o xor.o lib-$(CONFIG_KPROBES) += probes.o lib-$(CONFIG_UPROBES) += probes.o +obj-$(CONFIG_EXPOLINE_EXTERN) += expoline.o obj-$(CONFIG_S390_KPROBES_SANITY_TEST) += test_kprobes_s390.o test_kprobes_s390-objs += test_kprobes_asm.o test_kprobes.o diff --git a/arch/s390/lib/expoline.S b/arch/s390/lib/expoline.S new file mode 100644 index 000000000000..92ed8409a7a4 --- /dev/null +++ b/arch/s390/lib/expoline.S @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include +#include + +.macro GEN_ALL_BR_THUNK_EXTERN + .irp r1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + GEN_BR_THUNK_EXTERN %r\r1 + .endr +.endm + +GEN_ALL_BR_THUNK_EXTERN diff --git a/arch/s390/tools/gcc-thunk-extern.sh b/arch/s390/tools/gcc-thunk-extern.sh new file mode 100755 index 000000000000..20bcbf6dd7ab --- /dev/null +++ b/arch/s390/tools/gcc-thunk-extern.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Borrowed from gcc: gcc/testsuite/gcc.target/s390/nobp-section-type-conflict.c +# Checks that we don't get error: section type conflict with ‘put_page’. + +cat << "END" | $@ -x c - -fno-PIE -march=z10 -mindirect-branch=thunk-extern -mfunction-return=thunk-extern -mindirect-branch-table -O2 -c -o /dev/null +int a; +int b (void); +void c (int); + +static void +put_page (void) +{ + if (b ()) + c (a); +} + +__attribute__ ((__section__ (".init.text"), __cold__)) void +d (void) +{ + put_page (); + put_page (); +} +END diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 6bfa33217914..dbc0aaf69e43 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -658,6 +658,11 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) strstarts(symname, "_savevr_") || strcmp(symname, ".TOC.") == 0) return 1; + + if (info->hdr->e_machine == EM_S390) + /* Expoline thunks are linked on all kernel modules during final link of .ko */ + if (strstarts(symname, "__s390_indirect_jump_r")) + return 1; /* Do not ignore this symbol */ return 0; } -- cgit v1.2.3 From a0a7e453b502cbbf7ff372f907a4e27a2ebf5445 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 17 Feb 2022 12:12:40 +0100 Subject: sched/preempt: Tell about PREEMPT_DYNAMIC on kernel headers Displaying "PREEMPT" on kernel headers when CONFIG_PREEMPT_DYNAMIC=y can be misleading for anybody involved in remote debugging because it is then not guaranteed that there is an actual preemption behaviour. It depends on default Kconfig or boot defined choices. Therefore, tell about PREEMPT_DYNAMIC on static kernel headers and leave the search for the actual preemption behaviour to browsing dmesg. Reviewed-by: Valentin Schneider Signed-off-by: Frederic Weisbecker Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20220217111240.GA742892@lothringen --- init/Makefile | 3 ++- scripts/mkcompile_h | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/init/Makefile b/init/Makefile index 06326e304384..d82623d7fc8e 100644 --- a/init/Makefile +++ b/init/Makefile @@ -31,7 +31,8 @@ quiet_cmd_compile.h = CHK $@ cmd_compile.h = \ $(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT_BUILD)" \ - "$(CONFIG_PREEMPT_RT)" "$(CONFIG_CC_VERSION_TEXT)" "$(LD)" + "$(CONFIG_PREEMPT_DYNAMIC)" "$(CONFIG_PREEMPT_RT)" \ + "$(CONFIG_CC_VERSION_TEXT)" "$(LD)" include/generated/compile.h: FORCE $(call cmd,compile.h) diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index 6a2a04d92f42..ca40a5258c87 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -5,9 +5,10 @@ TARGET=$1 ARCH=$2 SMP=$3 PREEMPT=$4 -PREEMPT_RT=$5 -CC_VERSION="$6" -LD=$7 +PREEMPT_DYNAMIC=$5 +PREEMPT_RT=$6 +CC_VERSION="$7" +LD=$8 # Do not expand names set -f @@ -41,8 +42,14 @@ fi UTS_VERSION="#$VERSION" CONFIG_FLAGS="" if [ -n "$SMP" ] ; then CONFIG_FLAGS="SMP"; fi -if [ -n "$PREEMPT" ] ; then CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT"; fi -if [ -n "$PREEMPT_RT" ] ; then CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT_RT"; fi + +if [ -n "$PREEMPT_RT" ] ; then + CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT_RT" +elif [ -n "$PREEMPT_DYNAMIC" ] ; then + CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT_DYNAMIC" +elif [ -n "$PREEMPT" ] ; then + CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT" +fi # Truncate to maximum length UTS_LEN=64 -- cgit v1.2.3 From 2783a7f56f9980f61ca809b826bcd14dc77eb7b9 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 10 Mar 2022 10:05:12 -0600 Subject: dt-bindings: kbuild: Pass DT_SCHEMA_FILES to dt-validate In preparation for supporting validation of DTB files, the full processed schema will always be needed in order to extract type information from it. Therefore, the processed schema containing only what DT_SCHEMA_FILES specifies won't work. Instead, dt-validate has gained an option, -l or --limit, to specify which schema(s) to use for validation. As the command line option is new, we the minimum dtschema version must be updated. Cc: Masahiro Yamada Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220310160513.1708182-2-robh@kernel.org --- Documentation/devicetree/bindings/Makefile | 28 +++------------------------- scripts/Makefile.lib | 5 ++--- 2 files changed, 5 insertions(+), 28 deletions(-) (limited to 'scripts') diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile index 29b5dbd0807e..2716f7b9e25e 100644 --- a/Documentation/devicetree/bindings/Makefile +++ b/Documentation/devicetree/bindings/Makefile @@ -6,7 +6,7 @@ DT_MK_SCHEMA ?= dt-mk-schema DT_SCHEMA_LINT := $(shell which yamllint || \ echo "warning: python package 'yamllint' not installed, skipping" >&2) -DT_SCHEMA_MIN_VERSION = 2021.2.1 +DT_SCHEMA_MIN_VERSION = 2022.3 PHONY += check_dtschema_version check_dtschema_version: @@ -25,9 +25,6 @@ quiet_cmd_extract_ex = DTEX $@ $(obj)/%.example.dts: $(src)/%.yaml check_dtschema_version FORCE $(call if_changed,extract_ex) -# Use full schemas when checking %.example.dts -DT_TMP_SCHEMA := $(obj)/processed-schema-examples.json - find_all_cmd = find $(srctree)/$(src) \( -name '*.yaml' ! \ -name 'processed-schema*' ! \ -name '*.example.dt.yaml' \) @@ -70,29 +67,10 @@ override DTC_FLAGS := \ # Disable undocumented compatible checks until warning free override DT_CHECKER_FLAGS ?= -$(obj)/processed-schema-examples.json: $(DT_DOCS) $(src)/.yamllint check_dtschema_version FORCE +$(obj)/processed-schema.json: $(DT_DOCS) $(src)/.yamllint check_dtschema_version FORCE $(call if_changed_rule,chkdt) -ifeq ($(DT_SCHEMA_FILES),) - -# Unless DT_SCHEMA_FILES is specified, use the full schema for dtbs_check too. -# Just copy processed-schema-examples.json - -$(obj)/processed-schema.json: $(obj)/processed-schema-examples.json FORCE - $(call if_changed,copy) - -else - -# If DT_SCHEMA_FILES is specified, use it for processed-schema.json - -$(obj)/processed-schema.json: DT_MK_SCHEMA_FLAGS := -u -$(obj)/processed-schema.json: $(CHK_DT_DOCS) check_dtschema_version FORCE - $(call if_changed,mk_schema) - -endif - -always-$(CHECK_DT_BINDING) += processed-schema-examples.json -always-$(CHECK_DTBS) += processed-schema.json +always-y += processed-schema.json always-$(CHECK_DT_BINDING) += $(patsubst $(srctree)/$(src)/%.yaml,%.example.dts, $(CHK_DT_DOCS)) always-$(CHECK_DT_BINDING) += $(patsubst $(srctree)/$(src)/%.yaml,%.example.dt.yaml, $(CHK_DT_DOCS)) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 79be57fdd32a..c8c6f1745d03 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -361,10 +361,9 @@ $(multi-dtb-y): FORCE $(call multi_depend, $(multi-dtb-y), .dtb, -dtbs) DT_CHECKER ?= dt-validate -DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),,-m) +DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),-l $(DT_SCHEMA_FILES),-m) DT_BINDING_DIR := Documentation/devicetree/bindings -# DT_TMP_SCHEMA may be overridden from Documentation/devicetree/bindings/Makefile -DT_TMP_SCHEMA ?= $(objtree)/$(DT_BINDING_DIR)/processed-schema.json +DT_TMP_SCHEMA := $(objtree)/$(DT_BINDING_DIR)/processed-schema.json quiet_cmd_dtb_check = CHECK $@ cmd_dtb_check = $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ -- cgit v1.2.3 From ef8795f3f1cef2b2d2cd5dfab3758a7601898bc9 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 10 Mar 2022 10:05:13 -0600 Subject: dt-bindings: kbuild: Use DTB files for validation Switch the DT validation to use DTB files directly instead of a DTS to YAML conversion. The original motivation for supporting validation on DTB files was to enable running validation on a running system (e.g. 'dt-validate /sys/firmware/fdt') or other cases where the original source DTS is not available. The YAML format was not without issues. Using DTBs with the schema type information solves some of those problems. The YAML format relies on the DTS source level information including bracketing of properties, size directives, and phandle tags all of which are lost in a DTB file. While standardizing the bracketing is a good thing, it does cause a lot of extra warnings and churn to fix them. Another issue has been signed types are not validated correctly as sign information is not propagated to YAML. Using the schema type information allows for proper handling of signed types. YAML also can't represent the full range of 64-bit integers as numbers are stored as floats by most/all parsers. The DTB validation works by decoding property values using the type information in the schemas themselves. The main corner case this does not work for is matrix types where neither dimension is fixed. For now, checking the dimensions in these cases are skipped. Signed-off-by: Rob Herring Tested-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20220310160513.1708182-3-robh@kernel.org --- Documentation/devicetree/bindings/Makefile | 7 +++---- Documentation/devicetree/bindings/writing-schema.rst | 17 +++++------------ scripts/Makefile.lib | 20 +++++++------------- scripts/dtc/Makefile | 13 ------------- scripts/dtc/update-dtc-source.sh | 2 +- 5 files changed, 16 insertions(+), 43 deletions(-) (limited to 'scripts') diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile index 2716f7b9e25e..e594e5898be0 100644 --- a/Documentation/devicetree/bindings/Makefile +++ b/Documentation/devicetree/bindings/Makefile @@ -26,8 +26,7 @@ $(obj)/%.example.dts: $(src)/%.yaml check_dtschema_version FORCE $(call if_changed,extract_ex) find_all_cmd = find $(srctree)/$(src) \( -name '*.yaml' ! \ - -name 'processed-schema*' ! \ - -name '*.example.dt.yaml' \) + -name 'processed-schema*' \) find_cmd = $(find_all_cmd) | grep -F "$(DT_SCHEMA_FILES)" CHK_DT_DOCS := $(shell $(find_cmd)) @@ -72,9 +71,9 @@ $(obj)/processed-schema.json: $(DT_DOCS) $(src)/.yamllint check_dtschema_version always-y += processed-schema.json always-$(CHECK_DT_BINDING) += $(patsubst $(srctree)/$(src)/%.yaml,%.example.dts, $(CHK_DT_DOCS)) -always-$(CHECK_DT_BINDING) += $(patsubst $(srctree)/$(src)/%.yaml,%.example.dt.yaml, $(CHK_DT_DOCS)) +always-$(CHECK_DT_BINDING) += $(patsubst $(srctree)/$(src)/%.yaml,%.example.dtb, $(CHK_DT_DOCS)) # Hack: avoid 'Argument list too long' error for 'make clean'. Remove most of # build artifacts here before they are processed by scripts/Makefile.clean clean-files = $(shell find $(obj) \( -name '*.example.dts' -o \ - -name '*.example.dt.yaml' \) -delete 2>/dev/null) + -name '*.example.dtb' \) -delete 2>/dev/null) diff --git a/Documentation/devicetree/bindings/writing-schema.rst b/Documentation/devicetree/bindings/writing-schema.rst index 3b00fe981494..95ecf55559e5 100644 --- a/Documentation/devicetree/bindings/writing-schema.rst +++ b/Documentation/devicetree/bindings/writing-schema.rst @@ -120,20 +120,13 @@ project can be installed with pip:: pip3 install dtschema -Several executables (dt-doc-validate, dt-mk-schema, dt-validate) will be -installed. Ensure they are in your PATH (~/.local/bin by default). - -dtc must also be built with YAML output support enabled. This requires that -libyaml and its headers be installed on the host system. For some distributions -that involves installing the development package, such as: - -Debian:: +Note that 'dtschema' installation requires 'swig' and Python development files +installed first. On Debian/Ubuntu systems:: - apt-get install libyaml-dev + apt install swig python3-dev -Fedora:: - - dnf -y install libyaml-devel +Several executables (dt-doc-validate, dt-mk-schema, dt-validate) will be +installed. Ensure they are in your PATH (~/.local/bin by default). Running checks ~~~~~~~~~~~~~~ diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index c8c6f1745d03..9d5320a47ef8 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -87,11 +87,6 @@ base-dtb-y := $(foreach m, $(multi-dtb-y), $(firstword $(call suffix-search, $m, always-y += $(dtb-y) -ifneq ($(CHECK_DTBS),) -always-y += $(patsubst %.dtb,%.dt.yaml, $(real-dtb-y)) -always-y += $(patsubst %.dtbo,%.dt.yaml, $(real-dtb-y)) -endif - # Add subdir path extra-y := $(addprefix $(obj)/,$(extra-y)) @@ -347,12 +342,6 @@ cmd_dtc = $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; -d $(depfile).dtc.tmp $(dtc-tmp) ; \ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) -$(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE - $(call if_changed_dep,dtc) - -$(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE - $(call if_changed_dep,dtc) - quiet_cmd_fdtoverlay = DTOVL $@ cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(real-prereqs) @@ -360,22 +349,27 @@ $(multi-dtb-y): FORCE $(call if_changed,fdtoverlay) $(call multi_depend, $(multi-dtb-y), .dtb, -dtbs) +ifneq ($(CHECK_DTBS)$(CHECK_DT_BINDING),) DT_CHECKER ?= dt-validate DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),-l $(DT_SCHEMA_FILES),-m) DT_BINDING_DIR := Documentation/devicetree/bindings DT_TMP_SCHEMA := $(objtree)/$(DT_BINDING_DIR)/processed-schema.json quiet_cmd_dtb_check = CHECK $@ - cmd_dtb_check = $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ + cmd_dtb_check = $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ || true +endif define rule_dtc $(call cmd_and_fixdep,dtc) $(call cmd,dtb_check) endef -$(obj)/%.dt.yaml: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE +$(obj)/%.dtb: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE $(call if_changed_rule,dtc) +$(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE + $(call if_changed_dep,dtc) + dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) # Bzip2 diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile index 1cba78e1dce6..4d32b9497da9 100644 --- a/scripts/dtc/Makefile +++ b/scripts/dtc/Makefile @@ -17,20 +17,7 @@ fdtoverlay-objs := $(libfdt) fdtoverlay.o util.o # Source files need to get at the userspace version of libfdt_env.h to compile HOST_EXTRACFLAGS += -I $(srctree)/$(src)/libfdt - -ifeq ($(shell pkg-config --exists yaml-0.1 2>/dev/null && echo yes),) -ifneq ($(CHECK_DT_BINDING)$(CHECK_DTBS),) -$(error dtc needs libyaml for DT schema validation support. \ - Install the necessary libyaml development package.) -endif HOST_EXTRACFLAGS += -DNO_YAML -else -dtc-objs += yamltree.o -# To include installed in a non-default path -HOSTCFLAGS_yamltree.o := $(shell pkg-config --cflags yaml-0.1) -# To link libyaml installed in a non-default path -HOSTLDLIBS_dtc := $(shell pkg-config --libs yaml-0.1) -endif # Generated files need one more search path to include headers in source tree HOSTCFLAGS_dtc-lexer.lex.o := -I $(srctree)/$(src) diff --git a/scripts/dtc/update-dtc-source.sh b/scripts/dtc/update-dtc-source.sh index 32ff17ffd089..94627541533e 100755 --- a/scripts/dtc/update-dtc-source.sh +++ b/scripts/dtc/update-dtc-source.sh @@ -32,7 +32,7 @@ DTC_UPSTREAM_PATH=`pwd`/../dtc DTC_LINUX_PATH=`pwd`/scripts/dtc DTC_SOURCE="checks.c data.c dtc.c dtc.h flattree.c fstree.c livetree.c srcpos.c \ - srcpos.h treesource.c util.c util.h version_gen.h yamltree.c \ + srcpos.h treesource.c util.c util.h version_gen.h \ dtc-lexer.l dtc-parser.y" LIBFDT_SOURCE="fdt.c fdt.h fdt_addresses.c fdt_empty_tree.c \ fdt_overlay.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c \ -- cgit v1.2.3 From 1344794a59db2bd44b4919d2d75300fd3b1c2cd7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 8 Mar 2022 22:56:12 +0100 Subject: Kbuild: add -Wno-shift-negative-value where -Wextra is used As a preparation for moving to -std=gnu11, turn off the -Wshift-negative-value option. This warning is enabled by gcc when building with -Wextra for c99 or higher, but not for c89. Since the kernel already relies on well-defined overflow behavior, the warning is not helpful and can simply be disabled in all locations that use -Wextra. Signed-off-by: Arnd Bergmann Acked-by: Jani Nikula Reviewed-by: Nathan Chancellor Tested-by: Sedat Dilek # LLVM/Clang v13.0.0 (x86-64) Signed-off-by: Masahiro Yamada --- drivers/gpu/drm/i915/Makefile | 1 + drivers/staging/greybus/tools/Makefile | 3 ++- fs/btrfs/Makefile | 1 + scripts/Makefile.extrawarn | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 1b62b9f65196..1618a6e0af4e 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -17,6 +17,7 @@ subdir-ccflags-y += -Wno-unused-parameter subdir-ccflags-y += -Wno-type-limits subdir-ccflags-y += -Wno-missing-field-initializers subdir-ccflags-y += -Wno-sign-compare +subdir-ccflags-y += -Wno-shift-negative-value subdir-ccflags-y += $(call cc-disable-warning, unused-but-set-variable) subdir-ccflags-y += $(call cc-disable-warning, frame-address) subdir-ccflags-$(CONFIG_DRM_I915_WERROR) += -Werror diff --git a/drivers/staging/greybus/tools/Makefile b/drivers/staging/greybus/tools/Makefile index ad0ae8053b79..a3bbd73171f2 100644 --- a/drivers/staging/greybus/tools/Makefile +++ b/drivers/staging/greybus/tools/Makefile @@ -12,7 +12,8 @@ CFLAGS += -std=gnu99 -Wall -Wextra -g \ -Wredundant-decls \ -Wcast-align \ -Wsign-compare \ - -Wno-missing-field-initializers + -Wno-missing-field-initializers \ + -Wno-shift-negative-value CC := $(CROSS_COMPILE)gcc diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile index 4188ba3fd8c3..99f9995670ea 100644 --- a/fs/btrfs/Makefile +++ b/fs/btrfs/Makefile @@ -17,6 +17,7 @@ subdir-ccflags-y += $(condflags) subdir-ccflags-y += -Wno-missing-field-initializers subdir-ccflags-y += -Wno-sign-compare subdir-ccflags-y += -Wno-type-limits +subdir-ccflags-y += -Wno-shift-negative-value obj-$(CONFIG_BTRFS_FS) := btrfs.o diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 8be892887d71..650d0b8ceec3 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -36,6 +36,7 @@ KBUILD_CFLAGS += $(call cc-option, -Wstringop-truncation) KBUILD_CFLAGS += -Wno-missing-field-initializers KBUILD_CFLAGS += -Wno-sign-compare KBUILD_CFLAGS += -Wno-type-limits +KBUILD_CFLAGS += -Wno-shift-negative-value KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1 -- cgit v1.2.3 From 4d94f910e79a349b00a4f8aab6f3ae87129d8c5a Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Tue, 8 Mar 2022 22:56:13 +0100 Subject: Kbuild: use -Wdeclaration-after-statement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The kernel is moving from using `-std=gnu89` to `-std=gnu11`, permitting the use of additional C11 features such as for-loop initial declarations. One contentious aspect of C99 is that it permits mixed declarations and code, and for now at least, it seems preferable to enforce that declarations must come first. These warnings were already enabled in the kernel itself, but not for KBUILD_USERCFLAGS or the compat VDSO on arch/arm64, which uses a separate set of CFLAGS. This patch fixes an existing violation in modpost.c, which is not reported because of the missing flag in KBUILD_USERCFLAGS: | scripts/mod/modpost.c: In function ‘match’: | scripts/mod/modpost.c:837:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] | 837 | const char *endp = p + strlen(p) - 1; | | ^~~~~ Signed-off-by: Mark Rutland [arnd: don't add a duplicate flag to the default set, update changelog] Signed-off-by: Arnd Bergmann Reviewed-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Tested-by: Sedat Dilek # LLVM/Clang v13.0.0 (x86-64) Signed-off-by: Masahiro Yamada --- Makefile | 3 ++- arch/arm64/kernel/vdso32/Makefile | 1 + scripts/mod/modpost.c | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 51e142f760f7..84a2de340934 100644 --- a/Makefile +++ b/Makefile @@ -432,7 +432,8 @@ HOSTCXX = g++ endif export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ - -O2 -fomit-frame-pointer -std=gnu89 + -O2 -fomit-frame-pointer -std=gnu89 \ + -Wdeclaration-after-statement export KBUILD_USERLDFLAGS := KBUILD_HOSTCFLAGS := $(KBUILD_USERCFLAGS) $(HOST_LFS_CFLAGS) $(HOSTCFLAGS) diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile index 6c01b63ff56d..f46457f1f4f0 100644 --- a/arch/arm64/kernel/vdso32/Makefile +++ b/arch/arm64/kernel/vdso32/Makefile @@ -68,6 +68,7 @@ VDSO_CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common \ -Werror-implicit-function-declaration \ -Wno-format-security \ + -Wdeclaration-after-statement \ -std=gnu89 VDSO_CFLAGS += -O2 # Some useful compiler-dependent flags from top-level Makefile diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 6bfa33217914..fe693304b120 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -833,8 +833,10 @@ static int match(const char *sym, const char * const pat[]) { const char *p; while (*pat) { + const char *endp; + p = *pat++; - const char *endp = p + strlen(p) - 1; + endp = p + strlen(p) - 1; /* "*foo*" */ if (*p == '*' && *endp == '*') { -- cgit v1.2.3 From 53f7109ef957315ab53205ba3a3f4f48874c0428 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 8 Mar 2022 16:30:45 +0100 Subject: objtool: Rename --duplicate to --lto In order to prepare for LTO like objtool runs for modules, rename the duplicate argument to lto. Signed-off-by: Peter Zijlstra (Intel) Acked-by: Josh Poimboeuf Link: https://lore.kernel.org/r/20220308154319.172584233@infradead.org --- scripts/link-vmlinux.sh | 2 +- tools/objtool/builtin-check.c | 4 ++-- tools/objtool/check.c | 7 ++++++- tools/objtool/include/objtool/builtin.h | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 666f7bbc13eb..9b08dca26f99 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -115,7 +115,7 @@ objtool_link() objtoolcmd="orc generate" fi - objtoolopt="${objtoolopt} --duplicate" + objtoolopt="${objtoolopt} --lto" if is_enabled CONFIG_FTRACE_MCOUNT_USE_OBJTOOL; then objtoolopt="${objtoolopt} --mcount" diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index 853af934c9fd..5c2fcaa2c260 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -20,7 +20,7 @@ #include bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, - validate_dup, vmlinux, mcount, noinstr, backup, sls, dryrun; + lto, vmlinux, mcount, noinstr, backup, sls, dryrun; static const char * const check_usage[] = { "objtool check [] file.o", @@ -40,7 +40,7 @@ const struct option check_options[] = { OPT_BOOLEAN('b', "backtrace", &backtrace, "unwind on error"), OPT_BOOLEAN('a', "uaccess", &uaccess, "enable uaccess checking"), OPT_BOOLEAN('s', "stats", &stats, "print statistics"), - OPT_BOOLEAN('d', "duplicate", &validate_dup, "duplicate validation for vmlinux.o"), + OPT_BOOLEAN(0, "lto", <o, "whole-archive like runs"), OPT_BOOLEAN('n', "noinstr", &noinstr, "noinstr validation for vmlinux.o"), OPT_BOOLEAN('l', "vmlinux", &vmlinux, "vmlinux.o validation"), OPT_BOOLEAN('M', "mcount", &mcount, "generate __mcount_loc"), diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 311bfc6922c1..ae1d4f996803 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3499,6 +3499,11 @@ int check(struct objtool_file *file) { int ret, warnings = 0; + if (lto && !(vmlinux || module)) { + fprintf(stderr, "--lto requires: --vmlinux or --module\n"); + return 1; + } + arch_initial_func_cfi_state(&initial_func_cfi); init_cfi_state(&init_cfi); init_cfi_state(&func_cfi); @@ -3519,7 +3524,7 @@ int check(struct objtool_file *file) if (list_empty(&file->insn_list)) goto out; - if (vmlinux && !validate_dup) { + if (vmlinux && !lto) { ret = validate_vmlinux_functions(file); if (ret < 0) goto out; diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h index 7b4b124b9032..0cbe739ab0c8 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -9,7 +9,7 @@ extern const struct option check_options[]; extern bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, - validate_dup, vmlinux, mcount, noinstr, backup, sls, dryrun; + lto, vmlinux, mcount, noinstr, backup, sls, dryrun; extern int cmd_parse_options(int argc, const char **argv, const char * const usage[]); -- cgit v1.2.3 From ed53a0d971926e484d86cce617ec02a7ee85c3fe Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 8 Mar 2022 16:30:56 +0100 Subject: x86/alternative: Use .ibt_endbr_seal to seal indirect calls Objtool's --ibt option generates .ibt_endbr_seal which lists superfluous ENDBR instructions. That is those instructions for which the function is never indirectly called. Overwrite these ENDBR instructions with a NOP4 such that these function can never be indirect called, reducing the number of viable ENDBR targets in the kernel. Signed-off-by: Peter Zijlstra (Intel) Acked-by: Josh Poimboeuf Link: https://lore.kernel.org/r/20220308154319.822545231@infradead.org --- arch/um/kernel/um_arch.c | 4 ++++ arch/x86/Kconfig | 9 +++++++- arch/x86/include/asm/alternative.h | 1 + arch/x86/include/asm/ibt.h | 12 ++++++++++ arch/x86/kernel/alternative.c | 39 +++++++++++++++++++++++++++++++ arch/x86/kernel/module.c | 8 ++++++- scripts/Makefile.build | 47 ++++++++++++++++++++++++++++++-------- scripts/link-vmlinux.sh | 10 ++++++-- 8 files changed, 117 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index abceeabe29b9..0760e24f2eba 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -424,6 +424,10 @@ void __init check_bugs(void) os_check_bugs(); } +void apply_ibt_endbr(s32 *start, s32 *end) +{ +} + void apply_retpolines(s32 *start, s32 *end) { } diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 19d16c054a96..870e0d10452d 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1873,7 +1873,7 @@ config CC_HAS_IBT config X86_KERNEL_IBT prompt "Indirect Branch Tracking" bool - depends on X86_64 && CC_HAS_IBT + depends on X86_64 && CC_HAS_IBT && STACK_VALIDATION help Build the kernel with support for Indirect Branch Tracking, a hardware support course-grain forward-edge Control Flow Integrity @@ -1881,6 +1881,13 @@ config X86_KERNEL_IBT an ENDBR instruction, as such, the compiler will instrument the code with them to make this happen. + In addition to building the kernel with IBT, seal all functions that + are not indirect call targets, avoiding them ever becomming one. + + This requires LTO like objtool runs and will slow down the build. It + does significantly reduce the number of ENDBR instructions in the + kernel image. + config X86_INTEL_MEMORY_PROTECTION_KEYS prompt "Memory Protection Keys" def_bool y diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 58eee6402832..9b10c8c76087 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -76,6 +76,7 @@ extern int alternatives_patched; extern void alternative_instructions(void); extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end); extern void apply_retpolines(s32 *start, s32 *end); +extern void apply_ibt_endbr(s32 *start, s32 *end); struct module; diff --git a/arch/x86/include/asm/ibt.h b/arch/x86/include/asm/ibt.h index 52fb05d66489..689880eca9ba 100644 --- a/arch/x86/include/asm/ibt.h +++ b/arch/x86/include/asm/ibt.h @@ -46,8 +46,20 @@ static inline __attribute_const__ u32 gen_endbr(void) return endbr; } +static inline __attribute_const__ u32 gen_endbr_poison(void) +{ + /* + * 4 byte NOP that isn't NOP4 (in fact it is OSP NOP3), such that it + * will be unique to (former) ENDBR sites. + */ + return 0x001f0f66; /* osp nopl (%rax) */ +} + static inline bool is_endbr(u32 val) { + if (val == gen_endbr_poison()) + return true; + val &= ~0x01000000U; /* ENDBR32 -> ENDBR64 */ return val == gen_endbr(); } diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 954d39c15724..a79196fd364f 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -115,6 +115,7 @@ static void __init_or_module add_nops(void *insns, unsigned int len) } extern s32 __retpoline_sites[], __retpoline_sites_end[]; +extern s32 __ibt_endbr_seal[], __ibt_endbr_seal_end[]; extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; extern s32 __smp_locks[], __smp_locks_end[]; void text_poke_early(void *addr, const void *opcode, size_t len); @@ -512,6 +513,42 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) { } #endif /* CONFIG_RETPOLINE && CONFIG_STACK_VALIDATION */ +#ifdef CONFIG_X86_KERNEL_IBT + +/* + * Generated by: objtool --ibt + */ +void __init_or_module noinline apply_ibt_endbr(s32 *start, s32 *end) +{ + s32 *s; + + for (s = start; s < end; s++) { + u32 endbr, poison = gen_endbr_poison(); + void *addr = (void *)s + *s; + + if (WARN_ON_ONCE(get_kernel_nofault(endbr, addr))) + continue; + + if (WARN_ON_ONCE(!is_endbr(endbr))) + continue; + + DPRINTK("ENDBR at: %pS (%px)", addr, addr); + + /* + * When we have IBT, the lack of ENDBR will trigger #CP + */ + DUMP_BYTES(((u8*)addr), 4, "%px: orig: ", addr); + DUMP_BYTES(((u8*)&poison), 4, "%px: repl: ", addr); + text_poke_early(addr, &poison, 4); + } +} + +#else + +void __init_or_module noinline apply_ibt_endbr(s32 *start, s32 *end) { } + +#endif /* CONFIG_X86_KERNEL_IBT */ + #ifdef CONFIG_SMP static void alternatives_smp_lock(const s32 *start, const s32 *end, u8 *text, u8 *text_end) @@ -830,6 +867,8 @@ void __init alternative_instructions(void) */ apply_alternatives(__alt_instructions, __alt_instructions_end); + apply_ibt_endbr(__ibt_endbr_seal, __ibt_endbr_seal_end); + #ifdef CONFIG_SMP /* Patch to UP if other cpus not imminent. */ if (!noreplace_smp && (num_present_cpus() == 1 || setup_max_cpus <= 1)) { diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index 96d7c27b7093..58bafbd19b1d 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -253,7 +253,7 @@ int module_finalize(const Elf_Ehdr *hdr, { const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL, *para = NULL, *orc = NULL, *orc_ip = NULL, - *retpolines = NULL; + *retpolines = NULL, *ibt_endbr = NULL; char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { @@ -271,6 +271,8 @@ int module_finalize(const Elf_Ehdr *hdr, orc_ip = s; if (!strcmp(".retpoline_sites", secstrings + s->sh_name)) retpolines = s; + if (!strcmp(".ibt_endbr_seal", secstrings + s->sh_name)) + ibt_endbr = s; } /* @@ -290,6 +292,10 @@ int module_finalize(const Elf_Ehdr *hdr, void *aseg = (void *)alt->sh_addr; apply_alternatives(aseg, aseg + alt->sh_size); } + if (ibt_endbr) { + void *iseg = (void *)ibt_endbr->sh_addr; + apply_ibt_endbr(iseg, iseg + ibt_endbr->sh_size); + } if (locks && text) { void *lseg = (void *)locks->sh_addr; void *tseg = (void *)text->sh_addr; diff --git a/scripts/Makefile.build b/scripts/Makefile.build index a4b89b757287..926d2549a59c 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -86,12 +86,18 @@ ifdef need-builtin targets-for-builtin += $(obj)/built-in.a endif -targets-for-modules := $(patsubst %.o, %.mod, $(filter %.o, $(obj-m))) +targets-for-modules := ifdef CONFIG_LTO_CLANG targets-for-modules += $(patsubst %.o, %.lto.o, $(filter %.o, $(obj-m))) endif +ifdef CONFIG_X86_KERNEL_IBT +targets-for-modules += $(patsubst %.o, %.objtool, $(filter %.o, $(obj-m))) +endif + +targets-for-modules += $(patsubst %.o, %.mod, $(filter %.o, $(obj-m))) + ifdef need-modorder targets-for-modules += $(obj)/modules.order endif @@ -230,6 +236,7 @@ objtool := $(objtree)/tools/objtool/objtool objtool_args = \ $(if $(CONFIG_UNWINDER_ORC),orc generate,check) \ $(if $(part-of-module), --module) \ + $(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt) \ $(if $(CONFIG_FRAME_POINTER),, --no-fp) \ $(if $(CONFIG_GCOV_KERNEL)$(CONFIG_LTO_CLANG), --no-unreachable)\ $(if $(CONFIG_RETPOLINE), --retpoline) \ @@ -237,8 +244,8 @@ objtool_args = \ $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ $(if $(CONFIG_SLS), --sls) -cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@) -cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd) +cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $(@:.objtool=.o)) +cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$(@:.objtool=.o): $$(wildcard $(objtool))' ; } >> $(dot-target).cmd) endif # CONFIG_STACK_VALIDATION @@ -247,6 +254,21 @@ ifdef CONFIG_LTO_CLANG # Skip objtool for LLVM bitcode $(obj)/%.o: objtool-enabled := +# objtool was skipped for LLVM bitcode, run it now that we have compiled +# modules into native code +$(obj)/%.lto.o: objtool-enabled = y +$(obj)/%.lto.o: part-of-module := y + +else ifdef CONFIG_X86_KERNEL_IBT + +# Skip objtool on individual files +$(obj)/%.o: objtool-enabled := + +# instead run objtool on the module as a whole, right before +# the final link pass with the linker script. +$(obj)/%.objtool: objtool-enabled = y +$(obj)/%.objtool: part-of-module := y + else # 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory @@ -292,18 +314,13 @@ ifdef CONFIG_LTO_CLANG # Module .o files may contain LLVM bitcode, compile them into native code # before ELF processing quiet_cmd_cc_lto_link_modules = LTO [M] $@ -cmd_cc_lto_link_modules = \ + cmd_cc_lto_link_modules = \ $(LD) $(ld_flags) -r -o $@ \ $(shell [ -s $(@:.lto.o=.o.symversions) ] && \ echo -T $(@:.lto.o=.o.symversions)) \ --whole-archive $(filter-out FORCE,$^) \ $(cmd_objtool) -# objtool was skipped for LLVM bitcode, run it now that we have compiled -# modules into native code -$(obj)/%.lto.o: objtool-enabled = y -$(obj)/%.lto.o: part-of-module := y - $(obj)/%.lto.o: $(obj)/%.o FORCE $(call if_changed,cc_lto_link_modules) endif @@ -316,6 +333,18 @@ cmd_mod = { \ $(obj)/%.mod: $(obj)/%$(mod-prelink-ext).o FORCE $(call if_changed,mod) +# +# Since objtool will re-write the file it will change the timestamps, therefore +# it is critical that the %.objtool file gets a timestamp *after* objtool runs. +# +# Additionally, care must be had with ordering this rule against the other rules +# that take %.o as a dependency. +# +cmd_objtool_mod = true $(cmd_objtool) ; touch $@ + +$(obj)/%.objtool: $(obj)/%$(mod-prelink-ext).o FORCE + $(call if_changed,objtool_mod) + quiet_cmd_cc_lst_c = MKLST $@ cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \ $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \ diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 9b08dca26f99..f704034ebbe6 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -108,7 +108,9 @@ objtool_link() local objtoolcmd; local objtoolopt; - if is_enabled CONFIG_LTO_CLANG && is_enabled CONFIG_STACK_VALIDATION; then + if is_enabled CONFIG_STACK_VALIDATION && \ + ( is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT ); then + # Don't perform vmlinux validation unless explicitly requested, # but run objtool on vmlinux.o now that we have an object file. if is_enabled CONFIG_UNWINDER_ORC; then @@ -117,6 +119,10 @@ objtool_link() objtoolopt="${objtoolopt} --lto" + if is_enabled CONFIG_X86_KERNEL_IBT; then + objtoolopt="${objtoolopt} --ibt" + fi + if is_enabled CONFIG_FTRACE_MCOUNT_USE_OBJTOOL; then objtoolopt="${objtoolopt} --mcount" fi @@ -168,7 +174,7 @@ vmlinux_link() # skip output file argument shift - if is_enabled CONFIG_LTO_CLANG; then + if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then # Use vmlinux.o instead of performing the slow LTO link again. objs=vmlinux.o libs= -- cgit v1.2.3 From 5bff9632b538d63f61f1c4bba891a8f09f254369 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 25 Feb 2022 12:40:08 +0100 Subject: scripts: get_abi.pl: Fix typo in help message Fix misspelled word in the script. (s/COMAND/COMMAND/). Reviewed-by: Mauro Carvalho Chehab Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/1ff3605db3dead41bbde33fbbff6754900eceead.1645789205.git.michal.simek@xilinx.com Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 47b7eca5b0b7..7437e19ba3ac 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -988,7 +988,7 @@ abi_book.pl - parse the Linux ABI files and produce a ReST book. B [--debug ] [--enable-lineno] [--man] [--help] [--(no-)rst-source] [--dir=] [--show-hints] [--search-string ] - [] + [] Where B can be: -- cgit v1.2.3 From c7500c1b53bfc083e8968cdce13a5a9d1ca9bf83 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 16 Feb 2022 16:24:02 -0800 Subject: um: Allow builds with Clang Add SUBARCH target for Clang+um (which must go last, not alphabetically, so the other SUBARCHes are assigned). Remove open-coded "DEFINE" macro, instead using linux/kbuild.h's version which was updated to use Clang-friendly assembly in commit cf0c3e68aa81 ("kbuild: fix asm-offset generation to work with clang"). Redefine "DEFINE_LONGS" in terms of "COMMENT" and "DEFINE" so that the intended coment actually has useful content. Add a missed "break" to avoid implicit fall-through warnings. This lets me run KUnit tests with Clang: $ ./tools/testing/kunit/kunit.py run --make_options LLVM=1 ... Cc: Jeff Dike Cc: Richard Weinberger Cc: Anton Ivanov Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: Nathan Chancellor Cc: David Gow Cc: linux-um@lists.infradead.org Cc: linux-kbuild@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Cc: kunit-dev@googlegroups.com Cc: llvm@lists.linux.dev Reviewed-by: Nathan Chancellor Link: https://lore.kernel.org/lkml/Yg2YubZxvYvx7%2Fnm@dev-arch.archlinux-ax161/ Tested-by: David Gow Link: https://lore.kernel.org/lkml/CABVgOSk=oFxsbSbQE-v65VwR2+mXeGXDDjzq8t7FShwjJ3+kUg@mail.gmail.com/ Signed-off-by: Kees Cook --- v1: https://lore.kernel.org/lkml/20220217002843.2312603-1-keescook@chromium.org v2: https://lore.kernel.org/lkml/20220224055831.1854786-1-keescook@chromium.org v3: - use kbuild.h to avoid duplication (Masahiro) - fix intended comments (Masahiro) - use SUBARCH (Nathan) --- arch/um/os-Linux/execvp.c | 1 + arch/x86/um/user-offsets.c | 9 ++++----- scripts/Makefile.clang | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/arch/um/os-Linux/execvp.c b/arch/um/os-Linux/execvp.c index 84a0777c2a45..c09a5fd5e225 100644 --- a/arch/um/os-Linux/execvp.c +++ b/arch/um/os-Linux/execvp.c @@ -93,6 +93,7 @@ int execvp_noalloc(char *buf, const char *file, char *const argv[]) up finding no executable we can use, we want to diagnose that we did find one but were denied access. */ got_eacces = 1; + break; case ENOENT: case ESTALE: case ENOTDIR: diff --git a/arch/x86/um/user-offsets.c b/arch/x86/um/user-offsets.c index bae61554abcc..e54a9814ccf1 100644 --- a/arch/x86/um/user-offsets.c +++ b/arch/x86/um/user-offsets.c @@ -8,12 +8,11 @@ #define __FRAME_OFFSETS #include #include +#include -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define DEFINE_LONGS(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) +#define DEFINE_LONGS(sym, val) \ + COMMENT(#val " / sizeof(unsigned long)"); \ + DEFINE(sym, val / sizeof(unsigned long)) void foo(void) { diff --git a/scripts/Makefile.clang b/scripts/Makefile.clang index 51fc23e2e9e5..87285b76adb2 100644 --- a/scripts/Makefile.clang +++ b/scripts/Makefile.clang @@ -10,6 +10,7 @@ CLANG_TARGET_FLAGS_powerpc := powerpc64le-linux-gnu CLANG_TARGET_FLAGS_riscv := riscv64-linux-gnu CLANG_TARGET_FLAGS_s390 := s390x-linux-gnu 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),) -- cgit v1.2.3 From d31ed5d767c0452b4f49846d80a0bfeafa3a4ded Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 18 Mar 2022 12:19:27 +0100 Subject: kbuild: Fixup the IBT kbuild changes Masahiro-san deemed my kbuild changes to support whole module objtool runs too terrible to live and gracefully provided an alternative. Suggested-by: Masahiro Yamada Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/CAK7LNAQ2mYMnOKMQheVi+6byUFE3KEkjm1zcndNUfe0tORGvug@mail.gmail.com --- scripts/Makefile.build | 66 +++++++++++++++----------------------------------- scripts/Makefile.lib | 4 +-- scripts/mod/modpost.c | 12 ++++----- 3 files changed, 27 insertions(+), 55 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 926d2549a59c..2173a6729f30 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -86,18 +86,12 @@ ifdef need-builtin targets-for-builtin += $(obj)/built-in.a endif -targets-for-modules := +targets-for-modules := $(patsubst %.o, %.mod, $(filter %.o, $(obj-m))) -ifdef CONFIG_LTO_CLANG -targets-for-modules += $(patsubst %.o, %.lto.o, $(filter %.o, $(obj-m))) -endif - -ifdef CONFIG_X86_KERNEL_IBT -targets-for-modules += $(patsubst %.o, %.objtool, $(filter %.o, $(obj-m))) +ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) +targets-for-modules += $(patsubst %.o, %.prelink.o, $(filter %.o, $(obj-m))) endif -targets-for-modules += $(patsubst %.o, %.mod, $(filter %.o, $(obj-m))) - ifdef need-modorder targets-for-modules += $(obj)/modules.order endif @@ -244,31 +238,16 @@ objtool_args = \ $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ $(if $(CONFIG_SLS), --sls) -cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $(@:.objtool=.o)) -cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$(@:.objtool=.o): $$(wildcard $(objtool))' ; } >> $(dot-target).cmd) +cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@) +cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd) endif # CONFIG_STACK_VALIDATION -ifdef CONFIG_LTO_CLANG +ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) # Skip objtool for LLVM bitcode $(obj)/%.o: objtool-enabled := -# objtool was skipped for LLVM bitcode, run it now that we have compiled -# modules into native code -$(obj)/%.lto.o: objtool-enabled = y -$(obj)/%.lto.o: part-of-module := y - -else ifdef CONFIG_X86_KERNEL_IBT - -# Skip objtool on individual files -$(obj)/%.o: objtool-enabled := - -# instead run objtool on the module as a whole, right before -# the final link pass with the linker script. -$(obj)/%.objtool: objtool-enabled = y -$(obj)/%.objtool: part-of-module := y - else # 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory @@ -310,19 +289,24 @@ $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE $(call if_changed_rule,cc_o_c) $(call cmd,force_checksrc) -ifdef CONFIG_LTO_CLANG +ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) # Module .o files may contain LLVM bitcode, compile them into native code # before ELF processing -quiet_cmd_cc_lto_link_modules = LTO [M] $@ - cmd_cc_lto_link_modules = \ +quiet_cmd_cc_prelink_modules = LD [M] $@ + cmd_cc_prelink_modules = \ $(LD) $(ld_flags) -r -o $@ \ - $(shell [ -s $(@:.lto.o=.o.symversions) ] && \ - echo -T $(@:.lto.o=.o.symversions)) \ + $(shell [ -s $(@:.prelink.o=.o.symversions) ] && \ + echo -T $(@:.prelink.o=.o.symversions)) \ --whole-archive $(filter-out FORCE,$^) \ $(cmd_objtool) -$(obj)/%.lto.o: $(obj)/%.o FORCE - $(call if_changed,cc_lto_link_modules) +# objtool was skipped for LLVM bitcode, run it now that we have compiled +# modules into native code +$(obj)/%.prelink.o: objtool-enabled = y +$(obj)/%.prelink.o: part-of-module := y + +$(obj)/%.prelink.o: $(obj)/%.o FORCE + $(call if_changed,cc_prelink_modules) endif cmd_mod = { \ @@ -333,18 +317,6 @@ cmd_mod = { \ $(obj)/%.mod: $(obj)/%$(mod-prelink-ext).o FORCE $(call if_changed,mod) -# -# Since objtool will re-write the file it will change the timestamps, therefore -# it is critical that the %.objtool file gets a timestamp *after* objtool runs. -# -# Additionally, care must be had with ordering this rule against the other rules -# that take %.o as a dependency. -# -cmd_objtool_mod = true $(cmd_objtool) ; touch $@ - -$(obj)/%.objtool: $(obj)/%$(mod-prelink-ext).o FORCE - $(call if_changed,objtool_mod) - quiet_cmd_cc_lst_c = MKLST $@ cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \ $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \ @@ -498,7 +470,7 @@ $(obj)/lib.a: $(lib-y) FORCE # Do not replace $(filter %.o,^) with $(real-prereqs). When a single object # module is turned into a multi object module, $^ will contain header file # dependencies recorded in the .*.cmd file. -ifdef CONFIG_LTO_CLANG +ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) quiet_cmd_link_multi-m = AR [M] $@ cmd_link_multi-m = \ $(cmd_update_lto_symversions); \ diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 79be57fdd32a..8bfc9238237c 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -230,11 +230,11 @@ dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \ $(addprefix -I,$(DTC_INCLUDE)) \ -undef -D__DTS__ -ifeq ($(CONFIG_LTO_CLANG),y) +ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) # With CONFIG_LTO_CLANG, .o files in modules might be LLVM bitcode, so we # need to run LTO to compile them into native code (.lto.o) before further # processing. -mod-prelink-ext := .lto +mod-prelink-ext := .prelink endif # Useful for describing the dependency of composite objects diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 6bfa33217914..09c3ab0a9b37 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1989,9 +1989,9 @@ static char *remove_dot(char *s) if (m && (s[n + m] == '.' || s[n + m] == 0)) s[n] = 0; - /* strip trailing .lto */ - if (strends(s, ".lto")) - s[strlen(s) - 4] = '\0'; + /* strip trailing .prelink */ + if (strends(s, ".prelink")) + s[strlen(s) - 8] = '\0'; } return s; } @@ -2015,9 +2015,9 @@ static void read_symbols(const char *modname) /* strip trailing .o */ tmp = NOFAIL(strdup(modname)); tmp[strlen(tmp) - 2] = '\0'; - /* strip trailing .lto */ - if (strends(tmp, ".lto")) - tmp[strlen(tmp) - 4] = '\0'; + /* strip trailing .prelink */ + if (strends(tmp, ".prelink")) + tmp[strlen(tmp) - 8] = '\0'; mod = new_module(tmp); free(tmp); } -- cgit v1.2.3 From 2b76e68d7249f2f209b3ee3d15e8a2fb805220a3 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 22 Mar 2022 14:38:36 -0700 Subject: scripts/spelling.txt: add more spellings to spelling.txt Some of the more common spelling mistakes and typos that I've found while fixing up spelling mistakes in the kernel in the past four months. Link: https://lkml.kernel.org/r/20220216152343.105546-1-colin.i.king@gmail.com Signed-off-by: Colin Ian King Cc: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/spelling.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'scripts') diff --git a/scripts/spelling.txt b/scripts/spelling.txt index 0c8b79cfb1bb..8435b99452b6 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -180,6 +180,7 @@ asuming||assuming asycronous||asynchronous asychronous||asynchronous asynchnous||asynchronous +asynchronus||asynchronous asynchromous||asynchronous asymetric||asymmetric asymmeric||asymmetric @@ -231,6 +232,7 @@ baloons||balloons bandwith||bandwidth banlance||balance batery||battery +battey||battery beacuse||because becasue||because becomming||becoming @@ -333,6 +335,7 @@ commoditiy||commodity comsume||consume comsumer||consumer comsuming||consuming +comaptible||compatible compability||compatibility compaibility||compatibility comparsion||comparison @@ -353,7 +356,9 @@ compoment||component comppatible||compatible compres||compress compresion||compression +compresser||compressor comression||compression +comsumed||consumed comunicate||communicate comunication||communication conbination||combination @@ -530,6 +535,7 @@ dissconect||disconnect distiction||distinction divisable||divisible divsiors||divisors +dsiabled||disabled docuentation||documentation documantation||documentation documentaion||documentation @@ -677,6 +683,7 @@ frequence||frequency frequncy||frequency frequancy||frequency frome||from +fronend||frontend fucntion||function fuction||function fuctions||functions @@ -761,6 +768,7 @@ implmentation||implementation implmenting||implementing incative||inactive incomming||incoming +incompaitiblity||incompatibility incompatabilities||incompatibilities incompatable||incompatible incompatble||incompatible @@ -942,6 +950,7 @@ metdata||metadata micropone||microphone microprocesspr||microprocessor migrateable||migratable +millenium||millennium milliseonds||milliseconds minium||minimum minimam||minimum @@ -1007,6 +1016,7 @@ notity||notify nubmer||number numebr||number numner||number +nunber||number obtaion||obtain obusing||abusing occassionally||occasionally @@ -1136,6 +1146,7 @@ preprare||prepare pressre||pressure presuambly||presumably previosuly||previously +previsously||previously primative||primitive princliple||principle priorty||priority @@ -1297,6 +1308,7 @@ routins||routines rquest||request runing||running runned||ran +runnnig||running runnning||running runtine||runtime sacrifying||sacrificing @@ -1353,6 +1365,7 @@ similiar||similar simlar||similar simliar||similar simpified||simplified +simultanous||simultaneous singaled||signaled singal||signal singed||signed @@ -1461,6 +1474,7 @@ syste||system sytem||system sythesis||synthesis taht||that +tained||tainted tansmit||transmit targetted||targeted targetting||targeting @@ -1489,6 +1503,7 @@ timout||timeout tmis||this toogle||toggle torerable||tolerable +torlence||tolerance traget||target traking||tracking tramsmitted||transmitted @@ -1503,6 +1518,7 @@ transferd||transferred transfered||transferred transfering||transferring transision||transition +transistioned||transitioned transmittd||transmitted transormed||transformed trasfer||transfer -- cgit v1.2.3 From 6e8f42dc9c8548c6b37566f3b8bda1873700c4a6 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 23 Mar 2022 16:05:56 -0700 Subject: checkpatch: prefer MODULE_LICENSE("GPL") over MODULE_LICENSE("GPL v2") There is no effective difference. Given the large number of uses of "GPL v2", emit this message only for patches as a trivial treeside sed could be done one day. Ref: commit bf7fbeeae6db ("module: Cure the MODULE_LICENSE "GPL" vs. "GPL v2" bogosity") Link: https://lkml.kernel.org/r/20220128185924.80137-1-joe@perches.com Signed-off-by: Joe Perches Cc: Dwaipayan Ray Cc: Lukas Bulwahn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index b01c36a15d9d..b7c181ea0ac5 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -7418,6 +7418,13 @@ sub process { WARN("MODULE_LICENSE", "unknown module license " . $extracted_string . "\n" . $herecurr); } + if (!$file && $extracted_string eq '"GPL v2"') { + if (WARN("MODULE_LICENSE", + "Prefer \"GPL\" over \"GPL v2\" - see commit bf7fbeeae6db (\"module: Cure the MODULE_LICENSE \"GPL\" vs. \"GPL v2\" bogosity\")\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\bMODULE_LICENSE\s*\(\s*"GPL v2"\s*\)/MODULE_LICENSE("GPL")/; + } + } } # check for sysctl duplicate constants -- cgit v1.2.3 From 481efd7bd6f28febddf189e7a970bb0bc5a53de8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 23 Mar 2022 16:05:59 -0700 Subject: checkpatch: add --fix option for some TRAILING_STATEMENTS Single line code like: if (foo) bar; should generally be written: if (foo) bar; Add a --fix test to do so. This fix is not done when an ASSIGN_IN_IF in the same line exists. Link: https://lkml.kernel.org/r/20220128185924.80137-2-joe@perches.com Signed-off-by: Joe Perches Cc: Dwaipayan Ray Cc: Lukas Bulwahn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index b7c181ea0ac5..046a018093a7 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -5551,6 +5551,7 @@ sub process { defined($stat) && defined($cond) && $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { my ($s, $c) = ($stat, $cond); + my $fixed_assign_in_if = 0; if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { if (ERROR("ASSIGN_IN_IF", @@ -5575,6 +5576,7 @@ sub process { $newline .= ')'; $newline .= " {" if (defined($brace)); fix_insert_line($fixlinenr + 1, $newline); + $fixed_assign_in_if = 1; } } } @@ -5598,8 +5600,20 @@ sub process { $stat_real = "[...]\n$stat_real"; } - ERROR("TRAILING_STATEMENTS", - "trailing statements should be on next line\n" . $herecurr . $stat_real); + if (ERROR("TRAILING_STATEMENTS", + "trailing statements should be on next line\n" . $herecurr . $stat_real) && + !$fixed_assign_in_if && + $cond_lines == 0 && + $fix && $perl_version_ok && + $fixed[$fixlinenr] =~ /^\+(\s*)((?:if|while|for)\s*$balanced_parens)\s*(.*)$/) { + my $indent = $1; + my $test = $2; + my $rest = rtrim($4); + if ($rest =~ /;$/) { + $fixed[$fixlinenr] = "\+$indent$test"; + fix_insert_line($fixlinenr + 1, "$indent\t$rest"); + } + } } } -- cgit v1.2.3 From 05dc40e694e0ff527011d0b09542f08da60e28cc Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 23 Mar 2022 16:06:02 -0700 Subject: checkpatch: add early_param exception to blank line after struct/function test Add early_param as another exception to the blank line preferred after function/struct/union declaration or definition test. Link: https://lkml.kernel.org/r/3bd6ada59f411a7685d7e64eeb670540d4bfdcde.camel@perches.com Signed-off-by: Joe Perches Cc: Dwaipayan Ray Cc: Lukas Bulwahn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- 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 046a018093a7..2653177f52d9 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3926,7 +3926,7 @@ sub process { if ($prevline =~ /^[\+ ]};?\s*$/ && $line =~ /^\+/ && !($line =~ /^\+\s*$/ || - $line =~ /^\+\s*EXPORT_SYMBOL/ || + $line =~ /^\+\s*(?:EXPORT_SYMBOL|early_param)/ || $line =~ /^\+\s*MODULE_/i || $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || $line =~ /^\+[a-z_]*init/ || -- cgit v1.2.3 From c882c6b1cb3105d378768aa168d2283f50b6e304 Mon Sep 17 00:00:00 2001 From: Sagar Patel Date: Wed, 23 Mar 2022 16:06:05 -0700 Subject: checkpatch: use python3 to find codespell dictionary Commit 0ee3e7b8893e ("checkpatch: get default codespell dictionary path from package location") introduced the ability to search for the codespell dictionary rather than hardcoding its path. codespell requires Python 3.6 or above, but on some systems, the python executable is a Python 2.7 interpreter. In this case, searching for the dictionary fails, subsequently making codespell fail: No codespell typos will be found - file '/usr/share/codespell/dictionary.txt': No such file or directory So, use python3 to remove ambiguity. In addition, when searching for dictionary.txt, do not check if the codespell executable exists since, - checkpatch.pl only uses dictionary.txt, not the codespell executable. - codespell can be installed via a Python package manager, in which case the codespell executable may not be present in a typical $PATH, but a dictionary does exist. Link: https://lkml.kernel.org/r/20220309180048.147672-1-sagarmp@cs.unc.edu Signed-off-by: Sagar Patel Reviewed-by: Peter Ujfalusi Cc: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 2653177f52d9..577e02998701 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -334,7 +334,7 @@ if ($user_codespellfile) { } elsif (!(-f $codespellfile)) { # If /usr/share/codespell/dictionary.txt is not present, try to find it # under codespell's install directory: /data/dictionary.txt - if (($codespell || $help) && which("codespell") ne "" && which("python") ne "") { + if (($codespell || $help) && which("python3") ne "") { my $python_codespell_dict = << "EOF"; import os.path as op @@ -344,7 +344,7 @@ codespell_file = op.join(codespell_dir, 'data', 'dictionary.txt') print(codespell_file, end='') EOF - my $codespell_dict = `python -c "$python_codespell_dict" 2> /dev/null`; + my $codespell_dict = `python3 -c "$python_codespell_dict" 2> /dev/null`; $codespellfile = $codespell_dict if (-f $codespell_dict); } } -- cgit v1.2.3 From 01096e5cfe3ce5b26ccc933ad20401e24074a76a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 26 Mar 2022 11:27:19 +0100 Subject: scripts/get_feat.pl: allow output the parsed file names Such output could be helpful while debugging it, but its main goal is to tell kernel_feat.py about what files were used by the script. Thie way, kernel_feat.py can add those as documentation dependencies. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/11b438ee01e00c866f5ea197d6aecc26e9f86945.1648290305.git.mchehab@kernel.org Signed-off-by: Jonathan Corbet --- scripts/get_feat.pl | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'scripts') diff --git a/scripts/get_feat.pl b/scripts/get_feat.pl index 457712355676..76cfb96b59b6 100755 --- a/scripts/get_feat.pl +++ b/scripts/get_feat.pl @@ -13,6 +13,7 @@ my $man; my $debug; my $arch; my $feat; +my $enable_fname; my $basename = abs_path($0); $basename =~ s,/[^/]+$,/,; @@ -31,6 +32,7 @@ GetOptions( 'arch=s' => \$arch, 'feat=s' => \$feat, 'feature=s' => \$feat, + "enable-fname" => \$enable_fname, man => \$man ) or pod2usage(2); @@ -95,6 +97,10 @@ sub parse_feat { return if ($file =~ m,($prefix)/arch-support.txt,); return if (!($file =~ m,arch-support.txt$,)); + if ($enable_fname) { + printf ".. FILE %s\n", abs_path($file); + } + my $subsys = ""; $subsys = $2 if ( m,.*($prefix)/([^/]+).*,); @@ -580,6 +586,11 @@ Output features for a single specific feature. Changes the location of the Feature files. By default, it uses the Documentation/features directory. +=item B<--enable-fname> + +Prints the file name of the feature files. This can be used in order to +track dependencies during documentation build. + =item B<--debug> Put the script in verbose mode, useful for debugging. Can be called multiple -- cgit v1.2.3 From 92b6de17b21cf74448d2397ef92d5ca856c6419f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 26 Mar 2022 11:27:23 +0100 Subject: scripts/get_abi: change the file/line number meta info In order to make it more standard and ReST compatible, change the meta-tag used with --enable-lineno from: #define LINENO to .. LINENO In practice, no functional changes. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/125ffd31fbc77ad9eee4d6906e1830b8162fa6ca.1648290305.git.mchehab@kernel.org Signed-off-by: Jonathan Corbet --- Documentation/sphinx/kernel_abi.py | 2 +- scripts/get_abi.pl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/Documentation/sphinx/kernel_abi.py b/Documentation/sphinx/kernel_abi.py index efab9b14a9f5..b5feb5b1d905 100644 --- a/Documentation/sphinx/kernel_abi.py +++ b/Documentation/sphinx/kernel_abi.py @@ -138,7 +138,7 @@ class KernelCmd(Directive): code_block += "\n " + l lines = code_block + "\n\n" - line_regex = re.compile("^#define LINENO (\S+)\#([0-9]+)$") + line_regex = re.compile("^\.\. LINENO (\S+)\#([0-9]+)$") ln = 0 n = 0 f = fname diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 6212f58b69c6..25836ac0a33d 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -326,7 +326,7 @@ sub output_rest { my @filepath = split / /, $data{$what}->{filepath}; if ($enable_lineno) { - printf "#define LINENO %s%s#%s\n\n", + printf ".. LINENO %s%s#%s\n\n", $prefix, $file[0], $data{$what}->{line_no}; } @@ -1022,7 +1022,7 @@ logic (B<--no-rst-source>). =item B<--enable-lineno> -Enable output of #define LINENO lines. +Enable output of .. LINENO lines. =item B<--debug> I -- cgit v1.2.3 From b79dfef0e2fcf41c736e7012c59d1260aa60f075 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 26 Mar 2022 11:27:24 +0100 Subject: scripts/kernel-doc: change the line number meta info In order to make it more standard and ReST compatible, change the meta-tag used with --enable-lineno from: #define LINENO to .. LINENO In practice, no functional changes. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/40725032b5a4a33db740bf1de397523af958ff8a.1648290305.git.mchehab@kernel.org Signed-off-by: Jonathan Corbet --- Documentation/sphinx/kerneldoc.py | 2 +- scripts/kernel-doc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/Documentation/sphinx/kerneldoc.py b/Documentation/sphinx/kerneldoc.py index 8189c33b9dda..9395892c7ba3 100644 --- a/Documentation/sphinx/kerneldoc.py +++ b/Documentation/sphinx/kerneldoc.py @@ -130,7 +130,7 @@ class KernelDocDirective(Directive): result = ViewList() lineoffset = 0; - line_regex = re.compile("^#define LINENO ([0-9]+)$") + line_regex = re.compile("^\.\. LINENO ([0-9]+)$") for line in lines: match = line_regex.search(line) if match: diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 9c084a2ba3b0..7516949bb049 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -424,7 +424,7 @@ sub get_kernel_version() { sub print_lineno { my $lineno = shift; if ($enable_lineno && defined($lineno)) { - print "#define LINENO " . $lineno . "\n"; + print ".. LINENO " . $lineno . "\n"; } } ## @@ -2478,7 +2478,7 @@ May be specified multiple times. =item -enable-lineno -Enable output of #define LINENO lines. +Enable output of .. LINENO lines. =back -- cgit v1.2.3 From 69304379ff036ce8ecf41efc2aeea4b29dd0c43f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 6 Mar 2022 16:25:35 +0900 Subject: fixdep: use fflush() and ferror() to ensure successful write to files Currently, fixdep checks the return value from (v)printf(), but it does not ensure the complete write to the .cmd file. printf() just writes data to the internal buffer, which usually succeeds. (Of course, it may fail for another reason, for example when the file descriptor is closed, but that is another story.) When the buffer (4k?) is full, an actual write occurs, and printf() may really fail. One of typical cases is "No space left on device" when the disk is full. The data remaining in the buffer will be pushed out to the file when the program exits, but we never know if it is successful. One straight-forward fix would be to add the following code at the end of the program. ret = fflush(stdout); if (ret < 0) { /* error handling */ } However, it is tedious to check the return code in all the call sites of printf(), fflush(), fclose(), and whatever can cause actual writes to the end device. Doing that lets the program bail out at the first failure but is usually not worth the effort. Instead, let's check the error status from ferror(). This is 'sticky', so you need to check it just once. You still need to call fflush(). Signed-off-by: Masahiro Yamada Reviewed-by: David Laight Reviewed-by: Nick Desaulniers --- scripts/basic/fixdep.c | 46 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) (limited to 'scripts') diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 44e887cff49b..2328f9a641da 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -105,25 +105,6 @@ static void usage(void) exit(1); } -/* - * In the intended usage of this program, the stdout is redirected to .*.cmd - * files. The return value of printf() must be checked to catch any error, - * e.g. "No space left on device". - */ -static void xprintf(const char *format, ...) -{ - va_list ap; - int ret; - - va_start(ap, format); - ret = vprintf(format, ap); - if (ret < 0) { - perror("fixdep"); - exit(1); - } - va_end(ap); -} - struct item { struct item *next; unsigned int len; @@ -189,7 +170,7 @@ static void use_config(const char *m, int slen) define_config(m, slen, hash); /* Print out a dependency path from a symbol name. */ - xprintf(" $(wildcard include/config/%.*s) \\\n", slen, m); + printf(" $(wildcard include/config/%.*s) \\\n", slen, m); } /* test if s ends in sub */ @@ -318,13 +299,13 @@ static void parse_dep_file(char *m, const char *target) */ if (!saw_any_target) { saw_any_target = 1; - xprintf("source_%s := %s\n\n", - target, m); - xprintf("deps_%s := \\\n", target); + printf("source_%s := %s\n\n", + target, m); + printf("deps_%s := \\\n", target); } is_first_dep = 0; } else { - xprintf(" %s \\\n", m); + printf(" %s \\\n", m); } buf = read_file(m); @@ -347,8 +328,8 @@ static void parse_dep_file(char *m, const char *target) exit(1); } - xprintf("\n%s: $(deps_%s)\n\n", target, target); - xprintf("$(deps_%s):\n", target); + printf("\n%s: $(deps_%s)\n\n", target, target); + printf("$(deps_%s):\n", target); } int main(int argc, char *argv[]) @@ -363,11 +344,22 @@ int main(int argc, char *argv[]) target = argv[2]; cmdline = argv[3]; - xprintf("cmd_%s := %s\n\n", target, cmdline); + printf("cmd_%s := %s\n\n", target, cmdline); buf = read_file(depfile); parse_dep_file(buf, target); free(buf); + fflush(stdout); + + /* + * In the intended usage, the stdout is redirected to .*.cmd files. + * Call ferror() to catch errors such as "No space left on device". + */ + if (ferror(stdout)) { + fprintf(stderr, "fixdep: not all data was written to the output\n"); + exit(1); + } + return 0; } -- cgit v1.2.3 From b6ad541697ea9a673b838533a7f8c45b24b0275e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 29 Mar 2022 00:07:10 +0900 Subject: kconfig: remove stale comment about removed kconfig_print_symbol() This comment is about kconfig_print_symbol(), which was removed by commit 6ce45a91a982 ("kconfig: refactor conf_write_symbol()"). Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 901835a56e89..c4340c90e172 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -658,13 +658,6 @@ static char *escape_string_value(const char *in) return out; } -/* - * Kconfig configuration printer - * - * This printer is used when generating the resulting configuration after - * kconfig invocation and `defconfig' files. Unset symbol might be omitted by - * passing a non-NULL argument to the printer. - */ enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE }; static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n, -- cgit v1.2.3 From 099c22bdca406733c80f3d34ea2d2554bd15fb16 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 29 Mar 2022 11:14:36 +0900 Subject: kbuild: fix empty ${PYTHON} in scripts/link-vmlinux.sh The two commits d8d2d38275c1 ("kbuild: remove PYTHON variable") a8cccdd95473 ("init: lto: ensure initcall ordering") were applied in the same development cycle, into two different trees. After they were merged together, this ${PYTHON} expands to an empty string. Therefore, ${srctree}/scripts/jobserver-exec is executed directly. (it has the executable bit set) This is working but let's fix the code into the intended form. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Reviewed-by: Sedat Dilek --- 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 f704034ebbe6..20f44504a644 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -50,7 +50,7 @@ gen_initcalls() { info GEN .tmp_initcalls.lds - ${PYTHON} ${srctree}/scripts/jobserver-exec \ + ${PYTHON3} ${srctree}/scripts/jobserver-exec \ ${PERL} ${srctree}/scripts/generate_initcall_order.pl \ ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS} \ > .tmp_initcalls.lds -- cgit v1.2.3 From bf5c0c2231bcab677e5cdfb7f73e6c79f6d8c2d4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 2 Apr 2022 00:56:10 +0900 Subject: modpost: restore the warning message for missing symbol versions This log message was accidentally chopped off. I was wondering why this happened, but checking the ML log, Mark precisely followed my suggestion [1]. I just used "..." because I was too lazy to type the sentence fully. Sorry for the confusion. [1]: https://lore.kernel.org/all/CAK7LNAR6bXXk9-ZzZYpTqzFqdYbQsZHmiWspu27rtsFxvfRuVA@mail.gmail.com/ Fixes: 4a6795933a89 ("kbuild: modpost: Explicitly warn about unprototyped symbols") Signed-off-by: Masahiro Yamada Acked-by: Mark Brown Reviewed-by: Nick Desaulniers --- 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 d10f93aac1c8..ed9d056d2108 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -674,7 +674,7 @@ static void handle_modversion(const struct module *mod, unsigned int crc; if (sym->st_shndx == SHN_UNDEF) { - warn("EXPORT symbol \"%s\" [%s%s] version ...\n" + warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n" "Is \"%s\" prototyped in ?\n", symname, mod->name, mod->is_vmlinux ? "" : ".ko", symname); -- cgit v1.2.3 From dbae0a934f09208075ec3e73491bd0844e1397b3 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Thu, 27 Jan 2022 12:56:23 +0100 Subject: x86/cpu: Remove CONFIG_X86_SMAP and "nosmap" Those were added as part of the SMAP enablement but SMAP is currently an integral part of kernel proper and there's no need to disable it anymore. Rip out that functionality. Leave --uaccess default on for objtool as this is what objtool should do by default anyway. If still needed - clearcpuid=smap. Signed-off-by: Borislav Petkov Reviewed-by: Lai Jiangshan Reviewed-by: Kees Cook Link: https://lore.kernel.org/r/20220127115626.14179-4-bp@alien8.de --- Documentation/admin-guide/kernel-parameters.txt | 2 +- Documentation/x86/cpuinfo.rst | 5 ++--- arch/x86/Kconfig | 11 ----------- arch/x86/include/asm/disabled-features.h | 8 +------- arch/x86/include/asm/smap.h | 24 ------------------------ arch/x86/kernel/cpu/common.c | 15 +-------------- scripts/Makefile.build | 2 +- scripts/link-vmlinux.sh | 6 +++--- tools/arch/x86/include/asm/disabled-features.h | 8 +------- 9 files changed, 10 insertions(+), 71 deletions(-) (limited to 'scripts') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index a9f3d3158e77..e0bb710f0fa9 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -3461,7 +3461,7 @@ noexec=on: enable non-executable mappings (default) noexec=off: disable non-executable mappings - nosmap [X86,PPC] + nosmap [PPC] Disable SMAP (Supervisor Mode Access Prevention) even if it is supported by processor. diff --git a/Documentation/x86/cpuinfo.rst b/Documentation/x86/cpuinfo.rst index 5d54c39a063f..12fbe2b1e98a 100644 --- a/Documentation/x86/cpuinfo.rst +++ b/Documentation/x86/cpuinfo.rst @@ -140,9 +140,8 @@ from #define X86_FEATURE_UMIP (16*32 + 2). In addition, there exists a variety of custom command-line parameters that disable specific features. The list of parameters includes, but is not limited -to, nofsgsbase, nosmap, and nosmep. 5-level paging can also be disabled using -"no5lvl". SMAP and SMEP are disabled with the aforementioned parameters, -respectively. +to, nofsgsbase, and nosmep. 5-level paging can also be disabled using +"no5lvl". SMEP is disabled with the aforementioned parameter. e: The feature was known to be non-functional. ---------------------------------------------- diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index b0142e01002e..5bc8bee64bb0 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1816,17 +1816,6 @@ config ARCH_RANDOM If supported, this is a high bandwidth, cryptographically secure hardware random number generator. -config X86_SMAP - def_bool y - prompt "Supervisor Mode Access Prevention" if EXPERT - help - Supervisor Mode Access Prevention (SMAP) is a security - feature in newer Intel processors. There is a small - performance cost if this enabled and turned on; there is - also a small increase in the kernel size if this is enabled. - - If unsure, say Y. - config X86_UMIP def_bool y prompt "User Mode Instruction Prevention" if EXPERT diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h index 1231d63f836d..1ae0fab7d902 100644 --- a/arch/x86/include/asm/disabled-features.h +++ b/arch/x86/include/asm/disabled-features.h @@ -10,12 +10,6 @@ * cpu_feature_enabled(). */ -#ifdef CONFIG_X86_SMAP -# define DISABLE_SMAP 0 -#else -# define DISABLE_SMAP (1<<(X86_FEATURE_SMAP & 31)) -#endif - #ifdef CONFIG_X86_UMIP # define DISABLE_UMIP 0 #else @@ -80,7 +74,7 @@ #define DISABLED_MASK6 0 #define DISABLED_MASK7 (DISABLE_PTI) #define DISABLED_MASK8 0 -#define DISABLED_MASK9 (DISABLE_SMAP|DISABLE_SGX) +#define DISABLED_MASK9 (DISABLE_SGX) #define DISABLED_MASK10 0 #define DISABLED_MASK11 0 #define DISABLED_MASK12 0 diff --git a/arch/x86/include/asm/smap.h b/arch/x86/include/asm/smap.h index d17b39893b79..bab490379c65 100644 --- a/arch/x86/include/asm/smap.h +++ b/arch/x86/include/asm/smap.h @@ -19,25 +19,14 @@ #ifdef __ASSEMBLY__ -#ifdef CONFIG_X86_SMAP - #define ASM_CLAC \ ALTERNATIVE "", __ASM_CLAC, X86_FEATURE_SMAP #define ASM_STAC \ ALTERNATIVE "", __ASM_STAC, X86_FEATURE_SMAP -#else /* CONFIG_X86_SMAP */ - -#define ASM_CLAC -#define ASM_STAC - -#endif /* CONFIG_X86_SMAP */ - #else /* __ASSEMBLY__ */ -#ifdef CONFIG_X86_SMAP - static __always_inline void clac(void) { /* Note: a barrier is implicit in alternative() */ @@ -76,19 +65,6 @@ static __always_inline void smap_restore(unsigned long flags) #define ASM_STAC \ ALTERNATIVE("", __ASM_STAC, X86_FEATURE_SMAP) -#else /* CONFIG_X86_SMAP */ - -static inline void clac(void) { } -static inline void stac(void) { } - -static inline unsigned long smap_save(void) { return 0; } -static inline void smap_restore(unsigned long flags) { } - -#define ASM_CLAC -#define ASM_STAC - -#endif /* CONFIG_X86_SMAP */ - #endif /* __ASSEMBLY__ */ #endif /* _ASM_X86_SMAP_H */ diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c71d1075db93..747df070fb5e 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -382,13 +382,6 @@ static __always_inline void setup_smep(struct cpuinfo_x86 *c) cr4_set_bits(X86_CR4_SMEP); } -static __init int setup_disable_smap(char *arg) -{ - setup_clear_cpu_cap(X86_FEATURE_SMAP); - return 1; -} -__setup("nosmap", setup_disable_smap); - static __always_inline void setup_smap(struct cpuinfo_x86 *c) { unsigned long eflags = native_save_fl(); @@ -396,14 +389,8 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c) /* This should have been cleared long ago */ BUG_ON(eflags & X86_EFLAGS_AC); - if (cpu_has(c, X86_FEATURE_SMAP)) { -#ifdef CONFIG_X86_SMAP + if (cpu_has(c, X86_FEATURE_SMAP)) cr4_set_bits(X86_CR4_SMAP); -#else - clear_cpu_cap(c, X86_FEATURE_SMAP); - cr4_clear_bits(X86_CR4_SMAP); -#endif - } } static __always_inline void setup_umip(struct cpuinfo_x86 *c) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 9717e6f6fb31..7e7aa1d030a6 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -233,7 +233,7 @@ objtool_args = \ $(if $(CONFIG_FRAME_POINTER),, --no-fp) \ $(if $(CONFIG_GCOV_KERNEL)$(CONFIG_LTO_CLANG), --no-unreachable)\ $(if $(CONFIG_RETPOLINE), --retpoline) \ - $(if $(CONFIG_X86_SMAP), --uaccess) \ + --uaccess \ $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ $(if $(CONFIG_SLS), --sls) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 20f44504a644..3a2fffdf49d4 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -146,9 +146,9 @@ objtool_link() if is_enabled CONFIG_RETPOLINE; then objtoolopt="${objtoolopt} --retpoline" fi - if is_enabled CONFIG_X86_SMAP; then - objtoolopt="${objtoolopt} --uaccess" - fi + + objtoolopt="${objtoolopt} --uaccess" + if is_enabled CONFIG_SLS; then objtoolopt="${objtoolopt} --sls" fi diff --git a/tools/arch/x86/include/asm/disabled-features.h b/tools/arch/x86/include/asm/disabled-features.h index 1231d63f836d..1ae0fab7d902 100644 --- a/tools/arch/x86/include/asm/disabled-features.h +++ b/tools/arch/x86/include/asm/disabled-features.h @@ -10,12 +10,6 @@ * cpu_feature_enabled(). */ -#ifdef CONFIG_X86_SMAP -# define DISABLE_SMAP 0 -#else -# define DISABLE_SMAP (1<<(X86_FEATURE_SMAP & 31)) -#endif - #ifdef CONFIG_X86_UMIP # define DISABLE_UMIP 0 #else @@ -80,7 +74,7 @@ #define DISABLED_MASK6 0 #define DISABLED_MASK7 (DISABLE_PTI) #define DISABLED_MASK8 0 -#define DISABLED_MASK9 (DISABLE_SMAP|DISABLE_SGX) +#define DISABLED_MASK9 (DISABLE_SGX) #define DISABLED_MASK10 0 #define DISABLED_MASK11 0 #define DISABLED_MASK12 0 -- cgit v1.2.3 From d5ea4fece4508bf8e72b659cd22fa4840d8d61e5 Mon Sep 17 00:00:00 2001 From: Chun-Tse Shao Date: Fri, 1 Apr 2022 23:18:02 +0000 Subject: kbuild: Allow kernel installation packaging to override pkg-config Add HOSTPKG_CONFIG to allow tooling that builds the kernel to override what pkg-config and parameters are used. Signed-off-by: Chun-Tse Shao Reviewed-by: Nick Desaulniers Signed-off-by: Masahiro Yamada --- Makefile | 3 ++- certs/Makefile | 4 ++-- scripts/Makefile | 4 ++-- scripts/kconfig/gconf-cfg.sh | 12 ++++++------ scripts/kconfig/mconf-cfg.sh | 16 ++++++++-------- scripts/kconfig/nconf-cfg.sh | 16 ++++++++-------- scripts/kconfig/qconf-cfg.sh | 14 +++++++------- tools/objtool/Makefile | 4 ++-- 8 files changed, 37 insertions(+), 36 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 8c7de9a72ea2..d9336e783be3 100644 --- a/Makefile +++ b/Makefile @@ -436,6 +436,7 @@ else HOSTCC = gcc HOSTCXX = g++ endif +HOSTPKG_CONFIG = pkg-config KBUILD_USERHOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ -O2 -fomit-frame-pointer -std=gnu11 \ @@ -533,7 +534,7 @@ KBUILD_LDFLAGS_MODULE := KBUILD_LDFLAGS := CLANG_FLAGS := -export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC +export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD diff --git a/certs/Makefile b/certs/Makefile index d8443cfb1c40..e4a0488133f0 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -74,5 +74,5 @@ targets += x509_revocation_list hostprogs := extract-cert -HOSTCFLAGS_extract-cert.o = $(shell pkg-config --cflags libcrypto 2> /dev/null) -HOSTLDLIBS_extract-cert = $(shell pkg-config --libs libcrypto 2> /dev/null || echo -lcrypto) +HOSTCFLAGS_extract-cert.o = $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /dev/null) +HOSTLDLIBS_extract-cert = $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/null || echo -lcrypto) diff --git a/scripts/Makefile b/scripts/Makefile index ce5aa9030b74..f084f08ed176 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -14,8 +14,8 @@ hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include HOSTLDLIBS_sorttable = -lpthread HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include -HOSTCFLAGS_sign-file.o = $(shell pkg-config --cflags libcrypto 2> /dev/null) -HOSTLDLIBS_sign-file = $(shell pkg-config --libs libcrypto 2> /dev/null || echo -lcrypto) +HOSTCFLAGS_sign-file.o = $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /dev/null) +HOSTLDLIBS_sign-file = $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/null || echo -lcrypto) ifdef CONFIG_UNWINDER_ORC ifeq ($(ARCH),x86_64) diff --git a/scripts/kconfig/gconf-cfg.sh b/scripts/kconfig/gconf-cfg.sh index 480ecd8b9f41..cbd90c28c05f 100755 --- a/scripts/kconfig/gconf-cfg.sh +++ b/scripts/kconfig/gconf-cfg.sh @@ -3,14 +3,14 @@ PKG="gtk+-2.0 gmodule-2.0 libglade-2.0" -if [ -z "$(command -v pkg-config)" ]; then +if [ -z "$(command -v ${HOSTPKG_CONFIG})" ]; then echo >&2 "*" - echo >&2 "* 'make gconfig' requires 'pkg-config'. Please install it." + echo >&2 "* 'make gconfig' requires '${HOSTPKG_CONFIG}'. Please install it." echo >&2 "*" exit 1 fi -if ! pkg-config --exists $PKG; then +if ! ${HOSTPKG_CONFIG} --exists $PKG; then echo >&2 "*" echo >&2 "* Unable to find the GTK+ installation. Please make sure that" echo >&2 "* the GTK+ 2.0 development package is correctly installed." @@ -19,12 +19,12 @@ if ! pkg-config --exists $PKG; then exit 1 fi -if ! pkg-config --atleast-version=2.0.0 gtk+-2.0; then +if ! ${HOSTPKG_CONFIG} --atleast-version=2.0.0 gtk+-2.0; then echo >&2 "*" echo >&2 "* GTK+ is present but version >= 2.0.0 is required." echo >&2 "*" exit 1 fi -echo cflags=\"$(pkg-config --cflags $PKG)\" -echo libs=\"$(pkg-config --libs $PKG)\" +echo cflags=\"$(${HOSTPKG_CONFIG} --cflags $PKG)\" +echo libs=\"$(${HOSTPKG_CONFIG} --libs $PKG)\" diff --git a/scripts/kconfig/mconf-cfg.sh b/scripts/kconfig/mconf-cfg.sh index b520e407a8eb..025b565e0b7c 100755 --- a/scripts/kconfig/mconf-cfg.sh +++ b/scripts/kconfig/mconf-cfg.sh @@ -4,16 +4,16 @@ PKG="ncursesw" PKG2="ncurses" -if [ -n "$(command -v pkg-config)" ]; then - if pkg-config --exists $PKG; then - echo cflags=\"$(pkg-config --cflags $PKG)\" - echo libs=\"$(pkg-config --libs $PKG)\" +if [ -n "$(command -v ${HOSTPKG_CONFIG})" ]; then + if ${HOSTPKG_CONFIG} --exists $PKG; then + echo cflags=\"$(${HOSTPKG_CONFIG} --cflags $PKG)\" + echo libs=\"$(${HOSTPKG_CONFIG} --libs $PKG)\" exit 0 fi - if pkg-config --exists $PKG2; then - echo cflags=\"$(pkg-config --cflags $PKG2)\" - echo libs=\"$(pkg-config --libs $PKG2)\" + if ${HOSTPKG_CONFIG} --exists $PKG2; then + echo cflags=\"$(${HOSTPKG_CONFIG} --cflags $PKG2)\" + echo libs=\"$(${HOSTPKG_CONFIG} --libs $PKG2)\" exit 0 fi fi @@ -46,7 +46,7 @@ echo >&2 "* Unable to find the ncurses package." echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev" echo >&2 "* depending on your distribution)." echo >&2 "*" -echo >&2 "* You may also need to install pkg-config to find the" +echo >&2 "* You may also need to install ${HOSTPKG_CONFIG} to find the" echo >&2 "* ncurses installed in a non-default location." echo >&2 "*" exit 1 diff --git a/scripts/kconfig/nconf-cfg.sh b/scripts/kconfig/nconf-cfg.sh index c212255070c0..3a10bac2adb3 100755 --- a/scripts/kconfig/nconf-cfg.sh +++ b/scripts/kconfig/nconf-cfg.sh @@ -4,16 +4,16 @@ PKG="ncursesw menuw panelw" PKG2="ncurses menu panel" -if [ -n "$(command -v pkg-config)" ]; then - if pkg-config --exists $PKG; then - echo cflags=\"$(pkg-config --cflags $PKG)\" - echo libs=\"$(pkg-config --libs $PKG)\" +if [ -n "$(command -v ${HOSTPKG_CONFIG})" ]; then + if ${HOSTPKG_CONFIG} --exists $PKG; then + echo cflags=\"$(${HOSTPKG_CONFIG} --cflags $PKG)\" + echo libs=\"$(${HOSTPKG_CONFIG} --libs $PKG)\" exit 0 fi - if pkg-config --exists $PKG2; then - echo cflags=\"$(pkg-config --cflags $PKG2)\" - echo libs=\"$(pkg-config --libs $PKG2)\" + if ${HOSTPKG_CONFIG} --exists $PKG2; then + echo cflags=\"$(${HOSTPKG_CONFIG} --cflags $PKG2)\" + echo libs=\"$(${HOSTPKG_CONFIG} --libs $PKG2)\" exit 0 fi fi @@ -44,7 +44,7 @@ echo >&2 "* Unable to find the ncurses package." echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev" echo >&2 "* depending on your distribution)." echo >&2 "*" -echo >&2 "* You may also need to install pkg-config to find the" +echo >&2 "* You may also need to install ${HOSTPKG_CONFIG} to find the" echo >&2 "* ncurses installed in a non-default location." echo >&2 "*" exit 1 diff --git a/scripts/kconfig/qconf-cfg.sh b/scripts/kconfig/qconf-cfg.sh index fa564cd795b7..9b695e5cd9b3 100755 --- a/scripts/kconfig/qconf-cfg.sh +++ b/scripts/kconfig/qconf-cfg.sh @@ -3,22 +3,22 @@ PKG="Qt5Core Qt5Gui Qt5Widgets" -if [ -z "$(command -v pkg-config)" ]; then +if [ -z "$(command -v ${HOSTPKG_CONFIG})" ]; then echo >&2 "*" - echo >&2 "* 'make xconfig' requires 'pkg-config'. Please install it." + echo >&2 "* 'make xconfig' requires '${HOSTPKG_CONFIG}'. Please install it." echo >&2 "*" exit 1 fi -if pkg-config --exists $PKG; then - echo cflags=\"-std=c++11 -fPIC $(pkg-config --cflags $PKG)\" - echo libs=\"$(pkg-config --libs $PKG)\" - echo moc=\"$(pkg-config --variable=host_bins Qt5Core)/moc\" +if ${HOSTPKG_CONFIG} --exists $PKG; then + echo cflags=\"-std=c++11 -fPIC $(${HOSTPKG_CONFIG} --cflags $PKG)\" + echo libs=\"$(${HOSTPKG_CONFIG} --libs $PKG)\" + echo moc=\"$(${HOSTPKG_CONFIG} --variable=host_bins Qt5Core)/moc\" exit 0 fi echo >&2 "*" -echo >&2 "* Could not find Qt5 via pkg-config." +echo >&2 "* Could not find Qt5 via ${HOSTPKG_CONFIG}." echo >&2 "* Please install Qt5 and make sure it's in PKG_CONFIG_PATH" echo >&2 "*" exit 1 diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index 0dbd397f319d..29a92781b2ae 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -19,8 +19,8 @@ LIBSUBCMD = $(LIBSUBCMD_OUTPUT)libsubcmd.a OBJTOOL := $(OUTPUT)objtool OBJTOOL_IN := $(OBJTOOL)-in.o -LIBELF_FLAGS := $(shell pkg-config libelf --cflags 2>/dev/null) -LIBELF_LIBS := $(shell pkg-config libelf --libs 2>/dev/null || echo -lelf) +LIBELF_FLAGS := $(shell $(HOSTPKG_CONFIG) libelf --cflags 2>/dev/null) +LIBELF_LIBS := $(shell $(HOSTPKG_CONFIG) libelf --libs 2>/dev/null || echo -lelf) all: $(OBJTOOL) -- cgit v1.2.3 From f43e31d5cb7859189a8be5699f4347e07b07c1df Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 5 Apr 2022 20:33:49 +0900 Subject: kbuild: factor out genksyms command from cmd_gensymtypes_{c,S} The genksyms command part in cmd_gensymtypes_{c,S} is duplicated. Factor it out into the 'genksyms' macro. For the readability, I slightly refactor the arguments to genksyms. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Reviewed-by: Nicolas Schier --- scripts/Makefile.build | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 9717e6f6fb31..31e0e33dfe5d 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -125,13 +125,14 @@ cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $< $(obj)/%.i: $(src)/%.c FORCE $(call if_changed_dep,cpp_i_c) +genksyms = scripts/genksyms/genksyms \ + $(if $(1), -T $(2)) \ + $(if $(CONFIG_MODULE_REL_CRCS), -R) \ + $(if $(KBUILD_PRESERVE), -p) \ + -r $(or $(wildcard $(2:.symtypes=.symref)), /dev/null) + # These mirror gensymtypes_S and co below, keep them in synch. -cmd_gensymtypes_c = \ - $(CPP) -D__GENKSYMS__ $(c_flags) $< | \ - scripts/genksyms/genksyms $(if $(1), -T $(2)) \ - $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \ - $(if $(KBUILD_PRESERVE),-p) \ - -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) +cmd_gensymtypes_c = $(CPP) -D__GENKSYMS__ $(c_flags) $< | $(genksyms) quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ cmd_cc_symtypes_c = \ @@ -344,11 +345,7 @@ cmd_gensymtypes_S = \ $(CPP) $(a_flags) $< | \ grep "\<___EXPORT_SYMBOL\>" | \ sed 's/.*___EXPORT_SYMBOL[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*,.*/EXPORT_SYMBOL(\1);/' ; } | \ - $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | \ - scripts/genksyms/genksyms $(if $(1), -T $(2)) \ - $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \ - $(if $(KBUILD_PRESERVE),-p) \ - -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) + $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | $(genksyms) quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@ cmd_cc_symtypes_S = \ -- cgit v1.2.3 From dc6dc3e7a73fc09c9ce773bc23bc2864d4c13284 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 5 Apr 2022 20:33:50 +0900 Subject: kbuild: do not remove empty *.symtypes explicitly Presumably, 'test -s $@ || rm -f $@' intends to remove the output when the genksyms command fails. It is unneeded because .DELETE_ON_ERROR automatically removes the output on failure. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Reviewed-by: Nicolas Schier --- scripts/Makefile.build | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 31e0e33dfe5d..3ef2373f0a57 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -135,9 +135,7 @@ genksyms = scripts/genksyms/genksyms \ cmd_gensymtypes_c = $(CPP) -D__GENKSYMS__ $(c_flags) $< | $(genksyms) quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ -cmd_cc_symtypes_c = \ - $(call cmd_gensymtypes_c,true,$@) >/dev/null; \ - test -s $@ || rm -f $@ + cmd_cc_symtypes_c = $(call cmd_gensymtypes_c,true,$@) >/dev/null $(obj)/%.symtypes : $(src)/%.c FORCE $(call cmd,cc_symtypes_c) @@ -348,9 +346,7 @@ cmd_gensymtypes_S = \ $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | $(genksyms) quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@ -cmd_cc_symtypes_S = \ - $(call cmd_gensymtypes_S,true,$@) >/dev/null; \ - test -s $@ || rm -f $@ + cmd_cc_symtypes_S = $(call cmd_gensymtypes_S,true,$@) >/dev/null $(obj)/%.symtypes : $(src)/%.S FORCE $(call cmd,cc_symtypes_S) -- cgit v1.2.3 From c40160f2998c897231f8454bf797558d30a20375 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 6 Apr 2022 00:28:15 +0200 Subject: gcc-plugins: latent_entropy: use /dev/urandom While the latent entropy plugin mostly doesn't derive entropy from get_random_const() for measuring the call graph, when __latent_entropy is applied to a constant, then it's initialized statically to output from get_random_const(). In that case, this data is derived from a 64-bit seed, which means a buffer of 512 bits doesn't really have that amount of compile-time entropy. This patch fixes that shortcoming by just buffering chunks of /dev/urandom output and doling it out as requested. At the same time, it's important that we don't break the use of -frandom-seed, for people who want the runtime benefits of the latent entropy plugin, while still having compile-time determinism. In that case, we detect whether gcc's set_random_seed() has been called by making a call to get_random_seed(noinit=true) in the plugin init function, which is called after set_random_seed() is called but before anything that calls get_random_seed(noinit=false), and seeing if it's zero or not. If it's not zero, we're in deterministic mode, and so we just generate numbers with a basic xorshift prng. Note that we don't detect if -frandom-seed is being used using the documented local_tick variable, because it's assigned via: local_tick = (unsigned) tv.tv_sec * 1000 + tv.tv_usec / 1000; which may well overflow and become -1 on its own, and so isn't reliable: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105171 [kees: The 256 byte rnd_buf size was chosen based on average (250), median (64), and std deviation (575) bytes of used entropy for a defconfig x86_64 build] Fixes: 38addce8b600 ("gcc-plugins: Add latent_entropy plugin") Cc: stable@vger.kernel.org Cc: PaX Team Signed-off-by: Jason A. Donenfeld Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220405222815.21155-1-Jason@zx2c4.com --- scripts/gcc-plugins/latent_entropy_plugin.c | 44 ++++++++++++++++++----------- 1 file changed, 27 insertions(+), 17 deletions(-) (limited to 'scripts') diff --git a/scripts/gcc-plugins/latent_entropy_plugin.c b/scripts/gcc-plugins/latent_entropy_plugin.c index 589454bce930..8425da41de0d 100644 --- a/scripts/gcc-plugins/latent_entropy_plugin.c +++ b/scripts/gcc-plugins/latent_entropy_plugin.c @@ -86,25 +86,31 @@ static struct plugin_info latent_entropy_plugin_info = { .help = "disable\tturn off latent entropy instrumentation\n", }; -static unsigned HOST_WIDE_INT seed; -/* - * get_random_seed() (this is a GCC function) generates the seed. - * This is a simple random generator without any cryptographic security because - * the entropy doesn't come from here. - */ +static unsigned HOST_WIDE_INT deterministic_seed; +static unsigned HOST_WIDE_INT rnd_buf[32]; +static size_t rnd_idx = ARRAY_SIZE(rnd_buf); +static int urandom_fd = -1; + static unsigned HOST_WIDE_INT get_random_const(void) { - unsigned int i; - unsigned HOST_WIDE_INT ret = 0; - - for (i = 0; i < 8 * sizeof(ret); i++) { - ret = (ret << 1) | (seed & 1); - seed >>= 1; - if (ret & 1) - seed ^= 0xD800000000000000ULL; + if (deterministic_seed) { + unsigned HOST_WIDE_INT w = deterministic_seed; + w ^= w << 13; + w ^= w >> 7; + w ^= w << 17; + deterministic_seed = w; + return deterministic_seed; } - return ret; + if (urandom_fd < 0) { + urandom_fd = open("/dev/urandom", O_RDONLY); + gcc_assert(urandom_fd >= 0); + } + if (rnd_idx >= ARRAY_SIZE(rnd_buf)) { + gcc_assert(read(urandom_fd, rnd_buf, sizeof(rnd_buf)) == sizeof(rnd_buf)); + rnd_idx = 0; + } + return rnd_buf[rnd_idx++]; } static tree tree_get_random_const(tree type) @@ -537,8 +543,6 @@ static void latent_entropy_start_unit(void *gcc_data __unused, tree type, id; int quals; - seed = get_random_seed(false); - if (in_lto_p) return; @@ -573,6 +577,12 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, const struct plugin_argument * const argv = plugin_info->argv; int i; + /* + * Call get_random_seed() with noinit=true, so that this returns + * 0 in the case where no seed has been passed via -frandom-seed. + */ + deterministic_seed = get_random_seed(true); + static const struct ggc_root_tab gt_ggc_r_gt_latent_entropy[] = { { .base = &latent_entropy_decl, -- cgit v1.2.3 From 75c1182e18f4a66bbd2c91511b6b629dac6a27dc Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Thu, 7 Apr 2022 10:59:30 -0700 Subject: security: don't treat structure as an array of struct hlist_head The initialization of "security_hook_heads" is done by casting it to another structure pointer type, and treating it as an array of "struct hlist_head" objects. This requires an exception be made in "randstruct", because otherwise it will emit an error, reducing the effectiveness of the hardening technique. Instead of using a cast, initialize the individual struct hlist_head elements in security_hook_heads explicitly. This removes the need for the cast and randstruct exception. Signed-off-by: Bill Wendling Cc: Kees Cook Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220407175930.471870-1-morbo@google.com --- scripts/gcc-plugins/randomize_layout_plugin.c | 2 -- security/security.c | 9 ++++----- 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index 334741a31d0a..c2ec81b68505 100644 --- a/scripts/gcc-plugins/randomize_layout_plugin.c +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -52,8 +52,6 @@ static const struct whitelist_entry whitelist[] = { { "net/unix/af_unix.c", "unix_skb_parms", "char" }, /* big_key payload.data struct splashing */ { "security/keys/big_key.c", "path", "void *" }, - /* walk struct security_hook_heads as an array of struct hlist_head */ - { "security/security.c", "hlist_head", "security_hook_heads" }, { } }; diff --git a/security/security.c b/security/security.c index b7cf5cbfdc67..37a9eeb901e0 100644 --- a/security/security.c +++ b/security/security.c @@ -365,13 +365,12 @@ static void __init ordered_lsm_init(void) int __init early_security_init(void) { - int i; - struct hlist_head *list = (struct hlist_head *) &security_hook_heads; struct lsm_info *lsm; - for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct hlist_head); - i++) - INIT_HLIST_HEAD(&list[i]); +#define LSM_HOOK(RET, DEFAULT, NAME, ...) \ + INIT_HLIST_HEAD(&security_hook_heads.NAME); +#include "linux/lsm_hook_defs.h" +#undef LSM_HOOK for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) { if (!lsm->enabled) -- cgit v1.2.3 From 4a5de9b76fcb3f477f73d5a63f6e27709e8af81f Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 18 Apr 2022 09:50:20 -0700 Subject: objtool: Enable unreachable warnings for CLANG LTO With IBT support in, objtool is now fully capable of following vmlinux code flow in LTO mode. Start reporting unreachable warnings for Clang LTO as well. Fixes: ed53a0d97192 ("x86/alternative: Use .ibt_endbr_seal to seal indirect calls") Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/7b12df54bceeb0761fe9fc8269ea0c00501214a9.1650300597.git.jpoimboe@redhat.com --- scripts/Makefile.build | 2 +- scripts/link-vmlinux.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 9717e6f6fb31..33c1ed581522 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -231,7 +231,7 @@ objtool_args = \ $(if $(part-of-module), --module) \ $(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt) \ $(if $(CONFIG_FRAME_POINTER),, --no-fp) \ - $(if $(CONFIG_GCOV_KERNEL)$(CONFIG_LTO_CLANG), --no-unreachable)\ + $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) \ $(if $(CONFIG_RETPOLINE), --retpoline) \ $(if $(CONFIG_X86_SMAP), --uaccess) \ $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 20f44504a644..9361a1ef02c9 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -140,7 +140,7 @@ objtool_link() if ! is_enabled CONFIG_FRAME_POINTER; then objtoolopt="${objtoolopt} --no-fp" fi - if is_enabled CONFIG_GCOV_KERNEL || is_enabled CONFIG_LTO_CLANG; then + if is_enabled CONFIG_GCOV_KERNEL; then objtoolopt="${objtoolopt} --no-unreachable" fi if is_enabled CONFIG_RETPOLINE; then -- cgit v1.2.3 From 2daf7faba7ded8703e4b4ebc8b161f22272fc91a Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 18 Apr 2022 09:50:26 -0700 Subject: objtool: Reorganize cmdline options Split the existing options into two groups: actions, which actually do something; and options, which modify the actions in some way. Also there's no need to have short flags for all the non-action options. Reserve short flags for the more important actions. While at it: - change a few of the short flags to be more intuitive - make option descriptions more consistently descriptive - sort options in the source like they are when printed - move options to a global struct Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Miroslav Benes Link: https://lkml.kernel.org/r/9dcaa752f83aca24b1b21f0b0eeb28a0c181c0b0.1650300597.git.jpoimboe@redhat.com --- scripts/Makefile.build | 10 +++--- scripts/link-vmlinux.sh | 30 ++++++++++------ tools/objtool/arch/x86/decode.c | 2 +- tools/objtool/arch/x86/special.c | 2 +- tools/objtool/builtin-check.c | 40 +++++++++++---------- tools/objtool/check.c | 62 ++++++++++++++++----------------- tools/objtool/elf.c | 8 ++--- tools/objtool/include/objtool/builtin.h | 26 ++++++++++++-- tools/objtool/objtool.c | 6 ++-- 9 files changed, 108 insertions(+), 78 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 33c1ed581522..dd9d582808d6 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -228,14 +228,14 @@ objtool := $(objtree)/tools/objtool/objtool objtool_args = \ $(if $(CONFIG_UNWINDER_ORC),orc generate,check) \ - $(if $(part-of-module), --module) \ $(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt) \ - $(if $(CONFIG_FRAME_POINTER),, --no-fp) \ - $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) \ + $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ $(if $(CONFIG_RETPOLINE), --retpoline) \ + $(if $(CONFIG_SLS), --sls) \ $(if $(CONFIG_X86_SMAP), --uaccess) \ - $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ - $(if $(CONFIG_SLS), --sls) + $(if $(part-of-module), --module) \ + $(if $(CONFIG_FRAME_POINTER),, --no-fp) \ + $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@) cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 9361a1ef02c9..c6e9fef61b11 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -117,8 +117,6 @@ objtool_link() objtoolcmd="orc generate" fi - objtoolopt="${objtoolopt} --lto" - if is_enabled CONFIG_X86_KERNEL_IBT; then objtoolopt="${objtoolopt} --ibt" fi @@ -126,6 +124,8 @@ objtool_link() if is_enabled CONFIG_FTRACE_MCOUNT_USE_OBJTOOL; then objtoolopt="${objtoolopt} --mcount" fi + + objtoolopt="${objtoolopt} --lto" fi if is_enabled CONFIG_VMLINUX_VALIDATION; then @@ -133,25 +133,33 @@ objtool_link() fi if [ -n "${objtoolopt}" ]; then + if [ -z "${objtoolcmd}" ]; then objtoolcmd="check" fi - objtoolopt="${objtoolopt} --vmlinux" - if ! is_enabled CONFIG_FRAME_POINTER; then - objtoolopt="${objtoolopt} --no-fp" - fi - if is_enabled CONFIG_GCOV_KERNEL; then - objtoolopt="${objtoolopt} --no-unreachable" - fi + if is_enabled CONFIG_RETPOLINE; then objtoolopt="${objtoolopt} --retpoline" fi + + if is_enabled CONFIG_SLS; then + objtoolopt="${objtoolopt} --sls" + fi + if is_enabled CONFIG_X86_SMAP; then objtoolopt="${objtoolopt} --uaccess" fi - if is_enabled CONFIG_SLS; then - objtoolopt="${objtoolopt} --sls" + + if ! is_enabled CONFIG_FRAME_POINTER; then + objtoolopt="${objtoolopt} --no-fp" fi + + if is_enabled CONFIG_GCOV_KERNEL; then + objtoolopt="${objtoolopt} --no-unreachable" + fi + + objtoolopt="${objtoolopt} --vmlinux" + info OBJTOOL ${1} tools/objtool/objtool ${objtoolcmd} ${objtoolopt} ${1} fi diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c index 943cb41cddf7..8b990a52aada 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -581,7 +581,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec break; case 0xc7: /* mov imm, r/m */ - if (!noinstr) + if (!opts.noinstr) break; if (insn.length == 3+4+4 && !strncmp(sec->name, ".init.text", 10)) { diff --git a/tools/objtool/arch/x86/special.c b/tools/objtool/arch/x86/special.c index e707d9bcd161..7c97b7391279 100644 --- a/tools/objtool/arch/x86/special.c +++ b/tools/objtool/arch/x86/special.c @@ -20,7 +20,7 @@ void arch_handle_alternative(unsigned short feature, struct special_alt *alt) * find paths that see the STAC but take the NOP instead of * CLAC and the other way around. */ - if (uaccess) + if (opts.uaccess) alt->skip_orig = true; else alt->skip_alt = true; diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index fc6975ab8b06..bc447b3cd9f2 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -19,12 +19,10 @@ #include #include -bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, - lto, vmlinux, mcount, noinstr, backup, sls, dryrun, - ibt; +struct opts opts; static const char * const check_usage[] = { - "objtool check [] file.o", + "objtool check [] file.o", NULL, }; @@ -34,21 +32,25 @@ static const char * const env_usage[] = { }; const struct option check_options[] = { - OPT_BOOLEAN('f', "no-fp", &no_fp, "Skip frame pointer validation"), - OPT_BOOLEAN('u', "no-unreachable", &no_unreachable, "Skip 'unreachable instruction' warnings"), - OPT_BOOLEAN('r', "retpoline", &retpoline, "Validate retpoline assumptions"), - OPT_BOOLEAN('m', "module", &module, "Indicates the object will be part of a kernel module"), - OPT_BOOLEAN('b', "backtrace", &backtrace, "unwind on error"), - OPT_BOOLEAN('a', "uaccess", &uaccess, "enable uaccess checking"), - OPT_BOOLEAN('s', "stats", &stats, "print statistics"), - OPT_BOOLEAN(0, "lto", <o, "whole-archive like runs"), - OPT_BOOLEAN('n', "noinstr", &noinstr, "noinstr validation for vmlinux.o"), - OPT_BOOLEAN('l', "vmlinux", &vmlinux, "vmlinux.o validation"), - OPT_BOOLEAN('M', "mcount", &mcount, "generate __mcount_loc"), - OPT_BOOLEAN('B', "backup", &backup, "create .orig files before modification"), - OPT_BOOLEAN('S', "sls", &sls, "validate straight-line-speculation"), - OPT_BOOLEAN(0, "dry-run", &dryrun, "don't write the modifications"), - OPT_BOOLEAN(0, "ibt", &ibt, "validate ENDBR placement"), + OPT_GROUP("Actions:"), + OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"), + OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls for ftrace"), + OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"), + OPT_BOOLEAN('r', "retpoline", &opts.retpoline, "validate and annotate retpoline usage"), + OPT_BOOLEAN('l', "sls", &opts.sls, "validate straight-line-speculation mitigations"), + OPT_BOOLEAN('u', "uaccess", &opts.uaccess, "validate uaccess rules for SMAP"), + + OPT_GROUP("Options:"), + OPT_BOOLEAN(0, "backtrace", &opts.backtrace, "unwind on error"), + OPT_BOOLEAN(0, "backup", &opts.backup, "create .orig files before modification"), + OPT_BOOLEAN(0, "dry-run", &opts.dryrun, "don't write modifications"), + OPT_BOOLEAN(0, "lto", &opts.lto, "whole-archive like runs"), + OPT_BOOLEAN(0, "module", &opts.module, "object is part of a kernel module"), + OPT_BOOLEAN(0, "no-fp", &opts.no_fp, "skip frame pointer validation"), + OPT_BOOLEAN(0, "no-unreachable", &opts.no_unreachable, "skip 'unreachable instruction' warnings"), + OPT_BOOLEAN(0, "stats", &opts.stats, "print statistics"), + OPT_BOOLEAN(0, "vmlinux", &opts.vmlinux, "vmlinux.o validation"), + OPT_END(), }; diff --git a/tools/objtool/check.c b/tools/objtool/check.c index ca5b74603008..3362cc3bdf1a 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -273,7 +273,7 @@ static void init_insn_state(struct insn_state *state, struct section *sec) * not correctly determine insn->call_dest->sec (external symbols do * not have a section). */ - if (vmlinux && noinstr && sec) + if (opts.vmlinux && opts.noinstr && sec) state->noinstr = sec->noinstr; } @@ -339,7 +339,7 @@ static void *cfi_hash_alloc(unsigned long size) if (cfi_hash == (void *)-1L) { WARN("mmap fail cfi_hash"); cfi_hash = NULL; - } else if (stats) { + } else if (opts.stats) { printf("cfi_bits: %d\n", cfi_bits); } @@ -434,7 +434,7 @@ static int decode_instructions(struct objtool_file *file) } } - if (stats) + if (opts.stats) printf("nr_insns: %lu\n", nr_insns); return 0; @@ -497,7 +497,7 @@ static int init_pv_ops(struct objtool_file *file) struct symbol *sym; int idx, nr; - if (!noinstr) + if (!opts.noinstr) return 0; file->pv_ops = NULL; @@ -668,7 +668,7 @@ static int create_static_call_sections(struct objtool_file *file) key_sym = find_symbol_by_name(file->elf, tmp); if (!key_sym) { - if (!module) { + if (!opts.module) { WARN("static_call: can't find static_call_key symbol: %s", tmp); return -1; } @@ -761,7 +761,7 @@ static int create_ibt_endbr_seal_sections(struct objtool_file *file) list_for_each_entry(insn, &file->endbr_list, call_node) idx++; - if (stats) { + if (opts.stats) { printf("ibt: ENDBR at function start: %d\n", file->nr_endbr); printf("ibt: ENDBR inside functions: %d\n", file->nr_endbr_int); printf("ibt: superfluous ENDBR: %d\n", idx); @@ -1028,7 +1028,7 @@ static void add_uaccess_safe(struct objtool_file *file) struct symbol *func; const char **name; - if (!uaccess) + if (!opts.uaccess) return; for (name = uaccess_safe_builtin; *name; name++) { @@ -1170,7 +1170,7 @@ static void annotate_call_site(struct objtool_file *file, return; } - if (mcount && sym->fentry) { + if (opts.mcount && sym->fentry) { if (sibling) WARN_FUNC("Tail call to __fentry__ !?!?", insn->sec, insn->offset); @@ -1256,7 +1256,7 @@ static bool is_first_func_insn(struct objtool_file *file, struct instruction *in if (insn->offset == insn->func->offset) return true; - if (ibt) { + if (opts.ibt) { struct instruction *prev = prev_insn_same_sym(file, insn); if (prev && prev->type == INSN_ENDBR && @@ -1699,7 +1699,7 @@ static int add_special_section_alts(struct objtool_file *file) free(special_alt); } - if (stats) { + if (opts.stats) { printf("jl\\\tNOP\tJMP\n"); printf("short:\t%ld\t%ld\n", file->jl_nop_short, file->jl_short); printf("long:\t%ld\t%ld\n", file->jl_nop_long, file->jl_long); @@ -1945,7 +1945,7 @@ static int read_unwind_hints(struct objtool_file *file) insn->hint = true; - if (ibt && hint->type == UNWIND_HINT_TYPE_REGS_PARTIAL) { + if (opts.ibt && hint->type == UNWIND_HINT_TYPE_REGS_PARTIAL) { struct symbol *sym = find_symbol_by_offset(insn->sec, insn->offset); if (sym && sym->bind == STB_GLOBAL && @@ -2806,7 +2806,7 @@ static int update_cfi_state(struct instruction *insn, } /* detect when asm code uses rbp as a scratch register */ - if (!no_fp && insn->func && op->src.reg == CFI_BP && + if (!opts.no_fp && insn->func && op->src.reg == CFI_BP && cfa->base != CFI_BP) cfi->bp_scratch = true; break; @@ -3363,7 +3363,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, ret = validate_branch(file, func, alt->insn, state); if (ret) { - if (backtrace) + if (opts.backtrace) BT_FUNC("(alt)", insn); return ret; } @@ -3379,7 +3379,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, switch (insn->type) { case INSN_RETURN: - if (sls && !insn->retpoline_safe && + if (opts.sls && !insn->retpoline_safe && next_insn && next_insn->type != INSN_TRAP) { WARN_FUNC("missing int3 after ret", insn->sec, insn->offset); @@ -3392,7 +3392,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, if (ret) return ret; - if (!no_fp && func && !is_fentry_call(insn) && + if (!opts.no_fp && func && !is_fentry_call(insn) && !has_valid_stack_frame(&state)) { WARN_FUNC("call without frame pointer save/setup", sec, insn->offset); @@ -3415,7 +3415,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, ret = validate_branch(file, func, insn->jump_dest, state); if (ret) { - if (backtrace) + if (opts.backtrace) BT_FUNC("(branch)", insn); return ret; } @@ -3427,7 +3427,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, break; case INSN_JUMP_DYNAMIC: - if (sls && !insn->retpoline_safe && + if (opts.sls && !insn->retpoline_safe && next_insn && next_insn->type != INSN_TRAP) { WARN_FUNC("missing int3 after indirect jump", insn->sec, insn->offset); @@ -3499,7 +3499,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, break; } - if (ibt) + if (opts.ibt) validate_ibt_insn(file, insn); if (insn->dead_end) @@ -3541,7 +3541,7 @@ static int validate_unwind_hints(struct objtool_file *file, struct section *sec) while (&insn->list != &file->insn_list && (!sec || insn->sec == sec)) { if (insn->hint && !insn->visited && !insn->ignore) { ret = validate_branch(file, insn->func, insn, state); - if (ret && backtrace) + if (ret && opts.backtrace) BT_FUNC("<=== (hint)", insn); warnings += ret; } @@ -3571,7 +3571,7 @@ static int validate_retpoline(struct objtool_file *file) * loaded late, they very much do need retpoline in their * .init.text */ - if (!strcmp(insn->sec->name, ".init.text") && !module) + if (!strcmp(insn->sec->name, ".init.text") && !opts.module) continue; WARN_FUNC("indirect %s found in RETPOLINE build", @@ -3621,7 +3621,7 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio * In this case we'll find a piece of code (whole function) that is not * covered by a !section symbol. Ignore them. */ - if (!insn->func && lto) { + if (!insn->func && opts.lto) { int size = find_symbol_hole_containing(insn->sec, insn->offset); unsigned long end = insn->offset + size; @@ -3728,7 +3728,7 @@ static int validate_symbol(struct objtool_file *file, struct section *sec, state->uaccess = sym->uaccess_safe; ret = validate_branch(file, insn->func, insn, *state); - if (ret && backtrace) + if (ret && opts.backtrace) BT_FUNC("<=== (sym)", insn); return ret; } @@ -3853,12 +3853,12 @@ int check(struct objtool_file *file) { int ret, warnings = 0; - if (lto && !(vmlinux || module)) { + if (opts.lto && !(opts.vmlinux || opts.module)) { fprintf(stderr, "--lto requires: --vmlinux or --module\n"); return 1; } - if (ibt && !lto) { + if (opts.ibt && !opts.lto) { fprintf(stderr, "--ibt requires: --lto\n"); return 1; } @@ -3883,7 +3883,7 @@ int check(struct objtool_file *file) if (list_empty(&file->insn_list)) goto out; - if (vmlinux && !lto) { + if (opts.vmlinux && !opts.lto) { ret = validate_vmlinux_functions(file); if (ret < 0) goto out; @@ -3892,7 +3892,7 @@ int check(struct objtool_file *file) goto out; } - if (retpoline) { + if (opts.retpoline) { ret = validate_retpoline(file); if (ret < 0) return ret; @@ -3909,7 +3909,7 @@ int check(struct objtool_file *file) goto out; warnings += ret; - if (ibt) { + if (opts.ibt) { ret = validate_ibt(file); if (ret < 0) goto out; @@ -3928,28 +3928,28 @@ int check(struct objtool_file *file) goto out; warnings += ret; - if (retpoline) { + if (opts.retpoline) { ret = create_retpoline_sites_sections(file); if (ret < 0) goto out; warnings += ret; } - if (mcount) { + if (opts.mcount) { ret = create_mcount_loc_sections(file); if (ret < 0) goto out; warnings += ret; } - if (ibt) { + if (opts.ibt) { ret = create_ibt_endbr_seal_sections(file); if (ret < 0) goto out; warnings += ret; } - if (stats) { + if (opts.stats) { printf("nr_insns_visited: %ld\n", nr_insns_visited); printf("nr_cfi: %ld\n", nr_cfi); printf("nr_cfi_reused: %ld\n", nr_cfi_reused); diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index ebf2ba5755c1..0f6fa372e10e 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -355,7 +355,7 @@ static int read_sections(struct elf *elf) elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); } - if (stats) { + if (opts.stats) { printf("nr_sections: %lu\n", (unsigned long)sections_nr); printf("section_bits: %d\n", elf->section_bits); } @@ -475,7 +475,7 @@ static int read_symbols(struct elf *elf) elf_add_symbol(elf, sym); } - if (stats) { + if (opts.stats) { printf("nr_symbols: %lu\n", (unsigned long)symbols_nr); printf("symbol_bits: %d\n", elf->symbol_bits); } @@ -843,7 +843,7 @@ static int read_relocs(struct elf *elf) tot_reloc += nr_reloc; } - if (stats) { + if (opts.stats) { printf("max_reloc: %lu\n", max_reloc); printf("tot_reloc: %lu\n", tot_reloc); printf("reloc_bits: %d\n", elf->reloc_bits); @@ -1222,7 +1222,7 @@ int elf_write(struct elf *elf) struct section *sec; Elf_Scn *s; - if (dryrun) + if (opts.dryrun) return 0; /* Update changed relocation sections and section headers: */ diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h index c39dbfaef6dc..87c1a7351e3c 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -8,9 +8,29 @@ #include extern const struct option check_options[]; -extern bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, - lto, vmlinux, mcount, noinstr, backup, sls, dryrun, - ibt; + +struct opts { + /* actions: */ + bool ibt; + bool mcount; + bool noinstr; + bool retpoline; + bool sls; + bool uaccess; + + /* options: */ + bool backtrace; + bool backup; + bool dryrun; + bool lto; + bool module; + bool no_fp; + bool no_unreachable; + bool stats; + bool vmlinux; +}; + +extern struct opts opts; extern int cmd_parse_options(int argc, const char **argv, const char * const usage[]); diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c index 843ff3c2f28e..a0f3d3c9558d 100644 --- a/tools/objtool/objtool.c +++ b/tools/objtool/objtool.c @@ -118,7 +118,7 @@ struct objtool_file *objtool_open_read(const char *_objname) if (!file.elf) return NULL; - if (backup && !objtool_create_backup(objname)) { + if (opts.backup && !objtool_create_backup(objname)) { WARN("can't create backup file"); return NULL; } @@ -129,7 +129,7 @@ struct objtool_file *objtool_open_read(const char *_objname) INIT_LIST_HEAD(&file.static_call_list); INIT_LIST_HEAD(&file.mcount_loc_list); INIT_LIST_HEAD(&file.endbr_list); - file.ignore_unreachables = no_unreachable; + file.ignore_unreachables = opts.no_unreachable; file.hints = false; return &file; @@ -137,7 +137,7 @@ struct objtool_file *objtool_open_read(const char *_objname) void objtool_pv_add(struct objtool_file *f, int idx, struct symbol *func) { - if (!noinstr) + if (!opts.noinstr) return; if (!f->pv_ops) { -- cgit v1.2.3 From b51277eb9775ce916f9efd2c51533e481180c1e8 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 18 Apr 2022 09:50:27 -0700 Subject: objtool: Ditch subcommands Objtool has a fairly singular focus. It runs on object files and does validations and transformations which can be combined in various ways. The subcommand model has never been a good fit, making it awkward to combine and remove options. Remove the "check" and "orc" subcommands in favor of a more traditional cmdline option model. This makes it much more flexible to use, and easier to port individual features to other arches. Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Miroslav Benes Link: https://lkml.kernel.org/r/5c61ebf805e90aefc5fa62bc63468ffae53b9df6.1650300597.git.jpoimboe@redhat.com --- scripts/Makefile.build | 2 +- scripts/link-vmlinux.sh | 13 ++--- tools/objtool/Build | 12 ++-- tools/objtool/Makefile | 8 +-- tools/objtool/builtin-check.c | 56 +++++++++++++++---- tools/objtool/builtin-orc.c | 73 ------------------------- tools/objtool/check.c | 8 +++ tools/objtool/include/objtool/builtin.h | 5 +- tools/objtool/objtool.c | 97 +-------------------------------- tools/objtool/weak.c | 9 +-- 10 files changed, 72 insertions(+), 211 deletions(-) delete mode 100644 tools/objtool/builtin-orc.c (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index dd9d582808d6..116c7272b41c 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -227,9 +227,9 @@ ifdef CONFIG_STACK_VALIDATION objtool := $(objtree)/tools/objtool/objtool objtool_args = \ - $(if $(CONFIG_UNWINDER_ORC),orc generate,check) \ $(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt) \ $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ + $(if $(CONFIG_UNWINDER_ORC), --orc) \ $(if $(CONFIG_RETPOLINE), --retpoline) \ $(if $(CONFIG_SLS), --sls) \ $(if $(CONFIG_X86_SMAP), --uaccess) \ diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index c6e9fef61b11..f6db79b11573 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -113,9 +113,6 @@ objtool_link() # Don't perform vmlinux validation unless explicitly requested, # but run objtool on vmlinux.o now that we have an object file. - if is_enabled CONFIG_UNWINDER_ORC; then - objtoolcmd="orc generate" - fi if is_enabled CONFIG_X86_KERNEL_IBT; then objtoolopt="${objtoolopt} --ibt" @@ -125,6 +122,10 @@ objtool_link() objtoolopt="${objtoolopt} --mcount" fi + if is_enabled CONFIG_UNWINDER_ORC; then + objtoolopt="${objtoolopt} --orc" + fi + objtoolopt="${objtoolopt} --lto" fi @@ -134,10 +135,6 @@ objtool_link() if [ -n "${objtoolopt}" ]; then - if [ -z "${objtoolcmd}" ]; then - objtoolcmd="check" - fi - if is_enabled CONFIG_RETPOLINE; then objtoolopt="${objtoolopt} --retpoline" fi @@ -161,7 +158,7 @@ objtool_link() objtoolopt="${objtoolopt} --vmlinux" info OBJTOOL ${1} - tools/objtool/objtool ${objtoolcmd} ${objtoolopt} ${1} + tools/objtool/objtool ${objtoolopt} ${1} fi } diff --git a/tools/objtool/Build b/tools/objtool/Build index b7222d5cc7bc..33f2ee5a46d3 100644 --- a/tools/objtool/Build +++ b/tools/objtool/Build @@ -2,17 +2,15 @@ objtool-y += arch/$(SRCARCH)/ objtool-y += weak.o -objtool-$(SUBCMD_CHECK) += check.o -objtool-$(SUBCMD_CHECK) += special.o -objtool-$(SUBCMD_ORC) += check.o -objtool-$(SUBCMD_ORC) += orc_gen.o -objtool-$(SUBCMD_ORC) += orc_dump.o - +objtool-y += check.o +objtool-y += special.o objtool-y += builtin-check.o -objtool-y += builtin-orc.o objtool-y += elf.o objtool-y += objtool.o +objtool-$(BUILD_ORC) += orc_gen.o +objtool-$(BUILD_ORC) += orc_dump.o + objtool-y += libstring.o objtool-y += libctype.o objtool-y += str_error_r.o diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index 0dbd397f319d..061cf1cd42c4 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -39,15 +39,13 @@ CFLAGS += $(if $(elfshdr),,-DLIBELF_USE_DEPRECATED) AWK = awk -SUBCMD_CHECK := n -SUBCMD_ORC := n +BUILD_ORC := n ifeq ($(SRCARCH),x86) - SUBCMD_CHECK := y - SUBCMD_ORC := y + BUILD_ORC := y endif -export SUBCMD_CHECK SUBCMD_ORC +export BUILD_ORC export srctree OUTPUT CFLAGS SRCARCH AWK include $(srctree)/tools/build/Makefile.include diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index bc447b3cd9f2..8c3eed5b67e4 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -3,16 +3,6 @@ * Copyright (C) 2015-2017 Josh Poimboeuf */ -/* - * objtool check: - * - * This command analyzes every .o file and ensures the validity of its stack - * trace metadata. It enforces a set of rules on asm code and C inline - * assembly code so that stack traces can be reliable. - * - * For more information, see tools/objtool/Documentation/stack-validation.txt. - */ - #include #include #include @@ -22,7 +12,7 @@ struct opts opts; static const char * const check_usage[] = { - "objtool check [] file.o", + "objtool [] file.o", NULL, }; @@ -31,14 +21,26 @@ static const char * const env_usage[] = { NULL, }; +static int parse_dump(const struct option *opt, const char *str, int unset) +{ + if (!str || !strcmp(str, "orc")) { + opts.dump_orc = true; + return 0; + } + + return -1; +} + const struct option check_options[] = { OPT_GROUP("Actions:"), OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"), OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls for ftrace"), OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"), + OPT_BOOLEAN('o', "orc", &opts.orc, "generate ORC metadata"), OPT_BOOLEAN('r', "retpoline", &opts.retpoline, "validate and annotate retpoline usage"), OPT_BOOLEAN('l', "sls", &opts.sls, "validate straight-line-speculation mitigations"), OPT_BOOLEAN('u', "uaccess", &opts.uaccess, "validate uaccess rules for SMAP"), + OPT_CALLBACK_OPTARG(0, "dump", NULL, NULL, "orc", "dump metadata", parse_dump), OPT_GROUP("Options:"), OPT_BOOLEAN(0, "backtrace", &opts.backtrace, "unwind on error"), @@ -81,7 +83,31 @@ int cmd_parse_options(int argc, const char **argv, const char * const usage[]) return argc; } -int cmd_check(int argc, const char **argv) +static bool opts_valid(void) +{ + if (opts.ibt || + opts.mcount || + opts.noinstr || + opts.orc || + opts.retpoline || + opts.sls || + opts.uaccess) { + if (opts.dump_orc) { + fprintf(stderr, "--dump can't be combined with other options\n"); + return false; + } + + return true; + } + + if (opts.dump_orc) + return true; + + fprintf(stderr, "At least one command required\n"); + return false; +} + +int objtool_run(int argc, const char **argv) { const char *objname; struct objtool_file *file; @@ -90,6 +116,12 @@ int cmd_check(int argc, const char **argv) argc = cmd_parse_options(argc, argv, check_usage); objname = argv[0]; + if (!opts_valid()) + return 1; + + if (opts.dump_orc) + return orc_dump(objname); + file = objtool_open_read(objname); if (!file) return 1; diff --git a/tools/objtool/builtin-orc.c b/tools/objtool/builtin-orc.c deleted file mode 100644 index 17f8b9307738..000000000000 --- a/tools/objtool/builtin-orc.c +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2017 Josh Poimboeuf - */ - -/* - * objtool orc: - * - * This command analyzes a .o file and adds .orc_unwind and .orc_unwind_ip - * sections to it, which is used by the in-kernel ORC unwinder. - * - * This command is a superset of "objtool check". - */ - -#include -#include -#include - -static const char *orc_usage[] = { - "objtool orc generate [] file.o", - "objtool orc dump file.o", - NULL, -}; - -int cmd_orc(int argc, const char **argv) -{ - const char *objname; - - argc--; argv++; - if (argc <= 0) - usage_with_options(orc_usage, check_options); - - if (!strncmp(argv[0], "gen", 3)) { - struct objtool_file *file; - int ret; - - argc = cmd_parse_options(argc, argv, orc_usage); - objname = argv[0]; - - file = objtool_open_read(objname); - if (!file) - return 1; - - ret = check(file); - if (ret) - return ret; - - if (list_empty(&file->insn_list)) - return 0; - - ret = orc_create(file); - if (ret) - return ret; - - if (!file->elf->changed) - return 0; - - return elf_write(file->elf); - } - - if (!strcmp(argv[0], "dump")) { - if (argc != 2) - usage_with_options(orc_usage, check_options); - - objname = argv[1]; - - return orc_dump(objname); - } - - usage_with_options(orc_usage, check_options); - - return 0; -} diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 3362cc3bdf1a..16a6c4b4f6bb 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3949,6 +3949,14 @@ int check(struct objtool_file *file) warnings += ret; } + if (opts.orc && !list_empty(&file->insn_list)) { + ret = orc_create(file); + if (ret < 0) + goto out; + warnings += ret; + } + + if (opts.stats) { printf("nr_insns_visited: %ld\n", nr_insns_visited); printf("nr_cfi: %ld\n", nr_cfi); diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h index 87c1a7351e3c..44548e24473c 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -11,9 +11,11 @@ extern const struct option check_options[]; struct opts { /* actions: */ + bool dump_orc; bool ibt; bool mcount; bool noinstr; + bool orc; bool retpoline; bool sls; bool uaccess; @@ -34,7 +36,6 @@ extern struct opts opts; extern int cmd_parse_options(int argc, const char **argv, const char * const usage[]); -extern int cmd_check(int argc, const char **argv); -extern int cmd_orc(int argc, const char **argv); +extern int objtool_run(int argc, const char **argv); #endif /* _BUILTIN_H */ diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c index a0f3d3c9558d..512669ce064c 100644 --- a/tools/objtool/objtool.c +++ b/tools/objtool/objtool.c @@ -3,16 +3,6 @@ * Copyright (C) 2015 Josh Poimboeuf */ -/* - * objtool: - * - * The 'check' subcmd analyzes every .o file and ensures the validity of its - * stack trace metadata. It enforces a set of rules on asm code and C inline - * assembly code so that stack traces can be reliable. - * - * For more information, see tools/objtool/Documentation/stack-validation.txt. - */ - #include #include #include @@ -26,20 +16,6 @@ #include #include -struct cmd_struct { - const char *name; - int (*fn)(int, const char **); - const char *help; -}; - -static const char objtool_usage_string[] = - "objtool COMMAND [ARGS]"; - -static struct cmd_struct objtool_cmds[] = { - {"check", cmd_check, "Perform stack metadata validation on an object file" }, - {"orc", cmd_orc, "Generate in-place ORC unwind tables for an object file" }, -}; - bool help; const char *objname; @@ -161,70 +137,6 @@ void objtool_pv_add(struct objtool_file *f, int idx, struct symbol *func) f->pv_ops[idx].clean = false; } -static void cmd_usage(void) -{ - unsigned int i, longest = 0; - - printf("\n usage: %s\n\n", objtool_usage_string); - - for (i = 0; i < ARRAY_SIZE(objtool_cmds); i++) { - if (longest < strlen(objtool_cmds[i].name)) - longest = strlen(objtool_cmds[i].name); - } - - puts(" Commands:"); - for (i = 0; i < ARRAY_SIZE(objtool_cmds); i++) { - printf(" %-*s ", longest, objtool_cmds[i].name); - puts(objtool_cmds[i].help); - } - - printf("\n"); - - if (!help) - exit(129); - exit(0); -} - -static void handle_options(int *argc, const char ***argv) -{ - while (*argc > 0) { - const char *cmd = (*argv)[0]; - - if (cmd[0] != '-') - break; - - if (!strcmp(cmd, "--help") || !strcmp(cmd, "-h")) { - help = true; - break; - } else { - fprintf(stderr, "Unknown option: %s\n", cmd); - cmd_usage(); - } - - (*argv)++; - (*argc)--; - } -} - -static void handle_internal_command(int argc, const char **argv) -{ - const char *cmd = argv[0]; - unsigned int i, ret; - - for (i = 0; i < ARRAY_SIZE(objtool_cmds); i++) { - struct cmd_struct *p = objtool_cmds+i; - - if (strcmp(p->name, cmd)) - continue; - - ret = p->fn(argc, argv); - - exit(ret); - } - - cmd_usage(); -} - int main(int argc, const char **argv) { static const char *UNUSED = "OBJTOOL_NOT_IMPLEMENTED"; @@ -233,14 +145,7 @@ int main(int argc, const char **argv) exec_cmd_init("objtool", UNUSED, UNUSED, UNUSED); pager_init(UNUSED); - argv++; - argc--; - handle_options(&argc, &argv); - - if (!argc || help) - cmd_usage(); - - handle_internal_command(argc, argv); + objtool_run(argc, argv); return 0; } diff --git a/tools/objtool/weak.c b/tools/objtool/weak.c index 8314e824db4a..d83f607733b0 100644 --- a/tools/objtool/weak.c +++ b/tools/objtool/weak.c @@ -15,17 +15,12 @@ return ENOSYS; \ }) -int __weak check(struct objtool_file *file) -{ - UNSUPPORTED("check subcommand"); -} - int __weak orc_dump(const char *_objname) { - UNSUPPORTED("orc"); + UNSUPPORTED("ORC"); } int __weak orc_create(struct objtool_file *file) { - UNSUPPORTED("orc"); + UNSUPPORTED("ORC"); } -- cgit v1.2.3 From 7dce62041ac34b613a5ed1bd937117e492e06dc8 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 18 Apr 2022 09:50:33 -0700 Subject: objtool: Make stack validation optional Make stack validation an explicit cmdline option so that individual objtool features can be enabled individually by other arches. Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Miroslav Benes Link: https://lkml.kernel.org/r/52da143699574d756e65ca4c9d4acaffe9b0fe5f.1650300597.git.jpoimboe@redhat.com --- scripts/Makefile.build | 1 + scripts/link-vmlinux.sh | 4 ++++ tools/objtool/builtin-check.c | 2 ++ tools/objtool/check.c | 28 +++++++++++++++------------- tools/objtool/include/objtool/builtin.h | 1 + 5 files changed, 23 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 116c7272b41c..d5e15ae29156 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -232,6 +232,7 @@ objtool_args = \ $(if $(CONFIG_UNWINDER_ORC), --orc) \ $(if $(CONFIG_RETPOLINE), --retpoline) \ $(if $(CONFIG_SLS), --sls) \ + $(if $(CONFIG_STACK_VALIDATION), --stackval) \ $(if $(CONFIG_X86_SMAP), --uaccess) \ $(if $(part-of-module), --module) \ $(if $(CONFIG_FRAME_POINTER),, --no-fp) \ diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index f6db79b11573..0140bfa32c0c 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -126,6 +126,10 @@ objtool_link() objtoolopt="${objtoolopt} --orc" fi + if is_enabled CONFIG_STACK_VALIDATION; then + objtoolopt="${objtoolopt} --stackval" + fi + objtoolopt="${objtoolopt} --lto" fi diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index 6acfebd2c6ca..d4e6930ad0a0 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -39,6 +39,7 @@ const struct option check_options[] = { OPT_BOOLEAN('o', "orc", &opts.orc, "generate ORC metadata"), OPT_BOOLEAN('r', "retpoline", &opts.retpoline, "validate and annotate retpoline usage"), OPT_BOOLEAN('l', "sls", &opts.sls, "validate straight-line-speculation mitigations"), + OPT_BOOLEAN('s', "stackval", &opts.stackval, "validate stack unwinding rules"), OPT_BOOLEAN('u', "uaccess", &opts.uaccess, "validate uaccess rules for SMAP"), OPT_CALLBACK_OPTARG(0, "dump", NULL, NULL, "orc", "dump metadata", parse_dump), @@ -92,6 +93,7 @@ static bool opts_valid(void) opts.orc || opts.retpoline || opts.sls || + opts.stackval || opts.uaccess) { if (opts.dump_orc) { fprintf(stderr, "--dump can't be combined with other options\n"); diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 16a6c4b4f6bb..3456eb99b06e 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3899,25 +3899,27 @@ int check(struct objtool_file *file) warnings += ret; } - ret = validate_functions(file); - if (ret < 0) - goto out; - warnings += ret; - - ret = validate_unwind_hints(file, NULL); - if (ret < 0) - goto out; - warnings += ret; + if (opts.stackval || opts.orc || opts.uaccess || opts.ibt || opts.sls) { + ret = validate_functions(file); + if (ret < 0) + goto out; + warnings += ret; - if (opts.ibt) { - ret = validate_ibt(file); + ret = validate_unwind_hints(file, NULL); if (ret < 0) goto out; warnings += ret; + + if (!warnings) { + ret = validate_reachable_instructions(file); + if (ret < 0) + goto out; + warnings += ret; + } } - if (!warnings) { - ret = validate_reachable_instructions(file); + if (opts.ibt) { + ret = validate_ibt(file); if (ret < 0) goto out; warnings += ret; diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h index e0972fbfa09e..8618585bb742 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -18,6 +18,7 @@ struct opts { bool orc; bool retpoline; bool sls; + bool stackval; bool uaccess; /* options: */ -- cgit v1.2.3 From 03f16cd020eb8bb2eb837e2090086f296a9fa91d Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 18 Apr 2022 09:50:36 -0700 Subject: objtool: Add CONFIG_OBJTOOL Now that stack validation is an optional feature of objtool, add CONFIG_OBJTOOL and replace most usages of CONFIG_STACK_VALIDATION with it. CONFIG_STACK_VALIDATION can now be considered to be frame-pointer specific. CONFIG_UNWINDER_ORC is already inherently valid for live patching, so no need to "validate" it. Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Miroslav Benes Link: https://lkml.kernel.org/r/939bf3d85604b2a126412bf11af6e3bd3b872bcb.1650300597.git.jpoimboe@redhat.com --- Makefile | 2 +- arch/Kconfig | 8 ++++++-- arch/x86/Kconfig | 18 +++++++++++------- arch/x86/Kconfig.debug | 2 +- arch/x86/include/asm/jump_label.h | 6 +++--- arch/x86/kernel/alternative.c | 6 +++--- include/linux/compiler.h | 6 +++--- include/linux/instrumentation.h | 6 +++--- include/linux/objtool.h | 6 +++--- kernel/trace/Kconfig | 1 + lib/Kconfig.debug | 20 +++++++++++--------- lib/Kconfig.kcsan | 3 ++- lib/Kconfig.ubsan | 2 +- scripts/Makefile.build | 4 ++-- scripts/link-vmlinux.sh | 32 ++++++++++++++++++-------------- scripts/package/builddeb | 2 +- tools/include/linux/objtool.h | 6 +++--- 17 files changed, 73 insertions(+), 57 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index fa5112a0ec1b..250707647359 100644 --- a/Makefile +++ b/Makefile @@ -1302,7 +1302,7 @@ install: sub_make_done := # --------------------------------------------------------------------------- # Tools -ifdef CONFIG_STACK_VALIDATION +ifdef CONFIG_OBJTOOL prepare: tools/objtool endif diff --git a/arch/Kconfig b/arch/Kconfig index 29b0167c088b..04cdef16db24 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1028,11 +1028,14 @@ config ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT depends on MMU select ARCH_HAS_ELF_RANDOMIZE +config HAVE_OBJTOOL + bool + config HAVE_STACK_VALIDATION bool help - Architecture supports the 'objtool check' host tool command, which - performs compile-time stack metadata validation. + Architecture supports objtool compile-time frame pointer rule + validation. config HAVE_RELIABLE_STACKTRACE bool @@ -1302,6 +1305,7 @@ config HAVE_STATIC_CALL config HAVE_STATIC_CALL_INLINE bool depends on HAVE_STATIC_CALL + select OBJTOOL config HAVE_PREEMPT_DYNAMIC bool diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 4bed3abf444d..43e26ee1611e 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -188,7 +188,7 @@ config X86 select HAVE_CONTEXT_TRACKING if X86_64 select HAVE_CONTEXT_TRACKING_OFFSTACK if HAVE_CONTEXT_TRACKING select HAVE_C_RECORDMCOUNT - select HAVE_OBJTOOL_MCOUNT if STACK_VALIDATION + select HAVE_OBJTOOL_MCOUNT if HAVE_OBJTOOL select HAVE_BUILDTIME_MCOUNT_SORT select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_CONTIGUOUS @@ -231,6 +231,7 @@ config X86 select HAVE_MOVE_PMD select HAVE_MOVE_PUD select HAVE_NMI + select HAVE_OBJTOOL if X86_64 select HAVE_OPTPROBES select HAVE_PCSPKR_PLATFORM select HAVE_PERF_EVENTS @@ -239,17 +240,17 @@ config X86 select HAVE_PCI select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP - select MMU_GATHER_RCU_TABLE_FREE if PARAVIRT + select MMU_GATHER_RCU_TABLE_FREE if PARAVIRT select HAVE_POSIX_CPU_TIMERS_TASK_WORK select HAVE_REGS_AND_STACK_ACCESS_API - select HAVE_RELIABLE_STACKTRACE if X86_64 && (UNWINDER_FRAME_POINTER || UNWINDER_ORC) && STACK_VALIDATION + select HAVE_RELIABLE_STACKTRACE if UNWINDER_ORC || STACK_VALIDATION select HAVE_FUNCTION_ARG_ACCESS_API select HAVE_SETUP_PER_CPU_AREA select HAVE_SOFTIRQ_ON_OWN_STACK select HAVE_STACKPROTECTOR if CC_HAS_SANE_STACKPROTECTOR - select HAVE_STACK_VALIDATION if X86_64 + select HAVE_STACK_VALIDATION if HAVE_OBJTOOL select HAVE_STATIC_CALL - select HAVE_STATIC_CALL_INLINE if HAVE_STACK_VALIDATION + select HAVE_STATIC_CALL_INLINE if HAVE_OBJTOOL select HAVE_PREEMPT_DYNAMIC_CALL select HAVE_RSEQ select HAVE_SYSCALL_TRACEPOINTS @@ -268,7 +269,6 @@ config X86 select RTC_MC146818_LIB select SPARSE_IRQ select SRCU - select STACK_VALIDATION if HAVE_STACK_VALIDATION && (HAVE_STATIC_CALL_INLINE || RETPOLINE) select SYSCTL_EXCEPTION_TRACE select THREAD_INFO_IN_TASK select TRACE_IRQFLAGS_SUPPORT @@ -459,6 +459,7 @@ config GOLDFISH config RETPOLINE bool "Avoid speculative indirect branches in kernel" + select OBJTOOL if HAVE_OBJTOOL default y help Compile kernel with the retpoline compiler options to guard against @@ -472,6 +473,7 @@ config CC_HAS_SLS config SLS bool "Mitigate Straight-Line-Speculation" depends on CC_HAS_SLS && X86_64 + select OBJTOOL if HAVE_OBJTOOL default n help Compile the kernel with straight-line-speculation options to guard @@ -1819,6 +1821,7 @@ config ARCH_RANDOM config X86_SMAP def_bool y prompt "Supervisor Mode Access Prevention" if EXPERT + select OBJTOOL if HAVE_OBJTOOL help Supervisor Mode Access Prevention (SMAP) is a security feature in newer Intel processors. There is a small @@ -1855,9 +1858,10 @@ config CC_HAS_IBT config X86_KERNEL_IBT prompt "Indirect Branch Tracking" bool - depends on X86_64 && CC_HAS_IBT && STACK_VALIDATION + depends on X86_64 && CC_HAS_IBT && HAVE_OBJTOOL # https://github.com/llvm/llvm-project/commit/9d7001eba9c4cb311e03cd8cdc231f9e579f2d0f depends on !LD_IS_LLD || LLD_VERSION >= 140000 + select OBJTOOL help Build the kernel with support for Indirect Branch Tracking, a hardware support course-grain forward-edge Control Flow Integrity diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index d3a6f74a94bd..d872a7522e55 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -237,7 +237,7 @@ choice config UNWINDER_ORC bool "ORC unwinder" depends on X86_64 - select STACK_VALIDATION + select OBJTOOL help This option enables the ORC (Oops Rewind Capability) unwinder for unwinding kernel stack traces. It uses a custom data format which is diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h index 0449b125d27f..3ce0e67c579c 100644 --- a/arch/x86/include/asm/jump_label.h +++ b/arch/x86/include/asm/jump_label.h @@ -20,7 +20,7 @@ _ASM_PTR "%c0 + %c1 - .\n\t" \ ".popsection \n\t" -#ifdef CONFIG_STACK_VALIDATION +#ifdef CONFIG_OBJTOOL static __always_inline bool arch_static_branch(struct static_key *key, bool branch) { @@ -34,7 +34,7 @@ l_yes: return true; } -#else +#else /* !CONFIG_OBJTOOL */ static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch) { @@ -48,7 +48,7 @@ l_yes: return true; } -#endif /* STACK_VALIDATION */ +#endif /* CONFIG_OBJTOOL */ static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch) { diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index d374cb3cf024..3c66073e7645 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -338,7 +338,7 @@ next: } } -#if defined(CONFIG_RETPOLINE) && defined(CONFIG_STACK_VALIDATION) +#if defined(CONFIG_RETPOLINE) && defined(CONFIG_OBJTOOL) /* * CALL/JMP *%\reg @@ -507,11 +507,11 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) } } -#else /* !RETPOLINES || !CONFIG_STACK_VALIDATION */ +#else /* !CONFIG_RETPOLINE || !CONFIG_OBJTOOL */ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) { } -#endif /* CONFIG_RETPOLINE && CONFIG_STACK_VALIDATION */ +#endif /* CONFIG_RETPOLINE && CONFIG_OBJTOOL */ #ifdef CONFIG_X86_KERNEL_IBT diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 219aa5ddbc73..01ce94b58b42 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -109,7 +109,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, #endif /* Unreachable code */ -#ifdef CONFIG_STACK_VALIDATION +#ifdef CONFIG_OBJTOOL /* * These macros help objtool understand GCC code flow for unreachable code. * The __COUNTER__ based labels are a hack to make each instance of the macros @@ -128,10 +128,10 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, /* Annotate a C jump table to allow objtool to follow the code flow */ #define __annotate_jump_table __section(".rodata..c_jump_table") -#else +#else /* !CONFIG_OBJTOOL */ #define annotate_unreachable() #define __annotate_jump_table -#endif +#endif /* CONFIG_OBJTOOL */ #ifndef unreachable # define unreachable() do { \ diff --git a/include/linux/instrumentation.h b/include/linux/instrumentation.h index 24359b4a9605..9111a3704072 100644 --- a/include/linux/instrumentation.h +++ b/include/linux/instrumentation.h @@ -2,7 +2,7 @@ #ifndef __LINUX_INSTRUMENTATION_H #define __LINUX_INSTRUMENTATION_H -#if defined(CONFIG_DEBUG_ENTRY) && defined(CONFIG_STACK_VALIDATION) +#ifdef CONFIG_VMLINUX_VALIDATION #include @@ -53,9 +53,9 @@ ".popsection\n\t" : : "i" (c)); \ }) #define instrumentation_end() __instrumentation_end(__COUNTER__) -#else +#else /* !CONFIG_VMLINUX_VALIDATION */ # define instrumentation_begin() do { } while(0) # define instrumentation_end() do { } while(0) -#endif +#endif /* CONFIG_VMLINUX_VALIDATION */ #endif /* __LINUX_INSTRUMENTATION_H */ diff --git a/include/linux/objtool.h b/include/linux/objtool.h index 586d35720f13..977d90ba642d 100644 --- a/include/linux/objtool.h +++ b/include/linux/objtool.h @@ -38,7 +38,7 @@ struct unwind_hint { #define UNWIND_HINT_TYPE_REGS_PARTIAL 2 #define UNWIND_HINT_TYPE_FUNC 3 -#ifdef CONFIG_STACK_VALIDATION +#ifdef CONFIG_OBJTOOL #ifndef __ASSEMBLY__ @@ -157,7 +157,7 @@ struct unwind_hint { #endif /* __ASSEMBLY__ */ -#else /* !CONFIG_STACK_VALIDATION */ +#else /* !CONFIG_OBJTOOL */ #ifndef __ASSEMBLY__ @@ -179,6 +179,6 @@ struct unwind_hint { .endm #endif -#endif /* CONFIG_STACK_VALIDATION */ +#endif /* CONFIG_OBJTOOL */ #endif /* _LINUX_OBJTOOL_H */ diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 2c43e327a619..2956bc277150 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -728,6 +728,7 @@ config FTRACE_MCOUNT_USE_OBJTOOL depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY depends on !FTRACE_MCOUNT_USE_CC depends on FTRACE_MCOUNT_RECORD + select OBJTOOL config FTRACE_MCOUNT_USE_RECORDMCOUNT def_bool y diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 075cd25363ac..c0e4e47f3ce3 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -485,24 +485,25 @@ config FRAME_POINTER larger and slower, but it gives very useful debugging information in case of kernel bugs. (precise oopses/stacktraces/warnings) +config OBJTOOL + bool + config STACK_VALIDATION bool "Compile-time stack metadata validation" - depends on HAVE_STACK_VALIDATION + depends on HAVE_STACK_VALIDATION && UNWINDER_FRAME_POINTER + select OBJTOOL default n help - Add compile-time checks to validate stack metadata, including frame - pointers (if CONFIG_FRAME_POINTER is enabled). This helps ensure - that runtime stack traces are more reliable. - - This is also a prerequisite for generation of ORC unwind data, which - is needed for CONFIG_UNWINDER_ORC. + Validate frame pointer rules at compile-time. This helps ensure that + runtime stack traces are more reliable. For more information, see tools/objtool/Documentation/stack-validation.txt. config VMLINUX_VALIDATION bool - depends on STACK_VALIDATION && DEBUG_ENTRY + depends on HAVE_OBJTOOL && DEBUG_ENTRY + select OBJTOOL default y config VMLINUX_MAP @@ -2035,10 +2036,11 @@ config KCOV bool "Code coverage for fuzzing" depends on ARCH_HAS_KCOV depends on CC_HAS_SANCOV_TRACE_PC || GCC_PLUGINS - depends on !ARCH_WANTS_NO_INSTR || STACK_VALIDATION || \ + depends on !ARCH_WANTS_NO_INSTR || HAVE_OBJTOOL || \ GCC_VERSION >= 120000 || CLANG_VERSION >= 130000 select DEBUG_FS select GCC_PLUGIN_SANCOV if !CC_HAS_SANCOV_TRACE_PC + select OBJTOOL if HAVE_OBJTOOL help KCOV exposes kernel code coverage information in a form suitable for coverage-guided fuzzing (randomized testing). diff --git a/lib/Kconfig.kcsan b/lib/Kconfig.kcsan index de022445fbba..901c3b509aca 100644 --- a/lib/Kconfig.kcsan +++ b/lib/Kconfig.kcsan @@ -187,7 +187,8 @@ config KCSAN_WEAK_MEMORY # We can either let objtool nop __tsan_func_{entry,exit}() and builtin # atomics instrumentation in .noinstr.text, or use a compiler that can # implement __no_kcsan to really remove all instrumentation. - depends on STACK_VALIDATION || CC_IS_GCC || CLANG_VERSION >= 140000 + depends on HAVE_OBJTOOL || CC_IS_GCC || CLANG_VERSION >= 140000 + select OBJTOOL if HAVE_OBJTOOL help Enable support for modeling a subset of weak memory, which allows detecting a subset of data races due to missing memory barriers. diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan index f3c57ed51838..c4fe15d38b60 100644 --- a/lib/Kconfig.ubsan +++ b/lib/Kconfig.ubsan @@ -94,7 +94,7 @@ config UBSAN_UNREACHABLE bool "Perform checking for unreachable code" # objtool already handles unreachable checking and gets angry about # seeing UBSan instrumentation located in unreachable places. - depends on !STACK_VALIDATION + depends on !(OBJTOOL && (STACK_VALIDATION || UNWINDER_ORC || X86_SMAP)) depends on $(cc-option,-fsanitize=unreachable) help This option enables -fsanitize=unreachable which checks for control diff --git a/scripts/Makefile.build b/scripts/Makefile.build index d5e15ae29156..0f73e02b7cf1 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -222,7 +222,7 @@ cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), $(sub_cmd_record_mcount)) endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT -ifdef CONFIG_STACK_VALIDATION +ifdef CONFIG_OBJTOOL objtool := $(objtree)/tools/objtool/objtool @@ -241,7 +241,7 @@ objtool_args = \ cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@) cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd) -endif # CONFIG_STACK_VALIDATION +endif # CONFIG_OBJTOOL ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 0140bfa32c0c..5101a7fbfaaf 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -108,8 +108,11 @@ objtool_link() local objtoolcmd; local objtoolopt; - if is_enabled CONFIG_STACK_VALIDATION && \ - ( is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT ); then + if ! is_enabled CONFIG_OBJTOOL; then + return; + fi + + if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then # Don't perform vmlinux validation unless explicitly requested, # but run objtool on vmlinux.o now that we have an object file. @@ -126,10 +129,23 @@ objtool_link() objtoolopt="${objtoolopt} --orc" fi + if is_enabled CONFIG_RETPOLINE; then + objtoolopt="${objtoolopt} --retpoline" + fi + + if is_enabled CONFIG_SLS; then + objtoolopt="${objtoolopt} --sls" + fi + if is_enabled CONFIG_STACK_VALIDATION; then objtoolopt="${objtoolopt} --stackval" fi + if is_enabled CONFIG_X86_SMAP; then + objtoolopt="${objtoolopt} --uaccess" + fi + + objtoolopt="${objtoolopt} --lto" fi @@ -139,18 +155,6 @@ objtool_link() if [ -n "${objtoolopt}" ]; then - if is_enabled CONFIG_RETPOLINE; then - objtoolopt="${objtoolopt} --retpoline" - fi - - if is_enabled CONFIG_SLS; then - objtoolopt="${objtoolopt} --sls" - fi - - if is_enabled CONFIG_X86_SMAP; then - objtoolopt="${objtoolopt} --uaccess" - fi - if ! is_enabled CONFIG_FRAME_POINTER; then objtoolopt="${objtoolopt} --no-fp" fi diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 91a502bb97e8..67cd420dcf89 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -67,7 +67,7 @@ deploy_kernel_headers () { ) > debian/hdrsrcfiles { - if is_enabled CONFIG_STACK_VALIDATION; then + if is_enabled CONFIG_OBJTOOL; then echo tools/objtool/objtool fi diff --git a/tools/include/linux/objtool.h b/tools/include/linux/objtool.h index 586d35720f13..977d90ba642d 100644 --- a/tools/include/linux/objtool.h +++ b/tools/include/linux/objtool.h @@ -38,7 +38,7 @@ struct unwind_hint { #define UNWIND_HINT_TYPE_REGS_PARTIAL 2 #define UNWIND_HINT_TYPE_FUNC 3 -#ifdef CONFIG_STACK_VALIDATION +#ifdef CONFIG_OBJTOOL #ifndef __ASSEMBLY__ @@ -157,7 +157,7 @@ struct unwind_hint { #endif /* __ASSEMBLY__ */ -#else /* !CONFIG_STACK_VALIDATION */ +#else /* !CONFIG_OBJTOOL */ #ifndef __ASSEMBLY__ @@ -179,6 +179,6 @@ struct unwind_hint { .endm #endif -#endif /* CONFIG_STACK_VALIDATION */ +#endif /* CONFIG_OBJTOOL */ #endif /* _LINUX_OBJTOOL_H */ -- cgit v1.2.3 From 72064474964724c59ddff58a581a31b1ede75cf9 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 18 Apr 2022 09:50:37 -0700 Subject: objtool: Make stack validation frame-pointer-specific Now that CONFIG_STACK_VALIDATION is frame-pointer specific, do the same for the '--stackval' option. Now the '--no-fp' option is redundant and can be removed. Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Miroslav Benes Link: https://lkml.kernel.org/r/f563fa064b3b63d528de250c72012d49e14742a3.1650300597.git.jpoimboe@redhat.com --- scripts/Makefile.build | 1 - scripts/link-vmlinux.sh | 4 ---- tools/objtool/builtin-check.c | 3 +-- tools/objtool/check.c | 4 ++-- tools/objtool/include/objtool/builtin.h | 1 - 5 files changed, 3 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 0f73e02b7cf1..6eb99cb08821 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -235,7 +235,6 @@ objtool_args = \ $(if $(CONFIG_STACK_VALIDATION), --stackval) \ $(if $(CONFIG_X86_SMAP), --uaccess) \ $(if $(part-of-module), --module) \ - $(if $(CONFIG_FRAME_POINTER),, --no-fp) \ $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 5101a7fbfaaf..1be01163a9c5 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -155,10 +155,6 @@ objtool_link() if [ -n "${objtoolopt}" ]; then - if ! is_enabled CONFIG_FRAME_POINTER; then - objtoolopt="${objtoolopt} --no-fp" - fi - if is_enabled CONFIG_GCOV_KERNEL; then objtoolopt="${objtoolopt} --no-unreachable" fi diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index d4e6930ad0a0..30971cc50c63 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -39,7 +39,7 @@ const struct option check_options[] = { OPT_BOOLEAN('o', "orc", &opts.orc, "generate ORC metadata"), OPT_BOOLEAN('r', "retpoline", &opts.retpoline, "validate and annotate retpoline usage"), OPT_BOOLEAN('l', "sls", &opts.sls, "validate straight-line-speculation mitigations"), - OPT_BOOLEAN('s', "stackval", &opts.stackval, "validate stack unwinding rules"), + OPT_BOOLEAN('s', "stackval", &opts.stackval, "validate frame pointer rules"), OPT_BOOLEAN('u', "uaccess", &opts.uaccess, "validate uaccess rules for SMAP"), OPT_CALLBACK_OPTARG(0, "dump", NULL, NULL, "orc", "dump metadata", parse_dump), @@ -49,7 +49,6 @@ const struct option check_options[] = { OPT_BOOLEAN(0, "dry-run", &opts.dryrun, "don't write modifications"), OPT_BOOLEAN(0, "lto", &opts.lto, "whole-archive like runs"), OPT_BOOLEAN(0, "module", &opts.module, "object is part of a kernel module"), - OPT_BOOLEAN(0, "no-fp", &opts.no_fp, "skip frame pointer validation"), OPT_BOOLEAN(0, "no-unreachable", &opts.no_unreachable, "skip 'unreachable instruction' warnings"), OPT_BOOLEAN(0, "sec-address", &opts.sec_address, "print section addresses in warnings"), OPT_BOOLEAN(0, "stats", &opts.stats, "print statistics"), diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 27126fff91dc..3e02126738a1 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2806,7 +2806,7 @@ static int update_cfi_state(struct instruction *insn, } /* detect when asm code uses rbp as a scratch register */ - if (!opts.no_fp && insn->func && op->src.reg == CFI_BP && + if (opts.stackval && insn->func && op->src.reg == CFI_BP && cfa->base != CFI_BP) cfi->bp_scratch = true; break; @@ -3279,7 +3279,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, if (ret) return ret; - if (!opts.no_fp && func && !is_fentry_call(insn) && + if (opts.stackval && func && !is_fentry_call(insn) && !has_valid_stack_frame(&state)) { WARN_FUNC("call without frame pointer save/setup", sec, insn->offset); diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h index 8618585bb742..24a7ff4f37cc 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -27,7 +27,6 @@ struct opts { bool dryrun; bool lto; bool module; - bool no_fp; bool no_unreachable; bool sec_address; bool stats; -- cgit v1.2.3 From 26e176896a5bb9222ae3433da902edd2566a61a4 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 18 Apr 2022 09:50:38 -0700 Subject: objtool: Make static call annotation optional As part of making objtool more modular, put the existing static call code behind a new '--static-call' option. Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Miroslav Benes Link: https://lkml.kernel.org/r/d59ac57ef3d6d8380cdce20322314c9e2e556750.1650300597.git.jpoimboe@redhat.com --- scripts/Makefile.build | 1 + scripts/link-vmlinux.sh | 5 ++++- tools/objtool/builtin-check.c | 2 ++ tools/objtool/check.c | 10 ++++++---- tools/objtool/include/objtool/builtin.h | 1 + 5 files changed, 14 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 6eb99cb08821..3f20d565733c 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -233,6 +233,7 @@ objtool_args = \ $(if $(CONFIG_RETPOLINE), --retpoline) \ $(if $(CONFIG_SLS), --sls) \ $(if $(CONFIG_STACK_VALIDATION), --stackval) \ + $(if $(CONFIG_HAVE_STATIC_CALL_INLINE), --static-call) \ $(if $(CONFIG_X86_SMAP), --uaccess) \ $(if $(part-of-module), --module) \ $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 1be01163a9c5..33f14fe1ddde 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -141,11 +141,14 @@ objtool_link() objtoolopt="${objtoolopt} --stackval" fi + if is_enabled CONFIG_HAVE_STATIC_CALL_INLINE; then + objtoolopt="${objtoolopt} --static-call" + fi + if is_enabled CONFIG_X86_SMAP; then objtoolopt="${objtoolopt} --uaccess" fi - objtoolopt="${objtoolopt} --lto" fi diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index 30971cc50c63..c8c4d2bab42f 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -40,6 +40,7 @@ const struct option check_options[] = { OPT_BOOLEAN('r', "retpoline", &opts.retpoline, "validate and annotate retpoline usage"), OPT_BOOLEAN('l', "sls", &opts.sls, "validate straight-line-speculation mitigations"), OPT_BOOLEAN('s', "stackval", &opts.stackval, "validate frame pointer rules"), + OPT_BOOLEAN('t', "static-call", &opts.static_call, "annotate static calls"), OPT_BOOLEAN('u', "uaccess", &opts.uaccess, "validate uaccess rules for SMAP"), OPT_CALLBACK_OPTARG(0, "dump", NULL, NULL, "orc", "dump metadata", parse_dump), @@ -93,6 +94,7 @@ static bool opts_valid(void) opts.retpoline || opts.sls || opts.stackval || + opts.static_call || opts.uaccess) { if (opts.dump_orc) { fprintf(stderr, "--dump can't be combined with other options\n"); diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 3e02126738a1..b9ac351ea08b 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3969,10 +3969,12 @@ int check(struct objtool_file *file) warnings += ret; } - ret = create_static_call_sections(file); - if (ret < 0) - goto out; - warnings += ret; + if (opts.static_call) { + ret = create_static_call_sections(file); + if (ret < 0) + goto out; + warnings += ret; + } if (opts.retpoline) { ret = create_retpoline_sites_sections(file); diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h index 24a7ff4f37cc..dc4757205b8d 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -19,6 +19,7 @@ struct opts { bool retpoline; bool sls; bool stackval; + bool static_call; bool uaccess; /* options: */ -- cgit v1.2.3 From 4ab7674f5951ac6a8ac4fa8828090edb64a4771f Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 18 Apr 2022 09:50:39 -0700 Subject: objtool: Make jump label hack optional Objtool secretly does a jump label hack to overcome the limitations of the toolchain. Make the hack explicit (and optional for other arches) by turning it into a cmdline option and kernel config option. Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Miroslav Benes Link: https://lkml.kernel.org/r/3bdcbfdd27ecb01ddec13c04bdf756a583b13d24.1650300597.git.jpoimboe@redhat.com --- arch/Kconfig | 4 ++++ arch/x86/Kconfig | 1 + arch/x86/include/asm/jump_label.h | 6 +++--- scripts/Makefile.build | 1 + scripts/link-vmlinux.sh | 4 ++++ tools/objtool/builtin-check.c | 37 ++++++++++++++++++++++++++------- tools/objtool/check.c | 2 +- tools/objtool/include/objtool/builtin.h | 1 + 8 files changed, 44 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/arch/Kconfig b/arch/Kconfig index 04cdef16db24..9dce6d6e3bc3 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -46,6 +46,7 @@ config JUMP_LABEL bool "Optimize very unlikely/likely branches" depends on HAVE_ARCH_JUMP_LABEL depends on CC_HAS_ASM_GOTO + select OBJTOOL if HAVE_JUMP_LABEL_HACK help This option enables a transparent branch optimization that makes certain almost-always-true or almost-always-false branch @@ -1031,6 +1032,9 @@ config ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT config HAVE_OBJTOOL bool +config HAVE_JUMP_LABEL_HACK + bool + config HAVE_STACK_VALIDATION bool help diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 43e26ee1611e..26d012f1eeb8 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -212,6 +212,7 @@ config X86 select HAVE_IOREMAP_PROT select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64 select HAVE_IRQ_TIME_ACCOUNTING + select HAVE_JUMP_LABEL_HACK if HAVE_OBJTOOL select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZ4 diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h index 3ce0e67c579c..071572e23d3a 100644 --- a/arch/x86/include/asm/jump_label.h +++ b/arch/x86/include/asm/jump_label.h @@ -20,7 +20,7 @@ _ASM_PTR "%c0 + %c1 - .\n\t" \ ".popsection \n\t" -#ifdef CONFIG_OBJTOOL +#ifdef CONFIG_HAVE_JUMP_LABEL_HACK static __always_inline bool arch_static_branch(struct static_key *key, bool branch) { @@ -34,7 +34,7 @@ l_yes: return true; } -#else /* !CONFIG_OBJTOOL */ +#else /* !CONFIG_HAVE_JUMP_LABEL_HACK */ static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch) { @@ -48,7 +48,7 @@ l_yes: return true; } -#endif /* CONFIG_OBJTOOL */ +#endif /* CONFIG_HAVE_JUMP_LABEL_HACK */ static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch) { diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 3f20d565733c..f1d2c2e4f15b 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -227,6 +227,7 @@ ifdef CONFIG_OBJTOOL objtool := $(objtree)/tools/objtool/objtool objtool_args = \ + $(if $(CONFIG_HAVE_JUMP_LABEL_HACK), --hacks=jump_label) \ $(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt) \ $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ $(if $(CONFIG_UNWINDER_ORC), --orc) \ diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 33f14fe1ddde..fa1f16840e76 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -117,6 +117,10 @@ objtool_link() # Don't perform vmlinux validation unless explicitly requested, # but run objtool on vmlinux.o now that we have an object file. + if is_enabled CONFIG_HAVE_JUMP_LABEL_HACK; then + objtoolopt="${objtoolopt} --hacks=jump_label" + fi + if is_enabled CONFIG_X86_KERNEL_IBT; then objtoolopt="${objtoolopt} --ibt" fi diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index c8c4d2bab42f..b2c626d9e2bf 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -31,8 +31,28 @@ static int parse_dump(const struct option *opt, const char *str, int unset) return -1; } +static int parse_hacks(const struct option *opt, const char *str, int unset) +{ + bool found = false; + + /* + * Use strstr() as a lazy method of checking for comma-separated + * options. + * + * No string provided == enable all options. + */ + + if (!str || strstr(str, "jump_label")) { + opts.hack_jump_label = true; + found = true; + } + + return found ? 0 : -1; +} + const struct option check_options[] = { OPT_GROUP("Actions:"), + OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label", "patch toolchain bugs/limitations", parse_hacks), OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"), OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls for ftrace"), OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"), @@ -87,14 +107,15 @@ int cmd_parse_options(int argc, const char **argv, const char * const usage[]) static bool opts_valid(void) { - if (opts.ibt || - opts.mcount || - opts.noinstr || - opts.orc || - opts.retpoline || - opts.sls || - opts.stackval || - opts.static_call || + if (opts.hack_jump_label || + opts.ibt || + opts.mcount || + opts.noinstr || + opts.orc || + opts.retpoline || + opts.sls || + opts.stackval || + opts.static_call || opts.uaccess) { if (opts.dump_orc) { fprintf(stderr, "--dump can't be combined with other options\n"); diff --git a/tools/objtool/check.c b/tools/objtool/check.c index b9ac351ea08b..d157978c58b3 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1592,7 +1592,7 @@ static int handle_jump_alt(struct objtool_file *file, return -1; } - if (special_alt->key_addend & 2) { + if (opts.hack_jump_label && special_alt->key_addend & 2) { struct reloc *reloc = insn_reloc(file, orig_insn); if (reloc) { diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h index dc4757205b8d..c6acf05ec859 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -12,6 +12,7 @@ extern const struct option check_options[]; struct opts { /* actions: */ bool dump_orc; + bool hack_jump_label; bool ibt; bool mcount; bool noinstr; -- cgit v1.2.3 From 22102f4559beaabcea614b29ee090c6a214f002f Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 18 Apr 2022 09:50:40 -0700 Subject: objtool: Make noinstr hacks optional Objtool has some hacks in place to workaround toolchain limitations which otherwise would break no-instrumentation rules. Make the hacks explicit (and optional for other arches) by turning it into a cmdline option and kernel config option. Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Miroslav Benes Link: https://lkml.kernel.org/r/b326eeb9c33231b9dfbb925f194ed7ee40edcd7c.1650300597.git.jpoimboe@redhat.com --- arch/Kconfig | 3 +++ arch/x86/Kconfig | 1 + lib/Kconfig.debug | 4 ++-- lib/Kconfig.kcsan | 5 +++-- scripts/Makefile.build | 1 + scripts/link-vmlinux.sh | 4 ++++ tools/objtool/builtin-check.c | 8 +++++++- tools/objtool/check.c | 2 +- tools/objtool/include/objtool/builtin.h | 1 + 9 files changed, 23 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/arch/Kconfig b/arch/Kconfig index 9dce6d6e3bc3..6ba6e34db0ea 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1035,6 +1035,9 @@ config HAVE_OBJTOOL config HAVE_JUMP_LABEL_HACK bool +config HAVE_NOINSTR_HACK + bool + config HAVE_STACK_VALIDATION bool help diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 26d012f1eeb8..06e7cdd76691 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -231,6 +231,7 @@ config X86 select HAVE_MOD_ARCH_SPECIFIC select HAVE_MOVE_PMD select HAVE_MOVE_PUD + select HAVE_NOINSTR_HACK if HAVE_OBJTOOL select HAVE_NMI select HAVE_OBJTOOL if X86_64 select HAVE_OPTPROBES diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index c0e4e47f3ce3..7d2bbc3e558e 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2036,11 +2036,11 @@ config KCOV bool "Code coverage for fuzzing" depends on ARCH_HAS_KCOV depends on CC_HAS_SANCOV_TRACE_PC || GCC_PLUGINS - depends on !ARCH_WANTS_NO_INSTR || HAVE_OBJTOOL || \ + depends on !ARCH_WANTS_NO_INSTR || HAVE_NOINSTR_HACK || \ GCC_VERSION >= 120000 || CLANG_VERSION >= 130000 select DEBUG_FS select GCC_PLUGIN_SANCOV if !CC_HAS_SANCOV_TRACE_PC - select OBJTOOL if HAVE_OBJTOOL + select OBJTOOL if HAVE_NOINSTR_HACK help KCOV exposes kernel code coverage information in a form suitable for coverage-guided fuzzing (randomized testing). diff --git a/lib/Kconfig.kcsan b/lib/Kconfig.kcsan index 901c3b509aca..47a693c45864 100644 --- a/lib/Kconfig.kcsan +++ b/lib/Kconfig.kcsan @@ -187,8 +187,9 @@ config KCSAN_WEAK_MEMORY # We can either let objtool nop __tsan_func_{entry,exit}() and builtin # atomics instrumentation in .noinstr.text, or use a compiler that can # implement __no_kcsan to really remove all instrumentation. - depends on HAVE_OBJTOOL || CC_IS_GCC || CLANG_VERSION >= 140000 - select OBJTOOL if HAVE_OBJTOOL + depends on !ARCH_WANTS_NO_INSTR || HAVE_NOINSTR_HACK || \ + CC_IS_GCC || CLANG_VERSION >= 140000 + select OBJTOOL if HAVE_NOINSTR_HACK help Enable support for modeling a subset of weak memory, which allows detecting a subset of data races due to missing memory barriers. diff --git a/scripts/Makefile.build b/scripts/Makefile.build index f1d2c2e4f15b..6c206a1bab97 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -228,6 +228,7 @@ objtool := $(objtree)/tools/objtool/objtool objtool_args = \ $(if $(CONFIG_HAVE_JUMP_LABEL_HACK), --hacks=jump_label) \ + $(if $(CONFIG_HAVE_NOINSTR_HACK), --hacks=noinstr) \ $(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt) \ $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ $(if $(CONFIG_UNWINDER_ORC), --orc) \ diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index fa1f16840e76..90c9c4c05d95 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -121,6 +121,10 @@ objtool_link() objtoolopt="${objtoolopt} --hacks=jump_label" fi + if is_enabled CONFIG_HAVE_NOINSTR_HACK; then + objtoolopt="${objtoolopt} --hacks=noinstr" + fi + if is_enabled CONFIG_X86_KERNEL_IBT; then objtoolopt="${objtoolopt} --ibt" fi diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index b2c626d9e2bf..1803a63147e4 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -47,12 +47,17 @@ static int parse_hacks(const struct option *opt, const char *str, int unset) found = true; } + if (!str || strstr(str, "noinstr")) { + opts.hack_noinstr = true; + found = true; + } + return found ? 0 : -1; } const struct option check_options[] = { OPT_GROUP("Actions:"), - OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label", "patch toolchain bugs/limitations", parse_hacks), + OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label,noinstr", "patch toolchain bugs/limitations", parse_hacks), OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"), OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls for ftrace"), OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"), @@ -108,6 +113,7 @@ int cmd_parse_options(int argc, const char **argv, const char * const usage[]) static bool opts_valid(void) { if (opts.hack_jump_label || + opts.hack_noinstr || opts.ibt || opts.mcount || opts.noinstr || diff --git a/tools/objtool/check.c b/tools/objtool/check.c index d157978c58b3..30b24dce48b5 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1144,7 +1144,7 @@ static void annotate_call_site(struct objtool_file *file, * attribute so they need a little help, NOP out any such calls from * noinstr text. */ - if (insn->sec->noinstr && sym->profiling_func) { + if (opts.hack_noinstr && insn->sec->noinstr && sym->profiling_func) { if (reloc) { reloc->type = R_NONE; elf_write_reloc(file->elf, reloc); diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h index c6acf05ec859..f3a1a754b5c4 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -13,6 +13,7 @@ struct opts { /* actions: */ bool dump_orc; bool hack_jump_label; + bool hack_noinstr; bool ibt; bool mcount; bool noinstr; -- cgit v1.2.3 From 0f620cefd7753175b6258fed85f76c2014ec3799 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 18 Apr 2022 09:50:41 -0700 Subject: objtool: Rename "VMLINUX_VALIDATION" -> "NOINSTR_VALIDATION" CONFIG_VMLINUX_VALIDATION is just the validation of the "noinstr" rules. That name is a misnomer, because now objtool actually does vmlinux validation for other reasons. Rename CONFIG_VMLINUX_VALIDATION to CONFIG_NOINSTR_VALIDATION. Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Miroslav Benes Link: https://lkml.kernel.org/r/173f07e2d6d1afc0874aed975a61783207c6a531.1650300597.git.jpoimboe@redhat.com --- include/linux/instrumentation.h | 6 +++--- lib/Kconfig.debug | 2 +- scripts/link-vmlinux.sh | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/include/linux/instrumentation.h b/include/linux/instrumentation.h index 9111a3704072..bc7babe91b2e 100644 --- a/include/linux/instrumentation.h +++ b/include/linux/instrumentation.h @@ -2,7 +2,7 @@ #ifndef __LINUX_INSTRUMENTATION_H #define __LINUX_INSTRUMENTATION_H -#ifdef CONFIG_VMLINUX_VALIDATION +#ifdef CONFIG_NOINSTR_VALIDATION #include @@ -53,9 +53,9 @@ ".popsection\n\t" : : "i" (c)); \ }) #define instrumentation_end() __instrumentation_end(__COUNTER__) -#else /* !CONFIG_VMLINUX_VALIDATION */ +#else /* !CONFIG_NOINSTR_VALIDATION */ # define instrumentation_begin() do { } while(0) # define instrumentation_end() do { } while(0) -#endif /* CONFIG_VMLINUX_VALIDATION */ +#endif /* CONFIG_NOINSTR_VALIDATION */ #endif /* __LINUX_INSTRUMENTATION_H */ diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 7d2bbc3e558e..73359d6cd9a2 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -500,7 +500,7 @@ config STACK_VALIDATION For more information, see tools/objtool/Documentation/stack-validation.txt. -config VMLINUX_VALIDATION +config NOINSTR_VALIDATION bool depends on HAVE_OBJTOOL && DEBUG_ENTRY select OBJTOOL diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 90c9c4c05d95..fce4f41816cd 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -160,7 +160,7 @@ objtool_link() objtoolopt="${objtoolopt} --lto" fi - if is_enabled CONFIG_VMLINUX_VALIDATION; then + if is_enabled CONFIG_NOINSTR_VALIDATION; then objtoolopt="${objtoolopt} --noinstr" fi -- cgit v1.2.3 From 753da4179d08b625d8df72e97724e22749969fd3 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 18 Apr 2022 09:50:43 -0700 Subject: objtool: Remove --lto and --vmlinux in favor of --link The '--lto' option is a confusing way of telling objtool to do stack validation despite it being a linked object. It's no longer needed now that an explicit '--stackval' option exists. The '--vmlinux' option is also redundant. Remove both options in favor of a straightforward '--link' option which identifies a linked object. Also, implicitly set '--link' with a warning if the user forgets to do so and we can tell that it's a linked object. This makes it easier for manual vmlinux runs. Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Miroslav Benes Link: https://lkml.kernel.org/r/dcd3ceffd15a54822c6183e5766d21ad06082b45.1650300597.git.jpoimboe@redhat.com --- scripts/Makefile.build | 4 +++- scripts/link-vmlinux.sh | 8 +++---- tools/objtool/builtin-check.c | 39 ++++++++++++++++++++++++++++---- tools/objtool/check.c | 40 ++++++++++++--------------------- tools/objtool/elf.c | 3 +++ tools/objtool/include/objtool/builtin.h | 3 +-- tools/objtool/include/objtool/elf.h | 12 +++++++++- 7 files changed, 70 insertions(+), 39 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 6c206a1bab97..ac8167227bc0 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -229,7 +229,7 @@ objtool := $(objtree)/tools/objtool/objtool objtool_args = \ $(if $(CONFIG_HAVE_JUMP_LABEL_HACK), --hacks=jump_label) \ $(if $(CONFIG_HAVE_NOINSTR_HACK), --hacks=noinstr) \ - $(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt) \ + $(if $(CONFIG_X86_KERNEL_IBT), --ibt) \ $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ $(if $(CONFIG_UNWINDER_ORC), --orc) \ $(if $(CONFIG_RETPOLINE), --retpoline) \ @@ -237,6 +237,7 @@ objtool_args = \ $(if $(CONFIG_STACK_VALIDATION), --stackval) \ $(if $(CONFIG_HAVE_STATIC_CALL_INLINE), --static-call) \ $(if $(CONFIG_X86_SMAP), --uaccess) \ + $(if $(linked-object), --link) \ $(if $(part-of-module), --module) \ $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) @@ -306,6 +307,7 @@ quiet_cmd_cc_prelink_modules = LD [M] $@ # modules into native code $(obj)/%.prelink.o: objtool-enabled = y $(obj)/%.prelink.o: part-of-module := y +$(obj)/%.prelink.o: linked-object := y $(obj)/%.prelink.o: $(obj)/%.o FORCE $(call if_changed,cc_prelink_modules) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index fce4f41816cd..eb9324f07f3d 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -114,8 +114,8 @@ objtool_link() if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then - # Don't perform vmlinux validation unless explicitly requested, - # but run objtool on vmlinux.o now that we have an object file. + # For LTO and IBT, objtool doesn't run on individual + # translation units. Run everything on vmlinux instead. if is_enabled CONFIG_HAVE_JUMP_LABEL_HACK; then objtoolopt="${objtoolopt} --hacks=jump_label" @@ -156,8 +156,6 @@ objtool_link() if is_enabled CONFIG_X86_SMAP; then objtoolopt="${objtoolopt} --uaccess" fi - - objtoolopt="${objtoolopt} --lto" fi if is_enabled CONFIG_NOINSTR_VALIDATION; then @@ -170,7 +168,7 @@ objtool_link() objtoolopt="${objtoolopt} --no-unreachable" fi - objtoolopt="${objtoolopt} --vmlinux" + objtoolopt="${objtoolopt} --link" info OBJTOOL ${1} tools/objtool/objtool ${objtoolopt} ${1} diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index 1803a63147e4..f4c3a5091737 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -9,6 +9,11 @@ #include #include +#define ERROR(format, ...) \ + fprintf(stderr, \ + "error: objtool: " format "\n", \ + ##__VA_ARGS__) + struct opts opts; static const char * const check_usage[] = { @@ -73,12 +78,11 @@ const struct option check_options[] = { OPT_BOOLEAN(0, "backtrace", &opts.backtrace, "unwind on error"), OPT_BOOLEAN(0, "backup", &opts.backup, "create .orig files before modification"), OPT_BOOLEAN(0, "dry-run", &opts.dryrun, "don't write modifications"), - OPT_BOOLEAN(0, "lto", &opts.lto, "whole-archive like runs"), + OPT_BOOLEAN(0, "link", &opts.link, "object is a linked object"), OPT_BOOLEAN(0, "module", &opts.module, "object is part of a kernel module"), OPT_BOOLEAN(0, "no-unreachable", &opts.no_unreachable, "skip 'unreachable instruction' warnings"), OPT_BOOLEAN(0, "sec-address", &opts.sec_address, "print section addresses in warnings"), OPT_BOOLEAN(0, "stats", &opts.stats, "print statistics"), - OPT_BOOLEAN(0, "vmlinux", &opts.vmlinux, "vmlinux.o validation"), OPT_END(), }; @@ -124,7 +128,7 @@ static bool opts_valid(void) opts.static_call || opts.uaccess) { if (opts.dump_orc) { - fprintf(stderr, "--dump can't be combined with other options\n"); + ERROR("--dump can't be combined with other options"); return false; } @@ -134,10 +138,34 @@ static bool opts_valid(void) if (opts.dump_orc) return true; - fprintf(stderr, "At least one command required\n"); + ERROR("At least one command required"); return false; } +static bool link_opts_valid(struct objtool_file *file) +{ + if (opts.link) + return true; + + if (has_multiple_files(file->elf)) { + ERROR("Linked object detected, forcing --link"); + opts.link = true; + return true; + } + + if (opts.noinstr) { + ERROR("--noinstr requires --link"); + return false; + } + + if (opts.ibt) { + ERROR("--ibt requires --link"); + return false; + } + + return true; +} + int objtool_run(int argc, const char **argv) { const char *objname; @@ -157,6 +185,9 @@ int objtool_run(int argc, const char **argv) if (!file) return 1; + if (!link_opts_valid(file)) + return 1; + ret = check(file); if (ret) return ret; diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 30b24dce48b5..2063f9fea1a2 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -263,7 +263,8 @@ static void init_cfi_state(struct cfi_state *cfi) cfi->drap_offset = -1; } -static void init_insn_state(struct insn_state *state, struct section *sec) +static void init_insn_state(struct objtool_file *file, struct insn_state *state, + struct section *sec) { memset(state, 0, sizeof(*state)); init_cfi_state(&state->cfi); @@ -273,7 +274,7 @@ static void init_insn_state(struct insn_state *state, struct section *sec) * not correctly determine insn->call_dest->sec (external symbols do * not have a section). */ - if (opts.vmlinux && opts.noinstr && sec) + if (opts.link && opts.noinstr && sec) state->noinstr = sec->noinstr; } @@ -3405,7 +3406,7 @@ static int validate_unwind_hints(struct objtool_file *file, struct section *sec) if (!file->hints) return 0; - init_insn_state(&state, sec); + init_insn_state(file, &state, sec); if (sec) { insn = find_insn(file, sec, 0); @@ -3491,14 +3492,14 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio return true; /* - * Whole archive runs might encounder dead code from weak symbols. + * Whole archive runs might encounter dead code from weak symbols. * This is where the linker will have dropped the weak symbol in * favour of a regular symbol, but leaves the code in place. * * In this case we'll find a piece of code (whole function) that is not * covered by a !section symbol. Ignore them. */ - if (!insn->func && opts.lto) { + if (opts.link && !insn->func) { int size = find_symbol_hole_containing(insn->sec, insn->offset); unsigned long end = insn->offset + size; @@ -3620,7 +3621,7 @@ static int validate_section(struct objtool_file *file, struct section *sec) if (func->type != STT_FUNC) continue; - init_insn_state(&state, sec); + init_insn_state(file, &state, sec); set_func_state(&state.cfi); warnings += validate_symbol(file, sec, func, &state); @@ -3629,7 +3630,7 @@ static int validate_section(struct objtool_file *file, struct section *sec) return warnings; } -static int validate_vmlinux_functions(struct objtool_file *file) +static int validate_noinstr_sections(struct objtool_file *file) { struct section *sec; int warnings = 0; @@ -3890,16 +3891,6 @@ int check(struct objtool_file *file) { int ret, warnings = 0; - if (opts.lto && !(opts.vmlinux || opts.module)) { - fprintf(stderr, "--lto requires: --vmlinux or --module\n"); - return 1; - } - - if (opts.ibt && !opts.lto) { - fprintf(stderr, "--ibt requires: --lto\n"); - return 1; - } - arch_initial_func_cfi_state(&initial_func_cfi); init_cfi_state(&init_cfi); init_cfi_state(&func_cfi); @@ -3920,15 +3911,6 @@ int check(struct objtool_file *file) if (list_empty(&file->insn_list)) goto out; - if (opts.vmlinux && !opts.lto) { - ret = validate_vmlinux_functions(file); - if (ret < 0) - goto out; - - warnings += ret; - goto out; - } - if (opts.retpoline) { ret = validate_retpoline(file); if (ret < 0) @@ -3953,6 +3935,12 @@ int check(struct objtool_file *file) goto out; warnings += ret; } + + } else if (opts.noinstr) { + ret = validate_noinstr_sections(file); + if (ret < 0) + goto out; + warnings += ret; } if (opts.ibt) { diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 0f6fa372e10e..583a3ec987b5 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -377,6 +377,9 @@ static void elf_add_symbol(struct elf *elf, struct symbol *sym) sym->type = GELF_ST_TYPE(sym->sym.st_info); sym->bind = GELF_ST_BIND(sym->sym.st_info); + if (sym->type == STT_FILE) + elf->num_files++; + sym->offset = sym->sym.st_value; sym->len = sym->sym.st_size; diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h index f3a1a754b5c4..280ea18b7f2b 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -28,12 +28,11 @@ struct opts { bool backtrace; bool backup; bool dryrun; - bool lto; + bool link; bool module; bool no_unreachable; bool sec_address; bool stats; - bool vmlinux; }; extern struct opts opts; diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h index 9b36802ed86f..de0cb2f313ba 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -86,7 +86,7 @@ struct elf { int fd; bool changed; char *name; - unsigned int text_size; + unsigned int text_size, num_files; struct list_head sections; int symbol_bits; @@ -131,6 +131,16 @@ static inline u32 reloc_hash(struct reloc *reloc) return sec_offset_hash(reloc->sec, reloc->offset); } +/* + * Try to see if it's a whole archive (vmlinux.o or module). + * + * Note this will miss the case where a module only has one source file. + */ +static inline bool has_multiple_files(struct elf *elf) +{ + return elf->num_files > 1; +} + struct elf *elf_open_read(const char *name, int flags); struct section *elf_create_section(struct elf *elf, const char *name, unsigned int sh_flags, size_t entsize, int nr); -- cgit v1.2.3 From 5b5bfecaa333fb6a0cce1bfc4852a622dacfed1d Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Tue, 19 Apr 2022 12:16:36 +0000 Subject: scripts/get_abi: Fix wrong script file name in the help message The help message of 'get_abi.pl' is mistakenly saying it's 'abi_book.pl'. This commit fixes the wrong name in the help message. Fixes: bbc249f2b859 ("scripts: add an script to parse the ABI files") Signed-off-by: SeongJae Park Link: https://lore.kernel.org/r/20220419121636.290407-1-sj@kernel.org Signed-off-by: Greg Kroah-Hartman --- scripts/get_abi.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 1389db76cff3..0ffd5531242a 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -981,11 +981,11 @@ __END__ =head1 NAME -abi_book.pl - parse the Linux ABI files and produce a ReST book. +get_abi.pl - parse the Linux ABI files and produce a ReST book. =head1 SYNOPSIS -B [--debug ] [--enable-lineno] [--man] [--help] +B [--debug ] [--enable-lineno] [--man] [--help] [--(no-)rst-source] [--dir=] [--show-hints] [--search-string ] [] -- cgit v1.2.3 From 73f1d07e5f8a1dec989a5ec964f5f2ce5b6f8825 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 26 Apr 2022 00:32:12 -0500 Subject: checkpatch: add new alloc functions to alloc with multiplies check kvmalloc() and kvzalloc() functions have now 2-factor multiplication argument forms kvmalloc_array() and kvcalloc(), correspondingly. Add alloc-with-multiplies checks for these new functions. Link: https://github.com/KSPP/linux/issues/187 Signed-off-by: Gustavo A. R. Silva --- scripts/checkpatch.pl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 577e02998701..503e8abbb2c1 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -7033,14 +7033,16 @@ sub process { "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); } -# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc +# check for (kv|k)[mz]alloc with multiplies that could be kmalloc_array/kvmalloc_array/kvcalloc/kcalloc if ($perl_version_ok && defined $stat && - $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { + $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { my $oldfunc = $3; my $a1 = $4; my $a2 = $10; my $newfunc = "kmalloc_array"; + $newfunc = "kvmalloc_array" if ($oldfunc eq "kvmalloc"); + $newfunc = "kvcalloc" if ($oldfunc eq "kvzalloc"); $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); my $r1 = $a1; my $r2 = $a2; @@ -7057,7 +7059,7 @@ sub process { "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && $cnt == 1 && $fix) { - $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e; + $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e; } } } -- cgit v1.2.3 From c268c0a8a33047cd957fecc1349d09a68eb6ad9e Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Tue, 5 Apr 2022 19:27:54 +0530 Subject: bus: mhi: ep: Add uevent support for module autoloading Add uevent support to MHI endpoint bus so that the client drivers can be autoloaded by udev when the MHI endpoint devices gets created. The client drivers are expected to provide MODULE_DEVICE_TABLE with the MHI id_table struct so that the alias can be exported. The MHI endpoint reused the mhi_device_id structure of the MHI bus. Reviewed-by: Alex Elder Signed-off-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20220405135754.6622-19-manivannan.sadhasivam@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/bus/mhi/ep/main.c | 9 +++++++++ include/linux/mod_devicetable.h | 2 ++ scripts/mod/file2alias.c | 10 ++++++++++ 3 files changed, 21 insertions(+) (limited to 'scripts') diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index bae5f40ec15e..40109a79017a 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -1536,6 +1536,14 @@ void mhi_ep_driver_unregister(struct mhi_ep_driver *mhi_drv) } EXPORT_SYMBOL_GPL(mhi_ep_driver_unregister); +static int mhi_ep_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); + + return add_uevent_var(env, "MODALIAS=" MHI_EP_DEVICE_MODALIAS_FMT, + mhi_dev->name); +} + static int mhi_ep_match(struct device *dev, struct device_driver *drv) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); @@ -1562,6 +1570,7 @@ struct bus_type mhi_ep_bus_type = { .name = "mhi_ep", .dev_name = "mhi_ep", .match = mhi_ep_match, + .uevent = mhi_ep_uevent, }; static int __init mhi_ep_init(void) diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 5da5d990ff58..549590e9c644 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -835,6 +835,8 @@ struct wmi_device_id { #define MHI_DEVICE_MODALIAS_FMT "mhi:%s" #define MHI_NAME_SIZE 32 +#define MHI_EP_DEVICE_MODALIAS_FMT "mhi_ep:%s" + /** * struct mhi_device_id - MHI device identification * @chan: MHI channel name diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 5258247d78ac..d9d6a31446ea 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1391,6 +1391,15 @@ static int do_mhi_entry(const char *filename, void *symval, char *alias) return 1; } +/* Looks like: mhi_ep:S */ +static int do_mhi_ep_entry(const char *filename, void *symval, char *alias) +{ + DEF_FIELD_ADDR(symval, mhi_device_id, chan); + sprintf(alias, MHI_EP_DEVICE_MODALIAS_FMT, *chan); + + return 1; +} + /* Looks like: ishtp:{guid} */ static int do_ishtp_entry(const char *filename, void *symval, char *alias) { @@ -1519,6 +1528,7 @@ static const struct devtable devtable[] = { {"tee", SIZE_tee_client_device_id, do_tee_entry}, {"wmi", SIZE_wmi_device_id, do_wmi_entry}, {"mhi", SIZE_mhi_device_id, do_mhi_entry}, + {"mhi_ep", SIZE_mhi_device_id, do_mhi_ep_entry}, {"auxiliary", SIZE_auxiliary_device_id, do_auxiliary_entry}, {"ssam", SIZE_ssam_device_id, do_ssam_entry}, {"dfl", SIZE_dfl_device_id, do_dfl_entry}, -- cgit v1.2.3 From 6ccf9cb557bd32073b0d68baed97f1bd8a40ff1d Mon Sep 17 00:00:00 2001 From: Kalesh Singh Date: Wed, 20 Apr 2022 14:42:57 -0700 Subject: KVM: arm64: Symbolize the nVHE HYP addresses Reintroduce the __kvm_nvhe_ symbols in kallsyms, ignoring the local symbols in this namespace. The local symbols are not informative and can cause aliasing issues when symbolizing the addresses. With the necessary symbols now in kallsyms we can symbolize nVHE addresses using the %p print format specifier: [ 98.916444][ T426] kvm [426]: nVHE hyp panic at: [] __kvm_nvhe_overflow_stack+0x8/0x34! Signed-off-by: Kalesh Singh Tested-by: Fuad Tabba Reviewed-by: Fuad Tabba Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20220420214317.3303360-7-kaleshsingh@google.com --- arch/arm64/kvm/handle_exit.c | 13 +++++-------- scripts/kallsyms.c | 3 ++- 2 files changed, 7 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index 97fe14aab1a3..a377b871bf58 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -295,13 +295,8 @@ void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr, u64 elr_in_kimg = __phys_to_kimg(elr_phys); u64 hyp_offset = elr_in_kimg - kaslr_offset() - elr_virt; u64 mode = spsr & PSR_MODE_MASK; + u64 panic_addr = elr_virt + hyp_offset; - /* - * The nVHE hyp symbols are not included by kallsyms to avoid issues - * with aliasing. That means that the symbols cannot be printed with the - * "%pS" format specifier, so fall back to the vmlinux address if - * there's no better option. - */ if (mode != PSR_MODE_EL2t && mode != PSR_MODE_EL2h) { kvm_err("Invalid host exception to nVHE hyp!\n"); } else if (ESR_ELx_EC(esr) == ESR_ELx_EC_BRK64 && @@ -321,9 +316,11 @@ void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr, if (file) kvm_err("nVHE hyp BUG at: %s:%u!\n", file, line); else - kvm_err("nVHE hyp BUG at: %016llx!\n", elr_virt + hyp_offset); + kvm_err("nVHE hyp BUG at: [<%016llx>] %pB!\n", panic_addr, + (void *)panic_addr); } else { - kvm_err("nVHE hyp panic at: %016llx!\n", elr_virt + hyp_offset); + kvm_err("nVHE hyp panic at: [<%016llx>] %pB!\n", panic_addr, + (void *)panic_addr); } /* diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 8caabddf817c..e6906f79833d 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -111,7 +111,8 @@ static bool is_ignored_symbol(const char *name, char type) ".L", /* local labels, .LBB,.Ltmpxxx,.L__unnamed_xx,.LASANPC, etc. */ "__crc_", /* modversions */ "__efistub_", /* arm64 EFI stub namespace */ - "__kvm_nvhe_", /* arm64 non-VHE KVM 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_", -- cgit v1.2.3 From 3af8acf6aff2a98731522b52927429760f0b8006 Mon Sep 17 00:00:00 2001 From: Schspa Shi Date: Fri, 29 Apr 2022 14:37:57 -0700 Subject: scripts/decode_stacktrace.sh: support old bash version Old bash version don't support associative array variables. Avoid to use associative array variables to avoid error. Without this, old bash version will report error as fellowing [ 15.954042] Kernel panic - not syncing: sysrq triggered crash [ 15.955252] CPU: 1 PID: 167 Comm: sh Not tainted 5.18.0-rc1-00208-gb7d075db2fd5 #4 [ 15.956472] Hardware name: Hobot J5 Virtual development board (DT) [ 15.957856] Call trace: ./scripts/decode_stacktrace.sh: line 128: ,dump_backtrace: syntax error: operand expected (error token is ",dump_backtrace") Link: https://lkml.kernel.org/r/20220409180331.24047-1-schspa@gmail.com Signed-off-by: Schspa Shi Cc: Stephen Boyd Signed-off-by: Andrew Morton --- scripts/decode_stacktrace.sh | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh index 5fbad61fe490..7075e26ab2c4 100755 --- a/scripts/decode_stacktrace.sh +++ b/scripts/decode_stacktrace.sh @@ -45,8 +45,13 @@ else fi fi -declare -A cache -declare -A modcache +declare aarray_support=true +declare -A cache 2>/dev/null +if [[ $? != 0 ]]; then + aarray_support=false +else + declare -A modcache +fi find_module() { if [[ -n $debuginfod ]] ; then @@ -97,7 +102,7 @@ parse_symbol() { if [[ $module == "" ]] ; then local objfile=$vmlinux - elif [[ "${modcache[$module]+isset}" == "isset" ]]; then + elif [[ $aarray_support == true && "${modcache[$module]+isset}" == "isset" ]]; then local objfile=${modcache[$module]} else local objfile=$(find_module) @@ -105,7 +110,9 @@ parse_symbol() { echo "WARNING! Modules path isn't set, but is needed to parse this symbol" >&2 return fi - modcache[$module]=$objfile + if [[ $aarray_support == true ]]; then + modcache[$module]=$objfile + fi fi # Remove the englobing parenthesis @@ -125,7 +132,7 @@ parse_symbol() { # Use 'nm vmlinux' to figure out the base address of said symbol. # It's actually faster to call it every time than to load it # all into bash. - if [[ "${cache[$module,$name]+isset}" == "isset" ]]; then + if [[ $aarray_support == true && "${cache[$module,$name]+isset}" == "isset" ]]; then local base_addr=${cache[$module,$name]} else local base_addr=$(nm "$objfile" 2>/dev/null | awk '$3 == "'$name'" && ($2 == "t" || $2 == "T") {print $1; exit}') @@ -133,7 +140,9 @@ parse_symbol() { # address not found return fi - cache[$module,$name]="$base_addr" + if [[ $aarray_support == true ]]; then + cache[$module,$name]="$base_addr" + fi fi # Let's start doing the math to get the exact address into the # symbol. First, strip out the symbol total length. @@ -149,11 +158,13 @@ parse_symbol() { # Pass it to addr2line to get filename and line number # Could get more than one result - if [[ "${cache[$module,$address]+isset}" == "isset" ]]; then + if [[ $aarray_support == true && "${cache[$module,$address]+isset}" == "isset" ]]; then local code=${cache[$module,$address]} else local code=$(${CROSS_COMPILE}addr2line -i -e "$objfile" "$address" 2>/dev/null) - cache[$module,$address]=$code + if [[ $aarray_support == true ]]; then + cache[$module,$address]=$code + fi fi # addr2line doesn't return a proper error code if it fails, so -- cgit v1.2.3 From dec81a532027a77bd52f9bd8d8b3230843533d3f Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Fri, 29 Apr 2022 14:37:57 -0700 Subject: scripts/bloat-o-meter: filter out vermagic as it is not relevant Seeing it as a false positive increase at the top is just noise: linux-head$./scripts/bloat-o-meter ../pre/vmlinux ../post/vmlinux add/remove: 0/571 grow/shrink: 1/9 up/down: 20/-64662 (-64642) Function old new delta vermagic 49 69 +20 Since it really doesn't "grow", it makes sense to filter it out. Link: https://lkml.kernel.org/r/20220428035824.7934-1-paul.gortmaker@windriver.com Signed-off-by: Paul Gortmaker Signed-off-by: Andrew Morton --- scripts/bloat-o-meter | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter index dcd8d8750b8b..4dd6a804ce41 100755 --- a/scripts/bloat-o-meter +++ b/scripts/bloat-o-meter @@ -36,6 +36,7 @@ def getsizes(file, format): if name.startswith("__se_compat_sys"): continue if name.startswith("__addressable_"): continue if name == "linux_banner": continue + if name == "vermagic": continue # statics and some other optimizations adds random .NUMBER name = re_NUMBER.sub('', name) sym[name] = sym.get(name, 0) + int(size, 16) -- cgit v1.2.3 From 11fb48961e5250768767612da4a303fa2f5ea504 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 29 Apr 2022 14:38:00 -0700 Subject: get_maintainer: Honor mailmap for in file emails Add support to also use the mailmap for 'in file' email addresses. Link: https://lkml.kernel.org/r/20220323193645.317514-1-robh@kernel.org Signed-off-by: Rob Herring Reported-by: Marc Zyngier Acked-by: Joe Perches Signed-off-by: Andrew Morton --- scripts/get_maintainer.pl | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 6bd5221d37b8..ab123b498fd9 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -983,6 +983,7 @@ sub get_maintainers { } foreach my $email (@file_emails) { + $email = mailmap_email($email); my ($name, $address) = parse_email($email); my $tmp_email = format_email($name, $address, $email_usename); -- cgit v1.2.3 From ded34574d4d351ab0ca095a45496b393cef611c2 Mon Sep 17 00:00:00 2001 From: Christian Göttsche Date: Mon, 2 May 2022 16:43:38 +0200 Subject: selinux: declare data arrays const MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The arrays for the policy capability names, the initial sid identifiers and the class and permission names are not changed at runtime. Declare them const to avoid accidental modification. Do not override the classmap and the initial sid list in the build time script genheaders. Check flose(3) is successful in genheaders.c, otherwise the written data might be corrupted or incomplete. Signed-off-by: Christian Göttsche [PM: manual merge due to fuzz, minor style tweaks] Signed-off-by: Paul Moore --- scripts/selinux/genheaders/genheaders.c | 75 ++++++++++++++---------- scripts/selinux/mdp/mdp.c | 4 +- security/selinux/avc.c | 2 +- security/selinux/include/avc_ss.h | 2 +- security/selinux/include/classmap.h | 2 +- security/selinux/include/initial_sid_to_string.h | 2 +- security/selinux/include/policycap.h | 2 +- security/selinux/include/policycap_names.h | 2 +- security/selinux/ss/avtab.c | 2 +- security/selinux/ss/policydb.c | 32 +++++----- security/selinux/ss/services.c | 4 +- 11 files changed, 71 insertions(+), 58 deletions(-) (limited to 'scripts') diff --git a/scripts/selinux/genheaders/genheaders.c b/scripts/selinux/genheaders/genheaders.c index f355b3e0e968..15520806889e 100644 --- a/scripts/selinux/genheaders/genheaders.c +++ b/scripts/selinux/genheaders/genheaders.c @@ -59,35 +59,27 @@ int main(int argc, char *argv[]) exit(2); } - for (i = 0; secclass_map[i].name; i++) { - struct security_class_mapping *map = &secclass_map[i]; - map->name = stoupperx(map->name); - for (j = 0; map->perms[j]; j++) - map->perms[j] = stoupperx(map->perms[j]); - } - - isids_len = sizeof(initial_sid_to_string) / sizeof (char *); - for (i = 1; i < isids_len; i++) { - const char *s = initial_sid_to_string[i]; - - if (s) - initial_sid_to_string[i] = stoupperx(s); - } - fprintf(fout, "/* This file is automatically generated. Do not edit. */\n"); fprintf(fout, "#ifndef _SELINUX_FLASK_H_\n#define _SELINUX_FLASK_H_\n\n"); for (i = 0; secclass_map[i].name; i++) { - struct security_class_mapping *map = &secclass_map[i]; - fprintf(fout, "#define SECCLASS_%-39s %2d\n", map->name, i+1); + char *name = stoupperx(secclass_map[i].name); + + fprintf(fout, "#define SECCLASS_%-39s %2d\n", name, i+1); + free(name); } fprintf(fout, "\n"); + isids_len = sizeof(initial_sid_to_string) / sizeof(char *); for (i = 1; i < isids_len; i++) { const char *s = initial_sid_to_string[i]; - if (s) - fprintf(fout, "#define SECINITSID_%-39s %2d\n", s, i); + if (s) { + char *sidname = stoupperx(s); + + fprintf(fout, "#define SECINITSID_%-39s %2d\n", sidname, i); + free(sidname); + } } fprintf(fout, "\n#define SECINITSID_NUM %d\n", i-1); fprintf(fout, "\nstatic inline bool security_is_socket_class(u16 kern_tclass)\n"); @@ -96,10 +88,14 @@ int main(int argc, char *argv[]) fprintf(fout, "\tswitch (kern_tclass) {\n"); for (i = 0; secclass_map[i].name; i++) { static char s[] = "SOCKET"; - struct security_class_mapping *map = &secclass_map[i]; - int len = strlen(map->name), l = sizeof(s) - 1; - if (len >= l && memcmp(map->name + len - l, s, l) == 0) - fprintf(fout, "\tcase SECCLASS_%s:\n", map->name); + int len, l; + char *name = stoupperx(secclass_map[i].name); + + len = strlen(name); + l = sizeof(s) - 1; + if (len >= l && memcmp(name + len - l, s, l) == 0) + fprintf(fout, "\tcase SECCLASS_%s:\n", name); + free(name); } fprintf(fout, "\t\tsock = true;\n"); fprintf(fout, "\t\tbreak;\n"); @@ -110,33 +106,52 @@ int main(int argc, char *argv[]) fprintf(fout, "}\n"); fprintf(fout, "\n#endif\n"); - fclose(fout); + + if (fclose(fout) != 0) { + fprintf(stderr, "Could not successfully close %s: %s\n", + argv[1], strerror(errno)); + exit(4); + } fout = fopen(argv[2], "w"); if (!fout) { fprintf(stderr, "Could not open %s for writing: %s\n", argv[2], strerror(errno)); - exit(4); + exit(5); } fprintf(fout, "/* This file is automatically generated. Do not edit. */\n"); fprintf(fout, "#ifndef _SELINUX_AV_PERMISSIONS_H_\n#define _SELINUX_AV_PERMISSIONS_H_\n\n"); for (i = 0; secclass_map[i].name; i++) { - struct security_class_mapping *map = &secclass_map[i]; - int len = strlen(map->name); + const struct security_class_mapping *map = &secclass_map[i]; + int len; + char *name = stoupperx(map->name); + + len = strlen(name); for (j = 0; map->perms[j]; j++) { + char *permname; + if (j >= 32) { fprintf(stderr, "Too many permissions to fit into an access vector at (%s, %s).\n", map->name, map->perms[j]); exit(5); } - fprintf(fout, "#define %s__%-*s 0x%08xU\n", map->name, - 39-len, map->perms[j], 1U<perms[j]); + fprintf(fout, "#define %s__%-*s 0x%08xU\n", name, + 39-len, permname, 1U<name); fprintf(fout, "{\n"); for (j = 0; map->perms[j]; j++) @@ -103,7 +103,7 @@ int main(int argc, char *argv[]) #define SYSTEMLOW "s0" #define SYSTEMHIGH "s1:c0.c1" for (i = 0; secclass_map[i].name; i++) { - struct security_class_mapping *map = &secclass_map[i]; + const struct security_class_mapping *map = &secclass_map[i]; fprintf(fout, "mlsconstrain %s {\n", map->name); for (j = 0; map->perms[j]; j++) diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 874c1c6fe10b..9a43af0ebd7d 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -668,7 +668,7 @@ static void avc_audit_pre_callback(struct audit_buffer *ab, void *a) struct common_audit_data *ad = a; struct selinux_audit_data *sad = ad->selinux_audit_data; u32 av = sad->audited; - const char **perms; + const char *const *perms; int i, perm; audit_log_format(ab, "avc: %s ", sad->denied ? "denied" : "granted"); diff --git a/security/selinux/include/avc_ss.h b/security/selinux/include/avc_ss.h index 66a87559b788..42912c917fd4 100644 --- a/security/selinux/include/avc_ss.h +++ b/security/selinux/include/avc_ss.h @@ -18,7 +18,7 @@ struct security_class_mapping { const char *perms[sizeof(u32) * 8 + 1]; }; -extern struct security_class_mapping secclass_map[]; +extern const struct security_class_mapping secclass_map[]; #endif /* _SELINUX_AVC_SS_H_ */ diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index 35aac62a662e..ff757ae5f253 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -38,7 +38,7 @@ * Note: The name for any socket class should be suffixed by "socket", * and doesn't contain more than one substr of "socket". */ -struct security_class_mapping secclass_map[] = { +const struct security_class_mapping secclass_map[] = { { "security", { "compute_av", "compute_create", "compute_member", "check_context", "load_policy", "compute_relabel", diff --git a/security/selinux/include/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h index 9683f0ddecbc..60820517aa43 100644 --- a/security/selinux/include/initial_sid_to_string.h +++ b/security/selinux/include/initial_sid_to_string.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ -static const char *initial_sid_to_string[] = { +static const char *const initial_sid_to_string[] = { NULL, "kernel", "security", diff --git a/security/selinux/include/policycap.h b/security/selinux/include/policycap.h index 2680aa21205c..f35d3458e71d 100644 --- a/security/selinux/include/policycap.h +++ b/security/selinux/include/policycap.h @@ -16,6 +16,6 @@ enum { }; #define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1) -extern const char *selinux_policycap_names[__POLICYDB_CAP_MAX]; +extern const char *const selinux_policycap_names[__POLICYDB_CAP_MAX]; #endif /* _SELINUX_POLICYCAP_H_ */ diff --git a/security/selinux/include/policycap_names.h b/security/selinux/include/policycap_names.h index 100da7d043db..2a87fc3702b8 100644 --- a/security/selinux/include/policycap_names.h +++ b/security/selinux/include/policycap_names.h @@ -5,7 +5,7 @@ #include "policycap.h" /* Policy capability names */ -const char *selinux_policycap_names[__POLICYDB_CAP_MAX] = { +const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = { "network_peer_controls", "open_perms", "extended_socket_class", diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index ea9fc69568e3..8480ec6c6e75 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c @@ -385,7 +385,7 @@ void avtab_hash_eval(struct avtab *h, char *tag) chain2_len_sum); } -static uint16_t spec_order[] = { +static const uint16_t spec_order[] = { AVTAB_ALLOWED, AVTAB_AUDITDENY, AVTAB_AUDITALLOW, diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 3d50dfb0211b..adcfb63b3550 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -61,7 +61,7 @@ struct policydb_compat_info { }; /* These need to be updated if SYM_NUM or OCON_NUM changes */ -static struct policydb_compat_info policydb_compat[] = { +static const struct policydb_compat_info policydb_compat[] = { { .version = POLICYDB_VERSION_BASE, .sym_num = SYM_NUM - 3, @@ -159,18 +159,16 @@ static struct policydb_compat_info policydb_compat[] = { }, }; -static struct policydb_compat_info *policydb_lookup_compat(int version) +static const struct policydb_compat_info *policydb_lookup_compat(int version) { int i; - struct policydb_compat_info *info = NULL; for (i = 0; i < ARRAY_SIZE(policydb_compat); i++) { - if (policydb_compat[i].version == version) { - info = &policydb_compat[i]; - break; - } + if (policydb_compat[i].version == version) + return &policydb_compat[i]; } - return info; + + return NULL; } /* @@ -314,7 +312,7 @@ static int cat_destroy(void *key, void *datum, void *p) return 0; } -static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) = { +static int (*const destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) = { common_destroy, cls_destroy, role_destroy, @@ -669,7 +667,7 @@ static int cat_index(void *key, void *datum, void *datap) return 0; } -static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) = { +static int (*const index_f[SYM_NUM]) (void *key, void *datum, void *datap) = { common_index, class_index, role_index, @@ -1637,7 +1635,8 @@ bad: return rc; } -static int (*read_f[SYM_NUM]) (struct policydb *p, struct symtab *s, void *fp) = { +static int (*const read_f[SYM_NUM]) (struct policydb *p, + struct symtab *s, void *fp) = { common_read, class_read, role_read, @@ -2208,7 +2207,7 @@ out: return rc; } -static int ocontext_read(struct policydb *p, struct policydb_compat_info *info, +static int ocontext_read(struct policydb *p, const struct policydb_compat_info *info, void *fp) { int i, j, rc; @@ -2404,7 +2403,7 @@ int policydb_read(struct policydb *p, void *fp) u32 len, nprim, nel, perm; char *policydb_str; - struct policydb_compat_info *info; + const struct policydb_compat_info *info; policydb_init(p); @@ -3238,8 +3237,7 @@ static int user_write(void *vkey, void *datum, void *ptr) return 0; } -static int (*write_f[SYM_NUM]) (void *key, void *datum, - void *datap) = { +static int (*const write_f[SYM_NUM]) (void *key, void *datum, void *datap) = { common_write, class_write, role_write, @@ -3250,7 +3248,7 @@ static int (*write_f[SYM_NUM]) (void *key, void *datum, cat_write, }; -static int ocontext_write(struct policydb *p, struct policydb_compat_info *info, +static int ocontext_write(struct policydb *p, const struct policydb_compat_info *info, void *fp) { unsigned int i, j, rc; @@ -3607,7 +3605,7 @@ int policydb_write(struct policydb *p, void *fp) __le32 buf[4]; u32 config; size_t len; - struct policydb_compat_info *info; + const struct policydb_compat_info *info; /* * refuse to write policy older than compressed avtab diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index e62e04b1ec6c..69b2734311a6 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -99,7 +99,7 @@ static void context_struct_compute_av(struct policydb *policydb, struct extended_perms *xperms); static int selinux_set_mapping(struct policydb *pol, - struct security_class_mapping *map, + const struct security_class_mapping *map, struct selinux_map *out_map) { u16 i, j; @@ -121,7 +121,7 @@ static int selinux_set_mapping(struct policydb *pol, /* Store the raw class and permission values */ j = 0; while (map[j].name) { - struct security_class_mapping *p_in = map + (j++); + const struct security_class_mapping *p_in = map + (j++); struct selinux_mapping *p_out = out_map->mapping + j; /* An empty class string skips ahead */ -- cgit v1.2.3 From 7ce3e410e0188ce7ca65b49c90cff2863d6e232e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 5 Apr 2022 20:33:51 +0900 Subject: modpost: remove useless export_from_sec() With commit 1743694eb235 ("modpost: stop symbol preloading for modversion CRC") applied, now export_from_sec() is useless. handle_symbol() is called for every symbol in the ELF. When 'symname' does not start with "__ksymtab", export_from_sec() is called, and the returned value is stored in 'export'. It is used in the last part of handle_symbol(): if (strstarts(symname, "__ksymtab_")) { name = symname + strlen("__ksymtab_"); sym_add_exported(name, mod, export); } 'export' is used only when 'symname' starts with "__ksymtab_". So, the value returned by export_from_sec() is never used. Remove useless export_from_sec(). This makes further cleanups possible. I put the temporary code: export = export_unknown; Otherwise, I would get the compiler warning: warning: 'export' may be used uninitialized in this function [-Wmaybe-uninitialized] This is apparently false positive because if (strstarts(symname, "__ksymtab_") ... is a stronger condition than: if (strstarts(symname, "__ksymtab") Anyway, this part will be cleaned up by the next commit. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 17 ++--------------- scripts/mod/modpost.h | 2 -- 2 files changed, 2 insertions(+), 17 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index ed9d056d2108..eebb32689816 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -369,16 +369,6 @@ static enum export export_from_secname(struct elf_info *elf, unsigned int sec) return export_unknown; } -static enum export export_from_sec(struct elf_info *elf, unsigned int sec) -{ - if (sec == elf->export_sec) - return export_plain; - else if (sec == elf->export_gpl_sec) - return export_gpl; - else - return export_unknown; -} - static const char *namespace_from_kstrtabns(const struct elf_info *info, const Elf_Sym *sym) { @@ -576,10 +566,7 @@ static int parse_elf(struct elf_info *info, const char *filename) fatal("%s has NOBITS .modinfo\n", filename); info->modinfo = (void *)hdr + sechdrs[i].sh_offset; info->modinfo_len = sechdrs[i].sh_size; - } else if (strcmp(secname, "__ksymtab") == 0) - info->export_sec = i; - else if (strcmp(secname, "__ksymtab_gpl") == 0) - info->export_gpl_sec = i; + } if (sechdrs[i].sh_type == SHT_SYMTAB) { unsigned int sh_link_idx; @@ -703,7 +690,7 @@ static void handle_symbol(struct module *mod, struct elf_info *info, if (strstarts(symname, "__ksymtab")) export = export_from_secname(info, get_secindex(info, sym)); else - export = export_from_sec(info, get_secindex(info, sym)); + export = export_unknown; switch (sym->st_shndx) { case SHN_COMMON: diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 0c47ff95c0e2..0a940fd2e5c7 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -138,8 +138,6 @@ struct elf_info { Elf_Shdr *sechdrs; Elf_Sym *symtab_start; Elf_Sym *symtab_stop; - Elf_Section export_sec; - Elf_Section export_gpl_sec; char *strtab; char *modinfo; unsigned int modinfo_len; -- cgit v1.2.3 From 535b3e05f435698f8f661d9e6449beb5791fff59 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 5 Apr 2022 20:33:52 +0900 Subject: modpost: move export_from_secname() call to more relevant place The assigned 'export' is only used when if (strstarts(symname, "__ksymtab_")) is met. The else-part of the assignment is the dead code. Move the export_from_secname() call to where it is used. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index eebb32689816..f9e54247ae1d 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -684,14 +684,8 @@ static void handle_modversion(const struct module *mod, static void handle_symbol(struct module *mod, struct elf_info *info, const Elf_Sym *sym, const char *symname) { - enum export export; const char *name; - if (strstarts(symname, "__ksymtab")) - export = export_from_secname(info, get_secindex(info, sym)); - else - export = export_unknown; - switch (sym->st_shndx) { case SHN_COMMON: if (strstarts(symname, "__gnu_lto_")) { @@ -726,7 +720,11 @@ static void handle_symbol(struct module *mod, struct elf_info *info, default: /* All exported symbols */ if (strstarts(symname, "__ksymtab_")) { + enum export export; + name = symname + strlen("__ksymtab_"); + export = export_from_secname(info, + get_secindex(info, sym)); sym_add_exported(name, mod, export); } if (strcmp(symname, "init_module") == 0) -- cgit v1.2.3 From b5f1a52a59eb810f68c96d1cea7cf1256c39956c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 5 Apr 2022 20:33:53 +0900 Subject: modpost: remove redundant initializes for static variables These are initialized with zeros without explicit initializers. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index f9e54247ae1d..2a202764ff48 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -23,15 +23,15 @@ #include "../../include/linux/license.h" /* Are we using CONFIG_MODVERSIONS? */ -static int modversions = 0; +static int modversions; /* Is CONFIG_MODULE_SRCVERSION_ALL set? */ -static int all_versions = 0; +static int all_versions; /* If we are modposting external module set to 1 */ -static int external_module = 0; +static int external_module; /* Only warn about unresolved symbols */ -static int warn_unresolved = 0; +static int warn_unresolved; /* How a symbol is exported */ -static int sec_mismatch_count = 0; +static int sec_mismatch_count; static int sec_mismatch_warn_only = true; /* ignore missing files */ static int ignore_missing_files; -- cgit v1.2.3 From 79f646e8654b6b8e4f7dda456ec3eabd51052041 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 5 Apr 2022 20:33:54 +0900 Subject: modpost: remove annoying namespace_from_kstrtabns() There are two call sites for sym_update_namespace(). When the symbol has no namespace, s->namespace is set to NULL, but the conversion from "" to NULL is done in two different places. [1] read_symbols() This gets the namespace from __kstrtabns_. If the symbol has no namespace, sym_get_data(info, sym) returns the empty string "". namespace_from_kstrtabns() converts it to NULL before it is passed to sym_update_namespace(). [2] read_dump() This gets the namespace from the dump file, *.symvers. If the symbol has no namespace, the 'namespace' is the empty string "", which is directly passed into sym_update_namespace(). The conversion from "" to NULL is done in sym_update_namespace(). namespace_from_kstrtabns() exists only for creating this inconsistency. Remove namespace_from_kstrtabns() so that sym_update_namespace() is consistently passed with "" instead of NULL. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 2a202764ff48..522d5249d196 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -369,13 +369,6 @@ static enum export export_from_secname(struct elf_info *elf, unsigned int sec) return export_unknown; } -static const char *namespace_from_kstrtabns(const struct elf_info *info, - const Elf_Sym *sym) -{ - const char *value = sym_get_data(info, sym); - return value[0] ? value : NULL; -} - static void sym_update_namespace(const char *symname, const char *namespace) { struct symbol *s = find_symbol(symname); @@ -391,8 +384,7 @@ static void sym_update_namespace(const char *symname, const char *namespace) } free(s->namespace); - s->namespace = - namespace && namespace[0] ? NOFAIL(strdup(namespace)) : NULL; + s->namespace = namespace[0] ? NOFAIL(strdup(namespace)) : NULL; } /** @@ -2049,9 +2041,7 @@ static void read_symbols(const char *modname) /* Apply symbol namespaces from __kstrtabns_ entries. */ if (strstarts(symname, "__kstrtabns_")) sym_update_namespace(symname + strlen("__kstrtabns_"), - namespace_from_kstrtabns(&info, - sym)); - + sym_get_data(&info, sym)); if (strstarts(symname, "__crc_")) handle_modversion(mod, &info, sym, symname + strlen("__crc_")); -- cgit v1.2.3 From 8017ce50641c303b9b5d96f3c10229ecfd770a70 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 5 Apr 2022 20:33:57 +0900 Subject: kbuild: refactor cmd_modversions_c cmd_modversions_c implements two parts; run genksyms to calculate CRCs of exported symbols, run $(LD) to update the object with the CRCs. The latter is not executed for CONFIG_LTO_CLANG=y since the object is not ELF but LLVM bit code at this point. The first part can be unified because we can always use $(NM) instead of "$(OBJDUMP) -h" to dump the symbols. Split the code into the two macros, cmd_gen_symversions_c and cmd_modversions. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/Makefile.build | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 3ef2373f0a57..e1992ddc35f6 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -168,29 +168,25 @@ ifdef CONFIG_MODVERSIONS # the actual value of the checksum generated by genksyms # o remove .tmp_.o to .o -ifdef CONFIG_LTO_CLANG # Generate .o.symversions files for each .o with exported symbols, and link these # to the kernel and/or modules at the end. -cmd_modversions_c = \ +gen_symversions = \ if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then \ - $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ + $(call cmd_gensymtypes_$(1),$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ > $@.symversions; \ else \ rm -f $@.symversions; \ - fi; -else -cmd_modversions_c = \ - if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \ - $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ - > $(@D)/.tmp_$(@F:.o=.ver); \ - \ + fi + +cmd_gen_symversions_c = $(call gen_symversions,c) + +cmd_modversions = \ + if [ -r $@.symversions ]; then \ $(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \ - -T $(@D)/.tmp_$(@F:.o=.ver); \ + -T $@.symversions; \ mv -f $(@D)/.tmp_$(@F) $@; \ - rm -f $(@D)/.tmp_$(@F:.o=.ver); \ fi endif -endif ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT # compiler will not generate __mcount_loc use recordmcount or recordmcount.pl @@ -271,7 +267,8 @@ define rule_cc_o_c $(call cmd,checksrc) $(call cmd,checkdoc) $(call cmd,gen_objtooldep) - $(call cmd,modversions_c) + $(call cmd,gen_symversions_c) + $(if $(CONFIG_LTO_CLANG),,$(call cmd,modversions)) $(call cmd,record_mcount) endef -- cgit v1.2.3 From 7cfa2fcbac167ca0ceadf25a4b600391fd01fb29 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 5 Apr 2022 20:33:58 +0900 Subject: kbuild: refactor cmd_modversions_S Split the code into two macros, cmd_gen_symversions_S for running genksyms, and cmd_modversions for running $(LD) to update the object with CRCs. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/Makefile.build | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index e1992ddc35f6..f15c245dc17e 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -276,7 +276,8 @@ define rule_as_o_S $(call cmd_and_fixdep,as_o_S) $(call cmd,gen_ksymdeps) $(call cmd,gen_objtooldep) - $(call cmd,modversions_S) + $(call cmd,gen_symversions_S) + $(call cmd,modversions) endef # Built-in and composite module parts @@ -363,16 +364,8 @@ ifdef CONFIG_ASM_MODVERSIONS # versioning matches the C process described above, with difference that # we parse asm-prototypes.h C header to get function definitions. -cmd_modversions_S = \ - if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \ - $(call cmd_gensymtypes_S,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ - > $(@D)/.tmp_$(@F:.o=.ver); \ - \ - $(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \ - -T $(@D)/.tmp_$(@F:.o=.ver); \ - mv -f $(@D)/.tmp_$(@F) $@; \ - rm -f $(@D)/.tmp_$(@F:.o=.ver); \ - fi +cmd_gen_symversions_S = $(call gen_symversions,S) + endif $(obj)/%.o: $(src)/%.S FORCE -- cgit v1.2.3 From 9eef99f7a335e4ffc6dfe65fc29c7d38dafae915 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 7 Apr 2022 00:30:17 +0900 Subject: kbuild: reuse suffix-search to refactor multi_depend The complicated part of multi_depend is the same as suffix-search. Reuse it. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/Makefile.lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 9f69ecdd7977..d56cda3c1e8a 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -238,7 +238,7 @@ endif define multi_depend $(foreach m, $(notdir $1), \ $(eval $(obj)/$m: \ - $(addprefix $(obj)/, $(foreach s, $3, $($(m:%$(strip $2)=%$(s))))))) + $(addprefix $(obj)/, $(call suffix-search, $m, $2, $3)))) endef # Copy a file -- cgit v1.2.3 From f97cf399915bc928f5f97ce93e15ce40da514e16 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 7 Apr 2022 00:30:18 +0900 Subject: kbuild: make multi_depend work with targets in subdirectory Precisely speaking, when you get the stem of the path, you should use $(patsubst $(obj)/%,%,...) instead of $(notdir ...). I do not see this usecase, but if you create a composite object in a subdirectory, the Makefile should look like this: obj-$(CONFIG_FOO) += dir/foo.o dir/foo-objs := dir/foo1.o dir/foo2.o The member objects should be assigned to dir/foo-objs instead of foo-objs. This syntax is more consistent with commit 54b8ae66ae1a ("kbuild: change *FLAGS_.o to take the path relative to $(obj)"). Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/Makefile.lib | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index d56cda3c1e8a..0453a1904646 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -236,9 +236,9 @@ endif # Usage: # $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add) define multi_depend -$(foreach m, $(notdir $1), \ - $(eval $(obj)/$m: \ - $(addprefix $(obj)/, $(call suffix-search, $m, $2, $3)))) +$(foreach m, $1, \ + $(eval $m: \ + $(addprefix $(obj)/, $(call suffix-search, $(patsubst $(obj)/%,%,$m), $2, $3)))) endef # Copy a file -- cgit v1.2.3 From b3591e061919c837c14680c1ceff8f009ed0afb4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 7 Apr 2022 00:30:19 +0900 Subject: kbuild: reuse real-search to simplify cmd_mod The first command in cmd_mod is similar to the real-search macro. Reuse it. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/Makefile.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index f15c245dc17e..857329844789 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -306,7 +306,7 @@ $(obj)/%.prelink.o: $(obj)/%.o FORCE endif cmd_mod = { \ - echo $(if $($*-objs)$($*-y)$($*-m), $(addprefix $(obj)/, $($*-objs) $($*-y) $($*-m)), $(@:.mod=.o)); \ + echo $(addprefix $(obj)/, $(call real-search, $*.o, .o, -objs -y -m)); \ $(undefined_syms) echo; \ } > $@ -- cgit v1.2.3 From 9413e7640564fe70b24ea1a9ff3fb92c5bb52fcb Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 7 Apr 2022 00:30:20 +0900 Subject: kbuild: split the second line of *.mod into *.usyms The *.mod files have two lines; the first line lists the member objects of the module, and the second line, if CONFIG_TRIM_UNUSED_KSYMS=y, lists the undefined symbols. Currently, we generate *.mod after constructing composite modules, otherwise, we cannot compute the second line. No prerequisite is required to print the first line. They are orthogonal. Splitting them into separate commands will ease further cleanups. This commit splits the list of undefined symbols out to *.usyms files. Previously, the list of undefined symbols ended up with a very long line, but now it has one symbol per line. Use sed like we did before commit 7d32358be8ac ("kbuild: avoid split lines in .mod files"). Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- .gitignore | 1 + Makefile | 2 +- scripts/Makefile.build | 17 +++++++++-------- scripts/adjust_autoksyms.sh | 2 +- scripts/gen_autoksyms.sh | 18 +++++++++++------- scripts/mod/sumversion.c | 11 ++--------- 6 files changed, 25 insertions(+), 26 deletions(-) (limited to 'scripts') diff --git a/.gitignore b/.gitignore index 7afd412dadd2..265959544978 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,7 @@ *.symversions *.tab.[ch] *.tar +*.usyms *.xz *.zst Module.symvers diff --git a/Makefile b/Makefile index d9336e783be3..82ee893909e9 100644 --- a/Makefile +++ b/Makefile @@ -1848,7 +1848,7 @@ clean: $(clean-dirs) -o -name '*.ko.*' \ -o -name '*.dtb' -o -name '*.dtbo' -o -name '*.dtb.S' -o -name '*.dt.yaml' \ -o -name '*.dwo' -o -name '*.lst' \ - -o -name '*.su' -o -name '*.mod' \ + -o -name '*.su' -o -name '*.mod' -o -name '*.usyms' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '*.lex.c' -o -name '*.tab.[ch]' \ -o -name '*.asn1.[ch]' \ diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 857329844789..6ae92d119dfa 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -85,7 +85,8 @@ ifdef need-builtin targets-for-builtin += $(obj)/built-in.a endif -targets-for-modules := $(patsubst %.o, %.mod, $(filter %.o, $(obj-m))) +targets-for-modules := $(foreach x, mod $(if $(CONFIG_TRIM_UNUSED_KSYMS), usyms), \ + $(patsubst %.o, %.$x, $(filter %.o, $(obj-m)))) ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) targets-for-modules += $(patsubst %.o, %.prelink.o, $(filter %.o, $(obj-m))) @@ -256,9 +257,6 @@ endif ifdef CONFIG_TRIM_UNUSED_KSYMS cmd_gen_ksymdeps = \ $(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd - -# List module undefined symbols -undefined_syms = $(NM) $< | $(AWK) '$$1 == "U" { printf("%s%s", x++ ? " " : "", $$2) }'; endif define rule_cc_o_c @@ -305,14 +303,17 @@ $(obj)/%.prelink.o: $(obj)/%.o FORCE $(call if_changed,cc_prelink_modules) endif -cmd_mod = { \ - echo $(addprefix $(obj)/, $(call real-search, $*.o, .o, -objs -y -m)); \ - $(undefined_syms) echo; \ - } > $@ +cmd_mod = echo $(addprefix $(obj)/, $(call real-search, $*.o, .o, -objs -y -m)) > $@ $(obj)/%.mod: $(obj)/%$(mod-prelink-ext).o FORCE $(call if_changed,mod) +# List module undefined symbols +cmd_undefined_syms = $(NM) $< | sed -n 's/^ *U //p' > $@ + +$(obj)/%.usyms: $(obj)/%$(mod-prelink-ext).o FORCE + $(call if_changed,undefined_syms) + quiet_cmd_cc_lst_c = MKLST $@ cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \ $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \ diff --git a/scripts/adjust_autoksyms.sh b/scripts/adjust_autoksyms.sh index 59fdb875e818..f1b5ac818411 100755 --- a/scripts/adjust_autoksyms.sh +++ b/scripts/adjust_autoksyms.sh @@ -35,7 +35,7 @@ case "$KBUILD_VERBOSE" in esac # Generate a new symbol list file -$CONFIG_SHELL $srctree/scripts/gen_autoksyms.sh "$new_ksyms_file" +$CONFIG_SHELL $srctree/scripts/gen_autoksyms.sh --modorder "$new_ksyms_file" # Extract changes between old and new list and touch corresponding # dependency files. diff --git a/scripts/gen_autoksyms.sh b/scripts/gen_autoksyms.sh index 120225c541c5..faacf7062122 100755 --- a/scripts/gen_autoksyms.sh +++ b/scripts/gen_autoksyms.sh @@ -2,13 +2,10 @@ # SPDX-License-Identifier: GPL-2.0-only # Create an autoksyms.h header file from the list of all module's needed symbols -# as recorded on the second line of *.mod files and the user-provided symbol -# whitelist. +# as recorded in *.usyms files and the user-provided symbol whitelist. set -e -output_file="$1" - # Use "make V=1" to debug this script. case "$KBUILD_VERBOSE" in *1*) @@ -16,6 +13,15 @@ case "$KBUILD_VERBOSE" in ;; esac +read_modorder= + +if [ "$1" = --modorder ]; then + shift + read_modorder=1 +fi + +output_file="$1" + needed_symbols= # Special case for modversions (see modpost.c) @@ -41,10 +47,8 @@ cat > "$output_file" << EOT EOT -[ -f modules.order ] && modlist=modules.order || modlist=/dev/null - { - sed 's/ko$/mod/' $modlist | xargs -n1 sed -n -e '2p' + [ -n "${read_modorder}" ] && sed 's/ko$/usyms/' modules.order | xargs cat echo "$needed_symbols" [ -n "$ksym_wl" ] && cat "$ksym_wl" } | sed -e 's/ /\n/g' | sed -n -e '/^$/!p' | diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index 905c0ec291e1..0125698f2037 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -387,7 +387,7 @@ out_file: /* Calc and record src checksum. */ void get_src_version(const char *modname, char sum[], unsigned sumlen) { - char *buf, *pos, *firstline; + char *buf; struct md4_ctx md; char *fname; char filelist[PATH_MAX + 1]; @@ -397,15 +397,8 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) buf = read_text_file(filelist); - pos = buf; - firstline = get_line(&pos); - if (!firstline) { - warn("bad ending versions file for %s\n", modname); - goto free; - } - md4_init(&md); - while ((fname = strsep(&firstline, " "))) { + while ((fname = strsep(&buf, " \n"))) { if (!*fname) continue; if (!(is_static_library(fname)) && -- cgit v1.2.3 From 22f26f21774f838e97921952d8c5c4aab3da2ea4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 7 Apr 2022 00:30:21 +0900 Subject: kbuild: get rid of duplication in *.mod files It is allowed to add the same objects multiple times to obj-y / obj-m: obj-y += foo.o foo.o foo.o obj-m += bar.o bar.o bar.o It is also allowed to add the same objects multiple times to a composite module: obj-m += foo.o foo-y := foo1.o foo2.o foo2.o foo1.o This flexibility is useful because the same object might be selected by different CONFIG options, like this: obj-m += foo.o foo-y := foo1.o foo-$(CONFIG_FOO_X) += foo2.o foo-$(CONFIG_FOO_Y) += foo2.o The duplicated objects are omitted at link time. It works naturally in Makefiles because GNU Make removes duplication in $^ without changing the order. It is working well, almost... A small flaw I notice is, *.mod contains duplication in such a case. This is probably not a big deal. As far as I know, the only small problem is scripts/mod/sumversion.c parses the same file multiple times. I am fixing this because I plan to reuse *.mod for other purposes, where the duplication can be problematic. The code change is quite simple. We already use awk to drop duplicated lines in modules.order (see cmd_modules_order in the same file). I copied the code, but changed RS to use spaces as record separators. I also changed the file format to list one object per line. Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 3 ++- scripts/mod/sumversion.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 6ae92d119dfa..f7a30f378e20 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -303,7 +303,8 @@ $(obj)/%.prelink.o: $(obj)/%.o FORCE $(call if_changed,cc_prelink_modules) endif -cmd_mod = echo $(addprefix $(obj)/, $(call real-search, $*.o, .o, -objs -y -m)) > $@ +cmd_mod = echo $(addprefix $(obj)/, $(call real-search, $*.o, .o, -objs -y -m)) | \ + $(AWK) -v RS='( |\n)' '!x[$$0]++' > $@ $(obj)/%.mod: $(obj)/%$(mod-prelink-ext).o FORCE $(call if_changed,mod) diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index 0125698f2037..79bb9eaa65ac 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -398,7 +398,7 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) buf = read_text_file(filelist); md4_init(&md); - while ((fname = strsep(&buf, " \n"))) { + while ((fname = strsep(&buf, "\n"))) { if (!*fname) continue; if (!(is_static_library(fname)) && -- cgit v1.2.3 From fc93a4cdce1db7568fcdff608924324f5754efe5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 7 Apr 2022 00:30:22 +0900 Subject: kbuild: make *.mod not depend on *.o The dependency $(obj)/%.mod: $(obj)/%$(mod-prelink-ext).o ... exists because *.mod files previously contained undefined symbols, which are computed from *.o files when CONFIG_TRIM_UNUSED_KSYMS=y. Now that the undefined symbols are put into separate *.usyms files, there is no reason to make *.mod depend on *.o files. Signed-off-by: Masahiro Yamada --- Makefile | 3 ++- scripts/Makefile.build | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 82ee893909e9..e915aacd02b0 100644 --- a/Makefile +++ b/Makefile @@ -1792,7 +1792,8 @@ ifdef single-build # .ko is special because modpost is needed single-ko := $(sort $(filter %.ko, $(MAKECMDGOALS))) -single-no-ko := $(sort $(patsubst %.ko,%.mod, $(MAKECMDGOALS))) +single-no-ko := $(filter-out $(single-ko), $(MAKECMDGOALS)) \ + $(foreach x, o mod, $(patsubst %.ko, %.$x, $(single-ko))) $(single-ko): single_modpost @: diff --git a/scripts/Makefile.build b/scripts/Makefile.build index f7a30f378e20..3da731cf6978 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -85,7 +85,7 @@ ifdef need-builtin targets-for-builtin += $(obj)/built-in.a endif -targets-for-modules := $(foreach x, mod $(if $(CONFIG_TRIM_UNUSED_KSYMS), usyms), \ +targets-for-modules := $(foreach x, o mod $(if $(CONFIG_TRIM_UNUSED_KSYMS), usyms), \ $(patsubst %.o, %.$x, $(filter %.o, $(obj-m)))) ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) @@ -306,7 +306,7 @@ endif cmd_mod = echo $(addprefix $(obj)/, $(call real-search, $*.o, .o, -objs -y -m)) | \ $(AWK) -v RS='( |\n)' '!x[$$0]++' > $@ -$(obj)/%.mod: $(obj)/%$(mod-prelink-ext).o FORCE +$(obj)/%.mod: FORCE $(call if_changed,mod) # List module undefined symbols @@ -469,7 +469,6 @@ $(multi-obj-m): FORCE $(call if_changed,link_multi-m) $(call multi_depend, $(multi-obj-m), .o, -objs -y -m) -targets += $(multi-obj-m) targets := $(filter-out $(PHONY), $(targets)) # Add intermediate targets: -- cgit v1.2.3 From feb7d79fea1d43ddf51a09359b52e73bba0340fd Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 7 Apr 2022 00:30:23 +0900 Subject: kbuild: read *.mod to get objects passed to $(LD) or $(AR) ld and ar support @file, which command-line options are read from. Now that *.mod lists the member objects in the correct order, without duplication, it is ready to be passed to ld and ar. By using the @file syntax, people will not be worried about the pitfall described in the NOTE. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/Makefile.build | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 3da731cf6978..f6a506318795 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -450,22 +450,18 @@ quiet_cmd_ar_lib = AR $@ $(obj)/lib.a: $(lib-y) FORCE $(call if_changed,ar_lib) -# NOTE: -# Do not replace $(filter %.o,^) with $(real-prereqs). When a single object -# module is turned into a multi object module, $^ will contain header file -# dependencies recorded in the .*.cmd file. ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) quiet_cmd_link_multi-m = AR [M] $@ cmd_link_multi-m = \ $(cmd_update_lto_symversions); \ rm -f $@; \ - $(AR) cDPrsT $@ $(filter %.o,$^) + $(AR) cDPrsT $@ @$(patsubst %.o,%.mod,$@) else quiet_cmd_link_multi-m = LD [M] $@ - cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ $(filter %.o,$^) + cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ @$(patsubst %.o,%.mod,$@) endif -$(multi-obj-m): FORCE +$(multi-obj-m): %.o: %.mod FORCE $(call if_changed,link_multi-m) $(call multi_depend, $(multi-obj-m), .o, -objs -y -m) -- cgit v1.2.3 From c77d06e70d59cbc6e3c22bf644bb0b197a5fc182 Mon Sep 17 00:00:00 2001 From: Yann Droneaud Date: Fri, 8 Apr 2022 10:46:07 +0200 Subject: kbuild: support W=e to make build abort in case of warning When developing new code/feature, CONFIG_WERROR is most often turned off, especially for people using make W=12 to get more warnings. In such case, turning on -Werror temporarily would require switching on CONFIG_WERROR in the configuration, building, then switching off CONFIG_WERROR. For this use case, this patch introduces a new 'e' modifier to W= as a short hand for KCFLAGS+=-Werror" so that -Werror got added to the kernel (built-in) and modules' CFLAGS. Signed-off-by: Yann Droneaud Signed-off-by: Masahiro Yamada --- Makefile | 1 + scripts/Makefile.extrawarn | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index e915aacd02b0..235d68fa1470 100644 --- a/Makefile +++ b/Makefile @@ -1650,6 +1650,7 @@ help: @echo ' 1: warnings which may be relevant and do not occur too often' @echo ' 2: warnings which occur quite often but may still be relevant' @echo ' 3: more obscure warnings, can most likely be ignored' + @echo ' e: warnings are being treated as errors' @echo ' Multiple levels can be combined with W=12 or W=123' @echo '' @echo 'Execute "make" or "make all" to build all targets marked with [*] ' diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 650d0b8ceec3..f5f0d6f09053 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -2,8 +2,8 @@ # ========================================================================== # make W=... settings # -# There are three warning groups enabled by W=1, W=2, W=3. -# They are independent, and can be combined like W=12 or W=123. +# There are four warning groups enabled by W=1, W=2, W=3, and W=e +# They are independent, and can be combined like W=12 or W=123e. # ========================================================================== KBUILD_CFLAGS += $(call cc-disable-warning, packed-not-aligned) @@ -94,3 +94,12 @@ KBUILD_CFLAGS += $(call cc-option, -Wpacked-bitfield-compat) KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN3 endif + +# +# W=e - error out on warnings +# +ifneq ($(findstring e, $(KBUILD_EXTRA_WARN)),) + +KBUILD_CFLAGS += -Werror + +endif -- cgit v1.2.3 From a90bb65ae2168c8b36e53f82dc3cb35c6cff4f1e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 19 Apr 2022 08:30:09 +0200 Subject: scripts: dummy-tools, add pahole CONFIG_PAHOLE_VERSION is a part of a config since the commit below. And when multiple people update the config, this value constantly changes. Even if they use dummy scripts. To fix this, add a pahole dummy script returning v99.99. (This is translated into 9999 later in the process.) Thereafter, this script can be invoked easily for example as: make PAHOLE=scripts/dummy-tools/pahole oldconfig Fixes: 613fe1692377 (kbuild: Add CONFIG_PAHOLE_VERSION) Signed-off-by: Jiri Slaby Signed-off-by: Masahiro Yamada --- scripts/dummy-tools/pahole | 4 ++++ 1 file changed, 4 insertions(+) create mode 100755 scripts/dummy-tools/pahole (limited to 'scripts') diff --git a/scripts/dummy-tools/pahole b/scripts/dummy-tools/pahole new file mode 100755 index 000000000000..53501a36fa71 --- /dev/null +++ b/scripts/dummy-tools/pahole @@ -0,0 +1,4 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only + +echo v99.99 -- cgit v1.2.3 From f4d40868fc4dcfd5db4999149b13fea3902c8883 Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Sat, 23 Apr 2022 00:17:25 +0900 Subject: checksyscalls: ignore -Wunused-macros The macros defined in this file are for testing only and are purposely not used. When compiled with W=2, both gcc and clang yield some -Wunused-macros warnings. Ignore them. Signed-off-by: Vincent Mailhol Signed-off-by: Masahiro Yamada --- scripts/checksyscalls.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh index 9dbab13329fa..f33e61aca93d 100755 --- a/scripts/checksyscalls.sh +++ b/scripts/checksyscalls.sh @@ -268,4 +268,4 @@ syscall_list() { } (ignore_list && syscall_list $(dirname $0)/../arch/x86/entry/syscalls/syscall_32.tbl) | \ -$* -Wno-error -E -x c - > /dev/null +$* -Wno-error -Wno-unused-macros -E -x c - > /dev/null -- cgit v1.2.3 From 15a28c7c72917f96820e9e9ccd113606363ba3ac Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 25 Apr 2022 04:07:45 +0900 Subject: modpost: use snprintf() instead of sprintf() for safety Use snprintf() to avoid the potential buffer overflow, and also check the return value to detect the too long path. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 522d5249d196..141370ebbfd3 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2560,6 +2560,7 @@ int main(int argc, char **argv) for (mod = modules; mod; mod = mod->next) { char fname[PATH_MAX]; + int ret; if (mod->is_vmlinux || mod->from_dump) continue; @@ -2578,7 +2579,12 @@ int main(int argc, char **argv) add_moddevtable(&buf, mod); add_srcversion(&buf, mod); - sprintf(fname, "%s.mod.c", mod->name); + ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name); + if (ret >= sizeof(fname)) { + error("%s: too long path was truncated\n", fname); + continue; + } + write_if_changed(&buf, fname); } -- cgit v1.2.3 From c155a47d83ab0b5ee96ebe1721057cba1936d0d5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 25 Apr 2022 04:07:46 +0900 Subject: modpost: do not write out any file when error occurred If an error occurs, modpost will fail anyway. Do not write out any content (, which might be invalid). Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 141370ebbfd3..f0d48f65fb33 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2333,6 +2333,9 @@ static void write_buf(struct buffer *b, const char *fname) { FILE *file; + if (error_occurred) + return; + file = fopen(fname, "w"); if (!file) { perror(fname); -- cgit v1.2.3 From 594ade3eef3f2d458902ced2cb2614dfae8558de Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 25 Apr 2022 04:07:47 +0900 Subject: modpost: remove stale comment about sym_add_exported() The description, it may have already been added without a CRC, in this case just update the CRC ... is no longer valid. In the old days, this function was used to update the CRC as well. Commit 040fcc819a2e ("kbuild: improved modversioning support for external modules") started to use a separate function (sym_update_crc) for updating the CRC. The first part, "Add an exported symbol" is correct, but it is too obvious from the function name. Drop this comment entirely. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index f0d48f65fb33..c7cfeeb088f7 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -387,10 +387,6 @@ static void sym_update_namespace(const char *symname, const char *namespace) s->namespace = namespace[0] ? NOFAIL(strdup(namespace)) : NULL; } -/** - * Add an exported symbol - it may have already been added without a - * CRC, in this case just update the CRC - **/ static struct symbol *sym_add_exported(const char *name, struct module *mod, enum export export) { -- cgit v1.2.3 From 23beb44a0effaad1bd627fd134f0301c622deba7 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 25 Apr 2022 04:07:48 +0900 Subject: modpost: add a separate error for exported symbols without definition It took me a while to understand the intent of "exp->module == mod". This code goes back to 2003. [1] The commit is not in this git repository, and might be worth a little explanation. You can add EXPORT_SYMBOL() without having its definition in the same file (but you need to put a declaration). This is typical when EXPORT_SYMBOL() is added in a C file, but the actual implementation is in a separate assembly file. One example is arch/arm/kernel/armksyms.c In the old days, EXPORT_SYMBOL() was only available in C files (but this limitation does not exist any more). If you forget to add the definition, this error occurs. Add a separate, clearer message for this case. It should be an error even if KBUILD_MODPOST_WARN is given. [1]: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=2763b6bcb96e6a38a2fe31108fe5759ec5bcc80a Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c7cfeeb088f7..969a081dba62 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2147,13 +2147,18 @@ static void check_exports(struct module *mod) for (s = mod->unres; s; s = s->next) { const char *basename; exp = find_symbol(s->name); - if (!exp || exp->module == mod) { + if (!exp) { if (!s->weak && nr_unresolved++ < MAX_UNRESOLVED_REPORTS) modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR, "\"%s\" [%s.ko] undefined!\n", s->name, mod->name); continue; } + if (exp->module == mod) { + error("\"%s\" [%s.ko] was exported without definition\n", + s->name, mod->name); + continue; + } basename = strrchr(mod->name, '/'); if (basename) basename++; -- cgit v1.2.3 From 4cae77ac582b430d6ad6fbf0e1b23248997ceac8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 25 Apr 2022 04:07:49 +0900 Subject: modpost: retrieve the module dependency and CRCs in check_exports() Do not repeat the similar code. It is simpler to do this in check_exports() instead of add_versions(). Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 969a081dba62..f9cbb6b6b7a5 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2159,6 +2159,11 @@ static void check_exports(struct module *mod) s->name, mod->name); continue; } + + s->module = exp->module; + s->crc_valid = exp->crc_valid; + s->crc = exp->crc; + basename = strrchr(mod->name, '/'); if (basename) basename++; @@ -2251,16 +2256,7 @@ static void add_staging_flag(struct buffer *b, const char *name) **/ static void add_versions(struct buffer *b, struct module *mod) { - struct symbol *s, *exp; - - for (s = mod->unres; s; s = s->next) { - exp = find_symbol(s->name); - if (!exp || exp->module == mod) - continue; - s->module = exp->module; - s->crc_valid = exp->crc_valid; - s->crc = exp->crc; - } + struct symbol *s; if (!modversions) return; -- cgit v1.2.3 From 70ddb48db4aaddd3c2a7d8802463e15b21ce8525 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 25 Apr 2022 04:07:56 +0900 Subject: modpost: move struct namespace_list to modpost.c There is no good reason to define struct namespace_list in modpost.h struct module has pointers to struct namespace_list, but that does not require the definition of struct namespace_list. Move it to modpost.c. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 5 +++++ scripts/mod/modpost.h | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index f9cbb6b6b7a5..689a34229809 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -270,6 +270,11 @@ static struct symbol *find_symbol(const char *name) return NULL; } +struct namespace_list { + struct namespace_list *next; + char namespace[]; +}; + static bool contains_namespace(struct namespace_list *list, const char *namespace) { diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 0a940fd2e5c7..7aed57fe793e 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -109,11 +109,6 @@ buf_printf(struct buffer *buf, const char *fmt, ...); void buf_write(struct buffer *buf, const char *s, int len); -struct namespace_list { - struct namespace_list *next; - char namespace[]; -}; - struct module { struct module *next; int gpl_compatible; -- cgit v1.2.3 From 8d613a1d048c233a490d45a26d55fc2fd58d26e8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 30 Apr 2022 20:04:09 +0900 Subject: kbuild: drop $(objtree)/ prefix support for clean-files I think this hack is a bad idea. arch/powerpc/boot/Makefile is the only and last user. Let's stop doing this. Signed-off-by: Masahiro Yamada Acked-by: Michael Ellerman (powerpc) --- arch/powerpc/boot/Makefile | 4 ++-- scripts/Makefile.clean | 8 +------- 2 files changed, 3 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 4b4827c475c6..008bf0bff186 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -453,8 +453,8 @@ clean-files += $(image-) $(initrd-) cuImage.* dtbImage.* treeImage.* \ clean-kernel-base := vmlinux.strip vmlinux.bin clean-kernel := $(addsuffix .gz,$(clean-kernel-base)) clean-kernel += $(addsuffix .xz,$(clean-kernel-base)) -# If not absolute clean-files are relative to $(obj). -clean-files += $(addprefix $(objtree)/, $(clean-kernel)) +# clean-files are relative to $(obj). +clean-files += $(addprefix ../../../, $(clean-kernel)) WRAPPER_OBJDIR := /usr/lib/kernel-wrapper WRAPPER_DTSDIR := /usr/lib/kernel-wrapper/dts diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index 74cb1c5c3658..878cec648959 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -36,13 +36,7 @@ __clean-files := \ __clean-files := $(filter-out $(no-clean-files), $(__clean-files)) -# clean-files is given relative to the current directory, unless it -# starts with $(objtree)/ (which means "./", so do not add "./" unless -# you want to delete a file from the toplevel object directory). - -__clean-files := $(wildcard \ - $(addprefix $(obj)/, $(filter-out $(objtree)/%, $(__clean-files))) \ - $(filter $(objtree)/%, $(__clean-files))) +__clean-files := $(wildcard $(addprefix $(obj)/, $(__clean-files))) # ========================================================================== -- cgit v1.2.3 From 58e01fcae18c9d01be701bec9e9a8ee58269c7c1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 May 2022 17:40:07 +0900 Subject: modpost: use bool type where appropriate Use 'bool' to clarify that the valid value is true or false. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 56 ++++++++++++++++++++++++------------------------ scripts/mod/modpost.h | 11 +++++----- scripts/mod/sumversion.c | 8 +++---- 3 files changed, 37 insertions(+), 38 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 689a34229809..a6035ab78cd8 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -23,20 +23,20 @@ #include "../../include/linux/license.h" /* Are we using CONFIG_MODVERSIONS? */ -static int modversions; +static bool modversions; /* Is CONFIG_MODULE_SRCVERSION_ALL set? */ -static int all_versions; +static bool all_versions; /* If we are modposting external module set to 1 */ -static int external_module; +static bool external_module; /* Only warn about unresolved symbols */ -static int warn_unresolved; +static bool warn_unresolved; /* How a symbol is exported */ static int sec_mismatch_count; -static int sec_mismatch_warn_only = true; +static bool sec_mismatch_warn_only = true; /* ignore missing files */ -static int ignore_missing_files; +static bool ignore_missing_files; /* If set to 1, only warn (instead of error) about missing ns imports */ -static int allow_missing_ns_imports; +static bool allow_missing_ns_imports; static bool error_occurred; @@ -202,11 +202,11 @@ static struct module *new_module(const char *modname) struct symbol { struct symbol *next; struct module *module; - unsigned int crc; - int crc_valid; char *namespace; - unsigned int weak:1; - unsigned int is_static:1; /* 1 if symbol is not global */ + unsigned int crc; + bool crc_valid; + bool weak; + bool is_static; /* true if symbol is not global */ enum export export; /* Type of export */ char name[]; }; @@ -230,7 +230,7 @@ static inline unsigned int tdb_hash(const char *name) * Allocate a new symbols for use in the hash of exported symbols or * the list of unresolved symbols per module **/ -static struct symbol *alloc_symbol(const char *name, unsigned int weak, +static struct symbol *alloc_symbol(const char *name, bool weak, struct symbol *next) { struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1)); @@ -239,7 +239,7 @@ static struct symbol *alloc_symbol(const char *name, unsigned int weak, strcpy(s->name, name); s->weak = weak; s->next = next; - s->is_static = 1; + s->is_static = true; return s; } @@ -250,7 +250,7 @@ static struct symbol *new_symbol(const char *name, struct module *module, unsigned int hash; hash = tdb_hash(name) % SYMBOL_HASH_SIZE; - symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]); + symbolhash[hash] = alloc_symbol(name, false, symbolhash[hash]); return symbolhash[hash]; } @@ -424,7 +424,7 @@ static void sym_set_crc(const char *name, unsigned int crc) return; s->crc = crc; - s->crc_valid = 1; + s->crc_valid = true; } static void *grab_file(const char *filename, size_t *size) @@ -721,9 +721,9 @@ static void handle_symbol(struct module *mod, struct elf_info *info, sym_add_exported(name, mod, export); } if (strcmp(symname, "init_module") == 0) - mod->has_init = 1; + mod->has_init = true; if (strcmp(symname, "cleanup_module") == 0) - mod->has_cleanup = 1; + mod->has_cleanup = true; break; } } @@ -2058,7 +2058,7 @@ static void read_symbols(const char *modname) sym->st_name)); if (s) - s->is_static = 0; + s->is_static = false; } } @@ -2078,7 +2078,7 @@ static void read_symbols(const char *modname) * the automatic versioning doesn't pick it up, but it's really * important anyhow */ if (modversions) - mod->unres = alloc_symbol("module_layout", 0, mod->unres); + mod->unres = alloc_symbol("module_layout", false, mod->unres); } static void read_symbols_from_files(const char *filename) @@ -2310,7 +2310,7 @@ static void add_depends(struct buffer *b, struct module *mod) if (s->module->seen) continue; - s->module->seen = 1; + s->module->seen = true; p = strrchr(s->module->name, '/'); if (p) p++; @@ -2427,10 +2427,10 @@ static void read_dump(const char *fname) mod = find_module(modname); if (!mod) { mod = new_module(modname); - mod->from_dump = 1; + mod->from_dump = true; } s = sym_add_exported(symname, mod, export_no(export)); - s->is_static = 0; + s->is_static = false; sym_set_crc(symname, crc); sym_update_namespace(symname, namespace); } @@ -2508,7 +2508,7 @@ int main(int argc, char **argv) while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:")) != -1) { switch (opt) { case 'e': - external_module = 1; + external_module = true; break; case 'i': *dump_read_iter = @@ -2517,28 +2517,28 @@ int main(int argc, char **argv) dump_read_iter = &(*dump_read_iter)->next; break; case 'm': - modversions = 1; + modversions = true; break; case 'n': - ignore_missing_files = 1; + ignore_missing_files = true; break; case 'o': dump_write = optarg; break; case 'a': - all_versions = 1; + all_versions = true; break; case 'T': files_source = optarg; break; case 'w': - warn_unresolved = 1; + warn_unresolved = true; break; case 'E': sec_mismatch_warn_only = false; break; case 'N': - allow_missing_ns_imports = 1; + allow_missing_ns_imports = true; break; case 'd': missing_namespace_deps = optarg; diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 7aed57fe793e..0bd8f697f94c 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -1,4 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ +#include #include #include #include @@ -113,11 +114,11 @@ struct module { struct module *next; int gpl_compatible; struct symbol *unres; - int from_dump; /* 1 if module was loaded from *.symvers */ - int is_vmlinux; - int seen; - int has_init; - int has_cleanup; + bool from_dump; /* true if module was loaded from *.symvers */ + bool is_vmlinux; + bool seen; + bool has_init; + bool has_cleanup; struct buffer dev_table_buf; char srcversion[25]; // Missing namespace dependencies diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index 79bb9eaa65ac..6bf9caca0968 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -290,13 +290,11 @@ static int parse_file(const char *fname, struct md4_ctx *md) return 1; } /* Check whether the file is a static library or not */ -static int is_static_library(const char *objfile) +static bool is_static_library(const char *objfile) { int len = strlen(objfile); - if (objfile[len - 2] == '.' && objfile[len - 1] == 'a') - return 1; - else - return 0; + + return objfile[len - 2] == '.' && objfile[len - 1] == 'a'; } /* We have dir/file.o. Open dir/.file.o.cmd, look for source_ and deps_ line -- cgit v1.2.3 From 5066743e4c2f702c1da8ba00a1dc217527a0ab7c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 May 2022 17:40:08 +0900 Subject: modpost: change mod->gpl_compatible to bool type Currently, mod->gpl_compatible is tristate; it is set to -1 by default, then to 1 or 0 when MODULE_LICENSE() is found. Maybe, -1 was chosen to represent the 'unknown' license, but it is not useful. The current code: if (!mod->gpl_compatible) check_for_gpl_usage(exp->export, basename, exp->name); ... only cares whether gpl_compatible is zero or not. Change it to a bool type with the initial value 'true', which has no functional change. The default value should be 'true' instead of 'false'. Since commit 1d6cd3929360 ("modpost: turn missing MODULE_LICENSE() into error"), unknown module license is an error. The error message, "missing MODULE_LICENSE()" is enough to explain the issue. It is not sensible to show another message, "GPL-incompatible module ... uses GPL-only symbol". Add comments to explain this. While I was here, I renamed gpl_compatible to is_gpl_compatible for clarification, and also slightly refactored the code. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 17 +++++++++++------ scripts/mod/modpost.h | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index a6035ab78cd8..25066dc25790 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -187,7 +187,14 @@ static struct module *new_module(const char *modname) /* add to list */ strcpy(mod->name, modname); mod->is_vmlinux = (strcmp(modname, "vmlinux") == 0); - mod->gpl_compatible = -1; + + /* + * Set mod->is_gpl_compatible to true by default. If MODULE_LICENSE() + * is missing, do not check the use for EXPORT_SYMBOL_GPL() becasue + * modpost will exit wiht error anyway. + */ + mod->is_gpl_compatible = true; + mod->next = modules; modules = mod; @@ -2012,10 +2019,8 @@ static void read_symbols(const char *modname) if (!license) error("missing MODULE_LICENSE() in %s\n", modname); while (license) { - if (license_is_gpl_compatible(license)) - mod->gpl_compatible = 1; - else { - mod->gpl_compatible = 0; + if (!license_is_gpl_compatible(license)) { + mod->is_gpl_compatible = false; break; } license = get_next_modinfo(&info, "license", license); @@ -2183,7 +2188,7 @@ static void check_exports(struct module *mod) add_namespace(&mod->missing_namespaces, exp->namespace); } - if (!mod->gpl_compatible) + if (!mod->is_gpl_compatible) check_for_gpl_usage(exp->export, basename, exp->name); } } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 0bd8f697f94c..73c36dfbf0e1 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -112,7 +112,7 @@ buf_write(struct buffer *buf, const char *s, int len); struct module { struct module *next; - int gpl_compatible; + bool is_gpl_compatible; struct symbol *unres; bool from_dump; /* true if module was loaded from *.symvers */ bool is_vmlinux; -- cgit v1.2.3 From 97aa4aef532aed6885e887ad6979e5ffb2667c84 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 May 2022 17:40:09 +0900 Subject: modpost: import include/linux/list.h Import include/linux/list.h to use convenient list macros in modpost. I dropped kernel-space code such as {WRITE,READ}_ONCE etc. and unneeded macros. I also imported container_of() from include/linux/container_of.h and type definitions from include/linux/types.h. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/list.h | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 scripts/mod/list.h (limited to 'scripts') diff --git a/scripts/mod/list.h b/scripts/mod/list.h new file mode 100644 index 000000000000..a924a6c4aa4d --- /dev/null +++ b/scripts/mod/list.h @@ -0,0 +1,213 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LIST_H +#define LIST_H + +#include +#include + +/* Are two types/vars the same type (ignoring qualifiers)? */ +#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) + +/** + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + void *__mptr = (void *)(ptr); \ + _Static_assert(__same_type(*(ptr), ((type *)0)->member) || \ + __same_type(*(ptr), void), \ + "pointer type mismatch in container_of()"); \ + ((type *)(__mptr - offsetof(type, member))); }) + +#define LIST_POISON1 ((void *) 0x100) +#define LIST_POISON2 ((void *) 0x122) + +/* + * Circular doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +/** + * INIT_LIST_HEAD - Initialize a list_head structure + * @list: list_head structure to be initialized. + * + * Initializes the list_head to point to itself. If it is a list header, + * the result is an empty list. + */ +static inline void INIT_LIST_HEAD(struct list_head *list) +{ + list->next = list; + list->prev = list; +} + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +/** + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static inline void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static inline void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_del(struct list_head *prev, struct list_head *next) +{ + next->prev = prev; + prev->next = next; +} + +static inline void __list_del_entry(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty() on entry does not return true after this, the entry is + * in an undefined state. + */ +static inline void list_del(struct list_head *entry) +{ + __list_del_entry(entry); + entry->next = LIST_POISON1; + entry->prev = LIST_POISON2; +} + +/** + * list_is_head - tests whether @list is the list @head + * @list: the entry to test + * @head: the head of the list + */ +static inline int list_is_head(const struct list_head *list, const struct list_head *head) +{ + return list == head; +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int list_empty(const struct list_head *head) +{ + return head->next == head; +} + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_head within the struct. + */ +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +/** + * list_first_entry - get the first element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_head within the struct. + * + * Note, that list is expected to be not empty. + */ +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + +/** + * list_next_entry - get the next element in list + * @pos: the type * to cursor + * @member: the name of the list_head within the struct. + */ +#define list_next_entry(pos, member) \ + list_entry((pos)->member.next, typeof(*(pos)), member) + +/** + * list_entry_is_head - test if the entry points to the head of the list + * @pos: the type * to cursor + * @head: the head for your list. + * @member: the name of the list_head within the struct. + */ +#define list_entry_is_head(pos, head, member) \ + (&pos->member == (head)) + +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_head within the struct. + */ +#define list_for_each_entry(pos, head, member) \ + for (pos = list_first_entry(head, typeof(*pos), member); \ + !list_entry_is_head(pos, head, member); \ + pos = list_next_entry(pos, member)) + +/** + * list_for_each_entry_safe - iterate over list of given type. Safe against removal of list entry + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_head within the struct. + */ +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_first_entry(head, typeof(*pos), member), \ + n = list_next_entry(pos, member); \ + !list_entry_is_head(pos, head, member); \ + pos = n, n = list_next_entry(n, member)) + +#endif /* LIST_H */ -- cgit v1.2.3 From 325eba05e8ab53a9182a2734f0986c15e5f87349 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 May 2022 17:40:10 +0900 Subject: modpost: traverse modules in order Currently, modpost manages modules in a singly linked list; it adds a new node to the head, and traverses the list from new to old. It works, but the error messages are shown in the reverse order. If you have a Makefile like this: obj-m += foo.o bar.o then, modpost shows error messages in bar.o, foo.o, in this order. Use a doubly linked list to keep the order in modules.order; use list_add_tail() for the node addition and list_for_each_entry() for the list traverse. Now that the kernel's list macros have been imported to modpost, I will use them actively going forward. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 17 ++++++++--------- scripts/mod/modpost.h | 3 ++- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 25066dc25790..1b9dcb44621c 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -165,16 +165,17 @@ char *get_line(char **stringp) } /* A list of all modules we processed */ -static struct module *modules; +LIST_HEAD(modules); static struct module *find_module(const char *modname) { struct module *mod; - for (mod = modules; mod; mod = mod->next) + list_for_each_entry(mod, &modules, list) { if (strcmp(mod->name, modname) == 0) - break; - return mod; + return mod; + } + return NULL; } static struct module *new_module(const char *modname) @@ -184,7 +185,6 @@ static struct module *new_module(const char *modname) mod = NOFAIL(malloc(sizeof(*mod) + strlen(modname) + 1)); memset(mod, 0, sizeof(*mod)); - /* add to list */ strcpy(mod->name, modname); mod->is_vmlinux = (strcmp(modname, "vmlinux") == 0); @@ -195,8 +195,7 @@ static struct module *new_module(const char *modname) */ mod->is_gpl_compatible = true; - mod->next = modules; - modules = mod; + list_add_tail(&mod->list, &modules); return mod; } @@ -2477,7 +2476,7 @@ static void write_namespace_deps_files(const char *fname) struct namespace_list *ns; struct buffer ns_deps_buf = {}; - for (mod = modules; mod; mod = mod->next) { + list_for_each_entry(mod, &modules, list) { if (mod->from_dump || !mod->missing_namespaces) continue; @@ -2568,7 +2567,7 @@ int main(int argc, char **argv) if (files_source) read_symbols_from_files(files_source); - for (mod = modules; mod; mod = mod->next) { + list_for_each_entry(mod, &modules, list) { char fname[PATH_MAX]; int ret; diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 73c36dfbf0e1..69601f36d080 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -11,6 +11,7 @@ #include #include +#include "list.h" #include "elfconfig.h" /* On BSD-alike OSes elf.h defines these according to host's word size */ @@ -111,7 +112,7 @@ void buf_write(struct buffer *buf, const char *s, int len); struct module { - struct module *next; + struct list_head list; bool is_gpl_compatible; struct symbol *unres; bool from_dump; /* true if module was loaded from *.symvers */ -- cgit v1.2.3 From e882e89bcf1d54da2e4388570325774c3e3078a9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 May 2022 17:40:11 +0900 Subject: modpost: add sym_add_unresolved() helper Add a small helper, sym_add_unresolved() to ease the further refactoring. Remove the 'weak' argument from alloc_symbol() because it is sensible only for unresolved symbols. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 1b9dcb44621c..59d817692893 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -236,14 +236,12 @@ static inline unsigned int tdb_hash(const char *name) * Allocate a new symbols for use in the hash of exported symbols or * the list of unresolved symbols per module **/ -static struct symbol *alloc_symbol(const char *name, bool weak, - struct symbol *next) +static struct symbol *alloc_symbol(const char *name, struct symbol *next) { struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1)); memset(s, 0, sizeof(*s)); strcpy(s->name, name); - s->weak = weak; s->next = next; s->is_static = true; return s; @@ -256,11 +254,17 @@ static struct symbol *new_symbol(const char *name, struct module *module, unsigned int hash; hash = tdb_hash(name) % SYMBOL_HASH_SIZE; - symbolhash[hash] = alloc_symbol(name, false, symbolhash[hash]); + symbolhash[hash] = alloc_symbol(name, symbolhash[hash]); return symbolhash[hash]; } +static void sym_add_unresolved(const char *name, struct module *mod, bool weak) +{ + mod->unres = alloc_symbol(name, mod->unres); + mod->unres->weak = weak; +} + static struct symbol *find_symbol(const char *name) { struct symbol *s; @@ -712,9 +716,8 @@ static void handle_symbol(struct module *mod, struct elf_info *info, } } - mod->unres = alloc_symbol(symname, - ELF_ST_BIND(sym->st_info) == STB_WEAK, - mod->unres); + sym_add_unresolved(symname, mod, + ELF_ST_BIND(sym->st_info) == STB_WEAK); break; default: /* All exported symbols */ @@ -2082,7 +2085,7 @@ static void read_symbols(const char *modname) * the automatic versioning doesn't pick it up, but it's really * important anyhow */ if (modversions) - mod->unres = alloc_symbol("module_layout", false, mod->unres); + sym_add_unresolved("module_layout", mod, false); } static void read_symbols_from_files(const char *filename) -- cgit v1.2.3 From 8a69152be9a8c1f7a02c6b8410b35c68cb200f6d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 May 2022 17:40:12 +0900 Subject: modpost: traverse unresolved symbols in order Currently, modpost manages unresolved in a singly linked list; it adds a new node to the head, and traverses the list from new to old. Use a doubly linked list to keep the order in the symbol table in the ELF file. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 20 ++++++++++++++------ scripts/mod/modpost.h | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 59d817692893..70a66ce9ffd9 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -185,6 +185,8 @@ static struct module *new_module(const char *modname) mod = NOFAIL(malloc(sizeof(*mod) + strlen(modname) + 1)); memset(mod, 0, sizeof(*mod)); + INIT_LIST_HEAD(&mod->unresolved_symbols); + strcpy(mod->name, modname); mod->is_vmlinux = (strcmp(modname, "vmlinux") == 0); @@ -207,6 +209,7 @@ static struct module *new_module(const char *modname) struct symbol { struct symbol *next; + struct list_head list; /* link to module::unresolved_symbols */ struct module *module; char *namespace; unsigned int crc; @@ -261,8 +264,12 @@ static struct symbol *new_symbol(const char *name, struct module *module, static void sym_add_unresolved(const char *name, struct module *mod, bool weak) { - mod->unres = alloc_symbol(name, mod->unres); - mod->unres->weak = weak; + struct symbol *sym; + + sym = alloc_symbol(name, NULL); + sym->weak = weak; + + list_add_tail(&sym->list, &mod->unresolved_symbols); } static struct symbol *find_symbol(const char *name) @@ -2156,7 +2163,7 @@ static void check_exports(struct module *mod) { struct symbol *s, *exp; - for (s = mod->unres; s; s = s->next) { + list_for_each_entry(s, &mod->unresolved_symbols, list) { const char *basename; exp = find_symbol(s->name); if (!exp) { @@ -2277,7 +2284,7 @@ static void add_versions(struct buffer *b, struct module *mod) buf_printf(b, "static const struct modversion_info ____versions[]\n"); buf_printf(b, "__used __section(\"__versions\") = {\n"); - for (s = mod->unres; s; s = s->next) { + list_for_each_entry(s, &mod->unresolved_symbols, list) { if (!s->module) continue; if (!s->crc_valid) { @@ -2303,13 +2310,14 @@ static void add_depends(struct buffer *b, struct module *mod) int first = 1; /* Clear ->seen flag of modules that own symbols needed by this. */ - for (s = mod->unres; s; s = s->next) + list_for_each_entry(s, &mod->unresolved_symbols, list) { if (s->module) s->module->seen = s->module->is_vmlinux; + } buf_printf(b, "\n"); buf_printf(b, "MODULE_INFO(depends, \""); - for (s = mod->unres; s; s = s->next) { + list_for_each_entry(s, &mod->unresolved_symbols, list) { const char *p; if (!s->module) continue; diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 69601f36d080..f06bbd0ba93c 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -113,8 +113,8 @@ buf_write(struct buffer *buf, const char *s, int len); struct module { struct list_head list; + struct list_head unresolved_symbols; bool is_gpl_compatible; - struct symbol *unres; bool from_dump; /* true if module was loaded from *.symvers */ bool is_vmlinux; bool seen; -- cgit v1.2.3 From 4484054816cab940fc2fde23fa989174fec889d0 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 May 2022 17:40:13 +0900 Subject: modpost: use doubly linked list for dump_lists This looks easier to understand (just because this is a pattern in the kernel code). No functional change is intended. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 70a66ce9ffd9..a6a55f359396 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2505,7 +2505,7 @@ static void write_namespace_deps_files(const char *fname) } struct dump_list { - struct dump_list *next; + struct list_head list; const char *file; }; @@ -2517,8 +2517,8 @@ int main(int argc, char **argv) char *dump_write = NULL, *files_source = NULL; int opt; int n; - struct dump_list *dump_read_start = NULL; - struct dump_list **dump_read_iter = &dump_read_start; + LIST_HEAD(dump_lists); + struct dump_list *dl, *dl2; while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:")) != -1) { switch (opt) { @@ -2526,10 +2526,9 @@ int main(int argc, char **argv) external_module = true; break; case 'i': - *dump_read_iter = - NOFAIL(calloc(1, sizeof(**dump_read_iter))); - (*dump_read_iter)->file = optarg; - dump_read_iter = &(*dump_read_iter)->next; + dl = NOFAIL(malloc(sizeof(*dl))); + dl->file = optarg; + list_add_tail(&dl->list, &dump_lists); break; case 'm': modversions = true; @@ -2563,13 +2562,10 @@ int main(int argc, char **argv) } } - while (dump_read_start) { - struct dump_list *tmp; - - read_dump(dump_read_start->file); - tmp = dump_read_start->next; - free(dump_read_start); - dump_read_start = tmp; + list_for_each_entry_safe(dl, dl2, &dump_lists, list) { + read_dump(dl->file); + list_del(&dl->list); + free(dl); } while (optind < argc) -- cgit v1.2.3 From ab489d6002fc27dc5db6d66f121da6fc0bda13ad Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 May 2022 17:40:14 +0900 Subject: modpost: traverse the namespace_list in order Use the doubly linked list to traverse the list in the added order. This makes the code more consistent. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 33 +++++++++++++++------------------ scripts/mod/modpost.h | 4 ++-- 2 files changed, 17 insertions(+), 20 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index a6a55f359396..8bdde738803f 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -186,6 +186,8 @@ static struct module *new_module(const char *modname) memset(mod, 0, sizeof(*mod)); INIT_LIST_HEAD(&mod->unresolved_symbols); + INIT_LIST_HEAD(&mod->missing_namespaces); + INIT_LIST_HEAD(&mod->imported_namespaces); strcpy(mod->name, modname); mod->is_vmlinux = (strcmp(modname, "vmlinux") == 0); @@ -288,39 +290,34 @@ static struct symbol *find_symbol(const char *name) } struct namespace_list { - struct namespace_list *next; + struct list_head list; char namespace[]; }; -static bool contains_namespace(struct namespace_list *list, - const char *namespace) +static bool contains_namespace(struct list_head *head, const char *namespace) { - for (; list; list = list->next) + struct namespace_list *list; + + list_for_each_entry(list, head, list) { if (!strcmp(list->namespace, namespace)) return true; + } return false; } -static void add_namespace(struct namespace_list **list, const char *namespace) +static void add_namespace(struct list_head *head, const char *namespace) { struct namespace_list *ns_entry; - if (!contains_namespace(*list, namespace)) { - ns_entry = NOFAIL(malloc(sizeof(struct namespace_list) + + if (!contains_namespace(head, namespace)) { + ns_entry = NOFAIL(malloc(sizeof(*ns_entry) + strlen(namespace) + 1)); strcpy(ns_entry->namespace, namespace); - ns_entry->next = *list; - *list = ns_entry; + list_add_tail(&ns_entry->list, head); } } -static bool module_imports_namespace(struct module *module, - const char *namespace) -{ - return contains_namespace(module->imported_namespaces, namespace); -} - static const struct { const char *str; enum export export; @@ -2190,7 +2187,7 @@ static void check_exports(struct module *mod) basename = mod->name; if (exp->namespace && - !module_imports_namespace(mod, exp->namespace)) { + !contains_namespace(&mod->imported_namespaces, exp->namespace)) { modpost_log(allow_missing_ns_imports ? LOG_WARN : LOG_ERROR, "module %s uses symbol %s from namespace %s, but does not import it.\n", basename, exp->name, exp->namespace); @@ -2489,12 +2486,12 @@ static void write_namespace_deps_files(const char *fname) list_for_each_entry(mod, &modules, list) { - if (mod->from_dump || !mod->missing_namespaces) + if (mod->from_dump || list_empty(&mod->missing_namespaces)) continue; buf_printf(&ns_deps_buf, "%s.ko:", mod->name); - for (ns = mod->missing_namespaces; ns; ns = ns->next) + list_for_each_entry(ns, &mod->missing_namespaces, list) buf_printf(&ns_deps_buf, " %s", ns->namespace); buf_printf(&ns_deps_buf, "\n"); diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index f06bbd0ba93c..2e13a736ab38 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -123,9 +123,9 @@ struct module { struct buffer dev_table_buf; char srcversion[25]; // Missing namespace dependencies - struct namespace_list *missing_namespaces; + struct list_head missing_namespaces; // Actual imported namespaces - struct namespace_list *imported_namespaces; + struct list_head imported_namespaces; char name[]; }; -- cgit v1.2.3 From f841536e8c5b28e1fbf8743911ae1dc78993abd4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 May 2022 17:40:15 +0900 Subject: modpost: dump Module.symvers in the same order of modules.order modpost dumps the exported symbols into Module.symvers, but currently in random order because it iterates in the hash table. Add a linked list of exported symbols in struct module, so we can iterate on symbols per module. This commit makes Module.symvers much more readable; the outer loop in write_dump() iterates over the modules in the order of modules.order, and the inner loop dumps symbols in each module. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 29 +++++++++++++---------------- scripts/mod/modpost.h | 1 + 2 files changed, 14 insertions(+), 16 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 8bdde738803f..cdd9098b6035 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -185,6 +185,7 @@ static struct module *new_module(const char *modname) mod = NOFAIL(malloc(sizeof(*mod) + strlen(modname) + 1)); memset(mod, 0, sizeof(*mod)); + INIT_LIST_HEAD(&mod->exported_symbols); INIT_LIST_HEAD(&mod->unresolved_symbols); INIT_LIST_HEAD(&mod->missing_namespaces); INIT_LIST_HEAD(&mod->imported_namespaces); @@ -211,7 +212,7 @@ static struct module *new_module(const char *modname) struct symbol { struct symbol *next; - struct list_head list; /* link to module::unresolved_symbols */ + struct list_head list; /* link to module::exported_symbols or module::unresolved_symbols */ struct module *module; char *namespace; unsigned int crc; @@ -413,6 +414,7 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod, if (!s) { s = new_symbol(name, mod, export); + list_add_tail(&s->list, &mod->exported_symbols); } else if (!external_module || s->module->is_vmlinux || s->module == mod) { warn("%s: '%s' exported twice. Previous export was in %s%s\n", @@ -2456,22 +2458,17 @@ fail: static void write_dump(const char *fname) { struct buffer buf = { }; - struct symbol *symbol; - const char *namespace; - int n; + struct module *mod; + struct symbol *sym; - for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { - symbol = symbolhash[n]; - while (symbol) { - if (!symbol->module->from_dump) { - namespace = symbol->namespace; - buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n", - symbol->crc, symbol->name, - symbol->module->name, - export_str(symbol->export), - namespace ? namespace : ""); - } - symbol = symbol->next; + list_for_each_entry(mod, &modules, list) { + if (mod->from_dump) + continue; + list_for_each_entry(sym, &mod->exported_symbols, list) { + buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n", + sym->crc, sym->name, mod->name, + export_str(sym->export), + sym->namespace ?: ""); } } write_buf(&buf, fname); diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 2e13a736ab38..cfa127d2bb8f 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -113,6 +113,7 @@ buf_write(struct buffer *buf, const char *s, int len); struct module { struct list_head list; + struct list_head exported_symbols; struct list_head unresolved_symbols; bool is_gpl_compatible; bool from_dump; /* true if module was loaded from *.symvers */ -- cgit v1.2.3 From b8422711080f57cdf9fb1c0cb8683a2112bed27c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 May 2022 17:40:17 +0900 Subject: modpost: make multiple export error This is currently a warning, but I think modpost should stop building in this case. If the same symbol is exported multiple times and we let it keep going, the sanity check becomes difficult. Only the legitimate case is that an external module overrides the corresponding in-tree module to provide a different implementation with the same interface. Also, there exists an upstream example that exploits this feature. $ make M=tools/testing/nvdimm ... builds tools/testing/nvdimm/libnvdimm.ko. This is a mocked module that overrides the symbols from drivers/nvdimm/libnvdimm.ko. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index cdd9098b6035..841f69475247 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -417,9 +417,9 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod, list_add_tail(&s->list, &mod->exported_symbols); } else if (!external_module || s->module->is_vmlinux || s->module == mod) { - warn("%s: '%s' exported twice. Previous export was in %s%s\n", - mod->name, name, s->module->name, - s->module->is_vmlinux ? "" : ".ko"); + error("%s: '%s' exported twice. Previous export was in %s%s\n", + mod->name, name, s->module->name, + s->module->is_vmlinux ? "" : ".ko"); return s; } -- cgit v1.2.3 From e76cc48d8e6df5d949284132981db73d2dd8c6b5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 May 2022 17:40:18 +0900 Subject: modpost: make sym_add_exported() always allocate a new symbol Currently, sym_add_exported() does not allocate a symbol if the same name symbol already exists in the hash table. This does not reflect the real use cases. You can let an external module override the in-tree one. In this case, the external module will export the same name symbols as the in-tree one. However, modpost simply ignores those symbols, then Module.symvers for the external module loses its symbols. sym_add_exported() should allocate a new symbol. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 841f69475247..6024c668a07c 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -412,19 +412,17 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod, { struct symbol *s = find_symbol(name); - if (!s) { - s = new_symbol(name, mod, export); - list_add_tail(&s->list, &mod->exported_symbols); - } else if (!external_module || s->module->is_vmlinux || - s->module == mod) { + if (s && (!external_module || s->module->is_vmlinux || s->module == mod)) { error("%s: '%s' exported twice. Previous export was in %s%s\n", mod->name, name, s->module->name, s->module->is_vmlinux ? "" : ".ko"); - return s; } + s = new_symbol(name, mod, export); s->module = mod; s->export = export; + list_add_tail(&s->list, &mod->exported_symbols); + return s; } -- cgit v1.2.3 From f18379a30271c0289c2d0e1074e1ed633bfd708c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 May 2022 17:40:19 +0900 Subject: modpost: split new_symbol() to symbol allocation and hash table addition new_symbol() does two things; allocate a new symbol and register it to the hash table. Using a separate function for each is easier to understand. Replace new_symbol() with hash_add_symbol(). Remove the second parameter of alloc_symbol(). Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 6024c668a07c..085abe541280 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -242,34 +242,31 @@ static inline unsigned int tdb_hash(const char *name) * Allocate a new symbols for use in the hash of exported symbols or * the list of unresolved symbols per module **/ -static struct symbol *alloc_symbol(const char *name, struct symbol *next) +static struct symbol *alloc_symbol(const char *name) { struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1)); memset(s, 0, sizeof(*s)); strcpy(s->name, name); - s->next = next; s->is_static = true; return s; } /* For the hash of exported symbols */ -static struct symbol *new_symbol(const char *name, struct module *module, - enum export export) +static void hash_add_symbol(struct symbol *sym) { unsigned int hash; - hash = tdb_hash(name) % SYMBOL_HASH_SIZE; - symbolhash[hash] = alloc_symbol(name, symbolhash[hash]); - - return symbolhash[hash]; + hash = tdb_hash(sym->name) % SYMBOL_HASH_SIZE; + sym->next = symbolhash[hash]; + symbolhash[hash] = sym; } static void sym_add_unresolved(const char *name, struct module *mod, bool weak) { struct symbol *sym; - sym = alloc_symbol(name, NULL); + sym = alloc_symbol(name); sym->weak = weak; list_add_tail(&sym->list, &mod->unresolved_symbols); @@ -418,10 +415,11 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod, s->module->is_vmlinux ? "" : ".ko"); } - s = new_symbol(name, mod, export); + s = alloc_symbol(name); s->module = mod; s->export = export; list_add_tail(&s->list, &mod->exported_symbols); + hash_add_symbol(s); return s; } -- cgit v1.2.3 From d3646589703731026ae7bcba5731fa7a7d0e5291 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 3 May 2022 13:54:59 -0700 Subject: sancov: Split plugin build from plugin CFLAGS When the sancov_plugin is enabled, it gets added to gcc-plugin-y which is used to populate both GCC_PLUGIN (for building the plugin) and GCC_PLUGINS_CFLAGS (for enabling and options). Instead of adding sancov to both and then removing it from GCC_PLUGINS_CFLAGS, create a separate list, gcc-plugin-external-y, which is only added to GCC_PLUGIN. This will also be used by the coming randstruct build changes. Cc: Masahiro Yamada Cc: linux-kbuild@vger.kernel.org Cc: linux-hardening@vger.kernel.org Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220503205503.3054173-3-keescook@chromium.org --- scripts/Makefile.gcc-plugins | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index f67153b260c0..927c3dd57f84 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -8,8 +8,6 @@ ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY endif export DISABLE_LATENT_ENTROPY_PLUGIN -gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV) += sancov_plugin.so - gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += structleak_plugin.so gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) \ += -fplugin-arg-structleak_plugin-verbose @@ -53,13 +51,17 @@ export DISABLE_ARM_SSP_PER_TASK_PLUGIN # All the plugin CFLAGS are collected here in case a build target needs to # filter them out of the KBUILD_CFLAGS. GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) -# The sancov_plugin.so is included via CFLAGS_KCOV, so it is removed here. -GCC_PLUGINS_CFLAGS := $(filter-out %/sancov_plugin.so, $(GCC_PLUGINS_CFLAGS)) export GCC_PLUGINS_CFLAGS # Add the flags to the build! KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) -# All enabled GCC plugins are collected here for building below. -GCC_PLUGIN := $(gcc-plugin-y) +# Some plugins are enabled outside of this Makefile, but they still need to +# be included in GCC_PLUGIN so they can get built. +gcc-plugin-external-$(CONFIG_GCC_PLUGIN_SANCOV) \ + += sancov_plugin.so + +# All enabled GCC plugins are collected here for building in +# scripts/gcc-scripts/Makefile. +GCC_PLUGIN := $(gcc-plugin-y) $(gcc-plugin-external-y) export GCC_PLUGIN -- cgit v1.2.3 From 595b893e2087de306d0781795fb8ec47873596a6 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 3 May 2022 13:55:00 -0700 Subject: randstruct: Reorganize Kconfigs and attribute macros In preparation for Clang supporting randstruct, reorganize the Kconfigs, move the attribute macros, and generalize the feature to be named CONFIG_RANDSTRUCT for on/off, CONFIG_RANDSTRUCT_FULL for the full randomization mode, and CONFIG_RANDSTRUCT_PERFORMANCE for the cache-line sized mode. Cc: linux-hardening@vger.kernel.org Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220503205503.3054173-4-keescook@chromium.org --- Documentation/kbuild/reproducible-builds.rst | 7 ++-- arch/riscv/Kconfig | 2 +- arch/x86/mm/pti.c | 2 +- include/linux/compiler-gcc.h | 8 ---- include/linux/compiler_types.h | 14 +++---- include/linux/vermagic.h | 8 ++-- kernel/panic.c | 2 +- scripts/Makefile.gcc-plugins | 4 +- scripts/gcc-plugins/Kconfig | 38 ----------------- security/Kconfig.hardening | 62 ++++++++++++++++++++++++++++ 10 files changed, 81 insertions(+), 66 deletions(-) (limited to 'scripts') diff --git a/Documentation/kbuild/reproducible-builds.rst b/Documentation/kbuild/reproducible-builds.rst index 3b25655e441b..81ff30505d35 100644 --- a/Documentation/kbuild/reproducible-builds.rst +++ b/Documentation/kbuild/reproducible-builds.rst @@ -99,10 +99,9 @@ unreproducible parts can be treated as sources: Structure randomisation ----------------------- -If you enable ``CONFIG_GCC_PLUGIN_RANDSTRUCT``, you will need to -pre-generate the random seed in -``scripts/gcc-plugins/randomize_layout_seed.h`` so the same value -is used in rebuilds. +If you enable ``CONFIG_RANDSTRUCT``, you will need to pre-generate +the random seed in ``scripts/gcc-plugins/randomize_layout_seed.h`` +so the same value is used in rebuilds. Debug info conflicts -------------------- diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 00fd9c548f26..3ac2a81a55eb 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -468,7 +468,7 @@ config CC_HAVE_STACKPROTECTOR_TLS config STACKPROTECTOR_PER_TASK def_bool y - depends on !GCC_PLUGIN_RANDSTRUCT + depends on !RANDSTRUCT depends on STACKPROTECTOR && CC_HAVE_STACKPROTECTOR_TLS config PHYS_RAM_BASE_FIXED diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c index 5d5c7bb50ce9..ffe3b3a087fe 100644 --- a/arch/x86/mm/pti.c +++ b/arch/x86/mm/pti.c @@ -540,7 +540,7 @@ static inline bool pti_kernel_image_global_ok(void) * cases where RANDSTRUCT is in use to help keep the layout a * secret. */ - if (IS_ENABLED(CONFIG_GCC_PLUGIN_RANDSTRUCT)) + if (IS_ENABLED(CONFIG_RANDSTRUCT)) return false; return true; diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 52299c957c98..a0c55eeaeaf1 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -66,14 +66,6 @@ __builtin_unreachable(); \ } while (0) -#if defined(RANDSTRUCT_PLUGIN) && !defined(__CHECKER__) -#define __randomize_layout __attribute__((randomize_layout)) -#define __no_randomize_layout __attribute__((no_randomize_layout)) -/* This anon struct can add padding, so only enable it under randstruct. */ -#define randomized_struct_fields_start struct { -#define randomized_struct_fields_end } __randomize_layout; -#endif - /* * GCC 'asm goto' miscompiles certain code sequences: * diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index 1c2c33ae1b37..d08dfcb0ac68 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -242,15 +242,15 @@ struct ftrace_likely_data { # define __latent_entropy #endif -#ifndef __randomize_layout +#if defined(RANDSTRUCT) && !defined(__CHECKER__) +# define __randomize_layout __designated_init __attribute__((randomize_layout)) +# define __no_randomize_layout __attribute__((no_randomize_layout)) +/* This anon struct can add padding, so only enable it under randstruct. */ +# define randomized_struct_fields_start struct { +# define randomized_struct_fields_end } __randomize_layout; +#else # define __randomize_layout __designated_init -#endif - -#ifndef __no_randomize_layout # define __no_randomize_layout -#endif - -#ifndef randomized_struct_fields_start # define randomized_struct_fields_start # define randomized_struct_fields_end #endif diff --git a/include/linux/vermagic.h b/include/linux/vermagic.h index 329d63babaeb..efb51a2da599 100644 --- a/include/linux/vermagic.h +++ b/include/linux/vermagic.h @@ -32,11 +32,11 @@ #else #define MODULE_VERMAGIC_MODVERSIONS "" #endif -#ifdef RANDSTRUCT_PLUGIN +#ifdef RANDSTRUCT #include -#define MODULE_RANDSTRUCT_PLUGIN "RANDSTRUCT_PLUGIN_" RANDSTRUCT_HASHED_SEED +#define MODULE_RANDSTRUCT "RANDSTRUCT_" RANDSTRUCT_HASHED_SEED #else -#define MODULE_RANDSTRUCT_PLUGIN +#define MODULE_RANDSTRUCT #endif #define VERMAGIC_STRING \ @@ -44,6 +44,6 @@ MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \ MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \ MODULE_ARCH_VERMAGIC \ - MODULE_RANDSTRUCT_PLUGIN + MODULE_RANDSTRUCT #endif /* _LINUX_VERMAGIC_H */ diff --git a/kernel/panic.c b/kernel/panic.c index eb4dfb932c85..8355b19676f8 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -48,7 +48,7 @@ unsigned int __read_mostly sysctl_oops_all_cpu_backtrace; int panic_on_oops = CONFIG_PANIC_ON_OOPS_VALUE; static unsigned long tainted_mask = - IS_ENABLED(CONFIG_GCC_PLUGIN_RANDSTRUCT) ? (1 << TAINT_RANDSTRUCT) : 0; + IS_ENABLED(CONFIG_RANDSTRUCT) ? (1 << TAINT_RANDSTRUCT) : 0; static int pause_on_oops; static int pause_on_oops_flag; static DEFINE_SPINLOCK(pause_on_oops_lock); diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 927c3dd57f84..827c47ce5c73 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -24,8 +24,8 @@ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) \ gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) \ - += -DRANDSTRUCT_PLUGIN -gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE) \ + += -DRANDSTRUCT +gcc-plugin-cflags-$(CONFIG_RANDSTRUCT_PERFORMANCE) \ += -fplugin-arg-randomize_layout_plugin-performance-mode gcc-plugin-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak_plugin.so diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig index 51d81c3f03d6..e383cda05367 100644 --- a/scripts/gcc-plugins/Kconfig +++ b/scripts/gcc-plugins/Kconfig @@ -46,44 +46,6 @@ config GCC_PLUGIN_LATENT_ENTROPY * https://grsecurity.net/ * https://pax.grsecurity.net/ -config GCC_PLUGIN_RANDSTRUCT - bool "Randomize layout of sensitive kernel structures" - select MODVERSIONS if MODULES - help - If you say Y here, the layouts of structures that are entirely - function pointers (and have not been manually annotated with - __no_randomize_layout), or structures that have been explicitly - marked with __randomize_layout, will be randomized at compile-time. - This can introduce the requirement of an additional information - exposure vulnerability for exploits targeting these structure - types. - - Enabling this feature will introduce some performance impact, - slightly increase memory usage, and prevent the use of forensic - tools like Volatility against the system (unless the kernel - source tree isn't cleaned after kernel installation). - - The seed used for compilation is located at - scripts/gcc-plugins/randomize_layout_seed.h. It remains after - a make clean to allow for external modules to be compiled with - the existing seed and will be removed by a make mrproper or - make distclean. - - This plugin was ported from grsecurity/PaX. More information at: - * https://grsecurity.net/ - * https://pax.grsecurity.net/ - -config GCC_PLUGIN_RANDSTRUCT_PERFORMANCE - bool "Use cacheline-aware structure randomization" - depends on GCC_PLUGIN_RANDSTRUCT - depends on !COMPILE_TEST # do not reduce test coverage - help - If you say Y here, the RANDSTRUCT randomization will make a - best effort at restricting randomization to cacheline-sized - groups of elements. It will further not randomize bitfields - in structures. This reduces the performance hit of RANDSTRUCT - at the cost of weakened randomization. - config GCC_PLUGIN_ARM_SSP_PER_TASK bool depends on GCC_PLUGINS && ARM diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening index ded4d7c0d132..364e3f8c6eea 100644 --- a/security/Kconfig.hardening +++ b/security/Kconfig.hardening @@ -266,4 +266,66 @@ config ZERO_CALL_USED_REGS endmenu +choice + prompt "Randomize layout of sensitive kernel structures" + default RANDSTRUCT_FULL if COMPILE_TEST && GCC_PLUGINS + default RANDSTRUCT_NONE + help + If you enable this, the layouts of structures that are entirely + function pointers (and have not been manually annotated with + __no_randomize_layout), or structures that have been explicitly + marked with __randomize_layout, will be randomized at compile-time. + This can introduce the requirement of an additional information + exposure vulnerability for exploits targeting these structure + types. + + Enabling this feature will introduce some performance impact, + slightly increase memory usage, and prevent the use of forensic + tools like Volatility against the system (unless the kernel + source tree isn't cleaned after kernel installation). + + The seed used for compilation is located at + scripts/randomize_layout_seed.h. It remains after a "make clean" + to allow for external modules to be compiled with the existing + seed and will be removed by a "make mrproper" or "make distclean". + + config RANDSTRUCT_NONE + bool "Disable structure layout randomization" + help + Build normally: no structure layout randomization. + + config RANDSTRUCT_FULL + bool "Fully randomize structure layout" + depends on GCC_PLUGINS + select MODVERSIONS if MODULES + help + Fully randomize the member layout of sensitive + structures as much as possible, which may have both a + memory size and performance impact. + + config RANDSTRUCT_PERFORMANCE + bool "Limit randomization of structure layout to cache-lines" + depends on GCC_PLUGINS + select MODVERSIONS if MODULES + help + Randomization of sensitive kernel structures will make a + best effort at restricting randomization to cacheline-sized + groups of members. It will further not randomize bitfields + in structures. This reduces the performance hit of RANDSTRUCT + at the cost of weakened randomization. +endchoice + +config RANDSTRUCT + def_bool !RANDSTRUCT_NONE + +config GCC_PLUGIN_RANDSTRUCT + def_bool GCC_PLUGINS && RANDSTRUCT + help + Use GCC plugin to randomize structure layout. + + This plugin was ported from grsecurity/PaX. More + information at: + * https://grsecurity.net/ + * https://pax.grsecurity.net/ + endmenu -- cgit v1.2.3 From 613f4b3ed7902d1dbbc6ade6401e452a63dfbc21 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 3 May 2022 13:55:01 -0700 Subject: randstruct: Split randstruct Makefile and CFLAGS To enable the new Clang randstruct implementation[1], move randstruct into its own Makefile and split the CFLAGS from GCC_PLUGINS_CFLAGS into RANDSTRUCT_CFLAGS. [1] https://reviews.llvm.org/D121556 Cc: linux-hardening@vger.kernel.org Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220503205503.3054173-5-keescook@chromium.org --- Makefile | 1 + arch/arm/vdso/Makefile | 2 +- arch/arm64/kernel/vdso/Makefile | 3 ++- arch/sparc/vdso/Makefile | 3 ++- arch/x86/entry/vdso/Makefile | 3 ++- scripts/Makefile.gcc-plugins | 8 ++------ scripts/Makefile.randstruct | 14 ++++++++++++++ 7 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 scripts/Makefile.randstruct (limited to 'scripts') diff --git a/Makefile b/Makefile index 29e273d3f8cc..91c91fcf3c24 100644 --- a/Makefile +++ b/Makefile @@ -1011,6 +1011,7 @@ include-$(CONFIG_KASAN) += scripts/Makefile.kasan include-$(CONFIG_KCSAN) += scripts/Makefile.kcsan include-$(CONFIG_UBSAN) += scripts/Makefile.ubsan include-$(CONFIG_KCOV) += scripts/Makefile.kcov +include-$(CONFIG_RANDSTRUCT) += scripts/Makefile.randstruct include-$(CONFIG_GCC_PLUGINS) += scripts/Makefile.gcc-plugins include $(addprefix $(srctree)/, $(include-y)) diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile index ec52b776f926..8ca1c9f262a2 100644 --- a/arch/arm/vdso/Makefile +++ b/arch/arm/vdso/Makefile @@ -28,7 +28,7 @@ CPPFLAGS_vdso.lds += -P -C -U$(ARCH) CFLAGS_REMOVE_vdso.o = -pg # Force -O2 to avoid libgcc dependencies -CFLAGS_REMOVE_vgettimeofday.o = -pg -Os $(GCC_PLUGINS_CFLAGS) +CFLAGS_REMOVE_vgettimeofday.o = -pg -Os $(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) ifeq ($(c-gettimeofday-y),) CFLAGS_vgettimeofday.o = -O2 else diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile index 172452f79e46..d9147fba1a0b 100644 --- a/arch/arm64/kernel/vdso/Makefile +++ b/arch/arm64/kernel/vdso/Makefile @@ -32,7 +32,8 @@ ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO # -Wmissing-prototypes and -Wmissing-declarations are removed from # the CFLAGS of vgettimeofday.c to make possible to build the # kernel with CONFIG_WERROR enabled. -CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) $(GCC_PLUGINS_CFLAGS) \ +CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \ + $(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) \ $(CC_FLAGS_LTO) -Wmissing-prototypes -Wmissing-declarations KASAN_SANITIZE := n KCSAN_SANITIZE := n diff --git a/arch/sparc/vdso/Makefile b/arch/sparc/vdso/Makefile index c5e1545bc5cf..77d7b9032158 100644 --- a/arch/sparc/vdso/Makefile +++ b/arch/sparc/vdso/Makefile @@ -58,7 +58,7 @@ CFL := $(PROFILING) -mcmodel=medlow -fPIC -O2 -fasynchronous-unwind-tables -m64 SPARC_REG_CFLAGS = -ffixed-g4 -ffixed-g5 -fcall-used-g5 -fcall-used-g7 -$(vobjs): KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS) $(SPARC_REG_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) +$(vobjs): KBUILD_CFLAGS := $(filter-out $(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) $(SPARC_REG_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) # # vDSO code runs in userspace and -pg doesn't help with profiling anyway. @@ -88,6 +88,7 @@ $(obj)/vdso32.so.dbg: asflags-$(CONFIG_SPARC64) += -m32 KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS)) KBUILD_CFLAGS_32 := $(filter-out -mcmodel=medlow,$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32)) +KBUILD_CFLAGS_32 := $(filter-out $(RANDSTRUCT_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(SPARC_REG_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 += -m32 -msoft-float -fpic diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index 693f8b9031fb..c2a8b76ae0bc 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -91,7 +91,7 @@ ifneq ($(RETPOLINE_VDSO_CFLAGS),) endif endif -$(vobjs): KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO) $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) +$(vobjs): KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO) $(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) # # vDSO code runs in userspace and -pg doesn't help with profiling anyway. @@ -148,6 +148,7 @@ KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS)) KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32)) +KBUILD_CFLAGS_32 := $(filter-out $(RANDSTRUCT_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS_32)) diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 827c47ce5c73..692d64a70542 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -22,12 +22,6 @@ export DISABLE_STRUCTLEAK_PLUGIN gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) \ += -DSTRUCTLEAK_PLUGIN -gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so -gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) \ - += -DRANDSTRUCT -gcc-plugin-cflags-$(CONFIG_RANDSTRUCT_PERFORMANCE) \ - += -fplugin-arg-randomize_layout_plugin-performance-mode - gcc-plugin-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak_plugin.so gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ += -DSTACKLEAK_PLUGIN @@ -60,6 +54,8 @@ KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) # be included in GCC_PLUGIN so they can get built. gcc-plugin-external-$(CONFIG_GCC_PLUGIN_SANCOV) \ += sancov_plugin.so +gcc-plugin-external-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) \ + += randomize_layout_plugin.so # All enabled GCC plugins are collected here for building in # scripts/gcc-scripts/Makefile. diff --git a/scripts/Makefile.randstruct b/scripts/Makefile.randstruct new file mode 100644 index 000000000000..4d741e6db554 --- /dev/null +++ b/scripts/Makefile.randstruct @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 + +randstruct-cflags-y += -DRANDSTRUCT + +ifdef CONFIG_GCC_PLUGIN_RANDSTRUCT +randstruct-cflags-y \ + += -fplugin=$(objtree)/scripts/gcc-plugins/randomize_layout_plugin.so +randstruct-cflags-$(CONFIG_RANDSTRUCT_PERFORMANCE) \ + += -fplugin-arg-randomize_layout_plugin-performance-mode +endif + +export RANDSTRUCT_CFLAGS := $(randstruct-cflags-y) + +KBUILD_CFLAGS += $(RANDSTRUCT_CFLAGS) -- cgit v1.2.3 From be2b34fa9be31c60a95989f984c9a5d40cd781b6 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 3 May 2022 13:55:02 -0700 Subject: randstruct: Move seed generation into scripts/basic/ To enable Clang randstruct support, move the structure layout randomization seed generation out of scripts/gcc-plugins/ into scripts/basic/ so it happens early enough that it can be used by either compiler implementation. The gcc-plugin still builds its own header file, but now does so from the common "randstruct.seed" file. Cc: linux-hardening@vger.kernel.org Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220503205503.3054173-6-keescook@chromium.org --- Documentation/dontdiff | 1 + Documentation/kbuild/reproducible-builds.rst | 5 +++-- include/linux/vermagic.h | 2 +- scripts/basic/.gitignore | 1 + scripts/basic/Makefile | 11 +++++++++++ scripts/gcc-plugins/Makefile | 15 ++++++++++----- scripts/gcc-plugins/gen-random-seed.sh | 9 --------- scripts/gen-randstruct-seed.sh | 7 +++++++ security/Kconfig.hardening | 9 +++++---- 9 files changed, 39 insertions(+), 21 deletions(-) delete mode 100755 scripts/gcc-plugins/gen-random-seed.sh create mode 100755 scripts/gen-randstruct-seed.sh (limited to 'scripts') diff --git a/Documentation/dontdiff b/Documentation/dontdiff index 910b30a2a7d9..352ff53a2306 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff @@ -211,6 +211,7 @@ r200_reg_safe.h r300_reg_safe.h r420_reg_safe.h r600_reg_safe.h +randstruct.seed randomize_layout_hash.h randomize_layout_seed.h recordmcount diff --git a/Documentation/kbuild/reproducible-builds.rst b/Documentation/kbuild/reproducible-builds.rst index 81ff30505d35..071f0151a7a4 100644 --- a/Documentation/kbuild/reproducible-builds.rst +++ b/Documentation/kbuild/reproducible-builds.rst @@ -100,8 +100,9 @@ Structure randomisation ----------------------- If you enable ``CONFIG_RANDSTRUCT``, you will need to pre-generate -the random seed in ``scripts/gcc-plugins/randomize_layout_seed.h`` -so the same value is used in rebuilds. +the random seed in ``scripts/basic/randstruct.seed`` so the same +value is used by each build. See ``scripts/gen-randstruct-seed.sh`` +for details. Debug info conflicts -------------------- diff --git a/include/linux/vermagic.h b/include/linux/vermagic.h index efb51a2da599..a54046bf37e5 100644 --- a/include/linux/vermagic.h +++ b/include/linux/vermagic.h @@ -33,7 +33,7 @@ #define MODULE_VERMAGIC_MODVERSIONS "" #endif #ifdef RANDSTRUCT -#include +#include #define MODULE_RANDSTRUCT "RANDSTRUCT_" RANDSTRUCT_HASHED_SEED #else #define MODULE_RANDSTRUCT diff --git a/scripts/basic/.gitignore b/scripts/basic/.gitignore index 961c91c8a884..07c195f605a1 100644 --- a/scripts/basic/.gitignore +++ b/scripts/basic/.gitignore @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only /fixdep +/randstruct.seed diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile index eeb6a38c5551..dd289a6725ac 100644 --- a/scripts/basic/Makefile +++ b/scripts/basic/Makefile @@ -3,3 +3,14 @@ # fixdep: used to generate dependency information during build process hostprogs-always-y += fixdep + +# randstruct: the seed is needed before building the gcc-plugin or +# before running a Clang kernel build. +gen-randstruct-seed := $(srctree)/scripts/gen-randstruct-seed.sh +quiet_cmd_create_randstruct_seed = GENSEED $@ +cmd_create_randstruct_seed = \ + $(CONFIG_SHELL) $(gen-randstruct-seed) \ + $@ $(objtree)/include/generated/randstruct_hash.h +$(obj)/randstruct.seed: $(gen-randstruct-seed) FORCE + $(call if_changed,create_randstruct_seed) +always-$(CONFIG_RANDSTRUCT) += randstruct.seed diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile index 1952d3bb80c6..148f4639cf09 100644 --- a/scripts/gcc-plugins/Makefile +++ b/scripts/gcc-plugins/Makefile @@ -1,12 +1,17 @@ # SPDX-License-Identifier: GPL-2.0 -$(obj)/randomize_layout_plugin.so: $(objtree)/$(obj)/randomize_layout_seed.h -quiet_cmd_create_randomize_layout_seed = GENSEED $@ +$(obj)/randomize_layout_plugin.so: $(obj)/randomize_layout_seed.h +quiet_cmd_create_randomize_layout_seed = SEEDHDR $@ cmd_create_randomize_layout_seed = \ - $(CONFIG_SHELL) $(srctree)/$(src)/gen-random-seed.sh $@ $(objtree)/include/generated/randomize_layout_hash.h -$(objtree)/$(obj)/randomize_layout_seed.h: FORCE + SEED=$$(cat $(filter-out FORCE,$^) $@; \ + echo ' * This file is automatically generated. Keep it private.' >> $@; \ + echo ' * Exposing this value will expose the layout of randomized structures.' >> $@; \ + echo ' */' >> $@; \ + echo "const char *randstruct_seed = \"$$SEED\";" >> $@ +$(obj)/randomize_layout_seed.h: $(objtree)/scripts/basic/randstruct.seed FORCE $(call if_changed,create_randomize_layout_seed) -targets += randomize_layout_seed.h randomize_layout_hash.h +targets += randomize_layout_seed.h # Build rules for plugins # diff --git a/scripts/gcc-plugins/gen-random-seed.sh b/scripts/gcc-plugins/gen-random-seed.sh deleted file mode 100755 index 68af5cc20a64..000000000000 --- a/scripts/gcc-plugins/gen-random-seed.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 - -if [ ! -f "$1" ]; then - SEED=`od -A n -t x8 -N 32 /dev/urandom | tr -d ' \n'` - echo "const char *randstruct_seed = \"$SEED\";" > "$1" - HASH=`echo -n "$SEED" | sha256sum | cut -d" " -f1 | tr -d ' \n'` - echo "#define RANDSTRUCT_HASHED_SEED \"$HASH\"" > "$2" -fi diff --git a/scripts/gen-randstruct-seed.sh b/scripts/gen-randstruct-seed.sh new file mode 100755 index 000000000000..61017b36c464 --- /dev/null +++ b/scripts/gen-randstruct-seed.sh @@ -0,0 +1,7 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +SEED=$(od -A n -t x8 -N 32 /dev/urandom | tr -d ' \n') +echo "$SEED" > "$1" +HASH=$(echo -n "$SEED" | sha256sum | cut -d" " -f1) +echo "#define RANDSTRUCT_HASHED_SEED \"$HASH\"" > "$2" diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening index 364e3f8c6eea..0277ba578779 100644 --- a/security/Kconfig.hardening +++ b/security/Kconfig.hardening @@ -284,10 +284,11 @@ choice tools like Volatility against the system (unless the kernel source tree isn't cleaned after kernel installation). - The seed used for compilation is located at - scripts/randomize_layout_seed.h. It remains after a "make clean" - to allow for external modules to be compiled with the existing - seed and will be removed by a "make mrproper" or "make distclean". + The seed used for compilation is in scripts/basic/randomize.seed. + It remains after a "make clean" to allow for external modules to + be compiled with the existing seed and will be removed by a + "make mrproper" or "make distclean". This file should not be made + public, or the structure layout can be determined. config RANDSTRUCT_NONE bool "Disable structure layout randomization" -- cgit v1.2.3 From 035f7f87b7295a342577aebd7b5b451f1e2a353c Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 3 May 2022 13:55:03 -0700 Subject: randstruct: Enable Clang support Clang 15 will support randstruct via the -frandomize-layout-seed-file=... option. Update the Kconfig and Makefile to recognize this feature. Cc: Masahiro Yamada Cc: linux-kbuild@vger.kernel.org Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220503205503.3054173-7-keescook@chromium.org --- scripts/Makefile.randstruct | 3 +++ security/Kconfig.hardening | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.randstruct b/scripts/Makefile.randstruct index 4d741e6db554..24e283e89893 100644 --- a/scripts/Makefile.randstruct +++ b/scripts/Makefile.randstruct @@ -7,6 +7,9 @@ randstruct-cflags-y \ += -fplugin=$(objtree)/scripts/gcc-plugins/randomize_layout_plugin.so randstruct-cflags-$(CONFIG_RANDSTRUCT_PERFORMANCE) \ += -fplugin-arg-randomize_layout_plugin-performance-mode +else +randstruct-cflags-y \ + += -frandomize-layout-seed-file=$(objtree)/scripts/basic/randstruct.seed endif export RANDSTRUCT_CFLAGS := $(randstruct-cflags-y) diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening index 0277ba578779..bd2aabb2c60f 100644 --- a/security/Kconfig.hardening +++ b/security/Kconfig.hardening @@ -266,9 +266,12 @@ config ZERO_CALL_USED_REGS endmenu +config CC_HAS_RANDSTRUCT + def_bool $(cc-option,-frandomize-layout-seed-file=/dev/null) + choice prompt "Randomize layout of sensitive kernel structures" - default RANDSTRUCT_FULL if COMPILE_TEST && GCC_PLUGINS + default RANDSTRUCT_FULL if COMPILE_TEST && (GCC_PLUGINS || CC_HAS_RANDSTRUCT) default RANDSTRUCT_NONE help If you enable this, the layouts of structures that are entirely @@ -297,13 +300,20 @@ choice config RANDSTRUCT_FULL bool "Fully randomize structure layout" - depends on GCC_PLUGINS + depends on CC_HAS_RANDSTRUCT || GCC_PLUGINS select MODVERSIONS if MODULES help Fully randomize the member layout of sensitive structures as much as possible, which may have both a memory size and performance impact. + One difference between the Clang and GCC plugin + implementations is the handling of bitfields. The GCC + plugin treats them as fully separate variables, + introducing sometimes significant padding. Clang tries + to keep adjacent bitfields together, but with their bit + ordering randomized. + config RANDSTRUCT_PERFORMANCE bool "Limit randomization of structure layout to cache-lines" depends on GCC_PLUGINS -- cgit v1.2.3 From 61f60bac8c05f8ecd2ae2a6360520b91a45be9a2 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 10 May 2022 16:25:54 -0700 Subject: gcc-plugins: Change all version strings match kernel It's not meaningful for the GCC plugins to track their versions separately from the rest of the kernel. Switch all versions to the kernel version. Fix mismatched indenting while we're at it. Cc: linux-hardening@vger.kernel.org Signed-off-by: Kees Cook --- scripts/gcc-plugins/Makefile | 9 +++++---- scripts/gcc-plugins/latent_entropy_plugin.c | 2 +- scripts/gcc-plugins/randomize_layout_plugin.c | 2 +- scripts/gcc-plugins/sancov_plugin.c | 2 +- scripts/gcc-plugins/stackleak_plugin.c | 2 +- scripts/gcc-plugins/structleak_plugin.c | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile index 148f4639cf09..6f0aecad5d67 100644 --- a/scripts/gcc-plugins/Makefile +++ b/scripts/gcc-plugins/Makefile @@ -28,10 +28,11 @@ GCC_PLUGINS_DIR = $(shell $(CC) -print-file-name=plugin) plugin_cxxflags = -Wp,-MMD,$(depfile) $(KBUILD_HOSTCXXFLAGS) -fPIC \ -include $(srctree)/include/linux/compiler-version.h \ - -I $(GCC_PLUGINS_DIR)/include -I $(obj) -std=gnu++11 \ - -fno-rtti -fno-exceptions -fasynchronous-unwind-tables \ - -ggdb -Wno-narrowing -Wno-unused-variable \ - -Wno-format-diag + -include $(objtree)/include/generated/utsrelease.h \ + -I $(GCC_PLUGINS_DIR)/include -I $(obj) -std=gnu++11 \ + -fno-rtti -fno-exceptions -fasynchronous-unwind-tables \ + -ggdb -Wno-narrowing -Wno-unused-variable \ + -Wno-format-diag plugin_ldflags = -shared diff --git a/scripts/gcc-plugins/latent_entropy_plugin.c b/scripts/gcc-plugins/latent_entropy_plugin.c index 8425da41de0d..5d415b2572a8 100644 --- a/scripts/gcc-plugins/latent_entropy_plugin.c +++ b/scripts/gcc-plugins/latent_entropy_plugin.c @@ -82,7 +82,7 @@ __visible int plugin_is_GPL_compatible; static GTY(()) tree latent_entropy_decl; static struct plugin_info latent_entropy_plugin_info = { - .version = "201606141920vanilla", + .version = UTS_RELEASE, .help = "disable\tturn off latent entropy instrumentation\n", }; diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index c2ec81b68505..19214e573137 100644 --- a/scripts/gcc-plugins/randomize_layout_plugin.c +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -34,7 +34,7 @@ __visible int plugin_is_GPL_compatible; static int performance_mode; static struct plugin_info randomize_layout_plugin_info = { - .version = "201402201816vanilla", + .version = UTS_RELEASE, .help = "disable\t\t\tdo not activate plugin\n" "performance-mode\tenable cacheline-aware layout randomization\n" }; diff --git a/scripts/gcc-plugins/sancov_plugin.c b/scripts/gcc-plugins/sancov_plugin.c index 23bd023a283b..f3d629555b84 100644 --- a/scripts/gcc-plugins/sancov_plugin.c +++ b/scripts/gcc-plugins/sancov_plugin.c @@ -26,7 +26,7 @@ __visible int plugin_is_GPL_compatible; tree sancov_fndecl; static struct plugin_info sancov_plugin_info = { - .version = "20160402", + .version = UTS_RELEASE, .help = "sancov plugin\n", }; diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c index 42f0252ee2a4..de817d54b8af 100644 --- a/scripts/gcc-plugins/stackleak_plugin.c +++ b/scripts/gcc-plugins/stackleak_plugin.c @@ -44,7 +44,7 @@ static bool verbose = false; static GTY(()) tree track_function_decl; static struct plugin_info stackleak_plugin_info = { - .version = "201707101337", + .version = UTS_RELEASE, .help = "track-min-size=nn\ttrack stack for functions with a stack frame size >= nn bytes\n" "arch=target_arch\tspecify target build arch\n" "disable\t\tdo not activate the plugin\n" diff --git a/scripts/gcc-plugins/structleak_plugin.c b/scripts/gcc-plugins/structleak_plugin.c index 74e319288389..86b608a24ec0 100644 --- a/scripts/gcc-plugins/structleak_plugin.c +++ b/scripts/gcc-plugins/structleak_plugin.c @@ -37,7 +37,7 @@ __visible int plugin_is_GPL_compatible; static struct plugin_info structleak_plugin_info = { - .version = "20190125vanilla", + .version = UTS_RELEASE, .help = "disable\tdo not activate plugin\n" "byref\tinit structs passed by reference\n" "byref-all\tinit anything passed by reference\n" -- cgit v1.2.3 From f774f5bb87d132b48bc4a99598c45f35121ac054 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 3 May 2022 11:47:16 +0900 Subject: kbuild: factor out the common installation code into scripts/install.sh Many architectures have similar install.sh scripts. The first half is really generic; it verifies that the kernel image and System.map exist, then executes ~/bin/${INSTALLKERNEL} or /sbin/${INSTALLKERNEL} if available. The second half is kind of arch-specific; it copies the kernel image and System.map to the destination, but the code is slightly different. Factor out the generic part into scripts/install.sh. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- Makefile | 3 ++- arch/arm/Makefile | 4 ++-- arch/arm/boot/install.sh | 21 --------------------- arch/arm64/Makefile | 6 ++---- arch/arm64/boot/install.sh | 21 --------------------- arch/ia64/Makefile | 3 ++- arch/ia64/install.sh | 10 ---------- arch/m68k/Makefile | 3 ++- arch/m68k/install.sh | 22 ---------------------- arch/nios2/Makefile | 3 +-- arch/nios2/boot/install.sh | 22 ---------------------- arch/parisc/Makefile | 11 +++++------ arch/parisc/install.sh | 28 ---------------------------- arch/powerpc/Makefile | 3 +-- arch/powerpc/boot/install.sh | 23 ----------------------- arch/riscv/Makefile | 7 +++---- arch/riscv/boot/install.sh | 21 --------------------- arch/s390/Makefile | 3 +-- arch/s390/boot/install.sh | 6 ------ arch/sparc/Makefile | 3 +-- arch/sparc/boot/install.sh | 22 ---------------------- arch/x86/Makefile | 3 +-- arch/x86/boot/install.sh | 22 ---------------------- scripts/install.sh | 40 ++++++++++++++++++++++++++++++++++++++++ 24 files changed, 63 insertions(+), 247 deletions(-) mode change 100644 => 100755 arch/arm/boot/install.sh mode change 100644 => 100755 arch/arm64/boot/install.sh mode change 100644 => 100755 arch/ia64/install.sh mode change 100644 => 100755 arch/m68k/install.sh mode change 100644 => 100755 arch/nios2/boot/install.sh mode change 100644 => 100755 arch/parisc/install.sh mode change 100644 => 100755 arch/powerpc/boot/install.sh mode change 100644 => 100755 arch/riscv/boot/install.sh mode change 100644 => 100755 arch/s390/boot/install.sh mode change 100644 => 100755 arch/sparc/boot/install.sh mode change 100644 => 100755 arch/x86/boot/install.sh create mode 100755 scripts/install.sh (limited to 'scripts') diff --git a/Makefile b/Makefile index 9a60f732bb3c..154c32af8805 100644 --- a/Makefile +++ b/Makefile @@ -1298,7 +1298,8 @@ scripts_unifdef: scripts_basic # to this Makefile to build and install external modules. # Cancel sub_make_done so that options such as M=, V=, etc. are parsed. -install: sub_make_done := +quiet_cmd_install = INSTALL $(INSTALL_PATH) + cmd_install = unset sub_make_done; $(srctree)/scripts/install.sh # --------------------------------------------------------------------------- # Tools diff --git a/arch/arm/Makefile b/arch/arm/Makefile index a2391b8de5a5..187f4b2c5c73 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -318,9 +318,9 @@ $(BOOT_TARGETS): vmlinux $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ @$(kecho) ' Kernel: $(boot)/$@ is ready' +$(INSTALL_TARGETS): KBUILD_IMAGE = $(boot)/$(patsubst %install,%Image,$@) $(INSTALL_TARGETS): - $(CONFIG_SHELL) $(srctree)/$(boot)/install.sh "$(KERNELRELEASE)" \ - $(boot)/$(patsubst %install,%Image,$@) System.map "$(INSTALL_PATH)" + $(call cmd,install) PHONY += vdso_install vdso_install: diff --git a/arch/arm/boot/install.sh b/arch/arm/boot/install.sh old mode 100644 new mode 100755 index 2a45092a40e3..9ec11fac7d8d --- a/arch/arm/boot/install.sh +++ b/arch/arm/boot/install.sh @@ -1,7 +1,5 @@ #!/bin/sh # -# arch/arm/boot/install.sh -# # This file is subject to the terms and conditions of the GNU General Public # License. See the file "COPYING" in the main directory of this archive # for more details. @@ -18,25 +16,6 @@ # $2 - kernel image file # $3 - kernel map file # $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist -verify "$2" -verify "$3" - -# User may have a custom install script -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi if [ "$(basename $2)" = "zImage" ]; then # Compressed install diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 2f1de88651e6..6d9d4a58b898 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -162,11 +162,9 @@ Image: vmlinux Image.%: Image $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ -install: install-image := Image -zinstall: install-image := Image.gz +install: KBUILD_IMAGE := $(boot)/Image install zinstall: - $(CONFIG_SHELL) $(srctree)/$(boot)/install.sh $(KERNELRELEASE) \ - $(boot)/$(install-image) System.map "$(INSTALL_PATH)" + $(call cmd,install) PHONY += vdso_install vdso_install: diff --git a/arch/arm64/boot/install.sh b/arch/arm64/boot/install.sh old mode 100644 new mode 100755 index d91e1f022573..7399d706967a --- a/arch/arm64/boot/install.sh +++ b/arch/arm64/boot/install.sh @@ -1,7 +1,5 @@ #!/bin/sh # -# arch/arm64/boot/install.sh -# # This file is subject to the terms and conditions of the GNU General Public # License. See the file "COPYING" in the main directory of this archive # for more details. @@ -18,25 +16,6 @@ # $2 - kernel image file # $3 - kernel map file # $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist -verify "$2" -verify "$3" - -# User may have a custom install script -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi if [ "$(basename $2)" = "Image.gz" ]; then # Compressed install diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 6c4bfa54b703..e55c2f138656 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -72,8 +72,9 @@ archheaders: CLEAN_FILES += vmlinux.gz +install: KBUILD_IMAGE := vmlinux.gz install: - sh $(srctree)/arch/ia64/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)" + $(call cmd,install) define archhelp echo '* compressed - Build compressed kernel image' diff --git a/arch/ia64/install.sh b/arch/ia64/install.sh old mode 100644 new mode 100755 index 0e932f5dcd1a..2d4b66a9f362 --- a/arch/ia64/install.sh +++ b/arch/ia64/install.sh @@ -1,7 +1,5 @@ #!/bin/sh # -# arch/ia64/install.sh -# # This file is subject to the terms and conditions of the GNU General Public # License. See the file "COPYING" in the main directory of this archive # for more details. @@ -17,14 +15,6 @@ # $2 - kernel image file # $3 - kernel map file # $4 - default install path (blank if root directory) -# - -# User may have a custom install script - -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - -# Default install - same as make zlilo if [ -f $4/vmlinuz ]; then mv $4/vmlinuz $4/vmlinuz.old diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index 740fc97b9c0f..e358605b70ba 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile @@ -138,5 +138,6 @@ CLEAN_FILES += vmlinux.gz vmlinux.bz2 archheaders: $(Q)$(MAKE) $(build)=arch/m68k/kernel/syscalls all +install: KBUILD_IMAGE := vmlinux.gz install: - sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)" + $(call cmd,install) diff --git a/arch/m68k/install.sh b/arch/m68k/install.sh old mode 100644 new mode 100755 index 57d640d4382c..af65e16e5147 --- a/arch/m68k/install.sh +++ b/arch/m68k/install.sh @@ -15,28 +15,6 @@ # $2 - kernel image file # $3 - kernel map file # $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist -verify "$2" -verify "$3" - -# User may have a custom install script - -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - -# Default install - same as make zlilo if [ -f $4/vmlinuz ]; then mv $4/vmlinuz $4/vmlinuz.old diff --git a/arch/nios2/Makefile b/arch/nios2/Makefile index 02d678559066..d6a7499b814c 100644 --- a/arch/nios2/Makefile +++ b/arch/nios2/Makefile @@ -56,8 +56,7 @@ $(BOOT_TARGETS): vmlinux $(Q)$(MAKE) $(build)=$(nios2-boot) $(nios2-boot)/$@ install: - sh $(srctree)/$(nios2-boot)/install.sh $(KERNELRELEASE) \ - $(KBUILD_IMAGE) System.map "$(INSTALL_PATH)" + $(call cmd,install) define archhelp echo '* vmImage - Kernel-only image for U-Boot ($(KBUILD_IMAGE))' diff --git a/arch/nios2/boot/install.sh b/arch/nios2/boot/install.sh old mode 100644 new mode 100755 index 3cb3f468bc51..34a2feec42c8 --- a/arch/nios2/boot/install.sh +++ b/arch/nios2/boot/install.sh @@ -15,28 +15,6 @@ # $2 - kernel image file # $3 - kernel map file # $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist -verify "$2" -verify "$3" - -# User may have a custom install script - -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - -# Default install - same as make zlilo if [ -f $4/vmlinuz ]; then mv $4/vmlinuz $4/vmlinuz.old diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 7583fc39ab2d..aca1710fd658 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -184,12 +184,11 @@ vdso_install: $(Q)$(MAKE) $(build)=arch/parisc/kernel/vdso $@ $(if $(CONFIG_COMPAT_VDSO), \ $(Q)$(MAKE) $(build)=arch/parisc/kernel/vdso32 $@) -install: - $(CONFIG_SHELL) $(srctree)/arch/parisc/install.sh \ - $(KERNELRELEASE) vmlinux System.map "$(INSTALL_PATH)" -zinstall: - $(CONFIG_SHELL) $(srctree)/arch/parisc/install.sh \ - $(KERNELRELEASE) vmlinuz System.map "$(INSTALL_PATH)" + +install: KBUILD_IMAGE := vmlinux +zinstall: KBUILD_IMAGE := vmlinuz +install zinstall: + $(call cmd,install) CLEAN_FILES += lifimage MRPROPER_FILES += palo.conf diff --git a/arch/parisc/install.sh b/arch/parisc/install.sh old mode 100644 new mode 100755 index 70d3cffb0251..933d031c249a --- a/arch/parisc/install.sh +++ b/arch/parisc/install.sh @@ -1,7 +1,5 @@ #!/bin/sh # -# arch/parisc/install.sh, derived from arch/i386/boot/install.sh -# # This file is subject to the terms and conditions of the GNU General Public # License. See the file "COPYING" in the main directory of this archive # for more details. @@ -17,32 +15,6 @@ # $2 - kernel image file # $3 - kernel map file # $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist - -verify "$2" -verify "$3" - -# User may have a custom install script - -if [ -n "${INSTALLKERNEL}" ]; then - if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi - if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - if [ -x /usr/sbin/${INSTALLKERNEL} ]; then exec /usr/sbin/${INSTALLKERNEL} "$@"; fi -fi - -# Default install if [ "$(basename $2)" = "vmlinuz" ]; then # Compressed install diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index eb541e730d3c..45a9caa37b4e 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -408,8 +408,7 @@ endef PHONY += install install: - sh -x $(srctree)/$(boot)/install.sh "$(KERNELRELEASE)" vmlinux \ - System.map "$(INSTALL_PATH)" + $(call cmd,install) ifeq ($(KBUILD_EXTMOD),) # We need to generate vdso-offsets.h before compiling certain files in kernel/. diff --git a/arch/powerpc/boot/install.sh b/arch/powerpc/boot/install.sh old mode 100644 new mode 100755 index 14473150ddb4..461902c8a46d --- a/arch/powerpc/boot/install.sh +++ b/arch/powerpc/boot/install.sh @@ -15,32 +15,9 @@ # $2 - kernel image file # $3 - kernel map file # $4 - default install path (blank if root directory) -# -# Bail with error code if anything goes wrong set -e -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist -verify "$2" -verify "$3" - -# User may have a custom install script - -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - -# Default install - # this should work for both the pSeries zImage and the iSeries vmlinux.sm image_name=`basename $2` diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 7d81102cffd4..2b93ca9f4fc3 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -139,11 +139,10 @@ $(BOOT_TARGETS): vmlinux Image.%: Image $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ -install: install-image = Image -zinstall: install-image = Image.gz +install: KBUILD_IMAGE := $(boot)/Image +zinstall: KBUILD_IMAGE := $(boot)/Image.gz install zinstall: - $(CONFIG_SHELL) $(srctree)/$(boot)/install.sh $(KERNELRELEASE) \ - $(boot)/$(install-image) System.map "$(INSTALL_PATH)" + $(call cmd,install) PHONY += rv32_randconfig rv32_randconfig: diff --git a/arch/riscv/boot/install.sh b/arch/riscv/boot/install.sh old mode 100644 new mode 100755 index 18c39159c0ff..4c63f3f0643d --- a/arch/riscv/boot/install.sh +++ b/arch/riscv/boot/install.sh @@ -1,7 +1,5 @@ #!/bin/sh # -# arch/riscv/boot/install.sh -# # This file is subject to the terms and conditions of the GNU General Public # License. See the file "COPYING" in the main directory of this archive # for more details. @@ -18,25 +16,6 @@ # $2 - kernel image file # $3 - kernel map file # $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist -verify "$2" -verify "$3" - -# User may have a custom install script -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi if [ "$(basename $2)" = "Image.gz" ]; then # Compressed install diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 7a65bca1e5af..cc2425539ef0 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -128,8 +128,7 @@ all: bzImage KBUILD_IMAGE := $(boot)/bzImage install: - sh -x $(srctree)/$(boot)/install.sh $(KERNELRELEASE) $(KBUILD_IMAGE) \ - System.map "$(INSTALL_PATH)" + $(call cmd,install) bzImage: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ diff --git a/arch/s390/boot/install.sh b/arch/s390/boot/install.sh old mode 100644 new mode 100755 index 515b27a996b3..616ba1660f08 --- a/arch/s390/boot/install.sh +++ b/arch/s390/boot/install.sh @@ -14,12 +14,6 @@ # $2 - kernel image file # $3 - kernel map file # $4 - default install path (blank if root directory) -# - -# User may have a custom install script - -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi echo "Warning: '${INSTALLKERNEL}' command not available - additional " \ "bootloader config required" >&2 diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index c7008bbebc4c..fe58a410b4ce 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile @@ -72,8 +72,7 @@ image zImage uImage tftpboot.img vmlinux.aout: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ install: - sh $(srctree)/$(boot)/install.sh $(KERNELRELEASE) $(KBUILD_IMAGE) \ - System.map "$(INSTALL_PATH)" + $(call cmd,install) archheaders: $(Q)$(MAKE) $(build)=arch/sparc/kernel/syscalls all diff --git a/arch/sparc/boot/install.sh b/arch/sparc/boot/install.sh old mode 100644 new mode 100755 index b32851eae693..4f130f3f30d6 --- a/arch/sparc/boot/install.sh +++ b/arch/sparc/boot/install.sh @@ -15,28 +15,6 @@ # $2 - kernel image file # $3 - kernel map file # $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist -verify "$2" -verify "$3" - -# User may have a custom install script - -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - -# Default install - same as make zlilo if [ -f $4/vmlinuz ]; then mv $4/vmlinuz $4/vmlinuz.old diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 63d50f65b828..5e1f21aae12b 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -271,8 +271,7 @@ $(BOOT_TARGETS): vmlinux PHONY += install install: - $(CONFIG_SHELL) $(srctree)/$(boot)/install.sh $(KERNELRELEASE) \ - $(KBUILD_IMAGE) System.map "$(INSTALL_PATH)" + $(call cmd,install) PHONY += vdso_install vdso_install: diff --git a/arch/x86/boot/install.sh b/arch/x86/boot/install.sh old mode 100644 new mode 100755 index d13ec1c38640..0849f4b42745 --- a/arch/x86/boot/install.sh +++ b/arch/x86/boot/install.sh @@ -15,28 +15,6 @@ # $2 - kernel image file # $3 - kernel map file # $4 - default install path (blank if root directory) -# - -verify () { - if [ ! -f "$1" ]; then - echo "" 1>&2 - echo " *** Missing file: $1" 1>&2 - echo ' *** You need to run "make" before "make install".' 1>&2 - echo "" 1>&2 - exit 1 - fi -} - -# Make sure the files actually exist -verify "$2" -verify "$3" - -# User may have a custom install script - -if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi - -# Default install - same as make zlilo if [ -f $4/vmlinuz ]; then mv $4/vmlinuz $4/vmlinuz.old diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100755 index 000000000000..9bb0fb44f04a --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 1995 by Linus Torvalds +# +# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin +# Common code factored out by Masahiro Yamada + +set -e + +# Make sure the files actually exist +for file in "${KBUILD_IMAGE}" System.map +do + if [ ! -f "${file}" ]; then + echo >&2 + echo >&2 " *** Missing file: ${file}" + echo >&2 ' *** You need to run "make" before "make install".' + echo >&2 + exit 1 + fi +done + +# User/arch may have a custom install script +for file in "${HOME}/bin/${INSTALLKERNEL}" \ + "/sbin/${INSTALLKERNEL}" \ + "${srctree}/arch/${SRCARCH}/install.sh" \ + "${srctree}/arch/${SRCARCH}/boot/install.sh" +do + if [ ! -x "${file}" ]; then + continue + fi + + # installkernel(8) says the parameters are like follows: + # + # installkernel version zImage System.map [directory] + exec "${file}" "${KERNELRELEASE}" "${KBUILD_IMAGE}" System.map "${INSTALL_PATH}" +done + +echo "No install script found" >&2 +exit 1 -- cgit v1.2.3 From 5d53508d1bae79a84840bcfd3c45094d2081d6d2 Mon Sep 17 00:00:00 2001 From: Reza Arbab Date: Wed, 4 May 2022 16:27:14 -0500 Subject: scripts/prune-kernel: Use kernel-install if available If the new-kernel-pkg utility isn't present, try using kernel-install. This is what the %preun scriptlet in scripts/package/mkspec does too. Signed-off-by: Reza Arbab Signed-off-by: Masahiro Yamada --- scripts/prune-kernel | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/prune-kernel b/scripts/prune-kernel index e8aa940bc0a9..dadfd0e47f89 100755 --- a/scripts/prune-kernel +++ b/scripts/prune-kernel @@ -16,6 +16,10 @@ do rm -f "/boot/initramfs-$f.img" "/boot/System.map-$f" rm -f "/boot/vmlinuz-$f" "/boot/config-$f" rm -rf "/lib/modules/$f" - new-kernel-pkg --remove $f + if [ -x "$(command -v new-kernel-pkg)" ]; then + new-kernel-pkg --remove $f + elif [ -x "$(command -v kernel-install)" ]; then + kernel-install remove $f + fi fi done -- cgit v1.2.3 From 7fedac9698b3a56571064eb3b23063f09c93eb94 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 May 2022 16:22:32 +0900 Subject: modpost: merge add_{intree_flag,retpoline,staging_flag} to add_header add_intree_flag(), add_retpoline(), and add_staging_flag() are small enough to be merged into add_header(). Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Tested-by: Nathan Chancellor --- scripts/mod/modpost.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 085abe541280..8cc386346298 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2243,25 +2243,17 @@ static void add_header(struct buffer *b, struct module *mod) "#endif\n"); buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n"); buf_printf(b, "};\n"); -} -static void add_intree_flag(struct buffer *b, int is_intree) -{ - if (is_intree) + if (!external_module) buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n"); -} -/* Cannot check for assembler */ -static void add_retpoline(struct buffer *b) -{ - buf_printf(b, "\n#ifdef CONFIG_RETPOLINE\n"); - buf_printf(b, "MODULE_INFO(retpoline, \"Y\");\n"); - buf_printf(b, "#endif\n"); -} + buf_printf(b, + "\n" + "#ifdef CONFIG_RETPOLINE\n" + "MODULE_INFO(retpoline, \"Y\");\n" + "#endif\n"); -static void add_staging_flag(struct buffer *b, const char *name) -{ - if (strstarts(name, "drivers/staging")) + if (strstarts(mod->name, "drivers/staging")) buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); } @@ -2577,9 +2569,6 @@ int main(int argc, char **argv) check_exports(mod); add_header(&buf, mod); - add_intree_flag(&buf, !external_module); - add_retpoline(&buf); - add_staging_flag(&buf, mod->name); add_versions(&buf, mod); add_depends(&buf, mod); add_moddevtable(&buf, mod); -- cgit v1.2.3 From a44abaca0e196cfeef2374ed663b97daa1ad112a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 May 2022 16:22:33 +0900 Subject: modpost: move *.mod.c generation to write_mod_c_files() A later commit will add more code to this list_for_each_entry loop. Before that, move the loop body into a separate helper function. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Tested-by: Nathan Chancellor --- scripts/mod/modpost.c | 56 ++++++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 25 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 8cc386346298..d9efbd5b31a6 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2390,6 +2390,34 @@ static void write_if_changed(struct buffer *b, const char *fname) write_buf(b, fname); } +/* do sanity checks, and generate *.mod.c file */ +static void write_mod_c_file(struct module *mod) +{ + struct buffer buf = { }; + char fname[PATH_MAX]; + int ret; + + check_modname_len(mod); + check_exports(mod); + + add_header(&buf, mod); + add_versions(&buf, mod); + add_depends(&buf, mod); + add_moddevtable(&buf, mod); + add_srcversion(&buf, mod); + + ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name); + if (ret >= sizeof(fname)) { + error("%s: too long path was truncated\n", fname); + goto free; + } + + write_if_changed(&buf, fname); + +free: + free(buf.p); +} + /* parse Module.symvers file. line format: * 0x12345678symbolmoduleexportnamespace **/ @@ -2494,7 +2522,6 @@ struct dump_list { int main(int argc, char **argv) { struct module *mod; - struct buffer buf = { }; char *missing_namespace_deps = NULL; char *dump_write = NULL, *files_source = NULL; int opt; @@ -2557,30 +2584,11 @@ int main(int argc, char **argv) read_symbols_from_files(files_source); list_for_each_entry(mod, &modules, list) { - char fname[PATH_MAX]; - int ret; - - if (mod->is_vmlinux || mod->from_dump) - continue; - - buf.pos = 0; - - check_modname_len(mod); - check_exports(mod); - - add_header(&buf, mod); - add_versions(&buf, mod); - add_depends(&buf, mod); - add_moddevtable(&buf, mod); - add_srcversion(&buf, mod); - - ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name); - if (ret >= sizeof(fname)) { - error("%s: too long path was truncated\n", fname); + if (mod->from_dump) continue; - } - write_if_changed(&buf, fname); + if (!mod->is_vmlinux) + write_mod_c_file(mod); } if (missing_namespace_deps) @@ -2606,7 +2614,5 @@ int main(int argc, char **argv) warn("suppressed %u unresolved symbol warnings because there were too many)\n", nr_unresolved - MAX_UNRESOLVED_REPORTS); - free(buf.p); - return error_occurred ? 1 : 0; } -- cgit v1.2.3 From e493f472752000968f5b30aac10391288cfbf5b1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 May 2022 16:22:34 +0900 Subject: kbuild: generate a list of objects in vmlinux A *.mod file lists the member objects of a module, but vmlinux does not have such a file. Generate this list to allow modpost to know all the member objects. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Tested-by: Nathan Chancellor --- scripts/link-vmlinux.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'scripts') diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 20f44504a644..eceb3ee7ec06 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -311,6 +311,7 @@ cleanup() rm -f vmlinux.map rm -f vmlinux.o rm -f .vmlinux.d + rm -f .vmlinux.objs } # Use "make V=1" to debug this script @@ -342,6 +343,16 @@ ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1 modpost_link vmlinux.o objtool_link vmlinux.o +# Generate the list of objects in vmlinux +for f in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do + case ${f} in + *.a) + ${AR} t ${f} ;; + *) + echo ${f} ;; + esac +done > .vmlinux.objs + # modpost vmlinux.o to check for section mismatches ${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1 -- cgit v1.2.3 From 78e9e56af3858bf2c52c065daa6c8bee0d72048c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 May 2022 16:22:35 +0900 Subject: kbuild: record symbol versions in *.cmd files When CONFIG_MODVERSIONS=y, the output from genksyms is saved in separate *.symversions files, and will be used much later when CONFIG_LTO_CLANG=y because it is impossible to update LLVM bit code here. This approach is not robust because: - *.symversions may or may not exist. If *.symversions does not exist, we never know if it is missing for legitimate reason (i.e. no EXPORT_SYMBOL) or something bad has happened (for example, the user accidentally deleted it). Once it occurs, it is not self-healing because *.symversions is generated as a side effect. - stale (i.e. invalid) *.symversions might be picked up if an object is generated in a non-ordinary way, and corresponding *.symversions (, which was generated by old builds) just happen to exist. A more robust approach is to save symbol versions in *.cmd files because: - *.cmd always exists (if the object is generated by if_changed rule or friends). Even if the user accidentally deletes it, it will be regenerated in the next build. - *.cmd is always re-generated when the object is updated. This avoid stale version information being picked up. I will remove *.symversions later. Signed-off-by: Masahiro Yamada Tested-by: Nicolas Schier Reviewed-by: Nicolas Schier Tested-by: Nathan Chancellor --- scripts/Makefile.build | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index f6a506318795..a1023868775f 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -171,10 +171,17 @@ ifdef CONFIG_MODVERSIONS # Generate .o.symversions files for each .o with exported symbols, and link these # to the kernel and/or modules at the end. + +genksyms_format_rel_crc := [^_]*__crc_\([^ ]*\) = \.; LONG(\([^)]*\)).* +genksyms_format_normal := __crc_\(.*\) = \(.*\); +genksyms_format := $(if $(CONFIG_MODULE_REL_CRCS),$(genksyms_format_rel_crc),$(genksyms_format_normal)) + gen_symversions = \ if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then \ $(call cmd_gensymtypes_$(1),$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ > $@.symversions; \ + sed -n 's/$(genksyms_format)/$(pound)SYMVER \1 \2/p' $@.symversions \ + >> $(dot-target).cmd; \ else \ rm -f $@.symversions; \ fi -- cgit v1.2.3 From ce79c406a24c3825a2adeaa4668f79f8d5d72e58 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 9 May 2022 04:06:18 +0900 Subject: modpost: remove left-over cross_compile declaration This is a remnant of commit 6543becf26ff ("mod/file2alias: make modalias generation safe for cross compiling"). Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.h | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index cfa127d2bb8f..d9daeff07b83 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -174,7 +174,6 @@ static inline unsigned int get_secindex(const struct elf_info *info, } /* file2alias.c */ -extern unsigned int cross_build; void handle_moddevtable(struct module *mod, struct elf_info *info, Elf_Sym *sym, const char *symname); void add_moddevtable(struct buffer *buf, struct module *mod); -- cgit v1.2.3 From 2a66c3124afd2782015d160f8bad693488ce68de Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 9 May 2022 04:06:19 +0900 Subject: modpost: change the license of EXPORT_SYMBOL to bool type There were more EXPORT_SYMBOL types in the past. The following commits removed unused ones. - f1c3d73e973c ("module: remove EXPORT_SYMBOL_GPL_FUTURE") - 367948220fce ("module: remove EXPORT_UNUSED_SYMBOL*") There are 3 remaining in enum export, but export_unknown does not make any sense because we never expect such a situation like "we do not know how it was exported". If the symbol name starts with "__ksymtab_", but the section name does not start with "___ksymtab+" or "___ksymtab_gpl+", it is not an exported symbol. It occurs when a variable starting with "__ksymtab_" is directly defined: int __ksymtab_foo; Presumably, there is no practical issue for using such a weird variable name (but there is no good reason for doing so, either). Anyway, that is not an exported symbol. Setting export_unknown is not the right thing to do. Do not call sym_add_exported() in this case. With pointless export_unknown removed, the export type finally becomes boolean (either EXPORT_SYMBOL or EXPORT_SYMBOL_GPL). I renamed the field name to is_gpl_only. EXPORT_SYMBOL_GPL sets it true. Only GPL-compatible modules can use it. I removed the orphan comment, "How a symbol is exported", which is unrelated to sec_mismatch_count. It is about enum export. See commit bd5cbcedf446 ("kbuild: export-type enhancement to modpost.c") Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Tested-by: Nathan Chancellor --- scripts/mod/modpost.c | 108 ++++++++++++++------------------------------------ 1 file changed, 30 insertions(+), 78 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index d9efbd5b31a6..a78b75f0eeb0 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -30,7 +30,7 @@ static bool all_versions; static bool external_module; /* Only warn about unresolved symbols */ static bool warn_unresolved; -/* How a symbol is exported */ + static int sec_mismatch_count; static bool sec_mismatch_warn_only = true; /* ignore missing files */ @@ -47,12 +47,6 @@ static bool error_occurred; #define MAX_UNRESOLVED_REPORTS 10 static unsigned int nr_unresolved; -enum export { - export_plain, - export_gpl, - export_unknown -}; - /* In kernel, this size is defined in linux/module.h; * here we use Elf_Addr instead of long for covering cross-compile */ @@ -219,7 +213,7 @@ struct symbol { bool crc_valid; bool weak; bool is_static; /* true if symbol is not global */ - enum export export; /* Type of export */ + bool is_gpl_only; /* exported by EXPORT_SYMBOL_GPL */ char name[]; }; @@ -316,34 +310,6 @@ static void add_namespace(struct list_head *head, const char *namespace) } } -static const struct { - const char *str; - enum export export; -} export_list[] = { - { .str = "EXPORT_SYMBOL", .export = export_plain }, - { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl }, - { .str = "(unknown)", .export = export_unknown }, -}; - - -static const char *export_str(enum export ex) -{ - return export_list[ex].str; -} - -static enum export export_no(const char *s) -{ - int i; - - if (!s) - return export_unknown; - for (i = 0; export_list[i].export != export_unknown; i++) { - if (strcmp(export_list[i].str, s) == 0) - return export_list[i].export; - } - return export_unknown; -} - static void *sym_get_data_by_offset(const struct elf_info *info, unsigned int secindex, unsigned long offset) { @@ -374,18 +340,6 @@ static const char *sec_name(const struct elf_info *info, int secindex) #define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) -static enum export export_from_secname(struct elf_info *elf, unsigned int sec) -{ - const char *secname = sec_name(elf, sec); - - if (strstarts(secname, "___ksymtab+")) - return export_plain; - else if (strstarts(secname, "___ksymtab_gpl+")) - return export_gpl; - else - return export_unknown; -} - static void sym_update_namespace(const char *symname, const char *namespace) { struct symbol *s = find_symbol(symname); @@ -405,7 +359,7 @@ static void sym_update_namespace(const char *symname, const char *namespace) } static struct symbol *sym_add_exported(const char *name, struct module *mod, - enum export export) + bool gpl_only) { struct symbol *s = find_symbol(name); @@ -417,7 +371,7 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod, s = alloc_symbol(name); s->module = mod; - s->export = export; + s->is_gpl_only = gpl_only; list_add_tail(&s->list, &mod->exported_symbols); hash_add_symbol(s); @@ -689,8 +643,6 @@ static void handle_modversion(const struct module *mod, static void handle_symbol(struct module *mod, struct elf_info *info, const Elf_Sym *sym, const char *symname) { - const char *name; - switch (sym->st_shndx) { case SHN_COMMON: if (strstarts(symname, "__gnu_lto_")) { @@ -724,12 +676,15 @@ static void handle_symbol(struct module *mod, struct elf_info *info, default: /* All exported symbols */ if (strstarts(symname, "__ksymtab_")) { - enum export export; + const char *name, *secname; name = symname + strlen("__ksymtab_"); - export = export_from_secname(info, - get_secindex(info, sym)); - sym_add_exported(name, mod, export); + secname = sec_name(info, get_secindex(info, sym)); + + if (strstarts(secname, "___ksymtab_gpl+")) + sym_add_exported(name, mod, true); + else if (strstarts(secname, "___ksymtab+")) + sym_add_exported(name, mod, false); } if (strcmp(symname, "init_module") == 0) mod->has_init = true; @@ -2140,20 +2095,6 @@ void buf_write(struct buffer *buf, const char *s, int len) buf->pos += len; } -static void check_for_gpl_usage(enum export exp, const char *m, const char *s) -{ - switch (exp) { - case export_gpl: - error("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n", - m, s); - break; - case export_plain: - case export_unknown: - /* ignore */ - break; - } -} - static void check_exports(struct module *mod) { struct symbol *s, *exp; @@ -2192,8 +2133,9 @@ static void check_exports(struct module *mod) add_namespace(&mod->missing_namespaces, exp->namespace); } - if (!mod->is_gpl_compatible) - check_for_gpl_usage(exp->export, basename, exp->name); + if (!mod->is_gpl_compatible && exp->is_gpl_only) + error("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n", + basename, exp->name); } } @@ -2437,6 +2379,7 @@ static void read_dump(const char *fname) unsigned int crc; struct module *mod; struct symbol *s; + bool gpl_only; if (!(symname = strchr(line, '\t'))) goto fail; @@ -2454,12 +2397,22 @@ static void read_dump(const char *fname) crc = strtoul(line, &d, 16); if (*symname == '\0' || *modname == '\0' || *d != '\0') goto fail; + + if (!strcmp(export, "EXPORT_SYMBOL_GPL")) { + gpl_only = true; + } else if (!strcmp(export, "EXPORT_SYMBOL")) { + gpl_only = false; + } else { + error("%s: unknown license %s. skip", symname, export); + continue; + } + mod = find_module(modname); if (!mod) { mod = new_module(modname); mod->from_dump = true; } - s = sym_add_exported(symname, mod, export_no(export)); + s = sym_add_exported(symname, mod, gpl_only); s->is_static = false; sym_set_crc(symname, crc); sym_update_namespace(symname, namespace); @@ -2481,9 +2434,9 @@ static void write_dump(const char *fname) if (mod->from_dump) continue; list_for_each_entry(sym, &mod->exported_symbols, list) { - buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n", + buf_printf(&buf, "0x%08x\t%s\t%s\tEXPORT_SYMBOL%s\t%s\n", sym->crc, sym->name, mod->name, - export_str(sym->export), + sym->is_gpl_only ? "_GPL" : "", sym->namespace ?: ""); } } @@ -2604,9 +2557,8 @@ int main(int argc, char **argv) for (s = symbolhash[n]; s; s = s->next) { if (s->is_static) - error("\"%s\" [%s] is a static %s\n", - s->name, s->module->name, - export_str(s->export)); + error("\"%s\" [%s] is a static EXPORT_SYMBOL\n", + s->name, s->module->name); } } -- cgit v1.2.3 From 21e350233b07619dbfc3ce606ff1fc468fce2d82 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 21 Apr 2022 14:56:55 -0700 Subject: scripts: Create objdump-func helper script Add a simple script which disassembles a single function from an object file. Comes in handy for objtool warnings and kernel stack traces. Originally-by: Peter Zijlstra Acked-by: Borislav Petkov Signed-off-by: Josh Poimboeuf Link: https://lore.kernel.org/r/3eb3f091fd6bd9caba50392ceab98ce756804f3b.1650578171.git.jpoimboe@redhat.com --- scripts/objdump-func | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100755 scripts/objdump-func (limited to 'scripts') diff --git a/scripts/objdump-func b/scripts/objdump-func new file mode 100755 index 000000000000..4eb463dd9f52 --- /dev/null +++ b/scripts/objdump-func @@ -0,0 +1,29 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Disassemble a single function. +# +# usage: objdump-func + +set -o errexit +set -o nounset + +OBJDUMP="${CROSS_COMPILE:-}objdump" + +command -v gawk >/dev/null 2>&1 || die "gawk isn't installed" + +usage() { + 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; } }' -- cgit v1.2.3 From 1d1a0e7c5100d332583e20b40aa8c0a8ed3d7849 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 12 May 2022 12:05:27 -0700 Subject: scripts/faddr2line: Fix overlapping text section failures There have been some recent reports of faddr2line failures: $ scripts/faddr2line sound/soundcore.ko sound_devnode+0x5/0x35 bad symbol size: base: 0x0000000000000000 end: 0x0000000000000000 $ ./scripts/faddr2line vmlinux.o enter_from_user_mode+0x24 bad symbol size: base: 0x0000000000005fe0 end: 0x0000000000005fe0 The problem is that faddr2line is based on 'nm', which has a major limitation: it doesn't know how to distinguish between different text sections. So if an offset exists in multiple text sections in the object, it may fail. Rewrite faddr2line to be section-aware, by basing it on readelf. Fixes: 67326666e2d4 ("scripts: add script for translating stack dump function offsets") Reported-by: Kaiwan N Billimoria Reported-by: Peter Zijlstra Signed-off-by: Josh Poimboeuf Link: https://lore.kernel.org/r/29ff99f86e3da965b6e46c1cc2d72ce6528c17c3.1652382321.git.jpoimboe@kernel.org --- scripts/faddr2line | 150 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 97 insertions(+), 53 deletions(-) (limited to 'scripts') diff --git a/scripts/faddr2line b/scripts/faddr2line index 6c6439f69a72..0e6268d59883 100755 --- a/scripts/faddr2line +++ b/scripts/faddr2line @@ -44,17 +44,6 @@ set -o errexit set -o nounset -READELF="${CROSS_COMPILE:-}readelf" -ADDR2LINE="${CROSS_COMPILE:-}addr2line" -SIZE="${CROSS_COMPILE:-}size" -NM="${CROSS_COMPILE:-}nm" - -command -v awk >/dev/null 2>&1 || die "awk isn't installed" -command -v ${READELF} >/dev/null 2>&1 || die "readelf isn't installed" -command -v ${ADDR2LINE} >/dev/null 2>&1 || die "addr2line isn't installed" -command -v ${SIZE} >/dev/null 2>&1 || die "size isn't installed" -command -v ${NM} >/dev/null 2>&1 || die "nm isn't installed" - usage() { echo "usage: faddr2line [--list] ..." >&2 exit 1 @@ -69,6 +58,14 @@ die() { exit 1 } +READELF="${CROSS_COMPILE:-}readelf" +ADDR2LINE="${CROSS_COMPILE:-}addr2line" +AWK="awk" + +command -v ${AWK} >/dev/null 2>&1 || die "${AWK} isn't installed" +command -v ${READELF} >/dev/null 2>&1 || die "${READELF} isn't installed" +command -v ${ADDR2LINE} >/dev/null 2>&1 || die "${ADDR2LINE} isn't installed" + # Try to figure out the source directory prefix so we can remove it from the # addr2line output. HACK ALERT: This assumes that start_kernel() is in # init/main.c! This only works for vmlinux. Otherwise it falls back to @@ -76,7 +73,7 @@ die() { find_dir_prefix() { local objfile=$1 - local start_kernel_addr=$(${READELF} -sW $objfile | awk '$8 == "start_kernel" {printf "0x%s", $2}') + local start_kernel_addr=$(${READELF} --symbols --wide $objfile | ${AWK} '$8 == "start_kernel" {printf "0x%s", $2}') [[ -z $start_kernel_addr ]] && return local file_line=$(${ADDR2LINE} -e $objfile $start_kernel_addr) @@ -97,86 +94,133 @@ __faddr2line() { local dir_prefix=$3 local print_warnings=$4 - local func=${func_addr%+*} + local sym_name=${func_addr%+*} local offset=${func_addr#*+} offset=${offset%/*} - local size= - [[ $func_addr =~ "/" ]] && size=${func_addr#*/} + local user_size= + [[ $func_addr =~ "/" ]] && user_size=${func_addr#*/} - if [[ -z $func ]] || [[ -z $offset ]] || [[ $func = $func_addr ]]; then + if [[ -z $sym_name ]] || [[ -z $offset ]] || [[ $sym_name = $func_addr ]]; then warn "bad func+offset $func_addr" DONE=1 return fi # Go through each of the object's symbols which match the func name. - # In rare cases there might be duplicates. - file_end=$(${SIZE} -Ax $objfile | awk '$1 == ".text" {print $2}') - while read symbol; do - local fields=($symbol) - local sym_base=0x${fields[0]} - local sym_type=${fields[1]} - local sym_end=${fields[3]} - - # calculate the size - local sym_size=$(($sym_end - $sym_base)) + # In rare cases there might be duplicates, in which case we print all + # matches. + while read line; do + local fields=($line) + local sym_addr=0x${fields[1]} + local sym_elf_size=${fields[2]} + local sym_sec=${fields[6]} + + # Get the section size: + local sec_size=$(${READELF} --section-headers --wide $objfile | + sed 's/\[ /\[/' | + ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print "0x" $6; exit }') + + if [[ -z $sec_size ]]; then + warn "bad section size: section: $sym_sec" + DONE=1 + return + fi + + # Calculate the symbol size. + # + # Unfortunately we can't use the ELF size, because kallsyms + # also includes the padding bytes in its size calculation. For + # kallsyms, the size calculation is the distance between the + # symbol and the next symbol in a sorted list. + local sym_size + local cur_sym_addr + local found=0 + while read line; do + local fields=($line) + cur_sym_addr=0x${fields[1]} + local cur_sym_elf_size=${fields[2]} + local cur_sym_name=${fields[7]:-} + + if [[ $cur_sym_addr = $sym_addr ]] && + [[ $cur_sym_elf_size = $sym_elf_size ]] && + [[ $cur_sym_name = $sym_name ]]; then + found=1 + continue + fi + + if [[ $found = 1 ]]; then + sym_size=$(($cur_sym_addr - $sym_addr)) + [[ $sym_size -lt $sym_elf_size ]] && continue; + found=2 + break + fi + done < <(${READELF} --symbols --wide $objfile | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2) + + if [[ $found = 0 ]]; then + warn "can't find symbol: sym_name: $sym_name sym_sec: $sym_sec sym_addr: $sym_addr sym_elf_size: $sym_elf_size" + DONE=1 + return + fi + + # If nothing was found after the symbol, assume it's the last + # symbol in the section. + [[ $found = 1 ]] && sym_size=$(($sec_size - $sym_addr)) + if [[ -z $sym_size ]] || [[ $sym_size -le 0 ]]; then - warn "bad symbol size: base: $sym_base end: $sym_end" + warn "bad symbol size: sym_addr: $sym_addr cur_sym_addr: $cur_sym_addr" DONE=1 return fi + sym_size=0x$(printf %x $sym_size) - # calculate the address - local addr=$(($sym_base + $offset)) + # Calculate the section address from user-supplied offset: + local addr=$(($sym_addr + $offset)) if [[ -z $addr ]] || [[ $addr = 0 ]]; then - warn "bad address: $sym_base + $offset" + warn "bad address: $sym_addr + $offset" DONE=1 return fi addr=0x$(printf %x $addr) - # weed out non-function symbols - if [[ $sym_type != t ]] && [[ $sym_type != T ]]; then - [[ $print_warnings = 1 ]] && - echo "skipping $func address at $addr due to non-function symbol of type '$sym_type'" - continue - fi - - # if the user provided a size, make sure it matches the symbol's size - if [[ -n $size ]] && [[ $size -ne $sym_size ]]; then + # If the user provided a size, make sure it matches the symbol's size: + if [[ -n $user_size ]] && [[ $user_size -ne $sym_size ]]; then [[ $print_warnings = 1 ]] && - echo "skipping $func address at $addr due to size mismatch ($size != $sym_size)" + echo "skipping $sym_name address at $addr due to size mismatch ($user_size != $sym_size)" continue; fi - # make sure the provided offset is within the symbol's range + # Make sure the provided offset is within the symbol's range: if [[ $offset -gt $sym_size ]]; then [[ $print_warnings = 1 ]] && - echo "skipping $func address at $addr due to size mismatch ($offset > $sym_size)" + echo "skipping $sym_name address at $addr due to size mismatch ($offset > $sym_size)" continue fi - # separate multiple entries with a blank line + # In case of duplicates or multiple addresses specified on the + # cmdline, separate multiple entries with a blank line: [[ $FIRST = 0 ]] && echo FIRST=0 - # pass real address to addr2line - echo "$func+$offset/$sym_size:" - local file_lines=$(${ADDR2LINE} -fpie $objfile $addr | sed "s; $dir_prefix\(\./\)*; ;") - [[ -z $file_lines ]] && return + echo "$sym_name+$offset/$sym_size:" + # Pass section address to addr2line and strip absolute paths + # from the output: + local output=$(${ADDR2LINE} -fpie $objfile $addr | sed "s; $dir_prefix\(\./\)*; ;") + [[ -z $output ]] && continue + + # Default output (non --list): if [[ $LIST = 0 ]]; then - echo "$file_lines" | while read -r line + echo "$output" | while read -r line do echo $line done DONE=1; - return + continue fi - # show each line with context - echo "$file_lines" | while read -r line + # For --list, show each line with its corresponding source code: + echo "$output" | while read -r line do echo echo $line @@ -184,12 +228,12 @@ __faddr2line() { n1=$[$n-5] n2=$[$n+5] f=$(echo $line | sed 's/.*at \(.\+\):.*/\1/g') - awk 'NR>=strtonum("'$n1'") && NR<=strtonum("'$n2'") { if (NR=='$n') printf(">%d<", NR); else printf(" %d ", NR); printf("\t%s\n", $0)}' $f + ${AWK} 'NR>=strtonum("'$n1'") && NR<=strtonum("'$n2'") { if (NR=='$n') printf(">%d<", NR); else printf(" %d ", NR); printf("\t%s\n", $0)}' $f done DONE=1 - done < <(${NM} -n $objfile | awk -v fn=$func -v end=$file_end '$3 == fn { found=1; line=$0; start=$1; next } found == 1 { found=0; print line, "0x"$1 } END {if (found == 1) print line, end; }') + done < <(${READELF} --symbols --wide $objfile | ${AWK} -v fn=$sym_name '$4 == "FUNC" && $8 == fn') } [[ $# -lt 2 ]] && usage -- cgit v1.2.3 From c1298a3a1139c9a73a188fbb153b6eb83dbd4d7d Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sun, 8 May 2022 09:15:53 -0700 Subject: big_keys: Use struct for internal payload The randstruct GCC plugin gets upset when it sees struct path (which is randomized) being assigned from a "void *" (which it cannot type-check). There's no need for these casts, as the entire internal payload use is following a normal struct layout. Convert the enum-based void * offset dereferencing to the new big_key_payload struct. No meaningful machine code changes result after this change, and source readability is improved. Drop the randstruct exception now that there is no "confusing" cross-type assignment. Cc: David Howells Cc: Eric Biggers Cc: Christoph Hellwig Cc: Jarkko Sakkinen Cc: James Morris Cc: "Serge E. Hallyn" Cc: linux-hardening@vger.kernel.org Cc: keyrings@vger.kernel.org Cc: linux-security-module@vger.kernel.org Signed-off-by: Kees Cook --- scripts/gcc-plugins/randomize_layout_plugin.c | 2 - security/keys/big_key.c | 73 +++++++++++++-------------- 2 files changed, 36 insertions(+), 39 deletions(-) (limited to 'scripts') diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index 19214e573137..5836a7fc7532 100644 --- a/scripts/gcc-plugins/randomize_layout_plugin.c +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -50,8 +50,6 @@ static const struct whitelist_entry whitelist[] = { { "drivers/net/ethernet/sun/niu.c", "page", "address_space" }, /* unix_skb_parms via UNIXCB() buffer */ { "net/unix/af_unix.c", "unix_skb_parms", "char" }, - /* big_key payload.data struct splashing */ - { "security/keys/big_key.c", "path", "void *" }, { } }; diff --git a/security/keys/big_key.c b/security/keys/big_key.c index d17e5f09eeb8..c3367622c683 100644 --- a/security/keys/big_key.c +++ b/security/keys/big_key.c @@ -20,12 +20,13 @@ /* * Layout of key payload words. */ -enum { - big_key_data, - big_key_path, - big_key_path_2nd_part, - big_key_len, +struct big_key_payload { + u8 *data; + struct path path; + size_t length; }; +#define to_big_key_payload(payload) \ + (struct big_key_payload *)((payload).data) /* * If the data is under this limit, there's no point creating a shm file to @@ -55,7 +56,7 @@ struct key_type key_type_big_key = { */ int big_key_preparse(struct key_preparsed_payload *prep) { - struct path *path = (struct path *)&prep->payload.data[big_key_path]; + struct big_key_payload *payload = to_big_key_payload(prep->payload); struct file *file; u8 *buf, *enckey; ssize_t written; @@ -63,13 +64,15 @@ int big_key_preparse(struct key_preparsed_payload *prep) size_t enclen = datalen + CHACHA20POLY1305_AUTHTAG_SIZE; int ret; + BUILD_BUG_ON(sizeof(*payload) != sizeof(prep->payload.data)); + if (datalen <= 0 || datalen > 1024 * 1024 || !prep->data) return -EINVAL; /* Set an arbitrary quota */ prep->quotalen = 16; - prep->payload.data[big_key_len] = (void *)(unsigned long)datalen; + payload->length = datalen; if (datalen > BIG_KEY_FILE_THRESHOLD) { /* Create a shmem file to store the data in. This will permit the data @@ -117,9 +120,9 @@ int big_key_preparse(struct key_preparsed_payload *prep) /* Pin the mount and dentry to the key so that we can open it again * later */ - prep->payload.data[big_key_data] = enckey; - *path = file->f_path; - path_get(path); + payload->data = enckey; + payload->path = file->f_path; + path_get(&payload->path); fput(file); kvfree_sensitive(buf, enclen); } else { @@ -129,7 +132,7 @@ int big_key_preparse(struct key_preparsed_payload *prep) if (!data) return -ENOMEM; - prep->payload.data[big_key_data] = data; + payload->data = data; memcpy(data, prep->data, prep->datalen); } return 0; @@ -148,12 +151,11 @@ error: */ void big_key_free_preparse(struct key_preparsed_payload *prep) { - if (prep->datalen > BIG_KEY_FILE_THRESHOLD) { - struct path *path = (struct path *)&prep->payload.data[big_key_path]; + struct big_key_payload *payload = to_big_key_payload(prep->payload); - path_put(path); - } - kfree_sensitive(prep->payload.data[big_key_data]); + if (prep->datalen > BIG_KEY_FILE_THRESHOLD) + path_put(&payload->path); + kfree_sensitive(payload->data); } /* @@ -162,13 +164,12 @@ void big_key_free_preparse(struct key_preparsed_payload *prep) */ void big_key_revoke(struct key *key) { - struct path *path = (struct path *)&key->payload.data[big_key_path]; + struct big_key_payload *payload = to_big_key_payload(key->payload); /* clear the quota */ key_payload_reserve(key, 0); - if (key_is_positive(key) && - (size_t)key->payload.data[big_key_len] > BIG_KEY_FILE_THRESHOLD) - vfs_truncate(path, 0); + if (key_is_positive(key) && payload->length > BIG_KEY_FILE_THRESHOLD) + vfs_truncate(&payload->path, 0); } /* @@ -176,17 +177,15 @@ void big_key_revoke(struct key *key) */ void big_key_destroy(struct key *key) { - size_t datalen = (size_t)key->payload.data[big_key_len]; - - if (datalen > BIG_KEY_FILE_THRESHOLD) { - struct path *path = (struct path *)&key->payload.data[big_key_path]; + struct big_key_payload *payload = to_big_key_payload(key->payload); - path_put(path); - path->mnt = NULL; - path->dentry = NULL; + if (payload->length > BIG_KEY_FILE_THRESHOLD) { + path_put(&payload->path); + payload->path.mnt = NULL; + payload->path.dentry = NULL; } - kfree_sensitive(key->payload.data[big_key_data]); - key->payload.data[big_key_data] = NULL; + kfree_sensitive(payload->data); + payload->data = NULL; } /* @@ -211,14 +210,14 @@ int big_key_update(struct key *key, struct key_preparsed_payload *prep) */ void big_key_describe(const struct key *key, struct seq_file *m) { - size_t datalen = (size_t)key->payload.data[big_key_len]; + struct big_key_payload *payload = to_big_key_payload(key->payload); seq_puts(m, key->description); if (key_is_positive(key)) seq_printf(m, ": %zu [%s]", - datalen, - datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff"); + payload->length, + payload->length > BIG_KEY_FILE_THRESHOLD ? "file" : "buff"); } /* @@ -227,16 +226,16 @@ void big_key_describe(const struct key *key, struct seq_file *m) */ long big_key_read(const struct key *key, char *buffer, size_t buflen) { - size_t datalen = (size_t)key->payload.data[big_key_len]; + struct big_key_payload *payload = to_big_key_payload(key->payload); + size_t datalen = payload->length; long ret; if (!buffer || buflen < datalen) return datalen; if (datalen > BIG_KEY_FILE_THRESHOLD) { - struct path *path = (struct path *)&key->payload.data[big_key_path]; struct file *file; - u8 *buf, *enckey = (u8 *)key->payload.data[big_key_data]; + u8 *buf, *enckey = payload->data; size_t enclen = datalen + CHACHA20POLY1305_AUTHTAG_SIZE; loff_t pos = 0; @@ -244,7 +243,7 @@ long big_key_read(const struct key *key, char *buffer, size_t buflen) if (!buf) return -ENOMEM; - file = dentry_open(path, O_RDONLY, current_cred()); + file = dentry_open(&payload->path, O_RDONLY, current_cred()); if (IS_ERR(file)) { ret = PTR_ERR(file); goto error; @@ -274,7 +273,7 @@ error: kvfree_sensitive(buf, enclen); } else { ret = datalen; - memcpy(buffer, key->payload.data[big_key_data], datalen); + memcpy(buffer, payload->data, datalen); } return ret; -- cgit v1.2.3 From 2dcfe9e2d370f6643486e327c6ae17af8887756c Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 9 May 2022 15:11:54 -0700 Subject: niu: Silence randstruct warnings Clang randstruct gets upset when it sees struct addresspace (which is randomized) being assigned to a struct page (which is not randomized): drivers/net/ethernet/sun/niu.c:3385:12: error: casting from randomized structure pointer type 'struct address_space *' to 'struct page *' *link = (struct page *) page->mapping; ^ It looks like niu.c is looking for an in-line place to chain its allocated pages together and is overloading the "mapping" member, as it is unused. This is very non-standard, and is expected to be cleaned up in the future[1], but there is no "correct" way to handle it today. No meaningful machine code changes result after this change, and source readability is improved. Drop the randstruct exception now that there is no "confusing" cross-type assignment. [1] https://lore.kernel.org/lkml/YnqgjVoMDu5v9PNG@casper.infradead.org/ Cc: "Matthew Wilcox (Oracle)" Cc: Christoph Hellwig Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Du Cheng Cc: Christophe JAILLET Cc: Vlastimil Babka Cc: William Kucharski Cc: Arnd Bergmann Cc: Nathan Chancellor Cc: netdev@vger.kernel.org Cc: linux-mm@kvack.org Cc: linux-hardening@vger.kernel.org Acked-by: Jakub Kicinski Link: https://lore.kernel.org/lkml/20220511151647.7290adbe@kernel.org Signed-off-by: Kees Cook --- drivers/net/ethernet/sun/niu.c | 41 ++++++++++++++++++++------- scripts/gcc-plugins/randomize_layout_plugin.c | 2 -- 2 files changed, 31 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index 42460c0885fc..df70df29deea 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -35,6 +35,25 @@ #include "niu.h" +/* This driver wants to store a link to a "next page" within the + * page struct itself by overloading the content of the "mapping" + * member. This is not expected by the page API, but does currently + * work. However, the randstruct plugin gets very bothered by this + * case because "mapping" (struct address_space) is randomized, so + * casts to/from it trigger warnings. Hide this by way of a union, + * to create a typed alias of "mapping", since that's how it is + * actually being used here. + */ +union niu_page { + struct page page; + struct { + unsigned long __flags; /* unused alias of "flags" */ + struct list_head __lru; /* unused alias of "lru" */ + struct page *next; /* alias of "mapping" */ + }; +}; +#define niu_next_page(p) container_of(p, union niu_page, page)->next + #define DRV_MODULE_NAME "niu" #define DRV_MODULE_VERSION "1.1" #define DRV_MODULE_RELDATE "Apr 22, 2010" @@ -3283,7 +3302,7 @@ static struct page *niu_find_rxpage(struct rx_ring_info *rp, u64 addr, addr &= PAGE_MASK; pp = &rp->rxhash[h]; - for (; (p = *pp) != NULL; pp = (struct page **) &p->mapping) { + for (; (p = *pp) != NULL; pp = &niu_next_page(p)) { if (p->index == addr) { *link = pp; goto found; @@ -3300,7 +3319,7 @@ static void niu_hash_page(struct rx_ring_info *rp, struct page *page, u64 base) unsigned int h = niu_hash_rxaddr(rp, base); page->index = base; - page->mapping = (struct address_space *) rp->rxhash[h]; + niu_next_page(page) = rp->rxhash[h]; rp->rxhash[h] = page; } @@ -3382,11 +3401,11 @@ static int niu_rx_pkt_ignore(struct niu *np, struct rx_ring_info *rp) rcr_size = rp->rbr_sizes[(val & RCR_ENTRY_PKTBUFSZ) >> RCR_ENTRY_PKTBUFSZ_SHIFT]; if ((page->index + PAGE_SIZE) - rcr_size == addr) { - *link = (struct page *) page->mapping; + *link = niu_next_page(page); np->ops->unmap_page(np->device, page->index, PAGE_SIZE, DMA_FROM_DEVICE); page->index = 0; - page->mapping = NULL; + niu_next_page(page) = NULL; __free_page(page); rp->rbr_refill_pending++; } @@ -3451,11 +3470,11 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, niu_rx_skb_append(skb, page, off, append_size, rcr_size); if ((page->index + rp->rbr_block_size) - rcr_size == addr) { - *link = (struct page *) page->mapping; + *link = niu_next_page(page); np->ops->unmap_page(np->device, page->index, PAGE_SIZE, DMA_FROM_DEVICE); page->index = 0; - page->mapping = NULL; + niu_next_page(page) = NULL; rp->rbr_refill_pending++; } else get_page(page); @@ -3518,13 +3537,13 @@ static void niu_rbr_free(struct niu *np, struct rx_ring_info *rp) page = rp->rxhash[i]; while (page) { - struct page *next = (struct page *) page->mapping; + struct page *next = niu_next_page(page); u64 base = page->index; np->ops->unmap_page(np->device, base, PAGE_SIZE, DMA_FROM_DEVICE); page->index = 0; - page->mapping = NULL; + niu_next_page(page) = NULL; __free_page(page); @@ -6440,8 +6459,7 @@ static void niu_reset_buffers(struct niu *np) page = rp->rxhash[j]; while (page) { - struct page *next = - (struct page *) page->mapping; + struct page *next = niu_next_page(page); u64 base = page->index; base = base >> RBR_DESCR_ADDR_SHIFT; rp->rbr[k++] = cpu_to_le32(base); @@ -10176,6 +10194,9 @@ static int __init niu_init(void) BUILD_BUG_ON(PAGE_SIZE < 4 * 1024); + BUILD_BUG_ON(offsetof(struct page, mapping) != + offsetof(union niu_page, next)); + niu_debug = netif_msg_init(debug, NIU_MSG_DEFAULT); #ifdef CONFIG_SPARC64 diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index 5836a7fc7532..c9d345a91c41 100644 --- a/scripts/gcc-plugins/randomize_layout_plugin.c +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -46,8 +46,6 @@ struct whitelist_entry { }; static const struct whitelist_entry whitelist[] = { - /* NIU overloads mapping with page struct */ - { "drivers/net/ethernet/sun/niu.c", "page", "address_space" }, /* unix_skb_parms via UNIXCB() buffer */ { "net/unix/af_unix.c", "unix_skb_parms", "char" }, { } -- cgit v1.2.3 From b146cbf2e32f01f56244d670aef2f43d44fcf120 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 10 May 2022 15:46:26 -0700 Subject: af_unix: Silence randstruct GCC plugin warning While preparing for Clang randstruct support (which duplicated many of the warnings the randstruct GCC plugin warned about), one strange one remained only for the randstruct GCC plugin. Eliminating this rids the plugin of the last exception. It seems the plugin is happy to dereference individual members of a cross-struct cast, but it is upset about casting to a whole object pointer. This only manifests in one place in the kernel, so just replace the variable with individual member accesses. There is no change in executable instruction output. Drop the last exception from the randstruct GCC plugin. Cc: "David S. Miller" Cc: Christoph Hellwig Cc: Paolo Abeni Cc: Alexei Starovoitov Cc: Cong Wang Cc: Al Viro Cc: netdev@vger.kernel.org Cc: linux-hardening@vger.kernel.org Acked-by: Kuniyuki Iwashima Link: https://lore.kernel.org/lkml/20220511022217.58586-1-kuniyu@amazon.co.jp Acked-by: Jakub Kicinski Link: https://lore.kernel.org/lkml/20220511151542.4cb3ff17@kernel.org Signed-off-by: Kees Cook --- net/unix/af_unix.c | 8 +++----- scripts/gcc-plugins/randomize_layout_plugin.c | 2 -- 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index e71a312faa1e..36367e7e3e0a 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1808,11 +1808,9 @@ static int maybe_init_creds(struct scm_cookie *scm, static bool unix_skb_scm_eq(struct sk_buff *skb, struct scm_cookie *scm) { - const struct unix_skb_parms *u = &UNIXCB(skb); - - return u->pid == scm->pid && - uid_eq(u->uid, scm->creds.uid) && - gid_eq(u->gid, scm->creds.gid) && + return UNIXCB(skb).pid == scm->pid && + uid_eq(UNIXCB(skb).uid, scm->creds.uid) && + gid_eq(UNIXCB(skb).gid, scm->creds.gid) && unix_secdata_eq(scm, skb); } diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index c9d345a91c41..2ca768d88a68 100644 --- a/scripts/gcc-plugins/randomize_layout_plugin.c +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -46,8 +46,6 @@ struct whitelist_entry { }; static const struct whitelist_entry whitelist[] = { - /* unix_skb_parms via UNIXCB() buffer */ - { "net/unix/af_unix.c", "unix_skb_parms", "char" }, { } }; -- cgit v1.2.3 From 710e4ebfbacac53b05c86a01e6d636c69f6eca9f Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 10 May 2022 16:22:45 -0700 Subject: gcc-plugins: randstruct: Remove cast exception handling With all randstruct exceptions removed, remove all the exception handling code. Any future warnings are likely to be shared between this plugin and Clang randstruct, and will need to be addressed in a more wholistic fashion. Cc: Christoph Hellwig Cc: linux-hardening@vger.kernel.org Signed-off-by: Kees Cook --- scripts/gcc-plugins/randomize_layout_plugin.c | 79 +-------------------------- 1 file changed, 3 insertions(+), 76 deletions(-) (limited to 'scripts') diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index 2ca768d88a68..ea2aea570404 100644 --- a/scripts/gcc-plugins/randomize_layout_plugin.c +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -39,16 +39,6 @@ static struct plugin_info randomize_layout_plugin_info = { "performance-mode\tenable cacheline-aware layout randomization\n" }; -struct whitelist_entry { - const char *pathname; - const char *lhs; - const char *rhs; -}; - -static const struct whitelist_entry whitelist[] = { - { } -}; - /* from old Linux dcache.h */ static inline unsigned long partial_name_hash(unsigned long c, unsigned long prevhash) @@ -734,60 +724,6 @@ static void handle_local_var_initializers(void) } } -static bool type_name_eq(gimple stmt, const_tree type_tree, const char *wanted_name) -{ - const char *type_name; - - if (type_tree == NULL_TREE) - return false; - - switch (TREE_CODE(type_tree)) { - case RECORD_TYPE: - type_name = TYPE_NAME_POINTER(type_tree); - break; - case INTEGER_TYPE: - if (TYPE_PRECISION(type_tree) == CHAR_TYPE_SIZE) - type_name = "char"; - else { - INFORM(gimple_location(stmt), "found non-char INTEGER_TYPE cast comparison: %qT\n", type_tree); - debug_tree(type_tree); - return false; - } - break; - case POINTER_TYPE: - if (TREE_CODE(TREE_TYPE(type_tree)) == VOID_TYPE) { - type_name = "void *"; - break; - } else { - INFORM(gimple_location(stmt), "found non-void POINTER_TYPE cast comparison %qT\n", type_tree); - debug_tree(type_tree); - return false; - } - default: - INFORM(gimple_location(stmt), "unhandled cast comparison: %qT\n", type_tree); - debug_tree(type_tree); - return false; - } - - return strcmp(type_name, wanted_name) == 0; -} - -static bool whitelisted_cast(gimple stmt, const_tree lhs_tree, const_tree rhs_tree) -{ - const struct whitelist_entry *entry; - expanded_location xloc = expand_location(gimple_location(stmt)); - - for (entry = whitelist; entry->pathname; entry++) { - if (!strstr(xloc.file, entry->pathname)) - continue; - - if (type_name_eq(stmt, lhs_tree, entry->lhs) && type_name_eq(stmt, rhs_tree, entry->rhs)) - return true; - } - - return false; -} - /* * iterate over all statements to find "bad" casts: * those where the address of the start of a structure is cast @@ -864,10 +800,7 @@ static unsigned int find_bad_casts_execute(void) #ifndef __DEBUG_PLUGIN if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(ptr_lhs_type))) #endif - { - if (!whitelisted_cast(stmt, ptr_lhs_type, ptr_rhs_type)) - MISMATCH(gimple_location(stmt), "rhs", ptr_lhs_type, ptr_rhs_type); - } + MISMATCH(gimple_location(stmt), "rhs", ptr_lhs_type, ptr_rhs_type); continue; } @@ -890,10 +823,7 @@ static unsigned int find_bad_casts_execute(void) #ifndef __DEBUG_PLUGIN if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(op0_type))) #endif - { - if (!whitelisted_cast(stmt, ptr_lhs_type, op0_type)) - MISMATCH(gimple_location(stmt), "op0", ptr_lhs_type, op0_type); - } + MISMATCH(gimple_location(stmt), "op0", ptr_lhs_type, op0_type); } else { const_tree ssa_name_var = SSA_NAME_VAR(rhs1); /* skip bogus type casts introduced by container_of */ @@ -903,10 +833,7 @@ static unsigned int find_bad_casts_execute(void) #ifndef __DEBUG_PLUGIN if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(ptr_rhs_type))) #endif - { - if (!whitelisted_cast(stmt, ptr_lhs_type, ptr_rhs_type)) - MISMATCH(gimple_location(stmt), "ssa", ptr_lhs_type, ptr_rhs_type); - } + MISMATCH(gimple_location(stmt), "ssa", ptr_lhs_type, ptr_rhs_type); } } -- cgit v1.2.3 From 8218827b73c6e41029438a2d3cc573286beee914 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 11 May 2022 14:05:32 +0200 Subject: scripts/min-tool-version.sh: raise minimum clang version to 14.0.0 for s390 Before version 14.0.0 llvm's integrated assembler fails to handle some displacement variants: arch/s390/purgatory/head.S:108:10: error: invalid operand for instruction lg %r11,kernel_type-.base_crash(%r13) Instead of working around this and given that this is already fixed raise the minimum clang version from 13.0.0 to 14.0.0. Acked-by: Nick Desaulniers Tested-by: Nathan Chancellor Tested-by: Nick Desaulniers Link: https://reviews.llvm.org/D113341 Link: https://lore.kernel.org/r/20220511120532.2228616-9-hca@linux.ibm.com Signed-off-by: Heiko Carstens --- scripts/min-tool-version.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/min-tool-version.sh b/scripts/min-tool-version.sh index 7c20252a90c6..250925aab101 100755 --- a/scripts/min-tool-version.sh +++ b/scripts/min-tool-version.sh @@ -24,9 +24,8 @@ icc) echo 16.0.3 ;; llvm) - # https://lore.kernel.org/r/YMtib5hKVyNknZt3@osiris/ if [ "$SRCARCH" = s390 ]; then - echo 13.0.0 + echo 14.0.0 else echo 11.0.0 fi -- cgit v1.2.3 From 0aa7be05d83cc584da0782405e8007e351dfb6cc Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Sun, 15 May 2022 20:42:03 +0200 Subject: locking/atomic: Add generic try_cmpxchg64 support Add generic support for try_cmpxchg64{,_acquire,_release,_relaxed} and their falbacks involving cmpxchg64. Signed-off-by: Uros Bizjak Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20220515184205.103089-2-ubizjak@gmail.com --- include/linux/atomic/atomic-arch-fallback.h | 72 ++++++++++++++++++++++++++++- include/linux/atomic/atomic-instrumented.h | 40 +++++++++++++++- scripts/atomic/gen-atomic-fallback.sh | 31 +++++++------ scripts/atomic/gen-atomic-instrumented.sh | 2 +- 4 files changed, 129 insertions(+), 16 deletions(-) (limited to 'scripts') diff --git a/include/linux/atomic/atomic-arch-fallback.h b/include/linux/atomic/atomic-arch-fallback.h index 6db58d180866..77bc5522e61c 100644 --- a/include/linux/atomic/atomic-arch-fallback.h +++ b/include/linux/atomic/atomic-arch-fallback.h @@ -147,6 +147,76 @@ #endif /* arch_try_cmpxchg_relaxed */ +#ifndef arch_try_cmpxchg64_relaxed +#ifdef arch_try_cmpxchg64 +#define arch_try_cmpxchg64_acquire arch_try_cmpxchg64 +#define arch_try_cmpxchg64_release arch_try_cmpxchg64 +#define arch_try_cmpxchg64_relaxed arch_try_cmpxchg64 +#endif /* arch_try_cmpxchg64 */ + +#ifndef arch_try_cmpxchg64 +#define arch_try_cmpxchg64(_ptr, _oldp, _new) \ +({ \ + typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ + ___r = arch_cmpxchg64((_ptr), ___o, (_new)); \ + if (unlikely(___r != ___o)) \ + *___op = ___r; \ + likely(___r == ___o); \ +}) +#endif /* arch_try_cmpxchg64 */ + +#ifndef arch_try_cmpxchg64_acquire +#define arch_try_cmpxchg64_acquire(_ptr, _oldp, _new) \ +({ \ + typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ + ___r = arch_cmpxchg64_acquire((_ptr), ___o, (_new)); \ + if (unlikely(___r != ___o)) \ + *___op = ___r; \ + likely(___r == ___o); \ +}) +#endif /* arch_try_cmpxchg64_acquire */ + +#ifndef arch_try_cmpxchg64_release +#define arch_try_cmpxchg64_release(_ptr, _oldp, _new) \ +({ \ + typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ + ___r = arch_cmpxchg64_release((_ptr), ___o, (_new)); \ + if (unlikely(___r != ___o)) \ + *___op = ___r; \ + likely(___r == ___o); \ +}) +#endif /* arch_try_cmpxchg64_release */ + +#ifndef arch_try_cmpxchg64_relaxed +#define arch_try_cmpxchg64_relaxed(_ptr, _oldp, _new) \ +({ \ + typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ + ___r = arch_cmpxchg64_relaxed((_ptr), ___o, (_new)); \ + if (unlikely(___r != ___o)) \ + *___op = ___r; \ + likely(___r == ___o); \ +}) +#endif /* arch_try_cmpxchg64_relaxed */ + +#else /* arch_try_cmpxchg64_relaxed */ + +#ifndef arch_try_cmpxchg64_acquire +#define arch_try_cmpxchg64_acquire(...) \ + __atomic_op_acquire(arch_try_cmpxchg64, __VA_ARGS__) +#endif + +#ifndef arch_try_cmpxchg64_release +#define arch_try_cmpxchg64_release(...) \ + __atomic_op_release(arch_try_cmpxchg64, __VA_ARGS__) +#endif + +#ifndef arch_try_cmpxchg64 +#define arch_try_cmpxchg64(...) \ + __atomic_op_fence(arch_try_cmpxchg64, __VA_ARGS__) +#endif + +#endif /* arch_try_cmpxchg64_relaxed */ + #ifndef arch_atomic_read_acquire static __always_inline int arch_atomic_read_acquire(const atomic_t *v) @@ -2386,4 +2456,4 @@ arch_atomic64_dec_if_positive(atomic64_t *v) #endif #endif /* _LINUX_ATOMIC_FALLBACK_H */ -// 8e2cc06bc0d2c0967d2f8424762bd48555ee40ae +// b5e87bdd5ede61470c29f7a7e4de781af3770f09 diff --git a/include/linux/atomic/atomic-instrumented.h b/include/linux/atomic/atomic-instrumented.h index 5d69b143c28e..7a139ec030b0 100644 --- a/include/linux/atomic/atomic-instrumented.h +++ b/include/linux/atomic/atomic-instrumented.h @@ -2006,6 +2006,44 @@ atomic_long_dec_if_positive(atomic_long_t *v) arch_try_cmpxchg_relaxed(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) +#define try_cmpxchg64(ptr, oldp, ...) \ +({ \ + 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)); \ + arch_try_cmpxchg64(__ai_ptr, __ai_oldp, __VA_ARGS__); \ +}) + +#define try_cmpxchg64_acquire(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_acquire(__ai_ptr, __ai_oldp, __VA_ARGS__); \ +}) + +#define try_cmpxchg64_release(ptr, oldp, ...) \ +({ \ + 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)); \ + arch_try_cmpxchg64_release(__ai_ptr, __ai_oldp, __VA_ARGS__); \ +}) + +#define try_cmpxchg64_relaxed(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_relaxed(__ai_ptr, __ai_oldp, __VA_ARGS__); \ +}) + #define cmpxchg_local(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ @@ -2045,4 +2083,4 @@ atomic_long_dec_if_positive(atomic_long_t *v) }) #endif /* _LINUX_ATOMIC_INSTRUMENTED_H */ -// 87c974b93032afd42143613434d1a7788fa598f9 +// 764f741eb77a7ad565dc8d99ce2837d5542e8aee diff --git a/scripts/atomic/gen-atomic-fallback.sh b/scripts/atomic/gen-atomic-fallback.sh index 8e2da71f1d5f..3a07695e3c89 100755 --- a/scripts/atomic/gen-atomic-fallback.sh +++ b/scripts/atomic/gen-atomic-fallback.sh @@ -164,41 +164,44 @@ gen_xchg_fallbacks() gen_try_cmpxchg_fallback() { + local cmpxchg="$1"; shift; local order="$1"; shift; cat < Date: Mon, 16 May 2022 12:27:22 +0200 Subject: scripts/spdxcheck: Add percentage to statistics Files checked: 75856 Lines checked: 294516 Files with SPDX: 59410 78% Files with errors: 0 Signed-off-by: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman --- scripts/spdxcheck.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/spdxcheck.py b/scripts/spdxcheck.py index f3be8ed54f6d..c6ff37e935f5 100755 --- a/scripts/spdxcheck.py +++ b/scripts/spdxcheck.py @@ -285,7 +285,9 @@ if __name__ == '__main__': sys.stderr.write('\n') sys.stderr.write('Files checked: %12d\n' %parser.checked) sys.stderr.write('Lines checked: %12d\n' %parser.lines_checked) - sys.stderr.write('Files with SPDX: %12d\n' %parser.spdx_valid) + if parser.checked: + pc = int(100 * parser.spdx_valid / parser.checked) + sys.stderr.write('Files with SPDX: %12d %3d%%\n' %(parser.spdx_valid, pc)) sys.stderr.write('Files with errors: %12d\n' %parser.spdx_errors) sys.exit(0) -- cgit v1.2.3 From a377ce75e4916da5dbb84672218a7e61e51da3ce Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 16 May 2022 12:27:24 +0200 Subject: scripts/spdxcheck: Add directory statistics For better insights. Directories accounted: 4646 Directories complete: 2565 55% Signed-off-by: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman --- scripts/spdxcheck.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'scripts') diff --git a/scripts/spdxcheck.py b/scripts/spdxcheck.py index c6ff37e935f5..80fade8629e7 100755 --- a/scripts/spdxcheck.py +++ b/scripts/spdxcheck.py @@ -28,6 +28,15 @@ class SPDXdata(object): self.licenses = [ ] self.exceptions = { } +class dirinfo(object): + def __init__(self): + self.missing = 0 + self.total = 0 + + def update(self, miss): + self.total += 1 + self.missing += miss + # Read the spdx data from the LICENSES directory def read_spdxdata(repo): @@ -93,6 +102,7 @@ class id_parser(object): self.checked = 0 self.spdx_valid = 0 self.spdx_errors = 0 + self.spdx_dirs = {} self.curline = 0 self.deepest = 0 @@ -167,6 +177,7 @@ class id_parser(object): def parse_lines(self, fd, maxlines, fname): self.checked += 1 self.curline = 0 + fail = 1 try: for line in fd: line = line.decode(locale.getpreferredencoding(False), errors='ignore') @@ -192,6 +203,7 @@ class id_parser(object): # Should we check for more SPDX ids in the same file and # complain if there are any? # + fail = 0 break except ParserException as pe: @@ -203,6 +215,11 @@ class id_parser(object): sys.stdout.write('%s: %d:0 %s\n' %(fname, self.curline, pe.txt)) self.spdx_errors += 1 + base = os.path.dirname(fname) + di = self.spdx_dirs.get(base, dirinfo()) + di.update(fail) + self.spdx_dirs[base] = di + def scan_git_tree(tree): for el in tree.traverse(): # Exclude stuff which would make pointless noise @@ -289,6 +306,16 @@ if __name__ == '__main__': pc = int(100 * parser.spdx_valid / parser.checked) sys.stderr.write('Files with SPDX: %12d %3d%%\n' %(parser.spdx_valid, pc)) sys.stderr.write('Files with errors: %12d\n' %parser.spdx_errors) + ndirs = len(parser.spdx_dirs) + dirsok = 0 + if ndirs: + sys.stderr.write('\n') + sys.stderr.write('Directories accounted: %8d\n' %ndirs) + for di in parser.spdx_dirs.values(): + if not di.missing: + dirsok += 1 + pc = int(100 * dirsok / ndirs) + sys.stderr.write('Directories complete: %8d %3d%%\n' %(dirsok, pc)) sys.exit(0) -- cgit v1.2.3 From 0e7f030687efb7a6f8dddd0e967ca4377aee3001 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 16 May 2022 12:27:26 +0200 Subject: scripts/spdxcheck: Add [sub]directory statistics Add functionality to display [sub]directory statistics. This is enabled by adding '-d' to the command line. The optional -D parameter allows to limit the directory depth. If supplied the subdirectories are accumulated # scripts/spdxcheck.py -d kernel/ Incomplete directories: SPDX in Files ./kernel : 111 of 114 97% ./kernel/bpf : 43 of 45 95% ./kernel/bpf/preload : 4 of 5 80% ./kernel/bpf/preload/iterators : 4 of 5 80% ./kernel/cgroup : 10 of 13 76% ./kernel/configs : 0 of 9 0% ./kernel/debug : 3 of 4 75% ./kernel/debug/kdb : 1 of 11 9% ./kernel/locking : 29 of 32 90% ./kernel/sched : 38 of 39 97% The result can be accumulated by restricting the depth via the new command line option '-d $DEPTH': # scripts/spdxcheck.py -d -D1 Incomplete directories: SPDX in Files ./ : 6 of 13 46% ./Documentation : 4096 of 8451 48% ./arch : 13476 of 16402 82% ./block : 100 of 101 99% ./certs : 11 of 14 78% ./crypto : 145 of 176 82% ./drivers : 24682 of 30745 80% ./fs : 1876 of 2110 88% ./include : 5175 of 5757 89% ./ipc : 12 of 13 92% ./kernel : 493 of 527 93% ./lib : 393 of 524 75% ./mm : 151 of 159 94% ./net : 1713 of 1900 90% ./samples : 211 of 273 77% ./scripts : 341 of 435 78% ./security : 241 of 250 96% ./sound : 2438 of 2503 97% ./tools : 3810 of 5462 69% ./usr : 9 of 10 90% Signed-off-by: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman --- scripts/spdxcheck.py | 67 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/spdxcheck.py b/scripts/spdxcheck.py index 80fade8629e7..dc605d485dca 100755 --- a/scripts/spdxcheck.py +++ b/scripts/spdxcheck.py @@ -103,9 +103,21 @@ class id_parser(object): self.spdx_valid = 0 self.spdx_errors = 0 self.spdx_dirs = {} + self.dirdepth = -1 + self.basedir = '.' self.curline = 0 self.deepest = 0 + def set_dirinfo(self, basedir, dirdepth): + if dirdepth >= 0: + self.basedir = basedir + bdir = basedir.lstrip('./').rstrip('/') + if bdir != '': + parts = bdir.split('/') + else: + parts = [] + self.dirdepth = dirdepth + len(parts) + # Validate License and Exception IDs def validate(self, tok): id = tok.value.upper() @@ -215,12 +227,29 @@ class id_parser(object): sys.stdout.write('%s: %d:0 %s\n' %(fname, self.curline, pe.txt)) self.spdx_errors += 1 + if fname == '-': + return + base = os.path.dirname(fname) + if self.dirdepth > 0: + parts = base.split('/') + i = 0 + base = '.' + while i < self.dirdepth and i < len(parts) and len(parts[i]): + base += '/' + parts[i] + i += 1 + elif self.dirdepth == 0: + base = self.basedir + else: + base = './' + base.rstrip('/') + base += '/' + di = self.spdx_dirs.get(base, dirinfo()) di.update(fail) self.spdx_dirs[base] = di -def scan_git_tree(tree): +def scan_git_tree(tree, basedir, dirdepth): + parser.set_dirinfo(basedir, dirdepth) for el in tree.traverse(): # Exclude stuff which would make pointless noise # FIXME: Put this somewhere more sensible @@ -233,15 +262,19 @@ def scan_git_tree(tree): with open(el.path, 'rb') as fd: parser.parse_lines(fd, args.maxlines, el.path) -def scan_git_subtree(tree, path): +def scan_git_subtree(tree, path, dirdepth): for p in path.strip('/').split('/'): tree = tree[p] - scan_git_tree(tree) + scan_git_tree(tree, path.strip('/'), dirdepth) if __name__ == '__main__': ap = ArgumentParser(description='SPDX expression checker') ap.add_argument('path', nargs='*', help='Check path or file. If not given full git tree scan. For stdin use "-"') + ap.add_argument('-d', '--dirs', action='store_true', + help='Show [sub]directory statistics.') + ap.add_argument('-D', '--depth', type=int, default=-1, + help='Directory depth for -d statistics. Default: unlimited') ap.add_argument('-m', '--maxlines', type=int, default=15, help='Maximum number of lines to scan in a file. Default 15') ap.add_argument('-v', '--verbose', action='store_true', help='Verbose statistics output') @@ -285,13 +318,21 @@ if __name__ == '__main__': if os.path.isfile(p): parser.parse_lines(open(p, 'rb'), args.maxlines, p) elif os.path.isdir(p): - scan_git_subtree(repo.head.reference.commit.tree, p) + scan_git_subtree(repo.head.reference.commit.tree, p, + args.depth) else: sys.stderr.write('path %s does not exist\n' %p) sys.exit(1) else: # Full git tree scan - scan_git_tree(repo.head.commit.tree) + scan_git_tree(repo.head.commit.tree, '.', args.depth) + + ndirs = len(parser.spdx_dirs) + dirsok = 0 + if ndirs: + for di in parser.spdx_dirs.values(): + if not di.missing: + dirsok += 1 if args.verbose: sys.stderr.write('\n') @@ -306,17 +347,23 @@ if __name__ == '__main__': pc = int(100 * parser.spdx_valid / parser.checked) sys.stderr.write('Files with SPDX: %12d %3d%%\n' %(parser.spdx_valid, pc)) sys.stderr.write('Files with errors: %12d\n' %parser.spdx_errors) - ndirs = len(parser.spdx_dirs) - dirsok = 0 if ndirs: sys.stderr.write('\n') sys.stderr.write('Directories accounted: %8d\n' %ndirs) - for di in parser.spdx_dirs.values(): - if not di.missing: - dirsok += 1 pc = int(100 * dirsok / ndirs) sys.stderr.write('Directories complete: %8d %3d%%\n' %(dirsok, pc)) + if ndirs and ndirs != dirsok and args.dirs: + if args.verbose: + sys.stderr.write('\n') + sys.stderr.write('Incomplete directories: SPDX in Files\n') + for f in sorted(parser.spdx_dirs.keys()): + di = parser.spdx_dirs[f] + if di.missing: + valid = di.total - di.missing + pc = int(100 * valid / di.total) + sys.stderr.write(' %-80s: %5d of %5d %3d%%\n' %(f, valid, di.total, pc)) + sys.exit(0) except Exception as ex: -- cgit v1.2.3 From 67924b71412cd965e0d1c55c0cddb0014c8a725b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 16 May 2022 12:27:27 +0200 Subject: scripts/spdxcheck: Add option to display files without SPDX Makes life easier when chasing the missing ones. Is activated with '-f' on the command line. # scripts/spdxcheck.py -f kernel/ Files without SPDX: ./kernel/cpu.c ./kernel/kmod.c ./kernel/relay.c ./kernel/bpf/offload.c ./kernel/bpf/preload/.gitignore ./kernel/bpf/preload/iterators/README ./kernel/bpf/ringbuf.c ./kernel/cgroup/cgroup.c ./kernel/cgroup/cpuset.c ./kernel/cgroup/legacy_freezer.c ./kernel/debug/debug_core.h ./kernel/debug/kdb/Makefile ./kernel/debug/kdb/kdb_bp.c ./kernel/debug/kdb/kdb_bt.c ./kernel/debug/kdb/kdb_cmds ./kernel/debug/kdb/kdb_debugger.c ./kernel/debug/kdb/kdb_io.c ./kernel/debug/kdb/kdb_keyboard.c ./kernel/debug/kdb/kdb_main.c ./kernel/debug/kdb/kdb_private.h ./kernel/debug/kdb/kdb_support.c ./kernel/locking/lockdep_states.h ./kernel/locking/mutex-debug.c ./kernel/locking/spinlock_debug.c ./kernel/sched/pelt.h With the optional -D parameter the directory depth can be limited: # scripts/spdxcheck.py -f -D 0 kernel/ Files without SPDX: ./kernel/cpu.c ./kernel/kmod.c ./kernel/relay.c Signed-off-by: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman --- scripts/spdxcheck.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/spdxcheck.py b/scripts/spdxcheck.py index dc605d485dca..b9e0f1725a0a 100755 --- a/scripts/spdxcheck.py +++ b/scripts/spdxcheck.py @@ -32,10 +32,16 @@ class dirinfo(object): def __init__(self): self.missing = 0 self.total = 0 + self.files = [] - def update(self, miss): + def update(self, fname, basedir, miss): self.total += 1 self.missing += miss + if miss: + fname = './' + fname + bdir = os.path.dirname(fname) + if bdir == basedir.rstrip('/'): + self.files.append(fname) # Read the spdx data from the LICENSES directory def read_spdxdata(repo): @@ -245,7 +251,7 @@ class id_parser(object): base += '/' di = self.spdx_dirs.get(base, dirinfo()) - di.update(fail) + di.update(fname, base, fail) self.spdx_dirs[base] = di def scan_git_tree(tree, basedir, dirdepth): @@ -275,6 +281,8 @@ if __name__ == '__main__': help='Show [sub]directory statistics.') ap.add_argument('-D', '--depth', type=int, default=-1, help='Directory depth for -d statistics. Default: unlimited') + ap.add_argument('-f', '--files', action='store_true', + help='Show files without SPDX.') ap.add_argument('-m', '--maxlines', type=int, default=15, help='Maximum number of lines to scan in a file. Default 15') ap.add_argument('-v', '--verbose', action='store_true', help='Verbose statistics output') @@ -364,6 +372,15 @@ if __name__ == '__main__': pc = int(100 * valid / di.total) sys.stderr.write(' %-80s: %5d of %5d %3d%%\n' %(f, valid, di.total, pc)) + if ndirs and ndirs != dirsok and args.files: + if args.verbose or args.dirs: + sys.stderr.write('\n') + sys.stderr.write('Files without SPDX:\n') + for f in sorted(parser.spdx_dirs.keys()): + di = parser.spdx_dirs[f] + for f in sorted(di.files): + sys.stderr.write(' %s\n' %f) + sys.exit(0) except Exception as ex: -- cgit v1.2.3 From 0509b270a358fa563946368418f8e832d9b63452 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 16 May 2022 12:27:29 +0200 Subject: scripts/spdxcheck: Put excluded files and directories into a separate file The files and directories which are excluded from scanning are currently hard coded in the script. That's not maintainable and not accessible for external tools. Move the files and directories which should be excluded into a file. The default file is scripts/spdxexclude. This can be overridden with the '-e $FILE' command line option. The file format and syntax is similar to the .gitignore file. Signed-off-by: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman --- scripts/spdxcheck.py | 70 +++++++++++++++++++++++++++++++++++++++++++++++----- scripts/spdxexclude | 8 ++++++ 2 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 scripts/spdxexclude (limited to 'scripts') diff --git a/scripts/spdxcheck.py b/scripts/spdxcheck.py index b9e0f1725a0a..18cb9f5b3d3d 100755 --- a/scripts/spdxcheck.py +++ b/scripts/spdxcheck.py @@ -6,6 +6,7 @@ from argparse import ArgumentParser from ply import lex, yacc import locale import traceback +import fnmatch import sys import git import re @@ -106,6 +107,7 @@ class id_parser(object): self.parser = yacc.yacc(module = self, write_tables = False, debug = False) self.lines_checked = 0 self.checked = 0 + self.excluded = 0 self.spdx_valid = 0 self.spdx_errors = 0 self.spdx_dirs = {} @@ -254,17 +256,47 @@ class id_parser(object): di.update(fname, base, fail) self.spdx_dirs[base] = di +class pattern(object): + def __init__(self, line): + self.pattern = line + self.match = self.match_file + if line == '.*': + self.match = self.match_dot + elif line.endswith('/'): + self.pattern = line[:-1] + self.match = self.match_dir + elif line.startswith('/'): + self.pattern = line[1:] + self.match = self.match_fn + + def match_dot(self, fpath): + return os.path.basename(fpath).startswith('.') + + def match_file(self, fpath): + return os.path.basename(fpath) == self.pattern + + def match_fn(self, fpath): + return fnmatch.fnmatchcase(fpath, self.pattern) + + def match_dir(self, fpath): + if self.match_fn(os.path.dirname(fpath)): + return True + return fpath.startswith(self.pattern) + +def exclude_file(fpath): + for rule in exclude_rules: + if rule.match(fpath): + return True + return False + def scan_git_tree(tree, basedir, dirdepth): parser.set_dirinfo(basedir, dirdepth) for el in tree.traverse(): - # Exclude stuff which would make pointless noise - # FIXME: Put this somewhere more sensible - if el.path.startswith("LICENSES"): - continue - if el.path.find("license-rules.rst") >= 0: - continue if not os.path.isfile(el.path): continue + if exclude_file(el.path): + parser.excluded += 1 + continue with open(el.path, 'rb') as fd: parser.parse_lines(fd, args.maxlines, el.path) @@ -273,6 +305,20 @@ def scan_git_subtree(tree, path, dirdepth): tree = tree[p] scan_git_tree(tree, path.strip('/'), dirdepth) +def read_exclude_file(fname): + rules = [] + if not fname: + return rules + with open(fname) as fd: + for line in fd: + line = line.strip() + if line.startswith('#'): + continue + if not len(line): + continue + rules.append(pattern(line)) + return rules + if __name__ == '__main__': ap = ArgumentParser(description='SPDX expression checker') @@ -281,6 +327,8 @@ if __name__ == '__main__': help='Show [sub]directory statistics.') ap.add_argument('-D', '--depth', type=int, default=-1, help='Directory depth for -d statistics. Default: unlimited') + ap.add_argument('-e', '--exclude', + help='File containing file patterns to exclude. Default: scripts/spdxexclude') ap.add_argument('-f', '--files', action='store_true', help='Show files without SPDX.') ap.add_argument('-m', '--maxlines', type=int, default=15, @@ -316,6 +364,15 @@ if __name__ == '__main__': sys.stderr.write('%s\n' %traceback.format_exc()) sys.exit(1) + try: + fname = args.exclude + if not fname: + fname = os.path.join(os.path.dirname(__file__), 'spdxexclude') + exclude_rules = read_exclude_file(fname) + except Exception as ex: + sys.stderr.write('FAIL: Reading exclude file %s: %s\n' %(fname, ex)) + sys.exit(1) + try: if len(args.path) and args.path[0] == '-': stdin = os.fdopen(sys.stdin.fileno(), 'rb') @@ -349,6 +406,7 @@ if __name__ == '__main__': sys.stderr.write('License IDs %12d\n' %len(spdx.licenses)) sys.stderr.write('Exception IDs %12d\n' %len(spdx.exceptions)) sys.stderr.write('\n') + sys.stderr.write('Files excluded: %12d\n' %parser.excluded) sys.stderr.write('Files checked: %12d\n' %parser.checked) sys.stderr.write('Lines checked: %12d\n' %parser.lines_checked) if parser.checked: diff --git a/scripts/spdxexclude b/scripts/spdxexclude new file mode 100644 index 000000000000..5b30fe246197 --- /dev/null +++ b/scripts/spdxexclude @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Patterns for excluding files and directories + +# Ignore the license directory and the licensing documentation which would +# create lots of noise for no value +LICENSES/ +license-rules.rst -- cgit v1.2.3 From 2fb977133684bb74d301bd86a9bb1bd2762362fc Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 16 May 2022 12:27:30 +0200 Subject: scripts/spdxcheck: Exclude config directories Kernel configuration files like default configs are machine generated and pretty useless outside of the kernel context. Signed-off-by: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman --- scripts/spdxexclude | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'scripts') diff --git a/scripts/spdxexclude b/scripts/spdxexclude index 5b30fe246197..4a7fb16dc823 100644 --- a/scripts/spdxexclude +++ b/scripts/spdxexclude @@ -6,3 +6,8 @@ # create lots of noise for no value LICENSES/ license-rules.rst + +# Ignore config files and snippets. The majority is generated +# by the Kconfig tools +kernel/configs/ +arch/*/configs/ -- cgit v1.2.3 From 2ab99ce9780d3c3505db4b83669869627010307e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 16 May 2022 12:27:32 +0200 Subject: scripts/spdxcheck: Exclude MAINTAINERS/CREDITS Listings of maintainers and people who deserve credits are not really interesting in terms of copyright. The usage of these files outside of the kernel is pointless and the file format is trivial. No point in chasing them or slapping a SPDX identifier into them just because. Signed-off-by: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman --- scripts/spdxexclude | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'scripts') diff --git a/scripts/spdxexclude b/scripts/spdxexclude index 4a7fb16dc823..73ef8caf5e61 100644 --- a/scripts/spdxexclude +++ b/scripts/spdxexclude @@ -11,3 +11,7 @@ license-rules.rst # by the Kconfig tools kernel/configs/ arch/*/configs/ + +# Other files without copyrightable content +/CREDITS +/MAINTAINERS -- cgit v1.2.3 From e0208351383c19e62f5f04209ce4ecf24db64eaf Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 16 May 2022 12:27:35 +0200 Subject: scripts/spdxcheck: Exclude top-level README Nothing copyrightable to see here. Signed-off-by: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman --- scripts/spdxexclude | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/spdxexclude b/scripts/spdxexclude index 73ef8caf5e61..81bdb13ed789 100644 --- a/scripts/spdxexclude +++ b/scripts/spdxexclude @@ -15,3 +15,4 @@ arch/*/configs/ # Other files without copyrightable content /CREDITS /MAINTAINERS +/README -- cgit v1.2.3 From 7394d2ebb651a9f62e08c6ab864aac015d27c64d Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Tue, 17 May 2022 02:46:46 +0300 Subject: scripts/tags.sh: Invoke 'realpath' via 'xargs' When COMPILED_SOURCE is set, running make ARCH=x86_64 COMPILED_SOURCE=1 cscope tags could throw the following errors: scripts/tags.sh: line 98: /usr/bin/realpath: Argument list too long cscope: no source files found scripts/tags.sh: line 98: /usr/bin/realpath: Argument list too long ctags: No files specified. Try "ctags --help". This is most likely to happen when the kernel is configured to build a large number of modules, which has the consequence of passing too many arguments when calling 'realpath' in 'all_compiled_sources()'. Let's improve this by invoking 'realpath' through 'xargs', which takes care of properly limiting the argument list. Signed-off-by: Cristian Ciocaltea Link: https://lore.kernel.org/r/20220516234646.531208-1-cristian.ciocaltea@collabora.com Signed-off-by: Greg Kroah-Hartman --- scripts/tags.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/tags.sh b/scripts/tags.sh index 16d475b3e203..01fab3d4f90b 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -95,10 +95,13 @@ all_sources() all_compiled_sources() { - realpath -es $([ -z "$KBUILD_ABS_SRCTREE" ] && echo --relative-to=.) \ - include/generated/autoconf.h $(find $ignore -name "*.cmd" -exec \ - grep -Poh '(?(?=^source_.* \K).*|(?=^ \K\S).*(?= \\))' {} \+ | - awk '!a[$0]++') | sort -u + { + echo include/generated/autoconf.h + find $ignore -name "*.cmd" -exec \ + grep -Poh '(?(?=^source_.* \K).*|(?=^ \K\S).*(?= \\))' {} \+ | + awk '!a[$0]++' + } | xargs realpath -es $([ -z "$KBUILD_ABS_SRCTREE" ] && echo --relative-to=.) | + sort -u } all_target_sources() -- cgit v1.2.3 From b2441b3bdce6c02cb96278d98c620d7ba1d41b7b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 20 May 2022 22:40:56 +0200 Subject: h8300: remove stale bindings and symlink MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These four files are left over from the h8300 removal. Reported-by: Geert Uytterhoeven Reported-by: Uwe Kleine-König Signed-off-by: Arnd Bergmann --- .../bindings/clock/renesas,h8s2678-pll-clock.txt | 23 -------------------- .../bindings/timer/renesas,16bit-timer.txt | 25 ---------------------- .../bindings/timer/renesas,8bit-timer.txt | 25 ---------------------- scripts/dtc/include-prefixes/h8300 | 1 - 4 files changed, 74 deletions(-) delete mode 100644 Documentation/devicetree/bindings/clock/renesas,h8s2678-pll-clock.txt delete mode 100644 Documentation/devicetree/bindings/timer/renesas,16bit-timer.txt delete mode 100644 Documentation/devicetree/bindings/timer/renesas,8bit-timer.txt delete mode 120000 scripts/dtc/include-prefixes/h8300 (limited to 'scripts') diff --git a/Documentation/devicetree/bindings/clock/renesas,h8s2678-pll-clock.txt b/Documentation/devicetree/bindings/clock/renesas,h8s2678-pll-clock.txt deleted file mode 100644 index 500cdadbceb7..000000000000 --- a/Documentation/devicetree/bindings/clock/renesas,h8s2678-pll-clock.txt +++ /dev/null @@ -1,23 +0,0 @@ -Renesas H8S2678 PLL clock - -This device is Clock multiplyer - -Required Properties: - - - compatible: Must be "renesas,h8s2678-pll-clock" - - - clocks: Reference to the parent clocks - - - #clock-cells: Must be 0 - - - reg: Two rate selector (Multiply / Divide) register address - -Example -------- - - pllclk: pllclk { - compatible = "renesas,h8s2678-pll-clock"; - clocks = <&xclk>; - #clock-cells = <0>; - reg = <0xfee03b 2>, <0xfee045 2>; - }; diff --git a/Documentation/devicetree/bindings/timer/renesas,16bit-timer.txt b/Documentation/devicetree/bindings/timer/renesas,16bit-timer.txt deleted file mode 100644 index e8792447a199..000000000000 --- a/Documentation/devicetree/bindings/timer/renesas,16bit-timer.txt +++ /dev/null @@ -1,25 +0,0 @@ -* Renesas H8/300 16bit timer - -The 16bit timer is a 16bit timer/counter with configurable clock inputs and -programmable compare match. - -Required Properties: - - - compatible: must contain "renesas,16bit-timer" - - reg: base address and length of the registers block for the timer module. - - interrupts: interrupt-specifier for the timer, IMIA - - clocks: a list of phandle, one for each entry in clock-names. - - clock-names: must contain "peripheral_clk" for the functional clock. - - renesas,channel: timer channel number. - -Example: - - timer16: timer@ffff68 { - compatible = "reneas,16bit-timer"; - reg = <0xffff68 8>, <0xffff60 8>; - interrupts = <24>; - renesas,channel = <0>; - clocks = <&pclk>; - clock-names = "peripheral_clk"; - }; - diff --git a/Documentation/devicetree/bindings/timer/renesas,8bit-timer.txt b/Documentation/devicetree/bindings/timer/renesas,8bit-timer.txt deleted file mode 100644 index 9dca3759a0f0..000000000000 --- a/Documentation/devicetree/bindings/timer/renesas,8bit-timer.txt +++ /dev/null @@ -1,25 +0,0 @@ -* Renesas H8/300 8bit timer - -The 8bit timer is a 8bit timer/counter with configurable clock inputs and -programmable compare match. - -This implement only supported cascade mode. - -Required Properties: - - - compatible: must contain "renesas,8bit-timer" - - reg: base address and length of the registers block for the timer module. - - interrupts: interrupt-specifier for the timer, CMIA and TOVI - - clocks: a list of phandle, one for each entry in clock-names. - - clock-names: must contain "fck" for the functional clock. - -Example: - - timer8_0: timer@ffff80 { - compatible = "renesas,8bit-timer"; - reg = <0xffff80 10>; - interrupts = <36>; - clocks = <&fclk>; - clock-names = "fck"; - }; - diff --git a/scripts/dtc/include-prefixes/h8300 b/scripts/dtc/include-prefixes/h8300 deleted file mode 120000 index 3bdaa332c54c..000000000000 --- a/scripts/dtc/include-prefixes/h8300 +++ /dev/null @@ -1 +0,0 @@ -../../../arch/h8300/boot/dts \ No newline at end of file -- cgit v1.2.3 From 3bc253c2e652cf5f12cd8c00d80d8ec55d67d1a7 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 19 May 2022 16:30:10 -0700 Subject: bpf: Add bpf_skc_to_mptcp_sock_proto This patch implements a new struct bpf_func_proto, named bpf_skc_to_mptcp_sock_proto. Define a new bpf_id BTF_SOCK_TYPE_MPTCP, and a new helper bpf_skc_to_mptcp_sock(), which invokes another new helper bpf_mptcp_sock_from_subflow() in net/mptcp/bpf.c to get struct mptcp_sock from a given subflow socket. v2: Emit BTF type, add func_id checks in verifier.c and bpf_trace.c, remove build check for CONFIG_BPF_JIT v5: Drop EXPORT_SYMBOL (Martin) Co-developed-by: Nicolas Rybowski Co-developed-by: Matthieu Baerts Signed-off-by: Nicolas Rybowski Signed-off-by: Matthieu Baerts Signed-off-by: Geliang Tang Signed-off-by: Mat Martineau Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20220519233016.105670-2-mathew.j.martineau@linux.intel.com --- include/linux/bpf.h | 1 + include/linux/btf_ids.h | 3 ++- include/net/mptcp.h | 6 ++++++ include/uapi/linux/bpf.h | 7 +++++++ kernel/bpf/verifier.c | 1 + kernel/trace/bpf_trace.c | 2 ++ net/core/filter.c | 18 ++++++++++++++++++ net/mptcp/Makefile | 2 ++ net/mptcp/bpf.c | 21 +++++++++++++++++++++ scripts/bpf_doc.py | 2 ++ tools/include/uapi/linux/bpf.h | 7 +++++++ 11 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 net/mptcp/bpf.c (limited to 'scripts') diff --git a/include/linux/bpf.h b/include/linux/bpf.h index c107392b0ba7..a3ef078401cf 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -2231,6 +2231,7 @@ extern const struct bpf_func_proto bpf_skc_to_tcp_timewait_sock_proto; extern const struct bpf_func_proto bpf_skc_to_tcp_request_sock_proto; extern const struct bpf_func_proto bpf_skc_to_udp6_sock_proto; extern const struct bpf_func_proto bpf_skc_to_unix_sock_proto; +extern const struct bpf_func_proto bpf_skc_to_mptcp_sock_proto; extern const struct bpf_func_proto bpf_copy_from_user_proto; extern const struct bpf_func_proto bpf_snprintf_btf_proto; extern const struct bpf_func_proto bpf_snprintf_proto; diff --git a/include/linux/btf_ids.h b/include/linux/btf_ids.h index bc5d9cc34e4c..335a19092368 100644 --- a/include/linux/btf_ids.h +++ b/include/linux/btf_ids.h @@ -178,7 +178,8 @@ extern struct btf_id_set name; BTF_SOCK_TYPE(BTF_SOCK_TYPE_TCP6, tcp6_sock) \ BTF_SOCK_TYPE(BTF_SOCK_TYPE_UDP, udp_sock) \ BTF_SOCK_TYPE(BTF_SOCK_TYPE_UDP6, udp6_sock) \ - BTF_SOCK_TYPE(BTF_SOCK_TYPE_UNIX, unix_sock) + BTF_SOCK_TYPE(BTF_SOCK_TYPE_UNIX, unix_sock) \ + BTF_SOCK_TYPE(BTF_SOCK_TYPE_MPTCP, mptcp_sock) enum { #define BTF_SOCK_TYPE(name, str) name, diff --git a/include/net/mptcp.h b/include/net/mptcp.h index 8b1afd6f5cc4..2ba09de955c7 100644 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@ -284,4 +284,10 @@ static inline int mptcpv6_init(void) { return 0; } static inline void mptcpv6_handle_mapped(struct sock *sk, bool mapped) { } #endif +#if defined(CONFIG_MPTCP) && defined(CONFIG_BPF_SYSCALL) +struct mptcp_sock *bpf_mptcp_sock_from_subflow(struct sock *sk); +#else +static inline struct mptcp_sock *bpf_mptcp_sock_from_subflow(struct sock *sk) { return NULL; } +#endif + #endif /* __NET_MPTCP_H */ diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 0210f85131b3..56688bee20d9 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -5172,6 +5172,12 @@ union bpf_attr { * Return * Map value associated to *key* on *cpu*, or **NULL** if no entry * was found or *cpu* is invalid. + * + * struct mptcp_sock *bpf_skc_to_mptcp_sock(void *sk) + * Description + * Dynamically cast a *sk* pointer to a *mptcp_sock* pointer. + * Return + * *sk* if casting is valid, or **NULL** otherwise. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -5370,6 +5376,7 @@ union bpf_attr { FN(ima_file_hash), \ FN(kptr_xchg), \ FN(map_lookup_percpu_elem), \ + FN(skc_to_mptcp_sock), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 9b59581026f8..14e8c17d3d8d 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -509,6 +509,7 @@ static bool is_ptr_cast_function(enum bpf_func_id func_id) func_id == BPF_FUNC_skc_to_tcp_sock || func_id == BPF_FUNC_skc_to_tcp6_sock || func_id == BPF_FUNC_skc_to_udp6_sock || + func_id == BPF_FUNC_skc_to_mptcp_sock || func_id == BPF_FUNC_skc_to_tcp_timewait_sock || func_id == BPF_FUNC_skc_to_tcp_request_sock; } diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 7141ca8a1c2d..10b157a6d73e 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -1705,6 +1705,8 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_skc_to_udp6_sock_proto; case BPF_FUNC_skc_to_unix_sock: return &bpf_skc_to_unix_sock_proto; + case BPF_FUNC_skc_to_mptcp_sock: + return &bpf_skc_to_mptcp_sock_proto; case BPF_FUNC_sk_storage_get: return &bpf_sk_storage_get_tracing_proto; case BPF_FUNC_sk_storage_delete: diff --git a/net/core/filter.c b/net/core/filter.c index fe0da529d00f..5af58eb48587 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -78,6 +78,7 @@ #include #include #include +#include static const struct bpf_func_proto * bpf_sk_base_func_proto(enum bpf_func_id func_id); @@ -11281,6 +11282,20 @@ const struct bpf_func_proto bpf_skc_to_unix_sock_proto = { .ret_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_UNIX], }; +BPF_CALL_1(bpf_skc_to_mptcp_sock, struct sock *, sk) +{ + BTF_TYPE_EMIT(struct mptcp_sock); + return (unsigned long)bpf_mptcp_sock_from_subflow(sk); +} + +const struct bpf_func_proto bpf_skc_to_mptcp_sock_proto = { + .func = bpf_skc_to_mptcp_sock, + .gpl_only = false, + .ret_type = RET_PTR_TO_BTF_ID_OR_NULL, + .arg1_type = ARG_PTR_TO_SOCK_COMMON, + .ret_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_MPTCP], +}; + BPF_CALL_1(bpf_sock_from_file, struct file *, file) { return (unsigned long)sock_from_file(file); @@ -11323,6 +11338,9 @@ bpf_sk_base_func_proto(enum bpf_func_id func_id) case BPF_FUNC_skc_to_unix_sock: func = &bpf_skc_to_unix_sock_proto; break; + case BPF_FUNC_skc_to_mptcp_sock: + func = &bpf_skc_to_mptcp_sock_proto; + break; case BPF_FUNC_ktime_get_coarse_ns: return &bpf_ktime_get_coarse_ns_proto; default: diff --git a/net/mptcp/Makefile b/net/mptcp/Makefile index e54daceac58b..99dddf08ca73 100644 --- a/net/mptcp/Makefile +++ b/net/mptcp/Makefile @@ -10,3 +10,5 @@ obj-$(CONFIG_INET_MPTCP_DIAG) += mptcp_diag.o mptcp_crypto_test-objs := crypto_test.o mptcp_token_test-objs := token_test.o obj-$(CONFIG_MPTCP_KUNIT_TEST) += mptcp_crypto_test.o mptcp_token_test.o + +obj-$(CONFIG_BPF_SYSCALL) += bpf.o diff --git a/net/mptcp/bpf.c b/net/mptcp/bpf.c new file mode 100644 index 000000000000..5a0a84ad94af --- /dev/null +++ b/net/mptcp/bpf.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Multipath TCP + * + * Copyright (c) 2020, Tessares SA. + * Copyright (c) 2022, SUSE. + * + * Author: Nicolas Rybowski + */ + +#define pr_fmt(fmt) "MPTCP: " fmt + +#include +#include "protocol.h" + +struct mptcp_sock *bpf_mptcp_sock_from_subflow(struct sock *sk) +{ + if (sk && sk_fullsock(sk) && sk->sk_protocol == IPPROTO_TCP && sk_is_mptcp(sk)) + return mptcp_sk(mptcp_subflow_ctx(sk)->conn); + + return NULL; +} diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index 096625242475..d5452f7eb996 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -633,6 +633,7 @@ class PrinterHelpers(Printer): 'struct socket', 'struct file', 'struct bpf_timer', + 'struct mptcp_sock', ] known_types = { '...', @@ -682,6 +683,7 @@ class PrinterHelpers(Printer): 'struct socket', 'struct file', 'struct bpf_timer', + 'struct mptcp_sock', } mapped_types = { 'u8': '__u8', diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 0210f85131b3..56688bee20d9 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -5172,6 +5172,12 @@ union bpf_attr { * Return * Map value associated to *key* on *cpu*, or **NULL** if no entry * was found or *cpu* is invalid. + * + * struct mptcp_sock *bpf_skc_to_mptcp_sock(void *sk) + * Description + * Dynamically cast a *sk* pointer to a *mptcp_sock* pointer. + * Return + * *sk* if casting is valid, or **NULL** otherwise. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -5370,6 +5376,7 @@ union bpf_attr { FN(ima_file_hash), \ FN(kptr_xchg), \ FN(map_lookup_percpu_elem), \ + FN(skc_to_mptcp_sock), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper -- cgit v1.2.3 From addf466389d9d78f255e8b15ac44ab4791029852 Mon Sep 17 00:00:00 2001 From: Mickaël Salaün Date: Mon, 12 Jul 2021 19:03:10 +0200 Subject: certs: Check that builtin blacklist hashes are valid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add and use a check-blacklist-hashes.awk script to make sure that the builtin blacklist hashes set with CONFIG_SYSTEM_BLACKLIST_HASH_LIST will effectively be taken into account as blacklisted hashes. This is useful to debug invalid hash formats, and it make sure that previous hashes which could have been loaded in the kernel, but silently ignored, are now noticed and deal with by the user at kernel build time. This also prevent stricter blacklist key description checking (provided by following commits) to failed for builtin hashes. Update CONFIG_SYSTEM_BLACKLIST_HASH_LIST help to explain the content of a hash string and how to generate certificate ones. Cc: David Howells Cc: David Woodhouse Cc: Eric Snowberg Cc: Jarkko Sakkinen Signed-off-by: Mickaël Salaün Link: https://lore.kernel.org/r/20210712170313.884724-3-mic@digikod.net Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- MAINTAINERS | 1 + certs/.gitignore | 1 + certs/Kconfig | 7 +++++-- certs/Makefile | 14 +++++++++++++- scripts/check-blacklist-hashes.awk | 37 +++++++++++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 3 deletions(-) create mode 100755 scripts/check-blacklist-hashes.awk (limited to 'scripts') diff --git a/MAINTAINERS b/MAINTAINERS index 4f2a63b0ec3b..bf41a67635ec 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4575,6 +4575,7 @@ L: keyrings@vger.kernel.org S: Maintained F: Documentation/admin-guide/module-signing.rst F: certs/ +F: scripts/check-blacklist-hashes.awk F: scripts/sign-file.c F: tools/certs/ diff --git a/certs/.gitignore b/certs/.gitignore index 9e42fe3e02f5..56637aceaf81 100644 --- a/certs/.gitignore +++ b/certs/.gitignore @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only +/blacklist_hashes_checked /extract-cert /x509_certificate_list /x509_revocation_list diff --git a/certs/Kconfig b/certs/Kconfig index 73d1350c223a..4bd385b25084 100644 --- a/certs/Kconfig +++ b/certs/Kconfig @@ -104,8 +104,11 @@ config SYSTEM_BLACKLIST_HASH_LIST help If set, this option should be the filename of a list of hashes in the form "", "", ... . This will be included into a C - wrapper to incorporate the list into the kernel. Each should - be a string of hex digits. + wrapper to incorporate the list into the kernel. Each must be a + string starting with a prefix ("tbs" or "bin"), then a colon (":"), and + finally an even number of hexadecimal lowercase characters (up to 128). + Certificate hashes can be generated with + tools/certs/print-cert-tbs-hash.sh . config SYSTEM_REVOCATION_LIST bool "Provide system-wide ring of revocation certificates" diff --git a/certs/Makefile b/certs/Makefile index d8443cfb1c40..1d26ae36af20 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -7,6 +7,18 @@ obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o c obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o common.o obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),) +quiet_cmd_check_blacklist_hashes = CHECK $(patsubst "%",%,$(2)) + cmd_check_blacklist_hashes = $(AWK) -f $(srctree)/scripts/check-blacklist-hashes.awk $(2); touch $@ + +$(eval $(call config_filename,SYSTEM_BLACKLIST_HASH_LIST)) + +$(obj)/blacklist_hashes.o: $(obj)/blacklist_hashes_checked + +CFLAGS_blacklist_hashes.o += -I$(srctree) + +targets += blacklist_hashes_checked +$(obj)/blacklist_hashes_checked: $(SYSTEM_BLACKLIST_HASH_LIST_SRCPREFIX)$(SYSTEM_BLACKLIST_HASH_LIST_FILENAME) scripts/check-blacklist-hashes.awk FORCE + $(call if_changed,check_blacklist_hashes,$(SYSTEM_BLACKLIST_HASH_LIST_SRCPREFIX)$(CONFIG_SYSTEM_BLACKLIST_HASH_LIST)) obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o else obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o @@ -21,7 +33,7 @@ $(obj)/system_certificates.o: $(obj)/x509_certificate_list $(obj)/x509_certificate_list: $(CONFIG_SYSTEM_TRUSTED_KEYS) $(obj)/extract-cert FORCE $(call if_changed,extract_certs) -targets += x509_certificate_list +targets += x509_certificate_list blacklist_hashes_checked # If module signing is requested, say by allyesconfig, but a key has not been # supplied, then one will need to be generated to make sure the build does not diff --git a/scripts/check-blacklist-hashes.awk b/scripts/check-blacklist-hashes.awk new file mode 100755 index 000000000000..107c1d3204d4 --- /dev/null +++ b/scripts/check-blacklist-hashes.awk @@ -0,0 +1,37 @@ +#!/usr/bin/awk -f +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright © 2020, Microsoft Corporation. All rights reserved. +# +# Author: Mickaël Salaün +# +# Check that a CONFIG_SYSTEM_BLACKLIST_HASH_LIST file contains a valid array of +# hash strings. Such string must start with a prefix ("tbs" or "bin"), then a +# colon (":"), and finally an even number of hexadecimal lowercase characters +# (up to 128). + +BEGIN { + RS = "," +} +{ + if (!match($0, "^[ \t\n\r]*\"([^\"]*)\"[ \t\n\r]*$", part1)) { + print "Not a string (item " NR "):", $0; + exit 1; + } + if (!match(part1[1], "^(tbs|bin):(.*)$", part2)) { + print "Unknown prefix (item " NR "):", part1[1]; + exit 1; + } + if (!match(part2[2], "^([0-9a-f]+)$", part3)) { + print "Not a lowercase hexadecimal string (item " NR "):", part2[2]; + exit 1; + } + if (length(part3[1]) > 128) { + print "Hash string too long (item " NR "):", part3[1]; + exit 1; + } + if (length(part3[1]) % 2 == 1) { + print "Not an even number of hexadecimal characters (item " NR "):", part3[1]; + exit 1; + } +} -- cgit v1.2.3 From 69c4cc99bbcbf3ef2e1901b569954e9226180840 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 12 May 2022 01:45:04 +0900 Subject: modpost: add sym_find_with_module() helper find_symbol() returns the first symbol found in the hash table. This table is global, so it may return a symbol from an unexpected module. There is a case where we want to search for a symbol with a given name in a specified module. Add sym_find_with_module(), which receives the module pointer as the second argument. It is equivalent to find_module() if NULL is passed as the module pointer. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Tested-by: Nathan Chancellor Tested-by: Sedat Dilek # LLVM-14 (x86-64) --- scripts/mod/modpost.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index a78b75f0eeb0..f36f02d4b79b 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -266,7 +266,7 @@ static void sym_add_unresolved(const char *name, struct module *mod, bool weak) list_add_tail(&sym->list, &mod->unresolved_symbols); } -static struct symbol *find_symbol(const char *name) +static struct symbol *sym_find_with_module(const char *name, struct module *mod) { struct symbol *s; @@ -275,12 +275,17 @@ static struct symbol *find_symbol(const char *name) name++; for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) { - if (strcmp(s->name, name) == 0) + if (strcmp(s->name, name) == 0 && (!mod || s->module == mod)) return s; } return NULL; } +static struct symbol *find_symbol(const char *name) +{ + return sym_find_with_module(name, NULL); +} + struct namespace_list { struct list_head list; char namespace[]; -- cgit v1.2.3 From f292d875d0dc700b3af0bef04c5abc1dc7b3b62c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 13 May 2022 20:39:21 +0900 Subject: modpost: extract symbol versions from *.cmd files Currently, CONFIG_MODVERSIONS needs extra link to embed the symbol versions into ELF objects. Then, modpost extracts the version CRCs from them. The following figures show how it currently works, and how I am trying to change it. Current implementation ====================== |----------| embed CRC -------------------------->| final | $(CC) $(LD) / |---------| | link for | -----> *.o -------> *.o -->| modpost | | vmlinux | / / | |-- *.mod.c -->| or | / genksyms / |---------| | module | *.c ------> *.symversions |----------| Genksyms outputs the calculated CRCs in the form of linker script (*.symversions), which is used by $(LD) to update the object. If CONFIG_LTO_CLANG=y, the build process is much more complex. Embedding the CRCs is postponed until the LLVM bitcode is converted into ELF, creating another intermediate *.prelink.o. However, this complexity is unneeded. There is no reason why we must embed version CRCs in objects so early. There is final link stage for vmlinux (scripts/link-vmlinux.sh) and modules (scripts/Makefile.modfinal). We can link CRCs at the very last moment. New implementation ================== |----------| --------------------------------------->| final | $(CC) / |---------| | link for | -----> *.o ---->| | | vmlinux | / | modpost |--- .vmlinux.export.c -->| or | / genksyms | |--- *.mod.c ------------>| module | *.c ------> *.cmd -->|---------| |----------| Pass the symbol versions to modpost as separate text data, which are available in *.cmd files. This commit changes modpost to extract CRCs from *.cmd files instead of from ELF objects. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Tested-by: Nathan Chancellor Reviewed-by: Sami Tolvanen Tested-by: Sedat Dilek # LLVM-14 (x86-64) --- scripts/mod/modpost.c | 179 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 131 insertions(+), 48 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index f36f02d4b79b..1e2949775e1b 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -383,19 +383,10 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod, return s; } -static void sym_set_crc(const char *name, unsigned int crc) +static void sym_set_crc(struct symbol *sym, unsigned int crc) { - struct symbol *s = find_symbol(name); - - /* - * Ignore stand-alone __crc_*, which might be auto-generated symbols - * such as __*_veneer in ARM ELF. - */ - if (!s) - return; - - s->crc = crc; - s->crc_valid = true; + sym->crc = crc; + sym->crc_valid = true; } static void *grab_file(const char *filename, size_t *size) @@ -618,33 +609,6 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) return 0; } -static void handle_modversion(const struct module *mod, - const struct elf_info *info, - const Elf_Sym *sym, const char *symname) -{ - unsigned int crc; - - if (sym->st_shndx == SHN_UNDEF) { - warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n" - "Is \"%s\" prototyped in ?\n", - symname, mod->name, mod->is_vmlinux ? "" : ".ko", - symname); - - return; - } - - if (sym->st_shndx == SHN_ABS) { - crc = sym->st_value; - } else { - unsigned int *crcp; - - /* symbol points to the CRC in the ELF object */ - crcp = sym_get_data(info, sym); - crc = TO_NATIVE(*crcp); - } - sym_set_crc(symname, crc); -} - static void handle_symbol(struct module *mod, struct elf_info *info, const Elf_Sym *sym, const char *symname) { @@ -1952,6 +1916,104 @@ static char *remove_dot(char *s) return s; } +/* + * The CRCs are recorded in .*.cmd files in the form of: + * #SYMVER + */ +static void extract_crcs_for_object(const char *object, struct module *mod) +{ + char cmd_file[PATH_MAX]; + char *buf, *p; + const char *base; + int dirlen, ret; + + base = strrchr(object, '/'); + if (base) { + base++; + dirlen = base - object; + } else { + dirlen = 0; + base = object; + } + + ret = snprintf(cmd_file, sizeof(cmd_file), "%.*s.%s.cmd", + dirlen, object, base); + if (ret >= sizeof(cmd_file)) { + error("%s: too long path was truncated\n", cmd_file); + return; + } + + buf = read_text_file(cmd_file); + p = buf; + + while ((p = strstr(p, "\n#SYMVER "))) { + char *name; + size_t namelen; + unsigned int crc; + struct symbol *sym; + + name = p + strlen("\n#SYMVER "); + + p = strchr(name, ' '); + if (!p) + break; + + namelen = p - name; + p++; + + if (!isdigit(*p)) + continue; /* skip this line */ + + crc = strtol(p, &p, 0); + if (*p != '\n') + continue; /* skip this line */ + + name[namelen] = '\0'; + + /* + * sym_find_with_module() may return NULL here. + * It typically occurs when CONFIG_TRIM_UNUSED_KSYMS=y. + * Since commit e1327a127703, genksyms calculates CRCs of all + * symbols, including trimmed ones. Ignore orphan CRCs. + */ + sym = sym_find_with_module(name, mod); + if (sym) + sym_set_crc(sym, crc); + } + + free(buf); +} + +/* + * The symbol versions (CRC) are recorded in the .*.cmd files. + * Parse them to retrieve CRCs for the current module. + */ +static void mod_set_crcs(struct module *mod) +{ + char objlist[PATH_MAX]; + char *buf, *p, *obj; + int ret; + + if (mod->is_vmlinux) { + strcpy(objlist, ".vmlinux.objs"); + } else { + /* objects for a module are listed in the *.mod file. */ + ret = snprintf(objlist, sizeof(objlist), "%s.mod", mod->name); + if (ret >= sizeof(objlist)) { + error("%s: too long path was truncated\n", objlist); + return; + } + } + + buf = read_text_file(objlist); + p = buf; + + while ((obj = strsep(&p, "\n")) && obj[0]) + extract_crcs_for_object(obj, mod); + + free(buf); +} + static void read_symbols(const char *modname) { const char *symname; @@ -2012,9 +2074,6 @@ static void read_symbols(const char *modname) if (strstarts(symname, "__kstrtabns_")) sym_update_namespace(symname + strlen("__kstrtabns_"), sym_get_data(&info, sym)); - if (strstarts(symname, "__crc_")) - handle_modversion(mod, &info, sym, - symname + strlen("__crc_")); } // check for static EXPORT_SYMBOL_* functions && global vars @@ -2042,12 +2101,17 @@ static void read_symbols(const char *modname) parse_elf_finish(&info); - /* Our trick to get versioning for module struct etc. - it's - * never passed as an argument to an exported function, so - * the automatic versioning doesn't pick it up, but it's really - * important anyhow */ - if (modversions) + if (modversions) { + /* + * Our trick to get versioning for module struct etc. - it's + * never passed as an argument to an exported function, so + * the automatic versioning doesn't pick it up, but it's really + * important anyhow. + */ sym_add_unresolved("module_layout", mod, false); + + mod_set_crcs(mod); + } } static void read_symbols_from_files(const char *filename) @@ -2204,6 +2268,23 @@ static void add_header(struct buffer *b, struct module *mod) buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); } +static void check_symversions(struct module *mod) +{ + struct symbol *sym; + + if (!modversions) + return; + + list_for_each_entry(sym, &mod->exported_symbols, list) { + if (!sym->crc_valid) { + warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n" + "Is \"%s\" prototyped in ?\n", + sym->name, mod->name, mod->is_vmlinux ? "" : ".ko", + sym->name); + } + } +} + /** * Record CRCs for unresolved symbols **/ @@ -2419,7 +2500,7 @@ static void read_dump(const char *fname) } s = sym_add_exported(symname, mod, gpl_only); s->is_static = false; - sym_set_crc(symname, crc); + sym_set_crc(s, crc); sym_update_namespace(symname, namespace); } free(buf); @@ -2545,6 +2626,8 @@ int main(int argc, char **argv) if (mod->from_dump) continue; + check_symversions(mod); + if (!mod->is_vmlinux) write_mod_c_file(mod); } -- cgit v1.2.3 From 97e03f521050c092919591e668107b3d69c5f426 Mon Sep 17 00:00:00 2001 From: Joanne Koong Date: Mon, 23 May 2022 14:07:07 -0700 Subject: bpf: Add verifier support for dynptrs This patch adds the bulk of the verifier work for supporting dynamic pointers (dynptrs) in bpf. A bpf_dynptr is opaque to the bpf program. It is a 16-byte structure defined internally as: struct bpf_dynptr_kern { void *data; u32 size; u32 offset; } __aligned(8); The upper 8 bits of *size* is reserved (it contains extra metadata about read-only status and dynptr type). Consequently, a dynptr only supports memory less than 16 MB. There are different types of dynptrs (eg malloc, ringbuf, ...). In this patchset, the most basic one, dynptrs to a bpf program's local memory, is added. For now only local memory that is of reg type PTR_TO_MAP_VALUE is supported. In the verifier, dynptr state information will be tracked in stack slots. When the program passes in an uninitialized dynptr (ARG_PTR_TO_DYNPTR | MEM_UNINIT), the stack slots corresponding to the frame pointer where the dynptr resides at are marked STACK_DYNPTR. For helper functions that take in initialized dynptrs (eg bpf_dynptr_read + bpf_dynptr_write which are added later in this patchset), the verifier enforces that the dynptr has been initialized properly by checking that their corresponding stack slots have been marked as STACK_DYNPTR. The 6th patch in this patchset adds test cases that the verifier should successfully reject, such as for example attempting to use a dynptr after doing a direct write into it inside the bpf program. Signed-off-by: Joanne Koong Signed-off-by: Andrii Nakryiko Acked-by: Andrii Nakryiko Acked-by: David Vernet Link: https://lore.kernel.org/bpf/20220523210712.3641569-2-joannelkoong@gmail.com --- include/linux/bpf.h | 28 ++++++ include/linux/bpf_verifier.h | 18 ++++ include/uapi/linux/bpf.h | 5 ++ kernel/bpf/verifier.c | 188 ++++++++++++++++++++++++++++++++++++++++- scripts/bpf_doc.py | 2 + tools/include/uapi/linux/bpf.h | 5 ++ 6 files changed, 243 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/include/linux/bpf.h b/include/linux/bpf.h index a9b1875212f6..b26c8176b9e0 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -392,10 +392,15 @@ enum bpf_type_flag { MEM_UNINIT = BIT(7 + BPF_BASE_TYPE_BITS), + /* DYNPTR points to memory local to the bpf program. */ + DYNPTR_TYPE_LOCAL = BIT(8 + BPF_BASE_TYPE_BITS), + __BPF_TYPE_FLAG_MAX, __BPF_TYPE_LAST_FLAG = __BPF_TYPE_FLAG_MAX - 1, }; +#define DYNPTR_TYPE_FLAG_MASK DYNPTR_TYPE_LOCAL + /* Max number of base types. */ #define BPF_BASE_TYPE_LIMIT (1UL << BPF_BASE_TYPE_BITS) @@ -438,6 +443,7 @@ enum bpf_arg_type { ARG_PTR_TO_CONST_STR, /* pointer to a null terminated read-only string */ ARG_PTR_TO_TIMER, /* pointer to bpf_timer */ ARG_PTR_TO_KPTR, /* pointer to referenced kptr */ + ARG_PTR_TO_DYNPTR, /* pointer to bpf_dynptr. See bpf_type_flag for dynptr type */ __BPF_ARG_TYPE_MAX, /* Extended arg_types. */ @@ -2376,4 +2382,26 @@ int bpf_bprintf_prepare(char *fmt, u32 fmt_size, const u64 *raw_args, u32 **bin_buf, u32 num_args); void bpf_bprintf_cleanup(void); +/* the implementation of the opaque uapi struct bpf_dynptr */ +struct bpf_dynptr_kern { + void *data; + /* Size represents the number of usable bytes of dynptr data. + * If for example the offset is at 4 for a local dynptr whose data is + * of type u64, the number of usable bytes is 4. + * + * The upper 8 bits are reserved. It is as follows: + * Bits 0 - 23 = size + * Bits 24 - 30 = dynptr type + * Bit 31 = whether dynptr is read-only + */ + u32 size; + u32 offset; +} __aligned(8); + +enum bpf_dynptr_type { + BPF_DYNPTR_TYPE_INVALID, + /* Points to memory that is local to the bpf program */ + BPF_DYNPTR_TYPE_LOCAL, +}; + #endif /* _LINUX_BPF_H */ diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 1f1e7f2ea967..af5b2135215e 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -72,6 +72,18 @@ struct bpf_reg_state { u32 mem_size; /* for PTR_TO_MEM | PTR_TO_MEM_OR_NULL */ + /* For dynptr stack slots */ + struct { + enum bpf_dynptr_type type; + /* A dynptr is 16 bytes so it takes up 2 stack slots. + * We need to track which slot is the first slot + * to protect against cases where the user may try to + * pass in an address starting at the second slot of the + * dynptr. + */ + bool first_slot; + } dynptr; + /* Max size from any of the above. */ struct { unsigned long raw1; @@ -174,9 +186,15 @@ enum bpf_stack_slot_type { STACK_SPILL, /* register spilled into stack */ STACK_MISC, /* BPF program wrote some data into this slot */ STACK_ZERO, /* BPF program wrote constant zero */ + /* A dynptr is stored in this stack slot. The type of dynptr + * is stored in bpf_stack_state->spilled_ptr.dynptr.type + */ + STACK_DYNPTR, }; #define BPF_REG_SIZE 8 /* size of eBPF register in bytes */ +#define BPF_DYNPTR_SIZE sizeof(struct bpf_dynptr_kern) +#define BPF_DYNPTR_NR_SLOTS (BPF_DYNPTR_SIZE / BPF_REG_SIZE) struct bpf_stack_state { struct bpf_reg_state spilled_ptr; diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 56688bee20d9..610944cb3389 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -6528,6 +6528,11 @@ struct bpf_timer { __u64 :64; } __attribute__((aligned(8))); +struct bpf_dynptr { + __u64 :64; + __u64 :64; +} __attribute__((aligned(8))); + struct bpf_sysctl { __u32 write; /* Sysctl is being read (= 0) or written (= 1). * Allows 1,2,4-byte read, but no write. diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 45153cbc2bd6..1fd0b81c3fec 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -259,6 +259,7 @@ struct bpf_call_arg_meta { u32 ret_btf_id; u32 subprogno; struct bpf_map_value_off_desc *kptr_off_desc; + u8 uninit_dynptr_regno; }; struct btf *btf_vmlinux; @@ -581,6 +582,7 @@ static char slot_type_char[] = { [STACK_SPILL] = 'r', [STACK_MISC] = 'm', [STACK_ZERO] = '0', + [STACK_DYNPTR] = 'd', }; static void print_liveness(struct bpf_verifier_env *env, @@ -596,6 +598,25 @@ static void print_liveness(struct bpf_verifier_env *env, verbose(env, "D"); } +static int get_spi(s32 off) +{ + return (-off - 1) / BPF_REG_SIZE; +} + +static bool is_spi_bounds_valid(struct bpf_func_state *state, int spi, int nr_slots) +{ + int allocated_slots = state->allocated_stack / BPF_REG_SIZE; + + /* We need to check that slots between [spi - nr_slots + 1, spi] are + * within [0, allocated_stack). + * + * Please note that the spi grows downwards. For example, a dynptr + * takes the size of two stack slots; the first slot will be at + * spi and the second slot will be at spi - 1. + */ + return spi - nr_slots + 1 >= 0 && spi < allocated_slots; +} + static struct bpf_func_state *func(struct bpf_verifier_env *env, const struct bpf_reg_state *reg) { @@ -647,6 +668,108 @@ static void mark_verifier_state_scratched(struct bpf_verifier_env *env) env->scratched_stack_slots = ~0ULL; } +static enum bpf_dynptr_type arg_to_dynptr_type(enum bpf_arg_type arg_type) +{ + switch (arg_type & DYNPTR_TYPE_FLAG_MASK) { + case DYNPTR_TYPE_LOCAL: + return BPF_DYNPTR_TYPE_LOCAL; + default: + return BPF_DYNPTR_TYPE_INVALID; + } +} + +static int mark_stack_slots_dynptr(struct bpf_verifier_env *env, struct bpf_reg_state *reg, + enum bpf_arg_type arg_type, int insn_idx) +{ + struct bpf_func_state *state = func(env, reg); + enum bpf_dynptr_type type; + int spi, i; + + spi = get_spi(reg->off); + + if (!is_spi_bounds_valid(state, spi, BPF_DYNPTR_NR_SLOTS)) + return -EINVAL; + + for (i = 0; i < BPF_REG_SIZE; i++) { + state->stack[spi].slot_type[i] = STACK_DYNPTR; + state->stack[spi - 1].slot_type[i] = STACK_DYNPTR; + } + + type = arg_to_dynptr_type(arg_type); + if (type == BPF_DYNPTR_TYPE_INVALID) + return -EINVAL; + + state->stack[spi].spilled_ptr.dynptr.first_slot = true; + state->stack[spi].spilled_ptr.dynptr.type = type; + state->stack[spi - 1].spilled_ptr.dynptr.type = type; + + return 0; +} + +static int unmark_stack_slots_dynptr(struct bpf_verifier_env *env, struct bpf_reg_state *reg) +{ + struct bpf_func_state *state = func(env, reg); + int spi, i; + + spi = get_spi(reg->off); + + if (!is_spi_bounds_valid(state, spi, BPF_DYNPTR_NR_SLOTS)) + return -EINVAL; + + for (i = 0; i < BPF_REG_SIZE; i++) { + state->stack[spi].slot_type[i] = STACK_INVALID; + state->stack[spi - 1].slot_type[i] = STACK_INVALID; + } + + state->stack[spi].spilled_ptr.dynptr.first_slot = false; + state->stack[spi].spilled_ptr.dynptr.type = 0; + state->stack[spi - 1].spilled_ptr.dynptr.type = 0; + + return 0; +} + +static bool is_dynptr_reg_valid_uninit(struct bpf_verifier_env *env, struct bpf_reg_state *reg) +{ + struct bpf_func_state *state = func(env, reg); + int spi = get_spi(reg->off); + int i; + + if (!is_spi_bounds_valid(state, spi, BPF_DYNPTR_NR_SLOTS)) + return true; + + for (i = 0; i < BPF_REG_SIZE; i++) { + if (state->stack[spi].slot_type[i] == STACK_DYNPTR || + state->stack[spi - 1].slot_type[i] == STACK_DYNPTR) + return false; + } + + return true; +} + +static bool is_dynptr_reg_valid_init(struct bpf_verifier_env *env, struct bpf_reg_state *reg, + enum bpf_arg_type arg_type) +{ + struct bpf_func_state *state = func(env, reg); + int spi = get_spi(reg->off); + int i; + + if (!is_spi_bounds_valid(state, spi, BPF_DYNPTR_NR_SLOTS) || + !state->stack[spi].spilled_ptr.dynptr.first_slot) + return false; + + for (i = 0; i < BPF_REG_SIZE; i++) { + if (state->stack[spi].slot_type[i] != STACK_DYNPTR || + state->stack[spi - 1].slot_type[i] != STACK_DYNPTR) + return false; + } + + /* ARG_PTR_TO_DYNPTR takes any type of dynptr */ + if (arg_type == ARG_PTR_TO_DYNPTR) + return true; + + return state->stack[spi].spilled_ptr.dynptr.type == arg_to_dynptr_type(arg_type); +} + /* The reg state of a pointer or a bounded scalar was saved when * it was spilled to the stack. */ @@ -5400,6 +5523,11 @@ static bool arg_type_is_release(enum bpf_arg_type type) return type & OBJ_RELEASE; } +static bool arg_type_is_dynptr(enum bpf_arg_type type) +{ + return base_type(type) == ARG_PTR_TO_DYNPTR; +} + static int int_ptr_type_to_size(enum bpf_arg_type type) { if (type == ARG_PTR_TO_INT) @@ -5539,6 +5667,7 @@ static const struct bpf_reg_types *compatible_reg_types[__BPF_ARG_TYPE_MAX] = { [ARG_PTR_TO_CONST_STR] = &const_str_ptr_types, [ARG_PTR_TO_TIMER] = &timer_types, [ARG_PTR_TO_KPTR] = &kptr_types, + [ARG_PTR_TO_DYNPTR] = &stack_ptr_types, }; static int check_reg_type(struct bpf_verifier_env *env, u32 regno, @@ -5628,8 +5757,13 @@ int check_func_arg_reg_off(struct bpf_verifier_env *env, bool fixed_off_ok = false; switch ((u32)type) { - case SCALAR_VALUE: /* Pointer types where reg offset is explicitly allowed: */ + case PTR_TO_STACK: + if (arg_type_is_dynptr(arg_type) && reg->off % BPF_REG_SIZE) { + verbose(env, "cannot pass in dynptr at an offset\n"); + return -EINVAL; + } + fallthrough; case PTR_TO_PACKET: case PTR_TO_PACKET_META: case PTR_TO_MAP_KEY: @@ -5639,7 +5773,7 @@ int check_func_arg_reg_off(struct bpf_verifier_env *env, case PTR_TO_MEM | MEM_ALLOC: case PTR_TO_BUF: case PTR_TO_BUF | MEM_RDONLY: - case PTR_TO_STACK: + case SCALAR_VALUE: /* Some of the argument types nevertheless require a * zero register offset. */ @@ -5837,6 +5971,36 @@ skip_type_check: bool zero_size_allowed = (arg_type == ARG_CONST_SIZE_OR_ZERO); err = check_mem_size_reg(env, reg, regno, zero_size_allowed, meta); + } else if (arg_type_is_dynptr(arg_type)) { + if (arg_type & MEM_UNINIT) { + if (!is_dynptr_reg_valid_uninit(env, reg)) { + verbose(env, "Dynptr has to be an uninitialized dynptr\n"); + return -EINVAL; + } + + /* We only support one dynptr being uninitialized at the moment, + * which is sufficient for the helper functions we have right now. + */ + if (meta->uninit_dynptr_regno) { + verbose(env, "verifier internal error: multiple uninitialized dynptr args\n"); + return -EFAULT; + } + + meta->uninit_dynptr_regno = regno; + } else if (!is_dynptr_reg_valid_init(env, reg, arg_type)) { + const char *err_extra = ""; + + switch (arg_type & DYNPTR_TYPE_FLAG_MASK) { + case DYNPTR_TYPE_LOCAL: + err_extra = "local "; + break; + default: + break; + } + verbose(env, "Expected an initialized %sdynptr as arg #%d\n", + err_extra, arg + 1); + return -EINVAL; + } } else if (arg_type_is_alloc_size(arg_type)) { if (!tnum_is_const(reg->var_off)) { verbose(env, "R%d is not a known constant'\n", @@ -6970,9 +7134,27 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn regs = cur_regs(env); + if (meta.uninit_dynptr_regno) { + /* we write BPF_DW bits (8 bytes) at a time */ + for (i = 0; i < BPF_DYNPTR_SIZE; i += 8) { + err = check_mem_access(env, insn_idx, meta.uninit_dynptr_regno, + i, BPF_DW, BPF_WRITE, -1, false); + if (err) + return err; + } + + err = mark_stack_slots_dynptr(env, ®s[meta.uninit_dynptr_regno], + fn->arg_type[meta.uninit_dynptr_regno - BPF_REG_1], + insn_idx); + if (err) + return err; + } + if (meta.release_regno) { err = -EINVAL; - if (meta.ref_obj_id) + if (arg_type_is_dynptr(fn->arg_type[meta.release_regno - BPF_REG_1])) + err = unmark_stack_slots_dynptr(env, ®s[meta.release_regno]); + else if (meta.ref_obj_id) err = release_reference(env, meta.ref_obj_id); /* meta.ref_obj_id can only be 0 if register that is meant to be * released is NULL, which must be > R0. diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index d5452f7eb996..855b937e7585 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -634,6 +634,7 @@ class PrinterHelpers(Printer): 'struct file', 'struct bpf_timer', 'struct mptcp_sock', + 'struct bpf_dynptr', ] known_types = { '...', @@ -684,6 +685,7 @@ class PrinterHelpers(Printer): 'struct file', 'struct bpf_timer', 'struct mptcp_sock', + 'struct bpf_dynptr', } mapped_types = { 'u8': '__u8', diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 56688bee20d9..610944cb3389 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -6528,6 +6528,11 @@ struct bpf_timer { __u64 :64; } __attribute__((aligned(8))); +struct bpf_dynptr { + __u64 :64; + __u64 :64; +} __attribute__((aligned(8))); + struct bpf_sysctl { __u32 write; /* Sysctl is being read (= 0) or written (= 1). * Allows 1,2,4-byte read, but no write. -- cgit v1.2.3 From 7b4537199a4a8480b8c3ba37a2d44765ce76cd9b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 13 May 2022 20:39:22 +0900 Subject: kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS include/{linux,asm-generic}/export.h defines a weak symbol, __crc_* as a placeholder. Genksyms writes the version CRCs into the linker script, which will be used for filling the __crc_* symbols. The linker script format depends on CONFIG_MODULE_REL_CRCS. If it is enabled, __crc_* holds the offset to the reference of CRC. It is time to get rid of this complexity. Now that modpost parses text files (.*.cmd) to collect all the CRCs, it can generate C code that will be linked to the vmlinux or modules. Generate a new C file, .vmlinux.export.c, which contains the CRCs of symbols exported by vmlinux. It is compiled and linked to vmlinux in scripts/link-vmlinux.sh. Put the CRCs of symbols exported by modules into the existing *.mod.c files. No additional build step is needed for modules. As before, *.mod.c are compiled and linked to *.ko in scripts/Makefile.modfinal. No linker magic is used here. The new C implementation works in the same way, whether CONFIG_RELOCATABLE is enabled or not. CONFIG_MODULE_REL_CRCS is no longer needed. Previously, Kbuild invoked additional $(LD) to update the CRCs in objects, but this step is unneeded too. Signed-off-by: Masahiro Yamada Tested-by: Nathan Chancellor Tested-by: Nicolas Schier Reviewed-by: Nicolas Schier Tested-by: Sedat Dilek # LLVM-14 (x86-64) --- arch/m68k/include/asm/Kbuild | 1 + arch/m68k/include/asm/export.h | 2 -- arch/powerpc/Kconfig | 1 - arch/s390/Kconfig | 1 - arch/um/Kconfig | 1 - include/asm-generic/export.h | 22 ++++++++-------------- include/linux/export-internal.h | 17 +++++++++++++++++ include/linux/export.h | 30 ++++++++---------------------- init/Kconfig | 4 ---- kernel/module.c | 10 +--------- scripts/Makefile.build | 27 ++++----------------------- scripts/Makefile.vmlinux | 32 ++++++++++++++++++++++++++++++++ scripts/genksyms/genksyms.c | 18 ++++-------------- scripts/link-vmlinux.sh | 10 +++++++++- scripts/mod/modpost.c | 28 ++++++++++++++++++++++++---- 15 files changed, 108 insertions(+), 96 deletions(-) delete mode 100644 arch/m68k/include/asm/export.h create mode 100644 include/linux/export-internal.h create mode 100644 scripts/Makefile.vmlinux (limited to 'scripts') diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild index 0dbf9c5c6fae..1b720299deb1 100644 --- a/arch/m68k/include/asm/Kbuild +++ b/arch/m68k/include/asm/Kbuild @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 generated-y += syscall_table.h +generic-y += export.h generic-y += extable.h generic-y += kvm_para.h generic-y += mcs_spinlock.h diff --git a/arch/m68k/include/asm/export.h b/arch/m68k/include/asm/export.h deleted file mode 100644 index b53008b67ce1..000000000000 --- a/arch/m68k/include/asm/export.h +++ /dev/null @@ -1,2 +0,0 @@ -#define KCRC_ALIGN 2 -#include diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 174edabb74fa..a4e8dd889e29 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -566,7 +566,6 @@ config RELOCATABLE bool "Build a relocatable kernel" depends on PPC64 || (FLATMEM && (44x || FSL_BOOKE)) select NONSTATIC_KERNEL - select MODULE_REL_CRCS if MODVERSIONS help This builds a kernel image that is capable of running at the location the kernel is loaded at. For ppc32, there is no any diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 77b5a03de13a..aa5848004c76 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -567,7 +567,6 @@ endchoice config RELOCATABLE bool "Build a relocatable kernel" - select MODULE_REL_CRCS if MODVERSIONS default y help This builds a kernel image that retains relocation information diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 4d398b80aea8..e8983d098e73 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -106,7 +106,6 @@ config LD_SCRIPT_DYN bool default y depends on !LD_SCRIPT_STATIC - select MODULE_REL_CRCS if MODVERSIONS config LD_SCRIPT_DYN_RPATH bool "set rpath in the binary" if EXPERT diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 07a36a874dca..5e4b1f2369d2 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -2,6 +2,14 @@ #ifndef __ASM_GENERIC_EXPORT_H #define __ASM_GENERIC_EXPORT_H +/* + * This comment block is used by fixdep. Please do not remove. + * + * When CONFIG_MODVERSIONS is changed from n to y, all source files having + * EXPORT_SYMBOL variants must be re-compiled because genksyms is run as a + * side effect of the *.o build rule. + */ + #ifndef KSYM_FUNC #define KSYM_FUNC(x) x #endif @@ -12,9 +20,6 @@ #else #define KSYM_ALIGN 4 #endif -#ifndef KCRC_ALIGN -#define KCRC_ALIGN 4 -#endif .macro __put, val, name #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS @@ -43,17 +48,6 @@ __ksymtab_\name: __kstrtab_\name: .asciz "\name" .previous -#ifdef CONFIG_MODVERSIONS - .section ___kcrctab\sec+\name,"a" - .balign KCRC_ALIGN -#if defined(CONFIG_MODULE_REL_CRCS) - .long __crc_\name - . -#else - .long __crc_\name -#endif - .weak __crc_\name - .previous -#endif #endif .endm diff --git a/include/linux/export-internal.h b/include/linux/export-internal.h new file mode 100644 index 000000000000..c2b1d4fd5987 --- /dev/null +++ b/include/linux/export-internal.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Please do not include this explicitly. + * This is used by C files generated by modpost. + */ + +#ifndef __LINUX_EXPORT_INTERNAL_H__ +#define __LINUX_EXPORT_INTERNAL_H__ + +#include +#include + +/* __used is needed to keep __crc_* for LTO */ +#define SYMBOL_CRC(sym, crc, sec) \ + u32 __section("___kcrctab" sec "+" #sym) __used __crc_##sym = crc + +#endif /* __LINUX_EXPORT_INTERNAL_H__ */ diff --git a/include/linux/export.h b/include/linux/export.h index 27d848712b90..565c5ffcb26f 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -11,6 +11,14 @@ * hackers place grumpy comments in header files. */ +/* + * This comment block is used by fixdep. Please do not remove. + * + * When CONFIG_MODVERSIONS is changed from n to y, all source files having + * EXPORT_SYMBOL variants must be re-compiled because genksyms is run as a + * side effect of the *.o build rule. + */ + #ifndef __ASSEMBLY__ #ifdef MODULE extern struct module __this_module; @@ -19,26 +27,6 @@ extern struct module __this_module; #define THIS_MODULE ((struct module *)0) #endif -#ifdef CONFIG_MODVERSIONS -/* Mark the CRC weak since genksyms apparently decides not to - * generate a checksums for some symbols */ -#if defined(CONFIG_MODULE_REL_CRCS) -#define __CRC_SYMBOL(sym, sec) \ - asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \ - " .weak __crc_" #sym " \n" \ - " .long __crc_" #sym " - . \n" \ - " .previous \n") -#else -#define __CRC_SYMBOL(sym, sec) \ - asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \ - " .weak __crc_" #sym " \n" \ - " .long __crc_" #sym " \n" \ - " .previous \n") -#endif -#else -#define __CRC_SYMBOL(sym, sec) -#endif - #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS #include /* @@ -85,7 +73,6 @@ struct kernel_symbol { /* * For every exported symbol, do the following: * - * - If applicable, place a CRC entry in the __kcrctab section. * - Put the name of the symbol and namespace (empty string "" for none) in * __ksymtab_strings. * - Place a struct kernel_symbol entry in the __ksymtab section. @@ -98,7 +85,6 @@ struct kernel_symbol { extern typeof(sym) sym; \ extern const char __kstrtab_##sym[]; \ extern const char __kstrtabns_##sym[]; \ - __CRC_SYMBOL(sym, sec); \ asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1 \n" \ "__kstrtab_" #sym ": \n" \ " .asciz \"" #sym "\" \n" \ diff --git a/init/Kconfig b/init/Kconfig index ddcbefe535e9..f5b14318dfcb 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2136,10 +2136,6 @@ config ASM_MODVERSIONS assembly. This can be enabled only when the target architecture supports it. -config MODULE_REL_CRCS - bool - depends on MODVERSIONS - config MODULE_SRCVERSION_ALL bool "Source checksum for all modules" help diff --git a/kernel/module.c b/kernel/module.c index 6cea788fd965..c9e2342da28e 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1231,11 +1231,6 @@ static int try_to_force_load(struct module *mod, const char *reason) #ifdef CONFIG_MODVERSIONS -static u32 resolve_rel_crc(const s32 *crc) -{ - return *(u32 *)((void *)crc + *crc); -} - static int check_version(const struct load_info *info, const char *symname, struct module *mod, @@ -1264,10 +1259,7 @@ static int check_version(const struct load_info *info, if (strcmp(versions[i].name, symname) != 0) continue; - if (IS_ENABLED(CONFIG_MODULE_REL_CRCS)) - crcval = resolve_rel_crc(crc); - else - crcval = *crc; + crcval = *crc; if (versions[i].crc == crcval) return 1; pr_debug("Found checksum %X vs module %lX\n", diff --git a/scripts/Makefile.build b/scripts/Makefile.build index a1023868775f..ddd9080fc028 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -128,7 +128,6 @@ $(obj)/%.i: $(src)/%.c FORCE genksyms = scripts/genksyms/genksyms \ $(if $(1), -T $(2)) \ - $(if $(CONFIG_MODULE_REL_CRCS), -R) \ $(if $(KBUILD_PRESERVE), -p) \ -r $(or $(wildcard $(2:.symtypes=.symref)), /dev/null) @@ -162,19 +161,11 @@ ifdef CONFIG_MODVERSIONS # o if .o doesn't contain a __ksymtab version, i.e. does # not export symbols, it's done. # o otherwise, we calculate symbol versions using the good old -# genksyms on the preprocessed source and postprocess them in a way -# that they are usable as a linker script -# o generate .tmp_.o from .o using the linker to -# replace the unresolved symbols __crc_exported_symbol with -# the actual value of the checksum generated by genksyms -# o remove .tmp_.o to .o +# genksyms on the preprocessed source and dump them into the .cmd file. +# o modpost will extract versions from that file and create *.c files that will +# be compiled and linked to the kernel and/or modules. -# Generate .o.symversions files for each .o with exported symbols, and link these -# to the kernel and/or modules at the end. - -genksyms_format_rel_crc := [^_]*__crc_\([^ ]*\) = \.; LONG(\([^)]*\)).* -genksyms_format_normal := __crc_\(.*\) = \(.*\); -genksyms_format := $(if $(CONFIG_MODULE_REL_CRCS),$(genksyms_format_rel_crc),$(genksyms_format_normal)) +genksyms_format := __crc_\(.*\) = \(.*\); gen_symversions = \ if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then \ @@ -188,12 +179,6 @@ gen_symversions = \ cmd_gen_symversions_c = $(call gen_symversions,c) -cmd_modversions = \ - if [ -r $@.symversions ]; then \ - $(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \ - -T $@.symversions; \ - mv -f $(@D)/.tmp_$(@F) $@; \ - fi endif ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT @@ -273,7 +258,6 @@ define rule_cc_o_c $(call cmd,checkdoc) $(call cmd,gen_objtooldep) $(call cmd,gen_symversions_c) - $(if $(CONFIG_LTO_CLANG),,$(call cmd,modversions)) $(call cmd,record_mcount) endef @@ -282,7 +266,6 @@ define rule_as_o_S $(call cmd,gen_ksymdeps) $(call cmd,gen_objtooldep) $(call cmd,gen_symversions_S) - $(call cmd,modversions) endef # Built-in and composite module parts @@ -296,8 +279,6 @@ ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) quiet_cmd_cc_prelink_modules = LD [M] $@ cmd_cc_prelink_modules = \ $(LD) $(ld_flags) -r -o $@ \ - $(shell [ -s $(@:.prelink.o=.o.symversions) ] && \ - echo -T $(@:.prelink.o=.o.symversions)) \ --whole-archive $(filter-out FORCE,$^) \ $(cmd_objtool) diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux new file mode 100644 index 000000000000..7a63abf22399 --- /dev/null +++ b/scripts/Makefile.vmlinux @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: GPL-2.0-only + +include include/config/auto.conf +include $(srctree)/scripts/Kbuild.include + +# for c_flags +include $(srctree)/scripts/Makefile.lib + +quiet_cmd_cc_o_c = CC $@ + cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< + +%.o: %.c FORCE + $(call if_changed_dep,cc_o_c) + +targets := $(MAKECMDGOALS) + +# Add FORCE to the prequisites of a target to force it to be always rebuilt. +# --------------------------------------------------------------------------- + +PHONY += FORCE +FORCE: + +# Read all saved command lines and dependencies for the $(targets) we +# may be building above, using $(if_changed{,_dep}). As an +# optimization, we don't need to read them if the target does not +# exist, we will rebuild anyway in that case. + +existing-targets := $(wildcard $(sort $(targets))) + +-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) + +.PHONY: $(PHONY) diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index 4827c5abe5b7..67b23cc0df0f 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c @@ -33,7 +33,7 @@ char *cur_filename; int in_source_file; static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types, - flag_preserve, flag_warnings, flag_rel_crcs; + flag_preserve, flag_warnings; static int errors; static int nsyms; @@ -680,11 +680,7 @@ void export_symbol(const char *name) if (flag_dump_defs) fputs(">\n", debugfile); - /* Used as a linker script. */ - printf(!flag_rel_crcs ? "__crc_%s = 0x%08lx;\n" : - "SECTIONS { .rodata : ALIGN(4) { " - "__crc_%s = .; LONG(0x%08lx); } }\n", - name, crc); + printf("__crc_%s = 0x%08lx;\n", name, crc); } } @@ -733,7 +729,6 @@ static void genksyms_usage(void) " -q, --quiet Disable warnings (default)\n" " -h, --help Print this message\n" " -V, --version Print the release version\n" - " -R, --relative-crc Emit section relative symbol CRCs\n" #else /* __GNU_LIBRARY__ */ " -s Select symbol prefix\n" " -d Increment the debug level (repeatable)\n" @@ -745,7 +740,6 @@ static void genksyms_usage(void) " -q Disable warnings (default)\n" " -h Print this message\n" " -V Print the release version\n" - " -R Emit section relative symbol CRCs\n" #endif /* __GNU_LIBRARY__ */ , stderr); } @@ -766,14 +760,13 @@ int main(int argc, char **argv) {"preserve", 0, 0, 'p'}, {"version", 0, 0, 'V'}, {"help", 0, 0, 'h'}, - {"relative-crc", 0, 0, 'R'}, {0, 0, 0, 0} }; - while ((o = getopt_long(argc, argv, "s:dwqVDr:T:phR", + while ((o = getopt_long(argc, argv, "s:dwqVDr:T:ph", &long_opts[0], NULL)) != EOF) #else /* __GNU_LIBRARY__ */ - while ((o = getopt(argc, argv, "s:dwqVDr:T:phR")) != EOF) + while ((o = getopt(argc, argv, "s:dwqVDr:T:ph")) != EOF) #endif /* __GNU_LIBRARY__ */ switch (o) { case 'd': @@ -813,9 +806,6 @@ int main(int argc, char **argv) case 'h': genksyms_usage(); return 0; - case 'R': - flag_rel_crcs = 1; - break; default: genksyms_usage(); return 1; diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index eceb3ee7ec06..db34dc3163ae 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -90,7 +90,6 @@ modpost_link() if is_enabled CONFIG_MODVERSIONS; then gen_symversions - lds="${lds} -T .tmp_symversions.lds" fi # This might take a while, so indicate that we're doing @@ -183,6 +182,10 @@ vmlinux_link() libs="${KBUILD_VMLINUX_LIBS}" fi + if is_enabled CONFIG_MODULES; then + objs="${objs} .vmlinux.export.o" + fi + if [ "${SRCARCH}" = "um" ]; then wl=-Wl, ld="${CC}" @@ -312,6 +315,7 @@ cleanup() rm -f vmlinux.o rm -f .vmlinux.d rm -f .vmlinux.objs + rm -f .vmlinux.export.c } # Use "make V=1" to debug this script @@ -363,6 +367,10 @@ info GEN modules.builtin tr '\0' '\n' < modules.builtin.modinfo | sed -n 's/^[[:alnum:]:_]*\.file=//p' | tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$/.ko/' > modules.builtin +if is_enabled CONFIG_MODULES; then + ${MAKE} -f "${srctree}/scripts/Makefile.vmlinux" .vmlinux.export.o +fi + btf_vmlinux_bin_o="" if is_enabled CONFIG_DEBUG_INFO_BTF; then btf_vmlinux_bin_o=.btf.vmlinux.bin.o diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 1e2949775e1b..42e949cbc255 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2234,6 +2234,7 @@ static void add_header(struct buffer *b, struct module *mod) buf_printf(b, "#define INCLUDE_VERMAGIC\n"); buf_printf(b, "#include \n"); buf_printf(b, "#include \n"); + buf_printf(b, "#include \n"); buf_printf(b, "#include \n"); buf_printf(b, "#include \n"); buf_printf(b, "\n"); @@ -2268,20 +2269,26 @@ static void add_header(struct buffer *b, struct module *mod) buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); } -static void check_symversions(struct module *mod) +static void add_exported_symbols(struct buffer *buf, struct module *mod) { struct symbol *sym; if (!modversions) return; + /* record CRCs for exported symbols */ + buf_printf(buf, "\n"); list_for_each_entry(sym, &mod->exported_symbols, list) { if (!sym->crc_valid) { warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n" "Is \"%s\" prototyped in ?\n", sym->name, mod->name, mod->is_vmlinux ? "" : ".ko", sym->name); + continue; } + + buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x, \"%s\");\n", + sym->name, sym->crc, sym->is_gpl_only ? "_gpl" : ""); } } @@ -2418,6 +2425,18 @@ static void write_if_changed(struct buffer *b, const char *fname) write_buf(b, fname); } +static void write_vmlinux_export_c_file(struct module *mod) +{ + struct buffer buf = { }; + + buf_printf(&buf, + "#include \n"); + + add_exported_symbols(&buf, mod); + write_if_changed(&buf, ".vmlinux.export.c"); + free(buf.p); +} + /* do sanity checks, and generate *.mod.c file */ static void write_mod_c_file(struct module *mod) { @@ -2429,6 +2448,7 @@ static void write_mod_c_file(struct module *mod) check_exports(mod); add_header(&buf, mod); + add_exported_symbols(&buf, mod); add_versions(&buf, mod); add_depends(&buf, mod); add_moddevtable(&buf, mod); @@ -2626,9 +2646,9 @@ int main(int argc, char **argv) if (mod->from_dump) continue; - check_symversions(mod); - - if (!mod->is_vmlinux) + if (mod->is_vmlinux) + write_vmlinux_export_c_file(mod); + else write_mod_c_file(mod); } -- cgit v1.2.3 From 7375cbcf2343a9337b19846e76dfd94c3af98a27 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 13 May 2022 20:39:23 +0900 Subject: kbuild: stop merging *.symversions Now modpost reads symbol versions from .*.cmd files. The merged *.symversions are no longer needed. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Tested-by: Nathan Chancellor Tested-by: Sedat Dilek # LLVM-14 (x86-64) --- scripts/Makefile.build | 21 ++------------------- scripts/link-vmlinux.sh | 19 ------------------- 2 files changed, 2 insertions(+), 38 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index ddd9080fc028..dff9220135c4 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -390,17 +390,6 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler $(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ; $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; -# combine symversions for later processing -ifeq ($(CONFIG_LTO_CLANG) $(CONFIG_MODVERSIONS),y y) - cmd_update_lto_symversions = \ - rm -f $@.symversions \ - $(foreach n, $(filter-out FORCE,$^), \ - $(if $(shell test -s $(n).symversions && echo y), \ - ; cat $(n).symversions >> $@.symversions)) -else - cmd_update_lto_symversions = echo >/dev/null -endif - # # Rule to compile a set of .o files into one .a file (without symbol table) # @@ -408,11 +397,8 @@ endif quiet_cmd_ar_builtin = AR $@ cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs) -quiet_cmd_ar_and_symver = AR $@ - cmd_ar_and_symver = $(cmd_update_lto_symversions); $(cmd_ar_builtin) - $(obj)/built-in.a: $(real-obj-y) FORCE - $(call if_changed,ar_and_symver) + $(call if_changed,ar_builtin) # # Rule to create modules.order file @@ -432,16 +418,13 @@ $(obj)/modules.order: $(obj-m) FORCE # # Rule to compile a set of .o files into one .a file (with symbol table) # -quiet_cmd_ar_lib = AR $@ - cmd_ar_lib = $(cmd_update_lto_symversions); $(cmd_ar) $(obj)/lib.a: $(lib-y) FORCE - $(call if_changed,ar_lib) + $(call if_changed,ar) ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) quiet_cmd_link_multi-m = AR [M] $@ cmd_link_multi-m = \ - $(cmd_update_lto_symversions); \ rm -f $@; \ $(AR) cDPrsT $@ @$(patsubst %.o,%.mod,$@) else diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index db34dc3163ae..eb6721e2fc47 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -56,20 +56,6 @@ gen_initcalls() > .tmp_initcalls.lds } -# If CONFIG_LTO_CLANG is selected, collect generated symbol versions into -# .tmp_symversions.lds -gen_symversions() -{ - info GEN .tmp_symversions.lds - rm -f .tmp_symversions.lds - - for o in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do - if [ -f ${o}.symversions ]; then - cat ${o}.symversions >> .tmp_symversions.lds - fi - done -} - # Link of vmlinux.o used for section mismatch analysis # ${1} output file modpost_link() @@ -88,10 +74,6 @@ modpost_link() gen_initcalls lds="-T .tmp_initcalls.lds" - if is_enabled CONFIG_MODVERSIONS; then - gen_symversions - fi - # This might take a while, so indicate that we're doing # an LTO link info LTO ${1} @@ -307,7 +289,6 @@ cleanup() rm -f .btf.* rm -f .tmp_System.map rm -f .tmp_initcalls.lds - rm -f .tmp_symversions.lds rm -f .tmp_vmlinux* rm -f System.map rm -f vmlinux -- cgit v1.2.3 From 5ce2176b81f77366bd02c27509b83049f0020544 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 13 May 2022 20:39:24 +0900 Subject: genksyms: adjust the output format to modpost Make genksyms output symbol versions in the format modpost expects, so the 'sed' is unneeded. This commit makes *.symversions completely unneeded. I will keep *.symversions in .gitignore and 'make clean' for a while. Otherwise, 'git status' might be surprising. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Tested-by: Nathan Chancellor Tested-by: Sedat Dilek # LLVM-14 (x86-64) --- scripts/Makefile.build | 6 ------ scripts/genksyms/genksyms.c | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index dff9220135c4..461998a2ad2b 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -165,16 +165,10 @@ ifdef CONFIG_MODVERSIONS # o modpost will extract versions from that file and create *.c files that will # be compiled and linked to the kernel and/or modules. -genksyms_format := __crc_\(.*\) = \(.*\); - gen_symversions = \ if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then \ $(call cmd_gensymtypes_$(1),$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ - > $@.symversions; \ - sed -n 's/$(genksyms_format)/$(pound)SYMVER \1 \2/p' $@.symversions \ >> $(dot-target).cmd; \ - else \ - rm -f $@.symversions; \ fi cmd_gen_symversions_c = $(call gen_symversions,c) diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index 67b23cc0df0f..f5dfdb9d80e9 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c @@ -680,7 +680,7 @@ void export_symbol(const char *name) if (flag_dump_defs) fputs(">\n", debugfile); - printf("__crc_%s = 0x%08lx;\n", name, crc); + printf("#SYMVER %s 0x%08lx\n", name, crc); } } -- cgit v1.2.3 From d37aa2efc89b387cda93bf15317883519683d435 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 24 May 2022 22:55:41 +0900 Subject: gcc-plugins: use KERNELVERSION for plugin version Commit 61f60bac8c05 ("gcc-plugins: Change all version strings match kernel") broke parallel builds. Instead of adding the dependency between GCC plugins and utsrelease.h, let's use KERNELVERSION, which does not require any build artifact. Another reason why I want to avoid utsrelease.h is because it depends on CONFIG_LOCALVERSION(_AUTO) and localversion* files. (include/generated/utsrelease.h depends on include/config/kernel.release, which is generated by scripts/setlocalversion) I want to keep host tools independent of the kernel configuration. There is no good reason to rebuild GCC plugins just because of CONFIG_LOCALVERSION being changed. We just want to associate the plugin versions with the kernel source version. KERNELVERSION should be enough for our purpose. Fixes: 61f60bac8c05 ("gcc-plugins: Change all version strings match kernel") Reported-by: kernel test robot Link: https://lore.kernel.org/linux-mm/202205230239.EZxeZ3Fv-lkp@intel.com Reported-by: Guenter Roeck Signed-off-by: Masahiro Yamada Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220524135541.1453693-1-masahiroy@kernel.org --- scripts/gcc-plugins/Makefile | 2 +- scripts/gcc-plugins/latent_entropy_plugin.c | 2 +- scripts/gcc-plugins/randomize_layout_plugin.c | 2 +- scripts/gcc-plugins/sancov_plugin.c | 2 +- scripts/gcc-plugins/stackleak_plugin.c | 2 +- scripts/gcc-plugins/structleak_plugin.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile index 6f0aecad5d67..b34d11e22636 100644 --- a/scripts/gcc-plugins/Makefile +++ b/scripts/gcc-plugins/Makefile @@ -28,7 +28,7 @@ GCC_PLUGINS_DIR = $(shell $(CC) -print-file-name=plugin) plugin_cxxflags = -Wp,-MMD,$(depfile) $(KBUILD_HOSTCXXFLAGS) -fPIC \ -include $(srctree)/include/linux/compiler-version.h \ - -include $(objtree)/include/generated/utsrelease.h \ + -DPLUGIN_VERSION=$(call stringify,$(KERNELVERSION)) \ -I $(GCC_PLUGINS_DIR)/include -I $(obj) -std=gnu++11 \ -fno-rtti -fno-exceptions -fasynchronous-unwind-tables \ -ggdb -Wno-narrowing -Wno-unused-variable \ diff --git a/scripts/gcc-plugins/latent_entropy_plugin.c b/scripts/gcc-plugins/latent_entropy_plugin.c index 5d415b2572a8..848918764174 100644 --- a/scripts/gcc-plugins/latent_entropy_plugin.c +++ b/scripts/gcc-plugins/latent_entropy_plugin.c @@ -82,7 +82,7 @@ __visible int plugin_is_GPL_compatible; static GTY(()) tree latent_entropy_decl; static struct plugin_info latent_entropy_plugin_info = { - .version = UTS_RELEASE, + .version = PLUGIN_VERSION, .help = "disable\tturn off latent entropy instrumentation\n", }; diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index ea2aea570404..951b74ba1b24 100644 --- a/scripts/gcc-plugins/randomize_layout_plugin.c +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -34,7 +34,7 @@ __visible int plugin_is_GPL_compatible; static int performance_mode; static struct plugin_info randomize_layout_plugin_info = { - .version = UTS_RELEASE, + .version = PLUGIN_VERSION, .help = "disable\t\t\tdo not activate plugin\n" "performance-mode\tenable cacheline-aware layout randomization\n" }; diff --git a/scripts/gcc-plugins/sancov_plugin.c b/scripts/gcc-plugins/sancov_plugin.c index f3d629555b84..b76cb9c42cec 100644 --- a/scripts/gcc-plugins/sancov_plugin.c +++ b/scripts/gcc-plugins/sancov_plugin.c @@ -26,7 +26,7 @@ __visible int plugin_is_GPL_compatible; tree sancov_fndecl; static struct plugin_info sancov_plugin_info = { - .version = UTS_RELEASE, + .version = PLUGIN_VERSION, .help = "sancov plugin\n", }; diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c index de817d54b8af..ff91885f9470 100644 --- a/scripts/gcc-plugins/stackleak_plugin.c +++ b/scripts/gcc-plugins/stackleak_plugin.c @@ -44,7 +44,7 @@ static bool verbose = false; static GTY(()) tree track_function_decl; static struct plugin_info stackleak_plugin_info = { - .version = UTS_RELEASE, + .version = PLUGIN_VERSION, .help = "track-min-size=nn\ttrack stack for functions with a stack frame size >= nn bytes\n" "arch=target_arch\tspecify target build arch\n" "disable\t\tdo not activate the plugin\n" diff --git a/scripts/gcc-plugins/structleak_plugin.c b/scripts/gcc-plugins/structleak_plugin.c index 86b608a24ec0..8bc04068ed39 100644 --- a/scripts/gcc-plugins/structleak_plugin.c +++ b/scripts/gcc-plugins/structleak_plugin.c @@ -37,7 +37,7 @@ __visible int plugin_is_GPL_compatible; static struct plugin_info structleak_plugin_info = { - .version = UTS_RELEASE, + .version = PLUGIN_VERSION, .help = "disable\tdo not activate plugin\n" "byref\tinit structs passed by reference\n" "byref-all\tinit anything passed by reference\n" -- cgit v1.2.3 From 23a0cb8e3225122496bfa79172005c587c2d64bf Mon Sep 17 00:00:00 2001 From: Jing Leng Date: Tue, 17 May 2022 18:51:28 +0800 Subject: kbuild: Fix include path in scripts/Makefile.modpost When building an external module, if users don't need to separate the compilation output and source code, they run the following command: "make -C $(LINUX_SRC_DIR) M=$(PWD)". At this point, "$(KBUILD_EXTMOD)" and "$(src)" are the same. If they need to separate them, they run "make -C $(KERNEL_SRC_DIR) O=$(KERNEL_OUT_DIR) M=$(OUT_DIR) src=$(PWD)". Before running the command, they need to copy "Kbuild" or "Makefile" to "$(OUT_DIR)" to prevent compilation failure. So the kernel should change the included path to avoid the copy operation. Signed-off-by: Jing Leng [masahiro: I do not think "M=$(OUT_DIR) src=$(PWD)" is the official way, but this patch is a nice clean up anyway.] Signed-off-by: Masahiro Yamada --- scripts/Makefile.modpost | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 48585c4d04ad..0273bf7375e2 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -87,8 +87,7 @@ obj := $(KBUILD_EXTMOD) src := $(obj) # Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS -include $(if $(wildcard $(KBUILD_EXTMOD)/Kbuild), \ - $(KBUILD_EXTMOD)/Kbuild, $(KBUILD_EXTMOD)/Makefile) +include $(if $(wildcard $(src)/Kbuild), $(src)/Kbuild, $(src)/Makefile) # modpost option for external modules MODPOST += -e -- cgit v1.2.3 From 8d3a75078c83a26d2e637da4e8f95058a406f5e7 Mon Sep 17 00:00:00 2001 From: Yuntao Wang Date: Sun, 22 May 2022 22:12:40 +0800 Subject: scripts/kallsyms: update usage message of the kallsyms program The kallsyms program supports --absolute-percpu option but does not display it in the usage message, fix it. Signed-off-by: Yuntao Wang Signed-off-by: Masahiro Yamada --- 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 e6906f79833d..f18e6dfc68c5 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -70,7 +70,7 @@ static unsigned char best_table_len[256]; static void usage(void) { - fprintf(stderr, "Usage: kallsyms [--all-symbols] " + fprintf(stderr, "Usage: kallsyms [--all-symbols] [--absolute-percpu] " "[--base-relative] < in.map > out.S\n"); exit(1); } -- cgit v1.2.3 From b5beffa20d83c4e15306c991ffd00de0d8628338 Mon Sep 17 00:00:00 2001 From: Alexander Lobakin Date: Tue, 24 May 2022 17:27:18 +0200 Subject: modpost: fix removing numeric suffixes With the `-z unique-symbol` linker flag or any similar mechanism, it is possible to trigger the following: ERROR: modpost: "param_set_uint.0" [vmlinux] is a static EXPORT_SYMBOL The reason is that for now the condition from remove_dot(): if (m && (s[n + m] == '.' || s[n + m] == 0)) which was designed to test if it's a dot or a '\0' after the suffix is never satisfied. This is due to that `s[n + m]` always points to the last digit of a numeric suffix, not on the symbol next to it (from a custom debug print added to modpost): param_set_uint.0, s[n + m] is '0', s[n + m + 1] is '\0' So it's off-by-one and was like that since 2014. Fix this for the sake of any potential upcoming features, but don't bother stable-backporting, as it's well hidden -- apart from that LD flag, it can be triggered only with GCC LTO which never landed upstream. Fixes: fcd38ed0ff26 ("scripts: modpost: fix compilation warning") Signed-off-by: Alexander Lobakin Reviewed-by: Petr Mladek 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 42e949cbc255..08f6989437bd 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1906,7 +1906,7 @@ static char *remove_dot(char *s) if (n && s[n]) { size_t m = strspn(s + n + 1, "0123456789"); - if (m && (s[n + m] == '.' || s[n + m] == 0)) + if (m && (s[n + m + 1] == '.' || s[n + m + 1] == 0)) s[n] = 0; /* strip trailing .prelink */ -- cgit v1.2.3 From d6b732666a1bae0df3c3ae06925043bba34502b1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 24 May 2022 01:46:22 +0900 Subject: modpost: fix undefined behavior of is_arm_mapping_symbol() The return value of is_arm_mapping_symbol() is unpredictable when "$" is passed in. strchr(3) says: The strchr() and strrchr() functions return a pointer to the matched character or NULL if the character is not found. The terminating null byte is considered part of the string, so that if c is specified as '\0', these functions return a pointer to the terminator. When str[1] is '\0', strchr("axtd", str[1]) is not NULL, and str[2] is referenced (i.e. buffer overrun). Test code --------- char str1[] = "abc"; char str2[] = "ab"; strcpy(str1, "$"); strcpy(str2, "$"); printf("test1: %d\n", is_arm_mapping_symbol(str1)); printf("test2: %d\n", is_arm_mapping_symbol(str2)); Result ------ test1: 0 test2: 1 Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 08f6989437bd..1092906867f0 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1180,7 +1180,8 @@ static int secref_whitelist(const struct sectioncheck *mismatch, static inline int is_arm_mapping_symbol(const char *str) { - return str[0] == '$' && strchr("axtd", str[1]) + return str[0] == '$' && + (str[1] == 'a' || str[1] == 'd' || str[1] == 't' || str[1] == 'x') && (str[2] == '\0' || str[2] == '.'); } -- cgit v1.2.3 From 76954527fe05354add150737aa1b9a6baa4a6ee5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 24 May 2022 01:46:23 +0900 Subject: modpost: remove the unused argument of check_sec_ref() check_sec_ref() does not use the first parameter 'mod'. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 1092906867f0..2806a5c528c8 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1884,8 +1884,7 @@ static void section_rel(const char *modname, struct elf_info *elf, * to find all references to a section that reference a section that will * be discarded and warns about it. **/ -static void check_sec_ref(struct module *mod, const char *modname, - struct elf_info *elf) +static void check_sec_ref(const char *modname, struct elf_info *elf) { int i; Elf_Shdr *sechdrs = elf->sechdrs; @@ -2091,7 +2090,7 @@ static void read_symbols(const char *modname) } } - check_sec_ref(mod, modname, &info); + check_sec_ref(modname, &info); if (!mod->is_vmlinux) { version = get_modinfo(&info, "version"); -- cgit v1.2.3 From c5c468dcc25efc0095361bb63b6255622e22f695 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 24 May 2022 01:46:25 +0900 Subject: modpost: reuse ARRAY_SIZE() macro for section_mismatch() Move ARRAY_SIZE() from file2alias.c to modpost.h to reuse it in section_mismatch(). Also, move the variable 'check' inside the for-loop. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/file2alias.c | 2 -- scripts/mod/modpost.c | 7 +++---- scripts/mod/modpost.h | 3 +++ 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 5258247d78ac..e8a9c6816fec 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -734,8 +734,6 @@ static int do_vio_entry(const char *filename, void *symval, return 1; } -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - static void do_input(char *alias, kernel_ulong_t *arr, unsigned int min, unsigned int max) { diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 2806a5c528c8..fc8ba8585d23 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1049,8 +1049,6 @@ static const struct sectioncheck *section_mismatch( const char *fromsec, const char *tosec) { int i; - int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck); - const struct sectioncheck *check = §ioncheck[0]; /* * The target section could be the SHT_NUL section when we're @@ -1061,14 +1059,15 @@ static const struct sectioncheck *section_mismatch( if (*tosec == '\0') return NULL; - for (i = 0; i < elems; i++) { + for (i = 0; i < ARRAY_SIZE(sectioncheck); i++) { + const struct sectioncheck *check = §ioncheck[i]; + if (match(fromsec, check->fromsec)) { if (check->bad_tosec[0] && match(tosec, check->bad_tosec)) return check; if (check->good_tosec[0] && !match(tosec, check->good_tosec)) return check; } - check++; } return NULL; } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index d9daeff07b83..044bdfb894b7 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -97,6 +97,9 @@ static inline void __endian(const void *src, void *dest, unsigned int size) #endif #define NOFAIL(ptr) do_nofail((ptr), #ptr) + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + void *do_nofail(void *ptr, const char *expr); struct buffer { -- cgit v1.2.3 From 68fef6704e38581f7462cb7aac349978fd4ca5cc Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 24 May 2022 01:46:26 +0900 Subject: modpost: squash if...else-if in find_elf_symbol2() if ((addr - sym->st_value) < distance) { distance = addr - sym->st_value; near = sym; } else if ((addr - sym->st_value) == distance) { near = sym; } is equivalent to: if (addr - sym->st_value <= distance) { distance = addr - sym->st_value; near = sym; } (The else-if block can overwrite 'distance' with the same value). Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index fc8ba8585d23..b70a31b4245a 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1270,13 +1270,9 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, continue; if (!is_valid_name(elf, sym)) continue; - if (sym->st_value <= addr) { - if ((addr - sym->st_value) < distance) { - distance = addr - sym->st_value; - near = sym; - } else if ((addr - sym->st_value) == distance) { - near = sym; - } + if (sym->st_value <= addr && addr - sym->st_value <= distance) { + distance = addr - sym->st_value; + near = sym; } } return near; -- cgit v1.2.3 From c9db1884050fa6524ae851347731ba2ff9c8d734 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 24 May 2022 03:15:03 +0900 Subject: kbuild: replace $(if A,A,B) with $(or A,B) in scripts/Makefile.modpost Similar cleanup to commit 5c8166419acf ("kbuild: replace $(if A,A,B) with $(or A,B)"). Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/Makefile.modpost | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 0273bf7375e2..8b343480813d 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -87,7 +87,7 @@ obj := $(KBUILD_EXTMOD) src := $(obj) # Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS -include $(if $(wildcard $(src)/Kbuild), $(src)/Kbuild, $(src)/Makefile) +include $(or $(wildcard $(src)/Kbuild), $(src)/Makefile) # modpost option for external modules MODPOST += -e -- cgit v1.2.3 From 5f3da8c08508df82823566c32f753071c8ad36af Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Tue, 19 Apr 2022 09:05:09 -0700 Subject: objtool: Add CONFIG_HAVE_UACCESS_VALIDATION Allow an arch specify that it has objtool uaccess validation with CONFIG_HAVE_UACCESS_VALIDATION. For now, doing so unconditionally selects CONFIG_OBJTOOL. Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/d393d5e2fe73aec6e8e41d5c24f4b6fe8583f2d8.1650384225.git.jpoimboe@redhat.com --- arch/Kconfig | 4 ++++ arch/x86/Kconfig | 1 + scripts/Makefile.build | 2 +- scripts/link-vmlinux.sh | 4 +++- 4 files changed, 9 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/arch/Kconfig b/arch/Kconfig index 904ed51736d4..cb2954027d10 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1050,6 +1050,10 @@ config HAVE_NOINSTR_HACK config HAVE_NOINSTR_VALIDATION bool +config HAVE_UACCESS_VALIDATION + bool + select OBJTOOL + config HAVE_STACK_VALIDATION bool help diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index cf531fbcd229..5f41f3c3df9a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -258,6 +258,7 @@ config X86 select HAVE_PREEMPT_DYNAMIC_CALL select HAVE_RSEQ select HAVE_SYSCALL_TRACEPOINTS + select HAVE_UACCESS_VALIDATION if HAVE_OBJTOOL select HAVE_UNSTABLE_SCHED_CLOCK select HAVE_USER_RETURN_NOTIFIER select HAVE_GENERIC_VDSO diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 06400504150b..6a663b27b286 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -218,7 +218,7 @@ objtool_args = \ $(if $(CONFIG_SLS), --sls) \ $(if $(CONFIG_STACK_VALIDATION), --stackval) \ $(if $(CONFIG_HAVE_STATIC_CALL_INLINE), --static-call) \ - --uaccess \ + $(if $(CONFIG_HAVE_UACCESS_VALIDATION), --uaccess) \ $(if $(linked-object), --link) \ $(if $(part-of-module), --module) \ $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index a7f6196c7e41..fd578c380919 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -134,7 +134,9 @@ objtool_link() objtoolopt="${objtoolopt} --static-call" fi - objtoolopt="${objtoolopt} --uaccess" + if is_enabled CONFIG_HAVE_UACCESS_VALIDATION; then + objtoolopt="${objtoolopt} --uaccess" + fi fi if is_enabled CONFIG_NOINSTR_VALIDATION; then -- cgit v1.2.3 From 0aa24a79ee3b603f6e6cd470c364edc2d746f613 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 29 May 2022 13:23:18 +0900 Subject: kbuild: do not try to parse *.cmd files for objects provided by compiler Guenter Roeck reported the build breakage for parisc and csky. I confirmed nios2 and openrisc are broken as well. The reason is that they borrow libgcc.a from the toolchains. For example, see this line in arch/parisc/Makefile: LIBGCC := $(shell $(CC) -print-libgcc-file-name) Some objects in libgcc.a are linked to vmlinux.o, but they do not have .*.cmd files. Obviously, there is no EXPORT_SYMBOL in external objects. Ignore them. (Most of the architectures import library code into the kernel tree. Perhaps those 4 architectures can do similar, but I do not know how challenging it is.) Fixes: f292d875d0dc ("modpost: extract symbol versions from *.cmd files") Link: https://lore.kernel.org/linux-kbuild/20220528224745.GA2501857@roeck-us.net/T/#mac65c20c71c3e272db0350ecfba53fcd8905b0a0 Reported-by: Guenter Roeck Signed-off-by: Masahiro Yamada Tested-by: Guenter Roeck --- scripts/link-vmlinux.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index a7f6196c7e41..68e4be463a76 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -344,9 +344,16 @@ ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1 modpost_link vmlinux.o objtool_link vmlinux.o -# Generate the list of objects in vmlinux +# Generate the list of in-tree objects in vmlinux +# +# This is used to retrieve symbol versions generated by genksyms. for f in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do case ${f} in + *libgcc.a) + # Some architectures do '$(CC) --print-libgcc-file-name' to + # borrow libgcc.a from the toolchain. + # There is no EXPORT_SYMBOL in external objects. Ignore this. + ;; *.a) ${AR} t ${f} ;; *) -- cgit v1.2.3 From 0cfd90060d714e3d1e0d1b30cfd1c46b71f4e721 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 27 May 2022 19:01:48 +0900 Subject: kbuild: replace $(linked-object) with CONFIG options *.prelink.o is created when CONFIG_LTO_CLANG or CONFIG_X86_KERNEL_IBT is enabled. Replace $(linked-object) with $(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT) so you will get a quick idea of when the --link option is passed. No functional change is intended. Signed-off-by: Masahiro Yamada Acked-by: Josh Poimboeuf Reviewed-by: Nick Desaulniers Tested-by: Sedat Dilek # LLVM-14 --- scripts/Makefile.build | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 06400504150b..f80196eef03a 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -219,7 +219,7 @@ objtool_args = \ $(if $(CONFIG_STACK_VALIDATION), --stackval) \ $(if $(CONFIG_HAVE_STATIC_CALL_INLINE), --static-call) \ --uaccess \ - $(if $(linked-object), --link) \ + $(if $($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT)), --link) \ $(if $(part-of-module), --module) \ $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) @@ -284,7 +284,6 @@ quiet_cmd_cc_prelink_modules = LD [M] $@ # modules into native code $(obj)/%.prelink.o: objtool-enabled = y $(obj)/%.prelink.o: part-of-module := y -$(obj)/%.prelink.o: linked-object := y $(obj)/%.prelink.o: $(obj)/%.o FORCE $(call if_changed,cc_prelink_modules) -- cgit v1.2.3 From c25e1c55822f9b3b53ccbf88b85644317a525752 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 27 May 2022 19:01:49 +0900 Subject: kbuild: do not create *.prelink.o for Clang LTO or IBT When CONFIG_LTO_CLANG=y, additional intermediate *.prelink.o is created for each module. Also, objtool is postponed until LLVM IR is converted to ELF. CONFIG_X86_KERNEL_IBT works in a similar way to postpone objtool until objects are merged together. This commit stops generating *.prelink.o, so the build flow will look similar with/without LTO. The following figures show how the LTO build currently works, and how this commit is changing it. Current build flow ================== [1] single-object module $(LD) $(CC) +objtool $(LD) foo.c --------------------> foo.o -----> foo.prelink.o -----> foo.ko (LLVM IR) (ELF) | (ELF) | foo.mod.o --/ (LLVM IR) [2] multi-object module $(LD) $(CC) $(AR) +objtool $(LD) foo1.c -----> foo1.o -----> foo.o -----> foo.prelink.o -----> foo.ko | (archive) (ELF) | (ELF) foo2.c -----> foo2.o --/ | (LLVM IR) foo.mod.o --/ (LLVM IR) One confusion is that foo.o in multi-object module is an archive despite of its suffix. New build flow ============== [1] single-object module Since there is only one object, there is no need to keep the LLVM IR. Use $(CC)+$(LD) to generate an ELF object in one build rule. When LTO is disabled, $(LD) is unneeded because $(CC) produces an ELF object. $(CC)+$(LD)+objtool $(LD) foo.c ----------------------------> foo.o ---------> foo.ko (ELF) | (ELF) | foo.mod.o --/ (LLVM IR) [2] multi-object module Previously, $(AR) was used to combine LLVM IR files into an archive, but there was no technical reason to do so. Use $(LD) to merge them into a single ELF object. $(LD) $(CC) +objtool $(LD) foo1.c ---------> foo1.o ---------> foo.o ---------> foo.ko | (ELF) | (ELF) foo2.c ---------> foo2.o ----/ | (LLVM IR) foo.mod.o --/ (LLVM IR) Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Tested-by: Nathan Chancellor Reviewed-by: Sami Tolvanen Tested-by: Sedat Dilek # LLVM-14 (x86-64) Acked-by: Josh Poimboeuf --- scripts/Kbuild.include | 4 +++ scripts/Makefile.build | 63 +++++++++++++++-------------------------------- scripts/Makefile.lib | 7 ------ scripts/Makefile.modfinal | 5 ++-- scripts/Makefile.modpost | 9 ++----- scripts/mod/modpost.c | 7 ------ 6 files changed, 28 insertions(+), 67 deletions(-) (limited to 'scripts') diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 3514c2149e9d..455a0a6ce12d 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -15,6 +15,10 @@ pound := \# # Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o dot-target = $(dir $@).$(notdir $@) +### +# Name of target with a '.tmp_' as filename prefix. foo/bar.o => foo/.tmp_bar.o +tmp-target = $(dir $@).tmp_$(notdir $@) + ### # The temporary file to save gcc -MMD generated dependencies must not # contain a comma diff --git a/scripts/Makefile.build b/scripts/Makefile.build index f80196eef03a..cc7061258e42 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -88,10 +88,6 @@ endif targets-for-modules := $(foreach x, o mod $(if $(CONFIG_TRIM_UNUSED_KSYMS), usyms), \ $(patsubst %.o, %.$x, $(filter %.o, $(obj-m)))) -ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) -targets-for-modules += $(patsubst %.o, %.prelink.o, $(filter %.o, $(obj-m))) -endif - ifdef need-modorder targets-for-modules += $(obj)/modules.order endif @@ -152,8 +148,18 @@ $(obj)/%.ll: $(src)/%.c FORCE # The C file is compiled and updated dependency information is generated. # (See cmd_cc_o_c + relevant part of rule_cc_o_c) +is-single-obj-m = $(and $(part-of-module),$(filter $@, $(obj-m)),y) + +# When a module consists of a single object, there is no reason to keep LLVM IR. +# Make $(LD) covert LLVM IR to ELF here. +ifdef CONFIG_LTO_CLANG +cmd_ld_single_m = $(if $(is-single-obj-m), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@) +endif + quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ - cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< $(cmd_objtool) + cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \ + $(cmd_ld_single_m) \ + $(cmd_objtool) ifdef CONFIG_MODVERSIONS # When module versioning is enabled the following steps are executed: @@ -219,7 +225,7 @@ objtool_args = \ $(if $(CONFIG_STACK_VALIDATION), --stackval) \ $(if $(CONFIG_HAVE_STATIC_CALL_INLINE), --static-call) \ --uaccess \ - $(if $($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT)), --link) \ + $(if $(delay-objtool), --link) \ $(if $(part-of-module), --module) \ $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) @@ -228,21 +234,15 @@ cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(o endif # CONFIG_OBJTOOL -ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) - -# Skip objtool for LLVM bitcode -$(obj)/%.o: objtool-enabled := - -else - # 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory # 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file # 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file -$(obj)/%.o: objtool-enabled = $(if $(filter-out y%, \ - $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y) +is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y) -endif +delay-objtool := $(or $(CONFIG_LTO_CLANG),$(CONFIG_X86_KERNEL_IBT)) + +$(obj)/%.o: objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y)) ifdef CONFIG_TRIM_UNUSED_KSYMS cmd_gen_ksymdeps = \ @@ -271,24 +271,6 @@ $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE $(call if_changed_rule,cc_o_c) $(call cmd,force_checksrc) -ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) -# Module .o files may contain LLVM bitcode, compile them into native code -# before ELF processing -quiet_cmd_cc_prelink_modules = LD [M] $@ - cmd_cc_prelink_modules = \ - $(LD) $(ld_flags) -r -o $@ \ - --whole-archive $(filter-out FORCE,$^) \ - $(cmd_objtool) - -# objtool was skipped for LLVM bitcode, run it now that we have compiled -# modules into native code -$(obj)/%.prelink.o: objtool-enabled = y -$(obj)/%.prelink.o: part-of-module := y - -$(obj)/%.prelink.o: $(obj)/%.o FORCE - $(call if_changed,cc_prelink_modules) -endif - cmd_mod = echo $(addprefix $(obj)/, $(call real-search, $*.o, .o, -objs -y -m)) | \ $(AWK) -v RS='( |\n)' '!x[$$0]++' > $@ @@ -298,7 +280,7 @@ $(obj)/%.mod: FORCE # List module undefined symbols cmd_undefined_syms = $(NM) $< | sed -n 's/^ *U //p' > $@ -$(obj)/%.usyms: $(obj)/%$(mod-prelink-ext).o FORCE +$(obj)/%.usyms: $(obj)/%.o FORCE $(call if_changed,undefined_syms) quiet_cmd_cc_lst_c = MKLST $@ @@ -420,16 +402,11 @@ $(obj)/modules.order: $(obj-m) FORCE $(obj)/lib.a: $(lib-y) FORCE $(call if_changed,ar) -ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) -quiet_cmd_link_multi-m = AR [M] $@ -cmd_link_multi-m = \ - rm -f $@; \ - $(AR) cDPrsT $@ @$(patsubst %.o,%.mod,$@) -else quiet_cmd_link_multi-m = LD [M] $@ - cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ @$(patsubst %.o,%.mod,$@) -endif + cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ @$(patsubst %.o,%.mod,$@) $(cmd_objtool) +$(multi-obj-m): objtool-enabled := $(delay-objtool) +$(multi-obj-m): part-of-module := y $(multi-obj-m): %.o: %.mod FORCE $(call if_changed,link_multi-m) $(call multi_depend, $(multi-obj-m), .o, -objs -y -m) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 0453a1904646..f75138385449 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -225,13 +225,6 @@ dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \ $(addprefix -I,$(DTC_INCLUDE)) \ -undef -D__DTS__ -ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) -# With CONFIG_LTO_CLANG, .o files in modules might be LLVM bitcode, so we -# need to run LTO to compile them into native code (.lto.o) before further -# processing. -mod-prelink-ext := .prelink -endif - # Useful for describing the dependency of composite objects # Usage: # $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add) diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 7f39599e9fae..35100e981f4a 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -9,7 +9,7 @@ __modfinal: include include/config/auto.conf include $(srctree)/scripts/Kbuild.include -# for c_flags and mod-prelink-ext +# for c_flags include $(srctree)/scripts/Makefile.lib # find all modules listed in modules.order @@ -54,9 +54,8 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ $(cmd); \ printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:) - # Re-generate module BTFs if either module's .ko or vmlinux changed -$(modules): %.ko: %$(mod-prelink-ext).o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE +$(modules): %.ko: %.o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE +$(call if_changed_except,ld_ko_o,vmlinux) ifdef CONFIG_DEBUG_INFO_BTF_MODULES +$(if $(newer-prereqs),$(call cmd,btf_ko)) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 8b343480813d..911606496341 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -41,9 +41,6 @@ __modpost: include include/config/auto.conf include $(srctree)/scripts/Kbuild.include -# for mod-prelink-ext -include $(srctree)/scripts/Makefile.lib - MODPOST = scripts/mod/modpost \ $(if $(CONFIG_MODVERSIONS),-m) \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \ @@ -117,8 +114,6 @@ $(input-symdump): @echo >&2 ' Modules may not have dependencies or modversions.' @echo >&2 ' You may get many unresolved symbol warnings.' -modules := $(sort $(shell cat $(MODORDER))) - # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined symbols ifneq ($(KBUILD_MODPOST_WARN)$(filter-out $(existing-input-symdump), $(input-symdump)),) MODPOST += -w @@ -127,9 +122,9 @@ endif # Read out modules.order to pass in modpost. # Otherwise, allmodconfig would fail with "Argument list too long". quiet_cmd_modpost = MODPOST $@ - cmd_modpost = sed 's/\.ko$$/$(mod-prelink-ext)\.o/' $< | $(MODPOST) -T - + cmd_modpost = sed 's/ko$$/o/' $< | $(MODPOST) -T - -$(output-symdump): $(MODORDER) $(input-symdump) $(modules:.ko=$(mod-prelink-ext).o) FORCE +$(output-symdump): $(MODORDER) $(input-symdump) FORCE $(call if_changed,modpost) targets += $(output-symdump) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index b70a31b4245a..e74224a6a8e8 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1903,10 +1903,6 @@ static char *remove_dot(char *s) size_t m = strspn(s + n + 1, "0123456789"); if (m && (s[n + m + 1] == '.' || s[n + m + 1] == 0)) s[n] = 0; - - /* strip trailing .prelink */ - if (strends(s, ".prelink")) - s[strlen(s) - 8] = '\0'; } return s; } @@ -2028,9 +2024,6 @@ static void read_symbols(const char *modname) /* strip trailing .o */ tmp = NOFAIL(strdup(modname)); tmp[strlen(tmp) - 2] = '\0'; - /* strip trailing .prelink */ - if (strends(tmp, ".prelink")) - tmp[strlen(tmp) - 8] = '\0'; mod = new_module(tmp); free(tmp); } -- cgit v1.2.3 From 31cb50b5590fe911077b8463ad01144fac8fa4f3 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 27 May 2022 19:01:51 +0900 Subject: kbuild: check static EXPORT_SYMBOL* by script instead of modpost The 'static' specifier and EXPORT_SYMBOL() are an odd combination. Commit 15bfc2348d54 ("modpost: check for static EXPORT_SYMBOL* functions") tried to detect it, but this check has false negatives. Here is the sample code. Makefile: obj-y += foo1.o foo2.o foo1.c: #include static void foo(void) {} EXPORT_SYMBOL(foo); foo2.c: void foo(void) {} foo1.c exports the static symbol 'foo', but modpost cannot catch it because it is fooled by foo2.c, which has a global symbol with the same name. s->is_static is cleared if a global symbol with the same name is found somewhere, but EXPORT_SYMBOL() and the global symbol do not necessarily belong to the same compilation unit. This check should be done per compilation unit, but I do not know how to do it in modpost. modpost runs against vmlinux.o or modules, which merges multiple objects, then forgets their origin. modpost cannot parse individual objects because they may not be ELF but LLVM IR when CONFIG_LTO_CLANG=y. Add a simple bash script to parse the output from ${NM}. This works for CONFIG_LTO_CLANG=y because llvm-nm can dump symbols of LLVM IR files. Revert 15bfc2348d54. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Tested-by: Nathan Chancellor Tested-by: Sedat Dilek # LLVM-14 (x86-64) --- scripts/Makefile.build | 4 +++ scripts/check-local-export | 65 ++++++++++++++++++++++++++++++++++++++++++++++ scripts/mod/modpost.c | 28 +------------------- 3 files changed, 70 insertions(+), 27 deletions(-) create mode 100755 scripts/check-local-export (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index cc7061258e42..b6ae652a943f 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -249,9 +249,12 @@ cmd_gen_ksymdeps = \ $(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd endif +cmd_check_local_export = $(srctree)/scripts/check-local-export $@ + define rule_cc_o_c $(call cmd_and_fixdep,cc_o_c) $(call cmd,gen_ksymdeps) + $(call cmd,check_local_export) $(call cmd,checksrc) $(call cmd,checkdoc) $(call cmd,gen_objtooldep) @@ -262,6 +265,7 @@ endef define rule_as_o_S $(call cmd_and_fixdep,as_o_S) $(call cmd,gen_ksymdeps) + $(call cmd,check_local_export) $(call cmd,gen_objtooldep) $(call cmd,gen_symversions_S) endef diff --git a/scripts/check-local-export b/scripts/check-local-export new file mode 100755 index 000000000000..2c46912be0ef --- /dev/null +++ b/scripts/check-local-export @@ -0,0 +1,65 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2022 Masahiro Yamada +# +# Exit with error if a local exported symbol is found. +# EXPORT_SYMBOL should be used for global symbols. + +set -e + +declare -A symbol_types +declare -a export_symbols + +exit_code=0 + +while read value type name +do + # Skip the line if the number of fields is less than 3. + # + # case 1) + # For undefined symbols, the first field (value) is empty. + # The outout looks like this: + # " U _printk" + # It is unneeded to record undefined symbols. + # + # case 2) + # For Clang LTO, llvm-nm outputs a line with type 't' but empty name: + # "---------------- t" + if [[ -z ${name} ]]; then + continue + fi + + # save (name, type) in the associative array + symbol_types[${name}]=${type} + + # append the exported symbol to the array + if [[ ${name} == __ksymtab_* ]]; then + export_symbols+=(${name#__ksymtab_}) + fi + + # If there is no symbol in the object, ${NM} (both GNU nm and llvm-nm) + # shows 'no symbols' diagnostic (but exits with 0). It is harmless and + # hidden by '2>/dev/null'. However, it suppresses real error messages + # as well. Add a hand-crafted error message here. + # + # Use --quiet instead of 2>/dev/null when we upgrade the minimum version + # of binutils to 2.37, llvm to 13.0.0. + # + # Then, the following line will be really simple: + # done < <(${NM} --quiet ${1}) +done < <(${NM} ${1} 2>/dev/null || { echo "${0}: ${NM} failed" >&2; false; } ) + +# Catch error in the process substitution +wait $! + +for name in "${export_symbols[@]}" +do + # nm(3) says "If lowercase, the symbol is usually local" + if [[ ${symbol_types[$name]} =~ [a-z] ]]; then + echo "$@: error: local symbol '${name}' was exported" >&2 + exit_code=1 + fi +done + +exit ${exit_code} diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index e74224a6a8e8..9269735f85c5 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -212,7 +212,6 @@ struct symbol { unsigned int crc; bool crc_valid; bool weak; - bool is_static; /* true if symbol is not global */ bool is_gpl_only; /* exported by EXPORT_SYMBOL_GPL */ char name[]; }; @@ -242,7 +241,7 @@ static struct symbol *alloc_symbol(const char *name) memset(s, 0, sizeof(*s)); strcpy(s->name, name); - s->is_static = true; + return s; } @@ -2064,20 +2063,6 @@ static void read_symbols(const char *modname) sym_get_data(&info, sym)); } - // check for static EXPORT_SYMBOL_* functions && global vars - for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { - unsigned char bind = ELF_ST_BIND(sym->st_info); - - if (bind == STB_GLOBAL || bind == STB_WEAK) { - struct symbol *s = - find_symbol(remove_dot(info.strtab + - sym->st_name)); - - if (s) - s->is_static = false; - } - } - check_sec_ref(modname, &info); if (!mod->is_vmlinux) { @@ -2507,7 +2492,6 @@ static void read_dump(const char *fname) mod->from_dump = true; } s = sym_add_exported(symname, mod, gpl_only); - s->is_static = false; sym_set_crc(s, crc); sym_update_namespace(symname, namespace); } @@ -2572,7 +2556,6 @@ int main(int argc, char **argv) char *missing_namespace_deps = NULL; char *dump_write = NULL, *files_source = NULL; int opt; - int n; LIST_HEAD(dump_lists); struct dump_list *dl, *dl2; @@ -2648,15 +2631,6 @@ int main(int argc, char **argv) if (sec_mismatch_count && !sec_mismatch_warn_only) error("Section mismatches detected.\n" "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n"); - for (n = 0; n < SYMBOL_HASH_SIZE; n++) { - struct symbol *s; - - for (s = symbolhash[n]; s; s = s->next) { - if (s->is_static) - error("\"%s\" [%s] is a static EXPORT_SYMBOL\n", - s->name, s->module->name); - } - } if (nr_unresolved > MAX_UNRESOLVED_REPORTS) warn("suppressed %u unresolved symbol warnings because there were too many)\n", -- cgit v1.2.3 From cd968b97c49214e6557381bddddacbd0e0fb696e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 27 May 2022 19:01:52 +0900 Subject: kbuild: make built-in.a rule robust against too long argument error Kbuild runs at the top of objtree instead of changing the working directory to subdirectories. I think this design is nice overall but some commands have a scalability issue. The build command of built-in.a is one of them whose length scales with: O(D * N) Here, D is the length of the directory path (i.e. $(obj)/ prefix), N is the number of objects in the Makefile, O() is the big O notation. The deeper directory the Makefile directory is located, the more easily it will hit the too long argument error. We can make it better. Trim the $(obj)/ by Make's builtin function, and restore it by a shell command (sed). With this, the command length scales with: O(D + N) In-tree modules still have some room to the limit (ARG_MAX=2097152), but this is more future-proof for big modules in a deep directory. For example, you can build i915 as builtin (CONFIG_DRM_I915=y) and compare drivers/gpu/drm/i915/.built-in.a.cmd with/without this commit. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Tested-by: Nathan Chancellor Tested-by: Sedat Dilek # LLVM-14 (x86-64) --- scripts/Makefile.build | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index b6ae652a943f..3c1e20e4a4fc 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -377,9 +377,14 @@ $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; # # Rule to compile a set of .o files into one .a file (without symbol table) # +# To make this rule robust against "Argument list too long" error, +# remove $(obj)/ prefix, and restore it by a shell command. quiet_cmd_ar_builtin = AR $@ - cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs) + cmd_ar_builtin = rm -f $@; \ + echo $(patsubst $(obj)/%,%,$(real-prereqs)) | \ + sed -E 's:([^ ]+):$(obj)/\1:g' | \ + xargs $(AR) cDPrST $@ $(obj)/built-in.a: $(real-obj-y) FORCE $(call if_changed,ar_builtin) -- cgit v1.2.3 From c6031b1dbbbfec03891bf1baefa2e0803d705601 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 27 May 2022 19:01:53 +0900 Subject: kbuild: make *.mod rule robust against too long argument error Like built-in.a, the command length of the *.mod rule scales with the depth of the directory times the number of objects in the Makefile. Add $(obj)/ by the shell command (awk) instead of by Make's builtin function. In-tree modules still have some room to the limit (ARG_MAX=2097152), but this is more future-proof for big modules in a deep directory. For example, you can build i915 as a module (CONFIG_DRM_I915=m) and compare drivers/gpu/drm/i915/.i915.mod.cmd with/without this commit. The issue is more critical for external modules because the M= path can be very long as Jeff Johnson reported before [1]. [1] https://lore.kernel.org/linux-kbuild/4c02050c4e95e4cb8cc04282695f8404@codeaurora.org/ Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Tested-by: Nathan Chancellor Tested-by: Sedat Dilek # LLVM-14 (x86-64) --- scripts/Makefile.build | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 3c1e20e4a4fc..a1edbfe4310b 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -275,8 +275,10 @@ $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE $(call if_changed_rule,cc_o_c) $(call cmd,force_checksrc) -cmd_mod = echo $(addprefix $(obj)/, $(call real-search, $*.o, .o, -objs -y -m)) | \ - $(AWK) -v RS='( |\n)' '!x[$$0]++' > $@ +# To make this rule robust against "Argument list too long" error, +# ensure to add $(obj)/ prefix by a shell command. +cmd_mod = echo $(call real-search, $*.o, .o, -objs -y -m) | \ + $(AWK) -v RS='( |\n)' '!x[$$0]++ { print("$(obj)/"$$0) }' > $@ $(obj)/%.mod: FORCE $(call if_changed,mod) -- cgit v1.2.3 From ebd191b38c5ea177318543a08e544cf2f7df944d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 27 May 2022 19:01:54 +0900 Subject: kbuild: add cmd_and_savecmd macro Separate out the command execution part of if_changed, as we did for if_changed_dep. This allows us to reuse it in if_changed_rule. define rule_foo $(call cmd_and_savecmd,foo) $(call cmd,bar) endef Signed-off-by: Masahiro Yamada Reviewed-by: Kees Cook Tested-by: Nathan Chancellor Reviewed-by: Nicolas Schier Tested-by: Sedat Dilek # LLVM-14 (x86-64) --- scripts/Kbuild.include | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 455a0a6ce12d..ece44b735061 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -142,9 +142,11 @@ check-FORCE = $(if $(filter FORCE, $^),,$(warning FORCE prerequisite is missing) if-changed-cond = $(newer-prereqs)$(cmd-check)$(check-FORCE) # Execute command if command has changed or prerequisite(s) are updated. -if_changed = $(if $(if-changed-cond), \ +if_changed = $(if $(if-changed-cond),$(cmd_and_savecmd),@:) + +cmd_and_savecmd = \ $(cmd); \ - printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:) + printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd # Execute the command and also postprocess generated .d dependencies file. if_changed_dep = $(if $(if-changed-cond),$(cmd_and_fixdep),@:) -- cgit v1.2.3 From f6b66ca4f38b1169313383aec7fa0a8446205ebb Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 27 May 2022 19:01:55 +0900 Subject: kbuild: rebuild multi-object modules when objtool is updated When CONFIG_LTO_CLANG or CONFIG_X86_KERNEL_IBT is enabled, objtool for multi-object modules is postponed until the objects are linked together. Make sure to re-run objtool and re-link multi-object modules when objtool is updated. Signed-off-by: Masahiro Yamada Reviewed-by: Kees Cook Acked-by: Josh Poimboeuf Tested-by: Nathan Chancellor Reviewed-by: Nicolas Schier Tested-by: Sedat Dilek # LLVM-14 (x86-64) --- scripts/Makefile.build | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index a1edbfe4310b..4cb7145071b9 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -413,13 +413,18 @@ $(obj)/modules.order: $(obj-m) FORCE $(obj)/lib.a: $(lib-y) FORCE $(call if_changed,ar) -quiet_cmd_link_multi-m = LD [M] $@ - cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ @$(patsubst %.o,%.mod,$@) $(cmd_objtool) +quiet_cmd_ld_multi_m = LD [M] $@ + cmd_ld_multi_m = $(LD) $(ld_flags) -r -o $@ @$(patsubst %.o,%.mod,$@) $(cmd_objtool) + +define rule_ld_multi_m + $(call cmd_and_savecmd,ld_multi_m) + $(call cmd,gen_objtooldep) +endef $(multi-obj-m): objtool-enabled := $(delay-objtool) $(multi-obj-m): part-of-module := y $(multi-obj-m): %.o: %.mod FORCE - $(call if_changed,link_multi-m) + $(call if_changed_rule,ld_multi_m) $(call multi_depend, $(multi-obj-m), .o, -objs -y -m) targets := $(filter-out $(PHONY), $(targets)) -- cgit v1.2.3 From a78b6afa9913890e92aede1c17e72dec7e528549 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 29 May 2022 00:47:01 +0900 Subject: kbuild: remove redundant cleanups in scripts/link-vmlinux.sh These are cleaned by the top Makefile. vmlinux.o and .vmlinux.d matches the '*.[aios]' and '.*.d' patterns respectively. Signed-off-by: Masahiro Yamada Tested-by: Sedat Dilek # LLVM-14 (x86-64) --- scripts/link-vmlinux.sh | 2 -- 1 file changed, 2 deletions(-) (limited to 'scripts') diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 68e4be463a76..1c0af7288b79 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -309,8 +309,6 @@ cleanup() rm -f System.map rm -f vmlinux rm -f vmlinux.map - rm -f vmlinux.o - rm -f .vmlinux.d rm -f .vmlinux.objs rm -f .vmlinux.export.c } -- cgit v1.2.3 From fae35da4ace3721dfba1b3986a9239fc85cf8c72 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Sat, 28 May 2022 17:31:31 +0200 Subject: docs: move Linux logo into a new `images` folder Having assets in the top-level `Documentation` directory can make it harder to find the documents one needs, especially if we want to add more of them later on. Instead, create a new `images` folder inside it that is used to hold assets such as logos. In addition, update the reference in `scripts/spdxcheck-test.sh`. Link: https://lore.kernel.org/lkml/8735hicoy7.fsf@meer.lwn.net/ Suggested-by: Jonathan Corbet Signed-off-by: Miguel Ojeda Link: https://lore.kernel.org/r/20220528153132.8636-1-ojeda@kernel.org Signed-off-by: Jonathan Corbet --- Documentation/COPYING-logo | 13 ------------- Documentation/images/COPYING-logo | 13 +++++++++++++ Documentation/images/logo.gif | Bin 0 -> 16335 bytes Documentation/logo.gif | Bin 16335 -> 0 bytes scripts/spdxcheck-test.sh | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) delete mode 100644 Documentation/COPYING-logo create mode 100644 Documentation/images/COPYING-logo create mode 100644 Documentation/images/logo.gif delete mode 100644 Documentation/logo.gif (limited to 'scripts') diff --git a/Documentation/COPYING-logo b/Documentation/COPYING-logo deleted file mode 100644 index b21c7cf7d9f6..000000000000 --- a/Documentation/COPYING-logo +++ /dev/null @@ -1,13 +0,0 @@ -This is the full-colour version of the currently unofficial Linux logo -("currently unofficial" just means that there has been no paperwork and -that I have not really announced it yet). It was created by Larry Ewing, -and is freely usable as long as you acknowledge Larry as the original -artist. - -Note that there are black-and-white versions of this available that -scale down to smaller sizes and are better for letterheads or whatever -you want to use it for: for the full range of logos take a look at -Larry's web-page: - - https://www.isc.tamu.edu/~lewing/linux/ - diff --git a/Documentation/images/COPYING-logo b/Documentation/images/COPYING-logo new file mode 100644 index 000000000000..b21c7cf7d9f6 --- /dev/null +++ b/Documentation/images/COPYING-logo @@ -0,0 +1,13 @@ +This is the full-colour version of the currently unofficial Linux logo +("currently unofficial" just means that there has been no paperwork and +that I have not really announced it yet). It was created by Larry Ewing, +and is freely usable as long as you acknowledge Larry as the original +artist. + +Note that there are black-and-white versions of this available that +scale down to smaller sizes and are better for letterheads or whatever +you want to use it for: for the full range of logos take a look at +Larry's web-page: + + https://www.isc.tamu.edu/~lewing/linux/ + diff --git a/Documentation/images/logo.gif b/Documentation/images/logo.gif new file mode 100644 index 000000000000..2eae75fecfb9 Binary files /dev/null and b/Documentation/images/logo.gif differ diff --git a/Documentation/logo.gif b/Documentation/logo.gif deleted file mode 100644 index 2eae75fecfb9..000000000000 Binary files a/Documentation/logo.gif and /dev/null differ diff --git a/scripts/spdxcheck-test.sh b/scripts/spdxcheck-test.sh index cb76324756bd..9f6d1a74da6e 100644 --- a/scripts/spdxcheck-test.sh +++ b/scripts/spdxcheck-test.sh @@ -1,7 +1,7 @@ #!/bin/sh # run check on a text and a binary file -for FILE in Makefile Documentation/logo.gif; do +for FILE in Makefile Documentation/images/logo.gif; do python3 scripts/spdxcheck.py $FILE python3 scripts/spdxcheck.py - < $FILE done -- cgit v1.2.3 From 08145b087e4481458f6075f3af58021a3cf8a940 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Tue, 31 May 2022 18:04:10 +0800 Subject: LoongArch: Add ELF-related definitions Add ELF-related definitions for LoongArch, including: EM_LOONGARCH, KEXEC_ARCH_LOONGARCH, AUDIT_ARCH_LOONGARCH32, AUDIT_ARCH_LOONGARCH64 and NT_LOONGARCH_*. Reviewed-by: WANG Xuerui Reviewed-by: Jiaxun Yang Signed-off-by: Huacai Chen --- include/uapi/linux/audit.h | 2 ++ include/uapi/linux/elf-em.h | 1 + include/uapi/linux/elf.h | 5 +++++ include/uapi/linux/kexec.h | 1 + scripts/sorttable.c | 5 +++++ 5 files changed, 14 insertions(+) (limited to 'scripts') diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h index 8eda133ca4c1..7c1dc818b1d5 100644 --- a/include/uapi/linux/audit.h +++ b/include/uapi/linux/audit.h @@ -439,6 +439,8 @@ enum { #define AUDIT_ARCH_UNICORE (EM_UNICORE|__AUDIT_ARCH_LE) #define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) #define AUDIT_ARCH_XTENSA (EM_XTENSA) +#define AUDIT_ARCH_LOONGARCH32 (EM_LOONGARCH|__AUDIT_ARCH_LE) +#define AUDIT_ARCH_LOONGARCH64 (EM_LOONGARCH|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) #define AUDIT_PERM_EXEC 1 #define AUDIT_PERM_WRITE 2 diff --git a/include/uapi/linux/elf-em.h b/include/uapi/linux/elf-em.h index f47e853546fa..ef38c2bc5ab7 100644 --- a/include/uapi/linux/elf-em.h +++ b/include/uapi/linux/elf-em.h @@ -51,6 +51,7 @@ #define EM_RISCV 243 /* RISC-V */ #define EM_BPF 247 /* Linux BPF - in-kernel virtual machine */ #define EM_CSKY 252 /* C-SKY */ +#define EM_LOONGARCH 258 /* LoongArch */ #define EM_FRV 0x5441 /* Fujitsu FR-V */ /* diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h index c4abd09c3da9..2b9f5e9985e5 100644 --- a/include/uapi/linux/elf.h +++ b/include/uapi/linux/elf.h @@ -438,6 +438,11 @@ typedef struct elf64_shdr { #define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers */ #define NT_MIPS_FP_MODE 0x801 /* MIPS floating-point mode */ #define NT_MIPS_MSA 0x802 /* MIPS SIMD registers */ +#define NT_LOONGARCH_CPUCFG 0xa00 /* LoongArch CPU config registers */ +#define NT_LOONGARCH_CSR 0xa01 /* LoongArch control and status registers */ +#define NT_LOONGARCH_LSX 0xa02 /* LoongArch Loongson SIMD Extension registers */ +#define NT_LOONGARCH_LASX 0xa03 /* LoongArch Loongson Advanced SIMD Extension registers */ +#define NT_LOONGARCH_LBT 0xa04 /* LoongArch Loongson Binary Translation registers */ /* Note types with note name "GNU" */ #define NT_GNU_PROPERTY_TYPE_0 5 diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h index fb7e2ef60825..981016e05cfa 100644 --- a/include/uapi/linux/kexec.h +++ b/include/uapi/linux/kexec.h @@ -43,6 +43,7 @@ #define KEXEC_ARCH_MIPS ( 8 << 16) #define KEXEC_ARCH_AARCH64 (183 << 16) #define KEXEC_ARCH_RISCV (243 << 16) +#define KEXEC_ARCH_LOONGARCH (258 << 16) /* The artificial cap on the number of segments passed to kexec_load. */ #define KEXEC_SEGMENT_MAX 16 diff --git a/scripts/sorttable.c b/scripts/sorttable.c index d00504c5f530..fba40e99f354 100644 --- a/scripts/sorttable.c +++ b/scripts/sorttable.c @@ -60,6 +60,10 @@ #define EM_RISCV 243 #endif +#ifndef EM_LOONGARCH +#define EM_LOONGARCH 258 +#endif + static uint32_t (*r)(const uint32_t *); static uint16_t (*r2)(const uint16_t *); static uint64_t (*r8)(const uint64_t *); @@ -313,6 +317,7 @@ static int do_file(char const *const fname, void *addr) case EM_ARCOMPACT: case EM_ARCV2: case EM_ARM: + case EM_LOONGARCH: case EM_MICROBLAZE: case EM_MIPS: case EM_XTENSA: -- cgit v1.2.3 From fa96b57c149061f71a70bd6582d995f6424fbbf4 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Tue, 31 May 2022 18:04:11 +0800 Subject: LoongArch: Add build infrastructure Add Kbuild, Makefile, Kconfig and link script for LoongArch build infrastructure. Reviewed-by: Guo Ren Reviewed-by: WANG Xuerui Reviewed-by: Jiaxun Yang Signed-off-by: Huacai Chen --- arch/loongarch/Kbuild | 6 + arch/loongarch/Kconfig | 379 +++++++++++++++++++++++++++++++++ arch/loongarch/Kconfig.debug | 0 arch/loongarch/Makefile | 98 +++++++++ arch/loongarch/boot/.gitignore | 2 + arch/loongarch/boot/Makefile | 16 ++ arch/loongarch/boot/dts/Makefile | 4 + arch/loongarch/include/asm/Kbuild | 30 +++ arch/loongarch/include/uapi/asm/Kbuild | 2 + arch/loongarch/kernel/.gitignore | 2 + arch/loongarch/kernel/Makefile | 21 ++ arch/loongarch/kernel/vmlinux.lds.S | 116 ++++++++++ arch/loongarch/lib/Makefile | 6 + arch/loongarch/mm/Makefile | 9 + arch/loongarch/pci/Makefile | 7 + arch/loongarch/vdso/.gitignore | 2 + scripts/subarch.include | 2 +- 17 files changed, 701 insertions(+), 1 deletion(-) create mode 100644 arch/loongarch/Kbuild create mode 100644 arch/loongarch/Kconfig create mode 100644 arch/loongarch/Kconfig.debug create mode 100644 arch/loongarch/Makefile create mode 100644 arch/loongarch/boot/.gitignore create mode 100644 arch/loongarch/boot/Makefile create mode 100644 arch/loongarch/boot/dts/Makefile create mode 100644 arch/loongarch/include/asm/Kbuild create mode 100644 arch/loongarch/include/uapi/asm/Kbuild create mode 100644 arch/loongarch/kernel/.gitignore create mode 100644 arch/loongarch/kernel/Makefile create mode 100644 arch/loongarch/kernel/vmlinux.lds.S create mode 100644 arch/loongarch/lib/Makefile create mode 100644 arch/loongarch/mm/Makefile create mode 100644 arch/loongarch/pci/Makefile create mode 100644 arch/loongarch/vdso/.gitignore (limited to 'scripts') diff --git a/arch/loongarch/Kbuild b/arch/loongarch/Kbuild new file mode 100644 index 000000000000..ab5373d0a24f --- /dev/null +++ b/arch/loongarch/Kbuild @@ -0,0 +1,6 @@ +obj-y += kernel/ +obj-y += mm/ +obj-y += vdso/ + +# for cleaning +subdir- += boot diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig new file mode 100644 index 000000000000..03d9b74eb2a9 --- /dev/null +++ b/arch/loongarch/Kconfig @@ -0,0 +1,379 @@ +# SPDX-License-Identifier: GPL-2.0 +config LOONGARCH + bool + default y + select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI + select ARCH_BINFMT_ELF_STATE + select ARCH_ENABLE_MEMORY_HOTPLUG + select ARCH_ENABLE_MEMORY_HOTREMOVE + select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI + select ARCH_HAS_PTE_SPECIAL + select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST + select ARCH_INLINE_READ_LOCK if !PREEMPTION + select ARCH_INLINE_READ_LOCK_BH if !PREEMPTION + select ARCH_INLINE_READ_LOCK_IRQ if !PREEMPTION + select ARCH_INLINE_READ_LOCK_IRQSAVE if !PREEMPTION + select ARCH_INLINE_READ_UNLOCK if !PREEMPTION + select ARCH_INLINE_READ_UNLOCK_BH if !PREEMPTION + select ARCH_INLINE_READ_UNLOCK_IRQ if !PREEMPTION + select ARCH_INLINE_READ_UNLOCK_IRQRESTORE if !PREEMPTION + select ARCH_INLINE_WRITE_LOCK if !PREEMPTION + select ARCH_INLINE_WRITE_LOCK_BH if !PREEMPTION + select ARCH_INLINE_WRITE_LOCK_IRQ if !PREEMPTION + select ARCH_INLINE_WRITE_LOCK_IRQSAVE if !PREEMPTION + select ARCH_INLINE_WRITE_UNLOCK if !PREEMPTION + select ARCH_INLINE_WRITE_UNLOCK_BH if !PREEMPTION + select ARCH_INLINE_WRITE_UNLOCK_IRQ if !PREEMPTION + select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE if !PREEMPTION + select ARCH_INLINE_SPIN_TRYLOCK if !PREEMPTION + select ARCH_INLINE_SPIN_TRYLOCK_BH if !PREEMPTION + select ARCH_INLINE_SPIN_LOCK if !PREEMPTION + select ARCH_INLINE_SPIN_LOCK_BH if !PREEMPTION + select ARCH_INLINE_SPIN_LOCK_IRQ if !PREEMPTION + select ARCH_INLINE_SPIN_LOCK_IRQSAVE if !PREEMPTION + select ARCH_INLINE_SPIN_UNLOCK if !PREEMPTION + select ARCH_INLINE_SPIN_UNLOCK_BH if !PREEMPTION + select ARCH_INLINE_SPIN_UNLOCK_IRQ if !PREEMPTION + select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE if !PREEMPTION + select ARCH_MIGHT_HAVE_PC_PARPORT + select ARCH_MIGHT_HAVE_PC_SERIO + select ARCH_SPARSEMEM_ENABLE + select ARCH_SUPPORTS_ACPI + select ARCH_SUPPORTS_ATOMIC_RMW + select ARCH_SUPPORTS_HUGETLBFS + select ARCH_USE_BUILTIN_BSWAP + select ARCH_USE_CMPXCHG_LOCKREF + select ARCH_USE_QUEUED_RWLOCKS + select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT + select ARCH_WANTS_NO_INSTR + select BUILDTIME_TABLE_SORT + select COMMON_CLK + select GENERIC_CLOCKEVENTS + select GENERIC_CMOS_UPDATE + select GENERIC_CPU_AUTOPROBE + select GENERIC_ENTRY + select GENERIC_FIND_FIRST_BIT + select GENERIC_GETTIMEOFDAY + select GENERIC_IRQ_MULTI_HANDLER + select GENERIC_IRQ_PROBE + select GENERIC_IRQ_SHOW + select GENERIC_LIB_ASHLDI3 + select GENERIC_LIB_ASHRDI3 + select GENERIC_LIB_CMPDI2 + select GENERIC_LIB_LSHRDI3 + select GENERIC_LIB_UCMPDI2 + select GENERIC_PCI_IOMAP + select GENERIC_SCHED_CLOCK + select GENERIC_TIME_VSYSCALL + select GPIOLIB + select HAVE_ARCH_AUDITSYSCALL + select HAVE_ARCH_COMPILER_H + select HAVE_ARCH_MMAP_RND_BITS if MMU + select HAVE_ARCH_SECCOMP_FILTER + select HAVE_ARCH_TRACEHOOK + select HAVE_ARCH_TRANSPARENT_HUGEPAGE + select HAVE_ASM_MODVERSIONS + select HAVE_CONTEXT_TRACKING + select HAVE_COPY_THREAD_TLS + select HAVE_DEBUG_STACKOVERFLOW + select HAVE_DMA_CONTIGUOUS + select HAVE_EXIT_THREAD + select HAVE_FAST_GUP + select HAVE_GENERIC_VDSO + select HAVE_IOREMAP_PROT + select HAVE_IRQ_EXIT_ON_IRQ_STACK + select HAVE_IRQ_TIME_ACCOUNTING + select HAVE_MEMBLOCK + select HAVE_MEMBLOCK_NODE_MAP + select HAVE_MOD_ARCH_SPECIFIC + select HAVE_NMI + select HAVE_PERF_EVENTS + select HAVE_REGS_AND_STACK_ACCESS_API + select HAVE_RSEQ + select HAVE_SYSCALL_TRACEPOINTS + select HAVE_TIF_NOHZ + select HAVE_VIRT_CPU_ACCOUNTING_GEN + select IRQ_FORCED_THREADING + select IRQ_LOONGARCH_CPU + select MODULES_USE_ELF_RELA if MODULES + select OF + select OF_EARLY_FLATTREE + select PERF_USE_VMALLOC + select RTC_LIB + select SPARSE_IRQ + select SYSCTL_EXCEPTION_TRACE + select SWIOTLB + select TRACE_IRQFLAGS_SUPPORT + select ZONE_DMA32 + +config 32BIT + bool + +config 64BIT + def_bool y + +config CPU_HAS_FPU + bool + default y + +config CPU_HAS_PREFETCH + bool + default y + +config GENERIC_CALIBRATE_DELAY + def_bool y + +config GENERIC_CSUM + def_bool y + +config GENERIC_HWEIGHT + def_bool y + +config L1_CACHE_SHIFT + int + default "6" + +config LOCKDEP_SUPPORT + bool + default y + +# MACH_LOONGSON32 and MACH_LOONGSON64 are delibrately carried over from the +# MIPS Loongson code, to preserve Loongson-specific code paths in drivers that +# are shared between architectures, and specifically expecting the symbols. +config MACH_LOONGSON32 + def_bool 32BIT + +config MACH_LOONGSON64 + def_bool 64BIT + +config PAGE_SIZE_4KB + bool + +config PAGE_SIZE_16KB + bool + +config PAGE_SIZE_64KB + bool + +config PGTABLE_2LEVEL + bool + +config PGTABLE_3LEVEL + bool + +config PGTABLE_4LEVEL + bool + +config PGTABLE_LEVELS + int + default 2 if PGTABLE_2LEVEL + default 3 if PGTABLE_3LEVEL + default 4 if PGTABLE_4LEVEL + +config SCHED_OMIT_FRAME_POINTER + bool + default y + +menu "Kernel type and options" + +source "kernel/Kconfig.hz" + +choice + prompt "Page Table Layout" + default 16KB_2LEVEL if 32BIT + default 16KB_3LEVEL if 64BIT + help + Allows choosing the page table layout, which is a combination + of page size and page table levels. The size of virtual memory + address space are determined by the page table layout. + +config 4KB_3LEVEL + bool "4KB with 3 levels" + select PAGE_SIZE_4KB + select PGTABLE_3LEVEL + help + This option selects 4KB page size with 3 level page tables, which + support a maximum of 39 bits of application virtual memory. + +config 4KB_4LEVEL + bool "4KB with 4 levels" + select PAGE_SIZE_4KB + select PGTABLE_4LEVEL + help + This option selects 4KB page size with 4 level page tables, which + support a maximum of 48 bits of application virtual memory. + +config 16KB_2LEVEL + bool "16KB with 2 levels" + select PAGE_SIZE_16KB + select PGTABLE_2LEVEL + help + This option selects 16KB page size with 2 level page tables, which + support a maximum of 36 bits of application virtual memory. + +config 16KB_3LEVEL + bool "16KB with 3 levels" + select PAGE_SIZE_16KB + select PGTABLE_3LEVEL + help + This option selects 16KB page size with 3 level page tables, which + support a maximum of 47 bits of application virtual memory. + +config 64KB_2LEVEL + bool "64KB with 2 levels" + select PAGE_SIZE_64KB + select PGTABLE_2LEVEL + help + This option selects 64KB page size with 2 level page tables, which + support a maximum of 42 bits of application virtual memory. + +config 64KB_3LEVEL + bool "64KB with 3 levels" + select PAGE_SIZE_64KB + select PGTABLE_3LEVEL + help + This option selects 64KB page size with 3 level page tables, which + support a maximum of 55 bits of application virtual memory. + +endchoice + +config CMDLINE + string "Built-in kernel command line" + help + For most platforms, the arguments for the kernel's command line + are provided at run-time, during boot. However, there are cases + where either no arguments are being provided or the provided + arguments are insufficient or even invalid. + + When that occurs, it is possible to define a built-in command + line here and choose how the kernel should use it later on. + +choice + prompt "Kernel command line type" + default CMDLINE_BOOTLOADER + help + Choose how the kernel will handle the provided built-in command + line. + +config CMDLINE_BOOTLOADER + bool "Use bootloader kernel arguments if available" + help + Prefer the command-line passed by the boot loader if available. + Use the built-in command line as fallback in case we get nothing + during boot. This is the default behaviour. + +config CMDLINE_EXTEND + bool "Use built-in to extend bootloader kernel arguments" + help + The command-line arguments provided during boot will be + appended to the built-in command line. This is useful in + cases where the provided arguments are insufficient and + you don't want to or cannot modify them. + +config CMDLINE_FORCE + bool "Always use the built-in kernel command string" + help + Always use the built-in command line, even if we get one during + boot. This is useful in case you need to override the provided + command line on systems where you don't have or want control + over it. + +endchoice + +config DMI + bool "Enable DMI scanning" + select DMI_SCAN_MACHINE_NON_EFI_FALLBACK + default y + help + This enables SMBIOS/DMI feature for systems, and scanning of + DMI to identify machine quirks. + +config EFI + bool "EFI runtime service support" + select UCS2_STRING + select EFI_PARAMS_FROM_FDT + select EFI_RUNTIME_WRAPPERS + help + This enables the kernel to use EFI runtime services that are + available (such as the EFI variable services). + +config FORCE_MAX_ZONEORDER + int "Maximum zone order" + range 14 64 if PAGE_SIZE_64KB + default "14" if PAGE_SIZE_64KB + range 12 64 if PAGE_SIZE_16KB + default "12" if PAGE_SIZE_16KB + range 11 64 + default "11" + help + The kernel memory allocator divides physically contiguous memory + blocks into "zones", where each zone is a power of two number of + pages. This option selects the largest power of two that the kernel + keeps in the memory allocator. If you need to allocate very large + blocks of physically contiguous memory, then you may need to + increase this value. + + This config option is actually maximum order plus one. For example, + a value of 11 means that the largest free memory block is 2^10 pages. + + The page size is not necessarily 4KB. Keep this in mind + when choosing a value for this option. + +config SECCOMP + bool "Enable seccomp to safely compute untrusted bytecode" + depends on PROC_FS + default y + help + This kernel feature is useful for number crunching applications + that may need to compute untrusted bytecode during their + execution. By using pipes or other transports made available to + the process as file descriptors supporting the read/write + syscalls, it's possible to isolate those applications in + their own address space using seccomp. Once seccomp is + enabled via /proc//seccomp, it cannot be disabled + and the task is only allowed to execute a few safe syscalls + defined by each seccomp mode. + + If unsure, say Y. Only embedded should say N here. + +endmenu + +config ARCH_SELECT_MEMORY_MODEL + def_bool y + +config ARCH_FLATMEM_ENABLE + def_bool y + +config ARCH_SPARSEMEM_ENABLE + def_bool y + help + Say Y to support efficient handling of sparse physical memory, + for architectures which are either NUMA (Non-Uniform Memory Access) + or have huge holes in the physical address space for other reasons. + See for more. + +config ARCH_ENABLE_THP_MIGRATION + def_bool y + depends on TRANSPARENT_HUGEPAGE + +config ARCH_MEMORY_PROBE + def_bool y + depends on MEMORY_HOTPLUG + +config MMU + bool + default y + +config ARCH_MMAP_RND_BITS_MIN + default 12 + +config ARCH_MMAP_RND_BITS_MAX + default 18 + +menu "Power management options" + +source "drivers/acpi/Kconfig" + +endmenu + +source "drivers/firmware/Kconfig" diff --git a/arch/loongarch/Kconfig.debug b/arch/loongarch/Kconfig.debug new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile new file mode 100644 index 000000000000..4c124cc8db59 --- /dev/null +++ b/arch/loongarch/Makefile @@ -0,0 +1,98 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Author: Huacai Chen +# Copyright (C) 2020-2022 Loongson Technology Corporation Limited + +boot := arch/loongarch/boot + +KBUILD_IMAGE = $(boot)/vmlinux + +# +# Select the object file format to substitute into the linker script. +# +64bit-tool-archpref = loongarch64 +32bit-bfd = elf32-loongarch +64bit-bfd = elf64-loongarch +32bit-emul = elf32loongarch +64bit-emul = elf64loongarch + +ifdef CONFIG_64BIT +tool-archpref = $(64bit-tool-archpref) +UTS_MACHINE := loongarch64 +endif + +ifneq ($(SUBARCH),$(ARCH)) + ifeq ($(CROSS_COMPILE),) + CROSS_COMPILE := $(call cc-cross-prefix, $(tool-archpref)-linux- $(tool-archpref)-linux-gnu- $(tool-archpref)-unknown-linux-gnu-) + endif +endif + +ifdef CONFIG_64BIT +ld-emul = $(64bit-emul) +cflags-y += -mabi=lp64s +endif + +cflags-y += -G0 -pipe -msoft-float +LDFLAGS_vmlinux += -G0 -static -n -nostdlib +KBUILD_AFLAGS_KERNEL += -Wa,-mla-global-with-pcrel +KBUILD_CFLAGS_KERNEL += -Wa,-mla-global-with-pcrel +KBUILD_AFLAGS_MODULE += -Wa,-mla-global-with-abs +KBUILD_CFLAGS_MODULE += -fplt -Wa,-mla-global-with-abs,-mla-local-with-abs + +cflags-y += -ffreestanding +cflags-y += $(call cc-option, -mno-check-zero-division) + +load-y = 0x9000000000200000 +bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) + +KBUILD_AFLAGS += $(cflags-y) +KBUILD_CFLAGS += $(cflags-y) +KBUILD_CPPFLAGS += -DVMLINUX_LOAD_ADDRESS=$(load-y) + +# This is required to get dwarf unwinding tables into .debug_frame +# instead of .eh_frame so we don't discard them. +KBUILD_CFLAGS += -fno-asynchronous-unwind-tables + +# Don't emit unaligned accesses. +# Not all LoongArch cores support unaligned access, and as kernel we can't +# rely on others to provide emulation for these accesses. +KBUILD_CFLAGS += $(call cc-option,-mstrict-align) + +KBUILD_CFLAGS += -isystem $(shell $(CC) -print-file-name=include) + +KBUILD_LDFLAGS += -m $(ld-emul) + +ifdef CONFIG_LOONGARCH +CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ + egrep -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \ + sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g') +endif + +head-y := arch/loongarch/kernel/head.o + +libs-y += arch/loongarch/lib/ + +ifeq ($(KBUILD_EXTMOD),) +prepare: vdso_prepare +vdso_prepare: prepare0 + $(Q)$(MAKE) $(build)=arch/loongarch/vdso include/generated/vdso-offsets.h +endif + +PHONY += vdso_install +vdso_install: + $(Q)$(MAKE) $(build)=arch/loongarch/vdso $@ + +all: $(KBUILD_IMAGE) + +$(KBUILD_IMAGE): vmlinux + $(Q)$(MAKE) $(build)=$(boot) $(bootvars-y) $@ + +install: + $(Q)install -D -m 755 $(KBUILD_IMAGE) $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE) + $(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE) + $(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE) + +define archhelp + echo ' install - install kernel into $(INSTALL_PATH)' + echo +endef diff --git a/arch/loongarch/boot/.gitignore b/arch/loongarch/boot/.gitignore new file mode 100644 index 000000000000..49423ee96ef3 --- /dev/null +++ b/arch/loongarch/boot/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +vmlinux* diff --git a/arch/loongarch/boot/Makefile b/arch/loongarch/boot/Makefile new file mode 100644 index 000000000000..0125b17edc98 --- /dev/null +++ b/arch/loongarch/boot/Makefile @@ -0,0 +1,16 @@ +# +# arch/loongarch/boot/Makefile +# +# Copyright (C) 2020-2022 Loongson Technology Corporation Limited +# + +drop-sections := .comment .note .options .note.gnu.build-id +strip-flags := $(addprefix --remove-section=,$(drop-sections)) -S +OBJCOPYFLAGS_vmlinux.efi := -O binary $(strip-flags) + +targets := vmlinux +quiet_cmd_strip = STRIP $@ + cmd_strip = $(STRIP) -s -o $@ $< + +$(obj)/vmlinux: vmlinux FORCE + $(call if_changed,strip) diff --git a/arch/loongarch/boot/dts/Makefile b/arch/loongarch/boot/dts/Makefile new file mode 100644 index 000000000000..5f1f55e911ad --- /dev/null +++ b/arch/loongarch/boot/dts/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only +dtstree := $(srctree)/$(src) + +dtb-y := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts)) diff --git a/arch/loongarch/include/asm/Kbuild b/arch/loongarch/include/asm/Kbuild new file mode 100644 index 000000000000..83bc0681e72b --- /dev/null +++ b/arch/loongarch/include/asm/Kbuild @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0 +generic-y += dma-contiguous.h +generic-y += export.h +generic-y += parport.h +generic-y += early_ioremap.h +generic-y += qrwlock.h +generic-y += qrwlock_types.h +generic-y += spinlock.h +generic-y += spinlock_types.h +generic-y += rwsem.h +generic-y += segment.h +generic-y += user.h +generic-y += stat.h +generic-y += fcntl.h +generic-y += ioctl.h +generic-y += ioctls.h +generic-y += mman.h +generic-y += msgbuf.h +generic-y += sembuf.h +generic-y += shmbuf.h +generic-y += statfs.h +generic-y += socket.h +generic-y += sockios.h +generic-y += termios.h +generic-y += termbits.h +generic-y += poll.h +generic-y += param.h +generic-y += posix_types.h +generic-y += resource.h +generic-y += kvm_para.h diff --git a/arch/loongarch/include/uapi/asm/Kbuild b/arch/loongarch/include/uapi/asm/Kbuild new file mode 100644 index 000000000000..4aa680ca2e5f --- /dev/null +++ b/arch/loongarch/include/uapi/asm/Kbuild @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +generic-y += kvm_para.h diff --git a/arch/loongarch/kernel/.gitignore b/arch/loongarch/kernel/.gitignore new file mode 100644 index 000000000000..bbb90f92d051 --- /dev/null +++ b/arch/loongarch/kernel/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +vmlinux.lds diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile new file mode 100644 index 000000000000..e5a3b2fb9961 --- /dev/null +++ b/arch/loongarch/kernel/Makefile @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for the Linux/LoongArch kernel. +# + +extra-y := head.o vmlinux.lds + +obj-y += cpu-probe.o cacheinfo.o env.o setup.o entry.o genex.o \ + traps.o irq.o idle.o process.o dma.o mem.o io.o reset.o switch.o \ + elf.o syscall.o signal.o time.o topology.o inst.o ptrace.o vdso.o + +obj-$(CONFIG_ACPI) += acpi.o +obj-$(CONFIG_EFI) += efi.o + +obj-$(CONFIG_CPU_HAS_FPU) += fpu.o + +obj-$(CONFIG_MODULES) += module.o module-sections.o + +obj-$(CONFIG_PROC_FS) += proc.o + +CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS) diff --git a/arch/loongarch/kernel/vmlinux.lds.S b/arch/loongarch/kernel/vmlinux.lds.S new file mode 100644 index 000000000000..f6ce24f403c2 --- /dev/null +++ b/arch/loongarch/kernel/vmlinux.lds.S @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include +#include +#include + +#define PAGE_SIZE _PAGE_SIZE + +/* + * Put .bss..swapper_pg_dir as the first thing in .bss. This will + * ensure that it has .bss alignment (64K). + */ +#define BSS_FIRST_SECTIONS *(.bss..swapper_pg_dir) + +#include + +/* + * Max avaliable Page Size is 64K, so we set SectionAlignment + * field of EFI application to 64K. + */ +PECOFF_FILE_ALIGN = 0x200; +PECOFF_SEGMENT_ALIGN = 0x10000; + +OUTPUT_ARCH(loongarch) +ENTRY(kernel_entry) +PHDRS { + text PT_LOAD FLAGS(7); /* RWX */ + note PT_NOTE FLAGS(4); /* R__ */ +} + +jiffies = jiffies_64; + +SECTIONS +{ + . = VMLINUX_LOAD_ADDRESS; + + _text = .; + HEAD_TEXT_SECTION + + . = ALIGN(PECOFF_SEGMENT_ALIGN); + .text : { + TEXT_TEXT + SCHED_TEXT + CPUIDLE_TEXT + LOCK_TEXT + KPROBES_TEXT + IRQENTRY_TEXT + SOFTIRQENTRY_TEXT + *(.fixup) + *(.gnu.warning) + } :text = 0 + . = ALIGN(PECOFF_SEGMENT_ALIGN); + _etext = .; + + EXCEPTION_TABLE(16) + + . = ALIGN(PECOFF_SEGMENT_ALIGN); + __init_begin = .; + __inittext_begin = .; + + INIT_TEXT_SECTION(PAGE_SIZE) + .exit.text : { + EXIT_TEXT + } + + . = ALIGN(PECOFF_SEGMENT_ALIGN); + __inittext_end = .; + + __initdata_begin = .; + + INIT_DATA_SECTION(16) + .exit.data : { + EXIT_DATA + } + + .init.bss : { + *(.init.bss) + } + . = ALIGN(PECOFF_SEGMENT_ALIGN); + __initdata_end = .; + + __init_end = .; + + _sdata = .; + RO_DATA(4096) + RW_DATA(1 << CONFIG_L1_CACHE_SHIFT, PAGE_SIZE, THREAD_SIZE) + + .sdata : { + *(.sdata) + } + .edata_padding : { BYTE(0); . = ALIGN(PECOFF_FILE_ALIGN); } + _edata = .; + + BSS_SECTION(0, SZ_64K, 8) + . = ALIGN(PECOFF_SEGMENT_ALIGN); + + _end = .; + + STABS_DEBUG + DWARF_DEBUG + + .gptab.sdata : { + *(.gptab.data) + *(.gptab.sdata) + } + .gptab.sbss : { + *(.gptab.bss) + *(.gptab.sbss) + } + + DISCARDS + /DISCARD/ : { + *(.gnu.attributes) + *(.options) + *(.eh_frame) + } +} diff --git a/arch/loongarch/lib/Makefile b/arch/loongarch/lib/Makefile new file mode 100644 index 000000000000..e36635fccb69 --- /dev/null +++ b/arch/loongarch/lib/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for LoongArch-specific library files. +# + +lib-y += delay.o clear_user.o copy_user.o dump_tlb.o diff --git a/arch/loongarch/mm/Makefile b/arch/loongarch/mm/Makefile new file mode 100644 index 000000000000..8ffc6383f836 --- /dev/null +++ b/arch/loongarch/mm/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for the Linux/LoongArch-specific parts of the memory manager. +# + +obj-y += init.o cache.o tlb.o tlbex.o extable.o \ + fault.o ioremap.o maccess.o mmap.o pgtable.o page.o + +obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o diff --git a/arch/loongarch/pci/Makefile b/arch/loongarch/pci/Makefile new file mode 100644 index 000000000000..8101ef3df71c --- /dev/null +++ b/arch/loongarch/pci/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for the PCI specific kernel interface routines under Linux. +# + +obj-y += pci.o +obj-$(CONFIG_ACPI) += acpi.o diff --git a/arch/loongarch/vdso/.gitignore b/arch/loongarch/vdso/.gitignore new file mode 100644 index 000000000000..652e31d82582 --- /dev/null +++ b/arch/loongarch/vdso/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +vdso.lds diff --git a/scripts/subarch.include b/scripts/subarch.include index 776849a3c500..4bd327d0ae42 100644 --- a/scripts/subarch.include +++ b/scripts/subarch.include @@ -10,4 +10,4 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \ -e s/s390x/s390/ \ -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \ - -e s/riscv.*/riscv/) + -e s/riscv.*/riscv/ -e s/loongarch.*/loongarch/) -- cgit v1.2.3 From b0d6207bad2cb5a6f2099ac4a6ea4e76864dd596 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 29 May 2022 00:47:02 +0900 Subject: kbuild: clean .tmp_* pattern by make clean Change the "make clean" rule to remove all the .tmp_* files. .tmp_objdiff is the only exception, which should be removed by "make mrproper". Rename the record directory of objdiff, .tmp_objdiff to .objdiff to avoid the removal by "make clean". Signed-off-by: Masahiro Yamada Tested-by: Sedat Dilek # LLVM-14 (x86-64) --- Makefile | 4 ++-- scripts/link-vmlinux.sh | 3 --- scripts/objdiff | 6 +++--- 3 files changed, 5 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index edc3f44cd96c..7011d43dff35 100644 --- a/Makefile +++ b/Makefile @@ -1490,7 +1490,7 @@ CLEAN_FILES += include/ksym vmlinux.symvers modules-only.symvers \ # Directories & files removed with 'make mrproper' MRPROPER_FILES += include/config include/generated \ - arch/$(SRCARCH)/include/generated .tmp_objdiff \ + arch/$(SRCARCH)/include/generated .objdiff \ debian snap tar-install \ .config .config.old .version \ Module.symvers \ @@ -1857,7 +1857,7 @@ clean: $(clean-dirs) -o -name '*.lex.c' -o -name '*.tab.[ch]' \ -o -name '*.asn1.[ch]' \ -o -name '*.symtypes' -o -name 'modules.order' \ - -o -name '.tmp_*.o.*' \ + -o -name '.tmp_*' \ -o -name '*.c.[012]*.*' \ -o -name '*.ll' \ -o -name '*.gcno' \ diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 1c0af7288b79..3f51b08cc203 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -303,9 +303,6 @@ sorttable() cleanup() { rm -f .btf.* - rm -f .tmp_System.map - rm -f .tmp_initcalls.lds - rm -f .tmp_vmlinux* rm -f System.map rm -f vmlinux rm -f vmlinux.map diff --git a/scripts/objdiff b/scripts/objdiff index 72b0b63c3fe1..0685bc3ce3df 100755 --- a/scripts/objdiff +++ b/scripts/objdiff @@ -20,10 +20,10 @@ # $ ./scripts/objdiff diff COMMIT_A COMMIT_B # $ -# And to clean up (everything is in .tmp_objdiff/*) +# And to clean up (everything is in .objdiff/*) # $ ./scripts/objdiff clean all # -# Note: 'make mrproper' will also remove .tmp_objdiff +# Note: 'make mrproper' will also remove .objdiff SRCTREE=$(cd $(git rev-parse --show-toplevel 2>/dev/null); pwd) @@ -32,7 +32,7 @@ if [ -z "$SRCTREE" ]; then exit 1 fi -TMPD=$SRCTREE/.tmp_objdiff +TMPD=$SRCTREE/.objdiff usage() { echo >&2 "Usage: $0 " -- cgit v1.2.3 From 5d45950dfbb1540bba3e3762a3497de8b4a715d3 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 29 May 2022 00:47:03 +0900 Subject: kbuild: move vmlinux.o link to scripts/Makefile.vmlinux_o This is a preparation for moving the objtool rule in the next commit. Signed-off-by: Masahiro Yamada Tested-by: Sedat Dilek # LLVM-14 (x86-64) --- scripts/Makefile.vmlinux_o | 61 ++++++++++++++++++++++++++++++++++++++++++++++ scripts/link-vmlinux.sh | 41 +------------------------------ 2 files changed, 62 insertions(+), 40 deletions(-) create mode 100644 scripts/Makefile.vmlinux_o (limited to 'scripts') diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o new file mode 100644 index 000000000000..a9b375ca86d5 --- /dev/null +++ b/scripts/Makefile.vmlinux_o @@ -0,0 +1,61 @@ +# SPDX-License-Identifier: GPL-2.0-only + +PHONY := __default +__default: vmlinux.o + +include include/config/auto.conf +include $(srctree)/scripts/Kbuild.include + +# Generate a linker script to ensure correct ordering of initcalls for Clang LTO +# --------------------------------------------------------------------------- + +quiet_cmd_gen_initcalls_lds = GEN $@ + cmd_gen_initcalls_lds = \ + $(PYTHON3) $(srctree)/scripts/jobserver-exec \ + $(PERL) $(real-prereqs) > $@ + +.tmp_initcalls.lds: $(srctree)/scripts/generate_initcall_order.pl \ + $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) FORCE + $(call if_changed,gen_initcalls_lds) + +targets := .tmp_initcalls.lds + +ifdef CONFIG_LTO_CLANG +initcalls-lds := .tmp_initcalls.lds +endif + +# Link of vmlinux.o used for section mismatch analysis +# --------------------------------------------------------------------------- + +quiet_cmd_ld_vmlinux.o = LD $@ + cmd_ld_vmlinux.o = \ + $(LD) ${KBUILD_LDFLAGS} -r -o $@ \ + $(addprefix -T , $(initcalls-lds)) \ + --whole-archive $(KBUILD_VMLINUX_OBJS) --no-whole-archive \ + --start-group $(KBUILD_VMLINUX_LIBS) --end-group \ + +define rule_ld_vmlinux.o + $(call cmd_and_savecmd,ld_vmlinux.o) +endef + +vmlinux.o: $(initcalls-lds) $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) FORCE + $(call if_changed_rule,ld_vmlinux.o) + +targets += vmlinux.o + +# Add FORCE to the prequisites of a target to force it to be always rebuilt. +# --------------------------------------------------------------------------- + +PHONY += FORCE +FORCE: + +# Read all saved command lines and dependencies for the $(targets) we +# may be building above, using $(if_changed{,_dep}). As an +# optimization, we don't need to read them if the target does not +# exist, we will rebuild anyway in that case. + +existing-targets := $(wildcard $(sort $(targets))) + +-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) + +.PHONY: $(PHONY) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 3f51b08cc203..bf685d4547c1 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -45,45 +45,6 @@ info() printf " %-7s %s\n" "${1}" "${2}" } -# Generate a linker script to ensure correct ordering of initcalls. -gen_initcalls() -{ - info GEN .tmp_initcalls.lds - - ${PYTHON3} ${srctree}/scripts/jobserver-exec \ - ${PERL} ${srctree}/scripts/generate_initcall_order.pl \ - ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS} \ - > .tmp_initcalls.lds -} - -# Link of vmlinux.o used for section mismatch analysis -# ${1} output file -modpost_link() -{ - local objects - local lds="" - - objects="--whole-archive \ - ${KBUILD_VMLINUX_OBJS} \ - --no-whole-archive \ - --start-group \ - ${KBUILD_VMLINUX_LIBS} \ - --end-group" - - if is_enabled CONFIG_LTO_CLANG; then - gen_initcalls - lds="-T .tmp_initcalls.lds" - - # This might take a while, so indicate that we're doing - # an LTO link - info LTO ${1} - else - info LD ${1} - fi - - ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${lds} ${objects} -} - objtool_link() { local objtoolcmd; @@ -336,7 +297,7 @@ fi; ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1 #link vmlinux.o -modpost_link vmlinux.o +${MAKE} -f "${srctree}/scripts/Makefile.vmlinux_o" objtool_link vmlinux.o # Generate the list of in-tree objects in vmlinux -- cgit v1.2.3 From b42d2306502419688190aa6dd4dab4a6def24b3d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 29 May 2022 00:47:04 +0900 Subject: kbuild: factor out the common objtool arguments scripts/Makefile.build and scripts/link-vmlinux.sh have similar setups for the objtool arguments. It was difficult to factor out them because all the vmlinux build rules were written in a shell script. It is somewhat tedious to touch the two files every time a new objtool option is supported. To reduce the code duplication, move the objtool for vmlinux.o into scripts/Makefile.vmlinux_o. Then, move the common macros to Makefile.lib so they are shared between Makefile.build and Makefile.vmlinux_o. Signed-off-by: Masahiro Yamada Tested-by: Sedat Dilek # LLVM-14 (x86-64) --- scripts/Makefile.build | 26 ----------------- scripts/Makefile.lib | 26 +++++++++++++++++ scripts/Makefile.vmlinux_o | 26 +++++++++++++++++ scripts/link-vmlinux.sh | 71 ---------------------------------------------- 4 files changed, 52 insertions(+), 97 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 4cb7145071b9..1f01ac65c0cd 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -210,38 +210,12 @@ cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), $(sub_cmd_record_mcount)) endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT -ifdef CONFIG_OBJTOOL - -objtool := $(objtree)/tools/objtool/objtool - -objtool_args = \ - $(if $(CONFIG_HAVE_JUMP_LABEL_HACK), --hacks=jump_label) \ - $(if $(CONFIG_HAVE_NOINSTR_HACK), --hacks=noinstr) \ - $(if $(CONFIG_X86_KERNEL_IBT), --ibt) \ - $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ - $(if $(CONFIG_UNWINDER_ORC), --orc) \ - $(if $(CONFIG_RETPOLINE), --retpoline) \ - $(if $(CONFIG_SLS), --sls) \ - $(if $(CONFIG_STACK_VALIDATION), --stackval) \ - $(if $(CONFIG_HAVE_STATIC_CALL_INLINE), --static-call) \ - --uaccess \ - $(if $(delay-objtool), --link) \ - $(if $(part-of-module), --module) \ - $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) - -cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@) -cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd) - -endif # CONFIG_OBJTOOL - # 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory # 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file # 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y) -delay-objtool := $(or $(CONFIG_LTO_CLANG),$(CONFIG_X86_KERNEL_IBT)) - $(obj)/%.o: objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y)) ifdef CONFIG_TRIM_UNUSED_KSYMS diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index f75138385449..f691fb231ce5 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -225,6 +225,32 @@ dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \ $(addprefix -I,$(DTC_INCLUDE)) \ -undef -D__DTS__ +ifdef CONFIG_OBJTOOL + +objtool := $(objtree)/tools/objtool/objtool + +objtool_args = \ + $(if $(CONFIG_HAVE_JUMP_LABEL_HACK), --hacks=jump_label) \ + $(if $(CONFIG_HAVE_NOINSTR_HACK), --hacks=noinstr) \ + $(if $(CONFIG_X86_KERNEL_IBT), --ibt) \ + $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ + $(if $(CONFIG_UNWINDER_ORC), --orc) \ + $(if $(CONFIG_RETPOLINE), --retpoline) \ + $(if $(CONFIG_SLS), --sls) \ + $(if $(CONFIG_STACK_VALIDATION), --stackval) \ + $(if $(CONFIG_HAVE_STATIC_CALL_INLINE), --static-call) \ + --uaccess \ + $(if $(delay-objtool), --link) \ + $(if $(part-of-module), --module) \ + $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) + +delay-objtool := $(or $(CONFIG_LTO_CLANG),$(CONFIG_X86_KERNEL_IBT)) + +cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@) +cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd) + +endif # CONFIG_OBJTOOL + # Useful for describing the dependency of composite objects # Usage: # $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add) diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o index a9b375ca86d5..3c97a1564947 100644 --- a/scripts/Makefile.vmlinux_o +++ b/scripts/Makefile.vmlinux_o @@ -6,6 +6,9 @@ __default: vmlinux.o include include/config/auto.conf include $(srctree)/scripts/Kbuild.include +# for objtool +include $(srctree)/scripts/Makefile.lib + # Generate a linker script to ensure correct ordering of initcalls for Clang LTO # --------------------------------------------------------------------------- @@ -24,6 +27,27 @@ ifdef CONFIG_LTO_CLANG initcalls-lds := .tmp_initcalls.lds endif +# objtool for vmlinux.o +# --------------------------------------------------------------------------- +# +# For LTO and IBT, objtool doesn't run on individual translation units. +# Run everything on vmlinux instead. + +objtool-enabled := $(or $(delay-objtool),$(CONFIG_NOINSTR_VALIDATION)) + +# Reuse objtool_args defined in scripts/Makefile.lib if LTO or IBT is enabled. +# +# Add some more flags as needed. +# --no-unreachable and --link might be added twice, but it is fine. +# +# Expand objtool_args to a simple variable to avoid circular reference. + +objtool_args := \ + $(if $(delay-objtool),$(objtool_args)) \ + $(if $(CONFIG_NOINSTR_VALIDATION), --noinstr) \ + $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) \ + --link + # Link of vmlinux.o used for section mismatch analysis # --------------------------------------------------------------------------- @@ -33,9 +57,11 @@ quiet_cmd_ld_vmlinux.o = LD $@ $(addprefix -T , $(initcalls-lds)) \ --whole-archive $(KBUILD_VMLINUX_OBJS) --no-whole-archive \ --start-group $(KBUILD_VMLINUX_LIBS) --end-group \ + $(cmd_objtool) define rule_ld_vmlinux.o $(call cmd_and_savecmd,ld_vmlinux.o) + $(call cmd,gen_objtooldep) endef vmlinux.o: $(initcalls-lds) $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) FORCE diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index bf685d4547c1..eecc1863e556 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -45,76 +45,6 @@ info() printf " %-7s %s\n" "${1}" "${2}" } -objtool_link() -{ - local objtoolcmd; - local objtoolopt; - - if ! is_enabled CONFIG_OBJTOOL; then - return; - fi - - if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then - - # For LTO and IBT, objtool doesn't run on individual - # translation units. Run everything on vmlinux instead. - - if is_enabled CONFIG_HAVE_JUMP_LABEL_HACK; then - objtoolopt="${objtoolopt} --hacks=jump_label" - fi - - if is_enabled CONFIG_HAVE_NOINSTR_HACK; then - objtoolopt="${objtoolopt} --hacks=noinstr" - fi - - if is_enabled CONFIG_X86_KERNEL_IBT; then - objtoolopt="${objtoolopt} --ibt" - fi - - if is_enabled CONFIG_FTRACE_MCOUNT_USE_OBJTOOL; then - objtoolopt="${objtoolopt} --mcount" - fi - - if is_enabled CONFIG_UNWINDER_ORC; then - objtoolopt="${objtoolopt} --orc" - fi - - if is_enabled CONFIG_RETPOLINE; then - objtoolopt="${objtoolopt} --retpoline" - fi - - if is_enabled CONFIG_SLS; then - objtoolopt="${objtoolopt} --sls" - fi - - if is_enabled CONFIG_STACK_VALIDATION; then - objtoolopt="${objtoolopt} --stackval" - fi - - if is_enabled CONFIG_HAVE_STATIC_CALL_INLINE; then - objtoolopt="${objtoolopt} --static-call" - fi - - objtoolopt="${objtoolopt} --uaccess" - fi - - if is_enabled CONFIG_NOINSTR_VALIDATION; then - objtoolopt="${objtoolopt} --noinstr" - fi - - if [ -n "${objtoolopt}" ]; then - - if is_enabled CONFIG_GCOV_KERNEL; then - objtoolopt="${objtoolopt} --no-unreachable" - fi - - objtoolopt="${objtoolopt} --link" - - info OBJTOOL ${1} - tools/objtool/objtool ${objtoolopt} ${1} - fi -} - # Link of vmlinux # ${1} - output file # ${2}, ${3}, ... - optional extra .o files @@ -298,7 +228,6 @@ ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1 #link vmlinux.o ${MAKE} -f "${srctree}/scripts/Makefile.vmlinux_o" -objtool_link vmlinux.o # Generate the list of in-tree objects in vmlinux # -- cgit v1.2.3 From 8c9ce89c5b63028dd3be43807f10b009cd2c6e51 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 30 May 2022 18:01:38 +0900 Subject: modpost: simplify mod->name allocation mod->name is set to the ELF filename with the suffix ".o" stripped. The current code calls strdup() and free() to manipulate the string, but a simpler approach is to pass new_module() with the name length subtracted by 2. Also, check if the passed filename ends with ".o" before stripping it. The current code blindly chops the suffix: tmp[strlen(tmp) - 2] = '\0' It will cause buffer under-run if strlen(tmp) < 2; Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 9269735f85c5..c1558bacf717 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -172,11 +172,11 @@ static struct module *find_module(const char *modname) return NULL; } -static struct module *new_module(const char *modname) +static struct module *new_module(const char *name, size_t namelen) { struct module *mod; - mod = NOFAIL(malloc(sizeof(*mod) + strlen(modname) + 1)); + mod = NOFAIL(malloc(sizeof(*mod) + namelen + 1)); memset(mod, 0, sizeof(*mod)); INIT_LIST_HEAD(&mod->exported_symbols); @@ -184,8 +184,9 @@ static struct module *new_module(const char *modname) INIT_LIST_HEAD(&mod->missing_namespaces); INIT_LIST_HEAD(&mod->imported_namespaces); - strcpy(mod->name, modname); - mod->is_vmlinux = (strcmp(modname, "vmlinux") == 0); + memcpy(mod->name, name, namelen); + mod->name[namelen] = '\0'; + mod->is_vmlinux = (strcmp(mod->name, "vmlinux") == 0); /* * Set mod->is_gpl_compatible to true by default. If MODULE_LICENSE() @@ -2017,16 +2018,14 @@ static void read_symbols(const char *modname) if (!parse_elf(&info, modname)) return; - { - char *tmp; - - /* strip trailing .o */ - tmp = NOFAIL(strdup(modname)); - tmp[strlen(tmp) - 2] = '\0'; - mod = new_module(tmp); - free(tmp); + if (!strends(modname, ".o")) { + error("%s: filename must be suffixed with .o\n", modname); + return; } + /* strip trailing .o */ + mod = new_module(modname, strlen(modname) - strlen(".o")); + if (!mod->is_vmlinux) { license = get_modinfo(&info, "license"); if (!license) @@ -2488,7 +2487,7 @@ static void read_dump(const char *fname) mod = find_module(modname); if (!mod) { - mod = new_module(modname); + mod = new_module(modname, strlen(modname)); mod->from_dump = true; } s = sym_add_exported(symname, mod, gpl_only); -- cgit v1.2.3 From a89227d769845eb9e9ab113f9f83df34d3c91db5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 30 May 2022 18:01:39 +0900 Subject: modpost: use fnmatch() to simplify match() Replace the own implementation for wildcard (glob) matching with a function call to fnmatch(). Also, change the return type to 'bool'. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 74 +++++++++------------------------------------------ 1 file changed, 13 insertions(+), 61 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c1558bacf717..29d5a841e215 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -13,6 +13,7 @@ #define _GNU_SOURCE #include +#include #include #include #include @@ -710,29 +711,6 @@ static char *get_modinfo(struct elf_info *info, const char *tag) return get_next_modinfo(info, tag, NULL); } -/** - * Test if string s ends in string sub - * return 0 if match - **/ -static int strrcmp(const char *s, const char *sub) -{ - int slen, sublen; - - if (!s || !sub) - return 1; - - slen = strlen(s); - sublen = strlen(sub); - - if ((slen == 0) || (sublen == 0)) - return 1; - - if (sublen > slen) - return 1; - - return memcmp(s + slen - sublen, sub, sublen); -} - static const char *sym_name(struct elf_info *elf, Elf_Sym *sym) { if (sym) @@ -741,48 +719,22 @@ static const char *sym_name(struct elf_info *elf, Elf_Sym *sym) return "(unknown)"; } -/* The pattern is an array of simple patterns. - * "foo" will match an exact string equal to "foo" - * "*foo" will match a string that ends with "foo" - * "foo*" will match a string that begins with "foo" - * "*foo*" will match a string that contains "foo" +/* + * Check whether the 'string' argument matches one of the 'patterns', + * an array of shell wildcard patterns (glob). + * + * Return true is there is a match. */ -static int match(const char *sym, const char * const pat[]) +static bool match(const char *string, const char *const patterns[]) { - const char *p; - while (*pat) { - const char *endp; - - p = *pat++; - endp = p + strlen(p) - 1; + const char *pattern; - /* "*foo*" */ - if (*p == '*' && *endp == '*') { - char *bare = NOFAIL(strndup(p + 1, strlen(p) - 2)); - char *here = strstr(sym, bare); - - free(bare); - if (here != NULL) - return 1; - } - /* "*foo" */ - else if (*p == '*') { - if (strrcmp(sym, p + 1) == 0) - return 1; - } - /* "foo*" */ - else if (*endp == '*') { - if (strncmp(sym, p, strlen(p) - 1) == 0) - return 1; - } - /* no wildcards */ - else { - if (strcmp(p, sym) == 0) - return 1; - } + while ((pattern = *patterns++)) { + if (!fnmatch(pattern, string, 0)) + return true; } - /* no match */ - return 0; + + return false; } /* sections that we do not want to do full section mismatch check on */ -- cgit v1.2.3 From 2bbb486162c4ace673ea423bbd7e7b40f020ad45 Mon Sep 17 00:00:00 2001 From: Isak Ellmer Date: Wed, 1 Jun 2022 15:08:19 +0200 Subject: scripts: kconfig: nconf: make nconfig accept jk keybindings Make nconfig accept jk keybindings for movement in addition to arrow keys. Signed-off-by: Isak Ellmer Signed-off-by: Masahiro Yamada --- scripts/kconfig/nconf.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 7b371bd7fb36..3ba8b1af390f 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -52,8 +52,8 @@ static const char nconf_global_help[] = "\n" "Menu navigation keys\n" "----------------------------------------------------------------------\n" -"Linewise up \n" -"Linewise down \n" +"Linewise up \n" +"Linewise down \n" "Pagewise up \n" "Pagewise down \n" "First entry \n" @@ -1105,9 +1105,11 @@ static void conf(struct menu *menu) break; switch (res) { case KEY_DOWN: + case 'j': menu_driver(curses_menu, REQ_DOWN_ITEM); break; case KEY_UP: + case 'k': menu_driver(curses_menu, REQ_UP_ITEM); break; case KEY_NPAGE: @@ -1287,9 +1289,11 @@ static void conf_choice(struct menu *menu) break; switch (res) { case KEY_DOWN: + case 'j': menu_driver(curses_menu, REQ_DOWN_ITEM); break; case KEY_UP: + case 'k': menu_driver(curses_menu, REQ_UP_ITEM); break; case KEY_NPAGE: -- cgit v1.2.3 From 42ce60aa5aa46ae00f71aa806a11510b6db6d1a7 Mon Sep 17 00:00:00 2001 From: Schspa Shi Date: Fri, 3 Jun 2022 17:38:52 +0800 Subject: kbuild: Allow to select bash in a modified environment This fixes the build error when the system has a default bash version which is too old to support associative array variables. The build error log as fellowing: linux/scripts/check-local-export: line 11: declare: -A: invalid option declare: usage: declare [-afFirtx] [-p] [name[=value] ...] Signed-off-by: Schspa Shi Signed-off-by: Masahiro Yamada --- scripts/check-local-export | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/check-local-export b/scripts/check-local-export index 2c46912be0ef..da745e2743b7 100755 --- a/scripts/check-local-export +++ b/scripts/check-local-export @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # SPDX-License-Identifier: GPL-2.0-only # # Copyright (C) 2022 Masahiro Yamada -- cgit v1.2.3 From dcea997beed694cbd8705100ca1a6eb0d886de69 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Wed, 1 Jun 2022 17:42:22 -0700 Subject: faddr2line: Fix overlapping text section failures, the sequel If a function lives in a section other than .text, but .text also exists in the object, faddr2line may wrongly assume .text. This can result in comically wrong output. For example: $ scripts/faddr2line vmlinux.o enter_from_user_mode+0x1c enter_from_user_mode+0x1c/0x30: find_next_bit at /home/jpoimboe/git/linux/./include/linux/find.h:40 (inlined by) perf_clear_dirty_counters at /home/jpoimboe/git/linux/arch/x86/events/core.c:2504 Fix it by passing the section name to addr2line, unless the object file is vmlinux, in which case the symbol table uses absolute addresses. Fixes: 1d1a0e7c5100 ("scripts/faddr2line: Fix overlapping text section failures") Reported-by: Peter Zijlstra Signed-off-by: Josh Poimboeuf Link: https://lore.kernel.org/r/7d25bc1408bd3a750ac26e60d2f2815a5f4a8363.1654130536.git.jpoimboe@kernel.org --- scripts/faddr2line | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/scripts/faddr2line b/scripts/faddr2line index 0e6268d59883..94ed98dd899f 100755 --- a/scripts/faddr2line +++ b/scripts/faddr2line @@ -95,17 +95,25 @@ __faddr2line() { local print_warnings=$4 local sym_name=${func_addr%+*} - local offset=${func_addr#*+} - offset=${offset%/*} + local func_offset=${func_addr#*+} + func_offset=${func_offset%/*} local user_size= + local file_type + local is_vmlinux=0 [[ $func_addr =~ "/" ]] && user_size=${func_addr#*/} - if [[ -z $sym_name ]] || [[ -z $offset ]] || [[ $sym_name = $func_addr ]]; then + if [[ -z $sym_name ]] || [[ -z $func_offset ]] || [[ $sym_name = $func_addr ]]; then warn "bad func+offset $func_addr" DONE=1 return fi + # vmlinux uses absolute addresses in the section table rather than + # section offsets. + local file_type=$(${READELF} --file-header $objfile | + ${AWK} '$1 == "Type:" { print $2; exit }') + [[ $file_type = "EXEC" ]] && is_vmlinux=1 + # Go through each of the object's symbols which match the func name. # In rare cases there might be duplicates, in which case we print all # matches. @@ -114,9 +122,11 @@ __faddr2line() { local sym_addr=0x${fields[1]} local sym_elf_size=${fields[2]} local sym_sec=${fields[6]} + local sec_size + local sec_name # Get the section size: - local sec_size=$(${READELF} --section-headers --wide $objfile | + sec_size=$(${READELF} --section-headers --wide $objfile | sed 's/\[ /\[/' | ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print "0x" $6; exit }') @@ -126,6 +136,17 @@ __faddr2line() { return fi + # Get the section name: + sec_name=$(${READELF} --section-headers --wide $objfile | + sed 's/\[ /\[/' | + ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print $2; exit }') + + if [[ -z $sec_name ]]; then + warn "bad section name: section: $sym_sec" + DONE=1 + return + fi + # Calculate the symbol size. # # Unfortunately we can't use the ELF size, because kallsyms @@ -174,10 +195,10 @@ __faddr2line() { sym_size=0x$(printf %x $sym_size) - # Calculate the section address from user-supplied offset: - local addr=$(($sym_addr + $offset)) + # Calculate the address from user-supplied offset: + local addr=$(($sym_addr + $func_offset)) if [[ -z $addr ]] || [[ $addr = 0 ]]; then - warn "bad address: $sym_addr + $offset" + warn "bad address: $sym_addr + $func_offset" DONE=1 return fi @@ -191,9 +212,9 @@ __faddr2line() { fi # Make sure the provided offset is within the symbol's range: - if [[ $offset -gt $sym_size ]]; then + if [[ $func_offset -gt $sym_size ]]; then [[ $print_warnings = 1 ]] && - echo "skipping $sym_name address at $addr due to size mismatch ($offset > $sym_size)" + echo "skipping $sym_name address at $addr due to size mismatch ($func_offset > $sym_size)" continue fi @@ -202,11 +223,13 @@ __faddr2line() { [[ $FIRST = 0 ]] && echo FIRST=0 - echo "$sym_name+$offset/$sym_size:" + echo "$sym_name+$func_offset/$sym_size:" # Pass section address to addr2line and strip absolute paths # from the output: - local output=$(${ADDR2LINE} -fpie $objfile $addr | sed "s; $dir_prefix\(\./\)*; ;") + local args="--functions --pretty-print --inlines --exe=$objfile" + [[ $is_vmlinux = 0 ]] && args="$args --section=$sec_name" + local output=$(${ADDR2LINE} $args $addr | sed "s; $dir_prefix\(\./\)*; ;") [[ -z $output ]] && continue # Default output (non --list): -- cgit v1.2.3 From 7bf179de5b2dfae54a6839eaf7caba44a888ee2e Mon Sep 17 00:00:00 2001 From: Kevin Locke Date: Mon, 6 Jun 2022 20:42:54 -0600 Subject: kbuild: avoid regex RS for POSIX awk In 22f26f21774f8 awk was added to deduplicate *.mod files. The awk invocation passes -v RS='( |\n)' to match a space or newline character as the record separator. Unfortunately, POSIX states[1] > If RS contains more than one character, the results are unspecified. Some implementations (such as the One True Awk[2] used by the BSDs) do not treat RS as a regular expression. When awk does not support regex RS, build failures such as the following are produced (first error using allmodconfig): CC [M] arch/x86/events/intel/uncore.o CC [M] arch/x86/events/intel/uncore_nhmex.o CC [M] arch/x86/events/intel/uncore_snb.o CC [M] arch/x86/events/intel/uncore_snbep.o CC [M] arch/x86/events/intel/uncore_discovery.o LD [M] arch/x86/events/intel/intel-uncore.o ld: cannot find uncore_nhmex.o: No such file or directory ld: cannot find uncore_snb.o: No such file or directory ld: cannot find uncore_snbep.o: No such file or directory ld: cannot find uncore_discovery.o: No such file or directory make[3]: *** [scripts/Makefile.build:422: arch/x86/events/intel/intel-uncore.o] Error 1 make[2]: *** [scripts/Makefile.build:487: arch/x86/events/intel] Error 2 make[1]: *** [scripts/Makefile.build:487: arch/x86/events] Error 2 make: *** [Makefile:1839: arch/x86] Error 2 To avoid this, use printf(1) to produce a newline between each object path, instead of the space produced by echo(1), so that the default RS can be used by awk. [1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html [2]: https://github.com/onetrueawk/awk Fixes: 22f26f21774f ("kbuild: get rid of duplication in *.mod files") Signed-off-by: Kevin Locke Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 1f01ac65c0cd..cac070aee791 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -251,8 +251,8 @@ $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE # To make this rule robust against "Argument list too long" error, # ensure to add $(obj)/ prefix by a shell command. -cmd_mod = echo $(call real-search, $*.o, .o, -objs -y -m) | \ - $(AWK) -v RS='( |\n)' '!x[$$0]++ { print("$(obj)/"$$0) }' > $@ +cmd_mod = printf '%s\n' $(call real-search, $*.o, .o, -objs -y -m) | \ + $(AWK) '!x[$$0]++ { print("$(obj)/"$$0) }' > $@ $(obj)/%.mod: FORCE $(call if_changed,mod) -- cgit v1.2.3 From 49c3ca34f7dbe5227c0163cba4deb5d29e145fae Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Jun 2022 00:18:40 +0900 Subject: scripts/nsdeps: adjust to the format change of *.mod files Commit 22f26f21774f ("kbuild: get rid of duplication in *.mod files") changed the format of *.mod files to put one object per line, but missed to adjust scripts/nsdeps. Fixes: 22f26f21774f ("kbuild: get rid of duplication in *.mod files") Signed-off-by: Masahiro Yamada --- scripts/nsdeps | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/nsdeps b/scripts/nsdeps index 04c4b96e95ec..f1718cc0d700 100644 --- a/scripts/nsdeps +++ b/scripts/nsdeps @@ -34,9 +34,8 @@ generate_deps() { local mod=${1%.ko:} shift local namespaces="$*" - local mod_source_files="`cat $mod.mod | sed -n 1p \ - | sed -e 's/\.o/\.c/g' \ - | sed "s|[^ ]* *|${src_prefix}&|g"`" + local mod_source_files=$(sed "s|^\(.*\)\.o$|${src_prefix}\1.c|" $mod.mod) + for ns in $namespaces; do echo "Adding namespace $ns to module $mod.ko." generate_deps_for_ns $ns "$mod_source_files" -- cgit v1.2.3 From 6bfb56e93bcef41859c2d5ab234ffd80b691be35 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 8 Jun 2022 13:18:39 -0700 Subject: cert host tools: Stop complaining about deprecated OpenSSL functions OpenSSL 3.0 deprecated the OpenSSL's ENGINE API. That is as may be, but the kernel build host tools still use it. Disable the warning about deprecated declarations until somebody who cares fixes it. Signed-off-by: Linus Torvalds --- certs/extract-cert.c | 7 +++++++ scripts/sign-file.c | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'scripts') diff --git a/certs/extract-cert.c b/certs/extract-cert.c index f7ef7862f207..8c1fb9a70d66 100644 --- a/certs/extract-cert.c +++ b/certs/extract-cert.c @@ -23,6 +23,13 @@ #include #include +/* + * OpenSSL 3.0 deprecates the OpenSSL's ENGINE API. + * + * Remove this if/when that API is no longer used + */ +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + #define PKEY_ID_PKCS7 2 static __attribute__((noreturn)) diff --git a/scripts/sign-file.c b/scripts/sign-file.c index fbd34b8e8f57..7434e9ea926e 100644 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c @@ -29,6 +29,13 @@ #include #include +/* + * OpenSSL 3.0 deprecates the OpenSSL's ENGINE API. + * + * Remove this if/when that API is no longer used + */ +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + /* * Use CMS if we have openssl-1.0.0 or newer available - otherwise we have to * assume that it's not available and its header file is missing and that we -- cgit v1.2.3 From da4288b95baa1c7c9aa8a476f58b37eb238745b0 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Jun 2022 10:11:00 +0900 Subject: scripts/check-local-export: avoid 'wait $!' for process substitution Bash 4.4, released in 2016, supports 'wait $!' to check the exit status of a process substitution, but it seems too new. Some people using older bash versions (on CentOS 7, Ubuntu 16.04, etc.) reported an error like this: ./scripts/check-local-export: line 54: wait: pid 17328 is not a child of this shell I used the process substitution to avoid a pipeline, which executes each command in a subshell. If the while-loop is executed in the subshell context, variable changes within are lost after the subshell terminates. Fortunately, Bash 4.2, released in 2011, supports the 'lastpipe' option, which makes the last element of a pipeline run in the current shell process. Switch to the pipeline with 'lastpipe' solution, and also set 'pipefail' to catch errors from ${NM}. Add the bash requirement to Documentation/process/changes.rst. Fixes: 31cb50b5590f ("kbuild: check static EXPORT_SYMBOL* by script instead of modpost") Reported-by: Tetsuo Handa Reported-by: Michael Ellerman Reported-by: Wang Yugui Tested-by: Tetsuo Handa Tested-by: Jon Hunter Acked-by: Nick Desaulniers Tested-by: Sedat Dilek # LLVM-14 (x86-64) Signed-off-by: Masahiro Yamada --- Documentation/process/changes.rst | 12 ++++++++++++ scripts/check-local-export | 36 +++++++++++++++++++++--------------- 2 files changed, 33 insertions(+), 15 deletions(-) (limited to 'scripts') diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst index 34415ae1af1b..19c286c23786 100644 --- a/Documentation/process/changes.rst +++ b/Documentation/process/changes.rst @@ -32,6 +32,7 @@ you probably needn't concern yourself with pcmciautils. GNU C 5.1 gcc --version Clang/LLVM (optional) 11.0.0 clang --version GNU make 3.81 make --version +bash 4.2 bash --version binutils 2.23 ld -v flex 2.5.35 flex --version bison 2.0 bison --version @@ -84,6 +85,12 @@ Make You will need GNU make 3.81 or later to build the kernel. +Bash +---- + +Some bash scripts are used for the kernel build. +Bash 4.2 or newer is needed. + Binutils -------- @@ -362,6 +369,11 @@ Make - +Bash +---- + +- + Binutils -------- diff --git a/scripts/check-local-export b/scripts/check-local-export index da745e2743b7..6ccc2f467416 100755 --- a/scripts/check-local-export +++ b/scripts/check-local-export @@ -8,11 +8,31 @@ set -e +# catch errors from ${NM} +set -o pipefail + +# Run the last element of a pipeline in the current shell. +# Without this, the while-loop would be executed in a subshell, and +# the changes made to 'symbol_types' and 'export_symbols' would be lost. +shopt -s lastpipe + declare -A symbol_types declare -a export_symbols exit_code=0 +# If there is no symbol in the object, ${NM} (both GNU nm and llvm-nm) shows +# 'no symbols' diagnostic (but exits with 0). It is harmless and hidden by +# '2>/dev/null'. However, it suppresses real error messages as well. Add a +# hand-crafted error message here. +# +# TODO: +# Use --quiet instead of 2>/dev/null when we upgrade the minimum version of +# binutils to 2.37, llvm to 13.0.0. +# Then, the following line will be really simple: +# ${NM} --quiet ${1} | + +{ ${NM} ${1} 2>/dev/null || { echo "${0}: ${NM} failed" >&2; false; } } | while read value type name do # Skip the line if the number of fields is less than 3. @@ -37,21 +57,7 @@ do if [[ ${name} == __ksymtab_* ]]; then export_symbols+=(${name#__ksymtab_}) fi - - # If there is no symbol in the object, ${NM} (both GNU nm and llvm-nm) - # shows 'no symbols' diagnostic (but exits with 0). It is harmless and - # hidden by '2>/dev/null'. However, it suppresses real error messages - # as well. Add a hand-crafted error message here. - # - # Use --quiet instead of 2>/dev/null when we upgrade the minimum version - # of binutils to 2.37, llvm to 13.0.0. - # - # Then, the following line will be really simple: - # done < <(${NM} --quiet ${1}) -done < <(${NM} ${1} 2>/dev/null || { echo "${0}: ${NM} failed" >&2; false; } ) - -# Catch error in the process substitution -wait $! +done for name in "${export_symbols[@]}" do -- cgit v1.2.3 From fa82cce7a6bbb35ecf7fe66231c7076052cf66d5 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 7 Jun 2022 16:11:34 +0200 Subject: treewide: Replace GPLv2 boilerplate/reference with SPDX - gpl-2.0_385.RULE Based on the normalized pattern: licensed under the gpl v2 extracted by the scancode license scanner the SPDX license identifier GPL-2.0-only has been chosen to replace the boilerplate/reference. Reviewed-by: Allison Randal Signed-off-by: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman --- arch/sparc/vdso/vdso2c.c | 2 +- arch/x86/entry/vdso/vdso2c.c | 2 +- scripts/gcc-plugins/latent_entropy_plugin.c | 2 +- scripts/gcc-plugins/stackleak_plugin.c | 2 +- scripts/gcc-plugins/structleak_plugin.c | 2 +- tools/power/cpupower/debug/i386/dump_psb.c | 6 ++---- 6 files changed, 7 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/arch/sparc/vdso/vdso2c.c b/arch/sparc/vdso/vdso2c.c index ab7504176a7f..dc81240aab6f 100644 --- a/arch/sparc/vdso/vdso2c.c +++ b/arch/sparc/vdso/vdso2c.c @@ -1,7 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * vdso2c - A vdso image preparation tool * Copyright (c) 2014 Andy Lutomirski and others - * Licensed under the GPL v2 * * vdso2c requires stripped and unstripped input. It would be trivial * to fully strip the input in here, but, for reasons described below, diff --git a/arch/x86/entry/vdso/vdso2c.c b/arch/x86/entry/vdso/vdso2c.c index edfe9780f6d1..90d15f2a7205 100644 --- a/arch/x86/entry/vdso/vdso2c.c +++ b/arch/x86/entry/vdso/vdso2c.c @@ -1,7 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * vdso2c - A vdso image preparation tool * Copyright (c) 2014 Andy Lutomirski and others - * Licensed under the GPL v2 * * vdso2c requires stripped and unstripped input. It would be trivial * to fully strip the input in here, but, for reasons described below, diff --git a/scripts/gcc-plugins/latent_entropy_plugin.c b/scripts/gcc-plugins/latent_entropy_plugin.c index 848918764174..39e86be60dd2 100644 --- a/scripts/gcc-plugins/latent_entropy_plugin.c +++ b/scripts/gcc-plugins/latent_entropy_plugin.c @@ -1,7 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright 2012-2016 by the PaX Team * Copyright 2016 by Emese Revfy - * Licensed under the GPL v2 * * Note: the choice of the license means that the compilation process is * NOT 'eligible' as defined by gcc's library exception to the GPL v3, diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c index ff91885f9470..c5c2ce113c92 100644 --- a/scripts/gcc-plugins/stackleak_plugin.c +++ b/scripts/gcc-plugins/stackleak_plugin.c @@ -1,7 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright 2011-2017 by the PaX Team * Modified by Alexander Popov - * Licensed under the GPL v2 * * Note: the choice of the license means that the compilation process is * NOT 'eligible' as defined by gcc's library exception to the GPL v3, diff --git a/scripts/gcc-plugins/structleak_plugin.c b/scripts/gcc-plugins/structleak_plugin.c index 8bc04068ed39..d8c744233832 100644 --- a/scripts/gcc-plugins/structleak_plugin.c +++ b/scripts/gcc-plugins/structleak_plugin.c @@ -1,6 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright 2013-2017 by PaX Team - * Licensed under the GPL v2 * * Note: the choice of the license means that the compilation process is * NOT 'eligible' as defined by gcc's library exception to the GPL v3, diff --git a/tools/power/cpupower/debug/i386/dump_psb.c b/tools/power/cpupower/debug/i386/dump_psb.c index 2c768cf70128..6fb81b42ea61 100644 --- a/tools/power/cpupower/debug/i386/dump_psb.c +++ b/tools/power/cpupower/debug/i386/dump_psb.c @@ -1,7 +1,5 @@ -/* - * dump_psb. (c) 2004, Dave Jones, Red Hat Inc. - * Licensed under the GPL v2. - */ +// SPDX-License-Identifier: GPL-2.0-only +// dump_psb. (c) 2004, Dave Jones, Red Hat Inc. #include #include -- cgit v1.2.3 From 1f7a6cf6b07c74a17343c2559cd5f5018a245961 Mon Sep 17 00:00:00 2001 From: Kuan-Ying Lee Date: Fri, 10 Jun 2022 15:14:57 +0800 Subject: scripts/gdb: change kernel config dumping method MAGIC_START("IKCFG_ST") and MAGIC_END("IKCFG_ED") are moved out from the kernel_config_data variable. Thus, we parse kernel_config_data directly instead of considering offset of MAGIC_START and MAGIC_END. Fixes: 13610aa908dc ("kernel/configs: use .incbin directive to embed config_data.gz") Signed-off-by: Kuan-Ying Lee Signed-off-by: Masahiro Yamada --- scripts/gdb/linux/config.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/config.py b/scripts/gdb/linux/config.py index 90e1565b1967..8843ab3cbadd 100644 --- a/scripts/gdb/linux/config.py +++ b/scripts/gdb/linux/config.py @@ -24,9 +24,9 @@ class LxConfigDump(gdb.Command): filename = arg try: - py_config_ptr = gdb.parse_and_eval("kernel_config_data + 8") - py_config_size = gdb.parse_and_eval( - "sizeof(kernel_config_data) - 1 - 8 * 2") + py_config_ptr = gdb.parse_and_eval("&kernel_config_data") + py_config_ptr_end = gdb.parse_and_eval("&kernel_config_data_end") + py_config_size = py_config_ptr_end - py_config_ptr except gdb.error as e: raise gdb.GdbError("Can't find config, enable CONFIG_IKCONFIG?") -- cgit v1.2.3 From df4bf98ec2d199ae32f215d083774ebb6424bf1f Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Mon, 13 Jun 2022 11:05:10 +0200 Subject: scripts: kernel-doc: Always increment warnings counter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some warnings do not increment the warnings counter making the behavior of running kernel-doc with -Werror unlogical as some warnings will be generated but not treated as errors. Fix this by creating a helper function that always incrementing the warnings counter every time a warning is emitted. There is one location in get_sphinx_version() where a warning is not touched as it concerns the execution environment of the kernel-doc and not the documentation being processed. Incrementing the counter only have effect when running kernel-doc in either verbose mode (-v or environment variable KBUILD_VERBOSE) or when treating warnings as errors (-Werror or environment variable KDOC_WERROR). In both cases the number of warnings printed is printed to stderr and for the later the exit code of kernel-doc is non-zero if warnings where encountered. Simple test case to demo one of the warnings, $ cat test.c /** * foo() - Description */ int bar(); # Without this change $ ./scripts/kernel-doc -Werror -none test.c test.c:4: warning: expecting prototype for foo(). Prototype was for bar() instead # With this change $ ./scripts/kernel-doc -Werror -none test.c test.c:4: warning: expecting prototype for foo(). Prototype was for bar() instead 1 warnings as Errors Signed-off-by: Niklas Söderlund Link: https://lore.kernel.org/r/20220613090510.3088294-1-niklas.soderlund@corigine.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 82 +++++++++++++++++++++++------------------------------- 1 file changed, 35 insertions(+), 47 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 7516949bb049..aea04365bc69 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -427,6 +427,13 @@ sub print_lineno { print ".. LINENO " . $lineno . "\n"; } } + +sub emit_warning { + my $location = shift; + my $msg = shift; + print STDERR "$location: warning: $msg"; + ++$warnings; +} ## # dumps section contents to arrays/hashes intended for that purpose. # @@ -451,8 +458,7 @@ sub dump_section { if (defined($sections{$name}) && ($sections{$name} ne "")) { # Only warn on user specified duplicate section names. if ($name ne $section_default) { - print STDERR "${file}:$.: warning: duplicate section name '$name'\n"; - ++$warnings; + emit_warning("${file}:$.", "duplicate section name '$name'\n"); } $sections{$name} .= $contents; } else { @@ -1094,7 +1100,7 @@ sub dump_struct($$) { if ($members) { if ($identifier ne $declaration_name) { - print STDERR "${file}:$.: warning: expecting prototype for $decl_type $identifier. Prototype was for $decl_type $declaration_name instead\n"; + emit_warning("${file}:$.", "expecting prototype for $decl_type $identifier. Prototype was for $decl_type $declaration_name instead\n"); return; } @@ -1298,9 +1304,9 @@ sub dump_enum($$) { if ($members) { if ($identifier ne $declaration_name) { if ($identifier eq "") { - print STDERR "${file}:$.: warning: wrong kernel-doc identifier on line:\n"; + emit_warning("${file}:$.", "wrong kernel-doc identifier on line:\n"); } else { - print STDERR "${file}:$.: warning: expecting prototype for enum $identifier. Prototype was for enum $declaration_name instead\n"; + emit_warning("${file}:$.", "expecting prototype for enum $identifier. Prototype was for enum $declaration_name instead\n"); } return; } @@ -1316,7 +1322,7 @@ sub dump_enum($$) { if (!$parameterdescs{$arg}) { $parameterdescs{$arg} = $undescribed; if (show_warnings("enum", $declaration_name)) { - print STDERR "${file}:$.: warning: Enum value '$arg' not described in enum '$declaration_name'\n"; + emit_warning("${file}:$.", "Enum value '$arg' not described in enum '$declaration_name'\n"); } } $_members{$arg} = 1; @@ -1325,7 +1331,7 @@ sub dump_enum($$) { while (my ($k, $v) = each %parameterdescs) { if (!exists($_members{$k})) { if (show_warnings("enum", $declaration_name)) { - print STDERR "${file}:$.: warning: Excess enum value '$k' description in '$declaration_name'\n"; + emit_warning("${file}:$.", "Excess enum value '$k' description in '$declaration_name'\n"); } } } @@ -1367,7 +1373,7 @@ sub dump_typedef($$) { $return_type =~ s/^\s+//; if ($identifier ne $declaration_name) { - print STDERR "${file}:$.: warning: expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n"; + emit_warning("${file}:$.", "expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n"); return; } @@ -1398,7 +1404,7 @@ sub dump_typedef($$) { $declaration_name = $1; if ($identifier ne $declaration_name) { - print STDERR "${file}:$.: warning: expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n"; + emit_warning("${file}:$.", "expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n"); return; } @@ -1554,9 +1560,7 @@ sub push_parameter($$$$$) { $parameterdescs{$param} = $undescribed; if (show_warnings($type, $declaration_name) && $param !~ /\./) { - print STDERR - "${file}:$.: warning: Function parameter or member '$param' not described in '$declaration_name'\n"; - ++$warnings; + emit_warning("${file}:$.", "Function parameter or member '$param' not described in '$declaration_name'\n"); } } @@ -1604,11 +1608,10 @@ sub check_sections($$$$$) { } if ($err) { if ($decl_type eq "function") { - print STDERR "${file}:$.: warning: " . + emit_warning("${file}:$.", "Excess function parameter " . "'$sects[$sx]' " . - "description in '$decl_name'\n"; - ++$warnings; + "description in '$decl_name'\n"); } } } @@ -1629,10 +1632,9 @@ sub check_return_section { if (!defined($sections{$section_return}) || $sections{$section_return} eq "") { - print STDERR "${file}:$.: warning: " . + emit_warning("${file}:$.", "No description found for return value of " . - "'$declaration_name'\n"; - ++$warnings; + "'$declaration_name'\n"); } } @@ -1714,12 +1716,12 @@ sub dump_function($$) { create_parameterlist($args, ',', $file, $declaration_name); } else { - print STDERR "${file}:$.: warning: cannot understand function prototype: '$prototype'\n"; + emit_warning("${file}:$.", "cannot understand function prototype: '$prototype'\n"); return; } if ($identifier ne $declaration_name) { - print STDERR "${file}:$.: warning: expecting prototype for $identifier(). Prototype was for $declaration_name() instead\n"; + emit_warning("${file}:$.", "expecting prototype for $identifier(). Prototype was for $declaration_name() instead\n"); return; } @@ -1801,8 +1803,8 @@ sub tracepoint_munge($) { $tracepointargs = $1; } if (($tracepointname eq 0) || ($tracepointargs eq 0)) { - print STDERR "${file}:$.: warning: Unrecognized tracepoint format: \n". - "$prototype\n"; + emit_warning("${file}:$.", "Unrecognized tracepoint format: \n". + "$prototype\n"); } else { $prototype = "static inline void trace_$tracepointname($tracepointargs)"; $identifier = "trace_$identifier"; @@ -2027,22 +2029,16 @@ sub process_name($$) { } if (!$is_kernel_comment) { - print STDERR "${file}:$.: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst\n"; - print STDERR $_; - ++$warnings; + emit_warning("${file}:$.", "This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst\n$_"); $state = STATE_NORMAL; } if (($declaration_purpose eq "") && $verbose) { - print STDERR "${file}:$.: warning: missing initial short description on line:\n"; - print STDERR $_; - ++$warnings; + emit_warning("${file}:$.", "missing initial short description on line:\n$_"); } if ($identifier eq "" && $decl_type ne "enum") { - print STDERR "${file}:$.: warning: wrong kernel-doc identifier on line:\n"; - print STDERR $_; - ++$warnings; + emit_warning("${file}:$.", "wrong kernel-doc identifier on line:\n$_"); $state = STATE_NORMAL; } @@ -2050,9 +2046,7 @@ sub process_name($$) { print STDERR "${file}:$.: info: Scanning doc for $decl_type $identifier\n"; } } else { - print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", - " - I thought it was a doc line\n"; - ++$warnings; + emit_warning("${file}:$.", "Cannot understand $_ on line $. - I thought it was a doc line\n"); $state = STATE_NORMAL; } } @@ -2071,8 +2065,7 @@ sub process_body($$) { $section =~ s/\.\.\.$//; if ($verbose) { - print STDERR "${file}:$.: warning: Variable macro arguments should be documented without dots\n"; - ++$warnings; + emit_warning("${file}:$.", "Variable macro arguments should be documented without dots\n"); } } @@ -2101,8 +2094,7 @@ sub process_body($$) { if (($contents ne "") && ($contents ne "\n")) { if (!$in_doc_sect && $verbose) { - print STDERR "${file}:$.: warning: contents before sections\n"; - ++$warnings; + emit_warning("${file}:$.", "contents before sections\n"); } dump_section($file, $section, $contents); $section = $section_default; @@ -2128,8 +2120,7 @@ sub process_body($$) { } # look for doc_com + + doc_end: if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { - print STDERR "${file}:$.: warning: suspicious ending line: $_"; - ++$warnings; + emit_warning("${file}:$.", "suspicious ending line: $_"); } $prototype = ""; @@ -2173,8 +2164,7 @@ sub process_body($$) { } } else { # i dont know - bad line? ignore. - print STDERR "${file}:$.: warning: bad line: $_"; - ++$warnings; + emit_warning("${file}:$.", "bad line: $_"); } } @@ -2268,9 +2258,7 @@ sub process_inline($$) { } } elsif ($inline_doc_state == STATE_INLINE_NAME) { $inline_doc_state = STATE_INLINE_ERROR; - print STDERR "${file}:$.: warning: "; - print STDERR "Incorrect use of kernel-doc format: $_"; - ++$warnings; + emit_warning("${file}:$.", "Incorrect use of kernel-doc format: $_"); } } } @@ -2319,11 +2307,11 @@ sub process_file($) { if ($initial_section_counter == $section_counter && $ output_mode ne "none") { if ($output_selection == OUTPUT_INCLUDE) { - print STDERR "${file}:1: warning: '$_' not found\n" + emit_warning("${file}:1", "'$_' not found\n") for keys %function_table; } else { - print STDERR "${file}:1: warning: no structured comments found\n"; + emit_warning("${file}:1", "no structured comments found\n"); } } close IN_FILE; -- cgit v1.2.3 From dcea7964764aad41c2994084a4c0292371b14e36 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 25 May 2022 12:03:17 -0700 Subject: checkpatch: add XA_STATE and XA_STATE_ORDER to the macro declaration list XA_STATE() and XA_STATE_ORDER macro uses are declarations. Add them to the declaration macro list to avoid suggesting a blank line after declarations when used. Link: https://lkml.kernel.org/r/144314f4bf2c58cf2336028a75a5127e848abd81.camel@perches.com Signed-off-by: Joe Perches Reported-by: David Howells Cc: Matthew Wilcox Signed-off-by: Andrew Morton --- scripts/checkpatch.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 503e8abbb2c1..205bf5055acf 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1042,7 +1042,8 @@ our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; our $declaration_macros = qr{(?x: (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| - (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\( + (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(| + (?:$Storage\s+)?(?:XA_STATE|XA_STATE_ORDER)\s*\( )}; our %allow_repeated_words = ( -- cgit v1.2.3 From f858e23a29740757fe1ca602cb1f57845034b1c5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 13 Jun 2022 12:00:55 +0200 Subject: checkpatch: fix incorrect camelcase detection on numeric constant The code fragment below int foo(int *array, int index) { return array[index & 0xFF]; } triggers an incorrect camelcase detection by checking a substring of the hex constant: CHECK: Avoid CamelCase: #3: FILE: test.c:3: + return array[index & 0xFF]; This is caused by passing the whole string "array[index & 0xFF]" to the inner loop that iterates over a "$Ident" match. The numeric constant is not a $Ident as it doesn't start with [A-Za-z_] and should be excluded from the match. Similar issue can be detected with other constants like "1uL", "0xffffU". Force the match to start at word boundary so the $Ident will be properly checked starting from its first char and the constants will be filtered-out. Link: https://lkml.kernel.org/r/20220613100055.77821-1-borneo.antonio@gmail.com Signed-off-by: Antonio Borneo Cc: Joe Perches Cc: Andy Whitcroft Cc: Dwaipayan Ray Cc: Lukas Bulwahn 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 205bf5055acf..79e759aac543 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -5721,7 +5721,7 @@ sub process { $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ && #Ignore some three character SI units explicitly, like MiB and KHz $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { - while ($var =~ m{($Ident)}g) { + while ($var =~ m{\b($Ident)}g) { my $word = $1; next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); if ($check) { -- cgit v1.2.3 From 33bf9885040c399cf6a95bd33216644126728e14 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Wed, 15 Jun 2022 16:48:44 +0300 Subject: bpf: Add helpers to issue and check SYN cookies in XDP The new helpers bpf_tcp_raw_{gen,check}_syncookie_ipv{4,6} allow an XDP program to generate SYN cookies in response to TCP SYN packets and to check those cookies upon receiving the first ACK packet (the final packet of the TCP handshake). Unlike bpf_tcp_{gen,check}_syncookie these new helpers don't need a listening socket on the local machine, which allows to use them together with synproxy to accelerate SYN cookie generation. Signed-off-by: Maxim Mikityanskiy Reviewed-by: Tariq Toukan Link: https://lore.kernel.org/r/20220615134847.3753567-4-maximmi@nvidia.com Signed-off-by: Alexei Starovoitov --- include/net/tcp.h | 1 + include/uapi/linux/bpf.h | 78 +++++++++++++++++++++++++++ net/core/filter.c | 118 +++++++++++++++++++++++++++++++++++++++++ net/ipv4/tcp_input.c | 3 +- scripts/bpf_doc.py | 4 ++ tools/include/uapi/linux/bpf.h | 78 +++++++++++++++++++++++++++ 6 files changed, 281 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/include/net/tcp.h b/include/net/tcp.h index 1e99f5c61f84..9a1efe23fab7 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -432,6 +432,7 @@ u16 tcp_v4_get_syncookie(struct sock *sk, struct iphdr *iph, struct tcphdr *th, u32 *cookie); u16 tcp_v6_get_syncookie(struct sock *sk, struct ipv6hdr *iph, struct tcphdr *th, u32 *cookie); +u16 tcp_parse_mss_option(const struct tcphdr *th, u16 user_mss); u16 tcp_get_syncookie_mss(struct request_sock_ops *rsk_ops, const struct tcp_request_sock_ops *af_ops, struct sock *sk, struct tcphdr *th); diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index f545e39df72a..e81362891596 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -5251,6 +5251,80 @@ union bpf_attr { * Pointer to the underlying dynptr data, NULL if the dynptr is * read-only, if the dynptr is invalid, or if the offset and length * is out of bounds. + * + * s64 bpf_tcp_raw_gen_syncookie_ipv4(struct iphdr *iph, struct tcphdr *th, u32 th_len) + * Description + * Try to issue a SYN cookie for the packet with corresponding + * IPv4/TCP headers, *iph* and *th*, without depending on a + * listening socket. + * + * *iph* points to the IPv4 header. + * + * *th* points to the start of the TCP header, while *th_len* + * contains the length of the TCP header (at least + * **sizeof**\ (**struct tcphdr**)). + * Return + * On success, lower 32 bits hold the generated SYN cookie in + * followed by 16 bits which hold the MSS value for that cookie, + * and the top 16 bits are unused. + * + * On failure, the returned value is one of the following: + * + * **-EINVAL** if *th_len* is invalid. + * + * s64 bpf_tcp_raw_gen_syncookie_ipv6(struct ipv6hdr *iph, struct tcphdr *th, u32 th_len) + * Description + * Try to issue a SYN cookie for the packet with corresponding + * IPv6/TCP headers, *iph* and *th*, without depending on a + * listening socket. + * + * *iph* points to the IPv6 header. + * + * *th* points to the start of the TCP header, while *th_len* + * contains the length of the TCP header (at least + * **sizeof**\ (**struct tcphdr**)). + * Return + * On success, lower 32 bits hold the generated SYN cookie in + * followed by 16 bits which hold the MSS value for that cookie, + * and the top 16 bits are unused. + * + * On failure, the returned value is one of the following: + * + * **-EINVAL** if *th_len* is invalid. + * + * **-EPROTONOSUPPORT** if CONFIG_IPV6 is not builtin. + * + * long bpf_tcp_raw_check_syncookie_ipv4(struct iphdr *iph, struct tcphdr *th) + * Description + * Check whether *iph* and *th* contain a valid SYN cookie ACK + * without depending on a listening socket. + * + * *iph* points to the IPv4 header. + * + * *th* points to the TCP header. + * Return + * 0 if *iph* and *th* are a valid SYN cookie ACK. + * + * On failure, the returned value is one of the following: + * + * **-EACCES** if the SYN cookie is not valid. + * + * long bpf_tcp_raw_check_syncookie_ipv6(struct ipv6hdr *iph, struct tcphdr *th) + * Description + * Check whether *iph* and *th* contain a valid SYN cookie ACK + * without depending on a listening socket. + * + * *iph* points to the IPv6 header. + * + * *th* points to the TCP header. + * Return + * 0 if *iph* and *th* are a valid SYN cookie ACK. + * + * On failure, the returned value is one of the following: + * + * **-EACCES** if the SYN cookie is not valid. + * + * **-EPROTONOSUPPORT** if CONFIG_IPV6 is not builtin. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -5457,6 +5531,10 @@ union bpf_attr { FN(dynptr_read), \ FN(dynptr_write), \ FN(dynptr_data), \ + FN(tcp_raw_gen_syncookie_ipv4), \ + FN(tcp_raw_gen_syncookie_ipv6), \ + FN(tcp_raw_check_syncookie_ipv4), \ + FN(tcp_raw_check_syncookie_ipv6), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper diff --git a/net/core/filter.c b/net/core/filter.c index 5af58eb48587..b62d4126a561 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -7444,6 +7444,114 @@ static const struct bpf_func_proto bpf_skb_set_tstamp_proto = { .arg3_type = ARG_ANYTHING, }; +#ifdef CONFIG_SYN_COOKIES +BPF_CALL_3(bpf_tcp_raw_gen_syncookie_ipv4, struct iphdr *, iph, + struct tcphdr *, th, u32, th_len) +{ + u32 cookie; + u16 mss; + + if (unlikely(th_len < sizeof(*th) || th_len != th->doff * 4)) + return -EINVAL; + + mss = tcp_parse_mss_option(th, 0) ?: TCP_MSS_DEFAULT; + cookie = __cookie_v4_init_sequence(iph, th, &mss); + + return cookie | ((u64)mss << 32); +} + +static const struct bpf_func_proto bpf_tcp_raw_gen_syncookie_ipv4_proto = { + .func = bpf_tcp_raw_gen_syncookie_ipv4, + .gpl_only = true, /* __cookie_v4_init_sequence() is GPL */ + .pkt_access = true, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_FIXED_SIZE_MEM, + .arg1_size = sizeof(struct iphdr), + .arg2_type = ARG_PTR_TO_MEM, + .arg3_type = ARG_CONST_SIZE, +}; + +BPF_CALL_3(bpf_tcp_raw_gen_syncookie_ipv6, struct ipv6hdr *, iph, + struct tcphdr *, th, u32, th_len) +{ +#if IS_BUILTIN(CONFIG_IPV6) + const u16 mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - + sizeof(struct ipv6hdr); + u32 cookie; + u16 mss; + + if (unlikely(th_len < sizeof(*th) || th_len != th->doff * 4)) + return -EINVAL; + + mss = tcp_parse_mss_option(th, 0) ?: mss_clamp; + cookie = __cookie_v6_init_sequence(iph, th, &mss); + + return cookie | ((u64)mss << 32); +#else + return -EPROTONOSUPPORT; +#endif +} + +static const struct bpf_func_proto bpf_tcp_raw_gen_syncookie_ipv6_proto = { + .func = bpf_tcp_raw_gen_syncookie_ipv6, + .gpl_only = true, /* __cookie_v6_init_sequence() is GPL */ + .pkt_access = true, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_FIXED_SIZE_MEM, + .arg1_size = sizeof(struct ipv6hdr), + .arg2_type = ARG_PTR_TO_MEM, + .arg3_type = ARG_CONST_SIZE, +}; + +BPF_CALL_2(bpf_tcp_raw_check_syncookie_ipv4, struct iphdr *, iph, + struct tcphdr *, th) +{ + u32 cookie = ntohl(th->ack_seq) - 1; + + if (__cookie_v4_check(iph, th, cookie) > 0) + return 0; + + return -EACCES; +} + +static const struct bpf_func_proto bpf_tcp_raw_check_syncookie_ipv4_proto = { + .func = bpf_tcp_raw_check_syncookie_ipv4, + .gpl_only = true, /* __cookie_v4_check is GPL */ + .pkt_access = true, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_FIXED_SIZE_MEM, + .arg1_size = sizeof(struct iphdr), + .arg2_type = ARG_PTR_TO_FIXED_SIZE_MEM, + .arg2_size = sizeof(struct tcphdr), +}; + +BPF_CALL_2(bpf_tcp_raw_check_syncookie_ipv6, struct ipv6hdr *, iph, + struct tcphdr *, th) +{ +#if IS_BUILTIN(CONFIG_IPV6) + u32 cookie = ntohl(th->ack_seq) - 1; + + if (__cookie_v6_check(iph, th, cookie) > 0) + return 0; + + return -EACCES; +#else + return -EPROTONOSUPPORT; +#endif +} + +static const struct bpf_func_proto bpf_tcp_raw_check_syncookie_ipv6_proto = { + .func = bpf_tcp_raw_check_syncookie_ipv6, + .gpl_only = true, /* __cookie_v6_check is GPL */ + .pkt_access = true, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_FIXED_SIZE_MEM, + .arg1_size = sizeof(struct ipv6hdr), + .arg2_type = ARG_PTR_TO_FIXED_SIZE_MEM, + .arg2_size = sizeof(struct tcphdr), +}; +#endif /* CONFIG_SYN_COOKIES */ + #endif /* CONFIG_INET */ bool bpf_helper_changes_pkt_data(void *func) @@ -7856,6 +7964,16 @@ xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_tcp_check_syncookie_proto; case BPF_FUNC_tcp_gen_syncookie: return &bpf_tcp_gen_syncookie_proto; +#ifdef CONFIG_SYN_COOKIES + case BPF_FUNC_tcp_raw_gen_syncookie_ipv4: + return &bpf_tcp_raw_gen_syncookie_ipv4_proto; + case BPF_FUNC_tcp_raw_gen_syncookie_ipv6: + return &bpf_tcp_raw_gen_syncookie_ipv6_proto; + case BPF_FUNC_tcp_raw_check_syncookie_ipv4: + return &bpf_tcp_raw_check_syncookie_ipv4_proto; + case BPF_FUNC_tcp_raw_check_syncookie_ipv6: + return &bpf_tcp_raw_check_syncookie_ipv6_proto; +#endif #endif default: return bpf_sk_base_func_proto(func_id); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2e2a9ece9af2..6426f6a2e744 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3967,7 +3967,7 @@ static bool smc_parse_options(const struct tcphdr *th, /* Try to parse the MSS option from the TCP header. Return 0 on failure, clamped * value on success. */ -static u16 tcp_parse_mss_option(const struct tcphdr *th, u16 user_mss) +u16 tcp_parse_mss_option(const struct tcphdr *th, u16 user_mss) { const unsigned char *ptr = (const unsigned char *)(th + 1); int length = (th->doff * 4) - sizeof(struct tcphdr); @@ -4006,6 +4006,7 @@ static u16 tcp_parse_mss_option(const struct tcphdr *th, u16 user_mss) } return mss; } +EXPORT_SYMBOL_GPL(tcp_parse_mss_option); /* Look for tcp options. Normally only called on SYN and SYNACK packets. * But, this can also be called on packets in the established flow when diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index 855b937e7585..a0ec321469bd 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -635,6 +635,8 @@ class PrinterHelpers(Printer): 'struct bpf_timer', 'struct mptcp_sock', 'struct bpf_dynptr', + 'struct iphdr', + 'struct ipv6hdr', ] known_types = { '...', @@ -686,6 +688,8 @@ class PrinterHelpers(Printer): 'struct bpf_timer', 'struct mptcp_sock', 'struct bpf_dynptr', + 'struct iphdr', + 'struct ipv6hdr', } mapped_types = { 'u8': '__u8', diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index f545e39df72a..e81362891596 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -5251,6 +5251,80 @@ union bpf_attr { * Pointer to the underlying dynptr data, NULL if the dynptr is * read-only, if the dynptr is invalid, or if the offset and length * is out of bounds. + * + * s64 bpf_tcp_raw_gen_syncookie_ipv4(struct iphdr *iph, struct tcphdr *th, u32 th_len) + * Description + * Try to issue a SYN cookie for the packet with corresponding + * IPv4/TCP headers, *iph* and *th*, without depending on a + * listening socket. + * + * *iph* points to the IPv4 header. + * + * *th* points to the start of the TCP header, while *th_len* + * contains the length of the TCP header (at least + * **sizeof**\ (**struct tcphdr**)). + * Return + * On success, lower 32 bits hold the generated SYN cookie in + * followed by 16 bits which hold the MSS value for that cookie, + * and the top 16 bits are unused. + * + * On failure, the returned value is one of the following: + * + * **-EINVAL** if *th_len* is invalid. + * + * s64 bpf_tcp_raw_gen_syncookie_ipv6(struct ipv6hdr *iph, struct tcphdr *th, u32 th_len) + * Description + * Try to issue a SYN cookie for the packet with corresponding + * IPv6/TCP headers, *iph* and *th*, without depending on a + * listening socket. + * + * *iph* points to the IPv6 header. + * + * *th* points to the start of the TCP header, while *th_len* + * contains the length of the TCP header (at least + * **sizeof**\ (**struct tcphdr**)). + * Return + * On success, lower 32 bits hold the generated SYN cookie in + * followed by 16 bits which hold the MSS value for that cookie, + * and the top 16 bits are unused. + * + * On failure, the returned value is one of the following: + * + * **-EINVAL** if *th_len* is invalid. + * + * **-EPROTONOSUPPORT** if CONFIG_IPV6 is not builtin. + * + * long bpf_tcp_raw_check_syncookie_ipv4(struct iphdr *iph, struct tcphdr *th) + * Description + * Check whether *iph* and *th* contain a valid SYN cookie ACK + * without depending on a listening socket. + * + * *iph* points to the IPv4 header. + * + * *th* points to the TCP header. + * Return + * 0 if *iph* and *th* are a valid SYN cookie ACK. + * + * On failure, the returned value is one of the following: + * + * **-EACCES** if the SYN cookie is not valid. + * + * long bpf_tcp_raw_check_syncookie_ipv6(struct ipv6hdr *iph, struct tcphdr *th) + * Description + * Check whether *iph* and *th* contain a valid SYN cookie ACK + * without depending on a listening socket. + * + * *iph* points to the IPv6 header. + * + * *th* points to the TCP header. + * Return + * 0 if *iph* and *th* are a valid SYN cookie ACK. + * + * On failure, the returned value is one of the following: + * + * **-EACCES** if the SYN cookie is not valid. + * + * **-EPROTONOSUPPORT** if CONFIG_IPV6 is not builtin. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -5457,6 +5531,10 @@ union bpf_attr { FN(dynptr_read), \ FN(dynptr_write), \ FN(dynptr_data), \ + FN(tcp_raw_gen_syncookie_ipv4), \ + FN(tcp_raw_gen_syncookie_ipv6), \ + FN(tcp_raw_check_syncookie_ipv4), \ + FN(tcp_raw_check_syncookie_ipv6), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper -- cgit v1.2.3 From 28438794aba47a27e922857d27b31b74e8559143 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 11 Jun 2022 03:32:30 +0900 Subject: modpost: fix section mismatch check for exported init/exit sections Since commit f02e8a6596b7 ("module: Sort exported symbols"), EXPORT_SYMBOL* is placed in the individual section ___ksymtab(_gpl)+ (3 leading underscores instead of 2). Since then, modpost cannot detect the bad combination of EXPORT_SYMBOL and __init/__exit. Fix the .fromsec field. Fixes: f02e8a6596b7 ("module: Sort exported symbols") Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- 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 29d5a841e215..620dc8c4c814 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -980,7 +980,7 @@ static const struct sectioncheck sectioncheck[] = { }, /* Do not export init/exit functions or data */ { - .fromsec = { "__ksymtab*", NULL }, + .fromsec = { "___ksymtab*", NULL }, .bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, .mismatch = EXPORT_TO_INIT_EXIT, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, -- cgit v1.2.3 From ff139766764675b9df12bcbc8928a02149b7ba95 Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Thu, 16 Jun 2022 19:57:59 +0000 Subject: kbuild: Ignore __this_module in gen_autoksyms.sh Module object files can contain an undefined reference to __this_module, which isn't resolved until we link the final .ko. The kernel doesn't export this symbol, so ignore it in gen_autoksyms.sh. Signed-off-by: Sami Tolvanen Tested-by: Steve Muckle Reviewed-by: Nick Desaulniers Tested-by: Ramji Jiyani --- scripts/gen_autoksyms.sh | 3 +++ 1 file changed, 3 insertions(+) (limited to 'scripts') diff --git a/scripts/gen_autoksyms.sh b/scripts/gen_autoksyms.sh index faacf7062122..653fadbad302 100755 --- a/scripts/gen_autoksyms.sh +++ b/scripts/gen_autoksyms.sh @@ -56,4 +56,7 @@ EOT # point addresses. sed -e 's/^\.//' | sort -u | +# Ignore __this_module. It's not an exported symbol, and will be resolved +# when the final .ko's are linked. +grep -v '^__this_module$' | sed -e 's/\(.*\)/#define __KSYM_\1 1/' >> "$output_file" -- cgit v1.2.3 From a09a6e2399ba0595c3042b3164f3ca68a3cff33e Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 14 Jun 2022 23:16:03 +0200 Subject: objtool: Add entry UNRET validation Since entry asm is tricky, add a validation pass that ensures the retbleed mitigation has been done before the first actual RET instruction. Entry points are those that either have UNWIND_HINT_ENTRY, which acts as UNWIND_HINT_EMPTY but marks the instruction as an entry point, or those that have UWIND_HINT_IRET_REGS at +0. This is basically a variant of validate_branch() that is intra-function and it will simply follow all branches from marked entry points and ensures that all paths lead to ANNOTATE_UNRET_END. If a path hits RET or an indirection the path is a fail and will be reported. There are 3 ANNOTATE_UNRET_END instances: - UNTRAIN_RET itself - exception from-kernel; this path doesn't need UNTRAIN_RET - all early exceptions; these also don't need UNTRAIN_RET Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Borislav Petkov Reviewed-by: Josh Poimboeuf Signed-off-by: Borislav Petkov --- arch/x86/entry/entry_64.S | 3 +- arch/x86/entry/entry_64_compat.S | 6 +- arch/x86/include/asm/nospec-branch.h | 12 +++ arch/x86/include/asm/unwind_hints.h | 4 + arch/x86/kernel/head_64.S | 5 + arch/x86/xen/xen-asm.S | 10 +- include/linux/objtool.h | 3 + scripts/Makefile.vmlinux_o | 2 +- tools/include/linux/objtool.h | 3 + tools/objtool/builtin-check.c | 6 ++ tools/objtool/check.c | 177 ++++++++++++++++++++++++++++++-- tools/objtool/include/objtool/builtin.h | 1 + tools/objtool/include/objtool/check.h | 11 +- 13 files changed, 222 insertions(+), 21 deletions(-) (limited to 'scripts') diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 0c88802e1155..65e3b8b7cbe5 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -85,7 +85,7 @@ */ SYM_CODE_START(entry_SYSCALL_64) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY ENDBR swapgs @@ -1095,6 +1095,7 @@ SYM_CODE_START_LOCAL(error_entry) .Lerror_entry_done_lfence: FENCE_SWAPGS_KERNEL_ENTRY leaq 8(%rsp), %rax /* return pt_regs pointer */ + ANNOTATE_UNRET_END RET .Lbstep_iret: diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index bcb89d23ac0e..682338e7e2a3 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S @@ -49,7 +49,7 @@ * 0(%ebp) arg6 */ SYM_CODE_START(entry_SYSENTER_compat) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY ENDBR /* Interrupts are off on entry. */ swapgs @@ -179,7 +179,7 @@ SYM_CODE_END(entry_SYSENTER_compat) * 0(%esp) arg6 */ SYM_CODE_START(entry_SYSCALL_compat) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY ENDBR /* Interrupts are off on entry. */ swapgs @@ -305,7 +305,7 @@ SYM_CODE_END(entry_SYSCALL_compat) * ebp arg6 */ SYM_CODE_START(entry_INT80_compat) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY ENDBR /* * Interrupts are off on entry. diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h index 05dd75478d7b..bba42bd78edf 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -81,6 +81,17 @@ */ #define ANNOTATE_UNRET_SAFE ANNOTATE_RETPOLINE_SAFE +/* + * Abuse ANNOTATE_RETPOLINE_SAFE on a NOP to indicate UNRET_END, should + * eventually turn into it's own annotation. + */ +.macro ANNOTATE_UNRET_END +#ifdef CONFIG_DEBUG_ENTRY + ANNOTATE_RETPOLINE_SAFE + nop +#endif +.endm + /* * JMP_NOSPEC and CALL_NOSPEC macros can be used instead of a simple * indirect jmp/call which may be susceptible to the Spectre variant 2 @@ -131,6 +142,7 @@ */ .macro UNTRAIN_RET #ifdef CONFIG_RETPOLINE + ANNOTATE_UNRET_END ALTERNATIVE_2 "", \ "call zen_untrain_ret", X86_FEATURE_UNRET, \ "call entry_ibpb", X86_FEATURE_ENTRY_IBPB diff --git a/arch/x86/include/asm/unwind_hints.h b/arch/x86/include/asm/unwind_hints.h index 8b33674288ea..6f70fe4c93f2 100644 --- a/arch/x86/include/asm/unwind_hints.h +++ b/arch/x86/include/asm/unwind_hints.h @@ -11,6 +11,10 @@ UNWIND_HINT sp_reg=ORC_REG_UNDEFINED type=UNWIND_HINT_TYPE_CALL end=1 .endm +.macro UNWIND_HINT_ENTRY + UNWIND_HINT sp_reg=ORC_REG_UNDEFINED type=UNWIND_HINT_TYPE_ENTRY end=1 +.endm + .macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0 .if \base == %rsp .if \indirect diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 92c4afa2b729..d860d437631b 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -389,6 +389,8 @@ SYM_CODE_START_NOALIGN(vc_boot_ghcb) UNWIND_HINT_IRET_REGS offset=8 ENDBR + ANNOTATE_UNRET_END + /* Build pt_regs */ PUSH_AND_CLEAR_REGS @@ -448,6 +450,7 @@ SYM_CODE_END(early_idt_handler_array) SYM_CODE_START_LOCAL(early_idt_handler_common) UNWIND_HINT_IRET_REGS offset=16 + ANNOTATE_UNRET_END /* * The stack is the hardware frame, an error code or zero, and the * vector number. @@ -497,6 +500,8 @@ SYM_CODE_START_NOALIGN(vc_no_ghcb) UNWIND_HINT_IRET_REGS offset=8 ENDBR + ANNOTATE_UNRET_END + /* Build pt_regs */ PUSH_AND_CLEAR_REGS diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S index 6bf9d45b9178..6b4fdf6b9542 100644 --- a/arch/x86/xen/xen-asm.S +++ b/arch/x86/xen/xen-asm.S @@ -121,7 +121,7 @@ SYM_FUNC_END(xen_read_cr2_direct); .macro xen_pv_trap name SYM_CODE_START(xen_\name) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY ENDBR pop %rcx pop %r11 @@ -235,7 +235,7 @@ SYM_CODE_END(xenpv_restore_regs_and_return_to_usermode) /* Normal 64-bit system call target */ SYM_CODE_START(xen_entry_SYSCALL_64) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY ENDBR popq %rcx popq %r11 @@ -255,7 +255,7 @@ SYM_CODE_END(xen_entry_SYSCALL_64) /* 32-bit compat syscall target */ SYM_CODE_START(xen_entry_SYSCALL_compat) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY ENDBR popq %rcx popq %r11 @@ -273,7 +273,7 @@ SYM_CODE_END(xen_entry_SYSCALL_compat) /* 32-bit compat sysenter target */ SYM_CODE_START(xen_entry_SYSENTER_compat) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY ENDBR /* * NB: Xen is polite and clears TF from EFLAGS for us. This means @@ -297,7 +297,7 @@ SYM_CODE_END(xen_entry_SYSENTER_compat) SYM_CODE_START(xen_entry_SYSCALL_compat) SYM_CODE_START(xen_entry_SYSENTER_compat) - UNWIND_HINT_EMPTY + UNWIND_HINT_ENTRY ENDBR lea 16(%rsp), %rsp /* strip %rcx, %r11 */ mov $-ENOSYS, %rax diff --git a/include/linux/objtool.h b/include/linux/objtool.h index 15b940ec1eac..b026f1ae39c6 100644 --- a/include/linux/objtool.h +++ b/include/linux/objtool.h @@ -32,11 +32,14 @@ struct unwind_hint { * * UNWIND_HINT_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. */ #define UNWIND_HINT_TYPE_CALL 0 #define UNWIND_HINT_TYPE_REGS 1 #define UNWIND_HINT_TYPE_REGS_PARTIAL 2 #define UNWIND_HINT_TYPE_FUNC 3 +#define UNWIND_HINT_TYPE_ENTRY 4 #ifdef CONFIG_OBJTOOL diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o index 3c97a1564947..bc67748044a6 100644 --- a/scripts/Makefile.vmlinux_o +++ b/scripts/Makefile.vmlinux_o @@ -44,7 +44,7 @@ objtool-enabled := $(or $(delay-objtool),$(CONFIG_NOINSTR_VALIDATION)) objtool_args := \ $(if $(delay-objtool),$(objtool_args)) \ - $(if $(CONFIG_NOINSTR_VALIDATION), --noinstr) \ + $(if $(CONFIG_NOINSTR_VALIDATION), --noinstr $(if $(CONFIG_RETPOLINE), --unret)) \ $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) \ --link diff --git a/tools/include/linux/objtool.h b/tools/include/linux/objtool.h index 15b940ec1eac..b026f1ae39c6 100644 --- a/tools/include/linux/objtool.h +++ b/tools/include/linux/objtool.h @@ -32,11 +32,14 @@ struct unwind_hint { * * UNWIND_HINT_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. */ #define UNWIND_HINT_TYPE_CALL 0 #define UNWIND_HINT_TYPE_REGS 1 #define UNWIND_HINT_TYPE_REGS_PARTIAL 2 #define UNWIND_HINT_TYPE_FUNC 3 +#define UNWIND_HINT_TYPE_ENTRY 4 #ifdef CONFIG_OBJTOOL diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index f4c3a5091737..c063e1ff96b2 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -68,6 +68,7 @@ const struct option check_options[] = { OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"), OPT_BOOLEAN('o', "orc", &opts.orc, "generate ORC metadata"), OPT_BOOLEAN('r', "retpoline", &opts.retpoline, "validate and annotate retpoline usage"), + OPT_BOOLEAN(0, "unret", &opts.unret, "validate entry unret placement"), OPT_BOOLEAN('l', "sls", &opts.sls, "validate straight-line-speculation mitigations"), OPT_BOOLEAN('s', "stackval", &opts.stackval, "validate frame pointer rules"), OPT_BOOLEAN('t', "static-call", &opts.static_call, "annotate static calls"), @@ -163,6 +164,11 @@ static bool link_opts_valid(struct objtool_file *file) return false; } + if (opts.unret) { + ERROR("--unret requires --link"); + return false; + } + return true; } diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 7dc378156a63..822a490e6d87 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2032,16 +2032,24 @@ static int read_unwind_hints(struct objtool_file *file) insn->hint = true; - if (opts.ibt && hint->type == UNWIND_HINT_TYPE_REGS_PARTIAL) { + if (hint->type == UNWIND_HINT_TYPE_REGS_PARTIAL) { struct symbol *sym = find_symbol_by_offset(insn->sec, insn->offset); - if (sym && sym->bind == STB_GLOBAL && - insn->type != INSN_ENDBR && !insn->noendbr) { - WARN_FUNC("UNWIND_HINT_IRET_REGS without ENDBR", - insn->sec, insn->offset); + if (sym && sym->bind == STB_GLOBAL) { + if (opts.ibt && insn->type != INSN_ENDBR && !insn->noendbr) { + WARN_FUNC("UNWIND_HINT_IRET_REGS without ENDBR", + insn->sec, insn->offset); + } + + insn->entry = 1; } } + if (hint->type == UNWIND_HINT_TYPE_ENTRY) { + hint->type = UNWIND_HINT_TYPE_CALL; + insn->entry = 1; + } + if (hint->type == UNWIND_HINT_TYPE_FUNC) { insn->cfi = &func_cfi; continue; @@ -2116,8 +2124,9 @@ static int read_retpoline_hints(struct objtool_file *file) if (insn->type != INSN_JUMP_DYNAMIC && insn->type != INSN_CALL_DYNAMIC && - insn->type != INSN_RETURN) { - WARN_FUNC("retpoline_safe hint not an indirect jump/call/ret", + insn->type != INSN_RETURN && + insn->type != INSN_NOP) { + WARN_FUNC("retpoline_safe hint not an indirect jump/call/ret/nop", insn->sec, insn->offset); return -1; } @@ -3305,8 +3314,8 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, return 1; } - visited = 1 << state.uaccess; - if (insn->visited) { + visited = VISITED_BRANCH << state.uaccess; + if (insn->visited & VISITED_BRANCH_MASK) { if (!insn->hint && !insn_cfi_match(insn, &state.cfi)) return 1; @@ -3520,6 +3529,145 @@ static int validate_unwind_hints(struct objtool_file *file, struct section *sec) return warnings; } +/* + * Validate rethunk entry constraint: must untrain RET before the first RET. + * + * Follow every branch (intra-function) and ensure ANNOTATE_UNRET_END comes + * before an actual RET instruction. + */ +static int validate_entry(struct objtool_file *file, struct instruction *insn) +{ + struct instruction *next, *dest; + int ret, warnings = 0; + + for (;;) { + next = next_insn_to_validate(file, insn); + + if (insn->visited & VISITED_ENTRY) + return 0; + + insn->visited |= VISITED_ENTRY; + + if (!insn->ignore_alts && !list_empty(&insn->alts)) { + struct alternative *alt; + bool skip_orig = false; + + list_for_each_entry(alt, &insn->alts, list) { + if (alt->skip_orig) + skip_orig = true; + + ret = validate_entry(file, alt->insn); + if (ret) { + if (opts.backtrace) + BT_FUNC("(alt)", insn); + return ret; + } + } + + if (skip_orig) + return 0; + } + + switch (insn->type) { + + case INSN_CALL_DYNAMIC: + case INSN_JUMP_DYNAMIC: + case INSN_JUMP_DYNAMIC_CONDITIONAL: + WARN_FUNC("early indirect call", insn->sec, insn->offset); + return 1; + + case INSN_JUMP_UNCONDITIONAL: + case INSN_JUMP_CONDITIONAL: + if (!is_sibling_call(insn)) { + if (!insn->jump_dest) { + WARN_FUNC("unresolved jump target after linking?!?", + insn->sec, insn->offset); + return -1; + } + ret = validate_entry(file, insn->jump_dest); + if (ret) { + if (opts.backtrace) { + BT_FUNC("(branch%s)", insn, + insn->type == INSN_JUMP_CONDITIONAL ? "-cond" : ""); + } + return ret; + } + + if (insn->type == INSN_JUMP_UNCONDITIONAL) + return 0; + + break; + } + + /* fallthrough */ + case INSN_CALL: + dest = find_insn(file, insn->call_dest->sec, + insn->call_dest->offset); + if (!dest) { + WARN("Unresolved function after linking!?: %s", + insn->call_dest->name); + return -1; + } + + ret = validate_entry(file, dest); + if (ret) { + if (opts.backtrace) + BT_FUNC("(call)", insn); + return ret; + } + /* + * If a call returns without error, it must have seen UNTRAIN_RET. + * Therefore any non-error return is a success. + */ + return 0; + + case INSN_RETURN: + WARN_FUNC("RET before UNTRAIN", insn->sec, insn->offset); + return 1; + + case INSN_NOP: + if (insn->retpoline_safe) + return 0; + break; + + default: + break; + } + + if (!next) { + WARN_FUNC("teh end!", insn->sec, insn->offset); + return -1; + } + insn = next; + } + + return warnings; +} + +/* + * Validate that all branches starting at 'insn->entry' encounter UNRET_END + * before RET. + */ +static int validate_unret(struct objtool_file *file) +{ + struct instruction *insn; + int ret, warnings = 0; + + for_each_insn(file, insn) { + if (!insn->entry) + continue; + + ret = validate_entry(file, insn); + if (ret < 0) { + WARN_FUNC("Failed UNRET validation", insn->sec, insn->offset); + return ret; + } + warnings += ret; + } + + return warnings; +} + static int validate_retpoline(struct objtool_file *file) { struct instruction *insn; @@ -4039,6 +4187,17 @@ int check(struct objtool_file *file) warnings += ret; } + if (opts.unret) { + /* + * Must be after validate_branch() and friends, it plays + * further games with insn->visited. + */ + ret = validate_unret(file); + if (ret < 0) + return ret; + warnings += ret; + } + if (opts.ibt) { ret = validate_ibt(file); if (ret < 0) diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h index 280ea18b7f2b..0c476b0b40a3 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -19,6 +19,7 @@ struct opts { bool noinstr; bool orc; bool retpoline; + bool unret; bool sls; bool stackval; bool static_call; diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/objtool/check.h index f10d7374f388..0eeedeacbefb 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -51,8 +51,10 @@ struct instruction { ignore_alts : 1, hint : 1, retpoline_safe : 1, - noendbr : 1; - /* 2 bit hole */ + noendbr : 1, + entry : 1; + /* 1 bit hole */ + s8 instr; u8 visited; /* u8 hole */ @@ -69,6 +71,11 @@ struct instruction { struct cfi_state *cfi; }; +#define VISITED_BRANCH 0x01 +#define VISITED_BRANCH_UACCESS 0x02 +#define VISITED_BRANCH_MASK 0x03 +#define VISITED_ENTRY 0x04 + static inline bool is_static_jump(struct instruction *insn) { return insn->type == INSN_JUMP_CONDITIONAL || -- cgit v1.2.3 From a4ab14e1d8fe83cc1ed8910b788117ec2ed25179 Mon Sep 17 00:00:00 2001 From: John Hubbard Date: Mon, 27 Jun 2022 18:23:53 -0700 Subject: gen_compile_commands: handle multiple lines per .mod file scripts/clang-tools/gen_compile_commands.py incorrectly assumes that each .mod file only contains one line. That assumption was correct when the script was originally created, but commit 9413e7640564 ("kbuild: split the second line of *.mod into *.usyms") changed the .mod file format so that there is one entry per line, and potentially many lines. The problem can be reproduced by using Kbuild to generate compile_commands.json, like this: make CC=clang compile_commands.json In many cases, the problem might be overlooked because many subsystems only have one line anyway. However, in some subsystems (Nouveau, with 762 entries, is a notable example) it results in skipping most of the subsystem. Fix this by fully processing each .mod file. Fixes: 9413e7640564 ("kbuild: split the second line of *.mod into *.usyms") Signed-off-by: John Hubbard Reviewed-by: Nick Desaulniers Signed-off-by: Masahiro Yamada --- scripts/clang-tools/gen_compile_commands.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/clang-tools/gen_compile_commands.py b/scripts/clang-tools/gen_compile_commands.py index 1d1bde1fd45e..47da25b3ba7d 100755 --- a/scripts/clang-tools/gen_compile_commands.py +++ b/scripts/clang-tools/gen_compile_commands.py @@ -157,10 +157,10 @@ def cmdfiles_for_modorder(modorder): if ext != '.ko': sys.exit('{}: module path must end with .ko'.format(ko)) mod = base + '.mod' - # The first line of *.mod lists the objects that compose the module. + # Read from *.mod, to get a list of objects that compose the module. with open(mod) as m: - for obj in m.readline().split(): - yield to_cmdfile(obj) + for mod_line in m: + yield to_cmdfile(mod_line.rstrip()) def process_line(root_directory, command_prefix, file_path): -- cgit v1.2.3 From f43b9876e857c739d407bc56df288b0ebe1a9164 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 27 Jun 2022 22:21:17 +0000 Subject: x86/retbleed: Add fine grained Kconfig knobs Do fine-grained Kconfig for all the various retbleed parts. NOTE: if your compiler doesn't support return thunks this will silently 'upgrade' your mitigation to IBPB, you might not like this. Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Borislav Petkov --- arch/x86/Kconfig | 111 +++++++++++++++++++++++-------- arch/x86/Makefile | 8 ++- arch/x86/entry/calling.h | 4 ++ arch/x86/include/asm/disabled-features.h | 18 +++-- arch/x86/include/asm/linkage.h | 4 +- arch/x86/include/asm/nospec-branch.h | 10 ++- arch/x86/include/asm/static_call.h | 2 +- arch/x86/kernel/alternative.c | 5 ++ arch/x86/kernel/cpu/amd.c | 2 + arch/x86/kernel/cpu/bugs.c | 42 +++++++----- arch/x86/kernel/static_call.c | 2 +- arch/x86/kvm/emulate.c | 4 +- arch/x86/lib/retpoline.S | 4 ++ scripts/Makefile.lib | 1 + scripts/Makefile.vmlinux_o | 2 +- security/Kconfig | 11 --- tools/objtool/builtin-check.c | 7 ++ tools/objtool/check.c | 9 ++- tools/objtool/include/objtool/builtin.h | 1 + 19 files changed, 178 insertions(+), 69 deletions(-) (limited to 'scripts') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index e35eecfb74f2..e58798f636d4 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -462,32 +462,6 @@ config GOLDFISH def_bool y depends on X86_GOLDFISH -config RETPOLINE - bool "Avoid speculative indirect branches in kernel" - select OBJTOOL if HAVE_OBJTOOL - default y - help - Compile kernel with the retpoline compiler options to guard against - kernel-to-user data leaks by avoiding speculative indirect - branches. Requires a compiler with -mindirect-branch=thunk-extern - support for full protection. The kernel may run slower. - -config CC_HAS_SLS - def_bool $(cc-option,-mharden-sls=all) - -config CC_HAS_RETURN_THUNK - def_bool $(cc-option,-mfunction-return=thunk-extern) - -config SLS - bool "Mitigate Straight-Line-Speculation" - depends on CC_HAS_SLS && X86_64 - select OBJTOOL if HAVE_OBJTOOL - default n - help - Compile the kernel with straight-line-speculation options to guard - against straight line speculation. The kernel image might be slightly - larger. - config X86_CPU_RESCTRL bool "x86 CPU resource control support" depends on X86 && (CPU_SUP_INTEL || CPU_SUP_AMD) @@ -2456,6 +2430,91 @@ source "kernel/livepatch/Kconfig" endmenu +config CC_HAS_SLS + def_bool $(cc-option,-mharden-sls=all) + +config CC_HAS_RETURN_THUNK + def_bool $(cc-option,-mfunction-return=thunk-extern) + +menuconfig SPECULATION_MITIGATIONS + bool "Mitigations for speculative execution vulnerabilities" + default y + help + Say Y here to enable options which enable mitigations for + speculative execution hardware vulnerabilities. + + If you say N, all mitigations will be disabled. You really + should know what you are doing to say so. + +if SPECULATION_MITIGATIONS + +config PAGE_TABLE_ISOLATION + bool "Remove the kernel mapping in user mode" + default y + depends on (X86_64 || X86_PAE) + help + This feature reduces the number of hardware side channels by + ensuring that the majority of kernel addresses are not mapped + into userspace. + + See Documentation/x86/pti.rst for more details. + +config RETPOLINE + bool "Avoid speculative indirect branches in kernel" + select OBJTOOL if HAVE_OBJTOOL + default y + help + Compile kernel with the retpoline compiler options to guard against + kernel-to-user data leaks by avoiding speculative indirect + branches. Requires a compiler with -mindirect-branch=thunk-extern + support for full protection. The kernel may run slower. + +config RETHUNK + bool "Enable return-thunks" + depends on RETPOLINE && CC_HAS_RETURN_THUNK + select OBJTOOL if HAVE_OBJTOOL + default y + help + Compile the kernel with the return-thunks compiler option to guard + against kernel-to-user data leaks by avoiding return speculation. + Requires a compiler with -mfunction-return=thunk-extern + support for full protection. The kernel may run slower. + +config CPU_UNRET_ENTRY + bool "Enable UNRET on kernel entry" + depends on CPU_SUP_AMD && RETHUNK + default y + help + Compile the kernel with support for the retbleed=unret mitigation. + +config CPU_IBPB_ENTRY + bool "Enable IBPB on kernel entry" + depends on CPU_SUP_AMD + default y + help + Compile the kernel with support for the retbleed=ibpb mitigation. + +config CPU_IBRS_ENTRY + bool "Enable IBRS on kernel entry" + depends on CPU_SUP_INTEL + default y + help + Compile the kernel with support for the spectre_v2=ibrs mitigation. + This mitigates both spectre_v2 and retbleed at great cost to + performance. + +config SLS + bool "Mitigate Straight-Line-Speculation" + depends on CC_HAS_SLS && X86_64 + select OBJTOOL if HAVE_OBJTOOL + default n + help + Compile the kernel with straight-line-speculation options to guard + against straight line speculation. The kernel image might be slightly + larger. + +endif + config ARCH_HAS_ADD_PAGES def_bool y depends on ARCH_ENABLE_MEMORY_HOTPLUG diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 6e16057737e5..1f40dad30d50 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -15,14 +15,18 @@ endif ifdef CONFIG_CC_IS_GCC RETPOLINE_CFLAGS := $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register) RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix) -RETPOLINE_CFLAGS += $(call cc-option,-mfunction-return=thunk-extern) RETPOLINE_VDSO_CFLAGS := $(call cc-option,-mindirect-branch=thunk-inline -mindirect-branch-register) endif ifdef CONFIG_CC_IS_CLANG RETPOLINE_CFLAGS := -mretpoline-external-thunk RETPOLINE_VDSO_CFLAGS := -mretpoline -RETPOLINE_CFLAGS += $(call cc-option,-mfunction-return=thunk-extern) endif + +ifdef CONFIG_RETHUNK +RETHUNK_CFLAGS := -mfunction-return=thunk-extern +RETPOLINE_CFLAGS += $(RETHUNK_CFLAGS) +endif + export RETPOLINE_CFLAGS export RETPOLINE_VDSO_CFLAGS diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h index 074d04e434de..f6907627172b 100644 --- a/arch/x86/entry/calling.h +++ b/arch/x86/entry/calling.h @@ -297,6 +297,7 @@ For 32-bit we have the following conventions - kernel is built with * Assumes x86_spec_ctrl_{base,current} to have SPEC_CTRL_IBRS set. */ .macro IBRS_ENTER save_reg +#ifdef CONFIG_CPU_IBRS_ENTRY ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_KERNEL_IBRS movl $MSR_IA32_SPEC_CTRL, %ecx @@ -317,6 +318,7 @@ For 32-bit we have the following conventions - kernel is built with shr $32, %rdx wrmsr .Lend_\@: +#endif .endm /* @@ -324,6 +326,7 @@ For 32-bit we have the following conventions - kernel is built with * regs. Must be called after the last RET. */ .macro IBRS_EXIT save_reg +#ifdef CONFIG_CPU_IBRS_ENTRY ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_KERNEL_IBRS movl $MSR_IA32_SPEC_CTRL, %ecx @@ -338,6 +341,7 @@ For 32-bit we have the following conventions - kernel is built with shr $32, %rdx wrmsr .Lend_\@: +#endif .endm /* diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h index db75da511a36..33d2cd04d254 100644 --- a/arch/x86/include/asm/disabled-features.h +++ b/arch/x86/include/asm/disabled-features.h @@ -54,9 +54,19 @@ # define DISABLE_RETPOLINE 0 #else # define DISABLE_RETPOLINE ((1 << (X86_FEATURE_RETPOLINE & 31)) | \ - (1 << (X86_FEATURE_RETPOLINE_LFENCE & 31)) | \ - (1 << (X86_FEATURE_RETHUNK & 31)) | \ - (1 << (X86_FEATURE_UNRET & 31))) + (1 << (X86_FEATURE_RETPOLINE_LFENCE & 31))) +#endif + +#ifdef CONFIG_RETHUNK +# define DISABLE_RETHUNK 0 +#else +# define DISABLE_RETHUNK (1 << (X86_FEATURE_RETHUNK & 31)) +#endif + +#ifdef CONFIG_CPU_UNRET_ENTRY +# define DISABLE_UNRET 0 +#else +# define DISABLE_UNRET (1 << (X86_FEATURE_UNRET & 31)) #endif #ifdef CONFIG_INTEL_IOMMU_SVM @@ -91,7 +101,7 @@ #define DISABLED_MASK8 (DISABLE_TDX_GUEST) #define DISABLED_MASK9 (DISABLE_SGX) #define DISABLED_MASK10 0 -#define DISABLED_MASK11 (DISABLE_RETPOLINE) +#define DISABLED_MASK11 (DISABLE_RETPOLINE|DISABLE_RETHUNK|DISABLE_UNRET) #define DISABLED_MASK12 0 #define DISABLED_MASK13 0 #define DISABLED_MASK14 0 diff --git a/arch/x86/include/asm/linkage.h b/arch/x86/include/asm/linkage.h index e3ae331cabb1..73ca20049835 100644 --- a/arch/x86/include/asm/linkage.h +++ b/arch/x86/include/asm/linkage.h @@ -19,7 +19,7 @@ #define __ALIGN_STR __stringify(__ALIGN) #endif -#if defined(CONFIG_RETPOLINE) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO) +#if defined(CONFIG_RETHUNK) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO) #define RET jmp __x86_return_thunk #else /* CONFIG_RETPOLINE */ #ifdef CONFIG_SLS @@ -31,7 +31,7 @@ #else /* __ASSEMBLY__ */ -#if defined(CONFIG_RETPOLINE) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO) +#if defined(CONFIG_RETHUNK) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO) #define ASM_RET "jmp __x86_return_thunk\n\t" #else /* CONFIG_RETPOLINE */ #ifdef CONFIG_SLS diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h index ccde87e6eabb..bb05ed4f46bd 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -127,6 +127,12 @@ .Lskip_rsb_\@: .endm +#ifdef CONFIG_CPU_UNRET_ENTRY +#define CALL_ZEN_UNTRAIN_RET "call zen_untrain_ret" +#else +#define CALL_ZEN_UNTRAIN_RET "" +#endif + /* * Mitigate RETBleed for AMD/Hygon Zen uarch. Requires KERNEL CR3 because the * return thunk isn't mapped into the userspace tables (then again, AMD @@ -139,10 +145,10 @@ * where we have a stack but before any RET instruction. */ .macro UNTRAIN_RET -#ifdef CONFIG_RETPOLINE +#if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_IBPB_ENTRY) ANNOTATE_UNRET_END ALTERNATIVE_2 "", \ - "call zen_untrain_ret", X86_FEATURE_UNRET, \ + CALL_ZEN_UNTRAIN_RET, X86_FEATURE_UNRET, \ "call entry_ibpb", X86_FEATURE_ENTRY_IBPB #endif .endm diff --git a/arch/x86/include/asm/static_call.h b/arch/x86/include/asm/static_call.h index 70cc9ccb8029..343b722ccaf2 100644 --- a/arch/x86/include/asm/static_call.h +++ b/arch/x86/include/asm/static_call.h @@ -46,7 +46,7 @@ #define ARCH_DEFINE_STATIC_CALL_TRAMP(name, func) \ __ARCH_DEFINE_STATIC_CALL_TRAMP(name, ".byte 0xe9; .long " #func " - (. + 4)") -#ifdef CONFIG_RETPOLINE +#ifdef CONFIG_RETHUNK #define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) \ __ARCH_DEFINE_STATIC_CALL_TRAMP(name, "jmp __x86_return_thunk") #else diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index cf447ee18b3c..d6858533e6e5 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -508,6 +508,7 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) } } +#ifdef CONFIG_RETHUNK /* * Rewrite the compiler generated return thunk tail-calls. * @@ -569,6 +570,10 @@ void __init_or_module noinline apply_returns(s32 *start, s32 *end) } } } +#else +void __init_or_module noinline apply_returns(s32 *start, s32 *end) { } +#endif /* CONFIG_RETHUNK */ + #else /* !CONFIG_RETPOLINE || !CONFIG_OBJTOOL */ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) { } diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 9cfd11f7ba11..35d5288394cb 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -864,6 +864,7 @@ static void init_amd_bd(struct cpuinfo_x86 *c) void init_spectral_chicken(struct cpuinfo_x86 *c) { +#ifdef CONFIG_CPU_UNRET_ENTRY u64 value; /* @@ -880,6 +881,7 @@ void init_spectral_chicken(struct cpuinfo_x86 *c) wrmsrl_safe(MSR_ZEN2_SPECTRAL_CHICKEN, value); } } +#endif } static void init_amd_zn(struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 182f8b2e8a3c..cf08a1b8f3c7 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -842,7 +842,6 @@ static int __init retbleed_parse_cmdline(char *str) early_param("retbleed", retbleed_parse_cmdline); #define RETBLEED_UNTRAIN_MSG "WARNING: BTB untrained return thunk mitigation is only effective on AMD/Hygon!\n" -#define RETBLEED_COMPILER_MSG "WARNING: kernel not compiled with RETPOLINE or -mfunction-return capable compiler; falling back to IBPB!\n" #define RETBLEED_INTEL_MSG "WARNING: Spectre v2 mitigation leaves CPU vulnerable to RETBleed attacks, data leaks possible!\n" static void __init retbleed_select_mitigation(void) @@ -857,18 +856,33 @@ static void __init retbleed_select_mitigation(void) return; case RETBLEED_CMD_UNRET: - retbleed_mitigation = RETBLEED_MITIGATION_UNRET; + if (IS_ENABLED(CONFIG_CPU_UNRET_ENTRY)) { + retbleed_mitigation = RETBLEED_MITIGATION_UNRET; + } else { + pr_err("WARNING: kernel not compiled with CPU_UNRET_ENTRY.\n"); + goto do_cmd_auto; + } break; case RETBLEED_CMD_IBPB: - retbleed_mitigation = RETBLEED_MITIGATION_IBPB; + if (IS_ENABLED(CONFIG_CPU_IBPB_ENTRY)) { + retbleed_mitigation = RETBLEED_MITIGATION_IBPB; + } else { + pr_err("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n"); + goto do_cmd_auto; + } break; +do_cmd_auto: case RETBLEED_CMD_AUTO: default: if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD || - boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) - retbleed_mitigation = RETBLEED_MITIGATION_UNRET; + boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) { + if (IS_ENABLED(CONFIG_CPU_UNRET_ENTRY)) + retbleed_mitigation = RETBLEED_MITIGATION_UNRET; + else if (IS_ENABLED(CONFIG_CPU_IBPB_ENTRY)) + retbleed_mitigation = RETBLEED_MITIGATION_IBPB; + } /* * The Intel mitigation (IBRS or eIBRS) was already selected in @@ -881,14 +895,6 @@ static void __init retbleed_select_mitigation(void) switch (retbleed_mitigation) { case RETBLEED_MITIGATION_UNRET: - - if (!IS_ENABLED(CONFIG_RETPOLINE) || - !IS_ENABLED(CONFIG_CC_HAS_RETURN_THUNK)) { - pr_err(RETBLEED_COMPILER_MSG); - retbleed_mitigation = RETBLEED_MITIGATION_IBPB; - goto retbleed_force_ibpb; - } - setup_force_cpu_cap(X86_FEATURE_RETHUNK); setup_force_cpu_cap(X86_FEATURE_UNRET); @@ -900,7 +906,6 @@ static void __init retbleed_select_mitigation(void) break; case RETBLEED_MITIGATION_IBPB: -retbleed_force_ibpb: setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); mitigate_smt = true; break; @@ -1271,6 +1276,12 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) return SPECTRE_V2_CMD_AUTO; } + if (cmd == SPECTRE_V2_CMD_IBRS && !IS_ENABLED(CONFIG_CPU_IBRS_ENTRY)) { + pr_err("%s selected but not compiled in. Switching to AUTO select\n", + mitigation_options[i].option); + return SPECTRE_V2_CMD_AUTO; + } + if (cmd == SPECTRE_V2_CMD_IBRS && boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) { pr_err("%s selected but not Intel CPU. Switching to AUTO select\n", mitigation_options[i].option); @@ -1328,7 +1339,8 @@ static void __init spectre_v2_select_mitigation(void) break; } - if (boot_cpu_has_bug(X86_BUG_RETBLEED) && + if (IS_ENABLED(CONFIG_CPU_IBRS_ENTRY) && + boot_cpu_has_bug(X86_BUG_RETBLEED) && retbleed_cmd != RETBLEED_CMD_OFF && boot_cpu_has(X86_FEATURE_IBRS) && boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) { diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c index fe21fe778185..be7038a0da4d 100644 --- a/arch/x86/kernel/static_call.c +++ b/arch/x86/kernel/static_call.c @@ -126,7 +126,7 @@ void arch_static_call_transform(void *site, void *tramp, void *func, bool tail) } EXPORT_SYMBOL_GPL(arch_static_call_transform); -#ifdef CONFIG_RETPOLINE +#ifdef CONFIG_RETHUNK /* * This is called by apply_returns() to fix up static call trampolines, * specifically ARCH_DEFINE_STATIC_CALL_NULL_TRAMP which is recorded as diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index b01437015f99..db96bf7d1122 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -439,10 +439,10 @@ static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop); * * ENDBR [4 bytes; CONFIG_X86_KERNEL_IBT] * SETcc %al [3 bytes] - * RET | JMP __x86_return_thunk [1,5 bytes; CONFIG_RETPOLINE] + * RET | JMP __x86_return_thunk [1,5 bytes; CONFIG_RETHUNK] * INT3 [1 byte; CONFIG_SLS] */ -#define RET_LENGTH (1 + (4 * IS_ENABLED(CONFIG_RETPOLINE)) + \ +#define RET_LENGTH (1 + (4 * IS_ENABLED(CONFIG_RETHUNK)) + \ IS_ENABLED(CONFIG_SLS)) #define SETCC_LENGTH (ENDBR_INSN_SIZE + 3 + RET_LENGTH) #define SETCC_ALIGN (4 << ((SETCC_LENGTH > 4) & 1) << ((SETCC_LENGTH > 8) & 1)) diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S index fdd16163b996..073289a55f84 100644 --- a/arch/x86/lib/retpoline.S +++ b/arch/x86/lib/retpoline.S @@ -72,6 +72,8 @@ SYM_CODE_END(__x86_indirect_thunk_array) * This function name is magical and is used by -mfunction-return=thunk-extern * for the compiler to generate JMPs to it. */ +#ifdef CONFIG_RETHUNK + .section .text.__x86.return_thunk /* @@ -136,3 +138,5 @@ SYM_FUNC_END(zen_untrain_ret) __EXPORT_THUNK(zen_untrain_ret) EXPORT_SYMBOL(__x86_return_thunk) + +#endif /* CONFIG_RETHUNK */ diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index d1425778664b..3fb6a99e78c4 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -236,6 +236,7 @@ objtool_args = \ $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ $(if $(CONFIG_UNWINDER_ORC), --orc) \ $(if $(CONFIG_RETPOLINE), --retpoline) \ + $(if $(CONFIG_RETHUNK), --rethunk) \ $(if $(CONFIG_SLS), --sls) \ $(if $(CONFIG_STACK_VALIDATION), --stackval) \ $(if $(CONFIG_HAVE_STATIC_CALL_INLINE), --static-call) \ diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o index bc67748044a6..84019814f33f 100644 --- a/scripts/Makefile.vmlinux_o +++ b/scripts/Makefile.vmlinux_o @@ -44,7 +44,7 @@ objtool-enabled := $(or $(delay-objtool),$(CONFIG_NOINSTR_VALIDATION)) objtool_args := \ $(if $(delay-objtool),$(objtool_args)) \ - $(if $(CONFIG_NOINSTR_VALIDATION), --noinstr $(if $(CONFIG_RETPOLINE), --unret)) \ + $(if $(CONFIG_NOINSTR_VALIDATION), --noinstr $(if $(CONFIG_CPU_UNRET_ENTRY), --unret)) \ $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) \ --link diff --git a/security/Kconfig b/security/Kconfig index f29e4c656983..e6db09a779b7 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -54,17 +54,6 @@ config SECURITY_NETWORK implement socket and networking access controls. If you are unsure how to answer this question, answer N. -config PAGE_TABLE_ISOLATION - bool "Remove the kernel mapping in user mode" - default y - depends on (X86_64 || X86_PAE) && !UML - help - This feature reduces the number of hardware side channels by - ensuring that the majority of kernel addresses are not mapped - into userspace. - - See Documentation/x86/pti.rst for more details. - config SECURITY_INFINIBAND bool "Infiniband Security Hooks" depends on SECURITY && INFINIBAND diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index c063e1ff96b2..24fbe803a0d3 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -68,6 +68,7 @@ const struct option check_options[] = { OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"), OPT_BOOLEAN('o', "orc", &opts.orc, "generate ORC metadata"), OPT_BOOLEAN('r', "retpoline", &opts.retpoline, "validate and annotate retpoline usage"), + OPT_BOOLEAN(0, "rethunk", &opts.rethunk, "validate and annotate rethunk usage"), OPT_BOOLEAN(0, "unret", &opts.unret, "validate entry unret placement"), OPT_BOOLEAN('l', "sls", &opts.sls, "validate straight-line-speculation mitigations"), OPT_BOOLEAN('s', "stackval", &opts.stackval, "validate frame pointer rules"), @@ -124,6 +125,7 @@ static bool opts_valid(void) opts.noinstr || opts.orc || opts.retpoline || + opts.rethunk || opts.sls || opts.stackval || opts.static_call || @@ -136,6 +138,11 @@ static bool opts_valid(void) return true; } + if (opts.unret && !opts.rethunk) { + ERROR("--unret requires --rethunk"); + return false; + } + if (opts.dump_orc) return true; diff --git a/tools/objtool/check.c b/tools/objtool/check.c index ddfdd138cc2a..7bebdb8867cd 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3732,8 +3732,11 @@ static int validate_retpoline(struct objtool_file *file) continue; if (insn->type == INSN_RETURN) { - WARN_FUNC("'naked' return found in RETPOLINE build", - insn->sec, insn->offset); + if (opts.rethunk) { + WARN_FUNC("'naked' return found in RETHUNK build", + insn->sec, insn->offset); + } else + continue; } else { WARN_FUNC("indirect %s found in RETPOLINE build", insn->sec, insn->offset, @@ -4264,7 +4267,9 @@ int check(struct objtool_file *file) if (ret < 0) goto out; warnings += ret; + } + if (opts.rethunk) { ret = create_return_sites_sections(file); if (ret < 0) goto out; diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h index 0c476b0b40a3..42a52f1a0add 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -19,6 +19,7 @@ struct opts { bool noinstr; bool orc; bool retpoline; + bool rethunk; bool unret; bool sls; bool stackval; -- cgit v1.2.3 From 2bc6430884d5ee0e30ae18652d31f821d8e9ec32 Mon Sep 17 00:00:00 2001 From: David Reaver Date: Sat, 25 Jun 2022 14:15:48 -0700 Subject: scripts: get_feat.pl: use /usr/bin/env to find perl I tried running `make pdfdocs` on NixOS, but it failed because get_feat.pl uses a shebang line with /usr/bin/perl, and that file path doesn't exist on NixOS. Using the more portable /usr/bin/env perl fixes the problem. Signed-off-by: David Reaver Link: https://lore.kernel.org/r/20220625211548.1200198-1-me@davidreaver.com Signed-off-by: Jonathan Corbet --- scripts/get_feat.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/get_feat.pl b/scripts/get_feat.pl index 76cfb96b59b6..5c5397eeb237 100755 --- a/scripts/get_feat.pl +++ b/scripts/get_feat.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # SPDX-License-Identifier: GPL-2.0 use strict; -- cgit v1.2.3 From d60be533a0033c2cb9e36c0a1ee4b3080ed4eef2 Mon Sep 17 00:00:00 2001 From: Vipin Sharma Date: Fri, 17 Jun 2022 17:54:57 -0700 Subject: scripts/tags.sh: Include tools directory in tags generation Add tools directory in generating tags and quiet the "No such file or directory" warnings. It reverts the changes introduced in commit 162343a876f1 ("scripts/tags.sh: exclude tools directory from tags generation") while maintainig the original intent of the patch to get rid of the warnings. This allows the root level cscope files to include tools source code besides kernel and a single place to browse the code for both. Acked-by: Cristian Ciocaltea Signed-off-by: Vipin Sharma Link: https://lore.kernel.org/r/20220618005457.2379324-1-vipinsh@google.com Signed-off-by: Greg Kroah-Hartman --- scripts/tags.sh | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/tags.sh b/scripts/tags.sh index 01fab3d4f90b..e137cf15aae9 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -25,13 +25,6 @@ else tree=${srctree}/ fi -# ignore userspace tools -if [ -n "$COMPILED_SOURCE" ]; then - ignore="$ignore ( -path ./tools ) -prune -o" -else - ignore="$ignore ( -path ${tree}tools ) -prune -o" -fi - # Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH if [ "${ALLSOURCE_ARCHS}" = "" ]; then ALLSOURCE_ARCHS=${SRCARCH} @@ -100,7 +93,7 @@ all_compiled_sources() find $ignore -name "*.cmd" -exec \ grep -Poh '(?(?=^source_.* \K).*|(?=^ \K\S).*(?= \\))' {} \+ | awk '!a[$0]++' - } | xargs realpath -es $([ -z "$KBUILD_ABS_SRCTREE" ] && echo --relative-to=.) | + } | xargs realpath -esq $([ -z "$KBUILD_ABS_SRCTREE" ] && echo --relative-to=.) | sort -u } -- cgit v1.2.3 From 38857318692acd02353b47129bb06326528a47c0 Mon Sep 17 00:00:00 2001 From: Jérémy LEFAURE Date: Fri, 1 Jul 2022 16:01:36 +0000 Subject: coccinelle: Extend address test from ifaddr semantic patch to test expressions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test of an expression's address does not necessarily represent the whole condition, it may only be a part of it. Also, an expression's address is likely to be non-zero in every test expression, not only in if statements. This change aims at detecting an address test in more complex conditions and not only in if statements. Signed-off-by: Jérémy Lefaure Signed-off-by: Julia Lawall --- scripts/coccinelle/misc/ifaddr.cocci | 35 --------------------------------- scripts/coccinelle/misc/test_addr.cocci | 33 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 35 deletions(-) delete mode 100644 scripts/coccinelle/misc/ifaddr.cocci create mode 100644 scripts/coccinelle/misc/test_addr.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/misc/ifaddr.cocci b/scripts/coccinelle/misc/ifaddr.cocci deleted file mode 100644 index fc92e8fcbfcb..000000000000 --- a/scripts/coccinelle/misc/ifaddr.cocci +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/// The address of a variable or field is likely always to be non-zero. -/// -// Confidence: High -// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. -// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ -// Comments: -// Options: --no-includes --include-headers - -virtual org -virtual report -virtual context - -@r@ -expression x; -statement S1,S2; -position p; -@@ - -*if@p (&x) - S1 else S2 - -@script:python depends on org@ -p << r.p; -@@ - -cocci.print_main("test of a variable/field address",p) - -@script:python depends on report@ -p << r.p; -@@ - -msg = "ERROR: test of a variable/field address" -coccilib.report.print_report(p[0],msg) diff --git a/scripts/coccinelle/misc/test_addr.cocci b/scripts/coccinelle/misc/test_addr.cocci new file mode 100644 index 000000000000..029db9069c44 --- /dev/null +++ b/scripts/coccinelle/misc/test_addr.cocci @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// The address of a variable or field is likely always to be non-zero. +/// +// Confidence: High +// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. +// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: --no-includes --include-headers + +virtual org +virtual report +virtual context + +@r@ +expression x; +position p; +@@ + +*\(&x@p == NULL \| &x@p != NULL\) + +@script:python depends on org@ +p << r.p; +@@ + +cocci.print_main("test of a variable/field address",p) + +@script:python depends on report@ +p << r.p; +@@ + +msg = "ERROR: test of a variable/field address" +coccilib.report.print_report(p[0],msg) -- cgit v1.2.3 From 7c2d45a347c7933cbe0efff14fe96adeb13fd761 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 2 Jul 2022 11:11:25 +0100 Subject: scripts: sphinx-pre-install: fix venv version check logic The logic which checks if the venv version is good enough but was not activated is broken: it is checking against the wrong val, making it to recommend to re-create a venv every time. Fix it. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/afe01b7863fd655986d84ace8948f3d7aede796d.1656756450.git.mchehab@kernel.org Signed-off-by: Jonathan Corbet --- scripts/sphinx-pre-install | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install index f126ecbb0494..ae8c49734899 100755 --- a/scripts/sphinx-pre-install +++ b/scripts/sphinx-pre-install @@ -741,7 +741,7 @@ sub recommend_sphinx_upgrade() # Get the highest version from sphinx_*/bin/sphinx-build and the # corresponding command to activate the venv/virtenv - $activate_cmd = get_virtenv(); + ($activate_cmd, $venv_ver) = get_virtenv(); # Store the highest version from Sphinx existing virtualenvs if (($activate_cmd ne "") && ($venv_ver gt $cur_version)) { @@ -759,10 +759,14 @@ sub recommend_sphinx_upgrade() # Either there are already a virtual env or a new one should be created $need_pip = 1; + return if (!$latest_avail_ver); + # Return if the reason is due to an upgrade or not if ($latest_avail_ver lt $rec_version) { $rec_sphinx_upgrade = 1; } + + return $latest_avail_ver; } # @@ -820,7 +824,7 @@ sub recommend_sphinx_version($) } # Suggest newer versions if current ones are too old - if ($latest_avail_ver && $cur_version ge $min_version) { + if ($latest_avail_ver && $latest_avail_ver ge $min_version) { # If there's a good enough version, ask the user to enable it if ($latest_avail_ver ge $rec_version) { printf "\nNeed to activate Sphinx (version $latest_avail_ver) on virtualenv with:\n"; @@ -897,7 +901,7 @@ sub check_needs() } } - recommend_sphinx_upgrade(); + my $venv_ver = recommend_sphinx_upgrade(); my $virtualenv_cmd; -- cgit v1.2.3 From ed2133b7b5859bc1de86ed44d5cd93096cadc446 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 2 Jul 2022 11:11:26 +0100 Subject: scripts: sphinx-pre-install: report broken venv After distro upgrades, the directory names for python may change. On such case, the previously-created venv will be broken, and sphinx-build won't run. Add a logic to report it. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/f117f03555b0636d2be0b68f3a23b1d3f03ccf1d.1656756450.git.mchehab@kernel.org [jc: fixed typo in warning message] Signed-off-by: Jonathan Corbet --- scripts/sphinx-pre-install | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'scripts') diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install index ae8c49734899..cfb82c548fb3 100755 --- a/scripts/sphinx-pre-install +++ b/scripts/sphinx-pre-install @@ -720,6 +720,12 @@ sub get_virtenv() next if (! -f $sphinx_cmd); my $ver = get_sphinx_version($sphinx_cmd); + + if (!$ver) { + $f =~ s#/bin/activate##; + print("Warning: virtual environment $f is not working.\nPython version upgrade? Remove it with:\n\n\trm -rf $f\n\n"); + } + if ($need_sphinx && ($ver ge $min_version)) { return ($f, $ver); } elsif ($ver gt $cur_version) { -- cgit v1.2.3 From 5b27d2551c199c3077b7104b1417b6aecff15d34 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 2 Jul 2022 11:11:27 +0100 Subject: scripts: sphinx-pre-install: check for PDF min version later on Better to add the PDF note late for venv recommendation. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/8e117aabe6dfa1b1ec92dccd20e801393c977667.1656756450.git.mchehab@kernel.org Signed-off-by: Jonathan Corbet --- scripts/sphinx-pre-install | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install index cfb82c548fb3..2ef2c561fdc6 100755 --- a/scripts/sphinx-pre-install +++ b/scripts/sphinx-pre-install @@ -785,12 +785,13 @@ sub recommend_sphinx_version($) { my $virtualenv_cmd = shift; - if ($latest_avail_ver lt $min_pdf_version) { - print "note: If you want pdf, you need at least Sphinx $min_pdf_version.\n"; - } - # Version is OK. Nothing to do. - return if ($cur_version && ($cur_version ge $rec_version)); + if ($cur_version && ($cur_version ge $rec_version)) { + if ($cur_version lt $min_pdf_version) { + print "note: If you want pdf, you need at least Sphinx $min_pdf_version.\n"; + } + return; + }; if (!$need_sphinx) { # sphinx-build is present and its version is >= $min_version @@ -837,6 +838,10 @@ sub recommend_sphinx_version($) printf "\t. $activate_cmd\n"; deactivate_help(); + if ($latest_avail_ver lt $min_pdf_version) { + print "note: If you want pdf, you need at least Sphinx $min_pdf_version.\n"; + } + return; } -- cgit v1.2.3 From 6a5d7320fb75af071cde628e82ebc938575a2fd6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 2 Jul 2022 11:11:28 +0100 Subject: scripts: sphinx-pre-install: provide both venv and package installs As it is not a consensus about installing sphinx using venv, and modern distributions are now shipping with Sphinx versions above the minimal requirements to build the docs, provide both venv and package install commands by default. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/7c99d985df204c73e3daafd5fd2f30a31269405d.1656756450.git.mchehab@kernel.org Signed-off-by: Jonathan Corbet --- scripts/sphinx-pre-install | 55 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install index 2ef2c561fdc6..b9b7d5e301f4 100755 --- a/scripts/sphinx-pre-install +++ b/scripts/sphinx-pre-install @@ -25,6 +25,7 @@ my $need_sphinx = 0; my $need_pip = 0; my $need_virtualenv = 0; my $rec_sphinx_upgrade = 0; +my $verbose_warn_install = 1; my $install = ""; my $virtenv_dir = ""; my $python_cmd = ""; @@ -103,10 +104,12 @@ sub check_missing(%) next; } - if ($is_optional) { - print "Warning: better to also install \"$prog\".\n"; - } else { - print "ERROR: please install \"$prog\", otherwise, build won't work.\n"; + if ($verbose_warn_install) { + if ($is_optional) { + print "Warning: better to also install \"$prog\".\n"; + } else { + print "ERROR: please install \"$prog\", otherwise, build won't work.\n"; + } } if (defined($map{$prog})) { $install .= " " . $map{$prog}; @@ -386,7 +389,8 @@ sub give_debian_hints() check_missing(\%map); return if (!$need && !$optional); - printf("You should run:\n\n\tsudo apt-get install $install\n"); + printf("You should run:\n") if ($verbose_warn_install); + printf("\n\tsudo apt-get install $install\n"); } sub give_redhat_hints() @@ -458,10 +462,12 @@ sub give_redhat_hints() if (!$old) { # dnf, for Fedora 18+ - printf("You should run:\n\n\tsudo dnf install -y $install\n"); + printf("You should run:\n") if ($verbose_warn_install); + printf("\n\tsudo dnf install -y $install\n"); } else { # yum, for RHEL (and clones) or Fedora version < 18 - printf("You should run:\n\n\tsudo yum install -y $install\n"); + printf("You should run:\n") if ($verbose_warn_install); + printf("\n\tsudo yum install -y $install\n"); } } @@ -509,7 +515,8 @@ sub give_opensuse_hints() check_missing(\%map); return if (!$need && !$optional); - printf("You should run:\n\n\tsudo zypper install --no-recommends $install\n"); + printf("You should run:\n") if ($verbose_warn_install); + printf("\n\tsudo zypper install --no-recommends $install\n"); } sub give_mageia_hints() @@ -553,7 +560,8 @@ sub give_mageia_hints() check_missing(\%map); return if (!$need && !$optional); - printf("You should run:\n\n\tsudo $packager_cmd $install\n"); + printf("You should run:\n") if ($verbose_warn_install); + printf("\n\tsudo $packager_cmd $install\n"); } sub give_arch_linux_hints() @@ -583,7 +591,8 @@ sub give_arch_linux_hints() check_missing(\%map); return if (!$need && !$optional); - printf("You should run:\n\n\tsudo pacman -S $install\n"); + printf("You should run:\n") if ($verbose_warn_install); + printf("\n\tsudo pacman -S $install\n"); } sub give_gentoo_hints() @@ -610,7 +619,8 @@ sub give_gentoo_hints() return if (!$need && !$optional); - printf("You should run:\n\n"); + printf("You should run:\n") if ($verbose_warn_install); + printf("\n"); my $imagemagick = "media-gfx/imagemagick svg png"; my $cairo = "media-gfx/graphviz cairo pdf"; @@ -700,7 +710,7 @@ sub check_distros() sub deactivate_help() { - printf "\nIf you want to exit the virtualenv, you can use:\n"; + printf "\n If you want to exit the virtualenv, you can use:\n"; printf "\tdeactivate\n"; } @@ -863,7 +873,7 @@ sub recommend_sphinx_version($) print "To upgrade Sphinx, use:\n\n"; } } else { - print "Sphinx needs to be installed either as a package or via pip/pypi with:\n"; + print "\nSphinx needs to be installed either:\n1) via pip/pypi with:\n\n"; } $python_cmd = find_python_no_venv(); @@ -873,6 +883,25 @@ sub recommend_sphinx_version($) printf "\t. $virtenv_dir/bin/activate\n"; printf "\tpip install -r $requirement_file\n"; deactivate_help(); + + printf "\n2) As a package with:\n"; + + my $old_need = $need; + my $old_optional = $optional; + %missing = (); + $pdf = 0; + $optional = 0; + $install = ""; + $verbose_warn_install = 0; + + add_package("python-sphinx", 0); + check_python_module("sphinx_rtd_theme", 1); + + check_distros(); + + $need = $old_need; + $optional = $old_optional; + } sub check_needs() -- cgit v1.2.3 From 02bba8ca90b1877ae47400c31002ceb498b0dd9f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 2 Jul 2022 11:11:29 +0100 Subject: scripts: sphinx-pre-install: place a warning for Sphinx >= 3.0 Newer versions of Sphinx have a known bug: https://github.com/sphinx-doc/sphinx/pull/8313 Those currently produces 11 false-positive warnings On Sphinx version 3.1+. While Sphinx fix is not applied, let's warn adventurers that would be using Sphinx installed via distro packages. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/085e0ada65c11da9303d07e70c510dc45f21315b.1656756450.git.mchehab@kernel.org Signed-off-by: Jonathan Corbet --- scripts/sphinx-pre-install | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'scripts') diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install index b9b7d5e301f4..ec84fc62774e 100755 --- a/scripts/sphinx-pre-install +++ b/scripts/sphinx-pre-install @@ -902,6 +902,10 @@ sub recommend_sphinx_version($) $need = $old_need; $optional = $old_optional; + printf "\n Please note that Sphinx >= 3.0 will currently produce false-positive\n"; + printf " warning when the same name is used for more than one type (functions,\n"; + printf " structs, enums,...). This is known Sphinx bug. For more details, see:\n"; + printf "\thttps://github.com/sphinx-doc/sphinx/pull/8313\n"; } sub check_needs() -- cgit v1.2.3 From f5a4618587fb5c5eb5fec3dcce165ca8fd7d7f91 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 30 Jun 2022 17:09:35 +0900 Subject: kbuild: remove unused cmd_none in scripts/Makefile.modinst Commit 65ce9c38326e ("kbuild: move module strip/compression code into scripts/Makefile.modinst") added this unused code. Perhaps, I thought cmd_none was useful for CONFIG_MODULE_COMPRESS_NONE, but I did not use it after all. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/Makefile.modinst | 3 --- 1 file changed, 3 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index c2c43a0ecfe0..16a02e9237d3 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -28,9 +28,6 @@ modules := $(patsubst $(extmod_prefix)%, $(dst)/%$(suffix-y), $(modules)) __modinst: $(modules) @: -quiet_cmd_none = - cmd_none = : - # # Installation # -- cgit v1.2.3 From 87c482bdfa79f378297d92af49cdf265be199df5 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 8 Jul 2022 11:44:54 +0200 Subject: modules: Ensure natural alignment for .altinstructions and __bug_table sections In the kernel image vmlinux.lds.S linker scripts the .altinstructions and __bug_table sections are 4- or 8-byte aligned because they hold 32- and/or 64-bit values. Most architectures use altinstructions and BUG() or WARN() in modules as well, but in the module linker script (module.lds.S) those sections are currently missing. As consequence the linker will store their content byte-aligned by default, which then can lead to unnecessary unaligned memory accesses by the CPU when those tables are processed at runtime. Usually unaligned memory accesses are unnoticed, because either the hardware (as on x86 CPUs) or in-kernel exception handlers (e.g. on parisc or sparc) emulate and fix them up at runtime. Nevertheless, such unaligned accesses introduce a performance penalty and can even crash the kernel if there is a bug in the unalignment exception handlers (which happened once to me on the parisc architecture and which is why I noticed that issue at all). This patch fixes a non-critical issue and might be backported at any time. It's trivial and shouldn't introduce any regression because it simply tells the linker to use a different (8-byte alignment) for those sections by default. Signed-off-by: Helge Deller Link: https://lore.kernel.org/all/Yr8%2Fgr8e8I7tVX4d@p100/ Signed-off-by: Luis Chamberlain --- scripts/module.lds.S | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/module.lds.S b/scripts/module.lds.S index 1d0e1e4dc3d2..3a3aa2354ed8 100644 --- a/scripts/module.lds.S +++ b/scripts/module.lds.S @@ -27,6 +27,8 @@ SECTIONS { .ctors 0 : ALIGN(8) { *(SORT(.ctors.*)) *(.ctors) } .init_array 0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) } + .altinstructions 0 : ALIGN(8) { KEEP(*(.altinstructions)) } + __bug_table 0 : ALIGN(8) { KEEP(*(__bug_table)) } __jump_table 0 : ALIGN(8) { KEEP(*(__jump_table)) } __patchable_function_entries : { *(__patchable_function_entries) } -- cgit v1.2.3 From 74829ddf5977567d77440150d72d4c0c5c427446 Mon Sep 17 00:00:00 2001 From: David Gow Date: Fri, 8 Jul 2022 12:48:45 +0800 Subject: module: panic: Taint the kernel when selftest modules load Taint the kernel with TAINT_TEST whenever a test module loads, by adding a new "TEST" module property, and setting it for all modules in the tools/testing directory. This property can also be set manually, for tests which live outside the tools/testing directory with: MODULE_INFO(test, "Y"); Reviewed-by: Luis Chamberlain Reviewed-by: Aaron Tomlin Acked-by: Brendan Higgins Signed-off-by: David Gow Signed-off-by: Shuah Khan --- kernel/module/main.c | 7 +++++++ scripts/mod/modpost.c | 3 +++ 2 files changed, 10 insertions(+) (limited to 'scripts') diff --git a/kernel/module/main.c b/kernel/module/main.c index fed58d30725d..4723f1316709 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -1988,6 +1988,13 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags) /* Set up license info based on the info section */ set_license(mod, get_modinfo(info, "license")); + if (get_modinfo(info, "test")) { + if (!test_taint(TAINT_TEST)) + pr_warn("%s: loading test module taints kernel.\n", + mod->name); + add_taint_module(mod, TAINT_TEST, LOCKDEP_STILL_OK); + } + return 0; } diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 29d5a841e215..5937212b4433 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2191,6 +2191,9 @@ static void add_header(struct buffer *b, struct module *mod) if (strstarts(mod->name, "drivers/staging")) buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); + + if (strstarts(mod->name, "tools/testing")) + buf_printf(b, "\nMODULE_INFO(test, \"Y\");\n"); } static void add_exported_symbols(struct buffer *buf, struct module *mod) -- cgit v1.2.3 From 8e54fe1b0f03a89925925ed98acd2219e0c956d4 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Mon, 11 Jul 2022 16:42:43 -0400 Subject: coccinelle: Remove script that checks replacing 0/1 with false/true in functions returning bool There is nothing wrong with current code that returns 0 or 1 for a function returning bool. It is perfectly acceptable by the C standard. To avoid churn of unwanted patches that are constantly sent to maintainers who do not care about this change, remove the script that flags it as an issue. This issue is not worth the burden on maintainers to accept useless patches. Link: https://lore.kernel.org/all/20220705073822.7276-1-jiapeng.chong@linux.alibaba.com/ Link: https://lore.kernel.org/all/20220429075201.68581-1-jiapeng.chong@linux.alibaba.com/ Link: https://lore.kernel.org/all/1649236467-29390-1-git-send-email-baihaowen@meizu.com/ Link: https://lore.kernel.org/all/20220317014740.3138-1-jiapeng.chong@linux.alibaba.com/ Link: https://lore.kernel.org/all/190b5c2f2f2fb9cc775fce8daed72bf893be48a4.1642065293.git.davidcomponentone@gmail.com/ Link: https://lore.kernel.org/all/20211214113845.439392-1-deng.changcheng@zte.com.cn/ Link: https://lore.kernel.org/all/20210824065735.60660-1-deng.changcheng@zte.com.cn/ Link: https://lore.kernel.org/all/20210824064305.60081-1-deng.changcheng@zte.com.cn/ Link: https://lore.kernel.org/all/20210824062359.59474-1-deng.changcheng@zte.com.cn/ Cc: Rasmus Villemoes Cc: Julia Lawall Cc: Michal Marek Cc: Peter Zijlstra Signed-off-by: Steven Rostedt (Google) Signed-off-by: Julia Lawall Acked-by: Rasmus Villemoes Acked-by: Paul Gortmaker --- scripts/coccinelle/misc/boolreturn.cocci | 59 -------------------------------- 1 file changed, 59 deletions(-) delete mode 100644 scripts/coccinelle/misc/boolreturn.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/misc/boolreturn.cocci b/scripts/coccinelle/misc/boolreturn.cocci deleted file mode 100644 index 29d2bf41e95d..000000000000 --- a/scripts/coccinelle/misc/boolreturn.cocci +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/// Return statements in functions returning bool should use -/// true/false instead of 1/0. -// -// Confidence: High -// Options: --no-includes --include-headers - -virtual patch -virtual report -virtual context - -@r1 depends on patch@ -identifier fn; -typedef bool; -symbol false; -symbol true; -@@ - -bool fn ( ... ) -{ -<... -return -( -- 0 -+ false -| -- 1 -+ true -) - ; -...> -} - -@r2 depends on report || context@ -identifier fn; -position p; -@@ - -bool fn ( ... ) -{ -<... -return -( -* 0@p -| -* 1@p -) - ; -...> -} - - -@script:python depends on report@ -p << r2.p; -fn << r2.fn; -@@ - -msg = "WARNING: return of 0/1 in function '%s' with return type bool" % fn -coccilib.report.print_report(p[0], msg) -- cgit v1.2.3 From bbd5c96850d9de535a83a3a3842dec2169cb31d1 Mon Sep 17 00:00:00 2001 From: Ziyang Xuan Date: Thu, 16 Jun 2022 09:32:53 +0800 Subject: scripts/coccinelle/free: add NULL test before dev_{put, hold} functions Since commit b37a46683739 ("netdevice: add the case if dev is NULL"), NULL check before dev_{put, hold} functions is not needed. Signed-off-by: Ziyang Xuan Signed-off-by: Julia Lawall --- scripts/coccinelle/free/ifnulldev_put.cocci | 54 +++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 scripts/coccinelle/free/ifnulldev_put.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/free/ifnulldev_put.cocci b/scripts/coccinelle/free/ifnulldev_put.cocci new file mode 100644 index 000000000000..7ff36e6212ba --- /dev/null +++ b/scripts/coccinelle/free/ifnulldev_put.cocci @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// Since commit b37a46683739 ("netdevice: add the case if dev is NULL"), +/// NULL check before dev_{put, hold} functions is not needed. +/// +/// Based on ifnullfree.cocci by Fabian Frederick. +/// +// Copyright: (C) 2022 Ziyang Xuan. +// Comments: - +// Options: --no-includes --include-headers + +virtual patch +virtual org +virtual report +virtual context + +@r2 depends on patch@ +expression E; +@@ +- if (E != NULL) +( + __dev_put(E); +| + dev_put(E); +| + dev_put_track(E, ...); +| + __dev_hold(E); +| + dev_hold(E); +| + dev_hold_track(E, ...); +) + +@r depends on context || report || org @ +expression E; +position p; +@@ + +* if (E != NULL) +* \(__dev_put@p\|dev_put@p\|dev_put_track@p\|__dev_hold@p\|dev_hold@p\| +* dev_hold_track@p\)(E, ...); + +@script:python depends on org@ +p << r.p; +@@ + +cocci.print_main("NULL check before dev_{put, hold} functions is not needed", p) + +@script:python depends on report@ +p << r.p; +@@ + +msg = "WARNING: NULL check before dev_{put, hold} functions is not needed." +coccilib.report.print_report(p[0], msg) -- cgit v1.2.3 From b62eb2731e17e83c32e1a6089b4463da1a75e66e Mon Sep 17 00:00:00 2001 From: Nikolay Borisov Date: Fri, 1 Jul 2022 14:35:12 +0300 Subject: scripts/bloat-o-meter: switch argument parsing to using argparse This will facilitate further extension to the arguments the script takes. As an added benefit it also produces saner usage output, where mutual exclusivity of the c|d|t parameters is clearly visible: ./scripts/bloat-o-meter -h usage: bloat-o-meter [-h] [-c | -d | -t] file1 file2 Simple script used to compare the symbol sizes of 2 object files positional arguments: file1 First file to compare file2 Second file to compare optional arguments: -h, --help show this help message and exit -c categorize output based on symbol type -d Show delta of Data Section -t Show delta of text Section Link: https://lkml.kernel.org/r/20220701113513.1938008-1-nborisov@suse.com Signed-off-by: Nikolay Borisov Signed-off-by: Andrew Morton --- scripts/bloat-o-meter | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'scripts') diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter index 4dd6a804ce41..2a360118710e 100755 --- a/scripts/bloat-o-meter +++ b/scripts/bloat-o-meter @@ -7,18 +7,20 @@ # This software may be used and distributed according to the terms # of the GNU General Public License, incorporated herein by reference. -import sys, os, re +import sys, os, re, argparse from signal import signal, SIGPIPE, SIG_DFL signal(SIGPIPE, SIG_DFL) -if len(sys.argv) < 3: - sys.stderr.write("usage: %s [option] file1 file2\n" % sys.argv[0]) - sys.stderr.write("The options are:\n") - sys.stderr.write("-c categorize output based on symbol type\n") - sys.stderr.write("-d Show delta of Data Section\n") - sys.stderr.write("-t Show delta of text Section\n") - sys.exit(-1) +parser = argparse.ArgumentParser(description="Simple script used to compare the symbol sizes of 2 object files") +group = parser.add_mutually_exclusive_group() +group.add_argument('-c', help='categorize output based on symbol type', action='store_true') +group.add_argument('-d', help='Show delta of Data Section', action='store_true') +group.add_argument('-t', help='Show delta of text Section', action='store_true') +parser.add_argument('file1', help='First file to compare') +parser.add_argument('file2', help='Second file to compare') + +args = parser.parse_args() re_NUMBER = re.compile(r'\.[0-9]+') @@ -77,9 +79,9 @@ def calc(oldfile, newfile, format): delta.reverse() return grow, shrink, add, remove, up, down, delta, old, new, otot, ntot -def print_result(symboltype, symbolformat, argc): +def print_result(symboltype, symbolformat): grow, shrink, add, remove, up, down, delta, old, new, otot, ntot = \ - calc(sys.argv[argc - 1], sys.argv[argc], symbolformat) + calc(args.file1, args.file2, symbolformat) print("add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \ (add, remove, grow, shrink, up, -down, up-down)) @@ -93,13 +95,13 @@ def print_result(symboltype, symbolformat, argc): percent = 0 print("Total: Before=%d, After=%d, chg %+.2f%%" % (otot, ntot, percent)) -if sys.argv[1] == "-c": - print_result("Function", "tT", 3) - print_result("Data", "dDbB", 3) - print_result("RO Data", "rR", 3) -elif sys.argv[1] == "-d": - print_result("Data", "dDbBrR", 3) -elif sys.argv[1] == "-t": - print_result("Function", "tT", 3) +if args.c: + print_result("Function", "tT") + print_result("Data", "dDbB") + print_result("RO Data", "rR") +elif args.d: + print_result("Data", "dDbBrR") +elif args.t: + print_result("Function", "tT") else: - print_result("Function", "tTdDbBrR", 2) + print_result("Function", "tTdDbBrR") -- cgit v1.2.3 From 8b5db6679807fd0ab1154375ea6e5aa6b11c4350 Mon Sep 17 00:00:00 2001 From: Nikolay Borisov Date: Fri, 1 Jul 2022 14:35:13 +0300 Subject: scripts/bloat-o-meter: add -p argument When doing cross platform development on a machine sometimes it might be useful to invoke bloat-o-meter for files which haven't been build with the native toolchain. In cases when the host nm doesn't support the target one then a toolchain-specific nm could be used. Add this ability by adding the -p allowing invocations as: ./scripts/bloat-o-meter -p riscv64-unknown-linux-gnu- file1.o file2.o Link: https://lkml.kernel.org/r/20220701113513.1938008-2-nborisov@suse.com Signed-off-by: Nikolay Borisov Signed-off-by: Andrew Morton --- scripts/bloat-o-meter | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter index 2a360118710e..f9553f60a14a 100755 --- a/scripts/bloat-o-meter +++ b/scripts/bloat-o-meter @@ -17,6 +17,7 @@ group = parser.add_mutually_exclusive_group() group.add_argument('-c', help='categorize output based on symbol type', action='store_true') group.add_argument('-d', help='Show delta of Data Section', action='store_true') group.add_argument('-t', help='Show delta of text Section', action='store_true') +parser.add_argument('-p', dest='prefix', help='Arch prefix for the tool being used. Useful in cross build scenarios') parser.add_argument('file1', help='First file to compare') parser.add_argument('file2', help='Second file to compare') @@ -26,7 +27,11 @@ re_NUMBER = re.compile(r'\.[0-9]+') def getsizes(file, format): sym = {} - with os.popen("nm --size-sort " + file) as f: + nm = "nm" + if args.prefix: + nm = "{}nm".format(args.prefix) + + with os.popen("{} --size-sort {}".format(nm, file)) as f: for line in f: if line.startswith("\n") or ":" in line: continue -- cgit v1.2.3 From e3c8d33e0d62175c31ca7ab7ab01b18f0b6318d3 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 19 Jul 2022 14:28:31 +0200 Subject: scripts/gdb: fix 'lx-dmesg' on 32 bits arch The type atomic_long_t can have size 4 or 8 bytes, depending on CONFIG_64BIT; it's only content, the field 'counter', is either an int or a s64 value. Current code incorrectly uses the fixed size utils.read_u64() to read the field 'counter' inside atomic_long_t. On 32 bits architectures reading the last element 'tail_id' of the struct prb_desc_ring: struct prb_desc_ring { ... atomic_long_t tail_id; }; causes the utils.read_u64() to access outside the boundary of the struct and the gdb command 'lx-dmesg' exits with error: Python Exception : index out of range Error occurred in Python: index out of range Query the really used atomic_long_t counter type size. Link: https://lore.kernel.org/r/20220617143758.137307-1-antonio.borneo@foss.st.com Fixes: e60768311af8 ("scripts/gdb: update for lockless printk ringbuffer") Signed-off-by: Antonio Borneo [pmladek@suse.com: Query the really used atomic_long_t counter type size] Tested-by: Antonio Borneo Reviewed-by: John Ogness Signed-off-by: Petr Mladek Link: https://lore.kernel.org/r/20220719122831.19890-1-pmladek@suse.com --- scripts/gdb/linux/dmesg.py | 9 +++------ scripts/gdb/linux/utils.py | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py index d5983cf3db7d..c771831eb077 100644 --- a/scripts/gdb/linux/dmesg.py +++ b/scripts/gdb/linux/dmesg.py @@ -22,7 +22,6 @@ prb_desc_type = utils.CachedType("struct prb_desc") prb_desc_ring_type = utils.CachedType("struct prb_desc_ring") prb_data_ring_type = utils.CachedType("struct prb_data_ring") printk_ringbuffer_type = utils.CachedType("struct printk_ringbuffer") -atomic_long_type = utils.CachedType("atomic_long_t") class LxDmesg(gdb.Command): """Print Linux kernel log buffer.""" @@ -68,8 +67,6 @@ class LxDmesg(gdb.Command): off = prb_data_ring_type.get_type()['data'].bitpos // 8 text_data_addr = utils.read_ulong(text_data_ring, off) - counter_off = atomic_long_type.get_type()['counter'].bitpos // 8 - sv_off = prb_desc_type.get_type()['state_var'].bitpos // 8 off = prb_desc_type.get_type()['text_blk_lpos'].bitpos // 8 @@ -89,9 +86,9 @@ class LxDmesg(gdb.Command): # read in tail and head descriptor ids off = prb_desc_ring_type.get_type()['tail_id'].bitpos // 8 - tail_id = utils.read_u64(desc_ring, off + counter_off) + tail_id = utils.read_atomic_long(desc_ring, off) off = prb_desc_ring_type.get_type()['head_id'].bitpos // 8 - head_id = utils.read_u64(desc_ring, off + counter_off) + head_id = utils.read_atomic_long(desc_ring, off) did = tail_id while True: @@ -102,7 +99,7 @@ class LxDmesg(gdb.Command): desc = utils.read_memoryview(inf, desc_addr + desc_off, desc_sz).tobytes() # skip non-committed record - state = 3 & (utils.read_u64(desc, sv_off + counter_off) >> desc_flags_shift) + state = 3 & (utils.read_atomic_long(desc, sv_off) >> desc_flags_shift) if state != desc_committed and state != desc_finalized: if did == head_id: break diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py index ff7c1799d588..1553f68716cc 100644 --- a/scripts/gdb/linux/utils.py +++ b/scripts/gdb/linux/utils.py @@ -35,13 +35,12 @@ class CachedType: long_type = CachedType("long") - +atomic_long_type = CachedType("atomic_long_t") def get_long_type(): global long_type return long_type.get_type() - def offset_of(typeobj, field): element = gdb.Value(0).cast(typeobj) return int(str(element[field].address).split()[0], 16) @@ -129,6 +128,17 @@ def read_ulong(buffer, offset): else: return read_u32(buffer, offset) +atomic_long_counter_offset = atomic_long_type.get_type()['counter'].bitpos +atomic_long_counter_sizeof = atomic_long_type.get_type()['counter'].type.sizeof + +def read_atomic_long(buffer, offset): + global atomic_long_counter_offset + global atomic_long_counter_sizeof + + if atomic_long_counter_sizeof == 8: + return read_u64(buffer, offset + atomic_long_counter_offset) + else: + return read_u32(buffer, offset + atomic_long_counter_offset) target_arch = None -- cgit v1.2.3 From 23a67619bc7e12e1b3776802f16084530b357a5d Mon Sep 17 00:00:00 2001 From: Khalid Masum Date: Thu, 21 Jul 2022 15:30:42 +0600 Subject: scripts/gdb: Fix gdb 'lx-symbols' command Currently the command 'lx-symbols' in gdb exits with the error`Function "do_init_module" not defined in "kernel/module.c"`. This occurs because the file kernel/module.c was moved to kernel/module/main.c. Fix this breakage by changing the path to "kernel/module/main.c" in LoadModuleBreakpoint. Signed-off-by: Khalid Masum Acked-by: Luis Chamberlain Fixes: cfc1d277891e ("module: Move all into module/") Reviewed-by: Douglas Anderson Signed-off-by: Linus Torvalds --- scripts/gdb/linux/symbols.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py index 46f7542db08c..dc07b6d12e30 100644 --- a/scripts/gdb/linux/symbols.py +++ b/scripts/gdb/linux/symbols.py @@ -180,7 +180,7 @@ lx-symbols command.""" self.breakpoint.delete() self.breakpoint = None self.breakpoint = LoadModuleBreakpoint( - "kernel/module.c:do_init_module", self) + "kernel/module/main.c:do_init_module", self) else: gdb.write("Note: symbol update on module loading not supported " "with this gdb version\n") -- cgit v1.2.3 From 5cb62b7598f2413f54650d5124d7863e23f82a44 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Thu, 21 Jul 2022 13:08:22 +0200 Subject: bpf, docs: Use SPDX license identifier in bpf_doc.py The Linux man-pages project now uses SPDX tags, instead of the full license text. Signed-off-by: Alejandro Colomar Signed-off-by: Daniel Borkmann Link: https://www.kernel.org/doc/man-pages/licenses.html Link: https://spdx.org/licenses/Linux-man-pages-copyleft.html Link: https://lore.kernel.org/bpf/20220721110821.8240-1-alx.manpages@gmail.com --- scripts/bpf_doc.py | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) (limited to 'scripts') diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index a0ec321469bd..dfb260de17a8 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -333,27 +333,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. .. -.. %%%LICENSE_START(VERBATIM) -.. Permission is granted to make and distribute verbatim copies of this -.. manual provided the copyright notice and this permission notice are -.. preserved on all copies. -.. -.. Permission is granted to copy and distribute modified versions of this -.. manual under the conditions for verbatim copying, provided that the -.. entire resulting derived work is distributed under the terms of a -.. permission notice identical to this one. -.. -.. Since the Linux kernel and libraries are constantly changing, this -.. manual page may be incorrect or out-of-date. The author(s) assume no -.. responsibility for errors or omissions, or for damages resulting from -.. the use of the information contained herein. The author(s) may not -.. have taken the same level of care in the production of this manual, -.. which is licensed free of charge, as they might when working -.. professionally. -.. -.. Formatted or processed versions of this manual, if unaccompanied by -.. the source, must acknowledge the copyright and authors of this work. -.. %%%LICENSE_END +.. 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 v1.2.3 From 2d17bd24b0169d3fdbf003dfd55af600e9a30553 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 25 Jul 2022 11:08:12 +0900 Subject: x86/purgatory: Omit use of bin2c The .incbin assembler directive is much faster than bin2c + $(CC). Do similar refactoring as in 4c0f032d4963 ("s390/purgatory: Omit use of bin2c"). Please note the .quad directive matches to size_t in C (both 8 byte) because the purgatory is compiled only for the 64-bit kernel. (KEXEC_FILE depends on X86_64). Signed-off-by: Masahiro Yamada Signed-off-by: Borislav Petkov Link: https://lore.kernel.org/r/20220725020812.622255-2-masahiroy@kernel.org --- arch/x86/.gitignore | 2 -- arch/x86/Kconfig | 1 - arch/x86/purgatory/Makefile | 8 +------- arch/x86/purgatory/kexec-purgatory.S | 14 ++++++++++++++ scripts/remove-stale-files | 2 ++ 5 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 arch/x86/purgatory/kexec-purgatory.S (limited to 'scripts') diff --git a/arch/x86/.gitignore b/arch/x86/.gitignore index 677111acbaa3..f2e1d6c347fb 100644 --- a/arch/x86/.gitignore +++ b/arch/x86/.gitignore @@ -3,6 +3,4 @@ boot/compressed/vmlinux tools/test_get_len tools/insn_sanity tools/insn_decoder_test -purgatory/kexec-purgatory.c purgatory/purgatory.ro - diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 076adde7ead9..901cb59d3a90 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2032,7 +2032,6 @@ config KEXEC config KEXEC_FILE bool "kexec file based system call" select KEXEC_CORE - select BUILD_BIN2C depends on X86_64 depends on CRYPTO=y depends on CRYPTO_SHA256=y diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile index 248b009c4061..31c634a22818 100644 --- a/arch/x86/purgatory/Makefile +++ b/arch/x86/purgatory/Makefile @@ -73,12 +73,6 @@ $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE $(obj)/purgatory.chk: $(obj)/purgatory.ro FORCE $(call if_changed,ld) -targets += kexec-purgatory.c - -quiet_cmd_bin2c = BIN2C $@ - cmd_bin2c = $(objtree)/scripts/bin2c kexec_purgatory < $< > $@ - -$(obj)/kexec-purgatory.c: $(obj)/purgatory.ro $(obj)/purgatory.chk FORCE - $(call if_changed,bin2c) +$(obj)/kexec-purgatory.o: $(obj)/purgatory.ro $(obj)/purgatory.chk obj-y += kexec-purgatory.o diff --git a/arch/x86/purgatory/kexec-purgatory.S b/arch/x86/purgatory/kexec-purgatory.S new file mode 100644 index 000000000000..8530fe93b718 --- /dev/null +++ b/arch/x86/purgatory/kexec-purgatory.S @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + + .section .rodata, "a" + + .align 8 +kexec_purgatory: + .globl kexec_purgatory + .incbin "arch/x86/purgatory/purgatory.ro" +.Lkexec_purgatory_end: + + .align 8 +kexec_purgatory_size: + .globl kexec_purgatory_size + .quad .Lkexec_purgatory_end - kexec_purgatory diff --git a/scripts/remove-stale-files b/scripts/remove-stale-files index 7adab4618035..379e86c71bed 100755 --- a/scripts/remove-stale-files +++ b/scripts/remove-stale-files @@ -41,3 +41,5 @@ if [ -n "${building_out_of_srctree}" ]; then fi rm -f scripts/extract-cert + +rm -f arch/x86/purgatory/kexec-purgatory.c -- cgit v1.2.3 From 9257971377e2fe6e82f41f688651a82a2f160a88 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 25 Jul 2022 10:56:19 +0900 Subject: powerpc/purgatory: Omit use of bin2c The .incbin assembler directive is much faster than bin2c + $(CC). Do similar refactoring as in commit 4c0f032d4963 ("s390/purgatory: Omit use of bin2c"). Please note the .quad directive matches to size_t in C (both 8 byte) because the purgatory is compiled only for the 64-bit kernel. (KEXEC_FILE depends on PPC64). Signed-off-by: Masahiro Yamada Reviewed-by: Segher Boessenkool Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220725015619.618070-1-masahiroy@kernel.org --- arch/powerpc/Kconfig | 1 - arch/powerpc/purgatory/.gitignore | 1 - arch/powerpc/purgatory/Makefile | 8 ++------ arch/powerpc/purgatory/kexec-purgatory.S | 14 ++++++++++++++ scripts/remove-stale-files | 2 ++ 5 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 arch/powerpc/purgatory/kexec-purgatory.S (limited to 'scripts') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 26331cdd3642..c76d499e2aa3 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -553,7 +553,6 @@ config KEXEC_FILE bool "kexec file based system call" select KEXEC_CORE select HAVE_IMA_KEXEC if IMA - select BUILD_BIN2C select KEXEC_ELF depends on PPC64 depends on CRYPTO=y diff --git a/arch/powerpc/purgatory/.gitignore b/arch/powerpc/purgatory/.gitignore index b8dc6ff34254..5e40575c1f2b 100644 --- a/arch/powerpc/purgatory/.gitignore +++ b/arch/powerpc/purgatory/.gitignore @@ -1,3 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -kexec-purgatory.c purgatory.ro diff --git a/arch/powerpc/purgatory/Makefile b/arch/powerpc/purgatory/Makefile index 348f59581052..a81d155b89ae 100644 --- a/arch/powerpc/purgatory/Makefile +++ b/arch/powerpc/purgatory/Makefile @@ -2,17 +2,13 @@ KASAN_SANITIZE := n -targets += trampoline_$(BITS).o purgatory.ro kexec-purgatory.c +targets += trampoline_$(BITS).o purgatory.ro LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined $(obj)/purgatory.ro: $(obj)/trampoline_$(BITS).o FORCE $(call if_changed,ld) -quiet_cmd_bin2c = BIN2C $@ - cmd_bin2c = $(objtree)/scripts/bin2c kexec_purgatory < $< > $@ - -$(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE - $(call if_changed,bin2c) +$(obj)/kexec-purgatory.o: $(obj)/purgatory.ro obj-y += kexec-purgatory.o diff --git a/arch/powerpc/purgatory/kexec-purgatory.S b/arch/powerpc/purgatory/kexec-purgatory.S new file mode 100644 index 000000000000..f494fd5a0526 --- /dev/null +++ b/arch/powerpc/purgatory/kexec-purgatory.S @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + + .section .rodata, "a" + + .align 8 +kexec_purgatory: + .globl kexec_purgatory + .incbin "arch/powerpc/purgatory/purgatory.ro" +.Lkexec_purgatory_end: + + .align 8 +kexec_purgatory_size: + .globl kexec_purgatory_size + .quad .Lkexec_purgatory_end - kexec_purgatory diff --git a/scripts/remove-stale-files b/scripts/remove-stale-files index 7adab4618035..5a7543469698 100755 --- a/scripts/remove-stale-files +++ b/scripts/remove-stale-files @@ -20,6 +20,8 @@ set -e # yard. Stale files stay in this file for a while (for some release cycles?), # then will be really dead and removed from the code base entirely. +rm -f arch/powerpc/purgatory/kexec-purgatory.c + # These were previously generated source files. When you are building the kernel # with O=, make sure to remove the stale files in the output tree. Otherwise, # the build system wrongly compiles the stale ones. -- cgit v1.2.3 From 9008a676662a77ab98727d05bdffa0e3c38cba53 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 12 Jun 2022 02:22:32 +0900 Subject: certs: move scripts/check-blacklist-hashes.awk to certs/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This script is only used in certs/Makefile, so certs/ is a better home for it. Signed-off-by: Masahiro Yamada Reviewed-by: Mickaël Salaün Reviewed-by: Jarkko Sakkinen --- MAINTAINERS | 1 - certs/Makefile | 2 +- certs/check-blacklist-hashes.awk | 37 +++++++++++++++++++++++++++++++++++++ scripts/check-blacklist-hashes.awk | 37 ------------------------------------- 4 files changed, 38 insertions(+), 39 deletions(-) create mode 100755 certs/check-blacklist-hashes.awk delete mode 100755 scripts/check-blacklist-hashes.awk (limited to 'scripts') diff --git a/MAINTAINERS b/MAINTAINERS index f679152bdbad..cd569d35d55c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4718,7 +4718,6 @@ L: keyrings@vger.kernel.org S: Maintained F: Documentation/admin-guide/module-signing.rst F: certs/ -F: scripts/check-blacklist-hashes.awk F: scripts/sign-file.c F: tools/certs/ diff --git a/certs/Makefile b/certs/Makefile index 88a73b28d254..854647dbce05 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -13,7 +13,7 @@ CFLAGS_blacklist_hashes.o := -I $(obj) quiet_cmd_check_and_copy_blacklist_hash_list = GEN $@ cmd_check_and_copy_blacklist_hash_list = \ - $(AWK) -f $(srctree)/scripts/check-blacklist-hashes.awk $(CONFIG_SYSTEM_BLACKLIST_HASH_LIST) >&2; \ + $(AWK) -f $(srctree)/$(src)/check-blacklist-hashes.awk $(CONFIG_SYSTEM_BLACKLIST_HASH_LIST) >&2; \ cat $(CONFIG_SYSTEM_BLACKLIST_HASH_LIST) > $@ $(obj)/blacklist_hash_list: $(CONFIG_SYSTEM_BLACKLIST_HASH_LIST) FORCE diff --git a/certs/check-blacklist-hashes.awk b/certs/check-blacklist-hashes.awk new file mode 100755 index 000000000000..107c1d3204d4 --- /dev/null +++ b/certs/check-blacklist-hashes.awk @@ -0,0 +1,37 @@ +#!/usr/bin/awk -f +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright © 2020, Microsoft Corporation. All rights reserved. +# +# Author: Mickaël Salaün +# +# Check that a CONFIG_SYSTEM_BLACKLIST_HASH_LIST file contains a valid array of +# hash strings. Such string must start with a prefix ("tbs" or "bin"), then a +# colon (":"), and finally an even number of hexadecimal lowercase characters +# (up to 128). + +BEGIN { + RS = "," +} +{ + if (!match($0, "^[ \t\n\r]*\"([^\"]*)\"[ \t\n\r]*$", part1)) { + print "Not a string (item " NR "):", $0; + exit 1; + } + if (!match(part1[1], "^(tbs|bin):(.*)$", part2)) { + print "Unknown prefix (item " NR "):", part1[1]; + exit 1; + } + if (!match(part2[2], "^([0-9a-f]+)$", part3)) { + print "Not a lowercase hexadecimal string (item " NR "):", part2[2]; + exit 1; + } + if (length(part3[1]) > 128) { + print "Hash string too long (item " NR "):", part3[1]; + exit 1; + } + if (length(part3[1]) % 2 == 1) { + print "Not an even number of hexadecimal characters (item " NR "):", part3[1]; + exit 1; + } +} diff --git a/scripts/check-blacklist-hashes.awk b/scripts/check-blacklist-hashes.awk deleted file mode 100755 index 107c1d3204d4..000000000000 --- a/scripts/check-blacklist-hashes.awk +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/awk -f -# SPDX-License-Identifier: GPL-2.0 -# -# Copyright © 2020, Microsoft Corporation. All rights reserved. -# -# Author: Mickaël Salaün -# -# Check that a CONFIG_SYSTEM_BLACKLIST_HASH_LIST file contains a valid array of -# hash strings. Such string must start with a prefix ("tbs" or "bin"), then a -# colon (":"), and finally an even number of hexadecimal lowercase characters -# (up to 128). - -BEGIN { - RS = "," -} -{ - if (!match($0, "^[ \t\n\r]*\"([^\"]*)\"[ \t\n\r]*$", part1)) { - print "Not a string (item " NR "):", $0; - exit 1; - } - if (!match(part1[1], "^(tbs|bin):(.*)$", part2)) { - print "Unknown prefix (item " NR "):", part1[1]; - exit 1; - } - if (!match(part2[2], "^([0-9a-f]+)$", part3)) { - print "Not a lowercase hexadecimal string (item " NR "):", part2[2]; - exit 1; - } - if (length(part3[1]) > 128) { - print "Hash string too long (item " NR "):", part3[1]; - exit 1; - } - if (length(part3[1]) % 2 == 1) { - print "Not an even number of hexadecimal characters (item " NR "):", part3[1]; - exit 1; - } -} -- cgit v1.2.3 From 5439d4d4dcee548b1ad984c293225c1668045ad2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jun 2022 14:51:49 +0900 Subject: kbuild: remove sed command from cmd_ar_builtin Replace a pipeline of echo and sed with printf to decrease process forks. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/Makefile.build | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index cac070aee791..784f46d41959 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -358,9 +358,8 @@ $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; quiet_cmd_ar_builtin = AR $@ cmd_ar_builtin = rm -f $@; \ - echo $(patsubst $(obj)/%,%,$(real-prereqs)) | \ - sed -E 's:([^ ]+):$(obj)/\1:g' | \ - xargs $(AR) cDPrST $@ + $(if $(real-prereqs), printf "$(obj)/%s " $(patsubst $(obj)/%,%,$(real-prereqs)) | xargs) \ + $(AR) cDPrST $@ $(obj)/built-in.a: $(real-obj-y) FORCE $(call if_changed,ar_builtin) -- cgit v1.2.3 From 028062ec222d6ed0235bbf9612ba8a05efc9e633 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 11 Jul 2022 13:49:41 +0900 Subject: Revert "scripts/mod/modpost.c: permit '.cranges' secton for sh64 architecture." This reverts commit 4d10c223baab8be8f717df3625cfece5be26dead. Commit 37744feebc08 ("sh: remove sh5 support") removed the sh64 support entirely. Note: .cranges was only used for sh64 ever. Commit 211dc24b8744 ("Remove sh5 and sh64 support") in binutils-gdb already removed the relevant code. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 620dc8c4c814..e15227ee58fc 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -742,7 +742,6 @@ static const char *const section_white_list[] = { ".comment*", ".debug*", - ".cranges", /* sh64 */ ".zdebug*", /* Compressed debug sections. */ ".GCC.command.line", /* record-gcc-switches */ ".mdebug*", /* alpha, score, mips etc. */ -- cgit v1.2.3 From aac289653fa5adf9e9985e4912c1d24a3e8cbab2 Mon Sep 17 00:00:00 2001 From: Ondrej Mosnacek Date: Mon, 11 Jul 2022 14:09:23 +0200 Subject: kbuild: dummy-tools: avoid tmpdir leak in dummy gcc When passed -print-file-name=plugin, the dummy gcc script creates a temporary directory that is never cleaned up. To avoid cluttering $TMPDIR, instead use a static directory included in the source tree. Fixes: 76426e238834 ("kbuild: add dummy toolchains to enable all cc-option etc. in Kconfig") Signed-off-by: Ondrej Mosnacek Signed-off-by: Masahiro Yamada --- scripts/dummy-tools/dummy-plugin-dir/include/plugin-version.h | 0 scripts/dummy-tools/gcc | 8 ++------ 2 files changed, 2 insertions(+), 6 deletions(-) create mode 100644 scripts/dummy-tools/dummy-plugin-dir/include/plugin-version.h (limited to 'scripts') diff --git a/scripts/dummy-tools/dummy-plugin-dir/include/plugin-version.h b/scripts/dummy-tools/dummy-plugin-dir/include/plugin-version.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/scripts/dummy-tools/gcc b/scripts/dummy-tools/gcc index b2483149bbe5..7db825843435 100755 --- a/scripts/dummy-tools/gcc +++ b/scripts/dummy-tools/gcc @@ -96,12 +96,8 @@ fi # To set GCC_PLUGINS if arg_contain -print-file-name=plugin "$@"; then - plugin_dir=$(mktemp -d) - - mkdir -p $plugin_dir/include - touch $plugin_dir/include/plugin-version.h - - echo $plugin_dir + # Use $0 to find the in-tree dummy directory + echo "$(dirname "$(readlink -f "$0")")/dummy-plugin-dir" exit 0 fi -- cgit v1.2.3 From 3089b2be0cce14bd026a1018b8f6e5aed8244545 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 14 Jul 2022 14:02:40 +0900 Subject: kbuild: rpm-pkg: fix build error when _arch is undefined Cross-building (bin)rpm-pkg fails on several architectures. For example, 'make ARCH=arm binrpm-pkg' fails like follows: sh ./scripts/package/mkspec prebuilt > ./binkernel.spec rpmbuild --define "_builddir ." --target \ arm -bb ./binkernel.spec Building target platforms: arm Building for target arm warning: line 19: It's not recommended to have unversioned Obsoletes: Obsoletes: kernel-headers Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.0S8t2F + umask 022 + cd . + mkdir -p /home/masahiro/rpmbuild/BUILDROOT/kernel-5.19.0_rc6-19.%{_arch}/boot + make -f ./Makefile image_name + cp arch/arm/boot/zImage /home/masahiro/rpmbuild/BUILDROOT/kernel-5.19.0_rc6-19.%{_arch}/boot/vmlinuz-5.19.0-rc6 + make -f ./Makefile INSTALL_MOD_PATH=/home/masahiro/rpmbuild/BUILDROOT/kernel-5.19.0_rc6-19.%{_arch} modules_install make[3]: *** No rule to make target '/home/masahiro/rpmbuild/BUILDROOT/kernel-5.19.0_rc6-19.arch/arm/crypto/aes-arm-bs.ko{_arch}/lib/modules/5.19.0-rc6/kernel/%', needed by '__modinst'. Stop. make[2]: *** [Makefile:1768: modules_install] Error 2 error: Bad exit status from /var/tmp/rpm-tmp.0S8t2F (%install) By default, 'buildroot' contains %{_arch} (see /usr/lib/rpm/macros). _arch is generally defined in /usr/lib/rpm/platforms/*/macros, where the platform sub-directory is specified by --target= option for cross builds. If the given arch does not exist, %{_arch} is not expanded. In the example above, --target=arm is passed to rpmbuild, but /usr/lib/rpm/platforms/arm-linux/ does not exist. The '%' character in the path confuses GNU make and rpmbuild. The same occurs for such architectures as csky, microblaze, nios2, etc. Define _arch if it has not been defined. Reported-by: Jason Self Signed-off-by: Masahiro Yamada --- scripts/package/mkspec | 3 +++ 1 file changed, 3 insertions(+) (limited to 'scripts') diff --git a/scripts/package/mkspec b/scripts/package/mkspec index 7c477ca7dc98..8fa7c5b8a1a1 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -49,6 +49,9 @@ sed -e '/^DEL/d' -e 's/^\t*//' < Date: Thu, 14 Jul 2022 14:02:41 +0900 Subject: kbuild: rpm-pkg: pass 'linux' to --target option of rpmbuild Presumably, _target_os is defined even if the --target flag does not specify it, but it is better to make it explicit. Signed-off-by: Masahiro Yamada --- scripts/Makefile.package | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.package b/scripts/Makefile.package index 77b612183c08..5017f6b2da80 100644 --- a/scripts/Makefile.package +++ b/scripts/Makefile.package @@ -56,7 +56,7 @@ rpm-pkg: $(MAKE) clean $(CONFIG_SHELL) $(MKSPEC) >$(objtree)/kernel.spec $(call cmd,src_tar,$(KERNELPATH),kernel.spec) - +rpmbuild $(RPMOPTS) --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz \ + +rpmbuild $(RPMOPTS) --target $(UTS_MACHINE)-linux -ta $(KERNELPATH).tar.gz \ --define='_smp_mflags %{nil}' # binrpm-pkg @@ -66,7 +66,7 @@ binrpm-pkg: $(MAKE) -f $(srctree)/Makefile $(CONFIG_SHELL) $(MKSPEC) prebuilt > $(objtree)/binkernel.spec +rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \ - $(UTS_MACHINE) -bb $(objtree)/binkernel.spec + $(UTS_MACHINE)-linux -bb $(objtree)/binkernel.spec PHONY += deb-pkg deb-pkg: -- cgit v1.2.3 From 84850dbbbe60a75b27eb0f272fdbc28cfaae689b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 14 Jul 2022 14:02:43 +0900 Subject: kbuild: error out if $(INSTALL_MOD_PATH) contains % or : If the directory path given to INSTALL_MOD_PATH contains % or :, the module_install fails. % is used in pattern rules, and : as the separator of dependencies. Bail out with a clearer error message. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/Makefile.modinst | 3 +++ 1 file changed, 3 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 16a02e9237d3..a4c987c23750 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -18,6 +18,9 @@ INSTALL_MOD_DIR ?= extra dst := $(MODLIB)/$(INSTALL_MOD_DIR) endif +$(foreach x, % :, $(if $(findstring $x, $(dst)), \ + $(error module installation path cannot contain '$x'))) + suffix-y := suffix-$(CONFIG_MODULE_COMPRESS_GZIP) := .gz suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz -- cgit v1.2.3 From e3b746a384fc2f3b7b4a8c9aad5024130a975c43 Mon Sep 17 00:00:00 2001 From: Nicolas Schier Date: Mon, 18 Jul 2022 08:14:13 +0200 Subject: scripts: headers_install.sh: Update config leak ignore entries Remove two dated config leak ignore entries from scripts/headers_install.sh: arch/alpha/include/uapi/asm/setup.h does no more leak any CONFIG_* symbol to user-space any more since commit 3cb8b1537f8a ("alpha: Move setup.h out of uapi"). Same holds for include/uapi/asm-generic/fcntl.h since commit 306f7cc1e906 ("uapi: always define F_GETLK64/F_SETLK64/F_SETLKW64 in fcntl.h"). Signed-off-by: Nicolas Schier Signed-off-by: Masahiro Yamada --- scripts/headers_install.sh | 2 -- 1 file changed, 2 deletions(-) (limited to 'scripts') diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh index dd554bd436cc..4041881746ad 100755 --- a/scripts/headers_install.sh +++ b/scripts/headers_install.sh @@ -70,7 +70,6 @@ configs=$(sed -e ' # # The format is : in each line. config_leak_ignores=" -arch/alpha/include/uapi/asm/setup.h:CONFIG_ALPHA_LEGACY_START_ADDRESS arch/arc/include/uapi/asm/page.h:CONFIG_ARC_PAGE_SIZE_16K arch/arc/include/uapi/asm/page.h:CONFIG_ARC_PAGE_SIZE_4K arch/arc/include/uapi/asm/swab.h:CONFIG_ARC_HAS_SWAPE @@ -84,7 +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/asm-generic/fcntl.h:CONFIG_64BIT 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 -- cgit v1.2.3 From 10269fd37fc60bda700dd2554ff382446d45771d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 19 Jul 2022 11:35:39 +0900 Subject: kconfig: shorten the temporary directory name for cc-option The cc-option macro creates the temporary directory, .tmp_$$$$. Shell expands '$$' into its process ID. '$$$$' results in repeated PID. In Makefile, '$$$$' is correct (see TMPOUT in scripts/Malefile.compiler) because '$$' is an escape sequence of '$'. Make expands '$$$$' into '$$', then shell expands it into the process ID. This does not apply to Kconfig because Kconfig requires variable references to be enclosed by curly braces, like ${variable}. The '$' that is not followed by '{' loses its effect. Signed-off-by: Masahiro Yamada Tested-by: Nicolas Schier --- scripts/Kconfig.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include index 0496efd6e117..c1f4222d223d 100644 --- a/scripts/Kconfig.include +++ b/scripts/Kconfig.include @@ -25,7 +25,7 @@ failure = $(if-success,$(1),n,y) # $(cc-option,) # Return y if the compiler supports , n otherwise -cc-option = $(success,mkdir .tmp_$$$$; trap "rm -rf .tmp_$$$$" EXIT; $(CC) -Werror $(CLANG_FLAGS) $(1) -c -x c /dev/null -o .tmp_$$$$/tmp.o) +cc-option = $(success,mkdir .tmp_$$; trap "rm -rf .tmp_$$" EXIT; $(CC) -Werror $(CLANG_FLAGS) $(1) -c -x c /dev/null -o .tmp_$$/tmp.o) # $(ld-option,) # Return y if the linker supports , n otherwise -- cgit v1.2.3 From 1fd49a0b5c4330ceefef4de498cec271e240aaf1 Mon Sep 17 00:00:00 2001 From: Wadim Mueller Date: Wed, 13 Jul 2022 21:41:10 +0200 Subject: checkstack: add riscv support for scripts/checkstack.pl scripts/checkstack.pl lacks support for the riscv architecture. Add support to detect "addi sp,sp,-FRAME_SIZE" stack frame generation instruction Signed-off-by: Wadim Mueller Signed-off-by: Masahiro Yamada --- scripts/checkstack.pl | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'scripts') diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index d2c38584ece6..d48dfed6d3db 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl @@ -16,6 +16,7 @@ # AArch64, PARISC ports by Kyle McMartin # sparc port by Martin Habets # ppc64le port by Breno Leitao +# riscv port by Wadim Mueller # # Usage: # objdump -d vmlinux | scripts/checkstack.pl [arch] @@ -108,6 +109,9 @@ my (@stack, $re, $dre, $sub, $x, $xs, $funcre, $min_stack); } 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; + } elsif ($arch =~ /^riscv(64)?$/) { + #ffffffff8036e868: c2010113 addi sp,sp,-992 + $re = qr/.*addi.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o; } else { print("wrong or unknown architecture \"$arch\"\n"); exit -- cgit v1.2.3 From 5764f6626f5f334b27e168a33735b3899d08bcd2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Jul 2022 01:52:59 +0900 Subject: modpost: drop executable ELF support Since commit 269a535ca931 ("modpost: generate vmlinux.symvers and reuse it for the second modpost"), modpost only parses relocatable files (ET_REL). Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index e15227ee58fc..75aa10413ad4 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -321,9 +321,6 @@ static void *sym_get_data_by_offset(const struct elf_info *info, { Elf_Shdr *sechdr = &info->sechdrs[secindex]; - if (info->hdr->e_type != ET_REL) - offset -= sechdr->sh_addr; - return (void *)info->hdr + sechdr->sh_offset + offset; } @@ -466,6 +463,10 @@ static int parse_elf(struct elf_info *info, const char *filename) sechdrs = (void *)hdr + hdr->e_shoff; info->sechdrs = sechdrs; + /* modpost only works for relocatable objects */ + if (hdr->e_type != ET_REL) + fatal("%s: not relocatable object.", filename); + /* Check if file offset is correct */ if (hdr->e_shoff > info->size) { fatal("section header offset=%lu in file '%s' is bigger than filesize=%zu\n", @@ -1622,9 +1623,6 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) break; case R_386_PC32: r->r_addend = TO_NATIVE(*location) + 4; - /* For CONFIG_RELOCATABLE=y */ - if (elf->hdr->e_type == ET_EXEC) - r->r_addend += r->r_offset; break; } return 0; -- cgit v1.2.3 From abe864b8e19adf33b48997de8bc1a8f095390ade Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Jul 2022 01:53:00 +0900 Subject: modpost: use sym_get_data() to get module device_table data Use sym_get_data() to replace the long code. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/file2alias.c | 4 +--- scripts/mod/modpost.c | 2 +- scripts/mod/modpost.h | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index cbd6b0f48b4e..80d973144fde 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1571,9 +1571,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, zeros = calloc(1, sym->st_size); symval = zeros; } else { - symval = (void *)info->hdr - + info->sechdrs[get_secindex(info, sym)].sh_offset - + sym->st_value; + symval = sym_get_data(info, sym); } /* First handle the "special" cases */ diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 75aa10413ad4..08411fff3e17 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -324,7 +324,7 @@ static void *sym_get_data_by_offset(const struct elf_info *info, return (void *)info->hdr + sechdr->sh_offset + offset; } -static void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym) +void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym) { return sym_get_data_by_offset(info, get_secindex(info, sym), sym->st_value); diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 044bdfb894b7..4d8a1ae1d1e3 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -187,6 +187,7 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen); /* from modpost.c */ char *read_text_file(const char *filename); char *get_line(char **stringp); +void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym); enum loglevel { LOG_WARN, -- cgit v1.2.3 From 7dea20f2fecbde5df321d6d9d0b7765be6edc28c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 20 Jul 2022 10:37:49 -0700 Subject: kconfig: Qt5: tell the user which packages are required Along with saying "Please install Qt5 ...", tell exactly which parts of Qt5 are needed. This is useful when parts of Qt5 are installed but some of the required pieces are missing, and it eliminates the need for the user to find the shell script and the line in it that provide that information. Signed-off-by: Randy Dunlap Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf-cfg.sh | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/kconfig/qconf-cfg.sh b/scripts/kconfig/qconf-cfg.sh index 9b695e5cd9b3..ad652cb53947 100755 --- a/scripts/kconfig/qconf-cfg.sh +++ b/scripts/kconfig/qconf-cfg.sh @@ -20,5 +20,6 @@ fi echo >&2 "*" echo >&2 "* Could not find Qt5 via ${HOSTPKG_CONFIG}." echo >&2 "* Please install Qt5 and make sure it's in PKG_CONFIG_PATH" +echo >&2 "* You need $PKG" echo >&2 "*" exit 1 -- cgit v1.2.3 From b99695580bfc1f91364023c673681ddb88e375dc Mon Sep 17 00:00:00 2001 From: Aaron Tomlin Date: Tue, 12 Jul 2022 12:02:48 +0100 Subject: scripts/gdb: ensure the absolute path is generated on initial source Post 'make scripts_gdb' a symbolic link to scripts/gdb/vmlinux-gdb.py is created. Currently 'os.path.dirname(__file__)' does not generate the absolute path to scripts/gdb resulting in the following: (gdb) source vmlinux-gdb.py Traceback (most recent call last): File "scripts/gdb/vmlinux-gdb.py", line 25, in import linux.utils ModuleNotFoundError: No module named 'linux' This patch ensures that the absolute path to scripts/gdb in relation to the given file is generated so each module can be located accordingly. Link: https://lkml.kernel.org/r/20220712110248.1404125-1-atomlin@redhat.com Signed-off-by: Aaron Tomlin Reviewed-by: Douglas Anderson Cc: Jan Kiszka Cc: Kieran Bingham Signed-off-by: Andrew Morton --- scripts/gdb/vmlinux-gdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py index 4136dc2c59df..3e8d3669f0ce 100644 --- a/scripts/gdb/vmlinux-gdb.py +++ b/scripts/gdb/vmlinux-gdb.py @@ -13,7 +13,7 @@ import os -sys.path.insert(0, os.path.dirname(__file__) + "/scripts/gdb") +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) + "/scripts/gdb") try: gdb.parse_and_eval("0") -- cgit v1.2.3 From 95522f0b18a059afa5aca036aa454c98beb553b5 Mon Sep 17 00:00:00 2001 From: Slark Xiao Date: Fri, 22 Jul 2022 18:29:07 +0800 Subject: scripts/tracing: Fix typo 'the the' in comment Replace 'the the' with 'the' in the comment. Link: https://lkml.kernel.org/r/20220722102907.81949-1-slark_xiao@163.com Signed-off-by: Slark Xiao Signed-off-by: Steven Rostedt (Google) --- scripts/tracing/draw_functrace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/tracing/draw_functrace.py b/scripts/tracing/draw_functrace.py index 7011fbe003ff..438516bdfb3c 100755 --- a/scripts/tracing/draw_functrace.py +++ b/scripts/tracing/draw_functrace.py @@ -8,7 +8,7 @@ This script parses a trace provided by the function tracer in kernel/trace/trace_functions.c The resulted trace is processed into a tree to produce a more human view of the call stack by drawing textual but hierarchical tree of -calls. Only the functions's names and the the call time are provided. +calls. Only the functions's names and the call time are provided. Usage: Be sure that you have CONFIG_FUNCTION_TRACER -- cgit v1.2.3 From b6a5068854cfe372da7dee3224dcf023ed5b00cb Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 21 Jul 2022 11:01:23 -0700 Subject: scripts/faddr2line: Fix vmlinux detection on arm64 Since commit dcea997beed6 ("faddr2line: Fix overlapping text section failures, the sequel"), faddr2line is completely broken on arm64. For some reason, on arm64, the vmlinux ELF object file type is ET_DYN rather than ET_EXEC. Check for both when determining whether the object is vmlinux. Modules and vmlinux.o have type ET_REL on all arches. Fixes: dcea997beed6 ("faddr2line: Fix overlapping text section failures, the sequel") Reported-by: John Garry Signed-off-by: Josh Poimboeuf Signed-off-by: Ingo Molnar Tested-by: John Garry Link: https://lore.kernel.org/r/dad1999737471b06d6188ce4cdb11329aa41682c.1658426357.git.jpoimboe@kernel.org --- scripts/faddr2line | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/faddr2line b/scripts/faddr2line index 94ed98dd899f..57099687e5e1 100755 --- a/scripts/faddr2line +++ b/scripts/faddr2line @@ -112,7 +112,9 @@ __faddr2line() { # section offsets. local file_type=$(${READELF} --file-header $objfile | ${AWK} '$1 == "Type:" { print $2; exit }') - [[ $file_type = "EXEC" ]] && is_vmlinux=1 + if [[ $file_type = "EXEC" ]] || [[ $file_type == "DYN" ]]; then + is_vmlinux=1 + fi # Go through each of the object's symbols which match the func name. # In rare cases there might be duplicates, in which case we print all -- cgit v1.2.3 From a41a2e2e34a907bd8979a53c58f44287630616e8 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 21 Jul 2022 11:01:24 -0700 Subject: scripts/faddr2line: Add CONFIG_DEBUG_INFO check Otherwise without DWARF it spits out gibberish and gives no indication of what the problem is. Suggested-by: John Garry Signed-off-by: Josh Poimboeuf Signed-off-by: Ingo Molnar Tested-by: John Garry Link: https://lore.kernel.org/r/ffa7734c929445caa374bf9e68078300174f09b4.1658426357.git.jpoimboe@kernel.org --- scripts/faddr2line | 3 +++ 1 file changed, 3 insertions(+) (limited to 'scripts') diff --git a/scripts/faddr2line b/scripts/faddr2line index 57099687e5e1..5514c23f45c2 100755 --- a/scripts/faddr2line +++ b/scripts/faddr2line @@ -61,6 +61,7 @@ die() { READELF="${CROSS_COMPILE:-}readelf" ADDR2LINE="${CROSS_COMPILE:-}addr2line" AWK="awk" +GREP="grep" command -v ${AWK} >/dev/null 2>&1 || die "${AWK} isn't installed" command -v ${READELF} >/dev/null 2>&1 || die "${READELF} isn't installed" @@ -271,6 +272,8 @@ LIST=0 [[ ! -f $objfile ]] && die "can't find objfile $objfile" shift +${READELF} --section-headers --wide $objfile | ${GREP} -q '\.debug_info' || die "CONFIG_DEBUG_INFO not enabled" + DIR_PREFIX=supercalifragilisticexpialidocious find_dir_prefix $objfile -- cgit v1.2.3 From 258fafcd0683d9ccfa524129d489948ab3ddc24c Mon Sep 17 00:00:00 2001 From: Justin Stitt Date: Wed, 20 Jul 2022 16:23:32 -0700 Subject: Makefile.extrawarn: re-enable -Wformat for clang There's been an ongoing mission to re-enable the -Wformat warning for Clang. A previous attempt at enabling the warning showed that there were many instances of this warning throughout the codebase. The sheer amount of these warnings really polluted builds and thus -Wno-format was added to _temporarily_ toggle them off. After many patches the warning has largely been eradicated for x86, x86_64, arm, and arm64 on a variety of configs. The time to enable the warning has never been better as it seems for the first time we are ahead of them and can now solve them as they appear rather than tackling from a backlog. As to the root cause of this large backlog of warnings, Clang seems to pickup on some more nuanced cases of format warnings caused by implicit integer conversion as well as default argument promotions from printf-like functions. Link: https://github.com/ClangBuiltLinux/linux/issues/378 Suggested-by: Nick Desaulniers Signed-off-by: Justin Stitt Signed-off-by: Masahiro Yamada --- scripts/Makefile.extrawarn | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index f5f0d6f09053..9bbaf7112a9b 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -47,7 +47,6 @@ else ifdef CONFIG_CC_IS_CLANG KBUILD_CFLAGS += -Wno-initializer-overrides -KBUILD_CFLAGS += -Wno-format KBUILD_CFLAGS += -Wno-sign-compare KBUILD_CFLAGS += -Wno-format-zero-length KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast) -- cgit v1.2.3 From 7193cda917ffbf5a473cbf3d26ba6787b6b02a84 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 27 Jul 2022 01:52:04 +0900 Subject: modpost: remove unused Elf_Sword macro Commit 9ad21c3f3ecf ("kbuild: try harder to find symbol names in modpost") added Elf_Sword (in a wrong way), but did not use it at all. BTW, the current code looks weird. The fix for the 32-bit part would be: Elf64_Sword --> Elf32_Sword (inconsistet prefix, Elf32_ vs Elf64_) The fix for the 64-bit part would be: Elf64_Sxword --> Elf64_Sword (the size is different between Sword and Sxword) Note: Elf32_Sword == Elf64_Sword == int32_t Elf32_Sxword == Elf64_Sxword == int64_t Anyway, let's drop unused code instead of fixing it. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 4d8a1ae1d1e3..bd874f906781 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -26,7 +26,6 @@ #define Elf_Shdr Elf32_Shdr #define Elf_Sym Elf32_Sym #define Elf_Addr Elf32_Addr -#define Elf_Sword Elf64_Sword #define Elf_Section Elf32_Half #define ELF_ST_BIND ELF32_ST_BIND #define ELF_ST_TYPE ELF32_ST_TYPE @@ -41,7 +40,6 @@ #define Elf_Shdr Elf64_Shdr #define Elf_Sym Elf64_Sym #define Elf_Addr Elf64_Addr -#define Elf_Sword Elf64_Sxword #define Elf_Section Elf64_Half #define ELF_ST_BIND ELF64_ST_BIND #define ELF_ST_TYPE ELF64_ST_TYPE -- cgit v1.2.3 From dd29865633a5535889568b5f38f74a445c227e5d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 28 Jul 2022 12:14:33 +0900 Subject: kbuild: set EXIT trap before creating temporary directory Swap the order of 'mkdir' and 'trap' just in case the subshell is interrupted between 'mkdir' and 'trap' although the effect might be subtle. This does not intend to make the cleanup perfect. There are more cases that miss to remove the tmp directory, for example: - When interrupted, dash does not invoke the EXIT trap (bash does) - 'rm' command might be interrupted before removing the directory I am not addressing all the cases since the tmp directory is harmless after all. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/Kconfig.include | 2 +- scripts/Makefile.compiler | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include index c1f4222d223d..a0ccceb22cf8 100644 --- a/scripts/Kconfig.include +++ b/scripts/Kconfig.include @@ -25,7 +25,7 @@ failure = $(if-success,$(1),n,y) # $(cc-option,) # Return y if the compiler supports , n otherwise -cc-option = $(success,mkdir .tmp_$$; trap "rm -rf .tmp_$$" EXIT; $(CC) -Werror $(CLANG_FLAGS) $(1) -c -x c /dev/null -o .tmp_$$/tmp.o) +cc-option = $(success,trap "rm -rf .tmp_$$" EXIT; mkdir .tmp_$$; $(CC) -Werror $(CLANG_FLAGS) $(1) -c -x c /dev/null -o .tmp_$$/tmp.o) # $(ld-option,) # Return y if the linker supports , n otherwise diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler index 86ecd2ac874c..94d0d40cddb3 100644 --- a/scripts/Makefile.compiler +++ b/scripts/Makefile.compiler @@ -21,8 +21,8 @@ TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$ # automatically cleaned up. try-run = $(shell set -e; \ TMP=$(TMPOUT)/tmp; \ - mkdir -p $(TMPOUT); \ trap "rm -rf $(TMPOUT)" EXIT; \ + mkdir -p $(TMPOUT); \ if ($(1)) >/dev/null 2>&1; \ then echo "$(2)"; \ else echo "$(3)"; \ -- cgit v1.2.3 From 36b0f0deed4fcbe9ff31268e6c3554714e4d2387 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 3 Aug 2022 22:50:13 +0900 Subject: modpost: refactor get_secindex() SPECIAL() is only used in get_secindex(). Squash it. Make the code more readable with more comments. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.h | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index bd874f906781..1178f40a73f3 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -156,22 +156,28 @@ static inline int is_shndx_special(unsigned int i) return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE; } -/* - * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of - * the way to -256..-1, to avoid conflicting with real section - * indices. - */ -#define SPECIAL(i) ((i) - (SHN_HIRESERVE + 1)) - /* Accessor for sym->st_shndx, hides ugliness of "64k sections" */ static inline unsigned int get_secindex(const struct elf_info *info, const Elf_Sym *sym) { - if (is_shndx_special(sym->st_shndx)) - return SPECIAL(sym->st_shndx); - if (sym->st_shndx != SHN_XINDEX) - return sym->st_shndx; - return info->symtab_shndx_start[sym - info->symtab_start]; + unsigned int index = sym->st_shndx; + + /* + * Elf{32,64}_Sym::st_shndx is 2 byte. Big section numbers are available + * in the .symtab_shndx section. + */ + if (index == SHN_XINDEX) + return info->symtab_shndx_start[sym - info->symtab_start]; + + /* + * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of + * the way to UINT_MAX-255..UINT_MAX, to avoid conflicting with real + * section indices. + */ + if (index >= SHN_LORESERVE && index <= SHN_HIRESERVE) + return index - SHN_HIRESERVE - 1; + + return index; } /* file2alias.c */ -- cgit v1.2.3 From 125ed24a4ab0d704bab5dee5ccb2c3b05f627c78 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 31 Jul 2022 02:36:34 +0900 Subject: modpost: add array range check to sec_name() The section index is always positive, so the argument, secindex, should be unsigned. Also, inserted the array range check. If sym->st_shndx is a special section index (between SHN_LORESERVE and SHN_HIRESERVE), there is no corresponding section header. For example, if a symbol specifies an absolute value, sym->st_shndx is SHN_ABS (=0xfff1). The current users do not cause the out-of-range access of info->sechddrs[], but it is better to avoid such a pitfall. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 08411fff3e17..148b38699889 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -336,8 +336,16 @@ static const char *sech_name(const struct elf_info *info, Elf_Shdr *sechdr) sechdr->sh_name); } -static const char *sec_name(const struct elf_info *info, int secindex) +static const char *sec_name(const struct elf_info *info, unsigned int secindex) { + /* + * If sym->st_shndx is a special section index, there is no + * corresponding section header. + * Return "" if the index is out of range of info->sechdrs[] array. + */ + if (secindex >= info->num_sections) + return ""; + return sech_name(info, &info->sechdrs[secindex]); } -- cgit v1.2.3 From 5419aa2a8deea06b796222d3215dac6adc270c78 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 31 Jul 2022 02:36:35 +0900 Subject: modpost: use more reliable way to get fromsec in section_rel(a)() The section name of Rel and Rela starts with ".rel" and ".rela" respectively (but, I do not know whether this is specification or convention). For example, ".rela.text" holds relocation entries applied to the ".text" section. So, the code chops the ".rel" or ".rela" prefix to get the name of the section to which the relocation applies. However, I do not like to skip 4 or 5 bytes blindly because it is potential memory overrun. The ELF specification provides a more reliable way to do this. - The sh_info field holds extra information, whose interpretation depends on the section type - If the section type is SHT_REL or SHT_RELA, the sh_info field holds the section header index of the section to which the relocation applies. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 148b38699889..c6a055c0291e 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1723,8 +1723,7 @@ static void section_rela(const char *modname, struct elf_info *elf, Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset; Elf_Rela *stop = (void *)start + sechdr->sh_size; - fromsec = sech_name(elf, sechdr); - fromsec += strlen(".rela"); + fromsec = sec_name(elf, sechdr->sh_info); /* if from section (name) is know good then skip it */ if (match(fromsec, section_white_list)) return; @@ -1776,8 +1775,7 @@ static void section_rel(const char *modname, struct elf_info *elf, Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset; Elf_Rel *stop = (void *)start + sechdr->sh_size; - fromsec = sech_name(elf, sechdr); - fromsec += strlen(".rel"); + fromsec = sec_name(elf, sechdr->sh_info); /* if from section (name) is know good then skip it */ if (match(fromsec, section_white_list)) return; -- cgit v1.2.3 From 1a83950270684f860b15430394ea8df540d71353 Mon Sep 17 00:00:00 2001 From: Tianjia Zhang Date: Mon, 27 Jun 2022 17:21:07 +0800 Subject: sign-file: Fix confusing error messages When an error occurs, use errx() instead of err() to display the error message, because openssl has its own error record. When an error occurs, errno will not be changed, while err() displays the errno error message. It will cause confusion. For example, when CMS_add1_signer() fails, the following message will appear: sign-file: CMS_add1_signer: Success errx() ignores errno and does not cause such issue. Signed-off-by: Tianjia Zhang Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- scripts/sign-file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/sign-file.c b/scripts/sign-file.c index 7434e9ea926e..598ef5465f82 100644 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c @@ -114,7 +114,7 @@ static void drain_openssl_errors(void) bool __cond = (cond); \ display_openssl_errors(__LINE__); \ if (__cond) { \ - err(1, fmt, ## __VA_ARGS__); \ + errx(1, fmt, ## __VA_ARGS__); \ } \ } while(0) -- cgit v1.2.3 From a25efd6ef1ef4c32991a1d5a013dd41e3b8f7eff Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 31 Jul 2022 02:36:36 +0900 Subject: Revert "Kbuild, lto, workaround: Don't warn for initcall_reference in modpost" This reverts commit 77ab21adae509c5540956729e2d03bc1a59bc82a. Even after 8 years later, GCC LTO has not been upstreamed. Also, it said "This is a workaround". If this is needed in the future, it should be added in a proper way. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Acked-by: Jiri Slaby --- scripts/mod/modpost.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c6a055c0291e..a8ee27496da7 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1462,9 +1462,6 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, from = find_elf_symbol2(elf, r->r_offset, fromsec); fromsym = sym_name(elf, from); - if (strstarts(fromsym, "reference___initcall")) - return; - tosec = sec_name(elf, get_secindex(elf, sym)); to = find_elf_symbol(elf, r->r_addend, sym); tosym = sym_name(elf, to); -- cgit v1.2.3 From 072dd2c8928f2ecdc52cdf5acf30479b327386c9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Aug 2022 18:38:59 +0900 Subject: modpost: shorten warning messages in report_sec_mismatch() Each section mismatch results in long warning messages. Too much. Make each warning fit in one line, and remove a lot of messy code. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 179 +++----------------------------------------------- 1 file changed, 9 insertions(+), 170 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index a8ee27496da7..9e8ae2636ec1 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1238,42 +1238,6 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, return near; } -/* - * Convert a section name to the function/data attribute - * .init.text => __init - * .memexitconst => __memconst - * etc. - * - * The memory of returned value has been allocated on a heap. The user of this - * method should free it after usage. -*/ -static char *sec2annotation(const char *s) -{ - if (match(s, init_exit_sections)) { - char *p = NOFAIL(malloc(20)); - char *r = p; - - *p++ = '_'; - *p++ = '_'; - if (*s == '.') - s++; - while (*s && *s != '.') - *p++ = *s++; - *p = '\0'; - if (*s == '.') - s++; - if (strstr(s, "rodata") != NULL) - strcat(p, "const "); - else if (strstr(s, "data") != NULL) - strcat(p, "data "); - else - strcat(p, " "); - return r; - } else { - return NOFAIL(strdup("")); - } -} - static int is_function(Elf_Sym *sym) { if (sym) @@ -1282,19 +1246,6 @@ static int is_function(Elf_Sym *sym) return -1; } -static void print_section_list(const char * const list[20]) -{ - const char *const *s = list; - - while (*s) { - fprintf(stderr, "%s", *s); - s++; - if (*s) - fprintf(stderr, ", "); - } - fprintf(stderr, "\n"); -} - static inline void get_pretty_name(int is_func, const char** name, const char** name_p) { switch (is_func) { @@ -1312,141 +1263,31 @@ static inline void get_pretty_name(int is_func, const char** name, const char** static void report_sec_mismatch(const char *modname, const struct sectioncheck *mismatch, const char *fromsec, - unsigned long long fromaddr, const char *fromsym, - int from_is_func, - const char *tosec, const char *tosym, - int to_is_func) + const char *tosec, const char *tosym) { - const char *from, *from_p; - const char *to, *to_p; - char *prl_from; - char *prl_to; - sec_mismatch_count++; - get_pretty_name(from_is_func, &from, &from_p); - get_pretty_name(to_is_func, &to, &to_p); - - warn("%s(%s+0x%llx): Section mismatch in reference from the %s %s%s " - "to the %s %s:%s%s\n", - modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec, - tosym, to_p); - switch (mismatch->mismatch) { case TEXT_TO_ANY_INIT: - prl_from = sec2annotation(fromsec); - prl_to = sec2annotation(tosec); - fprintf(stderr, - "The function %s%s() references\n" - "the %s %s%s%s.\n" - "This is often because %s lacks a %s\n" - "annotation or the annotation of %s is wrong.\n", - prl_from, fromsym, - to, prl_to, tosym, to_p, - fromsym, prl_to, tosym); - free(prl_from); - free(prl_to); - break; - case DATA_TO_ANY_INIT: { - prl_to = sec2annotation(tosec); - fprintf(stderr, - "The variable %s references\n" - "the %s %s%s%s\n" - "If the reference is valid then annotate the\n" - "variable with __init* or __refdata (see linux/init.h) " - "or name the variable:\n", - fromsym, to, prl_to, tosym, to_p); - print_section_list(mismatch->symbol_white_list); - free(prl_to); - break; - } + case DATA_TO_ANY_INIT: case TEXT_TO_ANY_EXIT: - prl_to = sec2annotation(tosec); - fprintf(stderr, - "The function %s() references a %s in an exit section.\n" - "Often the %s %s%s has valid usage outside the exit section\n" - "and the fix is to remove the %sannotation of %s.\n", - fromsym, to, to, tosym, to_p, prl_to, tosym); - free(prl_to); - break; - case DATA_TO_ANY_EXIT: { - prl_to = sec2annotation(tosec); - fprintf(stderr, - "The variable %s references\n" - "the %s %s%s%s\n" - "If the reference is valid then annotate the\n" - "variable with __exit* (see linux/init.h) or " - "name the variable:\n", - fromsym, to, prl_to, tosym, to_p); - print_section_list(mismatch->symbol_white_list); - free(prl_to); - break; - } + case DATA_TO_ANY_EXIT: case XXXINIT_TO_SOME_INIT: case XXXEXIT_TO_SOME_EXIT: - prl_from = sec2annotation(fromsec); - prl_to = sec2annotation(tosec); - fprintf(stderr, - "The %s %s%s%s references\n" - "a %s %s%s%s.\n" - "If %s is only used by %s then\n" - "annotate %s with a matching annotation.\n", - from, prl_from, fromsym, from_p, - to, prl_to, tosym, to_p, - tosym, fromsym, tosym); - free(prl_from); - free(prl_to); - break; case ANY_INIT_TO_ANY_EXIT: - prl_from = sec2annotation(fromsec); - prl_to = sec2annotation(tosec); - fprintf(stderr, - "The %s %s%s%s references\n" - "a %s %s%s%s.\n" - "This is often seen when error handling " - "in the init function\n" - "uses functionality in the exit path.\n" - "The fix is often to remove the %sannotation of\n" - "%s%s so it may be used outside an exit section.\n", - from, prl_from, fromsym, from_p, - to, prl_to, tosym, to_p, - prl_to, tosym, to_p); - free(prl_from); - free(prl_to); - break; case ANY_EXIT_TO_ANY_INIT: - prl_from = sec2annotation(fromsec); - prl_to = sec2annotation(tosec); - fprintf(stderr, - "The %s %s%s%s references\n" - "a %s %s%s%s.\n" - "This is often seen when error handling " - "in the exit function\n" - "uses functionality in the init path.\n" - "The fix is often to remove the %sannotation of\n" - "%s%s so it may be used outside an init section.\n", - from, prl_from, fromsym, from_p, - to, prl_to, tosym, to_p, - prl_to, tosym, to_p); - free(prl_from); - free(prl_to); + warn("%s: section mismatch in reference: %s (section: %s) -> %s (section: %s)\n", + modname, fromsym, fromsec, tosym, tosec); break; case EXPORT_TO_INIT_EXIT: - prl_to = sec2annotation(tosec); - fprintf(stderr, - "The symbol %s is exported and annotated %s\n" - "Fix this by removing the %sannotation of %s " - "or drop the export.\n", - tosym, prl_to, prl_to, tosym); - free(prl_to); + warn("%s: EXPORT_SYMBOL used for init/exit symbol: %s (section: %s)\n", + modname, tosym, tosec); break; case EXTABLE_TO_NON_TEXT: - fatal("There's a special handler for this mismatch type, " - "we should never get here."); + fatal("There's a special handler for this mismatch type, we should never get here.\n"); break; } - fprintf(stderr, "\n"); } static void default_mismatch_handler(const char *modname, struct elf_info *elf, @@ -1470,9 +1311,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, if (secref_whitelist(mismatch, fromsec, fromsym, tosec, tosym)) { report_sec_mismatch(modname, mismatch, - fromsec, r->r_offset, fromsym, - is_function(from), tosec, tosym, - is_function(to)); + fromsec, fromsym, tosec, tosym); } } -- cgit v1.2.3 From 7452dd26a59a9dfcde3f179594f3be6c4752a9a9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Aug 2022 18:39:00 +0900 Subject: modpost: add PATTERNS() helper macro This will be useful to define a NULL-terminated array inside a function call. Currently, string arrays passed to match() are defined in separate places: static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL }; static const char *const text_sections[] = { ALL_TEXT_SECTIONS, NULL }; static const char *const optim_symbols[] = { "*.constprop.*", NULL }; ... /* Check for pattern 5 */ if (match(fromsec, text_sections) && match(tosec, init_sections) && match(fromsym, optim_symbols)) return 0; With the new helper macro, you can list the patterns directly in the function call, like this: /* Check for pattern 5 */ if (match(fromsec, PATTERNS(ALL_TEXT_SECTIONS)) && match(tosec, PATTERNS(ALL_INIT_SECTIONS)) && match(fromsym, PATTERNS("*.contprop.*"))) return 0; Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 9e8ae2636ec1..c2949a1a0d5e 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -746,6 +746,13 @@ static bool match(const char *string, const char *const patterns[]) return false; } +/* useful to pass patterns to match() directly */ +#define PATTERNS(...) \ + ({ \ + static const char *const patterns[] = {__VA_ARGS__, NULL}; \ + patterns; \ + }) + /* sections that we do not want to do full section mismatch check on */ static const char *const section_white_list[] = { -- cgit v1.2.3 From 1560cb0e186e83f0572a84d22e139c100060905c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Aug 2022 18:39:01 +0900 Subject: modpost: remove unneeded .symbol_white_list initializers The ->symbol_white_list field is referenced in secref_whitelist(), only when 'fromsec' is data_sections. /* Check for pattern 2 */ if (match(tosec, init_exit_sections) && match(fromsec, data_sections) && match(fromsym, mismatch->symbol_white_list)) return 0; If .fromsec is not data sections, the .symbol_white_list member is not used by anyone. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c2949a1a0d5e..bcd1319f3097 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -930,7 +930,6 @@ static const struct sectioncheck sectioncheck[] = { .fromsec = { TEXT_SECTIONS, NULL }, .bad_tosec = { ALL_INIT_SECTIONS, NULL }, .mismatch = TEXT_TO_ANY_INIT, - .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, { .fromsec = { DATA_SECTIONS, NULL }, @@ -951,7 +950,6 @@ static const struct sectioncheck sectioncheck[] = { .fromsec = { TEXT_SECTIONS, NULL }, .bad_tosec = { ALL_EXIT_SECTIONS, NULL }, .mismatch = TEXT_TO_ANY_EXIT, - .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, { .fromsec = { DATA_SECTIONS, NULL }, @@ -964,41 +962,35 @@ static const struct sectioncheck sectioncheck[] = { .fromsec = { ALL_XXXINIT_SECTIONS, NULL }, .bad_tosec = { INIT_SECTIONS, NULL }, .mismatch = XXXINIT_TO_SOME_INIT, - .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, /* Do not reference exit code/data from memexit code/data */ { .fromsec = { ALL_XXXEXIT_SECTIONS, NULL }, .bad_tosec = { EXIT_SECTIONS, NULL }, .mismatch = XXXEXIT_TO_SOME_EXIT, - .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, /* Do not use exit code/data from init code */ { .fromsec = { ALL_INIT_SECTIONS, NULL }, .bad_tosec = { ALL_EXIT_SECTIONS, NULL }, .mismatch = ANY_INIT_TO_ANY_EXIT, - .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, /* Do not use init code/data from exit code */ { .fromsec = { ALL_EXIT_SECTIONS, NULL }, .bad_tosec = { ALL_INIT_SECTIONS, NULL }, .mismatch = ANY_EXIT_TO_ANY_INIT, - .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, { .fromsec = { ALL_PCI_INIT_SECTIONS, NULL }, .bad_tosec = { INIT_SECTIONS, NULL }, .mismatch = ANY_INIT_TO_ANY_EXIT, - .symbol_white_list = { NULL }, }, /* Do not export init/exit functions or data */ { .fromsec = { "___ksymtab*", NULL }, .bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, .mismatch = EXPORT_TO_INIT_EXIT, - .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, { .fromsec = { "__ex_table", NULL }, -- cgit v1.2.3 From 672fb6740cbfde34f4d367ffa3c939b608a927e1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 1 Aug 2022 18:39:02 +0900 Subject: modpost: remove .symbol_white_list field entirely It is not so useful to have symbol whitelists in arrays. With this over-engineering, the code is difficult to follow. Let's do it more directly, and collect the relevant code to one place. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 55 +++++++++++++++------------------------------------ 1 file changed, 16 insertions(+), 39 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index bcd1319f3097..8484c0798f28 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -845,28 +845,12 @@ static const char *const init_data_sections[] = /* all init sections */ static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL }; -/* All init and exit sections (code + data) */ -static const char *const init_exit_sections[] = - {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL }; - /* all text sections */ static const char *const text_sections[] = { ALL_TEXT_SECTIONS, NULL }; /* data section */ static const char *const data_sections[] = { DATA_SECTIONS, NULL }; - -/* symbols in .data that may refer to init/exit sections */ -#define DEFAULT_SYMBOL_WHITE_LIST \ - "*driver", \ - "*_template", /* scsi uses *_template a lot */ \ - "*_timer", /* arm uses ops structures named _timer a lot */ \ - "*_sht", /* scsi also used *_sht to some extent */ \ - "*_ops", \ - "*_probe", \ - "*_probe_one", \ - "*_console" - static const char *const head_sections[] = { ".head.text*", NULL }; static const char *const linker_symbols[] = { "__init_begin", "_sinittext", "_einittext", NULL }; @@ -898,9 +882,6 @@ enum mismatch { * * @mismatch: Type of mismatch. * - * @symbol_white_list: Do not match a relocation to a symbol in this list - * even if it is targeting a section in @bad_to_sec. - * * @handler: Specific handler to call when a match is found. If NULL, * default_mismatch_handler() will be called. * @@ -910,7 +891,6 @@ struct sectioncheck { const char *bad_tosec[20]; const char *good_tosec[20]; enum mismatch mismatch; - const char *symbol_white_list[20]; void (*handler)(const char *modname, struct elf_info *elf, const struct sectioncheck* const mismatch, Elf_Rela *r, Elf_Sym *sym, const char *fromsec); @@ -935,16 +915,11 @@ static const struct sectioncheck sectioncheck[] = { .fromsec = { DATA_SECTIONS, NULL }, .bad_tosec = { ALL_XXXINIT_SECTIONS, NULL }, .mismatch = DATA_TO_ANY_INIT, - .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, { .fromsec = { DATA_SECTIONS, NULL }, .bad_tosec = { INIT_SECTIONS, NULL }, .mismatch = DATA_TO_ANY_INIT, - .symbol_white_list = { - "*_template", "*_timer", "*_sht", "*_ops", - "*_probe", "*_probe_one", "*_console", NULL - }, }, { .fromsec = { TEXT_SECTIONS, NULL }, @@ -955,7 +930,6 @@ static const struct sectioncheck sectioncheck[] = { .fromsec = { DATA_SECTIONS, NULL }, .bad_tosec = { ALL_EXIT_SECTIONS, NULL }, .mismatch = DATA_TO_ANY_EXIT, - .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, }, /* Do not reference init code/data from meminit code/data */ { @@ -1051,15 +1025,6 @@ static const struct sectioncheck *section_mismatch( * fromsec = .data* * atsym = __param_ops_* * - * Pattern 2: - * Many drivers utilise a *driver container with references to - * add, remove, probe functions etc. - * the pattern is identified by: - * tosec = init or exit section - * fromsec = data section - * atsym = *driver, *_template, *_sht, *_ops, *_probe, - * *probe_one, *_console, *_timer - * * Pattern 3: * Whitelist all references from .head.text to any init section * @@ -1108,10 +1073,22 @@ static int secref_whitelist(const struct sectioncheck *mismatch, strstarts(fromsym, "__param_ops_")) return 0; - /* Check for pattern 2 */ - if (match(tosec, init_exit_sections) && - match(fromsec, data_sections) && - match(fromsym, mismatch->symbol_white_list)) + /* symbols in data sections that may refer to any init/exit sections */ + if (match(fromsec, PATTERNS(DATA_SECTIONS)) && + match(tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) && + match(fromsym, PATTERNS("*_template", // scsi uses *_template a lot + "*_timer", // arm uses ops structures named _timer a lot + "*_sht", // scsi also used *_sht to some extent + "*_ops", + "*_probe", + "*_probe_one", + "*_console"))) + return 0; + + /* symbols in data sections that may refer to meminit/exit sections */ + if (match(fromsec, PATTERNS(DATA_SECTIONS)) && + match(tosec, PATTERNS(ALL_XXXINIT_SECTIONS, ALL_EXIT_SECTIONS)) && + match(fromsym, PATTERNS("*driver"))) return 0; /* Check for pattern 3 */ -- cgit v1.2.3 From 18c06cf868bc4e37b9766a91be02453c38f89745 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 16 Jul 2022 15:28:10 +0200 Subject: coccinelle: free: add version constraint The various functions contain a NULL check starting in v5.15. Signed-off-by: Julia Lawall --- scripts/coccinelle/free/ifnulldev_put.cocci | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/coccinelle/free/ifnulldev_put.cocci b/scripts/coccinelle/free/ifnulldev_put.cocci index 7ff36e6212ba..2bd2e8fae485 100644 --- a/scripts/coccinelle/free/ifnulldev_put.cocci +++ b/scripts/coccinelle/free/ifnulldev_put.cocci @@ -7,6 +7,7 @@ // Copyright: (C) 2022 Ziyang Xuan. // Comments: - // Options: --no-includes --include-headers +// Version min: 5.15 virtual patch virtual org -- cgit v1.2.3 From f01701cec8cbb94df209e9705b97abd01c151ba1 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 7 Aug 2022 18:19:54 +0200 Subject: update Coccinelle URL Signed-off-by: Julia Lawall --- scripts/coccinelle/api/alloc/zalloc-simple.cocci | 2 +- scripts/coccinelle/api/atomic_as_refcounter.cocci | 2 +- scripts/coccinelle/api/check_bq27xxx_data.cocci | 2 +- scripts/coccinelle/api/d_find_alias.cocci | 2 +- scripts/coccinelle/api/err_cast.cocci | 2 +- scripts/coccinelle/api/kstrdup.cocci | 2 +- scripts/coccinelle/api/memdup.cocci | 2 +- scripts/coccinelle/api/memdup_user.cocci | 2 +- scripts/coccinelle/api/pm_runtime.cocci | 2 +- scripts/coccinelle/api/resource_size.cocci | 2 +- scripts/coccinelle/free/clk_put.cocci | 2 +- scripts/coccinelle/free/devm_free.cocci | 2 +- scripts/coccinelle/free/iounmap.cocci | 2 +- scripts/coccinelle/free/kfree.cocci | 2 +- scripts/coccinelle/free/kfreeaddr.cocci | 2 +- scripts/coccinelle/free/pci_free_consistent.cocci | 2 +- scripts/coccinelle/iterators/device_node_continue.cocci | 2 +- scripts/coccinelle/iterators/for_each_child.cocci | 2 +- scripts/coccinelle/iterators/itnull.cocci | 2 +- scripts/coccinelle/iterators/list_entry_update.cocci | 2 +- scripts/coccinelle/iterators/use_after_iter.cocci | 2 +- scripts/coccinelle/locks/call_kern.cocci | 2 +- scripts/coccinelle/locks/double_lock.cocci | 2 +- scripts/coccinelle/locks/flags.cocci | 2 +- scripts/coccinelle/locks/mini_lock.cocci | 2 +- scripts/coccinelle/misc/cstptr.cocci | 2 +- scripts/coccinelle/misc/doubleinit.cocci | 2 +- scripts/coccinelle/misc/ifcol.cocci | 2 +- scripts/coccinelle/misc/newline_in_nl_msg.cocci | 2 +- scripts/coccinelle/misc/noderef.cocci | 2 +- scripts/coccinelle/misc/orplus.cocci | 2 +- scripts/coccinelle/misc/returnvar.cocci | 2 +- scripts/coccinelle/misc/semicolon.cocci | 2 +- scripts/coccinelle/misc/test_addr.cocci | 2 +- scripts/coccinelle/misc/warn.cocci | 2 +- scripts/coccinelle/null/badzero.cocci | 2 +- scripts/coccinelle/null/deref_null.cocci | 2 +- scripts/coccinelle/null/eno.cocci | 2 +- scripts/coccinelle/null/kmerr.cocci | 2 +- scripts/coccinelle/tests/doublebitand.cocci | 2 +- scripts/coccinelle/tests/doubletest.cocci | 2 +- scripts/coccinelle/tests/odd_ptr_err.cocci | 2 +- scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci | 2 +- 43 files changed, 43 insertions(+), 43 deletions(-) (limited to 'scripts') diff --git a/scripts/coccinelle/api/alloc/zalloc-simple.cocci b/scripts/coccinelle/api/alloc/zalloc-simple.cocci index b3d0c3c230c1..d66c45356691 100644 --- a/scripts/coccinelle/api/alloc/zalloc-simple.cocci +++ b/scripts/coccinelle/api/alloc/zalloc-simple.cocci @@ -10,7 +10,7 @@ // Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. // Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. // Copyright: (C) 2017 Himanshu Jha -// URL: http://coccinelle.lip6.fr/rules/kzalloc.html +// URL: https://coccinelle.gitlabpages.inria.fr/website // Options: --no-includes --include-headers // // Keywords: kmalloc, kzalloc diff --git a/scripts/coccinelle/api/atomic_as_refcounter.cocci b/scripts/coccinelle/api/atomic_as_refcounter.cocci index 0f78d94abc35..e63d52408b86 100644 --- a/scripts/coccinelle/api/atomic_as_refcounter.cocci +++ b/scripts/coccinelle/api/atomic_as_refcounter.cocci @@ -5,7 +5,7 @@ // Copyright (c) 2016-2017, Elena Reshetova, Intel Corporation // // Confidence: Moderate -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Options: --include-headers --very-quiet virtual report diff --git a/scripts/coccinelle/api/check_bq27xxx_data.cocci b/scripts/coccinelle/api/check_bq27xxx_data.cocci index fae539ef0ce5..27366c6169ec 100644 --- a/scripts/coccinelle/api/check_bq27xxx_data.cocci +++ b/scripts/coccinelle/api/check_bq27xxx_data.cocci @@ -6,7 +6,7 @@ /// // Confidence: High // Copyright: (C) 2017 Julia Lawall, Inria/LIP6, -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Requires: 1.0.7 // Keywords: BQ27XXX_DATA diff --git a/scripts/coccinelle/api/d_find_alias.cocci b/scripts/coccinelle/api/d_find_alias.cocci index 47e050166f20..3489001378ab 100644 --- a/scripts/coccinelle/api/d_find_alias.cocci +++ b/scripts/coccinelle/api/d_find_alias.cocci @@ -4,7 +4,7 @@ // Keywords: d_find_alias, dput // // Confidence: Moderate -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Options: --include-headers virtual context diff --git a/scripts/coccinelle/api/err_cast.cocci b/scripts/coccinelle/api/err_cast.cocci index 0e661c8d8d6f..7f9dc1212c74 100644 --- a/scripts/coccinelle/api/err_cast.cocci +++ b/scripts/coccinelle/api/err_cast.cocci @@ -6,7 +6,7 @@ // Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. // Copyright: (C) 2009, 2010 Julia Lawall, DIKU. // Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Options: // // Keywords: ERR_PTR, PTR_ERR, ERR_CAST diff --git a/scripts/coccinelle/api/kstrdup.cocci b/scripts/coccinelle/api/kstrdup.cocci index 3c6dc5469ee4..8a61534676da 100644 --- a/scripts/coccinelle/api/kstrdup.cocci +++ b/scripts/coccinelle/api/kstrdup.cocci @@ -5,7 +5,7 @@ // Copyright: (C) 2010-2012 Nicolas Palix. // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/api/memdup.cocci b/scripts/coccinelle/api/memdup.cocci index 30b15df734e5..d28741c69873 100644 --- a/scripts/coccinelle/api/memdup.cocci +++ b/scripts/coccinelle/api/memdup.cocci @@ -5,7 +5,7 @@ // Copyright: (C) 2010-2012 Nicolas Palix. // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/api/memdup_user.cocci b/scripts/coccinelle/api/memdup_user.cocci index e01e95108405..03e7afa09eee 100644 --- a/scripts/coccinelle/api/memdup_user.cocci +++ b/scripts/coccinelle/api/memdup_user.cocci @@ -6,7 +6,7 @@ // Copyright: (C) 2010-2012 Nicolas Palix. // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/api/pm_runtime.cocci b/scripts/coccinelle/api/pm_runtime.cocci index 1ccce3fd00b8..4b9778874453 100644 --- a/scripts/coccinelle/api/pm_runtime.cocci +++ b/scripts/coccinelle/api/pm_runtime.cocci @@ -4,7 +4,7 @@ // Keywords: pm_runtime // Confidence: Medium // Copyright (C) 2013 Texas Instruments Incorporated - -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Options: --include-headers virtual patch diff --git a/scripts/coccinelle/api/resource_size.cocci b/scripts/coccinelle/api/resource_size.cocci index a9a571ac04ce..16857072d162 100644 --- a/scripts/coccinelle/api/resource_size.cocci +++ b/scripts/coccinelle/api/resource_size.cocci @@ -7,7 +7,7 @@ // Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. // Copyright: (C) 2009, 2010 Julia Lawall, DIKU. // Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Options: // // Keywords: resource_size diff --git a/scripts/coccinelle/free/clk_put.cocci b/scripts/coccinelle/free/clk_put.cocci index 7237b49496f6..3c732cb7210b 100644 --- a/scripts/coccinelle/free/clk_put.cocci +++ b/scripts/coccinelle/free/clk_put.cocci @@ -8,7 +8,7 @@ // Confidence: Moderate // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: diff --git a/scripts/coccinelle/free/devm_free.cocci b/scripts/coccinelle/free/devm_free.cocci index da80050b91ff..0880729badbc 100644 --- a/scripts/coccinelle/free/devm_free.cocci +++ b/scripts/coccinelle/free/devm_free.cocci @@ -17,7 +17,7 @@ // Confidence: Moderate // Copyright: (C) 2011 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2011 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/free/iounmap.cocci b/scripts/coccinelle/free/iounmap.cocci index 63b81d0c97b6..90d85fa7bfdf 100644 --- a/scripts/coccinelle/free/iounmap.cocci +++ b/scripts/coccinelle/free/iounmap.cocci @@ -8,7 +8,7 @@ // Confidence: Moderate // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: diff --git a/scripts/coccinelle/free/kfree.cocci b/scripts/coccinelle/free/kfree.cocci index 9b6e2037c2a9..6338bbac2f7f 100644 --- a/scripts/coccinelle/free/kfree.cocci +++ b/scripts/coccinelle/free/kfree.cocci @@ -9,7 +9,7 @@ // Copyright: (C) 2010-2012 Nicolas Palix. // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/free/kfreeaddr.cocci b/scripts/coccinelle/free/kfreeaddr.cocci index 142af6337a04..85635a36f0ac 100644 --- a/scripts/coccinelle/free/kfreeaddr.cocci +++ b/scripts/coccinelle/free/kfreeaddr.cocci @@ -3,7 +3,7 @@ /// // Confidence: High // Copyright: (C) 2013 Julia Lawall, INRIA/LIP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/free/pci_free_consistent.cocci b/scripts/coccinelle/free/pci_free_consistent.cocci index d51e92556b42..e062b9ba09ff 100644 --- a/scripts/coccinelle/free/pci_free_consistent.cocci +++ b/scripts/coccinelle/free/pci_free_consistent.cocci @@ -3,7 +3,7 @@ /// // Confidence: Moderate // Copyright: (C) 2013 Petr Strnad. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Keywords: pci_free_consistent, pci_alloc_consistent // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/iterators/device_node_continue.cocci b/scripts/coccinelle/iterators/device_node_continue.cocci index f8cd14dfa604..5713c9cf59ff 100644 --- a/scripts/coccinelle/iterators/device_node_continue.cocci +++ b/scripts/coccinelle/iterators/device_node_continue.cocci @@ -4,7 +4,7 @@ /// // Confidence: High // Copyright: (C) 2015 Julia Lawall, Inria. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Options: --no-includes --include-headers // Requires: 1.0.4 // Keywords: for_each_child_of_node, etc. diff --git a/scripts/coccinelle/iterators/for_each_child.cocci b/scripts/coccinelle/iterators/for_each_child.cocci index bc394615948e..2ea98a61a1f2 100644 --- a/scripts/coccinelle/iterators/for_each_child.cocci +++ b/scripts/coccinelle/iterators/for_each_child.cocci @@ -5,7 +5,7 @@ /// // Confidence: High // Copyright: (C) 2020 Sumera Priyadarsini -// URL: http://coccinelle.lip6.fr +// URL: https://coccinelle.gitlabpages.inria.fr/website // Options: --no-includes --include-headers virtual patch diff --git a/scripts/coccinelle/iterators/itnull.cocci b/scripts/coccinelle/iterators/itnull.cocci index 9b362b98d7a1..7d34802f2724 100644 --- a/scripts/coccinelle/iterators/itnull.cocci +++ b/scripts/coccinelle/iterators/itnull.cocci @@ -10,7 +10,7 @@ // Copyright: (C) 2010-2012 Nicolas Palix. // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/iterators/list_entry_update.cocci b/scripts/coccinelle/iterators/list_entry_update.cocci index d62e8a16085f..9a7593667da6 100644 --- a/scripts/coccinelle/iterators/list_entry_update.cocci +++ b/scripts/coccinelle/iterators/list_entry_update.cocci @@ -8,7 +8,7 @@ // Copyright: (C) 2010 Nicolas Palix, DIKU. // Copyright: (C) 2010 Julia Lawall, DIKU. // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/iterators/use_after_iter.cocci b/scripts/coccinelle/iterators/use_after_iter.cocci index 676edd562eef..f67110ba7290 100644 --- a/scripts/coccinelle/iterators/use_after_iter.cocci +++ b/scripts/coccinelle/iterators/use_after_iter.cocci @@ -10,7 +10,7 @@ // Confidence: Moderate // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2012 Gilles Muller, INRIA/LIP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/locks/call_kern.cocci b/scripts/coccinelle/locks/call_kern.cocci index 5ca0d81b0015..3720f86d67c5 100644 --- a/scripts/coccinelle/locks/call_kern.cocci +++ b/scripts/coccinelle/locks/call_kern.cocci @@ -8,7 +8,7 @@ // Copyright: (C) 2012 Nicolas Palix. // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/locks/double_lock.cocci b/scripts/coccinelle/locks/double_lock.cocci index 9e88a578957c..619cfc714409 100644 --- a/scripts/coccinelle/locks/double_lock.cocci +++ b/scripts/coccinelle/locks/double_lock.cocci @@ -7,7 +7,7 @@ // Copyright: (C) 2010 Nicolas Palix, DIKU. // Copyright: (C) 2010 Julia Lawall, DIKU. // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/locks/flags.cocci b/scripts/coccinelle/locks/flags.cocci index 7f990cd55f5a..44acf20a98dd 100644 --- a/scripts/coccinelle/locks/flags.cocci +++ b/scripts/coccinelle/locks/flags.cocci @@ -5,7 +5,7 @@ // Copyright: (C) 2010-2012 Nicolas Palix. // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/locks/mini_lock.cocci b/scripts/coccinelle/locks/mini_lock.cocci index c3ad098f4a5b..71065d8a5d54 100644 --- a/scripts/coccinelle/locks/mini_lock.cocci +++ b/scripts/coccinelle/locks/mini_lock.cocci @@ -10,7 +10,7 @@ // Copyright: (C) 2010-2012 Nicolas Palix. // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/misc/cstptr.cocci b/scripts/coccinelle/misc/cstptr.cocci index c52e3c8ca9b3..74acf34bee03 100644 --- a/scripts/coccinelle/misc/cstptr.cocci +++ b/scripts/coccinelle/misc/cstptr.cocci @@ -5,7 +5,7 @@ // Confidence: High // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/misc/doubleinit.cocci b/scripts/coccinelle/misc/doubleinit.cocci index 2f80d3ab38dd..7dbfde3f44e1 100644 --- a/scripts/coccinelle/misc/doubleinit.cocci +++ b/scripts/coccinelle/misc/doubleinit.cocci @@ -7,7 +7,7 @@ // Copyright: (C) 2010-2012 Nicolas Palix. // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/misc/ifcol.cocci b/scripts/coccinelle/misc/ifcol.cocci index da0351ed5740..442742467c18 100644 --- a/scripts/coccinelle/misc/ifcol.cocci +++ b/scripts/coccinelle/misc/ifcol.cocci @@ -12,7 +12,7 @@ // Copyright: (C) 2010 Nicolas Palix, DIKU. // Copyright: (C) 2010 Julia Lawall, DIKU. // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/misc/newline_in_nl_msg.cocci b/scripts/coccinelle/misc/newline_in_nl_msg.cocci index c175886e4015..9baffe55d917 100644 --- a/scripts/coccinelle/misc/newline_in_nl_msg.cocci +++ b/scripts/coccinelle/misc/newline_in_nl_msg.cocci @@ -5,7 +5,7 @@ /// // Confidence: Very High // Copyright: (C) 2020 Intel Corporation -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Options: --no-includes --include-headers virtual context diff --git a/scripts/coccinelle/misc/noderef.cocci b/scripts/coccinelle/misc/noderef.cocci index 72de62a77a44..37ee7358d742 100644 --- a/scripts/coccinelle/misc/noderef.cocci +++ b/scripts/coccinelle/misc/noderef.cocci @@ -5,7 +5,7 @@ // Confidence: High // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/misc/orplus.cocci b/scripts/coccinelle/misc/orplus.cocci index 52203dc2ca4b..3a1566f1aec9 100644 --- a/scripts/coccinelle/misc/orplus.cocci +++ b/scripts/coccinelle/misc/orplus.cocci @@ -6,7 +6,7 @@ // Confidence: Moderate // Copyright: (C) 2013 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2013 Gilles Muller, INRIA/LIP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/misc/returnvar.cocci b/scripts/coccinelle/misc/returnvar.cocci index ce0d9eebc7e1..7ffc55bf51f9 100644 --- a/scripts/coccinelle/misc/returnvar.cocci +++ b/scripts/coccinelle/misc/returnvar.cocci @@ -4,7 +4,7 @@ /// // Confidence: Moderate // Copyright: (C) 2012 Peter Senna Tschudin, INRIA/LIP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: Comments on code can be deleted if near code that is removed. // "when strict" can be removed to get more hits, but adds false // positives diff --git a/scripts/coccinelle/misc/semicolon.cocci b/scripts/coccinelle/misc/semicolon.cocci index a53edb026dad..4476bf873deb 100644 --- a/scripts/coccinelle/misc/semicolon.cocci +++ b/scripts/coccinelle/misc/semicolon.cocci @@ -4,7 +4,7 @@ /// // Confidence: Moderate // Copyright: (C) 2012 Peter Senna Tschudin, INRIA/LIP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: Some false positives on empty default cases in switch statements. // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/misc/test_addr.cocci b/scripts/coccinelle/misc/test_addr.cocci index 029db9069c44..d559b297476c 100644 --- a/scripts/coccinelle/misc/test_addr.cocci +++ b/scripts/coccinelle/misc/test_addr.cocci @@ -4,7 +4,7 @@ // Confidence: High // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/misc/warn.cocci b/scripts/coccinelle/misc/warn.cocci index e379661e240d..b5f428035d03 100644 --- a/scripts/coccinelle/misc/warn.cocci +++ b/scripts/coccinelle/misc/warn.cocci @@ -4,7 +4,7 @@ // Confidence: High // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/null/badzero.cocci b/scripts/coccinelle/null/badzero.cocci index 882dd65313ab..35d443825c2a 100644 --- a/scripts/coccinelle/null/badzero.cocci +++ b/scripts/coccinelle/null/badzero.cocci @@ -10,7 +10,7 @@ // Confidence: High // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Requires: 1.0.0 // Options: diff --git a/scripts/coccinelle/null/deref_null.cocci b/scripts/coccinelle/null/deref_null.cocci index 98f1e7faf503..fdf098d4f522 100644 --- a/scripts/coccinelle/null/deref_null.cocci +++ b/scripts/coccinelle/null/deref_null.cocci @@ -7,7 +7,7 @@ // Copyright: (C) 2010 Nicolas Palix, DIKU. // Copyright: (C) 2010 Julia Lawall, DIKU. // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: -I ... -all_includes can give more complete results // Options: diff --git a/scripts/coccinelle/null/eno.cocci b/scripts/coccinelle/null/eno.cocci index 81584ff87956..7107d6c8db9e 100644 --- a/scripts/coccinelle/null/eno.cocci +++ b/scripts/coccinelle/null/eno.cocci @@ -5,7 +5,7 @@ // Copyright: (C) 2010-2012 Nicolas Palix. // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/null/kmerr.cocci b/scripts/coccinelle/null/kmerr.cocci index d0e004d4e130..68db20de62eb 100644 --- a/scripts/coccinelle/null/kmerr.cocci +++ b/scripts/coccinelle/null/kmerr.cocci @@ -9,7 +9,7 @@ // Copyright: (C) 2010 Nicolas Palix, DIKU. // Copyright: (C) 2010 Julia Lawall, DIKU. // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/tests/doublebitand.cocci b/scripts/coccinelle/tests/doublebitand.cocci index 0f0b94e7debd..025436a15040 100644 --- a/scripts/coccinelle/tests/doublebitand.cocci +++ b/scripts/coccinelle/tests/doublebitand.cocci @@ -9,7 +9,7 @@ // Copyright: (C) 2010 Nicolas Palix, DIKU. // Copyright: (C) 2010 Julia Lawall, DIKU. // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/tests/doubletest.cocci b/scripts/coccinelle/tests/doubletest.cocci index b35519cddb13..c3d94c31959f 100644 --- a/scripts/coccinelle/tests/doubletest.cocci +++ b/scripts/coccinelle/tests/doubletest.cocci @@ -8,7 +8,7 @@ // Copyright: (C) 2010 Nicolas Palix, DIKU. // Copyright: (C) 2010 Julia Lawall, DIKU. // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Comments: // Options: --no-includes --include-headers diff --git a/scripts/coccinelle/tests/odd_ptr_err.cocci b/scripts/coccinelle/tests/odd_ptr_err.cocci index 11d4e2b6deb8..377436abe2d0 100644 --- a/scripts/coccinelle/tests/odd_ptr_err.cocci +++ b/scripts/coccinelle/tests/odd_ptr_err.cocci @@ -6,7 +6,7 @@ // Confidence: High // Copyright: (C) 2012, 2015 Julia Lawall, INRIA. // Copyright: (C) 2012, 2015 Gilles Muller, INRIA. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Options: --no-includes --include-headers virtual patch diff --git a/scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci b/scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci index 91e286ace54c..5e188c62d8a9 100644 --- a/scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci +++ b/scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci @@ -13,7 +13,7 @@ /// // Confidence: Average // Copyright: (C) 2015 Andrzej Hajda, Samsung Electronics Co., Ltd. -// URL: http://coccinelle.lip6.fr/ +// URL: https://coccinelle.gitlabpages.inria.fr/website // Options: --all-includes virtual context -- cgit v1.2.3 From 21f9c8a13bb2a0c24d9c6b86bc0896542a28c197 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 11 Aug 2022 08:40:01 -0700 Subject: Revert "Makefile.extrawarn: re-enable -Wformat for clang" This reverts commit 258fafcd0683d9ccfa524129d489948ab3ddc24c. The clang -Wformat warning is terminally broken, and the clang people can't seem to get their act together. This test program causes a warning with clang: #include int main(int argc, char **argv) { printf("%hhu\n", 'a'); } resulting in t.c:5:19: warning: format specifies type 'unsigned char' but the argument has type 'int' [-Wformat] printf("%hhu\n", 'a'); ~~~~ ^~~ %d and apparently clang people consider that a feature, because they don't want to face the reality of how either C character constants, C arithmetic, and C varargs functions work. The rest of the world just shakes their head at that kind of incompetence, and turns off -Wformat for clang again. And no, the "you should use a pointless cast to shut this up" is not a valid answer. That warning should not exist in the first place, or at least be optinal with some "-Wformat-me-harder" kind of option. [ Admittedly, there's also very little reason to *ever* use '%hh[ud]' in C, but what little reason there is is entirely about 'I want to see only the low 8 bits of the argument'. So I would suggest nobody ever use that format in the first place, but if they do, the clang behavious is simply always wrong. Because '%hhu' takes an 'int'. It's that simple. ] Reported-by: Sudip Mukherjee (Codethink) Cc: Nick Desaulniers Signed-off-by: Linus Torvalds --- scripts/Makefile.extrawarn | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 9bbaf7112a9b..f5f0d6f09053 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -47,6 +47,7 @@ else ifdef CONFIG_CC_IS_CLANG KBUILD_CFLAGS += -Wno-initializer-overrides +KBUILD_CFLAGS += -Wno-format KBUILD_CFLAGS += -Wno-sign-compare KBUILD_CFLAGS += -Wno-format-zero-length KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast) -- cgit v1.2.3 From d8357e3bf8f7aabd98bf4dc2709ee877b741cefc Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 26 Jun 2022 07:34:37 +0900 Subject: riscv/purgatory: Omit use of bin2c The .incbin assembler directive is much faster than bin2c + $(CC). Do similar refactoring as in commit 4c0f032d4963 ("s390/purgatory: Omit use of bin2c"). Please note the .quad directive matches to size_t in C (both 8 byte) because the purgatory is compiled only for the 64-bit kernel. (KEXEC_FILE depends on 64BIT). Signed-off-by: Masahiro Yamada Link: https://lore.kernel.org/r/20220625223438.835408-2-masahiroy@kernel.org Signed-off-by: Palmer Dabbelt --- arch/riscv/Kconfig | 1 - arch/riscv/purgatory/.gitignore | 1 - arch/riscv/purgatory/Makefile | 8 +------- arch/riscv/purgatory/kexec-purgatory.S | 14 ++++++++++++++ scripts/remove-stale-files | 2 ++ 5 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 arch/riscv/purgatory/kexec-purgatory.S (limited to 'scripts') diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 3d49317f5019..ed66c31e4655 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -494,7 +494,6 @@ config KEXEC_FILE config ARCH_HAS_KEXEC_PURGATORY def_bool KEXEC_FILE - select BUILD_BIN2C depends on CRYPTO=y depends on CRYPTO_SHA256=y diff --git a/arch/riscv/purgatory/.gitignore b/arch/riscv/purgatory/.gitignore index 38d7d1bda4d7..6e4dfb024ad2 100644 --- a/arch/riscv/purgatory/.gitignore +++ b/arch/riscv/purgatory/.gitignore @@ -1,4 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only purgatory.chk purgatory.ro -kexec-purgatory.c diff --git a/arch/riscv/purgatory/Makefile b/arch/riscv/purgatory/Makefile index c2d14e2f345d..dd58e1d99397 100644 --- a/arch/riscv/purgatory/Makefile +++ b/arch/riscv/purgatory/Makefile @@ -84,12 +84,6 @@ $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE $(obj)/purgatory.chk: $(obj)/purgatory.ro FORCE $(call if_changed,ld) -targets += kexec-purgatory.c - -quiet_cmd_bin2c = BIN2C $@ - cmd_bin2c = $(objtree)/scripts/bin2c kexec_purgatory < $< > $@ - -$(obj)/kexec-purgatory.c: $(obj)/purgatory.ro $(obj)/purgatory.chk FORCE - $(call if_changed,bin2c) +$(obj)/kexec-purgatory.o: $(obj)/purgatory.ro $(obj)/purgatory.chk obj-y += kexec-purgatory.o diff --git a/arch/riscv/purgatory/kexec-purgatory.S b/arch/riscv/purgatory/kexec-purgatory.S new file mode 100644 index 000000000000..0e9188815718 --- /dev/null +++ b/arch/riscv/purgatory/kexec-purgatory.S @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + + .section .rodata, "a" + + .align 8 +kexec_purgatory: + .globl kexec_purgatory + .incbin "arch/riscv/purgatory/purgatory.ro" +.Lkexec_purgatroy_end: + + .align 8 +kexec_purgatory_size: + .globl kexec_purgatory_size + .quad .Lkexec_purgatroy_end - kexec_purgatory diff --git a/scripts/remove-stale-files b/scripts/remove-stale-files index 379e86c71bed..e1cd6effad61 100755 --- a/scripts/remove-stale-files +++ b/scripts/remove-stale-files @@ -40,6 +40,8 @@ if [ -n "${building_out_of_srctree}" ]; then done fi +rm -f arch/riscv/purgatory/kexec-purgatory.c + rm -f scripts/extract-cert rm -f arch/x86/purgatory/kexec-purgatory.c -- cgit v1.2.3 From 012e8d2034f1bda8863435cd589636e618d6a659 Mon Sep 17 00:00:00 2001 From: Andrew Donnellan Date: Tue, 16 Aug 2022 15:17:20 +1000 Subject: gcc-plugins: Undefine LATENT_ENTROPY_PLUGIN when plugin disabled for a file Commit 36d4b36b6959 ("lib/nodemask: inline next_node_in() and node_random()") refactored some code by moving node_random() from lib/nodemask.c to include/linux/nodemask.h, thus requiring nodemask.h to include random.h, which conditionally defines add_latent_entropy() depending on whether the macro LATENT_ENTROPY_PLUGIN is defined. This broke the build on powerpc, where nodemask.h is indirectly included in arch/powerpc/kernel/prom_init.c, part of the early boot machinery that is excluded from the latent entropy plugin using DISABLE_LATENT_ENTROPY_PLUGIN. It turns out that while we add a gcc flag to disable the actual plugin, we don't undefine LATENT_ENTROPY_PLUGIN. This leads to the following: CC arch/powerpc/kernel/prom_init.o In file included from ./include/linux/nodemask.h:97, from ./include/linux/mmzone.h:17, from ./include/linux/gfp.h:7, from ./include/linux/xarray.h:15, from ./include/linux/radix-tree.h:21, from ./include/linux/idr.h:15, from ./include/linux/kernfs.h:12, from ./include/linux/sysfs.h:16, from ./include/linux/kobject.h:20, from ./include/linux/pci.h:35, from arch/powerpc/kernel/prom_init.c:24: ./include/linux/random.h: In function 'add_latent_entropy': ./include/linux/random.h:25:46: error: 'latent_entropy' undeclared (first use in this function); did you mean 'add_latent_entropy'? 25 | add_device_randomness((const void *)&latent_entropy, sizeof(latent_entropy)); | ^~~~~~~~~~~~~~ | add_latent_entropy ./include/linux/random.h:25:46: note: each undeclared identifier is reported only once for each function it appears in make[2]: *** [scripts/Makefile.build:249: arch/powerpc/kernel/prom_init.o] Fehler 1 make[1]: *** [scripts/Makefile.build:465: arch/powerpc/kernel] Fehler 2 make: *** [Makefile:1855: arch/powerpc] Error 2 Change the DISABLE_LATENT_ENTROPY_PLUGIN flags to undefine LATENT_ENTROPY_PLUGIN for files where the plugin is disabled. Cc: Yury Norov Fixes: 38addce8b600 ("gcc-plugins: Add latent_entropy plugin") Link: https://bugzilla.kernel.org/show_bug.cgi?id=216367 Link: https://lore.kernel.org/linuxppc-dev/alpine.DEB.2.22.394.2208152006320.289321@ramsan.of.borg/ Reported-by: Erhard Furtner Signed-off-by: Andrew Donnellan Reviewed-by: Yury Norov Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220816051720.44108-1-ajd@linux.ibm.com --- scripts/Makefile.gcc-plugins | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 692d64a70542..e4deaf5fa571 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -4,7 +4,7 @@ gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += latent_entropy_plugin.so gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) \ += -DLATENT_ENTROPY_PLUGIN ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY - DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable + DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable -ULATENT_ENTROPY_PLUGIN endif export DISABLE_LATENT_ENTROPY_PLUGIN -- cgit v1.2.3 From 5b8a9a8fd1f0c3d55d407cf759d54ca68798d9ad Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 9 Aug 2022 23:11:17 +0900 Subject: modpost: fix module versioning when a symbol lacks valid CRC Since commit 7b4537199a4a ("kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS"), module versioning is broken on some architectures. Loading a module fails with "disagrees about version of symbol module_layout". On such architectures (e.g. ARCH=sparc build with sparc64_defconfig), modpost shows a warning, like follows: WARNING: modpost: EXPORT symbol "_mcount" [vmlinux] version generation failed, symbol will not be versioned. Is "_mcount" prototyped in ? Previously, it was a harmless warning (CRC check was just skipped), but now wrong CRCs are used for comparison because invalid CRCs are just skipped. $ sparc64-linux-gnu-nm -n vmlinux [snip] 0000000000c2cea0 r __ksymtab__kstrtol 0000000000c2ceb8 r __ksymtab__kstrtoul 0000000000c2ced0 r __ksymtab__local_bh_enable 0000000000c2cee8 r __ksymtab__mcount 0000000000c2cf00 r __ksymtab__printk 0000000000c2cf18 r __ksymtab__raw_read_lock 0000000000c2cf30 r __ksymtab__raw_read_lock_bh [snip] 0000000000c53b34 D __crc__kstrtol 0000000000c53b38 D __crc__kstrtoul 0000000000c53b3c D __crc__local_bh_enable 0000000000c53b40 D __crc__printk 0000000000c53b44 D __crc__raw_read_lock 0000000000c53b48 D __crc__raw_read_lock_bh Please notice __crc__mcount is missing here. When the module subsystem looks up a CRC that comes after, it results in reading out a wrong address. For example, when __crc__printk is needed, the module subsystem reads 0xc53b44 instead of 0xc53b40. All CRC entries must be output for correct index accessing. Invalid CRCs will be unused, but are needed to keep the one-to-one mapping between __ksymtab_* and __crc_*. The best is to fix all modpost warnings, but several warnings are still remaining on less popular architectures. Fixes: 7b4537199a4a ("kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS") Reported-by: matoro Signed-off-by: Masahiro Yamada Tested-by: matoro --- scripts/mod/modpost.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 55e32af2e53f..2c80da0220c3 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2021,13 +2021,11 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod) /* record CRCs for exported symbols */ buf_printf(buf, "\n"); list_for_each_entry(sym, &mod->exported_symbols, list) { - if (!sym->crc_valid) { + if (!sym->crc_valid) warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n" "Is \"%s\" prototyped in ?\n", sym->name, mod->name, mod->is_vmlinux ? "" : ".ko", sym->name); - continue; - } buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x, \"%s\");\n", sym->name, sym->crc, sym->is_gpl_only ? "_gpl" : ""); -- cgit v1.2.3 From 0df499eaf3c1a43ebb0a84ac854262e3fa731bcf Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 10 Aug 2022 11:26:03 +0200 Subject: kbuild: dummy-tools: pretend we understand __LONG_DOUBLE_128__ There is a test in powerpc's Kconfig which checks __LONG_DOUBLE_128__ and sets CONFIG_PPC_LONG_DOUBLE_128 if it is understood by the compiler. We currently don't handle it, so this results in PPC_LONG_DOUBLE_128 not being in super-config generated by dummy-tools. So take this into account in the gcc script and preprocess __LONG_DOUBLE_128__ as "1". Signed-off-by: Jiri Slaby Signed-off-by: Masahiro Yamada --- scripts/dummy-tools/gcc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/dummy-tools/gcc b/scripts/dummy-tools/gcc index 7db825843435..1db1889f6d81 100755 --- a/scripts/dummy-tools/gcc +++ b/scripts/dummy-tools/gcc @@ -59,7 +59,7 @@ fi if arg_contain -E "$@"; then # For scripts/cc-version.sh; This emulates GCC 20.0.0 if arg_contain - "$@"; then - sed -n '/^GCC/{s/__GNUC__/20/; s/__GNUC_MINOR__/0/; s/__GNUC_PATCHLEVEL__/0/; p;}' + sed -n '/^GCC/{s/__GNUC__/20/; s/__GNUC_MINOR__/0/; s/__GNUC_PATCHLEVEL__/0/; p;}; s/__LONG_DOUBLE_128__/1/ p' exit 0 else echo "no input files" >&2 -- cgit v1.2.3 From 370655bc183b1824ba623e621b58e8c2616c839c Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 10 Aug 2022 16:01:33 -0700 Subject: scripts/Makefile.extrawarn: Do not disable clang's -Wformat-zero-length There are no instances of this warning in the tree across several difference architectures and configurations. This was added by commit 26ea6bb1fef0 ("kbuild, LLVMLinux: Supress warnings unless W=1-3") back in 2014, where it might have been necessary, but there are no instances of it now so stop disabling it to increase warning coverage for clang. Signed-off-by: Nathan Chancellor Signed-off-by: Masahiro Yamada --- scripts/Makefile.extrawarn | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index f5f0d6f09053..0621c39a3955 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -49,7 +49,6 @@ ifdef CONFIG_CC_IS_CLANG KBUILD_CFLAGS += -Wno-initializer-overrides KBUILD_CFLAGS += -Wno-format KBUILD_CFLAGS += -Wno-sign-compare -KBUILD_CFLAGS += -Wno-format-zero-length KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast) KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access) -- cgit v1.2.3 From 4be72c1b9f298b4ad42391322eaddef64b282716 Mon Sep 17 00:00:00 2001 From: Guru Das Srinagesh Date: Thu, 4 Aug 2022 10:46:14 -0700 Subject: scripts/clang-tools: Remove DeprecatedOrUnsafeBufferHandling check This `clang-analyzer` check flags the use of memset(), suggesting a more secure version of the API, such as memset_s(), which does not exist in the kernel: warning: Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memset_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling] Signed-off-by: Guru Das Srinagesh Reviewed-by: Nick Desaulniers Signed-off-by: Masahiro Yamada --- scripts/clang-tools/run-clang-tools.py | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/clang-tools/run-clang-tools.py b/scripts/clang-tools/run-clang-tools.py index f754415af398..1337cedca096 100755 --- a/scripts/clang-tools/run-clang-tools.py +++ b/scripts/clang-tools/run-clang-tools.py @@ -51,6 +51,7 @@ def run_analysis(entry): checks += "linuxkernel-*" else: checks += "clang-analyzer-*" + checks += ",-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling" p = subprocess.run(["clang-tidy", "-p", args.path, checks, entry["file"]], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, -- cgit v1.2.3 From a0a12c3ed057af57552bf6c0aeaca6835693df04 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Fri, 19 Aug 2022 12:06:40 -0700 Subject: asm goto: eradicate CC_HAS_ASM_GOTO GCC has supported asm goto since 4.5, and Clang has since version 9.0.0. The minimum supported versions of these tools for the build according to Documentation/process/changes.rst are 5.1 and 11.0.0 respectively. Remove the feature detection script, Kconfig option, and clean up some fallback code that is no longer supported. The removed script was also testing for a GCC specific bug that was fixed in the 4.7 release. Also remove workarounds for bpftrace using clang older than 9.0.0, since other BPF backend fixes are required at this point. Link: https://lore.kernel.org/lkml/CAK7LNATSr=BXKfkdW8f-H5VT_w=xBpT2ZQcZ7rm6JfkdE+QnmA@mail.gmail.com/ Link: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48637 Acked-by: Borislav Petkov Suggested-by: Masahiro Yamada Suggested-by: Alexei Starovoitov Signed-off-by: Nick Desaulniers Reviewed-by: Ingo Molnar Reviewed-by: Nathan Chancellor Reviewed-by: Alexandre Belloni Signed-off-by: Linus Torvalds --- Documentation/kbuild/kconfig-language.rst | 4 ++-- arch/Kconfig | 3 +-- arch/um/include/asm/cpufeature.h | 15 --------------- arch/x86/Makefile | 4 ---- arch/x86/include/asm/cpufeature.h | 15 --------------- arch/x86/include/asm/rmwcc.h | 6 +++--- arch/x86/kvm/emulate.c | 2 +- init/Kconfig | 4 ---- scripts/gcc-goto.sh | 22 ---------------------- tools/arch/x86/include/asm/rmwcc.h | 21 --------------------- 10 files changed, 7 insertions(+), 89 deletions(-) delete mode 100755 scripts/gcc-goto.sh (limited to 'scripts') diff --git a/Documentation/kbuild/kconfig-language.rst b/Documentation/kbuild/kconfig-language.rst index 7fb398649f51..858ed5d80def 100644 --- a/Documentation/kbuild/kconfig-language.rst +++ b/Documentation/kbuild/kconfig-language.rst @@ -525,8 +525,8 @@ followed by a test macro:: If you need to expose a compiler capability to makefiles and/or C source files, `CC_HAS_` is the recommended prefix for the config option:: - config CC_HAS_ASM_GOTO - def_bool $(success,$(srctree)/scripts/gcc-goto.sh $(CC)) + config CC_HAS_FOO + def_bool $(success,$(srctree)/scripts/cc-check-foo.sh $(CC)) Build as module only ~~~~~~~~~~~~~~~~~~~~ diff --git a/arch/Kconfig b/arch/Kconfig index f330410da63a..5dbf11a5ba4e 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -53,7 +53,6 @@ config KPROBES config JUMP_LABEL bool "Optimize very unlikely/likely branches" depends on HAVE_ARCH_JUMP_LABEL - depends on CC_HAS_ASM_GOTO select OBJTOOL if HAVE_JUMP_LABEL_HACK help This option enables a transparent branch optimization that @@ -1361,7 +1360,7 @@ config HAVE_PREEMPT_DYNAMIC_CALL config HAVE_PREEMPT_DYNAMIC_KEY bool - depends on HAVE_ARCH_JUMP_LABEL && CC_HAS_ASM_GOTO + depends on HAVE_ARCH_JUMP_LABEL select HAVE_PREEMPT_DYNAMIC help An architecture should select this if it can handle the preemption diff --git a/arch/um/include/asm/cpufeature.h b/arch/um/include/asm/cpufeature.h index 19cd7ed6ec3c..4b6d1b526bc1 100644 --- a/arch/um/include/asm/cpufeature.h +++ b/arch/um/include/asm/cpufeature.h @@ -65,20 +65,6 @@ extern void setup_clear_cpu_cap(unsigned int bit); #define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit) -#if defined(__clang__) && !defined(CONFIG_CC_HAS_ASM_GOTO) - -/* - * Workaround for the sake of BPF compilation which utilizes kernel - * headers, but clang does not support ASM GOTO and fails the build. - */ -#ifndef __BPF_TRACING__ -#warning "Compiler lacks ASM_GOTO support. Add -D __BPF_TRACING__ to your compiler arguments" -#endif - -#define static_cpu_has(bit) boot_cpu_has(bit) - -#else - /* * Static testing of CPU features. Used the same as boot_cpu_has(). It * statically patches the target code for additional performance. Use @@ -137,7 +123,6 @@ t_no: boot_cpu_has(bit) : \ _static_cpu_has(bit) \ ) -#endif #define cpu_has_bug(c, bit) cpu_has(c, (bit)) #define set_cpu_bug(c, bit) set_cpu_cap(c, (bit)) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 7854685c5f25..bafbd905e6e7 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -286,10 +286,6 @@ vdso_install: archprepare: checkbin checkbin: -ifndef CONFIG_CC_HAS_ASM_GOTO - @echo Compiler lacks asm-goto support. - @exit 1 -endif ifdef CONFIG_RETPOLINE ifeq ($(RETPOLINE_CFLAGS),) @echo "You are building kernel with non-retpoline compiler." >&2 diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index ea34cc31b047..1a85e1fb0922 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -155,20 +155,6 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit); #define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit) -#if defined(__clang__) && !defined(CONFIG_CC_HAS_ASM_GOTO) - -/* - * Workaround for the sake of BPF compilation which utilizes kernel - * headers, but clang does not support ASM GOTO and fails the build. - */ -#ifndef __BPF_TRACING__ -#warning "Compiler lacks ASM_GOTO support. Add -D __BPF_TRACING__ to your compiler arguments" -#endif - -#define static_cpu_has(bit) boot_cpu_has(bit) - -#else - /* * Static testing of CPU features. Used the same as boot_cpu_has(). It * statically patches the target code for additional performance. Use @@ -208,7 +194,6 @@ t_no: boot_cpu_has(bit) : \ _static_cpu_has(bit) \ ) -#endif #define cpu_has_bug(c, bit) cpu_has(c, (bit)) #define set_cpu_bug(c, bit) set_cpu_cap(c, (bit)) diff --git a/arch/x86/include/asm/rmwcc.h b/arch/x86/include/asm/rmwcc.h index 8a9eba191516..7fa611216417 100644 --- a/arch/x86/include/asm/rmwcc.h +++ b/arch/x86/include/asm/rmwcc.h @@ -11,7 +11,7 @@ #define __CLOBBERS_MEM(clb...) "memory", ## clb -#if !defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(CONFIG_CC_HAS_ASM_GOTO) +#ifndef __GCC_ASM_FLAG_OUTPUTS__ /* Use asm goto */ @@ -27,7 +27,7 @@ cc_label: c = true; \ c; \ }) -#else /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CONFIG_CC_HAS_ASM_GOTO) */ +#else /* defined(__GCC_ASM_FLAG_OUTPUTS__) */ /* Use flags output or a set instruction */ @@ -40,7 +40,7 @@ cc_label: c = true; \ c; \ }) -#endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CONFIG_CC_HAS_ASM_GOTO) */ +#endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) */ #define GEN_UNARY_RMWcc_4(op, var, cc, arg0) \ __GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM()) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index f092c54d1a2f..d5ec3a2ed5a4 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -479,7 +479,7 @@ FOP_END; /* * XXX: inoutclob user must know where the argument is being expanded. - * Relying on CONFIG_CC_HAS_ASM_GOTO would allow us to remove _fault. + * Using asm goto would allow us to remove _fault. */ #define asm_safe(insn, inoutclob...) \ ({ \ diff --git a/init/Kconfig b/init/Kconfig index 80fe60fa77fb..532362fcfe31 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -70,11 +70,7 @@ config CC_CAN_LINK_STATIC default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(CLANG_FLAGS) $(USERCFLAGS) $(USERLDFLAGS) $(m64-flag) -static) if 64BIT default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(CLANG_FLAGS) $(USERCFLAGS) $(USERLDFLAGS) $(m32-flag) -static) -config CC_HAS_ASM_GOTO - def_bool $(success,$(srctree)/scripts/gcc-goto.sh $(CC)) - config CC_HAS_ASM_GOTO_OUTPUT - depends on CC_HAS_ASM_GOTO def_bool $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null) config CC_HAS_ASM_GOTO_TIED_OUTPUT diff --git a/scripts/gcc-goto.sh b/scripts/gcc-goto.sh deleted file mode 100755 index 8b980fb2270a..000000000000 --- a/scripts/gcc-goto.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 -# Test for gcc 'asm goto' support -# Copyright (C) 2010, Jason Baron - -cat << "END" | $@ -x c - -fno-PIE -c -o /dev/null -int main(void) -{ -#if defined(__arm__) || defined(__aarch64__) - /* - * Not related to asm goto, but used by jump label - * and broken on some ARM GCC versions (see GCC Bug 48637). - */ - static struct { int dummy; int state; } tp; - asm (".long %c0" :: "i" (&tp.state)); -#endif - -entry: - asm goto ("" :::: entry); - return 0; -} -END diff --git a/tools/arch/x86/include/asm/rmwcc.h b/tools/arch/x86/include/asm/rmwcc.h index fee7983a90b4..11ff975242ca 100644 --- a/tools/arch/x86/include/asm/rmwcc.h +++ b/tools/arch/x86/include/asm/rmwcc.h @@ -2,8 +2,6 @@ #ifndef _TOOLS_LINUX_ASM_X86_RMWcc #define _TOOLS_LINUX_ASM_X86_RMWcc -#ifdef CONFIG_CC_HAS_ASM_GOTO - #define __GEN_RMWcc(fullop, var, cc, ...) \ do { \ asm_volatile_goto (fullop "; j" cc " %l[cc_label]" \ @@ -20,23 +18,4 @@ cc_label: \ #define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \ __GEN_RMWcc(op " %1, " arg0, var, cc, vcon (val)) -#else /* !CONFIG_CC_HAS_ASM_GOTO */ - -#define __GEN_RMWcc(fullop, var, cc, ...) \ -do { \ - char c; \ - asm volatile (fullop "; set" cc " %1" \ - : "+m" (var), "=qm" (c) \ - : __VA_ARGS__ : "memory"); \ - return c != 0; \ -} while (0) - -#define GEN_UNARY_RMWcc(op, var, arg0, cc) \ - __GEN_RMWcc(op " " arg0, var, cc) - -#define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \ - __GEN_RMWcc(op " %2, " arg0, var, cc, vcon (val)) - -#endif /* CONFIG_CC_HAS_ASM_GOTO */ - #endif /* _TOOLS_LINUX_ASM_X86_RMWcc */ -- cgit v1.2.3 From fd0a38f9c37d539f5603f887cdb637a4e6e6944d Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Tue, 23 Aug 2022 16:53:26 +0100 Subject: scripts/bpf: Set version attribute for bpf-helpers(7) man page The bpf-helpers(7) manual page shipped in the man-pages project is generated from the documentation contained in the BPF UAPI header, in the Linux repository, parsed by script/bpf_doc.py and then fed to rst2man. After a recent update of that page [0], Alejandro reported that the linter used to validate the man pages complains about the generated document [1]. The header for the page is supposed to contain some attributes that we do not set correctly with the script. This commit updates the "project and version" field. We discussed the format of those fields in [1] and [2]. Before: $ ./scripts/bpf_doc.py helpers | rst2man | grep '\.TH' .TH BPF-HELPERS 7 "" "" "" After: $ ./scripts/bpf_doc.py helpers | rst2man | grep '\.TH' .TH BPF-HELPERS 7 "" "Linux v5.19-14022-g30d2a4d74e11" "" We get the version from "git describe", but if unavailable, we fall back on "make kernelversion". If none works, for example because neither git nore make are installed, we just set the field to "Linux" and keep generating the page. [0] https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/commit/man7/bpf-helpers.7?id=19c7f78393f2b038e76099f87335ddf43a87f039 [1] https://lore.kernel.org/all/20220823084719.13613-1-quentin@isovalent.com/t/#m58a418a318642c6428e14ce9bb84eba5183b06e8 [2] https://lore.kernel.org/all/20220721110821.8240-1-alx.manpages@gmail.com/t/#m8e689a822e03f6e2530a0d6de9d128401916c5de Reported-by: Alejandro Colomar Signed-off-by: Quentin Monnet Signed-off-by: Daniel Borkmann Reviewed-by: Alejandro Colomar Link: https://lore.kernel.org/bpf/20220823155327.98888-1-quentin@isovalent.com --- scripts/bpf_doc.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index dfb260de17a8..061ad1dc3212 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -10,6 +10,8 @@ from __future__ import print_function import argparse import re import sys, os +import subprocess + class NoHelperFound(BaseException): pass @@ -357,6 +359,20 @@ class PrinterRST(Printer): print('') + def get_kernel_version(self): + try: + version = subprocess.run(['git', 'describe'], cwd=linuxRoot, + capture_output=True, check=True) + version = version.stdout.decode().rstrip() + except: + try: + version = subprocess.run(['make', 'kernelversion'], cwd=linuxRoot, + capture_output=True, check=True) + version = version.stdout.decode().rstrip() + except: + return 'Linux' + return 'Linux {version}'.format(version=version) + class PrinterHelpersRST(PrinterRST): """ A printer for dumping collected information about helpers as a ReStructured @@ -378,6 +394,7 @@ list of eBPF helper functions ------------------------------------------------------------------------------- :Manual section: 7 +:Version: {version} DESCRIPTION =========== @@ -410,8 +427,10 @@ kernel at the top). HELPERS ======= ''' + kernelVersion = self.get_kernel_version() + PrinterRST.print_license(self) - print(header) + print(header.format(version=kernelVersion)) def print_footer(self): footer = ''' -- cgit v1.2.3 From 92ec1cc3784a2a8a7a62596dcec4f2224b85dcf4 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Tue, 23 Aug 2022 16:53:27 +0100 Subject: scripts/bpf: Set date attribute for bpf-helpers(7) man page The bpf-helpers(7) manual page shipped in the man-pages project is generated from the documentation contained in the BPF UAPI header, in the Linux repository, parsed by script/bpf_doc.py and then fed to rst2man. The man page should contain the date of last modification of the documentation. This commit adds the relevant date when generating the page. Before: $ ./scripts/bpf_doc.py helpers | rst2man | grep '\.TH' .TH BPF-HELPERS 7 "" "Linux v5.19-14022-g30d2a4d74e11" "" After: $ ./scripts/bpf_doc.py helpers | rst2man | grep '\.TH' .TH BPF-HELPERS 7 "2022-08-15" "Linux v5.19-14022-g30d2a4d74e11" "" We get the version by using "git log" to look for the commit date of the latest change to the section of the BPF header containing the documentation. If the command fails, we just skip the date field. and keep generating the page. Reported-by: Alejandro Colomar Signed-off-by: Quentin Monnet Signed-off-by: Daniel Borkmann Reviewed-by: Alejandro Colomar Link: https://lore.kernel.org/bpf/20220823155327.98888-2-quentin@isovalent.com --- scripts/bpf_doc.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index 061ad1dc3212..f4f3e7ec6d44 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -12,6 +12,7 @@ import re import sys, os import subprocess +helpersDocStart = 'Start of BPF helper function descriptions:' class NoHelperFound(BaseException): pass @@ -235,7 +236,7 @@ class HeaderParser(object): self.enum_syscalls = re.findall('(BPF\w+)+', bpf_cmd_str) def parse_desc_helpers(self): - self.seek_to('* Start of BPF helper function descriptions:', + self.seek_to(helpersDocStart, 'Could not find start of eBPF helper descriptions list') while True: try: @@ -373,6 +374,17 @@ class PrinterRST(Printer): return 'Linux' return 'Linux {version}'.format(version=version) + def get_last_doc_update(self, delimiter): + try: + cmd = ['git', 'log', '-1', '--pretty=format:%cs', '--no-patch', + '-L', + '/{}/,/\*\//:include/uapi/linux/bpf.h'.format(delimiter)] + date = subprocess.run(cmd, cwd=linuxRoot, + capture_output=True, check=True) + return date.stdout.decode().rstrip() + except: + return '' + class PrinterHelpersRST(PrinterRST): """ A printer for dumping collected information about helpers as a ReStructured @@ -395,6 +407,7 @@ list of eBPF helper functions :Manual section: 7 :Version: {version} +{date_field}{date} DESCRIPTION =========== @@ -428,9 +441,12 @@ HELPERS ======= ''' kernelVersion = self.get_kernel_version() + lastUpdate = self.get_last_doc_update(helpersDocStart) PrinterRST.print_license(self) - print(header.format(version=kernelVersion)) + print(header.format(version=kernelVersion, + date_field = ':Date: ' if lastUpdate else '', + date=lastUpdate)) def print_footer(self): footer = ''' -- cgit v1.2.3 From 0a0d55ef3e61d9f14e803cacb644fcc890f16774 Mon Sep 17 00:00:00 2001 From: Eyal Birger Date: Wed, 24 Aug 2022 21:10:43 +0300 Subject: bpf/scripts: Assert helper enum value is aligned with comment order The helper value is ABI as defined by enum bpf_func_id. As bpf_helper_defs.h is used for the userpace part, it must be consistent with this enum. Before this change the comments order was used by the bpf_doc script in order to set the helper values defined in the helpers file. When adding new helpers it is very puzzling when the userspace application breaks in weird places if the comment is inserted instead of appended - because the generated helper ABI is incorrect and shifted. This commit sets the helper value to the enum value. In addition it is currently the practice to have the comments appended and kept in the same order as the enum. As such, add an assertion validating the comment order is consistent with enum value. In case a different comments ordering is desired, this assertion can be lifted. Signed-off-by: Eyal Birger Signed-off-by: Andrii Nakryiko Reviewed-by: Quentin Monnet Link: https://lore.kernel.org/bpf/20220824181043.1601429-1-eyal.birger@gmail.com --- scripts/bpf_doc.py | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index f4f3e7ec6d44..d5c389df6045 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -50,6 +50,10 @@ class Helper(APIElement): @desc: textual description of the helper function @ret: description of the return value of the helper function """ + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.enum_val = None + def proto_break_down(self): """ Break down helper function protocol into smaller chunks: return type, @@ -92,6 +96,7 @@ class HeaderParser(object): self.commands = [] self.desc_unique_helpers = set() self.define_unique_helpers = [] + self.helper_enum_vals = {} self.desc_syscalls = [] self.enum_syscalls = [] @@ -248,30 +253,54 @@ class HeaderParser(object): break def parse_define_helpers(self): - # Parse the number of FN(...) in #define __BPF_FUNC_MAPPER to compare - # later with the number of unique function names present in description. + # Parse FN(...) in #define __BPF_FUNC_MAPPER to compare later with the + # number of unique function names present in description and use the + # correct enumeration value. # Note: seek_to(..) discards the first line below the target search text, # resulting in FN(unspec) being skipped and not added to self.define_unique_helpers. self.seek_to('#define __BPF_FUNC_MAPPER(FN)', 'Could not find start of eBPF helper definition list') - # Searches for either one or more FN(\w+) defines or a backslash for newline - p = re.compile('\s*(FN\(\w+\))+|\\\\') + # Searches for one FN(\w+) define or a backslash for newline + p = re.compile('\s*FN\((\w+)\)|\\\\') fn_defines_str = '' + i = 1 # 'unspec' is skipped as mentioned above while True: capture = p.match(self.line) if capture: fn_defines_str += self.line + self.helper_enum_vals[capture.expand(r'bpf_\1')] = i + i += 1 else: break self.line = self.reader.readline() # Find the number of occurences of FN(\w+) self.define_unique_helpers = re.findall('FN\(\w+\)', fn_defines_str) + def assign_helper_values(self): + seen_helpers = set() + for helper in self.helpers: + proto = helper.proto_break_down() + name = proto['name'] + try: + enum_val = self.helper_enum_vals[name] + except KeyError: + raise Exception("Helper %s is missing from enum bpf_func_id" % name) + + # Enforce current practice of having the descriptions ordered + # by enum value. + seen_helpers.add(name) + desc_val = len(seen_helpers) + if desc_val != enum_val: + raise Exception("Helper %s comment order (#%d) must be aligned with its position (#%d) in enum bpf_func_id" % (name, desc_val, enum_val)) + + helper.enum_val = enum_val + def run(self): self.parse_desc_syscall() self.parse_enum_syscall() self.parse_desc_helpers() self.parse_define_helpers() + self.assign_helper_values() self.reader.close() ############################################################################### @@ -796,7 +825,7 @@ class PrinterHelpers(Printer): comma = ', ' print(one_arg, end='') - print(') = (void *) %d;' % len(self.seen_helpers)) + print(') = (void *) %d;' % helper.enum_val) print('') ############################################################################### -- cgit v1.2.3 From 86879fd277e8e76bf29d10c23e7562d86b9286a0 Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Thu, 25 Aug 2022 11:15:17 +0200 Subject: scripts: remove obsolete gcc-ld script Since commit 8564ed2b3888 ("Kbuild, lto: Add a gcc-ld script to let run gcc as ld") in 2014, there was not specific work on this the gcc-ld script other than treewide clean-ups. There are no users within the kernel tree, and probably no out-of-tree users either, and there is no dedicated maintainer in MAINTAINERS. Delete this obsolete gcc-ld script. Signed-off-by: Lukas Bulwahn Reviewed-by: Nick Desaulniers Signed-off-by: Masahiro Yamada --- scripts/gcc-ld | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100755 scripts/gcc-ld (limited to 'scripts') diff --git a/scripts/gcc-ld b/scripts/gcc-ld deleted file mode 100755 index 997b818c3962..000000000000 --- a/scripts/gcc-ld +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 -# run gcc with ld options -# used as a wrapper to execute link time optimizations -# yes virginia, this is not pretty - -ARGS="-nostdlib" - -while [ "$1" != "" ] ; do - case "$1" in - -save-temps|-m32|-m64) N="$1" ;; - -r) N="$1" ;; - -[Wg]*) N="$1" ;; - -[olv]|-[Ofd]*|-nostdlib) N="$1" ;; - --end-group|--start-group) - N="-Wl,$1" ;; - -[RTFGhIezcbyYu]*|\ ---script|--defsym|-init|-Map|--oformat|-rpath|\ --rpath-link|--sort-section|--section-start|-Tbss|-Tdata|-Ttext|\ ---version-script|--dynamic-list|--version-exports-symbol|--wrap|-m) - A="$1" ; shift ; N="-Wl,$A,$1" ;; - -[m]*) N="$1" ;; - -*) N="-Wl,$1" ;; - *) N="$1" ;; - esac - ARGS="$ARGS $N" - shift -done - -exec $CC $ARGS -- cgit v1.2.3 From c11efc57d4ccca47c5cf89341c4500acbb2c7599 Mon Sep 17 00:00:00 2001 From: Thitat Auareesuksakul Date: Thu, 25 Aug 2022 03:03:40 +0700 Subject: scripts/extract-ikconfig: add zstd compression support Add extract-ikconfig support for kernel images compressed with zstd. Signed-off-by: Thitat Auareesuksakul Tested-by: Nicolas Schier Signed-off-by: Masahiro Yamada --- scripts/extract-ikconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/extract-ikconfig b/scripts/extract-ikconfig index 3b42f255e2ba..8df33e7d6daa 100755 --- a/scripts/extract-ikconfig +++ b/scripts/extract-ikconfig @@ -62,6 +62,7 @@ try_decompress 'BZh' xy bunzip2 try_decompress '\135\0\0\0' xxx unlzma try_decompress '\211\114\132' xy 'lzop -d' try_decompress '\002\041\114\030' xyy 'lz4 -d -l' +try_decompress '\050\265\057\375' xxx unzstd # Bail out: echo "$me: Cannot find kernel config." >&2 -- cgit v1.2.3 From b0839b281c427e844143dba3893e25c83cdd6c17 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Thu, 1 Sep 2022 10:59:13 -0700 Subject: Makefile.extrawarn: re-enable -Wformat for clang; take 2 -Wformat was recently re-enabled for builds with clang, then quickly re-disabled, due to concerns stemming from the frequency of default argument promotion related warning instances. commit 258fafcd0683 ("Makefile.extrawarn: re-enable -Wformat for clang") commit 21f9c8a13bb2 ("Revert "Makefile.extrawarn: re-enable -Wformat for clang"") ISO WG14 has ratified N2562 to address default argument promotion explicitly for printf, as part of the upcoming ISO C2X standard. The behavior of clang was changed in clang-16 to not warn for the cited cases in all language modes. Add a version check, so that users of clang-16 now get the full effect of -Wformat. For older clang versions, re-enable flags under the -Wformat group that way users still get some useful checks related to format strings, without noisy default argument promotion warnings. I intentionally omitted -Wformat-y2k and -Wformat-security from being re-enabled, which are also part of -Wformat in clang-16. Link: https://github.com/ClangBuiltLinux/linux/issues/378 Link: https://github.com/llvm/llvm-project/issues/57102 Link: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf Suggested-by: Justin Stitt Suggested-by: Nathan Chancellor Suggested-by: Youngmin Nam Signed-off-by: Nick Desaulniers Reviewed-by: Masahiro Yamada Reviewed-by: Nathan Chancellor Signed-off-by: Linus Torvalds --- scripts/Makefile.extrawarn | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 0621c39a3955..6ae482158bc4 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -47,7 +47,19 @@ else ifdef CONFIG_CC_IS_CLANG KBUILD_CFLAGS += -Wno-initializer-overrides +# Clang before clang-16 would warn on default argument promotions. +ifeq ($(shell [ $(CONFIG_CLANG_VERSION) -lt 160000 ] && echo y),y) +# Disable -Wformat KBUILD_CFLAGS += -Wno-format +# Then re-enable flags that were part of the -Wformat group that aren't +# problematic. +KBUILD_CFLAGS += -Wformat-extra-args -Wformat-invalid-specifier +KBUILD_CFLAGS += -Wformat-zero-length -Wnonnull +# Requires clang-12+. +ifeq ($(shell [ $(CONFIG_CLANG_VERSION) -ge 120000 ] && echo y),y) +KBUILD_CFLAGS += -Wformat-insufficient-args +endif +endif KBUILD_CFLAGS += -Wno-sign-compare KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast) KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare -- cgit v1.2.3 From c17a2538704f926ee4d167ba625e09b1040d8439 Mon Sep 17 00:00:00 2001 From: Youling Tang Date: Thu, 1 Sep 2022 19:10:59 +0800 Subject: mksysmap: Fix the mismatch of 'L0' symbols in System.map When System.map was generated, the kernel used mksysmap to filter the kernel symbols, we need to filter "L0" symbols in LoongArch architecture. $ cat System.map | grep L0 9000000000221540 t L0 The L0 symbol exists in System.map, but not in .tmp_System.map. When "cmp -s System.map .tmp_System.map" will show "Inconsistent kallsyms data" error message in link-vmlinux.sh script. Signed-off-by: Youling Tang Signed-off-by: Masahiro Yamada --- scripts/mksysmap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mksysmap b/scripts/mksysmap index 9aa23d15862a..ad8bbc52267d 100755 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -41,4 +41,4 @@ # so we just ignore them to let readprofile continue to work. # (At least sparc64 has __crc_ in the middle). -$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)\|\( \.L\)' > $2 +$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)\|\( \.L\)\|\( L0\)' > $2 -- cgit v1.2.3 From 765f2bf04fdaced4e7d7e94cfc3f743048629f31 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 8 Aug 2022 10:59:28 +0200 Subject: scripts/decodecode: improve faulting line determination There are cases where the IP pointer in a Code: line in an oops doesn't point at the beginning of an instruction: Code: 0f bd c2 e9 a0 cd b5 e4 48 0f bd c2 e9 97 cd b5 e4 0f 1f 80 00 00 00 00 \ e9 8b cd b5 e4 0f 1f 00 66 0f a3 d0 e9 7f cd b5 e4 0f 1f <80> 00 00 00 \ 00 0f a3 d0 e9 70 cd b5 e4 48 0f a3 d0 e9 67 cd b5 e9 7f cd b5 e4 jmp 0xffffffffe4b5cda8 0f 1f 80 00 00 00 00 nopl 0x0(%rax) ^^ and the current way of determining the faulting instruction line doesn't work because disassembled instructions are counted from the IP byte to the end and when that thing points in the middle, the trailing bytes can be interpreted as different insns: Code starting with the faulting instruction =========================================== 0: 80 00 00 addb $0x0,(%rax) 3: 00 00 add %al,(%rax) whereas, this is part of 0f 1f 80 00 00 00 00 nopl 0x0(%rax) 5: 0f a3 d0 bt %edx,%eax ... leading to: 1d: 0f 1f 00 nopl (%rax) 20: 66 0f a3 d0 bt %dx,%ax 24:* e9 7f cd b5 e4 jmp 0xffffffffe4b5cda8 <-- trapping instruction 29: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) 30: 0f a3 d0 bt %edx,%eax which is the wrong faulting instruction. Change the way the faulting line number is determined by matching the opcode bytes from the beginning, leading to correct output: 1d: 0f 1f 00 nopl (%rax) 20: 66 0f a3 d0 bt %dx,%ax 24: e9 7f cd b5 e4 jmp 0xffffffffe4b5cda8 29:* 0f 1f 80 00 00 00 00 nopl 0x0(%rax) <-- trapping instruction 30: 0f a3 d0 bt %edx,%eax While at it, make decodecode use bash as the interpreter - that thing should be present on everything by now. It simplifies the code a lot too. Link: https://lkml.kernel.org/r/20220808085928.29840-1-bp@alien8.de Signed-off-by: Borislav Petkov Cc: Marc Zyngier Cc: Will Deacon Signed-off-by: Andrew Morton --- scripts/decodecode | 120 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 105 insertions(+), 15 deletions(-) (limited to 'scripts') diff --git a/scripts/decodecode b/scripts/decodecode index c711a196511c..b28fd2686561 100755 --- a/scripts/decodecode +++ b/scripts/decodecode @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # SPDX-License-Identifier: GPL-2.0 # Disassemble the Code: line in Linux oopses # usage: decodecode < oops.file @@ -8,6 +8,8 @@ # AFLAGS=--32 decodecode < 386.oops # PC=hex - the PC (program counter) the oops points to +faultlinenum=1 + cleanup() { rm -f $T $T.s $T.o $T.oo $T.aa $T.dis exit 1 @@ -102,28 +104,125 @@ disas() { grep -v "/tmp\|Disassembly\|\.text\|^$" > $t.dis 2>&1 } +# Match the maximum number of opcode bytes from @op_bytes contained within +# @opline +# +# Params: +# @op_bytes: The string of bytes from the Code: line +# @opline: The disassembled line coming from objdump +# +# Returns: +# The max number of opcode bytes from the beginning of @op_bytes which match +# the opcode bytes in the objdump line. +get_substr_opcode_bytes_num() +{ + local op_bytes=$1 + local opline=$2 + + local retval=0 + substr="" + + for opc in $op_bytes; + do + substr+="$opc" + + # return if opcode bytes do not match @opline anymore + if ! echo $opline | grep -q "$substr"; + then + break + fi + + # add trailing space + substr+=" " + retval=$((retval+1)) + done + + return $retval +} + +# Return the line number in objdump output to where the IP marker in the Code: +# line points to +# +# Params: +# @all_code: code in bytes without the marker +# @dis_file: disassembled file +# @ip_byte: The byte to which the IP points to +get_faultlinenum() +{ + local all_code="$1" + local dis_file="$2" + + # num bytes including IP byte + local num_bytes_ip=$(( $3 + 1 * $width )) + + # Add the two header lines (we're counting from 1). + local retval=3 + + # remove marker + all_code=$(echo $all_code | sed -e 's/[<>()]//g') + + while read line + do + get_substr_opcode_bytes_num "$all_code" "$line" + ate_opcodes=$? + + if ! (( $ate_opcodes )); then + continue + fi + + num_bytes_ip=$((num_bytes_ip - ($ate_opcodes * $width) )) + if (( $num_bytes_ip <= 0 )); then + break + fi + + # Delete matched opcode bytes from all_code. For that, compute + # how many chars those opcodes are represented by and include + # trailing space. + # + # a byte is 2 chars, ate_opcodes is also the number of trailing + # spaces + del_chars=$(( ($ate_opcodes * $width * 2) + $ate_opcodes )) + + all_code=$(echo $all_code | sed -e "s!^.\{$del_chars\}!!") + + let "retval+=1" + + done < $dis_file + + return $retval +} + marker=`expr index "$code" "\<"` if [ $marker -eq 0 ]; then marker=`expr index "$code" "\("` fi - touch $T.oo if [ $marker -ne 0 ]; then - # 2 opcode bytes and a single space - pc_sub=$(( $marker / 3 )) + # How many bytes to subtract from the program counter + # in order to get to the beginning virtual address of the + # Code: + pc_sub=$(( (($marker - 1) / (2 * $width + 1)) * $width )) echo All code >> $T.oo echo ======== >> $T.oo beforemark=`echo "$code"` echo -n " .$type 0x" > $T.s + echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s + disas $T $pc_sub + cat $T.dis >> $T.oo - rm -f $T.o $T.s $T.dis -# and fix code at-and-after marker + get_faultlinenum "$code" "$T.dis" $pc_sub + faultlinenum=$? + + # and fix code at-and-after marker code=`echo "$code" | cut -c$((${marker} + 1))-` + + rm -f $T.o $T.s $T.dis fi + echo Code starting with the faulting instruction > $T.aa echo =========================================== >> $T.aa code=`echo $code | sed -e 's/\r//;s/ [<(]/ /;s/[>)] / /;s/ /,0x/g; s/[>)]$//'` @@ -132,15 +231,6 @@ echo $code >> $T.s disas $T 0 cat $T.dis >> $T.aa -# (lines of whole $T.oo) - (lines of $T.aa, i.e. "Code starting") + 3, -# i.e. the title + the "===..=" line (sed is counting from 1, 0 address is -# special) -faultlinenum=$(( $(wc -l $T.oo | cut -d" " -f1) - \ - $(wc -l $T.aa | cut -d" " -f1) + 3)) - -faultline=`cat $T.dis | head -1 | cut -d":" -f2-` -faultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'` - cat $T.oo | sed -e "${faultlinenum}s/^\([^:]*:\)\(.*\)/\1\*\2\t\t<-- trapping instruction/" echo cat $T.aa -- cgit v1.2.3 From defdaff15a84c68521c5f02b157fc8541e0356f3 Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Sat, 13 Aug 2022 15:00:34 -0700 Subject: checkpatch: add kmap and kmap_atomic to the deprecated list kmap() and kmap_atomic() are being deprecated in favor of kmap_local_page(). There are two main problems with kmap(): (1) It comes with an overhead as mapping space is restricted and protected by a global lock for synchronization and (2) it also requires global TLB invalidation when the kmap's pool wraps and it might block when the mapping space is fully utilized until a slot becomes available. kmap_local_page() is safe from any context and is therefore redundant with kmap_atomic() with the exception of any pagefault or preemption disable requirements. However, using kmap_atomic() for these side effects makes the code less clear. So any requirement for pagefault or preemption disable should be made explicitly. With kmap_local_page() the mappings are per thread, CPU local, can take page faults, and can be called from any context (including interrupts). It is faster than kmap() in kernels with HIGHMEM enabled. Furthermore, the tasks can be preempted and, when they are scheduled to run again, the kernel virtual addresses are restored. Link: https://lkml.kernel.org/r/20220813220034.806698-1-ira.weiny@intel.com Signed-off-by: Ira Weiny Suggested-by: Thomas Gleixner Suggested-by: Fabio M. De Francesco Reviewed-by: Chaitanya Kulkarni Cc: Joe Perches 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 79e759aac543..9ff219e0a9d5 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -807,6 +807,8 @@ our %deprecated_apis = ( "rcu_barrier_sched" => "rcu_barrier", "get_state_synchronize_sched" => "get_state_synchronize_rcu", "cond_synchronize_sched" => "cond_synchronize_rcu", + "kmap" => "kmap_local_page", + "kmap_atomic" => "kmap_local_page", ); #Create a search pattern for all these strings to speed up a loop below -- cgit v1.2.3 From 8ea0114eda0c1c85f8f01922ac8fc1e489a61129 Mon Sep 17 00:00:00 2001 From: Mickaël Salaün Date: Fri, 2 Sep 2022 13:19:23 +0200 Subject: checkpatch: handle FILE pointer type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using a "FILE *" type, checkpatch considers this an error: ERROR: need consistent spacing around '*' (ctx:WxV) #32: FILE: f.c:8: +static void a(FILE *const b) ^ Fix this by explicitly defining "FILE" as a common type. This is useful for user space patches. With this patch, we now get: <_>WS( ) <_>IDENT(static) <_>WS( ) <_>DECLARE(void ) <_>FUNC(a) PAREN('(') <_>DECLARE(FILE *const ) <_>IDENT(b) <_>PAREN(')') -> V <_>WS( ) 32 > . static void a(FILE *const b) 32 > EEVVVVVVVTTTTTVNTTTTTTTTTTTTVVV 32 > ______________________________ Link: https://lkml.kernel.org/r/20220902111923.1488671-1-mic@digikod.net Link: https://lore.kernel.org/r/20220902111923.1488671-1-mic@digikod.net Signed-off-by: Mickaël Salaün Acked-by: Joe Perches Cc: Andy Whitcroft Cc: Dwaipayan Ray Cc: Lukas Bulwahn Signed-off-by: Andrew Morton --- scripts/checkpatch.pl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 9ff219e0a9d5..18effbe1fe90 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -576,10 +576,14 @@ our $typeKernelTypedefs = qr{(?x: (?:__)?(?:u|s|be|le)(?:8|16|32|64)| atomic_t )}; +our $typeStdioTypedefs = qr{(?x: + FILE +)}; our $typeTypedefs = qr{(?x: $typeC99Typedefs\b| $typeOtherOSTypedefs\b| - $typeKernelTypedefs\b + $typeKernelTypedefs\b| + $typeStdioTypedefs\b )}; our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; -- cgit v1.2.3 From c969bb8dbaf2f3628927eae73e7c579a74cf1b6e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 20 Sep 2022 19:12:52 +0200 Subject: selinux: use "grep -E" instead of "egrep" The latest version of grep claims that egrep is now obsolete so the build now contains warnings that look like: egrep: warning: egrep is obsolescent; using grep -E fix this by using "grep -E" instead. Cc: Paul Moore Cc: Stephen Smalley Cc: Eric Paris Cc: selinux@vger.kernel.org Signed-off-by: Greg Kroah-Hartman [PM: tweak to remove vdso reference, cleanup subj line] Signed-off-by: Paul Moore --- scripts/selinux/install_policy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh index 2dccf141241d..20af56ce245c 100755 --- a/scripts/selinux/install_policy.sh +++ b/scripts/selinux/install_policy.sh @@ -78,7 +78,7 @@ cd /etc/selinux/dummy/contexts/files $SF -F file_contexts / mounts=`cat /proc/$$/mounts | \ - egrep "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \ + grep -E "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \ awk '{ print $2 '}` $SF -F file_contexts $mounts -- cgit v1.2.3 From 2fe2fb4ce60be9005d7bfdd5665be03b8efb5b13 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Tue, 20 Sep 2022 14:11:11 -0400 Subject: selinux: remove runtime disable message in the install_policy.sh script We are in the process of deprecating the runtime disable mechanism, let's not reference it in the scripts. Signed-off-by: Paul Moore --- scripts/selinux/install_policy.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh index 20af56ce245c..24086793b0d8 100755 --- a/scripts/selinux/install_policy.sh +++ b/scripts/selinux/install_policy.sh @@ -31,8 +31,7 @@ fi if selinuxenabled; then echo "SELinux is already enabled" echo "This prevents safely relabeling all files." - echo "Boot with selinux=0 on the kernel command-line or" - echo "SELINUX=disabled in /etc/selinux/config." + echo "Boot with selinux=0 on the kernel command-line." exit 1 fi -- cgit v1.2.3 From 237fe72749425f2cd3132bf54fa6b98807c27938 Mon Sep 17 00:00:00 2001 From: yangxingwu Date: Tue, 13 Sep 2022 04:07:53 +0000 Subject: scripts/clang-tools: remove unused module Remove unused imported 'os' module. Signed-off-by: yangxingwu Reviewed-by: Nathan Chancellor Signed-off-by: Masahiro Yamada --- scripts/clang-tools/run-clang-tools.py | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/clang-tools/run-clang-tools.py b/scripts/clang-tools/run-clang-tools.py index 1337cedca096..bb78c9bde55c 100755 --- a/scripts/clang-tools/run-clang-tools.py +++ b/scripts/clang-tools/run-clang-tools.py @@ -12,7 +12,6 @@ compile_commands.json. import argparse import json import multiprocessing -import os import subprocess import sys -- cgit v1.2.3 From 03764b30a4f0185a97515d616e60e2e00c558583 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Mon, 12 Sep 2022 17:48:38 +0800 Subject: Kconfig: remove unused function 'menu_get_root_menu' There is nowhere calling `menu_get_root_menu` function, so remove it. Signed-off-by: Zeng Heng Signed-off-by: Masahiro Yamada --- scripts/kconfig/lkc.h | 1 - scripts/kconfig/menu.c | 5 ----- 2 files changed, 6 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index fa8c010aa683..c396aa104090 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -98,7 +98,6 @@ bool menu_is_empty(struct menu *menu); bool menu_is_visible(struct menu *menu); bool menu_has_prompt(struct menu *menu); const char *menu_get_prompt(struct menu *menu); -struct menu *menu_get_root_menu(struct menu *menu); struct menu *menu_get_parent_menu(struct menu *menu); bool menu_has_help(struct menu *menu); const char *menu_get_help(struct menu *menu); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 3d6f7cba8846..62b6313f51c8 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -661,11 +661,6 @@ const char *menu_get_prompt(struct menu *menu) return NULL; } -struct menu *menu_get_root_menu(struct menu *menu) -{ - return &rootmenu; -} - struct menu *menu_get_parent_menu(struct menu *menu) { enum prop_type type; -- cgit v1.2.3 From 61f2b7c7497ba96cdde5bbaeb9e07f4c48f41f97 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Mon, 19 Sep 2022 10:30:30 -0700 Subject: Makefile.debug: set -g unconditional on CONFIG_DEBUG_INFO_SPLIT Dmitrii, Fangrui, and Mashahiro note: Before GCC 11 and Clang 12 -gsplit-dwarf implicitly uses -g2. Fix CONFIG_DEBUG_INFO_SPLIT for gcc-11+ & clang-12+ which now need -g specified in order for -gsplit-dwarf to work at all. -gsplit-dwarf has been mutually exclusive with -g since support for CONFIG_DEBUG_INFO_SPLIT was introduced in commit 866ced950bcd ("kbuild: Support split debug info v4") I don't think it ever needed to be. Link: https://lore.kernel.org/lkml/20220815013317.26121-1-dmitrii.bundin.a@gmail.com/ Link: https://lore.kernel.org/lkml/CAK7LNARPAmsJD5XKAw7m_X2g7Fi-CAAsWDQiP7+ANBjkg7R7ng@mail.gmail.com/ Link: https://reviews.llvm.org/D80391 Cc: Andi Kleen Reported-by: Dmitrii Bundin Reported-by: Fangrui Song Reported-by: Masahiro Yamada Suggested-by: Dmitrii Bundin Reviewed-by: Nathan Chancellor Signed-off-by: Nick Desaulniers Signed-off-by: Masahiro Yamada --- scripts/Makefile.debug | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.debug b/scripts/Makefile.debug index 9f39b0130551..26d6a9d97a20 100644 --- a/scripts/Makefile.debug +++ b/scripts/Makefile.debug @@ -1,9 +1,7 @@ -DEBUG_CFLAGS := +DEBUG_CFLAGS := -g ifdef CONFIG_DEBUG_INFO_SPLIT DEBUG_CFLAGS += -gsplit-dwarf -else -DEBUG_CFLAGS += -g endif ifndef CONFIG_AS_IS_LLVM -- cgit v1.2.3 From 32ef9e5054ec0321b9336058c58ec749e9c6b0fe Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Mon, 19 Sep 2022 10:45:47 -0700 Subject: Makefile.debug: re-enable debug info for .S files Alexey reported that the fraction of unknown filename instances in kallsyms grew from ~0.3% to ~10% recently; Bill and Greg tracked it down to assembler defined symbols, which regressed as a result of: commit b8a9092330da ("Kbuild: do not emit debug info for assembly with LLVM_IAS=1") In that commit, I allude to restoring debug info for assembler defined symbols in a follow up patch, but it seems I forgot to do so in commit a66049e2cf0e ("Kbuild: make DWARF version a choice") Link: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=31bf18645d98b4d3d7357353be840e320649a67d Fixes: b8a9092330da ("Kbuild: do not emit debug info for assembly with LLVM_IAS=1") Reported-by: Alexey Alexandrov Reported-by: Bill Wendling Reported-by: Greg Thelen Reviewed-by: Nathan Chancellor Suggested-by: Masahiro Yamada Signed-off-by: Nick Desaulniers Signed-off-by: Masahiro Yamada --- lib/Kconfig.debug | 4 +++- scripts/Makefile.debug | 21 +++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index bcbe60d6c80c..d3e5f36bb01e 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -264,8 +264,10 @@ config DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT config DEBUG_INFO_DWARF4 bool "Generate DWARF Version 4 debuginfo" select DEBUG_INFO + depends on !CC_IS_CLANG || (CC_IS_CLANG && (AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502))) help - Generate DWARF v4 debug info. This requires gcc 4.5+ and gdb 7.0+. + Generate DWARF v4 debug info. This requires gcc 4.5+, binutils 2.35.2 + if using clang without clang's integrated assembler, and gdb 7.0+. If you have consumers of DWARF debug info that are not ready for newer revisions of DWARF, you may wish to choose this or have your diff --git a/scripts/Makefile.debug b/scripts/Makefile.debug index 26d6a9d97a20..8cf1cb22dd93 100644 --- a/scripts/Makefile.debug +++ b/scripts/Makefile.debug @@ -1,18 +1,19 @@ -DEBUG_CFLAGS := -g +DEBUG_CFLAGS := +debug-flags-y := -g ifdef CONFIG_DEBUG_INFO_SPLIT DEBUG_CFLAGS += -gsplit-dwarf endif -ifndef CONFIG_AS_IS_LLVM -KBUILD_AFLAGS += -Wa,-gdwarf-2 -endif - -ifndef CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT -dwarf-version-$(CONFIG_DEBUG_INFO_DWARF4) := 4 -dwarf-version-$(CONFIG_DEBUG_INFO_DWARF5) := 5 -DEBUG_CFLAGS += -gdwarf-$(dwarf-version-y) +debug-flags-$(CONFIG_DEBUG_INFO_DWARF4) += -gdwarf-4 +debug-flags-$(CONFIG_DEBUG_INFO_DWARF5) += -gdwarf-5 +ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_AS_IS_GNU),yy) +# Clang does not pass -g or -gdwarf-* option down to GAS. +# Add -Wa, prefix to explicitly specify the flags. +KBUILD_AFLAGS += $(addprefix -Wa$(comma), $(debug-flags-y)) endif +DEBUG_CFLAGS += $(debug-flags-y) +KBUILD_AFLAGS += $(debug-flags-y) ifdef CONFIG_DEBUG_INFO_REDUCED DEBUG_CFLAGS += -fno-var-tracking @@ -27,5 +28,5 @@ KBUILD_AFLAGS += -gz=zlib KBUILD_LDFLAGS += --compress-debug-sections=zlib endif -KBUILD_CFLAGS += $(DEBUG_CFLAGS) +KBUILD_CFLAGS += $(DEBUG_CFLAGS) export DEBUG_CFLAGS -- cgit v1.2.3 From d0f9562ee43a135b941715d9e5e607de88898aca Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Thu, 8 Sep 2022 14:54:44 -0700 Subject: scripts/kallsyms: Ignore __kcfi_typeid_ The compiler generates __kcfi_typeid_ symbols for annotating assembly functions with type information. These are constants that can be referenced in assembly code and are resolved by the linker. Ignore them in kallsyms. Signed-off-by: Sami Tolvanen Reviewed-by: Kees Cook Tested-by: Kees Cook Tested-by: Nathan Chancellor Acked-by: Peter Zijlstra (Intel) Tested-by: Peter Zijlstra (Intel) Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220908215504.3686827-3-samitolvanen@google.com --- scripts/kallsyms.c | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index f18e6dfc68c5..ccdf0c897f31 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -119,6 +119,7 @@ static bool is_ignored_symbol(const char *name, char type) "__ThumbV7PILongThunk_", "__LA25Thunk_", /* mips lld */ "__microLA25Thunk_", + "__kcfi_typeid_", /* CFI type identifiers */ NULL }; -- cgit v1.2.3 From 89245600941e4e0f87d77f60ee269b5e61ef4e49 Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Thu, 8 Sep 2022 14:54:47 -0700 Subject: cfi: Switch to -fsanitize=kcfi Switch from Clang's original forward-edge control-flow integrity implementation to -fsanitize=kcfi, which is better suited for the kernel, as it doesn't require LTO, doesn't use a jump table that requires altering function references, and won't break cross-module function address equality. Signed-off-by: Sami Tolvanen Reviewed-by: Kees Cook Tested-by: Kees Cook Tested-by: Nathan Chancellor Acked-by: Peter Zijlstra (Intel) Tested-by: Peter Zijlstra (Intel) Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220908215504.3686827-6-samitolvanen@google.com --- Makefile | 13 +--- arch/Kconfig | 8 ++- include/asm-generic/vmlinux.lds.h | 37 +++++----- include/linux/cfi.h | 29 ++++++-- include/linux/compiler-clang.h | 14 +--- include/linux/module.h | 6 +- kernel/cfi.c | 144 ++++++++++++++++++-------------------- kernel/module/main.c | 35 +-------- scripts/module.lds.S | 23 ++---- 9 files changed, 133 insertions(+), 176 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index a4f71076cacb..43e08c9f95e9 100644 --- a/Makefile +++ b/Makefile @@ -921,18 +921,7 @@ export CC_FLAGS_LTO endif ifdef CONFIG_CFI_CLANG -CC_FLAGS_CFI := -fsanitize=cfi \ - -fsanitize-cfi-cross-dso \ - -fno-sanitize-cfi-canonical-jump-tables \ - -fno-sanitize-trap=cfi \ - -fno-sanitize-blacklist - -ifdef CONFIG_CFI_PERMISSIVE -CC_FLAGS_CFI += -fsanitize-recover=cfi -endif - -# If LTO flags are filtered out, we must also filter out CFI. -CC_FLAGS_LTO += $(CC_FLAGS_CFI) +CC_FLAGS_CFI := -fsanitize=kcfi KBUILD_CFLAGS += $(CC_FLAGS_CFI) export CC_FLAGS_CFI endif diff --git a/arch/Kconfig b/arch/Kconfig index 5fd875e18c99..1c1eca0c0019 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -738,11 +738,13 @@ config ARCH_SUPPORTS_CFI_CLANG An architecture should select this option if it can support Clang's Control-Flow Integrity (CFI) checking. +config ARCH_USES_CFI_TRAPS + bool + config CFI_CLANG bool "Use Clang's Control Flow Integrity (CFI)" - depends on LTO_CLANG && ARCH_SUPPORTS_CFI_CLANG - depends on CLANG_VERSION >= 140000 - select KALLSYMS + depends on ARCH_SUPPORTS_CFI_CLANG + depends on $(cc-option,-fsanitize=kcfi) help This option enables Clang’s forward-edge Control Flow Integrity (CFI) checking, where the compiler injects a runtime check to each diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 7515a465ec03..7501edfce11e 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -421,6 +421,22 @@ __end_ro_after_init = .; #endif +/* + * .kcfi_traps contains a list KCFI trap locations. + */ +#ifndef KCFI_TRAPS +#ifdef CONFIG_ARCH_USES_CFI_TRAPS +#define KCFI_TRAPS \ + __kcfi_traps : AT(ADDR(__kcfi_traps) - LOAD_OFFSET) { \ + __start___kcfi_traps = .; \ + KEEP(*(.kcfi_traps)) \ + __stop___kcfi_traps = .; \ + } +#else +#define KCFI_TRAPS +#endif +#endif + /* * Read only Data */ @@ -529,6 +545,8 @@ __stop___modver = .; \ } \ \ + KCFI_TRAPS \ + \ RO_EXCEPTION_TABLE \ NOTES \ BTF \ @@ -537,21 +555,6 @@ __end_rodata = .; -/* - * .text..L.cfi.jumptable.* contain Control-Flow Integrity (CFI) - * jump table entries. - */ -#ifdef CONFIG_CFI_CLANG -#define TEXT_CFI_JT \ - . = ALIGN(PMD_SIZE); \ - __cfi_jt_start = .; \ - *(.text..L.cfi.jumptable .text..L.cfi.jumptable.*) \ - . = ALIGN(PMD_SIZE); \ - __cfi_jt_end = .; -#else -#define TEXT_CFI_JT -#endif - /* * Non-instrumentable text section */ @@ -579,7 +582,6 @@ *(.text..refcount) \ *(.ref.text) \ *(.text.asan.* .text.tsan.*) \ - TEXT_CFI_JT \ MEM_KEEP(init.text*) \ MEM_KEEP(exit.text*) \ @@ -1008,8 +1010,7 @@ * keep any .init_array.* sections. * https://bugs.llvm.org/show_bug.cgi?id=46478 */ -#if defined(CONFIG_GCOV_KERNEL) || defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KCSAN) || \ - defined(CONFIG_CFI_CLANG) +#if defined(CONFIG_GCOV_KERNEL) || defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KCSAN) # ifdef CONFIG_CONSTRUCTORS # define SANITIZER_DISCARDS \ *(.eh_frame) diff --git a/include/linux/cfi.h b/include/linux/cfi.h index 2cdbc0fbd0ab..5e134f4ce8b7 100644 --- a/include/linux/cfi.h +++ b/include/linux/cfi.h @@ -2,17 +2,38 @@ /* * Clang Control Flow Integrity (CFI) support. * - * Copyright (C) 2021 Google LLC + * Copyright (C) 2022 Google LLC */ #ifndef _LINUX_CFI_H #define _LINUX_CFI_H +#include +#include + #ifdef CONFIG_CFI_CLANG -typedef void (*cfi_check_fn)(uint64_t id, void *ptr, void *diag); +enum bug_trap_type report_cfi_failure(struct pt_regs *regs, unsigned long addr, + unsigned long *target, u32 type); -/* Compiler-generated function in each module, and the kernel */ -extern void __cfi_check(uint64_t id, void *ptr, void *diag); +static inline enum bug_trap_type report_cfi_failure_noaddr(struct pt_regs *regs, + unsigned long addr) +{ + return report_cfi_failure(regs, addr, NULL, 0); +} +#ifdef CONFIG_ARCH_USES_CFI_TRAPS +bool is_cfi_trap(unsigned long addr); +#endif #endif /* CONFIG_CFI_CLANG */ +#ifdef CONFIG_MODULES +#ifdef CONFIG_ARCH_USES_CFI_TRAPS +void module_cfi_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, + struct module *mod); +#else +static inline void module_cfi_finalize(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + struct module *mod) {} +#endif /* CONFIG_ARCH_USES_CFI_TRAPS */ +#endif /* CONFIG_MODULES */ + #endif /* _LINUX_CFI_H */ diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h index c84fec767445..42e55579d649 100644 --- a/include/linux/compiler-clang.h +++ b/include/linux/compiler-clang.h @@ -66,17 +66,9 @@ # define __noscs __attribute__((__no_sanitize__("shadow-call-stack"))) #endif -#define __nocfi __attribute__((__no_sanitize__("cfi"))) -#define __cficanonical __attribute__((__cfi_canonical_jump_table__)) - -#if defined(CONFIG_CFI_CLANG) -/* - * With CONFIG_CFI_CLANG, the compiler replaces function address - * references with the address of the function's CFI jump table - * entry. The function_nocfi macro always returns the address of the - * actual function instead. - */ -#define function_nocfi(x) __builtin_function_start(x) +#if __has_feature(kcfi) +/* Disable CFI checking inside a function. */ +#define __nocfi __attribute__((__no_sanitize__("kcfi"))) #endif /* diff --git a/include/linux/module.h b/include/linux/module.h index 8937b020ec04..ec61fb53979a 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -387,8 +386,9 @@ struct module { const s32 *crcs; unsigned int num_syms; -#ifdef CONFIG_CFI_CLANG - cfi_check_fn cfi_check; +#ifdef CONFIG_ARCH_USES_CFI_TRAPS + s32 *kcfi_traps; + s32 *kcfi_traps_end; #endif /* Kernel parameters. */ diff --git a/kernel/cfi.c b/kernel/cfi.c index e8bc1b370edc..08caad776717 100644 --- a/kernel/cfi.c +++ b/kernel/cfi.c @@ -1,105 +1,101 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Clang Control Flow Integrity (CFI) error and slowpath handling. + * Clang Control Flow Integrity (CFI) error handling. * - * Copyright (C) 2021 Google LLC + * Copyright (C) 2022 Google LLC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Compiler-defined handler names */ -#ifdef CONFIG_CFI_PERMISSIVE -#define cfi_failure_handler __ubsan_handle_cfi_check_fail -#else -#define cfi_failure_handler __ubsan_handle_cfi_check_fail_abort -#endif - -static inline void handle_cfi_failure(void *ptr) +#include + +enum bug_trap_type report_cfi_failure(struct pt_regs *regs, unsigned long addr, + unsigned long *target, u32 type) { - if (IS_ENABLED(CONFIG_CFI_PERMISSIVE)) - WARN_RATELIMIT(1, "CFI failure (target: %pS):\n", ptr); + if (target) + pr_err("CFI failure at %pS (target: %pS; expected type: 0x%08x)\n", + (void *)addr, (void *)*target, type); else - panic("CFI failure (target: %pS)\n", ptr); + pr_err("CFI failure at %pS (no target information)\n", + (void *)addr); + + if (IS_ENABLED(CONFIG_CFI_PERMISSIVE)) { + __warn(NULL, 0, (void *)addr, 0, regs, NULL); + return BUG_TRAP_TYPE_WARN; + } + + return BUG_TRAP_TYPE_BUG; } -#ifdef CONFIG_MODULES +#ifdef CONFIG_ARCH_USES_CFI_TRAPS +static inline unsigned long trap_address(s32 *p) +{ + return (unsigned long)((long)p + (long)*p); +} -static inline cfi_check_fn find_module_check_fn(unsigned long ptr) +static bool is_trap(unsigned long addr, s32 *start, s32 *end) { - cfi_check_fn fn = NULL; - struct module *mod; + s32 *p; - rcu_read_lock_sched_notrace(); - mod = __module_address(ptr); - if (mod) - fn = mod->cfi_check; - rcu_read_unlock_sched_notrace(); + for (p = start; p < end; ++p) { + if (trap_address(p) == addr) + return true; + } - return fn; + return false; } -static inline cfi_check_fn find_check_fn(unsigned long ptr) +#ifdef CONFIG_MODULES +/* Populates `kcfi_trap(_end)?` fields in `struct module`. */ +void module_cfi_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, + struct module *mod) { - cfi_check_fn fn = NULL; - unsigned long flags; - bool rcu_idle; - - if (is_kernel_text(ptr)) - return __cfi_check; - - /* - * Indirect call checks can happen when RCU is not watching. Both - * the shadow and __module_address use RCU, so we need to wake it - * up if necessary. - */ - rcu_idle = !rcu_is_watching(); - if (rcu_idle) { - local_irq_save(flags); - ct_irq_enter(); - } + char *secstrings; + unsigned int i; - fn = find_module_check_fn(ptr); + mod->kcfi_traps = NULL; + mod->kcfi_traps_end = NULL; - if (rcu_idle) { - ct_irq_exit(); - local_irq_restore(flags); - } + secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + + for (i = 1; i < hdr->e_shnum; i++) { + if (strcmp(secstrings + sechdrs[i].sh_name, "__kcfi_traps")) + continue; - return fn; + mod->kcfi_traps = (s32 *)sechdrs[i].sh_addr; + mod->kcfi_traps_end = (s32 *)(sechdrs[i].sh_addr + sechdrs[i].sh_size); + break; + } } -void __cfi_slowpath_diag(uint64_t id, void *ptr, void *diag) +static bool is_module_cfi_trap(unsigned long addr) { - cfi_check_fn fn = find_check_fn((unsigned long)ptr); + struct module *mod; + bool found = false; - if (likely(fn)) - fn(id, ptr, diag); - else /* Don't allow unchecked modules */ - handle_cfi_failure(ptr); -} -EXPORT_SYMBOL(__cfi_slowpath_diag); + rcu_read_lock_sched_notrace(); -#else /* !CONFIG_MODULES */ + mod = __module_address(addr); + if (mod) + found = is_trap(addr, mod->kcfi_traps, mod->kcfi_traps_end); -void __cfi_slowpath_diag(uint64_t id, void *ptr, void *diag) + rcu_read_unlock_sched_notrace(); + + return found; +} +#else /* CONFIG_MODULES */ +static inline bool is_module_cfi_trap(unsigned long addr) { - handle_cfi_failure(ptr); /* No modules */ + return false; } -EXPORT_SYMBOL(__cfi_slowpath_diag); - #endif /* CONFIG_MODULES */ -void cfi_failure_handler(void *data, void *ptr, void *vtable) +extern s32 __start___kcfi_traps[]; +extern s32 __stop___kcfi_traps[]; + +bool is_cfi_trap(unsigned long addr) { - handle_cfi_failure(ptr); + if (is_trap(addr, __start___kcfi_traps, __stop___kcfi_traps)) + return true; + + return is_module_cfi_trap(addr); } -EXPORT_SYMBOL(cfi_failure_handler); +#endif /* CONFIG_ARCH_USES_CFI_TRAPS */ diff --git a/kernel/module/main.c b/kernel/module/main.c index 0228f44b58e5..70c0b2c6fef8 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include "internal.h" @@ -2597,8 +2598,9 @@ static int complete_formation(struct module *mod, struct load_info *info) if (err < 0) goto out; - /* This relies on module_mutex for list integrity. */ + /* These rely on module_mutex for list integrity. */ module_bug_finalize(info->hdr, info->sechdrs, mod); + module_cfi_finalize(info->hdr, info->sechdrs, mod); if (module_check_misalignment(mod)) goto out_misaligned; @@ -2660,8 +2662,6 @@ static int unknown_module_param_cb(char *param, char *val, const char *modname, return 0; } -static void cfi_init(struct module *mod); - /* * Allocate and load the module: note that size of section 0 is always * zero, and we rely on this for optional sections. @@ -2791,9 +2791,6 @@ static int load_module(struct load_info *info, const char __user *uargs, flush_module_icache(mod); - /* Setup CFI for the module. */ - cfi_init(mod); - /* Now copy in args */ mod->args = strndup_user(uargs, ~0UL >> 1); if (IS_ERR(mod->args)) { @@ -2955,32 +2952,6 @@ static inline int within(unsigned long addr, void *start, unsigned long size) return ((void *)addr >= start && (void *)addr < start + size); } -static void cfi_init(struct module *mod) -{ -#ifdef CONFIG_CFI_CLANG - initcall_t *init; -#ifdef CONFIG_MODULE_UNLOAD - exitcall_t *exit; -#endif - - rcu_read_lock_sched(); - mod->cfi_check = (cfi_check_fn) - find_kallsyms_symbol_value(mod, "__cfi_check"); - init = (initcall_t *) - find_kallsyms_symbol_value(mod, "__cfi_jt_init_module"); - /* Fix init/exit functions to point to the CFI jump table */ - if (init) - mod->init = *init; -#ifdef CONFIG_MODULE_UNLOAD - exit = (exitcall_t *) - find_kallsyms_symbol_value(mod, "__cfi_jt_cleanup_module"); - if (exit) - mod->exit = *exit; -#endif - rcu_read_unlock_sched(); -#endif -} - /* Keep in sync with MODULE_FLAGS_BUF_SIZE !!! */ char *module_flags(struct module *mod, char *buf, bool show_state) { diff --git a/scripts/module.lds.S b/scripts/module.lds.S index 3a3aa2354ed8..da4bddd26171 100644 --- a/scripts/module.lds.S +++ b/scripts/module.lds.S @@ -3,20 +3,10 @@ * Archs are free to supply their own linker scripts. ld will * combine them automatically. */ -#ifdef CONFIG_CFI_CLANG -# include -# define ALIGN_CFI ALIGN(PAGE_SIZE) -# define SANITIZER_DISCARDS *(.eh_frame) -#else -# define ALIGN_CFI -# define SANITIZER_DISCARDS -#endif - SECTIONS { /DISCARD/ : { *(.discard) *(.discard.*) - SANITIZER_DISCARDS } __ksymtab 0 : { *(SORT(___ksymtab+*)) } @@ -33,6 +23,10 @@ SECTIONS { __patchable_function_entries : { *(__patchable_function_entries) } +#ifdef CONFIG_ARCH_USES_CFI_TRAPS + __kcfi_traps : { KEEP(*(.kcfi_traps)) } +#endif + #ifdef CONFIG_LTO_CLANG /* * With CONFIG_LTO_CLANG, LLD always enables -fdata-sections and @@ -53,15 +47,6 @@ SECTIONS { *(.rodata .rodata.[0-9a-zA-Z_]*) *(.rodata..L*) } - - /* - * With CONFIG_CFI_CLANG, we assume __cfi_check is at the beginning - * of the .text section, and is aligned to PAGE_SIZE. - */ - .text : ALIGN_CFI { - *(.text.__cfi_check) - *(.text .text.[0-9a-zA-Z_]* .text..L.cfi*) - } #endif } -- cgit v1.2.3 From d7c6ea024c08bbdb799768f51ffd9fdd6236d190 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 15 Sep 2022 14:44:22 +0300 Subject: kbuild: take into account DT_SCHEMA_FILES changes while checking dtbs It is useful to be able to recheck dtbs files against a limited set of DT schema files. This can be accomplished by using differnt DT_SCHEMA_FILES argument values while rerunning make dtbs_check. However for some reason if_changed_rule doesn't pick up the rule_dtc changes (and doesn't retrigger the build). Fix this by changing if_changed_rule to if_changed_dep and squashing DTC and dt-validate into a single new command. Then if_changed_dep triggers on DT_SCHEMA_FILES changes and reruns the build/check. Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20220915114422.79378-1-dmitry.baryshkov@linaro.org Signed-off-by: Rob Herring --- scripts/Makefile.lib | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 3fb6a99e78c4..cec0560f6ac6 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -371,17 +371,15 @@ DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),-l $(DT_SCHEMA_FILES),-m) DT_BINDING_DIR := Documentation/devicetree/bindings DT_TMP_SCHEMA := $(objtree)/$(DT_BINDING_DIR)/processed-schema.json -quiet_cmd_dtb_check = CHECK $@ - cmd_dtb_check = $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ || true +quiet_cmd_dtb = DTC_CHK $@ + cmd_dtb = $(cmd_dtc) ; $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ || true +else +quiet_cmd_dtb = $(quiet_cmd_dtc) + cmd_dtb = $(cmd_dtc) endif -define rule_dtc - $(call cmd_and_fixdep,dtc) - $(call cmd,dtb_check) -endef - $(obj)/%.dtb: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE - $(call if_changed_rule,dtc) + $(call if_changed_dep,dtb) $(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE $(call if_changed_dep,dtc) -- cgit v1.2.3 From b6acf807351781c3c3810df7873b3f0d793d59b2 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 30 Jun 2022 15:37:22 -0600 Subject: dt: Add a check for undocumented compatible strings in kernel Add a make target, dt_compatible_check, to extract compatible strings from kernel sources and check if they are documented by a schema. At least version v2022.08 of dtschema with dt-check-compatible is required. This check can also be run manually on specific files or directories: scripts/dtc/dt-extract-compatibles drivers/clk/ | \ xargs dt-check-compatible -v -s Documentation/devicetree/bindings/processed-schema.json Currently, there are about 3800 undocumented compatible strings. Most of these are cases where the binding is not yet converted (given there are 1900 .txt binding files remaining). Link: https://lore.kernel.org/all/20220916012510.2718170-1-robh@kernel.org/ Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/Makefile | 3 ++ Makefile | 4 ++ scripts/dtc/dt-extract-compatibles | 69 ++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100755 scripts/dtc/dt-extract-compatibles (limited to 'scripts') diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile index 1eaccf135b30..bf2d8a8ced77 100644 --- a/Documentation/devicetree/bindings/Makefile +++ b/Documentation/devicetree/bindings/Makefile @@ -75,3 +75,6 @@ always-$(CHECK_DT_BINDING) += $(patsubst $(srctree)/$(src)/%.yaml,%.example.dtb, # build artifacts here before they are processed by scripts/Makefile.clean clean-files = $(shell find $(obj) \( -name '*.example.dts' -o \ -name '*.example.dtb' \) -delete 2>/dev/null) + +dt_compatible_check: $(obj)/processed-schema.json + $(Q)$(srctree)/scripts/dtc/dt-extract-compatibles $(srctree) | xargs dt-check-compatible -v -s $< diff --git a/Makefile b/Makefile index f09673b6c11d..7f19e1725b2f 100644 --- a/Makefile +++ b/Makefile @@ -1419,6 +1419,10 @@ PHONY += dt_binding_check dt_binding_check: scripts_dtc $(Q)$(MAKE) $(build)=Documentation/devicetree/bindings +PHONY += dt_compatible_check +dt_compatible_check: dt_binding_check + $(Q)$(MAKE) $(build)=Documentation/devicetree/bindings $@ + # --------------------------------------------------------------------------- # Modules diff --git a/scripts/dtc/dt-extract-compatibles b/scripts/dtc/dt-extract-compatibles new file mode 100755 index 000000000000..a1119762ed08 --- /dev/null +++ b/scripts/dtc/dt-extract-compatibles @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-only + +import os +import glob +import re +import argparse + + +def parse_of_declare_macros(data): + """ Find all compatible strings in OF_DECLARE() style macros """ + compat_list = [] + # CPU_METHOD_OF_DECLARE does not have a compatible string + for m in re.finditer(r'(? Date: Wed, 27 Jul 2022 17:58:20 +0200 Subject: kallsyms: use `ARRAY_SIZE` instead of hardcoded size This removes one place where the `500` constant is hardcoded. Reviewed-by: Kees Cook Reviewed-by: Geert Stappers Reviewed-by: Greg Kroah-Hartman Signed-off-by: Boqun Feng Co-developed-by: Miguel Ojeda Signed-off-by: Miguel Ojeda --- 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 f18e6dfc68c5..8551513f9311 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -206,7 +206,7 @@ static struct sym_entry *read_symbol(FILE *in) rc = fscanf(in, "%llx %c %499s\n", &addr, &type, name); if (rc != 3) { - if (rc != EOF && fgets(name, 500, in) == NULL) + if (rc != EOF && fgets(name, ARRAY_SIZE(name), in) == NULL) fprintf(stderr, "Read error or end of file.\n"); return NULL; } -- cgit v1.2.3 From b471927ebf9bb54ba6e99f20848d70193e645eed Mon Sep 17 00:00:00 2001 From: Boqun Feng Date: Wed, 27 Jul 2022 20:54:19 +0200 Subject: kallsyms: avoid hardcoding buffer size This introduces `KSYM_NAME_LEN_BUFFER` in place of the previously hardcoded size of the input buffer. It will also make it easier to update the size in a single place in a later patch. Reviewed-by: Kees Cook Reviewed-by: Greg Kroah-Hartman Signed-off-by: Boqun Feng Co-developed-by: Miguel Ojeda Signed-off-by: Miguel Ojeda --- scripts/kallsyms.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 8551513f9311..25e2fe5fbcd4 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -27,8 +27,14 @@ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) +#define _stringify_1(x) #x +#define _stringify(x) _stringify_1(x) + #define KSYM_NAME_LEN 128 +/* A substantially bigger size than the current maximum. */ +#define KSYM_NAME_LEN_BUFFER 499 + struct sym_entry { unsigned long long addr; unsigned int len; @@ -198,13 +204,13 @@ static void check_symbol_range(const char *sym, unsigned long long addr, static struct sym_entry *read_symbol(FILE *in) { - char name[500], type; + char name[KSYM_NAME_LEN_BUFFER+1], type; unsigned long long addr; unsigned int len; struct sym_entry *sym; int rc; - rc = fscanf(in, "%llx %c %499s\n", &addr, &type, name); + rc = fscanf(in, "%llx %c %" _stringify(KSYM_NAME_LEN_BUFFER) "s\n", &addr, &type, name); if (rc != 3) { if (rc != EOF && fgets(name, ARRAY_SIZE(name), in) == NULL) fprintf(stderr, "Read error or end of file.\n"); -- cgit v1.2.3 From 6e8c5bbd5e83e649251c198e743c8b9e7c48372b Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Wed, 27 Jul 2022 21:41:56 +0200 Subject: kallsyms: add static relationship between `KSYM_NAME_LEN{,_BUFFER}` This adds a static assert to ensure `KSYM_NAME_LEN_BUFFER` gets updated when `KSYM_NAME_LEN` changes. The relationship used is one that keeps the new size (512+1) close to the original buffer size (500). Reviewed-by: Greg Kroah-Hartman Co-developed-by: Boqun Feng Signed-off-by: Boqun Feng Signed-off-by: Miguel Ojeda --- scripts/kallsyms.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 25e2fe5fbcd4..411ff5058b51 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -32,8 +32,18 @@ #define KSYM_NAME_LEN 128 -/* A substantially bigger size than the current maximum. */ -#define KSYM_NAME_LEN_BUFFER 499 +/* + * A substantially bigger size than the current maximum. + * + * It cannot be defined as an expression because it gets stringified + * for the fscanf() format string. Therefore, a _Static_assert() is + * used instead to maintain the relationship with KSYM_NAME_LEN. + */ +#define KSYM_NAME_LEN_BUFFER 512 +_Static_assert( + KSYM_NAME_LEN_BUFFER == KSYM_NAME_LEN * 4, + "Please keep KSYM_NAME_LEN_BUFFER in sync with KSYM_NAME_LEN" +); struct sym_entry { unsigned long long addr; -- cgit v1.2.3 From 73bbb94466fd3f8b313eeb0b0467314a262dddb3 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Mon, 5 Apr 2021 04:58:39 +0200 Subject: kallsyms: support "big" kernel symbols Rust symbols can become quite long due to namespacing introduced by modules, types, traits, generics, etc. Increasing to 255 is not enough in some cases, therefore introduce longer lengths to the symbol table. In order to avoid increasing all lengths to 2 bytes (since most of them are small, including many Rust ones), use ULEB128 to keep smaller symbols in 1 byte, with the rest in 2 bytes. Reviewed-by: Kees Cook Reviewed-by: Greg Kroah-Hartman Co-developed-by: Alex Gaynor Signed-off-by: Alex Gaynor Co-developed-by: Wedson Almeida Filho Signed-off-by: Wedson Almeida Filho Co-developed-by: Gary Guo Signed-off-by: Gary Guo Co-developed-by: Boqun Feng Signed-off-by: Boqun Feng Co-developed-by: Matthew Wilcox Signed-off-by: Matthew Wilcox Signed-off-by: Miguel Ojeda --- kernel/kallsyms.c | 26 ++++++++++++++++++++++---- scripts/kallsyms.c | 29 ++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 3e7e2c2ad2f7..fc5e26348d25 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -50,12 +50,20 @@ static unsigned int kallsyms_expand_symbol(unsigned int off, data = &kallsyms_names[off]; len = *data; data++; + off++; + + /* If MSB is 1, it is a "big" symbol, so needs an additional byte. */ + if ((len & 0x80) != 0) { + len = (len & 0x7F) | (*data << 7); + data++; + off++; + } /* * Update the offset to return the offset for the next symbol on * the compressed stream. */ - off += len + 1; + off += len; /* * For every byte on the compressed symbol data, copy the table @@ -108,7 +116,7 @@ static char kallsyms_get_symbol_type(unsigned int off) static unsigned int get_symbol_offset(unsigned long pos) { const u8 *name; - int i; + int i, len; /* * Use the closest marker we have. We have markers every 256 positions, @@ -122,8 +130,18 @@ static unsigned int get_symbol_offset(unsigned long pos) * so we just need to add the len to the current pointer for every * symbol we wish to skip. */ - for (i = 0; i < (pos & 0xFF); i++) - name = name + (*name) + 1; + for (i = 0; i < (pos & 0xFF); i++) { + len = *name; + + /* + * If MSB is 1, it is a "big" symbol, so we need to look into + * the next byte (and skip it, too). + */ + if ((len & 0x80) != 0) + len = ((len & 0x7F) | (name[1] << 7)) + 1; + + name = name + len + 1; + } return name - kallsyms_names; } diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 411ff5058b51..6502c4001f01 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -487,12 +487,35 @@ static void write_src(void) if ((i & 0xFF) == 0) markers[i >> 8] = off; - printf("\t.byte 0x%02x", table[i]->len); + /* There cannot be any symbol of length zero. */ + if (table[i]->len == 0) { + fprintf(stderr, "kallsyms failure: " + "unexpected zero symbol length\n"); + exit(EXIT_FAILURE); + } + + /* Only lengths that fit in up-to-two-byte ULEB128 are supported. */ + if (table[i]->len > 0x3FFF) { + fprintf(stderr, "kallsyms failure: " + "unexpected huge symbol length\n"); + exit(EXIT_FAILURE); + } + + /* Encode length with ULEB128. */ + if (table[i]->len <= 0x7F) { + /* Most symbols use a single byte for the length. */ + printf("\t.byte 0x%02x", table[i]->len); + off += table[i]->len + 1; + } else { + /* "Big" symbols use two bytes. */ + printf("\t.byte 0x%02x, 0x%02x", + (table[i]->len & 0x7F) | 0x80, + (table[i]->len >> 7) & 0x7F); + off += table[i]->len + 2; + } for (k = 0; k < table[i]->len; k++) printf(", 0x%02x", table[i]->sym[k]); printf("\n"); - - off += table[i]->len + 1; } printf("\n"); -- cgit v1.2.3 From b8a94bfb33952bb17fbc65f8903d242a721c533d Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Mon, 5 Apr 2021 05:03:50 +0200 Subject: kallsyms: increase maximum kernel symbol length to 512 Rust symbols can become quite long due to namespacing introduced by modules, types, traits, generics, etc. For instance, the following code: pub mod my_module { pub struct MyType; pub struct MyGenericType(T); pub trait MyTrait { fn my_method() -> u32; } impl MyTrait for MyGenericType { fn my_method() -> u32 { 42 } } } generates a symbol of length 96 when using the upcoming v0 mangling scheme: _RNvXNtCshGpAVYOtgW1_7example9my_moduleINtB2_13MyGenericTypeNtB2_6MyTypeENtB2_7MyTrait9my_method At the moment, Rust symbols may reach up to 300 in length. Setting 512 as the maximum seems like a reasonable choice to keep some headroom. Reviewed-by: Kees Cook Reviewed-by: Petr Mladek Reviewed-by: Greg Kroah-Hartman Co-developed-by: Alex Gaynor Signed-off-by: Alex Gaynor Co-developed-by: Wedson Almeida Filho Signed-off-by: Wedson Almeida Filho Co-developed-by: Gary Guo Signed-off-by: Gary Guo Co-developed-by: Boqun Feng Signed-off-by: Boqun Feng Signed-off-by: Miguel Ojeda --- include/linux/kallsyms.h | 2 +- kernel/livepatch/core.c | 4 ++-- scripts/kallsyms.c | 4 ++-- tools/include/linux/kallsyms.h | 2 +- tools/lib/perf/include/perf/event.h | 2 +- tools/lib/symbol/kallsyms.h | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index ad39636e0c3f..649faac31ddb 100644 --- a/include/linux/kallsyms.h +++ b/include/linux/kallsyms.h @@ -15,7 +15,7 @@ #include -#define KSYM_NAME_LEN 128 +#define KSYM_NAME_LEN 512 #define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s %s]") + \ (KSYM_NAME_LEN - 1) + \ 2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + \ diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index bc475e62279d..ec06ce59d728 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -213,7 +213,7 @@ static int klp_resolve_symbols(Elf_Shdr *sechdrs, const char *strtab, * we use the smallest/strictest upper bound possible (56, based on * the current definition of MODULE_NAME_LEN) to prevent overflows. */ - BUILD_BUG_ON(MODULE_NAME_LEN < 56 || KSYM_NAME_LEN != 128); + BUILD_BUG_ON(MODULE_NAME_LEN < 56 || KSYM_NAME_LEN != 512); relas = (Elf_Rela *) relasec->sh_addr; /* For each rela in this klp relocation section */ @@ -227,7 +227,7 @@ static int klp_resolve_symbols(Elf_Shdr *sechdrs, const char *strtab, /* Format: .klp.sym.sym_objname.sym_name,sympos */ cnt = sscanf(strtab + sym->st_name, - ".klp.sym.%55[^.].%127[^,],%lu", + ".klp.sym.%55[^.].%511[^,],%lu", sym_objname, sym_name, &sympos); if (cnt != 3) { pr_err("symbol %s has an incorrectly formatted name\n", diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 6502c4001f01..c4793301a27e 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -30,7 +30,7 @@ #define _stringify_1(x) #x #define _stringify(x) _stringify_1(x) -#define KSYM_NAME_LEN 128 +#define KSYM_NAME_LEN 512 /* * A substantially bigger size than the current maximum. @@ -39,7 +39,7 @@ * for the fscanf() format string. Therefore, a _Static_assert() is * used instead to maintain the relationship with KSYM_NAME_LEN. */ -#define KSYM_NAME_LEN_BUFFER 512 +#define KSYM_NAME_LEN_BUFFER 2048 _Static_assert( KSYM_NAME_LEN_BUFFER == KSYM_NAME_LEN * 4, "Please keep KSYM_NAME_LEN_BUFFER in sync with KSYM_NAME_LEN" diff --git a/tools/include/linux/kallsyms.h b/tools/include/linux/kallsyms.h index efb6c3f5f2a9..5a37ccbec54f 100644 --- a/tools/include/linux/kallsyms.h +++ b/tools/include/linux/kallsyms.h @@ -6,7 +6,7 @@ #include #include -#define KSYM_NAME_LEN 128 +#define KSYM_NAME_LEN 512 struct module; diff --git a/tools/lib/perf/include/perf/event.h b/tools/lib/perf/include/perf/event.h index 93bf93a59c99..d8ae4e944467 100644 --- a/tools/lib/perf/include/perf/event.h +++ b/tools/lib/perf/include/perf/event.h @@ -97,7 +97,7 @@ struct perf_record_throttle { }; #ifndef KSYM_NAME_LEN -#define KSYM_NAME_LEN 256 +#define KSYM_NAME_LEN 512 #endif struct perf_record_ksymbol { diff --git a/tools/lib/symbol/kallsyms.h b/tools/lib/symbol/kallsyms.h index 72ab9870454b..542f9b059c3b 100644 --- a/tools/lib/symbol/kallsyms.h +++ b/tools/lib/symbol/kallsyms.h @@ -7,7 +7,7 @@ #include #ifndef KSYM_NAME_LEN -#define KSYM_NAME_LEN 256 +#define KSYM_NAME_LEN 512 #endif static inline u8 kallsyms2elf_binding(char type) -- cgit v1.2.3 From de48fa1a01e7752135c960a20d6c3b26544a8120 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Sun, 22 May 2022 03:11:08 +0200 Subject: scripts: checkpatch: diagnose uses of `%pA` in the C side as errors The `%pA` format specifier is only intended to be used from Rust. `checkpatch.pl` already gives a warning for invalid specificers: WARNING: Invalid vsprintf pointer extension '%pA' This makes it an error and introduces an explanatory message: ERROR: Invalid vsprintf pointer extension '%pA' - '%pA' is only intended to be used from Rust code Suggested-by: Kees Cook Reviewed-by: Greg Kroah-Hartman Co-developed-by: Alex Gaynor Signed-off-by: Alex Gaynor Co-developed-by: Wedson Almeida Filho Signed-off-by: Wedson Almeida Filho Co-developed-by: Joe Perches Signed-off-by: Joe Perches Signed-off-by: Miguel Ojeda --- scripts/checkpatch.pl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 79e759aac543..74a769310adf 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -6783,15 +6783,19 @@ sub process { } if ($bad_specifier ne "") { my $stat_real = get_stat_real($linenr, $lc); + my $msg_level = \&WARN; my $ext_type = "Invalid"; my $use = ""; if ($bad_specifier =~ /p[Ff]/) { $use = " - use %pS instead"; $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/); + } elsif ($bad_specifier =~ /pA/) { + $use = " - '%pA' is only intended to be used from Rust code"; + $msg_level = \&ERROR; } - WARN("VSPRINTF_POINTER_EXTENSION", - "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); + &{$msg_level}("VSPRINTF_POINTER_EXTENSION", + "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); } } } -- cgit v1.2.3 From d1d84b5f73888ccb9fc148dfc3cb3e15d3604d65 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Sun, 22 May 2022 17:22:58 +0200 Subject: scripts: checkpatch: enable language-independent checks for Rust Include Rust in the "source code files" category, so that the language-independent tests are checked for Rust too, and teach `checkpatch` about the comment style for Rust files. This enables the malformed SPDX check, the misplaced SPDX license tag check, the long line checks, the lines without a newline check and the embedded filename check. Reviewed-by: Kees Cook Reviewed-by: Greg Kroah-Hartman Co-developed-by: Alex Gaynor Signed-off-by: Alex Gaynor Co-developed-by: Wedson Almeida Filho Signed-off-by: Wedson Almeida Filho Signed-off-by: Miguel Ojeda --- scripts/checkpatch.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 74a769310adf..b5ed31d631fa 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3616,7 +3616,7 @@ sub process { my $comment = ""; if ($realfile =~ /\.(h|s|S)$/) { $comment = '/*'; - } elsif ($realfile =~ /\.(c|dts|dtsi)$/) { + } elsif ($realfile =~ /\.(c|rs|dts|dtsi)$/) { $comment = '//'; } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) { $comment = '#'; @@ -3664,7 +3664,7 @@ sub process { } # check we are in a valid source file if not then ignore this hunk - next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); + next if ($realfile !~ /\.(h|c|rs|s|S|sh|dtsi|dts)$/); # check for using SPDX-License-Identifier on the wrong line number if ($realline != $checklicenseline && -- cgit v1.2.3 From 99115db4ecc87af73415939439ec604ea0531e6f Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Sun, 5 Dec 2021 19:00:43 +0100 Subject: scripts: decode_stacktrace: demangle Rust symbols Recent versions of both Binutils (`c++filt`) and LLVM (`llvm-cxxfilt`) provide Rust v0 mangling support. Reviewed-by: Kees Cook Reviewed-by: Greg Kroah-Hartman Co-developed-by: Alex Gaynor Signed-off-by: Alex Gaynor Co-developed-by: Wedson Almeida Filho Signed-off-by: Wedson Almeida Filho Signed-off-by: Miguel Ojeda --- scripts/decode_stacktrace.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'scripts') diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh index 7075e26ab2c4..564c5632e1a2 100755 --- a/scripts/decode_stacktrace.sh +++ b/scripts/decode_stacktrace.sh @@ -8,6 +8,14 @@ usage() { echo " $0 -r | [|auto] []" } +# Try to find a Rust demangler +if type llvm-cxxfilt >/dev/null 2>&1 ; then + cppfilt=llvm-cxxfilt +elif type c++filt >/dev/null 2>&1 ; then + cppfilt=c++filt + cppfilt_opts=-i +fi + if [[ $1 == "-r" ]] ; then vmlinux="" basepath="auto" @@ -180,6 +188,12 @@ parse_symbol() { # In the case of inlines, move everything to same line code=${code//$'\n'/' '} + # Demangle if the name looks like a Rust symbol and if + # we got a Rust demangler + if [[ $name =~ ^_R && $cppfilt != "" ]] ; then + name=$("$cppfilt" "$cppfilt_opts" "$name") + fi + # Replace old address with pretty line numbers symbol="$segment$name ($code)" } -- cgit v1.2.3 From 8c4555ccc55cf90e1e3eb2507be3c354f3d15839 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Sat, 3 Jul 2021 17:26:15 +0200 Subject: scripts: add `generate_rust_analyzer.py` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `generate_rust_analyzer.py` script generates the configuration file (`rust-project.json`) for rust-analyzer. rust-analyzer is a modular compiler frontend for the Rust language. It provides an LSP server which can be used in editors such as VS Code, Emacs or Vim. Reviewed-by: Kees Cook Co-developed-by: Alex Gaynor Signed-off-by: Alex Gaynor Co-developed-by: Finn Behrens Signed-off-by: Finn Behrens Co-developed-by: Wedson Almeida Filho Signed-off-by: Wedson Almeida Filho Co-developed-by: Gary Guo Signed-off-by: Gary Guo Co-developed-by: Boris-Chengbiao Zhou Signed-off-by: Boris-Chengbiao Zhou Co-developed-by: Björn Roy Baron Signed-off-by: Björn Roy Baron Signed-off-by: Miguel Ojeda --- .gitignore | 3 + scripts/generate_rust_analyzer.py | 135 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100755 scripts/generate_rust_analyzer.py (limited to 'scripts') diff --git a/.gitignore b/.gitignore index 265959544978..80989914c97d 100644 --- a/.gitignore +++ b/.gitignore @@ -162,3 +162,6 @@ x509.genkey # Documentation toolchain sphinx_*/ + +# Rust analyzer configuration +/rust-project.json diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py new file mode 100755 index 000000000000..75bb611bd751 --- /dev/null +++ b/scripts/generate_rust_analyzer.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 +"""generate_rust_analyzer - Generates the `rust-project.json` file for `rust-analyzer`. +""" + +import argparse +import json +import logging +import pathlib +import sys + +def generate_crates(srctree, objtree, sysroot_src): + # Generate the configuration list. + cfg = [] + with open(objtree / "include" / "generated" / "rustc_cfg") as fd: + for line in fd: + line = line.replace("--cfg=", "") + line = line.replace("\n", "") + cfg.append(line) + + # Now fill the crates list -- dependencies need to come first. + # + # Avoid O(n^2) iterations by keeping a map of indexes. + crates = [] + crates_indexes = {} + + def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False): + crates_indexes[display_name] = len(crates) + crates.append({ + "display_name": display_name, + "root_module": str(root_module), + "is_workspace_member": is_workspace_member, + "is_proc_macro": is_proc_macro, + "deps": [{"crate": crates_indexes[dep], "name": dep} for dep in deps], + "cfg": cfg, + "edition": "2021", + "env": { + "RUST_MODFILE": "This is only for rust-analyzer" + } + }) + + # First, the ones in `rust/` since they are a bit special. + append_crate( + "core", + sysroot_src / "core" / "src" / "lib.rs", + [], + is_workspace_member=False, + ) + + append_crate( + "compiler_builtins", + srctree / "rust" / "compiler_builtins.rs", + [], + ) + + append_crate( + "alloc", + srctree / "rust" / "alloc" / "lib.rs", + ["core", "compiler_builtins"], + ) + + append_crate( + "macros", + srctree / "rust" / "macros" / "lib.rs", + [], + is_proc_macro=True, + ) + crates[-1]["proc_macro_dylib_path"] = "rust/libmacros.so" + + append_crate( + "bindings", + srctree / "rust"/ "bindings" / "lib.rs", + ["core"], + cfg=cfg, + ) + crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True)) + + append_crate( + "kernel", + srctree / "rust" / "kernel" / "lib.rs", + ["core", "alloc", "macros", "bindings"], + cfg=cfg, + ) + crates[-1]["source"] = { + "include_dirs": [ + str(srctree / "rust" / "kernel"), + str(objtree / "rust") + ], + "exclude_dirs": [], + } + + # Then, the rest outside of `rust/`. + # + # We explicitly mention the top-level folders we want to cover. + for folder in ("samples", "drivers"): + for path in (srctree / folder).rglob("*.rs"): + logging.info("Checking %s", path) + name = path.name.replace(".rs", "") + + # Skip those that are not crate roots. + if f"{name}.o" not in open(path.parent / "Makefile").read(): + continue + + logging.info("Adding %s", name) + append_crate( + name, + path, + ["core", "alloc", "kernel"], + cfg=cfg, + ) + + return crates + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--verbose', '-v', action='store_true') + parser.add_argument("srctree", type=pathlib.Path) + parser.add_argument("objtree", type=pathlib.Path) + parser.add_argument("sysroot_src", type=pathlib.Path) + args = parser.parse_args() + + logging.basicConfig( + format="[%(asctime)s] [%(levelname)s] %(message)s", + level=logging.INFO if args.verbose else logging.WARNING + ) + + rust_project = { + "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src), + "sysroot_src": str(args.sysroot_src), + } + + json.dump(rust_project, sys.stdout, sort_keys=True, indent=4) + +if __name__ == "__main__": + main() -- cgit v1.2.3 From 9a8ff24ce584ad9895f9416fe8fad6f8842f758d Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Thu, 4 Aug 2022 12:20:37 +0200 Subject: scripts: add `generate_rust_target.rs` This script takes care of generating the custom target specification file for `rustc`, based on the kernel configuration. It also serves as an example of a Rust host program. A dummy architecture is kept in this patch so that a later patch adds x86 support on top with as few changes as possible. Reviewed-by: Kees Cook Co-developed-by: Alex Gaynor Signed-off-by: Alex Gaynor Co-developed-by: Wedson Almeida Filho Signed-off-by: Wedson Almeida Filho Co-developed-by: David Gow Signed-off-by: David Gow Signed-off-by: Miguel Ojeda --- scripts/.gitignore | 1 + scripts/generate_rust_target.rs | 171 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 scripts/generate_rust_target.rs (limited to 'scripts') diff --git a/scripts/.gitignore b/scripts/.gitignore index eed308bef604..b7aec8eb1bd4 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only /asn1_compiler /bin2c +/generate_rust_target /insert-sys-cert /kallsyms /module.lds diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs new file mode 100644 index 000000000000..7256c9606cf0 --- /dev/null +++ b/scripts/generate_rust_target.rs @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! The custom target specification file generator for `rustc`. +//! +//! To configure a target from scratch, a JSON-encoded file has to be passed +//! to `rustc` (introduced in [RFC 131]). These options and the file itself are +//! unstable. Eventually, `rustc` should provide a way to do this in a stable +//! manner. For instance, via command-line arguments. Therefore, this file +//! should avoid using keys which can be set via `-C` or `-Z` options. +//! +//! [RFC 131]: https://rust-lang.github.io/rfcs/0131-target-specification.html + +use std::{ + collections::HashMap, + fmt::{Display, Formatter, Result}, + io::BufRead, +}; + +enum Value { + Boolean(bool), + Number(i32), + String(String), + Object(Object), +} + +type Object = Vec<(String, Value)>; + +/// Minimal "almost JSON" generator (e.g. no `null`s, no arrays, no escaping), +/// enough for this purpose. +impl Display for Value { + fn fmt(&self, formatter: &mut Formatter<'_>) -> Result { + match self { + Value::Boolean(boolean) => write!(formatter, "{}", boolean), + Value::Number(number) => write!(formatter, "{}", number), + Value::String(string) => write!(formatter, "\"{}\"", string), + Value::Object(object) => { + formatter.write_str("{")?; + if let [ref rest @ .., ref last] = object[..] { + for (key, value) in rest { + write!(formatter, "\"{}\": {},", key, value)?; + } + write!(formatter, "\"{}\": {}", last.0, last.1)?; + } + formatter.write_str("}") + } + } + } +} + +struct TargetSpec(Object); + +impl TargetSpec { + fn new() -> TargetSpec { + TargetSpec(Vec::new()) + } +} + +trait Push { + fn push(&mut self, key: &str, value: T); +} + +impl Push for TargetSpec { + fn push(&mut self, key: &str, value: bool) { + self.0.push((key.to_string(), Value::Boolean(value))); + } +} + +impl Push for TargetSpec { + fn push(&mut self, key: &str, value: i32) { + self.0.push((key.to_string(), Value::Number(value))); + } +} + +impl Push for TargetSpec { + fn push(&mut self, key: &str, value: String) { + self.0.push((key.to_string(), Value::String(value))); + } +} + +impl Push<&str> for TargetSpec { + fn push(&mut self, key: &str, value: &str) { + self.push(key, value.to_string()); + } +} + +impl Push for TargetSpec { + fn push(&mut self, key: &str, value: Object) { + self.0.push((key.to_string(), Value::Object(value))); + } +} + +impl Display for TargetSpec { + fn fmt(&self, formatter: &mut Formatter<'_>) -> Result { + // We add some newlines for clarity. + formatter.write_str("{\n")?; + if let [ref rest @ .., ref last] = self.0[..] { + for (key, value) in rest { + write!(formatter, " \"{}\": {},\n", key, value)?; + } + write!(formatter, " \"{}\": {}\n", last.0, last.1)?; + } + formatter.write_str("}") + } +} + +struct KernelConfig(HashMap); + +impl KernelConfig { + /// Parses `include/config/auto.conf` from `stdin`. + fn from_stdin() -> KernelConfig { + let mut result = HashMap::new(); + + let stdin = std::io::stdin(); + let mut handle = stdin.lock(); + let mut line = String::new(); + + loop { + line.clear(); + + if handle.read_line(&mut line).unwrap() == 0 { + break; + } + + if line.starts_with('#') { + continue; + } + + let (key, value) = line.split_once('=').expect("Missing `=` in line."); + result.insert(key.to_string(), value.trim_end_matches('\n').to_string()); + } + + KernelConfig(result) + } + + /// Does the option exist in the configuration (any value)? + /// + /// The argument must be passed without the `CONFIG_` prefix. + /// This avoids repetition and it also avoids `fixdep` making us + /// depend on it. + fn has(&self, option: &str) -> bool { + let option = "CONFIG_".to_owned() + option; + self.0.contains_key(&option) + } +} + +fn main() { + let cfg = KernelConfig::from_stdin(); + let mut ts = TargetSpec::new(); + + // `llvm-target`s are taken from `scripts/Makefile.clang`. + if cfg.has("DUMMY_ARCH") { + ts.push("arch", "dummy_arch"); + } else { + panic!("Unsupported architecture"); + } + + ts.push("emit-debug-gdb-scripts", false); + ts.push("frame-pointer", "may-omit"); + ts.push( + "stack-probes", + vec![("kind".to_string(), Value::String("none".to_string()))], + ); + + // Everything else is LE, whether `CPU_LITTLE_ENDIAN` is declared or not + // (e.g. x86). It is also `rustc`'s default. + if cfg.has("CPU_BIG_ENDIAN") { + ts.push("target-endian", "big"); + } + + println!("{}", ts); +} -- cgit v1.2.3 From 78521f3399abce9bb9db16d848044be873e117ac Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Thu, 4 Aug 2022 12:25:53 +0200 Subject: scripts: add `rust_is_available.sh` This script tests whether the Rust toolchain requirements are in place to enable Rust support. It uses `min-tool-version.sh` to fetch the version numbers. The build system will call it to set `CONFIG_RUST_IS_AVAILABLE` in a later patch. It also has an option (`-v`) to explain what is missing, which is useful to set up the development environment. This is used via the `make rustavailable` target added in a later patch. Reviewed-by: Kees Cook Co-developed-by: Alex Gaynor Signed-off-by: Alex Gaynor Co-developed-by: Wedson Almeida Filho Signed-off-by: Wedson Almeida Filho Co-developed-by: Finn Behrens Signed-off-by: Finn Behrens Co-developed-by: Miguel Cano Signed-off-by: Miguel Cano Co-developed-by: Tiago Lam Signed-off-by: Tiago Lam Signed-off-by: Miguel Ojeda --- scripts/min-tool-version.sh | 6 + scripts/rust_is_available.sh | 160 +++++++++++++++++++++++++++ scripts/rust_is_available_bindgen_libclang.h | 2 + 3 files changed, 168 insertions(+) create mode 100755 scripts/rust_is_available.sh create mode 100644 scripts/rust_is_available_bindgen_libclang.h (limited to 'scripts') diff --git a/scripts/min-tool-version.sh b/scripts/min-tool-version.sh index 250925aab101..b6593eac5003 100755 --- a/scripts/min-tool-version.sh +++ b/scripts/min-tool-version.sh @@ -30,6 +30,12 @@ llvm) echo 11.0.0 fi ;; +rustc) + echo 1.62.0 + ;; +bindgen) + echo 0.56.0 + ;; *) echo "$1: unknown tool" >&2 exit 1 diff --git a/scripts/rust_is_available.sh b/scripts/rust_is_available.sh new file mode 100755 index 000000000000..aebbf1913970 --- /dev/null +++ b/scripts/rust_is_available.sh @@ -0,0 +1,160 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Tests whether a suitable Rust toolchain is available. +# +# Pass `-v` for human output and more checks (as warnings). + +set -e + +min_tool_version=$(dirname $0)/min-tool-version.sh + +# Convert the version string x.y.z to a canonical up-to-7-digits form. +# +# Note that this function uses one more digit (compared to other +# instances in other version scripts) to give a bit more space to +# `rustc` since it will reach 1.100.0 in late 2026. +get_canonical_version() +{ + IFS=. + set -- $1 + echo $((100000 * $1 + 100 * $2 + $3)) +} + +# Check that the Rust compiler exists. +if ! command -v "$RUSTC" >/dev/null; then + if [ "$1" = -v ]; then + echo >&2 "***" + echo >&2 "*** Rust compiler '$RUSTC' could not be found." + echo >&2 "***" + fi + exit 1 +fi + +# Check that the Rust bindings generator exists. +if ! command -v "$BINDGEN" >/dev/null; then + if [ "$1" = -v ]; then + echo >&2 "***" + echo >&2 "*** Rust bindings generator '$BINDGEN' could not be found." + echo >&2 "***" + fi + exit 1 +fi + +# Check that the Rust compiler version is suitable. +# +# Non-stable and distributions' versions may have a version suffix, e.g. `-dev`. +rust_compiler_version=$( \ + LC_ALL=C "$RUSTC" --version 2>/dev/null \ + | head -n 1 \ + | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \ +) +rust_compiler_min_version=$($min_tool_version rustc) +rust_compiler_cversion=$(get_canonical_version $rust_compiler_version) +rust_compiler_min_cversion=$(get_canonical_version $rust_compiler_min_version) +if [ "$rust_compiler_cversion" -lt "$rust_compiler_min_cversion" ]; then + if [ "$1" = -v ]; then + echo >&2 "***" + echo >&2 "*** Rust compiler '$RUSTC' is too old." + echo >&2 "*** Your version: $rust_compiler_version" + echo >&2 "*** Minimum version: $rust_compiler_min_version" + echo >&2 "***" + fi + exit 1 +fi +if [ "$1" = -v ] && [ "$rust_compiler_cversion" -gt "$rust_compiler_min_cversion" ]; then + echo >&2 "***" + echo >&2 "*** Rust compiler '$RUSTC' is too new. This may or may not work." + echo >&2 "*** Your version: $rust_compiler_version" + echo >&2 "*** Expected version: $rust_compiler_min_version" + echo >&2 "***" +fi + +# Check that the Rust bindings generator is suitable. +# +# Non-stable and distributions' versions may have a version suffix, e.g. `-dev`. +rust_bindings_generator_version=$( \ + LC_ALL=C "$BINDGEN" --version 2>/dev/null \ + | head -n 1 \ + | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \ +) +rust_bindings_generator_min_version=$($min_tool_version bindgen) +rust_bindings_generator_cversion=$(get_canonical_version $rust_bindings_generator_version) +rust_bindings_generator_min_cversion=$(get_canonical_version $rust_bindings_generator_min_version) +if [ "$rust_bindings_generator_cversion" -lt "$rust_bindings_generator_min_cversion" ]; then + if [ "$1" = -v ]; then + echo >&2 "***" + echo >&2 "*** Rust bindings generator '$BINDGEN' is too old." + echo >&2 "*** Your version: $rust_bindings_generator_version" + echo >&2 "*** Minimum version: $rust_bindings_generator_min_version" + echo >&2 "***" + fi + exit 1 +fi +if [ "$1" = -v ] && [ "$rust_bindings_generator_cversion" -gt "$rust_bindings_generator_min_cversion" ]; then + echo >&2 "***" + echo >&2 "*** Rust bindings generator '$BINDGEN' is too new. This may or may not work." + echo >&2 "*** Your version: $rust_bindings_generator_version" + echo >&2 "*** Expected version: $rust_bindings_generator_min_version" + echo >&2 "***" +fi + +# Check that the `libclang` used by the Rust bindings generator is suitable. +bindgen_libclang_version=$( \ + LC_ALL=C "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang.h 2>&1 >/dev/null \ + | grep -F 'clang version ' \ + | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \ + | head -n 1 \ +) +bindgen_libclang_min_version=$($min_tool_version llvm) +bindgen_libclang_cversion=$(get_canonical_version $bindgen_libclang_version) +bindgen_libclang_min_cversion=$(get_canonical_version $bindgen_libclang_min_version) +if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then + if [ "$1" = -v ]; then + echo >&2 "***" + echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN') is too old." + echo >&2 "*** Your version: $bindgen_libclang_version" + echo >&2 "*** Minimum version: $bindgen_libclang_min_version" + echo >&2 "***" + fi + exit 1 +fi + +# If the C compiler is Clang, then we can also check whether its version +# matches the `libclang` version used by the Rust bindings generator. +# +# In the future, we might be able to perform a full version check, see +# https://github.com/rust-lang/rust-bindgen/issues/2138. +if [ "$1" = -v ]; then + cc_name=$($(dirname $0)/cc-version.sh "$CC" | cut -f1 -d' ') + if [ "$cc_name" = Clang ]; then + clang_version=$( \ + LC_ALL=C "$CC" --version 2>/dev/null \ + | sed -nE '1s:.*version ([0-9]+\.[0-9]+\.[0-9]+).*:\1:p' + ) + if [ "$clang_version" != "$bindgen_libclang_version" ]; then + echo >&2 "***" + echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN')" + echo >&2 "*** version does not match Clang's. This may be a problem." + echo >&2 "*** libclang version: $bindgen_libclang_version" + echo >&2 "*** Clang version: $clang_version" + echo >&2 "***" + fi + fi +fi + +# Check that the source code for the `core` standard library exists. +# +# `$KRUSTFLAGS` is passed in case the user added `--sysroot`. +rustc_sysroot=$("$RUSTC" $KRUSTFLAGS --print sysroot) +rustc_src=${RUST_LIB_SRC:-"$rustc_sysroot/lib/rustlib/src/rust/library"} +rustc_src_core="$rustc_src/core/src/lib.rs" +if [ ! -e "$rustc_src_core" ]; then + if [ "$1" = -v ]; then + echo >&2 "***" + echo >&2 "*** Source code for the 'core' standard library could not be found" + echo >&2 "*** at '$rustc_src_core'." + echo >&2 "***" + fi + exit 1 +fi diff --git a/scripts/rust_is_available_bindgen_libclang.h b/scripts/rust_is_available_bindgen_libclang.h new file mode 100644 index 000000000000..0ef6db10d674 --- /dev/null +++ b/scripts/rust_is_available_bindgen_libclang.h @@ -0,0 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#pragma message("clang version " __clang_version__) -- cgit v1.2.3 From e4b69cb9a99a567d1611f9cced92f475ae224cdb Mon Sep 17 00:00:00 2001 From: Daniel Xu Date: Thu, 4 Aug 2022 12:55:07 +0200 Subject: scripts: add `is_rust_module.sh` This script is used to detect whether a kernel module is written in Rust. It will later be used to disable BTF generation on Rust modules as BTF does not yet support Rust. Reviewed-by: Kees Cook Reviewed-by: Greg Kroah-Hartman Co-developed-by: Alex Gaynor Signed-off-by: Alex Gaynor Co-developed-by: Wedson Almeida Filho Signed-off-by: Wedson Almeida Filho Signed-off-by: Daniel Xu Co-developed-by: Miguel Ojeda Signed-off-by: Miguel Ojeda --- scripts/is_rust_module.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100755 scripts/is_rust_module.sh (limited to 'scripts') diff --git a/scripts/is_rust_module.sh b/scripts/is_rust_module.sh new file mode 100755 index 000000000000..28b3831a7593 --- /dev/null +++ b/scripts/is_rust_module.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# is_rust_module.sh module.ko +# +# Returns `0` if `module.ko` is a Rust module, `1` otherwise. + +set -e + +# Using the `16_` prefix ensures other symbols with the same substring +# are not picked up (even if it would be unlikely). The last part is +# used just in case LLVM decides to use the `.` suffix. +# +# 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:]]*$' -- cgit v1.2.3 From 2f7ab1267dc9b2d1f29695aff3211c87483480f3 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Sat, 3 Jul 2021 16:42:57 +0200 Subject: Kbuild: add Rust support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Having most of the new files in place, we now enable Rust support in the build system, including `Kconfig` entries related to Rust, the Rust configuration printer and a few other bits. Reviewed-by: Kees Cook Reviewed-by: Nick Desaulniers Tested-by: Nick Desaulniers Reviewed-by: Greg Kroah-Hartman Co-developed-by: Alex Gaynor Signed-off-by: Alex Gaynor Co-developed-by: Finn Behrens Signed-off-by: Finn Behrens Co-developed-by: Adam Bratschi-Kaye Signed-off-by: Adam Bratschi-Kaye Co-developed-by: Wedson Almeida Filho Signed-off-by: Wedson Almeida Filho Co-developed-by: Michael Ellerman Signed-off-by: Michael Ellerman Co-developed-by: Sven Van Asbroeck Signed-off-by: Sven Van Asbroeck Co-developed-by: Gary Guo Signed-off-by: Gary Guo Co-developed-by: Boris-Chengbiao Zhou Signed-off-by: Boris-Chengbiao Zhou Co-developed-by: Boqun Feng Signed-off-by: Boqun Feng Co-developed-by: Douglas Su Signed-off-by: Douglas Su Co-developed-by: Dariusz Sosnowski Signed-off-by: Dariusz Sosnowski Co-developed-by: Antonio Terceiro Signed-off-by: Antonio Terceiro Co-developed-by: Daniel Xu Signed-off-by: Daniel Xu Co-developed-by: Björn Roy Baron Signed-off-by: Björn Roy Baron Co-developed-by: Martin Rodriguez Reboredo Signed-off-by: Martin Rodriguez Reboredo Signed-off-by: Miguel Ojeda --- .gitignore | 2 + Makefile | 172 ++++++++++++++++++- arch/Kconfig | 6 + include/linux/compiler_types.h | 6 +- init/Kconfig | 46 ++++- kernel/configs/rust.config | 1 + lib/Kconfig.debug | 34 ++++ rust/.gitignore | 8 + rust/Makefile | 381 +++++++++++++++++++++++++++++++++++++++++ rust/bindgen_parameters | 21 +++ scripts/Kconfig.include | 6 +- scripts/Makefile | 3 + scripts/Makefile.build | 60 +++++++ scripts/Makefile.debug | 8 + scripts/Makefile.host | 34 +++- scripts/Makefile.lib | 12 ++ scripts/Makefile.modfinal | 8 +- scripts/cc-version.sh | 12 +- scripts/kconfig/confdata.c | 75 ++++++++ 19 files changed, 869 insertions(+), 26 deletions(-) create mode 100644 kernel/configs/rust.config create mode 100644 rust/.gitignore create mode 100644 rust/Makefile create mode 100644 rust/bindgen_parameters (limited to 'scripts') diff --git a/.gitignore b/.gitignore index 97e085d613a2..5da004814678 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,8 @@ *.o *.o.* *.patch +*.rmeta +*.rsi *.s *.so *.so.dbg diff --git a/Makefile b/Makefile index 647a42a1f800..c759ee315254 100644 --- a/Makefile +++ b/Makefile @@ -120,6 +120,15 @@ endif export KBUILD_CHECKSRC +# Enable "clippy" (a linter) as part of the Rust compilation. +# +# Use 'make CLIPPY=1' to enable it. +ifeq ("$(origin CLIPPY)", "command line") + KBUILD_CLIPPY := $(CLIPPY) +endif + +export KBUILD_CLIPPY + # Use make M=dir or set the environment variable KBUILD_EXTMOD to specify the # directory of external module to build. Setting M= takes precedence. ifeq ("$(origin M)", "command line") @@ -270,14 +279,14 @@ no-dot-config-targets := $(clean-targets) \ cscope gtags TAGS tags help% %docs check% coccicheck \ $(version_h) headers headers_% archheaders archscripts \ %asm-generic kernelversion %src-pkg dt_binding_check \ - outputmakefile + outputmakefile rustavailable rustfmt rustfmtcheck # Installation targets should not require compiler. Unfortunately, vdso_install # is an exception where build artifacts may be updated. This must be fixed. no-compiler-targets := $(no-dot-config-targets) install dtbs_install \ headers_install modules_install kernelrelease image_name no-sync-config-targets := $(no-dot-config-targets) %install kernelrelease \ image_name -single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/ +single-targets := %.a %.i %.rsi %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/ config-build := mixed-build := @@ -439,6 +448,7 @@ else HOSTCC = gcc HOSTCXX = g++ endif +HOSTRUSTC = rustc HOSTPKG_CONFIG = pkg-config KBUILD_USERHOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ @@ -447,8 +457,26 @@ KBUILD_USERHOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ KBUILD_USERCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(USERCFLAGS) KBUILD_USERLDFLAGS := $(USERLDFLAGS) +# These flags apply to all Rust code in the tree, including the kernel and +# host programs. +export rust_common_flags := --edition=2021 \ + -Zbinary_dep_depinfo=y \ + -Dunsafe_op_in_unsafe_fn -Drust_2018_idioms \ + -Dunreachable_pub -Dnon_ascii_idents \ + -Wmissing_docs \ + -Drustdoc::missing_crate_level_docs \ + -Dclippy::correctness -Dclippy::style \ + -Dclippy::suspicious -Dclippy::complexity \ + -Dclippy::perf \ + -Dclippy::let_unit_value -Dclippy::mut_mut \ + -Dclippy::needless_bitwise_bool \ + -Dclippy::needless_continue \ + -Wclippy::dbg_macro + KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) $(HOSTCFLAGS) KBUILD_HOSTCXXFLAGS := -Wall -O2 $(HOST_LFS_CFLAGS) $(HOSTCXXFLAGS) +KBUILD_HOSTRUSTFLAGS := $(rust_common_flags) -O -Cstrip=debuginfo \ + -Zallow-features= $(HOSTRUSTFLAGS) KBUILD_HOSTLDFLAGS := $(HOST_LFS_LDFLAGS) $(HOSTLDFLAGS) KBUILD_HOSTLDLIBS := $(HOST_LFS_LIBS) $(HOSTLDLIBS) @@ -473,6 +501,12 @@ OBJDUMP = $(CROSS_COMPILE)objdump READELF = $(CROSS_COMPILE)readelf STRIP = $(CROSS_COMPILE)strip endif +RUSTC = rustc +RUSTDOC = rustdoc +RUSTFMT = rustfmt +CLIPPY_DRIVER = clippy-driver +BINDGEN = bindgen +CARGO = cargo PAHOLE = pahole RESOLVE_BTFIDS = $(objtree)/tools/bpf/resolve_btfids/resolve_btfids LEX = flex @@ -498,9 +532,11 @@ CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \ -Wbitwise -Wno-return-void -Wno-unknown-attribute $(CF) NOSTDINC_FLAGS := CFLAGS_MODULE = +RUSTFLAGS_MODULE = AFLAGS_MODULE = LDFLAGS_MODULE = CFLAGS_KERNEL = +RUSTFLAGS_KERNEL = AFLAGS_KERNEL = LDFLAGS_vmlinux = @@ -529,15 +565,43 @@ KBUILD_CFLAGS := -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs \ -Werror=return-type -Wno-format-security \ -std=gnu11 KBUILD_CPPFLAGS := -D__KERNEL__ +KBUILD_RUSTFLAGS := $(rust_common_flags) \ + --target=$(objtree)/rust/target.json \ + -Cpanic=abort -Cembed-bitcode=n -Clto=n \ + -Cforce-unwind-tables=n -Ccodegen-units=1 \ + -Csymbol-mangling-version=v0 \ + -Crelocation-model=static \ + -Zfunction-sections=n \ + -Dclippy::float_arithmetic + KBUILD_AFLAGS_KERNEL := KBUILD_CFLAGS_KERNEL := +KBUILD_RUSTFLAGS_KERNEL := KBUILD_AFLAGS_MODULE := -DMODULE KBUILD_CFLAGS_MODULE := -DMODULE +KBUILD_RUSTFLAGS_MODULE := --cfg MODULE KBUILD_LDFLAGS_MODULE := KBUILD_LDFLAGS := CLANG_FLAGS := +ifeq ($(KBUILD_CLIPPY),1) + RUSTC_OR_CLIPPY_QUIET := CLIPPY + RUSTC_OR_CLIPPY = $(CLIPPY_DRIVER) +else + RUSTC_OR_CLIPPY_QUIET := RUSTC + RUSTC_OR_CLIPPY = $(RUSTC) +endif + +ifdef RUST_LIB_SRC + export RUST_LIB_SRC +endif + +# Allows the usage of unstable features in stable compilers. +export RUSTC_BOOTSTRAP := 1 + export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG +export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN CARGO +export HOSTRUSTC KBUILD_HOSTRUSTFLAGS export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD @@ -546,9 +610,10 @@ export KBUILD_USERCFLAGS KBUILD_USERLDFLAGS export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE +export KBUILD_RUSTFLAGS RUSTFLAGS_KERNEL RUSTFLAGS_MODULE export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE -export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE -export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL +export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_RUSTFLAGS_MODULE KBUILD_LDFLAGS_MODULE +export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL KBUILD_RUSTFLAGS_KERNEL export PAHOLE_FLAGS # Files to ignore in find ... statements @@ -729,7 +794,7 @@ $(KCONFIG_CONFIG): # # Do not use $(call cmd,...) here. That would suppress prompts from syncconfig, # so you cannot notice that Kconfig is waiting for the user input. -%/config/auto.conf %/config/auto.conf.cmd %/generated/autoconf.h: $(KCONFIG_CONFIG) +%/config/auto.conf %/config/auto.conf.cmd %/generated/autoconf.h %/generated/rustc_cfg: $(KCONFIG_CONFIG) $(Q)$(kecho) " SYNC $@" $(Q)$(MAKE) -f $(srctree)/Makefile syncconfig else # !may-sync-config @@ -758,10 +823,17 @@ KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE KBUILD_CFLAGS += -O2 +KBUILD_RUSTFLAGS += -Copt-level=2 else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE KBUILD_CFLAGS += -Os +KBUILD_RUSTFLAGS += -Copt-level=s endif +# Always set `debug-assertions` and `overflow-checks` because their default +# depends on `opt-level` and `debug-assertions`, respectively. +KBUILD_RUSTFLAGS += -Cdebug-assertions=$(if $(CONFIG_RUST_DEBUG_ASSERTIONS),y,n) +KBUILD_RUSTFLAGS += -Coverflow-checks=$(if $(CONFIG_RUST_OVERFLOW_CHECKS),y,n) + # Tell gcc to never replace conditional load with a non-conditional one ifdef CONFIG_CC_IS_GCC # gcc-10 renamed --param=allow-store-data-races=0 to @@ -792,6 +864,9 @@ KBUILD_CFLAGS-$(CONFIG_WERROR) += -Werror KBUILD_CFLAGS-$(CONFIG_CC_NO_ARRAY_BOUNDS) += -Wno-array-bounds KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH) +KBUILD_RUSTFLAGS-$(CONFIG_WERROR) += -Dwarnings +KBUILD_RUSTFLAGS += $(KBUILD_RUSTFLAGS-y) + ifdef CONFIG_CC_IS_CLANG KBUILD_CPPFLAGS += -Qunused-arguments # The kernel builds with '-std=gnu11' so use of GNU extensions is acceptable. @@ -812,12 +887,15 @@ KBUILD_CFLAGS += $(call cc-disable-warning, dangling-pointer) ifdef CONFIG_FRAME_POINTER KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls +KBUILD_RUSTFLAGS += -Cforce-frame-pointers=y else # Some targets (ARM with Thumb2, for example), can't be built with frame # pointers. For those, we don't have FUNCTION_TRACER automatically # select FRAME_POINTER. However, FUNCTION_TRACER adds -pg, and this is # incompatible with -fomit-frame-pointer with current GCC, so we don't use # -fomit-frame-pointer with FUNCTION_TRACER. +# In the Rust target specification, "frame-pointer" is set explicitly +# to "may-omit". ifndef CONFIG_FUNCTION_TRACER KBUILD_CFLAGS += -fomit-frame-pointer endif @@ -882,8 +960,10 @@ ifdef CONFIG_DEBUG_SECTION_MISMATCH KBUILD_CFLAGS += -fno-inline-functions-called-once endif +# `rustc`'s `-Zfunction-sections` applies to data too (as of 1.59.0). ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections +KBUILD_RUSTFLAGS_KERNEL += -Zfunction-sections=y LDFLAGS_vmlinux += --gc-sections endif @@ -1026,10 +1106,11 @@ include $(addprefix $(srctree)/, $(include-y)) # Do not add $(call cc-option,...) below this line. When you build the kernel # from the clean source tree, the GCC plugins do not exist at this point. -# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments +# Add user supplied CPPFLAGS, AFLAGS, CFLAGS and RUSTFLAGS as the last assignments KBUILD_CPPFLAGS += $(KCPPFLAGS) KBUILD_AFLAGS += $(KAFLAGS) KBUILD_CFLAGS += $(KCFLAGS) +KBUILD_RUSTFLAGS += $(KRUSTFLAGS) KBUILD_LDFLAGS_MODULE += --build-id=sha1 LDFLAGS_vmlinux += --build-id=sha1 @@ -1104,6 +1185,7 @@ ifeq ($(KBUILD_EXTMOD),) core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ core-$(CONFIG_BLOCK) += block/ core-$(CONFIG_IO_URING) += io_uring/ +core-$(CONFIG_RUST) += rust/ vmlinux-dirs := $(patsubst %/,%,$(filter %/, \ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ @@ -1206,6 +1288,10 @@ prepare0: archprepare # All the preparing.. prepare: prepare0 +ifdef CONFIG_RUST + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh -v + $(Q)$(MAKE) $(build)=rust +endif PHONY += remove-stale-files remove-stale-files: @@ -1499,7 +1585,7 @@ endif # CONFIG_MODULES # Directories & files removed with 'make clean' CLEAN_FILES += include/ksym vmlinux.symvers modules-only.symvers \ modules.builtin modules.builtin.modinfo modules.nsdeps \ - compile_commands.json .thinlto-cache + compile_commands.json .thinlto-cache rust/test rust/doc # Directories & files removed with 'make mrproper' MRPROPER_FILES += include/config include/generated \ @@ -1510,7 +1596,8 @@ MRPROPER_FILES += include/config include/generated \ certs/signing_key.pem \ certs/x509.genkey \ vmlinux-gdb.py \ - *.spec + *.spec \ + rust/target.json rust/libmacros.so # clean - Delete most, but leave enough to build external modules # @@ -1535,6 +1622,9 @@ $(mrproper-dirs): mrproper: clean $(mrproper-dirs) $(call cmd,rmfiles) + @find . $(RCS_FIND_IGNORE) \ + \( -name '*.rmeta' \) \ + -type f -print | xargs rm -f # distclean # @@ -1622,6 +1712,24 @@ help: @echo ' kselftest-merge - Merge all the config dependencies of' @echo ' kselftest to existing .config.' @echo '' + @echo 'Rust targets:' + @echo ' rustavailable - Checks whether the Rust toolchain is' + @echo ' available and, if not, explains why.' + @echo ' rustfmt - Reformat all the Rust code in the kernel' + @echo ' rustfmtcheck - Checks if all the Rust code in the kernel' + @echo ' is formatted, printing a diff otherwise.' + @echo ' rustdoc - Generate Rust documentation' + @echo ' (requires kernel .config)' + @echo ' rusttest - Runs the Rust tests' + @echo ' (requires kernel .config; downloads external repos)' + @echo ' rust-analyzer - Generate rust-project.json rust-analyzer support file' + @echo ' (requires kernel .config)' + @echo ' dir/file.[os] - Build specified target only' + @echo ' dir/file.rsi - Build macro expanded source, similar to C preprocessing.' + @echo ' Run with RUSTFMT=n to skip reformatting if needed.' + @echo ' The output is not intended to be compilable.' + @echo ' dir/file.ll - Build the LLVM assembly file' + @echo '' @$(if $(dtstree), \ echo 'Devicetree:'; \ echo '* dtbs - Build device tree blobs for enabled boards'; \ @@ -1694,6 +1802,52 @@ PHONY += $(DOC_TARGETS) $(DOC_TARGETS): $(Q)$(MAKE) $(build)=Documentation $@ + +# Rust targets +# --------------------------------------------------------------------------- + +# "Is Rust available?" target +PHONY += rustavailable +rustavailable: + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh -v && echo "Rust is available!" + +# Documentation target +# +# Using the singular to avoid running afoul of `no-dot-config-targets`. +PHONY += rustdoc +rustdoc: prepare + $(Q)$(MAKE) $(build)=rust $@ + +# Testing target +PHONY += rusttest +rusttest: prepare + $(Q)$(MAKE) $(build)=rust $@ + +# Formatting targets +PHONY += rustfmt rustfmtcheck + +# We skip `rust/alloc` since we want to minimize the diff w.r.t. upstream. +# +# We match using absolute paths since `find` does not resolve them +# when matching, which is a problem when e.g. `srctree` is `..`. +# We `grep` afterwards in order to remove the directory entry itself. +rustfmt: + $(Q)find $(abs_srctree) -type f -name '*.rs' \ + -o -path $(abs_srctree)/rust/alloc -prune \ + -o -path $(abs_objtree)/rust/test -prune \ + | grep -Fv $(abs_srctree)/rust/alloc \ + | grep -Fv $(abs_objtree)/rust/test \ + | grep -Fv generated \ + | xargs $(RUSTFMT) $(rustfmt_flags) + +rustfmtcheck: rustfmt_flags = --check +rustfmtcheck: rustfmt + +# IDE support targets +PHONY += rust-analyzer +rust-analyzer: + $(Q)$(MAKE) $(build)=rust $@ + # Misc # --------------------------------------------------------------------------- @@ -1861,7 +2015,7 @@ $(clean-dirs): clean: $(clean-dirs) $(call cmd,rmfiles) @find $(or $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \ - \( -name '*.[aios]' -o -name '*.ko' -o -name '.*.cmd' \ + \( -name '*.[aios]' -o -name '*.rsi' -o -name '*.ko' -o -name '.*.cmd' \ -o -name '*.ko.*' \ -o -name '*.dtb' -o -name '*.dtbo' -o -name '*.dtb.S' -o -name '*.dt.yaml' \ -o -name '*.dwo' -o -name '*.lst' \ diff --git a/arch/Kconfig b/arch/Kconfig index 8b311e400ec1..d9b4ae0fc805 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -355,6 +355,12 @@ config HAVE_RSEQ This symbol should be selected by an architecture if it supports an implementation of restartable sequences. +config HAVE_RUST + bool + help + This symbol should be selected by an architecture if it + supports Rust. + config HAVE_FUNCTION_ARG_ACCESS_API bool help diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index 4f2a819fd60a..50b3f6b9502e 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -4,8 +4,12 @@ #ifndef __ASSEMBLY__ +/* + * Skipped when running bindgen due to a libclang issue; + * see https://github.com/rust-lang/rust-bindgen/issues/2244. + */ #if defined(CONFIG_DEBUG_INFO_BTF) && defined(CONFIG_PAHOLE_HAS_BTF_TAG) && \ - __has_attribute(btf_type_tag) + __has_attribute(btf_type_tag) && !defined(__BINDGEN__) # define BTF_TYPE_TAG(value) __attribute__((btf_type_tag(#value))) #else # define BTF_TYPE_TAG(value) /* nothing */ diff --git a/init/Kconfig b/init/Kconfig index 532362fcfe31..a078cb026523 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -60,6 +60,17 @@ config LLD_VERSION default $(ld-version) if LD_IS_LLD default 0 +config RUST_IS_AVAILABLE + def_bool $(success,$(srctree)/scripts/rust_is_available.sh) + help + This shows whether a suitable Rust toolchain is available (found). + + Please see Documentation/rust/quick-start.rst for instructions on how + to satify the build requirements of Rust support. + + In particular, the Makefile target 'rustavailable' is useful to check + why the Rust toolchain is not being detected. + config CC_CAN_LINK bool default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(CLANG_FLAGS) $(USERCFLAGS) $(USERLDFLAGS) $(m64-flag)) if 64BIT @@ -147,7 +158,8 @@ config WERROR default COMPILE_TEST help A kernel build should not cause any compiler warnings, and this - enables the '-Werror' flag to enforce that rule by default. + enables the '-Werror' (for C) and '-Dwarnings' (for Rust) flags + to enforce that rule by default. However, if you have a new (or very old) compiler with odd and unusual warnings, or you have some architecture with problems, @@ -1899,6 +1911,38 @@ config PROFILING Say Y here to enable the extended profiling support mechanisms used by profilers. +config RUST + bool "Rust support" + depends on HAVE_RUST + depends on RUST_IS_AVAILABLE + depends on !MODVERSIONS + depends on !GCC_PLUGINS + depends on !RANDSTRUCT + depends on !DEBUG_INFO_BTF + select CONSTRUCTORS + help + Enables Rust support in the kernel. + + This allows other Rust-related options, like drivers written in Rust, + to be selected. + + It is also required to be able to load external kernel modules + written in Rust. + + See Documentation/rust/ for more information. + + If unsure, say N. + +config RUSTC_VERSION_TEXT + string + depends on RUST + default $(shell,command -v $(RUSTC) >/dev/null 2>&1 && $(RUSTC) --version || echo n) + +config BINDGEN_VERSION_TEXT + string + depends on RUST + default $(shell,command -v $(BINDGEN) >/dev/null 2>&1 && $(BINDGEN) --version || echo n) + # # Place an empty function call at each tracepoint site. Can be # dynamically changed for a probe function. diff --git a/kernel/configs/rust.config b/kernel/configs/rust.config new file mode 100644 index 000000000000..38a7c5362c9c --- /dev/null +++ b/kernel/configs/rust.config @@ -0,0 +1 @@ +CONFIG_RUST=y diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index d3e5f36bb01e..e62271da937f 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2710,6 +2710,40 @@ config HYPERV_TESTING endmenu # "Kernel Testing and Coverage" +menu "Rust hacking" + +config RUST_DEBUG_ASSERTIONS + bool "Debug assertions" + depends on RUST + help + Enables rustc's `-Cdebug-assertions` codegen option. + + This flag lets you turn `cfg(debug_assertions)` conditional + compilation on or off. This can be used to enable extra debugging + code in development but not in production. For example, it controls + the behavior of the standard library's `debug_assert!` macro. + + Note that this will apply to all Rust code, including `core`. + + If unsure, say N. + +config RUST_OVERFLOW_CHECKS + bool "Overflow checks" + default y + depends on RUST + help + Enables rustc's `-Coverflow-checks` codegen option. + + This flag allows you to control the behavior of runtime integer + overflow. When overflow-checks are enabled, a Rust panic will occur + on overflow. + + Note that this will apply to all Rust code, including `core`. + + If unsure, say Y. + +endmenu # "Rust" + source "Documentation/Kconfig" endmenu # Kernel hacking diff --git a/rust/.gitignore b/rust/.gitignore new file mode 100644 index 000000000000..9bd1af8e05a1 --- /dev/null +++ b/rust/.gitignore @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 + +target.json +bindings_generated.rs +bindings_helpers_generated.rs +exports_*_generated.h +doc/ +test/ diff --git a/rust/Makefile b/rust/Makefile new file mode 100644 index 000000000000..7700d3853404 --- /dev/null +++ b/rust/Makefile @@ -0,0 +1,381 @@ +# SPDX-License-Identifier: GPL-2.0 + +always-$(CONFIG_RUST) += target.json +no-clean-files += target.json + +obj-$(CONFIG_RUST) += core.o compiler_builtins.o +always-$(CONFIG_RUST) += exports_core_generated.h + +# Missing prototypes are expected in the helpers since these are exported +# for Rust only, thus there is no header nor prototypes. +obj-$(CONFIG_RUST) += helpers.o +CFLAGS_REMOVE_helpers.o = -Wmissing-prototypes -Wmissing-declarations + +always-$(CONFIG_RUST) += libmacros.so +no-clean-files += libmacros.so + +always-$(CONFIG_RUST) += bindings/bindings_generated.rs bindings/bindings_helpers_generated.rs +obj-$(CONFIG_RUST) += alloc.o bindings.o kernel.o +always-$(CONFIG_RUST) += exports_alloc_generated.h exports_bindings_generated.h \ + exports_kernel_generated.h + +obj-$(CONFIG_RUST) += exports.o + +# Avoids running `$(RUSTC)` for the sysroot when it may not be available. +ifdef CONFIG_RUST + +# `$(rust_flags)` is passed in case the user added `--sysroot`. +rustc_sysroot := $(shell $(RUSTC) $(rust_flags) --print sysroot) +rustc_host_target := $(shell $(RUSTC) --version --verbose | grep -F 'host: ' | cut -d' ' -f2) +RUST_LIB_SRC ?= $(rustc_sysroot)/lib/rustlib/src/rust/library + +ifeq ($(quiet),silent_) +cargo_quiet=-q +rust_test_quiet=-q +rustdoc_test_quiet=--test-args -q +else ifeq ($(quiet),quiet_) +rust_test_quiet=-q +rustdoc_test_quiet=--test-args -q +else +cargo_quiet=--verbose +endif + +core-cfgs = \ + --cfg no_fp_fmt_parse + +alloc-cfgs = \ + --cfg no_fmt \ + --cfg no_global_oom_handling \ + --cfg no_macros \ + --cfg no_rc \ + --cfg no_str \ + --cfg no_string \ + --cfg no_sync \ + --cfg no_thin + +quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< + cmd_rustdoc = \ + OBJTREE=$(abspath $(objtree)) \ + $(RUSTDOC) $(if $(rustdoc_host),$(rust_common_flags),$(rust_flags)) \ + $(rustc_target_flags) -L$(objtree)/$(obj) \ + --output $(objtree)/$(obj)/doc \ + --crate-name $(subst rustdoc-,,$@) \ + @$(objtree)/include/generated/rustc_cfg $< + +# The `html_logo_url` and `html_favicon_url` forms of the `doc` attribute +# can be used to specify a custom logo. However: +# - The given value is used as-is, thus it cannot be relative or a local file +# (unlike the non-custom case) since the generated docs have subfolders. +# - It requires adding it to every crate. +# - It requires changing `core` which comes from the sysroot. +# +# Using `-Zcrate-attr` would solve the last two points, but not the first. +# The https://github.com/rust-lang/rfcs/pull/3226 RFC suggests two new +# command-like flags to solve the issue. Meanwhile, we use the non-custom case +# and then retouch the generated files. +rustdoc: rustdoc-core rustdoc-macros rustdoc-compiler_builtins \ + rustdoc-alloc rustdoc-kernel + $(Q)cp $(srctree)/Documentation/images/logo.svg $(objtree)/$(obj)/doc + $(Q)cp $(srctree)/Documentation/images/COPYING-logo $(objtree)/$(obj)/doc + $(Q)find $(objtree)/$(obj)/doc -name '*.html' -type f -print0 | xargs -0 sed -Ei \ + -e 's:rust-logo\.svg:logo.svg:g' \ + -e 's:rust-logo\.png:logo.svg:g' \ + -e 's:favicon\.svg:logo.svg:g' \ + -e 's:::g' + $(Q)echo '.logo-container > img { object-fit: contain; }' \ + >> $(objtree)/$(obj)/doc/rustdoc.css + +rustdoc-macros: private rustdoc_host = yes +rustdoc-macros: private rustc_target_flags = --crate-type proc-macro \ + --extern proc_macro +rustdoc-macros: $(src)/macros/lib.rs FORCE + $(call if_changed,rustdoc) + +rustdoc-core: private rustc_target_flags = $(core-cfgs) +rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE + $(call if_changed,rustdoc) + +rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE + $(call if_changed,rustdoc) + +# We need to allow `rustdoc::broken_intra_doc_links` because some +# `no_global_oom_handling` functions refer to non-`no_global_oom_handling` +# functions. Ideally `rustdoc` would have a way to distinguish broken links +# due to things that are "configured out" vs. entirely non-existing ones. +rustdoc-alloc: private rustc_target_flags = $(alloc-cfgs) \ + -Arustdoc::broken_intra_doc_links +rustdoc-alloc: $(src)/alloc/lib.rs rustdoc-core rustdoc-compiler_builtins FORCE + $(call if_changed,rustdoc) + +rustdoc-kernel: private rustc_target_flags = --extern alloc \ + --extern macros=$(objtree)/$(obj)/libmacros.so \ + --extern bindings +rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-macros \ + rustdoc-compiler_builtins rustdoc-alloc $(obj)/libmacros.so \ + $(obj)/bindings.o FORCE + $(call if_changed,rustdoc) + +quiet_cmd_rustc_test_library = RUSTC TL $< + cmd_rustc_test_library = \ + OBJTREE=$(abspath $(objtree)) \ + $(RUSTC) $(rust_common_flags) \ + @$(objtree)/include/generated/rustc_cfg $(rustc_target_flags) \ + --crate-type $(if $(rustc_test_library_proc),proc-macro,rlib) \ + --out-dir $(objtree)/$(obj)/test --cfg testlib \ + --sysroot $(objtree)/$(obj)/test/sysroot \ + -L$(objtree)/$(obj)/test \ + --crate-name $(subst rusttest-,,$(subst rusttestlib-,,$@)) $< + +rusttestlib-macros: private rustc_target_flags = --extern proc_macro +rusttestlib-macros: private rustc_test_library_proc = yes +rusttestlib-macros: $(src)/macros/lib.rs rusttest-prepare FORCE + $(call if_changed,rustc_test_library) + +rusttestlib-bindings: $(src)/bindings/lib.rs rusttest-prepare FORCE + $(call if_changed,rustc_test_library) + +quiet_cmd_rustdoc_test = RUSTDOC T $< + cmd_rustdoc_test = \ + OBJTREE=$(abspath $(objtree)) \ + $(RUSTDOC) --test $(rust_common_flags) \ + @$(objtree)/include/generated/rustc_cfg \ + $(rustc_target_flags) $(rustdoc_test_target_flags) \ + --sysroot $(objtree)/$(obj)/test/sysroot $(rustdoc_test_quiet) \ + -L$(objtree)/$(obj)/test --output $(objtree)/$(obj)/doc \ + --crate-name $(subst rusttest-,,$@) $< + +# We cannot use `-Zpanic-abort-tests` because some tests are dynamic, +# so for the moment we skip `-Cpanic=abort`. +quiet_cmd_rustc_test = RUSTC T $< + cmd_rustc_test = \ + OBJTREE=$(abspath $(objtree)) \ + $(RUSTC) --test $(rust_common_flags) \ + @$(objtree)/include/generated/rustc_cfg \ + $(rustc_target_flags) --out-dir $(objtree)/$(obj)/test \ + --sysroot $(objtree)/$(obj)/test/sysroot \ + -L$(objtree)/$(obj)/test \ + --crate-name $(subst rusttest-,,$@) $<; \ + $(objtree)/$(obj)/test/$(subst rusttest-,,$@) $(rust_test_quiet) \ + $(rustc_test_run_flags) + +rusttest: rusttest-macros rusttest-kernel + +# This prepares a custom sysroot with our custom `alloc` instead of +# the standard one. +# +# This requires several hacks: +# - Unlike `core` and `alloc`, `std` depends on more than a dozen crates, +# including third-party crates that need to be downloaded, plus custom +# `build.rs` steps. Thus hardcoding things here is not maintainable. +# - `cargo` knows how to build the standard library, but it is an unstable +# feature so far (`-Zbuild-std`). +# - `cargo` only considers the use case of building the standard library +# to use it in a given package. Thus we need to create a dummy package +# and pick the generated libraries from there. +# - Since we only keep a subset of upstream `alloc` in-tree, we need +# to recreate it on the fly by putting our sources on top. +# - The usual ways of modifying the dependency graph in `cargo` do not seem +# to apply for the `-Zbuild-std` steps, thus we have to mislead it +# by modifying the sources in the sysroot. +# - To avoid messing with the user's Rust installation, we create a clone +# of the sysroot. However, `cargo` ignores `RUSTFLAGS` in the `-Zbuild-std` +# steps, thus we use a wrapper binary passed via `RUSTC` to pass the flag. +# +# In the future, we hope to avoid the whole ordeal by either: +# - Making the `test` crate not depend on `std` (either improving upstream +# or having our own custom crate). +# - Making the tests run in kernel space (requires the previous point). +# - Making `std` and friends be more like a "normal" crate, so that +# `-Zbuild-std` and related hacks are not needed. +quiet_cmd_rustsysroot = RUSTSYSROOT + cmd_rustsysroot = \ + rm -rf $(objtree)/$(obj)/test; \ + mkdir -p $(objtree)/$(obj)/test; \ + cp -a $(rustc_sysroot) $(objtree)/$(obj)/test/sysroot; \ + cp -r $(srctree)/$(src)/alloc/* \ + $(objtree)/$(obj)/test/sysroot/lib/rustlib/src/rust/library/alloc/src; \ + echo '\#!/bin/sh' > $(objtree)/$(obj)/test/rustc_sysroot; \ + echo "$(RUSTC) --sysroot=$(abspath $(objtree)/$(obj)/test/sysroot) \"\$$@\"" \ + >> $(objtree)/$(obj)/test/rustc_sysroot; \ + chmod u+x $(objtree)/$(obj)/test/rustc_sysroot; \ + $(CARGO) -q new $(objtree)/$(obj)/test/dummy; \ + RUSTC=$(objtree)/$(obj)/test/rustc_sysroot $(CARGO) $(cargo_quiet) \ + test -Zbuild-std --target $(rustc_host_target) \ + --manifest-path $(objtree)/$(obj)/test/dummy/Cargo.toml; \ + rm $(objtree)/$(obj)/test/sysroot/lib/rustlib/$(rustc_host_target)/lib/*; \ + cp $(objtree)/$(obj)/test/dummy/target/$(rustc_host_target)/debug/deps/* \ + $(objtree)/$(obj)/test/sysroot/lib/rustlib/$(rustc_host_target)/lib + +rusttest-prepare: FORCE + $(call if_changed,rustsysroot) + +rusttest-macros: private rustc_target_flags = --extern proc_macro +rusttest-macros: private rustdoc_test_target_flags = --crate-type proc-macro +rusttest-macros: $(src)/macros/lib.rs rusttest-prepare FORCE + $(call if_changed,rustc_test) + $(call if_changed,rustdoc_test) + +rusttest-kernel: private rustc_target_flags = --extern alloc \ + --extern macros --extern bindings +rusttest-kernel: $(src)/kernel/lib.rs rusttest-prepare \ + rusttestlib-macros rusttestlib-bindings FORCE + $(call if_changed,rustc_test) + $(call if_changed,rustc_test_library) + +filechk_rust_target = $(objtree)/scripts/generate_rust_target < $< + +$(obj)/target.json: $(objtree)/include/config/auto.conf FORCE + $(call filechk,rust_target) + +ifdef CONFIG_CC_IS_CLANG +bindgen_c_flags = $(c_flags) +else +# bindgen relies on libclang to parse C. Ideally, bindgen would support a GCC +# plugin backend and/or the Clang driver would be perfectly compatible with GCC. +# +# For the moment, here we are tweaking the flags on the fly. This is a hack, +# and some kernel configurations may not work (e.g. `GCC_PLUGIN_RANDSTRUCT` +# if we end up using one of those structs). +bindgen_skip_c_flags := -mno-fp-ret-in-387 -mpreferred-stack-boundary=% \ + -mskip-rax-setup -mgeneral-regs-only -msign-return-address=% \ + -mindirect-branch=thunk-extern -mindirect-branch-register \ + -mfunction-return=thunk-extern -mrecord-mcount -mabi=lp64 \ + -mindirect-branch-cs-prefix -mstack-protector-guard% -mtraceback=no \ + -mno-pointers-to-nested-functions -mno-string \ + -mno-strict-align -mstrict-align \ + -fconserve-stack -falign-jumps=% -falign-loops=% \ + -femit-struct-debug-baseonly -fno-ipa-cp-clone -fno-ipa-sra \ + -fno-partial-inlining -fplugin-arg-arm_ssp_per_task_plugin-% \ + -fno-reorder-blocks -fno-allow-store-data-races -fasan-shadow-offset=% \ + -fzero-call-used-regs=% -fno-stack-clash-protection \ + -fno-inline-functions-called-once \ + --param=% --param asan-% + +# Derived from `scripts/Makefile.clang`. +BINDGEN_TARGET_x86 := x86_64-linux-gnu +BINDGEN_TARGET := $(BINDGEN_TARGET_$(SRCARCH)) + +# All warnings are inhibited since GCC builds are very experimental, +# many GCC warnings are not supported by Clang, they may only appear in +# some configurations, with new GCC versions, etc. +bindgen_extra_c_flags = -w --target=$(BINDGEN_TARGET) + +bindgen_c_flags = $(filter-out $(bindgen_skip_c_flags), $(c_flags)) \ + $(bindgen_extra_c_flags) +endif + +ifdef CONFIG_LTO +bindgen_c_flags_lto = $(filter-out $(CC_FLAGS_LTO), $(bindgen_c_flags)) +else +bindgen_c_flags_lto = $(bindgen_c_flags) +endif + +bindgen_c_flags_final = $(bindgen_c_flags_lto) -D__BINDGEN__ + +quiet_cmd_bindgen = BINDGEN $@ + cmd_bindgen = \ + $(BINDGEN) $< $(bindgen_target_flags) \ + --use-core --with-derive-default --ctypes-prefix core::ffi --no-layout-tests \ + --no-debug '.*' \ + --size_t-is-usize -o $@ -- $(bindgen_c_flags_final) -DMODULE \ + $(bindgen_target_cflags) $(bindgen_target_extra) + +$(obj)/bindings/bindings_generated.rs: private bindgen_target_flags = \ + $(shell grep -v '^\#\|^$$' $(srctree)/$(src)/bindgen_parameters) +$(obj)/bindings/bindings_generated.rs: $(src)/bindings/bindings_helper.h \ + $(src)/bindgen_parameters FORCE + $(call if_changed_dep,bindgen) + +# See `CFLAGS_REMOVE_helpers.o` above. In addition, Clang on C does not warn +# with `-Wmissing-declarations` (unlike GCC), so it is not strictly needed here +# given it is `libclang`; but for consistency, future Clang changes and/or +# a potential future GCC backend for `bindgen`, we disable it too. +$(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_flags = \ + --blacklist-type '.*' --whitelist-var '' \ + --whitelist-function 'rust_helper_.*' +$(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_cflags = \ + -I$(objtree)/$(obj) -Wno-missing-prototypes -Wno-missing-declarations +$(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_extra = ; \ + sed -Ei 's/pub fn rust_helper_([a-zA-Z0-9_]*)/#[link_name="rust_helper_\1"]\n pub fn \1/g' $@ +$(obj)/bindings/bindings_helpers_generated.rs: $(src)/helpers.c FORCE + $(call if_changed_dep,bindgen) + +quiet_cmd_exports = EXPORTS $@ + cmd_exports = \ + $(NM) -p --defined-only $< \ + | grep -E ' (T|R|D) ' | cut -d ' ' -f 3 \ + | xargs -Isymbol \ + echo 'EXPORT_SYMBOL_RUST_GPL(symbol);' > $@ + +$(obj)/exports_core_generated.h: $(obj)/core.o FORCE + $(call if_changed,exports) + +$(obj)/exports_alloc_generated.h: $(obj)/alloc.o FORCE + $(call if_changed,exports) + +$(obj)/exports_bindings_generated.h: $(obj)/bindings.o FORCE + $(call if_changed,exports) + +$(obj)/exports_kernel_generated.h: $(obj)/kernel.o FORCE + $(call if_changed,exports) + +quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@ + cmd_rustc_procmacro = \ + $(RUSTC_OR_CLIPPY) $(rust_common_flags) \ + --emit=dep-info,link --extern proc_macro \ + --crate-type proc-macro --out-dir $(objtree)/$(obj) \ + --crate-name $(patsubst lib%.so,%,$(notdir $@)) $<; \ + mv $(objtree)/$(obj)/$(patsubst lib%.so,%,$(notdir $@)).d $(depfile); \ + sed -i '/^\#/d' $(depfile) + +# Procedural macros can only be used with the `rustc` that compiled it. +# Therefore, to get `libmacros.so` automatically recompiled when the compiler +# version changes, we add `core.o` as a dependency (even if it is not needed). +$(obj)/libmacros.so: $(src)/macros/lib.rs $(obj)/core.o FORCE + $(call if_changed_dep,rustc_procmacro) + +quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L $@ + cmd_rustc_library = \ + OBJTREE=$(abspath $(objtree)) \ + $(if $(skip_clippy),$(RUSTC),$(RUSTC_OR_CLIPPY)) \ + $(filter-out $(skip_flags),$(rust_flags) $(rustc_target_flags)) \ + --emit=dep-info,obj,metadata --crate-type rlib \ + --out-dir $(objtree)/$(obj) -L$(objtree)/$(obj) \ + --crate-name $(patsubst %.o,%,$(notdir $@)) $<; \ + mv $(objtree)/$(obj)/$(patsubst %.o,%,$(notdir $@)).d $(depfile); \ + sed -i '/^\#/d' $(depfile) \ + $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) + +rust-analyzer: + $(Q)$(srctree)/scripts/generate_rust_analyzer.py $(srctree) $(objtree) \ + $(RUST_LIB_SRC) > $(objtree)/rust-project.json + +$(obj)/core.o: private skip_clippy = 1 +$(obj)/core.o: private skip_flags = -Dunreachable_pub +$(obj)/core.o: private rustc_target_flags = $(core-cfgs) +$(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs $(obj)/target.json FORCE + $(call if_changed_dep,rustc_library) + +$(obj)/compiler_builtins.o: private rustc_objcopy = -w -W '__*' +$(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE + $(call if_changed_dep,rustc_library) + +$(obj)/alloc.o: private skip_clippy = 1 +$(obj)/alloc.o: private skip_flags = -Dunreachable_pub +$(obj)/alloc.o: private rustc_target_flags = $(alloc-cfgs) +$(obj)/alloc.o: $(src)/alloc/lib.rs $(obj)/compiler_builtins.o FORCE + $(call if_changed_dep,rustc_library) + +$(obj)/bindings.o: $(src)/bindings/lib.rs \ + $(obj)/compiler_builtins.o \ + $(obj)/bindings/bindings_generated.rs \ + $(obj)/bindings/bindings_helpers_generated.rs FORCE + $(call if_changed_dep,rustc_library) + +$(obj)/kernel.o: private rustc_target_flags = --extern alloc \ + --extern macros --extern bindings +$(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/alloc.o \ + $(obj)/libmacros.so $(obj)/bindings.o FORCE + $(call if_changed_dep,rustc_library) + +endif # CONFIG_RUST diff --git a/rust/bindgen_parameters b/rust/bindgen_parameters new file mode 100644 index 000000000000..be4963bf7203 --- /dev/null +++ b/rust/bindgen_parameters @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0 + +--opaque-type xregs_state +--opaque-type desc_struct +--opaque-type arch_lbr_state +--opaque-type local_apic + +# Packed type cannot transitively contain a `#[repr(align)]` type. +--opaque-type x86_msi_data +--opaque-type x86_msi_addr_lo + +# `try` is a reserved keyword since Rust 2018; solved in `bindgen` v0.59.2, +# commit 2aed6b021680 ("context: Escape the try keyword properly"). +--opaque-type kunit_try_catch + +# If SMP is disabled, `arch_spinlock_t` is defined as a ZST which triggers a Rust +# warning. We don't need to peek into it anyway. +--opaque-type spinlock + +# `seccomp`'s comment gets understood as a doctest +--no-doc-comments diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include index a0ccceb22cf8..274125307ebd 100644 --- a/scripts/Kconfig.include +++ b/scripts/Kconfig.include @@ -36,12 +36,12 @@ ld-option = $(success,$(LD) -v $(1)) as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -c -x assembler -o /dev/null -) # check if $(CC) and $(LD) exist -$(error-if,$(failure,command -v $(CC)),compiler '$(CC)' not found) +$(error-if,$(failure,command -v $(CC)),C compiler '$(CC)' not found) $(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found) -# Get the compiler name, version, and error out if it is not supported. +# Get the C compiler name, version, and error out if it is not supported. cc-info := $(shell,$(srctree)/scripts/cc-version.sh $(CC)) -$(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this compiler is not supported.) +$(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this C compiler is not supported.) cc-name := $(shell,set -- $(cc-info) && echo $1) cc-version := $(shell,set -- $(cc-info) && echo $2) diff --git a/scripts/Makefile b/scripts/Makefile index f084f08ed176..1575af84d557 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -10,6 +10,9 @@ hostprogs-always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable hostprogs-always-$(CONFIG_ASN1) += asn1_compiler hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert +hostprogs-always-$(CONFIG_RUST) += generate_rust_target + +generate_rust_target-rust := y HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include HOSTLDLIBS_sorttable = -lpthread diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 784f46d41959..27be77c0d6d8 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -26,6 +26,7 @@ EXTRA_CPPFLAGS := EXTRA_LDFLAGS := asflags-y := ccflags-y := +rustflags-y := cppflags-y := ldflags-y := @@ -271,6 +272,65 @@ quiet_cmd_cc_lst_c = MKLST $@ $(obj)/%.lst: $(src)/%.c FORCE $(call if_changed_dep,cc_lst_c) +# Compile Rust sources (.rs) +# --------------------------------------------------------------------------- + +rust_allowed_features := core_ffi_c + +rust_common_cmd = \ + RUST_MODFILE=$(modfile) $(RUSTC_OR_CLIPPY) $(rust_flags) \ + -Zallow-features=$(rust_allowed_features) \ + -Zcrate-attr=no_std \ + -Zcrate-attr='feature($(rust_allowed_features))' \ + --extern alloc --extern kernel \ + --crate-type rlib --out-dir $(obj) -L $(objtree)/rust/ \ + --crate-name $(basename $(notdir $@)) + +rust_handle_depfile = \ + mv $(obj)/$(basename $(notdir $@)).d $(depfile); \ + sed -i '/^\#/d' $(depfile) + +# `--emit=obj`, `--emit=asm` and `--emit=llvm-ir` imply a single codegen unit +# will be used. We explicitly request `-Ccodegen-units=1` in any case, and +# the compiler shows a warning if it is not 1. However, if we ever stop +# requesting it explicitly and we start using some other `--emit` that does not +# imply it (and for which codegen is performed), then we would be out of sync, +# i.e. the outputs we would get for the different single targets (e.g. `.ll`) +# would not match each other. + +quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ + cmd_rustc_o_rs = \ + $(rust_common_cmd) --emit=dep-info,obj $<; \ + $(rust_handle_depfile) + +$(obj)/%.o: $(src)/%.rs FORCE + $(call if_changed_dep,rustc_o_rs) + +quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ + cmd_rustc_rsi_rs = \ + $(rust_common_cmd) --emit=dep-info -Zunpretty=expanded $< >$@; \ + command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) $@; \ + $(rust_handle_depfile) + +$(obj)/%.rsi: $(src)/%.rs FORCE + $(call if_changed_dep,rustc_rsi_rs) + +quiet_cmd_rustc_s_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ + cmd_rustc_s_rs = \ + $(rust_common_cmd) --emit=dep-info,asm $<; \ + $(rust_handle_depfile) + +$(obj)/%.s: $(src)/%.rs FORCE + $(call if_changed_dep,rustc_s_rs) + +quiet_cmd_rustc_ll_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ + cmd_rustc_ll_rs = \ + $(rust_common_cmd) --emit=dep-info,llvm-ir $<; \ + $(rust_handle_depfile) + +$(obj)/%.ll: $(src)/%.rs FORCE + $(call if_changed_dep,rustc_ll_rs) + # Compile assembler sources (.S) # --------------------------------------------------------------------------- diff --git a/scripts/Makefile.debug b/scripts/Makefile.debug index 8cf1cb22dd93..332c486f705f 100644 --- a/scripts/Makefile.debug +++ b/scripts/Makefile.debug @@ -1,4 +1,6 @@ DEBUG_CFLAGS := +DEBUG_RUSTFLAGS := + debug-flags-y := -g ifdef CONFIG_DEBUG_INFO_SPLIT @@ -17,9 +19,12 @@ KBUILD_AFLAGS += $(debug-flags-y) ifdef CONFIG_DEBUG_INFO_REDUCED DEBUG_CFLAGS += -fno-var-tracking +DEBUG_RUSTFLAGS += -Cdebuginfo=1 ifdef CONFIG_CC_IS_GCC DEBUG_CFLAGS += -femit-struct-debug-baseonly endif +else +DEBUG_RUSTFLAGS += -Cdebuginfo=2 endif ifdef CONFIG_DEBUG_INFO_COMPRESSED @@ -30,3 +35,6 @@ endif KBUILD_CFLAGS += $(DEBUG_CFLAGS) export DEBUG_CFLAGS + +KBUILD_RUSTFLAGS += $(DEBUG_RUSTFLAGS) +export DEBUG_RUSTFLAGS diff --git a/scripts/Makefile.host b/scripts/Makefile.host index 278b4d6ac945..da133780b751 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -22,6 +22,8 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE # to preprocess a data file. # # Both C and C++ are supported, but preferred language is C for such utilities. +# Rust is also supported, but it may only be used in scenarios where a Rust +# toolchain is required to be available (e.g. when `CONFIG_RUST` is enabled). # # Sample syntax (see Documentation/kbuild/makefiles.rst for reference) # hostprogs := bin2hex @@ -37,15 +39,20 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE # qconf-objs := menu.o # Will compile qconf as a C++ program, and menu as a C program. # They are linked as C++ code to the executable qconf +# +# hostprogs := target +# target-rust := y +# Will compile `target` as a Rust program, using `target.rs` as the crate root. +# The crate may consist of several source files. # C code # Executables compiled from a single .c file host-csingle := $(foreach m,$(hostprogs), \ - $(if $($(m)-objs)$($(m)-cxxobjs),,$(m))) + $(if $($(m)-objs)$($(m)-cxxobjs)$($(m)-rust),,$(m))) # C executables linked based on several .o files host-cmulti := $(foreach m,$(hostprogs),\ - $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m)))) + $(if $($(m)-cxxobjs)$($(m)-rust),,$(if $($(m)-objs),$(m)))) # Object (.o) files compiled from .c files host-cobjs := $(sort $(foreach m,$(hostprogs),$($(m)-objs))) @@ -58,11 +65,17 @@ host-cxxmulti := $(foreach m,$(hostprogs),$(if $($(m)-cxxobjs),$(m))) # C++ Object (.o) files compiled from .cc files host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs))) +# Rust code +# Executables compiled from a single Rust crate (which may consist of +# one or more .rs files) +host-rust := $(foreach m,$(hostprogs),$(if $($(m)-rust),$(m))) + host-csingle := $(addprefix $(obj)/,$(host-csingle)) host-cmulti := $(addprefix $(obj)/,$(host-cmulti)) host-cobjs := $(addprefix $(obj)/,$(host-cobjs)) host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti)) host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs)) +host-rust := $(addprefix $(obj)/,$(host-rust)) ##### # Handle options to gcc. Support building with separate output directory @@ -71,6 +84,8 @@ _hostc_flags = $(KBUILD_HOSTCFLAGS) $(HOST_EXTRACFLAGS) \ $(HOSTCFLAGS_$(target-stem).o) _hostcxx_flags = $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \ $(HOSTCXXFLAGS_$(target-stem).o) +_hostrust_flags = $(KBUILD_HOSTRUSTFLAGS) $(HOST_EXTRARUSTFLAGS) \ + $(HOSTRUSTFLAGS_$(target-stem)) # $(objtree)/$(obj) for including generated headers from checkin source files ifeq ($(KBUILD_EXTMOD),) @@ -82,6 +97,7 @@ endif hostc_flags = -Wp,-MMD,$(depfile) $(_hostc_flags) hostcxx_flags = -Wp,-MMD,$(depfile) $(_hostcxx_flags) +hostrust_flags = $(_hostrust_flags) ##### # Compile programs on the host @@ -128,5 +144,17 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@ $(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE $(call if_changed_dep,host-cxxobjs) +# Create executable from a single Rust crate (which may consist of +# one or more `.rs` files) +# host-rust -> Executable +quiet_cmd_host-rust = HOSTRUSTC $@ + cmd_host-rust = \ + $(HOSTRUSTC) $(hostrust_flags) --emit=dep-info,link \ + --out-dir=$(obj)/ $<; \ + mv $(obj)/$(target-stem).d $(depfile); \ + sed -i '/^\#/d' $(depfile) +$(host-rust): $(obj)/%: $(src)/%.rs FORCE + $(call if_changed_dep,host-rust) + targets += $(host-csingle) $(host-cmulti) $(host-cobjs) \ - $(host-cxxmulti) $(host-cxxobjs) + $(host-cxxmulti) $(host-cxxobjs) $(host-rust) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 3fb6a99e78c4..c88b98b5dc44 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -8,6 +8,7 @@ ldflags-y += $(EXTRA_LDFLAGS) # flags that take effect in current and sub directories KBUILD_AFLAGS += $(subdir-asflags-y) KBUILD_CFLAGS += $(subdir-ccflags-y) +KBUILD_RUSTFLAGS += $(subdir-rustflags-y) # Figure out what we need to build from the various variables # =========================================================================== @@ -128,6 +129,10 @@ _c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \ $(filter-out $(ccflags-remove-y), \ $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ccflags-y)) \ $(CFLAGS_$(target-stem).o)) +_rust_flags = $(filter-out $(RUSTFLAGS_REMOVE_$(target-stem).o), \ + $(filter-out $(rustflags-remove-y), \ + $(KBUILD_RUSTFLAGS) $(rustflags-y)) \ + $(RUSTFLAGS_$(target-stem).o)) _a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), \ $(filter-out $(asflags-remove-y), \ $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(asflags-y)) \ @@ -202,6 +207,11 @@ modkern_cflags = \ $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \ $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL) $(modfile_flags)) +modkern_rustflags = \ + $(if $(part-of-module), \ + $(KBUILD_RUSTFLAGS_MODULE) $(RUSTFLAGS_MODULE), \ + $(KBUILD_RUSTFLAGS_KERNEL) $(RUSTFLAGS_KERNEL)) + modkern_aflags = $(if $(part-of-module), \ $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \ $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)) @@ -211,6 +221,8 @@ c_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ $(_c_flags) $(modkern_cflags) \ $(basename_flags) $(modname_flags) +rust_flags = $(_rust_flags) $(modkern_rustflags) @$(objtree)/include/generated/rustc_cfg + a_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ $(_a_flags) $(modkern_aflags) diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 35100e981f4a..9a1fa6aa30fe 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -39,11 +39,13 @@ quiet_cmd_ld_ko_o = LD [M] $@ quiet_cmd_btf_ko = BTF [M] $@ cmd_btf_ko = \ - if [ -f vmlinux ]; then \ + if [ ! -f vmlinux ]; then \ + printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \ + elif [ -n "$(CONFIG_RUST)" ] && $(srctree)/scripts/is_rust_module.sh $@; then \ + printf "Skipping BTF generation for %s because it's a Rust module\n" $@ 1>&2; \ + else \ LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) --btf_base vmlinux $@; \ $(RESOLVE_BTFIDS) -b vmlinux $@; \ - else \ - printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \ fi; # Same as newer-prereqs, but allows to exclude specified extra dependencies diff --git a/scripts/cc-version.sh b/scripts/cc-version.sh index f1952c522466..2401c86fcf53 100755 --- a/scripts/cc-version.sh +++ b/scripts/cc-version.sh @@ -1,13 +1,13 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 # -# Print the compiler name and its version in a 5 or 6-digit form. +# Print the C compiler name and its version in a 5 or 6-digit form. # Also, perform the minimum version check. set -e -# Print the compiler name and some version components. -get_compiler_info() +# Print the C compiler name and some version components. +get_c_compiler_info() { cat <<- EOF | "$@" -E -P -x c - 2>/dev/null #if defined(__clang__) @@ -32,7 +32,7 @@ get_canonical_version() # $@ instead of $1 because multiple words might be given, e.g. CC="ccache gcc". orig_args="$@" -set -- $(get_compiler_info "$@") +set -- $(get_c_compiler_info "$@") name=$1 @@ -52,7 +52,7 @@ ICC) min_version=$($min_tool_version icc) ;; *) - echo "$orig_args: unknown compiler" >&2 + echo "$orig_args: unknown C compiler" >&2 exit 1 ;; esac @@ -62,7 +62,7 @@ min_cversion=$(get_canonical_version $min_version) if [ "$cversion" -lt "$min_cversion" ]; then echo >&2 "***" - echo >&2 "*** Compiler is too old." + echo >&2 "*** C compiler is too old." echo >&2 "*** Your $name version: $version" echo >&2 "*** Minimum $name version: $min_version" echo >&2 "***" diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index c4340c90e172..b7c9f1dd5e42 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -216,6 +216,13 @@ static const char *conf_get_autoheader_name(void) return name ? name : "include/generated/autoconf.h"; } +static const char *conf_get_rustccfg_name(void) +{ + char *name = getenv("KCONFIG_RUSTCCFG"); + + return name ? name : "include/generated/rustc_cfg"; +} + static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) { char *p2; @@ -605,6 +612,9 @@ static const struct comment_style comment_style_c = { static void conf_write_heading(FILE *fp, const struct comment_style *cs) { + if (!cs) + return; + fprintf(fp, "%s\n", cs->prefix); fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n", @@ -745,6 +755,65 @@ static void print_symbol_for_c(FILE *fp, struct symbol *sym) free(escaped); } +static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym) +{ + const char *val; + const char *val_prefix = ""; + char *val_prefixed = NULL; + size_t val_prefixed_len; + char *escaped = NULL; + + if (sym->type == S_UNKNOWN) + return; + + val = sym_get_string_value(sym); + + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + /* + * We do not care about disabled ones, i.e. no need for + * what otherwise are "comments" in other printers. + */ + if (*val == 'n') + return; + + /* + * To have similar functionality to the C macro `IS_ENABLED()` + * we provide an empty `--cfg CONFIG_X` here in both `y` + * and `m` cases. + * + * Then, the common `fprintf()` below will also give us + * a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can + * be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`. + */ + fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name); + break; + case S_HEX: + if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) + val_prefix = "0x"; + break; + default: + break; + } + + if (strlen(val_prefix) > 0) { + val_prefixed_len = strlen(val) + strlen(val_prefix) + 1; + val_prefixed = xmalloc(val_prefixed_len); + snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val); + val = val_prefixed; + } + + /* All values get escaped: the `--cfg` option only takes strings */ + escaped = escape_string_value(val); + val = escaped; + + fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val); + + free(escaped); + free(val_prefixed); +} + /* * Write out a minimal config. * All values that has default values are skipped as this is redundant. @@ -1132,6 +1201,12 @@ int conf_write_autoconf(int overwrite) if (ret) return ret; + ret = __conf_write_autoconf(conf_get_rustccfg_name(), + print_symbol_for_rustccfg, + NULL); + if (ret) + return ret; + /* * Create include/config/auto.conf. This must be the last step because * Kbuild has a dependency on auto.conf and this marks the successful -- cgit v1.2.3 From 094981352ce27bc36018c009d07ddf974c9725f5 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Thu, 4 Aug 2022 12:16:44 +0200 Subject: x86: enable initial Rust support Note that only x86_64 is covered and not all features nor mitigations are handled, but it is enough as a starting point and showcases the basics needed to add Rust support for a new architecture. Reviewed-by: Kees Cook Reviewed-by: Greg Kroah-Hartman Co-developed-by: Alex Gaynor Signed-off-by: Alex Gaynor Co-developed-by: Wedson Almeida Filho Signed-off-by: Wedson Almeida Filho Co-developed-by: David Gow Signed-off-by: David Gow Signed-off-by: Miguel Ojeda --- Documentation/rust/arch-support.rst | 1 + arch/x86/Kconfig | 1 + arch/x86/Makefile | 10 ++++++++++ scripts/generate_rust_target.rs | 15 +++++++++++++-- 4 files changed, 25 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst index 1152e0fbdad0..6982b63775da 100644 --- a/Documentation/rust/arch-support.rst +++ b/Documentation/rust/arch-support.rst @@ -15,4 +15,5 @@ support corresponds to ``S`` values in the ``MAINTAINERS`` file. ============ ================ ============================================== Architecture Level of support Constraints ============ ================ ============================================== +``x86`` Maintained ``x86_64`` only. ============ ================ ============================================== diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f9920f1341c8..3ca198742b10 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -257,6 +257,7 @@ config X86 select HAVE_STATIC_CALL_INLINE if HAVE_OBJTOOL select HAVE_PREEMPT_DYNAMIC_CALL select HAVE_RSEQ + select HAVE_RUST if X86_64 select HAVE_SYSCALL_TRACEPOINTS select HAVE_UACCESS_VALIDATION if HAVE_OBJTOOL select HAVE_UNSTABLE_SCHED_CLOCK diff --git a/arch/x86/Makefile b/arch/x86/Makefile index bafbd905e6e7..2d7e640674c6 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -68,6 +68,7 @@ export BITS # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53383 # KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx +KBUILD_RUSTFLAGS += -Ctarget-feature=-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2 ifeq ($(CONFIG_X86_KERNEL_IBT),y) # @@ -155,8 +156,17 @@ else cflags-$(CONFIG_GENERIC_CPU) += -mtune=generic KBUILD_CFLAGS += $(cflags-y) + rustflags-$(CONFIG_MK8) += -Ctarget-cpu=k8 + rustflags-$(CONFIG_MPSC) += -Ctarget-cpu=nocona + rustflags-$(CONFIG_MCORE2) += -Ctarget-cpu=core2 + rustflags-$(CONFIG_MATOM) += -Ctarget-cpu=atom + rustflags-$(CONFIG_GENERIC_CPU) += -Ztune-cpu=generic + KBUILD_RUSTFLAGS += $(rustflags-y) + KBUILD_CFLAGS += -mno-red-zone KBUILD_CFLAGS += -mcmodel=kernel + KBUILD_RUSTFLAGS += -Cno-redzone=y + KBUILD_RUSTFLAGS += -Ccode-model=kernel endif # diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs index 7256c9606cf0..3c6cbe2b278d 100644 --- a/scripts/generate_rust_target.rs +++ b/scripts/generate_rust_target.rs @@ -148,8 +148,19 @@ fn main() { let mut ts = TargetSpec::new(); // `llvm-target`s are taken from `scripts/Makefile.clang`. - if cfg.has("DUMMY_ARCH") { - ts.push("arch", "dummy_arch"); + if cfg.has("X86_64") { + ts.push("arch", "x86_64"); + ts.push( + "data-layout", + "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", + ); + let mut features = "-3dnow,-3dnowa,-mmx,+soft-float".to_string(); + if cfg.has("RETPOLINE") { + features += ",+retpoline-external-thunk"; + } + ts.push("features", features); + ts.push("llvm-target", "x86_64-linux-gnu"); + ts.push("target-pointer-width", "64"); } else { panic!("Unsupported architecture"); } -- cgit v1.2.3 From a7f3257da8a86b96fb9bf1bba40ae0bbd7f1885a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 7 Aug 2022 09:48:09 +0900 Subject: kbuild: remove the target in signal traps when interrupted When receiving some signal, GNU Make automatically deletes the target if it has already been changed by the interrupted recipe. If the target is possibly incomplete due to interruption, it must be deleted so that it will be remade from scratch on the next run of make. Otherwise, the target would remain corrupted permanently because its timestamp had already been updated. Thanks to this behavior of Make, you can stop the build any time by pressing Ctrl-C, and just run 'make' to resume it. Kbuild also relies on this feature, but it is equivalently important for any build systems that make decisions based on timestamps (if you want to support Ctrl-C reliably). However, this does not always work as claimed; Make immediately dies with Ctrl-C if its stderr goes into a pipe. [Test Makefile] foo: echo hello > $@ sleep 3 echo world >> $@ [Test Result] $ make # hit Ctrl-C echo hello > foo sleep 3 ^Cmake: *** Deleting file 'foo' make: *** [Makefile:3: foo] Interrupt $ make 2>&1 | cat # hit Ctrl-C echo hello > foo sleep 3 ^C$ # 'foo' is often left-over The reason is because SIGINT is sent to the entire process group. In this example, SIGINT kills 'cat', and 'make' writes the message to the closed pipe, then dies with SIGPIPE before cleaning the target. A typical bad scenario (as reported by [1], [2]) is to save build log by using the 'tee' command: $ make 2>&1 | tee log This can be problematic for any build systems based on Make, so I hope it will be fixed in GNU Make. The maintainer of GNU Make stated this is a long-standing issue and difficult to fix [3]. It has not been fixed yet as of writing. So, we cannot rely on Make cleaning the target. We can do it by ourselves, in signal traps. As far as I understand, Make takes care of SIGHUP, SIGINT, SIGQUIT, and SITERM for the target removal. I added the traps for them, and also for SIGPIPE just in case cmd_* rule prints something to stdout or stderr (but I did not observe an actual case where SIGPIPE was triggered). [Note 1] The trap handler might be worth explaining. rm -f $@; trap - $(sig); kill -s $(sig) $$ This lets the shell kill itself by the signal it caught, so the parent process can tell the child has exited on the signal. Generally, this is a proper manner for handling signals, in case the calling program (like Bash) may monitor WIFSIGNALED() and WTERMSIG() for WCE although this may not be a big deal here because GNU Make handles SIGHUP, SIGINT, SIGQUIT in WUE and SIGTERM in IUE. IUE - Immediate Unconditional Exit WUE - Wait and Unconditional Exit WCE - Wait and Cooperative Exit For details, see "Proper handling of SIGINT/SIGQUIT" [4]. [Note 2] Reverting 392885ee82d3 ("kbuild: let fixdep directly write to .*.cmd files") would directly address [1], but it only saves if_changed_dep. As reported in [2], all commands that use redirection can potentially leave an empty (i.e. broken) target. [Note 3] Another (even safer) approach might be to always write to a temporary file, and rename it to $@ at the end of the recipe. > $(tmp-target) mv $(tmp-target) $@ It would require a lot of Makefile changes, and result in ugly code, so I did not take it. [Note 4] A little more thoughts about a pattern rule with multiple targets (or a grouped target). %.x %.y: %.z When interrupted, GNU Make deletes both %.x and %.y, while this solution only deletes $@. Probably, this is not a big deal. The next run of make will execute the rule again to create $@ along with the other files. [1]: https://lore.kernel.org/all/YLeot94yAaM4xbMY@gmail.com/ [2]: https://lore.kernel.org/all/20220510221333.2770571-1-robh@kernel.org/ [3]: https://lists.gnu.org/archive/html/help-make/2021-06/msg00001.html [4]: https://www.cons.org/cracauer/sigint.html Fixes: 392885ee82d3 ("kbuild: let fixdep directly write to .*.cmd files") Reported-by: Ingo Molnar Reported-by: Rob Herring Signed-off-by: Masahiro Yamada Tested-by: Ingo Molnar Reviewed-by: Nicolas Schier --- scripts/Kbuild.include | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index ece44b735061..2bc08ace38a3 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -100,8 +100,29 @@ echo-cmd = $(if $($(quiet)cmd_$(1)),\ quiet_redirect := silent_redirect := exec >/dev/null; +# Delete the target on interruption +# +# GNU Make automatically deletes the target if it has already been changed by +# the interrupted recipe. So, you can safely stop the build by Ctrl-C (Make +# will delete incomplete targets), and resume it later. +# +# However, this does not work when the stderr is piped to another program, like +# $ make >&2 | tee log +# Make dies with SIGPIPE before cleaning the targets. +# +# To address it, we clean the target in signal traps. +# +# Make deletes the target when it catches SIGHUP, SIGINT, SIGQUIT, SIGTERM. +# So, we cover them, and also SIGPIPE just in case. +# +# Of course, this is unneeded for phony targets. +delete-on-interrupt = \ + $(if $(filter-out $(PHONY), $@), \ + $(foreach sig, HUP INT QUIT TERM PIPE, \ + trap 'rm -f $@; trap - $(sig); kill -s $(sig) $$$$' $(sig);)) + # printing commands -cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(cmd_$(1)) +cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(delete-on-interrupt) $(cmd_$(1)) ### # if_changed - execute command if any prerequisite is newer than -- cgit v1.2.3 From a3c4d4abaaf0b3fb3335a432fa9b75d414d1f987 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 25 Sep 2022 03:19:09 +0900 Subject: kbuild: hard-code KBUILD_ALLDIRS in scripts/Makefile.package My future plan is to list subdirectories in ./Kbuild. When it occurs, $(vmlinux-alldirs) will not contain all subdirectories. Let's hard-code the directory list until I get around to implementing a more sophisticated way for generating a source tarball. Signed-off-by: Masahiro Yamada Tested-by: Nick Desaulniers Reviewed-by: Nicolas Schier --- Makefile | 8 ++------ scripts/Makefile.package | 5 ++++- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index b87794a26d95..a42b121d1cd5 100644 --- a/Makefile +++ b/Makefile @@ -1109,13 +1109,11 @@ vmlinux-dirs := $(patsubst %/,%,$(filter %/, \ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ $(libs-y) $(libs-m))) -vmlinux-alldirs := $(sort $(vmlinux-dirs) Documentation \ +build-dirs := $(vmlinux-dirs) +clean-dirs := $(sort $(vmlinux-dirs) Documentation \ $(patsubst %/,%,$(filter %/, $(core-) \ $(drivers-) $(libs-)))) -build-dirs := $(vmlinux-dirs) -clean-dirs := $(vmlinux-alldirs) - subdir-modorder := $(addsuffix /modules.order, $(build-dirs)) # Externally visible symbols (used by link-vmlinux.sh) @@ -1131,8 +1129,6 @@ KBUILD_VMLINUX_OBJS += $(patsubst %/,%/built-in.a, $(drivers-y)) export KBUILD_VMLINUX_OBJS KBUILD_VMLINUX_LIBS export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds -# used by scripts/Makefile.package -export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) LICENSES arch include scripts tools) vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) diff --git a/scripts/Makefile.package b/scripts/Makefile.package index 5017f6b2da80..8bbcced67c22 100644 --- a/scripts/Makefile.package +++ b/scripts/Makefile.package @@ -29,7 +29,10 @@ KDEB_SOURCENAME ?= linux-upstream KBUILD_PKG_ROOTCMD ?="fakeroot -u" export KDEB_SOURCENAME # Include only those top-level files that are needed by make, plus the GPL copy -TAR_CONTENT := $(KBUILD_ALLDIRS) .config .scmversion Makefile \ +TAR_CONTENT := Documentation LICENSES arch block certs crypto drivers fs \ + include init io_uring ipc kernel lib mm net samples scripts \ + security sound tools usr virt \ + .config .scmversion Makefile \ Kbuild Kconfig COPYING $(wildcard localversion*) MKSPEC := $(srctree)/scripts/package/mkspec -- cgit v1.2.3 From b10fdeea8cf42c0d97b337e9e501c92da4389a03 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 20 Aug 2022 18:15:29 +0900 Subject: kbuild: check sha1sum just once for each atomic header It is unneeded to check the sha1sum every time. Create the timestamp files to manage it. Add '.' to clean-dirs because 'make clean' must visit ./Kbuild to clean up the timestamp files. Signed-off-by: Masahiro Yamada --- Kbuild | 33 ++++++++++++++++++++++++--------- Makefile | 2 +- scripts/atomic/check-atomics.sh | 33 --------------------------------- 3 files changed, 25 insertions(+), 43 deletions(-) delete mode 100755 scripts/atomic/check-atomics.sh (limited to 'scripts') diff --git a/Kbuild b/Kbuild index e122d93cee32..0b9e8a16a621 100644 --- a/Kbuild +++ b/Kbuild @@ -43,17 +43,32 @@ PHONY += missing-syscalls missing-syscalls: scripts/checksyscalls.sh $(offsets-file) $(call cmd,syscalls) -# Check atomic headers are up-to-date - -quiet_cmd_atomics = CALL $< - cmd_atomics = $(CONFIG_SHELL) $< - -PHONY += old-atomics -old-atomics: scripts/atomic/check-atomics.sh - $(call cmd,atomics) +# Check the manual modification of atomic headers + +quiet_cmd_check_sha1 = CHKSHA1 $< + cmd_check_sha1 = \ + if ! command -v sha1sum >/dev/null; then \ + echo "warning: cannot check the header due to sha1sum missing"; \ + exit 0; \ + fi; \ + if [ "$$(sed -n '$$s:// ::p' $<)" != \ + "$$(sed '$$d' $< | sha1sum | sed 's/ .*//')" ]; then \ + echo "error: $< has been modified." >&2; \ + exit 1; \ + fi; \ + touch $@ + +atomic-checks += $(addprefix $(obj)/.checked-, \ + atomic-arch-fallback.h \ + atomic-instrumented.h \ + atomic-long.h) + +targets += $(atomic-checks) +$(atomic-checks): $(obj)/.checked-%: include/linux/atomic/% FORCE + $(call if_changed,check_sha1) # A phony target that depends on all the preparation targets PHONY += prepare -prepare: $(offsets-file) missing-syscalls old-atomics +prepare: $(offsets-file) missing-syscalls $(atomic-checks) @: diff --git a/Makefile b/Makefile index a42b121d1cd5..22a4afd51285 100644 --- a/Makefile +++ b/Makefile @@ -1110,7 +1110,7 @@ vmlinux-dirs := $(patsubst %/,%,$(filter %/, \ $(libs-y) $(libs-m))) build-dirs := $(vmlinux-dirs) -clean-dirs := $(sort $(vmlinux-dirs) Documentation \ +clean-dirs := $(sort $(vmlinux-dirs) Documentation . \ $(patsubst %/,%,$(filter %/, $(core-) \ $(drivers-) $(libs-)))) diff --git a/scripts/atomic/check-atomics.sh b/scripts/atomic/check-atomics.sh deleted file mode 100755 index 0e7bab3eb0d1..000000000000 --- a/scripts/atomic/check-atomics.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 -# -# Check if atomic headers are up-to-date - -ATOMICDIR=$(dirname $0) -ATOMICTBL=${ATOMICDIR}/atomics.tbl -LINUXDIR=${ATOMICDIR}/../.. - -echo '' | sha1sum - > /dev/null 2>&1 -if [ $? -ne 0 ]; then - printf "sha1sum not available, skipping atomic header checks.\n" - exit 0 -fi - -cat < Date: Sat, 20 Aug 2022 18:15:30 +0900 Subject: kbuild: do not deduplicate modules.order The AWK code was added to deduplicate modules.order in case $(obj-m) contains the same module multiple times, but it is actually unneeded since commit b2c885549122 ("kbuild: update modules.order only when contained modules are updated"). The list is already deduplicated before being processed by AWK because $^ is the deduplicated list of prerequisites. (Please note the real-prereqs macro uses $^) Yet, modules.order will contain duplication if two different Makefiles build the same module: foo/Makefile: obj-m += bar/baz.o foo/bar/Makefile: obj-m += baz.o However, the parallel builds cannot properly handle this case in the first place. So, it is better to let it fail (as already done by scripts/modules-check.sh). Signed-off-by: Masahiro Yamada --- Makefile | 5 +---- scripts/Makefile.build | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 22a4afd51285..498095b3825e 100644 --- a/Makefile +++ b/Makefile @@ -1430,14 +1430,11 @@ endif # Build modules # -# A module can be listed more than once in obj-m resulting in -# duplicate lines in modules.order files. Those are removed -# using awk while concatenating to the final file. PHONY += modules modules: $(if $(KBUILD_BUILTIN),vmlinux) modules_check modules_prepare -cmd_modules_order = $(AWK) '!x[$$0]++' $(real-prereqs) > $@ +cmd_modules_order = cat $(real-prereqs) > $@ modules.order: $(subdir-modorder) FORCE $(call if_changed,modules_order) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 784f46d41959..0df488d0bbb0 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -374,7 +374,7 @@ $(obj)/built-in.a: $(real-obj-y) FORCE cmd_modules_order = { $(foreach m, $(real-prereqs), \ $(if $(filter %/modules.order, $m), cat $m, echo $(patsubst %.o,%.ko,$m));) :; } \ - | $(AWK) '!x[$$0]++' - > $@ + > $@ $(obj)/modules.order: $(obj-m) FORCE $(call if_changed,modules_order) -- cgit v1.2.3 From 2df8220cc511326508ec4da2f43ef69311bdd7b9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 28 Aug 2022 11:39:53 +0900 Subject: kbuild: build init/built-in.a just once Kbuild builds init/built-in.a twice; first during the ordinary directory descending, second from scripts/link-vmlinux.sh. We do this because UTS_VERSION contains the build version and the timestamp. We cannot update it during the normal directory traversal since we do not yet know if we need to update vmlinux. UTS_VERSION is temporarily calculated, but omitted from the update check. Otherwise, vmlinux would be rebuilt every time. When Kbuild results in running link-vmlinux.sh, it increments the version number in the .version file and takes the timestamp at that time to really fix UTS_VERSION. However, updating the same file twice is a footgun. To avoid nasty timestamp issues, all build artifacts that depend on init/built-in.a are atomically generated in link-vmlinux.sh, where some of them do not need rebuilding. To fix this issue, this commit changes as follows: [1] Split UTS_VERSION out to include/generated/utsversion.h from include/generated/compile.h include/generated/utsversion.h is generated just before the vmlinux link. It is generated under include/generated/ because some decompressors (s390, x86) use UTS_VERSION. [2] Split init_uts_ns and linux_banner out to init/version-timestamp.c from init/version.c init_uts_ns and linux_banner contain UTS_VERSION. During the ordinary directory descending, they are compiled with __weak and used to determine if vmlinux needs relinking. Just before the vmlinux link, they are compiled without __weak to embed the real version and timestamp. Signed-off-by: Masahiro Yamada --- arch/powerpc/boot/wrapper | 2 +- arch/s390/boot/version.c | 1 + arch/x86/boot/compressed/kaslr.c | 1 + arch/x86/boot/version.c | 1 + init/.gitignore | 2 + init/Makefile | 55 +++++++++++++++++++------ init/build-version | 10 +++++ init/version-timestamp.c | 31 ++++++++++++++ init/version.c | 36 ++++++---------- kernel/gen_kheaders.sh | 6 +-- scripts/link-vmlinux.sh | 17 ++------ scripts/mkcompile_h | 89 +++++----------------------------------- 12 files changed, 120 insertions(+), 131 deletions(-) create mode 100644 init/.gitignore create mode 100755 init/build-version create mode 100644 init/version-timestamp.c (limited to 'scripts') diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index 55978f32fa77..5bdd4dd20bbb 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -433,7 +433,7 @@ fi # Extract kernel version information, some platforms want to include # it in the image header version=`${CROSS}strings "$kernel" | grep '^Linux version [-0-9.]' | \ - cut -d' ' -f3` + head -n1 | cut -d' ' -f3` if [ -n "$version" ]; then uboot_version="-n Linux-$version" fi diff --git a/arch/s390/boot/version.c b/arch/s390/boot/version.c index d32e58bdda6a..fd32f038777f 100644 --- a/arch/s390/boot/version.c +++ b/arch/s390/boot/version.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include #include #include "boot.h" diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c index 4a3f223973f4..e476bcbd9b42 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #define _SETUP diff --git a/arch/x86/boot/version.c b/arch/x86/boot/version.c index a1aaaf6c06a6..945383f0f606 100644 --- a/arch/x86/boot/version.c +++ b/arch/x86/boot/version.c @@ -11,6 +11,7 @@ */ #include "boot.h" +#include #include #include diff --git a/init/.gitignore b/init/.gitignore new file mode 100644 index 000000000000..cbbe270cec00 --- /dev/null +++ b/init/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +/utsversion-tmp.h diff --git a/init/Makefile b/init/Makefile index d82623d7fc8e..ba90eb817185 100644 --- a/init/Makefile +++ b/init/Makefile @@ -19,20 +19,49 @@ mounts-y := do_mounts.o mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o -# dependencies on generated files need to be listed explicitly -$(obj)/version.o: include/generated/compile.h +# +# UTS_VERSION +# + +smp-flag-$(CONFIG_SMP) := SMP +preempt-flag-$(CONFIG_PREEMPT_BUILD) := PREEMPT +preempt-flag-$(CONFIG_PREEMPT_DYNAMIC) := PREEMPT_DYNAMIC +preempt-flag-$(CONFIG_PREEMPT_RT) := PREEMPT_RT + +build-version = $(or $(KBUILD_BUILD_VERSION), $(build-version-auto)) +build-timestamp = $(or $(KBUILD_BUILD_TIMESTAMP), $(build-timestamp-auto)) + +# Maximum length of UTS_VERSION is 64 chars +filechk_uts_version = \ + utsver=$$(echo '$(pound)'"$(build-version)" $(smp-flag-y) $(preempt-flag-y) "$(build-timestamp)" | cut -b -64); \ + echo '$(pound)'define UTS_VERSION \""$${utsver}"\" + +# +# Build version.c with temporary UTS_VERSION +# -# compile.h changes depending on hostname, generation number, etc, -# so we regenerate it always. -# mkcompile_h will make sure to only update the -# actual file if its content has changed. +$(obj)/utsversion-tmp.h: FORCE + $(call filechk,uts_version) -quiet_cmd_compile.h = CHK $@ - cmd_compile.h = \ - $(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \ - "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT_BUILD)" \ - "$(CONFIG_PREEMPT_DYNAMIC)" "$(CONFIG_PREEMPT_RT)" \ - "$(CONFIG_CC_VERSION_TEXT)" "$(LD)" +clean-files += utsversion-tmp.h + +$(obj)/version.o: include/generated/compile.h $(obj)/utsversion-tmp.h +CFLAGS_version.o := -include $(obj)/utsversion-tmp.h + +filechk_compile.h = $(srctree)/scripts/mkcompile_h \ + "$(UTS_MACHINE)" "$(CONFIG_CC_VERSION_TEXT)" "$(LD)" include/generated/compile.h: FORCE - $(call cmd,compile.h) + $(call filechk,compile.h) + +# +# Build version-timestamp.c with final UTS_VERSION +# + +include/generated/utsversion.h: build-version-auto = $(shell $(srctree)/$(src)/build-version) +include/generated/utsversion.h: build-timestamp-auto = $(shell LC_ALL=C date) +include/generated/utsversion.h: FORCE + $(call filechk,uts_version) + +$(obj)/version-timestamp.o: include/generated/utsversion.h +CFLAGS_version-timestamp.o := -include include/generated/utsversion.h diff --git a/init/build-version b/init/build-version new file mode 100755 index 000000000000..537d45815083 --- /dev/null +++ b/init/build-version @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only + +prev_ver=$(cat .version 2>/dev/null) && +ver=$(expr ${prev_ver} + 1 2>/dev/null) || +ver=1 + +echo ${ver} > .version + +echo ${ver} diff --git a/init/version-timestamp.c b/init/version-timestamp.c new file mode 100644 index 000000000000..179e93bae539 --- /dev/null +++ b/init/version-timestamp.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include + +struct uts_namespace init_uts_ns = { + .ns.count = REFCOUNT_INIT(2), + .name = { + .sysname = UTS_SYSNAME, + .nodename = UTS_NODENAME, + .release = UTS_RELEASE, + .version = UTS_VERSION, + .machine = UTS_MACHINE, + .domainname = UTS_DOMAINNAME, + }, + .user_ns = &init_user_ns, + .ns.inum = PROC_UTS_INIT_INO, +#ifdef CONFIG_UTS_NS + .ns.ops = &utsns_operations, +#endif +}; + +/* FIXED STRINGS! Don't touch! */ +const char linux_banner[] = + "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@" + LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n"; diff --git a/init/version.c b/init/version.c index 3391c4051bf3..01d4ab05f0ba 100644 --- a/init/version.c +++ b/init/version.c @@ -18,24 +18,6 @@ #include #include -struct uts_namespace init_uts_ns = { - .ns.count = REFCOUNT_INIT(2), - .name = { - .sysname = UTS_SYSNAME, - .nodename = UTS_NODENAME, - .release = UTS_RELEASE, - .version = UTS_VERSION, - .machine = UTS_MACHINE, - .domainname = UTS_DOMAINNAME, - }, - .user_ns = &init_user_ns, - .ns.inum = PROC_UTS_INIT_INO, -#ifdef CONFIG_UTS_NS - .ns.ops = &utsns_operations, -#endif -}; -EXPORT_SYMBOL_GPL(init_uts_ns); - static int __init early_hostname(char *arg) { size_t bufsize = sizeof(init_uts_ns.name.nodename); @@ -51,11 +33,6 @@ static int __init early_hostname(char *arg) } early_param("hostname", early_hostname); -/* FIXED STRINGS! Don't touch! */ -const char linux_banner[] = - "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@" - LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n"; - const char linux_proc_banner[] = "%s version %s" " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ")" @@ -63,3 +40,16 @@ const char linux_proc_banner[] = BUILD_SALT; BUILD_LTO_INFO; + +/* + * init_uts_ns and linux_banner contain the build version and timestamp, + * which are really fixed at the very last step of build process. + * They are compiled with __weak first, and without __weak later. + */ + +struct uts_namespace init_uts_ns __weak; +const char linux_banner[] __weak; + +#include "version-timestamp.c" + +EXPORT_SYMBOL_GPL(init_uts_ns); diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh index 0c78e64f747d..473036b43c83 100755 --- a/kernel/gen_kheaders.sh +++ b/kernel/gen_kheaders.sh @@ -31,8 +31,8 @@ if [ "$building_out_of_srctree" ]; then fi all_dirs="$all_dirs $dir_list" -# include/generated/compile.h is ignored because it is touched even when none -# of the source files changed. +# include/generated/utsversion.h is ignored because it is generated after this +# script is executed. (utsversion.h is unneeded for kheaders) # # When Kconfig regenerates include/generated/autoconf.h, its timestamp is # updated, but the contents might be still the same. When any CONFIG option is @@ -42,7 +42,7 @@ all_dirs="$all_dirs $dir_list" # # Ignore them for md5 calculation to avoid pointless regeneration. headers_md5="$(find $all_dirs -name "*.h" | - grep -v "include/generated/compile.h" | + grep -v "include/generated/utsversion.h" | grep -v "include/generated/autoconf.h" | xargs ls -l | md5sum | cut -d ' ' -f1)" diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index eecc1863e556..8d982574145a 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -75,6 +75,8 @@ vmlinux_link() objs="${objs} .vmlinux.export.o" fi + objs="${objs} init/version-timestamp.o" + if [ "${SRCARCH}" = "um" ]; then wl=-Wl, ld="${CC}" @@ -213,19 +215,6 @@ if [ "$1" = "clean" ]; then exit 0 fi -# Update version -info GEN .version -if [ -r .version ]; then - VERSION=$(expr 0$(cat .version) + 1) - echo $VERSION > .version -else - rm -f .version - echo 1 > .version -fi; - -# final build of init/ -${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1 - #link vmlinux.o ${MAKE} -f "${srctree}/scripts/Makefile.vmlinux_o" @@ -260,6 +249,8 @@ if is_enabled CONFIG_MODULES; then ${MAKE} -f "${srctree}/scripts/Makefile.vmlinux" .vmlinux.export.o fi +${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init init/version-timestamp.o + btf_vmlinux_bin_o="" if is_enabled CONFIG_DEBUG_INFO_BTF; then btf_vmlinux_bin_o=.btf.vmlinux.bin.o diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index ca40a5258c87..f1a820d49e53 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -1,14 +1,9 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 -TARGET=$1 -ARCH=$2 -SMP=$3 -PREEMPT=$4 -PREEMPT_DYNAMIC=$5 -PREEMPT_RT=$6 -CC_VERSION="$7" -LD=$8 +UTS_MACHINE=$1 +CC_VERSION="$2" +LD=$3 # Do not expand names set -f @@ -17,17 +12,6 @@ set -f LC_ALL=C export LC_ALL -if [ -z "$KBUILD_BUILD_VERSION" ]; then - VERSION=$(cat .version 2>/dev/null || echo 1) -else - VERSION=$KBUILD_BUILD_VERSION -fi - -if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then - TIMESTAMP=`date` -else - TIMESTAMP=$KBUILD_BUILD_TIMESTAMP -fi if test -z "$KBUILD_BUILD_USER"; then LINUX_COMPILE_BY=$(whoami | sed 's/\\/\\\\/') else @@ -39,63 +23,12 @@ else LINUX_COMPILE_HOST=$KBUILD_BUILD_HOST fi -UTS_VERSION="#$VERSION" -CONFIG_FLAGS="" -if [ -n "$SMP" ] ; then CONFIG_FLAGS="SMP"; fi - -if [ -n "$PREEMPT_RT" ] ; then - CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT_RT" -elif [ -n "$PREEMPT_DYNAMIC" ] ; then - CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT_DYNAMIC" -elif [ -n "$PREEMPT" ] ; then - CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT" -fi - -# Truncate to maximum length -UTS_LEN=64 -UTS_VERSION="$(echo $UTS_VERSION $CONFIG_FLAGS $TIMESTAMP | cut -b -$UTS_LEN)" - -# Generate a temporary compile.h - -{ echo /\* This file is auto generated, version $VERSION \*/ - if [ -n "$CONFIG_FLAGS" ] ; then echo "/* $CONFIG_FLAGS */"; fi +LD_VERSION=$($LD -v | head -n1 | sed 's/(compatible with [^)]*)//' \ + | sed 's/[[:space:]]*$//') - echo \#define UTS_MACHINE \"$ARCH\" - - echo \#define UTS_VERSION \"$UTS_VERSION\" - - printf '#define LINUX_COMPILE_BY "%s"\n' "$LINUX_COMPILE_BY" - echo \#define LINUX_COMPILE_HOST \"$LINUX_COMPILE_HOST\" - - LD_VERSION=$($LD -v | head -n1 | sed 's/(compatible with [^)]*)//' \ - | sed 's/[[:space:]]*$//') - printf '#define LINUX_COMPILER "%s"\n' "$CC_VERSION, $LD_VERSION" -} > .tmpcompile - -# Only replace the real compile.h if the new one is different, -# in order to preserve the timestamp and avoid unnecessary -# recompilations. -# We don't consider the file changed if only the date/time changed, -# unless KBUILD_BUILD_TIMESTAMP was explicitly set (e.g. for -# reproducible builds with that value referring to a commit timestamp). -# A kernel config change will increase the generation number, thus -# causing compile.h to be updated (including date/time) due to the -# changed comment in the -# first line. - -if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then - IGNORE_PATTERN="UTS_VERSION" -else - IGNORE_PATTERN="NOT_A_PATTERN_TO_BE_MATCHED" -fi - -if [ -r $TARGET ] && \ - grep -v $IGNORE_PATTERN $TARGET > .tmpver.1 && \ - grep -v $IGNORE_PATTERN .tmpcompile > .tmpver.2 && \ - cmp -s .tmpver.1 .tmpver.2; then - rm -f .tmpcompile -else - echo " UPD $TARGET" - mv -f .tmpcompile $TARGET -fi -rm -f .tmpver.1 .tmpver.2 +cat < Date: Sun, 28 Aug 2022 11:39:55 +0900 Subject: scripts/mkcompile_h: move LC_ALL=C to '$LD -v' Minimize the scope of LC_ALL=C like before commit 87c94bfb8ad3 ("kbuild: override build timestamp & version"). Give LC_ALL=C to '$LD -v' to get the consistent version output, as commit bcbcf50f5218 ("kbuild: fix ld-version.sh to not be affected by locale") mentioned the LD version is affected by locale. While I was here, I merged two sed invocations. Signed-off-by: Masahiro Yamada --- scripts/mkcompile_h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index f1a820d49e53..b76ccbbc094b 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -8,10 +8,6 @@ LD=$3 # Do not expand names set -f -# Fix the language to get consistent output -LC_ALL=C -export LC_ALL - if test -z "$KBUILD_BUILD_USER"; then LINUX_COMPILE_BY=$(whoami | sed 's/\\/\\\\/') else @@ -23,8 +19,8 @@ else LINUX_COMPILE_HOST=$KBUILD_BUILD_HOST fi -LD_VERSION=$($LD -v | head -n1 | sed 's/(compatible with [^)]*)//' \ - | sed 's/[[:space:]]*$//') +LD_VERSION=$(LC_ALL=C $LD -v | head -n1 | + sed -e 's/(compatible with [^)]*)//' -e 's/[[:space:]]*$//') cat < Date: Sun, 28 Aug 2022 11:39:56 +0900 Subject: Revert "kbuild: Make scripts/compile.h when sh != bash" This reverts commit [1] in the pre-git era. I do not know what problem happened in the script when sh != bash because there is no commit message. Now that this script is much simpler than it used to be, let's revert it, and let' see. (If this turns out to be problematic, fix the code with proper commit description.) [1]: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=11acbbbb8a50f4de7dbe4bc1b5acc440dfe81810 Signed-off-by: Masahiro Yamada --- scripts/mkcompile_h | 3 --- 1 file changed, 3 deletions(-) (limited to 'scripts') diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index b76ccbbc094b..2596f78e52ef 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -5,9 +5,6 @@ UTS_MACHINE=$1 CC_VERSION="$2" LD=$3 -# Do not expand names -set -f - if test -z "$KBUILD_BUILD_USER"; then LINUX_COMPILE_BY=$(whoami | sed 's/\\/\\\\/') else -- cgit v1.2.3 From 033a52d033607dab1c9b93962921dc6a9a9146b3 Mon Sep 17 00:00:00 2001 From: Owen Rafferty Date: Wed, 31 Aug 2022 15:57:08 -0500 Subject: kbuild: rewrite check-local-export in sh/awk Remove the bash build dependency for those who otherwise do not have it installed. This also provides a significant speedup: $ make defconfig $ make yes2modconfig ... $ find . -name "*.o" | grep -v vmlinux | wc 3169 3169 89615 $ export NM=nm $ time sh -c 'find . -name "*.o" | grep -v vmlinux | xargs -n1 ./scripts/check-local-export' Without patch: 0m15.90s real 0m12.17s user 0m05.28s system With patch: dash + nawk 0m02.16s real 0m02.92s user 0m00.34s system dash + busybox awk 0m02.36s real 0m03.36s user 0m00.34s system dash + gawk 0m02.07s real 0m03.26s user 0m00.32s system bash + gawk 0m03.55s real 0m05.00s user 0m00.54s system Signed-off-by: Owen Rafferty Signed-off-by: Masahiro Yamada --- scripts/check-local-export | 97 +++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 49 deletions(-) (limited to 'scripts') diff --git a/scripts/check-local-export b/scripts/check-local-export index 6ccc2f467416..f90b5a9c67b3 100755 --- a/scripts/check-local-export +++ b/scripts/check-local-export @@ -1,25 +1,14 @@ -#!/usr/bin/env bash +#!/bin/sh # SPDX-License-Identifier: GPL-2.0-only # # Copyright (C) 2022 Masahiro Yamada +# Copyright (C) 2022 Owen Rafferty # # Exit with error if a local exported symbol is found. # EXPORT_SYMBOL should be used for global symbols. set -e - -# catch errors from ${NM} -set -o pipefail - -# Run the last element of a pipeline in the current shell. -# Without this, the while-loop would be executed in a subshell, and -# the changes made to 'symbol_types' and 'export_symbols' would be lost. -shopt -s lastpipe - -declare -A symbol_types -declare -a export_symbols - -exit_code=0 +pid=$$ # If there is no symbol in the object, ${NM} (both GNU nm and llvm-nm) shows # 'no symbols' diagnostic (but exits with 0). It is harmless and hidden by @@ -29,43 +18,53 @@ exit_code=0 # TODO: # Use --quiet instead of 2>/dev/null when we upgrade the minimum version of # binutils to 2.37, llvm to 13.0.0. -# Then, the following line will be really simple: -# ${NM} --quiet ${1} | +# Then, the following line will be simpler: +# { ${NM} --quiet ${1} || kill 0; } | + +{ ${NM} ${1} 2>/dev/null || { echo "${0}: ${NM} failed" >&2; kill $pid; } } | +${AWK} -v "file=${1}" ' +BEGIN { + i = 0 +} + +# Skip the line if the number of fields is less than 3. +# +# case 1) +# For undefined symbols, the first field (value) is empty. +# The outout looks like this: +# " U _printk" +# It is unneeded to record undefined symbols. +# +# case 2) +# For Clang LTO, llvm-nm outputs a line with type t but empty name: +# "---------------- t" +!length($3) { + next +} -{ ${NM} ${1} 2>/dev/null || { echo "${0}: ${NM} failed" >&2; false; } } | -while read value type name -do - # Skip the line if the number of fields is less than 3. - # - # case 1) - # For undefined symbols, the first field (value) is empty. - # The outout looks like this: - # " U _printk" - # It is unneeded to record undefined symbols. - # - # case 2) - # For Clang LTO, llvm-nm outputs a line with type 't' but empty name: - # "---------------- t" - if [[ -z ${name} ]]; then - continue - fi +# save (name, type) in the associative array +{ symbol_types[$3]=$2 } - # save (name, type) in the associative array - symbol_types[${name}]=${type} +# append the exported symbol to the array +($3 ~ /^__ksymtab_/) { + export_symbols[i] = $3 + sub(/^__ksymtab_/, "", export_symbols[i]) + i++ +} - # append the exported symbol to the array - if [[ ${name} == __ksymtab_* ]]; then - export_symbols+=(${name#__ksymtab_}) - fi -done +END { + exit_code = 0 + for (j = 0; j < i; ++j) { + name = export_symbols[j] + # nm(3) says "If lowercase, the symbol is usually local" + if (symbol_types[name] ~ /[a-z]/) { + printf "%s: error: local symbol %s was exported\n", + file, name | "cat 1>&2" + exit_code = 1 + } + } -for name in "${export_symbols[@]}" -do - # nm(3) says "If lowercase, the symbol is usually local" - if [[ ${symbol_types[$name]} =~ [a-z] ]]; then - echo "$@: error: local symbol '${name}' was exported" >&2 - exit_code=1 - fi -done + exit exit_code +}' -exit ${exit_code} +exit $? -- cgit v1.2.3 From cc306abd19e8acdd85072b162d09e80408389cd8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 6 Sep 2022 15:13:06 +0900 Subject: kbuild: fix and refactor single target build The single target build has a subtle bug for the combination for an individual file and a subdirectory. [1] 'make kernel/fork.i' builds only kernel/fork.i $ make kernel/fork.i CALL scripts/checksyscalls.sh DESCEND objtool CPP kernel/fork.i [2] 'make kernel/' builds only under the kernel/ directory. $ make kernel/ CALL scripts/checksyscalls.sh DESCEND objtool CC kernel/fork.o CC kernel/exec_domain.o [snip] CC kernel/rseq.o AR kernel/built-in.a But, if you try to do [1] and [2] in a single command, you will get only [1] with a weird log: $ make kernel/fork.i kernel/ CALL scripts/checksyscalls.sh DESCEND objtool CPP kernel/fork.i make[2]: Nothing to be done for 'kernel/'. With 'make kernel/fork.i kernel/', you should get both [1] and [2]. Rewrite the single target build. Signed-off-by: Masahiro Yamada --- Makefile | 9 ++++----- scripts/Makefile.build | 54 +++++++++++++++----------------------------------- 2 files changed, 20 insertions(+), 43 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index f9756ff7c750..b0a3cba5af94 100644 --- a/Makefile +++ b/Makefile @@ -1819,11 +1819,11 @@ single_modpost: $(single-no-ko) modules_prepare $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $(Q)rm -f $(MODORDER) -export KBUILD_SINGLE_TARGETS := $(addprefix $(extmod_prefix), $(single-no-ko)) +single-goals := $(addprefix $(extmod_prefix), $(single-no-ko)) # trim unrelated directories build-dirs := $(foreach d, $(build-dirs), \ - $(if $(filter $(d)/%, $(KBUILD_SINGLE_TARGETS)), $(d))) + $(if $(filter $d/%, $(single-goals)), $d)) endif @@ -1835,9 +1835,8 @@ endif PHONY += descend $(build-dirs) descend: $(build-dirs) $(build-dirs): prepare - $(Q)$(MAKE) $(build)=$@ \ - single-build=$(if $(filter-out $@/, $(filter $@/%, $(KBUILD_SINGLE_TARGETS))),1) \ - need-builtin=1 need-modorder=1 + $(Q)$(MAKE) $(build)=$@ need-builtin=1 need-modorder=1 \ + $(filter $@/%, $(single-goals)) clean-dirs := $(addprefix _clean_, $(clean-dirs)) PHONY += $(clean-dirs) clean diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 0df488d0bbb0..91d2e5461a3e 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -5,8 +5,8 @@ src := $(obj) -PHONY := __build -__build: +PHONY := $(obj)/ +$(obj)/: # Init all relevant variables used in kbuild files so # 1) they have correct type @@ -323,7 +323,7 @@ $(obj)/%.o: $(src)/%.S FORCE targets += $(filter-out $(subdir-builtin), $(real-obj-y)) targets += $(filter-out $(subdir-modorder), $(real-obj-m)) -targets += $(real-dtb-y) $(lib-y) $(always-y) $(MAKECMDGOALS) +targets += $(real-dtb-y) $(lib-y) $(always-y) # Linker scripts preprocessor (.lds.S -> .lds) # --------------------------------------------------------------------------- @@ -400,8 +400,6 @@ $(multi-obj-m): %.o: %.mod FORCE $(call if_changed_rule,ld_multi_m) $(call multi_depend, $(multi-obj-m), .o, -objs -y -m) -targets := $(filter-out $(PHONY), $(targets)) - # Add intermediate targets: # When building objects with specific suffix patterns, add intermediate # targets that the final targets are derived from. @@ -420,52 +418,29 @@ targets += $(call intermediate_targets, .asn1.o, .asn1.c .asn1.h) \ # Build # --------------------------------------------------------------------------- -ifdef single-build - -KBUILD_SINGLE_TARGETS := $(filter $(obj)/%, $(KBUILD_SINGLE_TARGETS)) - -curdir-single := $(sort $(foreach x, $(KBUILD_SINGLE_TARGETS), \ - $(if $(filter $(x) $(basename $(x)).o, $(targets)), $(x)))) - -# Handle single targets without any rule: show "Nothing to be done for ..." or -# "No rule to make target ..." depending on whether the target exists. -unknown-single := $(filter-out $(addsuffix /%, $(subdir-ym)), \ - $(filter-out $(curdir-single), $(KBUILD_SINGLE_TARGETS))) - -single-subdirs := $(foreach d, $(subdir-ym), \ - $(if $(filter $(d)/%, $(KBUILD_SINGLE_TARGETS)), $(d))) - -__build: $(curdir-single) $(single-subdirs) -ifneq ($(unknown-single),) - $(Q)$(MAKE) -f /dev/null $(unknown-single) -endif +$(obj)/: $(if $(KBUILD_BUILTIN), $(targets-for-builtin)) \ + $(if $(KBUILD_MODULES), $(targets-for-modules)) \ + $(subdir-ym) $(always-y) @: -ifeq ($(curdir-single),) -# Nothing to do in this directory. Do not include any .*.cmd file for speed-up -targets := -else -targets += $(curdir-single) -endif +# Single targets +# --------------------------------------------------------------------------- -else +single-subdirs := $(foreach d, $(subdir-ym), $(if $(filter $d/%, $(MAKECMDGOALS)), $d)) +single-subdir-goals := $(filter $(addsuffix /%, $(single-subdirs)), $(MAKECMDGOALS)) -__build: $(if $(KBUILD_BUILTIN), $(targets-for-builtin)) \ - $(if $(KBUILD_MODULES), $(targets-for-modules)) \ - $(subdir-ym) $(always-y) +$(single-subdir-goals): $(single-subdirs) @: -endif - # Descending # --------------------------------------------------------------------------- PHONY += $(subdir-ym) $(subdir-ym): $(Q)$(MAKE) $(build)=$@ \ - $(if $(filter $@/, $(KBUILD_SINGLE_TARGETS)),single-build=) \ need-builtin=$(if $(filter $@/built-in.a, $(subdir-builtin)),1) \ - need-modorder=$(if $(filter $@/modules.order, $(subdir-modorder)),1) + need-modorder=$(if $(filter $@/modules.order, $(subdir-modorder)),1) \ + $(filter $@/%, $(single-subdir-goals)) # Add FORCE to the prequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- @@ -474,6 +449,9 @@ PHONY += FORCE FORCE: +targets += $(filter-out $(single-subdir-goals), $(MAKECMDGOALS)) +targets := $(filter-out $(PHONY), $(targets)) + # Read all saved command lines and dependencies for the $(targets) we # may be building above, using $(if_changed{,_dep}). As an # optimization, we don't need to read them if the target does not -- cgit v1.2.3 From 9ec6ab6ee5ca72afdf8f60c330ad997825c0819b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 7 Sep 2022 03:49:35 +0900 Subject: kbuild: use objtool-args-y to clean up objtool arguments Based on Linus' patch. Refactor scripts/Makefile.vmlinux_o as well. Link: https://lore.kernel.org/lkml/CAHk-=wgjTMQgiKzBZTmb=uWGDEQxDdyF1+qxBkODYciuNsmwnw@mail.gmail.com/ Suggested-by: Linus Torvalds Signed-off-by: Masahiro Yamada Acked-by: Peter Zijlstra Reviewed-by: Nick Desaulniers --- scripts/Makefile.lib | 31 ++++++++++++++++--------------- scripts/Makefile.vmlinux_o | 15 ++++----------- 2 files changed, 20 insertions(+), 26 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 3fb6a99e78c4..52811b2783de 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -229,25 +229,26 @@ ifdef CONFIG_OBJTOOL objtool := $(objtree)/tools/objtool/objtool -objtool_args = \ - $(if $(CONFIG_HAVE_JUMP_LABEL_HACK), --hacks=jump_label) \ - $(if $(CONFIG_HAVE_NOINSTR_HACK), --hacks=noinstr) \ - $(if $(CONFIG_X86_KERNEL_IBT), --ibt) \ - $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \ - $(if $(CONFIG_UNWINDER_ORC), --orc) \ - $(if $(CONFIG_RETPOLINE), --retpoline) \ - $(if $(CONFIG_RETHUNK), --rethunk) \ - $(if $(CONFIG_SLS), --sls) \ - $(if $(CONFIG_STACK_VALIDATION), --stackval) \ - $(if $(CONFIG_HAVE_STATIC_CALL_INLINE), --static-call) \ - $(if $(CONFIG_HAVE_UACCESS_VALIDATION), --uaccess) \ +objtool-args-$(CONFIG_HAVE_JUMP_LABEL_HACK) += --hacks=jump_label +objtool-args-$(CONFIG_HAVE_NOINSTR_HACK) += --hacks=noinstr +objtool-args-$(CONFIG_X86_KERNEL_IBT) += --ibt +objtool-args-$(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL) += --mcount +objtool-args-$(CONFIG_UNWINDER_ORC) += --orc +objtool-args-$(CONFIG_RETPOLINE) += --retpoline +objtool-args-$(CONFIG_RETHUNK) += --rethunk +objtool-args-$(CONFIG_SLS) += --sls +objtool-args-$(CONFIG_STACK_VALIDATION) += --stackval +objtool-args-$(CONFIG_HAVE_STATIC_CALL_INLINE) += --static-call +objtool-args-$(CONFIG_HAVE_UACCESS_VALIDATION) += --uaccess +objtool-args-$(CONFIG_GCOV_KERNEL) += --no-unreachable + +objtool-args = $(objtool-args-y) \ $(if $(delay-objtool), --link) \ - $(if $(part-of-module), --module) \ - $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) + $(if $(part-of-module), --module) delay-objtool := $(or $(CONFIG_LTO_CLANG),$(CONFIG_X86_KERNEL_IBT)) -cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@) +cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool-args) $@) cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd) endif # CONFIG_OBJTOOL diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o index 84019814f33f..7d531b825712 100644 --- a/scripts/Makefile.vmlinux_o +++ b/scripts/Makefile.vmlinux_o @@ -35,18 +35,11 @@ endif objtool-enabled := $(or $(delay-objtool),$(CONFIG_NOINSTR_VALIDATION)) -# Reuse objtool_args defined in scripts/Makefile.lib if LTO or IBT is enabled. -# -# Add some more flags as needed. -# --no-unreachable and --link might be added twice, but it is fine. -# -# Expand objtool_args to a simple variable to avoid circular reference. +vmlinux-objtool-args-$(delay-objtool) += $(objtool-args-y) +vmlinux-objtool-args-$(CONFIG_GCOV_KERNEL) += --no-unreachable +vmlinux-objtool-args-$(CONFIG_NOINSTR_VALIDATION) += --noinstr $(if $(CONFIG_CPU_UNRET_ENTRY), --unret) -objtool_args := \ - $(if $(delay-objtool),$(objtool_args)) \ - $(if $(CONFIG_NOINSTR_VALIDATION), --noinstr $(if $(CONFIG_CPU_UNRET_ENTRY), --unret)) \ - $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) \ - --link +objtool-args = $(vmlinux-objtool-args-y) --link # Link of vmlinux.o used for section mismatch analysis # --------------------------------------------------------------------------- -- cgit v1.2.3 From efc8338e3a72baf95294634b48c5f2d80dce1c5c Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Wed, 14 Sep 2022 09:59:06 +0800 Subject: Kconfig: remove sym_set_choice_value sym_set_choice_value could be removed and directly call sym_set_tristate_value instead. Signed-off-by: Zeng Heng Suggested-by: Masahiro Yamada Signed-off-by: Masahiro Yamada --- scripts/kconfig/conf.c | 2 +- scripts/kconfig/lkc.h | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 4178065ca27f..33d19e419908 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -551,7 +551,7 @@ static int conf_choice(struct menu *menu) print_help(child); continue; } - sym_set_choice_value(sym, child->sym); + sym_set_tristate_value(child->sym, yes); for (child = child->list; child; child = child->next) { indent += 2; conf(child); diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index c396aa104090..6ac2eabe109d 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -123,11 +123,6 @@ static inline struct symbol *sym_get_choice_value(struct symbol *sym) return (struct symbol *)sym->curr.val; } -static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval) -{ - return sym_set_tristate_value(chval, yes); -} - static inline bool sym_is_choice(struct symbol *sym) { return sym->flags & SYMBOL_CHOICE ? true : false; -- cgit v1.2.3 From a8d5692659358eba46d3b2f7d96da7c390f41f71 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Wed, 14 Sep 2022 20:09:21 +0800 Subject: scripts: remove unused argument 'type' Remove unused function argument, and there is no logic changes. Signed-off-by: Zeng Heng Signed-off-by: Masahiro Yamada --- scripts/asn1_compiler.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/asn1_compiler.c b/scripts/asn1_compiler.c index adabd4145264..71d4a7c87900 100644 --- a/scripts/asn1_compiler.c +++ b/scripts/asn1_compiler.c @@ -832,7 +832,7 @@ static void parse(void) static struct element *element_list; -static struct element *alloc_elem(struct token *type) +static struct element *alloc_elem(void) { struct element *e = calloc(1, sizeof(*e)); if (!e) { @@ -860,7 +860,7 @@ static struct element *parse_type(struct token **_cursor, struct token *end, char *p; int labelled = 0, implicit = 0; - top = element = alloc_elem(cursor); + top = element = alloc_elem(); element->class = ASN1_UNIV; element->method = ASN1_PRIM; element->tag = token_to_tag[cursor->token_type]; @@ -939,7 +939,7 @@ static struct element *parse_type(struct token **_cursor, struct token *end, if (!implicit) element->method |= ASN1_CONS; element->compound = implicit ? TAG_OVERRIDE : SEQUENCE; - element->children = alloc_elem(cursor); + element->children = alloc_elem(); element = element->children; element->class = ASN1_UNIV; element->method = ASN1_PRIM; -- cgit v1.2.3 From 2e07005f4813a9ff6e895787e0c2d1fea859b033 Mon Sep 17 00:00:00 2001 From: Janis Schoetterl-Glausch Date: Fri, 16 Sep 2022 14:41:12 +0200 Subject: kbuild: rpm-pkg: fix breakage when V=1 is used Doing make V=1 binrpm-pkg results in: Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.EgV6qJ + umask 022 + cd . + /bin/rm -rf /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x + /bin/mkdir -p /home/scgl/rpmbuild/BUILDROOT + /bin/mkdir /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x + mkdir -p /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x/boot + make -f ./Makefile image_name + cp test -e include/generated/autoconf.h -a -e include/config/auto.conf || ( \ echo >&2; \ echo >&2 " ERROR: Kernel configuration is invalid."; \ echo >&2 " include/generated/autoconf.h or include/config/auto.conf are missing.";\ echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \ echo >&2 ; \ /bin/false) arch/s390/boot/bzImage /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x/boot/vmlinuz-6.0.0-rc5+ cp: invalid option -- 'e' Try 'cp --help' for more information. error: Bad exit status from /var/tmp/rpm-tmp.EgV6qJ (%install) Because the make call to get the image name is verbose and prints additional information. Fixes: 993bdde94547 ("kbuild: add image_name to no-sync-config-targets") Signed-off-by: Janis Schoetterl-Glausch Signed-off-by: Masahiro Yamada --- scripts/package/mkspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/package/mkspec b/scripts/package/mkspec index 8fa7c5b8a1a1..c920c1b18e7a 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -88,10 +88,10 @@ $S mkdir -p %{buildroot}/boot %ifarch ia64 mkdir -p %{buildroot}/boot/efi - cp \$($MAKE image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE + cp \$($MAKE -s image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE ln -s efi/vmlinuz-$KERNELRELEASE %{buildroot}/boot/ %else - cp \$($MAKE image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE + cp \$($MAKE -s image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE %endif $M $MAKE %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} modules_install $MAKE %{?_smp_mflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install -- cgit v1.2.3 From 88b61e3bff93f99712718db785b4aa0c1165f35c Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Mon, 19 Sep 2022 10:08:28 -0700 Subject: Makefile.compiler: replace cc-ifversion with compiler-specific macros cc-ifversion is GCC specific. Replace it with compiler specific variants. Update the users of cc-ifversion to use these new macros. Link: https://github.com/ClangBuiltLinux/linux/issues/350 Link: https://lore.kernel.org/llvm/CAGG=3QWSAUakO42kubrCap8fp-gm1ERJJAYXTnP1iHk_wrH=BQ@mail.gmail.com/ Suggested-by: Bill Wendling Reviewed-by: Nathan Chancellor Signed-off-by: Nick Desaulniers Signed-off-by: Masahiro Yamada --- Documentation/kbuild/makefiles.rst | 29 +++++++++++++++++------------ Makefile | 6 ++---- drivers/gpu/drm/amd/display/dc/dml/Makefile | 2 +- scripts/Makefile.compiler | 10 +++++++--- scripts/Makefile.extrawarn | 4 ++-- 5 files changed, 29 insertions(+), 22 deletions(-) (limited to 'scripts') diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index 11a296e52d68..ee7e3ea1fbe1 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -682,22 +682,27 @@ more details, with real examples. In the above example, -Wno-unused-but-set-variable will be added to KBUILD_CFLAGS only if gcc really accepts it. - cc-ifversion - cc-ifversion tests the version of $(CC) and equals the fourth parameter - if version expression is true, or the fifth (if given) if the version - expression is false. + gcc-min-version + gcc-min-version tests if the value of $(CONFIG_GCC_VERSION) is greater than + or equal to the provided value and evaluates to y if so. Example:: - #fs/reiserfs/Makefile - ccflags-y := $(call cc-ifversion, -lt, 0402, -O1) + cflags-$(call gcc-min-version, 70100) := -foo - In this example, ccflags-y will be assigned the value -O1 if the - $(CC) version is less than 4.2. - cc-ifversion takes all the shell operators: - -eq, -ne, -lt, -le, -gt, and -ge - The third parameter may be a text as in this example, but it may also - be an expanded variable or a macro. + In this example, cflags-y will be assigned the value -foo if $(CC) is gcc and + $(CONFIG_GCC_VERSION) is >= 7.1. + + clang-min-version + clang-min-version tests if the value of $(CONFIG_CLANG_VERSION) is greater + than or equal to the provided value and evaluates to y if so. + + Example:: + + cflags-$(call clang-min-version, 110000) := -foo + + In this example, cflags-y will be assigned the value -foo if $(CC) is clang + and $(CONFIG_CLANG_VERSION) is >= 11.0.0. cc-cross-prefix cc-cross-prefix is used to check if there exists a $(CC) in path with diff --git a/Makefile b/Makefile index b0a3cba5af94..09c9d9a005bd 100644 --- a/Makefile +++ b/Makefile @@ -790,7 +790,6 @@ KBUILD_CFLAGS += $(stackp-flags-y) KBUILD_CFLAGS-$(CONFIG_WERROR) += -Werror KBUILD_CFLAGS-$(CONFIG_CC_NO_ARRAY_BOUNDS) += -Wno-array-bounds -KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH) ifdef CONFIG_CC_IS_CLANG KBUILD_CPPFLAGS += -Qunused-arguments @@ -972,7 +971,6 @@ ifdef CONFIG_CC_IS_GCC KBUILD_CFLAGS += -Wno-maybe-uninitialized endif -ifdef CONFIG_CC_IS_GCC # The allocators already balk at large sizes, so silence the compiler # warnings for bounds checks involving those possible values. While # -Wno-alloc-size-larger-than would normally be used here, earlier versions @@ -984,8 +982,8 @@ ifdef CONFIG_CC_IS_GCC # ignored, continuing to default to PTRDIFF_MAX. So, left with no other # choice, we must perform a versioned check to disable this warning. # https://lore.kernel.org/lkml/20210824115859.187f272f@canb.auug.org.au -KBUILD_CFLAGS += $(call cc-ifversion, -ge, 0901, -Wno-alloc-size-larger-than) -endif +KBUILD_CFLAGS-$(call gcc-min-version, 90100) += -Wno-alloc-size-larger-than +KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH) # disable invalid "can't wrap" optimizations for signed / pointers KBUILD_CFLAGS += -fno-strict-overflow diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile index cb81ed2fbd53..d70838edba80 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile @@ -34,7 +34,7 @@ dml_ccflags := -mhard-float -maltivec endif ifdef CONFIG_CC_IS_GCC -ifeq ($(call cc-ifversion, -lt, 0701, y), y) +ifneq ($(call gcc-min-version, 70100),y) IS_OLD_GCC = 1 endif endif diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler index 94d0d40cddb3..20d353dcabfb 100644 --- a/scripts/Makefile.compiler +++ b/scripts/Makefile.compiler @@ -61,9 +61,13 @@ cc-option-yn = $(call try-run,\ cc-disable-warning = $(call try-run,\ $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) -# cc-ifversion -# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) -cc-ifversion = $(shell [ $(CONFIG_GCC_VERSION)0 $(1) $(2)000 ] && echo $(3) || echo $(4)) +# gcc-min-version +# Usage: cflags-$(call gcc-min-version, 70100) += -foo +gcc-min-version = $(shell [ $(CONFIG_GCC_VERSION)0 -ge $(1)0 ] && echo y) + +# clang-min-version +# Usage: cflags-$(call clang-min-version, 110000) += -foo +clang-min-version = $(shell [ $(CONFIG_CLANG_VERSION)0 -ge $(1)0 ] && echo y) # ld-option # Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y) diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 6ae482158bc4..5769c1939d40 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -48,7 +48,7 @@ else ifdef CONFIG_CC_IS_CLANG KBUILD_CFLAGS += -Wno-initializer-overrides # Clang before clang-16 would warn on default argument promotions. -ifeq ($(shell [ $(CONFIG_CLANG_VERSION) -lt 160000 ] && echo y),y) +ifneq ($(call clang-min-version, 160000),y) # Disable -Wformat KBUILD_CFLAGS += -Wno-format # Then re-enable flags that were part of the -Wformat group that aren't @@ -56,7 +56,7 @@ KBUILD_CFLAGS += -Wno-format KBUILD_CFLAGS += -Wformat-extra-args -Wformat-invalid-specifier KBUILD_CFLAGS += -Wformat-zero-length -Wnonnull # Requires clang-12+. -ifeq ($(shell [ $(CONFIG_CLANG_VERSION) -ge 120000 ] && echo y),y) +ifeq ($(call clang-min-version, 120000),y) KBUILD_CFLAGS += -Wformat-insufficient-args endif endif -- cgit v1.2.3 From 5750121ae7382ebac8d47ce6d68012d6cd1d7926 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 25 Sep 2022 03:19:10 +0900 Subject: kbuild: list sub-directories in ./Kbuild Use the ordinary obj-y syntax to list subdirectories. Note1: Previously, the link order of lib-y depended on CONFIG_MODULES; lib-y was linked before drivers-y when CONFIG_MODULES=y, otherwise after drivers-y. This was a bug of commit 7273ad2b08f8 ("kbuild: link lib-y objects to vmlinux forcibly when CONFIG_MODULES=y"), but it was not a big deal after all. Now, all objects listed in lib-y are linked last, irrespective of CONFIG_MODULES. Note2: Finally, the single target build in arch/*/lib/ works correctly. There was a bug report about this. [1] $ make ARCH=arm arch/arm/lib/findbit.o CALL scripts/checksyscalls.sh AS arch/arm/lib/findbit.o [1]: https://lore.kernel.org/linux-kbuild/YvUQOwL6lD4%2F5%2FU6@shell.armlinux.org.uk/ Signed-off-by: Masahiro Yamada Tested-by: Nick Desaulniers Reviewed-by: Nicolas Schier --- Kbuild | 24 ++++++++++++++++++++ Makefile | 63 +++++++++++++++++----------------------------------- scripts/Makefile.lib | 2 ++ 3 files changed, 46 insertions(+), 43 deletions(-) (limited to 'scripts') diff --git a/Kbuild b/Kbuild index 0b9e8a16a621..8a37584d1fd6 100644 --- a/Kbuild +++ b/Kbuild @@ -72,3 +72,27 @@ $(atomic-checks): $(obj)/.checked-%: include/linux/atomic/% FORCE PHONY += prepare prepare: $(offsets-file) missing-syscalls $(atomic-checks) @: + +# Ordinary directory descending +# --------------------------------------------------------------------------- + +obj-y += init/ +obj-y += usr/ +obj-y += arch/$(SRCARCH)/ +obj-y += $(ARCH_CORE) +obj-y += kernel/ +obj-y += certs/ +obj-y += mm/ +obj-y += fs/ +obj-y += ipc/ +obj-y += security/ +obj-y += crypto/ +obj-$(CONFIG_BLOCK) += block/ +obj-$(CONFIG_IO_URING) += io_uring/ +obj-y += $(ARCH_LIB) +obj-y += drivers/ +obj-y += sound/ +obj-$(CONFIG_SAMPLES) += samples/ +obj-$(CONFIG_NET) += net/ +obj-y += virt/ +obj-y += $(ARCH_DRIVERS) diff --git a/Makefile b/Makefile index 09c9d9a005bd..317e9f09440c 100644 --- a/Makefile +++ b/Makefile @@ -676,11 +676,8 @@ endif ifeq ($(KBUILD_EXTMOD),) # Objects we will link into vmlinux / subdirs we need to visit -core-y := init/ usr/ arch/$(SRCARCH)/ -drivers-y := drivers/ sound/ -drivers-$(CONFIG_SAMPLES) += samples/ -drivers-$(CONFIG_NET) += net/ -drivers-y += virt/ +core-y := +drivers-y := libs-y := lib/ endif # KBUILD_EXTMOD @@ -1099,31 +1096,24 @@ export MODORDER := $(extmod_prefix)modules.order export MODULES_NSDEPS := $(extmod_prefix)modules.nsdeps ifeq ($(KBUILD_EXTMOD),) -core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ -core-$(CONFIG_BLOCK) += block/ -core-$(CONFIG_IO_URING) += io_uring/ -vmlinux-dirs := $(patsubst %/,%,$(filter %/, \ - $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ - $(libs-y) $(libs-m))) - -build-dirs := $(vmlinux-dirs) -clean-dirs := $(sort $(vmlinux-dirs) Documentation . \ +build-dir := . +clean-dirs := $(sort . Documentation \ $(patsubst %/,%,$(filter %/, $(core-) \ $(drivers-) $(libs-)))) -subdir-modorder := $(addsuffix /modules.order, $(build-dirs)) - +export ARCH_CORE := $(core-y) +export ARCH_LIB := $(filter %/, $(libs-y)) +export ARCH_DRIVERS := $(drivers-y) $(drivers-m) # Externally visible symbols (used by link-vmlinux.sh) -KBUILD_VMLINUX_OBJS := $(head-y) $(patsubst %/,%/built-in.a, $(core-y)) -KBUILD_VMLINUX_OBJS += $(addsuffix built-in.a, $(filter %/, $(libs-y))) + +KBUILD_VMLINUX_OBJS := $(head-y) ./built-in.a ifdef CONFIG_MODULES KBUILD_VMLINUX_OBJS += $(patsubst %/, %/lib.a, $(filter %/, $(libs-y))) KBUILD_VMLINUX_LIBS := $(filter-out %/, $(libs-y)) else KBUILD_VMLINUX_LIBS := $(patsubst %/,%/lib.a, $(libs-y)) endif -KBUILD_VMLINUX_OBJS += $(patsubst %/,%/built-in.a, $(drivers-y)) export KBUILD_VMLINUX_OBJS KBUILD_VMLINUX_LIBS export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds @@ -1138,7 +1128,7 @@ ifdef CONFIG_TRIM_UNUSED_KSYMS # (this can be evaluated only once include/config/auto.conf has been included) KBUILD_MODULES := 1 -autoksyms_recursive: descend modules.order +autoksyms_recursive: $(build-dir) modules.order $(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh \ "$(MAKE) -f $(srctree)/Makefile autoksyms_recursive" endif @@ -1166,7 +1156,7 @@ targets := vmlinux # The actual objects are generated when descending, # make sure no implicit rule kicks in -$(sort $(vmlinux-deps) $(subdir-modorder)): descend ; +$(sort $(vmlinux-deps)): . ; filechk_kernel.release = \ echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" @@ -1437,13 +1427,6 @@ endif modules: $(if $(KBUILD_BUILTIN),vmlinux) modules_prepare -cmd_modules_order = cat $(real-prereqs) > $@ - -modules.order: $(subdir-modorder) FORCE - $(call if_changed,modules_order) - -targets += modules.order - # Target to prepare building external modules modules_prepare: prepare $(Q)$(MAKE) $(build)=scripts scripts/module.lds @@ -1714,9 +1697,7 @@ else # KBUILD_EXTMOD KBUILD_BUILTIN := KBUILD_MODULES := 1 -build-dirs := $(KBUILD_EXTMOD) -$(MODORDER): descend - @: +build-dir := $(KBUILD_EXTMOD) compile_commands.json: $(extmod_prefix)compile_commands.json PHONY += compile_commands.json @@ -1754,6 +1735,9 @@ PHONY += modules modules_install modules_prepare ifdef CONFIG_MODULES +$(MODORDER): $(build-dir) + @: + modules: modules_check $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost @@ -1807,7 +1791,7 @@ single-no-ko := $(filter-out $(single-ko), $(MAKECMDGOALS)) \ $(single-ko): single_modpost @: -$(single-no-ko): descend +$(single-no-ko): $(build-dir) @: # Remove MODORDER when done because it is not the real one. @@ -1817,24 +1801,17 @@ single_modpost: $(single-no-ko) modules_prepare $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $(Q)rm -f $(MODORDER) -single-goals := $(addprefix $(extmod_prefix), $(single-no-ko)) - -# trim unrelated directories -build-dirs := $(foreach d, $(build-dirs), \ - $(if $(filter $d/%, $(single-goals)), $d)) +single-goals := $(addprefix $(build-dir)/, $(single-no-ko)) endif -# Handle descending into subdirectories listed in $(build-dirs) # Preset locale variables to speed up the build process. Limit locale # tweaks to this spot to avoid wrong language settings when running # make menuconfig etc. # Error messages still appears in the original language -PHONY += descend $(build-dirs) -descend: $(build-dirs) -$(build-dirs): prepare - $(Q)$(MAKE) $(build)=$@ need-builtin=1 need-modorder=1 \ - $(filter $@/%, $(single-goals)) +PHONY += $(build-dir) +$(build-dir): prepare + $(Q)$(MAKE) $(build)=$@ need-builtin=1 need-modorder=1 $(single-goals) clean-dirs := $(addprefix _clean_, $(clean-dirs)) PHONY += $(clean-dirs) clean diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 52811b2783de..b7e650bc70f2 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -89,6 +89,7 @@ always-y += $(dtb-y) # Add subdir path +ifneq ($(obj),.) extra-y := $(addprefix $(obj)/,$(extra-y)) always-y := $(addprefix $(obj)/,$(always-y)) targets := $(addprefix $(obj)/,$(targets)) @@ -100,6 +101,7 @@ multi-obj-m := $(addprefix $(obj)/, $(multi-obj-m)) multi-dtb-y := $(addprefix $(obj)/, $(multi-dtb-y)) real-dtb-y := $(addprefix $(obj)/, $(real-dtb-y)) subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) +endif # Finds the multi-part object the current object will be linked into. # If the object belongs to two or more multi-part objects, list them all. -- cgit v1.2.3 From 26ef40de5cbb24728a34a319e8d42cdec99f186c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 25 Sep 2022 03:19:11 +0900 Subject: kbuild: move .vmlinux.objs rule to Makefile.modpost .vmlinux.objs is used by modpost, so scripts/Makefile.modpost is a better place to generate it. It is used only when CONFIG_MODVERSIONS=y. It should be guarded by "ifdef CONFIG_MODVERSIONS". Signed-off-by: Masahiro Yamada Tested-by: Nick Desaulniers Reviewed-by: Nicolas Schier --- Makefile | 2 +- scripts/Makefile.modpost | 30 ++++++++++++++++++++++++++++-- scripts/link-vmlinux.sh | 18 ------------------ 3 files changed, 29 insertions(+), 21 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 317e9f09440c..dac4ca2b900c 100644 --- a/Makefile +++ b/Makefile @@ -1477,7 +1477,7 @@ endif # CONFIG_MODULES # Directories & files removed with 'make clean' CLEAN_FILES += include/ksym vmlinux.symvers modules-only.symvers \ modules.builtin modules.builtin.modinfo modules.nsdeps \ - compile_commands.json .thinlto-cache + compile_commands.json .thinlto-cache .vmlinux.objs # Directories & files removed with 'make mrproper' MRPROPER_FILES += include/config include/generated \ diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 911606496341..04ad00917b2f 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -57,6 +57,32 @@ vmlinux.symvers: vmlinux.o __modpost: vmlinux.symvers +# Generate the list of in-tree objects in vmlinux +# --------------------------------------------------------------------------- + +# This is used to retrieve symbol versions generated by genksyms. +ifdef CONFIG_MODVERSIONS +vmlinux.symvers: .vmlinux.objs +endif + +# Ignore libgcc.a +# Some architectures do '$(CC) --print-libgcc-file-name' to borrow libgcc.a +# from the toolchain, but there is no EXPORT_SYMBOL in it. + +quiet_cmd_vmlinux_objs = GEN $@ + cmd_vmlinux_objs = \ + for f in $(real-prereqs); do \ + case $${f} in \ + *libgcc.a) ;; \ + *.a) $(AR) t $${f} ;; \ + *) echo $${f} ;; \ + esac \ + done > $@ + +targets += .vmlinux.objs +.vmlinux.objs: $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) FORCE + $(call if_changed,vmlinux_objs) + else ifeq ($(KBUILD_EXTMOD),) @@ -134,6 +160,8 @@ ifneq ($(KBUILD_MODPOST_NOFINAL),1) $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal endif +endif + PHONY += FORCE FORCE: @@ -141,6 +169,4 @@ existing-targets := $(wildcard $(sort $(targets))) -include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) -endif - .PHONY: $(PHONY) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 8d982574145a..161bca64e8aa 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -199,7 +199,6 @@ cleanup() rm -f System.map rm -f vmlinux rm -f vmlinux.map - rm -f .vmlinux.objs rm -f .vmlinux.export.c } @@ -218,23 +217,6 @@ fi #link vmlinux.o ${MAKE} -f "${srctree}/scripts/Makefile.vmlinux_o" -# Generate the list of in-tree objects in vmlinux -# -# This is used to retrieve symbol versions generated by genksyms. -for f in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do - case ${f} in - *libgcc.a) - # Some architectures do '$(CC) --print-libgcc-file-name' to - # borrow libgcc.a from the toolchain. - # There is no EXPORT_SYMBOL in external objects. Ignore this. - ;; - *.a) - ${AR} t ${f} ;; - *) - echo ${f} ;; - esac -done > .vmlinux.objs - # modpost vmlinux.o to check for section mismatches ${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1 -- cgit v1.2.3 From 9c5a0ac3c36917c4258f734bda98be02ca36b992 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 25 Sep 2022 03:19:12 +0900 Subject: kbuild: move vmlinux.o rule to the top Makefile Move the build rules of vmlinux.o out of scripts/link-vmlinux.sh to clearly separate 1) pre-modpost, 2) modpost, 3) post-modpost stages. This will make further refactoring possible. Signed-off-by: Masahiro Yamada Tested-by: Nick Desaulniers Reviewed-by: Nicolas Schier --- Makefile | 9 +++++---- scripts/link-vmlinux.sh | 3 --- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index dac4ca2b900c..21c41a03d98d 100644 --- a/Makefile +++ b/Makefile @@ -1118,8 +1118,6 @@ endif export KBUILD_VMLINUX_OBJS KBUILD_VMLINUX_LIBS export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds -vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) - # Recurse until adjust_autoksyms.sh is satisfied PHONY += autoksyms_recursive ifdef CONFIG_TRIM_UNUSED_KSYMS @@ -1142,6 +1140,9 @@ quiet_cmd_autoksyms_h = GEN $@ $(autoksyms_h): $(call cmd,autoksyms_h) +vmlinux.o: autoksyms_recursive $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) FORCE + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.vmlinux_o + ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) # Final link of vmlinux with optional arch pass after final link @@ -1149,14 +1150,14 @@ cmd_link-vmlinux = \ $(CONFIG_SHELL) $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)"; \ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) -vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE +vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE +$(call if_changed_dep,link-vmlinux) targets := vmlinux # The actual objects are generated when descending, # make sure no implicit rule kicks in -$(sort $(vmlinux-deps)): . ; +$(sort $(KBUILD_LDS) $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS)): . ; filechk_kernel.release = \ echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 161bca64e8aa..07486f90d5e2 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -214,9 +214,6 @@ if [ "$1" = "clean" ]; then exit 0 fi -#link vmlinux.o -${MAKE} -f "${srctree}/scripts/Makefile.vmlinux_o" - # modpost vmlinux.o to check for section mismatches ${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1 -- cgit v1.2.3 From f73edc8951b2de515b5ecc8a357ccd47dd41077e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 25 Sep 2022 03:19:13 +0900 Subject: kbuild: unify two modpost invocations Currently, modpost is executed twice; first for vmlinux, second for modules. This commit merges them. Current build flow ================== 1) build obj-y and obj-m objects 2) link vmlinux.o 3) modpost for vmlinux 4) link vmlinux 5) modpost for modules 6) link modules (*.ko) The build steps 1) through 6) are serialized, that is, modules are built after vmlinux. You do not get benefits of parallel builds when scripts/link-vmlinux.sh is being run. New build flow ============== 1) build obj-y and obj-m objects 2) link vmlinux.o 3) modpost for vmlinux and modules 4a) link vmlinux 4b) link modules (*.ko) In the new build flow, modpost is invoked just once. vmlinux and modules are built in parallel. One exception is CONFIG_DEBUG_INFO_BTF_MODULES=y, where modules depend on vmlinux. Signed-off-by: Masahiro Yamada Tested-by: Nick Desaulniers Reviewed-by: Nicolas Schier --- Makefile | 32 ++++++++++++---- scripts/Makefile.modfinal | 2 +- scripts/Makefile.modpost | 93 ++++++++++++++--------------------------------- scripts/link-vmlinux.sh | 3 -- 4 files changed, 54 insertions(+), 76 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 21c41a03d98d..41ab27601bb4 100644 --- a/Makefile +++ b/Makefile @@ -1150,7 +1150,7 @@ cmd_link-vmlinux = \ $(CONFIG_SHELL) $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)"; \ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) -vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE +vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) modpost FORCE +$(call if_changed_dep,link-vmlinux) targets := vmlinux @@ -1426,7 +1426,13 @@ endif # Build modules # -modules: $(if $(KBUILD_BUILTIN),vmlinux) modules_prepare +# *.ko are usually independent of vmlinux, but CONFIG_DEBUG_INFOBTF_MODULES +# is an exception. +ifdef CONFIG_DEBUG_INFO_BTF_MODULES +modules: vmlinux +endif + +modules: modules_prepare # Target to prepare building external modules modules_prepare: prepare @@ -1739,8 +1745,12 @@ ifdef CONFIG_MODULES $(MODORDER): $(build-dir) @: -modules: modules_check - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost +# KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. +# This is solely useful to speed up test compiles. +modules: modpost +ifneq ($(KBUILD_MODPOST_NOFINAL),1) + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal +endif PHONY += modules_check modules_check: $(MODORDER) @@ -1771,6 +1781,11 @@ KBUILD_MODULES := endif # CONFIG_MODULES +PHONY += modpost +modpost: $(if $(single-build),, $(if $(KBUILD_BUILTIN), vmlinux.o)) \ + $(if $(KBUILD_MODULES), modules_check) + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost + # Single targets # --------------------------------------------------------------------------- # To build individual files in subdirectories, you can do like this: @@ -1790,16 +1805,19 @@ single-ko := $(sort $(filter %.ko, $(MAKECMDGOALS))) single-no-ko := $(filter-out $(single-ko), $(MAKECMDGOALS)) \ $(foreach x, o mod, $(patsubst %.ko, %.$x, $(single-ko))) -$(single-ko): single_modpost +$(single-ko): single_modules @: $(single-no-ko): $(build-dir) @: # Remove MODORDER when done because it is not the real one. -PHONY += single_modpost -single_modpost: $(single-no-ko) modules_prepare +PHONY += single_modules +single_modules: $(single-no-ko) modules_prepare $(Q){ $(foreach m, $(single-ko), echo $(extmod_prefix)$m;) } > $(MODORDER) $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost +ifneq ($(KBUILD_MODPOST_NOFINAL),1) + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal +endif $(Q)rm -f $(MODORDER) single-goals := $(addprefix $(build-dir)/, $(single-no-ko)) diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 35100e981f4a..a3cf9e3647c9 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -55,7 +55,7 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:) # Re-generate module BTFs if either module's .ko or vmlinux changed -$(modules): %.ko: %.o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE +$(modules): %.ko: %.o %.mod.o scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE +$(call if_changed_except,ld_ko_o,vmlinux) ifdef CONFIG_DEBUG_INFO_BTF_MODULES +$(if $(newer-prereqs),$(call cmd,btf_ko)) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 04ad00917b2f..2daf760eeb25 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -32,9 +32,6 @@ # Step 4 is solely used to allow module versioning in external modules, # where the CRC of each module is retrieved from the Module.symvers file. -# KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. -# This is solely useful to speed up test compiles - PHONY := __modpost __modpost: @@ -45,24 +42,23 @@ MODPOST = scripts/mod/modpost \ $(if $(CONFIG_MODVERSIONS),-m) \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \ $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ + $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \ + $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) \ -o $@ -ifdef MODPOST_VMLINUX - -quiet_cmd_modpost = MODPOST $@ - cmd_modpost = $(MODPOST) $< - -vmlinux.symvers: vmlinux.o - $(call cmd,modpost) +# 'make -i -k' ignores compile errors, and builds as many modules as possible. +ifneq ($(findstring i,$(filter-out --%,$(MAKEFLAGS))),) +MODPOST += -n +endif -__modpost: vmlinux.symvers +ifeq ($(KBUILD_EXTMOD),) # Generate the list of in-tree objects in vmlinux # --------------------------------------------------------------------------- # This is used to retrieve symbol versions generated by genksyms. ifdef CONFIG_MODVERSIONS -vmlinux.symvers: .vmlinux.objs +vmlinux.symvers Module.symvers: .vmlinux.objs endif # Ignore libgcc.a @@ -83,24 +79,12 @@ targets += .vmlinux.objs .vmlinux.objs: $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) FORCE $(call if_changed,vmlinux_objs) -else - -ifeq ($(KBUILD_EXTMOD),) - -input-symdump := vmlinux.symvers -output-symdump := modules-only.symvers - -quiet_cmd_cat = GEN $@ - cmd_cat = cat $(real-prereqs) > $@ - -ifneq ($(wildcard vmlinux.symvers),) - -__modpost: Module.symvers -Module.symvers: vmlinux.symvers modules-only.symvers FORCE - $(call if_changed,cat) - -targets += Module.symvers +vmlinux.o-if-present := $(wildcard vmlinux.o) +output-symdump := vmlinux.symvers +ifdef KBUILD_MODULES +output-symdump := $(if $(vmlinux.o-if-present), Module.symvers, modules-only.symvers) +missing-input := $(filter-out $(vmlinux.o-if-present),vmlinux.o) endif else @@ -112,56 +96,35 @@ src := $(obj) # Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS include $(or $(wildcard $(src)/Kbuild), $(src)/Makefile) -# modpost option for external modules -MODPOST += -e - -input-symdump := Module.symvers $(KBUILD_EXTRA_SYMBOLS) +module.symvers-if-present := $(wildcard Module.symvers) output-symdump := $(KBUILD_EXTMOD)/Module.symvers +missing-input := $(filter-out $(module.symvers-if-present), Module.symvers) -endif - -existing-input-symdump := $(wildcard $(input-symdump)) - -# modpost options for modules (both in-kernel and external) -MODPOST += \ - $(addprefix -i ,$(existing-input-symdump)) \ - $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \ - $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) - -# 'make -i -k' ignores compile errors, and builds as many modules as possible. -ifneq ($(findstring i,$(filter-out --%,$(MAKEFLAGS))),) -MODPOST += -n -endif +MODPOST += -e $(addprefix -i ,$(module.symvers-if-present) $(KBUILD_EXTRA_SYMBOLS)) -# Clear VPATH to not search for *.symvers in $(srctree). Check only $(objtree). -VPATH := -$(input-symdump): - @echo >&2 'WARNING: Symbol version dump "$@" is missing.' - @echo >&2 ' Modules may not have dependencies or modversions.' - @echo >&2 ' You may get many unresolved symbol warnings.' +endif # ($(KBUILD_EXTMOD),) -# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined symbols -ifneq ($(KBUILD_MODPOST_WARN)$(filter-out $(existing-input-symdump), $(input-symdump)),) +ifneq ($(KBUILD_MODPOST_WARN)$(missing-input),) MODPOST += -w endif +modorder-if-needed := $(if $(KBUILD_MODULES), $(MODORDER)) + # Read out modules.order to pass in modpost. # Otherwise, allmodconfig would fail with "Argument list too long". quiet_cmd_modpost = MODPOST $@ - cmd_modpost = sed 's/ko$$/o/' $< | $(MODPOST) -T - - -$(output-symdump): $(MODORDER) $(input-symdump) FORCE - $(call if_changed,modpost) + cmd_modpost = \ + $(if $(missing-input), \ + echo >&2 "WARNING: $(missing-input) is missing."; \ + echo >&2 " Modules may not have dependencies or modversions."; \ + echo >&2 " You may get many unresolved symbol warnings.";) \ + sed 's/ko$$/o/' $(or $(modorder-if-needed), /dev/null) | $(MODPOST) $(vmlinux.o-if-present) -T - targets += $(output-symdump) +$(output-symdump): $(modorder-if-needed) $(vmlinux.o-if-present) $(moudle.symvers-if-present) FORCE + $(call if_changed,modpost) __modpost: $(output-symdump) -ifneq ($(KBUILD_MODPOST_NOFINAL),1) - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal -endif - -endif - PHONY += FORCE FORCE: diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 07486f90d5e2..6a197d8a88ac 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -214,9 +214,6 @@ if [ "$1" = "clean" ]; then exit 0 fi -# modpost vmlinux.o to check for section mismatches -${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1 - info MODINFO modules.builtin.modinfo ${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo info GEN modules.builtin -- cgit v1.2.3 From 425937381ec492d454cd4d8ba594711331128a44 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 15 Sep 2022 15:26:23 +0900 Subject: kbuild: re-run modpost when it is updated Modpost generates .vmlinux.export.c and *.mod.c, which are prerequisites of vmlinux and modules, respectively. The modpost stage should be re-run when the modpost code is updated. Signed-off-by: Masahiro Yamada --- scripts/Makefile.modpost | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 2daf760eeb25..40a3e9b0512b 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -38,7 +38,7 @@ __modpost: include include/config/auto.conf include $(srctree)/scripts/Kbuild.include -MODPOST = scripts/mod/modpost \ +modpost-args = \ $(if $(CONFIG_MODVERSIONS),-m) \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \ $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ @@ -48,7 +48,7 @@ MODPOST = scripts/mod/modpost \ # 'make -i -k' ignores compile errors, and builds as many modules as possible. ifneq ($(findstring i,$(filter-out --%,$(MAKEFLAGS))),) -MODPOST += -n +modpost-args += -n endif ifeq ($(KBUILD_EXTMOD),) @@ -100,16 +100,18 @@ module.symvers-if-present := $(wildcard Module.symvers) output-symdump := $(KBUILD_EXTMOD)/Module.symvers missing-input := $(filter-out $(module.symvers-if-present), Module.symvers) -MODPOST += -e $(addprefix -i ,$(module.symvers-if-present) $(KBUILD_EXTRA_SYMBOLS)) +modpost-args += -e $(addprefix -i ,$(module.symvers-if-present) $(KBUILD_EXTRA_SYMBOLS)) endif # ($(KBUILD_EXTMOD),) ifneq ($(KBUILD_MODPOST_WARN)$(missing-input),) -MODPOST += -w +modpost-args += -w endif modorder-if-needed := $(if $(KBUILD_MODULES), $(MODORDER)) +MODPOST = scripts/mod/modpost + # Read out modules.order to pass in modpost. # Otherwise, allmodconfig would fail with "Argument list too long". quiet_cmd_modpost = MODPOST $@ @@ -118,10 +120,10 @@ quiet_cmd_modpost = MODPOST $@ echo >&2 "WARNING: $(missing-input) is missing."; \ echo >&2 " Modules may not have dependencies or modversions."; \ echo >&2 " You may get many unresolved symbol warnings.";) \ - sed 's/ko$$/o/' $(or $(modorder-if-needed), /dev/null) | $(MODPOST) $(vmlinux.o-if-present) -T - + sed 's/ko$$/o/' $(or $(modorder-if-needed), /dev/null) | $(MODPOST) $(modpost-args) $(vmlinux.o-if-present) -T - targets += $(output-symdump) -$(output-symdump): $(modorder-if-needed) $(vmlinux.o-if-present) $(moudle.symvers-if-present) FORCE +$(output-symdump): $(modorder-if-needed) $(vmlinux.o-if-present) $(moudle.symvers-if-present) $(MODPOST) FORCE $(call if_changed,modpost) __modpost: $(output-symdump) -- cgit v1.2.3 From f4bf1cd4ac9c8c4610b687e49a1ba691ab286235 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Tue, 27 Sep 2022 10:05:57 -0600 Subject: docs: move asm-annotations.rst into core-api This one file should not really be in the top-level documentation directory. core-api/ may not be a perfect fit but seems to be best, so move it there. Adjust a couple of internal document references to make them location-independent, and point checkpatch.pl at the new location. Cc: Jiri Slaby Cc: Joe Perches Reviewed-by: David Vernet Acked-by: Jani Nikula Signed-off-by: Jonathan Corbet Acked-by: Randy Dunlap Link: https://lore.kernel.org/r/20220927160559.97154-6-corbet@lwn.net Signed-off-by: Jonathan Corbet --- Documentation/asm-annotations.rst | 221 ---------------------------- Documentation/core-api/asm-annotations.rst | 222 +++++++++++++++++++++++++++++ Documentation/core-api/index.rst | 1 + Documentation/index.rst | 8 -- scripts/checkpatch.pl | 2 +- 5 files changed, 224 insertions(+), 230 deletions(-) delete mode 100644 Documentation/asm-annotations.rst create mode 100644 Documentation/core-api/asm-annotations.rst (limited to 'scripts') diff --git a/Documentation/asm-annotations.rst b/Documentation/asm-annotations.rst deleted file mode 100644 index a64f2ca469d4..000000000000 --- a/Documentation/asm-annotations.rst +++ /dev/null @@ -1,221 +0,0 @@ -Assembler Annotations -===================== - -Copyright (c) 2017-2019 Jiri Slaby - -This document describes the new macros for annotation of data and code in -assembly. In particular, it contains information about ``SYM_FUNC_START``, -``SYM_FUNC_END``, ``SYM_CODE_START``, and similar. - -Rationale ---------- -Some code like entries, trampolines, or boot code needs to be written in -assembly. The same as in C, such code is grouped into functions and -accompanied with data. Standard assemblers do not force users into precisely -marking these pieces as code, data, or even specifying their length. -Nevertheless, assemblers provide developers with such annotations to aid -debuggers throughout assembly. On top of that, developers also want to mark -some functions as *global* in order to be visible outside of their translation -units. - -Over time, the Linux kernel has adopted macros from various projects (like -``binutils``) to facilitate such annotations. So for historic reasons, -developers have been using ``ENTRY``, ``END``, ``ENDPROC``, and other -annotations in assembly. Due to the lack of their documentation, the macros -are used in rather wrong contexts at some locations. Clearly, ``ENTRY`` was -intended to denote the beginning of global symbols (be it data or code). -``END`` used to mark the end of data or end of special functions with -*non-standard* calling convention. In contrast, ``ENDPROC`` should annotate -only ends of *standard* functions. - -When these macros are used correctly, they help assemblers generate a nice -object with both sizes and types set correctly. For example, the result of -``arch/x86/lib/putuser.S``:: - - Num: Value Size Type Bind Vis Ndx Name - 25: 0000000000000000 33 FUNC GLOBAL DEFAULT 1 __put_user_1 - 29: 0000000000000030 37 FUNC GLOBAL DEFAULT 1 __put_user_2 - 32: 0000000000000060 36 FUNC GLOBAL DEFAULT 1 __put_user_4 - 35: 0000000000000090 37 FUNC GLOBAL DEFAULT 1 __put_user_8 - -This is not only important for debugging purposes. When there are properly -annotated objects like this, tools can be run on them to generate more useful -information. In particular, on properly annotated objects, ``objtool`` can be -run to check and fix the object if needed. Currently, ``objtool`` can report -missing frame pointer setup/destruction in functions. It can also -automatically generate annotations for :doc:`ORC unwinder ` -for most code. Both of these are especially important to support reliable -stack traces which are in turn necessary for :doc:`Kernel live patching -`. - -Caveat and Discussion ---------------------- -As one might realize, there were only three macros previously. That is indeed -insufficient to cover all the combinations of cases: - -* standard/non-standard function -* code/data -* global/local symbol - -There was a discussion_ and instead of extending the current ``ENTRY/END*`` -macros, it was decided that brand new macros should be introduced instead:: - - So how about using macro names that actually show the purpose, instead - of importing all the crappy, historic, essentially randomly chosen - debug symbol macro names from the binutils and older kernels? - -.. _discussion: https://lore.kernel.org/r/20170217104757.28588-1-jslaby@suse.cz - -Macros Description ------------------- - -The new macros are prefixed with the ``SYM_`` prefix and can be divided into -three main groups: - -1. ``SYM_FUNC_*`` -- to annotate C-like functions. This means functions with - standard C calling conventions. For example, on x86, this means that the - stack contains a return address at the predefined place and a return from - the function can happen in a standard way. When frame pointers are enabled, - save/restore of frame pointer shall happen at the start/end of a function, - respectively, too. - - Checking tools like ``objtool`` should ensure such marked functions conform - to these rules. The tools can also easily annotate these functions with - debugging information (like *ORC data*) automatically. - -2. ``SYM_CODE_*`` -- special functions called with special stack. Be it - interrupt handlers with special stack content, trampolines, or startup - functions. - - Checking tools mostly ignore checking of these functions. But some debug - information still can be generated automatically. For correct debug data, - this code needs hints like ``UNWIND_HINT_REGS`` provided by developers. - -3. ``SYM_DATA*`` -- obviously data belonging to ``.data`` sections and not to - ``.text``. Data do not contain instructions, so they have to be treated - specially by the tools: they should not treat the bytes as instructions, - nor assign any debug information to them. - -Instruction Macros -~~~~~~~~~~~~~~~~~~ -This section covers ``SYM_FUNC_*`` and ``SYM_CODE_*`` enumerated above. - -``objtool`` requires that all code must be contained in an ELF symbol. Symbol -names that have a ``.L`` prefix do not emit symbol table entries. ``.L`` -prefixed symbols can be used within a code region, but should be avoided for -denoting a range of code via ``SYM_*_START/END`` annotations. - -* ``SYM_FUNC_START`` and ``SYM_FUNC_START_LOCAL`` are supposed to be **the - most frequent markings**. They are used for functions with standard calling - conventions -- global and local. Like in C, they both align the functions to - architecture specific ``__ALIGN`` bytes. There are also ``_NOALIGN`` variants - for special cases where developers do not want this implicit alignment. - - ``SYM_FUNC_START_WEAK`` and ``SYM_FUNC_START_WEAK_NOALIGN`` markings are - also offered as an assembler counterpart to the *weak* attribute known from - C. - - All of these **shall** be coupled with ``SYM_FUNC_END``. First, it marks - the sequence of instructions as a function and computes its size to the - generated object file. Second, it also eases checking and processing such - object files as the tools can trivially find exact function boundaries. - - So in most cases, developers should write something like in the following - example, having some asm instructions in between the macros, of course:: - - SYM_FUNC_START(memset) - ... asm insns ... - SYM_FUNC_END(memset) - - In fact, this kind of annotation corresponds to the now deprecated ``ENTRY`` - and ``ENDPROC`` macros. - -* ``SYM_FUNC_ALIAS``, ``SYM_FUNC_ALIAS_LOCAL``, and ``SYM_FUNC_ALIAS_WEAK`` can - be used to define multiple names for a function. The typical use is:: - - SYM_FUNC_START(__memset) - ... asm insns ... - SYN_FUNC_END(__memset) - SYM_FUNC_ALIAS(memset, __memset) - - In this example, one can call ``__memset`` or ``memset`` with the same - result, except the debug information for the instructions is generated to - the object file only once -- for the non-``ALIAS`` case. - -* ``SYM_CODE_START`` and ``SYM_CODE_START_LOCAL`` should be used only in - special cases -- if you know what you are doing. This is used exclusively - for interrupt handlers and similar where the calling convention is not the C - one. ``_NOALIGN`` variants exist too. The use is the same as for the ``FUNC`` - category above:: - - SYM_CODE_START_LOCAL(bad_put_user) - ... asm insns ... - SYM_CODE_END(bad_put_user) - - Again, every ``SYM_CODE_START*`` **shall** be coupled by ``SYM_CODE_END``. - - To some extent, this category corresponds to deprecated ``ENTRY`` and - ``END``. Except ``END`` had several other meanings too. - -* ``SYM_INNER_LABEL*`` is used to denote a label inside some - ``SYM_{CODE,FUNC}_START`` and ``SYM_{CODE,FUNC}_END``. They are very similar - to C labels, except they can be made global. An example of use:: - - SYM_CODE_START(ftrace_caller) - /* save_mcount_regs fills in first two parameters */ - ... - - SYM_INNER_LABEL(ftrace_caller_op_ptr, SYM_L_GLOBAL) - /* Load the ftrace_ops into the 3rd parameter */ - ... - - SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL) - call ftrace_stub - ... - retq - SYM_CODE_END(ftrace_caller) - -Data Macros -~~~~~~~~~~~ -Similar to instructions, there is a couple of macros to describe data in the -assembly. - -* ``SYM_DATA_START`` and ``SYM_DATA_START_LOCAL`` mark the start of some data - and shall be used in conjunction with either ``SYM_DATA_END``, or - ``SYM_DATA_END_LABEL``. The latter adds also a label to the end, so that - people can use ``lstack`` and (local) ``lstack_end`` in the following - example:: - - SYM_DATA_START_LOCAL(lstack) - .skip 4096 - SYM_DATA_END_LABEL(lstack, SYM_L_LOCAL, lstack_end) - -* ``SYM_DATA`` and ``SYM_DATA_LOCAL`` are variants for simple, mostly one-line - data:: - - SYM_DATA(HEAP, .long rm_heap) - SYM_DATA(heap_end, .long rm_stack) - - In the end, they expand to ``SYM_DATA_START`` with ``SYM_DATA_END`` - internally. - -Support Macros -~~~~~~~~~~~~~~ -All the above reduce themselves to some invocation of ``SYM_START``, -``SYM_END``, or ``SYM_ENTRY`` at last. Normally, developers should avoid using -these. - -Further, in the above examples, one could see ``SYM_L_LOCAL``. There are also -``SYM_L_GLOBAL`` and ``SYM_L_WEAK``. All are intended to denote linkage of a -symbol marked by them. They are used either in ``_LABEL`` variants of the -earlier macros, or in ``SYM_START``. - - -Overriding Macros -~~~~~~~~~~~~~~~~~ -Architecture can also override any of the macros in their own -``asm/linkage.h``, including macros specifying the type of a symbol -(``SYM_T_FUNC``, ``SYM_T_OBJECT``, and ``SYM_T_NONE``). As every macro -described in this file is surrounded by ``#ifdef`` + ``#endif``, it is enough -to define the macros differently in the aforementioned architecture-dependent -header. diff --git a/Documentation/core-api/asm-annotations.rst b/Documentation/core-api/asm-annotations.rst new file mode 100644 index 000000000000..bc514ed59887 --- /dev/null +++ b/Documentation/core-api/asm-annotations.rst @@ -0,0 +1,222 @@ +Assembler Annotations +===================== + +Copyright (c) 2017-2019 Jiri Slaby + +This document describes the new macros for annotation of data and code in +assembly. In particular, it contains information about ``SYM_FUNC_START``, +``SYM_FUNC_END``, ``SYM_CODE_START``, and similar. + +Rationale +--------- +Some code like entries, trampolines, or boot code needs to be written in +assembly. The same as in C, such code is grouped into functions and +accompanied with data. Standard assemblers do not force users into precisely +marking these pieces as code, data, or even specifying their length. +Nevertheless, assemblers provide developers with such annotations to aid +debuggers throughout assembly. On top of that, developers also want to mark +some functions as *global* in order to be visible outside of their translation +units. + +Over time, the Linux kernel has adopted macros from various projects (like +``binutils``) to facilitate such annotations. So for historic reasons, +developers have been using ``ENTRY``, ``END``, ``ENDPROC``, and other +annotations in assembly. Due to the lack of their documentation, the macros +are used in rather wrong contexts at some locations. Clearly, ``ENTRY`` was +intended to denote the beginning of global symbols (be it data or code). +``END`` used to mark the end of data or end of special functions with +*non-standard* calling convention. In contrast, ``ENDPROC`` should annotate +only ends of *standard* functions. + +When these macros are used correctly, they help assemblers generate a nice +object with both sizes and types set correctly. For example, the result of +``arch/x86/lib/putuser.S``:: + + Num: Value Size Type Bind Vis Ndx Name + 25: 0000000000000000 33 FUNC GLOBAL DEFAULT 1 __put_user_1 + 29: 0000000000000030 37 FUNC GLOBAL DEFAULT 1 __put_user_2 + 32: 0000000000000060 36 FUNC GLOBAL DEFAULT 1 __put_user_4 + 35: 0000000000000090 37 FUNC GLOBAL DEFAULT 1 __put_user_8 + +This is not only important for debugging purposes. When there are properly +annotated objects like this, tools can be run on them to generate more useful +information. In particular, on properly annotated objects, ``objtool`` can be +run to check and fix the object if needed. Currently, ``objtool`` can report +missing frame pointer setup/destruction in functions. It can also +automatically generate annotations for the ORC unwinder +(Documentation/x86/orc-unwinder.rst) +for most code. Both of these are especially important to support reliable +stack traces which are in turn necessary for kernel live patching +(Documentation/livepatch/livepatch.rst). + +Caveat and Discussion +--------------------- +As one might realize, there were only three macros previously. That is indeed +insufficient to cover all the combinations of cases: + +* standard/non-standard function +* code/data +* global/local symbol + +There was a discussion_ and instead of extending the current ``ENTRY/END*`` +macros, it was decided that brand new macros should be introduced instead:: + + So how about using macro names that actually show the purpose, instead + of importing all the crappy, historic, essentially randomly chosen + debug symbol macro names from the binutils and older kernels? + +.. _discussion: https://lore.kernel.org/r/20170217104757.28588-1-jslaby@suse.cz + +Macros Description +------------------ + +The new macros are prefixed with the ``SYM_`` prefix and can be divided into +three main groups: + +1. ``SYM_FUNC_*`` -- to annotate C-like functions. This means functions with + standard C calling conventions. For example, on x86, this means that the + stack contains a return address at the predefined place and a return from + the function can happen in a standard way. When frame pointers are enabled, + save/restore of frame pointer shall happen at the start/end of a function, + respectively, too. + + Checking tools like ``objtool`` should ensure such marked functions conform + to these rules. The tools can also easily annotate these functions with + debugging information (like *ORC data*) automatically. + +2. ``SYM_CODE_*`` -- special functions called with special stack. Be it + interrupt handlers with special stack content, trampolines, or startup + functions. + + Checking tools mostly ignore checking of these functions. But some debug + information still can be generated automatically. For correct debug data, + this code needs hints like ``UNWIND_HINT_REGS`` provided by developers. + +3. ``SYM_DATA*`` -- obviously data belonging to ``.data`` sections and not to + ``.text``. Data do not contain instructions, so they have to be treated + specially by the tools: they should not treat the bytes as instructions, + nor assign any debug information to them. + +Instruction Macros +~~~~~~~~~~~~~~~~~~ +This section covers ``SYM_FUNC_*`` and ``SYM_CODE_*`` enumerated above. + +``objtool`` requires that all code must be contained in an ELF symbol. Symbol +names that have a ``.L`` prefix do not emit symbol table entries. ``.L`` +prefixed symbols can be used within a code region, but should be avoided for +denoting a range of code via ``SYM_*_START/END`` annotations. + +* ``SYM_FUNC_START`` and ``SYM_FUNC_START_LOCAL`` are supposed to be **the + most frequent markings**. They are used for functions with standard calling + conventions -- global and local. Like in C, they both align the functions to + architecture specific ``__ALIGN`` bytes. There are also ``_NOALIGN`` variants + for special cases where developers do not want this implicit alignment. + + ``SYM_FUNC_START_WEAK`` and ``SYM_FUNC_START_WEAK_NOALIGN`` markings are + also offered as an assembler counterpart to the *weak* attribute known from + C. + + All of these **shall** be coupled with ``SYM_FUNC_END``. First, it marks + the sequence of instructions as a function and computes its size to the + generated object file. Second, it also eases checking and processing such + object files as the tools can trivially find exact function boundaries. + + So in most cases, developers should write something like in the following + example, having some asm instructions in between the macros, of course:: + + SYM_FUNC_START(memset) + ... asm insns ... + SYM_FUNC_END(memset) + + In fact, this kind of annotation corresponds to the now deprecated ``ENTRY`` + and ``ENDPROC`` macros. + +* ``SYM_FUNC_ALIAS``, ``SYM_FUNC_ALIAS_LOCAL``, and ``SYM_FUNC_ALIAS_WEAK`` can + be used to define multiple names for a function. The typical use is:: + + SYM_FUNC_START(__memset) + ... asm insns ... + SYN_FUNC_END(__memset) + SYM_FUNC_ALIAS(memset, __memset) + + In this example, one can call ``__memset`` or ``memset`` with the same + result, except the debug information for the instructions is generated to + the object file only once -- for the non-``ALIAS`` case. + +* ``SYM_CODE_START`` and ``SYM_CODE_START_LOCAL`` should be used only in + special cases -- if you know what you are doing. This is used exclusively + for interrupt handlers and similar where the calling convention is not the C + one. ``_NOALIGN`` variants exist too. The use is the same as for the ``FUNC`` + category above:: + + SYM_CODE_START_LOCAL(bad_put_user) + ... asm insns ... + SYM_CODE_END(bad_put_user) + + Again, every ``SYM_CODE_START*`` **shall** be coupled by ``SYM_CODE_END``. + + To some extent, this category corresponds to deprecated ``ENTRY`` and + ``END``. Except ``END`` had several other meanings too. + +* ``SYM_INNER_LABEL*`` is used to denote a label inside some + ``SYM_{CODE,FUNC}_START`` and ``SYM_{CODE,FUNC}_END``. They are very similar + to C labels, except they can be made global. An example of use:: + + SYM_CODE_START(ftrace_caller) + /* save_mcount_regs fills in first two parameters */ + ... + + SYM_INNER_LABEL(ftrace_caller_op_ptr, SYM_L_GLOBAL) + /* Load the ftrace_ops into the 3rd parameter */ + ... + + SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL) + call ftrace_stub + ... + retq + SYM_CODE_END(ftrace_caller) + +Data Macros +~~~~~~~~~~~ +Similar to instructions, there is a couple of macros to describe data in the +assembly. + +* ``SYM_DATA_START`` and ``SYM_DATA_START_LOCAL`` mark the start of some data + and shall be used in conjunction with either ``SYM_DATA_END``, or + ``SYM_DATA_END_LABEL``. The latter adds also a label to the end, so that + people can use ``lstack`` and (local) ``lstack_end`` in the following + example:: + + SYM_DATA_START_LOCAL(lstack) + .skip 4096 + SYM_DATA_END_LABEL(lstack, SYM_L_LOCAL, lstack_end) + +* ``SYM_DATA`` and ``SYM_DATA_LOCAL`` are variants for simple, mostly one-line + data:: + + SYM_DATA(HEAP, .long rm_heap) + SYM_DATA(heap_end, .long rm_stack) + + In the end, they expand to ``SYM_DATA_START`` with ``SYM_DATA_END`` + internally. + +Support Macros +~~~~~~~~~~~~~~ +All the above reduce themselves to some invocation of ``SYM_START``, +``SYM_END``, or ``SYM_ENTRY`` at last. Normally, developers should avoid using +these. + +Further, in the above examples, one could see ``SYM_L_LOCAL``. There are also +``SYM_L_GLOBAL`` and ``SYM_L_WEAK``. All are intended to denote linkage of a +symbol marked by them. They are used either in ``_LABEL`` variants of the +earlier macros, or in ``SYM_START``. + + +Overriding Macros +~~~~~~~~~~~~~~~~~ +Architecture can also override any of the macros in their own +``asm/linkage.h``, including macros specifying the type of a symbol +(``SYM_T_FUNC``, ``SYM_T_OBJECT``, and ``SYM_T_NONE``). As every macro +described in this file is surrounded by ``#ifdef`` + ``#endif``, it is enough +to define the macros differently in the aforementioned architecture-dependent +header. diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst index dc95df462eea..f5d8e3779fe8 100644 --- a/Documentation/core-api/index.rst +++ b/Documentation/core-api/index.rst @@ -23,6 +23,7 @@ it. printk-formats printk-index symbol-namespaces + asm-annotations Data structures and low-level utilities ======================================= diff --git a/Documentation/index.rst b/Documentation/index.rst index da80c584133c..5a700548ae82 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -89,14 +89,6 @@ platform firmwares. devicetree/index -Architecture-agnostic documentation ------------------------------------ - -.. toctree:: - :maxdepth: 1 - - asm-annotations - Architecture-specific documentation ----------------------------------- diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 79e759aac543..812af52f97d2 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3751,7 +3751,7 @@ sub process { if ($realfile =~ /\.S$/ && $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) { WARN("AVOID_L_PREFIX", - "Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/asm-annotations.rst\n" . $herecurr); + "Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/core-api/asm-annotations.rst\n" . $herecurr); } # check we are in a valid source file C or perl if not then ignore this hunk -- cgit v1.2.3 From 69d517e6e21099f81efbd39e47874649ae575804 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 23 Sep 2022 13:34:25 +0200 Subject: checkpatch: warn on usage of VM_BUG_ON() and other BUG variants checkpatch does not point out that VM_BUG_ON() and friends should be avoided, however, Linus notes: VM_BUG_ON() has the exact same semantics as BUG_ON. It is literally no different, the only difference is "we can make the code smaller because these are less important". [1] So let's warn on VM_BUG_ON() and other BUG variants as well. While at it, make it clearer that the kernel really shouldn't be crashed. As there are some subsystem BUG macros that actually don't end up crashing the kernel -- for example, KVM_BUG_ON() -- exclude these manually. [1] https://lore.kernel.org/r/CAHk-=wg40EAZofO16Eviaj7mfqDhZ2gVEbvfsMf6gYzspRjYvw@mail.gmail.com Signed-off-by: David Hildenbrand Link: https://lore.kernel.org/r/20220923113426.52871-3-david@redhat.com Signed-off-by: Jonathan Corbet --- scripts/checkpatch.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 812af52f97d2..4aa09e0cb86a 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -4695,12 +4695,12 @@ sub process { } } -# avoid BUG() or BUG_ON() - if ($line =~ /\b(?:BUG|BUG_ON)\b/) { +# do not use BUG() or variants + if ($line =~ /\b(?!AA_|BUILD_|DCCP_|IDA_|KVM_|RWLOCK_|snd_|SPIN_)(?:[a-zA-Z_]*_)?BUG(?:_ON)?(?:_[A-Z_]+)?\s*\(/) { my $msg_level = \&WARN; $msg_level = \&CHK if ($file); &{$msg_level}("AVOID_BUG", - "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); + "Do not crash the kernel unless it is absolutely unavoidable--use WARN_ON_ONCE() plus recovery code (if feasible) instead of BUG() or variants\n" . $herecurr); } # avoid LINUX_VERSION_CODE -- cgit v1.2.3 From 2120635108b35ecad9c59c8b44f6cbdf4f98214e Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Fri, 30 Sep 2022 20:33:10 +0000 Subject: Makefile.extrawarn: Move -Wcast-function-type-strict to W=1 We enable -Wcast-function-type globally in the kernel to warn about mismatching types in function pointer casts. Compilers currently warn only about ABI incompability with this flag, but Clang 16 will enable a stricter version of the check by default that checks for an exact type match. This will be very noisy in the kernel, so disable -Wcast-function-type-strict without W=1 until the new warnings have been addressed. Cc: stable@vger.kernel.org Link: https://reviews.llvm.org/D134831 Link: https://github.com/ClangBuiltLinux/linux/issues/1724 Suggested-by: Nathan Chancellor Signed-off-by: Sami Tolvanen Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220930203310.4010564-1-samitolvanen@google.com --- scripts/Makefile.extrawarn | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 0621c39a3955..20df48637373 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -52,6 +52,7 @@ KBUILD_CFLAGS += -Wno-sign-compare KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast) KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access) +KBUILD_CFLAGS += $(call cc-disable-warning, cast-function-type-strict) endif endif -- cgit v1.2.3 From 3216484550610470013b7ce1c9ed272da0a74589 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 25 Sep 2022 03:19:14 +0900 Subject: kbuild: use obj-y instead extra-y for objects placed at the head The objects placed at the head of vmlinux need special treatments: - arch/$(SRCARCH)/Makefile adds them to head-y in order to place them before other archives in the linker command line. - arch/$(SRCARCH)/kernel/Makefile adds them to extra-y instead of obj-y to avoid them going into built-in.a. This commit gets rid of the latter. Create vmlinux.a to collect all the objects that are unconditionally linked to vmlinux. The objects listed in head-y are moved to the head of vmlinux.a by using 'ar m'. With this, arch/$(SRCARCH)/kernel/Makefile can consistently use obj-y for builtin objects. There is no *.o that is directly linked to vmlinux. Drop unneeded code in scripts/clang-tools/gen_compile_commands.py. $(AR) mPi needs 'T' to workaround the llvm-ar bug. The fix was suggested by Nathan Chancellor [1]. [1]: https://lore.kernel.org/llvm/YyjjT5gQ2hGMH0ni@dev-arch.thelio-3990X/ Signed-off-by: Masahiro Yamada Tested-by: Nick Desaulniers Reviewed-by: Nicolas Schier --- Documentation/kbuild/makefiles.rst | 18 +----------------- Makefile | 23 ++++++++++++++++++----- arch/alpha/kernel/Makefile | 4 ++-- arch/arc/kernel/Makefile | 4 ++-- arch/arm/kernel/Makefile | 4 ++-- arch/arm64/kernel/Makefile | 4 ++-- arch/csky/kernel/Makefile | 4 ++-- arch/hexagon/kernel/Makefile | 3 ++- arch/ia64/kernel/Makefile | 4 ++-- arch/loongarch/kernel/Makefile | 4 ++-- arch/m68k/68000/Makefile | 2 +- arch/m68k/coldfire/Makefile | 2 +- arch/m68k/kernel/Makefile | 23 ++++++++++++----------- arch/microblaze/kernel/Makefile | 4 ++-- arch/mips/kernel/Makefile | 4 ++-- arch/nios2/kernel/Makefile | 2 +- arch/openrisc/kernel/Makefile | 4 ++-- arch/parisc/kernel/Makefile | 4 ++-- arch/powerpc/kernel/Makefile | 20 ++++++++++---------- arch/riscv/kernel/Makefile | 2 +- arch/s390/kernel/Makefile | 4 ++-- arch/sh/kernel/Makefile | 4 ++-- arch/sparc/kernel/Makefile | 3 +-- arch/x86/kernel/Makefile | 10 +++++----- arch/xtensa/kernel/Makefile | 4 ++-- scripts/Makefile.modpost | 5 ++--- scripts/Makefile.vmlinux_o | 6 +++--- scripts/clang-tools/gen_compile_commands.py | 19 +------------------ scripts/link-vmlinux.sh | 10 ++++------ 29 files changed, 91 insertions(+), 113 deletions(-) (limited to 'scripts') diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index ee7e3ea1fbe1..5a6a8426cc97 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -340,19 +340,7 @@ more details, with real examples. Examples are: - 1) head objects - - Some objects must be placed at the head of vmlinux. They are - directly linked to vmlinux without going through built-in.a - A typical use-case is an object that contains the entry point. - - arch/$(SRCARCH)/Makefile should specify such objects as head-y. - - Discussion: - Given that we can control the section order in the linker script, - why do we need head-y? - - 2) vmlinux linker script + 1) vmlinux linker script The linker script for vmlinux is located at arch/$(SRCARCH)/kernel/vmlinux.lds @@ -360,10 +348,6 @@ more details, with real examples. Example:: # arch/x86/kernel/Makefile - extra-y := head_$(BITS).o - extra-y += head$(BITS).o - extra-y += ebda.o - extra-y += platform-quirks.o extra-y += vmlinux.lds $(extra-y) should only contain targets needed for vmlinux. diff --git a/Makefile b/Makefile index 22a956b9ffe4..8da45f76ec31 100644 --- a/Makefile +++ b/Makefile @@ -645,6 +645,8 @@ else __all: modules endif +targets := + # Decide whether to build built-in, modular, or both. # Normally, just do built-in. @@ -1107,7 +1109,7 @@ export ARCH_LIB := $(filter %/, $(libs-y)) export ARCH_DRIVERS := $(drivers-y) $(drivers-m) # Externally visible symbols (used by link-vmlinux.sh) -KBUILD_VMLINUX_OBJS := $(head-y) ./built-in.a +KBUILD_VMLINUX_OBJS := ./built-in.a ifdef CONFIG_MODULES KBUILD_VMLINUX_OBJS += $(patsubst %/, %/lib.a, $(filter %/, $(libs-y))) KBUILD_VMLINUX_LIBS := $(filter-out %/, $(libs-y)) @@ -1115,7 +1117,7 @@ else KBUILD_VMLINUX_LIBS := $(patsubst %/,%/lib.a, $(libs-y)) endif -export KBUILD_VMLINUX_OBJS KBUILD_VMLINUX_LIBS +export KBUILD_VMLINUX_LIBS export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds # Recurse until adjust_autoksyms.sh is satisfied @@ -1140,7 +1142,18 @@ quiet_cmd_autoksyms_h = GEN $@ $(autoksyms_h): $(call cmd,autoksyms_h) -vmlinux.o: autoksyms_recursive $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) FORCE +# '$(AR) mPi' needs 'T' to workaround the bug of llvm-ar <= 14 +quiet_cmd_ar_vmlinux.a = AR $@ + cmd_ar_vmlinux.a = \ + rm -f $@; \ + $(AR) cDPrST $@ $(KBUILD_VMLINUX_OBJS); \ + $(AR) mPiT $$($(AR) t $@ | head -n1) $@ $(head-y) + +targets += vmlinux.a +vmlinux.a: $(KBUILD_VMLINUX_OBJS) autoksyms_recursive FORCE + $(call if_changed,ar_vmlinux.a) + +vmlinux.o: vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.vmlinux_o ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) @@ -1153,7 +1166,7 @@ cmd_link-vmlinux = \ vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) modpost FORCE +$(call if_changed_dep,link-vmlinux) -targets := vmlinux +targets += vmlinux # The actual objects are generated when descending, # make sure no implicit rule kicks in @@ -1878,7 +1891,7 @@ quiet_cmd_gen_compile_commands = GEN $@ cmd_gen_compile_commands = $(PYTHON3) $< -a $(AR) -o $@ $(filter-out $<, $(real-prereqs)) $(extmod_prefix)compile_commands.json: scripts/clang-tools/gen_compile_commands.py \ - $(if $(KBUILD_EXTMOD),,$(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS)) \ + $(if $(KBUILD_EXTMOD),, vmlinux.a $(KBUILD_VMLINUX_LIBS)) \ $(if $(CONFIG_MODULES), $(MODORDER)) FORCE $(call if_changed,gen_compile_commands) diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index 5a74581bf0ee..5a5b0a8b7c6a 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile @@ -3,11 +3,11 @@ # Makefile for the linux kernel. # -extra-y := head.o vmlinux.lds +extra-y := vmlinux.lds asflags-y := $(KBUILD_CFLAGS) ccflags-y := -Wno-sign-compare -obj-y := entry.o traps.o process.o osf_sys.o irq.o \ +obj-y := head.o entry.o traps.o process.o osf_sys.o irq.o \ irq_alpha.o signal.o setup.o ptrace.o time.o \ systbls.o err_common.o io.o bugs.o diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile index 8c4fc4b54c14..0723d888ac44 100644 --- a/arch/arc/kernel/Makefile +++ b/arch/arc/kernel/Makefile @@ -3,7 +3,7 @@ # Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) # -obj-y := arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o +obj-y := head.o arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o @@ -31,4 +31,4 @@ else obj-y += ctx_sw_asm.o endif -extra-y := vmlinux.lds head.o +extra-y := vmlinux.lds diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 553866751e1a..8feaa3217ec5 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -89,7 +89,7 @@ obj-$(CONFIG_VDSO) += vdso.o obj-$(CONFIG_EFI) += efi.o obj-$(CONFIG_PARAVIRT) += paravirt.o -head-y := head$(MMUEXT).o +obj-y += head$(MMUEXT).o obj-$(CONFIG_DEBUG_LL) += debug.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_ARM_PATCH_PHYS_VIRT) += phys2virt.o @@ -109,4 +109,4 @@ obj-$(CONFIG_HAVE_ARM_SMCCC) += smccc-call.o obj-$(CONFIG_GENERIC_CPU_VULNERABILITIES) += spectre.o -extra-y := $(head-y) vmlinux.lds +extra-y := vmlinux.lds diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 1add7b01efa7..b619ff207a57 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -85,8 +85,8 @@ $(obj)/vdso-wrap.o: $(obj)/vdso/vdso.so $(obj)/vdso32-wrap.o: $(obj)/vdso32/vdso.so obj-y += probes/ -head-y := head.o -extra-y += $(head-y) vmlinux.lds +obj-y += head.o +extra-y += vmlinux.lds ifeq ($(CONFIG_DEBUG_EFI),y) AFLAGS_head.o += -DVMLINUX_PATH="\"$(realpath $(objtree)/vmlinux)\"" diff --git a/arch/csky/kernel/Makefile b/arch/csky/kernel/Makefile index 6f14c924b20d..8a868316b912 100644 --- a/arch/csky/kernel/Makefile +++ b/arch/csky/kernel/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only -extra-y := head.o vmlinux.lds +extra-y := vmlinux.lds -obj-y += entry.o atomic.o signal.o traps.o irq.o time.o vdso.o vdso/ +obj-y += head.o entry.o atomic.o signal.o traps.o irq.o time.o vdso.o vdso/ obj-y += power.o syscall.o syscall_table.o setup.o io.o obj-y += process.o cpu-probe.o ptrace.o stacktrace.o obj-y += probes/ diff --git a/arch/hexagon/kernel/Makefile b/arch/hexagon/kernel/Makefile index fae3dce32fde..e73cb321630e 100644 --- a/arch/hexagon/kernel/Makefile +++ b/arch/hexagon/kernel/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 -extra-y := head.o vmlinux.lds +extra-y := vmlinux.lds +obj-y += head.o obj-$(CONFIG_SMP) += smp.o obj-y += setup.o irq_cpu.o traps.o syscalltab.o signal.o time.o diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 08d4a2ba0652..4a1fcb121dda 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -7,9 +7,9 @@ ifdef CONFIG_DYNAMIC_FTRACE CFLAGS_REMOVE_ftrace.o = -pg endif -extra-y := head.o vmlinux.lds +extra-y := vmlinux.lds -obj-y := entry.o efi.o efi_stub.o gate-data.o fsys.o irq.o irq_ia64.o \ +obj-y := head.o entry.o efi.o efi_stub.o gate-data.o fsys.o irq.o irq_ia64.o \ irq_lsapic.o ivt.o pal.o patch.o process.o ptrace.o sal.o \ salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \ unwind.o mca.o mca_asm.o topology.o dma-mapping.o iosapic.o acpi.o \ diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile index e5be17009fe8..6c33b5c45573 100644 --- a/arch/loongarch/kernel/Makefile +++ b/arch/loongarch/kernel/Makefile @@ -3,9 +3,9 @@ # Makefile for the Linux/LoongArch kernel. # -extra-y := head.o vmlinux.lds +extra-y := vmlinux.lds -obj-y += cpu-probe.o cacheinfo.o env.o setup.o entry.o genex.o \ +obj-y += head.o cpu-probe.o cacheinfo.o env.o setup.o entry.o genex.o \ traps.o irq.o idle.o process.o dma.o mem.o io.o reset.o switch.o \ elf.o syscall.o signal.o time.o topology.o inst.o ptrace.o vdso.o diff --git a/arch/m68k/68000/Makefile b/arch/m68k/68000/Makefile index 674541fdf5b8..279560add577 100644 --- a/arch/m68k/68000/Makefile +++ b/arch/m68k/68000/Makefile @@ -17,4 +17,4 @@ obj-$(CONFIG_DRAGEN2) += dragen2.o obj-$(CONFIG_UCSIMM) += ucsimm.o obj-$(CONFIG_UCDIMM) += ucsimm.o -extra-y := head.o +obj-y += head.o diff --git a/arch/m68k/coldfire/Makefile b/arch/m68k/coldfire/Makefile index 9419a6c1f036..c56bc0dc7f2e 100644 --- a/arch/m68k/coldfire/Makefile +++ b/arch/m68k/coldfire/Makefile @@ -45,4 +45,4 @@ obj-$(CONFIG_STMARK2) += stmark2.o obj-$(CONFIG_PCI) += pci.o obj-y += gpio.o -extra-y := head.o +obj-y += head.o diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index c0833da6a2ca..af015447dfb4 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile @@ -3,19 +3,20 @@ # Makefile for the linux kernel. # -extra-$(CONFIG_AMIGA) := head.o -extra-$(CONFIG_ATARI) := head.o -extra-$(CONFIG_MAC) := head.o -extra-$(CONFIG_APOLLO) := head.o -extra-$(CONFIG_VME) := head.o -extra-$(CONFIG_HP300) := head.o -extra-$(CONFIG_Q40) := head.o -extra-$(CONFIG_SUN3X) := head.o -extra-$(CONFIG_VIRT) := head.o -extra-$(CONFIG_SUN3) := sun3-head.o extra-y += vmlinux.lds -obj-y := entry.o irq.o module.o process.o ptrace.o +obj-$(CONFIG_AMIGA) := head.o +obj-$(CONFIG_ATARI) := head.o +obj-$(CONFIG_MAC) := head.o +obj-$(CONFIG_APOLLO) := head.o +obj-$(CONFIG_VME) := head.o +obj-$(CONFIG_HP300) := head.o +obj-$(CONFIG_Q40) := head.o +obj-$(CONFIG_SUN3X) := head.o +obj-$(CONFIG_VIRT) := head.o +obj-$(CONFIG_SUN3) := sun3-head.o + +obj-y += entry.o irq.o module.o process.o ptrace.o obj-y += setup.o signal.o sys_m68k.o syscalltable.o time.o traps.o obj-$(CONFIG_MMU_MOTOROLA) += ints.o vectors.o diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile index 15a20eb814ce..4393bee64eaf 100644 --- a/arch/microblaze/kernel/Makefile +++ b/arch/microblaze/kernel/Makefile @@ -12,9 +12,9 @@ CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_process.o = -pg endif -extra-y := head.o vmlinux.lds +extra-y := vmlinux.lds -obj-y += dma.o exceptions.o \ +obj-y += head.o dma.o exceptions.o \ hw_exception_handler.o irq.o \ process.o prom.o ptrace.o \ reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 7c96282bff2e..5d1addac5e28 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -3,9 +3,9 @@ # Makefile for the Linux/MIPS kernel. # -extra-y := head.o vmlinux.lds +extra-y := vmlinux.lds -obj-y += branch.o cmpxchg.o elf.o entry.o genex.o idle.o irq.o \ +obj-y += head.o branch.o cmpxchg.o elf.o entry.o genex.o idle.o irq.o \ process.o prom.o ptrace.o reset.o setup.o signal.o \ syscall.o time.o topology.o traps.o unaligned.o watch.o \ vdso.o cacheinfo.o diff --git a/arch/nios2/kernel/Makefile b/arch/nios2/kernel/Makefile index 0b645e1e3158..78a913181fa1 100644 --- a/arch/nios2/kernel/Makefile +++ b/arch/nios2/kernel/Makefile @@ -3,9 +3,9 @@ # Makefile for the nios2 linux kernel. # -extra-y += head.o extra-y += vmlinux.lds +obj-y += head.o obj-y += cpuinfo.o obj-y += entry.o obj-y += insnemu.o diff --git a/arch/openrisc/kernel/Makefile b/arch/openrisc/kernel/Makefile index 2d172e79f58d..79129161f3e0 100644 --- a/arch/openrisc/kernel/Makefile +++ b/arch/openrisc/kernel/Makefile @@ -3,9 +3,9 @@ # Makefile for the linux kernel. # -extra-y := head.o vmlinux.lds +extra-y := vmlinux.lds -obj-y := setup.o or32_ksyms.o process.o dma.o \ +obj-y := head.o setup.o or32_ksyms.o process.o dma.o \ traps.o time.o irq.o entry.o ptrace.o signal.o \ sys_call_table.o unwinder.o diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index d0bfac89a842..3d138c9cf9ce 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile @@ -3,9 +3,9 @@ # Makefile for arch/parisc/kernel # -extra-y := head.o vmlinux.lds +extra-y := vmlinux.lds -obj-y := cache.o pacache.o setup.o pdt.o traps.o time.o irq.o \ +obj-y := head.o cache.o pacache.o setup.o pdt.o traps.o time.o irq.o \ pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \ ptrace.o hardware.o inventory.o drivers.o alternative.o \ signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 06d2d1f78f71..ad3decb9f20b 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -118,12 +118,12 @@ obj-$(CONFIG_PPC_FSL_BOOK3E) += cpu_setup_fsl_booke.o obj-$(CONFIG_PPC_DOORBELL) += dbell.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o -extra-$(CONFIG_PPC64) := head_64.o -extra-$(CONFIG_PPC_BOOK3S_32) := head_book3s_32.o -extra-$(CONFIG_40x) := head_40x.o -extra-$(CONFIG_44x) := head_44x.o -extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o -extra-$(CONFIG_PPC_8xx) := head_8xx.o +obj-$(CONFIG_PPC64) += head_64.o +obj-$(CONFIG_PPC_BOOK3S_32) += head_book3s_32.o +obj-$(CONFIG_40x) += head_40x.o +obj-$(CONFIG_44x) += head_44x.o +obj-$(CONFIG_FSL_BOOKE) += head_fsl_booke.o +obj-$(CONFIG_PPC_8xx) += head_8xx.o extra-y += vmlinux.lds obj-$(CONFIG_RELOCATABLE) += reloc_$(BITS).o @@ -198,10 +198,10 @@ KCOV_INSTRUMENT_paca.o := n CFLAGS_setup_64.o += -fno-stack-protector CFLAGS_paca.o += -fno-stack-protector -extra-$(CONFIG_PPC_FPU) += fpu.o -extra-$(CONFIG_ALTIVEC) += vector.o -extra-$(CONFIG_PPC64) += entry_64.o -extra-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init.o +obj-$(CONFIG_PPC_FPU) += fpu.o +obj-$(CONFIG_ALTIVEC) += vector.o +obj-$(CONFIG_PPC64) += entry_64.o +obj-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init.o extra-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init_check diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile index 33bb60a354cd..db6e4b1294ba 100644 --- a/arch/riscv/kernel/Makefile +++ b/arch/riscv/kernel/Makefile @@ -28,9 +28,9 @@ KASAN_SANITIZE_cpufeature.o := n endif endif -extra-y += head.o extra-y += vmlinux.lds +obj-y += head.o obj-y += soc.o obj-$(CONFIG_RISCV_ALTERNATIVE) += alternative.o obj-y += cpu.o diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 3cbfa9fddd9a..7ce00816b8df 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -33,7 +33,7 @@ CFLAGS_stacktrace.o += -fno-optimize-sibling-calls CFLAGS_dumpstack.o += -fno-optimize-sibling-calls CFLAGS_unwind_bc.o += -fno-optimize-sibling-calls -obj-y := traps.o time.o process.o earlypgm.o early.o setup.o idle.o vtime.o +obj-y := head64.o traps.o time.o process.o earlypgm.o early.o setup.o idle.o vtime.o obj-y += processor.o syscall.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o obj-y += debug.o irq.o ipl.o dis.o diag.o vdso.o cpufeature.o obj-y += sysinfo.o lgr.o os_info.o machine_kexec.o @@ -42,7 +42,7 @@ obj-y += entry.o reipl.o relocate_kernel.o kdebugfs.o alternative.o obj-y += nospec-branch.o ipl_vmparm.o machine_kexec_reloc.o unwind_bc.o obj-y += smp.o text_amode31.o stacktrace.o -extra-y += head64.o vmlinux.lds +extra-y += vmlinux.lds obj-$(CONFIG_SYSFS) += nospec-sysfs.o CFLAGS_REMOVE_nospec-branch.o += $(CC_FLAGS_EXPOLINE) diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index aa0fbc9202b1..69cd9ac4b2ab 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -3,7 +3,7 @@ # Makefile for the Linux/SuperH kernel. # -extra-y := head_32.o vmlinux.lds +extra-y := vmlinux.lds ifdef CONFIG_FUNCTION_TRACER # Do not profile debug and lowlevel utilities @@ -12,7 +12,7 @@ endif CFLAGS_REMOVE_return_address.o = -pg -obj-y := debugtraps.o dumpstack.o \ +obj-y := head_32.o debugtraps.o dumpstack.o \ idle.o io.o irq.o irq_32.o kdebugfs.o \ machvec.o nmi_debug.o process.o \ process_32.o ptrace.o ptrace_32.o \ diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index d3a0e072ebe8..b328e4a0bd57 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -7,8 +7,6 @@ asflags-y := -ansi ccflags-y := -Werror -extra-y := head_$(BITS).o - # Undefine sparc when processing vmlinux.lds - it is used # And teach CPP we are doing $(BITS) builds (for this case) CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS) @@ -22,6 +20,7 @@ CFLAGS_REMOVE_perf_event.o := -pg CFLAGS_REMOVE_pcr.o := -pg endif +obj-y := head_$(BITS).o obj-$(CONFIG_SPARC64) += urtt_fill.o obj-$(CONFIG_SPARC32) += entry.o wof.o wuf.o obj-$(CONFIG_SPARC32) += etrap_32.o diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index a20a5ebfacd7..956e50ca06e0 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -3,10 +3,6 @@ # Makefile for the linux kernel. # -extra-y := head_$(BITS).o -extra-y += head$(BITS).o -extra-y += ebda.o -extra-y += platform-quirks.o extra-y += vmlinux.lds CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE) @@ -42,7 +38,11 @@ KCOV_INSTRUMENT := n CFLAGS_irq.o := -I $(srctree)/$(src)/../include/asm/trace -obj-y := process_$(BITS).o signal.o +obj-y += head_$(BITS).o +obj-y += head$(BITS).o +obj-y += ebda.o +obj-y += platform-quirks.o +obj-y += process_$(BITS).o signal.o obj-$(CONFIG_COMPAT) += signal_compat.o obj-y += traps.o idt.o irq.o irq_$(BITS).o dumpstack_$(BITS).o obj-y += time.o ioport.o dumpstack.o nmi.o diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile index 897c1c741058..f28b8e3d717e 100644 --- a/arch/xtensa/kernel/Makefile +++ b/arch/xtensa/kernel/Makefile @@ -3,9 +3,9 @@ # Makefile for the Linux/Xtensa kernel. # -extra-y := head.o vmlinux.lds +extra-y := vmlinux.lds -obj-y := align.o coprocessor.o entry.o irq.o platform.o process.o \ +obj-y := head.o align.o coprocessor.o entry.o irq.o platform.o process.o \ ptrace.o setup.o signal.o stacktrace.o syscall.o time.o traps.o \ vectors.o diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 40a3e9b0512b..7740ce3b29e8 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -70,13 +70,12 @@ quiet_cmd_vmlinux_objs = GEN $@ for f in $(real-prereqs); do \ case $${f} in \ *libgcc.a) ;; \ - *.a) $(AR) t $${f} ;; \ - *) echo $${f} ;; \ + *) $(AR) t $${f} ;; \ esac \ done > $@ targets += .vmlinux.objs -.vmlinux.objs: $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) FORCE +.vmlinux.objs: vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE $(call if_changed,vmlinux_objs) vmlinux.o-if-present := $(wildcard vmlinux.o) diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o index 7d531b825712..68c22879bade 100644 --- a/scripts/Makefile.vmlinux_o +++ b/scripts/Makefile.vmlinux_o @@ -18,7 +18,7 @@ quiet_cmd_gen_initcalls_lds = GEN $@ $(PERL) $(real-prereqs) > $@ .tmp_initcalls.lds: $(srctree)/scripts/generate_initcall_order.pl \ - $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) FORCE + vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE $(call if_changed,gen_initcalls_lds) targets := .tmp_initcalls.lds @@ -48,7 +48,7 @@ quiet_cmd_ld_vmlinux.o = LD $@ cmd_ld_vmlinux.o = \ $(LD) ${KBUILD_LDFLAGS} -r -o $@ \ $(addprefix -T , $(initcalls-lds)) \ - --whole-archive $(KBUILD_VMLINUX_OBJS) --no-whole-archive \ + --whole-archive vmlinux.a --no-whole-archive \ --start-group $(KBUILD_VMLINUX_LIBS) --end-group \ $(cmd_objtool) @@ -57,7 +57,7 @@ define rule_ld_vmlinux.o $(call cmd,gen_objtooldep) endef -vmlinux.o: $(initcalls-lds) $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) FORCE +vmlinux.o: $(initcalls-lds) vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE $(call if_changed_rule,ld_vmlinux.o) targets += vmlinux.o diff --git a/scripts/clang-tools/gen_compile_commands.py b/scripts/clang-tools/gen_compile_commands.py index 47da25b3ba7d..d800b2c0af97 100755 --- a/scripts/clang-tools/gen_compile_commands.py +++ b/scripts/clang-tools/gen_compile_commands.py @@ -109,20 +109,6 @@ def to_cmdfile(path): return os.path.join(dir, '.' + base + '.cmd') -def cmdfiles_for_o(obj): - """Generate the iterator of .cmd files associated with the object - - Yield the .cmd file used to build the given object - - Args: - obj: The object path - - Yields: - The path to .cmd file - """ - yield to_cmdfile(obj) - - def cmdfiles_for_a(archive, ar): """Generate the iterator of .cmd files associated with the archive. @@ -211,13 +197,10 @@ def main(): for path in paths: # If 'path' is a directory, handle all .cmd files under it. # Otherwise, handle .cmd files associated with the file. - # Most of built-in objects are linked via archives (built-in.a or lib.a) - # but some objects are linked to vmlinux directly. + # built-in objects are linked via vmlinux.a # Modules are listed in modules.order. if os.path.isdir(path): cmdfiles = cmdfiles_in_dir(path) - elif path.endswith('.o'): - cmdfiles = cmdfiles_for_o(path) elif path.endswith('.a'): cmdfiles = cmdfiles_for_a(path, ar) elif path.endswith('modules.order'): diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 6a197d8a88ac..23ac13fd9d89 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -3,17 +3,15 @@ # # link vmlinux # -# vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_OBJS) and -# $(KBUILD_VMLINUX_LIBS). Most are built-in.a files from top-level directories -# in the kernel tree, others are specified in arch/$(ARCH)/Makefile. +# vmlinux is linked from the objects in vmlinux.a and $(KBUILD_VMLINUX_LIBS). +# vmlinux.a contains objects that are linked unconditionally. # $(KBUILD_VMLINUX_LIBS) are archives which are linked conditionally # (not within --whole-archive), and do not require symbol indexes added. # # vmlinux # ^ # | -# +--< $(KBUILD_VMLINUX_OBJS) -# | +--< init/built-in.a drivers/built-in.a mm/built-in.a + more +# +--< vmlinux.a # | # +--< $(KBUILD_VMLINUX_LIBS) # | +--< lib/lib.a + more @@ -67,7 +65,7 @@ vmlinux_link() objs=vmlinux.o libs= else - objs="${KBUILD_VMLINUX_OBJS}" + objs=vmlinux.a libs="${KBUILD_VMLINUX_LIBS}" fi -- cgit v1.2.3 From ce697ccee1a8661da4e23fbe5f3d45d8d6922c20 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 25 Sep 2022 03:19:15 +0900 Subject: kbuild: remove head-y syntax Kbuild puts the objects listed in head-y at the head of vmlinux. Conventionally, we do this for head*.S, which contains the kernel entry point. A counter approach is to control the section order by the linker script. Actually, the code marked as __HEAD goes into the ".head.text" section, which is placed before the normal ".text" section. I do not know if both of them are needed. From the build system perspective, head-y is not mandatory. If you can achieve the proper code placement by the linker script only, it would be cleaner. I collected the current head-y objects into head-object-list.txt. It is a whitelist. My hope is it will be reduced in the long run. Signed-off-by: Masahiro Yamada Tested-by: Nick Desaulniers Reviewed-by: Nicolas Schier --- Documentation/kbuild/makefiles.rst | 9 ++++--- Makefile | 4 +-- arch/alpha/Makefile | 2 -- arch/arc/Makefile | 2 -- arch/arm/Makefile | 3 --- arch/arm64/Makefile | 3 --- arch/csky/Makefile | 2 -- arch/hexagon/Makefile | 2 -- arch/ia64/Makefile | 1 - arch/loongarch/Makefile | 2 -- arch/m68k/Makefile | 9 ------- arch/microblaze/Makefile | 1 - arch/mips/Makefile | 2 -- arch/nios2/Makefile | 1 - arch/openrisc/Makefile | 2 -- arch/parisc/Makefile | 2 -- arch/powerpc/Makefile | 12 --------- arch/riscv/Makefile | 2 -- arch/s390/Makefile | 2 -- arch/sh/Makefile | 2 -- arch/sparc/Makefile | 2 -- arch/x86/Makefile | 5 ---- arch/xtensa/Makefile | 2 -- scripts/head-object-list.txt | 53 ++++++++++++++++++++++++++++++++++++++ 24 files changed, 60 insertions(+), 67 deletions(-) create mode 100644 scripts/head-object-list.txt (limited to 'scripts') diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index 5a6a8426cc97..60134ddf3db1 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -1070,8 +1070,7 @@ When kbuild executes, the following steps are followed (roughly): - The values of the above variables are expanded in arch/$(SRCARCH)/Makefile. 5) All object files are then linked and the resulting file vmlinux is located at the root of the obj tree. - The very first objects linked are listed in head-y, assigned by - arch/$(SRCARCH)/Makefile. + The very first objects linked are listed in scripts/head-object-list.txt. 6) Finally, the architecture-specific part does any required post processing and builds the final bootimage. - This includes building boot records @@ -1219,6 +1218,9 @@ When kbuild executes, the following steps are followed (roughly): All object files for vmlinux. They are linked to vmlinux in the same order as listed in KBUILD_VMLINUX_OBJS. + The objects listed in scripts/head-object-list.txt are exceptions; + they are placed before the other objects. + KBUILD_VMLINUX_LIBS All .a "lib" files for vmlinux. KBUILD_VMLINUX_OBJS and @@ -1262,8 +1264,7 @@ When kbuild executes, the following steps are followed (roughly): machinery is all architecture-independent. - head-y, core-y, libs-y, drivers-y - $(head-y) lists objects to be linked first in vmlinux. + core-y, libs-y, drivers-y $(libs-y) lists directories where a lib.a archive can be located. diff --git a/Makefile b/Makefile index 8da45f76ec31..e4186c171049 100644 --- a/Makefile +++ b/Makefile @@ -1147,10 +1147,10 @@ quiet_cmd_ar_vmlinux.a = AR $@ cmd_ar_vmlinux.a = \ rm -f $@; \ $(AR) cDPrST $@ $(KBUILD_VMLINUX_OBJS); \ - $(AR) mPiT $$($(AR) t $@ | head -n1) $@ $(head-y) + $(AR) mPiT $$($(AR) t $@ | head -n1) $@ $$($(AR) t $@ | grep -F --file=$(srctree)/scripts/head-object-list.txt) targets += vmlinux.a -vmlinux.a: $(KBUILD_VMLINUX_OBJS) autoksyms_recursive FORCE +vmlinux.a: $(KBUILD_VMLINUX_OBJS) scripts/head-object-list.txt autoksyms_recursive FORCE $(call if_changed,ar_vmlinux.a) vmlinux.o: vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile index 881cb913e23a..45158024085e 100644 --- a/arch/alpha/Makefile +++ b/arch/alpha/Makefile @@ -36,8 +36,6 @@ cflags-y += $(cpuflags-y) # BWX is most important, but we don't really want any emulation ever. KBUILD_CFLAGS += $(cflags-y) -Wa,-mev6 -head-y := arch/alpha/kernel/head.o - libs-y += arch/alpha/lib/ # export what is needed by arch/alpha/boot/Makefile diff --git a/arch/arc/Makefile b/arch/arc/Makefile index efc54f3e35e0..329400a1c355 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile @@ -82,8 +82,6 @@ KBUILD_CFLAGS += $(cflags-y) KBUILD_AFLAGS += $(KBUILD_CFLAGS) KBUILD_LDFLAGS += $(ldflags-y) -head-y := arch/arc/kernel/head.o - # w/o this dtb won't embed into kernel binary core-y += arch/arc/boot/dts/ diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 56f655deebb1..29d15c9a433e 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -134,9 +134,6 @@ KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/uni CHECKFLAGS += -D__arm__ -#Default value -head-y := arch/arm/kernel/head$(MMUEXT).o - # Text offset. This list is sorted numerically by address in order to # provide a means to avoid/resolve conflicts in multi-arch kernels. # Note: the 32kB below this value is reserved for use by the kernel diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 6d9d4a58b898..6e03f15bb041 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -133,9 +133,6 @@ ifeq ($(CONFIG_DYNAMIC_FTRACE_WITH_REGS),y) CC_FLAGS_FTRACE := -fpatchable-function-entry=2 endif -# Default value -head-y := arch/arm64/kernel/head.o - ifeq ($(CONFIG_KASAN_SW_TAGS), y) KASAN_SHADOW_SCALE_SHIFT := 4 else ifeq ($(CONFIG_KASAN_GENERIC), y) diff --git a/arch/csky/Makefile b/arch/csky/Makefile index 4e1d619fd5c6..0e4237e55758 100644 --- a/arch/csky/Makefile +++ b/arch/csky/Makefile @@ -59,8 +59,6 @@ LDFLAGS += -EL KBUILD_AFLAGS += $(KBUILD_CFLAGS) -head-y := arch/csky/kernel/head.o - core-y += arch/csky/$(CSKYABI)/ libs-y += arch/csky/lib/ \ diff --git a/arch/hexagon/Makefile b/arch/hexagon/Makefile index 44312bc147d8..92d005958dfb 100644 --- a/arch/hexagon/Makefile +++ b/arch/hexagon/Makefile @@ -32,5 +32,3 @@ KBUILD_LDFLAGS += $(ldflags-y) TIR_NAME := r19 KBUILD_CFLAGS += -ffixed-$(TIR_NAME) -DTHREADINFO_REG=$(TIR_NAME) -D__linux__ KBUILD_AFLAGS += -DTHREADINFO_REG=$(TIR_NAME) - -head-y := arch/hexagon/kernel/head.o diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index e55c2f138656..56c4bb276b6e 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -44,7 +44,6 @@ quiet_cmd_objcopy = OBJCOPY $@ cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ KBUILD_CFLAGS += $(cflags-y) -head-y := arch/ia64/kernel/head.o libs-y += arch/ia64/lib/ diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile index ec3de6191276..131fc210c2bf 100644 --- a/arch/loongarch/Makefile +++ b/arch/loongarch/Makefile @@ -72,8 +72,6 @@ CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g') endif -head-y := arch/loongarch/kernel/head.o - libs-y += arch/loongarch/lib/ ifeq ($(KBUILD_EXTMOD),) diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index e358605b70ba..43e39040d3ac 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile @@ -86,15 +86,6 @@ ifdef CONFIG_KGDB KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g endif -# -# Select the assembler head startup code. Order is important. The default -# head code is first, processor specific selections can override it after. -# -head-y := arch/m68k/kernel/head.o -head-$(CONFIG_SUN3) := arch/m68k/kernel/sun3-head.o -head-$(CONFIG_M68000) := arch/m68k/68000/head.o -head-$(CONFIG_COLDFIRE) := arch/m68k/coldfire/head.o - libs-y += arch/m68k/lib/ diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile index 1826d9ce4459..3f8a86c4336a 100644 --- a/arch/microblaze/Makefile +++ b/arch/microblaze/Makefile @@ -48,7 +48,6 @@ CPUFLAGS-1 += $(call cc-option,-mcpu=v$(CPU_VER)) # r31 holds current when in kernel mode KBUILD_CFLAGS += -ffixed-r31 $(CPUFLAGS-y) $(CPUFLAGS-1) $(CPUFLAGS-2) -head-y := arch/microblaze/kernel/head.o libs-y += arch/microblaze/lib/ boot := arch/microblaze/boot diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 4d2a3e73fc45..b296e33f8e33 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -324,8 +324,6 @@ endif OBJCOPYFLAGS += --remove-section=.reginfo -head-y := arch/mips/kernel/head.o - libs-y += arch/mips/lib/ libs-$(CONFIG_MIPS_FP_SUPPORT) += arch/mips/math-emu/ diff --git a/arch/nios2/Makefile b/arch/nios2/Makefile index 3f34e6831863..f1ff4ce0f1a2 100644 --- a/arch/nios2/Makefile +++ b/arch/nios2/Makefile @@ -37,7 +37,6 @@ KBUILD_CFLAGS += -DUTS_SYSNAME=\"$(UTS_SYSNAME)\" KBUILD_CFLAGS += -fno-builtin KBUILD_CFLAGS += -G 0 -head-y := arch/nios2/kernel/head.o libs-y += arch/nios2/lib/ $(LIBGCC) INSTALL_PATH ?= /tftpboot diff --git a/arch/openrisc/Makefile b/arch/openrisc/Makefile index b446510173cd..68249521db5a 100644 --- a/arch/openrisc/Makefile +++ b/arch/openrisc/Makefile @@ -55,8 +55,6 @@ ifeq ($(CONFIG_OPENRISC_HAVE_INST_SEXT),y) KBUILD_CFLAGS += $(call cc-option,-msext) endif -head-y := arch/openrisc/kernel/head.o - libs-y += $(LIBGCC) PHONY += vmlinux.bin diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index e38d993d87f2..a2d8600521f9 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -113,8 +113,6 @@ cflags-$(CONFIG_PA7100LC) += -march=1.1 -mschedule=7100LC cflags-$(CONFIG_PA7300LC) += -march=1.1 -mschedule=7300 cflags-$(CONFIG_PA8X00) += -march=2.0 -mschedule=8000 -head-y := arch/parisc/kernel/head.o - KBUILD_CFLAGS += $(cflags-y) LIBGCC := $(shell $(CC) -print-libgcc-file-name) export LIBGCC diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 02742facf895..89c27827a11f 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -226,18 +226,6 @@ KBUILD_CFLAGS += $(cpu-as-y) KBUILD_AFLAGS += $(aflags-y) KBUILD_CFLAGS += $(cflags-y) -head-$(CONFIG_PPC64) := arch/powerpc/kernel/head_64.o -head-$(CONFIG_PPC_BOOK3S_32) := arch/powerpc/kernel/head_book3s_32.o -head-$(CONFIG_PPC_8xx) := arch/powerpc/kernel/head_8xx.o -head-$(CONFIG_40x) := arch/powerpc/kernel/head_40x.o -head-$(CONFIG_44x) := arch/powerpc/kernel/head_44x.o -head-$(CONFIG_FSL_BOOKE) := arch/powerpc/kernel/head_fsl_booke.o - -head-$(CONFIG_PPC64) += arch/powerpc/kernel/entry_64.o -head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o -head-$(CONFIG_ALTIVEC) += arch/powerpc/kernel/vector.o -head-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += arch/powerpc/kernel/prom_init.o - # Default to zImage, override when needed all: zImage diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 3fa8ef336822..e013df8e7b8b 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -110,8 +110,6 @@ else KBUILD_IMAGE := $(boot)/Image.gz endif -head-y := arch/riscv/kernel/head.o - libs-y += arch/riscv/lib/ libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 4cb5d17e7ead..de6d8b2ea4d8 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -119,8 +119,6 @@ export KBUILD_CFLAGS_DECOMPRESSOR OBJCOPYFLAGS := -O binary -head-y := arch/s390/kernel/head64.o - libs-y += arch/s390/lib/ drivers-y += drivers/s390/ diff --git a/arch/sh/Makefile b/arch/sh/Makefile index b39412bf91fb..5c8776482530 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -114,8 +114,6 @@ endif export ld-bfd -head-y := arch/sh/kernel/head_32.o - # Mach groups machdir-$(CONFIG_SOLUTION_ENGINE) += mach-se machdir-$(CONFIG_SH_HP6XX) += mach-hp6xx diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index fe58a410b4ce..a4ea5b05f288 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile @@ -56,8 +56,6 @@ endif endif -head-y := arch/sparc/kernel/head_$(BITS).o - libs-y += arch/sparc/prom/ libs-y += arch/sparc/lib/ diff --git a/arch/x86/Makefile b/arch/x86/Makefile index bafbd905e6e7..9afd323c6916 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -234,11 +234,6 @@ archheaders: ### # Kernel objects -head-y := arch/x86/kernel/head_$(BITS).o -head-y += arch/x86/kernel/head$(BITS).o -head-y += arch/x86/kernel/ebda.o -head-y += arch/x86/kernel/platform-quirks.o - libs-y += arch/x86/lib/ # drivers-y are linked after core-y diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 5097caa7bf0c..bfd8e433ed62 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -55,8 +55,6 @@ KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(vardirs) $(plfdirs)) KBUILD_DEFCONFIG := iss_defconfig -head-y := arch/xtensa/kernel/head.o - libs-y += arch/xtensa/lib/ boot := arch/xtensa/boot diff --git a/scripts/head-object-list.txt b/scripts/head-object-list.txt new file mode 100644 index 000000000000..dd2ba2eda636 --- /dev/null +++ b/scripts/head-object-list.txt @@ -0,0 +1,53 @@ +# Head objects +# +# The objects listed here are placed at the head of vmlinux. A typical use-case +# is an object that contains the entry point. This is kept for compatibility +# with head-y, which Kbuild used to support. +# +# A counter approach is to control the section placement by the linker script. +# The code marked as __HEAD goes into the ".head.text" section, which is placed +# before the normal ".text" section. +# +# If you can achieve the correct code ordering by linker script, please delete +# the entry from this file. +# +arch/alpha/kernel/head.o +arch/arc/kernel/head.o +arch/arm/kernel/head-nommu.o +arch/arm/kernel/head.o +arch/arm64/kernel/head.o +arch/csky/kernel/head.o +arch/hexagon/kernel/head.o +arch/ia64/kernel/head.o +arch/loongarch/kernel/head.o +arch/m68k/68000/head.o +arch/m68k/coldfire/head.o +arch/m68k/kernel/head.o +arch/m68k/kernel/sun3-head.o +arch/microblaze/kernel/head.o +arch/mips/kernel/head.o +arch/nios2/kernel/head.o +arch/openrisc/kernel/head.o +arch/parisc/kernel/head.o +arch/powerpc/kernel/head_40x.o +arch/powerpc/kernel/head_44x.o +arch/powerpc/kernel/head_64.o +arch/powerpc/kernel/head_8xx.o +arch/powerpc/kernel/head_book3s_32.o +arch/powerpc/kernel/head_fsl_booke.o +arch/powerpc/kernel/entry_64.o +arch/powerpc/kernel/fpu.o +arch/powerpc/kernel/vector.o +arch/powerpc/kernel/prom_init.o +arch/riscv/kernel/head.o +arch/s390/kernel/head64.o +arch/sh/kernel/head_32.o +arch/sparc/kernel/head_32.o +arch/sparc/kernel/head_64.o +arch/x86/kernel/head_32.o +arch/x86/kernel/head_64.o +arch/x86/kernel/head32.o +arch/x86/kernel/head64.o +arch/x86/kernel/ebda.o +arch/x86/kernel/platform-quirks.o +arch/xtensa/kernel/head.o -- cgit v1.2.3 From c13461693ea21d787f82232ce3a5667da370d973 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 26 Sep 2022 18:02:25 +0900 Subject: mksysmap: update comment about __crc_* Since commit 7b4537199a4a ("kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS"), __crc_* symbols never become absolute. Keep ignoring __crc_*, but update the comment. Signed-off-by: Masahiro Yamada --- scripts/mksysmap | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/mksysmap b/scripts/mksysmap index ad8bbc52267d..bc5396e255d8 100755 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -37,8 +37,8 @@ # 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'. __crc_ are 'A' and placed in the middle -# so we just ignore them to let readprofile continue to work. -# (At least sparc64 has __crc_ in the middle). - +# 'W' or 'w'. +# +# Ignored prefixes: +# __crc_ - modversions $NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)\|\( \.L\)\|\( L0\)' > $2 -- cgit v1.2.3 From 94ff2f63d6a31501ceb36ebc600240937cfff35f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 26 Sep 2022 18:02:26 +0900 Subject: kbuild: reuse mksysmap output for kallsyms scripts/mksysmap internally runs ${NM} (dropping some symbols). When CONFIG_KALLSYMS=y, mksysmap creates .tmp_System.map, but it is almost the same as the output from the ${NM} invocation in kallsyms(). It is true scripts/mksysmap drops some symbols, but scripts/kallsyms.c ignores more anyway. Keep the mksysmap output as *.syms, and reuse it for kallsyms and 'cmp -s'. It saves one ${NM} invocation. Signed-off-by: Masahiro Yamada --- scripts/link-vmlinux.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 23ac13fd9d89..6492c0862657 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -157,7 +157,7 @@ kallsyms() fi info KSYMS ${2} - ${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${2} + cat ${1} | scripts/kallsyms ${kallsymopt} > ${2} } # Perform one step in kallsyms generation, including temporary linking of @@ -170,7 +170,8 @@ kallsyms_step() kallsyms_S=${kallsyms_vmlinux}.S vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o} - kallsyms ${kallsyms_vmlinux} ${kallsyms_S} + mksysmap ${kallsyms_vmlinux} ${kallsyms_vmlinux}.syms + kallsyms ${kallsyms_vmlinux}.syms ${kallsyms_S} info AS ${kallsyms_S} ${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} \ @@ -182,6 +183,7 @@ kallsyms_step() # See mksymap for additional details mksysmap() { + info NM ${2} ${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2} } @@ -283,7 +285,6 @@ if is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then ${RESOLVE_BTFIDS} vmlinux fi -info SYSMAP System.map mksysmap vmlinux System.map if is_enabled CONFIG_BUILDTIME_TABLE_SORT; then @@ -296,9 +297,7 @@ fi # step a (see comment above) if is_enabled CONFIG_KALLSYMS; then - mksysmap ${kallsyms_vmlinux} .tmp_System.map - - if ! cmp -s System.map .tmp_System.map; 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 exit 1 -- cgit v1.2.3 From a2833d1b07ab107db71a18e6f3855f6908886361 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 26 Sep 2022 18:02:27 +0900 Subject: kallsyms: drop duplicated ignore patterns from kallsyms.c Now that kallsyms.c parses the output from mksysmap, some symbols have already been dropped. Move comments to scripts/mksysmap. Also, make the grep command readable. Signed-off-by: Masahiro Yamada --- scripts/kallsyms.c | 3 --- scripts/mksysmap | 14 +++++++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index f18e6dfc68c5..313cc8161123 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -107,9 +107,6 @@ static bool is_ignored_symbol(const char *name, char type) /* Symbol names that begin with the following are ignored.*/ static const char * const ignored_prefixes[] = { - "$", /* local symbols for ARM, MIPS, etc. */ - ".L", /* local labels, .LBB,.Ltmpxxx,.L__unnamed_xx,.LASANPC, etc. */ - "__crc_", /* modversions */ "__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 */ diff --git a/scripts/mksysmap b/scripts/mksysmap index bc5396e255d8..75f3dfd1c156 100755 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -40,5 +40,17 @@ # 'W' or 'w'. # # Ignored prefixes: +# $ - local symbols for ARM, MIPS, etc. +# .L - local labels, .LBB,.Ltmpxxx,.L__unnamed_xx,.LASANPC, etc. # __crc_ - modversions -$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)\|\( \.L\)\|\( L0\)' > $2 +# +# Ignored symbols: +# L0 - for LoongArch? + +$NM -n $1 | grep -v \ + -e ' [aNUw] ' \ + -e ' \$' \ + -e ' \.L' \ + -e ' __crc_' \ + -e ' L0$' \ +> $2 -- cgit v1.2.3 From aa221f2ea58655f5360e7b0c6fe5482f7c41855e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 26 Sep 2022 18:02:28 +0900 Subject: kallsyms: take the input file instead of reading stdin This gets rid of the pipe operator connected with 'cat'. Also use getopt_long() to parse the command line. Signed-off-by: Masahiro Yamada --- scripts/kallsyms.c | 51 ++++++++++++++++++++++++++++++++----------------- scripts/link-vmlinux.sh | 2 +- 2 files changed, 34 insertions(+), 19 deletions(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 313cc8161123..5b091625d4c5 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -18,6 +18,7 @@ * */ +#include #include #include #include @@ -71,7 +72,7 @@ static unsigned char best_table_len[256]; static void usage(void) { fprintf(stderr, "Usage: kallsyms [--all-symbols] [--absolute-percpu] " - "[--base-relative] < in.map > out.S\n"); + "[--base-relative] in.map > out.S\n"); exit(1); } @@ -310,12 +311,19 @@ static void shrink_table(void) } } -static void read_map(FILE *in) +static void read_map(const char *in) { + FILE *fp; struct sym_entry *sym; - while (!feof(in)) { - sym = read_symbol(in); + fp = fopen(in, "r"); + if (!fp) { + perror(in); + exit(1); + } + + while (!feof(fp)) { + sym = read_symbol(fp); if (!sym) continue; @@ -326,12 +334,15 @@ static void read_map(FILE *in) table = realloc(table, sizeof(*table) * table_size); if (!table) { fprintf(stderr, "out of memory\n"); + fclose(fp); exit (1); } } table[table_cnt++] = sym; } + + fclose(fp); } static void output_label(const char *label) @@ -762,22 +773,26 @@ static void record_relative_base(void) int main(int argc, char **argv) { - if (argc >= 2) { - int i; - for (i = 1; i < argc; i++) { - if(strcmp(argv[i], "--all-symbols") == 0) - all_symbols = 1; - else if (strcmp(argv[i], "--absolute-percpu") == 0) - absolute_percpu = 1; - else if (strcmp(argv[i], "--base-relative") == 0) - base_relative = 1; - else - usage(); - } - } else if (argc != 1) + while (1) { + static struct option long_options[] = { + {"all-symbols", no_argument, &all_symbols, 1}, + {"absolute-percpu", no_argument, &absolute_percpu, 1}, + {"base-relative", no_argument, &base_relative, 1}, + {}, + }; + + int c = getopt_long(argc, argv, "", long_options, NULL); + + if (c == -1) + break; + if (c != 0) + usage(); + } + + if (optind >= argc) usage(); - read_map(stdin); + read_map(argv[optind]); shrink_table(); if (absolute_percpu) make_percpus_absolute(); diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 6492c0862657..2782c5d1518b 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -157,7 +157,7 @@ kallsyms() fi info KSYMS ${2} - cat ${1} | scripts/kallsyms ${kallsymopt} > ${2} + scripts/kallsyms ${kallsymopt} ${1} > ${2} } # Perform one step in kallsyms generation, including temporary linking of -- cgit v1.2.3 From d32b55f4bb43466bc6cdd98a00f8a600bbf7e8ec Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 26 Sep 2022 18:02:29 +0900 Subject: kallsyms: ignore __kstrtab_* and __kstrtabns_* symbols Every EXPORT_SYMBOL creates __kstrtab_* and __kstrtabns_*, which consumes 15-20% of the kallsyms entries. For example, on the system built from the x86_64 defconfig, $ cat /proc/kallsyms | wc 129527 388581 5685465 $ cat /proc/kallsyms | grep __kstrtab | wc 23489 70467 1187932 We already ignore __crc_* symbols populated by EXPORT_SYMBOL, so it should be fine to ignore __kstrtab_* and __kstrtabns_* as well. This makes vmlinux a bit smaller. $ size vmlinux.before vmlinux.after text data bss dec hex filename 22785374 8559694 1413328 32758396 1f3da7c vmlinux.before 22785374 8137806 1413328 32336508 1ed6a7c vmlinux.after Signed-off-by: Masahiro Yamada --- scripts/mksysmap | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'scripts') diff --git a/scripts/mksysmap b/scripts/mksysmap index 75f3dfd1c156..16a08b8ef2f8 100755 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -43,6 +43,8 @@ # $ - 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) # # Ignored symbols: # L0 - for LoongArch? @@ -52,5 +54,7 @@ $NM -n $1 | grep -v \ -e ' \$' \ -e ' \.L' \ -e ' __crc_' \ + -e ' __kstrtab_' \ + -e ' __kstrtabns_' \ -e ' L0$' \ > $2 -- cgit v1.2.3 From 7a342e6c7735e13b294374cb0a0f6283d8667496 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 28 Sep 2022 15:39:40 +0900 Subject: kbuild: move modules.builtin(.modinfo) rules to Makefile.vmlinux_o Do not build modules.builtin(.modinfo) as a side-effect of vmlinux. There are no good reason to rebuild them just because any of vmlinux's prerequistes (vmlinux.lds, .vmlinux.export.c, etc.) has been updated. Signed-off-by: Masahiro Yamada --- Makefile | 6 +++++- scripts/Makefile.vmlinux_o | 26 +++++++++++++++++++++++++- scripts/link-vmlinux.sh | 7 ------- 3 files changed, 30 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index e4186c171049..2fcbd753cb27 100644 --- a/Makefile +++ b/Makefile @@ -1153,9 +1153,13 @@ targets += vmlinux.a vmlinux.a: $(KBUILD_VMLINUX_OBJS) scripts/head-object-list.txt autoksyms_recursive FORCE $(call if_changed,ar_vmlinux.a) -vmlinux.o: vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE +PHONY += vmlinux_o +vmlinux_o: vmlinux.a $(KBUILD_VMLINUX_LIBS) $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.vmlinux_o +vmlinux.o modules.builtin.modinfo modules.builtin: vmlinux_o + @: + ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) # Final link of vmlinux with optional arch pass after final link diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o index 68c22879bade..0edfdb40364b 100644 --- a/scripts/Makefile.vmlinux_o +++ b/scripts/Makefile.vmlinux_o @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only PHONY := __default -__default: vmlinux.o +__default: vmlinux.o modules.builtin.modinfo modules.builtin include include/config/auto.conf include $(srctree)/scripts/Kbuild.include @@ -62,6 +62,30 @@ vmlinux.o: $(initcalls-lds) vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE targets += vmlinux.o +# module.builtin.modinfo +# --------------------------------------------------------------------------- + +OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary + +targets += modules.builtin.modinfo +modules.builtin.modinfo: vmlinux.o FORCE + $(call if_changed,objcopy) + +# module.builtin +# --------------------------------------------------------------------------- + +# The second line aids cases where multiple modules share the same object. + +quiet_cmd_modules_builtin = GEN $@ + cmd_modules_builtin = \ + tr '\0' '\n' < $< | \ + sed -n 's/^[[:alnum:]:_]*\.file=//p' | \ + tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$$/.ko/' > $@ + +targets += modules.builtin +modules.builtin: modules.builtin.modinfo FORCE + $(call if_changed,modules_builtin) + # Add FORCE to the prequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 2782c5d1518b..e3d42202e54c 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -214,13 +214,6 @@ if [ "$1" = "clean" ]; then exit 0 fi -info MODINFO modules.builtin.modinfo -${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo -info GEN modules.builtin -# The second line aids cases where multiple modules share the same object. -tr '\0' '\n' < modules.builtin.modinfo | sed -n 's/^[[:alnum:]:_]*\.file=//p' | - tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$/.ko/' > modules.builtin - if is_enabled CONFIG_MODULES; then ${MAKE} -f "${srctree}/scripts/Makefile.vmlinux" .vmlinux.export.o fi -- cgit v1.2.3 From 5d4aeffbf7092b6bd7b2de71c2cd6fa14dffbad5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 28 Sep 2022 15:39:41 +0900 Subject: kbuild: rebuild .vmlinux.export.o when its prerequisite is updated When include/linux/export-internal.h is updated, .vmlinux.export.o must be rebuilt, but it does not happen because its rule is hidden behind scripts/link-vmlinux.sh. Move it out of the shell script, so that Make can see the dependency between vmlinux and .vmlinux.export.o. Move the vmlinux rule to scripts/Makefile.vmlinux. Signed-off-by: Masahiro Yamada --- Makefile | 18 +++++------------- scripts/Makefile.vmlinux | 21 ++++++++++++++++++++- scripts/link-vmlinux.sh | 5 ----- 3 files changed, 25 insertions(+), 19 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 2fcbd753cb27..f10a27c09d88 100644 --- a/Makefile +++ b/Makefile @@ -502,7 +502,7 @@ AFLAGS_MODULE = LDFLAGS_MODULE = CFLAGS_KERNEL = AFLAGS_KERNEL = -LDFLAGS_vmlinux = +export LDFLAGS_vmlinux = # Use USERINCLUDE when you must reference the UAPI directories only. USERINCLUDE := \ @@ -1160,17 +1160,9 @@ vmlinux_o: vmlinux.a $(KBUILD_VMLINUX_LIBS) vmlinux.o modules.builtin.modinfo modules.builtin: vmlinux_o @: -ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) - -# Final link of vmlinux with optional arch pass after final link -cmd_link-vmlinux = \ - $(CONFIG_SHELL) $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)"; \ - $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) - -vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) modpost FORCE - +$(call if_changed_dep,link-vmlinux) - -targets += vmlinux +PHONY += vmlinux +vmlinux: vmlinux.o $(KBUILD_LDS) modpost + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.vmlinux # The actual objects are generated when descending, # make sure no implicit rule kicks in @@ -1501,7 +1493,7 @@ endif # CONFIG_MODULES # Directories & files removed with 'make clean' CLEAN_FILES += include/ksym vmlinux.symvers modules-only.symvers \ modules.builtin modules.builtin.modinfo modules.nsdeps \ - compile_commands.json .thinlto-cache .vmlinux.objs + compile_commands.json .thinlto-cache .vmlinux.objs .vmlinux.export.c # Directories & files removed with 'make mrproper' MRPROPER_FILES += include/config include/generated \ diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index 7a63abf22399..49946cb96844 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -1,18 +1,37 @@ # SPDX-License-Identifier: GPL-2.0-only +PHONY := __default +__default: vmlinux + include include/config/auto.conf include $(srctree)/scripts/Kbuild.include # for c_flags include $(srctree)/scripts/Makefile.lib +targets := + quiet_cmd_cc_o_c = CC $@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< %.o: %.c FORCE $(call if_changed_dep,cc_o_c) -targets := $(MAKECMDGOALS) +ifdef CONFIG_MODULES +targets += .vmlinux.export.o +vmlinux: .vmlinux.export.o +endif + +ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) + +# Final link of vmlinux with optional arch pass after final link +cmd_link_vmlinux = \ + $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)"; \ + $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) + +targets += vmlinux +vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE + +$(call if_changed_dep,link_vmlinux) # Add FORCE to the prequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index e3d42202e54c..918470d768e9 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -199,7 +199,6 @@ cleanup() rm -f System.map rm -f vmlinux rm -f vmlinux.map - rm -f .vmlinux.export.c } # Use "make V=1" to debug this script @@ -214,10 +213,6 @@ if [ "$1" = "clean" ]; then exit 0 fi -if is_enabled CONFIG_MODULES; then - ${MAKE} -f "${srctree}/scripts/Makefile.vmlinux" .vmlinux.export.o -fi - ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init init/version-timestamp.o btf_vmlinux_bin_o="" -- cgit v1.2.3 From f80be4571b19b9fd8dd1528cd2a2f123aff51f70 Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Thu, 15 Sep 2022 17:03:45 +0200 Subject: kmsan: add KMSAN runtime core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For each memory location KernelMemorySanitizer maintains two types of metadata: 1. The so-called shadow of that location - а byte:byte mapping describing whether or not individual bits of memory are initialized (shadow is 0) or not (shadow is 1). 2. The origins of that location - а 4-byte:4-byte mapping containing 4-byte IDs of the stack traces where uninitialized values were created. Each struct page now contains pointers to two struct pages holding KMSAN metadata (shadow and origins) for the original struct page. Utility routines in mm/kmsan/core.c and mm/kmsan/shadow.c handle the metadata creation, addressing, copying and checking. mm/kmsan/report.c performs error reporting in the cases an uninitialized value is used in a way that leads to undefined behavior. KMSAN compiler instrumentation is responsible for tracking the metadata along with the kernel memory. mm/kmsan/instrumentation.c provides the implementation for instrumentation hooks that are called from files compiled with -fsanitize=kernel-memory. To aid parameter passing (also done at instrumentation level), each task_struct now contains a struct kmsan_task_state used to track the metadata of function parameters and return values for that task. Finally, this patch provides CONFIG_KMSAN that enables KMSAN, and declares CFLAGS_KMSAN, which are applied to files compiled with KMSAN. The KMSAN_SANITIZE:=n Makefile directive can be used to completely disable KMSAN instrumentation for certain files. Similarly, KMSAN_ENABLE_CHECKS:=n disables KMSAN checks and makes newly created stack memory initialized. Users can also use functions from include/linux/kmsan-checks.h to mark certain memory regions as uninitialized or initialized (this is called "poisoning" and "unpoisoning") or check that a particular region is initialized. Link: https://lkml.kernel.org/r/20220915150417.722975-12-glider@google.com Signed-off-by: Alexander Potapenko Acked-by: Marco Elver Cc: Alexander Viro Cc: Alexei Starovoitov Cc: Andrey Konovalov Cc: Andrey Konovalov Cc: Andy Lutomirski Cc: Arnd Bergmann Cc: Borislav Petkov Cc: Christoph Hellwig Cc: Christoph Lameter Cc: David Rientjes Cc: Dmitry Vyukov Cc: Eric Biggers Cc: Eric Biggers Cc: Eric Dumazet Cc: Greg Kroah-Hartman Cc: Herbert Xu Cc: Ilya Leoshkevich Cc: Ingo Molnar Cc: Jens Axboe Cc: Joonsoo Kim Cc: Kees Cook Cc: Mark Rutland Cc: Matthew Wilcox Cc: Michael S. Tsirkin Cc: Pekka Enberg Cc: Peter Zijlstra Cc: Petr Mladek Cc: Stephen Rothwell Cc: Steven Rostedt Cc: Thomas Gleixner Cc: Vasily Gorbik Cc: Vegard Nossum Cc: Vlastimil Babka Signed-off-by: Andrew Morton --- Makefile | 1 + include/linux/kmsan-checks.h | 64 +++++++ include/linux/kmsan_types.h | 35 ++++ include/linux/mm_types.h | 12 ++ include/linux/sched.h | 5 + lib/Kconfig.debug | 1 + lib/Kconfig.kmsan | 50 +++++ mm/Makefile | 1 + mm/kmsan/Makefile | 23 +++ mm/kmsan/core.c | 440 +++++++++++++++++++++++++++++++++++++++++++ mm/kmsan/hooks.c | 66 +++++++ mm/kmsan/instrumentation.c | 307 ++++++++++++++++++++++++++++++ mm/kmsan/kmsan.h | 204 ++++++++++++++++++++ mm/kmsan/report.c | 219 +++++++++++++++++++++ mm/kmsan/shadow.c | 147 +++++++++++++++ scripts/Makefile.kmsan | 8 + scripts/Makefile.lib | 9 + 17 files changed, 1592 insertions(+) create mode 100644 include/linux/kmsan-checks.h create mode 100644 include/linux/kmsan_types.h create mode 100644 lib/Kconfig.kmsan create mode 100644 mm/kmsan/Makefile create mode 100644 mm/kmsan/core.c create mode 100644 mm/kmsan/hooks.c create mode 100644 mm/kmsan/instrumentation.c create mode 100644 mm/kmsan/kmsan.h create mode 100644 mm/kmsan/report.c create mode 100644 mm/kmsan/shadow.c create mode 100644 scripts/Makefile.kmsan (limited to 'scripts') diff --git a/Makefile b/Makefile index 952d354069a4..c9f37d25ea63 100644 --- a/Makefile +++ b/Makefile @@ -1015,6 +1015,7 @@ include-y := scripts/Makefile.extrawarn include-$(CONFIG_DEBUG_INFO) += scripts/Makefile.debug include-$(CONFIG_KASAN) += scripts/Makefile.kasan include-$(CONFIG_KCSAN) += scripts/Makefile.kcsan +include-$(CONFIG_KMSAN) += scripts/Makefile.kmsan include-$(CONFIG_UBSAN) += scripts/Makefile.ubsan include-$(CONFIG_KCOV) += scripts/Makefile.kcov include-$(CONFIG_RANDSTRUCT) += scripts/Makefile.randstruct diff --git a/include/linux/kmsan-checks.h b/include/linux/kmsan-checks.h new file mode 100644 index 000000000000..a6522a0c28df --- /dev/null +++ b/include/linux/kmsan-checks.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * KMSAN checks to be used for one-off annotations in subsystems. + * + * Copyright (C) 2017-2022 Google LLC + * Author: Alexander Potapenko + * + */ + +#ifndef _LINUX_KMSAN_CHECKS_H +#define _LINUX_KMSAN_CHECKS_H + +#include + +#ifdef CONFIG_KMSAN + +/** + * kmsan_poison_memory() - Mark the memory range as uninitialized. + * @address: address to start with. + * @size: size of buffer to poison. + * @flags: GFP flags for allocations done by this function. + * + * Until other data is written to this range, KMSAN will treat it as + * uninitialized. Error reports for this memory will reference the call site of + * kmsan_poison_memory() as origin. + */ +void kmsan_poison_memory(const void *address, size_t size, gfp_t flags); + +/** + * kmsan_unpoison_memory() - Mark the memory range as initialized. + * @address: address to start with. + * @size: size of buffer to unpoison. + * + * Until other data is written to this range, KMSAN will treat it as + * initialized. + */ +void kmsan_unpoison_memory(const void *address, size_t size); + +/** + * kmsan_check_memory() - Check the memory range for being initialized. + * @address: address to start with. + * @size: size of buffer to check. + * + * If any piece of the given range is marked as uninitialized, KMSAN will report + * an error. + */ +void kmsan_check_memory(const void *address, size_t size); + +#else + +static inline void kmsan_poison_memory(const void *address, size_t size, + gfp_t flags) +{ +} +static inline void kmsan_unpoison_memory(const void *address, size_t size) +{ +} +static inline void kmsan_check_memory(const void *address, size_t size) +{ +} + +#endif + +#endif /* _LINUX_KMSAN_CHECKS_H */ diff --git a/include/linux/kmsan_types.h b/include/linux/kmsan_types.h new file mode 100644 index 000000000000..8bfa6c98176d --- /dev/null +++ b/include/linux/kmsan_types.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * A minimal header declaring types added by KMSAN to existing kernel structs. + * + * Copyright (C) 2017-2022 Google LLC + * Author: Alexander Potapenko + * + */ +#ifndef _LINUX_KMSAN_TYPES_H +#define _LINUX_KMSAN_TYPES_H + +/* These constants are defined in the MSan LLVM instrumentation pass. */ +#define KMSAN_RETVAL_SIZE 800 +#define KMSAN_PARAM_SIZE 800 + +struct kmsan_context_state { + char param_tls[KMSAN_PARAM_SIZE]; + char retval_tls[KMSAN_RETVAL_SIZE]; + char va_arg_tls[KMSAN_PARAM_SIZE]; + char va_arg_origin_tls[KMSAN_PARAM_SIZE]; + u64 va_arg_overflow_size_tls; + char param_origin_tls[KMSAN_PARAM_SIZE]; + u32 retval_origin_tls; +}; + +#undef KMSAN_PARAM_SIZE +#undef KMSAN_RETVAL_SIZE + +struct kmsan_ctx { + struct kmsan_context_state cstate; + int kmsan_in_runtime; + bool allow_reporting; +}; + +#endif /* _LINUX_KMSAN_TYPES_H */ diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 5c87d0f292a2..500e536796ca 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -224,6 +224,18 @@ struct page { not kmapped, ie. highmem) */ #endif /* WANT_PAGE_VIRTUAL */ +#ifdef CONFIG_KMSAN + /* + * KMSAN metadata for this page: + * - shadow page: every bit indicates whether the corresponding + * bit of the original page is initialized (0) or not (1); + * - origin page: every 4 bytes contain an id of the stack trace + * where the uninitialized value was created. + */ + struct page *kmsan_shadow; + struct page *kmsan_origin; +#endif + #ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS int _last_cpupid; #endif diff --git a/include/linux/sched.h b/include/linux/sched.h index fbac3c19fe35..88a043f7235e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -1362,6 +1363,10 @@ struct task_struct { #endif #endif +#ifdef CONFIG_KMSAN + struct kmsan_ctx kmsan_ctx; +#endif + #if IS_ENABLED(CONFIG_KUNIT) struct kunit *kunit_test; #endif diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 6d1544d9201e..0129bee7de01 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -970,6 +970,7 @@ config DEBUG_STACKOVERFLOW source "lib/Kconfig.kasan" source "lib/Kconfig.kfence" +source "lib/Kconfig.kmsan" endmenu # "Memory Debugging" diff --git a/lib/Kconfig.kmsan b/lib/Kconfig.kmsan new file mode 100644 index 000000000000..5b19dbd34d76 --- /dev/null +++ b/lib/Kconfig.kmsan @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: GPL-2.0-only +config HAVE_ARCH_KMSAN + bool + +config HAVE_KMSAN_COMPILER + # Clang versions <14.0.0 also support -fsanitize=kernel-memory, but not + # all the features necessary to build the kernel with KMSAN. + depends on CC_IS_CLANG && CLANG_VERSION >= 140000 + def_bool $(cc-option,-fsanitize=kernel-memory -mllvm -msan-disable-checks=1) + +config KMSAN + bool "KMSAN: detector of uninitialized values use" + depends on HAVE_ARCH_KMSAN && HAVE_KMSAN_COMPILER + depends on SLUB && DEBUG_KERNEL && !KASAN && !KCSAN + select STACKDEPOT + select STACKDEPOT_ALWAYS_INIT + help + KernelMemorySanitizer (KMSAN) is a dynamic detector of uses of + uninitialized values in the kernel. It is based on compiler + instrumentation provided by Clang and thus requires Clang to build. + + An important note is that KMSAN is not intended for production use, + because it drastically increases kernel memory footprint and slows + the whole system down. + + See for more details. + +if KMSAN + +config HAVE_KMSAN_PARAM_RETVAL + # -fsanitize-memory-param-retval is supported only by Clang >= 14. + depends on HAVE_KMSAN_COMPILER + def_bool $(cc-option,-fsanitize=kernel-memory -fsanitize-memory-param-retval) + +config KMSAN_CHECK_PARAM_RETVAL + bool "Check for uninitialized values passed to and returned from functions" + default y + depends on HAVE_KMSAN_PARAM_RETVAL + help + If the compiler supports -fsanitize-memory-param-retval, KMSAN will + eagerly check every function parameter passed by value and every + function return value. + + Disabling KMSAN_CHECK_PARAM_RETVAL will result in tracking shadow for + function parameters and return values across function borders. This + is a more relaxed mode, but it generates more instrumentation code and + may potentially report errors in corner cases when non-instrumented + functions call instrumented ones. + +endif diff --git a/mm/Makefile b/mm/Makefile index a731d1decbb1..cc23b0052584 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -89,6 +89,7 @@ obj-$(CONFIG_SLAB) += slab.o obj-$(CONFIG_SLUB) += slub.o obj-$(CONFIG_KASAN) += kasan/ obj-$(CONFIG_KFENCE) += kfence/ +obj-$(CONFIG_KMSAN) += kmsan/ obj-$(CONFIG_FAILSLAB) += failslab.o obj-$(CONFIG_MEMTEST) += memtest.o obj-$(CONFIG_MIGRATION) += migrate.o diff --git a/mm/kmsan/Makefile b/mm/kmsan/Makefile new file mode 100644 index 000000000000..550ad8625e4f --- /dev/null +++ b/mm/kmsan/Makefile @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for KernelMemorySanitizer (KMSAN). +# +# +obj-y := core.o instrumentation.o hooks.o report.o shadow.o + +KMSAN_SANITIZE := n +KCOV_INSTRUMENT := n +UBSAN_SANITIZE := n + +# Disable instrumentation of KMSAN runtime with other tools. +CC_FLAGS_KMSAN_RUNTIME := -fno-stack-protector +CC_FLAGS_KMSAN_RUNTIME += $(call cc-option,-fno-conserve-stack) +CC_FLAGS_KMSAN_RUNTIME += -DDISABLE_BRANCH_PROFILING + +CFLAGS_REMOVE.o = $(CC_FLAGS_FTRACE) + +CFLAGS_core.o := $(CC_FLAGS_KMSAN_RUNTIME) +CFLAGS_hooks.o := $(CC_FLAGS_KMSAN_RUNTIME) +CFLAGS_instrumentation.o := $(CC_FLAGS_KMSAN_RUNTIME) +CFLAGS_report.o := $(CC_FLAGS_KMSAN_RUNTIME) +CFLAGS_shadow.o := $(CC_FLAGS_KMSAN_RUNTIME) diff --git a/mm/kmsan/core.c b/mm/kmsan/core.c new file mode 100644 index 000000000000..5330138fda5b --- /dev/null +++ b/mm/kmsan/core.c @@ -0,0 +1,440 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KMSAN runtime library. + * + * Copyright (C) 2017-2022 Google LLC + * Author: Alexander Potapenko + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../slab.h" +#include "kmsan.h" + +bool kmsan_enabled __read_mostly; + +/* + * Per-CPU KMSAN context to be used in interrupts, where current->kmsan is + * unavaliable. + */ +DEFINE_PER_CPU(struct kmsan_ctx, kmsan_percpu_ctx); + +void kmsan_internal_poison_memory(void *address, size_t size, gfp_t flags, + unsigned int poison_flags) +{ + u32 extra_bits = + kmsan_extra_bits(/*depth*/ 0, poison_flags & KMSAN_POISON_FREE); + bool checked = poison_flags & KMSAN_POISON_CHECK; + depot_stack_handle_t handle; + + handle = kmsan_save_stack_with_flags(flags, extra_bits); + kmsan_internal_set_shadow_origin(address, size, -1, handle, checked); +} + +void kmsan_internal_unpoison_memory(void *address, size_t size, bool checked) +{ + kmsan_internal_set_shadow_origin(address, size, 0, 0, checked); +} + +depot_stack_handle_t kmsan_save_stack_with_flags(gfp_t flags, + unsigned int extra) +{ + unsigned long entries[KMSAN_STACK_DEPTH]; + unsigned int nr_entries; + + nr_entries = stack_trace_save(entries, KMSAN_STACK_DEPTH, 0); + + /* Don't sleep (see might_sleep_if() in __alloc_pages_nodemask()). */ + flags &= ~__GFP_DIRECT_RECLAIM; + + return __stack_depot_save(entries, nr_entries, extra, flags, true); +} + +/* Copy the metadata following the memmove() behavior. */ +void kmsan_internal_memmove_metadata(void *dst, void *src, size_t n) +{ + depot_stack_handle_t old_origin = 0, new_origin = 0; + int src_slots, dst_slots, i, iter, step, skip_bits; + depot_stack_handle_t *origin_src, *origin_dst; + void *shadow_src, *shadow_dst; + u32 *align_shadow_src, shadow; + bool backwards; + + shadow_dst = kmsan_get_metadata(dst, KMSAN_META_SHADOW); + if (!shadow_dst) + return; + KMSAN_WARN_ON(!kmsan_metadata_is_contiguous(dst, n)); + + shadow_src = kmsan_get_metadata(src, KMSAN_META_SHADOW); + if (!shadow_src) { + /* + * @src is untracked: zero out destination shadow, ignore the + * origins, we're done. + */ + __memset(shadow_dst, 0, n); + return; + } + KMSAN_WARN_ON(!kmsan_metadata_is_contiguous(src, n)); + + __memmove(shadow_dst, shadow_src, n); + + origin_dst = kmsan_get_metadata(dst, KMSAN_META_ORIGIN); + origin_src = kmsan_get_metadata(src, KMSAN_META_ORIGIN); + KMSAN_WARN_ON(!origin_dst || !origin_src); + src_slots = (ALIGN((u64)src + n, KMSAN_ORIGIN_SIZE) - + ALIGN_DOWN((u64)src, KMSAN_ORIGIN_SIZE)) / + KMSAN_ORIGIN_SIZE; + dst_slots = (ALIGN((u64)dst + n, KMSAN_ORIGIN_SIZE) - + ALIGN_DOWN((u64)dst, KMSAN_ORIGIN_SIZE)) / + KMSAN_ORIGIN_SIZE; + KMSAN_WARN_ON((src_slots < 1) || (dst_slots < 1)); + KMSAN_WARN_ON((src_slots - dst_slots > 1) || + (dst_slots - src_slots < -1)); + + backwards = dst > src; + i = backwards ? min(src_slots, dst_slots) - 1 : 0; + iter = backwards ? -1 : 1; + + align_shadow_src = + (u32 *)ALIGN_DOWN((u64)shadow_src, KMSAN_ORIGIN_SIZE); + for (step = 0; step < min(src_slots, dst_slots); step++, i += iter) { + KMSAN_WARN_ON(i < 0); + shadow = align_shadow_src[i]; + if (i == 0) { + /* + * If @src isn't aligned on KMSAN_ORIGIN_SIZE, don't + * look at the first @src % KMSAN_ORIGIN_SIZE bytes + * of the first shadow slot. + */ + skip_bits = ((u64)src % KMSAN_ORIGIN_SIZE) * 8; + shadow = (shadow >> skip_bits) << skip_bits; + } + if (i == src_slots - 1) { + /* + * If @src + n isn't aligned on + * KMSAN_ORIGIN_SIZE, don't look at the last + * (@src + n) % KMSAN_ORIGIN_SIZE bytes of the + * last shadow slot. + */ + skip_bits = (((u64)src + n) % KMSAN_ORIGIN_SIZE) * 8; + shadow = (shadow << skip_bits) >> skip_bits; + } + /* + * Overwrite the origin only if the corresponding + * shadow is nonempty. + */ + if (origin_src[i] && (origin_src[i] != old_origin) && shadow) { + old_origin = origin_src[i]; + new_origin = kmsan_internal_chain_origin(old_origin); + /* + * kmsan_internal_chain_origin() may return + * NULL, but we don't want to lose the previous + * origin value. + */ + if (!new_origin) + new_origin = old_origin; + } + if (shadow) + origin_dst[i] = new_origin; + else + origin_dst[i] = 0; + } + /* + * If dst_slots is greater than src_slots (i.e. + * dst_slots == src_slots + 1), there is an extra origin slot at the + * beginning or end of the destination buffer, for which we take the + * origin from the previous slot. + * This is only done if the part of the source shadow corresponding to + * slot is non-zero. + * + * E.g. if we copy 8 aligned bytes that are marked as uninitialized + * and have origins o111 and o222, to an unaligned buffer with offset 1, + * these two origins are copied to three origin slots, so one of then + * needs to be duplicated, depending on the copy direction (@backwards) + * + * src shadow: |uuuu|uuuu|....| + * src origin: |o111|o222|....| + * + * backwards = 0: + * dst shadow: |.uuu|uuuu|u...| + * dst origin: |....|o111|o222| - fill the empty slot with o111 + * backwards = 1: + * dst shadow: |.uuu|uuuu|u...| + * dst origin: |o111|o222|....| - fill the empty slot with o222 + */ + if (src_slots < dst_slots) { + if (backwards) { + shadow = align_shadow_src[src_slots - 1]; + skip_bits = (((u64)dst + n) % KMSAN_ORIGIN_SIZE) * 8; + shadow = (shadow << skip_bits) >> skip_bits; + if (shadow) + /* src_slots > 0, therefore dst_slots is at least 2 */ + origin_dst[dst_slots - 1] = + origin_dst[dst_slots - 2]; + } else { + shadow = align_shadow_src[0]; + skip_bits = ((u64)dst % KMSAN_ORIGIN_SIZE) * 8; + shadow = (shadow >> skip_bits) << skip_bits; + if (shadow) + origin_dst[0] = origin_dst[1]; + } + } +} + +depot_stack_handle_t kmsan_internal_chain_origin(depot_stack_handle_t id) +{ + unsigned long entries[3]; + u32 extra_bits; + int depth; + bool uaf; + + if (!id) + return id; + /* + * Make sure we have enough spare bits in @id to hold the UAF bit and + * the chain depth. + */ + BUILD_BUG_ON( + (1 << STACK_DEPOT_EXTRA_BITS) <= (KMSAN_MAX_ORIGIN_DEPTH << 1)); + + extra_bits = stack_depot_get_extra_bits(id); + depth = kmsan_depth_from_eb(extra_bits); + uaf = kmsan_uaf_from_eb(extra_bits); + + /* + * Stop chaining origins once the depth reached KMSAN_MAX_ORIGIN_DEPTH. + * This mostly happens in the case structures with uninitialized padding + * are copied around many times. Origin chains for such structures are + * usually periodic, and it does not make sense to fully store them. + */ + if (depth == KMSAN_MAX_ORIGIN_DEPTH) + return id; + + depth++; + extra_bits = kmsan_extra_bits(depth, uaf); + + entries[0] = KMSAN_CHAIN_MAGIC_ORIGIN; + entries[1] = kmsan_save_stack_with_flags(GFP_ATOMIC, 0); + entries[2] = id; + /* + * @entries is a local var in non-instrumented code, so KMSAN does not + * know it is initialized. Explicitly unpoison it to avoid false + * positives when __stack_depot_save() passes it to instrumented code. + */ + kmsan_internal_unpoison_memory(entries, sizeof(entries), false); + return __stack_depot_save(entries, ARRAY_SIZE(entries), extra_bits, + GFP_ATOMIC, true); +} + +void kmsan_internal_set_shadow_origin(void *addr, size_t size, int b, + u32 origin, bool checked) +{ + u64 address = (u64)addr; + void *shadow_start; + u32 *origin_start; + size_t pad = 0; + + KMSAN_WARN_ON(!kmsan_metadata_is_contiguous(addr, size)); + shadow_start = kmsan_get_metadata(addr, KMSAN_META_SHADOW); + if (!shadow_start) { + /* + * kmsan_metadata_is_contiguous() is true, so either all shadow + * and origin pages are NULL, or all are non-NULL. + */ + if (checked) { + pr_err("%s: not memsetting %ld bytes starting at %px, because the shadow is NULL\n", + __func__, size, addr); + KMSAN_WARN_ON(true); + } + return; + } + __memset(shadow_start, b, size); + + if (!IS_ALIGNED(address, KMSAN_ORIGIN_SIZE)) { + pad = address % KMSAN_ORIGIN_SIZE; + address -= pad; + size += pad; + } + size = ALIGN(size, KMSAN_ORIGIN_SIZE); + origin_start = + (u32 *)kmsan_get_metadata((void *)address, KMSAN_META_ORIGIN); + + for (int i = 0; i < size / KMSAN_ORIGIN_SIZE; i++) + origin_start[i] = origin; +} + +struct page *kmsan_vmalloc_to_page_or_null(void *vaddr) +{ + struct page *page; + + if (!kmsan_internal_is_vmalloc_addr(vaddr) && + !kmsan_internal_is_module_addr(vaddr)) + return NULL; + page = vmalloc_to_page(vaddr); + if (pfn_valid(page_to_pfn(page))) + return page; + else + return NULL; +} + +void kmsan_internal_check_memory(void *addr, size_t size, const void *user_addr, + int reason) +{ + depot_stack_handle_t cur_origin = 0, new_origin = 0; + unsigned long addr64 = (unsigned long)addr; + depot_stack_handle_t *origin = NULL; + unsigned char *shadow = NULL; + int cur_off_start = -1; + int chunk_size; + size_t pos = 0; + + if (!size) + return; + KMSAN_WARN_ON(!kmsan_metadata_is_contiguous(addr, size)); + while (pos < size) { + chunk_size = min(size - pos, + PAGE_SIZE - ((addr64 + pos) % PAGE_SIZE)); + shadow = kmsan_get_metadata((void *)(addr64 + pos), + KMSAN_META_SHADOW); + if (!shadow) { + /* + * This page is untracked. If there were uninitialized + * bytes before, report them. + */ + if (cur_origin) { + kmsan_enter_runtime(); + kmsan_report(cur_origin, addr, size, + cur_off_start, pos - 1, user_addr, + reason); + kmsan_leave_runtime(); + } + cur_origin = 0; + cur_off_start = -1; + pos += chunk_size; + continue; + } + for (int i = 0; i < chunk_size; i++) { + if (!shadow[i]) { + /* + * This byte is unpoisoned. If there were + * poisoned bytes before, report them. + */ + if (cur_origin) { + kmsan_enter_runtime(); + kmsan_report(cur_origin, addr, size, + cur_off_start, pos + i - 1, + user_addr, reason); + kmsan_leave_runtime(); + } + cur_origin = 0; + cur_off_start = -1; + continue; + } + origin = kmsan_get_metadata((void *)(addr64 + pos + i), + KMSAN_META_ORIGIN); + KMSAN_WARN_ON(!origin); + new_origin = *origin; + /* + * Encountered new origin - report the previous + * uninitialized range. + */ + if (cur_origin != new_origin) { + if (cur_origin) { + kmsan_enter_runtime(); + kmsan_report(cur_origin, addr, size, + cur_off_start, pos + i - 1, + user_addr, reason); + kmsan_leave_runtime(); + } + cur_origin = new_origin; + cur_off_start = pos + i; + } + } + pos += chunk_size; + } + KMSAN_WARN_ON(pos != size); + if (cur_origin) { + kmsan_enter_runtime(); + kmsan_report(cur_origin, addr, size, cur_off_start, pos - 1, + user_addr, reason); + kmsan_leave_runtime(); + } +} + +bool kmsan_metadata_is_contiguous(void *addr, size_t size) +{ + char *cur_shadow = NULL, *next_shadow = NULL, *cur_origin = NULL, + *next_origin = NULL; + u64 cur_addr = (u64)addr, next_addr = cur_addr + PAGE_SIZE; + depot_stack_handle_t *origin_p; + bool all_untracked = false; + + if (!size) + return true; + + /* The whole range belongs to the same page. */ + if (ALIGN_DOWN(cur_addr + size - 1, PAGE_SIZE) == + ALIGN_DOWN(cur_addr, PAGE_SIZE)) + return true; + + cur_shadow = kmsan_get_metadata((void *)cur_addr, /*is_origin*/ false); + if (!cur_shadow) + all_untracked = true; + cur_origin = kmsan_get_metadata((void *)cur_addr, /*is_origin*/ true); + if (all_untracked && cur_origin) + goto report; + + for (; next_addr < (u64)addr + size; + cur_addr = next_addr, cur_shadow = next_shadow, + cur_origin = next_origin, next_addr += PAGE_SIZE) { + next_shadow = kmsan_get_metadata((void *)next_addr, false); + next_origin = kmsan_get_metadata((void *)next_addr, true); + if (all_untracked) { + if (next_shadow || next_origin) + goto report; + if (!next_shadow && !next_origin) + continue; + } + if (((u64)cur_shadow == ((u64)next_shadow - PAGE_SIZE)) && + ((u64)cur_origin == ((u64)next_origin - PAGE_SIZE))) + continue; + goto report; + } + return true; + +report: + pr_err("%s: attempting to access two shadow page ranges.\n", __func__); + pr_err("Access of size %ld at %px.\n", size, addr); + pr_err("Addresses belonging to different ranges: %px and %px\n", + (void *)cur_addr, (void *)next_addr); + pr_err("page[0].shadow: %px, page[1].shadow: %px\n", cur_shadow, + next_shadow); + pr_err("page[0].origin: %px, page[1].origin: %px\n", cur_origin, + next_origin); + origin_p = kmsan_get_metadata(addr, KMSAN_META_ORIGIN); + if (origin_p) { + pr_err("Origin: %08x\n", *origin_p); + kmsan_print_origin(*origin_p); + } else { + pr_err("Origin: unavailable\n"); + } + return false; +} diff --git a/mm/kmsan/hooks.c b/mm/kmsan/hooks.c new file mode 100644 index 000000000000..4ac62fa67a02 --- /dev/null +++ b/mm/kmsan/hooks.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KMSAN hooks for kernel subsystems. + * + * These functions handle creation of KMSAN metadata for memory allocations. + * + * Copyright (C) 2018-2022 Google LLC + * Author: Alexander Potapenko + * + */ + +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../slab.h" +#include "kmsan.h" + +/* + * Instrumented functions shouldn't be called under + * kmsan_enter_runtime()/kmsan_leave_runtime(), because this will lead to + * skipping effects of functions like memset() inside instrumented code. + */ + +/* Functions from kmsan-checks.h follow. */ +void kmsan_poison_memory(const void *address, size_t size, gfp_t flags) +{ + if (!kmsan_enabled || kmsan_in_runtime()) + return; + kmsan_enter_runtime(); + /* The users may want to poison/unpoison random memory. */ + kmsan_internal_poison_memory((void *)address, size, flags, + KMSAN_POISON_NOCHECK); + kmsan_leave_runtime(); +} +EXPORT_SYMBOL(kmsan_poison_memory); + +void kmsan_unpoison_memory(const void *address, size_t size) +{ + unsigned long ua_flags; + + if (!kmsan_enabled || kmsan_in_runtime()) + return; + + ua_flags = user_access_save(); + kmsan_enter_runtime(); + /* The users may want to poison/unpoison random memory. */ + kmsan_internal_unpoison_memory((void *)address, size, + KMSAN_POISON_NOCHECK); + kmsan_leave_runtime(); + user_access_restore(ua_flags); +} +EXPORT_SYMBOL(kmsan_unpoison_memory); + +void kmsan_check_memory(const void *addr, size_t size) +{ + if (!kmsan_enabled) + return; + return kmsan_internal_check_memory((void *)addr, size, /*user_addr*/ 0, + REASON_ANY); +} +EXPORT_SYMBOL(kmsan_check_memory); diff --git a/mm/kmsan/instrumentation.c b/mm/kmsan/instrumentation.c new file mode 100644 index 000000000000..280d15413268 --- /dev/null +++ b/mm/kmsan/instrumentation.c @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KMSAN compiler API. + * + * This file implements __msan_XXX hooks that Clang inserts into the code + * compiled with -fsanitize=kernel-memory. + * See Documentation/dev-tools/kmsan.rst for more information on how KMSAN + * instrumentation works. + * + * Copyright (C) 2017-2022 Google LLC + * Author: Alexander Potapenko + * + */ + +#include "kmsan.h" +#include +#include +#include + +static inline bool is_bad_asm_addr(void *addr, uintptr_t size, bool is_store) +{ + if ((u64)addr < TASK_SIZE) + return true; + if (!kmsan_get_metadata(addr, KMSAN_META_SHADOW)) + return true; + return false; +} + +static inline struct shadow_origin_ptr +get_shadow_origin_ptr(void *addr, u64 size, bool store) +{ + unsigned long ua_flags = user_access_save(); + struct shadow_origin_ptr ret; + + ret = kmsan_get_shadow_origin_ptr(addr, size, store); + user_access_restore(ua_flags); + return ret; +} + +/* Get shadow and origin pointers for a memory load with non-standard size. */ +struct shadow_origin_ptr __msan_metadata_ptr_for_load_n(void *addr, + uintptr_t size) +{ + return get_shadow_origin_ptr(addr, size, /*store*/ false); +} +EXPORT_SYMBOL(__msan_metadata_ptr_for_load_n); + +/* Get shadow and origin pointers for a memory store with non-standard size. */ +struct shadow_origin_ptr __msan_metadata_ptr_for_store_n(void *addr, + uintptr_t size) +{ + return get_shadow_origin_ptr(addr, size, /*store*/ true); +} +EXPORT_SYMBOL(__msan_metadata_ptr_for_store_n); + +/* + * Declare functions that obtain shadow/origin pointers for loads and stores + * with fixed size. + */ +#define DECLARE_METADATA_PTR_GETTER(size) \ + struct shadow_origin_ptr __msan_metadata_ptr_for_load_##size( \ + void *addr) \ + { \ + return get_shadow_origin_ptr(addr, size, /*store*/ false); \ + } \ + EXPORT_SYMBOL(__msan_metadata_ptr_for_load_##size); \ + struct shadow_origin_ptr __msan_metadata_ptr_for_store_##size( \ + void *addr) \ + { \ + return get_shadow_origin_ptr(addr, size, /*store*/ true); \ + } \ + EXPORT_SYMBOL(__msan_metadata_ptr_for_store_##size) + +DECLARE_METADATA_PTR_GETTER(1); +DECLARE_METADATA_PTR_GETTER(2); +DECLARE_METADATA_PTR_GETTER(4); +DECLARE_METADATA_PTR_GETTER(8); + +/* + * Handle a memory store performed by inline assembly. KMSAN conservatively + * attempts to unpoison the outputs of asm() directives to prevent false + * positives caused by missed stores. + */ +void __msan_instrument_asm_store(void *addr, uintptr_t size) +{ + unsigned long ua_flags; + + if (!kmsan_enabled || kmsan_in_runtime()) + return; + + ua_flags = user_access_save(); + /* + * Most of the accesses are below 32 bytes. The two exceptions so far + * are clwb() (64 bytes) and FPU state (512 bytes). + * It's unlikely that the assembly will touch more than 512 bytes. + */ + if (size > 512) { + WARN_ONCE(1, "assembly store size too big: %ld\n", size); + size = 8; + } + if (is_bad_asm_addr(addr, size, /*is_store*/ true)) { + user_access_restore(ua_flags); + return; + } + kmsan_enter_runtime(); + /* Unpoisoning the memory on best effort. */ + kmsan_internal_unpoison_memory(addr, size, /*checked*/ false); + kmsan_leave_runtime(); + user_access_restore(ua_flags); +} +EXPORT_SYMBOL(__msan_instrument_asm_store); + +/* + * KMSAN instrumentation pass replaces LLVM memcpy, memmove and memset + * intrinsics with calls to respective __msan_ functions. We use + * get_param0_metadata() and set_retval_metadata() to store the shadow/origin + * values for the destination argument of these functions and use them for the + * functions' return values. + */ +static inline void get_param0_metadata(u64 *shadow, + depot_stack_handle_t *origin) +{ + struct kmsan_ctx *ctx = kmsan_get_context(); + + *shadow = *(u64 *)(ctx->cstate.param_tls); + *origin = ctx->cstate.param_origin_tls[0]; +} + +static inline void set_retval_metadata(u64 shadow, depot_stack_handle_t origin) +{ + struct kmsan_ctx *ctx = kmsan_get_context(); + + *(u64 *)(ctx->cstate.retval_tls) = shadow; + ctx->cstate.retval_origin_tls = origin; +} + +/* Handle llvm.memmove intrinsic. */ +void *__msan_memmove(void *dst, const void *src, uintptr_t n) +{ + depot_stack_handle_t origin; + void *result; + u64 shadow; + + get_param0_metadata(&shadow, &origin); + result = __memmove(dst, src, n); + if (!n) + /* Some people call memmove() with zero length. */ + return result; + if (!kmsan_enabled || kmsan_in_runtime()) + return result; + + kmsan_enter_runtime(); + kmsan_internal_memmove_metadata(dst, (void *)src, n); + kmsan_leave_runtime(); + + set_retval_metadata(shadow, origin); + return result; +} +EXPORT_SYMBOL(__msan_memmove); + +/* Handle llvm.memcpy intrinsic. */ +void *__msan_memcpy(void *dst, const void *src, uintptr_t n) +{ + depot_stack_handle_t origin; + void *result; + u64 shadow; + + get_param0_metadata(&shadow, &origin); + result = __memcpy(dst, src, n); + if (!n) + /* Some people call memcpy() with zero length. */ + return result; + + if (!kmsan_enabled || kmsan_in_runtime()) + return result; + + kmsan_enter_runtime(); + /* Using memmove instead of memcpy doesn't affect correctness. */ + kmsan_internal_memmove_metadata(dst, (void *)src, n); + kmsan_leave_runtime(); + + set_retval_metadata(shadow, origin); + return result; +} +EXPORT_SYMBOL(__msan_memcpy); + +/* Handle llvm.memset intrinsic. */ +void *__msan_memset(void *dst, int c, uintptr_t n) +{ + depot_stack_handle_t origin; + void *result; + u64 shadow; + + get_param0_metadata(&shadow, &origin); + result = __memset(dst, c, n); + if (!kmsan_enabled || kmsan_in_runtime()) + return result; + + kmsan_enter_runtime(); + /* + * Clang doesn't pass parameter metadata here, so it is impossible to + * use shadow of @c to set up the shadow for @dst. + */ + kmsan_internal_unpoison_memory(dst, n, /*checked*/ false); + kmsan_leave_runtime(); + + set_retval_metadata(shadow, origin); + return result; +} +EXPORT_SYMBOL(__msan_memset); + +/* + * Create a new origin from an old one. This is done when storing an + * uninitialized value to memory. When reporting an error, KMSAN unrolls and + * prints the whole chain of stores that preceded the use of this value. + */ +depot_stack_handle_t __msan_chain_origin(depot_stack_handle_t origin) +{ + depot_stack_handle_t ret = 0; + unsigned long ua_flags; + + if (!kmsan_enabled || kmsan_in_runtime()) + return ret; + + ua_flags = user_access_save(); + + /* Creating new origins may allocate memory. */ + kmsan_enter_runtime(); + ret = kmsan_internal_chain_origin(origin); + kmsan_leave_runtime(); + user_access_restore(ua_flags); + return ret; +} +EXPORT_SYMBOL(__msan_chain_origin); + +/* Poison a local variable when entering a function. */ +void __msan_poison_alloca(void *address, uintptr_t size, char *descr) +{ + depot_stack_handle_t handle; + unsigned long entries[4]; + unsigned long ua_flags; + + if (!kmsan_enabled || kmsan_in_runtime()) + return; + + ua_flags = user_access_save(); + entries[0] = KMSAN_ALLOCA_MAGIC_ORIGIN; + entries[1] = (u64)descr; + entries[2] = (u64)__builtin_return_address(0); + /* + * With frame pointers enabled, it is possible to quickly fetch the + * second frame of the caller stack without calling the unwinder. + * Without them, simply do not bother. + */ + if (IS_ENABLED(CONFIG_UNWINDER_FRAME_POINTER)) + entries[3] = (u64)__builtin_return_address(1); + else + entries[3] = 0; + + /* stack_depot_save() may allocate memory. */ + kmsan_enter_runtime(); + handle = stack_depot_save(entries, ARRAY_SIZE(entries), GFP_ATOMIC); + kmsan_leave_runtime(); + + kmsan_internal_set_shadow_origin(address, size, -1, handle, + /*checked*/ true); + user_access_restore(ua_flags); +} +EXPORT_SYMBOL(__msan_poison_alloca); + +/* Unpoison a local variable. */ +void __msan_unpoison_alloca(void *address, uintptr_t size) +{ + if (!kmsan_enabled || kmsan_in_runtime()) + return; + + kmsan_enter_runtime(); + kmsan_internal_unpoison_memory(address, size, /*checked*/ true); + kmsan_leave_runtime(); +} +EXPORT_SYMBOL(__msan_unpoison_alloca); + +/* + * Report that an uninitialized value with the given origin was used in a way + * that constituted undefined behavior. + */ +void __msan_warning(u32 origin) +{ + if (!kmsan_enabled || kmsan_in_runtime()) + return; + kmsan_enter_runtime(); + kmsan_report(origin, /*address*/ 0, /*size*/ 0, + /*off_first*/ 0, /*off_last*/ 0, /*user_addr*/ 0, + REASON_ANY); + kmsan_leave_runtime(); +} +EXPORT_SYMBOL(__msan_warning); + +/* + * At the beginning of an instrumented function, obtain the pointer to + * `struct kmsan_context_state` holding the metadata for function parameters. + */ +struct kmsan_context_state *__msan_get_context_state(void) +{ + return &kmsan_get_context()->cstate; +} +EXPORT_SYMBOL(__msan_get_context_state); diff --git a/mm/kmsan/kmsan.h b/mm/kmsan/kmsan.h new file mode 100644 index 000000000000..97d48b45dba5 --- /dev/null +++ b/mm/kmsan/kmsan.h @@ -0,0 +1,204 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Functions used by the KMSAN runtime. + * + * Copyright (C) 2017-2022 Google LLC + * Author: Alexander Potapenko + * + */ + +#ifndef __MM_KMSAN_KMSAN_H +#define __MM_KMSAN_KMSAN_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#define KMSAN_ALLOCA_MAGIC_ORIGIN 0xabcd0100 +#define KMSAN_CHAIN_MAGIC_ORIGIN 0xabcd0200 + +#define KMSAN_POISON_NOCHECK 0x0 +#define KMSAN_POISON_CHECK 0x1 +#define KMSAN_POISON_FREE 0x2 + +#define KMSAN_ORIGIN_SIZE 4 +#define KMSAN_MAX_ORIGIN_DEPTH 7 + +#define KMSAN_STACK_DEPTH 64 + +#define KMSAN_META_SHADOW (false) +#define KMSAN_META_ORIGIN (true) + +extern bool kmsan_enabled; +extern int panic_on_kmsan; + +/* + * KMSAN performs a lot of consistency checks that are currently enabled by + * default. BUG_ON is normally discouraged in the kernel, unless used for + * debugging, but KMSAN itself is a debugging tool, so it makes little sense to + * recover if something goes wrong. + */ +#define KMSAN_WARN_ON(cond) \ + ({ \ + const bool __cond = WARN_ON(cond); \ + if (unlikely(__cond)) { \ + WRITE_ONCE(kmsan_enabled, false); \ + if (panic_on_kmsan) { \ + /* Can't call panic() here because */ \ + /* of uaccess checks. */ \ + BUG(); \ + } \ + } \ + __cond; \ + }) + +/* + * A pair of metadata pointers to be returned by the instrumentation functions. + */ +struct shadow_origin_ptr { + void *shadow, *origin; +}; + +struct shadow_origin_ptr kmsan_get_shadow_origin_ptr(void *addr, u64 size, + bool store); +void *kmsan_get_metadata(void *addr, bool is_origin); + +enum kmsan_bug_reason { + REASON_ANY, + REASON_COPY_TO_USER, + REASON_SUBMIT_URB, +}; + +void kmsan_print_origin(depot_stack_handle_t origin); + +/** + * kmsan_report() - Report a use of uninitialized value. + * @origin: Stack ID of the uninitialized value. + * @address: Address at which the memory access happens. + * @size: Memory access size. + * @off_first: Offset (from @address) of the first byte to be reported. + * @off_last: Offset (from @address) of the last byte to be reported. + * @user_addr: When non-NULL, denotes the userspace address to which the kernel + * is leaking data. + * @reason: Error type from enum kmsan_bug_reason. + * + * kmsan_report() prints an error message for a consequent group of bytes + * sharing the same origin. If an uninitialized value is used in a comparison, + * this function is called once without specifying the addresses. When checking + * a memory range, KMSAN may call kmsan_report() multiple times with the same + * @address, @size, @user_addr and @reason, but different @off_first and + * @off_last corresponding to different @origin values. + */ +void kmsan_report(depot_stack_handle_t origin, void *address, int size, + int off_first, int off_last, const void *user_addr, + enum kmsan_bug_reason reason); + +DECLARE_PER_CPU(struct kmsan_ctx, kmsan_percpu_ctx); + +static __always_inline struct kmsan_ctx *kmsan_get_context(void) +{ + return in_task() ? ¤t->kmsan_ctx : raw_cpu_ptr(&kmsan_percpu_ctx); +} + +/* + * When a compiler hook or KMSAN runtime function is invoked, it may make a + * call to instrumented code and eventually call itself recursively. To avoid + * that, we guard the runtime entry regions with + * kmsan_enter_runtime()/kmsan_leave_runtime() and exit the hook if + * kmsan_in_runtime() is true. + * + * Non-runtime code may occasionally get executed in nested IRQs from the + * runtime code (e.g. when called via smp_call_function_single()). Because some + * KMSAN routines may take locks (e.g. for memory allocation), we conservatively + * bail out instead of calling them. To minimize the effect of this (potentially + * missing initialization events) kmsan_in_runtime() is not checked in + * non-blocking runtime functions. + */ +static __always_inline bool kmsan_in_runtime(void) +{ + if ((hardirq_count() >> HARDIRQ_SHIFT) > 1) + return true; + return kmsan_get_context()->kmsan_in_runtime; +} + +static __always_inline void kmsan_enter_runtime(void) +{ + struct kmsan_ctx *ctx; + + ctx = kmsan_get_context(); + KMSAN_WARN_ON(ctx->kmsan_in_runtime++); +} + +static __always_inline void kmsan_leave_runtime(void) +{ + struct kmsan_ctx *ctx = kmsan_get_context(); + + KMSAN_WARN_ON(--ctx->kmsan_in_runtime); +} + +depot_stack_handle_t kmsan_save_stack(void); +depot_stack_handle_t kmsan_save_stack_with_flags(gfp_t flags, + unsigned int extra_bits); + +/* + * Pack and unpack the origin chain depth and UAF flag to/from the extra bits + * provided by the stack depot. + * The UAF flag is stored in the lowest bit, followed by the depth in the upper + * bits. + * set_dsh_extra_bits() is responsible for clamping the value. + */ +static __always_inline unsigned int kmsan_extra_bits(unsigned int depth, + bool uaf) +{ + return (depth << 1) | uaf; +} + +static __always_inline bool kmsan_uaf_from_eb(unsigned int extra_bits) +{ + return extra_bits & 1; +} + +static __always_inline unsigned int kmsan_depth_from_eb(unsigned int extra_bits) +{ + return extra_bits >> 1; +} + +/* + * kmsan_internal_ functions are supposed to be very simple and not require the + * kmsan_in_runtime() checks. + */ +void kmsan_internal_memmove_metadata(void *dst, void *src, size_t n); +void kmsan_internal_poison_memory(void *address, size_t size, gfp_t flags, + unsigned int poison_flags); +void kmsan_internal_unpoison_memory(void *address, size_t size, bool checked); +void kmsan_internal_set_shadow_origin(void *address, size_t size, int b, + u32 origin, bool checked); +depot_stack_handle_t kmsan_internal_chain_origin(depot_stack_handle_t id); + +bool kmsan_metadata_is_contiguous(void *addr, size_t size); +void kmsan_internal_check_memory(void *addr, size_t size, const void *user_addr, + int reason); + +struct page *kmsan_vmalloc_to_page_or_null(void *vaddr); + +/* + * kmsan_internal_is_module_addr() and kmsan_internal_is_vmalloc_addr() are + * non-instrumented versions of is_module_address() and is_vmalloc_addr() that + * are safe to call from KMSAN runtime without recursion. + */ +static inline bool kmsan_internal_is_module_addr(void *vaddr) +{ + return ((u64)vaddr >= MODULES_VADDR) && ((u64)vaddr < MODULES_END); +} + +static inline bool kmsan_internal_is_vmalloc_addr(void *addr) +{ + return ((u64)addr >= VMALLOC_START) && ((u64)addr < VMALLOC_END); +} + +#endif /* __MM_KMSAN_KMSAN_H */ diff --git a/mm/kmsan/report.c b/mm/kmsan/report.c new file mode 100644 index 000000000000..02736ec757f2 --- /dev/null +++ b/mm/kmsan/report.c @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KMSAN error reporting routines. + * + * Copyright (C) 2019-2022 Google LLC + * Author: Alexander Potapenko + * + */ + +#include +#include +#include +#include +#include + +#include "kmsan.h" + +static DEFINE_RAW_SPINLOCK(kmsan_report_lock); +#define DESCR_SIZE 128 +/* Protected by kmsan_report_lock */ +static char report_local_descr[DESCR_SIZE]; +int panic_on_kmsan __read_mostly; + +#ifdef MODULE_PARAM_PREFIX +#undef MODULE_PARAM_PREFIX +#endif +#define MODULE_PARAM_PREFIX "kmsan." +module_param_named(panic, panic_on_kmsan, int, 0); + +/* + * Skip internal KMSAN frames. + */ +static int get_stack_skipnr(const unsigned long stack_entries[], + int num_entries) +{ + int len, skip; + char buf[64]; + + for (skip = 0; skip < num_entries; ++skip) { + len = scnprintf(buf, sizeof(buf), "%ps", + (void *)stack_entries[skip]); + + /* Never show __msan_* or kmsan_* functions. */ + if ((strnstr(buf, "__msan_", len) == buf) || + (strnstr(buf, "kmsan_", len) == buf)) + continue; + + /* + * No match for runtime functions -- @skip entries to skip to + * get to first frame of interest. + */ + break; + } + + return skip; +} + +/* + * Currently the descriptions of locals generated by Clang look as follows: + * ----local_name@function_name + * We want to print only the name of the local, as other information in that + * description can be confusing. + * The meaningful part of the description is copied to a global buffer to avoid + * allocating memory. + */ +static char *pretty_descr(char *descr) +{ + int pos = 0, len = strlen(descr); + + for (int i = 0; i < len; i++) { + if (descr[i] == '@') + break; + if (descr[i] == '-') + continue; + report_local_descr[pos] = descr[i]; + if (pos + 1 == DESCR_SIZE) + break; + pos++; + } + report_local_descr[pos] = 0; + return report_local_descr; +} + +void kmsan_print_origin(depot_stack_handle_t origin) +{ + unsigned long *entries = NULL, *chained_entries = NULL; + unsigned int nr_entries, chained_nr_entries, skipnr; + void *pc1 = NULL, *pc2 = NULL; + depot_stack_handle_t head; + unsigned long magic; + char *descr = NULL; + unsigned int depth; + + if (!origin) + return; + + while (true) { + nr_entries = stack_depot_fetch(origin, &entries); + depth = kmsan_depth_from_eb(stack_depot_get_extra_bits(origin)); + magic = nr_entries ? entries[0] : 0; + if ((nr_entries == 4) && (magic == KMSAN_ALLOCA_MAGIC_ORIGIN)) { + descr = (char *)entries[1]; + pc1 = (void *)entries[2]; + pc2 = (void *)entries[3]; + pr_err("Local variable %s created at:\n", + pretty_descr(descr)); + if (pc1) + pr_err(" %pSb\n", pc1); + if (pc2) + pr_err(" %pSb\n", pc2); + break; + } + if ((nr_entries == 3) && (magic == KMSAN_CHAIN_MAGIC_ORIGIN)) { + /* + * Origin chains deeper than KMSAN_MAX_ORIGIN_DEPTH are + * not stored, so the output may be incomplete. + */ + if (depth == KMSAN_MAX_ORIGIN_DEPTH) + pr_err("\n\n"); + head = entries[1]; + origin = entries[2]; + pr_err("Uninit was stored to memory at:\n"); + chained_nr_entries = + stack_depot_fetch(head, &chained_entries); + kmsan_internal_unpoison_memory( + chained_entries, + chained_nr_entries * sizeof(*chained_entries), + /*checked*/ false); + skipnr = get_stack_skipnr(chained_entries, + chained_nr_entries); + stack_trace_print(chained_entries + skipnr, + chained_nr_entries - skipnr, 0); + pr_err("\n"); + continue; + } + pr_err("Uninit was created at:\n"); + if (nr_entries) { + skipnr = get_stack_skipnr(entries, nr_entries); + stack_trace_print(entries + skipnr, nr_entries - skipnr, + 0); + } else { + pr_err("(stack is not available)\n"); + } + break; + } +} + +void kmsan_report(depot_stack_handle_t origin, void *address, int size, + int off_first, int off_last, const void *user_addr, + enum kmsan_bug_reason reason) +{ + unsigned long stack_entries[KMSAN_STACK_DEPTH]; + int num_stack_entries, skipnr; + char *bug_type = NULL; + unsigned long ua_flags; + bool is_uaf; + + if (!kmsan_enabled) + return; + if (!current->kmsan_ctx.allow_reporting) + return; + if (!origin) + return; + + current->kmsan_ctx.allow_reporting = false; + ua_flags = user_access_save(); + raw_spin_lock(&kmsan_report_lock); + pr_err("=====================================================\n"); + is_uaf = kmsan_uaf_from_eb(stack_depot_get_extra_bits(origin)); + switch (reason) { + case REASON_ANY: + bug_type = is_uaf ? "use-after-free" : "uninit-value"; + break; + case REASON_COPY_TO_USER: + bug_type = is_uaf ? "kernel-infoleak-after-free" : + "kernel-infoleak"; + break; + case REASON_SUBMIT_URB: + bug_type = is_uaf ? "kernel-usb-infoleak-after-free" : + "kernel-usb-infoleak"; + break; + } + + num_stack_entries = + stack_trace_save(stack_entries, KMSAN_STACK_DEPTH, 1); + skipnr = get_stack_skipnr(stack_entries, num_stack_entries); + + pr_err("BUG: KMSAN: %s in %pSb\n", bug_type, + (void *)stack_entries[skipnr]); + stack_trace_print(stack_entries + skipnr, num_stack_entries - skipnr, + 0); + pr_err("\n"); + + kmsan_print_origin(origin); + + if (size) { + pr_err("\n"); + if (off_first == off_last) + pr_err("Byte %d of %d is uninitialized\n", off_first, + size); + else + pr_err("Bytes %d-%d of %d are uninitialized\n", + off_first, off_last, size); + } + if (address) + pr_err("Memory access of size %d starts at %px\n", size, + address); + if (user_addr && reason == REASON_COPY_TO_USER) + pr_err("Data copied to user address %px\n", user_addr); + pr_err("\n"); + dump_stack_print_info(KERN_ERR); + pr_err("=====================================================\n"); + add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE); + raw_spin_unlock(&kmsan_report_lock); + if (panic_on_kmsan) + panic("kmsan.panic set ...\n"); + user_access_restore(ua_flags); + current->kmsan_ctx.allow_reporting = true; +} diff --git a/mm/kmsan/shadow.c b/mm/kmsan/shadow.c new file mode 100644 index 000000000000..acc5279acc3b --- /dev/null +++ b/mm/kmsan/shadow.c @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KMSAN shadow implementation. + * + * Copyright (C) 2017-2022 Google LLC + * Author: Alexander Potapenko + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "kmsan.h" + +#define shadow_page_for(page) ((page)->kmsan_shadow) + +#define origin_page_for(page) ((page)->kmsan_origin) + +static void *shadow_ptr_for(struct page *page) +{ + return page_address(shadow_page_for(page)); +} + +static void *origin_ptr_for(struct page *page) +{ + return page_address(origin_page_for(page)); +} + +static bool page_has_metadata(struct page *page) +{ + return shadow_page_for(page) && origin_page_for(page); +} + +static void set_no_shadow_origin_page(struct page *page) +{ + shadow_page_for(page) = NULL; + origin_page_for(page) = NULL; +} + +/* + * Dummy load and store pages to be used when the real metadata is unavailable. + * There are separate pages for loads and stores, so that every load returns a + * zero, and every store doesn't affect other loads. + */ +static char dummy_load_page[PAGE_SIZE] __aligned(PAGE_SIZE); +static char dummy_store_page[PAGE_SIZE] __aligned(PAGE_SIZE); + +static unsigned long vmalloc_meta(void *addr, bool is_origin) +{ + unsigned long addr64 = (unsigned long)addr, off; + + KMSAN_WARN_ON(is_origin && !IS_ALIGNED(addr64, KMSAN_ORIGIN_SIZE)); + if (kmsan_internal_is_vmalloc_addr(addr)) { + off = addr64 - VMALLOC_START; + return off + (is_origin ? KMSAN_VMALLOC_ORIGIN_START : + KMSAN_VMALLOC_SHADOW_START); + } + if (kmsan_internal_is_module_addr(addr)) { + off = addr64 - MODULES_VADDR; + return off + (is_origin ? KMSAN_MODULES_ORIGIN_START : + KMSAN_MODULES_SHADOW_START); + } + return 0; +} + +static struct page *virt_to_page_or_null(void *vaddr) +{ + if (kmsan_virt_addr_valid(vaddr)) + return virt_to_page(vaddr); + else + return NULL; +} + +struct shadow_origin_ptr kmsan_get_shadow_origin_ptr(void *address, u64 size, + bool store) +{ + struct shadow_origin_ptr ret; + void *shadow; + + /* + * Even if we redirect this memory access to the dummy page, it will + * go out of bounds. + */ + KMSAN_WARN_ON(size > PAGE_SIZE); + + if (!kmsan_enabled) + goto return_dummy; + + KMSAN_WARN_ON(!kmsan_metadata_is_contiguous(address, size)); + shadow = kmsan_get_metadata(address, KMSAN_META_SHADOW); + if (!shadow) + goto return_dummy; + + ret.shadow = shadow; + ret.origin = kmsan_get_metadata(address, KMSAN_META_ORIGIN); + return ret; + +return_dummy: + if (store) { + /* Ignore this store. */ + ret.shadow = dummy_store_page; + ret.origin = dummy_store_page; + } else { + /* This load will return zero. */ + ret.shadow = dummy_load_page; + ret.origin = dummy_load_page; + } + return ret; +} + +/* + * Obtain the shadow or origin pointer for the given address, or NULL if there's + * none. The caller must check the return value for being non-NULL if needed. + * The return value of this function should not depend on whether we're in the + * runtime or not. + */ +void *kmsan_get_metadata(void *address, bool is_origin) +{ + u64 addr = (u64)address, pad, off; + struct page *page; + + if (is_origin && !IS_ALIGNED(addr, KMSAN_ORIGIN_SIZE)) { + pad = addr % KMSAN_ORIGIN_SIZE; + addr -= pad; + } + address = (void *)addr; + if (kmsan_internal_is_vmalloc_addr(address) || + kmsan_internal_is_module_addr(address)) + return (void *)vmalloc_meta(address, is_origin); + + page = virt_to_page_or_null(address); + if (!page) + return NULL; + if (!page_has_metadata(page)) + return NULL; + off = addr % PAGE_SIZE; + + return (is_origin ? origin_ptr_for(page) : shadow_ptr_for(page)) + off; +} diff --git a/scripts/Makefile.kmsan b/scripts/Makefile.kmsan new file mode 100644 index 000000000000..b5b0aa61322e --- /dev/null +++ b/scripts/Makefile.kmsan @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +kmsan-cflags := -fsanitize=kernel-memory + +ifdef CONFIG_KMSAN_CHECK_PARAM_RETVAL +kmsan-cflags += -fsanitize-memory-param-retval +endif + +export CFLAGS_KMSAN := $(kmsan-cflags) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 3fb6a99e78c4..ac32429e93b7 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -157,6 +157,15 @@ _c_flags += $(if $(patsubst n%,, \ endif endif +ifeq ($(CONFIG_KMSAN),y) +_c_flags += $(if $(patsubst n%,, \ + $(KMSAN_SANITIZE_$(basetarget).o)$(KMSAN_SANITIZE)y), \ + $(CFLAGS_KMSAN)) +_c_flags += $(if $(patsubst n%,, \ + $(KMSAN_ENABLE_CHECKS_$(basetarget).o)$(KMSAN_ENABLE_CHECKS)y), \ + , -mllvm -msan-disable-checks=1) +endif + ifeq ($(CONFIG_UBSAN),y) _c_flags += $(if $(patsubst n%,, \ $(UBSAN_SANITIZE_$(basetarget).o)$(UBSAN_SANITIZE)$(CONFIG_UBSAN_SANITIZE_ALL)), \ -- cgit v1.2.3 From bd17e036b495bebbf07a5fc814c868e30e1dc131 Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Wed, 14 Sep 2022 12:02:55 +0200 Subject: checkpatch: warn for non-standard fixes tag style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a warning for fixes tags that does not follow community conventions. Link: https://lkml.kernel.org/r/20220914100255.1048460-1-niklas.soderlund@corigine.com Signed-off-by: Niklas Söderlund Reviewed-by: Simon Horman Reviewed-by: Louis Peens Reviewed-by: Philippe Schenker Acked-by: Dwaipayan Ray Reviewed-by: Lukas Bulwahn Acked-by: Lukas Bulwahn Acked-by: Joe Perches Signed-off-by: Andrew Morton --- Documentation/dev-tools/checkpatch.rst | 7 ++++++ scripts/checkpatch.pl | 44 ++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) (limited to 'scripts') diff --git a/Documentation/dev-tools/checkpatch.rst b/Documentation/dev-tools/checkpatch.rst index b52452bc2963..c3389c6f3838 100644 --- a/Documentation/dev-tools/checkpatch.rst +++ b/Documentation/dev-tools/checkpatch.rst @@ -612,6 +612,13 @@ Commit message See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes + **BAD_FIXES_TAG** + The Fixes: tag is malformed or does not follow the community conventions. + This can occur if the tag have been split into multiple lines (e.g., when + pasted in an email program with word wrapping enabled). + + See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes + Comparison style ---------------- diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 18effbe1fe90..e8e0542f29f0 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3146,6 +3146,50 @@ sub process { } } +# Check Fixes: styles is correct + if (!$in_header_lines && + $line =~ /^\s*fixes:?\s*(?:commit\s*)?[0-9a-f]{5,}\b/i) { + my $orig_commit = ""; + my $id = "0123456789ab"; + my $title = "commit title"; + my $tag_case = 1; + my $tag_space = 1; + my $id_length = 1; + my $id_case = 1; + my $title_has_quotes = 0; + + if ($line =~ /(\s*fixes:?)\s+([0-9a-f]{5,})\s+($balanced_parens)/i) { + my $tag = $1; + $orig_commit = $2; + $title = $3; + + $tag_case = 0 if $tag eq "Fixes:"; + $tag_space = 0 if ($line =~ /^fixes:? [0-9a-f]{5,} ($balanced_parens)/i); + + $id_length = 0 if ($orig_commit =~ /^[0-9a-f]{12}$/i); + $id_case = 0 if ($orig_commit !~ /[A-F]/); + + # Always strip leading/trailing parens then double quotes if existing + $title = substr($title, 1, -1); + if ($title =~ /^".*"$/) { + $title = substr($title, 1, -1); + $title_has_quotes = 1; + } + } + + my ($cid, $ctitle) = git_commit_info($orig_commit, $id, + $title); + + if ($ctitle ne $title || $tag_case || $tag_space || + $id_length || $id_case || !$title_has_quotes) { + if (WARN("BAD_FIXES_TAG", + "Please use correct Fixes: style 'Fixes: <12 chars of sha1> (\"\")' - ie: 'Fixes: $cid (\"$ctitle\")'\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] = "Fixes: $cid (\"$ctitle\")"; + } + } + } + # Check email subject for common tools that don't need to be mentioned if ($in_header_lines && $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { -- cgit v1.2.3 From fc8c2d8ff20651f887e574767533d1176e3a479c Mon Sep 17 00:00:00 2001 From: Zack Rusin <zackr@vmware.com> Date: Thu, 6 Oct 2022 10:33:19 -0400 Subject: kbuild: Stop including vmlinux.bz2 in the rpm's vmlinux.bz2 was added to the rpm packages in 2009 in the fc370ecfdb37 ("kbuild: add vmlinux to kernel rpm") but seemingly hasn't been used since. Originally this should have been split up in a seperate debugging package because it massively increases the size of the generated rpm's e.g. kernel rpm built using binrpm-pkg on Fedora 36 default 5.19.8 kernel config and localmodconfig is ~255MB with vmlinux.bz2 and only ~65MB without it. Make the kernel built rpms about 4x smaller by not including the unused vmlinux.bz2 in them. Signed-off-by: Zack Rusin <zackr@vmware.com> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> --- scripts/package/mkspec | 2 -- 1 file changed, 2 deletions(-) (limited to 'scripts') diff --git a/scripts/package/mkspec b/scripts/package/mkspec index c920c1b18e7a..70392fd2fd29 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -97,8 +97,6 @@ $M $MAKE %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} modules_install $MAKE %{?_smp_mflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install cp System.map %{buildroot}/boot/System.map-$KERNELRELEASE cp .config %{buildroot}/boot/config-$KERNELRELEASE - bzip2 -9 --keep vmlinux - mv vmlinux.bz2 %{buildroot}/boot/vmlinux-$KERNELRELEASE.bz2 $S$M rm -f %{buildroot}/lib/modules/$KERNELRELEASE/build $S$M rm -f %{buildroot}/lib/modules/$KERNELRELEASE/source $S$M mkdir -p %{buildroot}/usr/src/kernels/$KERNELRELEASE -- cgit v1.2.3 From 11df33c36c4b7a04d2674531f2c6178ad8d61572 Mon Sep 17 00:00:00 2001 From: Richard Acayan <mailingradian@gmail.com> Date: Mon, 10 Oct 2022 21:38:28 -0400 Subject: modpost: put modpost options before argument The musl implementation of getopt stops looking for options after the first non-option argument. Put the options before the non-option argument so environments using musl can still build the kernel and modules. Fixes: f73edc8951b2 ("kbuild: unify two modpost invocations") Link: https://git.musl-libc.org/cgit/musl/tree/src/misc/getopt.c?h=dc9285ad1dc19349c407072cc48ba70dab86de45#n44 Signed-off-by: Richard Acayan <mailingradian@gmail.com> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> --- scripts/Makefile.modpost | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 7740ce3b29e8..8489a3402eb8 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -119,7 +119,7 @@ quiet_cmd_modpost = MODPOST $@ echo >&2 "WARNING: $(missing-input) is missing."; \ echo >&2 " Modules may not have dependencies or modversions."; \ echo >&2 " You may get many unresolved symbol warnings.";) \ - sed 's/ko$$/o/' $(or $(modorder-if-needed), /dev/null) | $(MODPOST) $(modpost-args) $(vmlinux.o-if-present) -T - + sed 's/ko$$/o/' $(or $(modorder-if-needed), /dev/null) | $(MODPOST) $(modpost-args) -T - $(vmlinux.o-if-present) targets += $(output-symdump) $(output-symdump): $(modorder-if-needed) $(vmlinux.o-if-present) $(moudle.symvers-if-present) $(MODPOST) FORCE -- cgit v1.2.3 From 04518e4c2edc78bc90b4651d50c4aad48d09ac23 Mon Sep 17 00:00:00 2001 From: Guru Das Srinagesh <quic_gurus@quicinc.com> Date: Tue, 11 Oct 2022 12:06:00 -0700 Subject: scripts/clang-tools: Convert clang-tidy args to list Convert list of clang-tidy arguments to a list for ease of adding to them and extending them as required. Signed-off-by: Guru Das Srinagesh <quic_gurus@quicinc.com> Suggested-by: Nick Desaulniers <ndesaulniers@google.com> Reviewed-by: Nick Desaulniers <ndesaulniers@google.com> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> --- scripts/clang-tools/run-clang-tools.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/clang-tools/run-clang-tools.py b/scripts/clang-tools/run-clang-tools.py index bb78c9bde55c..56f2ec8f0f40 100755 --- a/scripts/clang-tools/run-clang-tools.py +++ b/scripts/clang-tools/run-clang-tools.py @@ -45,13 +45,14 @@ def init(l, a): def run_analysis(entry): # Disable all checks, then re-enable the ones we want - checks = "-checks=-*," + checks = [] + checks.append("-checks=-*") if args.type == "clang-tidy": - checks += "linuxkernel-*" + checks.append("linuxkernel-*") else: - checks += "clang-analyzer-*" - checks += ",-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling" - p = subprocess.run(["clang-tidy", "-p", args.path, checks, entry["file"]], + checks.append("clang-analyzer-*") + checks.append("-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling") + p = subprocess.run(["clang-tidy", "-p", args.path, ",".join(checks), entry["file"]], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=entry["directory"]) -- cgit v1.2.3 From c67a85bee78db74c6889a5ca645c3763ad23d863 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers <ndesaulniers@google.com> Date: Fri, 14 Oct 2022 09:53:02 -0700 Subject: kbuild: add -fno-discard-value-names to cmd_cc_ll_c When debugging LLVM IR, it can be handy for clang to not discard value names used for local variables and parameters. Compare the generated IR. -fdiscard-value-names: define i32 @core_sys_select(i32 %0, ptr %1, ptr %2, ptr %3, ptr %4) { %6 = alloca i64 %7 = alloca %struct.poll_wqueues %8 = alloca [64 x i32] -fno-discard-value-names: define i32 @core_sys_select(i32 %n, ptr %inp, ptr %outp, ptr %exp, ptr %end_time) { %expire.i = alloca i64 %table.i = alloca %struct.poll_wqueues %stack_fds = alloca [64 x i32] The rule for generating human readable LLVM IR (.ll) is only useful as a debugging feature: $ make LLVM=1 fs/select.ll As Fangrui notes: A LLVM_ENABLE_ASSERTIONS=off build of Clang defaults to -fdiscard-value-names. A LLVM_ENABLE_ASSERTIONS=on build of Clang defaults to -fno-discard-value-names. Explicitly enable -fno-discard-value-names so that the IR always contains value names regardless of whether assertions were enabled or not. Assertions generally are not enabled in releases of clang packaged by distributions. Link: https://github.com/ClangBuiltLinux/linux/issues/1467 Reviewed-by: Nathan Chancellor <nathan@kernel.org> Reviewed-by: Fangrui Song <maskray@google.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> --- scripts/Makefile.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 22adbf89cb31..41f3602fc8de 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -140,7 +140,7 @@ $(obj)/%.symtypes : $(src)/%.c FORCE # LLVM assembly # Generate .ll files from .c quiet_cmd_cc_ll_c = CC $(quiet_modtag) $@ - cmd_cc_ll_c = $(CC) $(c_flags) -emit-llvm -S -o $@ $< + cmd_cc_ll_c = $(CC) $(c_flags) -emit-llvm -S -fno-discard-value-names -o $@ $< $(obj)/%.ll: $(src)/%.c FORCE $(call if_changed_dep,cc_ll_c) -- cgit v1.2.3