6.1.167-rc1 review
Subsystems (6)
Greg Kroah-Hartman
maintainerPATCH 113/481 kunit: kunit.py extract handlers
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Pantyukhin <[email protected]>
[ Upstream commit 2dc9d6ca52a47fd00822e818c2a5e48fc5fbbd53 ]
The main function contains a wide if-elif block that handles different subcommands. It's possible to make code refactoring to extract subcommands handlers.
Fixed commit summary line.
Shuah Khan <[email protected]>
Stable-dep-of: 40804c4974b8 ("kunit: tool: copy caller args in run_kernel to prevent mutation")
--- tools/testing/kunit/kunit.py | 167 ++++++++++++++++++++--------------- 1 file changed, 96 insertions(+), 71 deletions(-)
tools/testing/kunit/kunit.py +96 -71
@@ -395,6 +395,95 @@ def tree_from_args(cli_args: argparse.Namespace) -> kunit_kernel.LinuxSourceTree extra_qemu_args=qemu_args) +def run_handler(cli_args): + if not os.path.exists(cli_args.build_dir): + os.mkdir(cli_args.build_dir) + + linux = tree_from_args(cli_args) + request = KunitRequest(build_dir=cli_args.build_dir, + make_options=cli_args.make_options, + jobs=cli_args.jobs, + raw_output=cli_args.raw_output, + json=cli_args.json, + timeout=cli_args.timeout, + filter_glob=cli_args.filter_glob, + kernel_args=cli_args.kernel_args, + run_isolated=cli_args.run_isolated) + result = run_tests(linux, request) + if result.status != KunitStatus.SUCCESS: + sys.exit(1) + + +def config_handler(cli_args): + if cli_args.build_dir and ( + not os.path.exists(cli_args.build_dir)): + os.mkdir(cli_args.build_dir) + + linux = tree_from_args(cli_args) + request = KunitConfigRequest(build_dir=cli_args.build_dir, + make_options=cli_args.make_options) + result = config_tests(linux, request) + stdout.print_with_timestamp(( + 'Elapsed time: %.3fs\n') % ( + result.elapsed_time)) + if result.status != KunitStatus.SUCCESS: + sys.exit(1) + + +def build_handler(cli_args): + linux = tree_from_args(cli_args) + request = KunitBuildRequest(build_dir=cli_args.build_dir, + make_options=cli_args.make_options, + jobs=cli_args.jobs) + result = config_and_build_tests(linux, request) + stdout.print_with_timestamp(( + 'Elapsed time: %.3fs\n') % ( + result.elapsed_time)) + if result.status != KunitStatus.SUCCESS: + sys.exit(1) + + +def exec_handler(cli_args): + linux = tree_from_args(cli_args) + exec_request = KunitExecRequest(raw_output=cli_args.raw_output, + build_dir=cli_args.build_dir, + json=cli_args.json, + timeout=cli_args.timeout, + filter_glob=cli_args.filter_glob, + kernel_args=cli_args.kernel_args, + run_isolated=cli_args.run_isolated) + result = exec_tests(linux, exec_request) + stdout.print_with_timestamp(( + 'Elapsed time: %.3fs\n') % (result.elapsed_time)) + if result.status != KunitStatus.SUCCESS: + sys.exit(1) + + +def parse_handler(cli_args): + if cli_args.file is None: + sys.stdin.reconfigure(errors='backslashreplace') # pytype: disable=attribute-error + kunit_output = sys.stdin + else: + with open(cli_args.file, 'r', errors='backslashreplace') as f: + kunit_output = f.read().splitlines() + # We know nothing about how the result was created! + metadata = kunit_json.Metadata() + request = KunitParseRequest(raw_output=cli_args.raw_output, + json=cli_args.json) + result, _ = parse_tests(request, metadata, kunit_output) + if result.status != KunitStatus.SUCCESS: + sys.exit(1) + + +subcommand_handlers_map = { + 'run': run_handler, + 'config': config_handler, + 'build': build_handler, + 'exec': exec_handler, + 'parse': parse_handler +} + + def main(argv): parser = argparse.ArgumentParser( description='Helps writing and running KUnit tests.')
@@ -438,78 +527,14 @@ def main(argv): if get_kernel_root_path(): os.chdir(get_kernel_root_path()) - if cli_args.subcommand == 'run': - if not os.path.exists(cli_args.build_dir): - os.mkdir(cli_args.build_dir) - - linux = tree_from_args(cli_args) - request = KunitRequest(build_dir=cli_args.build_dir, - make_options=cli_args.make_options, - jobs=cli_args.jobs, - raw_output=cli_args.raw_output, - json=cli_args.json, - timeout=cli_args.timeout, - filter_glob=cli_args.filter_glob, - kernel_args=cli_args.kernel_args, - run_isolated=cli_args.run_isolated) - result = run_tests(linux, request) - if result.status != KunitStatus.SUCCESS: - sys.exit(1) - elif cli_args.subcommand == 'config': - if cli_args.build_dir and ( - not os.path.exists(cli_args.build_dir)): - os.mkdir(cli_args.build_dir) - - linux = tree_from_args(cli_args) - request = KunitConfigRequest(build_dir=cli_args.build_dir, - make_options=cli_args.make_options) - result = config_tests(linux, request) - stdout.print_with_timestamp(( - 'Elapsed time: %.3fs\n') % ( - result.elapsed_time)) - if result.status != KunitStatus.SUCCESS: - sys.exit(1) - elif cli_args.subcommand == 'build': - linux = tree_from_args(cli_args) - request = KunitBuildRequest(build_dir=cli_args.build_dir, - make_options=cli_args.make_options, - jobs=cli_args.jobs) - result = config_and_build_tests(linux, request) - stdout.print_with_timestamp(( - 'Elapsed time: %.3fs\n') % ( - result.elapsed_time)) - if result.status != KunitStatus.SUCCESS: - sys.exit(1) - elif cli_args.subcommand == 'exec': - linux = tree_from_args(cli_args) - exec_request = KunitExecRequest(raw_output=cli_args.raw_output, - build_dir=cli_args.build_dir, - json=cli_args.json, - timeout=cli_args.timeout, - filter_glob=cli_args.filter_glob, - kernel_args=cli_args.kernel_args, - run_isolated=cli_args.run_isolated) - result = exec_tests(linux, exec_request) - stdout.print_with_timestamp(( - 'Elapsed time: %.3fs\n') % (result.elapsed_time)) - if result.status != KunitStatus.SUCCESS: - sys.exit(1) - elif cli_args.subcommand == 'parse': - if cli_args.file is None: - sys.stdin.reconfigure(errors='backslashreplace') # pytype: disable=attribute-error - kunit_output = sys.stdin - else: - with open(cli_args.file, 'r', errors='backslashreplace') as f: - kunit_output = f.read().splitlines() - # We know nothing about how the result was created! - metadata = kunit_json.Metadata() - request = KunitParseRequest(raw_output=cli_args.raw_output, - json=cli_args.json) - result, _ = parse_tests(request, metadata, kunit_output) - if result.status != KunitStatus.SUCCESS: - sys.exit(1) - else: + subcomand_handler = subcommand_handlers_map.get(cli_args.subcommand, None) + + if subcomand_handler is None: parser.print_help() + return + + subcomand_handler(cli_args) + if __name__ == '__main__': main(sys.argv[1:])
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 114/481 kunit: tool: remove unused imports and variables
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Latypov <[email protected]>
[ Upstream commit 126901ba3499880c9ed033633817cf7493120fda ]
We don't run a linter regularly over kunit.py code (the default settings on most don't like kernel style, e.g. tabs) so some of these imports didn't get removed when they stopped being used.
Stable-dep-of: 40804c4974b8 ("kunit: tool: copy caller args in run_kernel to prevent mutation")
--- tools/testing/kunit/kunit.py | 2 +- tools/testing/kunit/kunit_config.py | 2 +- tools/testing/kunit/kunit_kernel.py | 1 - tools/testing/kunit/kunit_parser.py | 1 - tools/testing/kunit/kunit_tool_test.py | 2 +- 5 files changed, 3 insertions(+), 5 deletions(-)
tools/testing/kunit/kunit.py +1 -1
@@ -132,7 +132,7 @@ def _suites_from_test_list(tests: List[str]) -> List[str]: parts = t.split('.', maxsplit=2) if len(parts) != 2: raise ValueError(f'internal KUnit error, test name should be of the form "<suite>.<test>", got "{t}"') - suite, case = parts + suite, _ = parts if not suites or suites[-1] != suite: suites.append(suite) return suites
tools/testing/kunit/kunit_config.py +1 -1
@@ -8,7 +8,7 @@ from dataclasses import dataclass import re -from typing import Dict, Iterable, List, Set, Tuple +from typing import Dict, Iterable, List, Tuple CONFIG_IS_NOT_SET_PATTERN = r'^# CONFIG_(\w+) is not set$' CONFIG_PATTERN = r'^CONFIG_(\w+)=(\S+|".*")$'
tools/testing/kunit/kunit_kernel.py +0 -1
@@ -18,7 +18,6 @@ import threading from typing import Iterator, List, Optional, Tuple import kunit_config -from kunit_printer import stdout import qemu_config KCONFIG_PATH = '.config'
tools/testing/kunit/kunit_parser.py +0 -1
@@ -11,7 +11,6 @@ from __future__ import annotations import re -import sys import textwrap from enum import Enum, auto
tools/testing/kunit/kunit_tool_test.py +1 -1
@@ -346,7 +346,7 @@ class KUnitParserTest(unittest.TestCase): def test_parse_subtest_header(self): ktap_log = test_data_path('test_parse_subtest_header.log') with open(ktap_log) as file: - result = kunit_parser.parse_run_tests(file.readlines()) + kunit_parser.parse_run_tests(file.readlines()) self.print_mock.assert_any_call(StrContains('suite (1 subtest)')) def test_show_test_output_on_failure(self):
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 115/481 kunit: tool: fix pre-existing `mypy --strict` errors and update run_checks.py
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Latypov <[email protected]>
[ Upstream commit 1da2e6220e1115930694c649605534baf6fa3dea ]
Basically, get this command to be happy and make run_checks.py happy
$ mypy --strict --exclude '_test.py$' --exclude qemu_configs/ ./tools/testing/kunit/
Primarily the changes are
* add -> None return type annotations
* add all the missing argument type annotations
Previously, we had false positives from mypy in main(), see commit 09641f7c7d8f ("kunit: tool: surface and address more typing issues"). But after commit 2dc9d6ca52a4 ("kunit: kunit.py extract handlers") refactored things, the variable name reuse mypy hated is gone.
Note: mypy complains we don't annotate the types the unused args in our signal handler. That's silly.
But to make it happy, I've copy-pasted an appropriate annotation from
https://github.com/python/typing/discussions/1042#discussioncomment-2013595.
Stable-dep-of: 40804c4974b8 ("kunit: tool: copy caller args in run_kernel to prevent mutation")
--- tools/testing/kunit/kunit.py | 24 ++++++++++++------------ tools/testing/kunit/kunit_config.py | 4 ++-- tools/testing/kunit/kunit_kernel.py | 29 +++++++++++++++-------------- tools/testing/kunit/run_checks.py | 4 ++-- 4 files changed, 31 insertions(+), 30 deletions(-)
tools/testing/kunit/kunit.py +12 -12
@@ -278,7 +278,7 @@ def massage_argv(argv: Sequence[str]) -> Sequence[str]: def get_default_jobs() -> int: return len(os.sched_getaffinity(0)) -def add_common_opts(parser) -> None: +def add_common_opts(parser: argparse.ArgumentParser) -> None: parser.add_argument('--build_dir', help='As in the make command, it specifies the build ' 'directory.',
@@ -329,13 +329,13 @@ def add_common_opts(parser) -> None: help='Additional QEMU arguments, e.g. "-smp 8"', action='append', metavar='') -def add_build_opts(parser) -> None: +def add_build_opts(parser: argparse.ArgumentParser) -> None: parser.add_argument('--jobs', help='As in the make command, "Specifies the number of ' 'jobs (commands) to run simultaneously."', type=int, default=get_default_jobs(), metavar='N') -def add_exec_opts(parser) -> None: +def add_exec_opts(parser: argparse.ArgumentParser) -> None: parser.add_argument('--timeout', help='maximum number of seconds to allow for all tests ' 'to run. This does not include time taken to build the '
@@ -360,7 +360,7 @@ def add_exec_opts(parser) -> None: type=str, choices=['suite', 'test']) -def add_parse_opts(parser) -> None: +def add_parse_opts(parser: argparse.ArgumentParser) -> None: parser.add_argument('--raw_output', help='If set don\'t parse output from kernel. ' 'By default, filters to just KUnit output. Use ' '--raw_output=all to show everything',
@@ -395,7 +395,7 @@ def tree_from_args(cli_args: argparse.Namespace) -> kunit_kernel.LinuxSourceTree extra_qemu_args=qemu_args) -def run_handler(cli_args): +def run_handler(cli_args: argparse.Namespace) -> None: if not os.path.exists(cli_args.build_dir): os.mkdir(cli_args.build_dir)
@@ -414,7 +414,7 @@ def run_handler(cli_args): sys.exit(1) -def config_handler(cli_args): +def config_handler(cli_args: argparse.Namespace) -> None: if cli_args.build_dir and ( not os.path.exists(cli_args.build_dir)): os.mkdir(cli_args.build_dir)
@@ -430,7 +430,7 @@ def config_handler(cli_args): sys.exit(1) -def build_handler(cli_args): +def build_handler(cli_args: argparse.Namespace) -> None: linux = tree_from_args(cli_args) request = KunitBuildRequest(build_dir=cli_args.build_dir, make_options=cli_args.make_options,
@@ -443,7 +443,7 @@ def build_handler(cli_args): sys.exit(1) -def exec_handler(cli_args): +def exec_handler(cli_args: argparse.Namespace) -> None: linux = tree_from_args(cli_args) exec_request = KunitExecRequest(raw_output=cli_args.raw_output, build_dir=cli_args.build_dir,
@@ -459,10 +459,10 @@ def exec_handler(cli_args): sys.exit(1) -def parse_handler(cli_args): +def parse_handler(cli_args: argparse.Namespace) -> None: if cli_args.file is None: - sys.stdin.reconfigure(errors='backslashreplace') # pytype: disable=attribute-error - kunit_output = sys.stdin + sys.stdin.reconfigure(errors='backslashreplace') # type: ignore + kunit_output = sys.stdin # type: Iterable[str] else: with open(cli_args.file, 'r', errors='backslashreplace') as f: kunit_output = f.read().splitlines()
@@ -484,7 +484,7 @@ subcommand_handlers_map = { } -def main(argv): +def main(argv: Sequence[str]) -> None: parser = argparse.ArgumentParser( description='Helps writing and running KUnit tests.') subparser = parser.add_subparsers(dest='subcommand')
tools/testing/kunit/kunit_config.py +2 -2
@@ -8,7 +8,7 @@ from dataclasses import dataclass import re -from typing import Dict, Iterable, List, Tuple +from typing import Any, Dict, Iterable, List, Tuple CONFIG_IS_NOT_SET_PATTERN = r'^# CONFIG_(\w+) is not set$' CONFIG_PATTERN = r'^CONFIG_(\w+)=(\S+|".*")$'
@@ -34,7 +34,7 @@ class Kconfig: def __init__(self) -> None: self._entries = {} # type: Dict[str, str] - def __eq__(self, other) -> bool: + def __eq__(self, other: Any) -> bool: if not isinstance(other, self.__class__): return False return self._entries == other._entries
tools/testing/kunit/kunit_kernel.py +15 -14
@@ -16,6 +16,7 @@ import shutil import signal import threading from typing import Iterator, List, Optional, Tuple +from types import FrameType import kunit_config import qemu_config
@@ -56,7 +57,7 @@ class LinuxSourceTreeOperations: def make_arch_config(self, base_kunitconfig: kunit_config.Kconfig) -> kunit_config.Kconfig: return base_kunitconfig - def make_olddefconfig(self, build_dir: str, make_options) -> None: + def make_olddefconfig(self, build_dir: str, make_options: Optional[List[str]]) -> None: command = ['make', 'ARCH=' + self._linux_arch, 'O=' + build_dir, 'olddefconfig'] if self._cross_compile: command += ['CROSS_COMPILE=' + self._cross_compile]
@@ -70,7 +71,7 @@ class LinuxSourceTreeOperations: except subprocess.CalledProcessError as e: raise ConfigError(e.output.decode()) - def make(self, jobs, build_dir: str, make_options) -> None: + def make(self, jobs: int, build_dir: str, make_options: Optional[List[str]]) -> None: command = ['make', 'ARCH=' + self._linux_arch, 'O=' + build_dir, '--jobs=' + str(jobs)] if make_options: command.extend(make_options)
@@ -132,7 +133,7 @@ class LinuxSourceTreeOperationsQemu(LinuxSourceTreeOperations): class LinuxSourceTreeOperationsUml(LinuxSourceTreeOperations): """An abstraction over command line operations performed on a source tree.""" - def __init__(self, cross_compile=None): + def __init__(self, cross_compile: Optional[str]=None): super().__init__(linux_arch='um', cross_compile=cross_compile) def make_arch_config(self, base_kunitconfig: kunit_config.Kconfig) -> kunit_config.Kconfig:
@@ -215,7 +216,7 @@ def _get_qemu_ops(config_path: str, if not hasattr(config, 'QEMU_ARCH'): raise ValueError('qemu_config module missing "QEMU_ARCH": ' + config_path) - params: qemu_config.QemuArchParams = config.QEMU_ARCH # type: ignore + params: qemu_config.QemuArchParams = config.QEMU_ARCH if extra_qemu_args: params.extra_qemu_params.extend(extra_qemu_args) return params.linux_arch, LinuxSourceTreeOperationsQemu(
@@ -229,10 +230,10 @@ class LinuxSourceTree: build_dir: str, kunitconfig_paths: Optional[List[str]]=None, kconfig_add: Optional[List[str]]=None, - arch=None, - cross_compile=None, - qemu_config_path=None, - extra_qemu_args=None) -> None: + arch: Optional[str]=None, + cross_compile: Optional[str]=None, + qemu_config_path: Optional[str]=None, + extra_qemu_args: Optional[List[str]]=None) -> None: signal.signal(signal.SIGINT, self.signal_handler) if qemu_config_path: self._arch, self._ops = _get_qemu_ops(qemu_config_path, extra_qemu_args, cross_compile)
@@ -275,7 +276,7 @@ class LinuxSourceTree: logging.error(message) return False - def build_config(self, build_dir: str, make_options) -> bool: + def build_config(self, build_dir: str, make_options: Optional[List[str]]) -> bool: kconfig_path = get_kconfig_path(build_dir) if build_dir and not os.path.exists(build_dir): os.mkdir(build_dir)
@@ -303,7 +304,7 @@ class LinuxSourceTree: old_kconfig = kunit_config.parse_file(old_path) return old_kconfig != self._kconfig - def build_reconfig(self, build_dir: str, make_options) -> bool: + def build_reconfig(self, build_dir: str, make_options: Optional[List[str]]) -> bool: """Creates a new .config if it is not a subset of the .kunitconfig.""" kconfig_path = get_kconfig_path(build_dir) if not os.path.exists(kconfig_path):
@@ -319,7 +320,7 @@ class LinuxSourceTree: os.remove(kconfig_path) return self.build_config(build_dir, make_options) - def build_kernel(self, jobs, build_dir: str, make_options) -> bool: + def build_kernel(self, jobs: int, build_dir: str, make_options: Optional[List[str]]) -> bool: try: self._ops.make_olddefconfig(build_dir, make_options) self._ops.make(jobs, build_dir, make_options)
@@ -328,7 +329,7 @@ class LinuxSourceTree: return False return self.validate_config(build_dir) - def run_kernel(self, args=None, build_dir='', filter_glob='', timeout=None) -> Iterator[str]: + def run_kernel(self, args: Optional[List[str]]=None, build_dir: str='', filter_glob: str='', timeout: Optional[int]=None) -> Iterator[str]: if not args: args = [] if filter_glob:
@@ -339,7 +340,7 @@ class LinuxSourceTree: assert process.stdout is not None # tell mypy it's set # Enforce the timeout in a background thread. - def _wait_proc(): + def _wait_proc() -> None: try: process.wait(timeout=timeout) except Exception as e:
@@ -365,6 +366,6 @@ class LinuxSourceTree: waiter.join() subprocess.call(['stty', 'sane']) - def signal_handler(self, unused_sig, unused_frame) -> None: + def signal_handler(self, unused_sig: int, unused_frame: Optional[FrameType]) -> None: logging.error('Build interruption occurred. Cleaning console.') subprocess.call(['stty', 'sane'])
tools/testing/kunit/run_checks.py +2 -2
@@ -23,7 +23,7 @@ commands: Dict[str, Sequence[str]] = { 'kunit_tool_test.py': ['./kunit_tool_test.py'], 'kunit smoke test': ['./kunit.py', 'run', '--kunitconfig=lib/kunit', '--build_dir=kunit_run_checks'], 'pytype': ['/bin/sh', '-c', 'pytype *.py'], - 'mypy': ['/bin/sh', '-c', 'mypy *.py'], + 'mypy': ['mypy', '--strict', '--exclude', '_test.py$', '--exclude', 'qemu_configs/', '.'], } # The user might not have mypy or pytype installed, skip them if so.
@@ -73,7 +73,7 @@ def main(argv: Sequence[str]) -> None: sys.exit(1) -def run_cmd(argv: Sequence[str]): +def run_cmd(argv: Sequence[str]) -> None: subprocess.check_output(argv, stderr=subprocess.STDOUT, cwd=ABS_TOOL_PATH, timeout=TIMEOUT)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 116/481 kunit: tool: Add command line interface to filter and report attributes
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rae Moar <[email protected]>
[ Upstream commit 723c8258c8fe167191b53e274dea435c4522e4d7 ]
Add ability to kunit.py to filter attributes and report a list of tests including attributes without running tests.
Add flag "--filter" to input filters on test attributes. Tests will be filtered out if they do not match all inputted filters.
Example: --filter speed=slow (This filter would run only the tests that are marked as slow)
Filters have operations: <, >, <=, >=, !=, and =. But note that the characters < and > are often interpreted by the shell, so they may need to be quoted or escaped.
Example: --filter "speed>slow" or --filter speed\>slow (This filter would run only the tests that have the speed faster than slow.
Additionally, multiple filters can be used.
Example: --filter "speed=slow, module!=example" (This filter would run only the tests that have the speed slow and are not in the "example" module)
Note if the user wants to skip filtered tests instead of not running/showing them use the "--filter_action=skip" flag instead.
Expose the output of kunit.action=list option with flag "--list_tests" to output a list of tests. Additionally, add flag "--list_tests_attr" to output a list of tests and their attributes. These flags are useful to see tests and test attributes without needing to run tests.
Example of the output of "--list_tests_attr":
example
example.test_1
example.test_2
# example.test_2.speed: slow
This output includes a suite, example, with two test cases, test_1 and test_2. And in this instance test_2 has been marked as slow.
Stable-dep-of: 40804c4974b8 ("kunit: tool: copy caller args in run_kernel to prevent mutation")
--- tools/testing/kunit/kunit.py | 70 ++++++++++++++++++++++++-- tools/testing/kunit/kunit_kernel.py | 8 ++- tools/testing/kunit/kunit_parser.py | 11 +++- tools/testing/kunit/kunit_tool_test.py | 39 +++++++------- 4 files changed, 99 insertions(+), 29 deletions(-)
tools/testing/kunit/kunit.py +65 -5
@@ -55,8 +55,12 @@ class KunitExecRequest(KunitParseRequest): build_dir: str timeout: int filter_glob: str + filter: str + filter_action: Optional[str] kernel_args: Optional[List[str]] run_isolated: Optional[str] + list_tests: bool + list_tests_attr: bool @dataclass class KunitRequest(KunitExecRequest, KunitBuildRequest):
@@ -111,19 +115,41 @@ def config_and_build_tests(linux: kunit_kernel.LinuxSourceTree, def _list_tests(linux: kunit_kernel.LinuxSourceTree, request: KunitExecRequest) -> List[str]: args = ['kunit.action=list'] + + if request.kernel_args: + args.extend(request.kernel_args) + + output = linux.run_kernel(args=args, + timeout=request.timeout, + filter_glob=request.filter_glob, + filter=request.filter, + filter_action=request.filter_action, + build_dir=request.build_dir) + lines = kunit_parser.extract_tap_lines(output) + # Hack! Drop the dummy TAP version header that the executor prints out. + lines.pop() + + # Filter out any extraneous non-test output that might have gotten mixed in. + return [l for l in output if re.match(r'^[^\s.]+\.[^\s.]+$', l)] + +def _list_tests_attr(linux: kunit_kernel.LinuxSourceTree, request: KunitExecRequest) -> Iterable[str]: + args = ['kunit.action=list_attr'] + if request.kernel_args: args.extend(request.kernel_args) output = linux.run_kernel(args=args, timeout=request.timeout, filter_glob=request.filter_glob, + filter=request.filter, + filter_action=request.filter_action, build_dir=request.build_dir) lines = kunit_parser.extract_tap_lines(output) # Hack! Drop the dummy TAP version header that the executor prints out. lines.pop() # Filter out any extraneous non-test output that might have gotten mixed in. - return [l for l in lines if re.match(r'^[^\s.]+\.[^\s.]+$', l)] + return lines def _suites_from_test_list(tests: List[str]) -> List[str]: """Extracts all the suites from an ordered list of tests."""
@@ -137,10 +163,18 @@ def _suites_from_test_list(tests: List[str]) -> List[str]: suites.append(suite) return suites - - def exec_tests(linux: kunit_kernel.LinuxSourceTree, request: KunitExecRequest) -> KunitResult: filter_globs = [request.filter_glob] + if request.list_tests: + output = _list_tests(linux, request) + for line in output: + print(line.rstrip()) + return KunitResult(status=KunitStatus.SUCCESS, elapsed_time=0.0) + if request.list_tests_attr: + attr_output = _list_tests_attr(linux, request) + for line in attr_output: + print(line.rstrip()) + return KunitResult(status=KunitStatus.SUCCESS, elapsed_time=0.0) if request.run_isolated: tests = _list_tests(linux, request) if request.run_isolated == 'test':
@@ -164,6 +198,8 @@ def exec_tests(linux: kunit_kernel.LinuxSourceTree, request: KunitExecRequest) - args=request.kernel_args, timeout=request.timeout, filter_glob=filter_glob, + filter=request.filter, + filter_action=request.filter_action, build_dir=request.build_dir) _, test_result = parse_tests(request, metadata, run_result)
@@ -350,6 +386,16 @@ def add_exec_opts(parser: argparse.ArgumentParser) -> None: nargs='?', default='', metavar='filter_glob') + parser.add_argument('--filter', + help='Filter KUnit tests with attributes, ' + 'e.g. module=example or speed>slow', + type=str, + default='') + parser.add_argument('--filter_action', + help='If set to skip, filtered tests will be skipped, ' + 'e.g. --filter_action=skip. Otherwise they will not run.', + type=str, + choices=['skip']) parser.add_argument('--kernel_args', help='Kernel command-line parameters. Maybe be repeated', action='append', metavar='')
@@ -359,6 +405,12 @@ def add_exec_opts(parser: argparse.ArgumentParser) -> None: 'what ran before it.', type=str, choices=['suite', 'test']) + parser.add_argument('--list_tests', help='If set, list all tests that will be ' + 'run.', + action='store_true') + parser.add_argument('--list_tests_attr', help='If set, list all tests and test ' + 'attributes.', + action='store_true') def add_parse_opts(parser: argparse.ArgumentParser) -> None: parser.add_argument('--raw_output', help='If set don\'t parse output from kernel. '
@@ -407,8 +459,12 @@ def run_handler(cli_args: argparse.Namespace) -> None: json=cli_args.json, timeout=cli_args.timeout, filter_glob=cli_args.filter_glob, + filter=cli_args.filter, + filter_action=cli_args.filter_action, kernel_args=cli_args.kernel_args, - run_isolated=cli_args.run_isolated) + run_isolated=cli_args.run_isolated, + list_tests=cli_args.list_tests, + list_tests_attr=cli_args.list_tests_attr) result = run_tests(linux, request) if result.status != KunitStatus.SUCCESS: sys.exit(1)
@@ -450,8 +506,12 @@ def exec_handler(cli_args: argparse.Namespace) -> None: json=cli_args.json, timeout=cli_args.timeout, filter_glob=cli_args.filter_glob, + filter=cli_args.filter, + filter_action=cli_args.filter_action, kernel_args=cli_args.kernel_args, - run_isolated=cli_args.run_isolated) + run_isolated=cli_args.run_isolated, + list_tests=cli_args.list_tests, + list_tests_attr=cli_args.list_tests_attr) result = exec_tests(linux, exec_request) stdout.print_with_timestamp(( 'Elapsed time: %.3fs\n') % (result.elapsed_time))
tools/testing/kunit/kunit_kernel.py +6 -2
@@ -329,11 +329,15 @@ class LinuxSourceTree: return False return self.validate_config(build_dir) - def run_kernel(self, args: Optional[List[str]]=None, build_dir: str='', filter_glob: str='', timeout: Optional[int]=None) -> Iterator[str]: + def run_kernel(self, args: Optional[List[str]]=None, build_dir: str='', filter_glob: str='', filter: str='', filter_action: Optional[str]=None, timeout: Optional[int]=None) -> Iterator[str]: if not args: args = [] if filter_glob: - args.append('kunit.filter_glob='+filter_glob) + args.append('kunit.filter_glob=' + filter_glob) + if filter: + args.append('kunit.filter="' + filter + '"') + if filter_action: + args.append('kunit.filter_action=' + filter_action) args.append('kunit.enable=1') process = self._ops.start(args, build_dir)
tools/testing/kunit/kunit_parser.py +10 -1
@@ -221,6 +221,7 @@ KTAP_START = re.compile(r'\s*KTAP version ([0-9]+)$') TAP_START = re.compile(r'\s*TAP version ([0-9]+)$') KTAP_END = re.compile(r'\s*(List of all partitions:|' 'Kernel panic - not syncing: VFS:|reboot: System halted)') +EXECUTOR_ERROR = re.compile(r'\s*kunit executor: (.*)$') def extract_tap_lines(kernel_output: Iterable[str]) -> LineStream: """Extracts KTAP lines from the kernel output."""
@@ -251,6 +252,8 @@ def extract_tap_lines(kernel_output: Iterable[str]) -> LineStream: # remove the prefix, if any. line = line[prefix_len:] yield line_num, line + elif EXECUTOR_ERROR.search(line): + yield line_num, line return LineStream(lines=isolate_ktap_output(kernel_output)) KTAP_VERSIONS = [1]
@@ -456,7 +459,7 @@ def parse_diagnostic(lines: LineStream) -> List[str]: Log of diagnostic lines """ log = [] # type: List[str] - non_diagnostic_lines = [TEST_RESULT, TEST_HEADER, KTAP_START] + non_diagnostic_lines = [TEST_RESULT, TEST_HEADER, KTAP_START, TAP_START] while lines and not any(re.match(lines.peek()) for re in non_diagnostic_lines): log.append(lines.pop())
@@ -722,6 +725,11 @@ def parse_test(lines: LineStream, expected_num: int, log: List[str], is_subtest: """ test = Test() test.log.extend(log) + + # Parse any errors prior to parsing tests + err_log = parse_diagnostic(lines) + test.log.extend(err_log) + if not is_subtest: # If parsing the main/top-level test, parse KTAP version line and # test plan
@@ -783,6 +791,7 @@ def parse_test(lines: LineStream, expected_num: int, log: List[str], is_subtest: # Don't override a bad status if this test had one reported. # Assumption: no subtests means CRASHED is from Test.__init__() if test.status in (TestStatus.TEST_CRASHED, TestStatus.SUCCESS): + print_log(test.log) test.status = TestStatus.NO_TESTS test.add_error('0 tests run!')
tools/testing/kunit/kunit_tool_test.py +18 -21
@@ -612,7 +612,7 @@ class KUnitMainTest(unittest.TestCase): self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 0) self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1) self.linux_source_mock.run_kernel.assert_called_once_with( - args=None, build_dir='.kunit', filter_glob='', timeout=300) + args=None, build_dir='.kunit', filter_glob='', filter='', filter_action=None, timeout=300) self.print_mock.assert_any_call(StrContains('Testing complete.')) def test_run_passes_args_pass(self):
@@ -620,7 +620,7 @@ class KUnitMainTest(unittest.TestCase): self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1) self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1) self.linux_source_mock.run_kernel.assert_called_once_with( - args=None, build_dir='.kunit', filter_glob='', timeout=300) + args=None, build_dir='.kunit', filter_glob='', filter='', filter_action=None, timeout=300) self.print_mock.assert_any_call(StrContains('Testing complete.')) def test_exec_passes_args_fail(self):
@@ -644,7 +644,7 @@ class KUnitMainTest(unittest.TestCase): kunit.main(['run']) self.assertEqual(e.exception.code, 1) self.linux_source_mock.run_kernel.assert_called_once_with( - args=None, build_dir='.kunit', filter_glob='', timeout=300) + args=None, build_dir='.kunit', filter_glob='', filter='', filter_action=None, timeout=300) self.print_mock.assert_any_call(StrContains(' 0 tests run!')) def test_exec_raw_output(self):
@@ -685,13 +685,13 @@ class KUnitMainTest(unittest.TestCase): self.linux_source_mock.run_kernel = mock.Mock(return_value=[]) kunit.main(['run', '--raw_output', 'filter_glob']) self.linux_source_mock.run_kernel.assert_called_once_with( - args=None, build_dir='.kunit', filter_glob='filter_glob', timeout=300) + args=None, build_dir='.kunit', filter_glob='filter_glob', filter='', filter_action=None, timeout=300) def test_exec_timeout(self): timeout = 3453 kunit.main(['exec', '--timeout', str(timeout)]) self.linux_source_mock.run_kernel.assert_called_once_with( - args=None, build_dir='.kunit', filter_glob='', timeout=timeout) + args=None, build_dir='.kunit', filter_glob='', filter='', filter_action=None, timeout=timeout) self.print_mock.assert_any_call(StrContains('Testing complete.')) def test_run_timeout(self):
@@ -699,7 +699,7 @@ class KUnitMainTest(unittest.TestCase): kunit.main(['run', '--timeout', str(timeout)]) self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1) self.linux_source_mock.run_kernel.assert_called_once_with( - args=None, build_dir='.kunit', filter_glob='', timeout=timeout) + args=None, build_dir='.kunit', filter_glob='', filter='', filter_action=None, timeout=timeout) self.print_mock.assert_any_call(StrContains('Testing complete.')) def test_run_builddir(self):
@@ -707,7 +707,7 @@ class KUnitMainTest(unittest.TestCase): kunit.main(['run', '--build_dir=.kunit']) self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1) self.linux_source_mock.run_kernel.assert_called_once_with( - args=None, build_dir=build_dir, filter_glob='', timeout=300) + args=None, build_dir=build_dir, filter_glob='', filter='', filter_action=None, timeout=300) self.print_mock.assert_any_call(StrContains('Testing complete.')) def test_config_builddir(self):
@@ -725,7 +725,7 @@ class KUnitMainTest(unittest.TestCase): build_dir = '.kunit' kunit.main(['exec', '--build_dir', build_dir]) self.linux_source_mock.run_kernel.assert_called_once_with( - args=None, build_dir=build_dir, filter_glob='', timeout=300) + args=None, build_dir=build_dir, filter_glob='', filter='', filter_action=None, timeout=300) self.print_mock.assert_any_call(StrContains('Testing complete.')) def test_run_kunitconfig(self):
@@ -801,7 +801,7 @@ class KUnitMainTest(unittest.TestCase): kunit.main(['run', '--kernel_args=a=1', '--kernel_args=b=2']) self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1) self.linux_source_mock.run_kernel.assert_called_once_with( - args=['a=1','b=2'], build_dir='.kunit', filter_glob='', timeout=300) + args=['a=1','b=2'], build_dir='.kunit', filter_glob='', filter='', filter_action=None, timeout=300) self.print_mock.assert_any_call(StrContains('Testing complete.')) def test_list_tests(self):
@@ -809,13 +809,11 @@ class KUnitMainTest(unittest.TestCase): self.linux_source_mock.run_kernel.return_value = ['TAP version 14', 'init: random output'] + want got = kunit._list_tests(self.linux_source_mock, - kunit.KunitExecRequest(None, None, '.kunit', 300, 'suite*', None, 'suite')) - + kunit.KunitExecRequest(None, None, '.kunit', 300, 'suite*', '', None, None, 'suite', False, False)) self.assertEqual(got, want) # Should respect the user's filter glob when listing tests. self.linux_source_mock.run_kernel.assert_called_once_with( - args=['kunit.action=list'], build_dir='.kunit', filter_glob='suite*', timeout=300) - + args=['kunit.action=list'], build_dir='.kunit', filter_glob='suite*', filter='', filter_action=None, timeout=300) @mock.patch.object(kunit, '_list_tests') def test_run_isolated_by_suite(self, mock_tests):
@@ -824,10 +822,10 @@ class KUnitMainTest(unittest.TestCase): # Should respect the user's filter glob when listing tests. mock_tests.assert_called_once_with(mock.ANY, - kunit.KunitExecRequest(None, None, '.kunit', 300, 'suite*.test*', None, 'suite')) + kunit.KunitExecRequest(None, None, '.kunit', 300, 'suite*.test*', '', None, None, 'suite', False, False)) self.linux_source_mock.run_kernel.assert_has_calls([ - mock.call(args=None, build_dir='.kunit', filter_glob='suite.test*', timeout=300), - mock.call(args=None, build_dir='.kunit', filter_glob='suite2.test*', timeout=300), + mock.call(args=None, build_dir='.kunit', filter_glob='suite.test*', filter='', filter_action=None, timeout=300), + mock.call(args=None, build_dir='.kunit', filter_glob='suite2.test*', filter='', filter_action=None, timeout=300), ]) @mock.patch.object(kunit, '_list_tests')
@@ -837,13 +835,12 @@ class KUnitMainTest(unittest.TestCase): # Should respect the user's filter glob when listing tests. mock_tests.assert_called_once_with(mock.ANY, - kunit.KunitExecRequest(None, None, '.kunit', 300, 'suite*', None, 'test')) + kunit.KunitExecRequest(None, None, '.kunit', 300, 'suite*', '', None, None, 'test', False, False)) self.linux_source_mock.run_kernel.assert_has_calls([ - mock.call(args=None, build_dir='.kunit', filter_glob='suite.test1', timeout=300), - mock.call(args=None, build_dir='.kunit', filter_glob='suite.test2', timeout=300), - mock.call(args=None, build_dir='.kunit', filter_glob='suite2.test1', timeout=300), + mock.call(args=None, build_dir='.kunit', filter_glob='suite.test1', filter='', filter_action=None, timeout=300), + mock.call(args=None, build_dir='.kunit', filter_glob='suite.test2', filter='', filter_action=None, timeout=300), + mock.call(args=None, build_dir='.kunit', filter_glob='suite2.test1', filter='', filter_action=None, timeout=300), ]) - if __name__ == '__main__': unittest.main()
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 117/481 kunit: tool: copy caller args in run_kernel to prevent mutation
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuvam Pandey <[email protected]>
[ Upstream commit 40804c4974b8df2adab72f6475d343eaff72b7f6 ]
run_kernel() appended KUnit flags directly to the caller-provided args list. When exec_tests() calls run_kernel() repeatedly (e.g. with --run_isolated), each call mutated the same list, causing later runs to inherit stale filter_glob values and duplicate kunit.enable flags.
Fix this by copying args at the start of run_kernel(). Add a regression test that calls run_kernel() twice with the same list and verifies the original remains unchanged.
--- tools/testing/kunit/kunit_kernel.py | 6 ++++-- tools/testing/kunit/kunit_tool_test.py | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-)
tools/testing/kunit/kunit_kernel.py +4 -2
@@ -330,8 +330,10 @@ class LinuxSourceTree: return self.validate_config(build_dir) def run_kernel(self, args: Optional[List[str]]=None, build_dir: str='', filter_glob: str='', filter: str='', filter_action: Optional[str]=None, timeout: Optional[int]=None) -> Iterator[str]: - if not args: - args = [] + # Copy to avoid mutating the caller-supplied list. exec_tests() reuses + # the same args across repeated run_kernel() calls (e.g. --run_isolated), + # so appending to the original would accumulate stale flags on each call. + args = list(args) if args else [] if filter_glob: args.append('kunit.filter_glob=' + filter_glob) if filter:
tools/testing/kunit/kunit_tool_test.py +26 -0
@@ -479,6 +479,32 @@ class LinuxSourceTreeTest(unittest.TestCase): with open(kunit_kernel.get_outfile_path(build_dir), 'rt') as outfile: self.assertEqual(outfile.read(), 'hi\nbye\n', msg='Missing some output') + def test_run_kernel_args_not_mutated(self): + """Verify run_kernel() copies args so callers can reuse them.""" + start_calls = [] + + def fake_start(start_args, unused_build_dir): + start_calls.append(list(start_args)) + return subprocess.Popen(['printf', 'KTAP version 1\n'], + text=True, stdout=subprocess.PIPE) + + with tempfile.TemporaryDirectory('') as build_dir: + tree = kunit_kernel.LinuxSourceTree(build_dir, + kunitconfig_paths=[os.devnull]) + with mock.patch.object(tree._ops, 'start', side_effect=fake_start), \ + mock.patch.object(kunit_kernel.subprocess, 'call'): + kernel_args = ['mem=1G'] + for _ in tree.run_kernel(args=kernel_args, build_dir=build_dir, + filter_glob='suite.test1'): + pass + for _ in tree.run_kernel(args=kernel_args, build_dir=build_dir, + filter_glob='suite.test2'): + pass + self.assertEqual(kernel_args, ['mem=1G'], + 'run_kernel() should not modify caller args') + self.assertIn('kunit.filter_glob=suite.test1', start_calls[0]) + self.assertIn('kunit.filter_glob=suite.test2', start_calls[1]) + def test_build_reconfig_no_config(self): with tempfile.TemporaryDirectory('') as build_dir: with open(kunit_kernel.get_kunitconfig_path(build_dir), 'w') as f:
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 118/481 net: dsa: realtek: rtl8365mb: fix rtl8365mb_phy_ocp_write return value
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mieczyslaw Nalewaj <[email protected]>
[ Upstream commit 7cbe98f7bef965241a5908d50d557008cf998aee ]
Function rtl8365mb_phy_ocp_write() always returns 0, even when an error occurs during register access. This patch fixes the return value to propagate the actual error code from regmap operations.
--- drivers/net/dsa/realtek/rtl8365mb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/dsa/realtek/rtl8365mb.c +1 -1
@@ -764,7 +764,7 @@ static int rtl8365mb_phy_ocp_write(struct realtek_priv *priv, int phy, out:mutex_unlock (&priv->map_lock); -return 0 ; +return ret; }static int rtl8365mb_phy_read (struct realtek_priv *priv,int phy,int regnum)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 119/481 octeon_ep: Relocate counter updates before NAPI
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vimlesh Kumar <[email protected]>
[ Upstream commit 18c04a808c436d629d5812ce883e3822a5f5a47f ]
Relocate IQ/OQ IN/OUT_CNTS updates to occur before NAPI completion, and replace napi_complete with napi_complete_done.
Moving the IQ/OQ counter updates before napi_complete_done ensures
1. Counter registers are updated before re-enabling interrupts.
2. Prevents a race where new packets arrive but counters aren't properly synchronized.napi_complete_done (vs napi_complete) allows for better interrupt coalescing.
--- .../ethernet/marvell/octeon_ep/octep_main.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
drivers/net/ethernet/marvell/octeon_ep/octep_main.c +15 -4
@@ -346,12 +346,12 @@ static void octep_clean_irqs(struct octep_device *oct) }/** -* octep_enable_ioq_irq() - Enable MSI-x interrupt of a Tx/Rx queue. +* octep_update_pkt() - Update IQ/OQ IN/OUT_CNT registers. * * @iq: Octeon Tx queue data structure. * @oq: Octeon Rx queue data structure. */ -static void octep_enable_ioq_irq (struct octep_iq *iq,struct octep_oq *oq) +static void octep_update_pkt (struct octep_iq *iq,struct octep_oq *oq) {u32 pkts_pend = oq->pkts_pending;
@@ -367,7 +367,17 @@ static void octep_enable_ioq_irq(struct octep_iq *iq, struct octep_oq *oq) }/* Flush the previous wrties before writing to RESEND bit */ -wmb (); +smp_wmb (); +} + +/** +* octep_enable_ioq_irq() - Enable MSI-x interrupt of a Tx/Rx queue. +* +* @iq: Octeon Tx queue data structure. +* @oq: Octeon Rx queue data structure. +*/ +static void octep_enable_ioq_irq (struct octep_iq *iq,struct octep_oq *oq) +{writeq (1UL <<OCTEP_OQ_INTR_RESEND_BIT , oq->pkts_sent_reg);writeq (1UL <<OCTEP_IQ_INTR_RESEND_BIT , iq->inst_cnt_reg); }
@@ -393,7 +403,8 @@ static int octep_napi_poll(struct napi_struct *napi, int budget)if (tx_pending || rx_done >= budget)return budget; -napi_complete (napi); +octep_update_pkt (ioq_vector->iq, ioq_vector->oq); +napi_complete_done (napi, rx_done);octep_enable_ioq_irq (ioq_vector->iq, ioq_vector->oq);return rx_done; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 120/481 octeon_ep: avoid compiler and IQ/OQ reordering
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vimlesh Kumar <[email protected]>
[ Upstream commit 43b3160cb639079a15daeb5f080120afbfbfc918 ]
Utilize READ_ONCE and WRITE_ONCE APIs for IO queue Tx/Rx variable access to prevent compiler optimization and reordering. Additionally, ensure IO queue OUT/IN_CNT registers are flushed by performing a read-back after writing.
The compiler could reorder reads/writes to pkts_pending, last_pkt_count, etc., causing stale values to be used when calculating packets to process or register updates to send to hardware. The Octeon hardware requires a read-back after writing to OUT_CNT/IN_CNT registers to ensure the write has been flushed through any posted write buffers before the interrupt resend bit is set. Without this, we have observed cases where the hardware didn't properly update its internal state.
wmb/rmb only provides ordering guarantees but doesn't prevent the compiler from performing optimizations like caching in registers, load tearing etc.
--- .../ethernet/marvell/octeon_ep/octep_main.c | 21 +++++++++------ .../net/ethernet/marvell/octeon_ep/octep_rx.c | 27 +++++++++++++------ 2 files changed, 32 insertions(+), 16 deletions(-)
drivers/net/ethernet/marvell/octeon_ep/octep_main.c +13 -8
@@ -353,17 +353,22 @@ static void octep_clean_irqs(struct octep_device *oct)*/ static void octep_update_pkt (struct octep_iq *iq,struct octep_oq *oq) { -u32 pkts_pend = oq->pkts_pending; +u32 pkts_pend =READ_ONCE (oq->pkts_pending); +u32 last_pkt_count =READ_ONCE (oq->last_pkt_count); +u32 pkts_processed =READ_ONCE (iq->pkts_processed); +u32 pkt_in_done =READ_ONCE (iq->pkt_in_done);netdev_dbg (iq->netdev,"enabling intr for Q-%u\n" , iq->q_no); -if (iq->pkts_processed) { -writel (iq->pkts_processed, iq->inst_cnt_reg); - iq->pkt_in_done -= iq->pkts_processed; - iq->pkts_processed =0 ; +if (pkts_processed) { +writel (pkts_processed, iq->inst_cnt_reg); +readl (iq->inst_cnt_reg); +WRITE_ONCE (iq->pkt_in_done, (pkt_in_done - pkts_processed)); +WRITE_ONCE (iq->pkts_processed,0 ); } -if (oq->last_pkt_count - pkts_pend) { -writel (oq->last_pkt_count - pkts_pend, oq->pkts_sent_reg); - oq->last_pkt_count = pkts_pend; +if (last_pkt_count - pkts_pend) { +writel (last_pkt_count - pkts_pend, oq->pkts_sent_reg); +readl (oq->pkts_sent_reg); +WRITE_ONCE (oq->last_pkt_count, pkts_pend); }/* Flush the previous wrties before writing to RESEND bit */
drivers/net/ethernet/marvell/octeon_ep/octep_rx.c +19 -8
@@ -317,10 +317,16 @@ static int octep_oq_check_hw_for_pkts(struct octep_device *oct, struct octep_oq *oq) {u32 pkt_count, new_pkts; +u32 last_pkt_count, pkts_pending; pkt_count =readl (oq->pkts_sent_reg); - new_pkts = pkt_count - oq->last_pkt_count; + last_pkt_count =READ_ONCE (oq->last_pkt_count); + new_pkts = pkt_count - last_pkt_count; +if (pkt_count < last_pkt_count) { +dev_err (oq->dev,"OQ-%u pkt_count(%u) < oq->last_pkt_count(%u)\n" , + oq->q_no, pkt_count, last_pkt_count); + }/* Clear the hardware packets counter register if the rx queue is * being processed continuously with-in a single interrupt and * reached half its max value.
@@ -331,8 +337,9 @@ static int octep_oq_check_hw_for_pkts(struct octep_device *oct, pkt_count =readl (oq->pkts_sent_reg); new_pkts += pkt_count; } - oq->last_pkt_count = pkt_count; - oq->pkts_pending += new_pkts; +WRITE_ONCE (oq->last_pkt_count, pkt_count); + pkts_pending =READ_ONCE (oq->pkts_pending); +WRITE_ONCE (oq->pkts_pending, (pkts_pending + new_pkts));return new_pkts; }
@@ -405,7 +412,7 @@ static int __octep_oq_process_rx(struct octep_device *oct,u16 data_offset;u32 read_idx; - read_idx = oq->host_read_idx; + read_idx =READ_ONCE (oq->host_read_idx); rx_bytes =0 ; desc_used =0 ;for (pkt =0 ; pkt < pkts_to_process; pkt++) {
@@ -488,7 +495,7 @@ static int __octep_oq_process_rx(struct octep_device *oct,napi_gro_receive (oq->napi, skb); } - oq->host_read_idx = read_idx; +WRITE_ONCE (oq->host_read_idx, read_idx); oq->refill_count += desc_used; oq->stats.packets += pkt; oq->stats.bytes += rx_bytes;
@@ -511,22 +518,26 @@ int octep_oq_process_rx(struct octep_oq *oq, int budget) {u32 pkts_available, pkts_processed, total_pkts_processed;struct octep_device *oct = oq->octep_dev; +u32 pkts_pending; pkts_available =0 ; pkts_processed =0 ; total_pkts_processed =0 ;while (total_pkts_processed < budget) {/* update pending count only when current one exhausted */ -if (oq->pkts_pending ==0 ) + pkts_pending =READ_ONCE (oq->pkts_pending); +if (pkts_pending ==0 )octep_oq_check_hw_for_pkts (oct, oq); + pkts_pending =READ_ONCE (oq->pkts_pending); pkts_available =min (budget - total_pkts_processed, - oq->pkts_pending); + pkts_pending);if (!pkts_available)break ; pkts_processed =__octep_oq_process_rx (oct, oq, pkts_available); - oq->pkts_pending -= pkts_processed; + pkts_pending =READ_ONCE (oq->pkts_pending); +WRITE_ONCE (oq->pkts_pending, (pkts_pending - pkts_processed)); total_pkts_processed += pkts_processed; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 121/481 wifi: cw1200: Fix locking in error paths
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit d98c24617a831e92e7224a07dcaed2dd0b02af96 ]
cw1200_wow_suspend() must only return with priv->conf_mutex locked if it returns zero. This mutex must be unlocked if an error is returned. Add mutex_unlock() calls to the error paths from which that call is missing. This has been detected by the Clang thread-safety analyzer.
--- drivers/net/wireless/st/cw1200/pm.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/wireless/st/cw1200/pm.c +2 -0
@@ -264,12 +264,14 @@ int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)wiphy_err (priv->hw->wiphy,"PM request failed: %d. WoW is disabled.\n" , ret);cw1200_wow_resume (hw); +mutex_unlock (&priv->conf_mutex);return -EBUSY ; }/* Force resume if event is coming from the device. */ if (atomic_read (&priv->bh_rx)) {cw1200_wow_resume (hw); +mutex_unlock (&priv->conf_mutex);return -EAGAIN ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 122/481 wifi: wlcore: Fix a locking bug
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit 72c6df8f284b3a49812ce2ac136727ace70acc7c ]
Make sure that wl->mutex is locked before it is unlocked. This has been detected by the Clang thread-safety analyzer.
--- drivers/net/wireless/ti/wlcore/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/ti/wlcore/main.c +2 -2
@@ -1800,6 +1800,8 @@ static int __maybe_unused wl1271_op_resume(struct ieee80211_hw *hw) wl->wow_enabled);WARN_ON (!wl->wow_enabled); +mutex_lock (&wl->mutex); + ret =pm_runtime_force_resume (wl->dev);if (ret <0 ) {wl1271_error ("ELP wakeup failure!" );
@@ -1816,8 +1818,6 @@ static int __maybe_unused wl1271_op_resume(struct ieee80211_hw *hw) run_irq_work = true;spin_unlock_irqrestore (&wl->wl_lock, flags); -mutex_lock (&wl->mutex); -/* test the recovery flag before calling any SDIO functions */ pending_recovery =test_bit (WL1271_FLAG_RECOVERY_IN_PROGRESS , &wl->flags);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 123/481 wifi: mt76: Fix possible oob access in mt76_connac2_mac_write_txwi_80211()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <[email protected]>
[ Upstream commit 4e10a730d1b511ff49723371ed6d694dd1b2c785 ]
Check frame length before accessing the mgmt fields in mt76_connac2_mac_write_txwi_80211 in order to avoid a possible oob access.
[fix check to also cover mgmt->u.action.u.addba_req.capab, correct Fixes tag]
--- drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +1 -0
@@ -375,6 +375,7 @@ mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi,u32 val;if (ieee80211_is_action (fc) && + skb->len >=IEEE80211_MIN_ACTION_SIZE +1 +1 +2 && mgmt->u.action.category ==WLAN_CATEGORY_BACK && mgmt->u.action.u.addba_req.action_code ==WLAN_ACTION_ADDBA_REQ ) {u16 capab =le16_to_cpu (mgmt->u.action.u.addba_req.capab);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 124/481 indirect_call_wrapper: do not reevaluate function pointer
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 710f5c76580306cdb9ec51fac8fcf6a8faff7821 ]
We have an increasing number of READ_ONCE(xxx->function) combined with INDIRECT_CALL_[1234]() helpers.
Unfortunately this forces INDIRECT_CALL_[1234]() to read xxx->function many times, which is not what we wanted.
Fix these macros so that xxx->function value is not reloaded.
$ scripts/bloat-o-meter -t vmlinux.0 vmlinux add/remove: 0/0 grow/shrink: 1/65 up/down: 122/-1084 (-962) Function old new delta ip_push_pending_frames 59 181 +122 ip6_finish_output 687 681 -6 __udp_enqueue_schedule_skb 1078 1072 -6 ioam6_output 2319 2312 -7 xfrm4_rcv_encap_finish2 64 56 -8 xfrm4_output 297 289 -8 vrf_ip_local_out 278 270 -8 vrf_ip6_local_out 278 270 -8 seg6_input_finish 64 56 -8 rpl_output 700 692 -8 ipmr_forward_finish 124 116 -8 ip_forward_finish 143 135 -8 ip6mr_forward2_finish 100 92 -8 ip6_forward_finish 73 65 -8 input_action_end_bpf 1091 1083 -8 dst_input 52 44 -8 __xfrm6_output 801 793 -8 __xfrm4_output 83 75 -8 bpf_input 500 491 -9 __tcp_check_space 530 521 -9 input_action_end_dt6 291 280 -11 vti6_tnl_xmit 1634 1622 -12 bpf_xmit 1203 1191 -12 rpl_input 497 483 -14 rawv6_send_hdrinc 1355 1341 -14 ndisc_send_skb 1030 1016 -14 ipv6_srh_rcv 1377 1363 -14 ip_send_unicast_reply 1253 1239 -14 ip_rcv_finish 226 212 -14 ip6_rcv_finish 300 286 -14 input_action_end_x_core 205 191 -14 input_action_end_x 355 341 -14 input_action_end_t 205 191 -14 input_action_end_dx6_finish 127 113 -14 input_action_end_dx4_finish 373 359 -14 input_action_end_dt4 426 412 -14 input_action_end_core 186 172 -14 input_action_end_b6_encap 292 278 -14 input_action_end_b6 198 184 -14 igmp6_send 1332 1318 -14 ip_sublist_rcv 864 848 -16 ip6_sublist_rcv 1091 1075 -16 ipv6_rpl_srh_rcv 1937 1920 -17 xfrm_policy_queue_process 1246 1228 -18 seg6_output_core 903 885 -18 mld_sendpack 856 836 -20 NF_HOOK 756 736 -20 vti_tunnel_xmit 1447 1426 -21 input_action_end_dx6 664 642 -22 input_action_end 1502 1480 -22 sock_sendmsg_nosec 134 111 -23 ip6mr_forward2 388 364 -24 sock_recvmsg_nosec 134 109 -25 seg6_input_core 836 810 -26 ip_send_skb 172 146 -26 ip_local_out 140 114 -26 ip6_local_out 140 114 -26 __sock_sendmsg 162 136 -26 __ip_queue_xmit 1196 1170 -26 __ip_finish_output 405 379 -26 ipmr_queue_fwd_xmit 373 346 -27 sock_recvmsg 173 145 -28 ip6_xmit 1635 1607 -28 xfrm_output_resume 1418 1389 -29 ip_build_and_send_pkt 625 591 -34 dst_output 504 432 -72 Total: Before=25217686, After=25216724, chg -0.00%
--- include/linux/indirect_call_wrapper.h | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
include/linux/indirect_call_wrapper.h +11 -7
@@ -16,22 +16,26 @@*/ #define INDIRECT_CALL_1 (f, f1, ...) \ ({ \ - likely(f == f1) ? f1(__VA_ARGS__) : f(__VA_ARGS__); \ + typeof(f) __f1 = (f); \ + likely(__f1 == f1) ? f1(__VA_ARGS__) : __f1(__VA_ARGS__); \ })#define INDIRECT_CALL_2 (f, f2, f1, ...) \ ({ \ - likely(f == f2) ? f2(__VA_ARGS__) : \ - INDIRECT_CALL_1(f, f1, __VA_ARGS__); \ + typeof(f) __f2 = (f); \ + likely(__f2 == f2) ? f2(__VA_ARGS__) : \ + INDIRECT_CALL_1(__f2, f1, __VA_ARGS__); \ })#define INDIRECT_CALL_3 (f, f3, f2, f1, ...) \ ({ \ - likely(f == f3) ? f3(__VA_ARGS__) : \ - INDIRECT_CALL_2(f, f2, f1, __VA_ARGS__); \ + typeof(f) __f3 = (f); \ + likely(__f3 == f3) ? f3(__VA_ARGS__) : \ + INDIRECT_CALL_2(__f3, f2, f1, __VA_ARGS__); \ })#define INDIRECT_CALL_4 (f, f4, f3, f2, f1, ...) \ ({ \ - likely(f == f4) ? f4(__VA_ARGS__) : \ - INDIRECT_CALL_3(f, f3, f2, f1, __VA_ARGS__); \ + typeof(f) __f4 = (f); \ + likely(__f4 == f4) ? f4(__VA_ARGS__) : \ + INDIRECT_CALL_3(__f4, f3, f2, f1, __VA_ARGS__); \ })#define INDIRECT_CALLABLE_DECLARE (f) f
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 125/481 xen/acpi-processor: fix _CST detection using undersized evaluation buffer
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Thomson <[email protected]>
[ Upstream commit 8b57227d59a86fc06d4f09de08f98133680f2cae ]
read_acpi_id() attempts to evaluate _CST using a stack buffer of sizeof(union acpi_object) (48 bytes), but _CST returns a nested Package of sub-Packages (one per C-state, each containing a register descriptor, type, latency, and power) requiring hundreds of bytes. The evaluation always fails with AE_BUFFER_OVERFLOW.
On modern systems using FFH/MWAIT entry (where pblk is zero), this causes the function to return before setting the acpi_id_cst_present bit. In check_acpi_ids(), flags.power is then zero for all Phase 2 CPUs (physical CPUs beyond dom0's vCPU count), so push_cxx_to_hypervisor() is never called for them.
On a system with dom0_max_vcpus=2 and 8 physical CPUs, only PCPUs 0-1 receive C-state data. PCPUs 2-7 are stuck in C0/C1 idle, unable to enter C2/C3. This costs measurable wall power (4W observed on an Intel Core Ultra 7 265K with Xen 4.20).
The function never uses the _CST return value -- it only needs to know whether _CST exists. Replace the broken acpi_evaluate_object() call with acpi_has_method(), which correctly detects _CST presence using acpi_get_handle() without any buffer allocation. This brings C-state detection to parity with the P-state path, which already works correctly for Phase 2 CPUs.
Message-ID: <[email protected]>
--- drivers/xen/xen-acpi-processor.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/xen/xen-acpi-processor.c +2 -5
@@ -379,11 +379,8 @@ read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv) acpi_psd[acpi_id].domain); } - status =acpi_evaluate_object (handle,"_CST" ,NULL , &buffer); -if (ACPI_FAILURE (status)) { -if (!pblk) -return AE_OK ; - } +if (!pblk && !acpi_has_method (handle,"_CST" )) +return AE_OK ;/* .. and it has a C-state */ __set_bit (acpi_id, acpi_id_cst_present);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 126/481 bpf: export bpf_link_inc_not_zero.
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kui-Feng Lee <[email protected]>
[ Upstream commit 67c3e8353f45c27800eecc46e00e8272f063f7d1 ]
bpf_link_inc_not_zero() will be used by kernel modules. We will use it in bpf_testmod.c later.
Stable-dep-of: 56145d237385 ("bpf: Fix a UAF issue in bpf_trampoline_link_cgroup_shim")
--- include/linux/bpf.h | 6 ++++++ kernel/bpf/syscall.c | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-)
include/linux/bpf.h +6 -0
@@ -1907,6 +1907,7 @@ int bpf_link_prime(struct bpf_link *link, struct bpf_link_primer *primer);int bpf_link_settle (struct bpf_link_primer *primer);void bpf_link_cleanup (struct bpf_link_primer *primer);void bpf_link_inc (struct bpf_link *link); +struct bpf_link *bpf_link_inc_not_zero (struct bpf_link *link);void bpf_link_put (struct bpf_link *link);int bpf_link_new_fd (struct bpf_link *link);struct file *bpf_link_new_file (struct bpf_link *link,int *reserved_fd);
@@ -2254,6 +2255,11 @@ static inline void bpf_link_inc(struct bpf_link *link) { } +static inline struct bpf_link *bpf_link_inc_not_zero (struct bpf_link *link) +{ +return NULL ; +} +static inline void bpf_link_put (struct bpf_link *link) { }
kernel/bpf/syscall.c +2 -1
@@ -4763,10 +4763,11 @@ static int link_detach(union bpf_attr *attr)return ret; } -static struct bpf_link *bpf_link_inc_not_zero (struct bpf_link *link) +struct bpf_link *bpf_link_inc_not_zero (struct bpf_link *link) {return atomic64_fetch_add_unless (&link->refcnt,1 ,0 ) ? link :ERR_PTR (-ENOENT ); } +EXPORT_SYMBOL (bpf_link_inc_not_zero);struct bpf_link *bpf_link_by_id (u32 id) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 127/481 bpf: Fix a UAF issue in bpf_trampoline_link_cgroup_shim
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lang Xu <[email protected]>
[ Upstream commit 56145d237385ca0e7ca9ff7b226aaf2eb8ef368b ]
The root cause of this bug is that when 'bpf_link_put' reduces the refcount of 'shim_link->link.link' to zero, the resource is considered released but may still be referenced via 'tr->progs_hlist' in 'cgroup_shim_find'. The actual cleanup of 'tr->progs_hlist' in 'bpf_shim_tramp_link_release' is deferred. During this window, another process can cause a use-after-free via 'bpf_trampoline_link_cgroup_shim'.
Based on Martin KaFai Lau's suggestions, I have created a simple patch.
To fix this:
Add an atomic non-zero check in 'bpf_trampoline_link_cgroup_shim'. Only increment the refcount if it is not already zero.
Testing:
I verified the fix by adding a delay in 'bpf_shim_tramp_link_release' to make the bug easier to trigger:
static void bpf_shim_tramp_link_release(struct bpf_link *link)
{
/* ... */
if (!shim_link->trampoline)
return;+ msleep(100); WARN_ON_ONCE(bpf_trampoline_unlink_prog(&shim_link->link, shim_link->trampoline, NULL)); bpf_trampoline_put(shim_link->trampoline); }
Before the patch, running a PoC easily reproduced the crash(almost 100%) with a call trace similar to KaiyanM's report.
After the patch, the bug no longer occurs even after millions of iterations.
--- kernel/bpf/trampoline.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
kernel/bpf/trampoline.c +1 -3
@@ -732,10 +732,8 @@ int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog,mutex_lock (&tr->mutex); shim_link =cgroup_shim_find (tr, bpf_func); -if (shim_link) { +if (shim_link && !IS_ERR (bpf_link_inc_not_zero (&shim_link->link.link))) {/* Reusing existing shim attached by the other program. */ -bpf_link_inc (&shim_link->link.link); -mutex_unlock (&tr->mutex);bpf_trampoline_put (tr);/* bpf_trampoline_get above */ return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 128/481 ipv6: fix NULL pointer deref in ip6_rt_get_dev_rcu()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
[ Upstream commit 2ffb4f5c2ccb2fa1c049dd11899aee7967deef5a ]
l3mdev_master_dev_rcu() can return NULL when the slave device is being un-slaved from a VRF. All other callers deal with this, but we lost the fallback to loopback in ip6_rt_pcpu_alloc() -> ip6_rt_get_dev_rcu() with commit 4832c30d5458 ("net: ipv6: put host and anycast routes on device with address").
KASAN: null-ptr-deref in range [0x0000000000000108-0x000000000000010f] RIP: 0010:ip6_rt_pcpu_alloc (net/ipv6/route.c:1418) Call Trace: ip6_pol_route (net/ipv6/route.c:2318) fib6_rule_lookup (net/ipv6/fib6_rules.c:115) ip6_route_output_flags (net/ipv6/route.c:2607) vrf_process_v6_outbound (drivers/net/vrf.c:437)
I was tempted to rework the un-slaving code to clear the flag first and insert synchronize_rcu() before we remove the upper. But looks like the explicit fallback to loopback_dev is an established pattern. And I guess avoiding the synchronize_rcu() is nice, too.
--- net/ipv6/route.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv6/route.c +2 -1
@@ -1058,7 +1058,8 @@ static struct net_device *ip6_rt_get_dev_rcu(const struct fib6_result *res)*/ if (netif_is_l3_slave (dev) && !rt6_need_strict (&res->f6i->fib6_dst.addr)) - dev =l3mdev_master_dev_rcu (dev); + dev =l3mdev_master_dev_rcu (dev) ? : +dev_net (dev)->loopback_dev;else if (!netif_is_l3_master (dev)) dev =dev_net (dev)->loopback_dev;/* last case is netif_is_l3_master(dev) is true in which
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 129/481 amd-xgbe: fix sleep while atomic on suspend/resume
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raju Rangoju <[email protected]>
[ Upstream commit e2f27363aa6d983504c6836dd0975535e2e9dba0 ]
The xgbe_powerdown() and xgbe_powerup() functions use spinlocks (spin_lock_irqsave) while calling functions that may sleep:
- napi_disable() can sleep waiting for NAPI polling to complete
- flush_workqueue() can sleep waiting for pending work items
This causes a "BUG: scheduling while atomic" error during suspend/resume cycles on systems using the AMD XGBE Ethernet controller.
The spinlock protection in these functions is unnecessary as these functions are called from suspend/resume paths which are already serialized by the PM core
Fix this by removing the spinlock. Since only code that takes this lock is xgbe_powerdown() and xgbe_powerup(), remove it completely.
--- drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 10 ---------- drivers/net/ethernet/amd/xgbe/xgbe-main.c | 1 - drivers/net/ethernet/amd/xgbe/xgbe.h | 3 --- 3 files changed, 14 deletions(-)
drivers/net/ethernet/amd/xgbe/xgbe-drv.c +0 -10
@@ -1181,7 +1181,6 @@ int xgbe_powerdown(struct net_device *netdev, unsigned int caller) {struct xgbe_prv_data *pdata =netdev_priv (netdev);struct xgbe_hw_if *hw_if = &pdata->hw_if; -unsigned long flags;DBGPR ("-->xgbe_powerdown\n" );
@@ -1192,8 +1191,6 @@ int xgbe_powerdown(struct net_device *netdev, unsigned int caller)return -EINVAL ; } -spin_lock_irqsave (&pdata->lock, flags); -if (caller ==XGMAC_DRIVER_CONTEXT )netif_device_detach (netdev);
@@ -1209,8 +1206,6 @@ int xgbe_powerdown(struct net_device *netdev, unsigned int caller) pdata->power_down =1 ; -spin_unlock_irqrestore (&pdata->lock, flags); -DBGPR ("<--xgbe_powerdown\n" );return 0 ;
@@ -1220,7 +1215,6 @@ int xgbe_powerup(struct net_device *netdev, unsigned int caller) {struct xgbe_prv_data *pdata =netdev_priv (netdev);struct xgbe_hw_if *hw_if = &pdata->hw_if; -unsigned long flags;DBGPR ("-->xgbe_powerup\n" );
@@ -1231,8 +1225,6 @@ int xgbe_powerup(struct net_device *netdev, unsigned int caller)return -EINVAL ; } -spin_lock_irqsave (&pdata->lock, flags); - pdata->power_down =0 ;xgbe_napi_enable (pdata,0 );
@@ -1247,8 +1239,6 @@ int xgbe_powerup(struct net_device *netdev, unsigned int caller)xgbe_start_timers (pdata); -spin_unlock_irqrestore (&pdata->lock, flags); -DBGPR ("<--xgbe_powerup\n" );return 0 ;
drivers/net/ethernet/amd/xgbe/xgbe-main.c +0 -1
@@ -185,7 +185,6 @@ struct xgbe_prv_data *xgbe_alloc_pdata(struct device *dev) pdata->netdev = netdev; pdata->dev = dev; -spin_lock_init (&pdata->lock);spin_lock_init (&pdata->xpcs_lock);mutex_init (&pdata->rss_mutex);spin_lock_init (&pdata->tstamp_lock);
drivers/net/ethernet/amd/xgbe/xgbe.h +0 -3
@@ -1077,9 +1077,6 @@ struct xgbe_prv_data {unsigned int pp3;unsigned int pp4; -/* Overall device lock */ -spinlock_t lock; -/* XPCS indirect addressing lock */ spinlock_t xpcs_lock;unsigned int xpcs_window_def_reg;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 130/481 net: sched: avoid qdisc_reset_all_tx_gt() vs dequeue race for lockless qdiscs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Koichiro Den <[email protected]>
[ Upstream commit 7f083faf59d14c04e01ec05a7507f036c965acf8 ]
When shrinking the number of real tx queues, netif_set_real_num_tx_queues() calls qdisc_reset_all_tx_gt() to flush qdiscs for queues which will no longer be used.
qdisc_reset_all_tx_gt() currently serializes qdisc_reset() with qdisc_lock(). However, for lockless qdiscs, the dequeue path is serialized by qdisc_run_begin/end() using qdisc->seqlock instead, so qdisc_reset() can run concurrently with __qdisc_run() and free skbs while they are still being dequeued, leading to UAF.
This can easily be reproduced on e.g. virtio-net by imposing heavy traffic while frequently changing the number of queue pairs:
iperf3 -ub0 -c $peer -t 0 &
while :; do
ethtool -L eth0 combined 1
ethtool -L eth0 combined 2
done
With KASAN enabled, this leads to reports like:
BUG: KASAN: slab-use-after-free in __qdisc_run+0x133f/0x1760 ... Call Trace: <TASK> ... __qdisc_run+0x133f/0x1760 __dev_queue_xmit+0x248f/0x3550 ip_finish_output2+0xa42/0x2110 ip_output+0x1a7/0x410 ip_send_skb+0x2e6/0x480 udp_send_skb+0xb0a/0x1590 udp_sendmsg+0x13c9/0x1fc0 ... </TASK> Allocated by task 1270 on cpu 5 at 44.558414s: ... alloc_skb_with_frags+0x84/0x7c0 sock_alloc_send_pskb+0x69a/0x830 __ip_append_data+0x1b86/0x48c0 ip_make_skb+0x1e8/0x2b0 udp_sendmsg+0x13a6/0x1fc0 ... Freed by task 1306 on cpu 3 at 44.558445s: ... kmem_cache_free+0x117/0x5e0 pfifo_fast_reset+0x14d/0x580 qdisc_reset+0x9e/0x5f0 netif_set_real_num_tx_queues+0x303/0x840 virtnet_set_channels+0x1bf/0x260 [virtio_net] ethnl_set_channels+0x684/0xae0 ethnl_default_set_doit+0x31a/0x890 ...
Serialize qdisc_reset_all_tx_gt() against the lockless dequeue path by taking qdisc->seqlock for TCQ_F_NOLOCK qdiscs, matching the serialization model already used by dev_reset_queue().
Additionally clear QDISC_STATE_NON_EMPTY after reset so the qdisc state reflects an empty queue, avoiding needless re-scheduling.
--- include/net/sch_generic.h | 10 ++++++++++ 1 file changed, 10 insertions(+)
include/net/sch_generic.h +10 -0
@@ -724,13 +724,23 @@ static inline bool skb_skip_tc_classify(struct sk_buff *skb)static inline void qdisc_reset_all_tx_gt (struct net_device *dev,unsigned int i) {struct Qdisc *qdisc; +bool nolock;for (; i < dev->num_tx_queues; i++) { qdisc =rtnl_dereference (netdev_get_tx_queue (dev, i)->qdisc);if (qdisc) { + nolock = qdisc->flags &TCQ_F_NOLOCK ; + +if (nolock) +spin_lock_bh (&qdisc->seqlock);spin_lock_bh (qdisc_lock (qdisc));qdisc_reset (qdisc);spin_unlock_bh (qdisc_lock (qdisc)); +if (nolock) { +clear_bit (__QDISC_STATE_MISSED, &qdisc->state); +clear_bit (__QDISC_STATE_DRAINING, &qdisc->state); +spin_unlock_bh (&qdisc->seqlock); + } } } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 131/481 net: nfc: nci: Fix zero-length proprietary notifications
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Ray <[email protected]>
[ Upstream commit f7d92f11bd33a6eb49c7c812255ef4ab13681f0f ]
NCI NFC controllers may have proprietary OIDs with zero-length payload. One example is: drivers/nfc/nxp-nci/core.c, NXP_NCI_RF_TXLDO_ERROR_NTF.
Allow a zero length payload in proprietary notifications *only*.
Before:
-- >8 --
kernel: nci: nci_recv_frame: len 3
-- >8 --
After:
-- >8 --
kernel: nci: nci_recv_frame: len 3
kernel: nci: nci_ntf_packet: NCI RX: MT=ntf, PBF=0, GID=0x1, OID=0x23, plen=0
kernel: nci: nci_ntf_packet: unknown ntf opcode 0x123
kernel: nfc nfc0: NFC: RF transmitter couldn't start. Bad power and/or configuration? -- >8 --
After fixing the hardware:
-- >8 --
kernel: nci: nci_recv_frame: len 27
kernel: nci: nci_ntf_packet: NCI RX: MT=ntf, PBF=0, GID=0x1, OID=0x5, plen=24
kernel: nci: nci_rf_intf_activated_ntf_packet: rf_discovery_id 1 -- >8 --
--- net/nfc/nci/core.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
net/nfc/nci/core.c +11 -1
@@ -1470,10 +1470,20 @@ static bool nci_valid_size(struct sk_buff *skb)unsigned int hdr_size =NCI_CTRL_HDR_SIZE ;if (skb->len < hdr_size || - !nci_plen (skb->data) || skb->len < hdr_size +nci_plen (skb->data)) {return false; } + +if (!nci_plen (skb->data)) { +/* Allow zero length in proprietary notifications (0x20 - 0x3F). */ +if (nci_opcode_oid (nci_opcode (skb->data)) >=0x20 && +nci_mt (skb->data) ==NCI_MT_NTF_PKT ) +return true; + +/* Disallow zero length otherwise. */ +return false; + } +return true; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 132/481 nfc: nci: free skb on nci_transceive early error paths
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
[ Upstream commit 7bd4b0c4779f978a6528c9b7937d2ca18e936e2c ]
nci_transceive() takes ownership of the skb passed by the caller, but the -EPROTO, -EINVAL, and -EBUSY error paths return without freeing it.
Due to issues clearing NCI_DATA_EXCHANGE fixed by subsequent changes the nci/nci_dev selftest hits the error path occasionally in NIPA, and kmemleak detects leaks:
unreferenced object 0xff11000015ce6a40 (size 640):
comm "nci_dev", pid 3954, jiffies 4295441246
hex dump (first 32 bytes):
6b 6b 6b 6b 00 a4 00 0c 02 e1 03 6b 6b 6b 6b 6b kkkk.......kkkkk 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
backtrace (crc 7c40cc2a):
kmem_cache_alloc_node_noprof+0x492/0x630
__alloc_skb+0x11e/0x5f0
alloc_skb_with_frags+0xc6/0x8f0
sock_alloc_send_pskb+0x326/0x3f0
nfc_alloc_send_skb+0x94/0x1d0
rawsock_sendmsg+0x162/0x4c0
do_syscall_64+0x117/0xfc0--- net/nfc/nci/core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
net/nfc/nci/core.c +7 -2
@@ -1023,18 +1023,23 @@ static int nci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target,struct nci_conn_info *conn_info; conn_info = ndev->rf_conn_info; -if (!conn_info) +if (!conn_info) { +kfree_skb (skb);return -EPROTO ; + }pr_debug ("target_idx %d, len %d\n" , target->idx, skb->len);if (!ndev->target_active_prot) {pr_err ("unable to exchange data, no active target\n" ); +kfree_skb (skb);return -EINVAL ; } -if (test_and_set_bit (NCI_DATA_EXCHANGE , &ndev->flags)) +if (test_and_set_bit (NCI_DATA_EXCHANGE , &ndev->flags)) { +kfree_skb (skb);return -EBUSY ; + }/* store cb and context to be used on receiving data */ conn_info->data_exchange_cb = cb;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 133/481 nfc: nci: clear NCI_DATA_EXCHANGE before calling completion callback
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
[ Upstream commit 0efdc02f4f6d52f8ca5d5889560f325a836ce0a8 ]
Move clear_bit(NCI_DATA_EXCHANGE) before invoking the data exchange callback in nci_data_exchange_complete().
The callback (e.g. rawsock_data_exchange_complete) may immediately schedule another data exchange via schedule_work(tx_work). On a multi-CPU system, tx_work can run and reach nci_transceive() before the current nci_data_exchange_complete() clears the flag, causing test_and_set_bit(NCI_DATA_EXCHANGE) to return -EBUSY and the new transfer to fail.
This causes intermittent flakes in nci/nci_dev in NIPA:
# # RUN NCI.NCI1_0.t4t_tag_read ...
# # t4t_tag_read: Test terminated by timeout
# # FAIL NCI.NCI1_0.t4t_tag_read
# not ok 3 NCI.NCI1_0.t4t_tag_read
--- net/nfc/nci/data.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
net/nfc/nci/data.c +8 -4
@@ -33,7 +33,8 @@ void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, conn_info =nci_get_conn_info_by_conn_id (ndev, conn_id);if (!conn_info) {kfree_skb (skb); - goto exit; +clear_bit (NCI_DATA_EXCHANGE , &ndev->flags); +return ; } cb = conn_info->data_exchange_cb;
@@ -45,6 +46,12 @@ void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb,del_timer_sync (&ndev->data_timer);clear_bit (NCI_DATA_EXCHANGE_TO , &ndev->flags); +/* Mark the exchange as done before calling the callback. +* The callback (e.g. rawsock_data_exchange_complete) may +* want to immediately queue another data exchange. +*/ +clear_bit (NCI_DATA_EXCHANGE , &ndev->flags); +if (cb) {/* forward skb to nfc core */ cb (cb_context, skb, err);
@@ -54,9 +61,6 @@ void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb,/* no waiting callback, free skb */ kfree_skb (skb); } - -exit: -clear_bit (NCI_DATA_EXCHANGE , &ndev->flags); }/* ----------------- NCI TX Data ----------------- */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 134/481 nfc: rawsock: cancel tx_work before socket teardown
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
[ Upstream commit d793458c45df2aed498d7f74145eab7ee22d25aa ]
In rawsock_release(), cancel any pending tx_work and purge the write queue before orphaning the socket. rawsock_tx_work runs on the system workqueue and calls nfc_data_exchange which dereferences the NCI device. Without synchronization, tx_work can race with socket and device teardown when a process is killed (e.g. by SIGKILL), leading to use-after-free or leaked references.
Set SEND_SHUTDOWN first so that if tx_work is already running it will see the flag and skip transmitting, then use cancel_work_sync to wait for any in-progress execution to finish, and finally purge any remaining queued skbs.
--- net/nfc/rawsock.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
net/nfc/rawsock.c +11 -0
@@ -66,6 +66,17 @@ static int rawsock_release(struct socket *sock)if (sock->type ==SOCK_RAW )nfc_sock_unlink (&raw_sk_list, sk); +if (sk->sk_state ==TCP_ESTABLISHED ) { +/* Prevent rawsock_tx_work from starting new transmits and +* wait for any in-progress work to finish. This must happen +* before the socket is orphaned to avoid a race where +* rawsock_tx_work runs after the NCI device has been freed. +*/ + sk->sk_shutdown |=SEND_SHUTDOWN ; +cancel_work_sync (&nfc_rawsock (sk)->tx_work); +rawsock_write_queue_purge (sk); + } +sock_orphan (sk);sock_put (sk);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 135/481 net: stmmac: Fix error handling in VLAN add and delete paths
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ovidiu Panait <[email protected]>
[ Upstream commit 35dfedce442c4060cfe5b98368bc9643fb995716 ]
stmmac_vlan_rx_add_vid() updates active_vlans and the VLAN hash register before writing the HW filter entry. If the filter write fails, it leaves a stale VID in active_vlans and the hash register.
stmmac_vlan_rx_kill_vid() has the reverse problem: it clears active_vlans before removing the HW filter. On failure, the VID is gone from active_vlans but still present in the HW filter table.
To fix this, reorder the operations to update the hash table first, then attempt the HW filter operation. If the HW filter fails, roll back both the active_vlans bitmap and the hash table by calling stmmac_vlan_update() again.
--- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +14 -4
@@ -6451,9 +6451,13 @@ static int stmmac_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vidif (priv->hw->num_vlan) { ret =stmmac_add_hw_vlan_rx_fltr (priv, ndev, priv->hw, proto, vid); -if (ret) +if (ret) { +clear_bit (vid, priv->active_vlans); +stmmac_vlan_update (priv, is_double); goto err_pm_put; + } } + err_pm_put:pm_runtime_put (priv->device);
@@ -6474,15 +6478,21 @@ static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vi is_double = true;clear_bit (vid, priv->active_vlans); + ret =stmmac_vlan_update (priv, is_double); +if (ret) { +set_bit (vid, priv->active_vlans); + goto del_vlan_error; + }if (priv->hw->num_vlan) { ret =stmmac_del_hw_vlan_rx_fltr (priv, ndev, priv->hw, proto, vid); -if (ret) +if (ret) { +set_bit (vid, priv->active_vlans); +stmmac_vlan_update (priv, is_double); goto del_vlan_error; + } } - ret =stmmac_vlan_update (priv, is_double); - del_vlan_error:pm_runtime_put (priv->device);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 136/481 net: ethernet: mtk_eth_soc: Reset prog ptr to old_prog in case of error in mtk_xdp_setup()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <[email protected]>
[ Upstream commit 0abc73c8a40fd64ac1739c90bb4f42c418d27a5e ]
Reset eBPF program pointer to old_prog and do not decrease its ref-count if mtk_open routine in mtk_xdp_setup() fails.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +12 -3
@@ -3119,12 +3119,21 @@ static int mtk_xdp_setup(struct net_device *dev, struct bpf_prog *prog,mtk_stop (dev); old_prog =rcu_replace_pointer (eth->prog, prog,lockdep_rtnl_is_held ()); + +if (netif_running (dev) && need_update) { +int err; + + err =mtk_open (dev); +if (err) { +rcu_assign_pointer (eth->prog, old_prog); + +return err; + } + } +if (old_prog)bpf_prog_put (old_prog); -if (netif_running (dev) && need_update) -return mtk_open (dev); -return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 137/481 net: bridge: fix nd_tbl NULL dereference when IPv6 is disabled
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fernando Fernandez Mancera <[email protected]>
[ Upstream commit e5e890630533bdc15b26a34bb8e7ef539bdf1322 ]
When booting with the 'ipv6.disable=1' parameter, the nd_tbl is never initialized because inet6_init() exits before ndisc_init() is called which initializes it. Then, if neigh_suppress is enabled and an ICMPv6 Neighbor Discovery packet reaches the bridge, br_do_suppress_nd() will dereference ipv6_stub->nd_tbl which is NULL, passing it to neigh_lookup(). This causes a kernel NULL pointer dereference.
BUG: kernel NULL pointer dereference, address: 0000000000000268 Oops: 0000 [#1] PREEMPT SMP NOPTI [...] RIP: 0010:neigh_lookup+0x16/0xe0 [...] Call Trace: <IRQ> ? neigh_lookup+0x16/0xe0 br_do_suppress_nd+0x160/0x290 [bridge] br_handle_frame_finish+0x500/0x620 [bridge] br_handle_frame+0x353/0x440 [bridge] __netif_receive_skb_core.constprop.0+0x298/0x1110 __netif_receive_skb_one_core+0x3d/0xa0 process_backlog+0xa0/0x140 __napi_poll+0x2c/0x170 net_rx_action+0x2c4/0x3a0 handle_softirqs+0xd0/0x270 do_softirq+0x3f/0x60
Fix this by replacing IS_ENABLED(IPV6) call with ipv6_mod_enabled() in the callers. This is in essence disabling NS/NA suppression when IPv6 is disabled.
--- net/bridge/br_device.c | 2 +- net/bridge/br_input.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
net/bridge/br_device.c +1 -1
@@ -71,7 +71,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) eth_hdr(skb)->h_proto == htons(ETH_P_RARP)) && br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED)) {br_do_proxy_suppress_arp (skb, br, vid,NULL ); - } else if (IS_ENABLED(CONFIG_IPV6) && + } else if (ipv6_mod_enabled() && skb->protocol == htons(ETH_P_IPV6) && br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED) && pskb_may_pull(skb, sizeof(struct ipv6hdr) +
net/bridge/br_input.c +1 -1
@@ -148,7 +148,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb (skb->protocol == htons(ETH_P_ARP) || skb->protocol == htons(ETH_P_RARP))) {br_do_proxy_suppress_arp (skb, br, vid, p); - } else if (IS_ENABLED(CONFIG_IPV6) && + } else if (ipv6_mod_enabled() && skb->protocol == htons(ETH_P_IPV6) && br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED) && pskb_may_pull(skb, sizeof(struct ipv6hdr) +
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 138/481 net: vxlan: fix nd_tbl NULL dereference when IPv6 is disabled
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fernando Fernandez Mancera <[email protected]>
[ Upstream commit 168ff39e4758897d2eee4756977d036d52884c7e ]
When booting with the 'ipv6.disable=1' parameter, the nd_tbl is never initialized because inet6_init() exits before ndisc_init() is called which initializes it. If an IPv6 packet is injected into the interface, route_shortcircuit() is called and a NULL pointer dereference happens on neigh_lookup().
BUG: kernel NULL pointer dereference, address: 0000000000000380 Oops: Oops: 0000 [#1] SMP NOPTI [...] RIP: 0010:neigh_lookup+0x20/0x270 [...] Call Trace: <TASK> vxlan_xmit+0x638/0x1ef0 [vxlan] dev_hard_start_xmit+0x9e/0x2e0 __dev_queue_xmit+0xbee/0x14e0 packet_sendmsg+0x116f/0x1930 __sys_sendto+0x1f5/0x200 __x64_sys_sendto+0x24/0x30 do_syscall_64+0x12f/0x1590 entry_SYSCALL_64_after_hwframe+0x76/0x7e
Fix this by adding an early check on route_shortcircuit() when protocol is ETH_P_IPV6. Note that ipv6_mod_enabled() cannot be used here because VXLAN can be built-in even when IPv6 is built as a module.
--- drivers/net/vxlan/vxlan_core.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/vxlan/vxlan_core.c +5 -0
@@ -2171,6 +2171,11 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb) {struct ipv6hdr *pip6; +/* check if nd_tbl is not initiliazed due to +* ipv6.disable=1 set during boot +*/ +if (!ipv6_stub->nd_tbl) +return false;if (!pskb_may_pull (skb,sizeof (struct ipv6hdr )))return false; pip6 =ipv6_hdr (skb);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 139/481 net: ipv6: fix panic when IPv4 route references loopback IPv6 nexthop
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
[ Upstream commit 21ec92774d1536f71bdc90b0e3d052eff99cf093 ]
When a standalone IPv6 nexthop object is created with a loopback device (e.g., "ip -6 nexthop add id 100 dev lo"), fib6_nh_init() misclassifies it as a reject route. This is because nexthop objects have no destination prefix (fc_dst=::), causing fib6_is_reject() to match any loopback nexthop. The reject path skips fib_nh_common_init(), leaving nhc_pcpu_rth_output unallocated. If an IPv4 route later references this nexthop, __mkroute_output() dereferences NULL nhc_pcpu_rth_output and panics.
Simplify the check in fib6_nh_init() to only match explicit reject routes (RTF_REJECT) instead of using fib6_is_reject(). The loopback promotion heuristic in fib6_is_reject() is handled separately by ip6_route_info_create_nh(). After this change, the three cases behave as follows:
1. Explicit reject route ("ip -6 route add unreachable 2001:db8::/64"):
RTF_REJECT is set, enters reject path, skips fib_nh_common_init(). No behavior change.
2. Implicit loopback reject route ("ip -6 route add 2001:db8::/32 dev lo"):
RTF_REJECT is not set, takes normal path, fib_nh_common_init() is called. ip6_route_info_create_nh() still promotes it to reject afterward. nhc_pcpu_rth_output is allocated but unused, which is harmless.
3. Standalone nexthop object ("ip -6 nexthop add id 100 dev lo"):
RTF_REJECT is not set, takes normal path, fib_nh_common_init() is called. nhc_pcpu_rth_output is properly allocated, fixing the crash when IPv4 routes reference this nexthop.
--- net/ipv6/route.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
net/ipv6/route.c +3 -5
@@ -3558,7 +3558,6 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh, {struct net_device *dev =NULL ;struct inet6_dev *idev =NULL ; -int addr_type;int err; fib6_nh->fib_nh_family =AF_INET6 ;
@@ -3599,11 +3598,10 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh, fib6_nh->fib_nh_weight =1 ; -/* We cannot add true routes via loopback here, -* they would result in kernel looping; promote them to reject routes +/* Reset the nexthop device to the loopback device in case of reject +* routes. */ - addr_type =ipv6_addr_type (&cfg->fc_dst); -if (fib6_is_reject (cfg->fc_flags, dev, addr_type)) { +if (cfg->fc_flags &RTF_REJECT ) {/* hold loopback dev/idev if we haven't done so. */ if (dev != net->loopback_dev) {if (dev) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 140/481 net/sched: act_ife: Fix metalist update behavior
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <[email protected]>
[ Upstream commit e2cedd400c3ec0302ffca2490e8751772906ac23 ]
Whenever an ife action replace changes the metalist, instead of replacing the old data on the metalist, the current ife code is appending the new metadata. Aside from being innapropriate behavior, this may lead to an unbounded addition of metadata to the metalist which might cause an out of bounds error when running the encode op:
[ 138.423369][ C1] ================================================================== [ 138.424317][ C1] BUG: KASAN: slab-out-of-bounds in ife_tlv_meta_encode (net/ife/ife.c:168) [ 138.424906][ C1] Write of size 4 at addr ffff8880077f4ffe by task ife_out_out_bou/255 [ 138.425778][ C1] CPU: 1 UID: 0 PID: 255 Comm: ife_out_out_bou Not tainted 7.0.0-rc1-00169-gfbdfa8da05b6 #624 PREEMPT(full) [ 138.425795][ C1] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 [ 138.425800][ C1] Call Trace: [ 138.425804][ C1] <IRQ> [ 138.425808][ C1] dump_stack_lvl (lib/dump_stack.c:122) [ 138.425828][ C1] print_report (mm/kasan/report.c:379 mm/kasan/report.c:482) [ 138.425839][ C1] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) [ 138.425844][ C1] ? __virt_addr_valid (./arch/x86/include/asm/preempt.h:95 (discriminator 1) ./include/linux/rcupdate.h:975 (discriminator 1) ./include/linux/mmzone.h:2207 (discriminator 1) arch/x86/mm/physaddr.c:54 (discriminator 1)) [ 138.425853][ C1] ? ife_tlv_meta_encode (net/ife/ife.c:168) [ 138.425859][ C1] kasan_report (mm/kasan/report.c:221 mm/kasan/report.c:597) [ 138.425868][ C1] ? ife_tlv_meta_encode (net/ife/ife.c:168) [ 138.425878][ C1] kasan_check_range (mm/kasan/generic.c:186 (discriminator 1) mm/kasan/generic.c:200 (discriminator 1)) [ 138.425884][ C1] __asan_memset (mm/kasan/shadow.c:84 (discriminator 2)) [ 138.425889][ C1] ife_tlv_meta_encode (net/ife/ife.c:168) [ 138.425893][ C1] ? ife_tlv_meta_encode (net/ife/ife.c:171) [ 138.425898][ C1] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) [ 138.425903][ C1] ife_encode_meta_u16 (net/sched/act_ife.c:57) [ 138.425910][ C1] ? __pfx_do_raw_spin_lock (kernel/locking/spinlock_debug.c:114) [ 138.425916][ C1] ? __asan_memcpy (mm/kasan/shadow.c:105 (discriminator 3)) [ 138.425921][ C1] ? __pfx_ife_encode_meta_u16 (net/sched/act_ife.c:45) [ 138.425927][ C1] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) [ 138.425931][ C1] tcf_ife_act (net/sched/act_ife.c:847 net/sched/act_ife.c:879)
To solve this issue, fix the replace behavior by adding the metalist to the ife rcu data structure.
--- include/net/tc_act/tc_ife.h | 4 +- net/sched/act_ife.c | 93 ++++++++++++++++++------------------- 2 files changed, 45 insertions(+), 52 deletions(-)
include/net/tc_act/tc_ife.h +1 -3
@@ -13,15 +13,13 @@ struct tcf_ife_params {u8 eth_src[ETH_ALEN ];u16 eth_type;u16 flags; - +struct list_head metalist;struct rcu_head rcu; };struct tcf_ife_info {struct tc_action common;struct tcf_ife_params __rcu *params; -/* list of metaids allowed */ -struct list_head metalist; };#define to_ife (a) ((struct tcf_ife_info *)a)
net/sched/act_ife.c +44 -49
294 lines not on this page · raw message
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 141/481 xdp: use modulo operation to calculate XDP frag tailroom
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Larysa Zaremba <[email protected]>
[ Upstream commit 88b6b7f7b216108a09887b074395fa7b751880b1 ]
The current formula for calculating XDP tailroom in mbuf packets works only if each frag has its own page (if rxq->frag_size is PAGE_SIZE), this defeats the purpose of the parameter overall and without any indication leads to negative calculated tailroom on at least half of frags, if shared pages are used.
There are not many drivers that set rxq->frag_size. Among them:
* i40e and enetc always split page uniformly between frags, use shared pages
* ice uses page_pool frags via libeth, those are power-of-2 and uniformly distributed across page
* idpf has variable frag_size with XDP on, so current API is not applicable
* mlx5, mtk and mvneta use PAGE_SIZE or 0 as frag_size for page_pool
As for AF_XDP ZC, only ice, i40e and idpf declare frag_size for it. Modulo operation yields good results for aligned chunks, they are all power-of-2, between 2K and PAGE_SIZE. Formula without modulo fails when chunk_size is 2K. Buffers in unaligned mode are not distributed uniformly, so modulo operation would not work.
To accommodate unaligned buffers, we could define frag_size as data + tailroom, and hence do not subtract offset when calculating tailroom, but this would necessitate more changes in the drivers.
Define rxq->frag_size as an even portion of a page that fully belongs to a single frag. When calculating tailroom, locate the data start within such portion by performing a modulo operation on page offset.
--- net/core/filter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/core/filter.c +2 -1
@@ -4083,7 +4083,8 @@ static int bpf_xdp_frags_increase_tail(struct xdp_buff *xdp, int offset)if (!rxq->frag_size || rxq->frag_size > xdp->frame_sz)return -EOPNOTSUPP ; - tailroom = rxq->frag_size -skb_frag_size (frag) -skb_frag_off (frag); + tailroom = rxq->frag_size -skb_frag_size (frag) - +skb_frag_off (frag) % rxq->frag_size;if (unlikely (offset > tailroom))return -EINVAL ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 142/481 xdp: produce a warning when calculated tailroom is negative
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Larysa Zaremba <[email protected]>
[ Upstream commit 8821e857759be9db3cde337ad328b71fe5c8a55f ]
Many ethernet drivers report xdp Rx queue frag size as being the same as DMA write size. However, the only user of this field, namely bpf_xdp_frags_increase_tail(), clearly expects a truesize.
Such difference leads to unspecific memory corruption issues under certain circumstances, e.g. in ixgbevf maximum DMA write size is 3 KB, so when running xskxceiver's XDP_ADJUST_TAIL_GROW_MULTI_BUFF, 6K packet fully uses all DMA-writable space in 2 buffers. This would be fine, if only rxq->frag_size was properly set to 4K, but value of 3K results in a negative tailroom, because there is a non-zero page offset.
We are supposed to return -EINVAL and be done with it in such case, but due to tailroom being stored as an unsigned int, it is reported to be somewhere near UINT_MAX, resulting in a tail being grown, even if the requested offset is too much (it is around 2K in the abovementioned test). This later leads to all kinds of unspecific calltraces.
[ 7340.337579] xskxceiver[1440]: segfault at 1da718 ip 00007f4161aeac9d sp 00007f41615a6a00 error 6 [ 7340.338040] xskxceiver[1441]: segfault at 7f410000000b ip 00000000004042b5 sp 00007f415bffecf0 error 4 [ 7340.338179] in libc.so.6[61c9d,7f4161aaf000+160000] [ 7340.339230] in xskxceiver[42b5,400000+69000] [ 7340.340300] likely on CPU 6 (core 0, socket 6) [ 7340.340302] Code: ff ff 01 e9 f4 fe ff ff 0f 1f 44 00 00 4c 39 f0 74 73 31 c0 ba 01 00 00 00 f0 0f b1 17 0f 85 ba 00 00 00 49 8b 87 88 00 00 00 <4c> 89 70 08 eb cc 0f 1f 44 00 00 48 8d bd f0 fe ff ff 89 85 ec fe [ 7340.340888] likely on CPU 3 (core 0, socket 3) [ 7340.345088] Code: 00 00 00 ba 00 00 00 00 be 00 00 00 00 89 c7 e8 31 ca ff ff 89 45 ec 8b 45 ec 85 c0 78 07 b8 00 00 00 00 eb 46 e8 0b c8 ff ff <8b> 00 83 f8 69 74 24 e8 ff c7 ff ff 8b 00 83 f8 0b 74 18 e8 f3 c7 [ 7340.404334] Oops: general protection fault, probably for non-canonical address 0x6d255010bdffc: 0000 [#1] SMP NOPTI [ 7340.405972] CPU: 7 UID: 0 PID: 1439 Comm: xskxceiver Not tainted 6.19.0-rc1+ #21 PREEMPT(lazy) [ 7340.408006] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-5.fc42 04/01/2014 [ 7340.409716] RIP: 0010:lookup_swap_cgroup_id+0x44/0x80 [ 7340.410455] Code: 83 f8 1c 73 39 48 ba ff ff ff ff ff ff ff 03 48 8b 04 c5 20 55 fa bd 48 21 d1 48 89 ca 83 e1 01 48 d1 ea c1 e1 04 48 8d 04 90 <8b> 00 48 83 c4 10 d3 e8 c3 cc cc cc cc 31 c0 e9 98 b7 dd 00 48 89 [ 7340.412787] RSP: 0018:ffffcc5c04f7f6d0 EFLAGS: 00010202 [ 7340.413494] RAX: 0006d255010bdffc RBX: ffff891f477895a8 RCX: 0000000000000010 [ 7340.414431] RDX: 0001c17e3fffffff RSI: 00fa070000000000 RDI: 000382fc7fffffff [ 7340.415354] RBP: 00fa070000000000 R08: ffffcc5c04f7f8f8 R09: ffffcc5c04f7f7d0 [ 7340.416283] R10: ffff891f4c1a7000 R11: ffffcc5c04f7f9c8 R12: ffffcc5c04f7f7d0 [ 7340.417218] R13: 03ffffffffffffff R14: 00fa06fffffffe00 R15: ffff891f47789500 [ 7340.418229] FS: 0000000000000000(0000) GS:ffff891ffdfaa000(0000) knlGS:0000000000000000 [ 7340.419489] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 7340.420286] CR2: 00007f415bfffd58 CR3: 0000000103f03002 CR4: 0000000000772ef0 [ 7340.421237] PKRU: 55555554 [ 7340.421623] Call Trace: [ 7340.421987] <TASK> [ 7340.422309] ? softleaf_from_pte+0x77/0xa0 [ 7340.422855] swap_pte_batch+0xa7/0x290 [ 7340.423363] zap_nonpresent_ptes.constprop.0.isra.0+0xd1/0x270 [ 7340.424102] zap_pte_range+0x281/0x580 [ 7340.424607] zap_pmd_range.isra.0+0xc9/0x240 [ 7340.425177] unmap_page_range+0x24d/0x420 [ 7340.425714] unmap_vmas+0xa1/0x180 [ 7340.426185] exit_mmap+0xe1/0x3b0 [ 7340.426644] __mmput+0x41/0x150 [ 7340.427098] exit_mm+0xb1/0x110 [ 7340.427539] do_exit+0x1b2/0x460 [ 7340.427992] do_group_exit+0x2d/0xc0 [ 7340.428477] get_signal+0x79d/0x7e0 [ 7340.428957] arch_do_signal_or_restart+0x34/0x100 [ 7340.429571] exit_to_user_mode_loop+0x8e/0x4c0 [ 7340.430159] do_syscall_64+0x188/0x6b0 [ 7340.430672] ? __do_sys_clone3+0xd9/0x120 [ 7340.431212] ? switch_fpu_return+0x4e/0xd0 [ 7340.431761] ? arch_exit_to_user_mode_prepare.isra.0+0xa1/0xc0 [ 7340.432498] ? do_syscall_64+0xbb/0x6b0 [ 7340.433015] ? __handle_mm_fault+0x445/0x690 [ 7340.433582] ? count_memcg_events+0xd6/0x210 [ 7340.434151] ? handle_mm_fault+0x212/0x340 [ 7340.434697] ? do_user_addr_fault+0x2b4/0x7b0 [ 7340.435271] ? clear_bhb_loop+0x30/0x80 [ 7340.435788] ? clear_bhb_loop+0x30/0x80 [ 7340.436299] ? clear_bhb_loop+0x30/0x80 [ 7340.436812] ? clear_bhb_loop+0x30/0x80 [ 7340.437323] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 7340.437973] RIP: 0033:0x7f4161b14169 [ 7340.438468] Code: Unable to access opcode bytes at 0x7f4161b1413f. [ 7340.439242] RSP: 002b:00007ffc6ebfa770 EFLAGS: 00000246 ORIG_RAX: 00000000000000ca [ 7340.440173] RAX: fffffffffffffe00 RBX: 00000000000005a1 RCX: 00007f4161b14169 [ 7340.441061] RDX: 00000000000005a1 RSI: 0000000000000109 RDI: 00007f415bfff990 [ 7340.441943] RBP: 00007ffc6ebfa7a0 R08: 0000000000000000 R09: 00000000ffffffff [ 7340.442824] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 [ 7340.443707] R13: 0000000000000000 R14: 00007f415bfff990 R15: 00007f415bfff6c0 [ 7340.444586] </TASK> [ 7340.444922] Modules linked in: rfkill intel_rapl_msr intel_rapl_common intel_uncore_frequency_common skx_edac_common nfit libnvdimm kvm_intel vfat fat kvm snd_pcm irqbypass rapl iTCO_wdt snd_timer intel_pmc_bxt iTCO_vendor_support snd ixgbevf virtio_net soundcore i2c_i801 pcspkr libeth_xdp net_failover i2c_smbus lpc_ich failover libeth virtio_balloon joydev 9p fuse loop zram lz4hc_compress lz4_compress 9pnet_virtio 9pnet netfs ghash_clmulni_intel serio_raw qemu_fw_cfg [ 7340.449650] ---[ end trace 0000000000000000 ]---
The issue can be fixed in all in-tree drivers, but we cannot just trust OOT drivers to not do this. Therefore, make tailroom a signed int and produce a warning when it is negative to prevent such mistakes in the future.
--- net/core/filter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/core/filter.c +2 -1
@@ -4078,13 +4078,14 @@ static int bpf_xdp_frags_increase_tail(struct xdp_buff *xdp, int offset)struct skb_shared_info *sinfo =xdp_get_shared_info_from_buff (xdp);skb_frag_t *frag = &sinfo->frags[sinfo->nr_frags -1 ];struct xdp_rxq_info *rxq = xdp->rxq; -unsigned int tailroom; +int tailroom;if (!rxq->frag_size || rxq->frag_size > xdp->frame_sz)return -EOPNOTSUPP ; tailroom = rxq->frag_size -skb_frag_size (frag) -skb_frag_off (frag) % rxq->frag_size; +WARN_ON_ONCE (tailroom <0 );if (unlikely (offset > tailroom))return -EINVAL ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 143/481 tracing: Add NULL pointer check to trigger_data_free()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit 457965c13f0837a289c9164b842d0860133f6274 ]
If trigger_data_alloc() fails and returns NULL, event_hist_trigger_parse() jumps to the out_free error path. While kfree() safely handles a NULL pointer, trigger_data_free() does not. This causes a NULL pointer dereference in trigger_data_free() when evaluating data->cmd_ops->set_filter.
Fix the problem by adding a NULL pointer check to trigger_data_free().
The problem was found by an experimental code review agent based on gemini-3.1-pro while reviewing backports into v6.18.y.
--- kernel/trace/trace_events_trigger.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/trace/trace_events_trigger.c +3 -0
@@ -19,6 +19,9 @@ static DEFINE_MUTEX(trigger_cmd_mutex);void trigger_data_free (struct event_trigger_data *data) { +if (!data) +return ; +if (data->cmd_ops->set_filter) data->cmd_ops->set_filter (NULL , data,NULL );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 144/481 net/sched: Only allow act_ct to bind to clsact/ingress qdiscs and shared blocks
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Nogueira <[email protected]>
commit 11cb63b0d1a0685e0831ae3c77223e002ef18189 upstream.
As Paolo said earlier [1]:
"Since the blamed commit below, classify can return TC_ACT_CONSUMED while the current skb being held by the defragmentation engine. As reported by GangMin Kim, if such packet is that may cause a UaF when the defrag engine later on tries to tuch again such packet."
act_ct was never meant to be used in the egress path, however some users are attaching it to egress today [2]. Attempting to reach a middle ground, we noticed that, while most qdiscs are not handling TC_ACT_CONSUMED, clsact/ingress qdiscs are. With that in mind, we address the issue by only allowing act_ct to bind to clsact/ingress qdiscs and shared blocks. That way it's still possible to attach act_ct to egress (albeit only with clsact).
[1] https://lore.kernel.org/netdev/674b8cbfc385c6f37fb29a1de08d8fe5c2b0fbee.1771321118.git.pabeni@redhat.com/
[2] https://lore.kernel.org/netdev/[email protected]/
--- include/net/act_api.h | 1 + net/sched/act_ct.c | 6 ++++++ net/sched/cls_api.c | 7 +++++++ 3 files changed, 14 insertions(+)
include/net/act_api.h +1 -0
@@ -67,6 +67,7 @@ struct tc_action {#define TCA_ACT_FLAGS_BIND (1U << (TCA_ACT_FLAGS_USER_BITS + 1))#define TCA_ACT_FLAGS_REPLACE (1U << (TCA_ACT_FLAGS_USER_BITS + 2))#define TCA_ACT_FLAGS_NO_RTNL (1U << (TCA_ACT_FLAGS_USER_BITS + 3)) +#define TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT (1U << (TCA_ACT_FLAGS_USER_BITS + 5))/* Update lastuse only if needed, to avoid dirtying a cache line. * We use a temp variable to avoid fetching jiffies twice.
net/sched/act_ct.c +6 -0
@@ -1440,6 +1440,12 @@ static int tcf_ct_init(struct net *net,return -EINVAL ; } +if (bind && !(flags &TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT )) { +NL_SET_ERR_MSG_MOD (extack, +"Attaching ct to a non ingress/clsact qdisc is unsupported" ); +return -EOPNOTSUPP ; + } + err =nla_parse_nested (tb,TCA_CT_MAX , nla, ct_policy, extack);if (err <0 )return err;
net/sched/cls_api.c +7 -0
@@ -1993,6 +1993,11 @@ static void tfilter_put(struct tcf_proto tp->ops->put (tp, fh); } +static bool is_ingress_or_clsact (struct tcf_block *block,struct Qdisc *q) +{ +return tcf_block_shared (block) || (q && !!(q->flags &TCQ_F_INGRESS )); +} +static int tc_new_tfilter (struct sk_buff *skb,struct nlmsghdr *n,struct netlink_ext_ack *extack) {
@@ -2184,6 +2189,8 @@ replay: flags |=TCA_ACT_FLAGS_REPLACE ;if (!rtnl_held) flags |=TCA_ACT_FLAGS_NO_RTNL ; +if (is_ingress_or_clsact (block, q)) + flags |=TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT ; err = tp->ops->change (net, skb, tp, cl, t->tcm_handle, tca, &fh, flags, extack);if (err ==0 ) {
Greg Kroah-Hartman
maintainerPATCH 145/481 net: tcp: accept old ack during closing
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Menglong Dong <[email protected]>
commit 795a7dfbc3d95e4c7c09569f319f026f8c7f5a9c upstream.
For now, the packet with an old ack is not accepted if we are in FIN_WAIT1 state, which can cause retransmission. Taking the following case as an example:
Client Server
| |
FIN_WAIT1(Send FIN, seq=10) FIN_WAIT1(Send FIN, seq=20, ack=10)
| |
| Send ACK(seq=21, ack=11)
Recv ACK(seq=21, ack=11)
| Recv FIN(seq=20, ack=10)
In the case above, simultaneous close is happening, and the FIN and ACK packet that send from the server is out of order. Then, the FIN will be dropped by the client, as it has an old ack. Then, the server has to retransmit the FIN, which can cause delay if the server has set the SO_LINGER on the socket.
Old ack is accepted in the ESTABLISHED and TIME_WAIT state, and I think it should be better to keep the same logic.
In this commit, we accept old ack in FIN_WAIT1/FIN_WAIT2/CLOSING/LAST_ACK states. Maybe we should limit it to FIN_WAIT1 for now?
--- net/ipv4/tcp_input.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
net/ipv4/tcp_input.c +11 -7
@@ -6630,17 +6630,21 @@ int tcp_rcv_state_process(struct sock *sreturn 0 ;/* step 5: check the ACK field */ - acceptable =tcp_ack (sk, skb,FLAG_SLOWPATH | -FLAG_UPDATE_TS_RECENT | -FLAG_NO_CHALLENGE_ACK ) >0 ; + reason =tcp_ack (sk, skb,FLAG_SLOWPATH | +FLAG_UPDATE_TS_RECENT | +FLAG_NO_CHALLENGE_ACK ); -if (!acceptable) { +if ((int )reason <=0 ) {if (sk->sk_state ==TCP_SYN_RECV )return 1 ;/* send one RST */ -tcp_send_challenge_ack (sk); -SKB_DR_SET (reason,TCP_OLD_ACK ); - goto discard; +/* accept old ack during closing */ +if ((int )reason <0 ) { +tcp_send_challenge_ack (sk); + reason = -reason; + goto discard; + } } +SKB_DR_SET (reason,NOT_SPECIFIED );switch (sk->sk_state) {case TCP_SYN_RECV : tp->delivered++;/* SYN-ACK delivery isn't tracked in tcp_ack */
Greg Kroah-Hartman
maintainerPATCH 146/481 scsi: storvsc: Fix scheduling while atomic on PREEMPT_RT
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kiszka <[email protected]>
[ Upstream commit 57297736c08233987e5d29ce6584c6ca2a831b12 ]
This resolves the follow splat and lock-up when running with PREEMPT_RT enabled on Hyper-V:
[ 415.140818] BUG: scheduling while atomic: stress-ng-iomix/1048/0x00000002
[ 415.140822] INFO: lockdep is turned off.
[ 415.140823] Modules linked in: intel_rapl_msr intel_rapl_common intel_uncore_frequency_common intel_pmc_core pmt_telemetry pmt_discovery pmt_class intel_pmc_ssram_telemetry intel_vsec ghash_clmulni_intel aesni_intel rapl binfmt_misc nls_ascii nls_cp437 vfat fat snd_pcm hyperv_drm snd_timer drm_client_lib drm_shmem_helper snd sg soundcore drm_kms_helper pcspkr hv_balloon hv_utils evdev joydev drm configfs efi_pstore nfnetlink vsock_loopback vmw_vsock_virtio_transport_common hv_sock vmw_vsock_vmci_transport vsock vmw_vmci efivarfs autofs4 ext4 crc16 mbcache jbd2 sr_mod sd_mod cdrom hv_storvsc serio_raw hid_generic scsi_transport_fc hid_hyperv scsi_mod hid hv_netvsc hyperv_keyboard scsi_common
[ 415.140846] Preemption disabled at:
[ 415.140847] [<ffffffffc0656171>] storvsc_queuecommand+0x2e1/0xbe0 [hv_storvsc]
[ 415.140854] CPU: 8 UID: 0 PID: 1048 Comm: stress-ng-iomix Not tainted 6.19.0-rc7 #30 PREEMPT_{RT,(full)}
[ 415.140856] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.1 09/04/2024
[ 415.140857] Call Trace:
[ 415.140861] <TASK>
[ 415.140861] ? storvsc_queuecommand+0x2e1/0xbe0 [hv_storvsc]
[ 415.140863] dump_stack_lvl+0x91/0xb0
[ 415.140870] __schedule_bug+0x9c/0xc0
[ 415.140875] __schedule+0xdf6/0x1300
[ 415.140877] ? rtlock_slowlock_locked+0x56c/0x1980
[ 415.140879] ? rcu_is_watching+0x12/0x60
[ 415.140883] schedule_rtlock+0x21/0x40
[ 415.140885] rtlock_slowlock_locked+0x502/0x1980
[ 415.140891] rt_spin_lock+0x89/0x1e0
[ 415.140893] hv_ringbuffer_write+0x87/0x2a0
[ 415.140899] vmbus_sendpacket_mpb_desc+0xb6/0xe0
[ 415.140900] ? rcu_is_watching+0x12/0x60
[ 415.140902] storvsc_queuecommand+0x669/0xbe0 [hv_storvsc]
[ 415.140904] ? HARDIRQ_verbose+0x10/0x10
[ 415.140908] ? __rq_qos_issue+0x28/0x40
[ 415.140911] scsi_queue_rq+0x760/0xd80 [scsi_mod]
[ 415.140926] __blk_mq_issue_directly+0x4a/0xc0
[ 415.140928] blk_mq_issue_direct+0x87/0x2b0
[ 415.140931] blk_mq_dispatch_queue_requests+0x120/0x440
[ 415.140933] blk_mq_flush_plug_list+0x7a/0x1a0
[ 415.140935] __blk_flush_plug+0xf4/0x150
[ 415.140940] __submit_bio+0x2b2/0x5c0
[ 415.140944] ? submit_bio_noacct_nocheck+0x272/0x360
[ 415.140946] submit_bio_noacct_nocheck+0x272/0x360
[ 415.140951] ext4_read_bh_lock+0x3e/0x60 [ext4]
[ 415.140995] ext4_block_write_begin+0x396/0x650 [ext4]
[ 415.141018] ? __pfx_ext4_da_get_block_prep+0x10/0x10 [ext4]
[ 415.141038] ext4_da_write_begin+0x1c4/0x350 [ext4]
[ 415.141060] generic_perform_write+0x14e/0x2c0
[ 415.141065] ext4_buffered_write_iter+0x6b/0x120 [ext4]
[ 415.141083] vfs_write+0x2ca/0x570
[ 415.141087] ksys_write+0x76/0xf0
[ 415.141089] do_syscall_64+0x99/0x1490
[ 415.141093] ? rcu_is_watching+0x12/0x60
[ 415.141095] ? finish_task_switch.isra.0+0xdf/0x3d0
[ 415.141097] ? rcu_is_watching+0x12/0x60
[ 415.141098] ? lock_release+0x1f0/0x2a0
[ 415.141100] ? rcu_is_watching+0x12/0x60
[ 415.141101] ? finish_task_switch.isra.0+0xe4/0x3d0
[ 415.141103] ? rcu_is_watching+0x12/0x60
[ 415.141104] ? __schedule+0xb34/0x1300
[ 415.141106] ? hrtimer_try_to_cancel+0x1d/0x170
[ 415.141109] ? do_nanosleep+0x8b/0x160
[ 415.141111] ? hrtimer_nanosleep+0x89/0x100
[ 415.141114] ? __pfx_hrtimer_wakeup+0x10/0x10
[ 415.141116] ? xfd_validate_state+0x26/0x90
[ 415.141118] ? rcu_is_watching+0x12/0x60
[ 415.141120] ? do_syscall_64+0x1e0/0x1490
[ 415.141121] ? do_syscall_64+0x1e0/0x1490
[ 415.141123] ? rcu_is_watching+0x12/0x60
[ 415.141124] ? do_syscall_64+0x1e0/0x1490
[ 415.141125] ? do_syscall_64+0x1e0/0x1490
[ 415.141127] ? irqentry_exit+0x140/0x7e0
[ 415.141129] entry_SYSCALL_64_after_hwframe+0x76/0x7eget_cpu() disables preemption while the spinlock hv_ringbuffer_write is using is converted to an rt-mutex under PREEMPT_RT.
--- drivers/scsi/storvsc_drv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/scsi/storvsc_drv.c +3 -2
@@ -1852,8 +1852,9 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) cmd_request->payload_sz = payload_sz;/* Invokes the vsc to start an IO */ - ret =storvsc_do_io (dev, cmd_request,get_cpu ()); -put_cpu (); +migrate_disable (); + ret =storvsc_do_io (dev, cmd_request,smp_processor_id ()); +migrate_enable ();if (ret)scsi_dma_unmap (scmnd);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 147/481 ACPI: PM: Save NVS memory on Lenovo G70-35
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Piotr Mazek <[email protected]>
[ Upstream commit 023cd6d90f8aa2ef7b72d84be84a18e61ecebd64 ]
[821d6f0359b0614792ab8e2fb93b503e25a65079] prevented machines produced later than 2012 from saving NVS region to accelerate S3.
Despite being made after 2012, Lenovo G70-35 still needs NVS memory saving during S3. A quirk is introduced for this platform.
--- drivers/acpi/sleep.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/acpi/sleep.c +8 -0
@@ -372,6 +372,14 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "80E1"), }, }, + { + .callback = init_nvs_save_s3, + .ident = "Lenovo G70-35", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "80Q5"), + }, + },/* * ThinkPad X1 Tablet(2016) cannot do suspend-to-idle using * the Low Power S0 Idle firmware interface (see
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 148/481 scsi: mpi3mr: Add NULL checks when resetting request and reply queues
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ranjan Kumar <[email protected]>
[ Upstream commit fa96392ebebc8fade2b878acb14cce0f71016503 ]
The driver encountered a crash during resource cleanup when the reply and request queues were NULL due to freed memory. This issue occurred when the creation of reply or request queues failed, and the driver freed the memory first, but attempted to mem set the content of the freed memory, leading to a system crash.
Add NULL pointer checks for reply and request queues before accessing the reply/request memory during cleanup
--- drivers/scsi/mpi3mr/mpi3mr_fw.c | 34 ++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-)
drivers/scsi/mpi3mr/mpi3mr_fw.c +19 -15
@@ -4246,21 +4246,25 @@ void mpi3mr_memset_buffers(struct mpi3mr_ioc *mrioc) }for (i =0 ; i < mrioc->num_queues; i++) { - mrioc->op_reply_qinfo[i].qid =0 ; - mrioc->op_reply_qinfo[i].ci =0 ; - mrioc->op_reply_qinfo[i].num_replies =0 ; - mrioc->op_reply_qinfo[i].ephase =0 ; -atomic_set (&mrioc->op_reply_qinfo[i].pend_ios,0 ); -atomic_set (&mrioc->op_reply_qinfo[i].in_use,0 ); -mpi3mr_memset_op_reply_q_buffers (mrioc, i); - - mrioc->req_qinfo[i].ci =0 ; - mrioc->req_qinfo[i].pi =0 ; - mrioc->req_qinfo[i].num_requests =0 ; - mrioc->req_qinfo[i].qid =0 ; - mrioc->req_qinfo[i].reply_qid =0 ; -spin_lock_init (&mrioc->req_qinfo[i].q_lock); -mpi3mr_memset_op_req_q_buffers (mrioc, i); +if (mrioc->op_reply_qinfo) { + mrioc->op_reply_qinfo[i].qid =0 ; + mrioc->op_reply_qinfo[i].ci =0 ; + mrioc->op_reply_qinfo[i].num_replies =0 ; + mrioc->op_reply_qinfo[i].ephase =0 ; +atomic_set (&mrioc->op_reply_qinfo[i].pend_ios,0 ); +atomic_set (&mrioc->op_reply_qinfo[i].in_use,0 ); +mpi3mr_memset_op_reply_q_buffers (mrioc, i); + } + +if (mrioc->req_qinfo) { + mrioc->req_qinfo[i].ci =0 ; + mrioc->req_qinfo[i].pi =0 ; + mrioc->req_qinfo[i].num_requests =0 ; + mrioc->req_qinfo[i].qid =0 ; + mrioc->req_qinfo[i].reply_qid =0 ; +spin_lock_init (&mrioc->req_qinfo[i].q_lock); +mpi3mr_memset_op_req_q_buffers (mrioc, i); + } }atomic_set (&mrioc->pend_large_data_sz,0 );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 149/481 unshare: fix unshare_fs() handling
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
[ Upstream commit 6c4b2243cb6c0755159bd567130d5e12e7b10d9f ]
There's an unpleasant corner case in unshare(2), when we have a CLONE_NEWNS in flags and current->fs hadn't been shared at all; in that case copy_mnt_ns() gets passed current->fs instead of a private copy, which causes interesting warts in proof of correctness]
Quoted 1 line
I guess if private means
fs->users== 1, the condition could still be true.
Unfortunately, it's worse than just a convoluted proof of correctness. Consider the case when we have CLONE_NEWCGROUP in addition to CLONE_NEWNS (and current->fs->users == 1).
We pass current->fs to copy_mnt_ns(), all right. Suppose it succeeds and flips current->fs->{pwd,root} to corresponding locations in the new namespace. Now we proceed to copy_cgroup_ns(), which fails (e.g. with -ENOMEM). We call put_mnt_ns() on the namespace created by copy_mnt_ns(), it's destroyed and its mount tree is dissolved, but... current->fs->root and current->fs->pwd are both left pointing to now detached mounts.
They are pinning those, so it's not a UAF, but it leaves the calling process with unshare(2) failing with -ENOMEM _and_ leaving it with pwd and root on detached isolated mounts. The last part is clearly a bug.
There is other fun related to that mess (races with pivot_root(), including the one between pivot_root() and fork(), of all things), but this one is easy to isolate and fix - treat CLONE_NEWNS as "allocate a new fs_struct even if it hadn't been shared in the first place". Sure, we could go for something like "if both CLONE_NEWNS *and* one of the things that might end up failing after copy_mnt_ns() call in create_new_namespaces() are set, force allocation of new fs_struct", but let's keep it simple - the cost of copy_fs_struct() is trivial.
Another benefit is that copy_mnt_ns() with CLONE_NEWNS *always* gets a freshly allocated fs_struct, yet to be attached to anything. That seriously simplifies the analysis...
FWIW, that bug had been there since the introduction of unshare(2) ;-/
--- kernel/fork.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/fork.c +1 -1
@@ -3193,7 +3193,7 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)return 0 ;/* don't need lock here; in the worst case we'll do useless copy */ -if (fs->users ==1 ) +if (!(unshare_flags &CLONE_NEWNS ) && fs->users ==1 )return 0 ; *new_fsp =copy_fs_struct (fs);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 150/481 wifi: mac80211: set default WMM parameters on all links
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ramanathan Choodamani <[email protected]>
[ Upstream commit 2259d14499d16b115ef8d5d2ddc867e2be7cb5b5 ]
Currently, mac80211 only initializes default WMM parameters on the deflink during do_open(). For MLO cases, this leaves the additional links without proper WMM defaults if hostapd does not supply per-link WMM parameters, leading to inconsistent QoS behavior across links.
Set default WMM parameters for each link during ieee80211_vif_update_links(), because this ensures all individual links in an MLD have valid WMM settings during bring-up and behave consistently across different BSS.
--- net/mac80211/link.c | 2 ++ 1 file changed, 2 insertions(+)
net/mac80211/link.c +2 -0
@@ -176,6 +176,7 @@ static int ieee80211_vif_update_links(struct ieee80211_sub_if_data *sdata,struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS ];struct ieee80211_link_data *old_data[IEEE80211_MLD_MAX_NUM_LINKS ];bool use_deflink = old_links ==0 ;/* set for error case */ +bool non_sta = sdata->vif.type !=NL80211_IFTYPE_STATION ;sdata_assert_lock (sdata);
@@ -229,6 +230,7 @@ static int ieee80211_vif_update_links(struct ieee80211_sub_if_data *sdata, link = links[link_id];ieee80211_link_init (sdata, link_id, &link->data, &link->conf);ieee80211_link_setup (&link->data); +ieee80211_set_wmm_default (&link->data, true, non_sta); }if (new_links ==0 )
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 151/481 ACPI: OSI: Add DMI quirk for Acer Aspire One D255
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sofia Schneider <[email protected]>
[ Upstream commit 5ede90206273ff156a778254f0f972a55e973c89 ]
The screen backlight turns off during boot (specifically during udev device initialization) when returning true for _OSI("Windows 2009").
Analyzing the device's DSDT reveals that the firmware takes a different code path when Windows 7 is reported, which leads to the backlight shutoff. Add a DMI quirk to invoke dmi_disable_osi_win7 for this model.
--- drivers/acpi/osi.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/acpi/osi.c +13 -0
@@ -389,6 +389,19 @@ static const struct dmi_system_id acpi_osi_dmi_table[] __initconst = { }, }, +/* +* The screen backlight turns off during udev device creation +* when returning true for _OSI("Windows 2009") +*/ + { + .callback = dmi_disable_osi_win7, + .ident = "Acer Aspire One D255", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "AOD255"), + }, + }, + /* * The wireless hotkey does not work on those machines when * returning true for _OSI("Windows 2012")
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 152/481 scsi: ses: Fix devices attaching to different hosts
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomas Henzl <[email protected]>
[ Upstream commit 70ca8caa96ce473647054f5c7b9dab5423902402 ]
On a multipath SAS system some devices don't end up with correct symlinks from the SCSI device to its enclosure. Some devices even have enclosure links pointing to enclosures attached to different SCSI hosts.
ses_match_to_enclosure() calls enclosure_for_each_device() which iterates over all enclosures on the system, not just enclosures attached to the current SCSI host.
Replace the iteration with a direct call to ses_enclosure_find_by_addr().
--- drivers/scsi/ses.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/scsi/ses.c +2 -3
@@ -497,9 +497,8 @@ struct efd { };static int ses_enclosure_find_by_addr (struct enclosure_device *edev, -void *data) +struct efd *efd) { -struct efd *efd = data;int i;struct ses_component *scomp;
@@ -652,7 +651,7 @@ static void ses_match_to_enclosure(struct enclosure_device *edev,if (efd.addr) { efd.dev = &sdev->sdev_gendev; -enclosure_for_each_device (ses_enclosure_find_by_addr, &efd); +ses_enclosure_find_by_addr (edev, &efd); } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 153/481 ASoC: amd: yc: Add ASUS EXPERTBOOK BM1503CDA to quirk table
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Azamat Almazbek uulu <[email protected]>
[ Upstream commit 32fc4168fa56f6301d858c778a3d712774e9657e ]
The ASUS ExpertBook BM1503CDA (Ryzen 5 7535U, Barcelo-R) has an internal DMIC connected through the AMD ACP (Audio CoProcessor) but is missing from the DMI quirk table, so the acp6x machine driver probe returns -ENODEV and no DMIC capture device is created.
Add the DMI entry so the internal microphone works out of the box.
--- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+)
sound/soc/amd/yc/acp6x-mach.c +7 -0
@@ -549,6 +549,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Vivobook_ASUSLaptop M6501RR_M6501RR"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "ASUS EXPERTBOOK BM1503CDA"), + } + }, {} };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 154/481 ALSA: usb-audio: Avoid implicit feedback mode on DIYINHK USB Audio 2.0
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit c5bf24c8aba1ff711226ee0f039ff01a5754692b ]
Although DIYINHK USB Audio 2.0 (ID 20b1:2009) shows the implicit feedback source for the capture stream, this would cause several problems for the playback. Namely, the device can get wMaxPackSize 1024 for 24/32 bit format with 6 channels, and when a high sample rate like 352.8kHz or 384kHz is played, the packet size overflows the max limit. Also, the device has another two playback altsets, and those aren't properly handled with the implicit feedback.
Since the device has been working well even before introducing the implicit feedback, we can assume that it works fine in the async mode. This patch adds the explicit skip of the implicit fb detection to make the playback running in the async mode.
--- sound/usb/quirks.c | 2 ++ 1 file changed, 2 insertions(+)
sound/usb/quirks.c +2 -0
@@ -2243,6 +2243,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),DEVICE_FLG (0x2040 ,0x7281 ,/* Hauppauge HVR-950Q-MXL */ QUIRK_FLAG_SHARE_MEDIA_DEVICE |QUIRK_FLAG_ALIGN_TRANSFER ), +DEVICE_FLG (0x20b1 ,0x2009 ,/* XMOS Ltd DIYINHK USB Audio 2.0 */ +QUIRK_FLAG_SKIP_IMPLICIT_FB |QUIRK_FLAG_DSD_RAW ),DEVICE_FLG (0x2040 ,0x8200 ,/* Hauppauge Woodbury */ QUIRK_FLAG_SHARE_MEDIA_DEVICE |QUIRK_FLAG_ALIGN_TRANSFER ), DEVICE_FLG(0x21b4, 0x0081, /* AudioQuest DragonFly */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 155/481 ALSA: usb-audio: Check max frame size for implicit feedback mode, too
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 7cb2a5422f5bbdf1cf32eae0eda41000485b9346 ]
When the packet sizes are taken from the capture stream in the implicit feedback mode, the sizes might be larger than the upper boundary defined by the descriptor. As already done for other transfer modes, we have to cap the sizes accordingly at sending, otherwise this would lead to an error in USB core at submission of URBs.
--- sound/usb/endpoint.c | 1 + 1 file changed, 1 insertion(+)
sound/usb/endpoint.c +1 -0
@@ -224,6 +224,7 @@ int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep, packet = ctx->packet_size[idx];if (packet) { + packet =min (packet, ep->maxframesize);if (avail && packet >= avail)return -EAGAIN ;return packet;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 156/481 powerpc/uaccess: Fix inline assembly for clang build on PPC32
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe Leroy (CS GROUP) <[email protected]>
[ Upstream commit 0ee95a1d458630272d0415d0ffa9424fcb606c90 ]
Test robot reports the following error with clang-16.0.6:
In file included from kernel/rseq.c:75:
include/linux/rseq_entry.h:141:3: error: invalid operand for instruction
unsafe_get_user(offset, &ucs->post_commit_offset, efault);
^
include/linux/uaccess.h:608:2: note: expanded from macro 'unsafe_get_user'
arch_unsafe_get_user(x, ptr, local_label); \
^
arch/powerpc/include/asm/uaccess.h:518:2: note: expanded from macro 'arch_unsafe_get_user'
__get_user_size_goto(__gu_val, __gu_addr, sizeof(*(p)), e); \
^
arch/powerpc/include/asm/uaccess.h:284:2: note: expanded from macro '__get_user_size_goto'
__get_user_size_allowed(x, ptr, size, __gus_retval); \
^
arch/powerpc/include/asm/uaccess.h:275:10: note: expanded from macro '__get_user_size_allowed'
case 8: __get_user_asm2(x, (u64 __user *)ptr, retval); break; \
^
arch/powerpc/include/asm/uaccess.h:258:4: note: expanded from macro '__get_user_asm2'
" li %1+1,0\n" \
^
<inline asm>:7:5: note: instantiated into assembly here
li 31+1,0
^
1 error generated.On PPC32, for 64 bits vars a pair of registers is used. Usually the lower register in the pair is the high part and the higher register is the low part. GCC uses r3/r4 ... r11/r12 ... r14/r15 ... r30/r31
In older kernel code inline assembly was using %1 and %1+1 to represent 64 bits values. However here it looks like clang uses r31 as high part, allthough r32 doesn't exist hence the error.
Allthoug %1+1 should work, most places now use %L1 instead of %1+1, so let's do the same here.
With that change, the build doesn't fail anymore and a disassembly shows clang uses r17/r18 and r31/r14 pair when GCC would have used r16/r17 and r30/r31:
Disassembly of section .fixup: 00000000 <.fixup>: 0: 38 a0 ff f2 li r5,-14 4: 3a 20 00 00 li r17,0 8: 3a 40 00 00 li r18,0 c: 48 00 00 00 b c <.fixup+0xc> c: R_PPC_REL24 .text+0xbc 10: 38 a0 ff f2 li r5,-14 14: 3b e0 00 00 li r31,0 18: 39 c0 00 00 li r14,0 1c: 48 00 00 00 b 1c <.fixup+0x1c> 1c: R_PPC_REL24 .text+0x144
--- arch/powerpc/include/asm/uaccess.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/include/asm/uaccess.h +1 -1
@@ -237,7 +237,7 @@ __gus_failed: \".section .fixup,\"ax\"\n" \"4: li %0,%3\n" \" li %1,0\n" \ -" li %1+1,0\n" \ +" li %L1,0\n" \" b 3b\n" \".previous\n" \EX_TABLE (1b ,4b ) \
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 157/481 remoteproc: sysmon: Correct subsys_name_len type in QMI request
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bjorn Andersson <[email protected]>
[ Upstream commit da994db94e60f9a9411108ddf4d1836147ad4c9c ]
The QMI message encoder has up until recently read a single byte (as elem_size == 1), but with the introduction of big endian support it's become apparent that this field is expected to be a full u32 - regardless of the size of the length in the encoded message (which is what elem_size specifies).
The result is that the encoder now reads past the length byte and rejects the unreasonably large length formed when including the following 3 bytes from the subsys_name array.
Fix this by changing to the expected type.
--- drivers/remoteproc/qcom_sysmon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/remoteproc/qcom_sysmon.c +1 -1
@@ -204,7 +204,7 @@ static struct qmi_elem_info ssctl_shutdown_resp_ei[] = { };struct ssctl_subsys_event_req { -u8 subsys_name_len; +u32 subsys_name_len;char subsys_name[SSCTL_SUBSYS_NAME_LENGTH ];u32 event;u8 evt_driven_valid;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 158/481 remoteproc: mediatek: Unprepare SCP clock during system suspend
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <[email protected]>
[ Upstream commit 35c3f72a2d55dbf52f28f4ecae51c76be1acf545 ]
Prior to commit d935187cfb27 ("remoteproc: mediatek: Break lock dependency to prepare_lock"), scp->clk was prepared and enabled only when it needs to communicate with the SCP. The commit d935187cfb27 moved the prepare operation to remoteproc's prepare(), keeping the clock prepared as long as the SCP is running.
The power consumption due to the prolonged clock preparation can be negligible when the system is running, as SCP is designed to be a very power efficient processor.
However, the clock remains prepared even when the system enters system suspend. This prevents the underlying clock controller (and potentially the parent PLLs) from shutting down, which increases power consumption and may block the system from entering deep sleep states.
Add suspend and resume callbacks. Unprepare the clock in suspend() if it was active and re-prepare it in resume() to ensure the clock is properly disabled during system suspend, while maintaining the "always prepared" semantics while the system is active. The driver doesn't implement .attach() callback, hence it only checks for RPROC_RUNNING.
--- drivers/remoteproc/mtk_scp.c | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
drivers/remoteproc/mtk_scp.c +39 -0
@@ -1025,12 +1025,51 @@ static const struct of_device_id mtk_scp_of_match[] = { };MODULE_DEVICE_TABLE (of, mtk_scp_of_match); +static int __maybe_unused scp_suspend (struct device *dev) +{ +struct mtk_scp *scp =dev_get_drvdata (dev); +struct rproc *rproc = scp->rproc; + +/* +* Only unprepare if the SCP is running and holding the clock. +* +* Note: `scp_ops` doesn't implement .attach() callback, hence +* `rproc->state` can never be RPROC_ATTACHED. Otherwise, it +* should also be checked here. +*/ +if (rproc->state ==RPROC_RUNNING ) +clk_unprepare (scp->clk); +return 0 ; +} + +static int __maybe_unused scp_resume (struct device *dev) +{ +struct mtk_scp *scp =dev_get_drvdata (dev); +struct rproc *rproc = scp->rproc; + +/* +* Only prepare if the SCP was running and holding the clock. +* +* Note: `scp_ops` doesn't implement .attach() callback, hence +* `rproc->state` can never be RPROC_ATTACHED. Otherwise, it +* should also be checked here. +*/ +if (rproc->state ==RPROC_RUNNING ) +return clk_prepare (scp->clk); +return 0 ; +} + +static const struct dev_pm_ops scp_pm_ops = { +SET_SYSTEM_SLEEP_PM_OPS (scp_suspend, scp_resume) +}; +static struct platform_driver mtk_scp_driver = { .probe = scp_probe, .remove = scp_remove, .driver = { .name ="mtk-scp" , .of_match_table = mtk_scp_of_match, + .pm = &scp_pm_ops, }, };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 159/481 powerpc: 83xx: km83xx: Fix keymile vendor prefix
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: J. Neuschäfer <[email protected]>
[ Upstream commit 691417ffe7821721e0a28bd25ad8c0dc0d4ae4ad ]
When kmeter.c was refactored into km83xx.c in 2011, the "keymile" vendor prefix was changed to upper-case "Keymile". The devicetree at arch/powerpc/boot/dts/kmeter1.dts never underwent the same change, suggesting that this was simply a mistake.
--- arch/powerpc/platforms/83xx/km83xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/powerpc/platforms/83xx/km83xx.c +2 -2
@@ -155,8 +155,8 @@ machine_device_initcall(mpc83xx_km, mpc83xx_declare_of_platform_devices);/* list of the supported boards */ static char *board[]__initdata = { -"Keymile,KMETER1" , -"Keymile,kmpbec8321" , +"keymile,KMETER1" , +"keymile,kmpbec8321" ,NULL };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 160/481 xprtrdma: Decrement re_receiving on the early exit paths
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Badger <[email protected]>
[ Upstream commit 7b6275c80a0c81c5f8943272292dfe67730ce849 ]
In the event that rpcrdma_post_recvs() fails to create a work request (due to memory allocation failure, say) or otherwise exits early, we should decrement ep->re_receiving before returning. Otherwise we will hang in rpcrdma_xprt_drain() as re_receiving will never reach zero and the completion will never be triggered.
On a system with high memory pressure, this can appear as the following hung task:
INFO: task kworker/u385:17:8393 blocked for more than 122 seconds.
Tainted: G S E 6.19.0 #3
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:kworker/u385:17 state:D stack:0 pid:8393 tgid:8393 ppid:2 task_flags:0x4248060 flags:0x00080000
Workqueue: xprtiod xprt_autoclose [sunrpc]
Call Trace:
<TASK>
__schedule+0x48b/0x18b0
? ib_post_send_mad+0x247/0xae0 [ib_core]
schedule+0x27/0xf0
schedule_timeout+0x104/0x110
__wait_for_common+0x98/0x180
? __pfx_schedule_timeout+0x10/0x10
wait_for_completion+0x24/0x40
rpcrdma_xprt_disconnect+0x444/0x460 [rpcrdma]
xprt_rdma_close+0x12/0x40 [rpcrdma]
xprt_autoclose+0x5f/0x120 [sunrpc]
process_one_work+0x191/0x3e0
worker_thread+0x2e3/0x420
? __pfx_worker_thread+0x10/0x10
kthread+0x10d/0x230
? __pfx_kthread+0x10/0x10
ret_from_fork+0x273/0x2b0
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30--- net/sunrpc/xprtrdma/verbs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
net/sunrpc/xprtrdma/verbs.c +4 -3
@@ -1362,7 +1362,7 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed, bool temp) needed +=RPCRDMA_MAX_RECV_BATCH ;if (atomic_inc_return (&ep->re_receiving) >1 ) - goto out; + goto out_dec;/* fast path: all needed reps can be found on the free list */ wr =NULL ;
@@ -1389,7 +1389,7 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed, bool temp) ++count; }if (!wr) - goto out; + goto out_dec; rc =ib_post_recv (ep->re_id->qp, wr, (const struct ib_recv_wr **)&bad_wr);
@@ -1404,9 +1404,10 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed, bool temp) --count; } } + +out_dec:if (atomic_dec_return (&ep->re_receiving) >0 )complete (&ep->re_done); - out:trace_xprtrdma_post_recvs (r_xprt, count); ep->re_receive_count += count;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 161/481 net: dsa: realtek: rtl8365mb: remove ifOutDiscards from rx_packets
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mieczyslaw Nalewaj <[email protected]>
[ Upstream commit f76a93241d71fbba8425e3967097b498c29264ed ]
rx_packets should report the number of frames successfully received:
unicast + multicast + broadcast. Subtracting ifOutDiscards (a TX counter) is incorrect and can undercount RX packets. RX drops are already reported via rx_dropped (e.g. etherStatsDropEvents), so there is no need to adjust rx_packets.
This patch removes the subtraction of ifOutDiscards from rx_packets in rtl8365mb_stats_update().
--- drivers/net/dsa/realtek/rtl8365mb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/dsa/realtek/rtl8365mb.c +1 -2
@@ -1451,8 +1451,7 @@ static void rtl8365mb_stats_update(struct realtek_priv *priv, int port) stats->rx_packets = cnt[RTL8365MB_MIB_ifInUcastPkts] + cnt[RTL8365MB_MIB_ifInMulticastPkts] + - cnt[RTL8365MB_MIB_ifInBroadcastPkts] - - cnt[RTL8365MB_MIB_ifOutDiscards]; + cnt[RTL8365MB_MIB_ifInBroadcastPkts]; stats->tx_packets = cnt[RTL8365MB_MIB_ifOutUcastPkts] + cnt[RTL8365MB_MIB_ifOutMulticastPkts] +
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 162/481 bonding: handle BOND_LINK_FAIL, BOND_LINK_BACK as valid link states
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hangbin Liu <[email protected]>
[ Upstream commit 3348be7978f450ede0c308a4e8416ac716cf1015 ]
Before the fixed commit, we check slave->new_link during commit state, which values are only BOND_LINK_{NOCHANGE, UP, DOWN}. After the commit, we start using slave->link_new_state, which state also could be BOND_LINK_{FAIL, BACK}.
For example, when we set updelay/downdelay, after a failover, the slave->link_new_state could be set to BOND_LINK_{FAIL, BACK} in bond_miimon_inspect(). And later in bond_miimon_commit(), it will treat it as invalid and print an error, which would cause confusion for users.
[ 106.440254] bond0: (slave veth2): link status down for interface, disabling it in 200 ms [ 106.440265] bond0: (slave veth2): invalid new link 1 on slave [ 106.648276] bond0: (slave veth2): link status definitely down, disabling slave [ 107.480271] bond0: (slave veth2): link status up, enabling it in 200 ms [ 107.480288] bond0: (slave veth2): invalid new link 3 on slave [ 107.688302] bond0: (slave veth2): link status definitely up, 10000 Mbps full duplex
Let's handle BOND_LINK_{FAIL, BACK} as valid link states.
--- drivers/net/bonding/bond_main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/net/bonding/bond_main.c +7 -1
@@ -2801,8 +2801,14 @@ static void bond_miimon_commit(struct bonding *bond)continue ; +case BOND_LINK_FAIL : +case BOND_LINK_BACK : +slave_dbg (bond->dev, slave->dev,"link_new_state %d on slave\n" , + slave->link_new_state); +continue ; +default : -slave_err (bond->dev, slave->dev,"invalid new link %d on slave\n" , +slave_err (bond->dev, slave->dev,"invalid link_new_state %d on slave\n" , slave->link_new_state);bond_propose_link_state (slave,BOND_LINK_NOCHANGE );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 163/481 net/mlx5: IFC updates for disabled host PF
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Jurgens <[email protected]>
[ Upstream commit cd1746cb6555a2238c4aae9f9d60b637a61bf177 ]
The port 2 host PF can be disabled, this bit reflects that setting.
Stable-dep-of: aed763abf0e9 ("net/mlx5: Fix deadlock between devlink lock and esw->wq")
--- include/linux/mlx5/mlx5_ifc.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
include/linux/mlx5/mlx5_ifc.h +3 -1
@@ -11496,7 +11496,9 @@ struct mlx5_ifc_mtrc_ctrl_bits {struct mlx5_ifc_host_params_context_bits {u8 host_number[0x8 ]; -u8 reserved_at_8[0x7 ]; +u8 reserved_at_8[0x5 ]; +u8 host_pf_not_exist[0x1 ]; +u8 reserved_at_14[0x1 ];u8 host_pf_disabled[0x1 ];u8 host_num_of_vfs[0x10 ];
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 164/481 net/mlx5: Query to see if host PF is disabled
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Jurgens <[email protected]>
[ Upstream commit 9e84de72aef9bcf0e751a0bff3ac91b0cf52366f ]
The host PF can be disabled, query firmware to check if the host PF of this function exists.
Stable-dep-of: aed763abf0e9 ("net/mlx5: Fix deadlock between devlink lock and esw->wq")
--- .../net/ethernet/mellanox/mlx5/core/eswitch.c | 23 +++++++++++++++++++ .../net/ethernet/mellanox/mlx5/core/eswitch.h | 1 + 2 files changed, 24 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +23 -0
@@ -969,6 +969,25 @@ const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev)return ERR_PTR (err); } +static int mlx5_esw_host_functions_enabled_query (struct mlx5_eswitch *esw) +{ +const u32 *query_host_out; + +if (!mlx5_core_is_ecpf_esw_manager (esw->dev)) +return 0 ; + + query_host_out =mlx5_esw_query_functions (esw->dev); +if (IS_ERR (query_host_out)) +return PTR_ERR (query_host_out); + + esw->esw_funcs.host_funcs_disabled = +MLX5_GET (query_esw_functions_out, query_host_out, + host_params_context.host_pf_not_exist); + +kvfree (query_host_out); +return 0 ; +} +static void mlx5_eswitch_event_handler_register (struct mlx5_eswitch *esw) {if (esw->mode ==MLX5_ESWITCH_OFFLOADS &&mlx5_eswitch_is_funcs_handler (esw->dev)) {
@@ -1596,6 +1615,10 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev) goto abort; } + err =mlx5_esw_host_functions_enabled_query (esw); +if (err) + goto abort; + err =mlx5_esw_vports_init (esw);if (err) goto abort;
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +1 -0
@@ -279,6 +279,7 @@ struct mlx5_host_work {struct mlx5_esw_functions {struct mlx5_nb nb; +bool host_funcs_disabled;u16 num_vfs; };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 165/481 net/mlx5: Fix deadlock between devlink lock and esw->wq
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cosmin Ratiu <[email protected]>
[ Upstream commit aed763abf0e905b4b8d747d1ba9e172961572f57 ]
esw->work_queue executes esw_functions_changed_event_handler -> esw_vfs_changed_event_handler and acquires the devlink lock.
.eswitch_mode_set (acquires devlink lock in devlink_nl_pre_doit) -> mlx5_devlink_eswitch_mode_set -> mlx5_eswitch_disable_locked -> mlx5_eswitch_event_handler_unregister -> flush_workqueue deadlocks when esw_vfs_changed_event_handler executes.
Fix that by no longer flushing the work to avoid the deadlock, and using a generation counter to keep track of work relevance. This avoids an old handler manipulating an esw that has undergone one or more mode changes:
- the counter is incremented in mlx5_eswitch_event_handler_unregister.
- the counter is read and passed to the ephemeral mlx5_host_work struct.
- the work handler takes the devlink lock and bails out if the current generation is different than the one it was scheduled to operate on.
- mlx5_eswitch_cleanup does the final draining before destroying the wq.
No longer flushing the workqueue has the side effect of maybe no longer cancelling pending vport_change_handler work items, but that's ok since those are disabled elsewhere:
- mlx5_eswitch_disable_locked disables the vport eq notifier.
- mlx5_esw_vport_disable disarms the HW EQ notification and marks vport->enabled under state_lock to false to prevent pending vport handler from doing anything.
- mlx5_eswitch_cleanup destroys the workqueue and makes sure all events are disabled/finished.
--- .../net/ethernet/mellanox/mlx5/core/eswitch.c | 7 ++++--- .../net/ethernet/mellanox/mlx5/core/eswitch.h | 2 ++ .../mellanox/mlx5/core/eswitch_offloads.c | 18 +++++++++++++----- 3 files changed, 19 insertions(+), 8 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +4 -3
@@ -999,10 +999,11 @@ static void mlx5_eswitch_event_handler_register(struct mlx5_eswitch *esw)static void mlx5_eswitch_event_handler_unregister (struct mlx5_eswitch *esw) { -if (esw->mode ==MLX5_ESWITCH_OFFLOADS &&mlx5_eswitch_is_funcs_handler (esw->dev)) +if (esw->mode ==MLX5_ESWITCH_OFFLOADS && +mlx5_eswitch_is_funcs_handler (esw->dev)) {mlx5_eq_notifier_unregister (esw->dev, &esw->esw_funcs.nb); - -flush_workqueue (esw->work_queue); +atomic_inc (&esw->esw_funcs.generation); + } }static void mlx5_eswitch_clear_vf_vports_info (struct mlx5_eswitch *esw)
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +2 -0
@@ -275,10 +275,12 @@ struct esw_mc_addr { /* SRIOV only */struct mlx5_host_work {struct work_struct work;struct mlx5_eswitch *esw; +int work_gen; };struct mlx5_esw_functions {struct mlx5_nb nb; +atomic_t generation;bool host_funcs_disabled;u16 num_vfs; };
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +13 -5
@@ -3207,22 +3207,28 @@ static void esw_offloads_steering_cleanup(struct mlx5_eswitch *esw) }static void -esw_vfs_changed_event_handler (struct mlx5_eswitch *esw,const u32 *out) +esw_vfs_changed_event_handler (struct mlx5_eswitch *esw,int work_gen, +const u32 *out) {struct devlink *devlink;bool host_pf_disabled;u16 new_num_vfs; + devlink =priv_to_devlink (esw->dev); +devl_lock (devlink); + +/* Stale work from one or more mode changes ago. Bail out. */ +if (work_gen !=atomic_read (&esw->esw_funcs.generation)) + goto unlock; + new_num_vfs =MLX5_GET (query_esw_functions_out, out, host_params_context.host_num_of_vfs); host_pf_disabled =MLX5_GET (query_esw_functions_out, out, host_params_context.host_pf_disabled);if (new_num_vfs == esw->esw_funcs.num_vfs || host_pf_disabled) -return ; + goto unlock; - devlink =priv_to_devlink (esw->dev); -devl_lock (devlink);/* Number of VFs can only change from "0 to x" or "x to 0". */ if (esw->esw_funcs.num_vfs >0 ) {mlx5_eswitch_unload_vf_vports (esw, esw->esw_funcs.num_vfs);
@@ -3237,6 +3243,7 @@ esw_vfs_changed_event_handler(struct mlx5_eswitch *esw, const u32 *out) } } esw->esw_funcs.num_vfs = new_num_vfs; +unlock:devl_unlock (devlink); }
@@ -3253,7 +3260,7 @@ static void esw_functions_changed_event_handler(struct work_struct *work)if (IS_ERR (out)) goto out; -esw_vfs_changed_event_handler (esw, out); +esw_vfs_changed_event_handler (esw, host_work->work_gen, out);kvfree (out); out:kfree (host_work);
@@ -3273,6 +3280,7 @@ int mlx5_esw_funcs_changed_handler(struct notifier_block *nb, unsigned long type esw = container_of(esw_funcs, struct mlx5_eswitch, esw_funcs); host_work->esw = esw; + host_work->work_gen =atomic_read (&esw_funcs->generation);INIT_WORK (&host_work->work, esw_functions_changed_event_handler);queue_work (esw->work_queue, &host_work->work);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 166/481 net/mlx5e: Fix DMA FIFO desync on error CQE SQ recovery
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gal Pressman <[email protected]>
[ Upstream commit 1633111d69053512d099658d4a05fc736fab36b0 ]
In case of a TX error CQE, a recovery flow is triggered, mlx5e_reset_txqsq_cc_pc() resets dma_fifo_cc to 0 but not dma_fifo_pc, desyncing the DMA FIFO producer and consumer.
After recovery, the producer pushes new DMA entries at the old dma_fifo_pc, while the consumer reads from position 0. This causes us to unmap stale DMA addresses from before the recovery.
The DMA FIFO is a purely software construct with no HW counterpart. At the point of reset, all WQEs have been flushed so dma_fifo_cc is already equal to dma_fifo_pc. There is no need to reset either counter, similar to how skb_fifo pc/cc are untouched.
Remove the 'dma_fifo_cc = 0' reset.
This fixes the following WARNING:
WARNING: CPU: 0 PID: 0 at drivers/iommu/dma-iommu.c:1240 iommu_dma_unmap_page+0x79/0x90
Modules linked in: mlx5_vdpa vringh vdpa bonding mlx5_ib mlx5_vfio_pci ipip mlx5_fwctl tunnel4 mlx5_core ib_ipoib geneve ip6_gre ip_gre gre nf_tables ip6_tunnel rdma_ucm ib_uverbs ib_umad vfio_pci vfio_pci_core act_mirred act_skbedit act_vlan vhost_net vhost tap ip6table_mangle ip6table_nat ip6table_filter ip6_tables iptable_mangle cls_matchall nfnetlink_cttimeout act_gact cls_flower sch_ingress vhost_iotlb iptable_raw tunnel6 vfio_iommu_type1 vfio openvswitch nsh rpcsec_gss_krb5 auth_rpcgss oid_registry xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink iptable_nat nf_nat xt_addrtype br_netfilter overlay zram zsmalloc rpcrdma ib_iser libiscsi scsi_transport_iscsi rdma_cm iw_cm ib_cm ib_core fuse [last unloaded: nf_tables]
CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.13.0-rc5_for_upstream_min_debug_2024_12_30_21_33 #1
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
RIP: 0010:iommu_dma_unmap_page+0x79/0x90
Code: 2b 4d 3b 21 72 26 4d 3b 61 08 73 20 49 89 d8 44 89 f9 5b 4c 89 f2 4c 89 e6 48 89 ef 5d 41 5c 41 5d 41 5e 41 5f e9 c7 ae 9e ff <0f> 0b 5b 5d 41 5c 41 5d 41 5e 41 5f c3 66 2e 0f 1f 84 00 00 00 00
Call Trace:
<IRQ>
? __warn+0x7d/0x110
? iommu_dma_unmap_page+0x79/0x90
? report_bug+0x16d/0x180
? handle_bug+0x4f/0x90
? exc_invalid_op+0x14/0x70
? asm_exc_invalid_op+0x16/0x20
? iommu_dma_unmap_page+0x79/0x90
? iommu_dma_unmap_page+0x2e/0x90
dma_unmap_page_attrs+0x10d/0x1b0
mlx5e_tx_wi_dma_unmap+0xbe/0x120 [mlx5_core]
mlx5e_poll_tx_cq+0x16d/0x690 [mlx5_core]
mlx5e_napi_poll+0x8b/0xac0 [mlx5_core]
__napi_poll+0x24/0x190
net_rx_action+0x32a/0x3b0
? mlx5_eq_comp_int+0x7e/0x270 [mlx5_core]
? notifier_call_chain+0x35/0xa0
handle_softirqs+0xc9/0x270
irq_exit_rcu+0x71/0xd0
common_interrupt+0x7f/0xa0
</IRQ>
<TASK>
asm_common_interrupt+0x22/0x40--- drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c | 1 - 1 file changed, 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c +0 -1
@@ -33,7 +33,6 @@ static void mlx5e_reset_txqsq_cc_pc(struct mlx5e_txqsq *sq)"SQ 0x%x: cc (0x%x) != pc (0x%x)\n" , sq->sqn, sq->cc, sq->pc); sq->cc =0 ; - sq->dma_fifo_cc =0 ; sq->pc =0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 167/481 net/sched: teql: fix NULL pointer dereference in iptunnel_xmit on TEQL slave xmit
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <[email protected]>
[ Upstream commit 0cc0c2e661af418bbf7074179ea5cfffc0a5c466 ]
teql_master_xmit() calls netdev_start_xmit(skb, slave) to transmit through slave devices, but does not update skb->dev to the slave device beforehand.
When a gretap tunnel is a TEQL slave, the transmit path reaches iptunnel_xmit() which saves dev = skb->dev (still pointing to teql0 master) and later calls iptunnel_xmit_stats(dev, pkt_len). This function does:
get_cpu_ptr(dev->tstats)
Since teql_master_setup() does not set dev->pcpu_stat_type to NETDEV_PCPU_STAT_TSTATS, the core network stack never allocates tstats for teql0, so dev->tstats is NULL. get_cpu_ptr(NULL) computes NULL + __per_cpu_offset[cpu], resulting in a page fault.
BUG: unable to handle page fault for address: ffff8880e6659018 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page PGD 68bc067 P4D 68bc067 PUD 0 Oops: Oops: 0002 [#1] SMP KASAN PTI RIP: 0010:iptunnel_xmit (./include/net/ip_tunnels.h:664 net/ipv4/ip_tunnel_core.c:89) Call Trace: <TASK> ip_tunnel_xmit (net/ipv4/ip_tunnel.c:847) __gre_xmit (net/ipv4/ip_gre.c:478) gre_tap_xmit (net/ipv4/ip_gre.c:779) teql_master_xmit (net/sched/sch_teql.c:319) dev_hard_start_xmit (net/core/dev.c:3887) sch_direct_xmit (net/sched/sch_generic.c:347) __dev_queue_xmit (net/core/dev.c:4802) neigh_direct_output (net/core/neighbour.c:1660) ip_finish_output2 (net/ipv4/ip_output.c:237) __ip_finish_output.part.0 (net/ipv4/ip_output.c:315) ip_mc_output (net/ipv4/ip_output.c:369) ip_send_skb (net/ipv4/ip_output.c:1508) udp_send_skb (net/ipv4/udp.c:1195) udp_sendmsg (net/ipv4/udp.c:1485) inet_sendmsg (net/ipv4/af_inet.c:859) __sys_sendto (net/socket.c:2206)
Fix this by setting skb->dev = slave before calling netdev_start_xmit(), so that tunnel xmit functions see the correct slave device with properly allocated tstats.
--- net/sched/sch_teql.c | 1 + 1 file changed, 1 insertion(+)
net/sched/sch_teql.c +1 -0
@@ -315,6 +315,7 @@ static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev)if (__netif_tx_trylock (slave_txq)) {unsigned int length =qdisc_pkt_len (skb); + skb->dev = slave;if (!netif_xmit_frozen_or_stopped (slave_txq) &&netdev_start_xmit (skb, slave, slave_txq, false) ==NETDEV_TX_OK ) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 168/481 ASoC: soc-core: drop delayed_work_pending() check before flush
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: matteo.cotifava <[email protected]>
[ Upstream commit 3c99c9f0ed60582c1c9852b685d78d5d3a50de63 ]
The delayed_work_pending() check before flush_delayed_work() in soc_free_pcm_runtime() is unnecessary and racy. flush_delayed_work() is safe to call unconditionally - it is a no-op when no work is pending. Remove the check.
The original check was added by commit 9c9b65203492 ("ASoC: core:
only flush inited work during free") but delayed_work_pending() followed by flush_delayed_work() has a time-of-check/time-of-use window where work can become pending between the two calls.
--- sound/soc/soc-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
sound/soc/soc-core.c +1 -2
@@ -381,8 +381,7 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)list_del (&rtd->list); -if (delayed_work_pending (&rtd->delayed_work)) -flush_delayed_work (&rtd->delayed_work); +flush_delayed_work (&rtd->delayed_work);snd_soc_pcm_component_free (rtd);/*
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 169/481 ASoC: core: Exit all links before removing their components
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cezary Rojewski <[email protected]>
[ Upstream commit c7eb967d70446971413061effca3226578cb4dab ]
Flows leading to link->init() and link->exit() are not symmetric. Currently the relevant part of card probe sequence goes as:
for_each_card_rtds(card, rtd) for_each_rtd_components(rtd, i, component) component->probe() for_each_card_rtds(card, rtd) for_each_rtd_dais(rtd, i, dai) dai->probe() for_each_card_rtds(card, rtd) rtd->init()
On the other side, equivalent remove sequence goes as:
for_each_card_rtds(card, rtd) for_each_rtd_dais(rtd, i, dai) dai->remove() for_each_card_rtds(card, rtd) for_each_rtd_components(rtd, i, component) component->remove() for_each_card_rtds(card, rtd) rtd->exit()
what can lead to errors as link->exit() may still operate on resources owned by its components despite the probability of them being freed during the component->remove().
This change modifies the remove sequence to:
for_each_card_rtds(card, rtd) rtd->exit() for_each_card_rtds(card, rtd) for_each_rtd_dais(rtd, i, dai) dai->remove() for_each_card_rtds(card, rtd) for_each_rtd_components(rtd, i, component) component->remove()
so code found in link->exit() is safe to touch any component stuff as component->remove() has not been called yet.
Stable-dep-of: 95bc5c225513 ("ASoC: soc-core: flush delayed work before removing DAIs and widgets")
--- sound/soc/soc-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/soc-core.c +3 -3
@@ -941,9 +941,6 @@ void snd_soc_remove_pcm_runtime(struct snd_soc_card *card,lockdep_assert_held (&client_mutex); -/* release machine specific resources */ -snd_soc_link_exit (rtd); -/* * Notify the machine driver for extra destruction */
@@ -1895,6 +1892,9 @@ static void soc_cleanup_card_resources(struct snd_soc_card *card)snd_soc_dapm_shutdown (card); +/* release machine specific resources */ +for_each_card_rtds (card, rtd) +snd_soc_link_exit (rtd);/* remove and free each DAI */ soc_remove_link_dais (card);soc_remove_link_components (card);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 170/481 ASoC: core: Do not call link_exit() on uninitialized rtd objects
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amadeusz Sławiński <[email protected]>
[ Upstream commit dd9f9cc1e6b9391140afa5cf27bb47c9e2a08d02 ]
On init we have sequence:
for_each_card_prelinks(card, i, dai_link) {
ret = snd_soc_add_pcm_runtime(card, dai_link);
ret = init_some_other_things(...);
if (ret)
goto probe_end:
for_each_card_rtds(card, rtd) {
ret = soc_init_pcm_runtime(card, rtd);probe_end:
while on exit:
for_each_card_rtds(card, rtd) snd_soc_link_exit(rtd);
If init_some_other_things() step fails due to error we end up with not fully setup rtds and try to call snd_soc_link_exit on them, which depending on contents on .link_exit handler, can end up dereferencing NULL pointer.
Stable-dep-of: 95bc5c225513 ("ASoC: soc-core: flush delayed work before removing DAIs and widgets")
--- include/sound/soc.h | 2 ++ sound/soc/soc-core.c | 20 +++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-)
include/sound/soc.h +2 -0
@@ -1110,6 +1110,8 @@ struct snd_soc_pcm_runtime { unsigned int pop_wait:1; unsigned int fe_compr:1; /* for Dynamic PCM */ +bool initialized; +int num_components;struct snd_soc_component *components[];/* CPU/Codec/Platform */ };
sound/soc/soc-core.c +15 -5
@@ -1256,7 +1256,7 @@ static int soc_init_pcm_runtime(struct snd_soc_card *card,snd_soc_runtime_get_dai_fmt (rtd); ret =snd_soc_runtime_set_dai_fmt (rtd, dai_link->dai_fmt);if (ret) -return ret; + goto err;/* add DPCM sysfs entries */ soc_dpcm_debugfs_add (rtd);
@@ -1281,17 +1281,26 @@ static int soc_init_pcm_runtime(struct snd_soc_card *card,/* create compress_device if possible */ ret =snd_soc_dai_compress_new (cpu_dai, rtd, num);if (ret != -ENOTSUPP ) -return ret; + goto err;/* create the pcm */ ret =soc_new_pcm (rtd, num);if (ret <0 ) {dev_err (card->dev,"ASoC: can't create pcm %s :%d\n" , dai_link->stream_name, ret); -return ret; + goto err; } -return snd_soc_pcm_dai_new (rtd); + ret =snd_soc_pcm_dai_new (rtd); +if (ret <0 ) + goto err; + + rtd->initialized = true; + +return 0 ; +err: +snd_soc_link_exit (rtd); +return ret; } static void soc_set_name_prefix(struct snd_soc_card *card,
@@ -1894,7 +1903,8 @@ static void soc_cleanup_card_resources(struct snd_soc_card *card)/* release machine specific resources */ for_each_card_rtds (card, rtd) -snd_soc_link_exit (rtd); +if (rtd->initialized) +snd_soc_link_exit (rtd);/* remove and free each DAI */ soc_remove_link_dais (card);soc_remove_link_components (card);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 171/481 ASoC: soc-core: flush delayed work before removing DAIs and widgets
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: matteo.cotifava <[email protected]>
[ Upstream commit 95bc5c225513fc3c4ce169563fb5e3929fbb938b ]
When a sound card is unbound while a PCM stream is open, a use-after-free can occur in snd_soc_dapm_stream_event(), called from the close_delayed_work workqueue handler.
During unbind, snd_soc_unbind_card() flushes delayed work and then calls soc_cleanup_card_resources(). Inside cleanup, snd_card_disconnect_sync() releases all PCM file descriptors, and the resulting PCM close path can call snd_soc_dapm_stream_stop() which schedules new delayed work with a pmdown_time timer delay. Since this happens after the flush in snd_soc_unbind_card(), the new work is not caught. soc_remove_link_components() then frees DAPM widgets before this work fires, leading to the use-after-free.
The existing flush in soc_free_pcm_runtime() also cannot help as it runs after soc_remove_link_components() has already freed the widgets.
Add a flush in soc_cleanup_card_resources() after snd_card_disconnect_sync() (after which no new PCM closes can schedule further delayed work) and before soc_remove_link_dais() and soc_remove_link_components() (which tear down the structures the delayed work accesses).
--- sound/soc/soc-core.c | 3 +++ 1 file changed, 3 insertions(+)
sound/soc/soc-core.c +3 -0
@@ -1905,6 +1905,9 @@ static void soc_cleanup_card_resources(struct snd_soc_card *card)for_each_card_rtds (card, rtd)if (rtd->initialized)snd_soc_link_exit (rtd); +/* flush delayed work before removing DAIs and DAPM widgets */ +snd_soc_flush_all_delayed_work (card); +/* remove and free each DAI */ soc_remove_link_dais (card);soc_remove_link_components (card);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 172/481 serial: caif: hold tty->link reference in ldisc_open and ser_release
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuangpeng Bai <[email protected]>
[ Upstream commit 288598d80a068a0e9281de35bcb4ce495f189e2a ]
A reproducer triggers a KASAN slab-use-after-free in pty_write_room() when caif_serial's TX path calls tty_write_room(). The faulting access is on tty->link->port.
Hold an extra kref on tty->link for the lifetime of the caif_serial line
discipline: get it in ldisc_open() and drop it in ser_release(), and also drop it on the ldisc_open() error path.
With this change applied, the reproducer no longer triggers the UAF in my testing.
--- drivers/net/caif/caif_serial.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/caif/caif_serial.c +3 -0
@@ -311,6 +311,7 @@ static void ser_release(struct work_struct *work)dev_close (ser->dev);unregister_netdevice (ser->dev);debugfs_deinit (ser); +tty_kref_put (tty->link);tty_kref_put (tty); }rtnl_unlock ();
@@ -345,6 +346,7 @@ static int ldisc_open(struct tty_struct *tty) ser =netdev_priv (dev); ser->tty =tty_kref_get (tty); +tty_kref_get (tty->link); ser->dev = dev;debugfs_init (ser, tty); tty->receive_room =N_TTY_BUF_SIZE ;
@@ -353,6 +355,7 @@ static int ldisc_open(struct tty_struct *tty)rtnl_lock (); result =register_netdevice (dev);if (result) { +tty_kref_put (tty->link);tty_kref_put (tty);rtnl_unlock ();free_netdev (dev);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 173/481 mctp: i2c: fix skb memory leak in receive path
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haiyue Wang <[email protected]>
[ Upstream commit e3f5e0f22cfc2371e7471c9fd5b4da78f9df7c69 ]
When 'midev->allow_rx' is false, the newly allocated skb isn't consumed by netif_rx(), it needs to free the skb directly.
--- drivers/net/mctp/mctp-i2c.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/mctp/mctp-i2c.c +1 -0
@@ -344,6 +344,7 @@ static int mctp_i2c_recv(struct mctp_i2c_dev *midev) }else { status =NET_RX_DROP ;spin_unlock_irqrestore (&midev->lock, flags); +kfree_skb (skb); }if (status ==NET_RX_SUCCESS ) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 174/481 can: hi311x: hi3110_open(): add check for hi3110_power_enable() return value
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wenyuan Li <[email protected]>
[ Upstream commit 47bba09b14fa21712398febf36cb14fd4fc3bded ]
In hi3110_open(), the return value of hi3110_power_enable() is not checked. If power enable fails, the device may not function correctly, while the driver still returns success.
Add a check for the return value and propagate the error accordingly.
--- drivers/net/can/spi/hi311x.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/can/spi/hi311x.c +4 -1
@@ -756,7 +756,9 @@ static int hi3110_open(struct net_device *net)return ret;mutex_lock (&priv->hi3110_lock); -hi3110_power_enable (priv->transceiver,1 ); + ret =hi3110_power_enable (priv->transceiver,1 ); +if (ret) + goto out_close_candev; priv->force_quit =0 ; priv->tx_skb =NULL ;
@@ -791,6 +793,7 @@ static int hi3110_open(struct net_device *net)hi3110_hw_sleep (spi); out_close:hi3110_power_enable (priv->transceiver,0 ); + out_close_candev:close_candev (net);mutex_unlock (&priv->hi3110_lock);return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 175/481 mctp: route: hold key->lock in mctp_flow_prepare_output()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <[email protected]>
[ Upstream commit 7d86aa41c073c4e7eb75fd2e674f1fd8f289728a ]
mctp_flow_prepare_output() checks key->dev and may call mctp_dev_set_key(), but it does not hold key->lock while doing so.
mctp_dev_set_key() and mctp_dev_release_key() are annotated with __must_hold(&key->lock), so key->dev access is intended to be serialized by key->lock. The mctp_sendmsg() transmit path reaches mctp_flow_prepare_output() via mctp_local_output() -> mctp_dst_output() without holding key->lock, so the check-and-set sequence is racy.
Example interleaving:
CPU0 CPU1
---- ----
mctp_flow_prepare_output(key, devA)
if (!key->dev) // sees NULL
mctp_flow_prepare_output(
key, devB)
if (!key->dev) // still NULL
mctp_dev_set_key(devB, key)
mctp_dev_hold(devB)
key->dev = devB
mctp_dev_set_key(devA, key)
mctp_dev_hold(devA)
key->dev = devA // overwrites devBNow both devA and devB references were acquired, but only the final key->dev value is tracked for release. One reference can be lost, causing a resource leak as mctp_dev_release_key() would only decrease the reference on one dev.
Fix by taking key->lock around the key->dev check and mctp_dev_set_key() call.
--- net/mctp/route.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
net/mctp/route.c +7 -4
@@ -267,6 +267,7 @@ static void mctp_flow_prepare_output(struct sk_buff *skb, struct mctp_dev *dev) {struct mctp_sk_key *key;struct mctp_flow *flow; +unsigned long flags; flow =skb_ext_find (skb,SKB_EXT_MCTP );if (!flow)
@@ -274,12 +275,14 @@ static void mctp_flow_prepare_output(struct sk_buff *skb, struct mctp_dev *dev) key = flow->key; -if (key->dev) { +spin_lock_irqsave (&key->lock, flags); + +if (!key->dev) +mctp_dev_set_key (dev, key); +else WARN_ON (key->dev != dev); -return ; - } - mctp_dev_set_key(dev, key); + spin_unlock_irqrestore(&key->lock, flags); }#else static void mctp_skb_set_flow (struct sk_buff *skb,struct mctp_sk_key *key) {}
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 176/481 netfilter: nft_set_pipapo: fix stack out-of-bounds read in pipapo_drop()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jenny Guanni Qu <[email protected]>
[ Upstream commit d6d8cd2db236a9dd13dbc2d05843b3445cc964b5 ]
pipapo_drop() passes rulemap[i + 1].n to pipapo_unmap() as the to_offset argument on every iteration, including the last one where i == m->field_count - 1. This reads one element past the end of the stack-allocated rulemap array (declared as rulemap[NFT_PIPAPO_MAX_FIELDS] with NFT_PIPAPO_MAX_FIELDS == 16).
Although pipapo_unmap() returns early when is_last is true without using the to_offset value, the argument is evaluated at the call site before the function body executes, making this a genuine out-of-bounds stack read confirmed by KASAN:
BUG: KASAN: stack-out-of-bounds in pipapo_drop+0x50c/0x57c [nf_tables] Read of size 4 at addr ffff8000810e71a4
This frame has 1 object:
[32, 160) 'rulemap'
The buggy address is at offset 164 -- exactly 4 bytes past the end of the rulemap array.
Pass 0 instead of rulemap[i + 1].n on the last iteration to avoid the out-of-bounds read.
--- net/netfilter/nft_set_pipapo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/netfilter/nft_set_pipapo.c +2 -1
@@ -1541,6 +1541,7 @@ static void pipapo_drop(struct nft_pipapo_match *m,int i;nft_pipapo_for_each_field (f, i, m) { +bool last = i == m->field_count -1 ;int g;for (g =0 ; g < f->groups; g++) {
@@ -1560,7 +1561,7 @@ static void pipapo_drop(struct nft_pipapo_match *m, }pipapo_unmap (f->mt, f->rules, rulemap[i].to, rulemap[i].n, - rulemap[i +1 ].n, i == m->field_count -1 ); + last ?0 : rulemap[i +1 ].n, last);if (pipapo_resize (f, f->rules, f->rules - rulemap[i].n)) {/* We can ignore this, a failure to shrink tables down * doesn't make tables invalid.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 177/481 netfilter: x_tables: guard option walkers against 1-byte tail reads
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Dull <[email protected]>
[ Upstream commit cfe770220ac2dbd3e104c6b45094037455da81d4 ]
When the last byte of options is a non-single-byte option kind, walkers that advance with i += op[i + 1] ? : 1 can read op[i + 1] past the end of the option area.
Add an explicit i == optlen - 1 check before dereferencing op[i + 1] in xt_tcpudp and xt_dccp option walkers.
--- net/netfilter/xt_dccp.c | 4 ++-- net/netfilter/xt_tcpudp.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-)
net/netfilter/xt_dccp.c +2 -2
@@ -62,10 +62,10 @@ dccp_find_option(u_int8_t option,return true; } -if (op[i] <2 ) +if (op[i] <2 || i == optlen -1 ) i++;else - i += op[i+1 ]?:1 ; + i += op[i +1 ] ? :1 ; }spin_unlock_bh (&dccp_buflock);
net/netfilter/xt_tcpudp.c +4 -2
@@ -56,8 +56,10 @@ tcp_find_option(u_int8_t option,for (i =0 ; i < optlen; ) {if (op[i] == option)return !invert; -if (op[i] <2 ) i++; -else i += op[i+1 ]?:1 ; +if (op[i] <2 || i == optlen -1 ) + i++; +else + i += op[i +1 ] ? :1 ; }return invert;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 178/481 netfilter: nfnetlink_queue: fix entry leak in bridge verdict error path
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hyunwoo Kim <[email protected]>
[ Upstream commit f1ba83755d81c6fc66ac7acd723d238f974091e9 ]
nfqnl_recv_verdict() calls find_dequeue_entry() to remove the queue entry from the queue data structures, taking ownership of the entry. For PF_BRIDGE packets, it then calls nfqa_parse_bridge() to parse VLAN attributes. If nfqa_parse_bridge() returns an error (e.g. NFQA_VLAN present but NFQA_VLAN_TCI missing), the function returns immediately without freeing the dequeued entry or its sk_buff.
This leaks the nf_queue_entry, its associated sk_buff, and all held references (net_device refcounts, struct net refcount). Repeated triggering exhausts kernel memory.
Fix this by dropping the entry via nfqnl_reinject() with NF_DROP verdict on the error path, consistent with other error handling in this file.
--- net/netfilter/nfnetlink_queue.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/netfilter/nfnetlink_queue.c +3 -1
@@ -1262,8 +1262,10 @@ static int nfqnl_recv_verdict(struct sk_buff *skb, const struct nfnl_info *info,if (entry->state.pf ==PF_BRIDGE ) { err =nfqa_parse_bridge (entry, nfqa); -if (err <0 ) +if (err <0 ) { +nfqnl_reinject (entry,NF_DROP );return err; + } }if (nfqa[NFQA_PAYLOAD ]) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 179/481 netfilter: nfnetlink_cthelper: fix OOB read in nfnl_cthelper_dump_table()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hyunwoo Kim <[email protected]>
[ Upstream commit 6dcee8496d53165b2d8a5909b3050b62ae71fe89 ]
nfnl_cthelper_dump_table() has a 'goto restart' that jumps to a label inside the for loop body. When the "last" helper saved in cb->args[1] is deleted between dump rounds, every entry fails the (cur != last) check, so cb->args[1] is never cleared. The for loop finishes with cb->args[0] == nf_ct_helper_hsize, and the 'goto restart' jumps back into the loop body bypassing the bounds check, causing an 8-byte out-of-bounds read on nf_ct_helper_hash[nf_ct_helper_hsize].
The 'goto restart' block was meant to re-traverse the current bucket when "last" is no longer found, but it was placed after the for loop instead of inside it. Move the block into the for loop body so that the restart only occurs while cb->args[0] is still within bounds.
BUG: KASAN: slab-out-of-bounds in nfnl_cthelper_dump_table+0x9f/0x1b0 Read of size 8 at addr ffff888104ca3000 by task poc_cthelper/131 Call Trace: nfnl_cthelper_dump_table+0x9f/0x1b0 netlink_dump+0x333/0x880 netlink_recvmsg+0x3e2/0x4b0 sock_recvmsg+0xde/0xf0 __sys_recvfrom+0x150/0x200 __x64_sys_recvfrom+0x76/0x90 do_syscall_64+0xc3/0x6e0 Allocated by task 1: __kvmalloc_node_noprof+0x21b/0x700 nf_ct_alloc_hashtable+0x65/0xd0 nf_conntrack_helper_init+0x21/0x60 nf_conntrack_init_start+0x18d/0x300 nf_conntrack_standalone_init+0x12/0xc0
--- net/netfilter/nfnetlink_cthelper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/netfilter/nfnetlink_cthelper.c +4 -4
@@ -603,10 +603,10 @@ nfnl_cthelper_dump_table(struct sk_buff *skb, struct netlink_callback *cb) goto out; } } - } -if (cb->args[1 ]) { - cb->args[1 ] =0 ; - goto restart; +if (cb->args[1 ]) { + cb->args[1 ] =0 ; + goto restart; + } } out:rcu_read_unlock ();
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 180/481 netfilter: xt_IDLETIMER: reject rev0 reuse of ALARM timer labels
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuan Tan <[email protected]>
[ Upstream commit 329f0b9b48ee6ab59d1ab72fef55fe8c6463a6cf ]
IDLETIMER revision 0 rules reuse existing timers by label and always call mod_timer() on timer->timer.
If the label was created first by revision 1 with XT_IDLETIMER_ALARM, the object uses alarm timer semantics and timer->timer is never initialized. Reusing that object from revision 0 causes mod_timer() on an uninitialized timer_list, triggering debugobjects warnings and possible panic when panic_on_warn=1.
Fix this by rejecting revision 0 rule insertion when an existing timer with the same label is of ALARM type.
--- net/netfilter/xt_IDLETIMER.c | 6 ++++++ 1 file changed, 6 insertions(+)
net/netfilter/xt_IDLETIMER.c +6 -0
@@ -320,6 +320,12 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par) info->timer =__idletimer_tg_find_by_label (info->label);if (info->timer) { +if (info->timer->timer_type &XT_IDLETIMER_ALARM ) { +pr_debug ("Adding/Replacing rule with same label and different timer type is not allowed\n" ); +mutex_unlock (&list_mutex); +return -EINVAL ; + } + info->timer->refcnt++;mod_timer (&info->timer->timer,msecs_to_jiffies (info->timeout *1000 ) + jiffies);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 181/481 regulator: pca9450: Make IRQ optional
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frieder Schrempf <[email protected]>
[ Upstream commit 83808c54064eef620ad8645dfdcaffe125551532 ]
The IRQ line might not be connected on some boards. Allow the driver to be probed without it.
Stable-dep-of: 5d0efaf47ee9 ("regulator: pca9450: Correct interrupt type")
--- drivers/regulator/pca9450-regulator.c | 41 +++++++++++++-------------- 1 file changed, 19 insertions(+), 22 deletions(-)
drivers/regulator/pca9450-regulator.c +19 -22
@@ -713,11 +713,6 @@ static int pca9450_i2c_probe(struct i2c_client *i2c,unsigned int reset_ctrl;int ret; -if (!i2c->irq) { -dev_err (&i2c->dev,"No IRQ configured?\n" ); -return -EINVAL ; - } - pca9450 =devm_kzalloc (&i2c->dev,sizeof (struct pca9450 ),GFP_KERNEL );if (!pca9450)return -ENOMEM ;
@@ -784,23 +779,25 @@ static int pca9450_i2c_probe(struct i2c_client *i2c, } } - ret =devm_request_threaded_irq (pca9450->dev, pca9450->irq,NULL , - pca9450_irq_handler, - (IRQF_TRIGGER_FALLING |IRQF_ONESHOT ), -"pca9450-irq" , pca9450); -if (ret !=0 ) { -dev_err (pca9450->dev,"Failed to request IRQ: %d\n" , - pca9450->irq); -return ret; - } -/* Unmask all interrupt except PWRON/WDOG/RSVD */ - ret =regmap_update_bits (pca9450->regmap,PCA9450_REG_INT1_MSK , -IRQ_VR_FLT1 |IRQ_VR_FLT2 |IRQ_LOWVSYS | -IRQ_THERM_105 |IRQ_THERM_125 , -IRQ_PWRON |IRQ_WDOGB |IRQ_RSVD ); -if (ret) { -dev_err (&i2c->dev,"Unmask irq error\n" ); -return ret; +if (pca9450->irq) { + ret =devm_request_threaded_irq (pca9450->dev, pca9450->irq,NULL , + pca9450_irq_handler, + (IRQF_TRIGGER_FALLING |IRQF_ONESHOT ), +"pca9450-irq" , pca9450); +if (ret !=0 ) { +dev_err (pca9450->dev,"Failed to request IRQ: %d\n" , + pca9450->irq); +return ret; + } +/* Unmask all interrupt except PWRON/WDOG/RSVD */ + ret =regmap_update_bits (pca9450->regmap,PCA9450_REG_INT1_MSK , +IRQ_VR_FLT1 |IRQ_VR_FLT2 |IRQ_LOWVSYS | +IRQ_THERM_105 |IRQ_THERM_125 , +IRQ_PWRON |IRQ_WDOGB |IRQ_RSVD ); +if (ret) { +dev_err (&i2c->dev,"Unmask irq error\n" ); +return ret; + } }/* Clear PRESET_EN bit in BUCK123_DVS to use DVS registers */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 182/481 regulator: pca9450: Correct interrupt type
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit 5d0efaf47ee90ac60efae790acee3a3ed99ebf80 ]
Kernel warning on i.MX8MP-EVK when doing module test:
irq: type mismatch, failed to map hwirq-3 for gpio@30200000!
Per PCA945[X] specification: The IRQ_B pin is pulled low when any unmasked interrupt bit status is changed and it is released high once application processor read INT1 register.
So the interrupt should be configured as IRQF_TRIGGER_LOW, not IRQF_TRIGGER_FALLING.
--- drivers/regulator/pca9450-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/regulator/pca9450-regulator.c +1 -1
@@ -782,7 +782,7 @@ static int pca9450_i2c_probe(struct i2c_client *i2c,if (pca9450->irq) { ret =devm_request_threaded_irq (pca9450->dev, pca9450->irq,NULL , pca9450_irq_handler, - (IRQF_TRIGGER_FALLING |IRQF_ONESHOT ), + (IRQF_TRIGGER_LOW |IRQF_ONESHOT ),"pca9450-irq" , pca9450);if (ret !=0 ) { dev_err(pca9450->dev, "Failed to request IRQ: %d\n",
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 183/481 sched: idle: Make skipping governor callbacks more consistent
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
[ Upstream commit d557640e4ce589a24dca5ca7ce3b9680f471325f ]
If the cpuidle governor .select() callback is skipped because there is only one idle state in the cpuidle driver, the .reflect() callback should be skipped as well, at least for consistency (if not for correctness), so do it.
--- drivers/cpuidle/cpuidle.c | 10 ---------- kernel/sched/idle.c | 11 ++++++++++- 2 files changed, 10 insertions(+), 11 deletions(-)
drivers/cpuidle/cpuidle.c +0 -10
@@ -324,16 +324,6 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,int cpuidle_select (struct cpuidle_driver *drv,struct cpuidle_device *dev,bool *stop_tick) { -/* -* If there is only a single idle state (or none), there is nothing -* meaningful for the governor to choose. Skip the governor and -* always use state 0 with the tick running. -*/ -if (drv->state_count <=1 ) { - *stop_tick = false; -return 0 ; - } -return cpuidle_curr_governor->select (drv, dev, stop_tick); }
kernel/sched/idle.c +10 -1
@@ -220,7 +220,7 @@ static void cpuidle_idle_call(void) next_state =cpuidle_find_deepest_state (drv, dev, max_latency_ns);call_cpuidle (drv, dev, next_state); - }else { + }else if (drv->state_count >1 ) {bool stop_tick = true;/*
@@ -238,6 +238,15 @@ static void cpuidle_idle_call(void)* Give the governor an opportunity to reflect on the outcome */ cpuidle_reflect (dev, entered_state); + }else { +tick_nohz_idle_retain_tick (); + +/* +* If there is only a single idle state (or none), there is +* nothing meaningful for the governor to choose. Skip the +* governor and always use state 0. +*/ +call_cpuidle (drv, dev,0 ); } exit_idle:
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 184/481 nvme-pci: Fix slab-out-of-bounds in nvme_dbbuf_set
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sungwoo Kim <[email protected]>
[ Upstream commit b4e78f1427c7d6859229ae9616df54e1fc05a516 ]
dev->online_queues is a count incremented in nvme_init_queue. Thus, valid indices are 0 through dev->online_queues − 1.
This patch fixes the loop condition to ensure the index stays within the valid range. Index 0 is excluded because it is the admin queue.
KASAN splat:
==================================================================
BUG: KASAN: slab-out-of-bounds in nvme_dbbuf_free drivers/nvme/host/pci.c:377 [inline] BUG: KASAN: slab-out-of-bounds in nvme_dbbuf_set+0x39c/0x400 drivers/nvme/host/pci.c:404 Read of size 2 at addr ffff88800592a574 by task kworker/u8:5/74 CPU: 0 UID: 0 PID: 74 Comm: kworker/u8:5 Not tainted 6.19.0-dirty #10 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 Workqueue: nvme-reset-wq nvme_reset_work Call Trace: <TASK> __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0xea/0x150 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 [inline] print_report+0xce/0x5d0 mm/kasan/report.c:482 kasan_report+0xdc/0x110 mm/kasan/report.c:595 __asan_report_load2_noabort+0x18/0x20 mm/kasan/report_generic.c:379 nvme_dbbuf_free drivers/nvme/host/pci.c:377 [inline] nvme_dbbuf_set+0x39c/0x400 drivers/nvme/host/pci.c:404 nvme_reset_work+0x36b/0x8c0 drivers/nvme/host/pci.c:3252 process_one_work+0x956/0x1aa0 kernel/workqueue.c:3257 process_scheduled_works kernel/workqueue.c:3340 [inline] worker_thread+0x65c/0xe60 kernel/workqueue.c:3421 kthread+0x41a/0x930 kernel/kthread.c:463 ret_from_fork+0x6f8/0x8c0 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:246 </TASK> Allocated by task 34 on cpu 1 at 4.241550s: kasan_save_stack+0x2c/0x60 mm/kasan/common.c:57 kasan_save_track+0x1c/0x70 mm/kasan/common.c:78 kasan_save_alloc_info+0x3c/0x50 mm/kasan/generic.c:570 poison_kmalloc_redzone mm/kasan/common.c:398 [inline] __kasan_kmalloc+0xb5/0xc0 mm/kasan/common.c:415 kasan_kmalloc include/linux/kasan.h:263 [inline] __do_kmalloc_node mm/slub.c:5657 [inline] __kmalloc_node_noprof+0x2bf/0x8d0 mm/slub.c:5663 kmalloc_array_node_noprof include/linux/slab.h:1075 [inline] nvme_pci_alloc_dev drivers/nvme/host/pci.c:3479 [inline] nvme_probe+0x2f1/0x1820 drivers/nvme/host/pci.c:3534 local_pci_probe+0xef/0x1c0 drivers/pci/pci-driver.c:324 pci_call_probe drivers/pci/pci-driver.c:392 [inline] __pci_device_probe drivers/pci/pci-driver.c:417 [inline] pci_device_probe+0x743/0x920 drivers/pci/pci-driver.c:451 call_driver_probe drivers/base/dd.c:583 [inline] really_probe+0x29b/0xb70 drivers/base/dd.c:661 __driver_probe_device+0x3b0/0x4a0 drivers/base/dd.c:803 driver_probe_device+0x56/0x1f0 drivers/base/dd.c:833 __driver_attach_async_helper+0x155/0x340 drivers/base/dd.c:1159 async_run_entry_fn+0xa6/0x4b0 kernel/async.c:129 process_one_work+0x956/0x1aa0 kernel/workqueue.c:3257 process_scheduled_works kernel/workqueue.c:3340 [inline] worker_thread+0x65c/0xe60 kernel/workqueue.c:3421 kthread+0x41a/0x930 kernel/kthread.c:463 ret_from_fork+0x6f8/0x8c0 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:246 The buggy address belongs to the object at ffff88800592a000 which belongs to the cache kmalloc-2k of size 2048
The buggy address is located 244 bytes to the right of
allocated 1152-byte region [ffff88800592a000, ffff88800592a480)
The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x5928 head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 anon flags: 0xfffffc0000040(head|node=0|zone=1|lastcpupid=0x1fffff) page_type: f5(slab) raw: 000fffffc0000040 ffff888001042000 0000000000000000 dead000000000001 raw: 0000000000000000 0000000000080008 00000000f5000000 0000000000000000
head: 000fffffc0000040 ffff888001042000 0000000000000000 dead000000000001
head: 0000000000000000 0000000000080008 00000000f5000000 0000000000000000
head: 000fffffc0000003 ffffea0000164a01 00000000ffffffff 00000000ffffffff
head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff88800592a400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff88800592a480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff88800592a500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
^
ffff88800592a580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff88800592a600: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================--- drivers/nvme/host/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nvme/host/pci.c +1 -1
@@ -329,7 +329,7 @@ static void nvme_dbbuf_set(struct nvme_dev *dev)/* Free memory and continue on */ nvme_dbbuf_dma_free (dev); -for (i =1 ; i <= dev->online_queues; i++) +for (i =1 ; i < dev->online_queues; i++)nvme_dbbuf_free (&dev->queues[i]); } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 185/481 nvme-pci: Fix race bug in nvme_poll_irqdisable()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sungwoo Kim <[email protected]>
[ Upstream commit fc71f409b22ca831a9f87a2712eaa09ef2bb4a5e ]
In the following scenario, pdev can be disabled between (1) and (3) by (2). This sets pdev->msix_enabled = 0. Then, pci_irq_vector() will return MSI-X IRQ(>15) for (1) whereas return INTx IRQ(<=15) for (2). This causes IRQ warning because it tries to enable INTx IRQ that has never been disabled before.
To fix this, save IRQ number into a local variable and ensure disable_irq() and enable_irq() operate on the same IRQ number. Even if pci_free_irq_vectors() frees the IRQ concurrently, disable_irq() and enable_irq() on a stale IRQ number is still valid and safe, and the depth accounting reamins balanced.
task 1:nvme_poll_irqdisable()
disable_irq(pci_irq_vector(pdev, nvmeq->cq_vector)) ...(1) enable_irq(pci_irq_vector(pdev, nvmeq->cq_vector)) ...(3)
task 2:nvme_reset_work()
nvme_dev_disable()
pdev->msix_enable = 0; ...(2)
crash log:
------------[ cut here ]------------ Unbalanced enable for IRQ 10 WARNING: kernel/irq/manage.c:753 at __enable_irq+0x102/0x190 kernel/irq/manage.c:753, CPU#1: kworker/1:0H/26 Modules linked in: CPU: 1 UID: 0 PID: 26 Comm: kworker/1:0H Not tainted 6.19.0-dirty #9 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 Workqueue: kblockd blk_mq_timeout_work RIP: 0010:__enable_irq+0x107/0x190 kernel/irq/manage.c:753 Code: ff df 48 89 fa 48 c1 ea 03 0f b6 14 02 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 04 84 d2 75 79 48 8d 3d 2e 7a 3f 05 41 8b 74 24 2c <67> 48 0f b9 3a e8 ef b9 21 00 5b 41 5c 5d e9 46 54 66 03 e8 e1 b9 RSP: 0018:ffffc900001bf550 EFLAGS: 00010046 RAX: 0000000000000007 RBX: 0000000000000000 RCX: ffffffffb20c0e90 RDX: 0000000000000000 RSI: 000000000000000a RDI: ffffffffb74b88f0 RBP: ffffc900001bf560 R08: ffff88800197cf00 R09: 0000000000000001 R10: 0000000000000003 R11: 0000000000000003 R12: ffff8880012a6000 R13: 1ffff92000037eae R14: 000000000000000a R15: 0000000000000293 FS: 0000000000000000(0000) GS:ffff8880b49f7000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000555da4a25fa8 CR3: 00000000208e8000 CR4: 00000000000006f0 Call Trace: <TASK> enable_irq+0x121/0x1e0 kernel/irq/manage.c:797 nvme_poll_irqdisable+0x162/0x1c0 drivers/nvme/host/pci.c:1494 nvme_timeout+0x965/0x14b0 drivers/nvme/host/pci.c:1744 blk_mq_rq_timed_out block/blk-mq.c:1653 [inline] blk_mq_handle_expired+0x227/0x2d0 block/blk-mq.c:1721 bt_iter+0x2fc/0x3a0 block/blk-mq-tag.c:292 __sbitmap_for_each_set include/linux/sbitmap.h:269 [inline] sbitmap_for_each_set include/linux/sbitmap.h:290 [inline] bt_for_each block/blk-mq-tag.c:324 [inline] blk_mq_queue_tag_busy_iter+0x969/0x1e80 block/blk-mq-tag.c:536 blk_mq_timeout_work+0x627/0x870 block/blk-mq.c:1763 process_one_work+0x956/0x1aa0 kernel/workqueue.c:3257 process_scheduled_works kernel/workqueue.c:3340 [inline] worker_thread+0x65c/0xe60 kernel/workqueue.c:3421 kthread+0x41a/0x930 kernel/kthread.c:463 ret_from_fork+0x6f8/0x8c0 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:246 </TASK> irq event stamp: 74478 hardirqs last enabled at (74477): [<ffffffffb5720a9c>] __raw_spin_unlock_irq include/linux/spinlock_api_smp.h:159 [inline] hardirqs last enabled at (74477): [<ffffffffb5720a9c>] _raw_spin_unlock_irq+0x2c/0x60 kernel/locking/spinlock.c:202 hardirqs last disabled at (74478): [<ffffffffb57207b5>] __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:108 [inline] hardirqs last disabled at (74478): [<ffffffffb57207b5>] _raw_spin_lock_irqsave+0x85/0xa0 kernel/locking/spinlock.c:162 softirqs last enabled at (74304): [<ffffffffb1e9466c>] __do_softirq kernel/softirq.c:656 [inline] softirqs last enabled at (74304): [<ffffffffb1e9466c>] invoke_softirq kernel/softirq.c:496 [inline] softirqs last enabled at (74304): [<ffffffffb1e9466c>] __irq_exit_rcu+0xdc/0x120 kernel/softirq.c:723 softirqs last disabled at (74287): [<ffffffffb1e9466c>] __do_softirq kernel/softirq.c:656 [inline] softirqs last disabled at (74287): [<ffffffffb1e9466c>] invoke_softirq kernel/softirq.c:496 [inline] softirqs last disabled at (74287): [<ffffffffb1e9466c>] __irq_exit_rcu+0xdc/0x120 kernel/softirq.c:723 ---[ end trace 0000000000000000 ]---
--- drivers/nvme/host/pci.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/nvme/host/pci.c +4 -2
@@ -1150,14 +1150,16 @@ static irqreturn_t nvme_irq_check(int irq, void *data)static void nvme_poll_irqdisable (struct nvme_queue *nvmeq) {struct pci_dev *pdev =to_pci_dev (nvmeq->dev->dev); +int irq;WARN_ON_ONCE (test_bit (NVMEQ_POLLED , &nvmeq->flags)); -disable_irq (pci_irq_vector (pdev, nvmeq->cq_vector)); + irq =pci_irq_vector (pdev, nvmeq->cq_vector); +disable_irq (irq);spin_lock (&nvmeq->cq_poll_lock);nvme_poll_cq (nvmeq,NULL );spin_unlock (&nvmeq->cq_poll_lock); -enable_irq (pci_irq_vector (pdev, nvmeq->cq_vector)); +enable_irq (irq); }static int nvme_poll (struct blk_mq_hw_ctx *hctx,struct io_comp_batch *iob)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 186/481 i40e: fix src IP mask checks and memcpy argument names in cloud filter
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alok Tiwari <[email protected]>
[ Upstream commit e809085f492842ce7a519c9ef72d40f4bca89c13 ]
Fix following issues in the IPv4 and IPv6 cloud filter handling logic in both the add and delete paths:
- The source-IP mask check incorrectly compares mask.src_ip[0] against tcf.dst_ip[0]. Update it to compare against tcf.src_ip[0]. This likely goes unnoticed because the check is in an "else if" path that only executes when dst_ip is not set, most cloud filter use cases focus on destination-IP matching, and the buggy condition can accidentally evaluate true in some cases.
- memcpy() for the IPv4 source address incorrectly uses ARRAY_SIZE(tcf.dst_ip) instead of ARRAY_SIZE(tcf.src_ip), although both arrays are the same size.
- The IPv4 memcpy operations used ARRAY_SIZE(tcf.dst_ip) and ARRAY_SIZE (tcf.src_ip), Update these to use sizeof(cfilter->ip.v4.dst_ip) and sizeof(cfilter->ip.v4.src_ip) to ensure correct and explicit copy size.
- In the IPv6 delete path, memcmp() uses sizeof(src_ip6) when comparing dst_ip6 fields. Replace this with sizeof(dst_ip6) to make the intent explicit, even though both fields are struct in6_addr.
--- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +7 -7
@@ -3755,10 +3755,10 @@ static int i40e_vc_del_cloud_filter(struct i40e_vf *vf, u8 *msg) cfilter.n_proto =ETH_P_IP ;if (mask.dst_ip[0 ] & tcf.dst_ip[0 ])memcpy (&cfilter.ip.v4.dst_ip, tcf.dst_ip, -ARRAY_SIZE (tcf.dst_ip)); -else if (mask.src_ip[0 ] & tcf.dst_ip[0 ]) +sizeof (cfilter.ip.v4.dst_ip)); +else if (mask.src_ip[0 ] & tcf.src_ip[0 ])memcpy (&cfilter.ip.v4.src_ip, tcf.src_ip, -ARRAY_SIZE (tcf.dst_ip)); +sizeof (cfilter.ip.v4.src_ip));break ;case VIRTCHNL_TCP_V6_FLOW : cfilter.n_proto =ETH_P_IPV6 ;
@@ -3813,7 +3813,7 @@ static int i40e_vc_del_cloud_filter(struct i40e_vf *vf, u8 *msg)/* for ipv6, mask is set for all sixteen bytes (4 words) */ if (cfilter.n_proto ==ETH_P_IPV6 && mask.dst_ip[3 ])if (memcmp (&cfilter.ip.v6.dst_ip6, &cf->ip.v6.dst_ip6, -sizeof (cfilter.ip.v6.src_ip6))) +sizeof (cfilter.ip.v6.dst_ip6)))continue ;if (mask.vlan_id)if (cfilter.vlan_id != cf->vlan_id)
@@ -3901,10 +3901,10 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) cfilter->n_proto =ETH_P_IP ;if (mask.dst_ip[0 ] & tcf.dst_ip[0 ])memcpy (&cfilter->ip.v4.dst_ip, tcf.dst_ip, -ARRAY_SIZE (tcf.dst_ip)); -else if (mask.src_ip[0 ] & tcf.dst_ip[0 ]) +sizeof (cfilter->ip.v4.dst_ip)); +else if (mask.src_ip[0 ] & tcf.src_ip[0 ])memcpy (&cfilter->ip.v4.src_ip, tcf.src_ip, -ARRAY_SIZE (tcf.dst_ip)); +sizeof (cfilter->ip.v4.src_ip));break ;case VIRTCHNL_TCP_V6_FLOW : cfilter->n_proto =ETH_P_IPV6 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 187/481 e1000/e1000e: Fix leak in DMA error cleanup
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Vollrath <[email protected]>
[ Upstream commit e94eaef11142b01f77bf8ba4d0b59720b7858109 ]
If an error is encountered while mapping TX buffers, the driver should unmap any buffers already mapped for that skb.
Because count is incremented after a successful mapping, it will always match the correct number of unmappings needed when dma_error is reached. Decrementing count before the while loop in dma_error causes an off-by-one error. If any mapping was successful before an unsuccessful mapping, exactly one DMA mapping would leak.
In these commits, a faulty while condition caused an infinite loop in dma_error:
Commit 03b1320dfcee ("e1000e: remove use of skb_dma_map from e1000e driver")
Commit 602c0554d7b0 ("e1000: remove use of skb_dma_map from e1000 driver")
Commit c1fa347f20f1 ("e1000/e1000e/igb/igbvf/ixgb/ixgbe: Fix tests of unsigned in *_tx_map()") fixed the infinite loop, but introduced the off-by-one error.
This issue may still exist in the igbvf driver, but I did not address it in this patch.
--- drivers/net/ethernet/intel/e1000/e1000_main.c | 2 -- drivers/net/ethernet/intel/e1000e/netdev.c | 2 -- 2 files changed, 4 deletions(-)
drivers/net/ethernet/intel/e1000/e1000_main.c +0 -2
@@ -2951,8 +2951,6 @@ static int e1000_tx_map(struct e1000_adapter *adapter, dma_error:dev_err (&pdev->dev,"TX DMA map failed\n" ); buffer_info->dma =0 ; -if (count) - count--;while (count--) {if (i ==0 )
drivers/net/ethernet/intel/e1000e/netdev.c +0 -2
@@ -5632,8 +5632,6 @@ static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb, dma_error:dev_err (&pdev->dev,"Tx DMA map failed\n" ); buffer_info->dma =0 ; -if (count) - count--;while (count--) {if (i ==0 )
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 188/481 ACPI: OSL: fix __iomem type on return from acpi_os_map_generic_address()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Dooks <[email protected]>
[ Upstream commit 393815f57651101f1590632092986d1d5a3a41bd ]
The pointer returned from acpi_os_map_generic_address() is tagged with __iomem, so make the rv it is returned to also of void __iomem * type.
Fixes the following sparse warning:
drivers/acpi/osl.c:1686:20: warning: incorrect type in assignment (different address spaces)drivers/acpi/osl.c:1686:20: expected void *rvdrivers/acpi/osl.c:1686:20: got void [noderef] __iomem *
--- drivers/acpi/osl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/osl.c +1 -1
@@ -1656,7 +1656,7 @@ acpi_status __init acpi_os_initialize(void)* Use acpi_os_map_generic_address to pre-map the reset * register if it's in system memory. */ -void *rv; +void __iomem *rv; rv =acpi_os_map_generic_address (&acpi_gbl_FADT.reset_register); pr_debug("%s: Reset register mapping %s\n", __func__,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 189/481 ASoC: amd: acp3x-rt5682-max9836: Add missing error check for clock acquisition
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Ni <[email protected]>
[ Upstream commit 53f3a900e9a383d47af7253076e19f510c5708d0 ]
The acp3x_5682_init() function did not check the return value of clk_get(), which could lead to dereferencing error pointers in rt5682_clk_enable().
Fix this by:
1. Changing clk_get() to the device-managed devm_clk_get().
2. Adding proper IS_ERR() checks for both clock acquisitions.
--- sound/soc/amd/acp3x-rt5682-max9836.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
sound/soc/amd/acp3x-rt5682-max9836.c +7 -2
@@ -83,8 +83,13 @@ static int acp3x_5682_init(struct snd_soc_pcm_runtime *rtd)return ret; } - rt5682_dai_wclk =clk_get (component->dev,"rt5682-dai-wclk" ); - rt5682_dai_bclk =clk_get (component->dev,"rt5682-dai-bclk" ); + rt5682_dai_wclk =devm_clk_get (component->dev,"rt5682-dai-wclk" ); +if (IS_ERR (rt5682_dai_wclk)) +return PTR_ERR (rt5682_dai_wclk); + + rt5682_dai_bclk =devm_clk_get (component->dev,"rt5682-dai-bclk" ); +if (IS_ERR (rt5682_dai_bclk)) +return PTR_ERR (rt5682_dai_bclk); ret = snd_soc_card_jack_new(card, "Headset Jack", SND_JACK_HEADSET | SND_JACK_LINEOUT |
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 190/481 ASoC: detect empty DMI strings
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Casey Connolly <[email protected]>
[ Upstream commit a9683730e8b1d632674f81844ed03ddfbe4821c0 ]
Some bootloaders like recent versions of U-Boot may install some DMI properties with empty values rather than not populate them. This manages to make its way through the validator and cleanup resulting in a rogue hyphen being appended to the card longname.
--- sound/soc/soc-core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
sound/soc/soc-core.c +4 -1
@@ -1628,12 +1628,15 @@ static void cleanup_dmi_name(char *name)/* * Check if a DMI field is valid, i.e. not containing any string -* in the black list. +* in the black list and not the empty string. */ static int is_dmi_valid (const char *field) {int i =0 ; +if (!field[0 ]) +return 0 ; +while (dmi_blacklist[i]) {if (strstr (field, dmi_blacklist[i]))return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 191/481 net: bonding: Fix nd_tbl NULL dereference when IPv6 is disabled
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo B. Marlière <[email protected]>
[ Upstream commit 30021e969d48e5819d5ae56936c2f34c0f7ce997 ]
When booting with the 'ipv6.disable=1' parameter, the nd_tbl is never initialized because inet6_init() exits before ndisc_init() is called which initializes it. If bonding ARP/NS validation is enabled, an IPv6 NS/NA packet received on a slave can reach bond_validate_na(), which calls bond_has_this_ip6(). That path calls ipv6_chk_addr() and can crash in __ipv6_chk_addr_and_flags().
BUG: kernel NULL pointer dereference, address: 00000000000005d8 Oops: Oops: 0000 [#1] SMP NOPTI RIP: 0010:__ipv6_chk_addr_and_flags+0x69/0x170 Call Trace: <IRQ> ipv6_chk_addr+0x1f/0x30 bond_validate_na+0x12e/0x1d0 [bonding] ? __pfx_bond_handle_frame+0x10/0x10 [bonding] bond_rcv_validate+0x1a0/0x450 [bonding] bond_handle_frame+0x5e/0x290 [bonding] ? srso_alias_return_thunk+0x5/0xfbef5 __netif_receive_skb_core.constprop.0+0x3e8/0xe50 ? srso_alias_return_thunk+0x5/0xfbef5 ? update_cfs_rq_load_avg+0x1a/0x240 ? srso_alias_return_thunk+0x5/0xfbef5 ? __enqueue_entity+0x5e/0x240 __netif_receive_skb_one_core+0x39/0xa0 process_backlog+0x9c/0x150 __napi_poll+0x30/0x200 ? srso_alias_return_thunk+0x5/0xfbef5 net_rx_action+0x338/0x3b0 handle_softirqs+0xc9/0x2a0 do_softirq+0x42/0x60 </IRQ> <TASK> __local_bh_enable_ip+0x62/0x70 __dev_queue_xmit+0x2d3/0x1000 ? srso_alias_return_thunk+0x5/0xfbef5 ? srso_alias_return_thunk+0x5/0xfbef5 ? packet_parse_headers+0x10a/0x1a0 packet_sendmsg+0x10da/0x1700 ? kick_pool+0x5f/0x140 ? srso_alias_return_thunk+0x5/0xfbef5 ? __queue_work+0x12d/0x4f0 __sys_sendto+0x1f3/0x220 __x64_sys_sendto+0x24/0x30 do_syscall_64+0x101/0xf80 ? exc_page_fault+0x6e/0x170 ? srso_alias_return_thunk+0x5/0xfbef5 entry_SYSCALL_64_after_hwframe+0x77/0x7f </TASK>
Fix this by checking ipv6_mod_enabled() before dispatching IPv6 packets to bond_na_rcv(). If IPv6 is disabled, return early from bond_rcv_validate() and avoid the path to ipv6_chk_addr().
--- drivers/net/bonding/bond_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/bonding/bond_main.c +1 -1
@@ -3387,7 +3387,7 @@ int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond, }else if (is_arp) {return bond_arp_rcv (skb, bond, slave);#if IS_ENABLED (CONFIG_IPV6 ) - } else if (is_ipv6) { + } else if (is_ipv6 && likely(ipv6_mod_enabled())) {return bond_na_rcv (skb, bond, slave);#endif }else {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 192/481 octeontx2-af: devlink: fix NIX RAS reporter recovery condition
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alok Tiwari <[email protected]>
[ Upstream commit dc26ca99b835e21e76a58b1463b84adb0ca34f58 ]
The NIX RAS health reporter recovery routine checks nix_af_rvu_int to decide whether to re-enable NIX_AF_RAS interrupts. This is the RVU interrupt status field and is unrelated to RAS events, so the recovery flow may incorrectly skip re-enabling NIX_AF_RAS interrupts.
Check nix_af_rvu_ras instead before writing NIX_AF_RAS_ENA_W1S.
--- drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c +1 -1
@@ -579,7 +579,7 @@ static int rvu_hw_nix_ras_recover(struct devlink_health_reporter *reporter,if (blkaddr <0 )return blkaddr; -if (nix_event_ctx->nix_af_rvu_int) +if (nix_event_ctx->nix_af_rvu_ras)rvu_write64 (rvu, blkaddr,NIX_AF_RAS_ENA_W1S , ~0ULL );return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 193/481 octeontx2-af: devlink health: use retained error fmsg API
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Przemek Kitszel <[email protected]>
[ Upstream commit d8cf03fca3411de8a493dae5e9fcf815a4f0977e ]
Drop unneeded error checking.
devlink_fmsg_*() family of functions is now retaining errors, so there is no need to check for them after each call.
Stable-dep-of: 87f7dff3ec75 ("octeontx2-af: devlink: fix NIX RAS reporter to use RAS interrupt status")
--- .../marvell/octeontx2/af/rvu_devlink.c | 464 +++++------------- 1 file changed, 133 insertions(+), 331 deletions(-)
drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c +133 -331
@@ -14,26 +14,16 @@#define DRV_NAME "octeontx2-af" -static int rvu_report_pair_start (struct devlink_fmsg *fmsg,const char *name) +static void rvu_report_pair_start (struct devlink_fmsg *fmsg,const char *name) { -int err; - - err =devlink_fmsg_pair_nest_start (fmsg, name); -if (err) -return err; - -return devlink_fmsg_obj_nest_start (fmsg); +devlink_fmsg_pair_nest_start (fmsg, name); +devlink_fmsg_obj_nest_start (fmsg); } -static int rvu_report_pair_end (struct devlink_fmsg *fmsg) +static void rvu_report_pair_end (struct devlink_fmsg *fmsg) { -int err; - - err =devlink_fmsg_obj_nest_end (fmsg); -if (err) -return err; - -return devlink_fmsg_pair_nest_end (fmsg); +devlink_fmsg_obj_nest_end (fmsg); +devlink_fmsg_pair_nest_end (fmsg); } static bool rvu_common_request_irq(struct rvu *rvu, int offset,
@@ -284,175 +274,81 @@ static int rvu_nix_report_show(struct devlink_fmsg *fmsg, void *ctx, {struct rvu_nix_event_ctx *nix_event_context;u64 intr_val; -int err; nix_event_context = ctx;switch (health_reporter) {case NIX_AF_RVU_INTR : intr_val = nix_event_context->nix_af_rvu_int; - err =rvu_report_pair_start (fmsg,"NIX_AF_RVU" ); -if (err) -return err; - err =devlink_fmsg_u64_pair_put (fmsg,"\tNIX RVU Interrupt Reg " , - nix_event_context->nix_af_rvu_int); -if (err) -return err; -if (intr_val &BIT_ULL (0 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tUnmap Slot Error" ); -if (err) -return err; - } - err =rvu_report_pair_end (fmsg); -if (err) -return err; +rvu_report_pair_start (fmsg,"NIX_AF_RVU" ); +devlink_fmsg_u64_pair_put (fmsg,"\tNIX RVU Interrupt Reg " , + nix_event_context->nix_af_rvu_int); +if (intr_val &BIT_ULL (0 )) +devlink_fmsg_string_put (fmsg,"\n\tUnmap Slot Error" ); +rvu_report_pair_end (fmsg);break ;case NIX_AF_RVU_GEN : intr_val = nix_event_context->nix_af_rvu_gen; - err =rvu_report_pair_start (fmsg,"NIX_AF_GENERAL" ); -if (err) -return err; - err =devlink_fmsg_u64_pair_put (fmsg,"\tNIX General Interrupt Reg " , - nix_event_context->nix_af_rvu_gen); -if (err) -return err; -if (intr_val &BIT_ULL (0 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tRx multicast pkt drop" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (1 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tRx mirror pkt drop" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (4 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tSMQ flush done" ); -if (err) -return err; - } - err =rvu_report_pair_end (fmsg); -if (err) -return err; +rvu_report_pair_start (fmsg,"NIX_AF_GENERAL" ); +devlink_fmsg_u64_pair_put (fmsg,"\tNIX General Interrupt Reg " , + nix_event_context->nix_af_rvu_gen); +if (intr_val &BIT_ULL (0 )) +devlink_fmsg_string_put (fmsg,"\n\tRx multicast pkt drop" ); +if (intr_val &BIT_ULL (1 )) +devlink_fmsg_string_put (fmsg,"\n\tRx mirror pkt drop" ); +if (intr_val &BIT_ULL (4 )) +devlink_fmsg_string_put (fmsg,"\n\tSMQ flush done" ); +rvu_report_pair_end (fmsg);break ;case NIX_AF_RVU_ERR : intr_val = nix_event_context->nix_af_rvu_err; - err =rvu_report_pair_start (fmsg,"NIX_AF_ERR" ); -if (err) -return err; - err =devlink_fmsg_u64_pair_put (fmsg,"\tNIX Error Interrupt Reg " , - nix_event_context->nix_af_rvu_err); -if (err) -return err; -if (intr_val &BIT_ULL (14 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tFault on NIX_AQ_INST_S read" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (13 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tFault on NIX_AQ_RES_S write" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (12 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tAQ Doorbell Error" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (6 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tRx on unmapped PF_FUNC" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (5 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tRx multicast replication error" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (4 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tFault on NIX_RX_MCE_S read" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (3 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tFault on multicast WQE read" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (2 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tFault on mirror WQE read" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (1 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tFault on mirror pkt write" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (0 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tFault on multicast pkt write" ); -if (err) -return err; - } - err =rvu_report_pair_end (fmsg); -if (err) -return err; +rvu_report_pair_start (fmsg,"NIX_AF_ERR" ); +devlink_fmsg_u64_pair_put (fmsg,"\tNIX Error Interrupt Reg " , + nix_event_context->nix_af_rvu_err); +if (intr_val &BIT_ULL (14 )) +devlink_fmsg_string_put (fmsg,"\n\tFault on NIX_AQ_INST_S read" ); +if (intr_val &BIT_ULL (13 )) +devlink_fmsg_string_put (fmsg,"\n\tFault on NIX_AQ_RES_S write" ); +if (intr_val &BIT_ULL (12 )) +devlink_fmsg_string_put (fmsg,"\n\tAQ Doorbell Error" ); +if (intr_val &BIT_ULL (6 )) +devlink_fmsg_string_put (fmsg,"\n\tRx on unmapped PF_FUNC" ); +if (intr_val &BIT_ULL (5 )) +devlink_fmsg_string_put (fmsg,"\n\tRx multicast replication error" ); +if (intr_val &BIT_ULL (4 )) +devlink_fmsg_string_put (fmsg,"\n\tFault on NIX_RX_MCE_S read" ); +if (intr_val &BIT_ULL (3 )) +devlink_fmsg_string_put (fmsg,"\n\tFault on multicast WQE read" ); +if (intr_val &BIT_ULL (2 )) +devlink_fmsg_string_put (fmsg,"\n\tFault on mirror WQE read" ); +if (intr_val &BIT_ULL (1 )) +devlink_fmsg_string_put (fmsg,"\n\tFault on mirror pkt write" ); +if (intr_val &BIT_ULL (0 )) +devlink_fmsg_string_put (fmsg,"\n\tFault on multicast pkt write" ); +rvu_report_pair_end (fmsg);break ;case NIX_AF_RVU_RAS : intr_val = nix_event_context->nix_af_rvu_err; - err =rvu_report_pair_start (fmsg,"NIX_AF_RAS" ); -if (err) -return err; - err =devlink_fmsg_u64_pair_put (fmsg,"\tNIX RAS Interrupt Reg " , - nix_event_context->nix_af_rvu_err); -if (err) -return err; - err =devlink_fmsg_string_put (fmsg,"\n\tPoison Data on:" ); -if (err) -return err; -if (intr_val &BIT_ULL (34 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tNIX_AQ_INST_S" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (33 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tNIX_AQ_RES_S" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (32 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tHW ctx" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (4 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tPacket from mirror buffer" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (3 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tPacket from multicast buffer" ); - -if (err) -return err; - } -if (intr_val &BIT_ULL (2 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tWQE read from mirror buffer" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (1 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tWQE read from multicast buffer" ); -if (err) -return err; - } -if (intr_val &BIT_ULL (0 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tNIX_RX_MCE_S read" ); -if (err) -return err; - } - err =rvu_report_pair_end (fmsg); -if (err) -return err; +rvu_report_pair_start (fmsg,"NIX_AF_RAS" ); +devlink_fmsg_u64_pair_put (fmsg,"\tNIX RAS Interrupt Reg " , + nix_event_context->nix_af_rvu_err); +devlink_fmsg_string_put (fmsg,"\n\tPoison Data on:" ); +if (intr_val &BIT_ULL (34 )) +devlink_fmsg_string_put (fmsg,"\n\tNIX_AQ_INST_S" ); +if (intr_val &BIT_ULL (33 )) +devlink_fmsg_string_put (fmsg,"\n\tNIX_AQ_RES_S" ); +if (intr_val &BIT_ULL (32 )) +devlink_fmsg_string_put (fmsg,"\n\tHW ctx" ); +if (intr_val &BIT_ULL (4 )) +devlink_fmsg_string_put (fmsg,"\n\tPacket from mirror buffer" ); +if (intr_val &BIT_ULL (3 )) +devlink_fmsg_string_put (fmsg,"\n\tPacket from multicast buffer" ); +if (intr_val &BIT_ULL (2 )) +devlink_fmsg_string_put (fmsg,"\n\tWQE read from mirror buffer" ); +if (intr_val &BIT_ULL (1 )) +devlink_fmsg_string_put (fmsg,"\n\tWQE read from multicast buffer" ); +if (intr_val &BIT_ULL (0 )) +devlink_fmsg_string_put (fmsg,"\n\tNIX_RX_MCE_S read" ); +rvu_report_pair_end (fmsg);break ;default :return -EINVAL ;
@@ -919,181 +815,87 @@ static int rvu_npa_report_show(struct devlink_fmsg *fmsg, void *ctx,struct rvu_npa_event_ctx *npa_event_context;unsigned int alloc_dis, free_dis;u64 intr_val; -int err; npa_event_context = ctx;switch (health_reporter) {case NPA_AF_RVU_GEN : intr_val = npa_event_context->npa_af_rvu_gen; - err =rvu_report_pair_start (fmsg,"NPA_AF_GENERAL" ); -if (err) -return err; - err =devlink_fmsg_u64_pair_put (fmsg,"\tNPA General Interrupt Reg " , - npa_event_context->npa_af_rvu_gen); -if (err) -return err; -if (intr_val &BIT_ULL (32 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tUnmap PF Error" ); -if (err) -return err; - } +rvu_report_pair_start (fmsg,"NPA_AF_GENERAL" ); +devlink_fmsg_u64_pair_put (fmsg,"\tNPA General Interrupt Reg " , + npa_event_context->npa_af_rvu_gen); +if (intr_val &BIT_ULL (32 )) +devlink_fmsg_string_put (fmsg,"\n\tUnmap PF Error" ); free_dis =FIELD_GET (GENMASK (15 ,0 ), intr_val); -if (free_dis &BIT (NPA_INPQ_NIX0_RX )) { - err =devlink_fmsg_string_put (fmsg,"\n\tNIX0: free disabled RX" ); -if (err) -return err; - } -if (free_dis &BIT (NPA_INPQ_NIX0_TX )) { - err =devlink_fmsg_string_put (fmsg,"\n\tNIX0:free disabled TX" ); -if (err) -return err; - } -if (free_dis &BIT (NPA_INPQ_NIX1_RX )) { - err =devlink_fmsg_string_put (fmsg,"\n\tNIX1: free disabled RX" ); -if (err) -return err; - } -if (free_dis &BIT (NPA_INPQ_NIX1_TX )) { - err =devlink_fmsg_string_put (fmsg,"\n\tNIX1:free disabled TX" ); -if (err) -return err; - } -if (free_dis &BIT (NPA_INPQ_SSO )) { - err =devlink_fmsg_string_put (fmsg,"\n\tFree Disabled for SSO" ); -if (err) -return err; - } -if (free_dis &BIT (NPA_INPQ_TIM )) { - err =devlink_fmsg_string_put (fmsg,"\n\tFree Disabled for TIM" ); -if (err) -return err; - } -if (free_dis &BIT (NPA_INPQ_DPI )) { - err =devlink_fmsg_string_put (fmsg,"\n\tFree Disabled for DPI" ); -if (err) -return err; - } -if (free_dis &BIT (NPA_INPQ_AURA_OP )) { - err =devlink_fmsg_string_put (fmsg,"\n\tFree Disabled for AURA" ); -if (err) -return err; - } +if (free_dis &BIT (NPA_INPQ_NIX0_RX )) +devlink_fmsg_string_put (fmsg,"\n\tNIX0: free disabled RX" ); +if (free_dis &BIT (NPA_INPQ_NIX0_TX )) +devlink_fmsg_string_put (fmsg,"\n\tNIX0:free disabled TX" ); +if (free_dis &BIT (NPA_INPQ_NIX1_RX )) +devlink_fmsg_string_put (fmsg,"\n\tNIX1: free disabled RX" ); +if (free_dis &BIT (NPA_INPQ_NIX1_TX )) +devlink_fmsg_string_put (fmsg,"\n\tNIX1:free disabled TX" ); +if (free_dis &BIT (NPA_INPQ_SSO )) +devlink_fmsg_string_put (fmsg,"\n\tFree Disabled for SSO" ); +if (free_dis &BIT (NPA_INPQ_TIM )) +devlink_fmsg_string_put (fmsg,"\n\tFree Disabled for TIM" ); +if (free_dis &BIT (NPA_INPQ_DPI )) +devlink_fmsg_string_put (fmsg,"\n\tFree Disabled for DPI" ); +if (free_dis &BIT (NPA_INPQ_AURA_OP )) +devlink_fmsg_string_put (fmsg,"\n\tFree Disabled for AURA" ); alloc_dis =FIELD_GET (GENMASK (31 ,16 ), intr_val); -if (alloc_dis &BIT (NPA_INPQ_NIX0_RX )) { - err =devlink_fmsg_string_put (fmsg,"\n\tNIX0: alloc disabled RX" ); -if (err) -return err; - } -if (alloc_dis &BIT (NPA_INPQ_NIX0_TX )) { - err =devlink_fmsg_string_put (fmsg,"\n\tNIX0:alloc disabled TX" ); -if (err) -return err; - } -if (alloc_dis &BIT (NPA_INPQ_NIX1_RX )) { - err =devlink_fmsg_string_put (fmsg,"\n\tNIX1: alloc disabled RX" ); -if (err) -return err; - } -if (alloc_dis &BIT (NPA_INPQ_NIX1_TX )) { - err =devlink_fmsg_string_put (fmsg,"\n\tNIX1:alloc disabled TX" ); -if (err) -return err; - } -if (alloc_dis &BIT (NPA_INPQ_SSO )) { - err =devlink_fmsg_string_put (fmsg,"\n\tAlloc Disabled for SSO" ); -if (err) -return err; - } -if (alloc_dis &BIT (NPA_INPQ_TIM )) { - err =devlink_fmsg_string_put (fmsg,"\n\tAlloc Disabled for TIM" ); -if (err) -return err; - } -if (alloc_dis &BIT (NPA_INPQ_DPI )) { - err =devlink_fmsg_string_put (fmsg,"\n\tAlloc Disabled for DPI" ); -if (err) -return err; - } -if (alloc_dis &BIT (NPA_INPQ_AURA_OP )) { - err =devlink_fmsg_string_put (fmsg,"\n\tAlloc Disabled for AURA" ); -if (err) -return err; - } - err =rvu_report_pair_end (fmsg); -if (err) -return err; +if (alloc_dis &BIT (NPA_INPQ_NIX0_RX )) +devlink_fmsg_string_put (fmsg,"\n\tNIX0: alloc disabled RX" ); +if (alloc_dis &BIT (NPA_INPQ_NIX0_TX )) +devlink_fmsg_string_put (fmsg,"\n\tNIX0:alloc disabled TX" ); +if (alloc_dis &BIT (NPA_INPQ_NIX1_RX )) +devlink_fmsg_string_put (fmsg,"\n\tNIX1: alloc disabled RX" ); +if (alloc_dis &BIT (NPA_INPQ_NIX1_TX )) +devlink_fmsg_string_put (fmsg,"\n\tNIX1:alloc disabled TX" ); +if (alloc_dis &BIT (NPA_INPQ_SSO )) +devlink_fmsg_string_put (fmsg,"\n\tAlloc Disabled for SSO" ); +if (alloc_dis &BIT (NPA_INPQ_TIM )) +devlink_fmsg_string_put (fmsg,"\n\tAlloc Disabled for TIM" ); +if (alloc_dis &BIT (NPA_INPQ_DPI )) +devlink_fmsg_string_put (fmsg,"\n\tAlloc Disabled for DPI" ); +if (alloc_dis &BIT (NPA_INPQ_AURA_OP )) +devlink_fmsg_string_put (fmsg,"\n\tAlloc Disabled for AURA" ); + +rvu_report_pair_end (fmsg);break ;case NPA_AF_RVU_ERR : - err =rvu_report_pair_start (fmsg,"NPA_AF_ERR" ); -if (err) -return err; - err =devlink_fmsg_u64_pair_put (fmsg,"\tNPA Error Interrupt Reg " , - npa_event_context->npa_af_rvu_err); -if (err) -return err; - -if (npa_event_context->npa_af_rvu_err &BIT_ULL (14 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tFault on NPA_AQ_INST_S read" ); -if (err) -return err; - } -if (npa_event_context->npa_af_rvu_err &BIT_ULL (13 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tFault on NPA_AQ_RES_S write" ); -if (err) -return err; - } -if (npa_event_context->npa_af_rvu_err &BIT_ULL (12 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tAQ Doorbell Error" ); -if (err) -return err; - } - err =rvu_report_pair_end (fmsg); -if (err) -return err; +rvu_report_pair_start (fmsg,"NPA_AF_ERR" ); +devlink_fmsg_u64_pair_put (fmsg,"\tNPA Error Interrupt Reg " , + npa_event_context->npa_af_rvu_err); +if (npa_event_context->npa_af_rvu_err &BIT_ULL (14 )) +devlink_fmsg_string_put (fmsg,"\n\tFault on NPA_AQ_INST_S read" ); +if (npa_event_context->npa_af_rvu_err &BIT_ULL (13 )) +devlink_fmsg_string_put (fmsg,"\n\tFault on NPA_AQ_RES_S write" ); +if (npa_event_context->npa_af_rvu_err &BIT_ULL (12 )) +devlink_fmsg_string_put (fmsg,"\n\tAQ Doorbell Error" ); +rvu_report_pair_end (fmsg);break ;case NPA_AF_RVU_RAS : - err =rvu_report_pair_start (fmsg,"NPA_AF_RVU_RAS" ); -if (err) -return err; - err =devlink_fmsg_u64_pair_put (fmsg,"\tNPA RAS Interrupt Reg " , - npa_event_context->npa_af_rvu_ras); -if (err) -return err; -if (npa_event_context->npa_af_rvu_ras &BIT_ULL (34 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tPoison data on NPA_AQ_INST_S" ); -if (err) -return err; - } -if (npa_event_context->npa_af_rvu_ras &BIT_ULL (33 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tPoison data on NPA_AQ_RES_S" ); -if (err) -return err; - } -if (npa_event_context->npa_af_rvu_ras &BIT_ULL (32 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tPoison data on HW context" ); -if (err) -return err; - } - err =rvu_report_pair_end (fmsg); -if (err) -return err; +rvu_report_pair_start (fmsg,"NPA_AF_RVU_RAS" ); +devlink_fmsg_u64_pair_put (fmsg,"\tNPA RAS Interrupt Reg " , + npa_event_context->npa_af_rvu_ras); +if (npa_event_context->npa_af_rvu_ras &BIT_ULL (34 )) +devlink_fmsg_string_put (fmsg,"\n\tPoison data on NPA_AQ_INST_S" ); +if (npa_event_context->npa_af_rvu_ras &BIT_ULL (33 )) +devlink_fmsg_string_put (fmsg,"\n\tPoison data on NPA_AQ_RES_S" ); +if (npa_event_context->npa_af_rvu_ras &BIT_ULL (32 )) +devlink_fmsg_string_put (fmsg,"\n\tPoison data on HW context" ); +rvu_report_pair_end (fmsg);break ;case NPA_AF_RVU_INTR : - err =rvu_report_pair_start (fmsg,"NPA_AF_RVU" ); -if (err) -return err; - err =devlink_fmsg_u64_pair_put (fmsg,"\tNPA RVU Interrupt Reg " , - npa_event_context->npa_af_rvu_int); -if (err) -return err; -if (npa_event_context->npa_af_rvu_int &BIT_ULL (0 )) { - err =devlink_fmsg_string_put (fmsg,"\n\tUnmap Slot Error" ); -if (err) -return err; - } -return rvu_report_pair_end (fmsg); +rvu_report_pair_start (fmsg,"NPA_AF_RVU" ); +devlink_fmsg_u64_pair_put (fmsg,"\tNPA RVU Interrupt Reg " , + npa_event_context->npa_af_rvu_int); +if (npa_event_context->npa_af_rvu_int &BIT_ULL (0 )) +devlink_fmsg_string_put (fmsg,"\n\tUnmap Slot Error" ); +rvu_report_pair_end (fmsg); +break ;default :return -EINVAL ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 194/481 octeontx2-af: devlink: fix NIX RAS reporter to use RAS interrupt status
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alok Tiwari <[email protected]>
[ Upstream commit 87f7dff3ec75b91def0024ebaaf732457f47a63b ]
The NIX RAS health report path uses nix_af_rvu_err when handling the NIX_AF_RVU_RAS case, so the report prints the ERR interrupt status rather than the RAS interrupt status.
Use nix_af_rvu_ras for the NIX_AF_RVU_RAS report.
--- drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c +2 -2
@@ -327,10 +327,10 @@ static int rvu_nix_report_show(struct devlink_fmsg *fmsg, void *ctx,rvu_report_pair_end (fmsg);break ;case NIX_AF_RVU_RAS : - intr_val = nix_event_context->nix_af_rvu_err; + intr_val = nix_event_context->nix_af_rvu_ras;rvu_report_pair_start (fmsg,"NIX_AF_RAS" );devlink_fmsg_u64_pair_put (fmsg,"\tNIX RAS Interrupt Reg " , - nix_event_context->nix_af_rvu_err); + nix_event_context->nix_af_rvu_ras);devlink_fmsg_string_put (fmsg,"\n\tPoison Data on:" );if (intr_val &BIT_ULL (34 ))devlink_fmsg_string_put (fmsg,"\n\tNIX_AQ_INST_S" );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 195/481 usb: gadget: f_mass_storage: Fix potential integer overflow in check_command_size_in_blocks()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Seungjin Bae <[email protected]>
[ Upstream commit 8479891d1f04a8ce55366fe4ca361ccdb96f02e1 ]
The check_command_size_in_blocks() function calculates the data size in bytes by left shifting common->data_size_from_cmnd by the block size (common->curlun->blkbits). However, it does not validate whether this shift operation will cause an integer overflow.
Initially, the block size is set up in fsg_lun_open() , and the common->data_size_from_cmnd is set up in do_scsi_command(). During initialization, there is no integer overflow check for the interaction between two variables.
So if a malicious USB host sends a SCSI READ or WRITE command requesting a large amount of data (common->data_size_from_cmnd), the left shift operation can wrap around. This results in a truncated data size, which can bypass boundary checks and potentially lead to memory corruption or out-of-bounds accesses.
Fix this by using the check_shl_overflow() macro to safely perform the shift and catch any overflows.
--- drivers/usb/gadget/function/f_mass_storage.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/usb/gadget/function/f_mass_storage.c +10 -2
@@ -179,6 +179,7 @@#include <linux/kthread.h> #include <linux/sched/signal.h> #include <linux/limits.h> +#include <linux/overflow.h> #include <linux/pagemap.h> #include <linux/rwsem.h> #include <linux/slab.h>
@@ -1852,8 +1853,15 @@ static int check_command_size_in_blocks(struct fsg_common *common, int cmnd_size, enum data_direction data_dir, unsigned int mask, int needs_medium, const char *name) { - if (common->curlun) - common->data_size_from_cmnd <<= common->curlun->blkbits; + if (common->curlun) { + if (check_shl_overflow(common->data_size_from_cmnd, + common->curlun->blkbits, + &common->data_size_from_cmnd)) { + common->phase_error = 1; +return -EINVAL ; + } + } +return check_command (common, cmnd_size, data_dir, mask, needs_medium, name); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 196/481 Revert "arm64: dts: qcom: sdm845-oneplus: Mark l14a regulator as boot-on"
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
This reverts commit d2a3230c1f655e5d1560ec005805f800b9873292.
The backport applied regulator-boot-on to vreg_l12a_1p8 (ldo12) instead of vreg_l14a_1p88 (ldo14) due to identical surrounding context lines.
--- arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi | 1 - 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +0 -1
@@ -224,7 +224,6 @@ vreg_l12a_1p8: ldo12 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - regulator-boot-on; }; vreg_l14a_1p88: ldo14 {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 197/481 cgroup: fix race between task migration and iteration
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qingye Zhao <[email protected]>
commit 5ee01f1a7343d6a3547b6802ca2d4cdce0edacb1 upstream.
When a task is migrated out of a css_set, cgroup_migrate_add_task() first moves it from cset->tasks to cset->mg_tasks via:
list_move_tail(&task->cg_list, &cset->mg_tasks);
If a css_task_iter currently has it->task_pos pointing to this task, css_set_move_task() calls css_task_iter_skip() to keep the iterator valid. However, since the task has already been moved to ->mg_tasks, the iterator is advanced relative to the mg_tasks list instead of the original tasks list. As a result, remaining tasks on cset->tasks, as well as tasks queued on cset->mg_tasks, can be skipped by iteration.
Fix this by calling css_set_skip_task_iters() before unlinking task->cg_list from cset->tasks. This advances all active iterators to the next task on cset->tasks, so iteration continues correctly even when a task is concurrently being migrated.
This race is hard to hit in practice without instrumentation, but it can be reproduced by artificially slowing down cgroup_procs_show(). For example, on an Android device a temporary /sys/kernel/cgroup/cgroup_test knob can be added to inject a delay into cgroup_procs_show(), and then:
1) Spawn three long-running tasks (PIDs 101, 102, 103).
2) Create a test cgroup and move the tasks into it.
3) Enable a large delay via /sys/kernel/cgroup/cgroup_test.
4) In one shell, read cgroup.procs from the test cgroup.
5) Within the delay window, in another shell migrate PID 102 by writing it to a different cgroup.procs file.
Under this setup, cgroup.procs can intermittently show only PID 101 while skipping PID 103. Once the migration completes, reading the file again shows all tasks as expected.
Note that this change does not allow removing the existing css_set_skip_task_iters() call in css_set_move_task(). The new call in cgroup_migrate_add_task() only handles iterators that are racing with migration while the task is still on cset->tasks. Iterators may also start after the task has been moved to cset->mg_tasks. If we dropped css_set_skip_task_iters() from css_set_move_task(), such iterators could keep task_pos pointing to a migrating task, causing css_task_iter_advance() to malfunction on the destination css_set, up to and including crashes or infinite loops.
The race window between migration and iteration is very small, and css_task_iter is not on a hot path. In the worst case, when an iterator is positioned on the first thread of the migrating process, cgroup_migrate_add_task() may have to skip multiple tasks via css_set_skip_task_iters(). However, this only happens when migration and iteration actually race, so the performance impact is negligible compared to the correctness fix provided here.
--- kernel/cgroup/cgroup.c | 1 + 1 file changed, 1 insertion(+)
kernel/cgroup/cgroup.c +1 -0
@@ -2519,6 +2519,7 @@ static void cgroup_migrate_add_task(stru mgctx->tset.nr_tasks++; +css_set_skip_task_iters (cset, task);list_move_tail (&task->cg_list, &cset->mg_tasks);if (list_empty (&cset->mg_node)) list_add_tail(&cset->mg_node,
Greg Kroah-Hartman
maintainerPATCH 198/481 ALSA: usb-audio: Check endpoint numbers at parsing Scarlett2 mixer interfaces
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit df1d8abf36ca3681c21a6809eaa9a1e01ef897a6 upstream.
The Scarlett2 mixer quirk in USB-audio driver may hit a NULL dereference when a malformed USB descriptor is passed, since it assumes the presence of an endpoint in the parsed interface in scarlett2_find_fc_interface(), as reported by fuzzer.
For avoiding the NULL dereference, just add the sanity check of bNumEndpoints and skip the invalid interface.
--- sound/usb/mixer_scarlett2.c | 2 ++ 1 file changed, 2 insertions(+)
sound/usb/mixer_scarlett2.c +2 -0
@@ -3898,6 +3898,8 @@ static int scarlett2_find_fc_interface(sif (desc->bInterfaceClass !=255 )continue ; +if (desc->bNumEndpoints <1 ) +continue ; epd =get_endpoint (intf->altsetting,0 ); private->bInterfaceNumber = desc->bInterfaceNumber;
Greg Kroah-Hartman
maintainerPATCH 199/481 net: usb: lan78xx: fix silent drop of packets with checksum errors
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
commit e4f774a0cc955ce762aec91c66915a6e15087ab7 upstream.
Do not drop packets with checksum errors at the USB driver level; pass them to the network stack.
Previously, the driver dropped all packets where the 'Receive Error Detected' (RED) bit was set, regardless of the specific error type. This caused packets with only IP or TCP/UDP checksum errors to be dropped before reaching the kernel, preventing the network stack from accounting for them or performing software fallback.
Add a mask for hard hardware errors to safely drop genuinely corrupt frames, while allowing checksum-errored frames to pass with their ip_summed field explicitly set to CHECKSUM_NONE.
--- drivers/net/usb/lan78xx.c | 4 +++- drivers/net/usb/lan78xx.h | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-)
drivers/net/usb/lan78xx.c +3 -1
@@ -3537,6 +3537,7 @@ static void lan78xx_rx_csum_offload(stru*/ if (!(dev->net->features &NETIF_F_RXCSUM ) ||unlikely (rx_cmd_a &RX_CMD_A_ICSM_ ) || +unlikely (rx_cmd_a &RX_CMD_A_CSE_MASK_ ) || ((rx_cmd_a &RX_CMD_A_FVTG_ ) && !(dev->net->features &NETIF_F_HW_VLAN_CTAG_RX ))) { skb->ip_summed =CHECKSUM_NONE ;
@@ -3609,7 +3610,8 @@ static int lan78xx_rx(struct lan78xx_netreturn 0 ; } -if (unlikely (rx_cmd_a &RX_CMD_A_RED_ )) { +if (unlikely (rx_cmd_a &RX_CMD_A_RED_ ) && + (rx_cmd_a &RX_CMD_A_RX_HARD_ERRS_MASK_ )) {netif_dbg (dev, rx_err, dev->net,"Error rx_cmd_a=0x%08x" , rx_cmd_a); }else {
drivers/net/usb/lan78xx.h +3 -0
@@ -74,6 +74,9 @@#define RX_CMD_A_ICSM_ (0x00004000)#define RX_CMD_A_LEN_MASK_ (0x00003FFF) +#define RX_CMD_A_RX_HARD_ERRS_MASK_ \ + (RX_CMD_A_RX_ERRS_MASK_ & ~RX_CMD_A_CSE_MASK_) +/* Rx Command B */ #define RX_CMD_B_CSUM_SHIFT_ (16)#define RX_CMD_B_CSUM_MASK_ (0xFFFF0000)
Greg Kroah-Hartman
maintainerPATCH 200/481 net: usb: lan78xx: fix TX byte statistics for small packets
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
commit 50988747c30df47b73b787f234f746027cb7ec6c upstream.
Account for hardware auto-padding in TX byte counters to reflect actual wire traffic.
The LAN7850 hardware automatically pads undersized frames to the minimum Ethernet frame length (ETH_ZLEN, 60 bytes). However, the driver tracks the network statistics based on the unpadded socket buffer length. This results in the tx_bytes counter under-reporting the actual physical bytes placed on the Ethernet wire for small packets (like short ARP or ICMP requests).
Use max_t() to ensure the transmission statistics accurately account for the hardware-generated padding.
--- drivers/net/usb/lan78xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/usb/lan78xx.c +1 -1
@@ -3886,7 +3886,7 @@ static struct skb_data *lan78xx_tx_buf_f } tx_data += len; - entry->length += len; + entry->length += max_t(unsigned int, len, ETH_ZLEN); entry->num_of_packet +=skb_shinfo (skb)->gso_segs ?:1 ;dev_kfree_skb_any (skb);
Greg Kroah-Hartman
maintainerPATCH 201/481 net: usb: lan78xx: skip LTM configuration for LAN7850
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
commit d9cc0e440f0664f6f3e2c26e39ab9dd5f3badba7 upstream.
Do not configure Latency Tolerance Messaging (LTM) on USB 2.0 hardware.
The LAN7850 is a High-Speed (USB 2.0) only device and does not support SuperSpeed features like LTM. Currently, the driver unconditionally attempts to configure LTM registers during initialization. On the LAN7850, these registers do not exist, resulting in writes to invalid or undocumented memory space.
This issue was identified during a port to the regmap API with strict register validation enabled. While no functional issues or crashes have been observed from these invalid writes, bypassing LTM initialization on the LAN7850 ensures the driver strictly adheres to the hardware's valid register map.
--- drivers/net/usb/lan78xx.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/usb/lan78xx.c +4 -0
@@ -2672,6 +2672,10 @@ static void lan78xx_init_ltm(struct lan7u32 buf;u32 regs[6 ] = {0 }; +/* LAN7850 is USB 2.0 and does not support LTM */ +if (dev->chipid ==ID_REV_CHIP_ID_7850_ ) +return ; + ret =lan78xx_read_reg (dev,USB_CFG1 , &buf);if (buf &USB_CFG1_LTM_ENABLE_ ) {u8 temp[2 ];
Greg Kroah-Hartman
maintainerPATCH 202/481 ASoC: amd: yc: Add DMI quirk for ASUS EXPERTBOOK PM1503CDA
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Heng <[email protected]>
commit 325291b20f8a6f14b9c82edbf5d12e4e71f6adaa upstream.
Add a DMI quirk for the ASUS EXPERTBOOK PM1503CDA fixing the issue where the internal microphone was not detected.
--- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+)
sound/soc/amd/yc/acp6x-mach.c +7 -0
@@ -556,6 +556,13 @@ static const struct dmi_system_id yc_acp DMI_MATCH(DMI_PRODUCT_NAME, "ASUS EXPERTBOOK BM1503CDA"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "PM1503CDA"), + } + }, {} };
Greg Kroah-Hartman
maintainerPATCH 203/481 KVM: SVM: Initialize AVIC VMCB fields if AVIC is enabled with in-kernel APIC
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit 3989a6d036c8ec82c0de3614bed23a1dacd45de5 upstream.
Initialize all per-vCPU AVIC control fields in the VMCB if AVIC is enabled in KVM and the VM has an in-kernel local APIC, i.e. if it's _possible_ the vCPU could activate AVIC at any point in its lifecycle. Configuring the VMCB if and only if AVIC is active "works" purely because of optimizations in kvm_create_lapic() to speculatively set apicv_active if AVIC is enabled *and* to defer updates until the first KVM_RUN. In quotes because KVM likely won't do the right thing if kvm_apicv_activated() is false, i.e. if a vCPU is created while APICv is inhibited at the VM level for whatever reason. E.g. if the inhibit is *removed* before KVM_REQ_APICV_UPDATE is handled in KVM_RUN, then __kvm_vcpu_update_apicv() will elide calls to vendor code due to seeing "apicv_active == activate".
Cleaning up the initialization code will also allow fixing a bug where KVM incorrectly leaves CR8 interception enabled when AVIC is activated without creating a mess with respect to whether AVIC is activated or not.
--- arch/x86/kvm/svm/avic.c | 2 +- arch/x86/kvm/svm/svm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/x86/kvm/svm/avic.c +1 -1
@@ -245,7 +245,7 @@ void avic_init_vmcb(struct vcpu_svm *svm vmcb->control.avic_physical_id = ppa &AVIC_HPA_MASK ; vmcb->control.avic_vapic_bar =APIC_DEFAULT_PHYS_BASE &VMCB_AVIC_APIC_BAR_MASK ; -if (kvm_apicv_activated (svm->vcpu.kvm)) +if (kvm_vcpu_apicv_active (&svm->vcpu))avic_activate_vmcb (svm);else avic_deactivate_vmcb (svm);
arch/x86/kvm/svm/svm.c +1 -1
@@ -1307,7 +1307,7 @@ static void init_vmcb(struct kvm_vcpu *vif (boot_cpu_has (X86_FEATURE_V_SPEC_CTRL ))set_msr_interception (vcpu, svm->msrpm,MSR_IA32_SPEC_CTRL ,1 ,1 ); -if (kvm_vcpu_apicv_active (vcpu)) +if (enable_apicv &&irqchip_in_kernel (vcpu->kvm))avic_init_vmcb (svm, vmcb);if (vgif) {
Greg Kroah-Hartman
maintainerPATCH 204/481 USB: add QUIRK_NO_BOS for video capture several devices
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: A1RM4X <[email protected]>
commit 93cd0d664661f58f7e7bed7373714ab2ace41734 upstream.
Several USB capture devices also need the USB_QUIRK_NO_BOS set for them to work properly, odds are they are all the same chip inside, just different vendor/product ids.
This fixes up:
- ASUS TUF 4K PRO
- Avermedia Live Gamer Ultra 2.1 (GC553G2)
- UGREEN 35871
to now run at full speed (10 Gbps/4K 60 fps mode.)
--- drivers/usb/core/quirks.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/usb/core/quirks.c +9 -0
@@ -377,6 +377,9 @@ static const struct usb_device_id usb_qu/* SanDisk Extreme 55AE */ { USB_DEVICE(0x0781, 0x55ae), .driver_info = USB_QUIRK_NO_LPM }, + /* Avermedia Live Gamer Ultra 2.1 (GC553G2) - BOS descriptor fetch hangs at SuperSpeed Plus */ + { USB_DEVICE(0x07ca, 0x2553), .driver_info = USB_QUIRK_NO_BOS }, + /* Realforce 87U Keyboard */ { USB_DEVICE(0x0853, 0x011b), .driver_info = USB_QUIRK_NO_LPM },
@@ -434,6 +437,9 @@ static const struct usb_device_id usb_qu { USB_DEVICE(0x0b05, 0x17e0), .driver_info = USB_QUIRK_IGNORE_REMOTE_WAKEUP }, + /* ASUS TUF 4K PRO - BOS descriptor fetch hangs at SuperSpeed Plus */ + { USB_DEVICE(0x0b05, 0x1ab9), .driver_info = USB_QUIRK_NO_BOS }, + /* Realtek Semiconductor Corp. Mass Storage Device (Multicard Reader)*/ { USB_DEVICE(0x0bda, 0x0151), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS },
@@ -562,6 +568,9 @@ static const struct usb_device_id usb_qu { USB_DEVICE(0x2386, 0x350e), .driver_info = USB_QUIRK_NO_LPM }, + /* UGREEN 35871 - BOS descriptor fetch hangs at SuperSpeed Plus */ + { USB_DEVICE(0x2b89, 0x5871), .driver_info = USB_QUIRK_NO_BOS }, + /* APTIV AUTOMOTIVE HUB */ { USB_DEVICE(0x2c48, 0x0132), .driver_info = USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT },
Greg Kroah-Hartman
maintainerPATCH 205/481 usb/core/quirks: Add Huawei ME906S-device to wakeup quirk
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoffer Sandberg <[email protected]>
commit 0326ff28d56b4fa202de36ffc8462a354f383a64 upstream.
Similar to other Huawei LTE modules using this quirk, this version with another vid/pid suffers from spurious wakeups.
Setting the quirk fixes the issue for this device as well.
--- drivers/usb/core/quirks.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/core/quirks.c +4 -0
@@ -208,6 +208,10 @@ static const struct usb_device_id usb_qu/* HP v222w 16GB Mini USB Drive */ { USB_DEVICE(0x03f0, 0x3f40), .driver_info = USB_QUIRK_DELAY_INIT }, + /* Huawei 4G LTE module ME906S */ + { USB_DEVICE(0x03f0, 0xa31d), .driver_info = + USB_QUIRK_DISCONNECT_SUSPEND }, + /* Creative SB Audigy 2 NX */ { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
Greg Kroah-Hartman
maintainerPATCH 206/481 USB: ezcap401 needs USB_QUIRK_NO_BOS to function on 10gbs usb speed
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vyacheslav Vahnenko <[email protected]>
commit d0d9b1f4f5391e6a00cee81d73ed2e8f98446d5f upstream.
Add USB_QUIRK_NO_BOS for ezcap401 capture card, without it dmesg will show "unable to get BOS descriptor or descriptor too short" and "unable to read config index 0 descriptor/start: -71" errors and device will not able to work at full speed at 10gbs
--- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/core/quirks.c +3 -0
@@ -585,6 +585,9 @@ static const struct usb_device_id usb_qu/* Alcor Link AK9563 SC Reader used in 2022 Lenovo ThinkPads */ { USB_DEVICE(0x2ce3, 0x9563), .driver_info = USB_QUIRK_NO_LPM }, + /* ezcap401 - BOS descriptor fetch hangs at SuperSpeed Plus */ + { USB_DEVICE(0x32ed, 0x0401), .driver_info = USB_QUIRK_NO_BOS }, + /* DELL USB GEN2 */ { USB_DEVICE(0x413c, 0xb062), .driver_info = USB_QUIRK_NO_LPM | USB_QUIRK_RESET_RESUME },
Greg Kroah-Hartman
maintainerPATCH 207/481 usb: xhci: Fix memory leak in xhci_disable_slot()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zilin Guan <[email protected]>
commit c1c8550e70401159184130a1afc6261db01fc0ce upstream.
xhci_alloc_command() allocates a command structure and, when the second argument is true, also allocates a completion structure. Currently, the error handling path in xhci_disable_slot() only frees the command structure using kfree(), causing the completion structure to leak.
Use xhci_free_command() instead of kfree(). xhci_free_command() correctly frees both the command structure and the associated completion structure. Since the command structure is allocated with zero-initialization, command->in_ctx is NULL and will not be erroneously freed by xhci_free_command().
This bug was found using an experimental static analysis tool we are developing. The tool is based on the LLVM framework and is specifically designed to detect memory management issues. It is currently under active development and not yet publicly available, but we plan to open-source it after our research is published.
The bug was originally detected on v6.13-rc1 using our static analysis tool, and we have verified that the issue persists in the latest mainline kernel.
We performed build testing on x86_64 with allyesconfig using GCC=11.4.0. Since triggering these error paths in xhci_disable_slot() requires specific hardware conditions or abnormal state, we were unable to construct a test case to reliably trigger these specific error paths at runtime.
--- drivers/usb/host/xhci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/host/xhci.c +2 -2
@@ -4067,7 +4067,7 @@ int xhci_disable_slot(struct xhci_hcd *xif (state ==0xffffffff || (xhci->xhc_state &XHCI_STATE_DYING ) || (xhci->xhc_state &XHCI_STATE_HALTED )) {spin_unlock_irqrestore (&xhci->lock, flags); -kfree (command); +xhci_free_command (xhci, command);return -ENODEV ; }
@@ -4075,7 +4075,7 @@ int xhci_disable_slot(struct xhci_hcd *x slot_id);if (ret) {spin_unlock_irqrestore (&xhci->lock, flags); -kfree (command); +xhci_free_command (xhci, command);return ret; }xhci_ring_cmd_db (xhci);
Greg Kroah-Hartman
maintainerPATCH 208/481 usb: yurex: fix race in probe
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit 7a875c09899ba0404844abfd8f0d54cdc481c151 upstream.
The bbu member of the descriptor must be set to the value standing for uninitialized values before the URB whose completion handler sets bbu is submitted. Otherwise there is a window during which probing can overwrite already retrieved data.
--- drivers/usb/misc/yurex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/misc/yurex.c +1 -1
@@ -272,6 +272,7 @@ static int yurex_probe(struct usb_interf dev->int_buffer,YUREX_BUF_SIZE , yurex_interrupt, dev, 1); dev->urb->transfer_flags |=URB_NO_TRANSFER_DMA_MAP ; + dev->bbu =-1 ;if (usb_submit_urb (dev->urb,GFP_KERNEL )) { retval = -EIO ;dev_err (&interface->dev,"Could not submitting URB\n" );
@@ -280,7 +281,6 @@ static int yurex_probe(struct usb_interf/* save our data pointer in this interface device */ usb_set_intfdata (interface, dev); - dev->bbu =-1 ;/* we can register the device now, as it is ready */ retval =usb_register_dev (interface, &yurex_class);
Greg Kroah-Hartman
maintainerPATCH 209/481 usb: misc: uss720: properly clean up reference in uss720_probe()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Kroah-Hartman <[email protected]>
commit 45dba8011efac11a2f360383221b541f5ea53ce5 upstream.
If get_1284_register() fails, the usb device reference count is incorrect and needs to be properly dropped before returning. That will happen when the kref is dropped in the call to destroy_priv(), so jump to that error path instead of returning directly.
--- drivers/usb/misc/uss720.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/misc/uss720.c +1 -1
@@ -733,7 +733,7 @@ static int uss720_probe(struct usb_inter ret =get_1284_register (pp,0 , ®,GFP_KERNEL );dev_dbg (&intf->dev,"reg: %7ph\n" , priv->reg);if (ret <0 ) -return ret; + goto probe_abort; ret =usb_find_last_int_in_endpoint (interface, &epd);if (!ret) {
Greg Kroah-Hartman
maintainerPATCH 210/481 usb: core: dont power off roothub PHYs if phy_set_mode() fails
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabor Juhos <[email protected]>
commit e293015ba76eb96ce4ebed7e3b2cb1a7d319f3e9 upstream.
Remove the error path from the usb_phy_roothub_set_mode() function. The code is clearly wrong, because phy_set_mode() calls can't be balanced with phy_power_off() calls.
Additionally, the usb_phy_roothub_set_mode() function is called only from usb_add_hcd() before it powers on the PHYs, so powering off those makes no sense anyway.
Presumably, the code is copy-pasted from the phy_power_on() function without adjusting the error handling.
--- drivers/usb/core/phy.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
drivers/usb/core/phy.c +1 -7
@@ -138,16 +138,10 @@ int usb_phy_roothub_set_mode(struct usb_list_for_each_entry (roothub_entry, head, list) { err =phy_set_mode (roothub_entry->phy, mode);if (err) - goto err_out; +return err; }return 0 ; - -err_out: -list_for_each_entry_continue_reverse (roothub_entry, head, list) -phy_power_off (roothub_entry->phy); - -return err; }EXPORT_SYMBOL_GPL (usb_phy_roothub_set_mode);
Greg Kroah-Hartman
maintainerPATCH 211/481 usb: cdc-acm: Restore CAP_BRK functionnality to CH343
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier <[email protected]>
commit 14ae24cba291bddfdc296bbcbfd00cd09d0498ef upstream.
The CH343 USB/serial adapter is as buggy as it is popular (very). One of its quirks is that despite being capable of signalling a BREAK condition, it doesn't advertise it.
This used to work nonetheless until 66aad7d8d3ec5 ("usb: cdc-acm:
return correct error code on unsupported break") applied some reasonable restrictions, preventing breaks from being emitted on devices that do not advertise CAP_BRK.
Add a quirk for this particular device, so that breaks can still be produced on some of my machines attached to my console server.
--- drivers/usb/class/cdc-acm.c | 5 +++++ drivers/usb/class/cdc-acm.h | 1 + 2 files changed, 6 insertions(+)
drivers/usb/class/cdc-acm.c +5 -0
@@ -1355,6 +1355,8 @@ made_compressed_probe: acm->ctrl_caps = h.usb_cdc_acm_descriptor->bmCapabilities;if (quirks &NO_CAP_LINE ) acm->ctrl_caps &= ~USB_CDC_CAP_LINE ; +if (quirks &MISSING_CAP_BRK ) + acm->ctrl_caps |=USB_CDC_CAP_BRK ; acm->ctrlsize = ctrlsize; acm->readsize = readsize; acm->rx_buflimit = num_rx_buf;
@@ -1978,6 +1980,9 @@ static const struct usb_device_id acm_id .driver_info = IGNORE_DEVICE, }, +/* CH343 supports CAP_BRK, but doesn't advertise it */ + { USB_DEVICE(0x1a86, 0x55d3), .driver_info = MISSING_CAP_BRK, }, + /* control interfaces without any protocol set */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, USB_CDC_PROTO_NONE) },
drivers/usb/class/cdc-acm.h +1 -0
@@ -113,3 +113,4 @@ struct acm {#define CLEAR_HALT_CONDITIONS BIT(5)#define SEND_ZERO_PACKET BIT(6)#define DISABLE_ECHO BIT(7) +#define MISSING_CAP_BRK BIT(8)
Greg Kroah-Hartman
maintainerPATCH 212/481 USB: usbcore: Introduce usb_bulk_msg_killable()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alan Stern <[email protected]>
commit 416909962e7cdf29fd01ac523c953f37708df93d upstream.
The synchronous message API in usbcore (usb_control_msg(), usb_bulk_msg(), and so on) uses uninterruptible waits. However, drivers may call these routines in the context of a user thread, which means it ought to be possible to at least kill them.
For this reason, introduce a new usb_bulk_msg_killable() function which behaves the same as usb_bulk_msg() except for using wait_for_completion_killable_timeout() instead of wait_for_completion_timeout(). The same can be done later for usb_control_msg() later on, if it turns out to be needed.
--- drivers/usb/core/message.c | 79 +++++++++++++++++++++++++++++++++++++++------ include/linux/usb.h | 5 +- 2 files changed, 72 insertions(+), 12 deletions(-)
drivers/usb/core/message.c +69 -10
@@ -41,16 +41,17 @@ static void usb_api_blocking_completion(/* -* Starts urb and waits for completion or timeout. Note that this call -* is NOT interruptible. Many device driver i/o requests should be -* interruptible and therefore these drivers should implement their -* own interruptible routines. +* Starts urb and waits for completion or timeout. +* Whether or not the wait is killable depends on the flag passed in. +* For example, compare usb_bulk_msg() and usb_bulk_msg_killable(). */ -static int usb_start_wait_urb (struct urb *urb,int timeout,int *actual_length) +static int usb_start_wait_urb (struct urb *urb,int timeout,int *actual_length, +bool killable) {struct api_context ctx;unsigned long expire;int retval; +long rc;init_completion (&ctx.done); urb->context = &ctx;
@@ -60,12 +61,21 @@ static int usb_start_wait_urb(struct urb goto out; expire = timeout ?msecs_to_jiffies (timeout) :MAX_SCHEDULE_TIMEOUT ; -if (!wait_for_completion_timeout (&ctx.done, expire)) { +if (killable) + rc =wait_for_completion_killable_timeout (&ctx.done, expire); +else + rc =wait_for_completion_timeout (&ctx.done, expire); +if (rc <=0 ) {usb_kill_urb (urb); - retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); +if (ctx.status != -ENOENT ) + retval = ctx.status; +else if (rc ==0 ) + retval = -ETIMEDOUT ; +else + retval = rc; dev_dbg(&urb->dev->dev, - "%s timed out on ep%d%s len=%u/%u\n", + "%s timed out or killed on ep%d%s len=%u/%u\n", current->comm, usb_endpoint_num(&urb->ep->desc), usb_urb_dir_in(urb) ? "in" : "out",
@@ -99,7 +109,7 @@ static int usb_internal_control_msg(struusb_fill_control_urb (urb, usb_dev, pipe, (unsigned char *)cmd, data, len, usb_api_blocking_completion,NULL ); - retv =usb_start_wait_urb (urb, timeout, &length); + retv =usb_start_wait_urb (urb, timeout, &length, false);if (retv <0 )return retv;else
@@ -384,10 +394,59 @@ int usb_bulk_msg(struct usb_device *usb_usb_fill_bulk_urb (urb, usb_dev, pipe, data, len, usb_api_blocking_completion,NULL ); -return usb_start_wait_urb (urb, timeout, actual_length); +return usb_start_wait_urb (urb, timeout, actual_length, false); }EXPORT_SYMBOL_GPL (usb_bulk_msg); +/** +* usb_bulk_msg_killable - Builds a bulk urb, sends it off and waits for completion in a killable state +* @usb_dev: pointer to the usb device to send the message to +* @pipe: endpoint "pipe" to send the message to +* @data: pointer to the data to send +* @len: length in bytes of the data to send +* @actual_length: pointer to a location to put the actual length transferred +* in bytes +* @timeout: time in msecs to wait for the message to complete before +* timing out (if 0 the wait is forever) +* +* Context: task context, might sleep. +* +* This function is just like usb_blk_msg() except that it waits in a +* killable state. +* +* Return: +* If successful, 0. Otherwise a negative error number. The number of actual +* bytes transferred will be stored in the @actual_length parameter. +* +*/ +int usb_bulk_msg_killable (struct usb_device *usb_dev,unsigned int pipe, +void *data,int len,int *actual_length,int timeout) +{ +struct urb *urb; +struct usb_host_endpoint *ep; + + ep =usb_pipe_endpoint (usb_dev, pipe); +if (!ep || len <0 ) +return -EINVAL ; + + urb =usb_alloc_urb (0 ,GFP_KERNEL ); +if (!urb) +return -ENOMEM ; + +if ((ep->desc.bmAttributes &USB_ENDPOINT_XFERTYPE_MASK ) == +USB_ENDPOINT_XFER_INT ) { + pipe = (pipe & ~(3 <<30 )) | (PIPE_INTERRUPT <<30 ); +usb_fill_int_urb (urb, usb_dev, pipe, data, len, + usb_api_blocking_completion,NULL , + ep->desc.bInterval); + }else +usb_fill_bulk_urb (urb, usb_dev, pipe, data, len, + usb_api_blocking_completion,NULL ); + +return usb_start_wait_urb (urb, timeout, actual_length, true); +} +EXPORT_SYMBOL_GPL (usb_bulk_msg_killable); +/*-------------------------------------------------------------------*/ static void sg_clean (struct usb_sg_request *io)
include/linux/usb.h +3 -2
@@ -1804,8 +1804,9 @@ extern int usb_control_msg(struct usb_deextern int usb_interrupt_msg (struct usb_device *usb_dev,unsigned int pipe,void *data,int len,int *actual_length,int timeout);extern int usb_bulk_msg (struct usb_device *usb_dev,unsigned int pipe, -void *data,int len,int *actual_length, -int timeout); +void *data,int len,int *actual_length,int timeout); +extern int usb_bulk_msg_killable (struct usb_device *usb_dev,unsigned int pipe, +void *data,int len,int *actual_length,int timeout);/* wrappers around usb_control_msg() for the most common standard requests */ int usb_control_msg_send(struct usb_device *dev, __u8 endpoint, __u8 request,
Greg Kroah-Hartman
maintainerPATCH 213/481 USB: usbtmc: Use usb_bulk_msg_killable() with user-specified timeouts
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alan Stern <[email protected]>
commit 7784caa413a89487dd14dd5c41db8753483b2acb upstream.
The usbtmc driver accepts timeout values specified by the user in an ioctl command, and uses these timeouts for some usb_bulk_msg() calls. Since the user can specify arbitrarily long timeouts and usb_bulk_msg() uses unkillable waits, call usb_bulk_msg_killable() instead to avoid the possibility of the user hanging a kernel thread indefinitely.
--- drivers/usb/class/usbtmc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/usb/class/usbtmc.c +3 -3
@@ -727,7 +727,7 @@ static int usbtmc488_ioctl_trigger(struc buffer[1 ] = data->bTag; buffer[2 ] = ~data->bTag; - retval = usb_bulk_msg(data->usb_dev, + retval = usb_bulk_msg_killable(data->usb_dev, usb_sndbulkpipe(data->usb_dev, data->bulk_out), buffer, USBTMC_HEADER_SIZE,
@@ -1347,7 +1347,7 @@ static int send_request_dev_dep_msg_in(s buffer[11 ] =0 ;/* Reserved */ /* Send bulk URB */ - retval = usb_bulk_msg(data->usb_dev, + retval = usb_bulk_msg_killable(data->usb_dev, usb_sndbulkpipe(data->usb_dev, data->bulk_out), buffer, USBTMC_HEADER_SIZE,
@@ -1419,7 +1419,7 @@ static ssize_t usbtmc_read(struct file * actual =0 ;/* Send bulk URB */ - retval = usb_bulk_msg(data->usb_dev, + retval = usb_bulk_msg_killable(data->usb_dev, usb_rcvbulkpipe(data->usb_dev, data->bulk_in), buffer, bufsize, &actual,
Greg Kroah-Hartman
maintainerPATCH 214/481 USB: core: Limit the length of unkillable synchronous timeouts
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alan Stern <[email protected]>
commit 1015c27a5e1a63efae2b18a9901494474b4d1dc3 upstream.
The usb_control_msg(), usb_bulk_msg(), and usb_interrupt_msg() APIs in usbcore allow unlimited timeout durations. And since they use uninterruptible waits, this leaves open the possibility of hanging a task for an indefinitely long time, with no way to kill it short of unplugging the target device.
To prevent this sort of problem, enforce a maximum limit on the length of these unkillable timeouts. The limit chosen here, somewhat arbitrarily, is 60 seconds. On many systems (although not all) this is short enough to avoid triggering the kernel's hung-task detector.
In addition, clear up the ambiguity of negative timeout values by treating them the same as 0, i.e., using the maximum allowed timeout.
--- drivers/usb/core/message.c | 27 +++++++++++++-------------- include/linux/usb.h | 3 +++ 2 files changed, 16 insertions(+), 14 deletions(-)
drivers/usb/core/message.c +13 -14
@@ -44,6 +44,8 @@ static void usb_api_blocking_completion(* Starts urb and waits for completion or timeout. * Whether or not the wait is killable depends on the flag passed in. * For example, compare usb_bulk_msg() and usb_bulk_msg_killable(). +* +* For non-killable waits, we enforce a maximum limit on the timeout value. */ static int usb_start_wait_urb (struct urb *urb,int timeout,int *actual_length,bool killable)
@@ -60,7 +62,9 @@ static int usb_start_wait_urb(struct urbif (unlikely (retval)) goto out; - expire = timeout ?msecs_to_jiffies (timeout) :MAX_SCHEDULE_TIMEOUT ; +if (!killable && (timeout <=0 || timeout >USB_MAX_SYNCHRONOUS_TIMEOUT )) + timeout =USB_MAX_SYNCHRONOUS_TIMEOUT ; + expire = (timeout >0 ) ?msecs_to_jiffies (timeout) :MAX_SCHEDULE_TIMEOUT ;if (killable) rc =wait_for_completion_killable_timeout (&ctx.done, expire);else
@@ -126,8 +130,7 @@ static int usb_internal_control_msg(stru* @index: USB message index value * @data: pointer to the data to send * @size: length in bytes of the data to send -* @timeout: time in msecs to wait for the message to complete before timing -* out (if 0 the wait is forever) +* @timeout: time in msecs to wait for the message to complete before timing out * * Context: task context, might sleep. *
@@ -182,8 +185,7 @@ EXPORT_SYMBOL_GPL(usb_control_msg);* @index: USB message index value * @driver_data: pointer to the data to send * @size: length in bytes of the data to send -* @timeout: time in msecs to wait for the message to complete before timing -* out (if 0 the wait is forever) +* @timeout: time in msecs to wait for the message to complete before timing out * @memflags: the flags for memory allocation for buffers * * Context: !in_interrupt ()
@@ -241,8 +243,7 @@ EXPORT_SYMBOL_GPL(usb_control_msg_send);* @index: USB message index value * @driver_data: pointer to the data to be filled in by the message * @size: length in bytes of the data to be received -* @timeout: time in msecs to wait for the message to complete before timing -* out (if 0 the wait is forever) +* @timeout: time in msecs to wait for the message to complete before timing out * @memflags: the flags for memory allocation for buffers * * Context: !in_interrupt ()
@@ -313,8 +314,7 @@ EXPORT_SYMBOL_GPL(usb_control_msg_recv);* @len: length in bytes of the data to send * @actual_length: pointer to a location to put the actual length transferred * in bytes -* @timeout: time in msecs to wait for the message to complete before -* timing out (if 0 the wait is forever) +* @timeout: time in msecs to wait for the message to complete before timing out * * Context: task context, might sleep. *
@@ -346,8 +346,7 @@ EXPORT_SYMBOL_GPL(usb_interrupt_msg);* @len: length in bytes of the data to send * @actual_length: pointer to a location to put the actual length transferred * in bytes -* @timeout: time in msecs to wait for the message to complete before -* timing out (if 0 the wait is forever) +* @timeout: time in msecs to wait for the message to complete before timing out * * Context: task context, might sleep. *
@@ -407,12 +406,12 @@ EXPORT_SYMBOL_GPL(usb_bulk_msg);* @actual_length: pointer to a location to put the actual length transferred * in bytes * @timeout: time in msecs to wait for the message to complete before -* timing out (if 0 the wait is forever) +* timing out (if <= 0, the wait is as long as possible) * * Context: task context, might sleep. * -* This function is just like usb_blk_msg() except that it waits in a -* killable state. +* This function is just like usb_blk_msg(), except that it waits in a +* killable state and there is no limit on the timeout length. * * Return: * If successful, 0. Otherwise a negative error number. The number of actual
include/linux/usb.h +3 -0
@@ -1798,6 +1798,9 @@ void usb_buffer_unmap_sg(const struct us* SYNCHRONOUS CALL SUPPORT * *-------------------------------------------------------------------*/ +/* Maximum value allowed for timeout in synchronous routines below */ +#define USB_MAX_SYNCHRONOUS_TIMEOUT 60000/* ms */ +extern int usb_control_msg (struct usb_device *dev,unsigned int pipe,__u8 request,__u8 requesttype,__u16 value,__u16 index,void *data,__u16 size,int timeout);
Greg Kroah-Hartman
maintainerPATCH 215/481 usb: class: cdc-wdm: fix reordering issue in read code path
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit 8df672bfe3ec2268c2636584202755898e547173 upstream.
Quoting the bug report:
Due to compiler optimization or CPU out-of-order execution, the desc->length update can be reordered before the memmove. If this happens, wdm_read() can see the new length and call copy_to_user() on uninitialized memory. This also violates LKMM data race rules [1].
Fix it by using WRITE_ONCE and memory barriers.
--- drivers/usb/class/cdc-wdm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/class/cdc-wdm.c +3 -1
@@ -225,7 +225,8 @@ static void wdm_in_callback(struct urb */* we may already be in overflow */ if (!test_bit (WDM_OVERFLOW , &desc->flags)) {memmove (desc->ubuf + desc->length, desc->inbuf, length); - desc->length += length; +smp_wmb ();/* against wdm_read() */ +WRITE_ONCE (desc->length, desc->length + length); } } skip_error:
@@ -533,6 +534,7 @@ static ssize_t wdm_readreturn -ERESTARTSYS ; cntr =READ_ONCE (desc->length); +smp_rmb ();/* against wdm_in_callback() */ if (cntr ==0 ) { desc->read =0 ; retry:
Greg Kroah-Hartman
maintainerPATCH 216/481 usb: renesas_usbhs: fix use-after-free in ISR during device removal
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <[email protected]>
commit 3cbc242b88c607f55da3d0d0d336b49bf1e20412 upstream.
In usbhs_remove(), the driver frees resources (including the pipe array) while the interrupt handler (usbhs_interrupt) is still registered. If an interrupt fires after usbhs_pipe_remove() but before the driver is fully unbound, the ISR may access freed memory, causing a use-after-free.
Fix this by calling devm_free_irq() before freeing resources. This ensures the interrupt handler is both disabled and synchronized (waits for any running ISR to complete) before usbhs_pipe_remove() is called.
--- drivers/usb/renesas_usbhs/common.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/usb/renesas_usbhs/common.c +9 -0
@@ -800,6 +800,15 @@ static void usbhs_remove(struct platformusbhs_platform_call (priv, hardware_exit, pdev);reset_control_assert (priv->rsts); + +/* +* Explicitly free the IRQ to ensure the interrupt handler is +* disabled and synchronized before freeing resources. +* devm_free_irq() calls free_irq() which waits for any running +* ISR to complete, preventing UAF. +*/ +devm_free_irq (&pdev->dev, priv->irq, priv); +usbhs_mod_remove (priv);usbhs_fifo_remove (priv);usbhs_pipe_remove (priv);
Greg Kroah-Hartman
maintainerPATCH 217/481 usb: mdc800: handle signal and read racing
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit 2d6d260e9a3576256fe9ef6d1f7930c9ec348723 upstream.
If a signal arrives after a read has partially completed, we need to return the number of bytes read. -EINTR is correct only if that number is zero.
--- drivers/usb/image/mdc800.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/image/mdc800.c +1 -1
@@ -708,7 +708,7 @@ static ssize_t mdc800_device_read (strucif (signal_pending (current)) {mutex_unlock (&mdc800->io_lock); -return -EINTR ; +return len == left ? -EINTR : len-left; } sts=left > (mdc800->out_count-mdc800->out_ptr)?mdc800->out_count-mdc800->out_ptr:left;
Greg Kroah-Hartman
maintainerPATCH 218/481 usb: image: mdc800: kill download URB on timeout
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ziyi Guo <[email protected]>
commit 1be3b77de4eb89af8ae2fd6610546be778e25589 upstream.
mdc800_device_read() submits download_urb and waits for completion. If the timeout fires and the device has not responded, the function returns without killing the URB, leaving it active.
A subsequent read() resubmits the same URB while it is still in-flight, triggering the WARN in usb_submit_urb():
"URB submitted while active"
Check the return value of wait_event_timeout() and kill the URB if it indicates timeout, ensuring the URB is complete before its status is inspected or the URB is resubmitted.
Similar to
- commit 372c93131998 ("USB: yurex: fix control-URB timeout handling")
- commit b98d5000c505 ("media: rc: iguanair: handle timeouts")
--- drivers/usb/image/mdc800.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/image/mdc800.c +3 -1
@@ -731,9 +731,11 @@ static ssize_t mdc800_device_read (strucmutex_unlock (&mdc800->io_lock);return len-left; } -wait_event_timeout (mdc800->download_wait, + retval =wait_event_timeout (mdc800->download_wait, mdc800->downloaded,msecs_to_jiffies (TO_DOWNLOAD_GET_READY )); +if (!retval) +usb_kill_urb (mdc800->download_urb); mdc800->downloaded =0 ;if (mdc800->download_urb->status !=0 ) {
Greg Kroah-Hartman
maintainerPATCH 219/481 mm/tracing: rss_stat: ensure curr is false from kthread context
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kalesh Singh <[email protected]>
commit 079c24d5690262e83ee476e2a548e416f3237511 upstream.
The rss_stat trace event allows userspace tools, like Perfetto [1], to inspect per-process RSS metric changes over time.
The curr field was introduced to rss_stat in commit e4dcad204d3a ("rss_stat: add support to detect RSS updates of external mm"). Its intent is to indicate whether the RSS update is for the mm_struct of the current execution context; and is set to false when operating on a remote mm_struct (e.g., via kswapd or a direct reclaimer).
However, an issue arises when a kernel thread temporarily adopts a user process's mm_struct. Kernel threads do not have their own mm_struct and normally have current->mm set to NULL. To operate on user memory, they can "borrow" a memory context using kthread_use_mm(), which sets current->mm to the user process's mm.
This can be observed, for example, in the USB Function Filesystem (FFS) driver. The ffs_user_copy_worker() handles AIO completions and uses kthread_use_mm() to copy data to a user-space buffer. If a page fault occurs during this copy, the fault handler executes in the kthread's context.
At this point, current is the kthread, but current->mm points to the user process's mm. Since the rss_stat event (from the page fault) is for that same mm, the condition current->mm == mm becomes true, causing curr to be incorrectly set to true when the trace event is emitted.
This is misleading because it suggests the mm belongs to the kthread, confusing userspace tools that track per-process RSS changes and corrupting their mm_id-to-process association.
Fix this by ensuring curr is always false when the trace event is emitted from a kthread context by checking for the PF_KTHREAD flag.
--- include/trace/events/kmem.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
include/trace/events/kmem.h +7 -1
@@ -360,7 +360,13 @@ TRACE_EVENT(rss_stat,TP_fast_assign ( __entry->mm_id = mm_ptr_to_hash(mm); - __entry->curr = !!(current->mm == mm); +/* +* curr is true if the mm matches the current task's mm_struct. +* Since kthreads (PF_KTHREAD) have no mm_struct of their own +* but can borrow one via kthread_use_mm(), we must filter them +* out to avoid incorrectly attributing the RSS update to them. +*/ + __entry->curr = current->mm == mm && !(current->flags &PF_KTHREAD ); __entry->member = member; __entry->size = (count <<PAGE_SHIFT ); ),
Greg Kroah-Hartman
maintainerPATCH 220/481 mmc: mmci: Fix device_node reference leak in of_get_dml_pipe_index()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
commit af12e64ae0661546e8b4f5d30d55c5f53a11efe7 upstream.
When calling of_parse_phandle_with_args(), the caller is responsible to call of_node_put() to release the reference of device node. In of_get_dml_pipe_index(), it does not release the reference.
--- drivers/mmc/host/mmci_qcom_dml.c | 1 + 1 file changed, 1 insertion(+)
drivers/mmc/host/mmci_qcom_dml.c +1 -0
@@ -109,6 +109,7 @@ static int of_get_dml_pipe_index(struct &dma_spec))return -ENODEV ; +of_node_put (dma_spec.np);if (dma_spec.args_count)return dma_spec.args[0 ];
Greg Kroah-Hartman
maintainerPATCH 221/481 mmc: core: Avoid bitfield RMW for claim/retune flags
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Penghe Geng <[email protected]>
commit 901084c51a0a8fb42a3f37d2e9c62083c495f824 upstream.
Move claimed and retune control flags out of the bitfield word to avoid unrelated RMW side effects in asynchronous contexts.
The host->claimed bit shared a word with retune flags. Writes to claimed in __mmc_claim_host() or retune_now in mmc_mq_queue_rq() can overwrite other bits when concurrent updates happen in other contexts, triggering spurious WARN_ON(!host->claimed). Convert claimed, can_retune, retune_now and retune_paused to bool to remove shared-word coupling.
--- include/linux/mmc/host.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
include/linux/mmc/host.h +5 -4
@@ -440,14 +440,12 @@ struct mmc_host {struct mmc_ios ios;/* current io bus settings */ +bool claimed;/* host exclusively claimed */ +/* group bitfields together to minimize padding */ unsigned int use_spi_crc:1; - unsigned int claimed:1; /* host exclusively claimed */ unsigned int doing_init_tune:1; /* initial tuning in progress */ - unsigned int can_retune:1; /* re-tuning can be used */ unsigned int doing_retune:1; /* re-tuning in progress */ - unsigned int retune_now:1; /* do re-tuning at next req */ - unsigned int retune_paused:1; /* re-tuning is temporarily disabled */ unsigned int retune_crc_disable:1; /* don't trigger retune upon crc */ unsigned int can_dma_map_merge:1; /* merging can be used */ unsigned int vqmmc_enabled:1; /* vqmmc regulator is enabled */
@@ -455,6 +453,9 @@ struct mmc_host {int rescan_disable;/* disable card detection */ int rescan_entered;/* used with nonremovable devices */ +bool can_retune;/* re-tuning can be used */ +bool retune_now;/* do re-tuning at next req */ +bool retune_paused;/* re-tuning is temporarily disabled */ int need_retune;/* re-tuning is needed */ int hold_retune;/* hold off re-tuning */ unsigned int retune_period;/* re-tuning period in secs */
Greg Kroah-Hartman
maintainerPATCH 222/481 tipc: fix divide-by-zero in tipc_sk_filter_connect()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mehul Rao <[email protected]>
commit 6c5a9baa15de240e747263aba435a0951da8d8d2 upstream.
A user can set conn_timeout to any value via setsockopt(TIPC_CONN_TIMEOUT), including values less than 4. When a SYN is rejected with TIPC_ERR_OVERLOAD and the retry path in tipc_sk_filter_connect() executes:
delay %= (tsk->conn_timeout / 4);
If conn_timeout is in the range [0, 3], the integer division yields 0, and the modulo operation triggers a divide-by-zero exception, causing a kernel oops/panic.
Fix this by clamping conn_timeout to a minimum of 4 at the point of use in tipc_sk_filter_connect().
Oops: divide error: 0000 [#1] SMP KASAN NOPTI CPU: 0 UID: 0 PID: 119 Comm: poc-F144 Not tainted 7.0.0-rc2+ RIP: 0010:tipc_sk_filter_rcv (net/tipc/socket.c:2236 net/tipc/socket.c:2362) Call Trace: tipc_sk_backlog_rcv (include/linux/instrumented.h:82 include/linux/atomic/atomic-instrumented.h:32 include/net/sock.h:2357 net/tipc/socket.c:2406) __release_sock (include/net/sock.h:1185 net/core/sock.c:3213) release_sock (net/core/sock.c:3797) tipc_connect (net/tipc/socket.c:2570) __sys_connect (include/linux/file.h:62 include/linux/file.h:83 net/socket.c:2098)
--- net/tipc/socket.c | 2 ++ 1 file changed, 2 insertions(+)
net/tipc/socket.c +2 -0
@@ -2235,6 +2235,8 @@ static bool tipc_sk_filter_connect(strucif (skb_queue_empty (&sk->sk_write_queue))break ;get_random_bytes (&delay,2 ); +if (tsk->conn_timeout <4 ) + tsk->conn_timeout =4 ; delay %= (tsk->conn_timeout /4 ); delay =msecs_to_jiffies (delay +100 );sk_reset_timer (sk, &sk->sk_timer, jiffies + delay);
Greg Kroah-Hartman
maintainerPATCH 223/481 libceph: Fix potential out-of-bounds access in ceph_handle_auth_reply()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raphael Zimmer <[email protected]>
commit b282c43ed156ae15ea76748fc15cd5c39dc9ab72 upstream.
This patch fixes an out-of-bounds access in ceph_handle_auth_reply() that can be triggered by a message of type CEPH_MSG_AUTH_REPLY. In ceph_handle_auth_reply(), the value of the payload_len field of such a message is stored in a variable of type int. A value greater than INT_MAX leads to an integer overflow and is interpreted as a negative value. This leads to decrementing the pointer address by this value and subsequently accessing it because ceph_decode_need() only checks that the memory access does not exceed the end address of the allocation.
This patch fixes the issue by changing the data type of payload_len to u32. Additionally, the data type of result_msg_len is changed to u32, as it is also a variable holding a non-negative length.
Also, an additional layer of sanity checks is introduced, ensuring that directly after reading it from the message, payload_len and result_msg_len are not greater than the overall segment length.
BUG: KASAN: slab-out-of-bounds in ceph_handle_auth_reply+0x642/0x7a0 [libceph] Read of size 4 at addr ffff88811404df14 by task kworker/20:1/262 CPU: 20 UID: 0 PID: 262 Comm: kworker/20:1 Not tainted 6.19.2 #5 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Workqueue: ceph-msgr ceph_con_workfn [libceph] Call Trace: <TASK> dump_stack_lvl+0x76/0xa0 print_report+0xd1/0x620 ? __pfx__raw_spin_lock_irqsave+0x10/0x10 ? kasan_complete_mode_report_info+0x72/0x210 kasan_report+0xe7/0x130 ? ceph_handle_auth_reply+0x642/0x7a0 [libceph] ? ceph_handle_auth_reply+0x642/0x7a0 [libceph] __asan_report_load_n_noabort+0xf/0x20 ceph_handle_auth_reply+0x642/0x7a0 [libceph] mon_dispatch+0x973/0x23d0 [libceph] ? apparmor_socket_recvmsg+0x6b/0xa0 ? __pfx_mon_dispatch+0x10/0x10 [libceph] ? __kasan_check_write+0x14/0x30i ? mutex_unlock+0x7f/0xd0 ? __pfx_mutex_unlock+0x10/0x10 ? __pfx_do_recvmsg+0x10/0x10 [libceph] ceph_con_process_message+0x1f1/0x650 [libceph] process_message+0x1e/0x450 [libceph] ceph_con_v2_try_read+0x2e48/0x6c80 [libceph] ? __pfx_ceph_con_v2_try_read+0x10/0x10 [libceph] ? save_fpregs_to_fpstate+0xb0/0x230 ? raw_spin_rq_unlock+0x17/0xa0 ? finish_task_switch.isra.0+0x13b/0x760 ? __switch_to+0x385/0xda0 ? __kasan_check_write+0x14/0x30 ? mutex_lock+0x8d/0xe0 ? __pfx_mutex_lock+0x10/0x10 ceph_con_workfn+0x248/0x10c0 [libceph] process_one_work+0x629/0xf80 ? __kasan_check_write+0x14/0x30 worker_thread+0x87f/0x1570 ? __pfx__raw_spin_lock_irqsave+0x10/0x10 ? __pfx_try_to_wake_up+0x10/0x10 ? kasan_print_address_stack_frame+0x1f7/0x280 ? __pfx_worker_thread+0x10/0x10 kthread+0x396/0x830 ? __pfx__raw_spin_lock_irq+0x10/0x10 ? __pfx_kthread+0x10/0x10 ? __kasan_check_write+0x14/0x30 ? recalc_sigpending+0x180/0x210 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x3f7/0x610 ? __pfx_ret_from_fork+0x10/0x10 ? __switch_to+0x385/0xda0 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK>
[ idryomov: replace if statements with ceph_decode_need() for
payload_len and result_msg_len ]
--- net/ceph/auth.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/ceph/auth.c +4 -2
@@ -205,9 +205,9 @@ int ceph_handle_auth_reply(struct ceph_as32 result;u64 global_id;void *payload, *payload_end; -int payload_len; +u32 payload_len;char *result_msg; -int result_msg_len; +u32 result_msg_len;int ret = -EINVAL ;mutex_lock (&ac->mutex);
@@ -217,10 +217,12 @@ int ceph_handle_auth_reply(struct ceph_a result =ceph_decode_32 (&p); global_id =ceph_decode_64 (&p); payload_len =ceph_decode_32 (&p); +ceph_decode_need (&p, end, payload_len, bad); payload = p; p += payload_len;ceph_decode_need (&p, end,sizeof (u32), bad); result_msg_len =ceph_decode_32 (&p); +ceph_decode_need (&p, end, result_msg_len, bad); result_msg = p; p += result_msg_len;if (p != end)
Greg Kroah-Hartman
maintainerPATCH 224/481 libceph: reject preamble if control segment is empty
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Dryomov <[email protected]>
commit c4c22b846eceff05b1129b8844a80310e55a7f87 upstream.
While head_onwire_len() has a branch to handle ctrl_len == 0 case, prepare_read_control() always sets up a kvec for the CRC meaning that a non-empty control segment is effectively assumed. All frames that clients deal with meet that assumption, so let's make it official and treat the preamble with an empty control segment as malformed.
--- net/ceph/messenger_v2.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
net/ceph/messenger_v2.c +8 -9
@@ -392,7 +392,7 @@ static int head_onwire_len(int ctrl_len,int head_len;int rem_len; -BUG_ON (ctrl_len <0 || ctrl_len >CEPH_MSG_MAX_CONTROL_LEN ); +BUG_ON (ctrl_len <1 || ctrl_len >CEPH_MSG_MAX_CONTROL_LEN );if (secure) { head_len =CEPH_PREAMBLE_SECURE_LEN ;
@@ -401,9 +401,7 @@ static int head_onwire_len(int ctrl_len, head_len +=padded_len (rem_len) +CEPH_GCM_TAG_LEN ; } }else { - head_len =CEPH_PREAMBLE_PLAIN_LEN ; -if (ctrl_len) - head_len += ctrl_len +CEPH_CRC_LEN ; + head_len =CEPH_PREAMBLE_PLAIN_LEN + ctrl_len +CEPH_CRC_LEN ; }return head_len; }
@@ -528,11 +526,16 @@ static int decode_preamble(void *p, stru desc->fd_aligns[i] =ceph_decode_16 (&p); } -if (desc->fd_lens[0 ] <0 || +/* +* This would fire for FRAME_TAG_WAIT (it has one empty +* segment), but we should never get it as client. +*/ +if (desc->fd_lens[0 ] <1 || desc->fd_lens[0 ] >CEPH_MSG_MAX_CONTROL_LEN ) {pr_err ("bad control segment length %d\n" , desc->fd_lens[0 ]);return -EINVAL ; } +if (desc->fd_lens[1 ] <0 || desc->fd_lens[1 ] >CEPH_MSG_MAX_FRONT_LEN ) {pr_err ("bad front segment length %d\n" , desc->fd_lens[1 ]);
@@ -549,10 +552,6 @@ static int decode_preamble(void *p, strureturn -EINVAL ; } -/* -* This would fire for FRAME_TAG_WAIT (it has one empty -* segment), but we should never get it as client. -*/ if (!desc->fd_lens[desc->fd_seg_cnt -1 ]) {pr_err ("last segment empty, segment count %d\n" , desc->fd_seg_cnt);
Greg Kroah-Hartman
maintainerPATCH 225/481 libceph: prevent potential out-of-bounds reads in process_message_header()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Dryomov <[email protected]>
commit 69fb5d91bba44ecf7eb80530b85fa4fb028921d5 upstream.
If the message frame is (maliciously) corrupted in a way that the length of the control segment ends up being less than the size of the message header or a different frame is made to look like a message frame, out-of-bounds reads may ensue in process_message_header().
Perform an explicit bounds check before decoding the message header.
--- net/ceph/messenger_v2.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
net/ceph/messenger_v2.c +8 -1
@@ -2646,12 +2646,15 @@ static int process_message_header(struct void *p, void *end) { struct ceph_frame_desc *desc = &con->v2.in_desc; -struct ceph_msg_header2 *hdr2 = p; +struct ceph_msg_header2 *hdr2;struct ceph_msg_header hdr;int skip;int ret;u64 seq; +ceph_decode_need (&p, end,sizeof (*hdr2), bad); + hdr2 = p; +/* verify seq# */ seq =le64_to_cpu (hdr2->seq);if ((s64 )seq - (s64 )con->in_seq <1 ) {
@@ -2682,6 +2685,10 @@ static int process_message_header(structWARN_ON (!con->in_msg);WARN_ON (con->in_msg->con != con);return 1 ; + +bad: +pr_err ("failed to decode message header\n" ); +return -EINVAL ; }static int process_message (struct ceph_connection *con)
Greg Kroah-Hartman
maintainerPATCH 226/481 libceph: Use u32 for non-negative values in ceph_monmap_decode()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raphael Zimmer <[email protected]>
commit 770444611f047dbfd4517ec0bc1b179d40c2f346 upstream.
This patch fixes unnecessary implicit conversions that change signedness of blob_len and num_mon in ceph_monmap_decode().
Currently blob_len and num_mon are (signed) int variables. They are used to hold values that are always non-negative and get assigned in ceph_decode_32_safe(), which is meant to assign u32 values. Both variables are subsequently used as unsigned values, and the value of num_mon is further assigned to monmap->num_mon, which is of type u32. Therefore, both variables should be of type u32. This is especially relevant for num_mon. If the value read from the incoming message is very large, it is interpreted as a negative value, and the check for num_mon > CEPH_MAX_MON does not catch it. This leads to the attempt to allocate a very large chunk of memory for monmap, which will most likely fail. In this case, an unnecessary attempt to allocate memory is performed, and -ENOMEM is returned instead of -EINVAL.
--- net/ceph/mon_client.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/ceph/mon_client.c +3 -3
@@ -72,8 +72,8 @@ static struct ceph_monmap *ceph_monmap_dstruct ceph_monmap *monmap =NULL ;struct ceph_fsid fsid;u32 struct_len; -int blob_len; -int num_mon; +u32 blob_len; +u32 num_mon;u8 struct_v;u32 epoch;int ret;
@@ -112,7 +112,7 @@ static struct ceph_monmap *ceph_monmap_d }ceph_decode_32_safe (p, end, num_mon, e_inval); -dout ("%s fsid %pU epoch %u num_mon %d\n" , __func__, &fsid, epoch, +dout ("%s fsid %pU epoch %u num_mon %u\n" , __func__, &fsid, epoch, num_mon);if (num_mon >CEPH_MAX_MON ) goto e_inval;
Greg Kroah-Hartman
maintainerPATCH 227/481 libceph: admit message frames only in CEPH_CON_S_OPEN state
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Dryomov <[email protected]>
commit a5a373705081d7cc6363e16990e2361b0b362314 upstream.
Similar checks are performed for all control frames, but an early check for message frames was missing. process_message() is already set up to terminate the loop in case the state changes while con->ops->dispatch() handler is being executed.
--- net/ceph/messenger_v2.c | 5 +++++ 1 file changed, 5 insertions(+)
net/ceph/messenger_v2.c +5 -0
@@ -2718,6 +2718,11 @@ static int __handle_control(struct ceph_if (con->v2.in_desc.fd_tag !=FRAME_TAG_MESSAGE )return process_control (con, p, end); +if (con->state !=CEPH_CON_S_OPEN ) { + con->error_msg ="protocol error, unexpected message" ; +return -EINVAL ; + } + ret =process_message_header (con, p, end);if (ret <0 )return ret;
Greg Kroah-Hartman
maintainerPATCH 228/481 ceph: fix i_nlink underrun during async unlink
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Max Kellermann <[email protected]>
commit ce0123cbb4a40a2f1bbb815f292b26e96088639f upstream.
During async unlink, we drop the i_nlink counter before we receive the completion (that will eventually update the i_nlink) because "we assume that the unlink will succeed". That is not a bad idea, but it races against deletions by other clients (or against the completion of our own unlink) and can lead to an underrun which emits a WARNING like this one:
WARNING: CPU: 85 PID: 25093 at fs/inode.c:407 drop_nlink+0x50/0x68 Modules linked in: CPU: 85 UID: 3221252029 PID: 25093 Comm: php-cgi8.1 Not tainted 6.14.11-cm4all1-ampere #655 Hardware name: Supermicro ARS-110M-NR/R12SPD-A, BIOS 1.1b 10/17/2023 pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : drop_nlink+0x50/0x68 lr : ceph_unlink+0x6c4/0x720 sp : ffff80012173bc90 x29: ffff80012173bc90 x28: ffff086d0a45aaf8 x27: ffff0871d0eb5680 x26: ffff087f2a64a718 x25: 0000020000000180 x24: 0000000061c88647 x23: 0000000000000002 x22: ffff07ff9236d800 x21: 0000000000001203 x20: ffff07ff9237b000 x19: ffff088b8296afc0 x18: 00000000f3c93365 x17: 0000000000070000 x16: ffff08faffcbdfe8 x15: ffff08faffcbdfec x14: 0000000000000000 x13: 45445f65645f3037 x12: 34385f6369706f74 x11: 0000a2653104bb20 x10: ffffd85f26d73290 x9 : ffffd85f25664f94 x8 : 00000000000000c0 x7 : 0000000000000000 x6 : 0000000000000002 x5 : 0000000000000081 x4 : 0000000000000481 x3 : 0000000000000000 x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff08727d3f91e8 Call trace: drop_nlink+0x50/0x68 (P) vfs_unlink+0xb0/0x2e8 do_unlinkat+0x204/0x288 __arm64_sys_unlinkat+0x3c/0x80 invoke_syscall.constprop.0+0x54/0xe8 do_el0_svc+0xa4/0xc8 el0_svc+0x18/0x58 el0t_64_sync_handler+0x104/0x130 el0t_64_sync+0x154/0x158
In ceph_unlink(), a call to ceph_mdsc_submit_request() submits the CEPH_MDS_OP_UNLINK to the MDS, but does not wait for completion.
Meanwhile, between this call and the following drop_nlink() call, a worker thread may process a CEPH_CAP_OP_IMPORT, CEPH_CAP_OP_GRANT or just a CEPH_MSG_CLIENT_REPLY (the latter of which could be our own completion). These will lead to a set_nlink() call, updating the i_nlink counter to the value received from the MDS. If that new i_nlink value happens to be zero, it is illegal to decrement it further. But that is exactly what ceph_unlink() will do then.
The WARNING can be reproduced this way:
1. Force async unlink; only the async code path is affected. Having no real clue about Ceph internals, I was unable to find out why the MDS wouldn't give me the "Fxr" capabilities, so I patched get_caps_for_async_unlink() to always succeed.
(Note that the WARNING dump above was found on an unpatched kernel, without this kludge - this is not a theoretical bug.)
2. Add a sleep call after ceph_mdsc_submit_request() so the unlink completion gets handled by a worker thread before drop_nlink() is called. This guarantees that the i_nlink is already zero before drop_nlink() runs.
The solution is to skip the counter decrement when it is already zero, but doing so without a lock is still racy (TOCTOU). Since ceph_fill_inode() and handle_cap_grant() both hold the ceph_inode_info.i_ceph_lock spinlock while set_nlink() runs, this seems like the proper lock to protect the i_nlink updates.
I found prior art in NFS and SMB (using inode.i_lock) and AFS (using afs_vnode.cb_lock). All three have the zero check as well.
--- fs/ceph/dir.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
fs/ceph/dir.c +14 -1
@@ -1183,6 +1183,7 @@ static int ceph_unlink(struct inode *dirstruct ceph_fs_client *fsc =ceph_sb_to_client (dir->i_sb);struct ceph_mds_client *mdsc = fsc->mdsc;struct inode *inode =d_inode (dentry); +struct ceph_inode_info *ci =ceph_inode (inode);struct ceph_mds_request *req;bool try_async =ceph_test_mount_opt (fsc,ASYNC_DIROPS );int err = -EROFS ;
@@ -1240,7 +1241,19 @@ retry:* We have enough caps, so we assume that the unlink * will succeed. Fix up the target inode and dcache. */ -drop_nlink (inode); + +/* +* Protect the i_nlink update with i_ceph_lock +* to precent racing against ceph_fill_inode() +* handling our completion on a worker thread +* and don't decrement if i_nlink has already +* been updated to zero by this completion. +*/ +spin_lock (&ci->i_ceph_lock); +if (inode->i_nlink >0 ) +drop_nlink (inode); +spin_unlock (&ci->i_ceph_lock); +d_delete (dentry); }else {spin_lock (&fsc->async_unlink_conflict_lock);
Greg Kroah-Hartman
maintainerPATCH 229/481 time: add kernel-doc in time.c
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randy Dunlap <[email protected]>
[ Upstream commit 67b3f564cb1e769ef8e45835129a4866152fcfdb ]
Add kernel-doc for all APIs that do not already have it.
Stable-dep-of: 755a648e78f1 ("time/jiffies: Mark jiffies_64_to_clock_t() notrace")
--- kernel/time/time.c | 169 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 158 insertions(+), 11 deletions(-)
kernel/time/time.c +158 -11
@@ -365,11 +365,14 @@ SYSCALL_DEFINE1(adjtimex_time32, struct old_timex32 __user *, utp) }#endif -/* -* Convert jiffies to milliseconds and back. +/** +* jiffies_to_msecs - Convert jiffies to milliseconds +* @j: jiffies value * * Avoid unnecessary multiplications/divisions in the -* two most common HZ cases: +* two most common HZ cases. +* +* Return: milliseconds value */ unsigned int jiffies_to_msecs (const unsigned long j) {
@@ -388,6 +391,12 @@ unsigned int jiffies_to_msecs(const unsigned long j) }EXPORT_SYMBOL (jiffies_to_msecs); +/** +* jiffies_to_usecs - Convert jiffies to microseconds +* @j: jiffies value +* +* Return: microseconds value +*/ unsigned int jiffies_to_usecs (const unsigned long j) {/*
@@ -408,8 +417,15 @@ unsigned int jiffies_to_usecs(const unsigned long j) }EXPORT_SYMBOL (jiffies_to_usecs); -/* +/** * mktime64 - Converts date to seconds. +* @year0: year to convert +* @mon0: month to convert +* @day: day to convert +* @hour: hour to convert +* @min: minute to convert +* @sec: second to convert +* * Converts Gregorian date to seconds since 1970-01-01 00:00:00. * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
@@ -427,6 +443,8 @@ EXPORT_SYMBOL(jiffies_to_usecs);* * An encoding of midnight at the end of the day as 24:00:00 - ie. midnight * tomorrow - (allowable under ISO 8601) is supported. +* +* Return: seconds since the epoch time for the given input date */ time64_t mktime64(const unsigned int year0, const unsigned int mon0, const unsigned int day, const unsigned int hour,
@@ -471,8 +489,7 @@ EXPORT_SYMBOL(ns_to_kernel_old_timeval);* Set seconds and nanoseconds field of a timespec variable and * normalize to the timespec storage format * -* Note: The tv_nsec part is always in the range of -* 0 <= tv_nsec < NSEC_PER_SEC +* Note: The tv_nsec part is always in the range of 0 <= tv_nsec < NSEC_PER_SEC. * For negative values only the tv_sec field is negative ! */ void set_normalized_timespec64 (struct timespec64 *ts,time64_t sec,s64 nsec)
@@ -501,7 +518,7 @@ EXPORT_SYMBOL(set_normalized_timespec64);* ns_to_timespec64 - Convert nanoseconds to timespec64 * @nsec: the nanoseconds value to be converted * -* Returns the timespec64 representation of the nsec parameter. +* Return: the timespec64 representation of the nsec parameter. */ struct timespec64 ns_to_timespec64 (s64 nsec) {
@@ -548,6 +565,8 @@ EXPORT_SYMBOL(ns_to_timespec64);* runtime. * the _msecs_to_jiffies helpers are the HZ dependent conversion * routines found in include/linux/jiffies.h +* +* Return: jiffies value */ unsigned long __msecs_to_jiffies (const unsigned int m) {
@@ -560,6 +579,12 @@ unsigned long __msecs_to_jiffies(const unsigned int m) }EXPORT_SYMBOL (__msecs_to_jiffies); +/** +* __usecs_to_jiffies: - convert microseconds to jiffies +* @u: time in milliseconds +* +* Return: jiffies value +*/ unsigned long __usecs_to_jiffies (const unsigned int u) {if (u >jiffies_to_usecs (MAX_JIFFY_OFFSET ))
@@ -568,7 +593,10 @@ unsigned long __usecs_to_jiffies(const unsigned int u) }EXPORT_SYMBOL (__usecs_to_jiffies); -/* +/** +* timespec64_to_jiffies - convert a timespec64 value to jiffies +* @value: pointer to &struct timespec64 +* * The TICK_NSEC - 1 rounds up the value to the next resolution. Note * that a remainder subtract here would not do the right thing as the * resolution values don't fall on second boundaries. I.e. the line:
@@ -582,8 +610,9 @@ EXPORT_SYMBOL(__usecs_to_jiffies);* * The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec * value to a scaled second value. +* +* Return: jiffies value */ -unsigned long timespec64_to_jiffies (const struct timespec64 *value) {
@@ -601,6 +630,11 @@ timespec64_to_jiffies(const struct timespec64 *value) }EXPORT_SYMBOL (timespec64_to_jiffies); +/** +* jiffies_to_timespec64 - convert jiffies value to &struct timespec64 +* @jiffies: jiffies value +* @value: pointer to &struct timespec64 +*/ void jiffies_to_timespec64 (const unsigned long jiffies,struct timespec64 *value) {
@@ -618,6 +652,13 @@ EXPORT_SYMBOL(jiffies_to_timespec64);/* * Convert jiffies/jiffies_64 to clock_t and back. */ + +/** +* jiffies_to_clock_t - Convert jiffies to clock_t +* @x: jiffies value +* +* Return: jiffies converted to clock_t (CLOCKS_PER_SEC) +*/ clock_t jiffies_to_clock_t (unsigned long x) {#if (TICK_NSEC % (NSEC_PER_SEC /USER_HZ )) ==0
@@ -632,6 +673,12 @@ clock_t jiffies_to_clock_t(unsigned long x) }EXPORT_SYMBOL (jiffies_to_clock_t); +/** +* clock_t_to_jiffies - Convert clock_t to jiffies +* @x: clock_t value +* +* Return: clock_t value converted to jiffies +*/ unsigned long clock_t_to_jiffies (unsigned long x) {#if (HZ %USER_HZ )==0
@@ -649,6 +696,12 @@ unsigned long clock_t_to_jiffies(unsigned long x) }EXPORT_SYMBOL (clock_t_to_jiffies); +/** +* jiffies_64_to_clock_t - Convert jiffies_64 to clock_t +* @x: jiffies_64 value +* +* Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) +*/ u64 jiffies_64_to_clock_t (u64 x) {#if (TICK_NSEC % (NSEC_PER_SEC /USER_HZ )) ==0
@@ -671,6 +724,12 @@ u64 jiffies_64_to_clock_t(u64 x) }EXPORT_SYMBOL (jiffies_64_to_clock_t); +/** +* nsec_to_clock_t - Convert nsec value to clock_t +* @x: nsec value +* +* Return: nsec value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) +*/ u64 nsec_to_clock_t (u64 x) {#if (NSEC_PER_SEC %USER_HZ ) ==0
@@ -687,6 +746,12 @@ u64 nsec_to_clock_t(u64 x)#endif } +/** +* jiffies64_to_nsecs - Convert jiffies64 to nanoseconds +* @j: jiffies64 value +* +* Return: nanoseconds value +*/ u64 jiffies64_to_nsecs (u64 j) {#if !(NSEC_PER_SEC %HZ )
@@ -697,6 +762,12 @@ u64 jiffies64_to_nsecs(u64 j) }EXPORT_SYMBOL (jiffies64_to_nsecs); +/** +* jiffies64_to_msecs - Convert jiffies64 to milliseconds +* @j: jiffies64 value +* +* Return: milliseconds value +*/ u64 jiffies64_to_msecs (const u64 j) {#if HZ <=MSEC_PER_SEC && !(MSEC_PER_SEC %HZ )
@@ -719,6 +790,8 @@ EXPORT_SYMBOL(jiffies64_to_msecs);* note: * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512) * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years +* +* Return: nsecs converted to jiffies64 value */ u64 nsecs_to_jiffies64 (u64 n) {
@@ -750,6 +823,8 @@ EXPORT_SYMBOL(nsecs_to_jiffies64);* note: * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512) * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years +* +* Return: nsecs converted to jiffies value */ unsigned long nsecs_to_jiffies (u64 n) {
@@ -757,10 +832,16 @@ unsigned long nsecs_to_jiffies(u64 n) }EXPORT_SYMBOL_GPL (nsecs_to_jiffies); -/* -* Add two timespec64 values and do a safety check for overflow. +/** +* timespec64_add_safe - Add two timespec64 values and do a safety check +* for overflow. +* @lhs: first (left) timespec64 to add +* @rhs: second (right) timespec64 to add +* * It's assumed that both values are valid (>= 0). * And, each timespec64 is in normalized form. +* +* Return: sum of @lhs + @rhs */ struct timespec64 timespec64_add_safe (const struct timespec64 lhs,const struct timespec64 rhs)
@@ -778,6 +859,15 @@ struct timespec64 timespec64_add_safe(const struct timespec64 lhs,return res; } +/** +* get_timespec64 - get user's time value into kernel space +* @ts: destination &struct timespec64 +* @uts: user's time value as &struct __kernel_timespec +* +* Handles compat or 32-bit modes. +* +* Return: %0 on success or negative errno on error +*/ int get_timespec64 (struct timespec64 *ts,const struct __kernel_timespec __user *uts) {
@@ -801,6 +891,14 @@ int get_timespec64(struct timespec64 *ts, }EXPORT_SYMBOL_GPL (get_timespec64); +/** +* put_timespec64 - convert timespec64 value to __kernel_timespec format and +* copy the latter to userspace +* @ts: input &struct timespec64 +* @uts: user's &struct __kernel_timespec +* +* Return: %0 on success or negative errno on error +*/ int put_timespec64 (const struct timespec64 *ts,struct __kernel_timespec __user *uts) {
@@ -839,6 +937,15 @@ static int __put_old_timespec32(const struct timespec64 *ts64,return copy_to_user (cts, &ts,sizeof (ts)) ? -EFAULT :0 ; } +/** +* get_old_timespec32 - get user's old-format time value into kernel space +* @ts: destination &struct timespec64 +* @uts: user's old-format time value (&struct old_timespec32) +* +* Handles X86_X32_ABI compatibility conversion. +* +* Return: %0 on success or negative errno on error +*/ int get_old_timespec32 (struct timespec64 *ts,const void __user *uts) {if (COMPAT_USE_64BIT_TIME )
@@ -848,6 +955,16 @@ int get_old_timespec32(struct timespec64 *ts, const void __user *uts) }EXPORT_SYMBOL_GPL (get_old_timespec32); +/** +* put_old_timespec32 - convert timespec64 value to &struct old_timespec32 and +* copy the latter to userspace +* @ts: input &struct timespec64 +* @uts: user's &struct old_timespec32 +* +* Handles X86_X32_ABI compatibility conversion. +* +* Return: %0 on success or negative errno on error +*/ int put_old_timespec32 (const struct timespec64 *ts,void __user *uts) {if (COMPAT_USE_64BIT_TIME )
@@ -857,6 +974,13 @@ int put_old_timespec32(const struct timespec64 *ts, void __user *uts) }EXPORT_SYMBOL_GPL (put_old_timespec32); +/** +* get_itimerspec64 - get user's &struct __kernel_itimerspec into kernel space +* @it: destination &struct itimerspec64 +* @uit: user's &struct __kernel_itimerspec +* +* Return: %0 on success or negative errno on error +*/ int get_itimerspec64 (struct itimerspec64 *it,const struct __kernel_itimerspec __user *uit) {
@@ -872,6 +996,14 @@ int get_itimerspec64(struct itimerspec64 *it, }EXPORT_SYMBOL_GPL (get_itimerspec64); +/** +* put_itimerspec64 - convert &struct itimerspec64 to __kernel_itimerspec format +* and copy the latter to userspace +* @it: input &struct itimerspec64 +* @uit: user's &struct __kernel_itimerspec +* +* Return: %0 on success or negative errno on error +*/ int put_itimerspec64 (const struct itimerspec64 *it,struct __kernel_itimerspec __user *uit) {
@@ -887,6 +1019,13 @@ int put_itimerspec64(const struct itimerspec64 *it, }EXPORT_SYMBOL_GPL (put_itimerspec64); +/** +* get_old_itimerspec32 - get user's &struct old_itimerspec32 into kernel space +* @its: destination &struct itimerspec64 +* @uits: user's &struct old_itimerspec32 +* +* Return: %0 on success or negative errno on error +*/ int get_old_itimerspec32 (struct itimerspec64 *its,const struct old_itimerspec32 __user *uits) {
@@ -898,6 +1037,14 @@ int get_old_itimerspec32(struct itimerspec64 *its, }EXPORT_SYMBOL_GPL (get_old_itimerspec32); +/** +* put_old_itimerspec32 - convert &struct itimerspec64 to &struct +* old_itimerspec32 and copy the latter to userspace +* @its: input &struct itimerspec64 +* @uits: user's &struct old_itimerspec32 +* +* Return: %0 on success or negative errno on error +*/ int put_old_itimerspec32 (const struct itimerspec64 *its,struct old_itimerspec32 __user *uits) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 230/481 time/jiffies: Mark jiffies_64_to_clock_t() notrace
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
[ Upstream commit 755a648e78f12574482d4698d877375793867fa1 ]
The trace_clock_jiffies() function that handles the "uptime" clock for tracing calls jiffies_64_to_clock_t(). This causes the function tracer to constantly recurse when the tracing clock is set to "uptime". Mark it notrace to prevent unnecessary recursion when using the "uptime" clock.
--- kernel/time/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/time/time.c +1 -1
@@ -702,7 +702,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies);* * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) */ -u64 jiffies_64_to_clock_t (u64 x) +notrace u64 jiffies_64_to_clock_t(u64 x) {#if (TICK_NSEC % (NSEC_PER_SEC /USER_HZ )) ==0 # if HZ <USER_HZ
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 231/481 drm/bridge: ti-sn65dsi86: Enable HPD polling if IRQ is not used
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Franz Schnyder <[email protected]>
commit 0b87d51690dd5131cbe9fbd23746b037aab89815 upstream.
Fallback to polling to detect hotplug events on systems without interrupts.
On systems where the interrupt line of the bridge is not connected, the bridge cannot notify hotplug events. Only add the DRM_BRIDGE_OP_HPD flag if an interrupt has been registered otherwise remain in polling mode.
--- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/drm/bridge/ti-sn65dsi86.c +4 -2
@@ -1307,6 +1307,7 @@ static int ti_sn_bridge_probe(struct aux {struct ti_sn65dsi86 *pdata =dev_get_drvdata (adev->dev.parent);struct device_node *np = pdata->dev->of_node; +const struct i2c_client *client =to_i2c_client (pdata->dev);int ret; pdata->next_bridge =devm_drm_of_get_bridge (&adev->dev, np,1 ,0 );
@@ -1326,8 +1327,9 @@ static int ti_sn_bridge_probe(struct aux ? DRM_MODE_CONNECTOR_DisplayPort : DRM_MODE_CONNECTOR_eDP;if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) { - pdata->bridge.ops =DRM_BRIDGE_OP_EDID |DRM_BRIDGE_OP_DETECT | -DRM_BRIDGE_OP_HPD ; + pdata->bridge.ops =DRM_BRIDGE_OP_EDID |DRM_BRIDGE_OP_DETECT ; +if (client->irq) + pdata->bridge.ops |=DRM_BRIDGE_OP_HPD ;/* * If comms were already enabled they would have been enabled * with the wrong value of HPD_DISABLE. Update it now. Comms
Greg Kroah-Hartman
maintainerPATCH 232/481 device property: Allow secondary lookup in fwnode_get_next_child_node()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
commit 2692c614f8f05929d692b3dbfd3faef1f00fbaf0 upstream.
When device_get_child_node_count() got split to the fwnode and device respective APIs, the fwnode didn't inherit the ability to traverse over the secondary fwnode. Hence any user, that switches from device to fwnode API misses this feature. In particular, this was revealed by the commit 1490cbb9dbfd ("device property: Split fwnode_get_child_node_count()") that effectively broke the GPIO enumeration on Intel Galileo boards. Fix this by moving the secondary lookup from device to fwnode API.
Note, in general no device_*() API should go into the depth of the fwnode implementation.
--- drivers/base/property.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-)
drivers/base/property.c +13 -14
@@ -749,7 +749,18 @@ struct fwnode_handle * fwnode_get_next_child_node(const struct fwnode_handle *fwnode, struct fwnode_handle *child) { - return fwnode_call_ptr_op(fwnode, get_next_child_node, child); + struct fwnode_handle *next; + +if (IS_ERR_OR_NULL (fwnode)) +return NULL ; + +/* Try to find a child in primary fwnode */ + next =fwnode_call_ptr_op (fwnode, get_next_child_node, child); +if (next) +return next; + +/* When no more children in primary, continue with secondary */ +return fwnode_call_ptr_op (fwnode->secondary, get_next_child_node, child); }EXPORT_SYMBOL_GPL (fwnode_get_next_child_node);
@@ -793,19 +804,7 @@ EXPORT_SYMBOL_GPL(fwnode_get_next_availastruct fwnode_handle *device_get_next_child_node (const struct device *dev,struct fwnode_handle *child) { -const struct fwnode_handle *fwnode =dev_fwnode (dev); -struct fwnode_handle *next; - -if (IS_ERR_OR_NULL (fwnode)) -return NULL ; - -/* Try to find a child in primary fwnode */ - next =fwnode_get_next_child_node (fwnode, child); -if (next) -return next; - -/* When no more children in primary, continue with secondary */ -return fwnode_get_next_child_node (fwnode->secondary, child); +return fwnode_get_next_child_node (dev_fwnode (dev), child); }EXPORT_SYMBOL_GPL (device_get_next_child_node);
Greg Kroah-Hartman
maintainerPATCH 233/481 irqchip/gic-v3-its: Limit number of per-device MSIs to the range the ITS supports
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier <[email protected]>
commit ce9e40a9a5e5cff0b1b0d2fa582b3d71a8ce68e8 upstream.
The ITS driver blindly assumes that EventIDs are in abundant supply, to the point where it never checks how many the hardware actually supports.
It turns out that some pretty esoteric integrations make it so that only a few bits are available, all the way down to a single bit.
Enforce the advertised limitation at the point of allocating the device structure, and hope that the endpoint driver can deal with such limitation.
--- drivers/irqchip/irq-gic-v3-its.c | 4 ++++ include/linux/irqchip/arm-gic-v3.h | 1 + 2 files changed, 5 insertions(+)
drivers/irqchip/irq-gic-v3-its.c +4 -0
@@ -3382,6 +3382,7 @@ static struct its_device *its_create_devint lpi_base;int nr_lpis;int nr_ites; +int id_bits;int sz;if (!its_alloc_device_table (its, dev_id))
@@ -3394,7 +3395,10 @@ static struct its_device *its_create_dev/* * Even if the device wants a single LPI, the ITT must be * sized as a power of two (and you need at least one bit...). +* Also honor the ITS's own EID limit. */ + id_bits =FIELD_GET (GITS_TYPER_IDBITS , its->typer) +1 ; + nvecs = min_t(unsigned int, nvecs, BIT(id_bits)); nr_ites =max (2 , nvecs); sz = nr_ites * (FIELD_GET (GITS_TYPER_ITT_ENTRY_SIZE , its->typer) +1 ); sz =max (sz,ITS_ITT_ALIGN ) +ITS_ITT_ALIGN -1 ;
include/linux/irqchip/arm-gic-v3.h +1 -0
@@ -394,6 +394,7 @@#define GITS_TYPER_VLPIS (1UL << 1)#define GITS_TYPER_ITT_ENTRY_SIZE_SHIFT 4#define GITS_TYPER_ITT_ENTRY_SIZE GENMASK_ULL(7, 4) +#define GITS_TYPER_IDBITS GENMASK_ULL(12, 8)#define GITS_TYPER_IDBITS_SHIFT 8#define GITS_TYPER_DEVBITS_SHIFT 13#define GITS_TYPER_DEVBITS GENMASK_ULL(17, 13)
Greg Kroah-Hartman
maintainerPATCH 234/481 ixgbevf: fix link setup issue
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jedrzej Jagielski <[email protected]>
commit feae40a6a178bb525a15f19288016e5778102a99 upstream.
It may happen that VF spawned for E610 adapter has problem with setting link up. This happens when ixgbevf supporting mailbox API 1.6 cooperates with PF driver which doesn't support this version of API, and hence doesn't support new approach for getting PF link data.
In that case VF asks PF to provide link data but as PF doesn't support it, returns -EOPNOTSUPP what leads to early bail from link configuration sequence.
Avoid such situation by using legacy VFLINKS approach whenever negotiated API version is less than 1.6.
To reproduce the issue just create VF and set its link up - adapter must be any from the E610 family, ixgbevf must support API 1.6 or higher while ixgbevf must not.
--- drivers/net/ethernet/intel/ixgbevf/vf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/ixgbevf/vf.c +2 -1
@@ -852,7 +852,8 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw,if (!mac->get_link_status) goto out; -if (hw->mac.type == ixgbe_mac_e610_vf) { +if (hw->mac.type == ixgbe_mac_e610_vf && + hw->api_version >= ixgbe_mbox_api_16) { ret_val =ixgbevf_get_pf_link_state (hw, speed, link_up);if (ret_val) goto out;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 235/481 staging: rtl8723bs: properly validate the data in rtw_get_ie_ex()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Kroah-Hartman <[email protected]>
commit f0109b9d3e1e455429279d602f6276e34689750a upstream.
Just like in commit 154828bf9559 ("staging: rtl8723bs: fix out-of-bounds read in rtw_get_ie() parser"), we don't trust the data in the frame so we should check the length better before acting on it
--- drivers/staging/rtl8723bs/core/rtw_ieee80211.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/staging/rtl8723bs/core/rtw_ieee80211.c +10 -5
@@ -186,20 +186,25 @@ u8 *rtw_get_ie_ex(u8 *in_ie, uint in_len cnt =0 ; -while (cnt < in_len) { +while (cnt +2 <= in_len) { +u8 ie_len = in_ie[cnt +1 ]; + +if (cnt +2 + ie_len > in_len) +break ; +if (eid == in_ie[cnt] - && (!oui || !memcmp (&in_ie[cnt+2 ], oui, oui_len))) { + && (!oui || (ie_len >= oui_len && !memcmp (&in_ie[cnt +2 ], oui, oui_len)))) { target_ie = &in_ie[cnt];if (ie) -memcpy (ie, &in_ie[cnt], in_ie[cnt+1 ]+2 ); +memcpy (ie, &in_ie[cnt], ie_len +2 );if (ielen) - *ielen = in_ie[cnt+1 ]+2 ; + *ielen = ie_len +2 ;break ; } - cnt += in_ie[cnt+1 ]+2 ;/* goto next */ + cnt += ie_len +2 ;/* goto next */ }return target_ie;
Greg Kroah-Hartman
maintainerPATCH 236/481 staging: rtl8723bs: fix potential out-of-bounds read in rtw_restruct_wmm_ie
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luka Gejak <[email protected]>
commit a75281626fc8fa6dc6c9cc314ee423e8bc45203b upstream.
The current code checks 'i + 5 < in_len' at the end of the if statement. However, it accesses 'in_ie[i + 5]' before that check, which can lead to an out-of-bounds read. Move the length check to the beginning of the conditional to ensure the index is within bounds before accessing the array.
--- drivers/staging/rtl8723bs/core/rtw_mlme.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/staging/rtl8723bs/core/rtw_mlme.c +4 -1
@@ -2010,7 +2010,10 @@ int rtw_restruct_wmm_ie(struct adapter *while (i < in_len) { ielength = initial_out_len; -if (in_ie[i] ==0xDD && in_ie[i+2 ] ==0x00 && in_ie[i+3 ] ==0x50 && in_ie[i+4 ] ==0xF2 && in_ie[i+5 ] ==0x02 && i+5 < in_len) {/* WMM element ID and OUI */ +if (i +5 < in_len && + in_ie[i] ==0xDD && in_ie[i +2 ] ==0x00 && + in_ie[i +3 ] ==0x50 && in_ie[i +4 ] ==0xF2 && + in_ie[i +5 ] ==0x02 ) {for (j = i; j < i +9 ; j++) { out_ie[ielength] = in_ie[j]; ielength++;
Greg Kroah-Hartman
maintainerPATCH 237/481 media: dvb-net: fix OOB access in ULE extension header tables
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ariel Silver <[email protected]>
commit 24d87712727a5017ad142d63940589a36cd25647 upstream.
The ule_mandatory_ext_handlers[] and ule_optional_ext_handlers[] tables in handle_one_ule_extension() are declared with 255 elements (valid indices 0-254), but the index htype is derived from network-controlled data as (ule_sndu_type & 0x00FF), giving a range of 0-255. When htype equals 255, an out-of-bounds read occurs on the function pointer table, and the OOB value may be called as a function pointer.
Add a bounds check on htype against the array size before either table is accessed. Out-of-range values now cause the SNDU to be discarded.
--- drivers/media/dvb-core/dvb_net.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/media/dvb-core/dvb_net.c +3 -0
@@ -228,6 +228,9 @@ static int handle_one_ule_extension( strunsigned char hlen = (p->ule_sndu_type &0x0700 ) >>8 ;unsigned char htype = p->ule_sndu_type &0x00FF ; +if (htype >=ARRAY_SIZE (ule_mandatory_ext_handlers)) +return -1 ; +/* Discriminate mandatory and optional extension headers. */ if (hlen ==0 ) {/* Mandatory extension header */
Greg Kroah-Hartman
maintainerPATCH 238/481 net: mana: Ring doorbell at 4 CQ wraparounds
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li <[email protected]>
commit dabffd08545ffa1d7183bc45e387860984025291 upstream.
MANA hardware requires at least one doorbell ring every 8 wraparounds of the CQ. The driver rings the doorbell as a form of flow control to inform hardware that CQEs have been consumed.
The NAPI poll functions mana_poll_tx_cq() and mana_poll_rx_cq() can poll up to CQE_POLLING_BUFFER (512) completions per call. If the CQ has fewer than 512 entries, a single poll call can process more than 4 wraparounds without ringing the doorbell. The doorbell threshold check also uses ">" instead of ">=", delaying the ring by one extra CQE beyond 4 wraparounds. Combined, these issues can cause the driver to exceed the 8-wraparound hardware limit, leading to missed completions and stalled queues.
Fix this by capping the number of CQEs polled per call to 4 wraparounds of the CQ in both TX and RX paths. Also change the doorbell threshold from ">" to ">=" so the doorbell is rung as soon as 4 wraparounds are reached.
--- drivers/net/ethernet/microsoft/mana/mana_en.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
drivers/net/ethernet/microsoft/mana/mana_en.c +18 -5
@@ -973,8 +973,14 @@ static void mana_poll_tx_cq(struct mana_ ndev = txq->ndev; apc =netdev_priv (ndev); +/* Limit CQEs polled to 4 wraparounds of the CQ to ensure the +* doorbell can be rung in time for the hardware's requirement +* of at least one doorbell ring every 8 wraparounds. +*/ comp_read =mana_gd_poll_cq (cq->gdma_cq, completions, -CQE_POLLING_BUFFER ); +min ((cq->gdma_cq->queue_size / +COMP_ENTRY_SIZE ) *4 , +CQE_POLLING_BUFFER ));if (comp_read <1 )return ;
@@ -1288,7 +1294,14 @@ static void mana_poll_rx_cq(struct mana_struct mana_rxq *rxq = cq->rxq;int comp_read, i; - comp_read =mana_gd_poll_cq (cq->gdma_cq, comp,CQE_POLLING_BUFFER ); +/* Limit CQEs polled to 4 wraparounds of the CQ to ensure the +* doorbell can be rung in time for the hardware's requirement +* of at least one doorbell ring every 8 wraparounds. +*/ + comp_read =mana_gd_poll_cq (cq->gdma_cq, comp, +min ((cq->gdma_cq->queue_size / +COMP_ENTRY_SIZE ) *4 , +CQE_POLLING_BUFFER ));WARN_ON_ONCE (comp_read >CQE_POLLING_BUFFER ); rxq->xdp_flush = false;
@@ -1327,11 +1340,11 @@ static int mana_cq_handler(void *contextmana_gd_ring_cq (gdma_queue,SET_ARM_BIT ); cq->work_done_since_doorbell =0 ;napi_complete_done (&cq->napi, w); - }else if (cq->work_done_since_doorbell > - cq->gdma_cq->queue_size /COMP_ENTRY_SIZE *4 ) { + }else if (cq->work_done_since_doorbell >= + (cq->gdma_cq->queue_size /COMP_ENTRY_SIZE ) *4 ) {/* MANA hardware requires at least one doorbell ring every 8 * wraparounds of CQ even if there is no need to arm the CQ. -* This driver rings the doorbell as soon as we have exceeded +* This driver rings the doorbell as soon as it has processed * 4 wraparounds. */ mana_gd_ring_cq (gdma_queue,0 );
Greg Kroah-Hartman
maintainerPATCH 239/481 ice: fix retry for AQ command 0x06EE
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Staniszewski <[email protected]>
commit fb4903b3354aed4a2301180cf991226f896c87ed upstream.
Executing ethtool -m can fail reporting a netlink I/O error while firmware link management holds the i2c bus used to communicate with the module.
According to Intel(R) Ethernet Controller E810 Datasheet Rev 2.8 [1] Section 3.3.10.4 Read/Write SFF EEPROM (0x06EE)
request should to be retried upon receiving EBUSY from firmware.
Commit e9c9692c8a81 ("ice: Reimplement module reads used by ethtool") implemented it only for part of ice_get_module_eeprom(), leaving all other calls to ice_aq_sff_eeprom() vulnerable to returning early on getting EBUSY without retrying.
Remove the retry loop from ice_get_module_eeprom() and add Admin Queue (AQ) command with opcode 0x06EE to the list of commands that should be retried on receiving EBUSY from firmware.
--- drivers/net/ethernet/intel/ice/ice_common.c | 1 drivers/net/ethernet/intel/ice/ice_ethtool.c | 35 ++++++++++----------------- 2 files changed, 15 insertions(+), 21 deletions(-)
drivers/net/ethernet/intel/ice/ice_common.c +1 -0
@@ -1570,6 +1570,7 @@ static bool ice_should_retry_sq_send_cmdcase ice_aqc_opc_lldp_stop:case ice_aqc_opc_lldp_start:case ice_aqc_opc_lldp_filter_ctrl: +case ice_aqc_opc_sff_eeprom:return true; }
drivers/net/ethernet/intel/ice/ice_ethtool.c +14 -21
@@ -4089,7 +4089,7 @@ ice_get_module_eeprom(struct net_devicestruct ice_pf *pf = vsi->back;struct ice_hw *hw = &pf->hw;bool is_sfp = false; -unsigned int i, j; +unsigned int i;u16 offset =0 ;u8 page =0 ;int status;
@@ -4131,26 +4131,19 @@ ice_get_module_eeprom(struct net_deviceif (page ==0 || !(data[0x2 ] &0x4 )) {u32 copy_len; -/* If i2c bus is busy due to slow page change or -* link management access, call can fail. This is normal. -* So we retry this a few times. -*/ -for (j =0 ; j <4 ; j++) { - status =ice_aq_sff_eeprom (hw,0 , addr, offset, page, - !is_sfp, value, -SFF_READ_BLOCK_SIZE , -0 ,NULL ); -netdev_dbg (netdev,"SFF %02X %02X %02X %X = %02X%02X%02X%02X.%02X%02X%02X%02X (%X)\n" , - addr, offset, page, is_sfp, - value[0 ], value[1 ], value[2 ], value[3 ], - value[4 ], value[5 ], value[6 ], value[7 ], - status); -if (status) { -usleep_range (1500 ,2500 ); -memset (value,0 ,SFF_READ_BLOCK_SIZE ); -continue ; - } -break ; + status =ice_aq_sff_eeprom (hw,0 , addr, offset, page, + !is_sfp, value, +SFF_READ_BLOCK_SIZE , +0 ,NULL ); +netdev_dbg (netdev,"SFF %02X %02X %02X %X = %02X%02X%02X%02X.%02X%02X%02X%02X (%pe)\n" , + addr, offset, page, is_sfp, + value[0 ], value[1 ], value[2 ], value[3 ], + value[4 ], value[5 ], value[6 ], value[7 ], +ERR_PTR (status)); +if (status) { +netdev_err (netdev,"%s: error reading module EEPROM: status %pe\n" , + __func__,ERR_PTR (status)); +return status; }/* Make sure we have enough room for the new block */
Greg Kroah-Hartman
maintainerPATCH 240/481 batman-adv: Avoid double-rtnl_lock ELP metric worker
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit cfc83a3c71517b59c1047db57da31e26a9dc2f33 upstream.
batadv_v_elp_get_throughput() might be called when the RTNL lock is already held. This could be problematic when the work queue item is cancelled via cancel_delayed_work_sync() in batadv_v_elp_iface_disable(). In this case, an rtnl_lock() would cause a deadlock.
To avoid this, rtnl_trylock() was used in this function to skip the retrieval of the ethtool information in case the RTNL lock was already held.
But for cfg80211 interfaces, batadv_get_real_netdev() was called - which also uses rtnl_lock(). The approach for __ethtool_get_link_ksettings() must also be used instead and the lockless version __batadv_get_real_netdev() has to be called.
--- net/batman-adv/bat_v_elp.c | 10 +++++++++- net/batman-adv/hard-interface.c | 8 ++++---- net/batman-adv/hard-interface.h | 1 + 3 files changed, 14 insertions(+), 5 deletions(-)
net/batman-adv/bat_v_elp.c +9 -1
@@ -113,7 +113,15 @@ static bool batadv_v_elp_get_throughput(/* unsupported WiFi driver version */ goto default_throughput; - real_netdev =batadv_get_real_netdev (hard_iface->net_dev); +/* only use rtnl_trylock because the elp worker will be cancelled while +* the rntl_lock is held. the cancel_delayed_work_sync() would otherwise +* wait forever when the elp work_item was started and it is then also +* trying to rtnl_lock +*/ +if (!rtnl_trylock ()) +return false; + real_netdev =__batadv_get_real_netdev (hard_iface->net_dev); +rtnl_unlock ();if (!real_netdev) goto default_throughput;
net/batman-adv/hard-interface.c +4 -4
@@ -202,7 +202,7 @@ static bool batadv_is_valid_iface(const }/** -* batadv_get_real_netdevice() - check if the given netdev struct is a virtual +* __batadv_get_real_netdev() - check if the given netdev struct is a virtual * interface on top of another 'real' interface * @netdev: the device to check *
@@ -212,7 +212,7 @@ static bool batadv_is_valid_iface(const* Return: the 'real' net device or the original net device and NULL in case * of an error. */ -static struct net_device *batadv_get_real_netdevice (struct net_device *netdev) +struct net_device *__batadv_get_real_netdev (struct net_device *netdev) {struct batadv_hard_iface *hard_iface =NULL ;struct net_device *real_netdev =NULL ;
@@ -265,7 +265,7 @@ struct net_device *batadv_get_real_netdestruct net_device *real_netdev;rtnl_lock (); - real_netdev =batadv_get_real_netdevice (net_device); + real_netdev =__batadv_get_real_netdev (net_device);rtnl_unlock ();return real_netdev;
@@ -334,7 +334,7 @@ static u32 batadv_wifi_flags_evaluate(stif (batadv_is_cfg80211_netdev (net_device)) wifi_flags |=BATADV_HARDIF_WIFI_CFG80211_DIRECT ; - real_netdev =batadv_get_real_netdevice (net_device); + real_netdev =__batadv_get_real_netdev (net_device);if (!real_netdev)return wifi_flags;
net/batman-adv/hard-interface.h +1 -0
@@ -68,6 +68,7 @@ enum batadv_hard_if_bcast {extern struct notifier_block batadv_hard_if_notifier; +struct net_device *__batadv_get_real_netdev (struct net_device *net_device);struct net_device *batadv_get_real_netdev (struct net_device *net_device);bool batadv_is_cfg80211_hardif (struct batadv_hard_iface *hard_iface);bool batadv_is_wifi_hardif (struct batadv_hard_iface *hard_iface);
Greg Kroah-Hartman
maintainerPATCH 241/481 parisc: Increase initial mapping to 64 MB with KALLSYMS
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit 8e732934fb81282be41602550e7e07baf265e972 upstream.
The 32MB initial kernel mapping can become too small when CONFIG_KALLSYMS is used. Increase the mapping to 64 MB in this case.
--- arch/parisc/include/asm/pgtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/parisc/include/asm/pgtable.h +1 -1
@@ -94,7 +94,7 @@ extern void __update_cache(pte_t pte);printk ("%s:%d: bad pgd %08lx.\n" , __FILE__, __LINE__, (unsigned long )pgd_val (e)) /* This is the size of the initially mapped kernel memory */ -#if defined(CONFIG_64BIT ) +#if defined(CONFIG_64BIT ) || defined(CONFIG_KALLSYMS )#define KERNEL_INITIAL_ORDER 26/* 1<<26 = 64MB */ #else #define KERNEL_INITIAL_ORDER 25/* 1<<25 = 32MB */
Greg Kroah-Hartman
maintainerPATCH 242/481 nouveau/dpcd: return EBUSY for aux xfer if the device is asleep
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Airlie <[email protected]>
commit 8f3c6f08ababad2e3bdd239728cf66a9949446b4 upstream.
If we have runtime suspended, and userspace wants to use /dev/drm_dp_* then just tell it the device is busy instead of crashing in the GSP code.
WARNING: CPU: 2 PID: 565741 at drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c:164 r535_gsp_msgq_wait+0x9a/0xb0 [nouveau] CPU: 2 UID: 0 PID: 565741 Comm: fwupd Not tainted 6.18.10-200.fc43.x86_64 #1 PREEMPT(lazy) Hardware name: LENOVO 20QTS0PQ00/20QTS0PQ00, BIOS N2OET65W (1.52 ) 08/05/2024 RIP: 0010:r535_gsp_msgq_wait+0x9a/0xb0 [nouveau]
This is a simple fix to get backported. We should probably engineer a proper power domain solution to wake up devices and keep them awake while fw updates are happening.
--- drivers/gpu/drm/nouveau/nouveau_connector.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/nouveau/nouveau_connector.c +3 -0
@@ -1210,6 +1210,9 @@ nouveau_connector_aux_xfer(struct drm_dpu8 size = msg->size;int ret; +if (pm_runtime_suspended (nv_connector->base.dev->dev)) +return -EBUSY ; + nv_encoder =find_encoder (&nv_connector->base,DCB_OUTPUT_DP );if (!nv_encoder || !(aux = nv_encoder->aux))return -ENODEV ;
Greg Kroah-Hartman
maintainerPATCH 243/481 hwmon: (pmbus/q54sj108a2) fix stack overflow in debugfs read
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanman Pradhan <[email protected]>
commit 25dd70a03b1f5f3aa71e1a5091ecd9cd2a13ee43 upstream.
The q54sj108a2_debugfs_read function suffers from a stack buffer overflow due to incorrect arguments passed to bin2hex(). The function currently passes 'data' as the destination and 'data_char' as the source.
Because bin2hex() converts each input byte into two hex characters, a 32-byte block read results in 64 bytes of output. Since 'data' is only 34 bytes (I2C_SMBUS_BLOCK_MAX + 2), this writes 30 bytes past the end of the buffer onto the stack.
Additionally, the arguments were swapped: it was reading from the zero-initialized 'data_char' and writing to 'data', resulting in all-zero output regardless of the actual I2C read.
Fix this by:
1. Expanding 'data_char' to 66 bytes to safely hold the hex output.
2. Correcting the bin2hex() argument order and using the actual read count.
3. Using a pointer to select the correct output buffer for the final simple_read_from_buffer call.
--- drivers/hwmon/pmbus/q54sj108a2.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
drivers/hwmon/pmbus/q54sj108a2.c +10 -9
@@ -77,7 +77,8 @@ static ssize_t q54sj108a2_debugfs_read(sint idx = *idxp;struct q54sj108a2_data *psu =to_psu (idxp, idx);char data[I2C_SMBUS_BLOCK_MAX +2 ] = {0 }; -char data_char[I2C_SMBUS_BLOCK_MAX +2 ] = {0 }; +char data_char[I2C_SMBUS_BLOCK_MAX *2 +2 ] = {0 }; +char *out = data;char *res;switch (idx) {
@@ -148,27 +149,27 @@ static ssize_t q54sj108a2_debugfs_read(sif (rc <0 )return rc; - res =bin2hex (data, data_char,32 ); - rc = res - data; - + res =bin2hex (data_char, data, rc); + rc = res - data_char; + out = data_char;break ;case Q54SJ108A2_DEBUGFS_FLASH_KEY : rc =i2c_smbus_read_block_data (psu->client,PMBUS_FLASH_KEY_WRITE , data);if (rc <0 )return rc; - res =bin2hex (data, data_char,4 ); - rc = res - data; - + res =bin2hex (data_char, data, rc); + rc = res - data_char; + out = data_char;break ;default :return -EINVAL ; } - data[rc] ='\n' ; + out[rc] ='\n' ; rc +=2 ; -return simple_read_from_buffer (buf, count, ppos, data, rc); +return simple_read_from_buffer (buf, count, ppos, out, rc); } static ssize_t q54sj108a2_debugfs_write(struct file *file, const char __user *buf,
Greg Kroah-Hartman
maintainerPATCH 244/481 parisc: Fix initial page table creation for boot
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit 8475d8fe21ec9c7eb2faca555fbc5b68cf0d2597 upstream.
The KERNEL_INITIAL_ORDER value defines the initial size (usually 32 or 64 MB) of the page table during bootup. Up until now the whole area was initialized with PTE entries, but there was no check if we filled too many entries. Change the code to fill up with so many entries that the "_end" symbol can be reached by the kernel, but not more entries than actually fit into the initial PTE tables.
--- arch/parisc/kernel/head.S | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
arch/parisc/kernel/head.S +6 -1
@@ -56,6 +56,7 @@ ENTRY(parisc_kernel_start) .import __bss_start,data .import __bss_stop,data + .import __end,data load32 PA(__bss_start),%r3 load32 PA(__bss_stop),%r4
@@ -149,7 +150,11 @@ $cpu_ok: * everything ... it will get remapped correctly later */ ldo 0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */ load32 (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */ - load32 PA(pg0),%r1 + load32 PA(_end),%r1 + SHRREG %r1,PAGE_SHIFT,%r1 /* %r1 is PFN count for _end symbol */ + cmpb,<<,n %r11,%r1,1f + copy %r1,%r11 /* %r1 PFN count smaller than %r11 */ +1: load32 PA(pg0),%r1 $pgt_fill_loop: STREGM %r3,ASM_PTE_ENTRY_SIZE(%r1)
Greg Kroah-Hartman
maintainerPATCH 245/481 parisc: Check kernel mapping earlier at bootup
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit 17c144f1104bfc29a3ce3f7d0931a1bfb7a3558c upstream.
The check if the initial mapping is sufficient needs to happen much earlier during bootup. Move this test directly to the start_parisc() function and use native PDC iodc functions to print the warning, because panic() and printk() are not functional yet.
This fixes boot when enabling various KALLSYSMS options which need much more space.
--- arch/parisc/kernel/setup.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-)
arch/parisc/kernel/setup.c +12 -8
@@ -135,14 +135,6 @@ void __init setup_arch(char **cmdline_p)#endif printk (KERN_CONT ".\n" ); -/* -* Check if initial kernel page mappings are sufficient. -* panic early if not, else we may access kernel functions -* and variables which can't be reached. -*/ -if (__pa ((unsigned long ) &_end) >=KERNEL_INITIAL_SIZE ) -panic ("KERNEL_INITIAL_ORDER too small!" ); -#ifdef CONFIG_64BIT if (parisc_narrow_firmware) {printk (KERN_INFO "Kernel is using PDC in 32-bit mode.\n" );
@@ -398,6 +390,18 @@ void __init start_parisc(void)int ret, cpunum;struct pdc_coproc_cfg coproc_cfg; +/* +* Check if initial kernel page mapping is sufficient. +* Print warning if not, because we may access kernel functions and +* variables which can't be reached yet through the initial mappings. +* Note that the panic() and printk() functions are not functional +* yet, so we need to use direct iodc() firmware calls instead. +*/ +const char warn1[] ="CRITICAL: Kernel may crash because " +"KERNEL_INITIAL_ORDER is too small.\n" ; +if (__pa ((unsigned long ) &_end) >=KERNEL_INITIAL_SIZE ) +pdc_iodc_print (warn1,sizeof (warn1) -1 ); +/* check QEMU/SeaBIOS marker in PAGE0 */ running_on_qemu = (memcmp (&PAGE0 ->pad0,"SeaBIOS" ,8 ) ==0 );
Greg Kroah-Hartman
maintainerPATCH 246/481 smb: server: fix use-after-free in smb2_open()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marios Makassikis <[email protected]>
commit 1e689a56173827669a35da7cb2a3c78ed5c53680 upstream.
The opinfo pointer obtained via rcu_dereference(fp->f_opinfo) is dereferenced after rcu_read_unlock(), creating a use-after-free window.
--- fs/smb/server/smb2pdu.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
fs/smb/server/smb2pdu.c +2 -3
@@ -3343,10 +3343,8 @@ int smb2_open(struct ksmbd_work *work)memcpy (fp->client_guid, conn->ClientGUID,SMB2_CLIENT_GUID_SIZE ); rsp->StructureSize =cpu_to_le16 (89 ); -rcu_read_lock (); - opinfo =rcu_dereference (fp->f_opinfo); + opinfo =opinfo_get (fp); rsp->OplockLevel = opinfo !=NULL ? opinfo->level :0 ; -rcu_read_unlock (); rsp->Flags =0 ; rsp->CreateAction =cpu_to_le32 (file_info); rsp->CreationTime =cpu_to_le64 (fp->create_time);
@@ -3387,6 +3385,7 @@ int smb2_open(struct ksmbd_work *work) next_ptr = &lease_ccontext->Next; next_off = conn->vals->create_lease_size; } +opinfo_put (opinfo);if (maximal_access_ctxt) {struct create_context *mxac_ccontext;
Greg Kroah-Hartman
maintainerPATCH 247/481 net: ncsi: fix skb leak in error paths
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jian Zhang <[email protected]>
commit 5c3398a54266541610c8d0a7082e654e9ff3e259 upstream.
Early return paths in NCSI RX and AEN handlers fail to release the received skb, resulting in a memory leak.
Specifically, ncsi_aen_handler() returns on invalid AEN packets without consuming the skb. Similarly, ncsi_rcv_rsp() exits early when failing to resolve the NCSI device, response handler, or request, leaving the skb unfreed.
--- net/ncsi/ncsi-aen.c | 3 ++- net/ncsi/ncsi-rsp.c | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-)
net/ncsi/ncsi-aen.c +2 -1
@@ -224,7 +224,8 @@ int ncsi_aen_handler(struct ncsi_dev_priif (!nah) {netdev_warn (ndp->ndev.dev,"Invalid AEN (0x%x) received\n" , h->type); -return -ENOENT ; + ret = -ENOENT ; + goto out; } ret =ncsi_validate_aen_pkt (h, nah->payload);
net/ncsi/ncsi-rsp.c +12 -4
@@ -1176,8 +1176,10 @@ int ncsi_rcv_rsp(struct sk_buff *skb, st/* Find the NCSI device */ nd =ncsi_find_dev (orig_dev); ndp = nd ?TO_NCSI_DEV_PRIV (nd) :NULL ; -if (!ndp) -return -ENODEV ; +if (!ndp) { + ret = -ENODEV ; + goto err_free_skb; + }/* Check if it is AEN packet */ hdr = (struct ncsi_pkt_hdr *)skb_network_header (skb);
@@ -1199,7 +1201,8 @@ int ncsi_rcv_rsp(struct sk_buff *skb, stif (!nrh) {netdev_err (nd->dev,"Received unrecognized packet (0x%x)\n" , hdr->type); -return -ENOENT ; + ret = -ENOENT ; + goto err_free_skb; }/* Associate with the request */
@@ -1207,7 +1210,8 @@ int ncsi_rcv_rsp(struct sk_buff *skb, st nr = &ndp->requests[hdr->id];if (!nr->used) {spin_unlock_irqrestore (&ndp->lock, flags); -return -ENODEV ; + ret = -ENODEV ; + goto err_free_skb; } nr->rsp = skb;
@@ -1261,4 +1265,8 @@ out_netlink: out:ncsi_free_request (nr);return ret; + +err_free_skb: +kfree_skb (skb); +return ret; }
Greg Kroah-Hartman
maintainerPATCH 248/481 net: ethernet: arc: emac: quiesce interrupts before requesting IRQ
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <[email protected]>
commit 2503d08f8a2de618e5c3a8183b250ff4a2e2d52c upstream.
Normal RX/TX interrupts are enabled later, in arc_emac_open(), so probe should not see interrupt delivery in the usual case. However, hardware may still present stale or latched interrupt status left by firmware or the bootloader.
If probe later unwinds after devm_request_irq() has installed the handler, such a stale interrupt can still reach arc_emac_intr() during teardown and race with release of the associated net_device.
Avoid that window by putting the device into a known quiescent state before requesting the IRQ: disable all EMAC interrupt sources and clear any pending EMAC interrupt status bits. This keeps the change hardware-focused and minimal, while preventing spurious IRQ delivery from leftover state.
--- drivers/net/ethernet/arc/emac_main.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/net/ethernet/arc/emac_main.c +11 -0
@@ -934,6 +934,17 @@ int arc_emac_probe(struct net_device *nd/* Set poll rate so that it polls every 1 ms */ arc_reg_set (priv,R_POLLRATE , clock_frequency /1000000 ); +/* +* Put the device into a known quiescent state before requesting +* the IRQ. Clear only EMAC interrupt status bits here; leave the +* MDIO completion bit alone and avoid writing TXPL_MASK, which is +* used to force TX polling rather than acknowledge interrupts. +*/ +arc_reg_set (priv,R_ENABLE ,0 ); +arc_reg_set (priv,R_STATUS ,RXINT_MASK |TXINT_MASK |ERR_MASK | +TXCH_MASK |MSER_MASK |RXCR_MASK | +RXFR_MASK |RXFL_MASK ); + ndev->irq = irq;dev_info (dev,"IRQ is %d\n" , ndev->irq);
Greg Kroah-Hartman
maintainerPATCH 249/481 drm/amdgpu: Fix use-after-free race in VM acquire
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alysa Liu <[email protected]>
commit 2c1030f2e84885cc58bffef6af67d5b9d2e7098f upstream.
Replace non-atomic vm->process_info assignment with cmpxchg() to prevent race when parent/child processes sharing a drm_file both try to acquire the same VM after fork().
--- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +5 -1
@@ -1371,7 +1371,10 @@ static int init_kfd_vm(struct amdgpu_vm *ef =dma_fence_get (&info->eviction_fence->base); } - vm->process_info = *process_info; +if (cmpxchg (&vm->process_info,NULL , *process_info) !=NULL ) { + ret = -EINVAL ; + goto already_acquired; + }/* Validate page directory and attach eviction fence */ ret =amdgpu_bo_reserve (vm->root.bo, true);
@@ -1409,6 +1412,7 @@ validate_pd_fail:amdgpu_bo_unreserve (vm->root.bo); reserve_pd_fail: vm->process_info =NULL ; +already_acquired:if (info) {/* Two fence references: one in info and one in *ef */ dma_fence_put (&info->eviction_fence->base);
Greg Kroah-Hartman
maintainerPATCH 250/481 drm/amd: Set num IP blocks to 0 if discovery fails
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 3646ff28780b4c52c5b5081443199e7a430110e5 upstream.
If discovery has failed for any reason (such as no support for a block) then there is no need to unwind all the IP blocks in fini. In this condition there can actually be failures during the unwind too.
Reset num_ip_blocks to zero during failure path and skip the unnecessary cleanup path.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 +++- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +3 -1
@@ -2182,8 +2182,10 @@ static int amdgpu_device_ip_early_init(sbreak ;default : r =amdgpu_discovery_set_ip_blocks (adev); -if (r) +if (r) { + adev->num_ip_blocks =0 ;return r; + }break ; }
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +1 -1
@@ -79,7 +79,7 @@ void amdgpu_driver_unload_kms(struct drm {struct amdgpu_device *adev =drm_to_adev (dev); -if (adev ==NULL ) +if (adev ==NULL || !adev->num_ip_blocks)return ;amdgpu_unregister_gpu_instance (adev);
Greg Kroah-Hartman
maintainerPATCH 251/481 drm/bridge: ti-sn65dsi83: fix CHA_DSI_CLK_RANGE rounding
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luca Ceresoli <[email protected]>
commit 2f22702dc0fee06a240404e0f7ead5b789b253d8 upstream.
The DSI frequency must be in the range:
(CHA_DSI_CLK_RANGE * 5 MHz) <= DSI freq < ((CHA_DSI_CLK_RANGE + 1) * 5 MHz)
So the register value should point to the lower range value, but DIV_ROUND_UP() rounds the division to the higher range value, resulting in an excess of 1 (unless the frequency is an exact multiple of 5 MHz).
For example for a 437100000 MHz clock CHA_DSI_CLK_RANGE should be 87 (0x57):
(87 * 5 = 435) <= 437.1 < (88 * 5 = 440)
but current code returns 88 (0x58).
Fix the computation by removing the DIV_ROUND_UP().
--- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/bridge/ti-sn65dsi83.c +3 -3
@@ -303,9 +303,9 @@ static u8 sn65dsi83_get_dsi_range(struct* DSI_CLK = mode clock * bpp / dsi_data_lanes / 2 * the 2 is there because the bus is DDR. */ -return DIV_ROUND_UP (clamp ((unsigned int )mode->clock * -mipi_dsi_pixel_format_to_bpp (ctx->dsi->format) / - ctx->dsi->lanes /2 ,40000U ,500000U ),5000U ); +return clamp ((unsigned int )mode->clock * +mipi_dsi_pixel_format_to_bpp (ctx->dsi->format) / + ctx->dsi->lanes /2 ,40000U ,500000U ) /5000U ; }static u8 sn65dsi83_get_dsi_div (struct sn65dsi83 *ctx)
Greg Kroah-Hartman
maintainerPATCH 252/481 tracing: Fix trace_buf_size= cmdline parameter with sizes >= 2G
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Calvin Owens <[email protected]>
commit d008ba8be8984760e36d7dcd4adbd5a41a645708 upstream.
Some of the sizing logic through tracer_alloc_buffers() uses int internally, causing unexpected behavior if the user passes a value that does not fit in an int (on my x86 machine, the result is uselessly tiny buffers).
Fix by plumbing the parameter's real type (unsigned long) through to the ring buffer allocation functions, which already use unsigned long.
It has always been possible to create larger ring buffers via the sysfs
interface: this only affects the cmdline parameter.
--- kernel/trace/trace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/trace/trace.c +3 -3
@@ -9298,7 +9298,7 @@ static void init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer);static int -allocate_trace_buffer (struct trace_array *tr,struct array_buffer *buf,int size) +allocate_trace_buffer (struct trace_array *tr,struct array_buffer *buf,unsigned long size) {enum ring_buffer_flags rb_flags;
@@ -9334,7 +9334,7 @@ static void free_trace_buffer(struct arr } } -static int allocate_trace_buffers (struct trace_array *tr,int size) +static int allocate_trace_buffers (struct trace_array *tr,unsigned long size) {int ret;
@@ -10278,7 +10278,7 @@ out:__init static int tracer_alloc_buffers (void ) { -int ring_buf_size; +unsigned long ring_buf_size;int ret = -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 253/481 xfs: fix undersized l_iclog_roundoff values
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <[email protected]>
commit 52a8a1ba883defbfe3200baa22cf4cd21985d51a upstream.
If the superblock doesn't list a log stripe unit, we set the incore log roundoff value to 512. This leads to corrupt logs and unmountable filesystems in generic/617 on a disk with 4k physical sectors...
XFS (sda1): Mounting V5 Filesystem ff3121ca-26e6-4b77-b742-aaff9a449e1c
XFS (sda1): Torn write (CRC failure) detected at log block 0x318e. Truncating head block from 0x3197. XFS (sda1): failed to locate log tail
XFS (sda1): log mount/recovery failed: error -74
XFS (sda1): log mount failed
XFS (sda1): Mounting V5 Filesystem ff3121ca-26e6-4b77-b742-aaff9a449e1c
XFS (sda1): Ending clean mount
...on the current xfsprogs for-next which has a broken mkfs. xfs_info shows this...
meta-data=/dev/sda1 isize=512 agcount=4, agsize=644992 blks
= sectsz=4096 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=1, rmapbt=1
= reflink=1 bigtime=1 inobtcount=1 nrext64=1
= exchange=1 metadir=1
data = bsize=4096 blocks=2579968, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0, ftype=1, parent=1
log =internal log bsize=4096 blocks=16384, version=2
= sectsz=4096 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
= rgcount=0 rgsize=268435456 extents
= zoned=0 start=0 reserved=0...observe that the log section has sectsz=4096 sunit=0, which means that the roundoff factor is 512, not 4096 as you'd expect. We should fix mkfs not to generate broken filesystems, but anyone can fuzz the ondisk superblock so we should be more cautious. I think the inadequate logic predates commit a6a65fef5ef8d0, but that's clearly going to require a different backport.
--- fs/xfs/xfs_log.c | 2 ++ 1 file changed, 2 insertions(+)
fs/xfs/xfs_log.c +2 -0
@@ -1549,6 +1549,8 @@ xlog_alloc_log(if (xfs_has_logv2 (mp) && mp->m_sb.sb_logsunit >1 ) log->l_iclog_roundoff = mp->m_sb.sb_logsunit; +else if (mp->m_sb.sb_logsectsize >0 ) + log->l_iclog_roundoff = mp->m_sb.sb_logsectsize;else log->l_iclog_roundoff =BBSIZE ;
Greg Kroah-Hartman
maintainerPATCH 254/481 s390/dasd: Move quiesce state with pprc swap
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Haberland <[email protected]>
commit 40e9cd4ae8ec43b107ed2bff422a8fa39dcf4e4b upstream.
Quiesce and resume is a mechanism to suspend operations on DASD devices. In the context of a controlled copy pair swap operation, the quiesce operation is usually issued before the actual swap and a resume afterwards.
During the swap operation, the underlying device is exchanged. Therefore, the quiesce flag must be moved to the secondary device to ensure a consistent quiesce state after the swap.
The secondary device itself cannot be suspended separately because there is no separate block device representation for it.
--- drivers/s390/block/dasd_eckd.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/s390/block/dasd_eckd.c +5 -0
@@ -6233,6 +6233,11 @@ static int dasd_eckd_copy_pair_swap(stru dev_name(&secondary->cdev->dev), rc); } +if (primary->stopped &DASD_STOPPED_QUIESCE ) { +dasd_device_set_stop_bits (secondary,DASD_STOPPED_QUIESCE ); +dasd_device_remove_stop_bits (primary,DASD_STOPPED_QUIESCE ); + } +/* re-enable device */ dasd_device_remove_stop_bits (primary,DASD_STOPPED_PPRC );dasd_device_remove_stop_bits (secondary,DASD_STOPPED_PPRC );
Greg Kroah-Hartman
maintainerPATCH 255/481 s390/dasd: Copy detected format information to secondary device
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Haberland <[email protected]>
commit 4c527c7e030672efd788d0806d7a68972a7ba3c1 upstream.
During online processing for a DASD device an IO operation is started to determine the format of the device. CDL format contains specifically sized blocks at the beginning of the disk.
For a PPRC secondary device no real IO operation is possible therefore this IO request can not be started and this step is skipped for online processing of secondary devices. This is generally fine since the secondary is a copy of the primary device.
In case of an additional partition detection that is run after a swap operation the format information is needed to properly drive partition detection IO.
Currently the information is not passed leading to IO errors during partition detection and a wrongly detected partition table which in turn might lead to data corruption on the disk with the wrong partition table.
Fix by passing the format information from primary to secondary device.
--- drivers/s390/block/dasd_eckd.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/s390/block/dasd_eckd.c +11 -0
@@ -6186,6 +6186,7 @@ static void copy_pair_set_active(structstatic int dasd_eckd_copy_pair_swap (struct dasd_device *device,char *prim_busid,char *sec_busid) { +struct dasd_eckd_private *prim_priv, *sec_priv;struct dasd_device *primary, *secondary;struct dasd_copy_relation *copy;struct dasd_block *block;
@@ -6206,6 +6207,9 @@ static int dasd_eckd_copy_pair_swap(struif (!secondary)return DASD_COPYPAIRSWAP_SECONDARY ; + prim_priv = primary->private; + sec_priv = secondary->private; +/* * usually the device should be quiesced for swap * for paranoia stop device and requeue requests again
@@ -6238,6 +6242,13 @@ static int dasd_eckd_copy_pair_swap(strudasd_device_remove_stop_bits (primary,DASD_STOPPED_QUIESCE ); } +/* +* The secondary device never got through format detection, but since it +* is a copy of the primary device, the format is exactly the same; +* therefore, the detected layout can simply be copied. +*/ + sec_priv->uses_cdl = prim_priv->uses_cdl; +/* re-enable device */ dasd_device_remove_stop_bits (primary,DASD_STOPPED_PPRC );dasd_device_remove_stop_bits (secondary,DASD_STOPPED_PPRC );