From 63e96ce050e52613eafe5c5dd90a9b81ce6eddb2 Mon Sep 17 00:00:00 2001 From: Dongliang Mu Date: Fri, 19 Jul 2024 12:13:33 +0800 Subject: scripts: fix all issues reported by pylint This patch 1) fixes all the issues (not most) reported by pylint, 2) add the functionability to tackle documents that need translation, 3) add logging to adjust the logging level and log file Signed-off-by: Dongliang Mu Reviewed-by: Yanteng Si Signed-off-by: Jonathan Corbet Link: https://lore.kernel.org/r/20240719041400.3909775-2-dzm91@hust.edu.cn --- scripts/checktransupdate.py | 214 +++++++++++++++++++++++++++++--------------- 1 file changed, 141 insertions(+), 73 deletions(-) (limited to 'scripts') diff --git a/scripts/checktransupdate.py b/scripts/checktransupdate.py index 5a0fc99e3f93..578c3fecfdfd 100755 --- a/scripts/checktransupdate.py +++ b/scripts/checktransupdate.py @@ -10,31 +10,28 @@ differences occur, report the file and commits that need to be updated. The usage is as follows: - ./scripts/checktransupdate.py -l zh_CN -This will print all the files that need to be updated in the zh_CN locale. +This will print all the files that need to be updated or translated in the zh_CN locale. - ./scripts/checktransupdate.py Documentation/translations/zh_CN/dev-tools/testing-overview.rst This will only print the status of the specified file. The output is something like: -Documentation/translations/zh_CN/dev-tools/testing-overview.rst (1 commits) +Documentation/dev-tools/kfence.rst +No translation in the locale of zh_CN + +Documentation/translations/zh_CN/dev-tools/testing-overview.rst commit 42fb9cfd5b18 ("Documentation: dev-tools: Add link to RV docs") +1 commits needs resolving in total """ import os -from argparse import ArgumentParser, BooleanOptionalAction +import time +import logging +from argparse import ArgumentParser, ArgumentTypeError, BooleanOptionalAction from datetime import datetime -flag_p_c = False -flag_p_uf = False -flag_debug = False - - -def dprint(*args, **kwargs): - if flag_debug: - print("[DEBUG] ", end="") - print(*args, **kwargs) - def get_origin_path(file_path): + """Get the origin path from the translation path""" paths = file_path.split("/") tidx = paths.index("translations") opaths = paths[:tidx] @@ -43,17 +40,16 @@ def get_origin_path(file_path): def get_latest_commit_from(file_path, commit): - command = "git log --pretty=format:%H%n%aD%n%cD%n%n%B {} -1 -- {}".format( - commit, file_path - ) - dprint(command) + """Get the latest commit from the specified commit for the specified file""" + command = f"git log --pretty=format:%H%n%aD%n%cD%n%n%B {commit} -1 -- {file_path}" + logging.debug(command) pipe = os.popen(command) result = pipe.read() result = result.split("\n") if len(result) <= 1: return None - dprint("Result: {}".format(result[0])) + logging.debug("Result: %s", result[0]) return { "hash": result[0], @@ -64,17 +60,19 @@ def get_latest_commit_from(file_path, commit): def get_origin_from_trans(origin_path, t_from_head): + """Get the latest origin commit from the translation commit""" o_from_t = get_latest_commit_from(origin_path, t_from_head["hash"]) while o_from_t is not None and o_from_t["author_date"] > t_from_head["author_date"]: o_from_t = get_latest_commit_from(origin_path, o_from_t["hash"] + "^") if o_from_t is not None: - dprint("tracked origin commit id: {}".format(o_from_t["hash"])) + logging.debug("tracked origin commit id: %s", o_from_t["hash"]) return o_from_t def get_commits_count_between(opath, commit1, commit2): - command = "git log --pretty=format:%H {}...{} -- {}".format(commit1, commit2, opath) - dprint(command) + """Get the commits count between two commits for the specified file""" + command = f"git log --pretty=format:%H {commit1}...{commit2} -- {opath}" + logging.debug(command) pipe = os.popen(command) result = pipe.read().split("\n") # filter out empty lines @@ -83,50 +81,120 @@ def get_commits_count_between(opath, commit1, commit2): def pretty_output(commit): - command = "git log --pretty='format:%h (\"%s\")' -1 {}".format(commit) - dprint(command) + """Pretty print the commit message""" + command = f"git log --pretty='format:%h (\"%s\")' -1 {commit}" + logging.debug(command) pipe = os.popen(command) return pipe.read() +def valid_commit(commit): + """Check if the commit is valid or not""" + msg = pretty_output(commit) + return "Merge tag" not in msg + def check_per_file(file_path): + """Check the translation status for the specified file""" opath = get_origin_path(file_path) if not os.path.isfile(opath): - dprint("Error: Cannot find the origin path for {}".format(file_path)) + logging.error("Cannot find the origin path for {file_path}") return o_from_head = get_latest_commit_from(opath, "HEAD") t_from_head = get_latest_commit_from(file_path, "HEAD") if o_from_head is None or t_from_head is None: - print("Error: Cannot find the latest commit for {}".format(file_path)) + logging.error("Cannot find the latest commit for %s", file_path) return o_from_t = get_origin_from_trans(opath, t_from_head) if o_from_t is None: - print("Error: Cannot find the latest origin commit for {}".format(file_path)) + logging.error("Error: Cannot find the latest origin commit for %s", file_path) return if o_from_head["hash"] == o_from_t["hash"]: - if flag_p_uf: - print("No update needed for {}".format(file_path)) - return + logging.debug("No update needed for %s", file_path) else: - print("{}".format(file_path), end="\t") + logging.info(file_path) commits = get_commits_count_between( opath, o_from_t["hash"], o_from_head["hash"] ) - print("({} commits)".format(len(commits))) - if flag_p_c: - for commit in commits: - msg = pretty_output(commit) - if "Merge tag" not in msg: - print("commit", msg) + count = 0 + for commit in commits: + if valid_commit(commit): + logging.info("commit %s", pretty_output(commit)) + count += 1 + logging.info("%d commits needs resolving in total\n", count) + + +def valid_locales(locale): + """Check if the locale is valid or not""" + script_path = os.path.dirname(os.path.abspath(__file__)) + linux_path = os.path.join(script_path, "..") + if not os.path.isdir(f"{linux_path}/Documentation/translations/{locale}"): + raise ArgumentTypeError("Invalid locale: {locale}") + return locale + + +def list_files_with_excluding_folders(folder, exclude_folders, include_suffix): + """List all files with the specified suffix in the folder and its subfolders""" + files = [] + stack = [folder] + + while stack: + pwd = stack.pop() + # filter out the exclude folders + if os.path.basename(pwd) in exclude_folders: + continue + # list all files and folders + for item in os.listdir(pwd): + ab_item = os.path.join(pwd, item) + if os.path.isdir(ab_item): + stack.append(ab_item) + else: + if ab_item.endswith(include_suffix): + files.append(ab_item) + + return files + + +class DmesgFormatter(logging.Formatter): + """Custom dmesg logging formatter""" + def format(self, record): + timestamp = time.time() + formatted_time = f"[{timestamp:>10.6f}]" + log_message = f"{formatted_time} {record.getMessage()}" + return log_message + + +def config_logging(log_level, log_file="checktransupdate.log"): + """configure logging based on the log level""" + # set up the root logger + logger = logging.getLogger() + logger.setLevel(log_level) + + # Create console handler + console_handler = logging.StreamHandler() + console_handler.setLevel(log_level) + + # Create file handler + file_handler = logging.FileHandler(log_file) + file_handler.setLevel(log_level) + + # Create formatter and add it to the handlers + formatter = DmesgFormatter() + console_handler.setFormatter(formatter) + file_handler.setFormatter(formatter) + + # Add the handler to the logger + logger.addHandler(console_handler) + logger.addHandler(file_handler) def main(): + """Main function of the script""" script_path = os.path.dirname(os.path.abspath(__file__)) linux_path = os.path.join(script_path, "..") @@ -134,62 +202,62 @@ def main(): parser.add_argument( "-l", "--locale", + default="zh_CN", + type=valid_locales, help="Locale to check when files are not specified", ) + parser.add_argument( - "--print-commits", + "--print-missing-translations", action=BooleanOptionalAction, default=True, - help="Print commits between the origin and the translation", + help="Print files that do not have translations", ) parser.add_argument( - "--print-updated-files", - action=BooleanOptionalAction, - default=False, - help="Print files that do no need to be updated", - ) + '--log', + default='INFO', + choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], + help='Set the logging level') parser.add_argument( - "--debug", - action=BooleanOptionalAction, - help="Print debug information", - default=False, - ) + '--logfile', + default='checktransupdate.log', + help='Set the logging file (default: checktransupdate.log)') parser.add_argument( "files", nargs="*", help="Files to check, if not specified, check all files" ) args = parser.parse_args() - global flag_p_c, flag_p_uf, flag_debug - flag_p_c = args.print_commits - flag_p_uf = args.print_updated_files - flag_debug = args.debug + # Configure logging based on the --log argument + log_level = getattr(logging, args.log.upper(), logging.INFO) + config_logging(log_level) - # get files related to linux path + # Get files related to linux path files = args.files if len(files) == 0: - if args.locale is not None: - files = ( - os.popen( - "find {}/Documentation/translations/{} -type f".format( - linux_path, args.locale - ) - ) - .read() - .split("\n") - ) - else: - files = ( - os.popen( - "find {}/Documentation/translations -type f".format(linux_path) - ) - .read() - .split("\n") - ) - - files = list(filter(lambda x: x != "", files)) + offical_files = list_files_with_excluding_folders( + os.path.join(linux_path, "Documentation"), ["translations", "output"], "rst" + ) + + for file in offical_files: + # split the path into parts + path_parts = file.split(os.sep) + # find the index of the "Documentation" directory + kindex = path_parts.index("Documentation") + # insert the translations and locale after the Documentation directory + new_path_parts = path_parts[:kindex + 1] + ["translations", args.locale] \ + + path_parts[kindex + 1 :] + # join the path parts back together + new_file = os.sep.join(new_path_parts) + if os.path.isfile(new_file): + files.append(new_file) + else: + if args.print_missing_translations: + logging.info(os.path.relpath(os.path.abspath(file), linux_path)) + logging.info("No translation in the locale of %s\n", args.locale) + files = list(map(lambda x: os.path.relpath(os.path.abspath(x), linux_path), files)) # cd to linux root directory -- cgit v1.2.3-70-g09d2 From 4e9903b0861c9df3464b82db4a7025863bac1897 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 28 Jul 2024 00:02:36 +0900 Subject: fortify: refactor test_fortify Makefile to fix some build problems There are some issues in the test_fortify Makefile code. Problem 1: cc-disable-warning invokes compiler dozens of times To see how many times the cc-disable-warning is evaluated, change this code: $(call cc-disable-warning,fortify-source) to: $(call cc-disable-warning,$(shell touch /tmp/fortify-$$$$)fortify-source) Then, build the kernel with CONFIG_FORTIFY_SOURCE=y. You will see a large number of '/tmp/fortify-' files created: $ ls -1 /tmp/fortify-* | wc 80 80 1600 This means the compiler was invoked 80 times just for checking the -Wno-fortify-source flag support. $(call cc-disable-warning,fortify-source) should be added to a simple variable instead of a recursive variable. Problem 2: do not recompile string.o when the test code is updated The test cases are independent of the kernel. However, when the test code is updated, $(obj)/string.o is rebuilt and vmlinux is relinked due to this dependency: $(obj)/string.o: $(obj)/$(TEST_FORTIFY_LOG) always-y is suitable for building the log files. Problem 3: redundant code clean-files += $(addsuffix .o, $(TEST_FORTIFY_LOGS)) ... is unneeded because the top Makefile globally cleans *.o files. This commit fixes these issues and makes the code readable. Signed-off-by: Masahiro Yamada Link: https://lore.kernel.org/r/20240727150302.1823750-2-masahiroy@kernel.org Signed-off-by: Kees Cook --- lib/.gitignore | 2 -- lib/Makefile | 38 +------------------------------------- lib/test_fortify/.gitignore | 2 ++ lib/test_fortify/Makefile | 28 ++++++++++++++++++++++++++++ scripts/remove-stale-files | 2 ++ 5 files changed, 33 insertions(+), 39 deletions(-) create mode 100644 lib/test_fortify/.gitignore create mode 100644 lib/test_fortify/Makefile (limited to 'scripts') diff --git a/lib/.gitignore b/lib/.gitignore index 54596b634ecb..101a4aa92fb5 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -5,5 +5,3 @@ /gen_crc32table /gen_crc64table /oid_registry_data.c -/test_fortify.log -/test_fortify/*.log diff --git a/lib/Makefile b/lib/Makefile index 322bb127b4dc..4df3c28b23b4 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -393,40 +393,4 @@ obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o obj-$(CONFIG_FIRMWARE_TABLE) += fw_table.o -# FORTIFY_SOURCE compile-time behavior tests -TEST_FORTIFY_SRCS = $(wildcard $(src)/test_fortify/*-*.c) -TEST_FORTIFY_LOGS = $(patsubst $(src)/%.c, %.log, $(TEST_FORTIFY_SRCS)) -TEST_FORTIFY_LOG = test_fortify.log - -quiet_cmd_test_fortify = TEST $@ - cmd_test_fortify = $(CONFIG_SHELL) $(srctree)/scripts/test_fortify.sh \ - $< $@ "$(NM)" $(CC) $(c_flags) \ - $(call cc-disable-warning,fortify-source) \ - -DKBUILD_EXTRA_WARN1 - -targets += $(TEST_FORTIFY_LOGS) -clean-files += $(TEST_FORTIFY_LOGS) -clean-files += $(addsuffix .o, $(TEST_FORTIFY_LOGS)) -$(obj)/test_fortify/%.log: $(src)/test_fortify/%.c \ - $(src)/test_fortify/test_fortify.h \ - $(srctree)/include/linux/fortify-string.h \ - $(srctree)/scripts/test_fortify.sh \ - FORCE - $(call if_changed,test_fortify) - -quiet_cmd_gen_fortify_log = GEN $@ - cmd_gen_fortify_log = cat /dev/null > $@ || true - -targets += $(TEST_FORTIFY_LOG) -clean-files += $(TEST_FORTIFY_LOG) -$(obj)/$(TEST_FORTIFY_LOG): $(addprefix $(obj)/, $(TEST_FORTIFY_LOGS)) FORCE - $(call if_changed,gen_fortify_log) - -# Fake dependency to trigger the fortify tests. -ifeq ($(CONFIG_FORTIFY_SOURCE),y) -$(obj)/string.o: $(obj)/$(TEST_FORTIFY_LOG) -endif - -# Some architectures define __NO_FORTIFY if __SANITIZE_ADDRESS__ is undefined. -# Pass CFLAGS_KASAN to avoid warnings. -$(foreach x, $(patsubst %.log,%.o,$(TEST_FORTIFY_LOGS)), $(eval KASAN_SANITIZE_$(x) := y)) +subdir-$(CONFIG_FORTIFY_SOURCE) += test_fortify diff --git a/lib/test_fortify/.gitignore b/lib/test_fortify/.gitignore new file mode 100644 index 000000000000..c1ba37d14b50 --- /dev/null +++ b/lib/test_fortify/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +/*.log diff --git a/lib/test_fortify/Makefile b/lib/test_fortify/Makefile new file mode 100644 index 000000000000..3907a2242ef9 --- /dev/null +++ b/lib/test_fortify/Makefile @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0 + +ccflags-y := $(call cc-disable-warning,fortify-source) + +quiet_cmd_test_fortify = TEST $@ + cmd_test_fortify = $(CONFIG_SHELL) $(srctree)/scripts/test_fortify.sh \ + $< $@ "$(NM)" $(CC) $(c_flags) -DKBUILD_EXTRA_WARN1 + +$(obj)/%.log: $(src)/%.c $(srctree)/scripts/test_fortify.sh \ + $(src)/test_fortify.h \ + $(srctree)/include/linux/fortify-string.h \ + FORCE + $(call if_changed,test_fortify) + +logs = $(patsubst $(src)/%.c, %.log, $(wildcard $(src)/*-*.c)) +targets += $(logs) + +quiet_cmd_gen_fortify_log = CAT $@ + cmd_gen_fortify_log = cat $(or $(real-prereqs),/dev/null) > $@ + +$(obj)/test_fortify.log: $(addprefix $(obj)/, $(logs)) FORCE + $(call if_changed,gen_fortify_log) + +always-y += test_fortify.log + +# Some architectures define __NO_FORTIFY if __SANITIZE_ADDRESS__ is undefined. +# Pass CFLAGS_KASAN to avoid warnings. +KASAN_SANITIZE := y diff --git a/scripts/remove-stale-files b/scripts/remove-stale-files index f38d26b78c2a..8fc55a749ccc 100755 --- a/scripts/remove-stale-files +++ b/scripts/remove-stale-files @@ -21,3 +21,5 @@ set -e # then will be really dead and removed from the code base entirely. rm -f *.spec + +rm -f lib/test_fortify.log -- cgit v1.2.3-70-g09d2 From 5a8d0c46c9e024bed4805a9335fe6124d8a78d3a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 28 Jul 2024 00:02:37 +0900 Subject: fortify: move test_fortify.sh to lib/test_fortify/ This script is only used in lib/test_fortify/. There is no reason to keep it in scripts/. Signed-off-by: Masahiro Yamada Link: https://lore.kernel.org/r/20240727150302.1823750-3-masahiroy@kernel.org Signed-off-by: Kees Cook --- MAINTAINERS | 1 - lib/test_fortify/Makefile | 4 +-- lib/test_fortify/test_fortify.sh | 66 ++++++++++++++++++++++++++++++++++++++++ scripts/test_fortify.sh | 66 ---------------------------------------- 4 files changed, 68 insertions(+), 69 deletions(-) create mode 100644 lib/test_fortify/test_fortify.sh delete mode 100644 scripts/test_fortify.sh (limited to 'scripts') diff --git a/MAINTAINERS b/MAINTAINERS index 8766f3e5e87e..36c0af94cf08 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8772,7 +8772,6 @@ F: include/linux/fortify-string.h F: lib/fortify_kunit.c F: lib/memcpy_kunit.c F: lib/test_fortify/* -F: scripts/test_fortify.sh K: \b__NO_FORTIFY\b FPGA DFL DRIVERS diff --git a/lib/test_fortify/Makefile b/lib/test_fortify/Makefile index 3907a2242ef9..1826172c32d4 100644 --- a/lib/test_fortify/Makefile +++ b/lib/test_fortify/Makefile @@ -3,10 +3,10 @@ ccflags-y := $(call cc-disable-warning,fortify-source) quiet_cmd_test_fortify = TEST $@ - cmd_test_fortify = $(CONFIG_SHELL) $(srctree)/scripts/test_fortify.sh \ + cmd_test_fortify = $(CONFIG_SHELL) $(src)/test_fortify.sh \ $< $@ "$(NM)" $(CC) $(c_flags) -DKBUILD_EXTRA_WARN1 -$(obj)/%.log: $(src)/%.c $(srctree)/scripts/test_fortify.sh \ +$(obj)/%.log: $(src)/%.c $(src)/test_fortify.sh \ $(src)/test_fortify.h \ $(srctree)/include/linux/fortify-string.h \ FORCE diff --git a/lib/test_fortify/test_fortify.sh b/lib/test_fortify/test_fortify.sh new file mode 100644 index 000000000000..c2688ab8281d --- /dev/null +++ b/lib/test_fortify/test_fortify.sh @@ -0,0 +1,66 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +set -e + +# Argument 1: Source file to build. +IN="$1" +shift +# Extract just the filename for error messages below. +FILE="${IN##*/}" +# Extract the function name for error messages below. +FUNC="${FILE#*-}" +FUNC="${FUNC%%-*}" +FUNC="${FUNC%%.*}" +# Extract the symbol to test for in build/symbol test below. +WANT="__${FILE%%-*}" + +# Argument 2: Where to write the build log. +OUT="$1" +shift +TMP="${OUT}.tmp" + +# Argument 3: Path to "nm" tool. +NM="$1" +shift + +# Remaining arguments are: $(CC) $(c_flags) + +# Clean up temporary file at exit. +__cleanup() { + rm -f "$TMP" +} +trap __cleanup EXIT + +# Function names in warnings are wrapped in backticks under UTF-8 locales. +# Run the commands with LANG=C so that grep output will not change. +export LANG=C + +status= +# Attempt to build a source that is expected to fail with a specific warning. +if "$@" -Werror -c "$IN" -o "$OUT".o 2> "$TMP" ; then + # If the build succeeds, either the test has failed or the + # warning may only happen at link time (Clang). In that case, + # make sure the expected symbol is unresolved in the symbol list. + # If so, FORTIFY is working for this case. + if ! $NM -A "$OUT".o | grep -m1 "\bU ${WANT}$" >>"$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: + # ./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 + +if [ -n "$status" ]; then + # Report on failure results, including compilation warnings. + echo "$status" | tee "$OUT" >&2 +else + # Report on good results, and save any compilation output to log. + echo "ok: unsafe ${FUNC}() usage correctly detected with '$WANT' in $IN" >"$OUT" +fi +cat "$TMP" >>"$OUT" diff --git a/scripts/test_fortify.sh b/scripts/test_fortify.sh deleted file mode 100644 index c2688ab8281d..000000000000 --- a/scripts/test_fortify.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0-only -set -e - -# Argument 1: Source file to build. -IN="$1" -shift -# Extract just the filename for error messages below. -FILE="${IN##*/}" -# Extract the function name for error messages below. -FUNC="${FILE#*-}" -FUNC="${FUNC%%-*}" -FUNC="${FUNC%%.*}" -# Extract the symbol to test for in build/symbol test below. -WANT="__${FILE%%-*}" - -# Argument 2: Where to write the build log. -OUT="$1" -shift -TMP="${OUT}.tmp" - -# Argument 3: Path to "nm" tool. -NM="$1" -shift - -# Remaining arguments are: $(CC) $(c_flags) - -# Clean up temporary file at exit. -__cleanup() { - rm -f "$TMP" -} -trap __cleanup EXIT - -# Function names in warnings are wrapped in backticks under UTF-8 locales. -# Run the commands with LANG=C so that grep output will not change. -export LANG=C - -status= -# Attempt to build a source that is expected to fail with a specific warning. -if "$@" -Werror -c "$IN" -o "$OUT".o 2> "$TMP" ; then - # If the build succeeds, either the test has failed or the - # warning may only happen at link time (Clang). In that case, - # make sure the expected symbol is unresolved in the symbol list. - # If so, FORTIFY is working for this case. - if ! $NM -A "$OUT".o | grep -m1 "\bU ${WANT}$" >>"$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: - # ./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 - -if [ -n "$status" ]; then - # Report on failure results, including compilation warnings. - echo "$status" | tee "$OUT" >&2 -else - # Report on good results, and save any compilation output to log. - echo "ok: unsafe ${FUNC}() usage correctly detected with '$WANT' in $IN" >"$OUT" -fi -cat "$TMP" >>"$OUT" -- cgit v1.2.3-70-g09d2 From 9b97452bcce77f8ef29b20c9662d95988b5990e4 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Thu, 25 Jul 2024 12:18:41 +0200 Subject: coccinelle: Add rules to find str_up_down() replacements Add rules for finding places where str_up_down() can be used. This currently finds over 20 locations. Signed-off-by: Michal Wajdeczko Link: https://lore.kernel.org/r/20240725101841.574-2-michal.wajdeczko@intel.com Signed-off-by: Kees Cook --- scripts/coccinelle/api/string_choices.cocci | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'scripts') diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index a71966c0494e..d517f6bc850b 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -39,3 +39,26 @@ e << str_plural_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_plural(%s)" % e) + +@str_up_down depends on patch@ +expression E; +@@ +( +- ((E) ? "up" : "down") ++ str_up_down(E) +) + +@str_up_down_r depends on !patch exists@ +expression E; +position P; +@@ +( +* ((E@P) ? "up" : "down") +) + +@script:python depends on report@ +p << str_up_down_r.P; +e << str_up_down_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_up_down(%s)" % e) -- cgit v1.2.3-70-g09d2 From 0336f898881ae13b92dfd8b72e69ed1246eac762 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 12 Aug 2024 11:36:38 -0700 Subject: coccinelle: Add rules to find str_down_up() replacements As done with str_up_down(), add checks for str_down_up() opportunities. 5 cases currently exist in the tree. Suggested-by: Andy Shevchenko Link: https://lore.kernel.org/r/20240812183637.work.999-kees@kernel.org Reviewed-by: Andy Shevchenko Signed-off-by: Kees Cook --- scripts/coccinelle/api/string_choices.cocci | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'scripts') diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index d517f6bc850b..5e729f187f22 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -62,3 +62,26 @@ e << str_up_down_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_up_down(%s)" % e) + +@str_down_up depends on patch@ +expression E; +@@ +( +- ((E) ? "down" : "up") ++ str_down_up(E) +) + +@str_down_up_r depends on !patch exists@ +expression E; +position P; +@@ +( +* ((E@P) ? "down" : "up") +) + +@script:python depends on report@ +p << str_down_up_r.P; +e << str_down_up_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_down_up(%s)" % e) -- cgit v1.2.3-70-g09d2 From d2a97be34548fc5643b4e9536ac8789d839f7374 Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Thu, 15 Aug 2024 12:23:05 -0600 Subject: scripts/dtc: Update to upstream version v1.7.0-95-gbcd02b523429 Some pending overlay additions need the graph check fix. This adds the following commits from upstream: bcd02b523429 fdtoverlay: remove wrong singular article in a comment 84b056a89d3c checks: relax graph checks for overlays Signed-off-by: Rob Herring (Arm) --- scripts/dtc/checks.c | 16 ++++++++++++---- scripts/dtc/fdtoverlay.c | 2 +- scripts/dtc/version_gen.h | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c index 10fb63894369..6e06aeab5503 100644 --- a/scripts/dtc/checks.c +++ b/scripts/dtc/checks.c @@ -1826,10 +1826,14 @@ static void check_graph_port(struct check *c, struct dt_info *dti, if (node->bus != &graph_port_bus) return; + check_graph_reg(c, dti, node); + + /* skip checks below for overlays */ + if (dti->dtsflags & DTSF_PLUGIN) + return; + if (!strprefixeq(node->name, node->basenamelen, "port")) FAIL(c, dti, node, "graph port node name should be 'port'"); - - check_graph_reg(c, dti, node); } WARNING(graph_port, check_graph_port, NULL, &graph_nodes); @@ -1864,11 +1868,15 @@ static void check_graph_endpoint(struct check *c, struct dt_info *dti, if (!node->parent || node->parent->bus != &graph_port_bus) return; + check_graph_reg(c, dti, node); + + /* skip checks below for overlays */ + if (dti->dtsflags & DTSF_PLUGIN) + return; + if (!strprefixeq(node->name, node->basenamelen, "endpoint")) FAIL(c, dti, node, "graph endpoint node name should be 'endpoint'"); - check_graph_reg(c, dti, node); - remote_node = get_remote_endpoint(c, dti, node); if (!remote_node) return; diff --git a/scripts/dtc/fdtoverlay.c b/scripts/dtc/fdtoverlay.c index 4eba0460f240..699b4f616502 100644 --- a/scripts/dtc/fdtoverlay.c +++ b/scripts/dtc/fdtoverlay.c @@ -48,7 +48,7 @@ static void *apply_one(char *base, const char *overlay, size_t *buf_len, int ret; /* - * We take a copies first, because a failed apply can trash + * We take copies first, because a failed apply can trash * both the base blob and the overlay */ tmpo = xmalloc(fdt_totalsize(overlay)); diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h index 4c5e17639d2b..bf81ce593685 100644 --- a/scripts/dtc/version_gen.h +++ b/scripts/dtc/version_gen.h @@ -1 +1 @@ -#define DTC_VERSION "DTC 1.7.0-g1df7b047" +#define DTC_VERSION "DTC 1.7.0-gbcd02b52" -- cgit v1.2.3-70-g09d2 From 284a3ac4a96c619af269dfbdef5431a9a2a34d3b Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Thu, 25 Jul 2024 20:33:19 +0200 Subject: x86/rust: support MITIGATION_RETPOLINE Support `MITIGATION_RETPOLINE` by enabling the target features that Clang does. The existing target feature being enabled was a leftover from our old `rust` branch, and it is not enough: the target feature `retpoline-external-thunk` only implies `retpoline-indirect-calls`, but not `retpoline-indirect-branches` (see LLVM's `X86.td`), unlike Clang's flag of the same name `-mretpoline-external-thunk` which does imply both (see Clang's `lib/Driver/ToolChains/Arch/X86.cpp`). Without this, `objtool` would complain if enabled for Rust, e.g.: rust/core.o: warning: objtool: _R...escape_default+0x13: indirect jump found in RETPOLINE build In addition, change the comment to note that LLVM is the one disabling jump tables when retpoline is enabled, thus we do not need to use `-Zno-jump-tables` for Rust here -- see commit c58f2166ab39 ("Introduce the "retpoline" x86 mitigation technique ...") [1]: The goal is simple: avoid generating code which contains an indirect branch that could have its prediction poisoned by an attacker. In many cases, the compiler can simply use directed conditional branches and a small search tree. LLVM already has support for lowering switches in this way and the first step of this patch is to disable jump-table lowering of switches and introduce a pass to rewrite explicit indirectbr sequences into a switch over integers. As well as a live example at [2]. These should be eventually enabled via `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated flag) [3]. Cc: Daniel Borkmann Link: https://github.com/llvm/llvm-project/commit/c58f2166ab3987f37cb0d7815b561bff5a20a69a [1] Link: https://godbolt.org/z/G4YPr58qG [2] Link: https://github.com/rust-lang/rust/issues/116852 [3] Reviewed-by: Gary Guo Tested-by: Alice Ryhl Tested-by: Benno Lossin Link: https://github.com/Rust-for-Linux/linux/issues/945 Link: https://lore.kernel.org/r/20240725183325.122827-3-ojeda@kernel.org Signed-off-by: Miguel Ojeda --- arch/x86/Makefile | 2 +- scripts/generate_rust_target.rs | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 801fd85c3ef6..e8214bff1aeb 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -220,7 +220,7 @@ ifdef CONFIG_MITIGATION_RETPOLINE KBUILD_CFLAGS += $(RETPOLINE_CFLAGS) # Additionally, avoid generating expensive indirect jumps which # are subject to retpolines for small number of switch cases. - # clang turns off jump table generation by default when under + # LLVM turns off jump table generation by default when under # retpoline builds, however, gcc does not for x86. This has # only been fixed starting from gcc stable version 8.4.0 and # onwards, but not for older ones. See gcc bug #86952. diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs index 404edf7587e0..836fdf622c2d 100644 --- a/scripts/generate_rust_target.rs +++ b/scripts/generate_rust_target.rs @@ -164,7 +164,14 @@ fn main() { ); let mut features = "-mmx,+soft-float".to_string(); if cfg.has("MITIGATION_RETPOLINE") { + // The kernel uses `-mretpoline-external-thunk` (for Clang), which Clang maps to the + // target feature of the same name plus the other two target features in + // `clang/lib/Driver/ToolChains/Arch/X86.cpp`. These should be eventually enabled via + // `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated + // flag); see https://github.com/rust-lang/rust/issues/116852. features += ",+retpoline-external-thunk"; + features += ",+retpoline-indirect-branches"; + features += ",+retpoline-indirect-calls"; } ts.push("features", features); ts.push("llvm-target", "x86_64-linux-gnu"); -- cgit v1.2.3-70-g09d2 From fc582dfc1f20476cab9d43d0ee8ec0a6bfe13485 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Thu, 25 Jul 2024 20:33:21 +0200 Subject: x86/rust: support MITIGATION_SLS Support `MITIGATION_SLS` by enabling the target features that Clang does. Without this, `objtool` would complain if enabled for Rust, e.g.: rust/core.o: warning: objtool: _R...next_up+0x44: missing int3 after ret These should be eventually enabled via `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated flag) [1]. Link: https://github.com/rust-lang/rust/issues/116851 [1] Reviewed-by: Gary Guo Tested-by: Alice Ryhl Tested-by: Benno Lossin Link: https://lore.kernel.org/r/20240725183325.122827-5-ojeda@kernel.org Signed-off-by: Miguel Ojeda --- scripts/generate_rust_target.rs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'scripts') diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs index 836fdf622c2d..863720777313 100644 --- a/scripts/generate_rust_target.rs +++ b/scripts/generate_rust_target.rs @@ -173,6 +173,14 @@ fn main() { features += ",+retpoline-indirect-branches"; features += ",+retpoline-indirect-calls"; } + if cfg.has("MITIGATION_SLS") { + // The kernel uses `-mharden-sls=all`, which Clang maps to both these target features in + // `clang/lib/Driver/ToolChains/Arch/X86.cpp`. These should be eventually enabled via + // `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated + // flag); see https://github.com/rust-lang/rust/issues/116851. + features += ",+harden-sls-ijmp"; + features += ",+harden-sls-ret"; + } ts.push("features", features); ts.push("llvm-target", "x86_64-linux-gnu"); ts.push("target-pointer-width", "64"); -- cgit v1.2.3-70-g09d2 From c4d7f546dd9aa9780716cdb07416ca97264dce43 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Thu, 25 Jul 2024 20:33:23 +0200 Subject: objtool/kbuild/rust: enable objtool for Rust Now that we should be `objtool`-warning free, enable `objtool` for Rust too. Before this patch series, we were already getting warnings under e.g. IBT builds, since those would see Rust code via `vmlinux.o`. Tested-by: Alice Ryhl Tested-by: Benno Lossin Reviewed-by: Gary Guo Link: https://lore.kernel.org/r/20240725183325.122827-7-ojeda@kernel.org [ Solved trivial conflict. - Miguel ] Signed-off-by: Miguel Ojeda --- rust/Makefile | 22 ++++++++++++++-------- scripts/Makefile.build | 9 +++++++-- 2 files changed, 21 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/rust/Makefile b/rust/Makefile index 07e670d1b6d5..99204e33f1dd 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -344,7 +344,8 @@ quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L --crate-type rlib -L$(objtree)/$(obj) \ --crate-name $(patsubst %.o,%,$(notdir $@)) $< \ --sysroot=/dev/null \ - $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) + $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) \ + $(cmd_objtool) rust-analyzer: $(Q)$(srctree)/scripts/generate_rust_analyzer.py \ @@ -366,44 +367,49 @@ ifneq ($(or $(CONFIG_ARM64),$(and $(CONFIG_RISCV),$(CONFIG_64BIT))),) __ashlti3 __lshrti3 endif +define rule_rustc_library + $(call cmd_and_fixdep,rustc_library) + $(call cmd,gen_objtooldep) +endef + $(obj)/core.o: private skip_clippy = 1 $(obj)/core.o: private skip_flags = -Wunreachable_pub $(obj)/core.o: private rustc_objcopy = $(foreach sym,$(redirect-intrinsics),--redefine-sym $(sym)=__rust$(sym)) $(obj)/core.o: private rustc_target_flags = $(core-cfgs) $(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs FORCE - +$(call if_changed_dep,rustc_library) + +$(call if_changed_rule,rustc_library) ifneq ($(or $(CONFIG_X86_64),$(CONFIG_X86_32)),) $(obj)/core.o: scripts/target.json endif $(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) + +$(call if_changed_rule,rustc_library) $(obj)/alloc.o: private skip_clippy = 1 $(obj)/alloc.o: private skip_flags = -Wunreachable_pub $(obj)/alloc.o: private rustc_target_flags = $(alloc-cfgs) $(obj)/alloc.o: $(RUST_LIB_SRC)/alloc/src/lib.rs $(obj)/compiler_builtins.o FORCE - +$(call if_changed_dep,rustc_library) + +$(call if_changed_rule,rustc_library) $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE - +$(call if_changed_dep,rustc_library) + +$(call if_changed_rule,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) + +$(call if_changed_rule,rustc_library) $(obj)/uapi.o: $(src)/uapi/lib.rs \ $(obj)/compiler_builtins.o \ $(obj)/uapi/uapi_generated.rs FORCE - +$(call if_changed_dep,rustc_library) + +$(call if_changed_rule,rustc_library) $(obj)/kernel.o: private rustc_target_flags = --extern alloc \ --extern build_error --extern macros --extern bindings --extern uapi $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/alloc.o $(obj)/build_error.o \ $(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE - +$(call if_changed_dep,rustc_library) + +$(call if_changed_rule,rustc_library) endif # CONFIG_RUST diff --git a/scripts/Makefile.build b/scripts/Makefile.build index efacca63c897..72b1232b1f7d 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -288,10 +288,15 @@ rust_common_cmd = \ # would not match each other. quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ - cmd_rustc_o_rs = $(rust_common_cmd) --emit=obj=$@ $< + cmd_rustc_o_rs = $(rust_common_cmd) --emit=obj=$@ $< $(cmd_objtool) + +define rule_rustc_o_rs + $(call cmd_and_fixdep,rustc_o_rs) + $(call cmd,gen_objtooldep) +endef $(obj)/%.o: $(obj)/%.rs FORCE - +$(call if_changed_dep,rustc_o_rs) + +$(call if_changed_rule,rustc_o_rs) quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ cmd_rustc_rsi_rs = \ -- cgit v1.2.3-70-g09d2 From c7ff693fa2094ba0a9d0a20feb4ab1658eff9c33 Mon Sep 17 00:00:00 2001 From: Petr Pavlu Date: Mon, 22 Jul 2024 11:06:21 +0200 Subject: module: Split modules_install compression and in-kernel decompression The kernel configuration allows specifying a module compression mode. If one is selected then each module gets compressed during 'make modules_install' and additionally one can also enable support for a respective direct in-kernel decompression support. This means that the decompression support cannot be enabled without the automatic compression. Some distributions, such as the (open)SUSE family, use a signer service for modules. A build runs on a worker machine but signing is done by a separate locked-down server that is in possession of the signing key. The build invokes 'make modules_install' to create a modules tree, collects information about the modules, asks the signer service for their signature, appends each signature to the respective module and compresses all modules. When using this arrangment, the 'make modules_install' step produces unsigned+uncompressed modules and the distribution's own build recipe takes care of signing and compression later. The signing support can be currently enabled without automatically signing modules during 'make modules_install'. However, the in-kernel decompression support can be selected only after first enabling automatic compression during this step. To allow only enabling the in-kernel decompression support without the automatic compression during 'make modules_install', separate the compression options similarly to the signing options, as follows: > Enable loadable module support [*] Module compression Module compression type (GZIP) ---> [*] Automatically compress all modules [ ] Support in-kernel module decompression * "Module compression" (MODULE_COMPRESS) is a new main switch for the compression/decompression support. It replaces MODULE_COMPRESS_NONE. * "Module compression type" (MODULE_COMPRESS_) chooses the compression type, one of GZ, XZ, ZSTD. * "Automatically compress all modules" (MODULE_COMPRESS_ALL) is a new option to enable module compression during 'make modules_install'. It defaults to Y. * "Support in-kernel module decompression" (MODULE_DECOMPRESS) enables in-kernel decompression. Signed-off-by: Petr Pavlu Acked-by: Masahiro Yamada Signed-off-by: Luis Chamberlain --- kernel/module/Kconfig | 61 ++++++++++++++++++++++++------------------------ scripts/Makefile.modinst | 2 ++ 2 files changed, 33 insertions(+), 30 deletions(-) (limited to 'scripts') diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig index 4047b6d48255..bb7f7930fef6 100644 --- a/kernel/module/Kconfig +++ b/kernel/module/Kconfig @@ -278,64 +278,65 @@ config MODULE_SIG_HASH default "sha3-384" if MODULE_SIG_SHA3_384 default "sha3-512" if MODULE_SIG_SHA3_512 -choice - prompt "Module compression mode" +config MODULE_COMPRESS + bool "Module compression" help - This option allows you to choose the algorithm which will be used to - compress modules when 'make modules_install' is run. (or, you can - choose to not compress modules at all.) - - External modules will also be compressed in the same way during the - installation. - - For modules inside an initrd or initramfs, it's more efficient to - compress the whole initrd or initramfs instead. - + Enable module compression to reduce on-disk size of module binaries. This is fully compatible with signed modules. - Please note that the tool used to load modules needs to support the - corresponding algorithm. module-init-tools MAY support gzip, and kmod - MAY support gzip, xz and zstd. + The tool used to work with modules needs to support the selected + compression type. kmod MAY support gzip, xz and zstd. Other tools + might have a limited selection of the supported types. - Your build system needs to provide the appropriate compression tool - to compress the modules. + Note that for modules inside an initrd or initramfs, it's more + efficient to compress the whole ramdisk instead. - If in doubt, select 'None'. + If unsure, say N. -config MODULE_COMPRESS_NONE - bool "None" +choice + prompt "Module compression type" + depends on MODULE_COMPRESS help - Do not compress modules. The installed modules are suffixed - with .ko. + Choose the supported algorithm for module compression. config MODULE_COMPRESS_GZIP bool "GZIP" help - Compress modules with GZIP. The installed modules are suffixed - with .ko.gz. + Support modules compressed with GZIP. The installed modules are + suffixed with .ko.gz. config MODULE_COMPRESS_XZ bool "XZ" help - Compress modules with XZ. The installed modules are suffixed - with .ko.xz. + Support modules compressed with XZ. The installed modules are + suffixed with .ko.xz. config MODULE_COMPRESS_ZSTD bool "ZSTD" help - Compress modules with ZSTD. The installed modules are suffixed - with .ko.zst. + Support modules compressed with ZSTD. The installed modules are + suffixed with .ko.zst. endchoice +config MODULE_COMPRESS_ALL + bool "Automatically compress all modules" + default y + depends on MODULE_COMPRESS + help + Compress all modules during 'make modules_install'. + + Your build system needs to provide the appropriate compression tool + for the selected compression type. External modules will also be + compressed in the same way during the installation. + config MODULE_DECOMPRESS bool "Support in-kernel module decompression" - depends on MODULE_COMPRESS_GZIP || MODULE_COMPRESS_XZ || MODULE_COMPRESS_ZSTD + depends on MODULE_COMPRESS select ZLIB_INFLATE if MODULE_COMPRESS_GZIP select XZ_DEC if MODULE_COMPRESS_XZ select ZSTD_DECOMPRESS if MODULE_COMPRESS_ZSTD help - Support for decompressing kernel modules by the kernel itself instead of relying on userspace to perform this task. Useful when load pinning security policy is enabled. diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 0afd75472679..bce4a9adb893 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -51,9 +51,11 @@ $(foreach x, % :, $(if $(findstring $x, $(dst)), \ $(error module installation path cannot contain '$x'))) suffix-y := +ifdef CONFIG_MODULE_COMPRESS_ALL suffix-$(CONFIG_MODULE_COMPRESS_GZIP) := .gz suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz suffix-$(CONFIG_MODULE_COMPRESS_ZSTD) := .zst +endif modules := $(patsubst $(extmod_prefix)%.o, $(dst)/%.ko$(suffix-y), $(modules)) install-$(CONFIG_MODULES) += $(modules) -- cgit v1.2.3-70-g09d2 From ba199dc909a20fe62270ae4e93f263987bb9d119 Mon Sep 17 00:00:00 2001 From: Deven Bowers Date: Fri, 2 Aug 2024 23:08:31 -0700 Subject: scripts: add boot policy generation program Enables an IPE policy to be enforced from kernel start, enabling access control based on trust from kernel startup. This is accomplished by transforming an IPE policy indicated by CONFIG_IPE_BOOT_POLICY into a c-string literal that is parsed at kernel startup as an unsigned policy. Signed-off-by: Deven Bowers Signed-off-by: Fan Wu Signed-off-by: Paul Moore --- scripts/Makefile | 1 + scripts/ipe/Makefile | 2 + scripts/ipe/polgen/.gitignore | 2 + scripts/ipe/polgen/Makefile | 5 ++ scripts/ipe/polgen/polgen.c | 145 ++++++++++++++++++++++++++++++++++++++++++ security/ipe/.gitignore | 2 + security/ipe/Kconfig | 10 +++ security/ipe/Makefile | 11 ++++ security/ipe/fs.c | 8 +++ security/ipe/ipe.c | 12 ++++ 10 files changed, 198 insertions(+) create mode 100644 scripts/ipe/Makefile create mode 100644 scripts/ipe/polgen/.gitignore create mode 100644 scripts/ipe/polgen/Makefile create mode 100644 scripts/ipe/polgen/polgen.c create mode 100644 security/ipe/.gitignore (limited to 'scripts') diff --git a/scripts/Makefile b/scripts/Makefile index dccef663ca82..6bcda4b9d054 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -55,6 +55,7 @@ targets += module.lds subdir-$(CONFIG_GCC_PLUGINS) += gcc-plugins subdir-$(CONFIG_MODVERSIONS) += genksyms subdir-$(CONFIG_SECURITY_SELINUX) += selinux +subdir-$(CONFIG_SECURITY_IPE) += ipe # Let clean descend into subdirs subdir- += basic dtc gdb kconfig mod diff --git a/scripts/ipe/Makefile b/scripts/ipe/Makefile new file mode 100644 index 000000000000..e87553fbb8d6 --- /dev/null +++ b/scripts/ipe/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +subdir-y := polgen diff --git a/scripts/ipe/polgen/.gitignore b/scripts/ipe/polgen/.gitignore new file mode 100644 index 000000000000..b6f05cf3dc0e --- /dev/null +++ b/scripts/ipe/polgen/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +polgen diff --git a/scripts/ipe/polgen/Makefile b/scripts/ipe/polgen/Makefile new file mode 100644 index 000000000000..c20456a2f2e9 --- /dev/null +++ b/scripts/ipe/polgen/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 +hostprogs-always-y := polgen +HOST_EXTRACFLAGS += \ + -I$(srctree)/include \ + -I$(srctree)/include/uapi \ diff --git a/scripts/ipe/polgen/polgen.c b/scripts/ipe/polgen/polgen.c new file mode 100644 index 000000000000..c6283b3ff006 --- /dev/null +++ b/scripts/ipe/polgen/polgen.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved. + */ + +#include +#include +#include +#include +#include + +static void usage(const char *const name) +{ + printf("Usage: %s OutputFile (PolicyFile)\n", name); + exit(EINVAL); +} + +static int policy_to_buffer(const char *pathname, char **buffer, size_t *size) +{ + size_t fsize; + size_t read; + char *lbuf; + int rc = 0; + FILE *fd; + + fd = fopen(pathname, "r"); + if (!fd) { + rc = errno; + goto out; + } + + fseek(fd, 0, SEEK_END); + fsize = ftell(fd); + rewind(fd); + + lbuf = malloc(fsize); + if (!lbuf) { + rc = ENOMEM; + goto out_close; + } + + read = fread((void *)lbuf, sizeof(*lbuf), fsize, fd); + if (read != fsize) { + rc = -1; + goto out_free; + } + + *buffer = lbuf; + *size = fsize; + fclose(fd); + + return rc; + +out_free: + free(lbuf); +out_close: + fclose(fd); +out: + return rc; +} + +static int write_boot_policy(const char *pathname, const char *buf, size_t size) +{ + int rc = 0; + FILE *fd; + size_t i; + + fd = fopen(pathname, "w"); + if (!fd) { + rc = errno; + goto err; + } + + fprintf(fd, "/* This file is automatically generated."); + fprintf(fd, " Do not edit. */\n"); + fprintf(fd, "#include \n"); + fprintf(fd, "\nextern const char *const ipe_boot_policy;\n\n"); + fprintf(fd, "const char *const ipe_boot_policy =\n"); + + if (!buf || size == 0) { + fprintf(fd, "\tNULL;\n"); + fclose(fd); + return 0; + } + + fprintf(fd, "\t\""); + + for (i = 0; i < size; ++i) { + switch (buf[i]) { + case '"': + fprintf(fd, "\\\""); + break; + case '\'': + fprintf(fd, "'"); + break; + case '\n': + fprintf(fd, "\\n\"\n\t\""); + break; + case '\\': + fprintf(fd, "\\\\"); + break; + case '\t': + fprintf(fd, "\\t"); + break; + case '\?': + fprintf(fd, "\\?"); + break; + default: + fprintf(fd, "%c", buf[i]); + } + } + fprintf(fd, "\";\n"); + fclose(fd); + + return 0; + +err: + if (fd) + fclose(fd); + return rc; +} + +int main(int argc, const char *const argv[]) +{ + char *policy = NULL; + size_t len = 0; + int rc = 0; + + if (argc < 2) + usage(argv[0]); + + if (argc > 2) { + rc = policy_to_buffer(argv[2], &policy, &len); + if (rc != 0) + goto cleanup; + } + + rc = write_boot_policy(argv[1], policy, len); +cleanup: + if (policy) + free(policy); + if (rc != 0) + perror("An error occurred during policy conversion: "); + return rc; +} diff --git a/security/ipe/.gitignore b/security/ipe/.gitignore new file mode 100644 index 000000000000..6e9939be1cb7 --- /dev/null +++ b/security/ipe/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +boot_policy.c diff --git a/security/ipe/Kconfig b/security/ipe/Kconfig index 6bc487b689e0..fccc69e66af1 100644 --- a/security/ipe/Kconfig +++ b/security/ipe/Kconfig @@ -21,6 +21,16 @@ menuconfig SECURITY_IPE If unsure, answer N. if SECURITY_IPE +config IPE_BOOT_POLICY + string "Integrity policy to apply on system startup" + help + This option specifies a filepath to an IPE policy that is compiled + into the kernel. This policy will be enforced until a policy update + is deployed via the $securityfs/ipe/policies/$policy_name/active + interface. + + If unsure, leave blank. + menu "IPE Trust Providers" config IPE_PROP_DM_VERITY diff --git a/security/ipe/Makefile b/security/ipe/Makefile index e1019bb9f0f3..70eea140306b 100644 --- a/security/ipe/Makefile +++ b/security/ipe/Makefile @@ -5,7 +5,16 @@ # Makefile for building the IPE module as part of the kernel tree. # +quiet_cmd_polgen = IPE_POL $(2) + cmd_polgen = scripts/ipe/polgen/polgen security/ipe/boot_policy.c $(2) + +targets += boot_policy.c + +$(obj)/boot_policy.c: scripts/ipe/polgen/polgen $(CONFIG_IPE_BOOT_POLICY) FORCE + $(call if_changed,polgen,$(CONFIG_IPE_BOOT_POLICY)) + obj-$(CONFIG_SECURITY_IPE) += \ + boot_policy.o \ digest.o \ eval.o \ hooks.o \ @@ -15,3 +24,5 @@ obj-$(CONFIG_SECURITY_IPE) += \ policy_fs.o \ policy_parser.o \ audit.o \ + +clean-files := boot_policy.c \ diff --git a/security/ipe/fs.c b/security/ipe/fs.c index b52fb6023904..5b6d19fb844a 100644 --- a/security/ipe/fs.c +++ b/security/ipe/fs.c @@ -190,6 +190,7 @@ static const struct file_operations enforce_fops = { static int __init ipe_init_securityfs(void) { int rc = 0; + struct ipe_policy *ap; if (!ipe_enabled) return -EOPNOTSUPP; @@ -220,6 +221,13 @@ static int __init ipe_init_securityfs(void) goto err; } + ap = rcu_access_pointer(ipe_active_policy); + if (ap) { + rc = ipe_new_policyfs_node(ap); + if (rc) + goto err; + } + np = securityfs_create_file("new_policy", 0200, root, NULL, &np_fops); if (IS_ERR(np)) { rc = PTR_ERR(np); diff --git a/security/ipe/ipe.c b/security/ipe/ipe.c index b410db0b486c..e19a18078cf3 100644 --- a/security/ipe/ipe.c +++ b/security/ipe/ipe.c @@ -9,6 +9,7 @@ #include "hooks.h" #include "eval.h" +extern const char *const ipe_boot_policy; bool ipe_enabled; static struct lsm_blob_sizes ipe_blobs __ro_after_init = { @@ -74,9 +75,20 @@ static struct security_hook_list ipe_hooks[] __ro_after_init = { */ static int __init ipe_init(void) { + struct ipe_policy *p = NULL; + security_add_hooks(ipe_hooks, ARRAY_SIZE(ipe_hooks), &ipe_lsmid); ipe_enabled = true; + if (ipe_boot_policy) { + p = ipe_new_policy(ipe_boot_policy, strlen(ipe_boot_policy), + NULL, 0); + if (IS_ERR(p)) + return PTR_ERR(p); + + rcu_assign_pointer(ipe_active_policy, p); + } + return 0; } -- cgit v1.2.3-70-g09d2 From c6945acad7a14b6afb390a4afc1d354ef5413ea6 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Tue, 30 Jul 2024 09:26:24 +0000 Subject: rust: support arrays in target JSON Some configuration options such as the supported sanitizer list are arrays. To support using Rust with sanitizers on x86, we must update the target.json generator to support this case. The Push trait is removed in favor of the From trait because the Push trait doesn't work well in the nested case where you are not really pushing values to a TargetSpec. Signed-off-by: Matthew Maurer Signed-off-by: Alice Ryhl Reviewed-by: Gary Guo Tested-by: Gatlin Newhouse Link: https://lore.kernel.org/r/20240730-target-json-arrays-v1-1-2b376fd0ecf4@google.com Signed-off-by: Miguel Ojeda --- scripts/generate_rust_target.rs | 82 ++++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 29 deletions(-) (limited to 'scripts') diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs index 863720777313..fbf723996d20 100644 --- a/scripts/generate_rust_target.rs +++ b/scripts/generate_rust_target.rs @@ -20,12 +20,28 @@ enum Value { Boolean(bool), Number(i32), String(String), + Array(Vec), Object(Object), } type Object = Vec<(String, Value)>; -/// Minimal "almost JSON" generator (e.g. no `null`s, no arrays, no escaping), +fn comma_sep( + seq: &[T], + formatter: &mut Formatter<'_>, + f: impl Fn(&mut Formatter<'_>, &T) -> Result, +) -> Result { + if let [ref rest @ .., ref last] = seq[..] { + for v in rest { + f(formatter, v)?; + formatter.write_str(",")?; + } + f(formatter, last)?; + } + Ok(()) +} + +/// Minimal "almost JSON" generator (e.g. no `null`s, no escaping), /// enough for this purpose. impl Display for Value { fn fmt(&self, formatter: &mut Formatter<'_>) -> Result { @@ -33,59 +49,67 @@ impl Display for Value { Value::Boolean(boolean) => write!(formatter, "{}", boolean), Value::Number(number) => write!(formatter, "{}", number), Value::String(string) => write!(formatter, "\"{}\"", string), + Value::Array(values) => { + formatter.write_str("[")?; + comma_sep(&values[..], formatter, |formatter, v| v.fmt(formatter))?; + formatter.write_str("]") + } 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)?; - } + comma_sep(&object[..], formatter, |formatter, v| { + write!(formatter, "\"{}\": {}", v.0, v.1) + })?; formatter.write_str("}") } } } } -struct TargetSpec(Object); - -impl TargetSpec { - fn new() -> TargetSpec { - TargetSpec(Vec::new()) +impl From for Value { + fn from(value: bool) -> Self { + Self::Boolean(value) } } -trait Push { - fn push(&mut self, key: &str, value: T); +impl From for Value { + fn from(value: i32) -> Self { + Self::Number(value) + } } -impl Push for TargetSpec { - fn push(&mut self, key: &str, value: bool) { - self.0.push((key.to_string(), Value::Boolean(value))); +impl From for Value { + fn from(value: String) -> Self { + Self::String(value) } } -impl Push for TargetSpec { - fn push(&mut self, key: &str, value: i32) { - self.0.push((key.to_string(), Value::Number(value))); +impl From<&str> for Value { + fn from(value: &str) -> Self { + Self::String(value.to_string()) } } -impl Push for TargetSpec { - fn push(&mut self, key: &str, value: String) { - self.0.push((key.to_string(), Value::String(value))); +impl From for Value { + fn from(object: Object) -> Self { + Self::Object(object) } } -impl Push<&str> for TargetSpec { - fn push(&mut self, key: &str, value: &str) { - self.push(key, value.to_string()); +impl, const N: usize> From<[T; N]> for Value { + fn from(i: [T; N]) -> Self { + Self::Array(i.into_iter().map(|v| v.into()).collect()) } } -impl Push for TargetSpec { - fn push(&mut self, key: &str, value: Object) { - self.0.push((key.to_string(), Value::Object(value))); +struct TargetSpec(Object); + +impl TargetSpec { + fn new() -> TargetSpec { + TargetSpec(Vec::new()) + } + + fn push(&mut self, key: &str, value: impl Into) { + self.0.push((key.to_string(), value.into())); } } -- cgit v1.2.3-70-g09d2 From 033964f13ef2aec1c0ae090755935055c11aaef7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 15 Aug 2024 14:34:49 +0300 Subject: get_maintainer: add --bug option to print bug reporting info For example Documentation/adming-guide/bug-hunting.rst suggest using get_maintainer.pl to get a list of maintainers and mailing lists to report bugs to, while a number of subsystems and drivers explicitly use the "B:" MAINTAINERS entry to direct bug reports at issue trackers instead of mailing lists and people. Add the --bug option to get_maintainer.pl to print the bug reporting URIs, if any. Cc: Joe Perches Cc: Jonathan Corbet Signed-off-by: Jani Nikula Acked-by: Joe Perches Signed-off-by: Jonathan Corbet Link: https://lore.kernel.org/r/20240815113450.3397499-1-jani.nikula@intel.com --- scripts/get_maintainer.pl | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index ee1aed7e090c..5ac02e198737 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -54,6 +54,7 @@ my $output_section_maxlen = 50; my $scm = 0; my $tree = 1; my $web = 0; +my $bug = 0; my $subsystem = 0; my $status = 0; my $letters = ""; @@ -271,6 +272,7 @@ if (!GetOptions( 'scm!' => \$scm, 'tree!' => \$tree, 'web!' => \$web, + 'bug!' => \$bug, 'letters=s' => \$letters, 'pattern-depth=i' => \$pattern_depth, 'k|keywords!' => \$keywords, @@ -320,13 +322,14 @@ if ($sections || $letters ne "") { $status = 0; $subsystem = 0; $web = 0; + $bug = 0; $keywords = 0; $keywords_in_file = 0; $interactive = 0; } else { - my $selections = $email + $scm + $status + $subsystem + $web; + my $selections = $email + $scm + $status + $subsystem + $web + $bug; if ($selections == 0) { - die "$P: Missing required option: email, scm, status, subsystem or web\n"; + die "$P: Missing required option: email, scm, status, subsystem, web or bug\n"; } } @@ -631,6 +634,7 @@ my %hash_list_to; my @list_to = (); my @scm = (); my @web = (); +my @bug = (); my @subsystem = (); my @status = (); my %deduplicate_name_hash = (); @@ -662,6 +666,11 @@ if ($web) { output(@web); } +if ($bug) { + @bug = uniq(@bug); + output(@bug); +} + exit($exit); sub self_test { @@ -847,6 +856,7 @@ sub get_maintainers { @list_to = (); @scm = (); @web = (); + @bug = (); @subsystem = (); @status = (); %deduplicate_name_hash = (); @@ -1069,6 +1079,7 @@ MAINTAINER field selection options: --status => print status if any --subsystem => print subsystem name if any --web => print website(s) if any + --bug => print bug reporting info if any Output type options: --separator [, ] => separator for multiple entries on 1 line @@ -1382,6 +1393,8 @@ sub add_categories { push(@scm, $pvalue . $suffix); } elsif ($ptype eq "W") { push(@web, $pvalue . $suffix); + } elsif ($ptype eq "B") { + push(@bug, $pvalue . $suffix); } elsif ($ptype eq "S") { push(@status, $pvalue . $suffix); } -- cgit v1.2.3-70-g09d2 From 4f32f799a950c7fffa17971177be42c79d74b69f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 27 Jul 2024 16:42:01 +0900 Subject: modpost: remove unused HOST_ELFCLASS HOST_ELFCLASS is output to elfconfig.h, but it is not used in modpost. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/mod/mk_elfconfig.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c index 680eade89be1..aca96b3aada0 100644 --- a/scripts/mod/mk_elfconfig.c +++ b/scripts/mod/mk_elfconfig.c @@ -39,12 +39,6 @@ main(int argc, char **argv) exit(1); } - if (sizeof(unsigned long) == 4) { - printf("#define HOST_ELFCLASS ELFCLASS32\n"); - } else if (sizeof(unsigned long) == 8) { - printf("#define HOST_ELFCLASS ELFCLASS64\n"); - } - endian_test.s = 0x0102; if (memcmp(endian_test.c, "\x01\x02", 2) == 0) printf("#define HOST_ELFDATA ELFDATA2MSB\n"); -- cgit v1.2.3-70-g09d2 From a660deb0f1f62214439640292cd7726f6ed8023d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 27 Jul 2024 16:42:02 +0900 Subject: modpost: detect endianness on run-time Endianness is currently detected on compile-time, but we can defer this until run-time. This change avoids re-executing scripts/mod/mk_elfconfig even if modpost in the linux-headers package needs to be rebuilt for a foreign architecture. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/mod/mk_elfconfig.c | 19 ------------------- scripts/mod/modpost.c | 36 ++++++++++++++++++++++++++++++++++++ scripts/mod/modpost.h | 13 ++++--------- 3 files changed, 40 insertions(+), 28 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c index aca96b3aada0..e8cee4e4bc73 100644 --- a/scripts/mod/mk_elfconfig.c +++ b/scripts/mod/mk_elfconfig.c @@ -8,7 +8,6 @@ int main(int argc, char **argv) { unsigned char ei[EI_NIDENT]; - union { short s; char c[2]; } endian_test; if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) { fprintf(stderr, "Error: input truncated\n"); @@ -28,24 +27,6 @@ main(int argc, char **argv) default: exit(1); } - switch (ei[EI_DATA]) { - case ELFDATA2LSB: - printf("#define KERNEL_ELFDATA ELFDATA2LSB\n"); - break; - case ELFDATA2MSB: - printf("#define KERNEL_ELFDATA ELFDATA2MSB\n"); - break; - default: - exit(1); - } - - endian_test.s = 0x0102; - if (memcmp(endian_test.c, "\x01\x02", 2) == 0) - printf("#define HOST_ELFDATA ELFDATA2MSB\n"); - else if (memcmp(endian_test.c, "\x02\x01", 2) == 0) - printf("#define HOST_ELFDATA ELFDATA2LSB\n"); - else - exit(1); return 0; } diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index d16d0ace2775..bfd758ad9e4f 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -50,6 +50,9 @@ static bool error_occurred; static bool extra_warn; +bool target_is_big_endian; +bool host_is_big_endian; + /* * Cut off the warnings when there are too many. This typically occurs when * vmlinux is missing. ('make modules' without building vmlinux.) @@ -438,6 +441,18 @@ static int parse_elf(struct elf_info *info, const char *filename) /* Not an ELF file - silently ignore it */ return 0; } + + switch (hdr->e_ident[EI_DATA]) { + case ELFDATA2LSB: + target_is_big_endian = false; + break; + case ELFDATA2MSB: + target_is_big_endian = true; + break; + default: + fatal("target endian is unknown\n"); + } + /* Fix endianness in ELF header */ hdr->e_type = TO_NATIVE(hdr->e_type); hdr->e_machine = TO_NATIVE(hdr->e_machine); @@ -2117,6 +2132,25 @@ struct dump_list { const char *file; }; +static void check_host_endian(void) +{ + static const union { + short s; + char c[2]; + } endian_test = { .c = {0x01, 0x02} }; + + switch (endian_test.s) { + case 0x0102: + host_is_big_endian = true; + break; + case 0x0201: + host_is_big_endian = false; + break; + default: + fatal("Unknown host endian\n"); + } +} + int main(int argc, char **argv) { struct module *mod; @@ -2181,6 +2215,8 @@ int main(int argc, char **argv) } } + check_host_endian(); + list_for_each_entry_safe(dl, dl2, &dump_lists, list) { read_dump(dl->file); list_del(&dl->list); diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 58197b34a3c8..54ba9431713f 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -62,15 +62,8 @@ x); \ }) -#if KERNEL_ELFDATA != HOST_ELFDATA - -#define TO_NATIVE(x) (bswap(x)) - -#else /* endianness matches */ - -#define TO_NATIVE(x) (x) - -#endif +#define TO_NATIVE(x) \ + (target_is_big_endian == host_is_big_endian ? x : bswap(x)) #define NOFAIL(ptr) do_nofail((ptr), #ptr) @@ -187,6 +180,8 @@ void add_moddevtable(struct buffer *buf, struct module *mod); void get_src_version(const char *modname, char sum[], unsigned sumlen); /* from modpost.c */ +extern bool target_is_big_endian; +extern bool host_is_big_endian; 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); -- cgit v1.2.3-70-g09d2 From aaed5c7739be81ebdd6008aedc8befd98c88e67a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 27 Jul 2024 16:42:03 +0900 Subject: kbuild: slim down package for building external modules Exclude directories and files unnecessary for building external modules: - include/config/ (except include/config/{auto.conf,kernel.release}) - scripts/atomic/ - scripts/dtc/ - scripts/kconfig/ - scripts/mod/mk_elfconfig - scripts/package/ - scripts/unifdef - .config - *.o - .*.cmd Avoid copying files twice for the following directories: - include/generated/ - arch/*/include/generated/ Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/package/install-extmod-build | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/package/install-extmod-build b/scripts/package/install-extmod-build index 8cc9e13403ae..9fee4a3236cc 100755 --- a/scripts/package/install-extmod-build +++ b/scripts/package/install-extmod-build @@ -9,15 +9,22 @@ is_enabled() { grep -q "^$1=y" include/config/auto.conf } +find_in_scripts() { + find scripts \ + \( -name atomic -o -name dtc -o -name kconfig -o -name package \) -prune -o \ + ! -name unifdef -a ! -name mk_elfconfig -a \( -type f -o -type l \) -print +} + mkdir -p "${destdir}" ( cd "${srctree}" echo Makefile find "arch/${SRCARCH}" -maxdepth 1 -name 'Makefile*' - find include scripts -type f -o -type l + find "arch/${SRCARCH}" -name generated -prune -o -name include -type d -print find "arch/${SRCARCH}" -name Kbuild.platforms -o -name Platform - find "arch/${SRCARCH}" -name include -type d + find include \( -name config -o -name generated \) -prune -o \( -type f -o -type l \) -print + find_in_scripts ) | tar -c -f - -C "${srctree}" -T - | tar -xf - -C "${destdir}" { @@ -25,12 +32,16 @@ mkdir -p "${destdir}" echo tools/objtool/objtool fi - find "arch/${SRCARCH}/include" Module.symvers include scripts -type f + echo Module.symvers + echo "arch/${SRCARCH}/include/generated" + echo include/config/auto.conf + echo include/config/kernel.release + echo include/generated + find_in_scripts if is_enabled CONFIG_GCC_PLUGINS; then find scripts/gcc-plugins -name '*.so' fi } | tar -c -f - -T - | tar -xf - -C "${destdir}" -# copy .config manually to be where it's expected to be -cp "${KCONFIG_CONFIG}" "${destdir}/.config" +find "${destdir}" \( -name '.*.cmd' -o -name '*.o' \) -delete -- cgit v1.2.3-70-g09d2 From f1d87664b82aeeaa1be9ee22dc85a59fd5a60d63 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 27 Jul 2024 16:42:04 +0900 Subject: kbuild: cross-compile linux-headers package when possible A long standing issue in the upstream kernel packaging is that the linux-headers package is not cross-compiled. For example, you can cross-build Debian packages for arm64 by running the following command: $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bindeb-pkg However, the generated linux-headers-*_arm64.deb is useless because the host programs in it were built for your build machine architecture (likely x86), not arm64. The Debian kernel maintains its own Makefiles to cross-compile host tools without relying on Kbuild. [1] Instead of adding such full custom Makefiles, this commit adds a small piece of code to cross-compile host programs located under the scripts/ directory. A straightforward solution is to pass HOSTCC=${CROSS_COMPILE}gcc, but it would also cross-compile scripts/basic/fixdep, which needs to be native to process the if_changed_dep macro. (This approach may work under some circumstances; you can execute foreign architecture programs with the help of binfmt_misc because Debian systems enable CONFIG_BINFMT_MISC, but it would require installing QEMU and libc for that architecture.) A trick is to use the external module build (KBUILD_EXTMOD=), which does not rebuild scripts/basic/fixdep. ${CC} needs to be able to link userspace programs (CONFIG_CC_CAN_LINK=y). There are known limitations: - GCC plugins It would possible to rebuild GCC plugins for the target architecture by passing HOSTCXX=${CROSS_COMPILE}g++ with necessary packages installed, but gcc on the installed system emits "cc1: error: incompatible gcc/plugin versions". - objtool and resolve_btfids These are built by the tools build system. They are not covered by the current solution. The resulting linux-headers package is broken if CONFIG_OBJTOOL or CONFIG_DEBUG_INFO_BTF is enabled. I only tested this with Debian, but it should work for other package systems as well. [1]: https://salsa.debian.org/kernel-team/linux/-/blob/debian/6.9.9-1/debian/rules.real#L586 Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- scripts/package/install-extmod-build | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'scripts') diff --git a/scripts/package/install-extmod-build b/scripts/package/install-extmod-build index 9fee4a3236cc..d2c9cacecc0c 100755 --- a/scripts/package/install-extmod-build +++ b/scripts/package/install-extmod-build @@ -44,4 +44,38 @@ mkdir -p "${destdir}" fi } | tar -c -f - -T - | tar -xf - -C "${destdir}" +# When ${CC} and ${HOSTCC} differ, we are likely cross-compiling. Rebuild host +# programs using ${CC}. This assumes CC=${CROSS_COMPILE}gcc, which is usually +# the case for package building. It does not cross-compile when CC=clang. +# +# This caters to host programs that participate in Kbuild. objtool and +# resolve_btfids are out of scope. +if [ "${CC}" != "${HOSTCC}" ] && is_enabled CONFIG_CC_CAN_LINK; then + echo "Rebuilding host programs with ${CC}..." + + cat <<-'EOF' > "${destdir}/Kbuild" + subdir-y := scripts + EOF + + # HOSTCXX is not overridden. The C++ compiler is used to build: + # - scripts/kconfig/qconf, which is unneeded for external module builds + # - GCC plugins, which will not work on the installed system even after + # being rebuilt. + # + # Use the single-target build to avoid the modpost invocation, which + # would overwrite Module.symvers. + "${MAKE}" HOSTCC="${CC}" KBUILD_EXTMOD="${destdir}" scripts/ + + cat <<-'EOF' > "${destdir}/scripts/Kbuild" + subdir-y := basic + hostprogs-always-y := mod/modpost + mod/modpost-objs := $(addprefix mod/, modpost.o file2alias.o sumversion.o symsearch.o) + EOF + + # Run once again to rebuild scripts/basic/ and scripts/mod/modpost. + "${MAKE}" HOSTCC="${CC}" KBUILD_EXTMOD="${destdir}" scripts/ + + rm -f "${destdir}/Kbuild" "${destdir}/scripts/Kbuild" +fi + find "${destdir}" \( -name '.*.cmd' -o -name '*.o' \) -delete -- cgit v1.2.3-70-g09d2 From 0c4beffbfe3fcd711b5d9268e7c7d63d4c1cc964 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 4 Aug 2024 12:33:07 +0900 Subject: kbuild: modinst: remove the multithread option from zstd compression Parallel execution is supported by GNU Make: $ make -j modules_install It is questionable to enable multithreading within each zstd process by default. If you still want to do it, you can use the environment variable: $ ZSTD_NBTHREADS= make modules_install Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Tested-by: Sedat Dilek --- scripts/Makefile.modinst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 0afd75472679..04f5229efa6b 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -146,7 +146,7 @@ quiet_cmd_gzip = GZIP $@ quiet_cmd_xz = XZ $@ cmd_xz = $(XZ) --check=crc32 --lzma2=dict=1MiB -f $< quiet_cmd_zstd = ZSTD $@ - cmd_zstd = $(ZSTD) -T0 --rm -f -q $< + cmd_zstd = $(ZSTD) --rm -f -q $< $(dst)/%.ko.gz: $(dst)/%.ko FORCE $(call cmd,gzip) -- cgit v1.2.3-70-g09d2 From dc73a57aeaaabe148c69c16b388771f891a996a2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 12 Aug 2024 20:49:45 +0900 Subject: kconfig: remove dummy assignments to cur_{filename,lineno} Since commit ca4c74ba306e ("kconfig: remove P_CHOICE property"), menu_finalize() no longer calls menu_add_symbol(). No function references cur_filename or cur_lineno after yyparse(). Signed-off-by: Masahiro Yamada --- scripts/kconfig/parser.y | 8 -------- 1 file changed, 8 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y index 61900feb4254..e03731184840 100644 --- a/scripts/kconfig/parser.y +++ b/scripts/kconfig/parser.y @@ -530,14 +530,6 @@ void conf_parse(const char *name) yydebug = 1; yyparse(); - /* - * FIXME: - * cur_filename and cur_lineno are used even after yyparse(); - * menu_finalize() calls menu_add_symbol(). This should be fixed. - */ - cur_filename = ""; - cur_lineno = 0; - str_printf(&autoconf_cmd, "\n" "$(autoconfig): $(deps_config)\n" -- cgit v1.2.3-70-g09d2 From 5e6cc7e3f2965fc3df901416336f6bf985a363da Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 12 Aug 2024 20:49:46 +0900 Subject: kconfig: stop adding P_SYMBOL property to symbols I believe its last usage was in the following code: if (prop == NULL) prop = stack->sym->prop; This code was previously used to print the file name and line number of associated symbols in sym_check_print_recursive(), which was removed by commit 9d0d26604657 ("kconfig: recursive checks drop file/lineno"). Signed-off-by: Masahiro Yamada --- scripts/kconfig/menu.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 323cc0b62be6..854edeb4d2db 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -78,10 +78,8 @@ void menu_add_entry(struct symbol *sym) *last_entry_ptr = menu; last_entry_ptr = &menu->next; current_entry = menu; - if (sym) { - menu_add_symbol(P_SYMBOL, sym, NULL); + if (sym) list_add_tail(&menu->link, &sym->menus); - } } struct menu *menu_add_menu(void) -- cgit v1.2.3-70-g09d2 From 96490176f1e11947be2bdd2700075275e2c27310 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 12 Aug 2024 20:49:47 +0900 Subject: kconfig: remove P_SYMBOL property P_SYMBOL is a pseudo property that was previously used for data linking purposes. It is no longer used except for debug prints. Remove it. Signed-off-by: Masahiro Yamada --- scripts/kconfig/expr.h | 1 - scripts/kconfig/parser.y | 4 ---- scripts/kconfig/qconf.cc | 1 - scripts/kconfig/symbol.c | 2 -- 4 files changed, 8 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 2bc96cd28253..c82d08bbd704 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -168,7 +168,6 @@ enum prop_type { P_SELECT, /* select BAR */ P_IMPLY, /* imply BAR */ P_RANGE, /* range 7..100 (for a symbol) */ - P_SYMBOL, /* where a symbol is defined */ }; struct property { diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y index e03731184840..2d5e5ed56aba 100644 --- a/scripts/kconfig/parser.y +++ b/scripts/kconfig/parser.y @@ -707,10 +707,6 @@ static void print_symbol(FILE *out, const struct menu *menu) print_quoted_string(out, prop->text); fputc('\n', out); break; - case P_SYMBOL: - fputs( " symbol ", out); - fprintf(out, "%s\n", prop->menu->sym->name); - break; default: fprintf(out, " unknown prop %d!\n", prop->type); break; diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 7d239c032b3d..88797d174261 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1094,7 +1094,6 @@ QString ConfigInfoView::debug_info(struct symbol *sym) case P_RANGE: case P_COMMENT: case P_IMPLY: - case P_SYMBOL: stream << prop_get_type_name(prop->type); stream << ": "; expr_print(prop->expr, expr_print_help, diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 71502abd3b12..d75665f3dfa2 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -1321,8 +1321,6 @@ const char *prop_get_type_name(enum prop_type type) return "imply"; case P_RANGE: return "range"; - case P_SYMBOL: - return "symbol"; case P_UNKNOWN: break; } -- cgit v1.2.3-70-g09d2 From a9d83d74783b00f9189c14180f77bbed133b092c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 12 Aug 2024 21:48:50 +0900 Subject: kbuild: split x*alloc() functions in kconfig to scripts/include/xalloc.h These functions will be useful for other host programs. Signed-off-by: Masahiro Yamada --- scripts/include/xalloc.h | 53 ++++++++++++++++++++++++++++++++++++++++++++ scripts/kconfig/confdata.c | 1 + scripts/kconfig/expr.c | 1 + scripts/kconfig/lexer.l | 1 + scripts/kconfig/lkc.h | 5 ----- scripts/kconfig/mconf.c | 1 + scripts/kconfig/menu.c | 1 + scripts/kconfig/nconf.c | 1 + scripts/kconfig/nconf.gui.c | 1 + scripts/kconfig/parser.y | 1 + scripts/kconfig/preprocess.c | 1 + scripts/kconfig/qconf.cc | 1 + scripts/kconfig/symbol.c | 1 + scripts/kconfig/util.c | 50 +---------------------------------------- 14 files changed, 65 insertions(+), 54 deletions(-) create mode 100644 scripts/include/xalloc.h (limited to 'scripts') diff --git a/scripts/include/xalloc.h b/scripts/include/xalloc.h new file mode 100644 index 000000000000..cdadb07d0592 --- /dev/null +++ b/scripts/include/xalloc.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef XALLOC_H +#define XALLOC_H + +#include +#include + +static inline void *xmalloc(size_t size) +{ + void *p = malloc(size); + + if (!p) + exit(1); + return p; +} + +static inline void *xcalloc(size_t nmemb, size_t size) +{ + void *p = calloc(nmemb, size); + + if (!p) + exit(1); + return p; +} + +static inline void *xrealloc(void *p, size_t size) +{ + p = realloc(p, size); + if (!p) + exit(1); + return p; +} + +static inline char *xstrdup(const char *s) +{ + char *p = strdup(s); + + if (!p) + exit(1); + return p; +} + +static inline char *xstrndup(const char *s, size_t n) +{ + char *p = strndup(s, n); + + if (!p) + exit(1); + return p; +} + +#endif /* XALLOC_H */ diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 76193ce5a792..d8849dfb06db 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -18,6 +18,7 @@ #include #include +#include #include "internal.h" #include "lkc.h" diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index c349da7fe3f8..a16451347f63 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -9,6 +9,7 @@ #include #include +#include #include "lkc.h" #define DEBUG_EXPR 0 diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l index 8dd597c4710d..9c2cdfc33c6f 100644 --- a/scripts/kconfig/lexer.l +++ b/scripts/kconfig/lexer.l @@ -13,6 +13,7 @@ #include #include +#include #include "lkc.h" #include "preprocess.h" diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 401bdf36323a..ddfb2b1cb737 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -53,11 +53,6 @@ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) /* util.c */ unsigned int strhash(const char *s); const char *file_lookup(const char *name); -void *xmalloc(size_t size); -void *xcalloc(size_t nmemb, size_t size); -void *xrealloc(void *p, size_t size); -char *xstrdup(const char *s); -char *xstrndup(const char *s, size_t n); /* lexer.l */ int yylex(void); diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 3887eac75289..84ea9215c0a7 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -20,6 +20,7 @@ #include #include +#include #include "lkc.h" #include "lxdialog/dialog.h" #include "mnconf-common.h" diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 854edeb4d2db..f61327fabead 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -9,6 +9,7 @@ #include #include +#include #include "lkc.h" #include "internal.h" diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index b91ca47e9e9a..063b4f7ccbdb 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -12,6 +12,7 @@ #include #include +#include #include "lkc.h" #include "mnconf-common.h" #include "nconf.h" diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index 25a7263ef3c8..72b605efe549 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -4,6 +4,7 @@ * * Derived from menuconfig. */ +#include #include "nconf.h" #include "lkc.h" diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y index 2d5e5ed56aba..1ad60f9e164e 100644 --- a/scripts/kconfig/parser.y +++ b/scripts/kconfig/parser.y @@ -11,6 +11,7 @@ #include #include +#include #include "lkc.h" #include "internal.h" #include "preprocess.h" diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c index 67d1fb95c491..783abcaa5cc5 100644 --- a/scripts/kconfig/preprocess.c +++ b/scripts/kconfig/preprocess.c @@ -11,6 +11,7 @@ #include #include +#include #include "internal.h" #include "lkc.h" #include "preprocess.h" diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 88797d174261..97fce13e551e 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -22,6 +22,7 @@ #include +#include #include "lkc.h" #include "qconf.h" diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index d75665f3dfa2..6793f016af5e 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -9,6 +9,7 @@ #include #include +#include #include "internal.h" #include "lkc.h" diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c index 696ff477671e..50698fff5b9d 100644 --- a/scripts/kconfig/util.c +++ b/scripts/kconfig/util.c @@ -9,6 +9,7 @@ #include #include +#include #include "lkc.h" unsigned int strhash(const char *s) @@ -102,52 +103,3 @@ char *str_get(const struct gstr *gs) { return gs->s; } - -void *xmalloc(size_t size) -{ - void *p = malloc(size); - if (p) - return p; - fprintf(stderr, "Out of memory.\n"); - exit(1); -} - -void *xcalloc(size_t nmemb, size_t size) -{ - void *p = calloc(nmemb, size); - if (p) - return p; - fprintf(stderr, "Out of memory.\n"); - exit(1); -} - -void *xrealloc(void *p, size_t size) -{ - p = realloc(p, size); - if (p) - return p; - fprintf(stderr, "Out of memory.\n"); - exit(1); -} - -char *xstrdup(const char *s) -{ - char *p; - - p = strdup(s); - if (p) - return p; - fprintf(stderr, "Out of memory.\n"); - exit(1); -} - -char *xstrndup(const char *s, size_t n) -{ - char *p; - - p = strndup(s, n); - if (p) - return p; - fprintf(stderr, "Out of memory.\n"); - exit(1); -} -- cgit v1.2.3-70-g09d2 From 4c2598e3b62102d5ea7f618e13d996b069cde27d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 12 Aug 2024 21:48:51 +0900 Subject: modpost: replace the use of NOFAIL() with xmalloc() etc. I think x*alloc() functions are cleaner. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 28 ++++++++++------------------ scripts/mod/modpost.h | 4 ---- scripts/mod/sumversion.c | 6 ++++-- scripts/mod/symsearch.c | 6 +++--- 4 files changed, 17 insertions(+), 27 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index bfd758ad9e4f..66bd89b2a8b6 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -23,6 +23,7 @@ #include #include +#include #include "modpost.h" #include "../../include/linux/license.h" @@ -97,14 +98,6 @@ static inline bool strends(const char *str, const char *postfix) return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0; } -void *do_nofail(void *ptr, const char *expr) -{ - if (!ptr) - fatal("Memory allocation failure: %s.\n", expr); - - return ptr; -} - char *read_text_file(const char *filename) { struct stat st; @@ -123,7 +116,7 @@ char *read_text_file(const char *filename) exit(1); } - buf = NOFAIL(malloc(st.st_size + 1)); + buf = xmalloc(st.st_size + 1); nbytes = st.st_size; @@ -181,7 +174,7 @@ static struct module *new_module(const char *name, size_t namelen) { struct module *mod; - mod = NOFAIL(malloc(sizeof(*mod) + namelen + 1)); + mod = xmalloc(sizeof(*mod) + namelen + 1); memset(mod, 0, sizeof(*mod)); INIT_LIST_HEAD(&mod->exported_symbols); @@ -240,7 +233,7 @@ static inline unsigned int tdb_hash(const char *name) **/ static struct symbol *alloc_symbol(const char *name) { - struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1)); + struct symbol *s = xmalloc(sizeof(*s) + strlen(name) + 1); memset(s, 0, sizeof(*s)); strcpy(s->name, name); @@ -313,8 +306,7 @@ static void add_namespace(struct list_head *head, const char *namespace) struct namespace_list *ns_entry; if (!contains_namespace(head, namespace)) { - ns_entry = NOFAIL(malloc(sizeof(*ns_entry) + - strlen(namespace) + 1)); + ns_entry = xmalloc(sizeof(*ns_entry) + strlen(namespace) + 1); strcpy(ns_entry->namespace, namespace); list_add_tail(&ns_entry->list, head); } @@ -369,7 +361,7 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod, s = alloc_symbol(name); s->module = mod; s->is_gpl_only = gpl_only; - s->namespace = NOFAIL(strdup(namespace)); + s->namespace = xstrdup(namespace); list_add_tail(&s->list, &mod->exported_symbols); hash_add_symbol(s); @@ -637,7 +629,7 @@ static void handle_symbol(struct module *mod, struct elf_info *info, if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER) break; if (symname[0] == '.') { - char *munged = NOFAIL(strdup(symname)); + char *munged = xstrdup(symname); munged[0] = '_'; munged[1] = toupper(munged[1]); symname = munged; @@ -1677,7 +1669,7 @@ void buf_write(struct buffer *buf, const char *s, int len) { if (buf->size - buf->pos < len) { buf->size += len + SZ; - buf->p = NOFAIL(realloc(buf->p, buf->size)); + buf->p = xrealloc(buf->p, buf->size); } strncpy(buf->p + buf->pos, s, len); buf->pos += len; @@ -1962,7 +1954,7 @@ static void write_if_changed(struct buffer *b, const char *fname) if (st.st_size != b->pos) goto close_write; - tmp = NOFAIL(malloc(b->pos)); + tmp = xmalloc(b->pos); if (fread(tmp, 1, b->pos, file) != b->pos) goto free_write; @@ -2167,7 +2159,7 @@ int main(int argc, char **argv) external_module = true; break; case 'i': - dl = NOFAIL(malloc(sizeof(*dl))); + dl = xmalloc(sizeof(*dl)); dl->file = optarg; list_add_tail(&dl->list, &dump_lists); break; diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 54ba9431713f..7fa8bdd801a9 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -65,12 +65,8 @@ #define TO_NATIVE(x) \ (target_is_big_endian == host_is_big_endian ? x : bswap(x)) -#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 { char *p; int pos; diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index dc4878502276..e7d2da45b0df 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -8,6 +8,8 @@ #include #include #include + +#include #include "modpost.h" /* @@ -305,7 +307,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) const char *base; int dirlen, ret = 0, check_files = 0; - cmd = NOFAIL(malloc(strlen(objfile) + sizeof("..cmd"))); + cmd = xmalloc(strlen(objfile) + sizeof("..cmd")); base = strrchr(objfile, '/'); if (base) { @@ -316,7 +318,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) dirlen = 0; sprintf(cmd, ".%s.cmd", objfile); } - dir = NOFAIL(malloc(dirlen + 1)); + dir = xmalloc(dirlen + 1); strncpy(dir, objfile, dirlen); dir[dirlen] = '\0'; diff --git a/scripts/mod/symsearch.c b/scripts/mod/symsearch.c index aa4ed51f9960..b9737b92f7f8 100644 --- a/scripts/mod/symsearch.c +++ b/scripts/mod/symsearch.c @@ -4,7 +4,7 @@ * Helper functions for finding the symbol in an ELF which is "nearest" * to a given address. */ - +#include #include "modpost.h" struct syminfo { @@ -125,8 +125,8 @@ void symsearch_init(struct elf_info *elf) { unsigned int table_size = symbol_count(elf); - elf->symsearch = NOFAIL(malloc(sizeof(struct symsearch) + - sizeof(struct syminfo) * table_size)); + elf->symsearch = xmalloc(sizeof(struct symsearch) + + sizeof(struct syminfo) * table_size); elf->symsearch->table_size = table_size; symsearch_populate(elf, elf->symsearch->table, table_size); -- cgit v1.2.3-70-g09d2 From aeaa4283a309520c22a783071f554645943955d8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 12 Aug 2024 21:48:52 +0900 Subject: kallsyms: use xmalloc() and xrealloc() When malloc() or realloc() fails, there is not much userspace programs can do. xmalloc() and xrealloc() are useful to bail out on a memory allocation failure. Signed-off-by: Masahiro Yamada --- scripts/kallsyms.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 123dab0572f8..c70458e68ece 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -27,6 +27,8 @@ #include #include +#include + #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) #define KSYM_NAME_LEN 512 @@ -168,12 +170,7 @@ static struct sym_entry *read_symbol(FILE *in, char **buf, size_t *buf_len) * compressed together */ len++; - sym = malloc(sizeof(*sym) + len + 1); - if (!sym) { - fprintf(stderr, "kallsyms failure: " - "unable to allocate required amount of memory\n"); - exit(EXIT_FAILURE); - } + sym = xmalloc(sizeof(*sym) + len + 1); sym->addr = addr; sym->len = len; sym->sym[0] = type; @@ -278,12 +275,7 @@ static void read_map(const char *in) if (table_cnt >= table_size) { table_size += 10000; - table = realloc(table, sizeof(*table) * table_size); - if (!table) { - fprintf(stderr, "out of memory\n"); - fclose(fp); - exit (1); - } + table = xrealloc(table, sizeof(*table) * table_size); } table[table_cnt++] = sym; @@ -391,12 +383,7 @@ static void write_src(void) /* table of offset markers, that give the offset in the compressed stream * every 256 symbols */ markers_cnt = (table_cnt + 255) / 256; - markers = malloc(sizeof(*markers) * markers_cnt); - if (!markers) { - fprintf(stderr, "kallsyms failure: " - "unable to allocate required memory\n"); - exit(EXIT_FAILURE); - } + markers = xmalloc(sizeof(*markers) * markers_cnt); output_label("kallsyms_names"); off = 0; -- cgit v1.2.3-70-g09d2 From a46078d651819c988d36379e8df68cb866eae747 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 12 Aug 2024 21:48:53 +0900 Subject: fixdep: use xmalloc() When malloc() fails, there is not much userspace programs can do. xmalloc() is useful to bail out on a memory allocation failure. Signed-off-by: Masahiro Yamada --- scripts/basic/fixdep.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 84b6efa849f4..cdd5da7e009b 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -99,6 +99,8 @@ #include #include +#include + static void usage(void) { fprintf(stderr, "Usage: fixdep \n"); @@ -131,12 +133,9 @@ static unsigned int strhash(const char *str, unsigned int sz) static void add_to_hashtable(const char *name, int len, unsigned int hash, struct item *hashtab[]) { - struct item *aux = malloc(sizeof(*aux) + len); + struct item *aux; - if (!aux) { - perror("fixdep:malloc"); - exit(1); - } + aux = xmalloc(sizeof(*aux) + len); memcpy(aux->name, name, len); aux->len = len; aux->hash = hash; @@ -228,11 +227,7 @@ static void *read_file(const char *filename) perror(filename); exit(2); } - buf = malloc(st.st_size + 1); - if (!buf) { - perror("fixdep: malloc"); - exit(2); - } + buf = xmalloc(st.st_size + 1); if (read(fd, buf, st.st_size) != st.st_size) { perror("fixdep: read"); exit(2); -- cgit v1.2.3-70-g09d2 From 7a7f974594cd5d6723242cb8c018b59db16fe27b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 13 Aug 2024 01:54:51 +0900 Subject: modpost: improve the section mismatch warning format This commit improves the section mismatch warning format when there is no suitable symbol name to print. The section mismatch warning prints the reference source in the form of + and the reference destination in the form of . However, there are some corner cases where becomes "(unknown)", as reported in commit 23dfd914d2bf ("modpost: fix null pointer dereference"). In such cases, it is better to print the symbol address. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 66bd89b2a8b6..704963cba5fe 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -697,10 +697,7 @@ static char *get_modinfo(struct elf_info *info, const char *tag) static const char *sym_name(struct elf_info *elf, Elf_Sym *sym) { - if (sym) - return elf->strtab + sym->st_name; - else - return "(unknown)"; + return sym ? elf->strtab + sym->st_name : ""; } /* @@ -1013,6 +1010,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, Elf_Sym *from; const char *tosym; const char *fromsym; + char taddr_str[16]; from = find_fromsym(elf, faddr, fsecndx); fromsym = sym_name(elf, from); @@ -1026,10 +1024,17 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, sec_mismatch_count++; - warn("%s: section mismatch in reference: %s+0x%x (section: %s) -> %s (section: %s)\n", - modname, fromsym, - (unsigned int)(faddr - (from ? from->st_value : 0)), - fromsec, tosym, tosec); + if (!tosym[0]) + snprintf(taddr_str, sizeof(taddr_str), "0x%x", (unsigned int)taddr); + + /* + * The format for the reference source: + or
+ * The format for the reference destination: or
+ */ + warn("%s: section mismatch in reference: %s%s0x%x (section: %s) -> %s (section: %s)\n", + modname, fromsym, fromsym[0] ? "+" : "", + (unsigned int)(faddr - (fromsym[0] ? from->st_value : 0)), + fromsec, tosym[0] ? tosym : taddr_str, tosec); if (mismatch->mismatch == EXTABLE_TO_NON_TEXT) { if (match(tosec, mismatch->bad_tosec)) -- cgit v1.2.3-70-g09d2 From e6b65ee10588a552d04d488ebeac24bba20747a8 Mon Sep 17 00:00:00 2001 From: Jose Fernandez Date: Mon, 12 Aug 2024 19:16:19 -0600 Subject: kbuild: control extra pacman packages with PACMAN_EXTRAPACKAGES MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce the PACMAN_EXTRAPACKAGES variable in PKGBUILD to allow users to specify which additional packages are built by the pacman-pkg target. Previously, the api-headers package was always included, and the headers package was included only if CONFIG_MODULES=y. With this change, both headers and api-headers packages are included by default. Users can now control this behavior by setting PACMAN_EXTRAPACKAGES to a space-separated list of desired extra packages or leaving it empty to exclude all. For example, to build only the base package without extras: make pacman-pkg PACMAN_EXTRAPACKAGES="" Signed-off-by: Jose Fernandez Reviewed-by: Peter Jung Reviewed-by: Nathan Chancellor Tested-by: Nathan Chancellor Reviewed-by: Christian Heusel Tested-by: Christian Heusel Acked-by: Thomas Weißschuh Signed-off-by: Masahiro Yamada --- scripts/package/PKGBUILD | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/package/PKGBUILD b/scripts/package/PKGBUILD index 663ce300dd06..fbd7eb10a52c 100644 --- a/scripts/package/PKGBUILD +++ b/scripts/package/PKGBUILD @@ -3,10 +3,13 @@ # Contributor: Jan Alexander Steffens (heftig) pkgbase=${PACMAN_PKGBASE:-linux-upstream} -pkgname=("${pkgbase}" "${pkgbase}-api-headers") -if grep -q CONFIG_MODULES=y include/config/auto.conf; then - pkgname+=("${pkgbase}-headers") -fi +pkgname=("${pkgbase}") + +_extrapackages=${PACMAN_EXTRAPACKAGES-headers api-headers} +for pkg in $_extrapackages; do + pkgname+=("${pkgbase}-${pkg}") +done + pkgver="${KERNELRELEASE//-/_}" # The PKGBUILD is evaluated multiple times. # Running scripts/build-version from here would introduce inconsistencies. @@ -77,10 +80,13 @@ _package-headers() { cd "${objtree}" local builddir="${pkgdir}/usr/${MODLIB}/build" - echo "Installing build files..." - "${srctree}/scripts/package/install-extmod-build" "${builddir}" + if grep -q CONFIG_MODULES=y include/config/auto.conf; then + echo "Installing build files..." + "${srctree}/scripts/package/install-extmod-build" "${builddir}" + fi echo "Installing System.map and config..." + mkdir -p "${builddir}" cp System.map "${builddir}/System.map" cp .config "${builddir}/.config" -- cgit v1.2.3-70-g09d2 From b6223c2de6b0cade1e1d37490b304cb5df8d45d9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 16 Aug 2024 23:18:14 +0900 Subject: kbuild: pacman-pkg: move common commands to a separate function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All build and package functions share the following commands: export MAKEFLAGS="${KBUILD_MAKEFLAGS}" cd "${objtree}" Factor out the common code. Signed-off-by: Masahiro Yamada Acked-by:  Thomas Weißschuh Reviewed-by: Nathan Chancellor Reviewed-by: Christian Heusel --- scripts/package/PKGBUILD | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/package/PKGBUILD b/scripts/package/PKGBUILD index fbd7eb10a52c..e2d9c2601ca9 100644 --- a/scripts/package/PKGBUILD +++ b/scripts/package/PKGBUILD @@ -36,11 +36,15 @@ makedepends=( ) options=(!debug !strip !buildflags !makeflags) -build() { +_prologue() { # MAKEFLAGS from makepkg.conf override the ones inherited from kbuild. # Bypass this override with a custom variable. export MAKEFLAGS="${KBUILD_MAKEFLAGS}" cd "${objtree}" +} + +build() { + _prologue ${MAKE} KERNELRELEASE="${KERNELRELEASE}" KBUILD_BUILD_VERSION="${pkgrel}" } @@ -48,10 +52,10 @@ build() { _package() { pkgdesc="The ${pkgdesc} kernel and modules" - export MAKEFLAGS="${KBUILD_MAKEFLAGS}" - cd "${objtree}" local modulesdir="${pkgdir}/usr/${MODLIB}" + _prologue + echo "Installing boot image..." # systemd expects to find the kernel here to allow hibernation # https://github.com/systemd/systemd/commit/edda44605f06a41fb86b7ab8128dcf99161d2344 @@ -76,10 +80,10 @@ _package() { _package-headers() { pkgdesc="Headers and scripts for building modules for the ${pkgdesc} kernel" - export MAKEFLAGS="${KBUILD_MAKEFLAGS}" - cd "${objtree}" local builddir="${pkgdir}/usr/${MODLIB}/build" + _prologue + if grep -q CONFIG_MODULES=y include/config/auto.conf; then echo "Installing build files..." "${srctree}/scripts/package/install-extmod-build" "${builddir}" @@ -100,8 +104,7 @@ _package-api-headers() { provides=(linux-api-headers) conflicts=(linux-api-headers) - export MAKEFLAGS="${KBUILD_MAKEFLAGS}" - cd "${objtree}" + _prologue ${MAKE} headers_install INSTALL_HDR_PATH="${pkgdir}/usr" } -- cgit v1.2.3-70-g09d2 From 5b000f3cbb38c23992ee95fcd3e983ca66164eff Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 16 Aug 2024 23:18:15 +0900 Subject: kbuild: pacman-pkg: do not override objtree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit objtree is defined and exported by the top-level Makefile. I prefer not to override it. There is no need to pass the absolute path of objtree. PKGBUILD can detect it by itself. Signed-off-by: Masahiro Yamada Acked-by:  Thomas Weißschuh Reviewed-by: Nathan Chancellor Reviewed-by: Christian Heusel --- scripts/Makefile.package | 3 +-- scripts/package/PKGBUILD | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.package b/scripts/Makefile.package index 4a80584ec771..11d53f240a2b 100644 --- a/scripts/Makefile.package +++ b/scripts/Makefile.package @@ -147,8 +147,7 @@ snap-pkg: PHONY += pacman-pkg pacman-pkg: @ln -srf $(srctree)/scripts/package/PKGBUILD $(objtree)/PKGBUILD - +objtree="$(realpath $(objtree))" \ - BUILDDIR="$(realpath $(objtree))/pacman" \ + +BUILDDIR="$(realpath $(objtree))/pacman" \ CARCH="$(UTS_MACHINE)" \ KBUILD_MAKEFLAGS="$(MAKEFLAGS)" \ KBUILD_REVISION="$(shell $(srctree)/scripts/build-version)" \ diff --git a/scripts/package/PKGBUILD b/scripts/package/PKGBUILD index e2d9c2601ca9..839cd5e634d2 100644 --- a/scripts/package/PKGBUILD +++ b/scripts/package/PKGBUILD @@ -40,7 +40,9 @@ _prologue() { # MAKEFLAGS from makepkg.conf override the ones inherited from kbuild. # Bypass this override with a custom variable. export MAKEFLAGS="${KBUILD_MAKEFLAGS}" - cd "${objtree}" + + # Kbuild works in the output directory, where this PKGBUILD is located. + cd "$(dirname "${BASH_SOURCE[0]}")" } build() { -- cgit v1.2.3-70-g09d2 From 4079fe8e7b2b42b278e77dae7cb9d95e62c415a2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 16 Aug 2024 22:44:29 +0900 Subject: modpost: simplify modpost_log() With commit cda5f94e88b4 ("modpost: avoid using the alias attribute"), only two log levels remain: LOG_WARN and LOG_ERROR. Simplify this by making it a boolean variable. Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor --- scripts/mod/modpost.c | 17 ++++++----------- scripts/mod/modpost.h | 11 +++-------- 2 files changed, 9 insertions(+), 19 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 704963cba5fe..c8cd5d822bb6 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -67,20 +67,15 @@ static unsigned int nr_unresolved; #define MODULE_NAME_LEN (64 - sizeof(Elf_Addr)) -void modpost_log(enum loglevel loglevel, const char *fmt, ...) +void modpost_log(bool is_error, const char *fmt, ...) { va_list arglist; - switch (loglevel) { - case LOG_WARN: - fprintf(stderr, "WARNING: "); - break; - case LOG_ERROR: + if (is_error) { fprintf(stderr, "ERROR: "); error_occurred = true; - break; - default: /* invalid loglevel, ignore */ - break; + } else { + fprintf(stderr, "WARNING: "); } fprintf(stderr, "modpost: "); @@ -1689,7 +1684,7 @@ static void check_exports(struct module *mod) exp = find_symbol(s->name); if (!exp) { if (!s->weak && nr_unresolved++ < MAX_UNRESOLVED_REPORTS) - modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR, + modpost_log(!warn_unresolved, "\"%s\" [%s.ko] undefined!\n", s->name, mod->name); continue; @@ -1712,7 +1707,7 @@ static void check_exports(struct module *mod) basename = mod->name; if (!contains_namespace(&mod->imported_namespaces, exp->namespace)) { - modpost_log(allow_missing_ns_imports ? LOG_WARN : LOG_ERROR, + modpost_log(!allow_missing_ns_imports, "module %s uses symbol %s from namespace %s, but does not import it.\n", basename, exp->name, exp->namespace); add_namespace(&mod->missing_namespaces, exp->namespace); diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 7fa8bdd801a9..ada3a36cc4bc 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -182,13 +182,8 @@ 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, - LOG_ERROR, -}; - void __attribute__((format(printf, 2, 3))) -modpost_log(enum loglevel loglevel, const char *fmt, ...); +modpost_log(bool is_error, const char *fmt, ...); /* * warn - show the given message, then let modpost continue running, still @@ -203,6 +198,6 @@ modpost_log(enum loglevel loglevel, const char *fmt, ...); * fatal - show the given message, and bail out immediately. This should be * used when there is no point to continue running modpost. */ -#define warn(fmt, args...) modpost_log(LOG_WARN, fmt, ##args) -#define error(fmt, args...) modpost_log(LOG_ERROR, fmt, ##args) +#define warn(fmt, args...) modpost_log(false, fmt, ##args) +#define error(fmt, args...) modpost_log(true, fmt, ##args) #define fatal(fmt, args...) do { error(fmt, ##args); exit(1); } while (1) -- cgit v1.2.3-70-g09d2 From 836d13a6ef8a2eb0eab2bd2de06f2deabc62b060 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Sun, 21 Jul 2024 16:36:18 +0300 Subject: xz: switch from public domain to BSD Zero Clause License (0BSD) Remove the public domain notices and add SPDX license identifiers. Change MODULE_LICENSE from "GPL" to "Dual BSD/GPL" because 0BSD should count as a BSD license variant here. The switch to 0BSD was done in the upstream XZ Embedded project because public domain has (real or perceived) legal issues in some jurisdictions. Link: https://lkml.kernel.org/r/20240721133633.47721-4-lasse.collin@tukaani.org Signed-off-by: Lasse Collin Reviewed-by: Sam James Cc: Thomas Gleixner Cc: Greg Kroah-Hartman Cc: Albert Ou Cc: Catalin Marinas Cc: Emil Renner Berthing Cc: Herbert Xu Cc: Joel Stanley Cc: Jonathan Corbet Cc: Jubin Zhong Cc: Jules Maselbas Cc: Krzysztof Kozlowski Cc: Michael Ellerman Cc: Palmer Dabbelt Cc: Paul Walmsley Cc: Randy Dunlap Cc: Rui Li Cc: Simon Glass Cc: Will Deacon Signed-off-by: Andrew Morton --- include/linux/decompress/unxz.h | 5 ++--- include/linux/xz.h | 5 ++--- lib/decompress_unxz.c | 5 ++--- lib/xz/xz_crc32.c | 5 ++--- lib/xz/xz_dec_bcj.c | 5 ++--- lib/xz/xz_dec_lzma2.c | 5 ++--- lib/xz/xz_dec_stream.c | 5 ++--- lib/xz/xz_dec_syms.c | 12 +++--------- lib/xz/xz_dec_test.c | 12 +++--------- lib/xz/xz_lzma2.h | 5 ++--- lib/xz/xz_private.h | 5 ++--- lib/xz/xz_stream.h | 5 ++--- scripts/xz_wrap.sh | 5 +---- 13 files changed, 27 insertions(+), 52 deletions(-) (limited to 'scripts') diff --git a/include/linux/decompress/unxz.h b/include/linux/decompress/unxz.h index f764e2a7201e..3dd2658a9dab 100644 --- a/include/linux/decompress/unxz.h +++ b/include/linux/decompress/unxz.h @@ -1,10 +1,9 @@ +/* SPDX-License-Identifier: 0BSD */ + /* * Wrapper for decompressing XZ-compressed kernel, initramfs, and initrd * * Author: Lasse Collin - * - * This file has been put into the public domain. - * You can do whatever you want with this file. */ #ifndef DECOMPRESS_UNXZ_H diff --git a/include/linux/xz.h b/include/linux/xz.h index 7285ca5d56e9..5728d57aecc0 100644 --- a/include/linux/xz.h +++ b/include/linux/xz.h @@ -1,11 +1,10 @@ +/* SPDX-License-Identifier: 0BSD */ + /* * XZ decompressor * * Authors: Lasse Collin * Igor Pavlov - * - * This file has been put into the public domain. - * You can do whatever you want with this file. */ #ifndef XZ_H diff --git a/lib/decompress_unxz.c b/lib/decompress_unxz.c index 842894158944..34bb7efc0412 100644 --- a/lib/decompress_unxz.c +++ b/lib/decompress_unxz.c @@ -1,10 +1,9 @@ +// SPDX-License-Identifier: 0BSD + /* * Wrapper for decompressing XZ-compressed kernel, initramfs, and initrd * * Author: Lasse Collin - * - * This file has been put into the public domain. - * You can do whatever you want with this file. */ /* diff --git a/lib/xz/xz_crc32.c b/lib/xz/xz_crc32.c index 88a2c35e1b59..30b8a27110b1 100644 --- a/lib/xz/xz_crc32.c +++ b/lib/xz/xz_crc32.c @@ -1,11 +1,10 @@ +// SPDX-License-Identifier: 0BSD + /* * CRC32 using the polynomial from IEEE-802.3 * * Authors: Lasse Collin * Igor Pavlov - * - * This file has been put into the public domain. - * You can do whatever you want with this file. */ /* diff --git a/lib/xz/xz_dec_bcj.c b/lib/xz/xz_dec_bcj.c index ef449e97d1a1..ab9237ed6db8 100644 --- a/lib/xz/xz_dec_bcj.c +++ b/lib/xz/xz_dec_bcj.c @@ -1,11 +1,10 @@ +// SPDX-License-Identifier: 0BSD + /* * Branch/Call/Jump (BCJ) filter decoders * * Authors: Lasse Collin * Igor Pavlov - * - * This file has been put into the public domain. - * You can do whatever you want with this file. */ #include "xz_private.h" diff --git a/lib/xz/xz_dec_lzma2.c b/lib/xz/xz_dec_lzma2.c index 27ce34520e78..613939f5dd6c 100644 --- a/lib/xz/xz_dec_lzma2.c +++ b/lib/xz/xz_dec_lzma2.c @@ -1,11 +1,10 @@ +// SPDX-License-Identifier: 0BSD + /* * LZMA2 decoder * * Authors: Lasse Collin * Igor Pavlov - * - * This file has been put into the public domain. - * You can do whatever you want with this file. */ #include "xz_private.h" diff --git a/lib/xz/xz_dec_stream.c b/lib/xz/xz_dec_stream.c index 683570b93a8c..0058406ccd17 100644 --- a/lib/xz/xz_dec_stream.c +++ b/lib/xz/xz_dec_stream.c @@ -1,10 +1,9 @@ +// SPDX-License-Identifier: 0BSD + /* * .xz Stream decoder * * Author: Lasse Collin - * - * This file has been put into the public domain. - * You can do whatever you want with this file. */ #include "xz_private.h" diff --git a/lib/xz/xz_dec_syms.c b/lib/xz/xz_dec_syms.c index 61098c67a413..495d2cc2e6e8 100644 --- a/lib/xz/xz_dec_syms.c +++ b/lib/xz/xz_dec_syms.c @@ -1,10 +1,9 @@ +// SPDX-License-Identifier: 0BSD + /* * XZ decoder module information * * Author: Lasse Collin - * - * This file has been put into the public domain. - * You can do whatever you want with this file. */ #include @@ -25,9 +24,4 @@ EXPORT_SYMBOL(xz_dec_microlzma_end); MODULE_DESCRIPTION("XZ decompressor"); MODULE_VERSION("1.1"); MODULE_AUTHOR("Lasse Collin and Igor Pavlov"); - -/* - * This code is in the public domain, but in Linux it's simplest to just - * say it's GPL and consider the authors as the copyright holders. - */ -MODULE_LICENSE("GPL"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/lib/xz/xz_dec_test.c b/lib/xz/xz_dec_test.c index da28a19d6c98..53d3600f2ddb 100644 --- a/lib/xz/xz_dec_test.c +++ b/lib/xz/xz_dec_test.c @@ -1,10 +1,9 @@ +// SPDX-License-Identifier: 0BSD + /* * XZ decoder tester * * Author: Lasse Collin - * - * This file has been put into the public domain. - * You can do whatever you want with this file. */ #include @@ -212,9 +211,4 @@ module_exit(xz_dec_test_exit); MODULE_DESCRIPTION("XZ decompressor tester"); MODULE_VERSION("1.0"); MODULE_AUTHOR("Lasse Collin "); - -/* - * This code is in the public domain, but in Linux it's simplest to just - * say it's GPL and consider the authors as the copyright holders. - */ -MODULE_LICENSE("GPL"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/lib/xz/xz_lzma2.h b/lib/xz/xz_lzma2.h index 92d852d4f87a..d2632b7dfb9c 100644 --- a/lib/xz/xz_lzma2.h +++ b/lib/xz/xz_lzma2.h @@ -1,11 +1,10 @@ +/* SPDX-License-Identifier: 0BSD */ + /* * LZMA2 definitions * * Authors: Lasse Collin * Igor Pavlov - * - * This file has been put into the public domain. - * You can do whatever you want with this file. */ #ifndef XZ_LZMA2_H diff --git a/lib/xz/xz_private.h b/lib/xz/xz_private.h index bf1e94ec7873..2412a5d54801 100644 --- a/lib/xz/xz_private.h +++ b/lib/xz/xz_private.h @@ -1,10 +1,9 @@ +/* SPDX-License-Identifier: 0BSD */ + /* * Private includes and definitions * * Author: Lasse Collin - * - * This file has been put into the public domain. - * You can do whatever you want with this file. */ #ifndef XZ_PRIVATE_H diff --git a/lib/xz/xz_stream.h b/lib/xz/xz_stream.h index 430bb3a0d195..55f9f6f94b78 100644 --- a/lib/xz/xz_stream.h +++ b/lib/xz/xz_stream.h @@ -1,10 +1,9 @@ +/* SPDX-License-Identifier: 0BSD */ + /* * Definitions for handling the .xz file format * * Author: Lasse Collin - * - * This file has been put into the public domain. - * You can do whatever you want with this file. */ #ifndef XZ_STREAM_H diff --git a/scripts/xz_wrap.sh b/scripts/xz_wrap.sh index d06baf626abe..bb760b721b2c 100755 --- a/scripts/xz_wrap.sh +++ b/scripts/xz_wrap.sh @@ -1,13 +1,10 @@ #!/bin/sh +# SPDX-License-Identifier: 0BSD # # This is a wrapper for xz to compress the kernel image using appropriate # compression options depending on the architecture. # # Author: Lasse Collin -# -# This file has been put into the public domain. -# You can do whatever you want with this file. -# BCJ= LZMA2OPTS= -- cgit v1.2.3-70-g09d2 From ff221153aafa08159f3dcc187c6f3a7a837e1c3d Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Sun, 21 Jul 2024 16:36:19 +0300 Subject: xz: fix comments and coding style - Fix comments that were no longer in sync with the code below them. - Fix language errors. - Fix coding style. Link: https://lkml.kernel.org/r/20240721133633.47721-5-lasse.collin@tukaani.org Signed-off-by: Lasse Collin Reviewed-by: Sam James Cc: Albert Ou Cc: Catalin Marinas Cc: Emil Renner Berthing Cc: Greg Kroah-Hartman Cc: Herbert Xu Cc: Joel Stanley Cc: Jonathan Corbet Cc: Jubin Zhong Cc: Jules Maselbas Cc: Krzysztof Kozlowski Cc: Michael Ellerman Cc: Palmer Dabbelt Cc: Paul Walmsley Cc: Randy Dunlap Cc: Rui Li Cc: Simon Glass Cc: Thomas Gleixner Cc: Will Deacon Signed-off-by: Andrew Morton --- lib/decompress_unxz.c | 20 ++++++++++---------- lib/xz/Kconfig | 3 ++- scripts/Makefile.lib | 13 ++++++++----- 3 files changed, 20 insertions(+), 16 deletions(-) (limited to 'scripts') diff --git a/lib/decompress_unxz.c b/lib/decompress_unxz.c index 34bb7efc0412..46aa3be13fc5 100644 --- a/lib/decompress_unxz.c +++ b/lib/decompress_unxz.c @@ -102,7 +102,7 @@ #ifdef STATIC # define XZ_PREBOOT #else -#include +# include #endif #ifdef __KERNEL__ # include @@ -219,7 +219,7 @@ void *memmove(void *dest, const void *src, size_t size) #endif /* - * Since we need memmove anyway, would use it as memcpy too. + * Since we need memmove anyway, we could use it as memcpy too. * Commented out for now to avoid breaking things. */ /* @@ -389,17 +389,17 @@ error_alloc_state: } /* - * This macro is used by architecture-specific files to decompress + * This function is used by architecture-specific files to decompress * the kernel image. */ #ifdef XZ_PREBOOT -STATIC int INIT __decompress(unsigned char *buf, long len, - long (*fill)(void*, unsigned long), - long (*flush)(void*, unsigned long), - unsigned char *out_buf, long olen, - long *pos, - void (*error)(char *x)) +STATIC int INIT __decompress(unsigned char *in, long in_size, + long (*fill)(void *dest, unsigned long size), + long (*flush)(void *src, unsigned long size), + unsigned char *out, long out_size, + long *in_used, + void (*error)(char *x)) { - return unxz(buf, len, fill, flush, out_buf, pos, error); + return unxz(in, in_size, fill, flush, out, in_used, error); } #endif diff --git a/lib/xz/Kconfig b/lib/xz/Kconfig index aef086a6bf2f..6b80453d8f54 100644 --- a/lib/xz/Kconfig +++ b/lib/xz/Kconfig @@ -5,7 +5,8 @@ config XZ_DEC help LZMA2 compression algorithm and BCJ filters are supported using the .xz file format as the container. For integrity checking, - CRC32 is supported. See Documentation/staging/xz.rst for more information. + CRC32 is supported. See Documentation/staging/xz.rst for more + information. if XZ_DEC diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 207325eaf1d1..dae2089e7bc6 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -530,14 +530,17 @@ quiet_cmd_fit = FIT $@ # XZ # --------------------------------------------------------------------------- -# Use xzkern to compress the kernel image and xzmisc to compress other things. +# Use xzkern or xzkern_with_size to compress the kernel image and xzmisc to +# compress other things. # # xzkern uses a big LZMA2 dictionary since it doesn't increase memory usage # of the kernel decompressor. A BCJ filter is used if it is available for -# the target architecture. xzkern also appends uncompressed size of the data -# using size_append. The .xz format has the size information available at -# the end of the file too, but it's in more complex format and it's good to -# avoid changing the part of the boot code that reads the uncompressed size. +# the target architecture. +# +# xzkern_with_size also appends uncompressed size of the data using +# size_append. The .xz format has the size information available at the end +# of the file too, but it's in more complex format and it's good to avoid +# changing the part of the boot code that reads the uncompressed size. # Note that the bytes added by size_append will make the xz tool think that # the file is corrupt. This is expected. # -- cgit v1.2.3-70-g09d2 From 8653c909922743bceb4800e5cc26087208c9e0e6 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Sun, 21 Jul 2024 16:36:28 +0300 Subject: xz: use 128 MiB dictionary and force single-threaded mode This only affects kernel image compression, not any other xz usage. Desktop kernels on x86-64 are already around 60 MiB. Using a dictionary larger than 32 MiB should have no downsides nowadays as anyone building the kernel should have plenty of RAM. 128 MiB dictionary needs 1346 MiB of RAM with xz versions 5.0.x - 5.6.x in single-threaded mode. On archs that use xz_wrap.sh, kernel decompression is done in single-call mode so a larger dictionary doesn't affect boot-time memory requirements. xz >= 5.6.0 uses multithreaded mode by default which compresses slightly worse than single-threaded mode. Kernel compression rarely used more than one thread anyway because with 32 MiB dictionary size the default block size was 96 MiB in multithreaded mode. So only a single thread was used anyway unless the kernel was over 96 MiB. Comparison to CONFIG_KERNEL_LZMA: It uses "lzma -9" which mapped to 32 MiB dictionary in LZMA Utils 4.32.7 (the final release in 2008). Nowadays the lzma tool on most systems is from XZ Utils where -9 maps to 64 MiB dictionary. So using a 32 MiB dictionary with CONFIG_KERNEL_XZ may have compressed big kernels slightly worse than the old LZMA option. Comparison to CONFIG_KERNEL_ZSTD: zstd uses 128 MiB dictionary. Link: https://lkml.kernel.org/r/20240721133633.47721-14-lasse.collin@tukaani.org Signed-off-by: Lasse Collin Reviewed-by: Sam James Cc: Albert Ou Cc: Catalin Marinas Cc: Emil Renner Berthing Cc: Greg Kroah-Hartman Cc: Herbert Xu Cc: Joel Stanley Cc: Jonathan Corbet Cc: Jubin Zhong Cc: Jules Maselbas Cc: Krzysztof Kozlowski Cc: Michael Ellerman Cc: Palmer Dabbelt Cc: Paul Walmsley Cc: Randy Dunlap Cc: Rui Li Cc: Simon Glass Cc: Thomas Gleixner Cc: Will Deacon Signed-off-by: Andrew Morton --- scripts/xz_wrap.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/xz_wrap.sh b/scripts/xz_wrap.sh index bb760b721b2c..c8c36441ab70 100755 --- a/scripts/xz_wrap.sh +++ b/scripts/xz_wrap.sh @@ -16,4 +16,15 @@ case $SRCARCH in sparc) BCJ=--sparc ;; esac -exec $XZ --check=crc32 $BCJ --lzma2=$LZMA2OPTS,dict=32MiB +# Use single-threaded mode because it compresses a little better +# (and uses less RAM) than multithreaded mode. +# +# For the best compression, the dictionary size shouldn't be +# smaller than the uncompressed kernel. 128 MiB dictionary +# needs less than 1400 MiB of RAM in single-threaded mode. +# +# On the archs that use this script to compress the kernel, +# decompression in the preboot code is done in single-call mode. +# Thus the dictionary size doesn't affect the memory requirements +# of the preboot decompressor at all. +exec $XZ --check=crc32 --threads=1 $BCJ --lzma2=$LZMA2OPTS,dict=128MiB -- cgit v1.2.3-70-g09d2 From 7472ff8adad8655f38b060a602f66e59c93c4793 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Sun, 21 Jul 2024 16:36:29 +0300 Subject: xz: adjust arch-specific options for better kernel compression Use LZMA2 options that match the arch-specific alignment of instructions. This change reduces compressed kernel size 0-2 % depending on the arch. On 1-byte-aligned x86 it makes no difference and on 4-byte-aligned archs it helps the most. Use the ARM-Thumb filter for ARM-Thumb2 kernels. This reduces compressed kernel size about 5 %.[1] Previously such kernels were compressed using the ARM filter which didn't do anything useful with ARM-Thumb2 code. Add BCJ filter support for ARM64 and RISC-V. Compared to unfiltered XZ or plain LZMA, the compressed kernel size is reduced about 5 % on ARM64 and 7 % on RISC-V. A new enough version of the xz tool is required: 5.4.0 for ARM64 and 5.6.0 for RISC-V. With an old xz version, a message is printed to standard error and the kernel is compressed without the filter. Update lib/decompress_unxz.c to match the changes to xz_wrap.sh. Update the CONFIG_KERNEL_XZ help text in init/Kconfig: - Add the RISC-V and ARM64 filters. - Clarify that the PowerPC filter is for big endian only. - Omit IA-64. Link: https://lore.kernel.org/lkml/1637379771-39449-1-git-send-email-zhongjubin@huawei.com/ [1] Link: https://lkml.kernel.org/r/20240721133633.47721-15-lasse.collin@tukaani.org Signed-off-by: Lasse Collin Reviewed-by: Sam James Cc: Simon Glass Cc: Catalin Marinas Cc: Will Deacon Cc: Paul Walmsley Cc: Palmer Dabbelt Cc: Albert Ou Cc: Jubin Zhong Cc: Jules Maselbas Cc: Emil Renner Berthing Cc: Greg Kroah-Hartman Cc: Herbert Xu Cc: Joel Stanley Cc: Jonathan Corbet Cc: Krzysztof Kozlowski Cc: Michael Ellerman Cc: Randy Dunlap Cc: Rui Li Cc: Thomas Gleixner Signed-off-by: Andrew Morton --- init/Kconfig | 5 +- lib/decompress_unxz.c | 14 ++++- scripts/xz_wrap.sh | 142 ++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 152 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/init/Kconfig b/init/Kconfig index 5783a0b87517..583cb07176a9 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -310,8 +310,9 @@ config KERNEL_XZ BCJ filters which can improve compression ratio of executable code. The size of the kernel is about 30% smaller with XZ in comparison to gzip. On architectures for which there is a BCJ - filter (i386, x86_64, ARM, IA-64, PowerPC, and SPARC), XZ - will create a few percent smaller kernel than plain LZMA. + filter (i386, x86_64, ARM, ARM64, RISC-V, big endian PowerPC, + and SPARC), XZ will create a few percent smaller kernel than + plain LZMA. The speed is about the same as with LZMA: The decompression speed of XZ is better than that of bzip2 but worse than gzip diff --git a/lib/decompress_unxz.c b/lib/decompress_unxz.c index 46aa3be13fc5..cae00395d7a6 100644 --- a/lib/decompress_unxz.c +++ b/lib/decompress_unxz.c @@ -126,11 +126,21 @@ #ifdef CONFIG_X86 # define XZ_DEC_X86 #endif -#ifdef CONFIG_PPC +#if defined(CONFIG_PPC) && defined(CONFIG_CPU_BIG_ENDIAN) # define XZ_DEC_POWERPC #endif #ifdef CONFIG_ARM -# define XZ_DEC_ARM +# ifdef CONFIG_THUMB2_KERNEL +# define XZ_DEC_ARMTHUMB +# else +# define XZ_DEC_ARM +# endif +#endif +#ifdef CONFIG_ARM64 +# define XZ_DEC_ARM64 +#endif +#ifdef CONFIG_RISCV +# define XZ_DEC_RISCV #endif #ifdef CONFIG_SPARC # define XZ_DEC_SPARC diff --git a/scripts/xz_wrap.sh b/scripts/xz_wrap.sh index c8c36441ab70..f19369687030 100755 --- a/scripts/xz_wrap.sh +++ b/scripts/xz_wrap.sh @@ -6,14 +6,146 @@ # # Author: Lasse Collin +# This has specialized settings for the following archs. However, +# XZ-compressed kernel isn't currently supported on every listed arch. +# +# Arch Align Notes +# arm 2/4 ARM and ARM-Thumb2 +# arm64 4 +# csky 2 +# loongarch 4 +# mips 2/4 MicroMIPS is 2-byte aligned +# parisc 4 +# powerpc 4 Uses its own wrapper for compressors instead of this. +# riscv 2/4 +# s390 2 +# sh 2 +# sparc 4 +# x86 1 + +# A few archs use 2-byte or 4-byte aligned instructions depending on +# the kernel config. This function is used to check if the relevant +# config option is set to "y". +is_enabled() +{ + grep -q "^$1=y$" include/config/auto.conf +} + +# XZ_VERSION is needed to disable features that aren't available in +# old XZ Utils versions. +XZ_VERSION=$($XZ --robot --version) || exit +XZ_VERSION=$(printf '%s\n' "$XZ_VERSION" | sed -n 's/^XZ_VERSION=//p') + +# Assume that no BCJ filter is available. BCJ= -LZMA2OPTS= +# Set the instruction alignment to 1, 2, or 4 bytes. +# +# Set the BCJ filter if one is available. +# It must match the #ifdef usage in lib/decompress_unxz.c. case $SRCARCH in - x86) BCJ=--x86 ;; - powerpc) BCJ=--powerpc ;; - arm) BCJ=--arm ;; - sparc) BCJ=--sparc ;; + arm) + if is_enabled CONFIG_THUMB2_KERNEL; then + ALIGN=2 + BCJ=--armthumb + else + ALIGN=4 + BCJ=--arm + fi + ;; + + arm64) + ALIGN=4 + + # ARM64 filter was added in XZ Utils 5.4.0. + if [ "$XZ_VERSION" -ge 50040002 ]; then + BCJ=--arm64 + else + echo "$0: Upgrading to xz >= 5.4.0" \ + "would enable the ARM64 filter" \ + "for better compression" >&2 + fi + ;; + + csky) + ALIGN=2 + ;; + + loongarch) + ALIGN=4 + ;; + + mips) + if is_enabled CONFIG_CPU_MICROMIPS; then + ALIGN=2 + else + ALIGN=4 + fi + ;; + + parisc) + ALIGN=4 + ;; + + powerpc) + ALIGN=4 + + # The filter is only for big endian instruction encoding. + if is_enabled CONFIG_CPU_BIG_ENDIAN; then + BCJ=--powerpc + fi + ;; + + riscv) + if is_enabled CONFIG_RISCV_ISA_C; then + ALIGN=2 + else + ALIGN=4 + fi + + # RISC-V filter was added in XZ Utils 5.6.0. + if [ "$XZ_VERSION" -ge 50060002 ]; then + BCJ=--riscv + else + echo "$0: Upgrading to xz >= 5.6.0" \ + "would enable the RISC-V filter" \ + "for better compression" >&2 + fi + ;; + + s390) + ALIGN=2 + ;; + + sh) + ALIGN=2 + ;; + + sparc) + ALIGN=4 + BCJ=--sparc + ;; + + x86) + ALIGN=1 + BCJ=--x86 + ;; + + *) + echo "$0: Arch-specific tuning is missing for '$SRCARCH'" >&2 + + # Guess 2-byte-aligned instructions. Guessing too low + # should hurt less than guessing too high. + ALIGN=2 + ;; +esac + +# Select the LZMA2 options matching the instruction alignment. +case $ALIGN in + 1) LZMA2OPTS= ;; + 2) LZMA2OPTS=lp=1 ;; + 4) LZMA2OPTS=lp=2,lc=2 ;; + *) echo "$0: ALIGN wrong or missing" >&2; exit 1 ;; esac # Use single-threaded mode because it compresses a little better -- cgit v1.2.3-70-g09d2 From d1c7848b58c610bc83f4b05ff0b8244b59f56175 Mon Sep 17 00:00:00 2001 From: Julian Sun Date: Tue, 23 Jul 2024 05:11:54 -0400 Subject: scripts: add macro_checker script to check unused parameters in macros Recently, I saw a patch[1] on the ext4 mailing list regarding the correction of a macro definition error. Jan mentioned that "The bug in the macro is a really nasty trap...". Because existing compilers are unable to detect unused parameters in macro definitions. This inspired me to write a script to check for unused parameters in macro definitions and to run it. Surprisingly, the script uncovered numerous issues across various subsystems, including filesystems, drivers, and sound etc. Some of these issues involved parameters that were accepted but never used, for example: #define XFS_DAENTER_DBS(mp,w) \ (XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 0)) where mp was unused. While others are actual bugs. For example: #define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(x) \ (ab->hw_params.regs->hal_seq_wcss_umac_ce0_src_reg) #define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(x) \ (ab->hw_params.regs->hal_seq_wcss_umac_ce0_dst_reg) #define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(x) \ (ab->hw_params.regs->hal_seq_wcss_umac_ce1_src_reg) #define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(x) \ (ab->hw_params.regs->hal_seq_wcss_umac_ce1_dst_reg) where x was entirely unused, and instead, a local variable ab was used. I have submitted patches[2-5] to fix some of these issues, but due to the large number, many still remain unaddressed. I believe that the kernel and matainers would benefit from this script to check for unused parameters in macro definitions. It should be noted that it may cause some false positives in conditional compilation scenarios, such as #ifdef DEBUG static int debug(arg) {}; #else #define debug(arg) #endif So the caller needs to manually verify whether it is a true issue. But this should be fine, because Maintainers should only need to review their own subsystems, which typically results in only a few reports. [1]: https://patchwork.ozlabs.org/project/linux-ext4/patch/1717652596-58760-1-git-send-email-carrionbent@linux.alibaba.com/ [2]: https://lore.kernel.org/linux-xfs/20240721112701.212342-1-sunjunchao2870@gmail.com/ [3]: https://lore.kernel.org/linux-bcachefs/20240721123943.246705-1-sunjunchao2870@gmail.com/ [4]: https://sourceforge.net/p/linux-f2fs/mailman/message/58797811/ [5]: https://sourceforge.net/p/linux-f2fs/mailman/message/58797812/ [sunjunchao2870@gmail.com: reduce false positives] Link: https://lkml.kernel.org/r/20240726031310.254742-1-sunjunchao2870@gmail.com Link: https://lkml.kernel.org/r/20240723091154.52458-1-sunjunchao2870@gmail.com Signed-off-by: Julian Sun Cc: Al Viro Cc: Christian Brauner Cc: Darrick J. Wong Cc: Jan Kara Cc: Junchao Sun Cc: Kalle Valo Cc: Masahiro Yamada Cc: Miguel Ojeda Cc: Nicolas Schier Signed-off-by: Andrew Morton --- scripts/macro_checker.py | 131 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100755 scripts/macro_checker.py (limited to 'scripts') diff --git a/scripts/macro_checker.py b/scripts/macro_checker.py new file mode 100755 index 000000000000..ba550982e98f --- /dev/null +++ b/scripts/macro_checker.py @@ -0,0 +1,131 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: GPL-2.0 +# Author: Julian Sun + +""" Find macro definitions with unused parameters. """ + +import argparse +import os +import re + +parser = argparse.ArgumentParser() + +parser.add_argument("path", type=str, help="The file or dir path that needs check") +parser.add_argument("-v", "--verbose", action="store_true", + help="Check conditional macros, but may lead to more false positives") +args = parser.parse_args() + +macro_pattern = r"#define\s+(\w+)\(([^)]*)\)" +# below vars were used to reduce false positives +fp_patterns = [r"\s*do\s*\{\s*\}\s*while\s*\(\s*0\s*\)", + r"\(?0\)?", r"\(?1\)?"] +correct_macros = [] +cond_compile_mark = "#if" +cond_compile_end = "#endif" + +def check_macro(macro_line, report): + match = re.match(macro_pattern, macro_line) + if match: + macro_def = re.sub(macro_pattern, '', macro_line) + identifier = match.group(1) + content = match.group(2) + arguments = [item.strip() for item in content.split(',') if item.strip()] + + macro_def = macro_def.strip() + if not macro_def: + return + # used to reduce false positives, like #define endfor_nexthops(rt) } + if len(macro_def) == 1: + return + + for fp_pattern in fp_patterns: + if (re.match(fp_pattern, macro_def)): + return + + for arg in arguments: + # used to reduce false positives + if "..." in arg: + return + for arg in arguments: + if not arg in macro_def and report == False: + return + # if there is a correct macro with the same name, do not report it. + if not arg in macro_def and identifier not in correct_macros: + print(f"Argument {arg} is not used in function-line macro {identifier}") + return + + correct_macros.append(identifier) + + +# remove comment and whitespace +def macro_strip(macro): + comment_pattern1 = r"\/\/*" + comment_pattern2 = r"\/\**\*\/" + + macro = macro.strip() + macro = re.sub(comment_pattern1, '', macro) + macro = re.sub(comment_pattern2, '', macro) + + return macro + +def file_check_macro(file_path, report): + # number of conditional compiling + cond_compile = 0 + # only check .c and .h file + if not file_path.endswith(".c") and not file_path.endswith(".h"): + return + + with open(file_path, "r") as f: + while True: + line = f.readline() + if not line: + break + line = line.strip() + if line.startswith(cond_compile_mark): + cond_compile += 1 + continue + if line.startswith(cond_compile_end): + cond_compile -= 1 + continue + + macro = re.match(macro_pattern, line) + if macro: + macro = macro_strip(macro.string) + while macro[-1] == '\\': + macro = macro[0:-1] + macro = macro.strip() + macro += f.readline() + macro = macro_strip(macro) + if not args.verbose: + if file_path.endswith(".c") and cond_compile != 0: + continue + # 1 is for #ifdef xxx at the beginning of the header file + if file_path.endswith(".h") and cond_compile != 1: + continue + check_macro(macro, report) + +def get_correct_macros(path): + file_check_macro(path, False) + +def dir_check_macro(dir_path): + + for dentry in os.listdir(dir_path): + path = os.path.join(dir_path, dentry) + if os.path.isdir(path): + dir_check_macro(path) + elif os.path.isfile(path): + get_correct_macros(path) + file_check_macro(path, True) + + +def main(): + if os.path.isfile(args.path): + get_correct_macros(args.path) + file_check_macro(args.path, True) + elif os.path.isdir(args.path): + dir_check_macro(args.path) + else: + print(f"{args.path} doesn't exit or is neither a file nor a dir") + +if __name__ == "__main__": + main() \ No newline at end of file -- cgit v1.2.3-70-g09d2 From a633a4b8001a7f2a12584f267a3280990d9ababa Mon Sep 17 00:00:00 2001 From: Kuan-Ying Lee Date: Tue, 23 Jul 2024 14:48:57 +0800 Subject: scripts/gdb: fix timerlist parsing issue Patch series "Fix some GDB command error and add some GDB commands", v3. Fix some GDB command errors and add some useful GDB commands. This patch (of 5): Commit 7988e5ae2be7 ("tick: Split nohz and highres features from nohz_mode") and commit 7988e5ae2be7 ("tick: Split nohz and highres features from nohz_mode") move 'tick_stopped' and 'nohz_mode' to flags field which will break the gdb lx-mounts command: (gdb) lx-timerlist Python Exception : There is no member named nohz_mode. Error occurred in Python: There is no member named nohz_mode. (gdb) lx-timerlist Python Exception : There is no member named tick_stopped. Error occurred in Python: There is no member named tick_stopped. We move 'tick_stopped' and 'nohz_mode' to flags field instead. Link: https://lkml.kernel.org/r/20240723064902.124154-1-kuan-ying.lee@canonical.com Link: https://lkml.kernel.org/r/20240723064902.124154-2-kuan-ying.lee@canonical.com Fixes: a478ffb2ae23 ("tick: Move individual bit features to debuggable mask accesses") Fixes: 7988e5ae2be7 ("tick: Split nohz and highres features from nohz_mode") Signed-off-by: Kuan-Ying Lee Cc: Jan Kiszka Cc: Kieran Bingham Cc: Signed-off-by: Andrew Morton --- scripts/gdb/linux/timerlist.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/timerlist.py b/scripts/gdb/linux/timerlist.py index 64bc87191003..98445671fe83 100644 --- a/scripts/gdb/linux/timerlist.py +++ b/scripts/gdb/linux/timerlist.py @@ -87,21 +87,22 @@ def print_cpu(hrtimer_bases, cpu, max_clock_bases): text += "\n" if constants.LX_CONFIG_TICK_ONESHOT: - fmts = [(" .{} : {}", 'nohz_mode'), - (" .{} : {} nsecs", 'last_tick'), - (" .{} : {}", 'tick_stopped'), - (" .{} : {}", 'idle_jiffies'), - (" .{} : {}", 'idle_calls'), - (" .{} : {}", 'idle_sleeps'), - (" .{} : {} nsecs", 'idle_entrytime'), - (" .{} : {} nsecs", 'idle_waketime'), - (" .{} : {} nsecs", 'idle_exittime'), - (" .{} : {} nsecs", 'idle_sleeptime'), - (" .{}: {} nsecs", 'iowait_sleeptime'), - (" .{} : {}", 'last_jiffies'), - (" .{} : {}", 'next_timer'), - (" .{} : {} nsecs", 'idle_expires')] - text += "\n".join([s.format(f, ts[f]) for s, f in fmts]) + TS_FLAG_STOPPED = 1 << 1 + TS_FLAG_NOHZ = 1 << 4 + text += f" .{'nohz':15s}: {int(bool(ts['flags'] & TS_FLAG_NOHZ))}\n" + text += f" .{'last_tick':15s}: {ts['last_tick']}\n" + text += f" .{'tick_stopped':15s}: {int(bool(ts['flags'] & TS_FLAG_STOPPED))}\n" + text += f" .{'idle_jiffies':15s}: {ts['idle_jiffies']}\n" + text += f" .{'idle_calls':15s}: {ts['idle_calls']}\n" + text += f" .{'idle_sleeps':15s}: {ts['idle_sleeps']}\n" + text += f" .{'idle_entrytime':15s}: {ts['idle_entrytime']} nsecs\n" + text += f" .{'idle_waketime':15s}: {ts['idle_waketime']} nsecs\n" + text += f" .{'idle_exittime':15s}: {ts['idle_exittime']} nsecs\n" + text += f" .{'idle_sleeptime':15s}: {ts['idle_sleeptime']} nsecs\n" + text += f" .{'iowait_sleeptime':15s}: {ts['iowait_sleeptime']} nsecs\n" + text += f" .{'last_jiffies':15s}: {ts['last_jiffies']}\n" + text += f" .{'next_timer':15s}: {ts['next_timer']}\n" + text += f" .{'idle_expires':15s}: {ts['idle_expires']} nsecs\n" text += "\njiffies: {}\n".format(jiffies) text += "\n" -- cgit v1.2.3-70-g09d2 From 0c77e103c45fa1b119f5d3bb4625eee081c1a6cf Mon Sep 17 00:00:00 2001 From: Kuan-Ying Lee Date: Tue, 23 Jul 2024 14:48:58 +0800 Subject: scripts/gdb: add iteration function for rbtree Add inorder iteration function for rbtree usage. This is a preparation patch for the next patch to fix the gdb mounts issue. Link: https://lkml.kernel.org/r/20240723064902.124154-3-kuan-ying.lee@canonical.com Fixes: 2eea9ce4310d ("mounts: keep list of mounts in an rbtree") Signed-off-by: Kuan-Ying Lee Cc: Jan Kiszka Cc: Kieran Bingham Cc: Signed-off-by: Andrew Morton --- scripts/gdb/linux/rbtree.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'scripts') diff --git a/scripts/gdb/linux/rbtree.py b/scripts/gdb/linux/rbtree.py index fe462855eefd..fcbcc5f4153c 100644 --- a/scripts/gdb/linux/rbtree.py +++ b/scripts/gdb/linux/rbtree.py @@ -9,6 +9,18 @@ from linux import utils rb_root_type = utils.CachedType("struct rb_root") rb_node_type = utils.CachedType("struct rb_node") +def rb_inorder_for_each(root): + def inorder(node): + if node: + yield from inorder(node['rb_left']) + yield node + yield from inorder(node['rb_right']) + + yield from inorder(root['rb_node']) + +def rb_inorder_for_each_entry(root, gdbtype, member): + for node in rb_inorder_for_each(root): + yield utils.container_of(node, gdbtype, member) def rb_first(root): if root.type == rb_root_type.get_type(): -- cgit v1.2.3-70-g09d2 From 4b183f613924ad536be2f8bd12b307e9c5a96bf6 Mon Sep 17 00:00:00 2001 From: Kuan-Ying Lee Date: Tue, 23 Jul 2024 14:48:59 +0800 Subject: scripts/gdb: fix lx-mounts command error (gdb) lx-mounts mount super_block devname pathname fstype options Python Exception : There is no member named list. Error occurred in Python: There is no member named list. We encounter the above issue after commit 2eea9ce4310d ("mounts: keep list of mounts in an rbtree"). The commit move a mount from list into rbtree. So we can instead use rbtree to iterate all mounts information. Link: https://lkml.kernel.org/r/20240723064902.124154-4-kuan-ying.lee@canonical.com Fixes: 2eea9ce4310d ("mounts: keep list of mounts in an rbtree") Signed-off-by: Kuan-Ying Lee Cc: Jan Kiszka Cc: Kieran Bingham Cc: Signed-off-by: Andrew Morton --- scripts/gdb/linux/proc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py index 43c687e7a69d..65dd1bd12964 100644 --- a/scripts/gdb/linux/proc.py +++ b/scripts/gdb/linux/proc.py @@ -18,6 +18,7 @@ from linux import utils from linux import tasks from linux import lists from linux import vfs +from linux import rbtree from struct import * @@ -172,8 +173,7 @@ values of that process namespace""" gdb.write("{:^18} {:^15} {:>9} {} {} options\n".format( "mount", "super_block", "devname", "pathname", "fstype")) - for mnt in lists.list_for_each_entry(namespace['list'], - mount_ptr_type, "mnt_list"): + for mnt in rbtree.rb_inorder_for_each_entry(namespace['mounts'], mount_ptr_type, "mnt_node"): devname = mnt['mnt_devname'].string() devname = devname if devname else "none" -- cgit v1.2.3-70-g09d2 From 35249f68b5d38bff1c616cc9761ecc3d820163b1 Mon Sep 17 00:00:00 2001 From: Kuan-Ying Lee Date: Tue, 23 Jul 2024 14:49:00 +0800 Subject: scripts/gdb: add 'lx-stack_depot_lookup' command. This command allows users to quickly retrieve a stacktrace using a handle obtained from a memory coredump. Example output: (gdb) lx-stack_depot_lookup 0x00c80300 0xffff8000807965b4 : mov x20, x0 0xffff800081a077d8 : mov x1, x0 0xffff800081a079a0 : cbnz w0, 0xffff800081a07968 0xffff800082f4a3fc : ldr x19, [sp, #16] 0xffff800080a0fb34 : ldp x3, x4, [sp, #96] 0xffff800080a0a550 : ldp x19, x20, [sp, #16] 0xffff8000808e7b40 : mov w5, w0 0xffff800080a0b8ac : mov x23, x0 0xffff800080914a48 : mov x6, x0 0xffff8000809151c4 : ldr x21, [sp, #32] Link: https://lkml.kernel.org/r/20240723064902.124154-5-kuan-ying.lee@canonical.com Signed-off-by: Kuan-Ying Lee Cc: Jan Kiszka Cc: Kieran Bingham Signed-off-by: Andrew Morton --- scripts/gdb/linux/stackdepot.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'scripts') diff --git a/scripts/gdb/linux/stackdepot.py b/scripts/gdb/linux/stackdepot.py index bb3a0f843931..37313a5a51a0 100644 --- a/scripts/gdb/linux/stackdepot.py +++ b/scripts/gdb/linux/stackdepot.py @@ -13,6 +13,13 @@ if constants.LX_CONFIG_STACKDEPOT: stack_record_type = utils.CachedType('struct stack_record') DEPOT_STACK_ALIGN = 4 +def help(): + t = """Usage: lx-stack_depot_lookup [Hex handle value] + Example: + lx-stack_depot_lookup 0x00c80300\n""" + gdb.write("Unrecognized command\n") + raise gdb.GdbError(t) + def stack_depot_fetch(handle): global DEPOT_STACK_ALIGN global stack_record_type @@ -57,3 +64,23 @@ def stack_depot_print(handle): gdb.execute("x /i 0x%x" % (int(entries[i]))) except Exception as e: gdb.write("%s\n" % e) + +class StackDepotLookup(gdb.Command): + """Search backtrace by handle""" + + def __init__(self): + if constants.LX_CONFIG_STACKDEPOT: + super(StackDepotLookup, self).__init__("lx-stack_depot_lookup", gdb.COMMAND_SUPPORT) + + def invoke(self, args, from_tty): + if not constants.LX_CONFIG_STACKDEPOT: + raise gdb.GdbError('CONFIG_STACKDEPOT is not set') + + argv = gdb.string_to_argv(args) + if len(argv) == 1: + handle = int(argv[0], 16) + stack_depot_print(gdb.Value(handle).cast(utils.get_uint_type())) + else: + help() + +StackDepotLookup() -- cgit v1.2.3-70-g09d2 From 0833952c0768daea7d9b6dc59a35bef309234b88 Mon Sep 17 00:00:00 2001 From: Kuan-Ying Lee Date: Tue, 23 Jul 2024 14:49:01 +0800 Subject: scripts/gdb: add 'lx-kasan_mem_to_shadow' command This command allows users to quickly translate memory address to the kasan shadow memory address. Example output: (gdb) lx-kasan_mem_to_shadow 0xffff000019acc008 shadow addr: 0xffff600003359801 Link: https://lkml.kernel.org/r/20240723064902.124154-6-kuan-ying.lee@canonical.com Signed-off-by: Kuan-Ying Lee Cc: Jan Kiszka Cc: Kieran Bingham Signed-off-by: Andrew Morton --- scripts/gdb/linux/kasan.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ scripts/gdb/vmlinux-gdb.py | 1 + 2 files changed, 45 insertions(+) create mode 100644 scripts/gdb/linux/kasan.py (limited to 'scripts') diff --git a/scripts/gdb/linux/kasan.py b/scripts/gdb/linux/kasan.py new file mode 100644 index 000000000000..56730b3fde0b --- /dev/null +++ b/scripts/gdb/linux/kasan.py @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright 2024 Canonical Ltd. +# +# Authors: +# Kuan-Ying Lee +# + +import gdb +from linux import constants, mm + +def help(): + t = """Usage: lx-kasan_mem_to_shadow [Hex memory addr] + Example: + lx-kasan_mem_to_shadow 0xffff000008eca008\n""" + gdb.write("Unrecognized command\n") + raise gdb.GdbError(t) + +class KasanMemToShadow(gdb.Command): + """Translate memory address to kasan shadow address""" + + p_ops = None + + def __init__(self): + if constants.LX_CONFIG_KASAN_GENERIC or constants.LX_CONFIG_KASAN_SW_TAGS: + super(KasanMemToShadow, self).__init__("lx-kasan_mem_to_shadow", gdb.COMMAND_SUPPORT) + + def invoke(self, args, from_tty): + if not constants.LX_CONFIG_KASAN_GENERIC or constants.LX_CONFIG_KASAN_SW_TAGS: + raise gdb.GdbError('CONFIG_KASAN_GENERIC or CONFIG_KASAN_SW_TAGS is not set') + + argv = gdb.string_to_argv(args) + if len(argv) == 1: + if self.p_ops is None: + self.p_ops = mm.page_ops().ops + addr = int(argv[0], 16) + shadow_addr = self.kasan_mem_to_shadow(addr) + gdb.write('shadow addr: 0x%x\n' % shadow_addr) + else: + help() + def kasan_mem_to_shadow(self, addr): + return (addr >> self.p_ops.KASAN_SHADOW_SCALE_SHIFT) + self.p_ops.KASAN_SHADOW_OFFSET + +KasanMemToShadow() diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py index fc53cdf286f1..d4eeed4506fd 100644 --- a/scripts/gdb/vmlinux-gdb.py +++ b/scripts/gdb/vmlinux-gdb.py @@ -49,3 +49,4 @@ else: import linux.page_owner import linux.slab import linux.vmalloc + import linux.kasan -- cgit v1.2.3-70-g09d2 From 076979ee62f23c0eff035e0528b4cfadbe743255 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sat, 17 Aug 2024 17:50:25 -0400 Subject: scripts/decode_stacktrace.sh: nix-ify nix only puts /usr/bin/env at the standard location (as required by posix), so shebangs have to be tweaked. Link: https://lkml.kernel.org/r/20240817215025.161628-1-kent.overstreet@linux.dev Signed-off-by: Kent Overstreet Cc: Bjorn Andersson Cc: Elliot Berman Cc: Xiong Nandi Signed-off-by: Andrew Morton --- scripts/decode_stacktrace.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh index a0f50a5b4f7c..ed9f914334cc 100755 --- a/scripts/decode_stacktrace.sh +++ b/scripts/decode_stacktrace.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # SPDX-License-Identifier: GPL-2.0 # (c) 2014, Sasha Levin #set -x -- cgit v1.2.3-70-g09d2 From 0f69dc295b681753ac3455705357e600bc9c7745 Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Fri, 23 Aug 2024 10:27:42 +0200 Subject: scripts/decode_stacktrace.sh: remove find_module recursion and improve error reporting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch series "scripts/decode_stacktrace.sh: improve error reporting and usability", v2. This small series improves usability of scripts/decode_stacktrace.sh by improving the usage text and correctly reporting when modules are built without debugging symbols. This patch (of 3): The find_module() function can fail for two reasons: * the module was not found * the module was found but without debugging info In both cases the user is reported the same error: WARNING! Modules path isn't set, but is needed to parse this symbol This is misleading in case the modules path is set correctly. find_module() is currently implemented as a recursive function based on global variables in order to check up to 4 different paths. This is not straightforward to read and even less to modify. Besides, the debuginfo code at the beginning of find_module() is executed identically every time the function is entered, i.e. up to 4 times per each module search due to recursion. To be able to improve error reporting, first rewrite the find_module() function to remove recursion. The new version of the function iterates over all the same (up to 4) paths as before and for each of them does the same checks as before. At the end of the iteration it is now able to print an appropriate error message, so that has been moved from the caller into find_module(). Finally, when the module is found but without debugging info, mention the two Kconfig variables one needs to set in order to have the needed debugging symbols. Link: https://lkml.kernel.org/r/20240823-decode_stacktrace-find_module-improvements-v2-0-d7a57d35558b@bootlin.com Link: https://lkml.kernel.org/r/20240823-decode_stacktrace-find_module-improvements-v2-1-d7a57d35558b@bootlin.com Signed-off-by: Luca Ceresoli Reviewed-by: Stephen Boyd Cc: Alexis Lothoré (eBPF Foundation) Cc: Konstantin Khlebnikov Cc: Luca Ceresoli Cc: Sasha Levin Cc: Thomas Petazzoni Signed-off-by: Andrew Morton --- scripts/decode_stacktrace.sh | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'scripts') diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh index ed9f914334cc..e6b38ab7c8c5 100755 --- a/scripts/decode_stacktrace.sh +++ b/scripts/decode_stacktrace.sh @@ -89,31 +89,32 @@ find_module() { fi fi - if [[ "$modpath" != "" ]] ; then - for fn in $(find "$modpath" -name "${module//_/[-_]}.ko*") ; do - if ${READELF} -WS "$fn" | grep -qwF .debug_line ; then - echo $fn - return - fi - done - return 1 - fi - - modpath=$(dirname "$vmlinux") - find_module && return - - if [[ $release == "" ]] ; then + if [ -z $release ] ; then release=$(gdb -ex 'print init_uts_ns.name.release' -ex 'quit' -quiet -batch "$vmlinux" 2>/dev/null | sed -n 's/\$1 = "\(.*\)".*/\1/p') fi + if [ -n "${release}" ] ; then + release_dirs="/usr/lib/debug/lib/modules/$release /lib/modules/$release" + fi - for dn in {/usr/lib/debug,}/lib/modules/$release ; do - if [ -e "$dn" ] ; then - modpath="$dn" - find_module && return + found_without_debug_info=false + for dir in "$modpath" "$(dirname "$vmlinux")" ${release_dirs}; do + if [ -n "${dir}" ] && [ -e "${dir}" ]; then + for fn in $(find "$dir" -name "${module//_/[-_]}.ko*") ; do + if ${READELF} -WS "$fn" | grep -qwF .debug_line ; then + echo $fn + return + fi + found_without_debug_info=true + done fi done - modpath="" + if [[ ${found_without_debug_info} == true ]]; then + echo "WARNING! No debugging info in module ${module}, rebuild with DEBUG_KERNEL and DEBUG_INFO" >&2 + else + echo "WARNING! Cannot find .ko for module ${module}, please pass a valid module path" >&2 + fi + return 1 } @@ -131,7 +132,6 @@ parse_symbol() { else local objfile=$(find_module) if [[ $objfile == "" ]] ; then - echo "WARNING! Modules path isn't set, but is needed to parse this symbol" >&2 return fi if [[ $aarray_support == true ]]; then -- cgit v1.2.3-70-g09d2 From a6d05e826d48cdffe11d9b73cf386840c19129d4 Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Fri, 23 Aug 2024 10:27:43 +0200 Subject: scripts/decode_stacktrace.sh: clarify command line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The syntax as expressed by usage() is not entirely correct: "" cannot be passed without "|auto". Additionally human reading of this syntax can be subject to misunderstanding due the mixture of '|' and '[]'. Improve readability in various ways: * rewrite using two lines for the two allowed usages * add square brackets around "" as it is optional when using debuginfod-find * move "" to inside the square brackets of the 2nd positional parameter * use underscores instead of spaces in <...> strings Link: https://lkml.kernel.org/r/20240823-decode_stacktrace-find_module-improvements-v2-2-d7a57d35558b@bootlin.com Signed-off-by: Luca Ceresoli Reviewed-by: Stephen Boyd Cc: Alexis Lothoré (eBPF Foundation) Cc: Konstantin Khlebnikov Cc: Sasha Levin Cc: Thomas Petazzoni Signed-off-by: Andrew Morton --- scripts/decode_stacktrace.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh index e6b38ab7c8c5..bac7ea8ee24f 100755 --- a/scripts/decode_stacktrace.sh +++ b/scripts/decode_stacktrace.sh @@ -5,7 +5,8 @@ usage() { echo "Usage:" - echo " $0 -r | [|auto] []" + echo " $0 -r " + echo " $0 [ [|auto []]]" } # Try to find a Rust demangler -- cgit v1.2.3-70-g09d2 From 7e1083598909f0fda82a0bf8cf788524ce4fccff Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Fri, 23 Aug 2024 10:27:44 +0200 Subject: scripts/decode_stacktrace.sh: add '-h' flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When no parameters are passed, the usage instructions are presented only when debuginfod-find is not found. This makes sense because with debuginfod none of the positional parameters are needed. However it means that users having debuginfod-find installed will have no chance of reading the usage text without opening the file. Many programs have a '-h' flag to get the usage, so add such a flag. Invoking 'scripts/decode_stacktrace.sh -h' will now show the usage text and exit. Link: https://lkml.kernel.org/r/20240823-decode_stacktrace-find_module-improvements-v2-3-d7a57d35558b@bootlin.com Signed-off-by: Luca Ceresoli Reviewed-by: Stephen Boyd Cc: Alexis Lothoré (eBPF Foundation) Cc: Konstantin Khlebnikov Cc: Sasha Levin Cc: Thomas Petazzoni Signed-off-by: Andrew Morton --- scripts/decode_stacktrace.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh index bac7ea8ee24f..826836d264c6 100755 --- a/scripts/decode_stacktrace.sh +++ b/scripts/decode_stacktrace.sh @@ -7,6 +7,7 @@ usage() { echo "Usage:" echo " $0 -r " echo " $0 [ [|auto []]]" + echo " $0 -h" } # Try to find a Rust demangler @@ -33,7 +34,10 @@ READELF=${UTIL_PREFIX}readelf${UTIL_SUFFIX} ADDR2LINE=${UTIL_PREFIX}addr2line${UTIL_SUFFIX} NM=${UTIL_PREFIX}nm${UTIL_SUFFIX} -if [[ $1 == "-r" ]] ; then +if [[ $1 == "-h" ]] ; then + usage + exit 0 +elif [[ $1 == "-r" ]] ; then vmlinux="" basepath="auto" modpath="" -- cgit v1.2.3-70-g09d2 From b4b8183055789b0d981e83217ce401db8037d033 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 2 Sep 2024 15:10:04 +0100 Subject: slimbus: generate MODULE_ALIAS() from MODULE_DEVICE_TABLE() Commit 9e663f4811c6 ("slimbus: core: add support to uevent") added the MODALIAS=slim:* uevent variable, but modpost does not generate the corresponding MODULE_ALIAS(). To support automatic module loading, slimbus drivers still need to manually add MODULE_ALIAS("slim:::*"), as seen in sound/soc/codecs/wcd9335.c. To automate this, make modpost generate the proper MODULE_ALIAS() from MODULE_DEVICE_TABLE(slim, ). Signed-off-by: Masahiro Yamada Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20240902141004.70048-5-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- scripts/mod/devicetable-offsets.c | 4 ++++ scripts/mod/file2alias.c | 11 +++++++++++ 2 files changed, 15 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index 518200813d4e..9c7b404defbd 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -153,6 +153,10 @@ int main(void) DEVID_FIELD(i3c_device_id, part_id); DEVID_FIELD(i3c_device_id, extra_info); + DEVID(slim_device_id); + DEVID_FIELD(slim_device_id, manf_id); + DEVID_FIELD(slim_device_id, prod_code); + DEVID(spi_device_id); DEVID_FIELD(spi_device_id, name); diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 5d1c61fa5a55..99dce93a4188 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -960,6 +960,16 @@ static int do_i3c_entry(const char *filename, void *symval, return 1; } +static int do_slim_entry(const char *filename, void *symval, char *alias) +{ + DEF_FIELD(symval, slim_device_id, manf_id); + DEF_FIELD(symval, slim_device_id, prod_code); + + sprintf(alias, "slim:%x:%x:*", manf_id, prod_code); + + return 1; +} + /* Looks like: spi:S */ static int do_spi_entry(const char *filename, void *symval, char *alias) @@ -1555,6 +1565,7 @@ static const struct devtable devtable[] = { {"rpmsg", SIZE_rpmsg_device_id, do_rpmsg_entry}, {"i2c", SIZE_i2c_device_id, do_i2c_entry}, {"i3c", SIZE_i3c_device_id, do_i3c_entry}, + {"slim", SIZE_slim_device_id, do_slim_entry}, {"spi", SIZE_spi_device_id, do_spi_entry}, {"dmi", SIZE_dmi_system_id, do_dmi_entry}, {"platform", SIZE_platform_device_id, do_platform_entry}, -- cgit v1.2.3-70-g09d2 From 78788c3ede90727ffb7b17287468a08b4e78ee3d Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Wed, 14 Aug 2024 00:40:27 +0200 Subject: kasan: simplify and clarify Makefile When KASAN support was being added to the Linux kernel, GCC did not yet support all of the KASAN-related compiler options. Thus, the KASAN Makefile had to probe the compiler for supported options. Nowadays, the Linux kernel GCC version requirement is 5.1+, and thus we don't need the probing of the -fasan-shadow-offset parameter: it exists in all 5.1+ GCCs. Simplify the KASAN Makefile to drop CFLAGS_KASAN_MINIMAL. Also add a few more comments and unify the indentation. [andreyknvl@gmail.com: comments fixes per Miguel] Link: https://lkml.kernel.org/r/20240814161052.10374-1-andrey.konovalov@linux.dev Link: https://lkml.kernel.org/r/20240813224027.84503-1-andrey.konovalov@linux.dev Signed-off-by: Andrey Konovalov Reviewed-by: Miguel Ojeda Acked-by: Marco Elver Cc: Alexander Potapenko Cc: Andrey Ryabinin Cc: Dmitry Vyukov Cc: Matthew Maurer Signed-off-by: Andrew Morton --- scripts/Makefile.kasan | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan index 390658a2d5b7..aab4154af00a 100644 --- a/scripts/Makefile.kasan +++ b/scripts/Makefile.kasan @@ -22,30 +22,31 @@ endif ifdef CONFIG_KASAN_GENERIC ifdef CONFIG_KASAN_INLINE + # When the number of memory accesses in a function is less than this + # call threshold number, the compiler will use inline instrumentation. + # 10000 is chosen offhand as a sufficiently large number to make all + # kernel functions to be instrumented inline. call_threshold := 10000 else call_threshold := 0 endif -CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address - -# -fasan-shadow-offset fails without -fsanitize -CFLAGS_KASAN_SHADOW := $(call cc-option, -fsanitize=kernel-address \ - -fasan-shadow-offset=$(KASAN_SHADOW_OFFSET), \ - $(call cc-option, -fsanitize=kernel-address \ - -mllvm -asan-mapping-offset=$(KASAN_SHADOW_OFFSET))) - -ifeq ($(strip $(CFLAGS_KASAN_SHADOW)),) - CFLAGS_KASAN := $(CFLAGS_KASAN_MINIMAL) -else - # Now add all the compiler specific options that are valid standalone - CFLAGS_KASAN := $(CFLAGS_KASAN_SHADOW) \ - $(call cc-param,asan-globals=1) \ - $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ - $(call cc-param,asan-instrument-allocas=1) -endif - -CFLAGS_KASAN += $(call cc-param,asan-stack=$(stack_enable)) +# First, enable -fsanitize=kernel-address together with providing the shadow +# mapping offset, as for GCC, -fasan-shadow-offset fails without -fsanitize +# (GCC accepts the shadow mapping offset via -fasan-shadow-offset instead of +# a --param like the other KASAN parameters). +# Instead of ifdef-checking the compiler, rely on cc-option. +CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \ + -fasan-shadow-offset=$(KASAN_SHADOW_OFFSET), \ + $(call cc-option, -fsanitize=kernel-address \ + -mllvm -asan-mapping-offset=$(KASAN_SHADOW_OFFSET))) + +# Now, add other parameters enabled similarly in both GCC and Clang. +# As some of them are not supported by older compilers, use cc-param. +CFLAGS_KASAN += $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ + $(call cc-param,asan-stack=$(stack_enable)) \ + $(call cc-param,asan-instrument-allocas=1) \ + $(call cc-param,asan-globals=1) # Instrument memcpy/memset/memmove calls by using instrumented __asan_mem*() # instead. With compilers that don't support this option, compiler-inserted @@ -57,9 +58,9 @@ endif # CONFIG_KASAN_GENERIC ifdef CONFIG_KASAN_SW_TAGS ifdef CONFIG_KASAN_INLINE - instrumentation_flags := $(call cc-param,hwasan-mapping-offset=$(KASAN_SHADOW_OFFSET)) + instrumentation_flags := $(call cc-param,hwasan-mapping-offset=$(KASAN_SHADOW_OFFSET)) else - instrumentation_flags := $(call cc-param,hwasan-instrument-with-calls=1) + instrumentation_flags := $(call cc-param,hwasan-instrument-with-calls=1) endif CFLAGS_KASAN := -fsanitize=kernel-hwaddress \ @@ -70,7 +71,7 @@ CFLAGS_KASAN := -fsanitize=kernel-hwaddress \ # Instrument memcpy/memset/memmove calls by using instrumented __hwasan_mem*(). ifeq ($(call clang-min-version, 150000)$(call gcc-min-version, 130000),y) -CFLAGS_KASAN += $(call cc-param,hwasan-kernel-mem-intrinsic-prefix=1) + CFLAGS_KASAN += $(call cc-param,hwasan-kernel-mem-intrinsic-prefix=1) endif endif # CONFIG_KASAN_SW_TAGS -- cgit v1.2.3-70-g09d2 From 4c727150a629a59933cbd12ab4230a30789e4c90 Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Wed, 17 Jul 2024 08:39:55 -0600 Subject: dt: dt-extract-compatibles: Extract compatibles from function parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Various DT and fwnode functions take a compatible string as a parameter. These are often used in cases which don't have a driver, so they've been missed. The additional checks add about 400 more undocumented compatible strings. Link: https://lore.kernel.org/all/20240903200753.2097911-1-robh@kernel.org/ Acked-by: Saravana Kannan Reviewed-by: Nícolas F. R. A. Prado Signed-off-by: Rob Herring (Arm) --- scripts/dtc/dt-extract-compatibles | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'scripts') diff --git a/scripts/dtc/dt-extract-compatibles b/scripts/dtc/dt-extract-compatibles index 5ffb2364409b..6570efabaa64 100755 --- a/scripts/dtc/dt-extract-compatibles +++ b/scripts/dtc/dt-extract-compatibles @@ -46,6 +46,15 @@ def parse_of_match_table(data): return match_table_list +def parse_of_functions(data, func_name): + """ Find all compatibles in the last argument of a given function """ + compat_list = [] + for m in re.finditer(rf'{func_name}\(([a-zA-Z0-9_>\(\)"\-]+,\s)*"([a-zA-Z0-9_,-]+)"\)', data): + compat_list.append(m[2]) + + return compat_list + + def parse_compatibles(file, compat_ignore_list): with open(file, 'r', encoding='utf-8') as f: data = f.read().replace('\n', '') @@ -60,6 +69,10 @@ def parse_compatibles(file, compat_ignore_list): else: compat_list = parse_of_declare_macros(data) compat_list += parse_of_device_id(data) + compat_list += parse_of_functions(data, "_is_compatible") + compat_list += parse_of_functions(data, "of_find_compatible_node") + compat_list += parse_of_functions(data, "for_each_compatible_node") + compat_list += parse_of_functions(data, "of_get_compatible_child") return compat_list -- cgit v1.2.3-70-g09d2 From 9b8a79f4c1d844d52273a31bc6511fa8ab5e8669 Mon Sep 17 00:00:00 2001 From: Sebastian Muxel Date: Tue, 27 Aug 2024 15:32:24 +0200 Subject: scripts: sphinx-pre-install: remove unnecessary double check for $cur_version $cur_version is currently being tested twice with the first test resulting in an unhelpful "$sphinx returned an error", not continuing to the more helpful "$sphinx didn't return its version". This patch removes the first test to return the more useful message. Fixes: a8b380c379ef ("scripts: sphinx-pre-install: only ask to activate valid venvs") Signed-off-by: Sebastian Muxel Signed-off-by: Jonathan Corbet Link: https://lore.kernel.org/r/20240827133224.160776-1-sebastian@muxel.dev --- scripts/sphinx-pre-install | 2 -- 1 file changed, 2 deletions(-) (limited to 'scripts') diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install index c1121f098542..ad9945ccb0cf 100755 --- a/scripts/sphinx-pre-install +++ b/scripts/sphinx-pre-install @@ -300,8 +300,6 @@ sub check_sphinx() } $cur_version = get_sphinx_version($sphinx); - die ("$sphinx returned an error") if (!$cur_version); - die "$sphinx didn't return its version" if (!$cur_version); if ($cur_version lt $min_version) { -- cgit v1.2.3-70-g09d2 From 6e74c6b5a42e6a7313fcd29e814f211b392a00f5 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Mon, 2 Sep 2024 18:55:28 +0200 Subject: kbuild: rust: add `CONFIG_RUSTC_VERSION` Now that we support several Rust versions, introduce `CONFIG_RUSTC_VERSION` so that it can be used in Kconfig to enable and disable configuration options based on the `rustc` version. The approach taken resembles `pahole`'s -- see commit 613fe1692377 ("kbuild: Add CONFIG_PAHOLE_VERSION"), i.e. a simple version parsing without trying to identify several kinds of compilers, since so far there is only one (`rustc`). However, unlike `pahole`'s, we also print a zero if executing failed for any reason, rather than checking if the command is found and executable (which still leaves things like a file that exists and is executable, but e.g. is built for another platform [1]). An equivalent approach to the one here was also submitted for `pahole` [2]. Link: https://lore.kernel.org/rust-for-linux/CANiq72=4vX_tJMJLE6e+bg7ZECHkS-AQpm8GBzuK75G1EB7+Nw@mail.gmail.com/ [1] Link: https://lore.kernel.org/linux-kbuild/20240728125527.690726-1-ojeda@kernel.org/ [2] Reviewed-by: Nicolas Schier Tested-by: Alice Ryhl Acked-by: Masahiro Yamada Link: https://lore.kernel.org/r/20240902165535.1101978-2-ojeda@kernel.org Signed-off-by: Miguel Ojeda --- init/Kconfig | 7 +++++++ scripts/rustc-version.sh | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100755 scripts/rustc-version.sh (limited to 'scripts') diff --git a/init/Kconfig b/init/Kconfig index 839c83034006..38c1cfcce821 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -60,6 +60,13 @@ config LLD_VERSION default $(ld-version) if LD_IS_LLD default 0 +config RUSTC_VERSION + int + default $(shell,$(srctree)/scripts/rustc-version.sh $(RUSTC)) + help + It does not depend on `RUST` since that one may need to use the version + in a `depends on`. + config RUST_IS_AVAILABLE def_bool $(success,$(srctree)/scripts/rust_is_available.sh) help diff --git a/scripts/rustc-version.sh b/scripts/rustc-version.sh new file mode 100755 index 000000000000..4e22593e2eab --- /dev/null +++ b/scripts/rustc-version.sh @@ -0,0 +1,26 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Usage: $ ./rustc-version.sh rustc +# +# Print the Rust compiler version in a 6 or 7-digit form. + +# 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)) +} + +if output=$("$@" --version 2>/dev/null); then + set -- $output + get_canonical_version $2 +else + echo 0 + exit 1 +fi -- cgit v1.2.3-70-g09d2 From 4929f5b95f6b20ae10f2c409fb2ca58253e73706 Mon Sep 17 00:00:00 2001 From: Jose Fernandez Date: Sat, 24 Aug 2024 16:07:56 -0600 Subject: kbuild: add debug package to pacman PKGBUILD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new debug package to the PKGBUILD for the pacman-pkg target. The debug package includes the non-stripped vmlinux file with debug symbols for kernel debugging and profiling. The file is installed at /usr/src/debug/${pkgbase}, with a symbolic link at /usr/lib/modules/$(uname -r)/build/vmlinux. The debug package is built by default. Signed-off-by: Jose Fernandez Reviewed-by: Peter Jung Acked-by: Thomas Weißschuh Signed-off-by: Masahiro Yamada --- scripts/package/PKGBUILD | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/package/PKGBUILD b/scripts/package/PKGBUILD index 839cd5e634d2..f83493838cf9 100644 --- a/scripts/package/PKGBUILD +++ b/scripts/package/PKGBUILD @@ -5,7 +5,7 @@ pkgbase=${PACMAN_PKGBASE:-linux-upstream} pkgname=("${pkgbase}") -_extrapackages=${PACMAN_EXTRAPACKAGES-headers api-headers} +_extrapackages=${PACMAN_EXTRAPACKAGES-headers api-headers debug} for pkg in $_extrapackages; do pkgname+=("${pkgbase}-${pkg}") done @@ -111,6 +111,19 @@ _package-api-headers() { ${MAKE} headers_install INSTALL_HDR_PATH="${pkgdir}/usr" } +_package-debug(){ + pkgdesc="Non-stripped vmlinux file for the ${pkgdesc} kernel" + + local debugdir="${pkgdir}/usr/src/debug/${pkgbase}" + local builddir="${pkgdir}/usr/${MODLIB}/build" + + _prologue + + install -Dt "${debugdir}" -m644 vmlinux + mkdir -p "${builddir}" + ln -sr "${debugdir}/vmlinux" "${builddir}/vmlinux" +} + for _p in "${pkgname[@]}"; do eval "package_$_p() { $(declare -f "_package${_p#$pkgbase}") -- cgit v1.2.3-70-g09d2 From dde60e7d103bf6cf820b2c4c4bb5658bad1759a9 Mon Sep 17 00:00:00 2001 From: Tony Battersby Date: Thu, 29 Aug 2024 09:51:25 -0400 Subject: kbuild: remove recent dependency on "truncate" program Remove the recently-added dependency on the truncate program for building the kernel. truncate is not available when building the kernel under Yocto. It could be added, but it would be better just to avoid the unnecessary dependency. Fixes: 1472464c6248 ("kbuild: avoid scripts/kallsyms parsing /dev/null") Signed-off-by: Tony Battersby Reviewed-by: Nathan Chancellor Signed-off-by: Masahiro Yamada --- 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 070a319140e8..c27b4e969f20 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -215,7 +215,7 @@ kallsymso= strip_debug= if is_enabled CONFIG_KALLSYMS; then - truncate -s0 .tmp_vmlinux.kallsyms0.syms + true > .tmp_vmlinux.kallsyms0.syms kallsyms .tmp_vmlinux.kallsyms0.syms .tmp_vmlinux0.kallsyms fi -- cgit v1.2.3-70-g09d2 From fdf94e4403ece60b29ef9e2da95e2fcefe50817f Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Sun, 1 Sep 2024 19:55:21 +0200 Subject: kbuild: compile constant module information only once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Various information about modules is compiled into the info sections. For that a dedicated .mod.c file is generated by modpost for each module and then linked into the module. However most of the information in the .mod.c is the same for all modules, internal and external. Split the shared information into a dedicated source file that is compiled once and then linked into all modules. This avoids frequent rebuilds for all .mod.c files when using CONFIG_LOCALVERSION_AUTO because the local version ends up in .mod.c through UTS_RELEASE and VERMAGIC_STRING. The modules are still relinked in this case. The code is also easier to maintain as it's now in a proper source file instead of an inline string literal. Signed-off-by: Thomas Weißschuh Signed-off-by: Masahiro Yamada --- scripts/Makefile.modfinal | 7 +++++-- scripts/mod/modpost.c | 23 ----------------------- scripts/module-common.c | 25 +++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 25 deletions(-) create mode 100644 scripts/module-common.c (limited to 'scripts') diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 306a6bb86e4d..6b1b72257b29 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -30,6 +30,9 @@ quiet_cmd_cc_o_c = CC [M] $@ %.mod.o: %.mod.c FORCE $(call if_changed_dep,cc_o_c) +$(extmod_prefix).module-common.o: $(srctree)/scripts/module-common.c FORCE + $(call if_changed_dep,cc_o_c) + quiet_cmd_ld_ko_o = LD [M] $@ cmd_ld_ko_o += \ $(LD) -r $(KBUILD_LDFLAGS) \ @@ -54,13 +57,13 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:) # Re-generate module BTFs if either module's .ko or vmlinux changed -%.ko: %.o %.mod.o scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE +%.ko: %.o %.mod.o $(extmod_prefix).module-common.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)) endif -targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) +targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) $(extmod_prefix).module-common.o # Add FORCE to the prerequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c8cd5d822bb6..107393a8c48a 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1755,26 +1755,9 @@ static void check_modname_len(struct module *mod) static void add_header(struct buffer *b, struct module *mod) { buf_printf(b, "#include \n"); - /* - * Include build-salt.h after module.h in order to - * inherit the definitions. - */ - 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"); - buf_printf(b, "#ifdef CONFIG_UNWINDER_ORC\n"); - buf_printf(b, "#include \n"); - buf_printf(b, "ORC_HEADER;\n"); - buf_printf(b, "#endif\n"); - buf_printf(b, "\n"); - buf_printf(b, "BUILD_SALT;\n"); - buf_printf(b, "BUILD_LTO_INFO;\n"); - buf_printf(b, "\n"); - buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n"); buf_printf(b, "\n"); buf_printf(b, "__visible struct module __this_module\n"); @@ -1792,12 +1775,6 @@ static void add_header(struct buffer *b, struct module *mod) if (!external_module) buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n"); - buf_printf(b, - "\n" - "#ifdef CONFIG_MITIGATION_RETPOLINE\n" - "MODULE_INFO(retpoline, \"Y\");\n" - "#endif\n"); - if (strstarts(mod->name, "drivers/staging")) buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); diff --git a/scripts/module-common.c b/scripts/module-common.c new file mode 100644 index 000000000000..12fbc6d3aae8 --- /dev/null +++ b/scripts/module-common.c @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +/* + * Include build-salt.h after module.h in order to + * inherit the definitions. + */ +#define INCLUDE_VERMAGIC +#include +#include +#include + +#ifdef CONFIG_UNWINDER_ORC +#include +ORC_HEADER; +#endif + +BUILD_SALT; +BUILD_LTO_INFO; + +MODULE_INFO(vermagic, VERMAGIC_STRING); + +#ifdef CONFIG_MITIGATION_RETPOLINE +MODULE_INFO(retpoline, "Y"); +#endif -- cgit v1.2.3-70-g09d2 From fc41a0a7498636ac0af7c37be80ca8571c2f4173 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Sep 2024 08:47:37 +0900 Subject: kbuild: add intermediate targets for Flex/Bison in scripts/Makefile.host Flex and Bison are used only for host programs. Move their intermediate target processing from scripts/Makefile.build to scripts/Makefile.host. Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 35 ++++++++++++++++------------------- scripts/Makefile.host | 5 +++++ 2 files changed, 21 insertions(+), 19 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index a5ac8ed1936f..4b6942653093 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -41,20 +41,6 @@ include $(srctree)/scripts/Makefile.compiler include $(kbuild-file) include $(srctree)/scripts/Makefile.lib -# Do not include hostprogs rules unless needed. -# $(sort ...) is used here to remove duplicated words and excessive spaces. -hostprogs := $(sort $(hostprogs)) -ifneq ($(hostprogs),) -include $(srctree)/scripts/Makefile.host -endif - -# Do not include userprogs rules unless needed. -# $(sort ...) is used here to remove duplicated words and excessive spaces. -userprogs := $(sort $(userprogs)) -ifneq ($(userprogs),) -include $(srctree)/scripts/Makefile.userprogs -endif - ifndef obj $(warning kbuild: Makefile.build is included improperly) endif @@ -452,13 +438,24 @@ intermediate_targets = $(foreach sfx, $(2), \ # %.asn1.o <- %.asn1.[ch] <- %.asn1 # %.dtb.o <- %.dtb.S <- %.dtb <- %.dts # %.dtbo.o <- %.dtbo.S <- %.dtbo <- %.dtso -# %.lex.o <- %.lex.c <- %.l -# %.tab.o <- %.tab.[ch] <- %.y targets += $(call intermediate_targets, .asn1.o, .asn1.c .asn1.h) \ $(call intermediate_targets, .dtb.o, .dtb.S .dtb) \ - $(call intermediate_targets, .dtbo.o, .dtbo.S .dtbo) \ - $(call intermediate_targets, .lex.o, .lex.c) \ - $(call intermediate_targets, .tab.o, .tab.c .tab.h) + $(call intermediate_targets, .dtbo.o, .dtbo.S .dtbo) + +# Include additional build rules when necessary +# --------------------------------------------------------------------------- + +# $(sort ...) is used here to remove duplicated words and excessive spaces. +hostprogs := $(sort $(hostprogs)) +ifneq ($(hostprogs),) +include $(srctree)/scripts/Makefile.host +endif + +# $(sort ...) is used here to remove duplicated words and excessive spaces. +userprogs := $(sort $(userprogs)) +ifneq ($(userprogs),) +include $(srctree)/scripts/Makefile.userprogs +endif # Build # --------------------------------------------------------------------------- diff --git a/scripts/Makefile.host b/scripts/Makefile.host index e85be7721a48..e01c13a588dd 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -160,3 +160,8 @@ $(host-rust): $(obj)/%: $(src)/%.rs FORCE targets += $(host-csingle) $(host-cmulti) $(host-cobjs) \ $(host-cxxmulti) $(host-cxxobjs) $(host-rust) + +# %.lex.o <- %.lex.c <- %.l +# %.tab.o <- %.tab.[ch] <- %.y +targets += $(call intermediate_targets, .lex.o, .lex.c) \ + $(call intermediate_targets, .tab.o, .tab.c .tab.h) -- cgit v1.2.3-70-g09d2 From e7e2941300d258d551dda6ca9a370e29e085fa73 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Sep 2024 08:47:38 +0900 Subject: kbuild: split device tree build rules into scripts/Makefile.dtbs scripts/Makefile.lib is included not only from scripts/Makefile.build but also from scripts/Makefile.{modfinal,package,vmlinux,vmlinux_o}, where DT build rules are not required. Split the DT build rules out to scripts/Makefile.dtbs, and include it only when necessary. While I was here, I added $(DT_TMP_SCHEMA) as a prerequisite of $(multi-dtb-y). Signed-off-by: Masahiro Yamada Reviewed-by: Rob Herring (Arm) --- drivers/of/fdt.c | 2 +- drivers/of/unittest.c | 4 +- scripts/Makefile.build | 25 +++------ scripts/Makefile.dtbs | 142 +++++++++++++++++++++++++++++++++++++++++++++++++ scripts/Makefile.lib | 115 --------------------------------------- 5 files changed, 153 insertions(+), 135 deletions(-) create mode 100644 scripts/Makefile.dtbs (limited to 'scripts') diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 68103ad230ee..4d528c10df3a 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -34,7 +34,7 @@ /* * __dtb_empty_root_begin[] and __dtb_empty_root_end[] magically created by - * cmd_dt_S_dtb in scripts/Makefile.lib + * cmd_wrap_S_dtb in scripts/Makefile.dtbs */ extern uint8_t __dtb_empty_root_begin[]; extern uint8_t __dtb_empty_root_end[]; diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index c830f346df45..fd8cb931b1cc 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -1861,7 +1861,7 @@ static int __init unittest_data_add(void) struct device_node *unittest_data_node = NULL, *np; /* * __dtbo_testcases_begin[] and __dtbo_testcases_end[] are magically - * created by cmd_dt_S_dtbo in scripts/Makefile.lib + * created by cmd_wrap_S_dtbo in scripts/Makefile.dtbs */ extern uint8_t __dtbo_testcases_begin[]; extern uint8_t __dtbo_testcases_end[]; @@ -3525,7 +3525,7 @@ out_skip_tests: /* * __dtbo_##overlay_name##_begin[] and __dtbo_##overlay_name##_end[] are - * created by cmd_dt_S_dtbo in scripts/Makefile.lib + * created by cmd_wrap_S_dtbo in scripts/Makefile.dtbs */ #define OVERLAY_INFO_EXTERN(overlay_name) \ diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 4b6942653093..8403eba15457 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -57,7 +57,6 @@ endif # subdir-builtin and subdir-modorder may contain duplications. Use $(sort ...) subdir-builtin := $(sort $(filter %/built-in.a, $(real-obj-y))) subdir-modorder := $(sort $(filter %/modules.order, $(obj-m))) -subdir-dtbslist := $(sort $(filter %/dtbs-list, $(dtb-y))) targets-for-builtin := $(extra-y) @@ -349,7 +348,7 @@ $(obj)/%.o: $(obj)/%.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) +targets += $(lib-y) $(always-y) # Linker scripts preprocessor (.lds.S -> .lds) # --------------------------------------------------------------------------- @@ -375,7 +374,6 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler # To build objects in subdirs, we need to descend into the directories $(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ; $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; -$(subdir-dtbslist): $(obj)/%/dtbs-list: $(obj)/% ; # # Rule to compile a set of .o files into one .a file (without symbol table) @@ -391,12 +389,8 @@ quiet_cmd_ar_builtin = AR $@ $(obj)/built-in.a: $(real-obj-y) FORCE $(call if_changed,ar_builtin) -# -# Rule to create modules.order and dtbs-list -# -# This is a list of build artifacts (module or dtb) from the current Makefile -# and its sub-directories. The timestamp should be updated when any of the -# member files. +# This is a list of build artifacts from the current Makefile and its +# sub-directories. The timestamp should be updated when any of the member files. cmd_gen_order = { $(foreach m, $(real-prereqs), \ $(if $(filter %/$(notdir $@), $m), cat $m, echo $m);) :; } \ @@ -405,9 +399,6 @@ cmd_gen_order = { $(foreach m, $(real-prereqs), \ $(obj)/modules.order: $(obj-m) FORCE $(call if_changed,gen_order) -$(obj)/dtbs-list: $(dtb-y) FORCE - $(call if_changed,gen_order) - # # Rule to compile a set of .o files into one .a file (with symbol table) # @@ -436,11 +427,7 @@ intermediate_targets = $(foreach sfx, $(2), \ $(patsubst %$(strip $(1)),%$(sfx), \ $(filter %$(strip $(1)), $(targets)))) # %.asn1.o <- %.asn1.[ch] <- %.asn1 -# %.dtb.o <- %.dtb.S <- %.dtb <- %.dts -# %.dtbo.o <- %.dtbo.S <- %.dtbo <- %.dtso -targets += $(call intermediate_targets, .asn1.o, .asn1.c .asn1.h) \ - $(call intermediate_targets, .dtb.o, .dtb.S .dtb) \ - $(call intermediate_targets, .dtbo.o, .dtbo.S .dtbo) +targets += $(call intermediate_targets, .asn1.o, .asn1.c .asn1.h) # Include additional build rules when necessary # --------------------------------------------------------------------------- @@ -457,6 +444,10 @@ ifneq ($(userprogs),) include $(srctree)/scripts/Makefile.userprogs endif +ifneq ($(need-dtbslist)$(dtb-y)$(dtb-)$(filter %.dtb %.dtb.o %.dtbo.o,$(targets)),) +include $(srctree)/scripts/Makefile.dtbs +endif + # Build # --------------------------------------------------------------------------- diff --git a/scripts/Makefile.dtbs b/scripts/Makefile.dtbs new file mode 100644 index 000000000000..46009d5f1486 --- /dev/null +++ b/scripts/Makefile.dtbs @@ -0,0 +1,142 @@ +# SPDX-License-Identifier: GPL-2.0-only + +# If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built +dtb-$(CONFIG_OF_ALL_DTBS) += $(dtb-) + +# Composite DTB (i.e. DTB constructed by overlay) +multi-dtb-y := $(call multi-search, $(dtb-y), .dtb, -dtbs) +# Primitive DTB compiled from *.dts +real-dtb-y := $(call real-search, $(dtb-y), .dtb, -dtbs) +# Base DTB that overlay is applied onto +base-dtb-y := $(filter %.dtb, $(call real-search, $(multi-dtb-y), .dtb, -dtbs)) + +dtb-y := $(addprefix $(obj)/, $(dtb-y)) +multi-dtb-y := $(addprefix $(obj)/, $(multi-dtb-y)) +real-dtb-y := $(addprefix $(obj)/, $(real-dtb-y)) + +always-y += $(dtb-y) +targets += $(real-dtb-y) + +# dtbs-list +# --------------------------------------------------------------------------- + +ifdef need-dtbslist +subdir-dtbslist := $(addsuffix /dtbs-list, $(subdir-ym)) +dtb-y += $(subdir-dtbslist) +always-y += $(obj)/dtbs-list +endif + +$(subdir-dtbslist): $(obj)/%/dtbs-list: $(obj)/% ; + +$(obj)/dtbs-list: $(dtb-y) FORCE + $(call if_changed,gen_order) + +# Assembly file to wrap dtb(o) +# --------------------------------------------------------------------------- + +# Generate an assembly file to wrap the output of the device tree compiler +quiet_cmd_wrap_S_dtb = WRAP $@ + cmd_wrap_S_dtb = { \ + symbase=__$(patsubst .%,%,$(suffix $<))_$(subst -,_,$(notdir $*)); \ + echo '\#include '; \ + echo '.section .dtb.init.rodata,"a"'; \ + echo '.balign STRUCT_ALIGNMENT'; \ + echo ".global $${symbase}_begin"; \ + echo "$${symbase}_begin:"; \ + echo '.incbin "$<" '; \ + echo ".global $${symbase}_end"; \ + echo "$${symbase}_end:"; \ + echo '.balign STRUCT_ALIGNMENT'; \ + } > $@ + +$(obj)/%.dtb.S: $(obj)/%.dtb FORCE + $(call if_changed,wrap_S_dtb) + +$(obj)/%.dtbo.S: $(obj)/%.dtbo FORCE + $(call if_changed,wrap_S_dtb) + +# Schema check +# --------------------------------------------------------------------------- + +ifneq ($(CHECK_DTBS),) +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 +dtb-check-enabled = $(if $(filter %.dtb, $@),y) +endif + +quiet_dtb_check_tag = $(if $(dtb-check-enabled),[C], ) +cmd_dtb_check = $(if $(dtb-check-enabled),; $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ || true) + +# Overlay +# --------------------------------------------------------------------------- + +# NOTE: +# Do not replace $(filter %.dtb %.dtbo, $^) with $(real-prereqs). When a single +# DTB is turned into a multi-blob DTB, $^ will contain header file dependencies +# recorded in the .*.cmd file. +quiet_cmd_fdtoverlay = OVL $(quiet_dtb_check_tag) $@ + cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(filter %.dtb %.dtbo, $^) $(cmd_dtb_check) + +$(multi-dtb-y): $(DT_TMP_SCHEMA) FORCE + $(call if_changed,fdtoverlay) +$(call multi_depend, $(multi-dtb-y), .dtb, -dtbs) + +# DTC +# --------------------------------------------------------------------------- + +DTC ?= $(objtree)/scripts/dtc/dtc +DTC_FLAGS += -Wno-unique_unit_address + +# Disable noisy checks by default +ifeq ($(findstring 1,$(KBUILD_EXTRA_WARN)),) +DTC_FLAGS += -Wno-unit_address_vs_reg \ + -Wno-avoid_unnecessary_addr_size \ + -Wno-alias_paths \ + -Wno-graph_child_address \ + -Wno-simple_bus_reg +else +DTC_FLAGS += -Wunique_unit_address_if_enabled +endif + +ifneq ($(findstring 2,$(KBUILD_EXTRA_WARN)),) +DTC_FLAGS += -Wnode_name_chars_strict \ + -Wproperty_name_chars_strict \ + -Wunique_unit_address +endif + +DTC_FLAGS += $(DTC_FLAGS_$(target-stem)) + +# Set -@ if the target is a base DTB that overlay is applied onto +DTC_FLAGS += $(if $(filter $(patsubst $(obj)/%,%,$@), $(base-dtb-y)), -@) + +DTC_INCLUDE := $(srctree)/scripts/dtc/include-prefixes + +dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc -I $(DTC_INCLUDE) -undef -D__DTS__ + +dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) + +quiet_cmd_dtc = DTC $(quiet_dtb_check_tag) $@ + cmd_dtc = \ + $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ + $(DTC) -o $@ -b 0 $(addprefix -i,$(dir $<) $(DTC_INCLUDE)) \ + $(DTC_FLAGS) -d $(depfile).dtc.tmp $(dtc-tmp) ; \ + cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) \ + $(cmd_dtb_check) + +$(obj)/%.dtb: $(obj)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE + $(call if_changed_dep,dtc) + +$(obj)/%.dtbo: $(src)/%.dtso $(DTC) FORCE + $(call if_changed_dep,dtc) + +# targets +# --------------------------------------------------------------------------- + +targets += $(always-y) + +# %.dtb.o <- %.dtb.S <- %.dtb <- %.dts +# %.dtbo.o <- %.dtbo.S <- %.dtbo <- %.dtso +targets += $(call intermediate_targets, .dtb.o, .dtb.S .dtb) \ + $(call intermediate_targets, .dtbo.o, .dtbo.S .dtbo) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 207325eaf1d1..4fea9e9bec3c 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -45,11 +45,6 @@ else obj-y := $(filter-out %/, $(obj-y)) endif -ifdef need-dtbslist -dtb-y += $(addsuffix /dtbs-list, $(subdir-ym)) -always-y += dtbs-list -endif - # Expand $(foo-objs) $(foo-y) etc. by replacing their individuals suffix-search = $(strip $(foreach s, $3, $($(1:%$(strip $2)=%$s)))) # List composite targets that are constructed by combining other targets @@ -80,19 +75,6 @@ always-y += $(hostprogs-always-y) $(hostprogs-always-m) userprogs += $(userprogs-always-y) $(userprogs-always-m) always-y += $(userprogs-always-y) $(userprogs-always-m) -# DTB -# If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built -dtb-$(CONFIG_OF_ALL_DTBS) += $(dtb-) - -# Composite DTB (i.e. DTB constructed by overlay) -multi-dtb-y := $(call multi-search, $(dtb-y), .dtb, -dtbs) -# Primitive DTB compiled from *.dts -real-dtb-y := $(call real-search, $(dtb-y), .dtb, -dtbs) -# Base DTB that overlay is applied onto -base-dtb-y := $(filter %.dtb, $(call real-search, $(multi-dtb-y), .dtb, -dtbs)) - -always-y += $(dtb-y) - # Add subdir path ifneq ($(obj),.) @@ -104,9 +86,6 @@ lib-y := $(addprefix $(obj)/,$(lib-y)) real-obj-y := $(addprefix $(obj)/,$(real-obj-y)) real-obj-m := $(addprefix $(obj)/,$(real-obj-m)) multi-obj-m := $(addprefix $(obj)/, $(multi-obj-m)) -dtb-y := $(addprefix $(obj)/, $(dtb-y)) -multi-dtb-y := $(addprefix $(obj)/, $(multi-dtb-y)) -real-dtb-y := $(addprefix $(obj)/, $(real-dtb-y)) subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) endif @@ -255,12 +234,6 @@ cpp_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ ld_flags = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F)) -DTC_INCLUDE := $(srctree)/scripts/dtc/include-prefixes - -dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \ - $(addprefix -I,$(DTC_INCLUDE)) \ - -undef -D__DTS__ - ifdef CONFIG_OBJTOOL objtool := $(objtree)/tools/objtool/objtool @@ -350,94 +323,6 @@ cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ quiet_cmd_gzip = GZIP $@ cmd_gzip = cat $(real-prereqs) | $(KGZIP) -n -f -9 > $@ -# DTC -# --------------------------------------------------------------------------- -DTC ?= $(objtree)/scripts/dtc/dtc -DTC_FLAGS += \ - -Wno-unique_unit_address - -# Disable noisy checks by default -ifeq ($(findstring 1,$(KBUILD_EXTRA_WARN)),) -DTC_FLAGS += -Wno-unit_address_vs_reg \ - -Wno-avoid_unnecessary_addr_size \ - -Wno-alias_paths \ - -Wno-graph_child_address \ - -Wno-simple_bus_reg -else -DTC_FLAGS += \ - -Wunique_unit_address_if_enabled -endif - -ifneq ($(findstring 2,$(KBUILD_EXTRA_WARN)),) -DTC_FLAGS += -Wnode_name_chars_strict \ - -Wproperty_name_chars_strict \ - -Wunique_unit_address -endif - -DTC_FLAGS += $(DTC_FLAGS_$(target-stem)) - -# Set -@ if the target is a base DTB that overlay is applied onto -DTC_FLAGS += $(if $(filter $(patsubst $(obj)/%,%,$@), $(base-dtb-y)), -@) - -# Generate an assembly file to wrap the output of the device tree compiler -quiet_cmd_wrap_S_dtb = WRAP $@ - cmd_wrap_S_dtb = { \ - symbase=__$(patsubst .%,%,$(suffix $<))_$(subst -,_,$(notdir $*)); \ - echo '\#include '; \ - echo '.section .dtb.init.rodata,"a"'; \ - echo '.balign STRUCT_ALIGNMENT'; \ - echo ".global $${symbase}_begin"; \ - echo "$${symbase}_begin:"; \ - echo '.incbin "$<" '; \ - echo ".global $${symbase}_end"; \ - echo "$${symbase}_end:"; \ - echo '.balign STRUCT_ALIGNMENT'; \ - } > $@ - -$(obj)/%.dtb.S: $(obj)/%.dtb FORCE - $(call if_changed,wrap_S_dtb) - -$(obj)/%.dtbo.S: $(obj)/%.dtbo FORCE - $(call if_changed,wrap_S_dtb) - -quiet_dtb_check_tag = $(if $(dtb-check-enabled),[C], ) -cmd_dtb_check = $(if $(dtb-check-enabled),; $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ || true) - -quiet_cmd_dtc = DTC $(quiet_dtb_check_tag) $@ -cmd_dtc = $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ - $(DTC) -o $@ -b 0 \ - $(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \ - -d $(depfile).dtc.tmp $(dtc-tmp) ; \ - cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) \ - $(cmd_dtb_check) - -# NOTE: -# Do not replace $(filter %.dtb %.dtbo, $^) with $(real-prereqs). When a single -# DTB is turned into a multi-blob DTB, $^ will contain header file dependencies -# recorded in the .*.cmd file. -quiet_cmd_fdtoverlay = OVL $(quiet_dtb_check_tag) $@ - cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(filter %.dtb %.dtbo, $^) $(cmd_dtb_check) - -$(multi-dtb-y): FORCE - $(call if_changed,fdtoverlay) -$(call multi_depend, $(multi-dtb-y), .dtb, -dtbs) - -ifneq ($(CHECK_DTBS),) -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 -dtb-check-enabled = $(if $(filter %.dtb, $@),y) -endif - -$(obj)/%.dtb: $(obj)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE - $(call if_changed_dep,dtc) - -$(obj)/%.dtbo: $(src)/%.dtso $(DTC) FORCE - $(call if_changed_dep,dtc) - -dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) - # Bzip2 # --------------------------------------------------------------------------- -- cgit v1.2.3-70-g09d2 From 16ff3f606c7e639d815ede92c258b63484242783 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Sep 2024 08:54:48 +0900 Subject: scripts: import more hash table macros Add more macros used for removing hash table entries. Signed-off-by: Masahiro Yamada --- scripts/include/hashtable.h | 50 ++++++++++++++++++++++++++++++++ scripts/include/list.h | 69 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) (limited to 'scripts') diff --git a/scripts/include/hashtable.h b/scripts/include/hashtable.h index a0a2c8f5f639..45abcb12bfce 100644 --- a/scripts/include/hashtable.h +++ b/scripts/include/hashtable.h @@ -15,6 +15,23 @@ #define hash_head(table, key) (&(table)[(key) % HASH_SIZE(table)]) +static inline void __hash_init(struct hlist_head *ht, unsigned int sz) +{ + unsigned int i; + + for (i = 0; i < sz; i++) + INIT_HLIST_HEAD(&ht[i]); +} + +/** + * hash_init - initialize a hash table + * @table: hashtable to be initialized + * + * This has to be a macro since HASH_SIZE() will not work on pointers since + * it calculates the size during preprocessing. + */ +#define hash_init(table) __hash_init(table, HASH_SIZE(table)) + /** * hash_add - add an object to a hashtable * @table: hashtable to add to @@ -24,6 +41,15 @@ #define hash_add(table, node, key) \ hlist_add_head(node, hash_head(table, key)) +/** + * hash_del - remove an object from a hashtable + * @node: &struct hlist_node of the object to remove + */ +static inline void hash_del(struct hlist_node *node) +{ + hlist_del_init(node); +} + /** * hash_for_each - iterate over a hashtable * @table: hashtable to iterate @@ -34,6 +60,18 @@ for (int _bkt = 0; _bkt < HASH_SIZE(table); _bkt++) \ hlist_for_each_entry(obj, &table[_bkt], member) +/** + * hash_for_each_safe - iterate over a hashtable safe against removal of + * hash entry + * @table: hashtable to iterate + * @obj: the type * to use as a loop cursor for each entry + * @tmp: a &struct hlist_node used for temporary storage + * @member: the name of the hlist_node within the struct + */ +#define hash_for_each_safe(table, obj, tmp, member) \ + for (int _bkt = 0; _bkt < HASH_SIZE(table); _bkt++) \ + hlist_for_each_entry_safe(obj, tmp, &table[_bkt], member) + /** * hash_for_each_possible - iterate over all possible objects hashing to the * same bucket @@ -45,4 +83,16 @@ #define hash_for_each_possible(table, obj, member, key) \ hlist_for_each_entry(obj, hash_head(table, key), member) +/** + * hash_for_each_possible_safe - iterate over all possible objects hashing to the + * same bucket safe against removals + * @table: hashtable to iterate + * @obj: the type * to use as a loop cursor for each entry + * @tmp: a &struct hlist_node used for temporary storage + * @member: the name of the hlist_node within the struct + * @key: the key of the objects to iterate over + */ +#define hash_for_each_possible_safe(table, obj, tmp, member, key) \ + hlist_for_each_entry_safe(obj, tmp, hash_head(table, key), member) + #endif /* HASHTABLE_H */ diff --git a/scripts/include/list.h b/scripts/include/list.h index 409201cd495b..fea1e2b79063 100644 --- a/scripts/include/list.h +++ b/scripts/include/list.h @@ -268,6 +268,63 @@ static inline int list_empty(const struct list_head *head) */ #define HLIST_HEAD_INIT { .first = NULL } +#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) +static inline void INIT_HLIST_NODE(struct hlist_node *h) +{ + h->next = NULL; + h->pprev = NULL; +} + +/** + * hlist_unhashed - Has node been removed from list and reinitialized? + * @h: Node to be checked + * + * Not that not all removal functions will leave a node in unhashed + * state. For example, hlist_nulls_del_init_rcu() does leave the + * node in unhashed state, but hlist_nulls_del() does not. + */ +static inline int hlist_unhashed(const struct hlist_node *h) +{ + return !h->pprev; +} + +static inline void __hlist_del(struct hlist_node *n) +{ + struct hlist_node *next = n->next; + struct hlist_node **pprev = n->pprev; + + *pprev = next; + if (next) + next->pprev = pprev; +} + +/** + * hlist_del - Delete the specified hlist_node from its list + * @n: Node to delete. + * + * Note that this function leaves the node in hashed state. Use + * hlist_del_init() or similar instead to unhash @n. + */ +static inline void hlist_del(struct hlist_node *n) +{ + __hlist_del(n); + n->next = LIST_POISON1; + n->pprev = LIST_POISON2; +} + +/** + * hlist_del_init - Delete the specified hlist_node from its list and initialize + * @n: Node to delete. + * + * Note that this function leaves the node in unhashed state. + */ +static inline void hlist_del_init(struct hlist_node *n) +{ + if (!hlist_unhashed(n)) { + __hlist_del(n); + INIT_HLIST_NODE(n); + } +} /** * hlist_add_head - add a new entry at the beginning of the hlist @@ -306,4 +363,16 @@ static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) pos; \ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) +/** + * hlist_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: a &struct hlist_node to use as temporary storage + * @head: the head for your list. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_safe(pos, n, head, member) \ + for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\ + pos && ({ n = pos->member.next; 1; }); \ + pos = hlist_entry_safe(n, typeof(*pos), member)) + #endif /* LIST_H */ -- cgit v1.2.3-70-g09d2 From 8a62d44588451095fd6645d6ed7ff8761edf62aa Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Fri, 6 Sep 2024 13:01:28 +0200 Subject: scripts: subarch.include: fix SUBARCH on macOS hosts When building the Linux kernel on an aarch64 macOS based host, if we don't specify a value for ARCH when invoking make, we default to arm and thus multi_v7_defconfig rather than the expected arm64 and arm64's defconfig. This is because subarch.include invokes `uname -m` which on MacOS hosts evaluates to `arm64` but on Linux hosts evaluates to `aarch64`, This allows us to build ARCH=arm64 natively on macOS (as in ARCH need not be specified on an aarch64-based system). Avoid matching arm64 by excluding it from the arm.* sed expression. Signed-off-by: Nick Desaulniers Suggested-by: Nicolas Schier Signed-off-by: Daniel Gomez Signed-off-by: Masahiro Yamada --- scripts/subarch.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/subarch.include b/scripts/subarch.include index 4bd327d0ae42..c4592d59d69b 100644 --- a/scripts/subarch.include +++ b/scripts/subarch.include @@ -6,7 +6,7 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \ -e s/sun4u/sparc64/ \ - -e s/arm.*/arm/ -e s/sa110/arm/ \ + -e /^arm64$$/!s/arm.*/arm/ -e s/sa110/arm/ \ -e s/s390x/s390/ \ -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \ -- cgit v1.2.3-70-g09d2 From 23d93aa4b3b90b6e3dc8e6b6bb36580c1068bc07 Mon Sep 17 00:00:00 2001 From: Kris Van Hees Date: Fri, 6 Sep 2024 10:45:02 -0400 Subject: kbuild: add mod(name,file)_flags to assembler flags for module objects In order to create the file at build time, modules.builtin.ranges, that contains the range of addresses for all built-in modules, there needs to be a way to identify what code is compiled into modules. To identify what code is compiled into modules during a kernel build, one can look for the presence of the -DKBUILD_MODFILE and -DKBUILD_MODNAME options in the compile command lines. A simple grep in .*.cmd files for those options is sufficient for this. Unfortunately, these options are only passed when compiling C source files. Various modules also include objects built from assembler source, and these options are not passed in that case. Adding $(modfile_flags) to modkern_aflags (similar to modkern_cflags), and adding $(modname_flags) to a_flags (similar to c_flags) makes it possible to identify which objects are compiled into modules for both C and assembler source files. While KBUILD_MODFILE is sufficient to generate the modules ranges data, KBUILD_MODNAME is passed as well for consistency with the C source code case. Signed-off-by: Kris Van Hees Reviewed-by: Steven Rostedt (Google) Tested-by: Sam James Reviewed-by: Sami Tolvanen Tested-by: Sami Tolvanen Signed-off-by: Masahiro Yamada --- scripts/Makefile.lib | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 4fea9e9bec3c..1bdd77f42289 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -217,7 +217,7 @@ modkern_rustflags = \ modkern_aflags = $(if $(part-of-module), \ $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \ - $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)) + $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL) $(modfile_flags)) c_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ -include $(srctree)/include/linux/compiler_types.h \ @@ -227,7 +227,7 @@ c_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ rust_flags = $(_rust_flags) $(modkern_rustflags) @$(objtree)/include/generated/rustc_cfg a_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ - $(_a_flags) $(modkern_aflags) + $(_a_flags) $(modkern_aflags) $(modname_flags) cpp_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ $(_cpp_flags) -- cgit v1.2.3-70-g09d2 From c980dc9c67a94ab716ffc06767cb435480bda09d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 14 Sep 2024 02:37:52 +0900 Subject: btf: remove redundant CONFIG_BPF test in scripts/link-vmlinux.sh CONFIG_DEBUG_INFO_BTF depends on CONFIG_BPF_SYSCALL, which in turn selects CONFIG_BPF. When CONFIG_DEBUG_INFO_BTF=y, CONFIG_BPF=y is always met. Signed-off-by: Masahiro Yamada Reviewed-by: Alan Maguire Acked-by: Andrii Nakryiko Reviewed-by: Nathan Chancellor Link: https://lore.kernel.org/r/20240913173759.1316390-1-masahiroy@kernel.org Signed-off-by: Alexei Starovoitov --- 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 22d0bc843986..8a06907fea32 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -283,7 +283,7 @@ strip_debug= vmlinux_link vmlinux # fill in BTF IDs -if is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then +if is_enabled CONFIG_DEBUG_INFO_BTF; then info BTFIDS vmlinux ${RESOLVE_BTFIDS} vmlinux fi -- cgit v1.2.3-70-g09d2 From 42450f7a9086cf38e97c3aeeaabd229af7abbbad Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 14 Sep 2024 02:37:53 +0900 Subject: btf: move pahole check in scripts/link-vmlinux.sh to lib/Kconfig.debug When DEBUG_INFO_DWARF5 is selected, pahole 1.21+ is required to enable DEBUG_INFO_BTF. When DEBUG_INFO_DWARF4 or DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is selected, DEBUG_INFO_BTF can be enabled without pahole installed, but a build error will occur in scripts/link-vmlinux.sh: LD .tmp_vmlinux1 BTF: .tmp_vmlinux1: pahole (pahole) is not available Failed to generate BTF for vmlinux Try to disable CONFIG_DEBUG_INFO_BTF We did not guard DEBUG_INFO_BTF by PAHOLE_VERSION when previously discussed [1]. However, commit 613fe1692377 ("kbuild: Add CONFIG_PAHOLE_VERSION") added CONFIG_PAHOLE_VERSION after all. Now several CONFIG options, as well as the combination of DEBUG_INFO_BTF and DEBUG_INFO_DWARF5, are guarded by PAHOLE_VERSION. The remaining compile-time check in scripts/link-vmlinux.sh now appears to be an awkward inconsistency. This commit adopts Nathan's original work. [1]: https://lore.kernel.org/lkml/20210111180609.713998-1-natechancellor@gmail.com/ Signed-off-by: Masahiro Yamada Reviewed-by: Alan Maguire Acked-by: Andrii Nakryiko Reviewed-by: Nathan Chancellor Link: https://lore.kernel.org/r/20240913173759.1316390-2-masahiroy@kernel.org Signed-off-by: Alexei Starovoitov --- lib/Kconfig.debug | 6 ++++-- scripts/link-vmlinux.sh | 12 ------------ 2 files changed, 4 insertions(+), 14 deletions(-) (limited to 'scripts') diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index a30c03a66172..f627147d6c25 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -379,13 +379,15 @@ config DEBUG_INFO_BTF depends on !DEBUG_INFO_SPLIT && !DEBUG_INFO_REDUCED depends on !GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST depends on BPF_SYSCALL + depends on PAHOLE_VERSION >= 116 depends on !DEBUG_INFO_DWARF5 || PAHOLE_VERSION >= 121 # pahole uses elfutils, which does not have support for Hexagon relocations depends on !HEXAGON help Generate deduplicated BTF type information from DWARF debug info. - Turning this on expects presence of pahole tool, which will convert - DWARF type info into equivalent deduplicated BTF type info. + Turning this on requires pahole v1.16 or later (v1.21 or later to + support DWARF 5), which will convert DWARF type info into equivalent + deduplicated BTF type info. config PAHOLE_HAS_SPLIT_BTF def_bool PAHOLE_VERSION >= 119 diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 8a06907fea32..069d34112e6a 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -107,20 +107,8 @@ vmlinux_link() # ${1} - vmlinux image gen_btf() { - local pahole_ver local btf_data=${1}.btf.o - if ! [ -x "$(command -v ${PAHOLE})" ]; then - echo >&2 "BTF: ${1}: pahole (${PAHOLE}) is not available" - return 1 - fi - - pahole_ver=$(${PAHOLE} --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/') - if [ "${pahole_ver}" -lt "116" ]; then - echo >&2 "BTF: ${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.16" - return 1 - fi - info BTF "${btf_data}" LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J ${PAHOLE_FLAGS} ${1} -- cgit v1.2.3-70-g09d2 From ca627e636551e74b528f150d744f67d9a63f0ae7 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Thu, 12 Sep 2024 21:00:44 +0200 Subject: rust: cfi: add support for CFI_CLANG with Rust Make it possible to use the Control Flow Integrity (CFI) sanitizer when Rust is enabled. Enabling CFI with Rust requires that CFI is configured to normalize integer types so that all integer types of the same size and signedness are compatible under CFI. Rust and C use the same LLVM backend for code generation, so Rust KCFI is compatible with the KCFI used in the kernel for C. In the case of FineIBT, CFI also depends on -Zpatchable-function-entry for rewriting the function prologue, so we set that flag for Rust as well. The flag for FineIBT requires rustc 1.80.0 or later, so include a Kconfig requirement for that. Enabling Rust will select CFI_ICALL_NORMALIZE_INTEGERS because the flag is required to use Rust with CFI. Using select rather than `depends on` avoids the case where Rust is not visible in menuconfig due to CFI_ICALL_NORMALIZE_INTEGERS not being enabled. One disadvantage of select is that RUST must `depends on` all of the things that CFI_ICALL_NORMALIZE_INTEGERS depends on to avoid invalid configurations. Alice has been using KCFI on her phone for several months, so it is reasonably well tested on arm64. Signed-off-by: Matthew Maurer Co-developed-by: Alice Ryhl Signed-off-by: Alice Ryhl Reviewed-by: Sami Tolvanen Tested-by: Gatlin Newhouse Acked-by: Kees Cook Acked-by: Peter Zijlstra (Intel) Link: https://lore.kernel.org/r/20240801-kcfi-v2-2-c93caed3d121@google.com [ Replaced `!FINEIBT` requirement with `!CALL_PADDING` to prevent a build error on older Rust compilers. Fixed typo. - Miguel ] Signed-off-by: Miguel Ojeda --- Makefile | 7 +++++++ arch/x86/Makefile | 4 ++++ init/Kconfig | 4 +++- rust/Makefile | 2 +- scripts/generate_rust_target.rs | 1 + 5 files changed, 16 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 35253bff5ca2..08ba14ef128e 100644 --- a/Makefile +++ b/Makefile @@ -957,6 +957,13 @@ CC_FLAGS_CFI := -fsanitize=kcfi ifdef CONFIG_CFI_ICALL_NORMALIZE_INTEGERS CC_FLAGS_CFI += -fsanitize-cfi-icall-experimental-normalize-integers endif +ifdef CONFIG_RUST + # Always pass -Zsanitizer-cfi-normalize-integers as CONFIG_RUST selects + # CONFIG_CFI_ICALL_NORMALIZE_INTEGERS. + RUSTC_FLAGS_CFI := -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers + KBUILD_RUSTFLAGS += $(RUSTC_FLAGS_CFI) + export RUSTC_FLAGS_CFI +endif KBUILD_CFLAGS += $(CC_FLAGS_CFI) export CC_FLAGS_CFI endif diff --git a/arch/x86/Makefile b/arch/x86/Makefile index a1883a30a5d8..cd75e78a06c1 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -242,6 +242,10 @@ ifdef CONFIG_CALL_PADDING PADDING_CFLAGS := -fpatchable-function-entry=$(CONFIG_FUNCTION_PADDING_BYTES),$(CONFIG_FUNCTION_PADDING_BYTES) KBUILD_CFLAGS += $(PADDING_CFLAGS) export PADDING_CFLAGS + +PADDING_RUSTFLAGS := -Zpatchable-function-entry=$(CONFIG_FUNCTION_PADDING_BYTES),$(CONFIG_FUNCTION_PADDING_BYTES) +KBUILD_RUSTFLAGS += $(PADDING_RUSTFLAGS) +export PADDING_RUSTFLAGS endif KBUILD_LDFLAGS += -m elf_$(UTS_MACHINE) diff --git a/init/Kconfig b/init/Kconfig index 9bcda3b0a20f..53f4589b7847 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1905,11 +1905,13 @@ config RUST bool "Rust support" depends on HAVE_RUST depends on RUST_IS_AVAILABLE - depends on !CFI_CLANG depends on !MODVERSIONS depends on !GCC_PLUGIN_RANDSTRUCT depends on !RANDSTRUCT depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE + depends on !CFI_CLANG || RUSTC_VERSION >= 107900 && $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers) + select CFI_ICALL_NORMALIZE_INTEGERS if CFI_CLANG + depends on !CALL_PADDING || RUSTC_VERSION >= 108000 help Enables Rust support in the kernel. diff --git a/rust/Makefile b/rust/Makefile index 4eae318f36ff..dd76dc27d666 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -306,7 +306,7 @@ $(obj)/bindings/bindings_helpers_generated.rs: $(src)/helpers/helpers.c FORCE quiet_cmd_exports = EXPORTS $@ cmd_exports = \ $(NM) -p --defined-only $< \ - | awk '/ (T|R|D) / {printf "EXPORT_SYMBOL_RUST_GPL(%s);\n",$$3}' > $@ + | awk '$$2~/(T|R|D)/ && $$3!~/__cfi/ {printf "EXPORT_SYMBOL_RUST_GPL(%s);\n",$$3}' > $@ $(obj)/exports_core_generated.h: $(obj)/core.o FORCE $(call if_changed,exports) diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs index fbf723996d20..087c1d13d33b 100644 --- a/scripts/generate_rust_target.rs +++ b/scripts/generate_rust_target.rs @@ -207,6 +207,7 @@ fn main() { } ts.push("features", features); ts.push("llvm-target", "x86_64-linux-gnu"); + ts.push("supported-sanitizers", ["kcfi"]); ts.push("target-pointer-width", "64"); } else if cfg.has("X86_32") { // This only works on UML, as i386 otherwise needs regparm support in rustc -- cgit v1.2.3-70-g09d2 From cc1d98f9fe30467a2224184336b3166ef4adbc25 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Wed, 14 Aug 2024 18:10:52 +0200 Subject: kasan: simplify and clarify Makefile When KASAN support was being added to the Linux kernel, GCC did not yet support all of the KASAN-related compiler options. Thus, the KASAN Makefile had to probe the compiler for supported options. Nowadays, the Linux kernel GCC version requirement is 5.1+, and thus we don't need the probing of the -fasan-shadow-offset parameter: it exists in all 5.1+ GCCs. Simplify the KASAN Makefile to drop CFLAGS_KASAN_MINIMAL. Also add a few more comments and unify the indentation. Signed-off-by: Andrey Konovalov Acked-by: Marco Elver Link: https://lore.kernel.org/r/20240814161052.10374-1-andrey.konovalov@linux.dev Signed-off-by: Miguel Ojeda --- scripts/Makefile.kasan | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan index 390658a2d5b7..aab4154af00a 100644 --- a/scripts/Makefile.kasan +++ b/scripts/Makefile.kasan @@ -22,30 +22,31 @@ endif ifdef CONFIG_KASAN_GENERIC ifdef CONFIG_KASAN_INLINE + # When the number of memory accesses in a function is less than this + # call threshold number, the compiler will use inline instrumentation. + # 10000 is chosen offhand as a sufficiently large number to make all + # kernel functions to be instrumented inline. call_threshold := 10000 else call_threshold := 0 endif -CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address - -# -fasan-shadow-offset fails without -fsanitize -CFLAGS_KASAN_SHADOW := $(call cc-option, -fsanitize=kernel-address \ - -fasan-shadow-offset=$(KASAN_SHADOW_OFFSET), \ - $(call cc-option, -fsanitize=kernel-address \ - -mllvm -asan-mapping-offset=$(KASAN_SHADOW_OFFSET))) - -ifeq ($(strip $(CFLAGS_KASAN_SHADOW)),) - CFLAGS_KASAN := $(CFLAGS_KASAN_MINIMAL) -else - # Now add all the compiler specific options that are valid standalone - CFLAGS_KASAN := $(CFLAGS_KASAN_SHADOW) \ - $(call cc-param,asan-globals=1) \ - $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ - $(call cc-param,asan-instrument-allocas=1) -endif - -CFLAGS_KASAN += $(call cc-param,asan-stack=$(stack_enable)) +# First, enable -fsanitize=kernel-address together with providing the shadow +# mapping offset, as for GCC, -fasan-shadow-offset fails without -fsanitize +# (GCC accepts the shadow mapping offset via -fasan-shadow-offset instead of +# a --param like the other KASAN parameters). +# Instead of ifdef-checking the compiler, rely on cc-option. +CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \ + -fasan-shadow-offset=$(KASAN_SHADOW_OFFSET), \ + $(call cc-option, -fsanitize=kernel-address \ + -mllvm -asan-mapping-offset=$(KASAN_SHADOW_OFFSET))) + +# Now, add other parameters enabled similarly in both GCC and Clang. +# As some of them are not supported by older compilers, use cc-param. +CFLAGS_KASAN += $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ + $(call cc-param,asan-stack=$(stack_enable)) \ + $(call cc-param,asan-instrument-allocas=1) \ + $(call cc-param,asan-globals=1) # Instrument memcpy/memset/memmove calls by using instrumented __asan_mem*() # instead. With compilers that don't support this option, compiler-inserted @@ -57,9 +58,9 @@ endif # CONFIG_KASAN_GENERIC ifdef CONFIG_KASAN_SW_TAGS ifdef CONFIG_KASAN_INLINE - instrumentation_flags := $(call cc-param,hwasan-mapping-offset=$(KASAN_SHADOW_OFFSET)) + instrumentation_flags := $(call cc-param,hwasan-mapping-offset=$(KASAN_SHADOW_OFFSET)) else - instrumentation_flags := $(call cc-param,hwasan-instrument-with-calls=1) + instrumentation_flags := $(call cc-param,hwasan-instrument-with-calls=1) endif CFLAGS_KASAN := -fsanitize=kernel-hwaddress \ @@ -70,7 +71,7 @@ CFLAGS_KASAN := -fsanitize=kernel-hwaddress \ # Instrument memcpy/memset/memmove calls by using instrumented __hwasan_mem*(). ifeq ($(call clang-min-version, 150000)$(call gcc-min-version, 130000),y) -CFLAGS_KASAN += $(call cc-param,hwasan-kernel-mem-intrinsic-prefix=1) + CFLAGS_KASAN += $(call cc-param,hwasan-kernel-mem-intrinsic-prefix=1) endif endif # CONFIG_KASAN_SW_TAGS -- cgit v1.2.3-70-g09d2 From c42297438aee70e2d391225de3d35ffeb2bdbaf9 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Tue, 20 Aug 2024 19:48:56 +0000 Subject: kbuild: rust: Define probing macros for rustc Creates flag probe macro variants for `rustc`. These are helpful because: 1. The kernel now supports a minimum `rustc` version rather than a single version. 2. `rustc` links against a range of LLVM revisions, occasionally even ones without an official release number. Since the availability of some Rust flags depends on which LLVM it has been linked against, probing is necessary. Signed-off-by: Matthew Maurer Link: https://github.com/Rust-for-Linux/linux/pull/1087 Link: https://lore.kernel.org/r/20240820194910.187826-2-mmaurer@google.com Signed-off-by: Miguel Ojeda --- scripts/Kconfig.include | 8 ++++++++ scripts/Makefile.compiler | 15 +++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'scripts') diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include index 3500a3d62f0d..785a491e5996 100644 --- a/scripts/Kconfig.include +++ b/scripts/Kconfig.include @@ -64,3 +64,11 @@ ld-version := $(shell,set -- $(ld-info) && echo $2) cc-option-bit = $(if-success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null,$(1)) m32-flag := $(cc-option-bit,-m32) m64-flag := $(cc-option-bit,-m64) + +# $(rustc-option,) +# Return y if the Rust compiler supports , n otherwise +# Calls to this should be guarded so that they are not evaluated if +# CONFIG_RUST_IS_AVAILABLE is not set. +# If you are testing for unstable features, consider testing RUSTC_VERSION +# instead, as features may have different completeness while available. +rustc-option = $(success,trap "rm -rf .tmp_$$" EXIT; mkdir .tmp_$$; $(RUSTC) $(1) --crate-type=rlib /dev/null --out-dir=.tmp_$$ -o .tmp_$$/tmp.rlib) diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler index 92be0c9a13ee..057305eae85c 100644 --- a/scripts/Makefile.compiler +++ b/scripts/Makefile.compiler @@ -72,3 +72,18 @@ clang-min-version = $(call test-ge, $(CONFIG_CLANG_VERSION), $1) # ld-option # Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y) ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3)) + +# __rustc-option +# Usage: MY_RUSTFLAGS += $(call __rustc-option,$(RUSTC),$(MY_RUSTFLAGS),-Cinstrument-coverage,-Zinstrument-coverage) +__rustc-option = $(call try-run,\ + $(1) $(2) $(3) --crate-type=rlib /dev/null --out-dir=$$TMPOUT -o "$$TMP",$(3),$(4)) + +# rustc-option +# Usage: rustflags-y += $(call rustc-option,-Cinstrument-coverage,-Zinstrument-coverage) +rustc-option = $(call __rustc-option, $(RUSTC),\ + $(KBUILD_RUSTFLAGS),$(1),$(2)) + +# rustc-option-yn +# Usage: flag := $(call rustc-option-yn,-Cinstrument-coverage) +rustc-option-yn = $(call try-run,\ + $(RUSTC) $(KBUILD_RUSTFLAGS) $(1) --crate-type=rlib /dev/null --out-dir=$$TMPOUT -o "$$TMP",y,n) -- cgit v1.2.3-70-g09d2 From e3117404b41124c88a4d834fc3222669a880addc Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Tue, 20 Aug 2024 19:48:58 +0000 Subject: kbuild: rust: Enable KASAN support Rust supports KASAN via LLVM, but prior to this patch, the flags aren't set properly. Suggested-by: Miguel Ojeda Signed-off-by: Matthew Maurer Reviewed-by: Andrey Konovalov Link: https://lore.kernel.org/r/20240820194910.187826-4-mmaurer@google.com [ Applied "SW_TAGS KASAN" nit. - Miguel ] Signed-off-by: Miguel Ojeda --- scripts/Makefile.kasan | 57 +++++++++++++++++++++++++++++------------ scripts/Makefile.lib | 3 +++ scripts/generate_rust_target.rs | 2 +- 3 files changed, 45 insertions(+), 17 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan index aab4154af00a..693dbbebebba 100644 --- a/scripts/Makefile.kasan +++ b/scripts/Makefile.kasan @@ -12,6 +12,11 @@ endif KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET) cc-param = $(call cc-option, -mllvm -$(1), $(call cc-option, --param $(1))) +rustc-param = $(call rustc-option, -Cllvm-args=-$(1),) + +check-args = $(foreach arg,$(2),$(call $(1),$(arg))) + +kasan_params := ifdef CONFIG_KASAN_STACK stack_enable := 1 @@ -41,39 +46,59 @@ CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \ $(call cc-option, -fsanitize=kernel-address \ -mllvm -asan-mapping-offset=$(KASAN_SHADOW_OFFSET))) -# Now, add other parameters enabled similarly in both GCC and Clang. -# As some of them are not supported by older compilers, use cc-param. -CFLAGS_KASAN += $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ - $(call cc-param,asan-stack=$(stack_enable)) \ - $(call cc-param,asan-instrument-allocas=1) \ - $(call cc-param,asan-globals=1) +# The minimum supported `rustc` version has a minimum supported LLVM +# version late enough that we can assume support for -asan-mapping-offset. +RUSTFLAGS_KASAN := -Zsanitizer=kernel-address \ + -Zsanitizer-recover=kernel-address \ + -Cllvm-args=-asan-mapping-offset=$(KASAN_SHADOW_OFFSET) + +# Now, add other parameters enabled similarly in GCC, Clang, and rustc. +# As some of them are not supported by older compilers, these will be filtered +# through `cc-param` or `rust-param` as applicable. +kasan_params += asan-instrumentation-with-call-threshold=$(call_threshold) \ + asan-stack=$(stack_enable) \ + asan-instrument-allocas=1 \ + asan-globals=1 # Instrument memcpy/memset/memmove calls by using instrumented __asan_mem*() # instead. With compilers that don't support this option, compiler-inserted # memintrinsics won't be checked by KASAN on GENERIC_ENTRY architectures. -CFLAGS_KASAN += $(call cc-param,asan-kernel-mem-intrinsic-prefix=1) +kasan_params += asan-kernel-mem-intrinsic-prefix=1 endif # CONFIG_KASAN_GENERIC ifdef CONFIG_KASAN_SW_TAGS +CFLAGS_KASAN := -fsanitize=kernel-hwaddress + +# This sets flags that will enable SW_TAGS KASAN once enabled in Rust. These +# will not work today, and is guarded against in dependencies for CONFIG_RUST. +RUSTFLAGS_KASAN := -Zsanitizer=kernel-hwaddress \ + -Zsanitizer-recover=kernel-hwaddress + ifdef CONFIG_KASAN_INLINE - instrumentation_flags := $(call cc-param,hwasan-mapping-offset=$(KASAN_SHADOW_OFFSET)) + kasan_params += hwasan-mapping-offset=$(KASAN_SHADOW_OFFSET) else - instrumentation_flags := $(call cc-param,hwasan-instrument-with-calls=1) + kasan_params += hwasan-instrument-with-calls=1 endif -CFLAGS_KASAN := -fsanitize=kernel-hwaddress \ - $(call cc-param,hwasan-instrument-stack=$(stack_enable)) \ - $(call cc-param,hwasan-use-short-granules=0) \ - $(call cc-param,hwasan-inline-all-checks=0) \ - $(instrumentation_flags) +kasan_params += hwasan-instrument-stack=$(stack_enable) \ + hwasan-use-short-granules=0 \ + hwasan-inline-all-checks=0 # Instrument memcpy/memset/memmove calls by using instrumented __hwasan_mem*(). ifeq ($(call clang-min-version, 150000)$(call gcc-min-version, 130000),y) - CFLAGS_KASAN += $(call cc-param,hwasan-kernel-mem-intrinsic-prefix=1) + kasan_params += hwasan-kernel-mem-intrinsic-prefix=1 endif endif # CONFIG_KASAN_SW_TAGS -export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE +# Add all as-supported KASAN LLVM parameters requested by the configuration. +CFLAGS_KASAN += $(call check-args, cc-param, $(kasan_params)) + +ifdef CONFIG_RUST + # Avoid calling `rustc-param` unless Rust is enabled. + RUSTFLAGS_KASAN += $(call check-args, rustc-param, $(kasan_params)) +endif # CONFIG_RUST + +export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE RUSTFLAGS_KASAN diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index fe3668dc4954..27999da3d382 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -167,6 +167,9 @@ ifneq ($(CONFIG_KASAN_HW_TAGS),y) _c_flags += $(if $(patsubst n%,, \ $(KASAN_SANITIZE_$(target-stem).o)$(KASAN_SANITIZE)$(is-kernel-object)), \ $(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE)) +_rust_flags += $(if $(patsubst n%,, \ + $(KASAN_SANITIZE_$(target-stem).o)$(KASAN_SANITIZE)$(is-kernel-object)), \ + $(RUSTFLAGS_KASAN)) endif endif diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs index 087c1d13d33b..0d00ac3723b5 100644 --- a/scripts/generate_rust_target.rs +++ b/scripts/generate_rust_target.rs @@ -207,7 +207,7 @@ fn main() { } ts.push("features", features); ts.push("llvm-target", "x86_64-linux-gnu"); - ts.push("supported-sanitizers", ["kcfi"]); + ts.push("supported-sanitizers", ["kcfi", "kernel-address"]); ts.push("target-pointer-width", "64"); } else if cfg.has("X86_32") { // This only works on UML, as i386 otherwise needs regparm support in rustc -- cgit v1.2.3-70-g09d2 From 5f5e7344322f0b0676579af054c787ed57d1c1df Mon Sep 17 00:00:00 2001 From: Kris Van Hees Date: Fri, 6 Sep 2024 10:45:03 -0400 Subject: kbuild: generate offset range data for builtin modules Create file module.builtin.ranges that can be used to find where built-in modules are located by their addresses. This will be useful for tracing tools to find what functions are for various built-in modules. The offset range data for builtin modules is generated using: - modules.builtin: associates object files with module names - vmlinux.map: provides load order of sections and offset of first member per section - vmlinux.o.map: provides offset of object file content per section - .*.cmd: build cmd file with KBUILD_MODFILE The generated data will look like: .text 00000000-00000000 = _text .text 0000baf0-0000cb10 amd_uncore .text 0009bd10-0009c8e0 iosf_mbi ... .text 00b9f080-00ba011a intel_skl_int3472_discrete .text 00ba0120-00ba03c0 intel_skl_int3472_discrete intel_skl_int3472_tps68470 .text 00ba03c0-00ba08d6 intel_skl_int3472_tps68470 ... .data 00000000-00000000 = _sdata .data 0000f020-0000f680 amd_uncore For each ELF section, it lists the offset of the first symbol. This can be used to determine the base address of the section at runtime. Next, it lists (in strict ascending order) offset ranges in that section that cover the symbols of one or more builtin modules. Multiple ranges can apply to a single module, and ranges can be shared between modules. The CONFIG_BUILTIN_MODULE_RANGES option controls whether offset range data is generated for kernel modules that are built into the kernel image. How it works: 1. The modules.builtin file is parsed to obtain a list of built-in module names and their associated object names (the .ko file that the module would be in if it were a loadable module, hereafter referred to as ). This object name can be used to identify objects in the kernel compile because any C or assembler code that ends up into a built-in module will have the option -DKBUILD_MODFILE= present in its build command, and those can be found in the ..cmd file in the kernel build tree. If an object is part of multiple modules, they will all be listed in the KBUILD_MODFILE option argument. This allows us to conclusively determine whether an object in the kernel build belong to any modules, and which. 2. The vmlinux.map is parsed next to determine the base address of each top level section so that all addresses into the section can be turned into offsets. This makes it possible to handle sections getting loaded at different addresses at system boot. We also determine an 'anchor' symbol at the beginning of each section to make it possible to calculate the true base address of a section at runtime (i.e. symbol address - symbol offset). We collect start addresses of sections that are included in the top level section. This is used when vmlinux is linked using vmlinux.o, because in that case, we need to look at the vmlinux.o linker map to know what object a symbol is found in. And finally, we process each symbol that is listed in vmlinux.map (or vmlinux.o.map) based on the following structure: vmlinux linked from vmlinux.a: vmlinux.map: -- might be same as top level section) -- built-in association known -- belongs to module(s) object belongs to ... vmlinux linked from vmlinux.o: vmlinux.map: -- might be same as top level section) vmlinux.o -- need to use vmlinux.o.map -- ignored ... vmlinux.o.map:
-- built-in association known -- belongs to module(s) object belongs to ... 3. As sections, objects, and symbols are processed, offset ranges are constructed in a straight-forward way: - If the symbol belongs to one or more built-in modules: - If we were working on the same module(s), extend the range to include this object - If we were working on another module(s), close that range, and start the new one - If the symbol does not belong to any built-in modules: - If we were working on a module(s) range, close that range Signed-off-by: Kris Van Hees Reviewed-by: Nick Alcock Reviewed-by: Alan Maguire Reviewed-by: Steven Rostedt (Google) Tested-by: Sam James Reviewed-by: Sami Tolvanen Tested-by: Sami Tolvanen Signed-off-by: Masahiro Yamada --- .gitignore | 1 + Documentation/dontdiff | 1 + Documentation/kbuild/kbuild.rst | 5 + Documentation/process/changes.rst | 7 + Makefile | 1 + lib/Kconfig.debug | 15 ++ scripts/Makefile.vmlinux | 18 ++ scripts/Makefile.vmlinux_o | 3 + scripts/generate_builtin_ranges.awk | 508 ++++++++++++++++++++++++++++++++++++ 9 files changed, 559 insertions(+) create mode 100755 scripts/generate_builtin_ranges.awk (limited to 'scripts') diff --git a/.gitignore b/.gitignore index c06a3ef6d6c6..625bf59ad845 100644 --- a/.gitignore +++ b/.gitignore @@ -69,6 +69,7 @@ modules.order /Module.markers /modules.builtin /modules.builtin.modinfo +/modules.builtin.ranges /modules.nsdeps # diff --git a/Documentation/dontdiff b/Documentation/dontdiff index 3c399f132e2d..a867aea95c40 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff @@ -180,6 +180,7 @@ modpost modules-only.symvers modules.builtin modules.builtin.modinfo +modules.builtin.ranges modules.nsdeps modules.order modversions.h* diff --git a/Documentation/kbuild/kbuild.rst b/Documentation/kbuild/kbuild.rst index 9c8d1d046ea5..a0f7726c46f8 100644 --- a/Documentation/kbuild/kbuild.rst +++ b/Documentation/kbuild/kbuild.rst @@ -22,6 +22,11 @@ modules.builtin.modinfo This file contains modinfo from all modules that are built into the kernel. Unlike modinfo of a separate module, all fields are prefixed with module name. +modules.builtin.ranges +---------------------- +This file contains address offset ranges (per ELF section) for all modules +that are built into the kernel. Together with System.map, it can be used +to associate module names with symbols. Environment variables ===================== diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst index 3fc63f27c226..00f1ed7c59c3 100644 --- a/Documentation/process/changes.rst +++ b/Documentation/process/changes.rst @@ -64,6 +64,7 @@ GNU tar 1.28 tar --version gtags (optional) 6.6.5 gtags --version mkimage (optional) 2017.01 mkimage --version Python (optional) 3.5.x python3 --version +GNU AWK (optional) 5.1.0 gawk --version ====================== =============== ======================================== .. [#f1] Sphinx is needed only to build the Kernel documentation @@ -192,6 +193,12 @@ platforms. The tool is available via the ``u-boot-tools`` package or can be built from the U-Boot source code. See the instructions at https://docs.u-boot.org/en/latest/build/tools.html#building-tools-for-linux +GNU AWK +------- + +GNU AWK is needed if you want kernel builds to generate address range data for +builtin modules (CONFIG_BUILTIN_MODULE_RANGES). + System utilities **************** diff --git a/Makefile b/Makefile index 145112bf281a..b4a941a30c73 100644 --- a/Makefile +++ b/Makefile @@ -1482,6 +1482,7 @@ endif # CONFIG_MODULES # Directories & files removed with 'make clean' CLEAN_FILES += vmlinux.symvers modules-only.symvers \ modules.builtin modules.builtin.modinfo modules.nsdeps \ + modules.builtin.ranges vmlinux.o.map \ compile_commands.json rust/test \ rust-project.json .vmlinux.objs .vmlinux.export.c diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index a30c03a66172..5e2f30921cb2 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -571,6 +571,21 @@ config VMLINUX_MAP pieces of code get eliminated with CONFIG_LD_DEAD_CODE_DATA_ELIMINATION. +config BUILTIN_MODULE_RANGES + bool "Generate address range information for builtin modules" + depends on !LTO + depends on VMLINUX_MAP + help + When modules are built into the kernel, there will be no module name + associated with its symbols in /proc/kallsyms. Tracers may want to + identify symbols by module name and symbol name regardless of whether + the module is configured as loadable or not. + + This option generates modules.builtin.ranges in the build tree with + offset ranges (per ELF section) for the module(s) they belong to. + It also records an anchor symbol to determine the load address of the + section. + config DEBUG_FORCE_WEAK_PER_CPU bool "Force weak per-cpu definitions" depends on DEBUG_KERNEL diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index 5ceecbed31eb..1284f05555b9 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -33,6 +33,24 @@ targets += vmlinux vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE +$(call if_changed_dep,link_vmlinux) +# module.builtin.ranges +# --------------------------------------------------------------------------- +ifdef CONFIG_BUILTIN_MODULE_RANGES +__default: modules.builtin.ranges + +quiet_cmd_modules_builtin_ranges = GEN $@ + cmd_modules_builtin_ranges = gawk -f $(real-prereqs) > $@ + +targets += modules.builtin.ranges +modules.builtin.ranges: $(srctree)/scripts/generate_builtin_ranges.awk \ + modules.builtin vmlinux.map vmlinux.o.map FORCE + $(call if_changed,modules_builtin_ranges) + +vmlinux.map: vmlinux + @: + +endif + # Add FORCE to the prerequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o index d64070b6b4bc..0b6e2ebf60dc 100644 --- a/scripts/Makefile.vmlinux_o +++ b/scripts/Makefile.vmlinux_o @@ -45,9 +45,12 @@ objtool-args = $(vmlinux-objtool-args-y) --link # Link of vmlinux.o used for section mismatch analysis # --------------------------------------------------------------------------- +vmlinux-o-ld-args-$(CONFIG_BUILTIN_MODULE_RANGES) += -Map=$@.map + quiet_cmd_ld_vmlinux.o = LD $@ cmd_ld_vmlinux.o = \ $(LD) ${KBUILD_LDFLAGS} -r -o $@ \ + $(vmlinux-o-ld-args-y) \ $(addprefix -T , $(initcalls-lds)) \ --whole-archive vmlinux.a --no-whole-archive \ --start-group $(KBUILD_VMLINUX_LIBS) --end-group \ diff --git a/scripts/generate_builtin_ranges.awk b/scripts/generate_builtin_ranges.awk new file mode 100755 index 000000000000..b9ec761b3bef --- /dev/null +++ b/scripts/generate_builtin_ranges.awk @@ -0,0 +1,508 @@ +#!/usr/bin/gawk -f +# SPDX-License-Identifier: GPL-2.0 +# generate_builtin_ranges.awk: Generate address range data for builtin modules +# Written by Kris Van Hees +# +# Usage: generate_builtin_ranges.awk modules.builtin vmlinux.map \ +# vmlinux.o.map > modules.builtin.ranges +# + +# Return the module name(s) (if any) associated with the given object. +# +# If we have seen this object before, return information from the cache. +# Otherwise, retrieve it from the corresponding .cmd file. +# +function get_module_info(fn, mod, obj, s) { + if (fn in omod) + return omod[fn]; + + if (match(fn, /\/[^/]+$/) == 0) + return ""; + + obj = fn; + mod = ""; + fn = substr(fn, 1, RSTART) "." substr(fn, RSTART + 1) ".cmd"; + if (getline s 0) { + mod = substr(s, RSTART + 16, RLENGTH - 16); + gsub(/['"]/, "", mod); + } else if (match(s, /RUST_MODFILE=[^ ]+/) > 0) + mod = substr(s, RSTART + 13, RLENGTH - 13); + } + close(fn); + + # A single module (common case) also reflects objects that are not part + # of a module. Some of those objects have names that are also a module + # name (e.g. core). We check the associated module file name, and if + # they do not match, the object is not part of a module. + if (mod !~ / /) { + if (!(mod in mods)) + mod = ""; + } + + gsub(/([^/ ]*\/)+/, "", mod); + gsub(/-/, "_", mod); + + # At this point, mod is a single (valid) module name, or a list of + # module names (that do not need validation). + omod[obj] = mod; + + return mod; +} + +# Update the ranges entry for the given module 'mod' in section 'osect'. +# +# We use a modified absolute start address (soff + base) as index because we +# may need to insert an anchor record later that must be at the start of the +# section data, and the first module may very well start at the same address. +# So, we use (addr << 1) + 1 to allow a possible anchor record to be placed at +# (addr << 1). This is safe because the index is only used to sort the entries +# before writing them out. +# +function update_entry(osect, mod, soff, eoff, sect, idx) { + sect = sect_in[osect]; + idx = sprintf("%016x", (soff + sect_base[osect]) * 2 + 1); + entries[idx] = sprintf("%s %08x-%08x %s", sect, soff, eoff, mod); + count[sect]++; +} + +# (1) Build a lookup map of built-in module names. +# +# The first file argument is used as input (modules.builtin). +# +# Lines will be like: +# kernel/crypto/lzo-rle.ko +# and we record the object name "crypto/lzo-rle". +# +ARGIND == 1 { + sub(/kernel\//, ""); # strip off "kernel/" prefix + sub(/\.ko$/, ""); # strip off .ko suffix + + mods[$1] = 1; + next; +} + +# (2) Collect address information for each section. +# +# The second file argument is used as input (vmlinux.map). +# +# We collect the base address of the section in order to convert all addresses +# in the section into offset values. +# +# We collect the address of the anchor (or first symbol in the section if there +# is no explicit anchor) to allow users of the range data to calculate address +# ranges based on the actual load address of the section in the running kernel. +# +# We collect the start address of any sub-section (section included in the top +# level section being processed). This is needed when the final linking was +# done using vmlinux.a because then the list of objects contained in each +# section is to be obtained from vmlinux.o.map. The offset of the sub-section +# is recorded here, to be used as an addend when processing vmlinux.o.map +# later. +# + +# Both GNU ld and LLVM lld linker map format are supported by converting LLVM +# lld linker map records into equivalent GNU ld linker map records. +# +# The first record of the vmlinux.map file provides enough information to know +# which format we are dealing with. +# +ARGIND == 2 && FNR == 1 && NF == 7 && $1 == "VMA" && $7 == "Symbol" { + map_is_lld = 1; + if (dbg) + printf "NOTE: %s uses LLVM lld linker map format\n", FILENAME >"/dev/stderr"; + next; +} + +# (LLD) Convert a section record fronm lld format to ld format. +# +# lld: ffffffff82c00000 2c00000 2493c0 8192 .data +# -> +# ld: .data 0xffffffff82c00000 0x2493c0 load address 0x0000000002c00000 +# +ARGIND == 2 && map_is_lld && NF == 5 && /[0-9] [^ ]+$/ { + $0 = $5 " 0x"$1 " 0x"$3 " load address 0x"$2; +} + +# (LLD) Convert an anchor record from lld format to ld format. +# +# lld: ffffffff81000000 1000000 0 1 _text = . +# -> +# ld: 0xffffffff81000000 _text = . +# +ARGIND == 2 && map_is_lld && !anchor && NF == 7 && raw_addr == "0x"$1 && $6 == "=" && $7 == "." { + $0 = " 0x"$1 " " $5 " = ."; +} + +# (LLD) Convert an object record from lld format to ld format. +# +# lld: 11480 11480 1f07 16 vmlinux.a(arch/x86/events/amd/uncore.o):(.text) +# -> +# ld: .text 0x0000000000011480 0x1f07 arch/x86/events/amd/uncore.o +# +ARGIND == 2 && map_is_lld && NF == 5 && $5 ~ /:\(/ { + gsub(/\)/, ""); + sub(/ vmlinux\.a\(/, " "); + sub(/:\(/, " "); + $0 = " "$6 " 0x"$1 " 0x"$3 " " $5; +} + +# (LLD) Convert a symbol record from lld format to ld format. +# +# We only care about these while processing a section for which no anchor has +# been determined yet. +# +# lld: ffffffff82a859a4 2a859a4 0 1 btf_ksym_iter_id +# -> +# ld: 0xffffffff82a859a4 btf_ksym_iter_id +# +ARGIND == 2 && map_is_lld && sect && !anchor && NF == 5 && $5 ~ /^[_A-Za-z][_A-Za-z0-9]*$/ { + $0 = " 0x"$1 " " $5; +} + +# (LLD) We do not need any other ldd linker map records. +# +ARGIND == 2 && map_is_lld && /^[0-9a-f]{16} / { + next; +} + +# (LD) Section records with just the section name at the start of the line +# need to have the next line pulled in to determine whether it is a +# loadable section. If it is, the next line will contains a hex value +# as first and second items. +# +ARGIND == 2 && !map_is_lld && NF == 1 && /^[^ ]/ { + s = $0; + getline; + if ($1 !~ /^0x/ || $2 !~ /^0x/) + next; + + $0 = s " " $0; +} + +# (LD) Object records with just the section name denote records with a long +# section name for which the remainder of the record can be found on the +# next line. +# +# (This is also needed for vmlinux.o.map, when used.) +# +ARGIND >= 2 && !map_is_lld && NF == 1 && /^ [^ \*]/ { + s = $0; + getline; + $0 = s " " $0; +} + +# Beginning a new section - done with the previous one (if any). +# +ARGIND == 2 && /^[^ ]/ { + sect = 0; +} + +# Process a loadable section (we only care about .-sections). +# +# Record the section name and its base address. +# We also record the raw (non-stripped) address of the section because it can +# be used to identify an anchor record. +# +# Note: +# Since some AWK implementations cannot handle large integers, we strip off the +# first 4 hex digits from the address. This is safe because the kernel space +# is not large enough for addresses to extend into those digits. The portion +# to strip off is stored in addr_prefix as a regexp, so further clauses can +# perform a simple substitution to do the address stripping. +# +ARGIND == 2 && /^\./ { + # Explicitly ignore a few sections that are not relevant here. + if ($1 ~ /^\.orc_/ || $1 ~ /_sites$/ || $1 ~ /\.percpu/) + next; + + # Sections with a 0-address can be ignored as well. + if ($2 ~ /^0x0+$/) + next; + + raw_addr = $2; + addr_prefix = "^" substr($2, 1, 6); + base = $2; + sub(addr_prefix, "0x", base); + base = strtonum(base); + sect = $1; + anchor = 0; + sect_base[sect] = base; + sect_size[sect] = strtonum($3); + + if (dbg) + printf "[%s] BASE %016x\n", sect, base >"/dev/stderr"; + + next; +} + +# If we are not in a section we care about, we ignore the record. +# +ARGIND == 2 && !sect { + next; +} + +# Record the first anchor symbol for the current section. +# +# An anchor record for the section bears the same raw address as the section +# record. +# +ARGIND == 2 && !anchor && NF == 4 && raw_addr == $1 && $3 == "=" && $4 == "." { + anchor = sprintf("%s %08x-%08x = %s", sect, 0, 0, $2); + sect_anchor[sect] = anchor; + + if (dbg) + printf "[%s] ANCHOR %016x = %s (.)\n", sect, 0, $2 >"/dev/stderr"; + + next; +} + +# If no anchor record was found for the current section, use the first symbol +# in the section as anchor. +# +ARGIND == 2 && !anchor && NF == 2 && $1 ~ /^0x/ && $2 !~ /^0x/ { + addr = $1; + sub(addr_prefix, "0x", addr); + addr = strtonum(addr) - base; + anchor = sprintf("%s %08x-%08x = %s", sect, addr, addr, $2); + sect_anchor[sect] = anchor; + + if (dbg) + printf "[%s] ANCHOR %016x = %s\n", sect, addr, $2 >"/dev/stderr"; + + next; +} + +# The first occurrence of a section name in an object record establishes the +# addend (often 0) for that section. This information is needed to handle +# sections that get combined in the final linking of vmlinux (e.g. .head.text +# getting included at the start of .text). +# +# If the section does not have a base yet, use the base of the encapsulating +# section. +# +ARGIND == 2 && sect && NF == 4 && /^ [^ \*]/ && !($1 in sect_addend) { + if (!($1 in sect_base)) { + sect_base[$1] = base; + + if (dbg) + printf "[%s] BASE %016x\n", $1, base >"/dev/stderr"; + } + + addr = $2; + sub(addr_prefix, "0x", addr); + addr = strtonum(addr); + sect_addend[$1] = addr - sect_base[$1]; + sect_in[$1] = sect; + + if (dbg) + printf "[%s] ADDEND %016x - %016x = %016x\n", $1, addr, base, sect_addend[$1] >"/dev/stderr"; + + # If the object is vmlinux.o then we will need vmlinux.o.map to get the + # actual offsets of objects. + if ($4 == "vmlinux.o") + need_o_map = 1; +} + +# (3) Collect offset ranges (relative to the section base address) for built-in +# modules. +# +# If the final link was done using the actual objects, vmlinux.map contains all +# the information we need (see section (3a)). +# If linking was done using vmlinux.a as intermediary, we will need to process +# vmlinux.o.map (see section (3b)). + +# (3a) Determine offset range info using vmlinux.map. +# +# Since we are already processing vmlinux.map, the top level section that is +# being processed is already known. If we do not have a base address for it, +# we do not need to process records for it. +# +# Given the object name, we determine the module(s) (if any) that the current +# object is associated with. +# +# If we were already processing objects for a (list of) module(s): +# - If the current object belongs to the same module(s), update the range data +# to include the current object. +# - Otherwise, ensure that the end offset of the range is valid. +# +# If the current object does not belong to a built-in module, ignore it. +# +# If it does, we add a new built-in module offset range record. +# +ARGIND == 2 && !need_o_map && /^ [^ ]/ && NF == 4 && $3 != "0x0" { + if (!(sect in sect_base)) + next; + + # Turn the address into an offset from the section base. + soff = $2; + sub(addr_prefix, "0x", soff); + soff = strtonum(soff) - sect_base[sect]; + eoff = soff + strtonum($3); + + # Determine which (if any) built-in modules the object belongs to. + mod = get_module_info($4); + + # If we are processing a built-in module: + # - If the current object is within the same module, we update its + # entry by extending the range and move on + # - Otherwise: + # + If we are still processing within the same main section, we + # validate the end offset against the start offset of the + # current object (e.g. .rodata.str1.[18] objects are often + # listed with an incorrect size in the linker map) + # + Otherwise, we validate the end offset against the section + # size + if (mod_name) { + if (mod == mod_name) { + mod_eoff = eoff; + update_entry(mod_sect, mod_name, mod_soff, eoff); + + next; + } else if (sect == sect_in[mod_sect]) { + if (mod_eoff > soff) + update_entry(mod_sect, mod_name, mod_soff, soff); + } else { + v = sect_size[sect_in[mod_sect]]; + if (mod_eoff > v) + update_entry(mod_sect, mod_name, mod_soff, v); + } + } + + mod_name = mod; + + # If we encountered an object that is not part of a built-in module, we + # do not need to record any data. + if (!mod) + next; + + # At this point, we encountered the start of a new built-in module. + mod_name = mod; + mod_soff = soff; + mod_eoff = eoff; + mod_sect = $1; + update_entry($1, mod, soff, mod_eoff); + + next; +} + +# If we do not need to parse the vmlinux.o.map file, we are done. +# +ARGIND == 3 && !need_o_map { + if (dbg) + printf "Note: %s is not needed.\n", FILENAME >"/dev/stderr"; + exit; +} + +# (3) Collect offset ranges (relative to the section base address) for built-in +# modules. +# + +# (LLD) Convert an object record from lld format to ld format. +# +ARGIND == 3 && map_is_lld && NF == 5 && $5 ~ /:\(/ { + gsub(/\)/, ""); + sub(/:\(/, " "); + + sect = $6; + if (!(sect in sect_addend)) + next; + + sub(/ vmlinux\.a\(/, " "); + $0 = " "sect " 0x"$1 " 0x"$3 " " $5; +} + +# (3b) Determine offset range info using vmlinux.o.map. +# +# If we do not know an addend for the object's section, we are interested in +# anything within that section. +# +# Determine the top-level section that the object's section was included in +# during the final link. This is the section name offset range data will be +# associated with for this object. +# +# The remainder of the processing of the current object record follows the +# procedure outlined in (3a). +# +ARGIND == 3 && /^ [^ ]/ && NF == 4 && $3 != "0x0" { + osect = $1; + if (!(osect in sect_addend)) + next; + + # We need to work with the main section. + sect = sect_in[osect]; + + # Turn the address into an offset from the section base. + soff = $2; + sub(addr_prefix, "0x", soff); + soff = strtonum(soff) + sect_addend[osect]; + eoff = soff + strtonum($3); + + # Determine which (if any) built-in modules the object belongs to. + mod = get_module_info($4); + + # If we are processing a built-in module: + # - If the current object is within the same module, we update its + # entry by extending the range and move on + # - Otherwise: + # + If we are still processing within the same main section, we + # validate the end offset against the start offset of the + # current object (e.g. .rodata.str1.[18] objects are often + # listed with an incorrect size in the linker map) + # + Otherwise, we validate the end offset against the section + # size + if (mod_name) { + if (mod == mod_name) { + mod_eoff = eoff; + update_entry(mod_sect, mod_name, mod_soff, eoff); + + next; + } else if (sect == sect_in[mod_sect]) { + if (mod_eoff > soff) + update_entry(mod_sect, mod_name, mod_soff, soff); + } else { + v = sect_size[sect_in[mod_sect]]; + if (mod_eoff > v) + update_entry(mod_sect, mod_name, mod_soff, v); + } + } + + mod_name = mod; + + # If we encountered an object that is not part of a built-in module, we + # do not need to record any data. + if (!mod) + next; + + # At this point, we encountered the start of a new built-in module. + mod_name = mod; + mod_soff = soff; + mod_eoff = eoff; + mod_sect = osect; + update_entry(osect, mod, soff, mod_eoff); + + next; +} + +# (4) Generate the output. +# +# Anchor records are added for each section that contains offset range data +# records. They are added at an adjusted section base address (base << 1) to +# ensure they come first in the second records (see update_entry() above for +# more information). +# +# All entries are sorted by (adjusted) address to ensure that the output can be +# parsed in strict ascending address order. +# +END { + for (sect in count) { + if (sect in sect_anchor) { + idx = sprintf("%016x", sect_base[sect] * 2); + entries[idx] = sect_anchor[sect]; + } + } + + n = asorti(entries, indices); + for (i = 1; i <= n; i++) + print entries[indices[i]]; +} -- cgit v1.2.3-70-g09d2 From ac7bd0945e3db5253bd03bfc40e71afafb08d225 Mon Sep 17 00:00:00 2001 From: Kris Van Hees Date: Fri, 6 Sep 2024 10:45:04 -0400 Subject: scripts: add verifier script for builtin module range data The modules.builtin.ranges offset range data for builtin modules is generated at compile time based on the list of built-in modules and the vmlinux.map and vmlinux.o.map linker maps. This data can be used to determine whether a symbol at a particular address belongs to module code that was configured to be compiled into the kernel proper as a built-in module (rather than as a standalone module). This patch adds a script that uses the generated modules.builtin.ranges data to annotate the symbols in the System.map with module names if their address falls within a range that belongs to one or more built-in modules. It then processes the vmlinux.map (and if needed, vmlinux.o.map) to verify the annotation: - For each top-level section: - For each object in the section: - Determine whether the object is part of a built-in module (using modules.builtin and the .*.cmd file used to compile the object as suggested in [0]) - For each symbol in that object, verify that the built-in module association (or lack thereof) matches the annotation given to the symbol. Signed-off-by: Kris Van Hees Reviewed-by: Nick Alcock Reviewed-by: Alan Maguire Tested-by: Sam James Reviewed-by: Sami Tolvanen Tested-by: Sami Tolvanen Signed-off-by: Masahiro Yamada --- scripts/verify_builtin_ranges.awk | 370 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 370 insertions(+) create mode 100755 scripts/verify_builtin_ranges.awk (limited to 'scripts') diff --git a/scripts/verify_builtin_ranges.awk b/scripts/verify_builtin_ranges.awk new file mode 100755 index 000000000000..0de7ed521601 --- /dev/null +++ b/scripts/verify_builtin_ranges.awk @@ -0,0 +1,370 @@ +#!/usr/bin/gawk -f +# SPDX-License-Identifier: GPL-2.0 +# verify_builtin_ranges.awk: Verify address range data for builtin modules +# Written by Kris Van Hees +# +# Usage: verify_builtin_ranges.awk modules.builtin.ranges System.map \ +# modules.builtin vmlinux.map vmlinux.o.map +# + +# Return the module name(s) (if any) associated with the given object. +# +# If we have seen this object before, return information from the cache. +# Otherwise, retrieve it from the corresponding .cmd file. +# +function get_module_info(fn, mod, obj, s) { + if (fn in omod) + return omod[fn]; + + if (match(fn, /\/[^/]+$/) == 0) + return ""; + + obj = fn; + mod = ""; + fn = substr(fn, 1, RSTART) "." substr(fn, RSTART + 1) ".cmd"; + if (getline s 0) { + mod = substr(s, RSTART + 16, RLENGTH - 16); + gsub(/['"]/, "", mod); + } else if (match(s, /RUST_MODFILE=[^ ]+/) > 0) + mod = substr(s, RSTART + 13, RLENGTH - 13); + } else { + print "ERROR: Failed to read: " fn "\n\n" \ + " For kernels built with O=, cd to \n" \ + " and execute this script as ./source/scripts/..." \ + >"/dev/stderr"; + close(fn); + total = 0; + exit(1); + } + close(fn); + + # A single module (common case) also reflects objects that are not part + # of a module. Some of those objects have names that are also a module + # name (e.g. core). We check the associated module file name, and if + # they do not match, the object is not part of a module. + if (mod !~ / /) { + if (!(mod in mods)) + mod = ""; + } + + gsub(/([^/ ]*\/)+/, "", mod); + gsub(/-/, "_", mod); + + # At this point, mod is a single (valid) module name, or a list of + # module names (that do not need validation). + omod[obj] = mod; + + return mod; +} + +# Return a representative integer value for a given hexadecimal address. +# +# Since all kernel addresses fall within the same memory region, we can safely +# strip off the first 6 hex digits before performing the hex-to-dec conversion, +# thereby avoiding integer overflows. +# +function addr2val(val) { + sub(/^0x/, "", val); + if (length(val) == 16) + val = substr(val, 5); + return strtonum("0x" val); +} + +# Determine the kernel build directory to use (default is .). +# +BEGIN { + if (ARGC < 6) { + print "Syntax: verify_builtin_ranges.awk \n" \ + " \n" \ + >"/dev/stderr"; + total = 0; + exit(1); + } +} + +# (1) Load the built-in module address range data. +# +ARGIND == 1 { + ranges[FNR] = $0; + rcnt++; + next; +} + +# (2) Annotate System.map symbols with module names. +# +ARGIND == 2 { + addr = addr2val($1); + name = $3; + + while (addr >= mod_eaddr) { + if (sect_symb) { + if (sect_symb != name) + next; + + sect_base = addr - sect_off; + if (dbg) + printf "[%s] BASE (%s) %016x - %016x = %016x\n", sect_name, sect_symb, addr, sect_off, sect_base >"/dev/stderr"; + sect_symb = 0; + } + + if (++ridx > rcnt) + break; + + $0 = ranges[ridx]; + sub(/-/, " "); + if ($4 != "=") { + sub(/-/, " "); + mod_saddr = strtonum("0x" $2) + sect_base; + mod_eaddr = strtonum("0x" $3) + sect_base; + $1 = $2 = $3 = ""; + sub(/^ +/, ""); + mod_name = $0; + + if (dbg) + printf "[%s] %s from %016x to %016x\n", sect_name, mod_name, mod_saddr, mod_eaddr >"/dev/stderr"; + } else { + sect_name = $1; + sect_off = strtonum("0x" $2); + sect_symb = $5; + } + } + + idx = addr"-"name; + if (addr >= mod_saddr && addr < mod_eaddr) + sym2mod[idx] = mod_name; + + next; +} + +# Once we are done annotating the System.map, we no longer need the ranges data. +# +FNR == 1 && ARGIND == 3 { + delete ranges; +} + +# (3) Build a lookup map of built-in module names. +# +# Lines from modules.builtin will be like: +# kernel/crypto/lzo-rle.ko +# and we record the object name "crypto/lzo-rle". +# +ARGIND == 3 { + sub(/kernel\//, ""); # strip off "kernel/" prefix + sub(/\.ko$/, ""); # strip off .ko suffix + + mods[$1] = 1; + next; +} + +# (4) Get a list of symbols (per object). +# +# Symbols by object are read from vmlinux.map, with fallback to vmlinux.o.map +# if vmlinux is found to have inked in vmlinux.o. +# + +# If we were able to get the data we need from vmlinux.map, there is no need to +# process vmlinux.o.map. +# +FNR == 1 && ARGIND == 5 && total > 0 { + if (dbg) + printf "Note: %s is not needed.\n", FILENAME >"/dev/stderr"; + exit; +} + +# First determine whether we are dealing with a GNU ld or LLVM lld linker map. +# +ARGIND >= 4 && FNR == 1 && NF == 7 && $1 == "VMA" && $7 == "Symbol" { + map_is_lld = 1; + next; +} + +# (LLD) Convert a section record fronm lld format to ld format. +# +ARGIND >= 4 && map_is_lld && NF == 5 && /[0-9] [^ ]+$/ { + $0 = $5 " 0x"$1 " 0x"$3 " load address 0x"$2; +} + +# (LLD) Convert an object record from lld format to ld format. +# +ARGIND >= 4 && map_is_lld && NF == 5 && $5 ~ /:\(/ { + if (/\.a\(/ && !/ vmlinux\.a\(/) + next; + + gsub(/\)/, ""); + sub(/:\(/, " "); + sub(/ vmlinux\.a\(/, " "); + $0 = " "$6 " 0x"$1 " 0x"$3 " " $5; +} + +# (LLD) Convert a symbol record from lld format to ld format. +# +ARGIND >= 4 && map_is_lld && NF == 5 && $5 ~ /^[A-Za-z_][A-Za-z0-9_]*$/ { + $0 = " 0x" $1 " " $5; +} + +# (LLD) We do not need any other ldd linker map records. +# +ARGIND >= 4 && map_is_lld && /^[0-9a-f]{16} / { + next; +} + +# Handle section records with long section names (spilling onto a 2nd line). +# +ARGIND >= 4 && !map_is_lld && NF == 1 && /^[^ ]/ { + s = $0; + getline; + $0 = s " " $0; +} + +# Next section - previous one is done. +# +ARGIND >= 4 && /^[^ ]/ { + sect = 0; +} + +# Get the (top level) section name. +# +ARGIND >= 4 && /^\./ { + # Explicitly ignore a few sections that are not relevant here. + if ($1 ~ /^\.orc_/ || $1 ~ /_sites$/ || $1 ~ /\.percpu/) + next; + + # Sections with a 0-address can be ignored as well (in vmlinux.map). + if (ARGIND == 4 && $2 ~ /^0x0+$/) + next; + + sect = $1; + + next; +} + +# If we are not currently in a section we care about, ignore records. +# +!sect { + next; +} + +# Handle object records with long section names (spilling onto a 2nd line). +# +ARGIND >= 4 && /^ [^ \*]/ && NF == 1 { + # If the section name is long, the remainder of the entry is found on + # the next line. + s = $0; + getline; + $0 = s " " $0; +} + +# Objects linked in from static libraries are ignored. +# If the object is vmlinux.o, we need to consult vmlinux.o.map for per-object +# symbol information +# +ARGIND == 4 && /^ [^ ]/ && NF == 4 { + if ($4 ~ /\.a\(/) + next; + + idx = sect":"$1; + if (!(idx in sect_addend)) { + sect_addend[idx] = addr2val($2); + if (dbg) + printf "ADDEND %s = %016x\n", idx, sect_addend[idx] >"/dev/stderr"; + } + if ($4 == "vmlinux.o") { + need_o_map = 1; + next; + } +} + +# If data from vmlinux.o.map is needed, we only process section and object +# records from vmlinux.map to determine which section we need to pay attention +# to in vmlinux.o.map. So skip everything else from vmlinux.map. +# +ARGIND == 4 && need_o_map { + next; +} + +# Get module information for the current object. +# +ARGIND >= 4 && /^ [^ ]/ && NF == 4 { + msect = $1; + mod_name = get_module_info($4); + mod_eaddr = addr2val($2) + addr2val($3); + + next; +} + +# Process a symbol record. +# +# Evaluate the module information obtained from vmlinux.map (or vmlinux.o.map) +# as follows: +# - For all symbols in a given object: +# - If the symbol is annotated with the same module name(s) that the object +# belongs to, count it as a match. +# - Otherwise: +# - If the symbol is known to have duplicates of which at least one is +# in a built-in module, disregard it. +# - If the symbol us not annotated with any module name(s) AND the +# object belongs to built-in modules, count it as missing. +# - Otherwise, count it as a mismatch. +# +ARGIND >= 4 && /^ / && NF == 2 && $1 ~ /^0x/ { + idx = sect":"msect; + if (!(idx in sect_addend)) + next; + + addr = addr2val($1); + + # Handle the rare but annoying case where a 0-size symbol is placed at + # the byte *after* the module range. Based on vmlinux.map it will be + # considered part of the current object, but it falls just beyond the + # module address range. Unfortunately, its address could be at the + # start of another built-in module, so the only safe thing to do is to + # ignore it. + if (mod_name && addr == mod_eaddr) + next; + + # If we are processing vmlinux.o.map, we need to apply the base address + # of the section to the relative address on the record. + # + if (ARGIND == 5) + addr += sect_addend[idx]; + + idx = addr"-"$2; + mod = ""; + if (idx in sym2mod) { + mod = sym2mod[idx]; + if (sym2mod[idx] == mod_name) { + mod_matches++; + matches++; + } else if (mod_name == "") { + print $2 " in " mod " (should NOT be)"; + mismatches++; + } else { + print $2 " in " mod " (should be " mod_name ")"; + mismatches++; + } + } else if (mod_name != "") { + print $2 " should be in " mod_name; + missing++; + } else + matches++; + + total++; + + next; +} + +# Issue the comparison report. +# +END { + if (total) { + printf "Verification of %s:\n", ARGV[1]; + printf " Correct matches: %6d (%d%% of total)\n", matches, 100 * matches / total; + printf " Module matches: %6d (%d%% of matches)\n", mod_matches, 100 * mod_matches / matches; + printf " Mismatches: %6d (%d%% of total)\n", mismatches, 100 * mismatches / total; + printf " Missing: %6d (%d%% of total)\n", missing, 100 * missing / total; + + if (mismatches || missing) + exit(1); + } +} -- cgit v1.2.3-70-g09d2 From ae70d708c932e7bc08b6c1975e1a010ee0b4e272 Mon Sep 17 00:00:00 2001 From: Kris Van Hees Date: Fri, 6 Sep 2024 10:45:05 -0400 Subject: kbuild: add install target for modules.builtin.ranges When CONFIG_BUILTIN_MODULE_RANGES is enabled, the modules.builtin.ranges file should be installed in the module install location. Signed-off-by: Kris Van Hees Reviewed-by: Nick Alcock Tested-by: Sam James Reviewed-by: Sami Tolvanen Tested-by: Sami Tolvanen Signed-off-by: Masahiro Yamada --- scripts/Makefile.modinst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 04f5229efa6b..4d81ed9af294 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -30,10 +30,12 @@ $(MODLIB)/modules.order: modules.order FORCE quiet_cmd_install_modorder = INSTALL $@ cmd_install_modorder = sed 's:^\(.*\)\.o$$:kernel/\1.ko:' $< > $@ -# Install modules.builtin(.modinfo) even when CONFIG_MODULES is disabled. +# Install modules.builtin(.modinfo,.ranges) even when CONFIG_MODULES is disabled. install-y += $(addprefix $(MODLIB)/, modules.builtin modules.builtin.modinfo) -$(addprefix $(MODLIB)/, modules.builtin modules.builtin.modinfo): $(MODLIB)/%: % FORCE +install-$(CONFIG_BUILTIN_MODULE_RANGES) += $(MODLIB)/modules.builtin.ranges + +$(addprefix $(MODLIB)/, modules.builtin modules.builtin.modinfo modules.builtin.ranges): $(MODLIB)/%: % FORCE $(call cmd,install) endif -- cgit v1.2.3-70-g09d2 From 327df5bf540e1cde17ae35d5a043ece773c80ff6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 7 Sep 2024 17:53:22 +0900 Subject: kallsyms: squash output_address() After commit 64e166099b69 ("kallsyms: get rid of code for absolute, kallsyms"), there is only one call site for output_address(). Squash it. Signed-off-by: Masahiro Yamada --- scripts/kallsyms.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index c70458e68ece..f6bb7fb2536b 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -292,15 +292,6 @@ static void output_label(const char *label) printf("%s:\n", label); } -/* Provide proper symbols relocatability by their '_text' relativeness. */ -static void output_address(unsigned long long addr) -{ - if (_text <= addr) - printf("\tPTR\t_text + %#llx\n", addr - _text); - else - printf("\tPTR\t_text - %#llx\n", _text - addr); -} - /* uncompress a compressed symbol. When this function is called, the best table * might still be compressed itself, so the function needs to be recursive */ static int expand_symbol(const unsigned char *data, int len, char *result) @@ -488,7 +479,11 @@ static void write_src(void) printf("\n"); output_label("kallsyms_relative_base"); - output_address(relative_base); + /* Provide proper symbols relocatability by their '_text' relativeness. */ + if (_text <= relative_base) + printf("\tPTR\t_text + %#llx\n", relative_base - _text); + else + printf("\tPTR\t_text - %#llx\n", _text - relative_base); printf("\n"); sort_symbols_by_name(); -- cgit v1.2.3-70-g09d2 From 9a418218dadf913fe78dbe6ad6b2e31e721b84ef Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 7 Sep 2024 17:53:23 +0900 Subject: kallsyms: change overflow variable to bool type Change the 'overflow' variable to bool. Also, remove unnecessary parentheses. Signed-off-by: Masahiro Yamada --- scripts/kallsyms.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index f6bb7fb2536b..03852da3d249 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -455,17 +455,17 @@ static void write_src(void) */ long long offset; - int overflow; + bool overflow; if (!absolute_percpu) { offset = table[i]->addr - relative_base; - overflow = (offset < 0 || offset > UINT_MAX); + overflow = offset < 0 || offset > UINT_MAX; } else if (symbol_absolute(table[i])) { offset = table[i]->addr; - overflow = (offset < 0 || offset > INT_MAX); + overflow = offset < 0 || offset > INT_MAX; } else { offset = relative_base - table[i]->addr - 1; - overflow = (offset < INT_MIN || offset >= 0); + overflow = offset < INT_MIN || offset >= 0; } if (overflow) { fprintf(stderr, "kallsyms failure: " -- cgit v1.2.3-70-g09d2 From a16219bdd34777cce35b9b6a704bfbaad28adb72 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 8 Sep 2024 21:43:16 +0900 Subject: scripts: move hash function from scripts/kconfig/ to scripts/include/ This function was originally added by commit 8af27e1dc4e4 ("fixdep: use hash table instead of a single array"). Move it to scripts/include/ so that other host programs can use it. Signed-off-by: Masahiro Yamada --- scripts/include/hash.h | 15 +++++++++++++++ scripts/kconfig/lkc.h | 1 - scripts/kconfig/symbol.c | 5 +++-- scripts/kconfig/util.c | 13 ++----------- 4 files changed, 20 insertions(+), 14 deletions(-) create mode 100644 scripts/include/hash.h (limited to 'scripts') diff --git a/scripts/include/hash.h b/scripts/include/hash.h new file mode 100644 index 000000000000..ce2bc43b308b --- /dev/null +++ b/scripts/include/hash.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef HASH_H +#define HASH_H + +static inline unsigned int hash_str(const char *s) +{ + /* fnv32 hash */ + unsigned int hash = 2166136261U; + + for (; *s; s++) + hash = (hash ^ *s) * 0x01000193; + return hash; +} + +#endif /* HASH_H */ diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index ddfb2b1cb737..b8ebc3094a23 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -51,7 +51,6 @@ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) } /* util.c */ -unsigned int strhash(const char *s); const char *file_lookup(const char *name); /* lexer.l */ diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 6793f016af5e..6243f0143ecf 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -9,6 +9,7 @@ #include #include +#include #include #include "internal.h" #include "lkc.h" @@ -893,7 +894,7 @@ struct symbol *sym_lookup(const char *name, int flags) case 'n': return &symbol_no; } } - hash = strhash(name); + hash = hash_str(name); hash_for_each_possible(sym_hashtable, symbol, node, hash) { if (symbol->name && @@ -936,7 +937,7 @@ struct symbol *sym_find(const char *name) case 'n': return &symbol_no; } } - hash = strhash(name); + hash = hash_str(name); hash_for_each_possible(sym_hashtable, symbol, node, hash) { if (symbol->name && diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c index 50698fff5b9d..5cdcee144b58 100644 --- a/scripts/kconfig/util.c +++ b/scripts/kconfig/util.c @@ -8,20 +8,11 @@ #include #include +#include #include #include #include "lkc.h" -unsigned int strhash(const char *s) -{ - /* fnv32 hash */ - unsigned int hash = 2166136261U; - - for (; *s; s++) - hash = (hash ^ *s) * 0x01000193; - return hash; -} - /* hash table of all parsed Kconfig files */ static HASHTABLE_DEFINE(file_hashtable, 1U << 11); @@ -35,7 +26,7 @@ const char *file_lookup(const char *name) { struct file *file; size_t len; - int hash = strhash(name); + int hash = hash_str(name); hash_for_each_possible(file_hashtable, file, node, hash) if (!strcmp(name, file->name)) -- cgit v1.2.3-70-g09d2 From d607e0e7a8d2ea6565f11064d28b0825a95748aa Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 8 Sep 2024 21:43:17 +0900 Subject: kconfig: change some expr_*() functions to bool This clarifies the behavior of these functions. Signed-off-by: Masahiro Yamada --- scripts/kconfig/expr.c | 15 ++++++++------- scripts/kconfig/expr.h | 6 +++--- 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index a16451347f63..d5dc682f7dc6 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -243,9 +243,10 @@ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) * equals some operand in the other (operands do not need to appear in the same * order), recursively. */ -int expr_eq(struct expr *e1, struct expr *e2) +bool expr_eq(struct expr *e1, struct expr *e2) { - int res, old_count; + int old_count; + bool res; /* * A NULL expr is taken to be yes, but there's also a different way to @@ -255,7 +256,7 @@ int expr_eq(struct expr *e1, struct expr *e2) return expr_is_yes(e1) && expr_is_yes(e2); if (e1->type != e2->type) - return 0; + return false; switch (e1->type) { case E_EQUAL: case E_GEQ: @@ -292,7 +293,7 @@ int expr_eq(struct expr *e1, struct expr *e2) printf(" ?\n"); } - return 0; + return false; } /* @@ -804,10 +805,10 @@ struct expr *expr_transform(struct expr *e) return e; } -int expr_contains_symbol(struct expr *dep, struct symbol *sym) +bool expr_contains_symbol(struct expr *dep, struct symbol *sym) { if (!dep) - return 0; + return false; switch (dep->type) { case E_AND: @@ -829,7 +830,7 @@ int expr_contains_symbol(struct expr *dep, struct symbol *sym) default: ; } - return 0; + return false; } bool expr_depends_symbol(struct expr *dep, struct symbol *sym) diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index c82d08bbd704..4ab7422ddbd8 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -278,11 +278,11 @@ struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); struct expr *expr_copy(const struct expr *org); void expr_free(struct expr *e); void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); -int expr_eq(struct expr *e1, struct expr *e2); +bool expr_eq(struct expr *e1, struct expr *e2); tristate expr_calc_value(struct expr *e); struct expr *expr_eliminate_dups(struct expr *e); struct expr *expr_transform(struct expr *e); -int expr_contains_symbol(struct expr *dep, struct symbol *sym); +bool expr_contains_symbol(struct expr *dep, struct symbol *sym); bool expr_depends_symbol(struct expr *dep, struct symbol *sym); struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); @@ -292,7 +292,7 @@ void expr_gstr_print(const struct expr *e, struct gstr *gs); void expr_gstr_print_revdep(struct expr *e, struct gstr *gs, tristate pr_type, const char *title); -static inline int expr_is_yes(const struct expr *e) +static inline bool expr_is_yes(const struct expr *e) { return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes); } -- cgit v1.2.3-70-g09d2 From 4fa146eaecaee6301e8f5b104fe63b41afdf83e6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 8 Sep 2024 21:43:18 +0900 Subject: kconfig: add comments to expression transformations Provide explanations for complex transformations. Signed-off-by: Masahiro Yamada --- scripts/kconfig/expr.c | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index d5dc682f7dc6..e83fe0c3d62f 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -442,6 +442,7 @@ static struct expr *expr_join_or(struct expr *e1, struct expr *e2) } } if (sym1->type == S_BOOLEAN) { + // a || !a -> y if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) || (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL)) return expr_alloc_symbol(&symbol_yes); @@ -647,6 +648,30 @@ struct expr *expr_eliminate_dups(struct expr *e) * Performs various simplifications involving logical operators and * comparisons. * + * For bool type: + * A=n -> !A + * A=m -> n + * A=y -> A + * A!=n -> A + * A!=m -> y + * A!=y -> !A + * + * For any type: + * !!A -> A + * !(A=B) -> A!=B + * !(A!=B) -> A=B + * !(A<=B) -> A>B + * !(A>=B) -> A A>=B + * !(A>B) -> A<=B + * !(A || B) -> !A && !B + * !(A && B) -> !A || !B + * + * For constant: + * !y -> n + * !m -> m + * !n -> y + * * Allocates and returns a new expression. */ struct expr *expr_transform(struct expr *e) @@ -674,12 +699,14 @@ struct expr *expr_transform(struct expr *e) if (e->left.sym->type != S_BOOLEAN) break; if (e->right.sym == &symbol_no) { + // A=n -> !A e->type = E_NOT; e->left.expr = expr_alloc_symbol(e->left.sym); e->right.sym = NULL; break; } if (e->right.sym == &symbol_mod) { + // A=m -> n printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name); e->type = E_SYMBOL; e->left.sym = &symbol_no; @@ -687,6 +714,7 @@ struct expr *expr_transform(struct expr *e) break; } if (e->right.sym == &symbol_yes) { + // A=y -> A e->type = E_SYMBOL; e->right.sym = NULL; break; @@ -696,11 +724,13 @@ struct expr *expr_transform(struct expr *e) if (e->left.sym->type != S_BOOLEAN) break; if (e->right.sym == &symbol_no) { + // A!=n -> A e->type = E_SYMBOL; e->right.sym = NULL; break; } if (e->right.sym == &symbol_mod) { + // A!=m -> y printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name); e->type = E_SYMBOL; e->left.sym = &symbol_yes; @@ -708,6 +738,7 @@ struct expr *expr_transform(struct expr *e) break; } if (e->right.sym == &symbol_yes) { + // A!=y -> !A e->type = E_NOT; e->left.expr = expr_alloc_symbol(e->left.sym); e->right.sym = NULL; @@ -717,7 +748,7 @@ struct expr *expr_transform(struct expr *e) case E_NOT: switch (e->left.expr->type) { case E_NOT: - // !!a -> a + // !!A -> A tmp = e->left.expr->left.expr; free(e->left.expr); free(e); @@ -726,7 +757,7 @@ struct expr *expr_transform(struct expr *e) break; case E_EQUAL: case E_UNEQUAL: - // !a='x' -> a!='x' + // !(A=B) -> A!=B tmp = e->left.expr; free(e); e = tmp; @@ -734,7 +765,7 @@ struct expr *expr_transform(struct expr *e) break; case E_LEQ: case E_GEQ: - // !a<='x' -> a>'x' + // !(A<=B) -> A>B tmp = e->left.expr; free(e); e = tmp; @@ -742,14 +773,14 @@ struct expr *expr_transform(struct expr *e) break; case E_LTH: case E_GTH: - // !a<'x' -> a>='x' + // !(A A>=B tmp = e->left.expr; free(e); e = tmp; e->type = e->type == E_LTH ? E_GEQ : E_LEQ; break; case E_OR: - // !(a || b) -> !a && !b + // !(A || B) -> !A && !B tmp = e->left.expr; e->type = E_AND; e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); @@ -758,7 +789,7 @@ struct expr *expr_transform(struct expr *e) e = expr_transform(e); break; case E_AND: - // !(a && b) -> !a || !b + // !(A && B) -> !A || !B tmp = e->left.expr; e->type = E_OR; e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); -- cgit v1.2.3-70-g09d2 From 440f67ccdcd31ca33d8d0439b16e4b6d4d7aba17 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 8 Sep 2024 21:43:19 +0900 Subject: kconfig: refactor expr_eliminate_dups() Currently, expr_eliminate_dups() passes two identical pointers down to expr_eliminate_dups1(), which later skips processing identical leaves. This approach is somewhat tricky and, more importantly, it will not work with the refactoring made in the next commit. This commit slightly changes the recursion logic; it deduplicates both the left and right arms, and then passes them to expr_eliminate_dups1(). expr_eliminate_dups() should produce the same result. Signed-off-by: Masahiro Yamada --- scripts/kconfig/expr.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index e83fe0c3d62f..5b826d197f12 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -578,16 +578,6 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct /* *ep1 and *ep2 are leaves. Compare and process them. */ - if (*ep1 == *ep2) - return; - - switch ((*ep1)->type) { - case E_OR: case E_AND: - expr_eliminate_dups1((*ep1)->type, ep1, ep1); - default: - ; - } - switch (type) { case E_OR: tmp = expr_join_or(*ep1, *ep2); @@ -634,7 +624,9 @@ struct expr *expr_eliminate_dups(struct expr *e) trans_count = 0; switch (e->type) { case E_OR: case E_AND: - expr_eliminate_dups1(e->type, &e, &e); + e->left.expr = expr_eliminate_dups(e->left.expr); + e->right.expr = expr_eliminate_dups(e->right.expr); + expr_eliminate_dups1(e->type, &e->left.expr, &e->right.expr); default: ; } -- cgit v1.2.3-70-g09d2 From f93d6bfbd2f74d79041c153a59df5336f6e9a14a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 8 Sep 2024 21:43:20 +0900 Subject: kconfig: use hash table to reuse expressions Currently, every expression in Kconfig files produces a new abstract syntax tree (AST), even if it is identical to a previously encountered one. Consider the following code: config FOO bool "FOO" depends on (A || B) && C config BAR bool "BAR" depends on (A || B) && C config BAZ bool "BAZ" depends on A || B The "depends on" lines are similar, but currently a separate AST is allocated for each one. The current data structure looks like this: FOO->dep ==> AND BAR->dep ==> AND BAZ->dep ==> OR / \ / \ / \ OR C OR C A B / \ / \ A B A B This is redundant; FOO->dep and BAR->dep have identical ASTs but different memory instances. We can optimize this; FOO->dep and BAR->dep can share the same AST, and BAZ->dep can reference its sub tree. The optimized data structure looks like this: FOO->dep, BAR->dep ==> AND / \ BAZ->dep ==> OR C / \ A B This commit introduces a hash table to keep track of allocated expressions. If an identical expression is found, it is reused. This does not necessarily result in memory savings, as menu_finalize() transforms expressions without freeing up stale ones. This will be addressed later. One optimization that can be easily implemented is caching the expression's value. Once FOO's dependency, (A || B) && C, is calculated, it can be cached, eliminating the need to recalculate it for BAR. This commit also reverts commit e983b7b17ad1 ("kconfig/menu.c: fix multiple references to expressions in menu_add_prop()"). Signed-off-by: Masahiro Yamada --- scripts/include/hash.h | 13 ++ scripts/kconfig/expr.c | 381 ++++++++++++++++----------------------------- scripts/kconfig/expr.h | 16 +- scripts/kconfig/internal.h | 4 + scripts/kconfig/menu.c | 33 ++-- 5 files changed, 170 insertions(+), 277 deletions(-) (limited to 'scripts') diff --git a/scripts/include/hash.h b/scripts/include/hash.h index ce2bc43b308b..efa904368a62 100644 --- a/scripts/include/hash.h +++ b/scripts/include/hash.h @@ -12,4 +12,17 @@ static inline unsigned int hash_str(const char *s) return hash; } +/* simplified version of functions from include/linux/hash.h */ +#define GOLDEN_RATIO_32 0x61C88647 + +static inline unsigned int hash_32(unsigned int val) +{ + return 0x61C88647 * val; +} + +static inline unsigned int hash_ptr(const void *ptr) +{ + return hash_32((unsigned int)(unsigned long)ptr); +} + #endif /* HASH_H */ diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 5b826d197f12..476dcaa9078e 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -9,45 +9,68 @@ #include #include +#include #include +#include "internal.h" #include "lkc.h" #define DEBUG_EXPR 0 +HASHTABLE_DEFINE(expr_hashtable, EXPR_HASHSIZE); + static struct expr *expr_eliminate_yn(struct expr *e); -struct expr *expr_alloc_symbol(struct symbol *sym) +/** + * expr_lookup - return the expression with the given type and sub-nodes + * This looks up an expression with the specified type and sub-nodes. If such + * an expression is found in the hash table, it is returned. Otherwise, a new + * expression node is allocated and added to the hash table. + * @type: expression type + * @l: left node + * @r: right node + * return: expression + */ +static struct expr *expr_lookup(enum expr_type type, void *l, void *r) { - struct expr *e = xcalloc(1, sizeof(*e)); - e->type = E_SYMBOL; - e->left.sym = sym; + struct expr *e; + int hash; + + hash = hash_32((unsigned int)type ^ hash_ptr(l) ^ hash_ptr(r)); + + hash_for_each_possible(expr_hashtable, e, node, hash) { + if (e->type == type && e->left._initdata == l && + e->right._initdata == r) + return e; + } + + e = xmalloc(sizeof(*e)); + e->type = type; + e->left._initdata = l; + e->right._initdata = r; + + hash_add(expr_hashtable, &e->node, hash); + return e; } +struct expr *expr_alloc_symbol(struct symbol *sym) +{ + return expr_lookup(E_SYMBOL, sym, NULL); +} + struct expr *expr_alloc_one(enum expr_type type, struct expr *ce) { - struct expr *e = xcalloc(1, sizeof(*e)); - e->type = type; - e->left.expr = ce; - return e; + return expr_lookup(type, ce, NULL); } struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2) { - struct expr *e = xcalloc(1, sizeof(*e)); - e->type = type; - e->left.expr = e1; - e->right.expr = e2; - return e; + return expr_lookup(type, e1, e2); } struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2) { - struct expr *e = xcalloc(1, sizeof(*e)); - e->type = type; - e->left.sym = s1; - e->right.sym = s2; - return e; + return expr_lookup(type, s1, s2); } struct expr *expr_alloc_and(struct expr *e1, struct expr *e2) @@ -64,76 +87,6 @@ struct expr *expr_alloc_or(struct expr *e1, struct expr *e2) return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; } -struct expr *expr_copy(const struct expr *org) -{ - struct expr *e; - - if (!org) - return NULL; - - e = xmalloc(sizeof(*org)); - memcpy(e, org, sizeof(*org)); - switch (org->type) { - case E_SYMBOL: - e->left = org->left; - break; - case E_NOT: - e->left.expr = expr_copy(org->left.expr); - break; - case E_EQUAL: - case E_GEQ: - case E_GTH: - case E_LEQ: - case E_LTH: - case E_UNEQUAL: - e->left.sym = org->left.sym; - e->right.sym = org->right.sym; - break; - case E_AND: - case E_OR: - e->left.expr = expr_copy(org->left.expr); - e->right.expr = expr_copy(org->right.expr); - break; - default: - fprintf(stderr, "can't copy type %d\n", e->type); - free(e); - e = NULL; - break; - } - - return e; -} - -void expr_free(struct expr *e) -{ - if (!e) - return; - - switch (e->type) { - case E_SYMBOL: - break; - case E_NOT: - expr_free(e->left.expr); - break; - case E_EQUAL: - case E_GEQ: - case E_GTH: - case E_LEQ: - case E_LTH: - case E_UNEQUAL: - break; - case E_OR: - case E_AND: - expr_free(e->left.expr); - expr_free(e->right.expr); - break; - default: - fprintf(stderr, "how to free type %d?\n", e->type); - break; - } - free(e); -} - static int trans_count; /* @@ -146,16 +99,24 @@ static int trans_count; */ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2) { + struct expr *l, *r; + /* Recurse down to leaves */ if ((*ep1)->type == type) { - __expr_eliminate_eq(type, &(*ep1)->left.expr, ep2); - __expr_eliminate_eq(type, &(*ep1)->right.expr, ep2); + l = (*ep1)->left.expr; + r = (*ep1)->right.expr; + __expr_eliminate_eq(type, &l, ep2); + __expr_eliminate_eq(type, &r, ep2); + *ep1 = expr_alloc_two(type, l, r); return; } if ((*ep2)->type == type) { - __expr_eliminate_eq(type, ep1, &(*ep2)->left.expr); - __expr_eliminate_eq(type, ep1, &(*ep2)->right.expr); + l = (*ep2)->left.expr; + r = (*ep2)->right.expr; + __expr_eliminate_eq(type, ep1, &l); + __expr_eliminate_eq(type, ep1, &r); + *ep2 = expr_alloc_two(type, l, r); return; } @@ -171,7 +132,6 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e /* *ep1 and *ep2 are equal leaves. Prepare them for elimination. */ trans_count++; - expr_free(*ep1); expr_free(*ep2); switch (type) { case E_OR: *ep1 = expr_alloc_symbol(&symbol_no); @@ -271,14 +231,10 @@ bool expr_eq(struct expr *e1, struct expr *e2) return expr_eq(e1->left.expr, e2->left.expr); case E_AND: case E_OR: - e1 = expr_copy(e1); - e2 = expr_copy(e2); old_count = trans_count; expr_eliminate_eq(&e1, &e2); res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL && e1->left.sym == e2->left.sym); - expr_free(e1); - expr_free(e2); trans_count = old_count; return res; case E_RANGE: @@ -297,7 +253,7 @@ bool expr_eq(struct expr *e1, struct expr *e2) } /* - * Recursively performs the following simplifications in-place (as well as the + * Recursively performs the following simplifications (as well as the * corresponding simplifications with swapped operands): * * expr && n -> n @@ -309,79 +265,39 @@ bool expr_eq(struct expr *e1, struct expr *e2) */ static struct expr *expr_eliminate_yn(struct expr *e) { - struct expr *tmp; + struct expr *l, *r; if (e) switch (e->type) { case E_AND: - e->left.expr = expr_eliminate_yn(e->left.expr); - e->right.expr = expr_eliminate_yn(e->right.expr); - if (e->left.expr->type == E_SYMBOL) { - if (e->left.expr->left.sym == &symbol_no) { - expr_free(e->left.expr); - expr_free(e->right.expr); - e->type = E_SYMBOL; - e->left.sym = &symbol_no; - e->right.expr = NULL; - return e; - } else if (e->left.expr->left.sym == &symbol_yes) { - free(e->left.expr); - tmp = e->right.expr; - *e = *(e->right.expr); - free(tmp); - return e; - } + l = expr_eliminate_yn(e->left.expr); + r = expr_eliminate_yn(e->right.expr); + if (l->type == E_SYMBOL) { + if (l->left.sym == &symbol_no) + return l; + else if (l->left.sym == &symbol_yes) + return r; } - if (e->right.expr->type == E_SYMBOL) { - if (e->right.expr->left.sym == &symbol_no) { - expr_free(e->left.expr); - expr_free(e->right.expr); - e->type = E_SYMBOL; - e->left.sym = &symbol_no; - e->right.expr = NULL; - return e; - } else if (e->right.expr->left.sym == &symbol_yes) { - free(e->right.expr); - tmp = e->left.expr; - *e = *(e->left.expr); - free(tmp); - return e; - } + if (r->type == E_SYMBOL) { + if (r->left.sym == &symbol_no) + return r; + else if (r->left.sym == &symbol_yes) + return l; } break; case E_OR: - e->left.expr = expr_eliminate_yn(e->left.expr); - e->right.expr = expr_eliminate_yn(e->right.expr); - if (e->left.expr->type == E_SYMBOL) { - if (e->left.expr->left.sym == &symbol_no) { - free(e->left.expr); - tmp = e->right.expr; - *e = *(e->right.expr); - free(tmp); - return e; - } else if (e->left.expr->left.sym == &symbol_yes) { - expr_free(e->left.expr); - expr_free(e->right.expr); - e->type = E_SYMBOL; - e->left.sym = &symbol_yes; - e->right.expr = NULL; - return e; - } + l = expr_eliminate_yn(e->left.expr); + r = expr_eliminate_yn(e->right.expr); + if (l->type == E_SYMBOL) { + if (l->left.sym == &symbol_no) + return r; + else if (l->left.sym == &symbol_yes) + return l; } - if (e->right.expr->type == E_SYMBOL) { - if (e->right.expr->left.sym == &symbol_no) { - free(e->right.expr); - tmp = e->left.expr; - *e = *(e->left.expr); - free(tmp); - return e; - } else if (e->right.expr->left.sym == &symbol_yes) { - expr_free(e->left.expr); - expr_free(e->right.expr); - e->type = E_SYMBOL; - e->left.sym = &symbol_yes; - e->right.expr = NULL; - return e; - } + if (r->type == E_SYMBOL) { + if (r->left.sym == &symbol_no) + return l; + else if (r->left.sym == &symbol_yes) + return r; } break; default: @@ -399,7 +315,7 @@ static struct expr *expr_join_or(struct expr *e1, struct expr *e2) struct symbol *sym1, *sym2; if (expr_eq(e1, e2)) - return expr_copy(e1); + return e1; if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) return NULL; if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) @@ -464,7 +380,7 @@ static struct expr *expr_join_and(struct expr *e1, struct expr *e2) struct symbol *sym1, *sym2; if (expr_eq(e1, e2)) - return expr_copy(e1); + return e1; if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) return NULL; if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) @@ -561,18 +477,24 @@ static struct expr *expr_join_and(struct expr *e1, struct expr *e2) */ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2) { - struct expr *tmp; + struct expr *tmp, *l, *r; /* Recurse down to leaves */ if ((*ep1)->type == type) { - expr_eliminate_dups1(type, &(*ep1)->left.expr, ep2); - expr_eliminate_dups1(type, &(*ep1)->right.expr, ep2); + l = (*ep1)->left.expr; + r = (*ep1)->right.expr; + expr_eliminate_dups1(type, &l, ep2); + expr_eliminate_dups1(type, &r, ep2); + *ep1 = expr_alloc_two(type, l, r); return; } if ((*ep2)->type == type) { - expr_eliminate_dups1(type, ep1, &(*ep2)->left.expr); - expr_eliminate_dups1(type, ep1, &(*ep2)->right.expr); + l = (*ep2)->left.expr; + r = (*ep2)->right.expr; + expr_eliminate_dups1(type, ep1, &l); + expr_eliminate_dups1(type, ep1, &r); + *ep2 = expr_alloc_two(type, l, r); return; } @@ -582,7 +504,6 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct case E_OR: tmp = expr_join_or(*ep1, *ep2); if (tmp) { - expr_free(*ep1); expr_free(*ep2); *ep1 = expr_alloc_symbol(&symbol_no); *ep2 = tmp; trans_count++; @@ -591,7 +512,6 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct case E_AND: tmp = expr_join_and(*ep1, *ep2); if (tmp) { - expr_free(*ep1); expr_free(*ep2); *ep1 = expr_alloc_symbol(&symbol_yes); *ep2 = tmp; trans_count++; @@ -621,12 +541,15 @@ struct expr *expr_eliminate_dups(struct expr *e) oldcount = trans_count; do { + struct expr *l, *r; + trans_count = 0; switch (e->type) { case E_OR: case E_AND: - e->left.expr = expr_eliminate_dups(e->left.expr); - e->right.expr = expr_eliminate_dups(e->right.expr); - expr_eliminate_dups1(e->type, &e->left.expr, &e->right.expr); + l = expr_eliminate_dups(e->left.expr); + r = expr_eliminate_dups(e->right.expr); + expr_eliminate_dups1(e->type, &l, &r); + e = expr_alloc_two(e->type, l, r); default: ; } @@ -668,8 +591,6 @@ struct expr *expr_eliminate_dups(struct expr *e) */ struct expr *expr_transform(struct expr *e) { - struct expr *tmp; - if (!e) return NULL; switch (e->type) { @@ -682,8 +603,9 @@ struct expr *expr_transform(struct expr *e) case E_SYMBOL: break; default: - e->left.expr = expr_transform(e->left.expr); - e->right.expr = expr_transform(e->right.expr); + e = expr_alloc_two(e->type, + expr_transform(e->left.expr), + expr_transform(e->right.expr)); } switch (e->type) { @@ -692,23 +614,18 @@ struct expr *expr_transform(struct expr *e) break; if (e->right.sym == &symbol_no) { // A=n -> !A - e->type = E_NOT; - e->left.expr = expr_alloc_symbol(e->left.sym); - e->right.sym = NULL; + e = expr_alloc_one(E_NOT, expr_alloc_symbol(e->left.sym)); break; } if (e->right.sym == &symbol_mod) { // A=m -> n printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name); - e->type = E_SYMBOL; - e->left.sym = &symbol_no; - e->right.sym = NULL; + e = expr_alloc_symbol(&symbol_no); break; } if (e->right.sym == &symbol_yes) { // A=y -> A - e->type = E_SYMBOL; - e->right.sym = NULL; + e = expr_alloc_symbol(e->left.sym); break; } break; @@ -717,23 +634,18 @@ struct expr *expr_transform(struct expr *e) break; if (e->right.sym == &symbol_no) { // A!=n -> A - e->type = E_SYMBOL; - e->right.sym = NULL; + e = expr_alloc_symbol(e->left.sym); break; } if (e->right.sym == &symbol_mod) { // A!=m -> y printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name); - e->type = E_SYMBOL; - e->left.sym = &symbol_yes; - e->right.sym = NULL; + e = expr_alloc_symbol(&symbol_yes); break; } if (e->right.sym == &symbol_yes) { // A!=y -> !A - e->type = E_NOT; - e->left.expr = expr_alloc_symbol(e->left.sym); - e->right.sym = NULL; + e = expr_alloc_one(E_NOT, e->left.expr); break; } break; @@ -741,82 +653,51 @@ struct expr *expr_transform(struct expr *e) switch (e->left.expr->type) { case E_NOT: // !!A -> A - tmp = e->left.expr->left.expr; - free(e->left.expr); - free(e); - e = tmp; - e = expr_transform(e); + e = e->left.expr->left.expr; break; case E_EQUAL: case E_UNEQUAL: // !(A=B) -> A!=B - tmp = e->left.expr; - free(e); - e = tmp; - e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; + e = expr_alloc_comp(e->left.expr->type == E_EQUAL ? E_UNEQUAL : E_EQUAL, + e->left.expr->left.sym, + e->left.expr->right.sym); break; case E_LEQ: case E_GEQ: // !(A<=B) -> A>B - tmp = e->left.expr; - free(e); - e = tmp; - e->type = e->type == E_LEQ ? E_GTH : E_LTH; + e = expr_alloc_comp(e->left.expr->type == E_LEQ ? E_GTH : E_LTH, + e->left.expr->left.sym, + e->left.expr->right.sym); break; case E_LTH: case E_GTH: // !(A A>=B - tmp = e->left.expr; - free(e); - e = tmp; - e->type = e->type == E_LTH ? E_GEQ : E_LEQ; + e = expr_alloc_comp(e->left.expr->type == E_LTH ? E_GEQ : E_LEQ, + e->left.expr->left.sym, + e->left.expr->right.sym); break; case E_OR: // !(A || B) -> !A && !B - tmp = e->left.expr; - e->type = E_AND; - e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); - tmp->type = E_NOT; - tmp->right.expr = NULL; + e = expr_alloc_and(expr_alloc_one(E_NOT, e->left.expr->left.expr), + expr_alloc_one(E_NOT, e->left.expr->right.expr)); e = expr_transform(e); break; case E_AND: // !(A && B) -> !A || !B - tmp = e->left.expr; - e->type = E_OR; - e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); - tmp->type = E_NOT; - tmp->right.expr = NULL; + e = expr_alloc_or(expr_alloc_one(E_NOT, e->left.expr->left.expr), + expr_alloc_one(E_NOT, e->left.expr->right.expr)); e = expr_transform(e); break; case E_SYMBOL: - if (e->left.expr->left.sym == &symbol_yes) { + if (e->left.expr->left.sym == &symbol_yes) // !'y' -> 'n' - tmp = e->left.expr; - free(e); - e = tmp; - e->type = E_SYMBOL; - e->left.sym = &symbol_no; - break; - } - if (e->left.expr->left.sym == &symbol_mod) { + e = expr_alloc_symbol(&symbol_no); + else if (e->left.expr->left.sym == &symbol_mod) // !'m' -> 'm' - tmp = e->left.expr; - free(e); - e = tmp; - e->type = E_SYMBOL; - e->left.sym = &symbol_mod; - break; - } - if (e->left.expr->left.sym == &symbol_no) { + e = expr_alloc_symbol(&symbol_mod); + else if (e->left.expr->left.sym == &symbol_no) // !'n' -> 'y' - tmp = e->left.expr; - free(e); - e = tmp; - e->type = E_SYMBOL; - e->left.sym = &symbol_yes; - break; - } + e = expr_alloc_symbol(&symbol_yes); break; default: ; @@ -940,18 +821,18 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb case E_EQUAL: if (type == E_EQUAL) { if (sym == &symbol_yes) - return expr_copy(e); + return e; if (sym == &symbol_mod) return expr_alloc_symbol(&symbol_no); if (sym == &symbol_no) - return expr_alloc_one(E_NOT, expr_copy(e)); + return expr_alloc_one(E_NOT, e); } else { if (sym == &symbol_yes) - return expr_alloc_one(E_NOT, expr_copy(e)); + return expr_alloc_one(E_NOT, e); if (sym == &symbol_mod) return expr_alloc_symbol(&symbol_yes); if (sym == &symbol_no) - return expr_copy(e); + return e; } break; case E_SYMBOL: diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 4ab7422ddbd8..a398b2b2dbe0 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -29,11 +29,21 @@ enum expr_type { }; union expr_data { - struct expr *expr; - struct symbol *sym; + struct expr * const expr; + struct symbol * const sym; + void *_initdata; }; +/** + * struct expr - expression + * + * @node: link node for the hash table + * @type: expressoin type + * @left: left node + * @right: right node + */ struct expr { + struct hlist_node node; enum expr_type type; union expr_data left, right; }; @@ -275,8 +285,6 @@ struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); -struct expr *expr_copy(const struct expr *org); -void expr_free(struct expr *e); void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); bool expr_eq(struct expr *e1, struct expr *e2); tristate expr_calc_value(struct expr *e); diff --git a/scripts/kconfig/internal.h b/scripts/kconfig/internal.h index 02106eb7815e..84c2ea0389fd 100644 --- a/scripts/kconfig/internal.h +++ b/scripts/kconfig/internal.h @@ -11,6 +11,10 @@ extern HASHTABLE_DECLARE(sym_hashtable, SYMBOL_HASHSIZE); #define for_all_symbols(sym) \ hash_for_each(sym_hashtable, sym, node) +#define EXPR_HASHSIZE (1U << 14) + +extern HASHTABLE_DECLARE(expr_hashtable, EXPR_HASHSIZE); + struct menu; extern struct menu *current_menu, *current_entry; diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index f61327fabead..4addd33749bb 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -107,12 +107,13 @@ static struct expr *rewrite_m(struct expr *e) switch (e->type) { case E_NOT: - e->left.expr = rewrite_m(e->left.expr); + e = expr_alloc_one(E_NOT, rewrite_m(e->left.expr)); break; case E_OR: case E_AND: - e->left.expr = rewrite_m(e->left.expr); - e->right.expr = rewrite_m(e->right.expr); + e = expr_alloc_two(e->type, + rewrite_m(e->left.expr), + rewrite_m(e->right.expr)); break; case E_SYMBOL: /* change 'm' into 'm' && MODULES */ @@ -192,21 +193,11 @@ struct property *menu_add_prompt(enum prop_type type, const char *prompt, struct menu *menu = current_entry; while ((menu = menu->parent) != NULL) { - struct expr *dup_expr; if (!menu->visibility) continue; - /* - * Do not add a reference to the menu's visibility - * expression but use a copy of it. Otherwise the - * expression reduction functions will modify - * expressions that have multiple references which - * can cause unwanted side effects. - */ - dup_expr = expr_copy(menu->visibility); - prop->visible.expr = expr_alloc_and(prop->visible.expr, - dup_expr); + menu->visibility); } } @@ -322,7 +313,7 @@ static void _menu_finalize(struct menu *parent, bool inside_choice) */ basedep = rewrite_m(menu->dep); basedep = expr_transform(basedep); - basedep = expr_alloc_and(expr_copy(parent->dep), basedep); + basedep = expr_alloc_and(parent->dep, basedep); basedep = expr_eliminate_dups(basedep); menu->dep = basedep; @@ -366,7 +357,7 @@ static void _menu_finalize(struct menu *parent, bool inside_choice) */ dep = rewrite_m(prop->visible.expr); dep = expr_transform(dep); - dep = expr_alloc_and(expr_copy(basedep), dep); + dep = expr_alloc_and(basedep, dep); dep = expr_eliminate_dups(dep); prop->visible.expr = dep; @@ -377,11 +368,11 @@ static void _menu_finalize(struct menu *parent, bool inside_choice) if (prop->type == P_SELECT) { struct symbol *es = prop_get_symbol(prop); es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, - expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); + expr_alloc_and(expr_alloc_symbol(menu->sym), dep)); } else if (prop->type == P_IMPLY) { struct symbol *es = prop_get_symbol(prop); es->implied.expr = expr_alloc_or(es->implied.expr, - expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); + expr_alloc_and(expr_alloc_symbol(menu->sym), dep)); } } } @@ -441,22 +432,18 @@ static void _menu_finalize(struct menu *parent, bool inside_choice) */ dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no); dep = expr_eliminate_dups(expr_transform(dep)); - dep2 = expr_copy(basedep); + dep2 = basedep; expr_eliminate_eq(&dep, &dep2); - expr_free(dep); if (!expr_is_yes(dep2)) { /* Not superset, quit */ - expr_free(dep2); break; } /* Superset, put in submenu */ - expr_free(dep2); next: _menu_finalize(menu, false); menu->parent = parent; last_menu = menu; } - expr_free(basedep); if (last_menu) { parent->list = parent->next; parent->next = last_menu->next; -- cgit v1.2.3-70-g09d2 From 95573cac25c6b11f02d599d18e9a1c778706e838 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 8 Sep 2024 21:43:21 +0900 Subject: kconfig: cache expression values Cache expression values to avoid recalculating them repeatedly. Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 2 ++ scripts/kconfig/expr.c | 34 ++++++++++++++++++++++++++++++---- scripts/kconfig/expr.h | 4 ++++ scripts/kconfig/internal.h | 2 ++ scripts/kconfig/symbol.c | 1 + 5 files changed, 39 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index d8849dfb06db..4286d5e7f95d 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -396,6 +396,8 @@ load: } } + expr_invalidate_all(); + while (getline_stripped(&line, &line_asize, in) != -1) { struct menu *choice; diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 476dcaa9078e..78738ef412de 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -887,7 +887,7 @@ static enum string_value_kind expr_parse_string(const char *str, ? kind : k_string; } -tristate expr_calc_value(struct expr *e) +static tristate __expr_calc_value(struct expr *e) { tristate val1, val2; const char *str1, *str2; @@ -895,9 +895,6 @@ tristate expr_calc_value(struct expr *e) union string_value lval = {}, rval = {}; int res; - if (!e) - return yes; - switch (e->type) { case E_SYMBOL: sym_calc_value(e->left.sym); @@ -961,6 +958,35 @@ tristate expr_calc_value(struct expr *e) } } +/** + * expr_calc_value - return the tristate value of the given expression + * @e: expression + * return: tristate value of the expression + */ +tristate expr_calc_value(struct expr *e) +{ + if (!e) + return yes; + + if (!e->val_is_valid) { + e->val = __expr_calc_value(e); + e->val_is_valid = true; + } + + return e->val; +} + +/** + * expr_invalidate_all - invalidate all cached expression values + */ +void expr_invalidate_all(void) +{ + struct expr *e; + + hash_for_each(expr_hashtable, e, node) + e->val_is_valid = false; +} + static int expr_compare_type(enum expr_type t1, enum expr_type t2) { if (t1 == t2) diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index a398b2b2dbe0..21578dcd4292 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -39,12 +39,16 @@ union expr_data { * * @node: link node for the hash table * @type: expressoin type + * @val: calculated tristate value + * @val_is_valid: indicate whether the value is valid * @left: left node * @right: right node */ struct expr { struct hlist_node node; enum expr_type type; + tristate val; + bool val_is_valid; union expr_data left, right; }; diff --git a/scripts/kconfig/internal.h b/scripts/kconfig/internal.h index 84c2ea0389fd..d0ffce2dfbba 100644 --- a/scripts/kconfig/internal.h +++ b/scripts/kconfig/internal.h @@ -15,6 +15,8 @@ extern HASHTABLE_DECLARE(sym_hashtable, SYMBOL_HASHSIZE); extern HASHTABLE_DECLARE(expr_hashtable, EXPR_HASHSIZE); +void expr_invalidate_all(void); + struct menu; extern struct menu *current_menu, *current_entry; diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 6243f0143ecf..a3af93aaaf32 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -519,6 +519,7 @@ void sym_clear_all_valid(void) for_all_symbols(sym) sym->flags &= ~SYMBOL_VALID; + expr_invalidate_all(); conf_set_changed(true); sym_calc_value(modules_sym); } -- cgit v1.2.3-70-g09d2 From cc6d281fcc7319babc6dde8f95a8b7feb1eeffd0 Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Sun, 8 Sep 2024 15:26:00 +0200 Subject: kbuild: remove append operation on cmd_ld_ko_o MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The append operation was introduced in commit b1a1a1a09b46 ("kbuild: lto: postpone objtool") when the command was created from two parts. In commit 850ded46c642 ("kbuild: Fix TRIM_UNUSED_KSYMS with LTO_CLANG") however the first part was removed again, making the append operation unnecessary. To keep this command definition aligned with all other command definitions, remove the append again. Signed-off-by: Thomas Weißschuh Signed-off-by: Masahiro Yamada --- scripts/Makefile.modfinal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 6b1b72257b29..1482884ec3ca 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -34,7 +34,7 @@ $(extmod_prefix).module-common.o: $(srctree)/scripts/module-common.c FORCE $(call if_changed_dep,cc_o_c) quiet_cmd_ld_ko_o = LD [M] $@ - cmd_ld_ko_o += \ + cmd_ld_ko_o = \ $(LD) -r $(KBUILD_LDFLAGS) \ $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ -T scripts/module.lds -o $@ $(filter %.o, $^) -- cgit v1.2.3-70-g09d2 From 300e6d4116f956b035281ec94297dc4dc8d4e1d3 Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Fri, 12 Jul 2024 09:11:14 +0200 Subject: sign-file,extract-cert: move common SSL helper functions to a header Couple error handling helpers are repeated in both tools, so move them to a common header. Signed-off-by: Jan Stancek Reviewed-by: Jarkko Sakkinen Tested-by: R Nageswara Sastry Reviewed-by: Neal Gompa Signed-off-by: Jarkko Sakkinen --- MAINTAINERS | 1 + certs/Makefile | 2 +- certs/extract-cert.c | 37 ++----------------------------------- scripts/sign-file.c | 37 ++----------------------------------- scripts/ssl-common.h | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 45 insertions(+), 71 deletions(-) create mode 100644 scripts/ssl-common.h (limited to 'scripts') diff --git a/MAINTAINERS b/MAINTAINERS index 9278c30ef1d5..23f902884855 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5204,6 +5204,7 @@ S: Maintained F: Documentation/admin-guide/module-signing.rst F: certs/ F: scripts/sign-file.c +F: scripts/ssl-common.h F: tools/certs/ CFAG12864B LCD DRIVER diff --git a/certs/Makefile b/certs/Makefile index 1094e3860c2a..f6fa4d8d75e0 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -84,5 +84,5 @@ targets += x509_revocation_list hostprogs := extract-cert -HOSTCFLAGS_extract-cert.o = $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /dev/null) +HOSTCFLAGS_extract-cert.o = $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /dev/null) -I$(srctree)/scripts HOSTLDLIBS_extract-cert = $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/null || echo -lcrypto) diff --git a/certs/extract-cert.c b/certs/extract-cert.c index 70e9ec89d87d..8e7ba9974a1f 100644 --- a/certs/extract-cert.c +++ b/certs/extract-cert.c @@ -23,6 +23,8 @@ #include #include +#include "ssl-common.h" + /* * OpenSSL 3.0 deprecates the OpenSSL's ENGINE API. * @@ -40,41 +42,6 @@ void format(void) exit(2); } -static void display_openssl_errors(int l) -{ - const char *file; - char buf[120]; - int e, line; - - if (ERR_peek_error() == 0) - return; - fprintf(stderr, "At main.c:%d:\n", l); - - while ((e = ERR_get_error_line(&file, &line))) { - ERR_error_string(e, buf); - fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line); - } -} - -static void drain_openssl_errors(void) -{ - const char *file; - int line; - - if (ERR_peek_error() == 0) - return; - while (ERR_get_error_line(&file, &line)) {} -} - -#define ERR(cond, fmt, ...) \ - do { \ - bool __cond = (cond); \ - display_openssl_errors(__LINE__); \ - if (__cond) { \ - err(1, fmt, ## __VA_ARGS__); \ - } \ - } while(0) - static const char *key_pass; static BIO *wb; static char *cert_dst; diff --git a/scripts/sign-file.c b/scripts/sign-file.c index 3edb156ae52c..39ba58db5d4e 100644 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c @@ -29,6 +29,8 @@ #include #include +#include "ssl-common.h" + /* * OpenSSL 3.0 deprecates the OpenSSL's ENGINE API. * @@ -83,41 +85,6 @@ void format(void) exit(2); } -static void display_openssl_errors(int l) -{ - const char *file; - char buf[120]; - int e, line; - - if (ERR_peek_error() == 0) - return; - fprintf(stderr, "At main.c:%d:\n", l); - - while ((e = ERR_get_error_line(&file, &line))) { - ERR_error_string(e, buf); - fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line); - } -} - -static void drain_openssl_errors(void) -{ - const char *file; - int line; - - if (ERR_peek_error() == 0) - return; - while (ERR_get_error_line(&file, &line)) {} -} - -#define ERR(cond, fmt, ...) \ - do { \ - bool __cond = (cond); \ - display_openssl_errors(__LINE__); \ - if (__cond) { \ - errx(1, fmt, ## __VA_ARGS__); \ - } \ - } while(0) - static const char *key_pass; static int pem_pw_cb(char *buf, int len, int w, void *v) diff --git a/scripts/ssl-common.h b/scripts/ssl-common.h new file mode 100644 index 000000000000..e6711c75ed91 --- /dev/null +++ b/scripts/ssl-common.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/* + * SSL helper functions shared by sign-file and extract-cert. + */ + +static void display_openssl_errors(int l) +{ + const char *file; + char buf[120]; + int e, line; + + if (ERR_peek_error() == 0) + return; + fprintf(stderr, "At main.c:%d:\n", l); + + while ((e = ERR_get_error_line(&file, &line))) { + ERR_error_string(e, buf); + fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line); + } +} + +static void drain_openssl_errors(void) +{ + const char *file; + int line; + + if (ERR_peek_error() == 0) + return; + while (ERR_get_error_line(&file, &line)) {} +} + +#define ERR(cond, fmt, ...) \ + do { \ + bool __cond = (cond); \ + display_openssl_errors(__LINE__); \ + if (__cond) { \ + errx(1, fmt, ## __VA_ARGS__); \ + } \ + } while (0) -- cgit v1.2.3-70-g09d2 From 467d60eddf55588add232feda325da7215ddaf30 Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Fri, 12 Jul 2024 09:11:15 +0200 Subject: sign-file,extract-cert: avoid using deprecated ERR_get_error_line() ERR_get_error_line() is deprecated since OpenSSL 3.0. Use ERR_peek_error_line() instead, and combine display_openssl_errors() and drain_openssl_errors() to a single function where parameter decides if it should consume errors silently. Signed-off-by: Jan Stancek Reviewed-by: Jarkko Sakkinen Tested-by: R Nageswara Sastry Reviewed-by: Neal Gompa Signed-off-by: Jarkko Sakkinen --- certs/extract-cert.c | 4 ++-- scripts/sign-file.c | 6 +++--- scripts/ssl-common.h | 23 ++++++++--------------- 3 files changed, 13 insertions(+), 20 deletions(-) (limited to 'scripts') diff --git a/certs/extract-cert.c b/certs/extract-cert.c index 8e7ba9974a1f..61bbe0085671 100644 --- a/certs/extract-cert.c +++ b/certs/extract-cert.c @@ -99,11 +99,11 @@ int main(int argc, char **argv) parms.cert = NULL; ENGINE_load_builtin_engines(); - drain_openssl_errors(); + drain_openssl_errors(__LINE__, 1); e = ENGINE_by_id("pkcs11"); ERR(!e, "Load PKCS#11 ENGINE"); if (ENGINE_init(e)) - drain_openssl_errors(); + drain_openssl_errors(__LINE__, 1); else ERR(1, "ENGINE_init"); if (key_pass) diff --git a/scripts/sign-file.c b/scripts/sign-file.c index 39ba58db5d4e..bb3fdf1a617c 100644 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c @@ -114,11 +114,11 @@ static EVP_PKEY *read_private_key(const char *private_key_name) ENGINE *e; ENGINE_load_builtin_engines(); - drain_openssl_errors(); + drain_openssl_errors(__LINE__, 1); e = ENGINE_by_id("pkcs11"); ERR(!e, "Load PKCS#11 ENGINE"); if (ENGINE_init(e)) - drain_openssl_errors(); + drain_openssl_errors(__LINE__, 1); else ERR(1, "ENGINE_init"); if (key_pass) @@ -273,7 +273,7 @@ int main(int argc, char **argv) /* Digest the module data. */ OpenSSL_add_all_digests(); - display_openssl_errors(__LINE__); + drain_openssl_errors(__LINE__, 0); digest_algo = EVP_get_digestbyname(hash_algo); ERR(!digest_algo, "EVP_get_digestbyname"); diff --git a/scripts/ssl-common.h b/scripts/ssl-common.h index e6711c75ed91..2db0e181143c 100644 --- a/scripts/ssl-common.h +++ b/scripts/ssl-common.h @@ -3,7 +3,7 @@ * SSL helper functions shared by sign-file and extract-cert. */ -static void display_openssl_errors(int l) +static void drain_openssl_errors(int l, int silent) { const char *file; char buf[120]; @@ -11,28 +11,21 @@ static void display_openssl_errors(int l) if (ERR_peek_error() == 0) return; - fprintf(stderr, "At main.c:%d:\n", l); + if (!silent) + fprintf(stderr, "At main.c:%d:\n", l); - while ((e = ERR_get_error_line(&file, &line))) { + while ((e = ERR_peek_error_line(&file, &line))) { ERR_error_string(e, buf); - fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line); + if (!silent) + fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line); + ERR_get_error(); } } -static void drain_openssl_errors(void) -{ - const char *file; - int line; - - if (ERR_peek_error() == 0) - return; - while (ERR_get_error_line(&file, &line)) {} -} - #define ERR(cond, fmt, ...) \ do { \ bool __cond = (cond); \ - display_openssl_errors(__LINE__); \ + drain_openssl_errors(__LINE__, 0); \ if (__cond) { \ errx(1, fmt, ## __VA_ARGS__); \ } \ -- cgit v1.2.3-70-g09d2 From 558bdc45dfb2669e1741384a0c80be9c82fa052c Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Fri, 20 Sep 2024 19:52:48 +0300 Subject: sign-file,extract-cert: use pkcs11 provider for OPENSSL MAJOR >= 3 ENGINE API has been deprecated since OpenSSL version 3.0 [1]. Distros have started dropping support from headers and in future it will likely disappear also from library. It has been superseded by the PROVIDER API, so use it instead for OPENSSL MAJOR >= 3. [1] https://github.com/openssl/openssl/blob/master/README-ENGINES.md [jarkko: fixed up alignment issues reported by checkpatch.pl --strict] Signed-off-by: Jan Stancek Reviewed-by: Jarkko Sakkinen Tested-by: R Nageswara Sastry Reviewed-by: Neal Gompa Signed-off-by: Jarkko Sakkinen --- certs/extract-cert.c | 103 ++++++++++++++++++++++++++++++++++++--------------- scripts/sign-file.c | 93 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 138 insertions(+), 58 deletions(-) (limited to 'scripts') diff --git a/certs/extract-cert.c b/certs/extract-cert.c index 61bbe0085671..7d6d468ed612 100644 --- a/certs/extract-cert.c +++ b/certs/extract-cert.c @@ -21,17 +21,18 @@ #include #include #include -#include - +#if OPENSSL_VERSION_MAJOR >= 3 +# define USE_PKCS11_PROVIDER +# include +# include +#else +# if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0) +# define USE_PKCS11_ENGINE +# include +# endif +#endif #include "ssl-common.h" -/* - * 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)) @@ -61,6 +62,66 @@ static void write_cert(X509 *x509) fprintf(stderr, "Extracted cert: %s\n", buf); } +static X509 *load_cert_pkcs11(const char *cert_src) +{ + X509 *cert = NULL; +#ifdef USE_PKCS11_PROVIDER + OSSL_STORE_CTX *store; + + if (!OSSL_PROVIDER_try_load(NULL, "pkcs11", true)) + ERR(1, "OSSL_PROVIDER_try_load(pkcs11)"); + if (!OSSL_PROVIDER_try_load(NULL, "default", true)) + ERR(1, "OSSL_PROVIDER_try_load(default)"); + + store = OSSL_STORE_open(cert_src, NULL, NULL, NULL, NULL); + ERR(!store, "OSSL_STORE_open"); + + while (!OSSL_STORE_eof(store)) { + OSSL_STORE_INFO *info = OSSL_STORE_load(store); + + if (!info) { + drain_openssl_errors(__LINE__, 0); + continue; + } + if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_CERT) { + cert = OSSL_STORE_INFO_get1_CERT(info); + ERR(!cert, "OSSL_STORE_INFO_get1_CERT"); + } + OSSL_STORE_INFO_free(info); + if (cert) + break; + } + OSSL_STORE_close(store); +#elif defined(USE_PKCS11_ENGINE) + ENGINE *e; + struct { + const char *cert_id; + X509 *cert; + } parms; + + parms.cert_id = cert_src; + parms.cert = NULL; + + ENGINE_load_builtin_engines(); + drain_openssl_errors(__LINE__, 1); + e = ENGINE_by_id("pkcs11"); + ERR(!e, "Load PKCS#11 ENGINE"); + if (ENGINE_init(e)) + drain_openssl_errors(__LINE__, 1); + else + ERR(1, "ENGINE_init"); + if (key_pass) + ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN"); + ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &parms, NULL, 1); + ERR(!parms.cert, "Get X.509 from PKCS#11"); + cert = parms.cert; +#else + fprintf(stderr, "no pkcs11 engine/provider available\n"); + exit(1); +#endif + return cert; +} + int main(int argc, char **argv) { char *cert_src; @@ -89,28 +150,10 @@ int main(int argc, char **argv) fclose(f); exit(0); } else if (!strncmp(cert_src, "pkcs11:", 7)) { - ENGINE *e; - struct { - const char *cert_id; - X509 *cert; - } parms; + X509 *cert = load_cert_pkcs11(cert_src); - parms.cert_id = cert_src; - parms.cert = NULL; - - ENGINE_load_builtin_engines(); - drain_openssl_errors(__LINE__, 1); - e = ENGINE_by_id("pkcs11"); - ERR(!e, "Load PKCS#11 ENGINE"); - if (ENGINE_init(e)) - drain_openssl_errors(__LINE__, 1); - else - ERR(1, "ENGINE_init"); - if (key_pass) - ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN"); - ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &parms, NULL, 1); - ERR(!parms.cert, "Get X.509 from PKCS#11"); - write_cert(parms.cert); + ERR(!cert, "load_cert_pkcs11 failed"); + write_cert(cert); } else { BIO *b; X509 *x509; diff --git a/scripts/sign-file.c b/scripts/sign-file.c index bb3fdf1a617c..7070245edfc1 100644 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c @@ -27,17 +27,18 @@ #include #include #include -#include - +#if OPENSSL_VERSION_MAJOR >= 3 +# define USE_PKCS11_PROVIDER +# include +# include +#else +# if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0) +# define USE_PKCS11_ENGINE +# include +# endif +#endif #include "ssl-common.h" -/* - * 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 @@ -106,28 +107,64 @@ static int pem_pw_cb(char *buf, int len, int w, void *v) return pwlen; } -static EVP_PKEY *read_private_key(const char *private_key_name) +static EVP_PKEY *read_private_key_pkcs11(const char *private_key_name) { - EVP_PKEY *private_key; + EVP_PKEY *private_key = NULL; +#ifdef USE_PKCS11_PROVIDER + OSSL_STORE_CTX *store; - if (!strncmp(private_key_name, "pkcs11:", 7)) { - ENGINE *e; + if (!OSSL_PROVIDER_try_load(NULL, "pkcs11", true)) + ERR(1, "OSSL_PROVIDER_try_load(pkcs11)"); + if (!OSSL_PROVIDER_try_load(NULL, "default", true)) + ERR(1, "OSSL_PROVIDER_try_load(default)"); + + store = OSSL_STORE_open(private_key_name, NULL, NULL, NULL, NULL); + ERR(!store, "OSSL_STORE_open"); - ENGINE_load_builtin_engines(); + while (!OSSL_STORE_eof(store)) { + OSSL_STORE_INFO *info = OSSL_STORE_load(store); + + if (!info) { + drain_openssl_errors(__LINE__, 0); + continue; + } + if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) { + private_key = OSSL_STORE_INFO_get1_PKEY(info); + ERR(!private_key, "OSSL_STORE_INFO_get1_PKEY"); + } + OSSL_STORE_INFO_free(info); + if (private_key) + break; + } + OSSL_STORE_close(store); +#elif defined(USE_PKCS11_ENGINE) + ENGINE *e; + + ENGINE_load_builtin_engines(); + drain_openssl_errors(__LINE__, 1); + e = ENGINE_by_id("pkcs11"); + ERR(!e, "Load PKCS#11 ENGINE"); + if (ENGINE_init(e)) drain_openssl_errors(__LINE__, 1); - e = ENGINE_by_id("pkcs11"); - ERR(!e, "Load PKCS#11 ENGINE"); - if (ENGINE_init(e)) - drain_openssl_errors(__LINE__, 1); - else - ERR(1, "ENGINE_init"); - if (key_pass) - ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), - "Set PKCS#11 PIN"); - private_key = ENGINE_load_private_key(e, private_key_name, - NULL, NULL); - ERR(!private_key, "%s", private_key_name); + else + ERR(1, "ENGINE_init"); + if (key_pass) + ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN"); + private_key = ENGINE_load_private_key(e, private_key_name, NULL, NULL); + ERR(!private_key, "%s", private_key_name); +#else + fprintf(stderr, "no pkcs11 engine/provider available\n"); + exit(1); +#endif + return private_key; +} + +static EVP_PKEY *read_private_key(const char *private_key_name) +{ + if (!strncmp(private_key_name, "pkcs11:", 7)) { + return read_private_key_pkcs11(private_key_name); } else { + EVP_PKEY *private_key; BIO *b; b = BIO_new_file(private_key_name, "rb"); @@ -136,9 +173,9 @@ static EVP_PKEY *read_private_key(const char *private_key_name) NULL); ERR(!private_key, "%s", private_key_name); BIO_free(b); - } - return private_key; + return private_key; + } } static X509 *read_x509(const char *x509_name) -- cgit v1.2.3-70-g09d2 From cb787f4ac0c2e439ea8d7e6387b925f74576bdf8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 27 Sep 2024 02:56:11 +0100 Subject: [tree-wide] finally take no_llseek out no_llseek had been defined to NULL two years ago, in commit 868941b14441 ("fs: remove no_llseek") To quote that commit, At -rc1 we'll need do a mechanical removal of no_llseek - git grep -l -w no_llseek | grep -v porting.rst | while read i; do sed -i '/\/d' $i done would do it. Unfortunately, that hadn't been done. Linus, could you do that now, so that we could finally put that thing to rest? All instances are of the form .llseek = no_llseek, so it's obviously safe. Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- Documentation/watchdog/convert_drivers_to_kernel_api.rst | 1 - arch/parisc/kernel/perf.c | 1 - arch/s390/hypfs/hypfs_dbfs.c | 1 - arch/s390/hypfs/inode.c | 1 - arch/s390/kernel/debug.c | 1 - arch/s390/kernel/perf_cpum_cf.c | 1 - arch/s390/kernel/sysinfo.c | 1 - arch/s390/pci/pci_clp.c | 1 - arch/um/drivers/harddog_kern.c | 1 - arch/um/drivers/hostaudio_kern.c | 2 -- arch/x86/kernel/cpu/mce/dev-mcelog.c | 1 - arch/x86/kernel/cpu/resctrl/pseudo_lock.c | 1 - drivers/acpi/apei/erst-dbg.c | 1 - drivers/auxdisplay/charlcd.c | 1 - drivers/block/mtip32xx/mtip32xx.c | 2 -- drivers/block/pktcdvd.c | 1 - drivers/block/ublk_drv.c | 1 - drivers/bluetooth/hci_vhci.c | 1 - drivers/bus/moxtet.c | 2 -- drivers/char/applicom.c | 1 - drivers/char/ds1620.c | 1 - drivers/char/dtlk.c | 1 - drivers/char/hpet.c | 1 - drivers/char/ipmi/ipmi_watchdog.c | 1 - drivers/char/pc8736x_gpio.c | 1 - drivers/char/ppdev.c | 1 - drivers/char/scx200_gpio.c | 1 - drivers/char/sonypi.c | 1 - drivers/char/tpm/tpm-dev.c | 1 - drivers/char/tpm/tpm_vtpm_proxy.c | 1 - drivers/char/tpm/tpmrm-dev.c | 1 - drivers/char/virtio_console.c | 1 - drivers/counter/counter-chrdev.c | 1 - drivers/firewire/core-cdev.c | 1 - drivers/firmware/arm_scmi/driver.c | 1 - drivers/firmware/arm_scmi/raw_mode.c | 5 ----- drivers/firmware/efi/capsule-loader.c | 1 - drivers/firmware/efi/test/efi_test.c | 1 - drivers/firmware/turris-mox-rwtm.c | 1 - drivers/gnss/core.c | 1 - drivers/gpio/gpio-mockup.c | 1 - drivers/gpio/gpio-sloppy-logic-analyzer.c | 1 - drivers/gpio/gpiolib-cdev.c | 1 - drivers/gpu/drm/drm_file.c | 1 - drivers/gpu/drm/i915/i915_perf.c | 1 - drivers/gpu/drm/msm/msm_perf.c | 1 - drivers/gpu/drm/msm/msm_rd.c | 1 - drivers/gpu/drm/xe/xe_oa.c | 1 - drivers/hid/uhid.c | 1 - drivers/hwmon/asus_atk0110.c | 1 - drivers/hwmon/fschmd.c | 1 - drivers/hwmon/w83793.c | 1 - drivers/hwtracing/coresight/coresight-etb10.c | 1 - drivers/hwtracing/coresight/coresight-tmc-core.c | 1 - drivers/hwtracing/coresight/ultrasoc-smb.c | 1 - drivers/hwtracing/intel_th/msu.c | 1 - drivers/hwtracing/stm/core.c | 1 - drivers/i2c/i2c-dev.c | 1 - drivers/infiniband/core/ucma.c | 1 - drivers/infiniband/core/user_mad.c | 2 -- drivers/infiniband/core/uverbs_main.c | 4 ---- drivers/infiniband/hw/hfi1/fault.c | 1 - drivers/infiniband/hw/mlx5/devx.c | 2 -- drivers/input/evdev.c | 1 - drivers/input/joydev.c | 1 - drivers/input/keyboard/applespi.c | 1 - drivers/input/misc/uinput.c | 1 - drivers/input/serio/userio.c | 1 - drivers/iommu/iommufd/fault.c | 1 - drivers/isdn/capi/capi.c | 1 - drivers/isdn/mISDN/timerdev.c | 1 - drivers/leds/uleds.c | 1 - drivers/macintosh/adb.c | 1 - drivers/macintosh/smu.c | 1 - drivers/media/cec/core/cec-api.c | 1 - drivers/media/mc/mc-devnode.c | 1 - drivers/media/rc/lirc_dev.c | 1 - drivers/media/usb/uvc/uvc_debugfs.c | 1 - drivers/media/v4l2-core/v4l2-dev.c | 1 - drivers/message/fusion/mptctl.c | 1 - drivers/misc/lis3lv02d/lis3lv02d.c | 1 - drivers/misc/mei/main.c | 1 - drivers/misc/ntsync.c | 2 -- drivers/misc/phantom.c | 1 - drivers/mmc/core/block.c | 1 - drivers/mtd/ubi/cdev.c | 2 -- drivers/mtd/ubi/debug.c | 1 - drivers/net/netdevsim/fib.c | 1 - drivers/net/tap.c | 1 - drivers/net/tun.c | 1 - drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 1 - drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 1 - drivers/platform/chrome/cros_ec_debugfs.c | 1 - drivers/platform/chrome/wilco_ec/debugfs.c | 1 - drivers/platform/chrome/wilco_ec/event.c | 1 - drivers/platform/chrome/wilco_ec/telemetry.c | 1 - drivers/platform/surface/surface_aggregator_cdev.c | 1 - drivers/platform/surface/surface_dtx.c | 1 - drivers/pps/pps.c | 1 - drivers/rtc/dev.c | 1 - drivers/rtc/rtc-m41t80.c | 1 - drivers/s390/char/fs3270.c | 1 - drivers/s390/char/sclp_ctl.c | 1 - drivers/s390/char/tape_char.c | 1 - drivers/s390/char/uvdevice.c | 1 - drivers/s390/char/vmcp.c | 1 - drivers/s390/char/vmlogrdr.c | 1 - drivers/s390/char/zcore.c | 2 -- drivers/s390/cio/chsc_sch.c | 1 - drivers/s390/cio/css.c | 1 - drivers/s390/crypto/pkey_api.c | 1 - drivers/s390/crypto/zcrypt_api.c | 1 - drivers/sbus/char/openprom.c | 1 - drivers/sbus/char/uctrl.c | 1 - drivers/scsi/sg.c | 1 - drivers/spi/spidev.c | 1 - drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c | 1 - drivers/tty/tty_io.c | 3 --- drivers/usb/gadget/function/f_fs.c | 2 -- drivers/usb/gadget/legacy/inode.c | 2 -- drivers/usb/gadget/legacy/raw_gadget.c | 1 - drivers/usb/gadget/udc/atmel_usba_udc.c | 1 - drivers/usb/misc/ldusb.c | 1 - drivers/usb/mon/mon_bin.c | 1 - drivers/usb/mon/mon_stat.c | 1 - drivers/usb/mon/mon_text.c | 2 -- drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 2 -- drivers/vfio/pci/mlx5/main.c | 2 -- drivers/vfio/pci/pds/lm.c | 2 -- drivers/vfio/pci/qat/main.c | 2 -- drivers/virt/coco/tdx-guest/tdx-guest.c | 1 - drivers/watchdog/acquirewdt.c | 1 - drivers/watchdog/advantechwdt.c | 1 - drivers/watchdog/alim1535_wdt.c | 1 - drivers/watchdog/alim7101_wdt.c | 1 - drivers/watchdog/at91rm9200_wdt.c | 1 - drivers/watchdog/ath79_wdt.c | 1 - drivers/watchdog/cpu5wdt.c | 1 - drivers/watchdog/cpwd.c | 1 - drivers/watchdog/eurotechwdt.c | 1 - drivers/watchdog/gef_wdt.c | 1 - drivers/watchdog/geodewdt.c | 1 - drivers/watchdog/ib700wdt.c | 1 - drivers/watchdog/ibmasr.c | 1 - drivers/watchdog/indydog.c | 1 - drivers/watchdog/it8712f_wdt.c | 1 - drivers/watchdog/m54xx_wdt.c | 1 - drivers/watchdog/machzwd.c | 1 - drivers/watchdog/mixcomwd.c | 1 - drivers/watchdog/mtx-1_wdt.c | 1 - drivers/watchdog/nv_tco.c | 1 - drivers/watchdog/pc87413_wdt.c | 1 - drivers/watchdog/pcwd.c | 2 -- drivers/watchdog/pcwd_pci.c | 2 -- drivers/watchdog/pcwd_usb.c | 2 -- drivers/watchdog/pika_wdt.c | 1 - drivers/watchdog/rc32434_wdt.c | 1 - drivers/watchdog/rdc321x_wdt.c | 1 - drivers/watchdog/riowd.c | 1 - drivers/watchdog/sa1100_wdt.c | 1 - drivers/watchdog/sb_wdog.c | 1 - drivers/watchdog/sbc60xxwdt.c | 1 - drivers/watchdog/sbc7240_wdt.c | 1 - drivers/watchdog/sbc8360.c | 1 - drivers/watchdog/sbc_epx_c3.c | 1 - drivers/watchdog/sbc_fitpc2_wdt.c | 1 - drivers/watchdog/sc1200wdt.c | 1 - drivers/watchdog/sc520_wdt.c | 1 - drivers/watchdog/sch311x_wdt.c | 1 - drivers/watchdog/scx200_wdt.c | 1 - drivers/watchdog/smsc37b787_wdt.c | 1 - drivers/watchdog/w83877f_wdt.c | 1 - drivers/watchdog/w83977f_wdt.c | 1 - drivers/watchdog/wafer5823wdt.c | 1 - drivers/watchdog/wdrtas.c | 2 -- drivers/watchdog/wdt.c | 2 -- drivers/watchdog/wdt285.c | 1 - drivers/watchdog/wdt977.c | 1 - drivers/watchdog/wdt_pci.c | 2 -- drivers/xen/evtchn.c | 1 - drivers/xen/mcelog.c | 1 - drivers/xen/xenbus/xenbus_dev_frontend.c | 1 - fs/bcachefs/chardev.c | 1 - fs/bcachefs/thread_with_file.c | 2 -- fs/debugfs/file.c | 1 - fs/dlm/debug_fs.c | 1 - fs/efivarfs/file.c | 1 - fs/fsopen.c | 1 - fs/fuse/control.c | 4 ---- fs/fuse/dev.c | 1 - fs/nsfs.c | 1 - fs/pipe.c | 1 - fs/ubifs/debug.c | 2 -- include/linux/debugfs.h | 1 - include/linux/fs.h | 1 - kernel/bpf/bpf_iter.c | 1 - kernel/events/core.c | 1 - kernel/power/user.c | 1 - kernel/relay.c | 1 - kernel/time/posix-clock.c | 1 - kernel/trace/rv/rv.c | 3 --- kernel/trace/rv/rv_reactors.c | 1 - kernel/trace/trace.c | 3 --- mm/huge_memory.c | 1 - net/mac80211/rc80211_minstrel_ht_debugfs.c | 2 -- net/rfkill/core.c | 1 - net/socket.c | 1 - net/sunrpc/cache.c | 4 ---- net/sunrpc/rpc_pipe.c | 1 - samples/vfio-mdev/mtty.c | 2 -- scripts/coccinelle/api/stream_open.cocci | 1 - sound/core/control.c | 1 - sound/core/oss/mixer_oss.c | 1 - sound/core/oss/pcm_oss.c | 1 - sound/core/pcm_native.c | 2 -- sound/core/rawmidi.c | 1 - sound/core/seq/seq_clientmgr.c | 1 - sound/core/timer.c | 1 - sound/oss/dmasound/dmasound_core.c | 3 --- sound/soc/intel/avs/debugfs.c | 3 --- virt/kvm/kvm_main.c | 1 - 221 files changed, 270 deletions(-) (limited to 'scripts') diff --git a/Documentation/watchdog/convert_drivers_to_kernel_api.rst b/Documentation/watchdog/convert_drivers_to_kernel_api.rst index a1c3f038ce0e..e83609a5d007 100644 --- a/Documentation/watchdog/convert_drivers_to_kernel_api.rst +++ b/Documentation/watchdog/convert_drivers_to_kernel_api.rst @@ -75,7 +75,6 @@ Example conversion:: -static const struct file_operations s3c2410wdt_fops = { - .owner = THIS_MODULE, - - .llseek = no_llseek, - .write = s3c2410wdt_write, - .unlocked_ioctl = s3c2410wdt_ioctl, - .open = s3c2410wdt_open, diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c index b0f0816879df..5e8e37a722ef 100644 --- a/arch/parisc/kernel/perf.c +++ b/arch/parisc/kernel/perf.c @@ -466,7 +466,6 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } static const struct file_operations perf_fops = { - .llseek = no_llseek, .read = perf_read, .write = perf_write, .unlocked_ioctl = perf_ioctl, diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c index 0e855c5e91c5..5d9effb0867c 100644 --- a/arch/s390/hypfs/hypfs_dbfs.c +++ b/arch/s390/hypfs/hypfs_dbfs.c @@ -76,7 +76,6 @@ static long dbfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static const struct file_operations dbfs_ops = { .read = dbfs_read, - .llseek = no_llseek, .unlocked_ioctl = dbfs_ioctl, }; diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index 858beaf4a8cb..d428635abf08 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -443,7 +443,6 @@ static const struct file_operations hypfs_file_ops = { .release = hypfs_release, .read_iter = hypfs_read_iter, .write_iter = hypfs_write_iter, - .llseek = no_llseek, }; static struct file_system_type hypfs_type = { diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index bce50ca75ea7..e62bea9ab21e 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -163,7 +163,6 @@ static const struct file_operations debug_file_ops = { .write = debug_input, .open = debug_open, .release = debug_close, - .llseek = no_llseek, }; static struct dentry *debug_debugfs_root_entry; diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c index 18b0d025f3a2..e2e0aa463fbd 100644 --- a/arch/s390/kernel/perf_cpum_cf.c +++ b/arch/s390/kernel/perf_cpum_cf.c @@ -1698,7 +1698,6 @@ static const struct file_operations cfset_fops = { .release = cfset_release, .unlocked_ioctl = cfset_ioctl, .compat_ioctl = cfset_ioctl, - .llseek = no_llseek }; static struct miscdevice cfset_dev = { diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c index 2be30a96696a..88055f58fbda 100644 --- a/arch/s390/kernel/sysinfo.c +++ b/arch/s390/kernel/sysinfo.c @@ -498,7 +498,6 @@ static const struct file_operations stsi_##fc##_##s1##_##s2##_fs_ops = { \ .open = stsi_open_##fc##_##s1##_##s2, \ .release = stsi_release, \ .read = stsi_read, \ - .llseek = no_llseek, \ }; static int stsi_release(struct inode *inode, struct file *file) diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index ee90a91ed888..6f55a59a0871 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c @@ -657,7 +657,6 @@ static const struct file_operations clp_misc_fops = { .release = clp_misc_release, .unlocked_ioctl = clp_misc_ioctl, .compat_ioctl = clp_misc_ioctl, - .llseek = no_llseek, }; static struct miscdevice clp_misc_device = { diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c index 99a7144b229f..819aabb4ecdc 100644 --- a/arch/um/drivers/harddog_kern.c +++ b/arch/um/drivers/harddog_kern.c @@ -164,7 +164,6 @@ static const struct file_operations harddog_fops = { .compat_ioctl = compat_ptr_ioctl, .open = harddog_open, .release = harddog_release, - .llseek = no_llseek, }; static struct miscdevice harddog_miscdev = { diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index c42b793bce65..9d228878cea2 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c @@ -291,7 +291,6 @@ static int hostmixer_release(struct inode *inode, struct file *file) static const struct file_operations hostaudio_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = hostaudio_read, .write = hostaudio_write, .poll = hostaudio_poll, @@ -304,7 +303,6 @@ static const struct file_operations hostaudio_fops = { static const struct file_operations hostmixer_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .unlocked_ioctl = hostmixer_ioctl_mixdev, .open = hostmixer_open_mixdev, .release = hostmixer_release, diff --git a/arch/x86/kernel/cpu/mce/dev-mcelog.c b/arch/x86/kernel/cpu/mce/dev-mcelog.c index a3aa0199222e..af44fd5dbd7c 100644 --- a/arch/x86/kernel/cpu/mce/dev-mcelog.c +++ b/arch/x86/kernel/cpu/mce/dev-mcelog.c @@ -331,7 +331,6 @@ static const struct file_operations mce_chrdev_ops = { .poll = mce_chrdev_poll, .unlocked_ioctl = mce_chrdev_ioctl, .compat_ioctl = compat_ptr_ioctl, - .llseek = no_llseek, }; static struct miscdevice mce_chrdev_device = { diff --git a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c index e69489d48625..972e6b6b0481 100644 --- a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c +++ b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c @@ -1567,7 +1567,6 @@ static int pseudo_lock_dev_mmap(struct file *filp, struct vm_area_struct *vma) static const struct file_operations pseudo_lock_dev_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = NULL, .write = NULL, .open = pseudo_lock_dev_open, diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c index 8bc71cdc2270..246076341e8c 100644 --- a/drivers/acpi/apei/erst-dbg.c +++ b/drivers/acpi/apei/erst-dbg.c @@ -199,7 +199,6 @@ static const struct file_operations erst_dbg_ops = { .read = erst_dbg_read, .write = erst_dbg_write, .unlocked_ioctl = erst_dbg_ioctl, - .llseek = no_llseek, }; static struct miscdevice erst_dbg_dev = { diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c index bb9463814454..19b619376d48 100644 --- a/drivers/auxdisplay/charlcd.c +++ b/drivers/auxdisplay/charlcd.c @@ -526,7 +526,6 @@ static const struct file_operations charlcd_fops = { .write = charlcd_write, .open = charlcd_open, .release = charlcd_release, - .llseek = no_llseek, }; static struct miscdevice charlcd_dev = { diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 11901f2812ad..223faa9d5ffd 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -2259,14 +2259,12 @@ static const struct file_operations mtip_regs_fops = { .owner = THIS_MODULE, .open = simple_open, .read = mtip_hw_read_registers, - .llseek = no_llseek, }; static const struct file_operations mtip_flags_fops = { .owner = THIS_MODULE, .open = simple_open, .read = mtip_hw_read_flags, - .llseek = no_llseek, }; static void mtip_hw_debugfs_init(struct driver_data *dd) diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 3edb37a41312..499c110465e3 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -2835,7 +2835,6 @@ static const struct file_operations pkt_ctl_fops = { .compat_ioctl = pkt_ctl_compat_ioctl, #endif .owner = THIS_MODULE, - .llseek = no_llseek, }; static struct miscdevice pkt_misc = { diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index bca06bfb4bc3..a6c8e5cc6051 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -1983,7 +1983,6 @@ static const struct file_operations ublk_ch_fops = { .owner = THIS_MODULE, .open = ublk_ch_open, .release = ublk_ch_release, - .llseek = no_llseek, .read_iter = ublk_ch_read_iter, .write_iter = ublk_ch_write_iter, .uring_cmd = ublk_ch_uring_cmd, diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 43e9ac5a3324..aa6af351d02d 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -679,7 +679,6 @@ static const struct file_operations vhci_fops = { .poll = vhci_poll, .open = vhci_open, .release = vhci_release, - .llseek = no_llseek, }; static struct miscdevice vhci_miscdev = { diff --git a/drivers/bus/moxtet.c b/drivers/bus/moxtet.c index 8412406c4f1d..6276551d7968 100644 --- a/drivers/bus/moxtet.c +++ b/drivers/bus/moxtet.c @@ -484,7 +484,6 @@ static const struct file_operations input_fops = { .owner = THIS_MODULE, .open = moxtet_debug_open, .read = input_read, - .llseek = no_llseek, }; static ssize_t output_read(struct file *file, char __user *buf, size_t len, @@ -549,7 +548,6 @@ static const struct file_operations output_fops = { .open = moxtet_debug_open, .read = output_read, .write = output_write, - .llseek = no_llseek, }; static int moxtet_register_debugfs(struct moxtet *moxtet) diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index 69314532f38c..9fed9706d9cd 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c @@ -111,7 +111,6 @@ static irqreturn_t ac_interrupt(int, void *); static const struct file_operations ac_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = ac_read, .write = ac_write, .unlocked_ioctl = ac_ioctl, diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c index a4f4291b4492..44a1cdbd4bfb 100644 --- a/drivers/char/ds1620.c +++ b/drivers/char/ds1620.c @@ -353,7 +353,6 @@ static const struct file_operations ds1620_fops = { .open = ds1620_open, .read = ds1620_read, .unlocked_ioctl = ds1620_unlocked_ioctl, - .llseek = no_llseek, }; static struct miscdevice ds1620_miscdev = { diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index 5a1a73310e97..27f5f9d19531 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c @@ -107,7 +107,6 @@ static const struct file_operations dtlk_fops = .unlocked_ioctl = dtlk_ioctl, .open = dtlk_open, .release = dtlk_release, - .llseek = no_llseek, }; /* local prototypes */ diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 3dadc4accee3..e904e476e49a 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -700,7 +700,6 @@ hpet_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static const struct file_operations hpet_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = hpet_read, .poll = hpet_poll, .unlocked_ioctl = hpet_ioctl, diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 9a459257489f..335eea80054e 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -903,7 +903,6 @@ static const struct file_operations ipmi_wdog_fops = { .open = ipmi_open, .release = ipmi_close, .fasync = ipmi_fasync, - .llseek = no_llseek, }; static struct miscdevice ipmi_wdog_miscdev = { diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index c39a836ebd15..5f4696813cea 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c @@ -235,7 +235,6 @@ static const struct file_operations pc8736x_gpio_fileops = { .open = pc8736x_gpio_open, .write = nsc_gpio_write, .read = nsc_gpio_read, - .llseek = no_llseek, }; static void __init pc8736x_init_shadow(void) diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index eaff98dbaa8c..d1dfbd8d4d42 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -786,7 +786,6 @@ static const struct class ppdev_class = { static const struct file_operations pp_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = pp_read, .write = pp_write, .poll = pp_poll, diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c index 9f701dcba95c..700e6affea6f 100644 --- a/drivers/char/scx200_gpio.c +++ b/drivers/char/scx200_gpio.c @@ -68,7 +68,6 @@ static const struct file_operations scx200_gpio_fileops = { .read = nsc_gpio_read, .open = scx200_gpio_open, .release = scx200_gpio_release, - .llseek = no_llseek, }; static struct cdev scx200_gpio_cdev; /* use 1 cdev for all pins */ diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index bb5115b1736a..0f8185e541ed 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -1054,7 +1054,6 @@ static const struct file_operations sonypi_misc_fops = { .release = sonypi_misc_release, .fasync = sonypi_misc_fasync, .unlocked_ioctl = sonypi_misc_ioctl, - .llseek = no_llseek, }; static struct miscdevice sonypi_misc_device = { diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c index e2c0baa69fef..97c94b5e9340 100644 --- a/drivers/char/tpm/tpm-dev.c +++ b/drivers/char/tpm/tpm-dev.c @@ -59,7 +59,6 @@ static int tpm_release(struct inode *inode, struct file *file) const struct file_operations tpm_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .open = tpm_open, .read = tpm_common_read, .write = tpm_common_write, diff --git a/drivers/char/tpm/tpm_vtpm_proxy.c b/drivers/char/tpm/tpm_vtpm_proxy.c index 11c502039faf..8fe4a01eea12 100644 --- a/drivers/char/tpm/tpm_vtpm_proxy.c +++ b/drivers/char/tpm/tpm_vtpm_proxy.c @@ -243,7 +243,6 @@ static int vtpm_proxy_fops_release(struct inode *inode, struct file *filp) static const struct file_operations vtpm_proxy_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = vtpm_proxy_fops_read, .write = vtpm_proxy_fops_write, .poll = vtpm_proxy_fops_poll, diff --git a/drivers/char/tpm/tpmrm-dev.c b/drivers/char/tpm/tpmrm-dev.c index eef0fb06ea83..c25df7ea064e 100644 --- a/drivers/char/tpm/tpmrm-dev.c +++ b/drivers/char/tpm/tpmrm-dev.c @@ -46,7 +46,6 @@ static int tpmrm_release(struct inode *inode, struct file *file) const struct file_operations tpmrm_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .open = tpmrm_open, .read = tpm_common_read, .write = tpm_common_write, diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index de7d720d99fa..99a7f2441e70 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1093,7 +1093,6 @@ static const struct file_operations port_fops = { .poll = port_fops_poll, .release = port_fops_release, .fasync = port_fops_fasync, - .llseek = no_llseek, }; /* diff --git a/drivers/counter/counter-chrdev.c b/drivers/counter/counter-chrdev.c index afc94d0062b1..3ee75e1a78cd 100644 --- a/drivers/counter/counter-chrdev.c +++ b/drivers/counter/counter-chrdev.c @@ -454,7 +454,6 @@ out_unlock: static const struct file_operations counter_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = counter_chrdev_read, .poll = counter_chrdev_poll, .unlocked_ioctl = counter_chrdev_ioctl, diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 518eaa073b2b..b360dca2c69e 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -1911,7 +1911,6 @@ static __poll_t fw_device_op_poll(struct file *file, poll_table * pt) const struct file_operations fw_device_ops = { .owner = THIS_MODULE, - .llseek = no_llseek, .open = fw_device_op_open, .read = fw_device_op_read, .unlocked_ioctl = fw_device_op_ioctl, diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 69c15135371c..88c5c4ff4bb6 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -2886,7 +2886,6 @@ static ssize_t reset_all_on_write(struct file *filp, const char __user *buf, static const struct file_operations fops_reset_counts = { .owner = THIS_MODULE, .open = simple_open, - .llseek = no_llseek, .write = reset_all_on_write, }; diff --git a/drivers/firmware/arm_scmi/raw_mode.c b/drivers/firmware/arm_scmi/raw_mode.c index 130d13e9cd6b..9e89a6a763da 100644 --- a/drivers/firmware/arm_scmi/raw_mode.c +++ b/drivers/firmware/arm_scmi/raw_mode.c @@ -950,7 +950,6 @@ static const struct file_operations scmi_dbg_raw_mode_reset_fops = { .open = scmi_dbg_raw_mode_open, .release = scmi_dbg_raw_mode_release, .write = scmi_dbg_raw_mode_reset_write, - .llseek = no_llseek, .owner = THIS_MODULE, }; @@ -960,7 +959,6 @@ static const struct file_operations scmi_dbg_raw_mode_message_fops = { .read = scmi_dbg_raw_mode_message_read, .write = scmi_dbg_raw_mode_message_write, .poll = scmi_dbg_raw_mode_message_poll, - .llseek = no_llseek, .owner = THIS_MODULE, }; @@ -977,7 +975,6 @@ static const struct file_operations scmi_dbg_raw_mode_message_async_fops = { .read = scmi_dbg_raw_mode_message_read, .write = scmi_dbg_raw_mode_message_async_write, .poll = scmi_dbg_raw_mode_message_poll, - .llseek = no_llseek, .owner = THIS_MODULE, }; @@ -1001,7 +998,6 @@ static const struct file_operations scmi_dbg_raw_mode_notification_fops = { .release = scmi_dbg_raw_mode_release, .read = scmi_test_dbg_raw_mode_notif_read, .poll = scmi_test_dbg_raw_mode_notif_poll, - .llseek = no_llseek, .owner = THIS_MODULE, }; @@ -1025,7 +1021,6 @@ static const struct file_operations scmi_dbg_raw_mode_errors_fops = { .release = scmi_dbg_raw_mode_release, .read = scmi_test_dbg_raw_mode_errors_read, .poll = scmi_test_dbg_raw_mode_errors_poll, - .llseek = no_llseek, .owner = THIS_MODULE, }; diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c index 97bafb5f7038..0c17bdd388e1 100644 --- a/drivers/firmware/efi/capsule-loader.c +++ b/drivers/firmware/efi/capsule-loader.c @@ -309,7 +309,6 @@ static const struct file_operations efi_capsule_fops = { .open = efi_capsule_open, .write = efi_capsule_write, .release = efi_capsule_release, - .llseek = no_llseek, }; static struct miscdevice efi_capsule_misc = { diff --git a/drivers/firmware/efi/test/efi_test.c b/drivers/firmware/efi/test/efi_test.c index 47d67bb0a516..9e2628728aad 100644 --- a/drivers/firmware/efi/test/efi_test.c +++ b/drivers/firmware/efi/test/efi_test.c @@ -750,7 +750,6 @@ static const struct file_operations efi_test_fops = { .unlocked_ioctl = efi_test_ioctl, .open = efi_test_open, .release = efi_test_close, - .llseek = no_llseek, }; static struct miscdevice efi_test_dev = { diff --git a/drivers/firmware/turris-mox-rwtm.c b/drivers/firmware/turris-mox-rwtm.c index 525ebdc7ded5..f3bc0d427825 100644 --- a/drivers/firmware/turris-mox-rwtm.c +++ b/drivers/firmware/turris-mox-rwtm.c @@ -386,7 +386,6 @@ static const struct file_operations do_sign_fops = { .open = rwtm_debug_open, .read = do_sign_read, .write = do_sign_write, - .llseek = no_llseek, }; static void rwtm_debugfs_release(void *root) diff --git a/drivers/gnss/core.c b/drivers/gnss/core.c index 48f2ee0f78c4..883ef86ad3fc 100644 --- a/drivers/gnss/core.c +++ b/drivers/gnss/core.c @@ -206,7 +206,6 @@ static const struct file_operations gnss_fops = { .read = gnss_read, .write = gnss_write, .poll = gnss_poll, - .llseek = no_llseek, }; static struct class *gnss_class; diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c index 455eecf6380e..d39c6618bade 100644 --- a/drivers/gpio/gpio-mockup.c +++ b/drivers/gpio/gpio-mockup.c @@ -347,7 +347,6 @@ static const struct file_operations gpio_mockup_debugfs_ops = { .open = gpio_mockup_debugfs_open, .read = gpio_mockup_debugfs_read, .write = gpio_mockup_debugfs_write, - .llseek = no_llseek, .release = single_release, }; diff --git a/drivers/gpio/gpio-sloppy-logic-analyzer.c b/drivers/gpio/gpio-sloppy-logic-analyzer.c index aed6d1f6cfc3..07e0d7180579 100644 --- a/drivers/gpio/gpio-sloppy-logic-analyzer.c +++ b/drivers/gpio/gpio-sloppy-logic-analyzer.c @@ -217,7 +217,6 @@ static const struct file_operations fops_trigger = { .owner = THIS_MODULE, .open = trigger_open, .write = trigger_write, - .llseek = no_llseek, .release = single_release, }; diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 5aac59de0d76..78c9d9ed3d68 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -2842,7 +2842,6 @@ static const struct file_operations gpio_fileops = { .poll = lineinfo_watch_poll, .read = lineinfo_watch_read, .owner = THIS_MODULE, - .llseek = no_llseek, .unlocked_ioctl = gpio_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = gpio_ioctl_compat, diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index 07e493d14d0c..ad1dc638c83b 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -103,7 +103,6 @@ bool drm_dev_needs_global_mutex(struct drm_device *dev) * .compat_ioctl = drm_compat_ioctl, // NULL if CONFIG_COMPAT=n * .poll = drm_poll, * .read = drm_read, - * .llseek = no_llseek, * .mmap = drm_gem_mmap, * }; * diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 025a79fe5920..2406cda75b7b 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -3751,7 +3751,6 @@ static int i915_perf_release(struct inode *inode, struct file *file) static const struct file_operations fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .release = i915_perf_release, .poll = i915_perf_poll, .read = i915_perf_read, diff --git a/drivers/gpu/drm/msm/msm_perf.c b/drivers/gpu/drm/msm/msm_perf.c index 3d3da79fec2a..d3c7889aaf26 100644 --- a/drivers/gpu/drm/msm/msm_perf.c +++ b/drivers/gpu/drm/msm/msm_perf.c @@ -192,7 +192,6 @@ static const struct file_operations perf_debugfs_fops = { .owner = THIS_MODULE, .open = perf_open, .read = perf_read, - .llseek = no_llseek, .release = perf_release, }; diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c index ca44fd291c5b..39138e190cb9 100644 --- a/drivers/gpu/drm/msm/msm_rd.c +++ b/drivers/gpu/drm/msm/msm_rd.c @@ -227,7 +227,6 @@ static const struct file_operations rd_debugfs_fops = { .owner = THIS_MODULE, .open = rd_open, .read = rd_read, - .llseek = no_llseek, .release = rd_release, }; diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index 0369cc016f6a..eae38a49ee8e 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -1263,7 +1263,6 @@ static int xe_oa_mmap(struct file *file, struct vm_area_struct *vma) static const struct file_operations xe_oa_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .release = xe_oa_release, .poll = xe_oa_poll, .read = xe_oa_read, diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index a54c7995b9be..21a70420151e 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -803,7 +803,6 @@ static const struct file_operations uhid_fops = { .read = uhid_char_read, .write = uhid_char_write, .poll = uhid_char_poll, - .llseek = no_llseek, }; static struct miscdevice uhid_misc = { diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 3751c1e3eddd..1dc7e24fe4c5 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -783,7 +783,6 @@ static const struct file_operations atk_debugfs_ggrp_fops = { .read = atk_debugfs_ggrp_read, .open = atk_debugfs_ggrp_open, .release = atk_debugfs_ggrp_release, - .llseek = no_llseek, }; static void atk_debugfs_init(struct atk_data *data) diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index 1811f84d835e..a303959879ef 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c @@ -948,7 +948,6 @@ static long watchdog_ioctl(struct file *filp, unsigned int cmd, static const struct file_operations watchdog_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .open = watchdog_open, .release = watchdog_release, .write = watchdog_write, diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 0acf6bd0227f..67728f60333f 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -1451,7 +1451,6 @@ static long watchdog_ioctl(struct file *filp, unsigned int cmd, static const struct file_operations watchdog_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .open = watchdog_open, .release = watchdog_close, .write = watchdog_write, diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index 7edd3f1d0d46..aea9ac9c4bd0 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -652,7 +652,6 @@ static const struct file_operations etb_fops = { .open = etb_open, .read = etb_read, .release = etb_release, - .llseek = no_llseek, }; static struct attribute *coresight_etb_mgmt_attrs[] = { diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c index b54562f392f3..3a482fd2cb22 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-core.c +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c @@ -220,7 +220,6 @@ static const struct file_operations tmc_fops = { .open = tmc_open, .read = tmc_read, .release = tmc_release, - .llseek = no_llseek, }; static enum tmc_mem_intf_width tmc_get_memwidth(u32 devid) diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c index f9ebf20c91e6..ef7f560f0ffa 100644 --- a/drivers/hwtracing/coresight/ultrasoc-smb.c +++ b/drivers/hwtracing/coresight/ultrasoc-smb.c @@ -163,7 +163,6 @@ static const struct file_operations smb_fops = { .open = smb_open, .read = smb_read, .release = smb_release, - .llseek = no_llseek, }; static ssize_t buf_size_show(struct device *dev, struct device_attribute *attr, diff --git a/drivers/hwtracing/intel_th/msu.c b/drivers/hwtracing/intel_th/msu.c index be63d5b8f193..66123d684ac9 100644 --- a/drivers/hwtracing/intel_th/msu.c +++ b/drivers/hwtracing/intel_th/msu.c @@ -1677,7 +1677,6 @@ static const struct file_operations intel_th_msc_fops = { .release = intel_th_msc_release, .read = intel_th_msc_read, .mmap = intel_th_msc_mmap, - .llseek = no_llseek, .owner = THIS_MODULE, }; diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c index ccf39a80dc4f..cdba4e875b28 100644 --- a/drivers/hwtracing/stm/core.c +++ b/drivers/hwtracing/stm/core.c @@ -839,7 +839,6 @@ static const struct file_operations stm_fops = { .mmap = stm_char_mmap, .unlocked_ioctl = stm_char_ioctl, .compat_ioctl = compat_ptr_ioctl, - .llseek = no_llseek, }; static void stm_device_release(struct device *dev) diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index f4fb212b7f39..61f7c4003d2f 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -637,7 +637,6 @@ static int i2cdev_release(struct inode *inode, struct file *file) static const struct file_operations i2cdev_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = i2cdev_read, .write = i2cdev_write, .unlocked_ioctl = i2cdev_ioctl, diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index dc57d07a1f45..5dbb248e9625 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -1817,7 +1817,6 @@ static const struct file_operations ucma_fops = { .release = ucma_close, .write = ucma_write, .poll = ucma_poll, - .llseek = no_llseek, }; static struct miscdevice ucma_misc = { diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index f760dfffa188..fd67fc9fe85a 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -1082,7 +1082,6 @@ static const struct file_operations umad_fops = { #endif .open = ib_umad_open, .release = ib_umad_close, - .llseek = no_llseek, }; static int ib_umad_sm_open(struct inode *inode, struct file *filp) @@ -1150,7 +1149,6 @@ static const struct file_operations umad_sm_fops = { .owner = THIS_MODULE, .open = ib_umad_sm_open, .release = ib_umad_sm_close, - .llseek = no_llseek, }; static struct ib_umad_port *get_port(struct ib_device *ibdev, diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index bc099287de9a..94454186ed81 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -353,7 +353,6 @@ const struct file_operations uverbs_event_fops = { .poll = ib_uverbs_comp_event_poll, .release = uverbs_uobject_fd_release, .fasync = ib_uverbs_comp_event_fasync, - .llseek = no_llseek, }; const struct file_operations uverbs_async_event_fops = { @@ -362,7 +361,6 @@ const struct file_operations uverbs_async_event_fops = { .poll = ib_uverbs_async_event_poll, .release = uverbs_async_event_release, .fasync = ib_uverbs_async_event_fasync, - .llseek = no_llseek, }; void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) @@ -991,7 +989,6 @@ static const struct file_operations uverbs_fops = { .write = ib_uverbs_write, .open = ib_uverbs_open, .release = ib_uverbs_close, - .llseek = no_llseek, .unlocked_ioctl = ib_uverbs_ioctl, .compat_ioctl = compat_ptr_ioctl, }; @@ -1002,7 +999,6 @@ static const struct file_operations uverbs_mmap_fops = { .mmap = ib_uverbs_mmap, .open = ib_uverbs_open, .release = ib_uverbs_close, - .llseek = no_llseek, .unlocked_ioctl = ib_uverbs_ioctl, .compat_ioctl = compat_ptr_ioctl, }; diff --git a/drivers/infiniband/hw/hfi1/fault.c b/drivers/infiniband/hw/hfi1/fault.c index 35d2382ee618..ec9ee59fcf0c 100644 --- a/drivers/infiniband/hw/hfi1/fault.c +++ b/drivers/infiniband/hw/hfi1/fault.c @@ -203,7 +203,6 @@ static const struct file_operations __fault_opcodes_fops = { .open = fault_opcodes_open, .read = fault_opcodes_read, .write = fault_opcodes_write, - .llseek = no_llseek }; void hfi1_fault_exit_debugfs(struct hfi1_ibdev *ibd) diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c index 253fea374a72..69999d8d24f3 100644 --- a/drivers/infiniband/hw/mlx5/devx.c +++ b/drivers/infiniband/hw/mlx5/devx.c @@ -2673,7 +2673,6 @@ static const struct file_operations devx_async_cmd_event_fops = { .read = devx_async_cmd_event_read, .poll = devx_async_cmd_event_poll, .release = uverbs_uobject_fd_release, - .llseek = no_llseek, }; static ssize_t devx_async_event_read(struct file *filp, char __user *buf, @@ -2788,7 +2787,6 @@ static const struct file_operations devx_async_event_fops = { .read = devx_async_event_read, .poll = devx_async_event_poll, .release = uverbs_uobject_fd_release, - .llseek = no_llseek, }; static void devx_async_cmd_event_destroy_uobj(struct ib_uobject *uobj, diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index eb4906552ac8..b5cbb57ee5f6 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -1299,7 +1299,6 @@ static const struct file_operations evdev_fops = { .compat_ioctl = evdev_ioctl_compat, #endif .fasync = evdev_fasync, - .llseek = no_llseek, }; /* diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 5824bca02e5a..ba2b17288bcd 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -718,7 +718,6 @@ static const struct file_operations joydev_fops = { .compat_ioctl = joydev_compat_ioctl, #endif .fasync = joydev_fasync, - .llseek = no_llseek, }; /* diff --git a/drivers/input/keyboard/applespi.c b/drivers/input/keyboard/applespi.c index cf25177b4830..707c5a8ae736 100644 --- a/drivers/input/keyboard/applespi.c +++ b/drivers/input/keyboard/applespi.c @@ -1007,7 +1007,6 @@ static const struct file_operations applespi_tp_dim_fops = { .owner = THIS_MODULE, .open = applespi_tp_dim_open, .read = applespi_tp_dim_read, - .llseek = no_llseek, }; static void report_finger_data(struct input_dev *input, int slot, diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 445856c9127a..2c51ea9d01d7 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -1132,7 +1132,6 @@ static const struct file_operations uinput_fops = { #ifdef CONFIG_COMPAT .compat_ioctl = uinput_compat_ioctl, #endif - .llseek = no_llseek, }; static struct miscdevice uinput_misc = { diff --git a/drivers/input/serio/userio.c b/drivers/input/serio/userio.c index a88e2eee55c3..1ab12b247f98 100644 --- a/drivers/input/serio/userio.c +++ b/drivers/input/serio/userio.c @@ -267,7 +267,6 @@ static const struct file_operations userio_fops = { .read = userio_char_read, .write = userio_char_write, .poll = userio_char_poll, - .llseek = no_llseek, }; static struct miscdevice userio_misc = { diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/fault.c index 8c8226f0dffd..e590973ce5cf 100644 --- a/drivers/iommu/iommufd/fault.c +++ b/drivers/iommu/iommufd/fault.c @@ -360,7 +360,6 @@ static const struct file_operations iommufd_fault_fops = { .write = iommufd_fault_fops_write, .poll = iommufd_fault_fops_poll, .release = iommufd_fault_fops_release, - .llseek = no_llseek, }; int iommufd_fault_alloc(struct iommufd_ucmd *ucmd) diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 3ed257334562..70dee9ad4bae 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1024,7 +1024,6 @@ static int capi_release(struct inode *inode, struct file *file) static const struct file_operations capi_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = capi_read, .write = capi_write, .poll = capi_poll, diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c index 83d6b484d3c6..7cfa8c61dba0 100644 --- a/drivers/isdn/mISDN/timerdev.c +++ b/drivers/isdn/mISDN/timerdev.c @@ -266,7 +266,6 @@ static const struct file_operations mISDN_fops = { .unlocked_ioctl = mISDN_ioctl, .open = mISDN_open, .release = mISDN_close, - .llseek = no_llseek, }; static struct miscdevice mISDNtimer = { diff --git a/drivers/leds/uleds.c b/drivers/leds/uleds.c index 3d361c920030..374a841f18c3 100644 --- a/drivers/leds/uleds.c +++ b/drivers/leds/uleds.c @@ -200,7 +200,6 @@ static const struct file_operations uleds_fops = { .read = uleds_read, .write = uleds_write, .poll = uleds_poll, - .llseek = no_llseek, }; static struct miscdevice uleds_misc = { diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index b0407c5fadb2..88adee42ba82 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -842,7 +842,6 @@ out: static const struct file_operations adb_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = adb_read, .write = adb_write, .open = adb_open, diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index b2b78a53e532..a01bc5090cdf 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -1314,7 +1314,6 @@ static int smu_release(struct inode *inode, struct file *file) static const struct file_operations smu_device_fops = { - .llseek = no_llseek, .read = smu_read, .write = smu_write, .poll = smu_fpoll, diff --git a/drivers/media/cec/core/cec-api.c b/drivers/media/cec/core/cec-api.c index c75a4057f00e..c50299246fc4 100644 --- a/drivers/media/cec/core/cec-api.c +++ b/drivers/media/cec/core/cec-api.c @@ -698,5 +698,4 @@ const struct file_operations cec_devnode_fops = { .compat_ioctl = cec_ioctl, .release = cec_release, .poll = cec_poll, - .llseek = no_llseek, }; diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 318e267e798e..56444edaf136 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -204,7 +204,6 @@ static const struct file_operations media_devnode_fops = { #endif /* CONFIG_COMPAT */ .release = media_release, .poll = media_poll, - .llseek = no_llseek, }; int __must_check media_devnode_register(struct media_device *mdev, diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index b8dfd530fab7..f042f3f14afa 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -706,7 +706,6 @@ static const struct file_operations lirc_fops = { .poll = lirc_poll, .open = lirc_open, .release = lirc_close, - .llseek = no_llseek, }; static void lirc_release_device(struct device *ld) diff --git a/drivers/media/usb/uvc/uvc_debugfs.c b/drivers/media/usb/uvc/uvc_debugfs.c index 1a1258d4ffca..14fa41cb8148 100644 --- a/drivers/media/usb/uvc/uvc_debugfs.c +++ b/drivers/media/usb/uvc/uvc_debugfs.c @@ -59,7 +59,6 @@ static int uvc_debugfs_stats_release(struct inode *inode, struct file *file) static const struct file_operations uvc_debugfs_stats_fops = { .owner = THIS_MODULE, .open = uvc_debugfs_stats_open, - .llseek = no_llseek, .read = uvc_debugfs_stats_read, .release = uvc_debugfs_stats_release, }; diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 570ba00e00b3..3d7711cc42bc 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -483,7 +483,6 @@ static const struct file_operations v4l2_fops = { #endif .release = v4l2_release, .poll = v4l2_poll, - .llseek = no_llseek, }; /** diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 9f3999750c23..4766d8518dc9 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -2691,7 +2691,6 @@ mptctl_hp_targetinfo(MPT_ADAPTER *ioc, unsigned long arg) static const struct file_operations mptctl_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .fasync = mptctl_fasync, .unlocked_ioctl = mptctl_ioctl, #ifdef CONFIG_COMPAT diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c index 1fc635a27568..4233dc4cc7d6 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.c +++ b/drivers/misc/lis3lv02d/lis3lv02d.c @@ -669,7 +669,6 @@ static int lis3lv02d_misc_fasync(int fd, struct file *file, int on) static const struct file_operations lis3lv02d_misc_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = lis3lv02d_misc_read, .open = lis3lv02d_misc_open, .release = lis3lv02d_misc_release, diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 40c3fe26f76d..1f5aaf16e300 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -1176,7 +1176,6 @@ static const struct file_operations mei_fops = { .poll = mei_poll, .fsync = mei_fsync, .fasync = mei_fasync, - .llseek = no_llseek }; /** diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c index 3c2f743c58b0..4954553b7baa 100644 --- a/drivers/misc/ntsync.c +++ b/drivers/misc/ntsync.c @@ -126,7 +126,6 @@ static const struct file_operations ntsync_obj_fops = { .release = ntsync_obj_release, .unlocked_ioctl = ntsync_obj_ioctl, .compat_ioctl = compat_ptr_ioctl, - .llseek = no_llseek, }; static struct ntsync_obj *ntsync_alloc_obj(struct ntsync_device *dev, @@ -233,7 +232,6 @@ static const struct file_operations ntsync_fops = { .release = ntsync_char_release, .unlocked_ioctl = ntsync_char_ioctl, .compat_ioctl = compat_ptr_ioctl, - .llseek = no_llseek, }; static struct miscdevice ntsync_misc = { diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c index 30bd7c39c261..701db2c5859b 100644 --- a/drivers/misc/phantom.c +++ b/drivers/misc/phantom.c @@ -279,7 +279,6 @@ static const struct file_operations phantom_file_ops = { .unlocked_ioctl = phantom_ioctl, .compat_ioctl = phantom_compat_ioctl, .poll = phantom_poll, - .llseek = no_llseek, }; static irqreturn_t phantom_isr(int irq, void *data) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index f58bea534004..ef06a4d5d65b 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -2734,7 +2734,6 @@ static const struct file_operations mmc_rpmb_fileops = { .release = mmc_rpmb_chrdev_release, .open = mmc_rpmb_chrdev_open, .owner = THIS_MODULE, - .llseek = no_llseek, .unlocked_ioctl = mmc_rpmb_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = mmc_rpmb_ioctl_compat, diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 0d8f04cf03c5..6bb80d7714bc 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -1095,7 +1095,6 @@ const struct file_operations ubi_vol_cdev_operations = { /* UBI character device operations */ const struct file_operations ubi_cdev_operations = { .owner = THIS_MODULE, - .llseek = no_llseek, .unlocked_ioctl = ubi_cdev_ioctl, .compat_ioctl = compat_ptr_ioctl, }; @@ -1105,5 +1104,4 @@ const struct file_operations ubi_ctrl_cdev_operations = { .owner = THIS_MODULE, .unlocked_ioctl = ctrl_cdev_ioctl, .compat_ioctl = compat_ptr_ioctl, - .llseek = no_llseek, }; diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 9ec3b8b6a0aa..d2a53961d8e2 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -470,7 +470,6 @@ static const struct file_operations dfs_fops = { .read = dfs_file_read, .write = dfs_file_write, .open = simple_open, - .llseek = no_llseek, .owner = THIS_MODULE, }; diff --git a/drivers/net/netdevsim/fib.c b/drivers/net/netdevsim/fib.c index a1f91ff8ec56..41e80f78b316 100644 --- a/drivers/net/netdevsim/fib.c +++ b/drivers/net/netdevsim/fib.c @@ -1414,7 +1414,6 @@ out: static const struct file_operations nsim_nexthop_bucket_activity_fops = { .open = simple_open, .write = nsim_nexthop_bucket_activity_write, - .llseek = no_llseek, .owner = THIS_MODULE, }; diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 77574f7a3bd4..5aa41d5f7765 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -1162,7 +1162,6 @@ static const struct file_operations tap_fops = { .read_iter = tap_read_iter, .write_iter = tap_write_iter, .poll = tap_poll, - .llseek = no_llseek, .unlocked_ioctl = tap_ioctl, .compat_ioctl = compat_ptr_ioctl, }; diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 5f77faef0ff1..9a0f6eb32016 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -3543,7 +3543,6 @@ static void tun_chr_show_fdinfo(struct seq_file *m, struct file *file) static const struct file_operations tun_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read_iter = tun_chr_read_iter, .write_iter = tun_chr_write_iter, .poll = tun_chr_poll, diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index df53dd1d7e74..da72fd2d541f 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -1184,7 +1184,6 @@ static ssize_t bus_reset_write(struct file *file, const char __user *user_buf, static const struct file_operations bus_reset_fops = { .open = simple_open, - .llseek = no_llseek, .write = bus_reset_write, }; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 99a541d442bb..49a6aff42376 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -3768,7 +3768,6 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file) } const struct file_operations iwl_dbgfs_d3_test_ops = { - .llseek = no_llseek, .open = iwl_mvm_d3_test_open, .read = iwl_mvm_d3_test_read, .release = iwl_mvm_d3_test_release, diff --git a/drivers/platform/chrome/cros_ec_debugfs.c b/drivers/platform/chrome/cros_ec_debugfs.c index 4525ad1b59f4..839154c46e46 100644 --- a/drivers/platform/chrome/cros_ec_debugfs.c +++ b/drivers/platform/chrome/cros_ec_debugfs.c @@ -302,7 +302,6 @@ static const struct file_operations cros_ec_console_log_fops = { .owner = THIS_MODULE, .open = cros_ec_console_log_open, .read = cros_ec_console_log_read, - .llseek = no_llseek, .poll = cros_ec_console_log_poll, .release = cros_ec_console_log_release, }; diff --git a/drivers/platform/chrome/wilco_ec/debugfs.c b/drivers/platform/chrome/wilco_ec/debugfs.c index 983f2fa44ba5..99486086af6a 100644 --- a/drivers/platform/chrome/wilco_ec/debugfs.c +++ b/drivers/platform/chrome/wilco_ec/debugfs.c @@ -156,7 +156,6 @@ static const struct file_operations fops_raw = { .owner = THIS_MODULE, .read = raw_read, .write = raw_write, - .llseek = no_llseek, }; #define CMD_KB_CHROME 0x88 diff --git a/drivers/platform/chrome/wilco_ec/event.c b/drivers/platform/chrome/wilco_ec/event.c index bd1fb53ba028..196e46a1d489 100644 --- a/drivers/platform/chrome/wilco_ec/event.c +++ b/drivers/platform/chrome/wilco_ec/event.c @@ -403,7 +403,6 @@ static const struct file_operations event_fops = { .poll = event_poll, .read = event_read, .release = event_release, - .llseek = no_llseek, .owner = THIS_MODULE, }; diff --git a/drivers/platform/chrome/wilco_ec/telemetry.c b/drivers/platform/chrome/wilco_ec/telemetry.c index 21d4cbbb009a..a87877e4300a 100644 --- a/drivers/platform/chrome/wilco_ec/telemetry.c +++ b/drivers/platform/chrome/wilco_ec/telemetry.c @@ -330,7 +330,6 @@ static const struct file_operations telem_fops = { .write = telem_write, .read = telem_read, .release = telem_release, - .llseek = no_llseek, .owner = THIS_MODULE, }; diff --git a/drivers/platform/surface/surface_aggregator_cdev.c b/drivers/platform/surface/surface_aggregator_cdev.c index 07e065b9159f..165b1416230d 100644 --- a/drivers/platform/surface/surface_aggregator_cdev.c +++ b/drivers/platform/surface/surface_aggregator_cdev.c @@ -670,7 +670,6 @@ static const struct file_operations ssam_controller_fops = { .fasync = ssam_cdev_fasync, .unlocked_ioctl = ssam_cdev_device_ioctl, .compat_ioctl = ssam_cdev_device_ioctl, - .llseek = no_llseek, }; diff --git a/drivers/platform/surface/surface_dtx.c b/drivers/platform/surface/surface_dtx.c index 2de843b7ea70..89ca6b50e812 100644 --- a/drivers/platform/surface/surface_dtx.c +++ b/drivers/platform/surface/surface_dtx.c @@ -555,7 +555,6 @@ static const struct file_operations surface_dtx_fops = { .fasync = surface_dtx_fasync, .unlocked_ioctl = surface_dtx_ioctl, .compat_ioctl = surface_dtx_ioctl, - .llseek = no_llseek, }; diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c index 5d19baae6a38..25d47907db17 100644 --- a/drivers/pps/pps.c +++ b/drivers/pps/pps.c @@ -319,7 +319,6 @@ static int pps_cdev_release(struct inode *inode, struct file *file) static const struct file_operations pps_cdev_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .poll = pps_cdev_poll, .fasync = pps_cdev_fasync, .compat_ioctl = pps_cdev_compat_ioctl, diff --git a/drivers/rtc/dev.c b/drivers/rtc/dev.c index 4aad9bb99868..c4a3ab53dcd4 100644 --- a/drivers/rtc/dev.c +++ b/drivers/rtc/dev.c @@ -523,7 +523,6 @@ static int rtc_dev_release(struct inode *inode, struct file *file) static const struct file_operations rtc_dev_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = rtc_dev_read, .poll = rtc_dev_poll, .unlocked_ioctl = rtc_dev_ioctl, diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 0013bff0447d..1f58ae8b151e 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -850,7 +850,6 @@ static const struct file_operations wdt_fops = { .write = wdt_write, .open = wdt_open, .release = wdt_release, - .llseek = no_llseek, }; static struct miscdevice wdt_dev = { diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 61515781c5dd..cfe7efd5b5da 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -515,7 +515,6 @@ static const struct file_operations fs3270_fops = { .compat_ioctl = fs3270_ioctl, /* ioctl */ .open = fs3270_open, /* open */ .release = fs3270_close, /* release */ - .llseek = no_llseek, }; static void fs3270_create_cb(int minor) diff --git a/drivers/s390/char/sclp_ctl.c b/drivers/s390/char/sclp_ctl.c index 248b5db3eaa8..dd6051602070 100644 --- a/drivers/s390/char/sclp_ctl.c +++ b/drivers/s390/char/sclp_ctl.c @@ -115,7 +115,6 @@ static const struct file_operations sclp_ctl_fops = { .open = nonseekable_open, .unlocked_ioctl = sclp_ctl_ioctl, .compat_ioctl = sclp_ctl_ioctl, - .llseek = no_llseek, }; /* diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index cc8237afeffa..89778d922d9f 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -52,7 +52,6 @@ static const struct file_operations tape_fops = #endif .open = tapechar_open, .release = tapechar_release, - .llseek = no_llseek, }; static int tapechar_major = TAPECHAR_MAJOR; diff --git a/drivers/s390/char/uvdevice.c b/drivers/s390/char/uvdevice.c index 42c9f77f8da0..f598edc5f251 100644 --- a/drivers/s390/char/uvdevice.c +++ b/drivers/s390/char/uvdevice.c @@ -448,7 +448,6 @@ static long uvio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) static const struct file_operations uvio_dev_fops = { .owner = THIS_MODULE, .unlocked_ioctl = uvio_ioctl, - .llseek = no_llseek, }; static struct miscdevice uvio_dev_miscdev = { diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index eb0520a9d4af..c6d58335beb4 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c @@ -242,7 +242,6 @@ static const struct file_operations vmcp_fops = { .write = vmcp_write, .unlocked_ioctl = vmcp_ioctl, .compat_ioctl = vmcp_ioctl, - .llseek = no_llseek, }; static struct miscdevice vmcp_dev = { diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index c09e1e09fb66..bd5cecc44123 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -96,7 +96,6 @@ static const struct file_operations vmlogrdr_fops = { .open = vmlogrdr_open, .release = vmlogrdr_release, .read = vmlogrdr_read, - .llseek = no_llseek, }; diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 0969fa01df58..33cebb91b933 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -165,7 +165,6 @@ static const struct file_operations zcore_reipl_fops = { .write = zcore_reipl_write, .open = zcore_reipl_open, .release = zcore_reipl_release, - .llseek = no_llseek, }; static ssize_t zcore_hsa_read(struct file *filp, char __user *buf, @@ -200,7 +199,6 @@ static const struct file_operations zcore_hsa_fops = { .write = zcore_hsa_write, .read = zcore_hsa_read, .open = nonseekable_open, - .llseek = no_llseek, }; static int __init check_sdias(void) diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index e6c800653f98..1e58ee3cc87d 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -924,7 +924,6 @@ static const struct file_operations chsc_fops = { .release = chsc_release, .unlocked_ioctl = chsc_ioctl, .compat_ioctl = chsc_ioctl, - .llseek = no_llseek, }; static struct miscdevice chsc_misc_device = { diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 53b68f8c32f3..7b59d20bf785 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -1332,7 +1332,6 @@ static ssize_t cio_settle_write(struct file *file, const char __user *buf, static const struct proc_ops cio_settle_proc_ops = { .proc_open = nonseekable_open, .proc_write = cio_settle_write, - .proc_lseek = no_llseek, }; static int __init cio_settle_init(void) diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c index c20251e00cf9..3a39e167bdbf 100644 --- a/drivers/s390/crypto/pkey_api.c +++ b/drivers/s390/crypto/pkey_api.c @@ -776,7 +776,6 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, static const struct file_operations pkey_fops = { .owner = THIS_MODULE, .open = nonseekable_open, - .llseek = no_llseek, .unlocked_ioctl = pkey_unlocked_ioctl, }; diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index f9a47b54c51a..5020696f1379 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -1908,7 +1908,6 @@ static const struct file_operations zcrypt_fops = { #endif .open = zcrypt_open, .release = zcrypt_release, - .llseek = no_llseek, }; /* diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c index cc178874c4a6..8643947fee8e 100644 --- a/drivers/sbus/char/openprom.c +++ b/drivers/sbus/char/openprom.c @@ -687,7 +687,6 @@ static int openprom_release(struct inode * inode, struct file * file) static const struct file_operations openprom_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .unlocked_ioctl = openprom_ioctl, .compat_ioctl = openprom_compat_ioctl, .open = openprom_open, diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index 3c88f29f4c47..8bbed7a7afb7 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -221,7 +221,6 @@ static irqreturn_t uctrl_interrupt(int irq, void *dev_id) static const struct file_operations uctrl_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .unlocked_ioctl = uctrl_ioctl, .open = uctrl_open, }; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index baf870a03ecf..f86be197fedd 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1424,7 +1424,6 @@ static const struct file_operations sg_fops = { .mmap = sg_mmap, .release = sg_release, .fasync = sg_fasync, - .llseek = no_llseek, }; static const struct class sg_sysfs_class = { diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 5539c5d139d4..653f82984216 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -685,7 +685,6 @@ static const struct file_operations spidev_fops = { .compat_ioctl = spidev_compat_ioctl, .open = spidev_open, .release = spidev_release, - .llseek = no_llseek, }; /*-------------------------------------------------------------------------*/ diff --git a/drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c b/drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c index 4b4a4d63e61f..cb149bcdd7d5 100644 --- a/drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c +++ b/drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c @@ -564,7 +564,6 @@ static const struct file_operations acpi_thermal_rel_fops = { .open = acpi_thermal_rel_open, .release = acpi_thermal_rel_release, .unlocked_ioctl = acpi_thermal_rel_ioctl, - .llseek = no_llseek, }; static struct miscdevice acpi_thermal_rel_misc_device = { diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 6bd28a042dff..9771072da177 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -459,7 +459,6 @@ static void tty_show_fdinfo(struct seq_file *m, struct file *file) } static const struct file_operations tty_fops = { - .llseek = no_llseek, .read_iter = tty_read, .write_iter = tty_write, .splice_read = copy_splice_read, @@ -474,7 +473,6 @@ static const struct file_operations tty_fops = { }; static const struct file_operations console_fops = { - .llseek = no_llseek, .read_iter = tty_read, .write_iter = redirected_tty_write, .splice_read = copy_splice_read, @@ -488,7 +486,6 @@ static const struct file_operations console_fops = { }; static const struct file_operations hung_up_tty_fops = { - .llseek = no_llseek, .read_iter = hung_up_tty_read, .write_iter = hung_up_tty_write, .poll = hung_up_tty_poll, diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 05b52e61a66f..c626bb73ea59 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -722,7 +722,6 @@ static __poll_t ffs_ep0_poll(struct file *file, poll_table *wait) } static const struct file_operations ffs_ep0_operations = { - .llseek = no_llseek, .open = ffs_ep0_open, .write = ffs_ep0_write, @@ -1830,7 +1829,6 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, } static const struct file_operations ffs_epfile_operations = { - .llseek = no_llseek, .open = ffs_epfile_open, .write_iter = ffs_epfile_write_iter, diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 03179b1880fd..9c7381661016 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -705,7 +705,6 @@ static const struct file_operations ep_io_operations = { .open = ep_open, .release = ep_release, - .llseek = no_llseek, .unlocked_ioctl = ep_ioctl, .read_iter = ep_read_iter, .write_iter = ep_write_iter, @@ -1939,7 +1938,6 @@ gadget_dev_open (struct inode *inode, struct file *fd) } static const struct file_operations ep0_operations = { - .llseek = no_llseek, .open = gadget_dev_open, .read = ep0_read, diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c index 399fca32a8ac..112fd18d8c99 100644 --- a/drivers/usb/gadget/legacy/raw_gadget.c +++ b/drivers/usb/gadget/legacy/raw_gadget.c @@ -1364,7 +1364,6 @@ static const struct file_operations raw_fops = { .unlocked_ioctl = raw_ioctl, .compat_ioctl = raw_ioctl, .release = raw_release, - .llseek = no_llseek, }; static struct miscdevice raw_misc_device = { diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index b76885d78e8a..4928eba19327 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -187,7 +187,6 @@ static int regs_dbg_release(struct inode *inode, struct file *file) static const struct file_operations queue_dbg_fops = { .owner = THIS_MODULE, .open = queue_dbg_open, - .llseek = no_llseek, .read = queue_dbg_read, .release = queue_dbg_release, }; diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 7cbef74dfc9a..f392d6f84df9 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -627,7 +627,6 @@ static const struct file_operations ld_usb_fops = { .open = ld_usb_open, .release = ld_usb_release, .poll = ld_usb_poll, - .llseek = no_llseek, }; /* diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 4e30de4db1c0..afb71c18415d 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -1289,7 +1289,6 @@ static int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma) static const struct file_operations mon_fops_binary = { .owner = THIS_MODULE, .open = mon_bin_open, - .llseek = no_llseek, .read = mon_bin_read, /* .write = mon_text_write, */ .poll = mon_bin_poll, diff --git a/drivers/usb/mon/mon_stat.c b/drivers/usb/mon/mon_stat.c index 3c23805ab1a4..398e02af6a2b 100644 --- a/drivers/usb/mon/mon_stat.c +++ b/drivers/usb/mon/mon_stat.c @@ -62,7 +62,6 @@ static int mon_stat_release(struct inode *inode, struct file *file) const struct file_operations mon_fops_stat = { .owner = THIS_MODULE, .open = mon_stat_open, - .llseek = no_llseek, .read = mon_stat_read, /* .write = mon_stat_write, */ /* .poll = mon_stat_poll, */ diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 2fe9b95bac1d..68b9b2b41189 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -685,7 +685,6 @@ static int mon_text_release(struct inode *inode, struct file *file) static const struct file_operations mon_fops_text_t = { .owner = THIS_MODULE, .open = mon_text_open, - .llseek = no_llseek, .read = mon_text_read_t, .release = mon_text_release, }; @@ -693,7 +692,6 @@ static const struct file_operations mon_fops_text_t = { static const struct file_operations mon_fops_text_u = { .owner = THIS_MODULE, .open = mon_text_open, - .llseek = no_llseek, .read = mon_text_read_u, .release = mon_text_release, }; diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c index 9a3e97108ace..0d632ba5d2a3 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c @@ -723,7 +723,6 @@ static const struct file_operations hisi_acc_vf_resume_fops = { .owner = THIS_MODULE, .write = hisi_acc_vf_resume_write, .release = hisi_acc_vf_release_file, - .llseek = no_llseek, }; static struct hisi_acc_vf_migration_file * @@ -845,7 +844,6 @@ static const struct file_operations hisi_acc_vf_save_fops = { .unlocked_ioctl = hisi_acc_vf_precopy_ioctl, .compat_ioctl = compat_ptr_ioctl, .release = hisi_acc_vf_release_file, - .llseek = no_llseek, }; static struct hisi_acc_vf_migration_file * diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 61d9b0f9146d..242c23eef452 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -587,7 +587,6 @@ static const struct file_operations mlx5vf_save_fops = { .unlocked_ioctl = mlx5vf_precopy_ioctl, .compat_ioctl = compat_ptr_ioctl, .release = mlx5vf_release_file, - .llseek = no_llseek, }; static int mlx5vf_pci_save_device_inc_data(struct mlx5vf_pci_core_device *mvdev) @@ -1000,7 +999,6 @@ static const struct file_operations mlx5vf_resume_fops = { .owner = THIS_MODULE, .write = mlx5vf_resume_write, .release = mlx5vf_release_file, - .llseek = no_llseek, }; static struct mlx5_vf_migration_file * diff --git a/drivers/vfio/pci/pds/lm.c b/drivers/vfio/pci/pds/lm.c index 6b94cc0bf45b..f2673d395236 100644 --- a/drivers/vfio/pci/pds/lm.c +++ b/drivers/vfio/pci/pds/lm.c @@ -235,7 +235,6 @@ static const struct file_operations pds_vfio_save_fops = { .owner = THIS_MODULE, .read = pds_vfio_save_read, .release = pds_vfio_release_file, - .llseek = no_llseek, }; static int pds_vfio_get_save_file(struct pds_vfio_pci_device *pds_vfio) @@ -334,7 +333,6 @@ static const struct file_operations pds_vfio_restore_fops = { .owner = THIS_MODULE, .write = pds_vfio_restore_write, .release = pds_vfio_release_file, - .llseek = no_llseek, }; static int pds_vfio_get_restore_file(struct pds_vfio_pci_device *pds_vfio) diff --git a/drivers/vfio/pci/qat/main.c b/drivers/vfio/pci/qat/main.c index e36740a282e7..be3644ced17b 100644 --- a/drivers/vfio/pci/qat/main.c +++ b/drivers/vfio/pci/qat/main.c @@ -220,7 +220,6 @@ static const struct file_operations qat_vf_save_fops = { .unlocked_ioctl = qat_vf_precopy_ioctl, .compat_ioctl = compat_ptr_ioctl, .release = qat_vf_release_file, - .llseek = no_llseek, }; static int qat_vf_save_state(struct qat_vf_core_device *qat_vdev, @@ -345,7 +344,6 @@ static const struct file_operations qat_vf_resume_fops = { .owner = THIS_MODULE, .write = qat_vf_resume_write, .release = qat_vf_release_file, - .llseek = no_llseek, }; static struct qat_vf_migration_file * diff --git a/drivers/virt/coco/tdx-guest/tdx-guest.c b/drivers/virt/coco/tdx-guest/tdx-guest.c index 2acba56ad42e..d7db6c824e13 100644 --- a/drivers/virt/coco/tdx-guest/tdx-guest.c +++ b/drivers/virt/coco/tdx-guest/tdx-guest.c @@ -285,7 +285,6 @@ static long tdx_guest_ioctl(struct file *file, unsigned int cmd, static const struct file_operations tdx_guest_fops = { .owner = THIS_MODULE, .unlocked_ioctl = tdx_guest_ioctl, - .llseek = no_llseek, }; static struct miscdevice tdx_misc_dev = { diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c index 53b04abd55b0..08ca18e91124 100644 --- a/drivers/watchdog/acquirewdt.c +++ b/drivers/watchdog/acquirewdt.c @@ -218,7 +218,6 @@ static int acq_close(struct inode *inode, struct file *file) static const struct file_operations acq_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = acq_write, .unlocked_ioctl = acq_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c index 7a0acbc3e4dd..e41cd3ba4e0e 100644 --- a/drivers/watchdog/advantechwdt.c +++ b/drivers/watchdog/advantechwdt.c @@ -217,7 +217,6 @@ static int advwdt_close(struct inode *inode, struct file *file) static const struct file_operations advwdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = advwdt_write, .unlocked_ioctl = advwdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c index bfb9a91ca1df..1ecbd1ac5c3a 100644 --- a/drivers/watchdog/alim1535_wdt.c +++ b/drivers/watchdog/alim1535_wdt.c @@ -359,7 +359,6 @@ static int __init ali_find_watchdog(void) static const struct file_operations ali_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = ali_write, .unlocked_ioctl = ali_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c index 4ff7f5afb7aa..9c7cf939ba3d 100644 --- a/drivers/watchdog/alim7101_wdt.c +++ b/drivers/watchdog/alim7101_wdt.c @@ -289,7 +289,6 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static const struct file_operations wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = fop_write, .open = fop_open, .release = fop_close, diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index 558015f08c7a..17382512a609 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c @@ -210,7 +210,6 @@ static ssize_t at91_wdt_write(struct file *file, const char *data, static const struct file_operations at91wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .unlocked_ioctl = at91_wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, .open = at91_wdt_open, diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c index e5cc30622b12..d16b2c583fa4 100644 --- a/drivers/watchdog/ath79_wdt.c +++ b/drivers/watchdog/ath79_wdt.c @@ -231,7 +231,6 @@ static long ath79_wdt_ioctl(struct file *file, unsigned int cmd, static const struct file_operations ath79_wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = ath79_wdt_write, .unlocked_ioctl = ath79_wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c index 9f279c0e13a6..f94b84048612 100644 --- a/drivers/watchdog/cpu5wdt.c +++ b/drivers/watchdog/cpu5wdt.c @@ -185,7 +185,6 @@ static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, static const struct file_operations cpu5wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .unlocked_ioctl = cpu5wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, .open = cpu5wdt_open, diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index 901b94d456db..8ee81f018dda 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -507,7 +507,6 @@ static const struct file_operations cpwd_fops = { .write = cpwd_write, .read = cpwd_read, .release = cpwd_release, - .llseek = no_llseek, }; static int cpwd_probe(struct platform_device *op) diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c index e26609ad4c17..10c647b1226a 100644 --- a/drivers/watchdog/eurotechwdt.c +++ b/drivers/watchdog/eurotechwdt.c @@ -368,7 +368,6 @@ static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code, static const struct file_operations eurwdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = eurwdt_write, .unlocked_ioctl = eurwdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index 6a1db1c783fa..d854fcfbfa5b 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c @@ -245,7 +245,6 @@ static int gef_wdt_release(struct inode *inode, struct file *file) static const struct file_operations gef_wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = gef_wdt_write, .unlocked_ioctl = gef_wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c index 5186c37ad451..4ed6d139320b 100644 --- a/drivers/watchdog/geodewdt.c +++ b/drivers/watchdog/geodewdt.c @@ -196,7 +196,6 @@ static long geodewdt_ioctl(struct file *file, unsigned int cmd, static const struct file_operations geodewdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = geodewdt_write, .unlocked_ioctl = geodewdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c index 39ea97009abd..b041ad90a62c 100644 --- a/drivers/watchdog/ib700wdt.c +++ b/drivers/watchdog/ib700wdt.c @@ -256,7 +256,6 @@ static int ibwdt_close(struct inode *inode, struct file *file) static const struct file_operations ibwdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = ibwdt_write, .unlocked_ioctl = ibwdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c index 6955c693b5fd..cf845f865945 100644 --- a/drivers/watchdog/ibmasr.c +++ b/drivers/watchdog/ibmasr.c @@ -340,7 +340,6 @@ static int asr_release(struct inode *inode, struct file *file) static const struct file_operations asr_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = asr_write, .unlocked_ioctl = asr_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c index 9857bb74a723..d3092d261345 100644 --- a/drivers/watchdog/indydog.c +++ b/drivers/watchdog/indydog.c @@ -149,7 +149,6 @@ static int indydog_notify_sys(struct notifier_block *this, static const struct file_operations indydog_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = indydog_write, .unlocked_ioctl = indydog_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c index 3ce6a58bd81e..b776e6766c9d 100644 --- a/drivers/watchdog/it8712f_wdt.c +++ b/drivers/watchdog/it8712f_wdt.c @@ -341,7 +341,6 @@ static int it8712f_wdt_release(struct inode *inode, struct file *file) static const struct file_operations it8712f_wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = it8712f_wdt_write, .unlocked_ioctl = it8712f_wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/m54xx_wdt.c b/drivers/watchdog/m54xx_wdt.c index 062ea3e6497e..26bd073bd375 100644 --- a/drivers/watchdog/m54xx_wdt.c +++ b/drivers/watchdog/m54xx_wdt.c @@ -179,7 +179,6 @@ static int m54xx_wdt_release(struct inode *inode, struct file *file) static const struct file_operations m54xx_wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = m54xx_wdt_write, .unlocked_ioctl = m54xx_wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c index 73f2221f6222..73d641486909 100644 --- a/drivers/watchdog/machzwd.c +++ b/drivers/watchdog/machzwd.c @@ -359,7 +359,6 @@ static int zf_notify_sys(struct notifier_block *this, unsigned long code, static const struct file_operations zf_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = zf_write, .unlocked_ioctl = zf_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c index d387bad377c4..70d9cf84c342 100644 --- a/drivers/watchdog/mixcomwd.c +++ b/drivers/watchdog/mixcomwd.c @@ -224,7 +224,6 @@ static long mixcomwd_ioctl(struct file *file, static const struct file_operations mixcomwd_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = mixcomwd_write, .unlocked_ioctl = mixcomwd_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index 06756135033d..11f05024a181 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c @@ -177,7 +177,6 @@ static ssize_t mtx1_wdt_write(struct file *file, const char *buf, static const struct file_operations mtx1_wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .unlocked_ioctl = mtx1_wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, .open = mtx1_wdt_open, diff --git a/drivers/watchdog/nv_tco.c b/drivers/watchdog/nv_tco.c index ac4a9c16341d..f8eb1f65a59e 100644 --- a/drivers/watchdog/nv_tco.c +++ b/drivers/watchdog/nv_tco.c @@ -264,7 +264,6 @@ static long nv_tco_ioctl(struct file *file, unsigned int cmd, static const struct file_operations nv_tco_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = nv_tco_write, .unlocked_ioctl = nv_tco_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c index c7f745caf203..fbf835d112b8 100644 --- a/drivers/watchdog/pc87413_wdt.c +++ b/drivers/watchdog/pc87413_wdt.c @@ -470,7 +470,6 @@ static int pc87413_notify_sys(struct notifier_block *this, static const struct file_operations pc87413_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = pc87413_write, .unlocked_ioctl = pc87413_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c index a793b03a785d..1a4282235aac 100644 --- a/drivers/watchdog/pcwd.c +++ b/drivers/watchdog/pcwd.c @@ -749,7 +749,6 @@ static int pcwd_temp_close(struct inode *inode, struct file *file) static const struct file_operations pcwd_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = pcwd_write, .unlocked_ioctl = pcwd_ioctl, .compat_ioctl = compat_ptr_ioctl, @@ -765,7 +764,6 @@ static struct miscdevice pcwd_miscdev = { static const struct file_operations pcwd_temp_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = pcwd_temp_read, .open = pcwd_temp_open, .release = pcwd_temp_close, diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c index 54d86fcb1837..a489b426f2ba 100644 --- a/drivers/watchdog/pcwd_pci.c +++ b/drivers/watchdog/pcwd_pci.c @@ -643,7 +643,6 @@ static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, static const struct file_operations pcipcwd_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = pcipcwd_write, .unlocked_ioctl = pcipcwd_ioctl, .compat_ioctl = compat_ptr_ioctl, @@ -659,7 +658,6 @@ static struct miscdevice pcipcwd_miscdev = { static const struct file_operations pcipcwd_temp_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = pcipcwd_temp_read, .open = pcipcwd_temp_open, .release = pcipcwd_temp_release, diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c index 8202f0a6b093..132699e2f247 100644 --- a/drivers/watchdog/pcwd_usb.c +++ b/drivers/watchdog/pcwd_usb.c @@ -549,7 +549,6 @@ static int usb_pcwd_notify_sys(struct notifier_block *this, unsigned long code, static const struct file_operations usb_pcwd_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = usb_pcwd_write, .unlocked_ioctl = usb_pcwd_ioctl, .compat_ioctl = compat_ptr_ioctl, @@ -565,7 +564,6 @@ static struct miscdevice usb_pcwd_miscdev = { static const struct file_operations usb_pcwd_temperature_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = usb_pcwd_temperature_read, .open = usb_pcwd_temperature_open, .release = usb_pcwd_temperature_release, diff --git a/drivers/watchdog/pika_wdt.c b/drivers/watchdog/pika_wdt.c index 782b8c23d99c..393aa4b1bc13 100644 --- a/drivers/watchdog/pika_wdt.c +++ b/drivers/watchdog/pika_wdt.c @@ -209,7 +209,6 @@ static long pikawdt_ioctl(struct file *file, static const struct file_operations pikawdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .open = pikawdt_open, .release = pikawdt_release, .write = pikawdt_write, diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c index 417f9b75679c..efadbb9d7ce7 100644 --- a/drivers/watchdog/rc32434_wdt.c +++ b/drivers/watchdog/rc32434_wdt.c @@ -242,7 +242,6 @@ static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd, static const struct file_operations rc32434_wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = rc32434_wdt_write, .unlocked_ioctl = rc32434_wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index 6176f4343fc5..80490316a27f 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c @@ -197,7 +197,6 @@ static ssize_t rdc321x_wdt_write(struct file *file, const char __user *buf, static const struct file_operations rdc321x_wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .unlocked_ioctl = rdc321x_wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, .open = rdc321x_wdt_open, diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index b293792a292a..f47d90d01c19 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c @@ -160,7 +160,6 @@ static ssize_t riowd_write(struct file *file, const char __user *buf, static const struct file_operations riowd_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .unlocked_ioctl = riowd_ioctl, .compat_ioctl = compat_ptr_ioctl, .open = riowd_open, diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c index 34a917221e31..6e91ee3fbfb5 100644 --- a/drivers/watchdog/sa1100_wdt.c +++ b/drivers/watchdog/sa1100_wdt.c @@ -164,7 +164,6 @@ static long sa1100dog_ioctl(struct file *file, unsigned int cmd, static const struct file_operations sa1100dog_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = sa1100dog_write, .unlocked_ioctl = sa1100dog_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c index 504be461f992..eaa68b54cf56 100644 --- a/drivers/watchdog/sb_wdog.c +++ b/drivers/watchdog/sb_wdog.c @@ -234,7 +234,6 @@ static int sbwdog_notify_sys(struct notifier_block *this, unsigned long code, static const struct file_operations sbwdog_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = sbwdog_write, .unlocked_ioctl = sbwdog_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/sbc60xxwdt.c b/drivers/watchdog/sbc60xxwdt.c index 7b974802dfc7..e9bf12918ed8 100644 --- a/drivers/watchdog/sbc60xxwdt.c +++ b/drivers/watchdog/sbc60xxwdt.c @@ -275,7 +275,6 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static const struct file_operations wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = fop_write, .open = fop_open, .release = fop_close, diff --git a/drivers/watchdog/sbc7240_wdt.c b/drivers/watchdog/sbc7240_wdt.c index d640b26e18a6..21a1f0b32070 100644 --- a/drivers/watchdog/sbc7240_wdt.c +++ b/drivers/watchdog/sbc7240_wdt.c @@ -205,7 +205,6 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static const struct file_operations wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = fop_write, .open = fop_open, .release = fop_close, diff --git a/drivers/watchdog/sbc8360.c b/drivers/watchdog/sbc8360.c index 4f8b9912fc51..a9fd1615b4c3 100644 --- a/drivers/watchdog/sbc8360.c +++ b/drivers/watchdog/sbc8360.c @@ -301,7 +301,6 @@ static int sbc8360_notify_sys(struct notifier_block *this, unsigned long code, static const struct file_operations sbc8360_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = sbc8360_write, .open = sbc8360_open, .release = sbc8360_close, diff --git a/drivers/watchdog/sbc_epx_c3.c b/drivers/watchdog/sbc_epx_c3.c index 5e3a9ddb952e..1d291dc0a4a6 100644 --- a/drivers/watchdog/sbc_epx_c3.c +++ b/drivers/watchdog/sbc_epx_c3.c @@ -153,7 +153,6 @@ static int epx_c3_notify_sys(struct notifier_block *this, unsigned long code, static const struct file_operations epx_c3_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = epx_c3_write, .unlocked_ioctl = epx_c3_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/sbc_fitpc2_wdt.c b/drivers/watchdog/sbc_fitpc2_wdt.c index b8eb8d5ca1af..ff9e44825423 100644 --- a/drivers/watchdog/sbc_fitpc2_wdt.c +++ b/drivers/watchdog/sbc_fitpc2_wdt.c @@ -181,7 +181,6 @@ static int fitpc2_wdt_release(struct inode *inode, struct file *file) static const struct file_operations fitpc2_wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = fitpc2_wdt_write, .unlocked_ioctl = fitpc2_wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/sc1200wdt.c b/drivers/watchdog/sc1200wdt.c index f22ebe89fe13..76a58715f665 100644 --- a/drivers/watchdog/sc1200wdt.c +++ b/drivers/watchdog/sc1200wdt.c @@ -304,7 +304,6 @@ static struct notifier_block sc1200wdt_notifier = { static const struct file_operations sc1200wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = sc1200wdt_write, .unlocked_ioctl = sc1200wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/sc520_wdt.c b/drivers/watchdog/sc520_wdt.c index ca65468f4b9c..e849e1af267b 100644 --- a/drivers/watchdog/sc520_wdt.c +++ b/drivers/watchdog/sc520_wdt.c @@ -331,7 +331,6 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static const struct file_operations wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = fop_write, .open = fop_open, .release = fop_close, diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c index 409d49880170..76053158d259 100644 --- a/drivers/watchdog/sch311x_wdt.c +++ b/drivers/watchdog/sch311x_wdt.c @@ -334,7 +334,6 @@ static int sch311x_wdt_close(struct inode *inode, struct file *file) static const struct file_operations sch311x_wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = sch311x_wdt_write, .unlocked_ioctl = sch311x_wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/scx200_wdt.c b/drivers/watchdog/scx200_wdt.c index 7b5e18323f3f..4dd8549e3674 100644 --- a/drivers/watchdog/scx200_wdt.c +++ b/drivers/watchdog/scx200_wdt.c @@ -198,7 +198,6 @@ static long scx200_wdt_ioctl(struct file *file, unsigned int cmd, static const struct file_operations scx200_wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = scx200_wdt_write, .unlocked_ioctl = scx200_wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/smsc37b787_wdt.c b/drivers/watchdog/smsc37b787_wdt.c index 7463df479d11..97ca500ec8a8 100644 --- a/drivers/watchdog/smsc37b787_wdt.c +++ b/drivers/watchdog/smsc37b787_wdt.c @@ -502,7 +502,6 @@ static int wb_smsc_wdt_notify_sys(struct notifier_block *this, static const struct file_operations wb_smsc_wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = wb_smsc_wdt_write, .unlocked_ioctl = wb_smsc_wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/w83877f_wdt.c b/drivers/watchdog/w83877f_wdt.c index f2650863fd02..1937084c182c 100644 --- a/drivers/watchdog/w83877f_wdt.c +++ b/drivers/watchdog/w83877f_wdt.c @@ -299,7 +299,6 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static const struct file_operations wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = fop_write, .open = fop_open, .release = fop_close, diff --git a/drivers/watchdog/w83977f_wdt.c b/drivers/watchdog/w83977f_wdt.c index 31bf21ceaf48..3776030fa7c6 100644 --- a/drivers/watchdog/w83977f_wdt.c +++ b/drivers/watchdog/w83977f_wdt.c @@ -443,7 +443,6 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, static const struct file_operations wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = wdt_write, .unlocked_ioctl = wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/wafer5823wdt.c b/drivers/watchdog/wafer5823wdt.c index a8a1ed215e1e..291109349e73 100644 --- a/drivers/watchdog/wafer5823wdt.c +++ b/drivers/watchdog/wafer5823wdt.c @@ -227,7 +227,6 @@ static int wafwdt_notify_sys(struct notifier_block *this, unsigned long code, static const struct file_operations wafwdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = wafwdt_write, .unlocked_ioctl = wafwdt_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c index c00627825de8..d4fe0bc82211 100644 --- a/drivers/watchdog/wdrtas.c +++ b/drivers/watchdog/wdrtas.c @@ -469,7 +469,6 @@ static int wdrtas_reboot(struct notifier_block *this, static const struct file_operations wdrtas_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = wdrtas_write, .unlocked_ioctl = wdrtas_ioctl, .compat_ioctl = compat_ptr_ioctl, @@ -485,7 +484,6 @@ static struct miscdevice wdrtas_miscdev = { static const struct file_operations wdrtas_temp_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = wdrtas_temp_read, .open = wdrtas_temp_open, .release = wdrtas_temp_close, diff --git a/drivers/watchdog/wdt.c b/drivers/watchdog/wdt.c index 183876156243..3980d60bacd8 100644 --- a/drivers/watchdog/wdt.c +++ b/drivers/watchdog/wdt.c @@ -520,7 +520,6 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, static const struct file_operations wdt_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = wdt_write, .unlocked_ioctl = wdt_ioctl, .compat_ioctl = compat_ptr_ioctl, @@ -536,7 +535,6 @@ static struct miscdevice wdt_miscdev = { static const struct file_operations wdt_temp_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = wdt_temp_read, .open = wdt_temp_open, .release = wdt_temp_release, diff --git a/drivers/watchdog/wdt285.c b/drivers/watchdog/wdt285.c index 5b7be7a62d54..78681d9f7d53 100644 --- a/drivers/watchdog/wdt285.c +++ b/drivers/watchdog/wdt285.c @@ -178,7 +178,6 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, static const struct file_operations watchdog_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = watchdog_write, .unlocked_ioctl = watchdog_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/wdt977.c b/drivers/watchdog/wdt977.c index c9b8e863f70f..4f449ac4dda4 100644 --- a/drivers/watchdog/wdt977.c +++ b/drivers/watchdog/wdt977.c @@ -419,7 +419,6 @@ static int wdt977_notify_sys(struct notifier_block *this, unsigned long code, static const struct file_operations wdt977_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = wdt977_write, .unlocked_ioctl = wdt977_ioctl, .compat_ioctl = compat_ptr_ioctl, diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c index d5e56b601351..dc5f29560e9b 100644 --- a/drivers/watchdog/wdt_pci.c +++ b/drivers/watchdog/wdt_pci.c @@ -563,7 +563,6 @@ static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code, static const struct file_operations wdtpci_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = wdtpci_write, .unlocked_ioctl = wdtpci_ioctl, .compat_ioctl = compat_ptr_ioctl, @@ -579,7 +578,6 @@ static struct miscdevice wdtpci_miscdev = { static const struct file_operations wdtpci_temp_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = wdtpci_temp_read, .open = wdtpci_temp_open, .release = wdtpci_temp_release, diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index 9b7fcc7dbb38..7e4a13e632dc 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -694,7 +694,6 @@ static const struct file_operations evtchn_fops = { .fasync = evtchn_fasync, .open = evtchn_open, .release = evtchn_release, - .llseek = no_llseek, }; static struct miscdevice evtchn_miscdev = { diff --git a/drivers/xen/mcelog.c b/drivers/xen/mcelog.c index e9ac3b8c4167..4f65b641c054 100644 --- a/drivers/xen/mcelog.c +++ b/drivers/xen/mcelog.c @@ -182,7 +182,6 @@ static const struct file_operations xen_mce_chrdev_ops = { .read = xen_mce_chrdev_read, .poll = xen_mce_chrdev_poll, .unlocked_ioctl = xen_mce_chrdev_ioctl, - .llseek = no_llseek, }; static struct miscdevice xen_mce_chrdev_device = { diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c index 6f56640092a9..46f8916597e5 100644 --- a/drivers/xen/xenbus/xenbus_dev_frontend.c +++ b/drivers/xen/xenbus/xenbus_dev_frontend.c @@ -700,7 +700,6 @@ const struct file_operations xen_xenbus_fops = { .open = xenbus_file_open, .release = xenbus_file_release, .poll = xenbus_file_poll, - .llseek = no_llseek, }; EXPORT_SYMBOL_GPL(xen_xenbus_fops); diff --git a/fs/bcachefs/chardev.c b/fs/bcachefs/chardev.c index ef1f74866e23..cbfd88f98472 100644 --- a/fs/bcachefs/chardev.c +++ b/fs/bcachefs/chardev.c @@ -471,7 +471,6 @@ static ssize_t bch2_data_job_read(struct file *file, char __user *buf, static const struct file_operations bcachefs_data_ops = { .release = bch2_data_job_release, .read = bch2_data_job_read, - .llseek = no_llseek, }; static long bch2_ioctl_data(struct bch_fs *c, diff --git a/fs/bcachefs/thread_with_file.c b/fs/bcachefs/thread_with_file.c index fb3442a7c67f..dea73bc1cb51 100644 --- a/fs/bcachefs/thread_with_file.c +++ b/fs/bcachefs/thread_with_file.c @@ -275,7 +275,6 @@ static long thread_with_stdio_ioctl(struct file *file, unsigned int cmd, unsigne } static const struct file_operations thread_with_stdio_fops = { - .llseek = no_llseek, .read = thread_with_stdio_read, .write = thread_with_stdio_write, .poll = thread_with_stdio_poll, @@ -285,7 +284,6 @@ static const struct file_operations thread_with_stdio_fops = { }; static const struct file_operations thread_with_stdout_fops = { - .llseek = no_llseek, .read = thread_with_stdio_read, .poll = thread_with_stdout_poll, .flush = thread_with_stdio_flush, diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index c6f4a9a98b85..67299e8b734e 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -1218,7 +1218,6 @@ static const struct file_operations u32_array_fops = { .open = u32_array_open, .release = u32_array_release, .read = u32_array_read, - .llseek = no_llseek, }; /** diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c index 7112958c2e5b..700a0cbb2f14 100644 --- a/fs/dlm/debug_fs.c +++ b/fs/dlm/debug_fs.c @@ -733,7 +733,6 @@ out: static const struct file_operations dlm_rawmsg_fops = { .open = simple_open, .write = dlm_rawmsg_write, - .llseek = no_llseek, }; void *dlm_create_debug_comms_file(int nodeid, void *data) diff --git a/fs/efivarfs/file.c b/fs/efivarfs/file.c index 7e9961639802..23c51d62f902 100644 --- a/fs/efivarfs/file.c +++ b/fs/efivarfs/file.c @@ -110,5 +110,4 @@ const struct file_operations efivarfs_file_operations = { .open = simple_open, .read = efivarfs_file_read, .write = efivarfs_file_write, - .llseek = no_llseek, }; diff --git a/fs/fsopen.c b/fs/fsopen.c index ee92ca58429e..6cef3deccded 100644 --- a/fs/fsopen.c +++ b/fs/fsopen.c @@ -78,7 +78,6 @@ static int fscontext_release(struct inode *inode, struct file *file) const struct file_operations fscontext_fops = { .read = fscontext_read, .release = fscontext_release, - .llseek = no_llseek, }; /* diff --git a/fs/fuse/control.c b/fs/fuse/control.c index 97ac994ff78f..2a730d88cc3b 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c @@ -183,27 +183,23 @@ out: static const struct file_operations fuse_ctl_abort_ops = { .open = nonseekable_open, .write = fuse_conn_abort_write, - .llseek = no_llseek, }; static const struct file_operations fuse_ctl_waiting_ops = { .open = nonseekable_open, .read = fuse_conn_waiting_read, - .llseek = no_llseek, }; static const struct file_operations fuse_conn_max_background_ops = { .open = nonseekable_open, .read = fuse_conn_max_background_read, .write = fuse_conn_max_background_write, - .llseek = no_llseek, }; static const struct file_operations fuse_conn_congestion_threshold_ops = { .open = nonseekable_open, .read = fuse_conn_congestion_threshold_read, .write = fuse_conn_congestion_threshold_write, - .llseek = no_llseek, }; static struct dentry *fuse_ctl_add_dentry(struct dentry *parent, diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 46ed30a4e0fc..1f64ae6d7a69 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -2456,7 +2456,6 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd, const struct file_operations fuse_dev_operations = { .owner = THIS_MODULE, .open = fuse_dev_open, - .llseek = no_llseek, .read_iter = fuse_dev_read, .splice_read = fuse_dev_splice_read, .write_iter = fuse_dev_write, diff --git a/fs/nsfs.c b/fs/nsfs.c index 67ee176b8824..c675fc40ce2d 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -22,7 +22,6 @@ static struct vfsmount *nsfs_mnt; static long ns_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg); static const struct file_operations ns_file_operations = { - .llseek = no_llseek, .unlocked_ioctl = ns_ioctl, .compat_ioctl = compat_ptr_ioctl, }; diff --git a/fs/pipe.c b/fs/pipe.c index 4083ba492cb6..12b22c2723b7 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -1231,7 +1231,6 @@ err: const struct file_operations pipefifo_fops = { .open = fifo_open, - .llseek = no_llseek, .read_iter = pipe_read, .write_iter = pipe_write, .poll = pipe_poll, diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index d91cec93d968..5cc69beaa62e 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c @@ -2807,7 +2807,6 @@ static const struct file_operations dfs_fops = { .read = dfs_file_read, .write = dfs_file_write, .owner = THIS_MODULE, - .llseek = no_llseek, }; /** @@ -2952,7 +2951,6 @@ static const struct file_operations dfs_global_fops = { .read = dfs_global_file_read, .write = dfs_global_file_write, .owner = THIS_MODULE, - .llseek = no_llseek, }; /** diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index c9c65b132c0f..0928a6c8ae1e 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -57,7 +57,6 @@ static const struct file_operations __fops = { \ .release = simple_attr_release, \ .read = debugfs_attr_read, \ .write = (__is_signed) ? debugfs_attr_write_signed : debugfs_attr_write, \ - .llseek = no_llseek, \ } #define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \ diff --git a/include/linux/fs.h b/include/linux/fs.h index eae5b67e4a15..e3c603d01337 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3234,7 +3234,6 @@ extern ssize_t iter_file_splice_write(struct pipe_inode_info *, extern void file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); extern loff_t noop_llseek(struct file *file, loff_t offset, int whence); -#define no_llseek NULL extern loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize); extern loff_t generic_file_llseek(struct file *file, loff_t offset, int whence); extern loff_t generic_file_llseek_size(struct file *file, loff_t offset, diff --git a/kernel/bpf/bpf_iter.c b/kernel/bpf/bpf_iter.c index 112581cf97e7..106735145948 100644 --- a/kernel/bpf/bpf_iter.c +++ b/kernel/bpf/bpf_iter.c @@ -283,7 +283,6 @@ static int iter_release(struct inode *inode, struct file *file) const struct file_operations bpf_iter_fops = { .open = iter_open, - .llseek = no_llseek, .read = bpf_seq_read, .release = iter_release, }; diff --git a/kernel/events/core.c b/kernel/events/core.c index 5a8071c45c80..e3589c4287cb 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6821,7 +6821,6 @@ static int perf_fasync(int fd, struct file *filp, int on) } static const struct file_operations perf_fops = { - .llseek = no_llseek, .release = perf_release, .read = perf_read, .poll = perf_poll, diff --git a/kernel/power/user.c b/kernel/power/user.c index 3aa41ba22129..3f9e3efb9f6e 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -447,7 +447,6 @@ static const struct file_operations snapshot_fops = { .release = snapshot_release, .read = snapshot_read, .write = snapshot_write, - .llseek = no_llseek, .unlocked_ioctl = snapshot_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = snapshot_compat_ioctl, diff --git a/kernel/relay.c b/kernel/relay.c index a8e90e98bf2c..a8ae436dc77e 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -1079,7 +1079,6 @@ const struct file_operations relay_file_operations = { .poll = relay_file_poll, .mmap = relay_file_mmap, .read = relay_file_read, - .llseek = no_llseek, .release = relay_file_release, }; EXPORT_SYMBOL_GPL(relay_file_operations); diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c index 4782edcbe7b9..c2f3d0c490d5 100644 --- a/kernel/time/posix-clock.c +++ b/kernel/time/posix-clock.c @@ -168,7 +168,6 @@ static int posix_clock_release(struct inode *inode, struct file *fp) static const struct file_operations posix_clock_file_operations = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = posix_clock_read, .poll = posix_clock_poll, .unlocked_ioctl = posix_clock_ioctl, diff --git a/kernel/trace/rv/rv.c b/kernel/trace/rv/rv.c index df0745a42a3f..dc819aec43e8 100644 --- a/kernel/trace/rv/rv.c +++ b/kernel/trace/rv/rv.c @@ -306,7 +306,6 @@ static ssize_t monitor_enable_write_data(struct file *filp, const char __user *u static const struct file_operations interface_enable_fops = { .open = simple_open, - .llseek = no_llseek, .write = monitor_enable_write_data, .read = monitor_enable_read_data, }; @@ -329,7 +328,6 @@ static ssize_t monitor_desc_read_data(struct file *filp, char __user *user_buf, static const struct file_operations interface_desc_fops = { .open = simple_open, - .llseek = no_llseek, .read = monitor_desc_read_data, }; @@ -674,7 +672,6 @@ static ssize_t monitoring_on_write_data(struct file *filp, const char __user *us static const struct file_operations monitoring_on_fops = { .open = simple_open, - .llseek = no_llseek, .write = monitoring_on_write_data, .read = monitoring_on_read_data, }; diff --git a/kernel/trace/rv/rv_reactors.c b/kernel/trace/rv/rv_reactors.c index 6aae106695b6..7b49cbe388d4 100644 --- a/kernel/trace/rv/rv_reactors.c +++ b/kernel/trace/rv/rv_reactors.c @@ -426,7 +426,6 @@ static ssize_t reacting_on_write_data(struct file *filp, const char __user *user static const struct file_operations reacting_on_fops = { .open = simple_open, - .llseek = no_llseek, .write = reacting_on_write_data, .read = reacting_on_read_data, }; diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b4f348b4653f..c01375adc471 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -7557,7 +7557,6 @@ static const struct file_operations tracing_pipe_fops = { .read = tracing_read_pipe, .splice_read = tracing_splice_read_pipe, .release = tracing_release_pipe, - .llseek = no_llseek, }; static const struct file_operations tracing_entries_fops = { @@ -7636,7 +7635,6 @@ static const struct file_operations snapshot_raw_fops = { .read = tracing_buffers_read, .release = tracing_buffers_release, .splice_read = tracing_buffers_splice_read, - .llseek = no_llseek, }; #endif /* CONFIG_TRACER_SNAPSHOT */ @@ -8466,7 +8464,6 @@ static const struct file_operations tracing_buffers_fops = { .flush = tracing_buffers_flush, .splice_read = tracing_buffers_splice_read, .unlocked_ioctl = tracing_buffers_ioctl, - .llseek = no_llseek, .mmap = tracing_buffers_mmap, }; diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 0580ac9e47b9..3ca89e0279a7 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4115,7 +4115,6 @@ out: static const struct file_operations split_huge_pages_fops = { .owner = THIS_MODULE, .write = split_huge_pages_write, - .llseek = no_llseek, }; static int __init split_huge_pages_debugfs(void) diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c index 25b8a67a63a4..85149c774505 100644 --- a/net/mac80211/rc80211_minstrel_ht_debugfs.c +++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c @@ -187,7 +187,6 @@ static const struct file_operations minstrel_ht_stat_fops = { .open = minstrel_ht_stats_open, .read = minstrel_stats_read, .release = minstrel_stats_release, - .llseek = no_llseek, }; static char * @@ -323,7 +322,6 @@ static const struct file_operations minstrel_ht_stat_csv_fops = { .open = minstrel_ht_stats_csv_open, .read = minstrel_stats_read, .release = minstrel_stats_release, - .llseek = no_llseek, }; void diff --git a/net/rfkill/core.c b/net/rfkill/core.c index 13a5126bc36e..7d3e82e4c2fc 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c @@ -1394,7 +1394,6 @@ static const struct file_operations rfkill_fops = { .release = rfkill_fop_release, .unlocked_ioctl = rfkill_fop_ioctl, .compat_ioctl = compat_ptr_ioctl, - .llseek = no_llseek, }; #define RFKILL_NAME "rfkill" diff --git a/net/socket.c b/net/socket.c index 7b046dd3e9a7..601ad74930ef 100644 --- a/net/socket.c +++ b/net/socket.c @@ -153,7 +153,6 @@ static void sock_show_fdinfo(struct seq_file *m, struct file *f) static const struct file_operations socket_file_ops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read_iter = sock_read_iter, .write_iter = sock_write_iter, .poll = sock_poll, diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 4f31e73dc34d..1bd3e531b0e0 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -1592,7 +1592,6 @@ static int cache_release_procfs(struct inode *inode, struct file *filp) } static const struct proc_ops cache_channel_proc_ops = { - .proc_lseek = no_llseek, .proc_read = cache_read_procfs, .proc_write = cache_write_procfs, .proc_poll = cache_poll_procfs, @@ -1658,7 +1657,6 @@ static const struct proc_ops cache_flush_proc_ops = { .proc_read = read_flush_procfs, .proc_write = write_flush_procfs, .proc_release = release_flush_procfs, - .proc_lseek = no_llseek, }; static void remove_cache_proc_entries(struct cache_detail *cd) @@ -1811,7 +1809,6 @@ static int cache_release_pipefs(struct inode *inode, struct file *filp) const struct file_operations cache_file_operations_pipefs = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = cache_read_pipefs, .write = cache_write_pipefs, .poll = cache_poll_pipefs, @@ -1877,7 +1874,6 @@ const struct file_operations cache_flush_operations_pipefs = { .read = read_flush_pipefs, .write = write_flush_pipefs, .release = release_flush_pipefs, - .llseek = no_llseek, }; int sunrpc_cache_register_pipefs(struct dentry *parent, diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 910a5d850d04..7ce3721c06ca 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -385,7 +385,6 @@ rpc_pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) static const struct file_operations rpc_pipe_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = rpc_pipe_read, .write = rpc_pipe_write, .poll = rpc_pipe_poll, diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c index b382c696c877..59eefe2fed10 100644 --- a/samples/vfio-mdev/mtty.c +++ b/samples/vfio-mdev/mtty.c @@ -927,7 +927,6 @@ static const struct file_operations mtty_save_fops = { .unlocked_ioctl = mtty_precopy_ioctl, .compat_ioctl = compat_ptr_ioctl, .release = mtty_release_migf, - .llseek = no_llseek, }; static void mtty_save_state(struct mdev_state *mdev_state) @@ -1082,7 +1081,6 @@ static const struct file_operations mtty_resume_fops = { .owner = THIS_MODULE, .write = mtty_resume_write, .release = mtty_release_migf, - .llseek = no_llseek, }; static struct mtty_migration_file * diff --git a/scripts/coccinelle/api/stream_open.cocci b/scripts/coccinelle/api/stream_open.cocci index df00d6619b06..50ab60c81f13 100644 --- a/scripts/coccinelle/api/stream_open.cocci +++ b/scripts/coccinelle/api/stream_open.cocci @@ -131,7 +131,6 @@ identifier llseek_f; identifier fops0.fops; @@ struct file_operations fops = { - .llseek = no_llseek, }; @ has_noop_llseek @ diff --git a/sound/core/control.c b/sound/core/control.c index 4f55f64c42e1..2f790a7b1e90 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -2267,7 +2267,6 @@ static const struct file_operations snd_ctl_f_ops = .read = snd_ctl_read, .open = snd_ctl_open, .release = snd_ctl_release, - .llseek = no_llseek, .poll = snd_ctl_poll, .unlocked_ioctl = snd_ctl_ioctl, .compat_ioctl = snd_ctl_ioctl_compat, diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 33bf9a220ada..668604d0ec9d 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -412,7 +412,6 @@ static const struct file_operations snd_mixer_oss_f_ops = .owner = THIS_MODULE, .open = snd_mixer_oss_open, .release = snd_mixer_oss_release, - .llseek = no_llseek, .unlocked_ioctl = snd_mixer_oss_ioctl, .compat_ioctl = snd_mixer_oss_ioctl_compat, }; diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 7386982cf40e..4683b9139c56 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -3106,7 +3106,6 @@ static const struct file_operations snd_pcm_oss_f_reg = .write = snd_pcm_oss_write, .open = snd_pcm_oss_open, .release = snd_pcm_oss_release, - .llseek = no_llseek, .poll = snd_pcm_oss_poll, .unlocked_ioctl = snd_pcm_oss_ioctl, .compat_ioctl = snd_pcm_oss_ioctl_compat, diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 99e39b5359cc..5b9076829ade 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -4115,7 +4115,6 @@ const struct file_operations snd_pcm_f_ops[2] = { .write_iter = snd_pcm_writev, .open = snd_pcm_playback_open, .release = snd_pcm_release, - .llseek = no_llseek, .poll = snd_pcm_poll, .unlocked_ioctl = snd_pcm_ioctl, .compat_ioctl = snd_pcm_ioctl_compat, @@ -4129,7 +4128,6 @@ const struct file_operations snd_pcm_f_ops[2] = { .read_iter = snd_pcm_readv, .open = snd_pcm_capture_open, .release = snd_pcm_release, - .llseek = no_llseek, .poll = snd_pcm_poll, .unlocked_ioctl = snd_pcm_ioctl, .compat_ioctl = snd_pcm_ioctl_compat, diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 7accf9a1ddf4..03306be5fa02 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -1784,7 +1784,6 @@ static const struct file_operations snd_rawmidi_f_ops = { .write = snd_rawmidi_write, .open = snd_rawmidi_open, .release = snd_rawmidi_release, - .llseek = no_llseek, .poll = snd_rawmidi_poll, .unlocked_ioctl = snd_rawmidi_ioctl, .compat_ioctl = snd_rawmidi_ioctl_compat, diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 6437193e42bf..3930e2f9082f 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -2722,7 +2722,6 @@ static const struct file_operations snd_seq_f_ops = .write = snd_seq_write, .open = snd_seq_open, .release = snd_seq_release, - .llseek = no_llseek, .poll = snd_seq_poll, .unlocked_ioctl = snd_seq_ioctl, .compat_ioctl = snd_seq_ioctl_compat, diff --git a/sound/core/timer.c b/sound/core/timer.c index 668c40bac318..fbada79380f9 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -2436,7 +2436,6 @@ static const struct file_operations snd_timer_f_ops = .read = snd_timer_user_read, .open = snd_timer_user_open, .release = snd_timer_user_release, - .llseek = no_llseek, .poll = snd_timer_user_poll, .unlocked_ioctl = snd_timer_user_ioctl, .compat_ioctl = snd_timer_user_ioctl_compat, diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index 4b1baf4dd50e..dea2d9b18fc9 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -381,7 +381,6 @@ static long mixer_unlocked_ioctl(struct file *file, u_int cmd, u_long arg) static const struct file_operations mixer_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .unlocked_ioctl = mixer_unlocked_ioctl, .compat_ioctl = compat_ptr_ioctl, .open = mixer_open, @@ -1155,7 +1154,6 @@ static long sq_unlocked_ioctl(struct file *file, u_int cmd, u_long arg) static const struct file_operations sq_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = sq_write, .poll = sq_poll, .unlocked_ioctl = sq_unlocked_ioctl, @@ -1351,7 +1349,6 @@ static ssize_t state_read(struct file *file, char __user *buf, size_t count, static const struct file_operations state_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = state_read, .open = state_open, .release = state_release, diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c index 3fc2bbb63369..1767ded4d983 100644 --- a/sound/soc/intel/avs/debugfs.c +++ b/sound/soc/intel/avs/debugfs.c @@ -68,7 +68,6 @@ static ssize_t fw_regs_read(struct file *file, char __user *to, size_t count, lo static const struct file_operations fw_regs_fops = { .open = simple_open, .read = fw_regs_read, - .llseek = no_llseek, }; static ssize_t debug_window_read(struct file *file, char __user *to, size_t count, loff_t *ppos) @@ -93,7 +92,6 @@ static ssize_t debug_window_read(struct file *file, char __user *to, size_t coun static const struct file_operations debug_window_fops = { .open = simple_open, .read = debug_window_read, - .llseek = no_llseek, }; static ssize_t probe_points_read(struct file *file, char __user *to, size_t count, loff_t *ppos) @@ -170,7 +168,6 @@ static const struct file_operations probe_points_fops = { .open = simple_open, .read = probe_points_read, .write = probe_points_write, - .llseek = no_llseek, }; static ssize_t probe_points_disconnect_write(struct file *file, const char __user *from, diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f416d5e3f9c0..4f81366f8b61 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -6186,7 +6186,6 @@ static const struct file_operations stat_fops_per_vm = { .release = kvm_debugfs_release, .read = simple_attr_read, .write = simple_attr_write, - .llseek = no_llseek, }; static int vm_stat_get(void *_offset, u64 *val) -- cgit v1.2.3-70-g09d2 From 716bf84ef39218a56fadaa413f70da008ad85888 Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:18 +0800 Subject: coccinelle: Add rules to find str_true_false() replacements After str_true_false() has been introduced in the tree, we can add rules for finding places where str_true_false() can be used. A simple test can find over 10 locations. Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'scripts') diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index 5e729f187f22..6942ad7c4224 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -85,3 +85,22 @@ e << str_down_up_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_down_up(%s)" % e) + +@str_true_false depends on patch@ +expression E; +@@ +- ((E) ? "true" : "false") ++ str_true_false(E) + +@str_true_false_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "true" : "false") + +@script:python depends on report@ +p << str_true_false_r.P; +e << str_true_false_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_true_false(%s)" % e) -- cgit v1.2.3-70-g09d2 From 8a0236bab4d6f0761f29eae4d55d1ba32c1ecd47 Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:19 +0800 Subject: coccinelle: Add rules to find str_false_true() replacements As done with str_true_false(), add checks for str_false_true() opportunities. A simple test can find over 9 cases currently exist in the tree. Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'scripts') diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index 6942ad7c4224..c3c5bc94fab0 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -104,3 +104,22 @@ e << str_true_false_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_true_false(%s)" % e) + +@str_false_true depends on patch@ +expression E; +@@ +- ((E) ? "false" : "true") ++ str_false_true(E) + +@str_false_true_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "false" : "true") + +@script:python depends on report@ +p << str_false_true_r.P; +e << str_false_true_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_false_true(%s)" % e) -- cgit v1.2.3-70-g09d2 From d4c7544002db32dedbb162b2b89e655ac437ab08 Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:20 +0800 Subject: coccinelle: Add rules to find str_hi{gh}_lo{w}() replacements As other rules done, we add rules for str_hi{gh}_lo{w}() to check the relative opportunities. Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'scripts') diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index c3c5bc94fab0..7c631fd8abe2 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -123,3 +123,45 @@ e << str_false_true_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_false_true(%s)" % e) + +@str_hi_lo depends on patch@ +expression E; +@@ +( +- ((E) ? "hi" : "lo") ++ str_hi_lo(E) +) + +@str_hi_lo_r depends on !patch exists@ +expression E; +position P; +@@ +( +* ((E@P) ? "hi" : "lo") +) + +@script:python depends on report@ +p << str_hi_lo_r.P; +e << str_hi_lo_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_hi_lo(%s)" % e) + +@str_high_low depends on patch@ +expression E; +@@ +- ((E) ? "high" : "low") ++ str_high_low(E) + +@str_high_low_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "high" : "low") + +@script:python depends on report@ +p << str_high_low_r.P; +e << str_high_low_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_high_low(%s)" % e) -- cgit v1.2.3-70-g09d2 From 5b7ca4507d64de729011c145d8ee9a2731f9502f Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:21 +0800 Subject: coccinelle: Add rules to find str_lo{w}_hi{gh}() replacements As other rules done, we add rules for str_lo{w}_hi{gh}() to check the relative opportunities. Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'scripts') diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index 7c631fd8abe2..e91d4eb30161 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -165,3 +165,41 @@ e << str_high_low_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_high_low(%s)" % e) + +@str_lo_hi depends on patch@ +expression E; +@@ +- ((E) ? "lo" : "hi") ++ str_lo_hi(E) + +@str_lo_hi_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "lo" : "hi") + +@script:python depends on report@ +p << str_lo_hi_r.P; +e << str_lo_hi_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_lo_hi(%s)" % e) + +@str_low_high depends on patch@ +expression E; +@@ +- ((E) ? "low" : "high") ++ str_low_high(E) + +@str_low_high_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "low" : "high") + +@script:python depends on report@ +p << str_low_high_r.P; +e << str_low_high_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_low_high(%s)" % e) -- cgit v1.2.3-70-g09d2 From dd2275d349c2f02ceb6cd37f89b8b9920c602488 Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:22 +0800 Subject: coccinelle: Add rules to find str_enable{d}_disable{d}() replacements As other rules done, we add rules for str_enable{d}_ disable{d}() to check the relative opportunities. Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'scripts') diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index e91d4eb30161..bb6b851ee2aa 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -203,3 +203,41 @@ e << str_low_high_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_low_high(%s)" % e) + +@str_enable_disable depends on patch@ +expression E; +@@ +- ((E) ? "enable" : "disable") ++ str_enable_disable(E) + +@str_enable_disable_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "enable" : "disable") + +@script:python depends on report@ +p << str_enable_disable_r.P; +e << str_enable_disable_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_enable_disable(%s)" % e) + +@str_enabled_disabled depends on patch@ +expression E; +@@ +- ((E) ? "enabled" : "disabled") ++ str_enabled_disabled(E) + +@str_enabled_disabled_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "enabled" : "disabled") + +@script:python depends on report@ +p << str_enabled_disabled_r.P; +e << str_enabled_disabled_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_enabled_disabled(%s)" % e) -- cgit v1.2.3-70-g09d2 From ba4b514a6f4ac420d872b8f16245e3ffa05c10a5 Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:23 +0800 Subject: coccinelle: Add rules to find str_read_write() replacements As other rules done, we add rules for str_read_write() to check the relative opportunities. Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'scripts') diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index bb6b851ee2aa..29c507d86ffd 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -241,3 +241,22 @@ e << str_enabled_disabled_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_enabled_disabled(%s)" % e) + +@str_read_write depends on patch@ +expression E; +@@ +- ((E) ? "read" : "write") ++ str_read_write(E) + +@str_read_write_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "read" : "write") + +@script:python depends on report@ +p << str_read_write_r.P; +e << str_read_write_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_read_write(%s)" % e) -- cgit v1.2.3-70-g09d2 From c81ca023c30691dcae543bd770e7a3a4c63263ff Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:24 +0800 Subject: coccinelle: Add rules to find str_write_read() replacements As other rules done, we add rules for str_write_read() to check the relative opportunities. Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'scripts') diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index 29c507d86ffd..64f04da2e9f4 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -260,3 +260,22 @@ e << str_read_write_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_read_write(%s)" % e) + +@str_write_read depends on patch@ +expression E; +@@ +- ((E) ? "write" : "read") ++ str_write_read(E) + +@str_write_read_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "write" : "read") + +@script:python depends on report@ +p << str_write_read_r.P; +e << str_write_read_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_write_read(%s)" % e) -- cgit v1.2.3-70-g09d2 From 9b5b4810559d3716aef9fdc8d555e4db1a031749 Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:25 +0800 Subject: coccinelle: Add rules to find str_on_off() replacements As other rules done, we add rules for str_on_off() to check the relative opportunities. Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'scripts') diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index 64f04da2e9f4..34ff8f48965c 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -279,3 +279,22 @@ e << str_write_read_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_write_read(%s)" % e) + +@str_on_off depends on patch@ +expression E; +@@ +- ((E) ? "on" : "off") ++ str_on_off(E) + +@str_on_off_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "on" : "off") + +@script:python depends on report@ +p << str_on_off_r.P; +e << str_on_off_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_on_off(%s)" % e) -- cgit v1.2.3-70-g09d2 From 253244cdf16a755039f9078b0a785176712f2584 Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:26 +0800 Subject: coccinelle: Add rules to find str_yes_no() replacements As other rules done, we add rules for str_yes_no() to check the relative opportunities. Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'scripts') diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index 34ff8f48965c..96dc7090395d 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -298,3 +298,22 @@ e << str_on_off_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_on_off(%s)" % e) + +@str_yes_no depends on patch@ +expression E; +@@ +- ((E) ? "yes" : "no") ++ str_yes_no(E) + +@str_yes_no_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "yes" : "no") + +@script:python depends on report@ +p << str_yes_no_r.P; +e << str_yes_no_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_yes_no(%s)" % e) -- cgit v1.2.3-70-g09d2 From f584e3752ca7bb1f8849a85816b3c974f1aa67ec Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:27 +0800 Subject: coccinelle: Remove unnecessary parentheses for only one possible change. The parentheses are only needed if there is a disjunction, ie a set of possible changes. If there is only one pattern, we can remove these parentheses. Just like the format: - x + y not: ( - x + y ) Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 8 -------- 1 file changed, 8 deletions(-) (limited to 'scripts') diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index 96dc7090395d..95e9a3b31f86 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -43,18 +43,14 @@ coccilib.report.print_report(p[0], "opportunity for str_plural(%s)" % e) @str_up_down depends on patch@ expression E; @@ -( - ((E) ? "up" : "down") + str_up_down(E) -) @str_up_down_r depends on !patch exists@ expression E; position P; @@ -( * ((E@P) ? "up" : "down") -) @script:python depends on report@ p << str_up_down_r.P; @@ -66,18 +62,14 @@ coccilib.report.print_report(p[0], "opportunity for str_up_down(%s)" % e) @str_down_up depends on patch@ expression E; @@ -( - ((E) ? "down" : "up") + str_down_up(E) -) @str_down_up_r depends on !patch exists@ expression E; position P; @@ -( * ((E@P) ? "down" : "up") -) @script:python depends on report@ p << str_down_up_r.P; -- cgit v1.2.3-70-g09d2 From 4003ba664bd16f5a969cc883295a9eb5a5aef19e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 28 Sep 2024 21:26:22 +0200 Subject: Reduce Coccinelle choices in string_choices.cocci The isomorphism neg_if_exp negates the test of a ?: conditional, making it unnecessary to have an explicit case for a negated test with the branches inverted. At the same time, we can disable neg_if_exp in cases where a different API function may be more suitable for a negated test. Finally, in the non-patch cases, E matches an expression with parentheses around it, so there is no need to mention () explicitly in the pattern. The () are still needed in the patch cases, because we want to drop them, if they are present. Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 91 +++++++++++++---------------- 1 file changed, 41 insertions(+), 50 deletions(-) (limited to 'scripts') diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index 95e9a3b31f86..375045086912 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -14,23 +14,18 @@ expression E; - ((E == 1) ? "" : "s") + str_plural(E) | -- ((E != 1) ? "s" : "") -+ str_plural(E) -| - ((E > 1) ? "s" : "") + str_plural(E) ) -@str_plural_r depends on !patch exists@ +@str_plural_r depends on !patch@ expression E; position P; @@ ( -* ((E@P == 1) ? "" : "s") +* (E@P == 1) ? "" : "s" | -* ((E@P != 1) ? "s" : "") -| -* ((E@P > 1) ? "s" : "") +* (E@P > 1) ? "s" : "" ) @script:python depends on report@ @@ -40,17 +35,17 @@ e << str_plural_r.E; coccilib.report.print_report(p[0], "opportunity for str_plural(%s)" % e) -@str_up_down depends on patch@ +@str_up_down depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "up" : "down") + str_up_down(E) -@str_up_down_r depends on !patch exists@ +@str_up_down_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "up" : "down") +* E@P ? "up" : "down" @script:python depends on report@ p << str_up_down_r.P; @@ -59,17 +54,17 @@ e << str_up_down_r.E; coccilib.report.print_report(p[0], "opportunity for str_up_down(%s)" % e) -@str_down_up depends on patch@ +@str_down_up depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "down" : "up") + str_down_up(E) -@str_down_up_r depends on !patch exists@ +@str_down_up_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "down" : "up") +* E@P ? "down" : "up" @script:python depends on report@ p << str_down_up_r.P; @@ -78,17 +73,17 @@ e << str_down_up_r.E; coccilib.report.print_report(p[0], "opportunity for str_down_up(%s)" % e) -@str_true_false depends on patch@ +@str_true_false depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "true" : "false") + str_true_false(E) -@str_true_false_r depends on !patch exists@ +@str_true_false_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "true" : "false") +* E@P ? "true" : "false" @script:python depends on report@ p << str_true_false_r.P; @@ -97,17 +92,17 @@ e << str_true_false_r.E; coccilib.report.print_report(p[0], "opportunity for str_true_false(%s)" % e) -@str_false_true depends on patch@ +@str_false_true depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "false" : "true") + str_false_true(E) -@str_false_true_r depends on !patch exists@ +@str_false_true_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "false" : "true") +* E@P ? "false" : "true" @script:python depends on report@ p << str_false_true_r.P; @@ -116,21 +111,17 @@ e << str_false_true_r.E; coccilib.report.print_report(p[0], "opportunity for str_false_true(%s)" % e) -@str_hi_lo depends on patch@ +@str_hi_lo depends on patch disable neg_if_exp@ expression E; @@ -( - ((E) ? "hi" : "lo") + str_hi_lo(E) -) -@str_hi_lo_r depends on !patch exists@ +@str_hi_lo_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -( -* ((E@P) ? "hi" : "lo") -) +* E@P ? "hi" : "lo" @script:python depends on report@ p << str_hi_lo_r.P; @@ -139,17 +130,17 @@ e << str_hi_lo_r.E; coccilib.report.print_report(p[0], "opportunity for str_hi_lo(%s)" % e) -@str_high_low depends on patch@ +@str_high_low depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "high" : "low") + str_high_low(E) -@str_high_low_r depends on !patch exists@ +@str_high_low_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "high" : "low") +* E@P ? "high" : "low" @script:python depends on report@ p << str_high_low_r.P; @@ -158,17 +149,17 @@ e << str_high_low_r.E; coccilib.report.print_report(p[0], "opportunity for str_high_low(%s)" % e) -@str_lo_hi depends on patch@ +@str_lo_hi depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "lo" : "hi") + str_lo_hi(E) -@str_lo_hi_r depends on !patch exists@ +@str_lo_hi_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "lo" : "hi") +* E@P ? "lo" : "hi" @script:python depends on report@ p << str_lo_hi_r.P; @@ -177,17 +168,17 @@ e << str_lo_hi_r.E; coccilib.report.print_report(p[0], "opportunity for str_lo_hi(%s)" % e) -@str_low_high depends on patch@ +@str_low_high depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "low" : "high") + str_low_high(E) -@str_low_high_r depends on !patch exists@ +@str_low_high_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "low" : "high") +* E@P ? "low" : "high" @script:python depends on report@ p << str_low_high_r.P; @@ -202,11 +193,11 @@ expression E; - ((E) ? "enable" : "disable") + str_enable_disable(E) -@str_enable_disable_r depends on !patch exists@ +@str_enable_disable_r depends on !patch@ expression E; position P; @@ -* ((E@P) ? "enable" : "disable") +* E@P ? "enable" : "disable" @script:python depends on report@ p << str_enable_disable_r.P; @@ -221,11 +212,11 @@ expression E; - ((E) ? "enabled" : "disabled") + str_enabled_disabled(E) -@str_enabled_disabled_r depends on !patch exists@ +@str_enabled_disabled_r depends on !patch@ expression E; position P; @@ -* ((E@P) ? "enabled" : "disabled") +* E@P ? "enabled" : "disabled" @script:python depends on report@ p << str_enabled_disabled_r.P; @@ -234,17 +225,17 @@ e << str_enabled_disabled_r.E; coccilib.report.print_report(p[0], "opportunity for str_enabled_disabled(%s)" % e) -@str_read_write depends on patch@ +@str_read_write depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "read" : "write") + str_read_write(E) -@str_read_write_r depends on !patch exists@ +@str_read_write_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "read" : "write") +* E@P ? "read" : "write" @script:python depends on report@ p << str_read_write_r.P; @@ -253,17 +244,17 @@ e << str_read_write_r.E; coccilib.report.print_report(p[0], "opportunity for str_read_write(%s)" % e) -@str_write_read depends on patch@ +@str_write_read depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "write" : "read") + str_write_read(E) -@str_write_read_r depends on !patch exists@ +@str_write_read_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "write" : "read") +* E@P ? "write" : "read" @script:python depends on report@ p << str_write_read_r.P; @@ -278,11 +269,11 @@ expression E; - ((E) ? "on" : "off") + str_on_off(E) -@str_on_off_r depends on !patch exists@ +@str_on_off_r depends on !patch@ expression E; position P; @@ -* ((E@P) ? "on" : "off") +* E@P ? "on" : "off" @script:python depends on report@ p << str_on_off_r.P; @@ -297,11 +288,11 @@ expression E; - ((E) ? "yes" : "no") + str_yes_no(E) -@str_yes_no_r depends on !patch exists@ +@str_yes_no_r depends on !patch@ expression E; position P; @@ -* ((E@P) ? "yes" : "no") +* E@P ? "yes" : "no" @script:python depends on report@ p << str_yes_no_r.P; -- cgit v1.2.3-70-g09d2