From 923a932c982fd71856f80dbeaaa3ca41a75e89e0 Mon Sep 17 00:00:00 2001 From: Joe Stringer Date: Tue, 2 Mar 2021 09:19:41 -0800 Subject: scripts/bpf: Abstract eBPF API target parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Abstract out the target parameter so that upcoming commits, more than just the existing "helpers" target can be called to generate specific portions of docs from the eBPF UAPI headers. Signed-off-by: Joe Stringer Signed-off-by: Alexei Starovoitov Reviewed-by: Quentin Monnet Acked-by: Toke Høiland-Jørgensen Link: https://lore.kernel.org/bpf/20210302171947.2268128-10-joe@cilium.io --- scripts/bpf_doc.py | 650 +++++++++++++++++++++++++++++++++++++++++++++ scripts/bpf_helpers_doc.py | 615 ------------------------------------------ 2 files changed, 650 insertions(+), 615 deletions(-) create mode 100755 scripts/bpf_doc.py delete mode 100755 scripts/bpf_helpers_doc.py (limited to 'scripts') diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py new file mode 100755 index 000000000000..5a4f68aab335 --- /dev/null +++ b/scripts/bpf_doc.py @@ -0,0 +1,650 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2018-2019 Netronome Systems, Inc. +# Copyright (C) 2021 Isovalent, Inc. + +# In case user attempts to run with Python 2. +from __future__ import print_function + +import argparse +import re +import sys, os + +class NoHelperFound(BaseException): + pass + +class ParsingError(BaseException): + def __init__(self, line='', reader=None): + if reader: + BaseException.__init__(self, + 'Error at file offset %d, parsing line: %s' % + (reader.tell(), line)) + else: + BaseException.__init__(self, 'Error parsing line: %s' % line) + +class Helper(object): + """ + An object representing the description of an eBPF helper function. + @proto: function prototype of the helper function + @desc: textual description of the helper function + @ret: description of the return value of the helper function + """ + def __init__(self, proto='', desc='', ret=''): + self.proto = proto + self.desc = desc + self.ret = ret + + def proto_break_down(self): + """ + Break down helper function protocol into smaller chunks: return type, + name, distincts arguments. + """ + arg_re = re.compile('((\w+ )*?(\w+|...))( (\**)(\w+))?$') + res = {} + proto_re = re.compile('(.+) (\**)(\w+)\(((([^,]+)(, )?){1,5})\)$') + + capture = proto_re.match(self.proto) + res['ret_type'] = capture.group(1) + res['ret_star'] = capture.group(2) + res['name'] = capture.group(3) + res['args'] = [] + + args = capture.group(4).split(', ') + for a in args: + capture = arg_re.match(a) + res['args'].append({ + 'type' : capture.group(1), + 'star' : capture.group(5), + 'name' : capture.group(6) + }) + + return res + +class HeaderParser(object): + """ + An object used to parse a file in order to extract the documentation of a + list of eBPF helper functions. All the helpers that can be retrieved are + stored as Helper object, in the self.helpers() array. + @filename: name of file to parse, usually include/uapi/linux/bpf.h in the + kernel tree + """ + def __init__(self, filename): + self.reader = open(filename, 'r') + self.line = '' + self.helpers = [] + + def parse_helper(self): + proto = self.parse_proto() + desc = self.parse_desc() + ret = self.parse_ret() + return Helper(proto=proto, desc=desc, ret=ret) + + def parse_proto(self): + # Argument can be of shape: + # - "void" + # - "type name" + # - "type *name" + # - Same as above, with "const" and/or "struct" in front of type + # - "..." (undefined number of arguments, for bpf_trace_printk()) + # There is at least one term ("void"), and at most five arguments. + p = re.compile(' \* ?((.+) \**\w+\((((const )?(struct )?(\w+|\.\.\.)( \**\w+)?)(, )?){1,5}\))$') + capture = p.match(self.line) + if not capture: + raise NoHelperFound + self.line = self.reader.readline() + return capture.group(1) + + def parse_desc(self): + p = re.compile(' \* ?(?:\t| {5,8})Description$') + capture = p.match(self.line) + if not capture: + # Helper can have empty description and we might be parsing another + # attribute: return but do not consume. + return '' + # Description can be several lines, some of them possibly empty, and it + # stops when another subsection title is met. + desc = '' + while True: + self.line = self.reader.readline() + if self.line == ' *\n': + desc += '\n' + else: + p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)') + capture = p.match(self.line) + if capture: + desc += capture.group(1) + '\n' + else: + break + return desc + + def parse_ret(self): + p = re.compile(' \* ?(?:\t| {5,8})Return$') + capture = p.match(self.line) + if not capture: + # Helper can have empty retval and we might be parsing another + # attribute: return but do not consume. + return '' + # Return value description can be several lines, some of them possibly + # empty, and it stops when another subsection title is met. + ret = '' + while True: + self.line = self.reader.readline() + if self.line == ' *\n': + ret += '\n' + else: + p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)') + capture = p.match(self.line) + if capture: + ret += capture.group(1) + '\n' + else: + break + return ret + + def run(self): + # Advance to start of helper function descriptions. + offset = self.reader.read().find('* Start of BPF helper function descriptions:') + if offset == -1: + raise Exception('Could not find start of eBPF helper descriptions list') + self.reader.seek(offset) + self.reader.readline() + self.reader.readline() + self.line = self.reader.readline() + + while True: + try: + helper = self.parse_helper() + self.helpers.append(helper) + except NoHelperFound: + break + + self.reader.close() + +############################################################################### + +class Printer(object): + """ + A generic class for printers. Printers should be created with an array of + Helper objects, and implement a way to print them in the desired fashion. + @parser: A HeaderParser with objects to print to standard output + """ + def __init__(self, parser): + self.parser = parser + self.elements = [] + + def print_header(self): + pass + + def print_footer(self): + pass + + def print_one(self, helper): + pass + + def print_all(self): + self.print_header() + for elem in self.elements: + self.print_one(elem) + self.print_footer() + + +class PrinterRST(Printer): + """ + A generic class for printers that print ReStructured Text. Printers should + be created with a HeaderParser object, and implement a way to print API + elements in the desired fashion. + @parser: A HeaderParser with objects to print to standard output + """ + def __init__(self, parser): + self.parser = parser + + def print_license(self): + license = '''\ +.. Copyright (C) All BPF authors and contributors from 2014 to present. +.. See git log include/uapi/linux/bpf.h in kernel tree for details. +.. +.. %%%LICENSE_START(VERBATIM) +.. Permission is granted to make and distribute verbatim copies of this +.. manual provided the copyright notice and this permission notice are +.. preserved on all copies. +.. +.. Permission is granted to copy and distribute modified versions of this +.. manual under the conditions for verbatim copying, provided that the +.. entire resulting derived work is distributed under the terms of a +.. permission notice identical to this one. +.. +.. Since the Linux kernel and libraries are constantly changing, this +.. manual page may be incorrect or out-of-date. The author(s) assume no +.. responsibility for errors or omissions, or for damages resulting from +.. the use of the information contained herein. The author(s) may not +.. have taken the same level of care in the production of this manual, +.. which is licensed free of charge, as they might when working +.. professionally. +.. +.. Formatted or processed versions of this manual, if unaccompanied by +.. the source, must acknowledge the copyright and authors of this work. +.. %%%LICENSE_END +.. +.. Please do not edit this file. It was generated from the documentation +.. located in file include/uapi/linux/bpf.h of the Linux kernel sources +.. (helpers description), and from scripts/bpf_doc.py in the same +.. repository (header and footer). +''' + print(license) + + def print_elem(self, elem): + if (elem.desc): + print('\tDescription') + # Do not strip all newline characters: formatted code at the end of + # a section must be followed by a blank line. + for line in re.sub('\n$', '', elem.desc, count=1).split('\n'): + print('{}{}'.format('\t\t' if line else '', line)) + + if (elem.ret): + print('\tReturn') + for line in elem.ret.rstrip().split('\n'): + print('{}{}'.format('\t\t' if line else '', line)) + + print('') + + +class PrinterHelpersRST(PrinterRST): + """ + A printer for dumping collected information about helpers as a ReStructured + Text page compatible with the rst2man program, which can be used to + generate a manual page for the helpers. + @parser: A HeaderParser with Helper objects to print to standard output + """ + def __init__(self, parser): + self.elements = parser.helpers + + def print_header(self): + header = '''\ +=========== +BPF-HELPERS +=========== +------------------------------------------------------------------------------- +list of eBPF helper functions +------------------------------------------------------------------------------- + +:Manual section: 7 + +DESCRIPTION +=========== + +The extended Berkeley Packet Filter (eBPF) subsystem consists in programs +written in a pseudo-assembly language, then attached to one of the several +kernel hooks and run in reaction of specific events. This framework differs +from the older, "classic" BPF (or "cBPF") in several aspects, one of them being +the ability to call special functions (or "helpers") from within a program. +These functions are restricted to a white-list of helpers defined in the +kernel. + +These helpers are used by eBPF programs to interact with the system, or with +the context in which they work. For instance, they can be used to print +debugging messages, to get the time since the system was booted, to interact +with eBPF maps, or to manipulate network packets. Since there are several eBPF +program types, and that they do not run in the same context, each program type +can only call a subset of those helpers. + +Due to eBPF conventions, a helper can not have more than five arguments. + +Internally, eBPF programs call directly into the compiled helper functions +without requiring any foreign-function interface. As a result, calling helpers +introduces no overhead, thus offering excellent performance. + +This document is an attempt to list and document the helpers available to eBPF +developers. They are sorted by chronological order (the oldest helpers in the +kernel at the top). + +HELPERS +======= +''' + PrinterRST.print_license(self) + print(header) + + def print_footer(self): + footer = ''' +EXAMPLES +======== + +Example usage for most of the eBPF helpers listed in this manual page are +available within the Linux kernel sources, at the following locations: + +* *samples/bpf/* +* *tools/testing/selftests/bpf/* + +LICENSE +======= + +eBPF programs can have an associated license, passed along with the bytecode +instructions to the kernel when the programs are loaded. The format for that +string is identical to the one in use for kernel modules (Dual licenses, such +as "Dual BSD/GPL", may be used). Some helper functions are only accessible to +programs that are compatible with the GNU Privacy License (GPL). + +In order to use such helpers, the eBPF program must be loaded with the correct +license string passed (via **attr**) to the **bpf**\ () system call, and this +generally translates into the C source code of the program containing a line +similar to the following: + +:: + + char ____license[] __attribute__((section("license"), used)) = "GPL"; + +IMPLEMENTATION +============== + +This manual page is an effort to document the existing eBPF helper functions. +But as of this writing, the BPF sub-system is under heavy development. New eBPF +program or map types are added, along with new helper functions. Some helpers +are occasionally made available for additional program types. So in spite of +the efforts of the community, this page might not be up-to-date. If you want to +check by yourself what helper functions exist in your kernel, or what types of +programs they can support, here are some files among the kernel tree that you +may be interested in: + +* *include/uapi/linux/bpf.h* is the main BPF header. It contains the full list + of all helper functions, as well as many other BPF definitions including most + of the flags, structs or constants used by the helpers. +* *net/core/filter.c* contains the definition of most network-related helper + functions, and the list of program types from which they can be used. +* *kernel/trace/bpf_trace.c* is the equivalent for most tracing program-related + helpers. +* *kernel/bpf/verifier.c* contains the functions used to check that valid types + of eBPF maps are used with a given helper function. +* *kernel/bpf/* directory contains other files in which additional helpers are + defined (for cgroups, sockmaps, etc.). +* The bpftool utility can be used to probe the availability of helper functions + on the system (as well as supported program and map types, and a number of + other parameters). To do so, run **bpftool feature probe** (see + **bpftool-feature**\ (8) for details). Add the **unprivileged** keyword to + list features available to unprivileged users. + +Compatibility between helper functions and program types can generally be found +in the files where helper functions are defined. Look for the **struct +bpf_func_proto** objects and for functions returning them: these functions +contain a list of helpers that a given program type can call. Note that the +**default:** label of the **switch ... case** used to filter helpers can call +other functions, themselves allowing access to additional helpers. The +requirement for GPL license is also in those **struct bpf_func_proto**. + +Compatibility between helper functions and map types can be found in the +**check_map_func_compatibility**\ () function in file *kernel/bpf/verifier.c*. + +Helper functions that invalidate the checks on **data** and **data_end** +pointers for network processing are listed in function +**bpf_helper_changes_pkt_data**\ () in file *net/core/filter.c*. + +SEE ALSO +======== + +**bpf**\ (2), +**bpftool**\ (8), +**cgroups**\ (7), +**ip**\ (8), +**perf_event_open**\ (2), +**sendmsg**\ (2), +**socket**\ (7), +**tc-bpf**\ (8)''' + print(footer) + + def print_proto(self, helper): + """ + Format function protocol with bold and italics markers. This makes RST + file less readable, but gives nice results in the manual page. + """ + proto = helper.proto_break_down() + + print('**%s %s%s(' % (proto['ret_type'], + proto['ret_star'].replace('*', '\\*'), + proto['name']), + end='') + + comma = '' + for a in proto['args']: + one_arg = '{}{}'.format(comma, a['type']) + if a['name']: + if a['star']: + one_arg += ' {}**\ '.format(a['star'].replace('*', '\\*')) + else: + one_arg += '** ' + one_arg += '*{}*\\ **'.format(a['name']) + comma = ', ' + print(one_arg, end='') + + print(')**') + + def print_one(self, helper): + self.print_proto(helper) + self.print_elem(helper) + + + + +class PrinterHelpers(Printer): + """ + A printer for dumping collected information about helpers as C header to + be included from BPF program. + @parser: A HeaderParser with Helper objects to print to standard output + """ + def __init__(self, parser): + self.elements = parser.helpers + + type_fwds = [ + 'struct bpf_fib_lookup', + 'struct bpf_sk_lookup', + 'struct bpf_perf_event_data', + 'struct bpf_perf_event_value', + 'struct bpf_pidns_info', + 'struct bpf_redir_neigh', + 'struct bpf_sock', + 'struct bpf_sock_addr', + 'struct bpf_sock_ops', + 'struct bpf_sock_tuple', + 'struct bpf_spin_lock', + 'struct bpf_sysctl', + 'struct bpf_tcp_sock', + 'struct bpf_tunnel_key', + 'struct bpf_xfrm_state', + 'struct linux_binprm', + 'struct pt_regs', + 'struct sk_reuseport_md', + 'struct sockaddr', + 'struct tcphdr', + 'struct seq_file', + 'struct tcp6_sock', + 'struct tcp_sock', + 'struct tcp_timewait_sock', + 'struct tcp_request_sock', + 'struct udp6_sock', + 'struct task_struct', + + 'struct __sk_buff', + 'struct sk_msg_md', + 'struct xdp_md', + 'struct path', + 'struct btf_ptr', + 'struct inode', + 'struct socket', + 'struct file', + ] + known_types = { + '...', + 'void', + 'const void', + 'char', + 'const char', + 'int', + 'long', + 'unsigned long', + + '__be16', + '__be32', + '__wsum', + + 'struct bpf_fib_lookup', + 'struct bpf_perf_event_data', + 'struct bpf_perf_event_value', + 'struct bpf_pidns_info', + 'struct bpf_redir_neigh', + 'struct bpf_sk_lookup', + 'struct bpf_sock', + 'struct bpf_sock_addr', + 'struct bpf_sock_ops', + 'struct bpf_sock_tuple', + 'struct bpf_spin_lock', + 'struct bpf_sysctl', + 'struct bpf_tcp_sock', + 'struct bpf_tunnel_key', + 'struct bpf_xfrm_state', + 'struct linux_binprm', + 'struct pt_regs', + 'struct sk_reuseport_md', + 'struct sockaddr', + 'struct tcphdr', + 'struct seq_file', + 'struct tcp6_sock', + 'struct tcp_sock', + 'struct tcp_timewait_sock', + 'struct tcp_request_sock', + 'struct udp6_sock', + 'struct task_struct', + 'struct path', + 'struct btf_ptr', + 'struct inode', + 'struct socket', + 'struct file', + } + mapped_types = { + 'u8': '__u8', + 'u16': '__u16', + 'u32': '__u32', + 'u64': '__u64', + 's8': '__s8', + 's16': '__s16', + 's32': '__s32', + 's64': '__s64', + 'size_t': 'unsigned long', + 'struct bpf_map': 'void', + 'struct sk_buff': 'struct __sk_buff', + 'const struct sk_buff': 'const struct __sk_buff', + 'struct sk_msg_buff': 'struct sk_msg_md', + 'struct xdp_buff': 'struct xdp_md', + } + # Helpers overloaded for different context types. + overloaded_helpers = [ + 'bpf_get_socket_cookie', + 'bpf_sk_assign', + ] + + def print_header(self): + header = '''\ +/* This is auto-generated file. See bpf_doc.py for details. */ + +/* Forward declarations of BPF structs */''' + + print(header) + for fwd in self.type_fwds: + print('%s;' % fwd) + print('') + + def print_footer(self): + footer = '' + print(footer) + + def map_type(self, t): + if t in self.known_types: + return t + if t in self.mapped_types: + return self.mapped_types[t] + print("Unrecognized type '%s', please add it to known types!" % t, + file=sys.stderr) + sys.exit(1) + + seen_helpers = set() + + def print_one(self, helper): + proto = helper.proto_break_down() + + if proto['name'] in self.seen_helpers: + return + self.seen_helpers.add(proto['name']) + + print('/*') + print(" * %s" % proto['name']) + print(" *") + if (helper.desc): + # Do not strip all newline characters: formatted code at the end of + # a section must be followed by a blank line. + for line in re.sub('\n$', '', helper.desc, count=1).split('\n'): + print(' *{}{}'.format(' \t' if line else '', line)) + + if (helper.ret): + print(' *') + print(' * Returns') + for line in helper.ret.rstrip().split('\n'): + print(' *{}{}'.format(' \t' if line else '', line)) + + print(' */') + print('static %s %s(*%s)(' % (self.map_type(proto['ret_type']), + proto['ret_star'], proto['name']), end='') + comma = '' + for i, a in enumerate(proto['args']): + t = a['type'] + n = a['name'] + if proto['name'] in self.overloaded_helpers and i == 0: + t = 'void' + n = 'ctx' + one_arg = '{}{}'.format(comma, self.map_type(t)) + if n: + if a['star']: + one_arg += ' {}'.format(a['star']) + else: + one_arg += ' ' + one_arg += '{}'.format(n) + comma = ', ' + print(one_arg, end='') + + print(') = (void *) %d;' % len(self.seen_helpers)) + print('') + +############################################################################### + +# If script is launched from scripts/ from kernel tree and can access +# ../include/uapi/linux/bpf.h, use it as a default name for the file to parse, +# otherwise the --filename argument will be required from the command line. +script = os.path.abspath(sys.argv[0]) +linuxRoot = os.path.dirname(os.path.dirname(script)) +bpfh = os.path.join(linuxRoot, 'include/uapi/linux/bpf.h') + +printers = { + 'helpers': PrinterHelpersRST, +} + +argParser = argparse.ArgumentParser(description=""" +Parse eBPF header file and generate documentation for the eBPF API. +The RST-formatted output produced can be turned into a manual page with the +rst2man utility. +""") +argParser.add_argument('--header', action='store_true', + help='generate C header file') +if (os.path.isfile(bpfh)): + argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h', + default=bpfh) +else: + argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h') +argParser.add_argument('target', nargs='?', default='helpers', + choices=printers.keys(), help='eBPF API target') +args = argParser.parse_args() + +# Parse file. +headerParser = HeaderParser(args.filename) +headerParser.run() + +# Print formatted output to standard output. +if args.header: + printer = PrinterHelpers(headerParser) +else: + printer = printers[args.target](headerParser) +printer.print_all() diff --git a/scripts/bpf_helpers_doc.py b/scripts/bpf_helpers_doc.py deleted file mode 100755 index 867ada23281c..000000000000 --- a/scripts/bpf_helpers_doc.py +++ /dev/null @@ -1,615 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2018-2019 Netronome Systems, Inc. - -# In case user attempts to run with Python 2. -from __future__ import print_function - -import argparse -import re -import sys, os - -class NoHelperFound(BaseException): - pass - -class ParsingError(BaseException): - def __init__(self, line='', reader=None): - if reader: - BaseException.__init__(self, - 'Error at file offset %d, parsing line: %s' % - (reader.tell(), line)) - else: - BaseException.__init__(self, 'Error parsing line: %s' % line) - -class Helper(object): - """ - An object representing the description of an eBPF helper function. - @proto: function prototype of the helper function - @desc: textual description of the helper function - @ret: description of the return value of the helper function - """ - def __init__(self, proto='', desc='', ret=''): - self.proto = proto - self.desc = desc - self.ret = ret - - def proto_break_down(self): - """ - Break down helper function protocol into smaller chunks: return type, - name, distincts arguments. - """ - arg_re = re.compile('((\w+ )*?(\w+|...))( (\**)(\w+))?$') - res = {} - proto_re = re.compile('(.+) (\**)(\w+)\(((([^,]+)(, )?){1,5})\)$') - - capture = proto_re.match(self.proto) - res['ret_type'] = capture.group(1) - res['ret_star'] = capture.group(2) - res['name'] = capture.group(3) - res['args'] = [] - - args = capture.group(4).split(', ') - for a in args: - capture = arg_re.match(a) - res['args'].append({ - 'type' : capture.group(1), - 'star' : capture.group(5), - 'name' : capture.group(6) - }) - - return res - -class HeaderParser(object): - """ - An object used to parse a file in order to extract the documentation of a - list of eBPF helper functions. All the helpers that can be retrieved are - stored as Helper object, in the self.helpers() array. - @filename: name of file to parse, usually include/uapi/linux/bpf.h in the - kernel tree - """ - def __init__(self, filename): - self.reader = open(filename, 'r') - self.line = '' - self.helpers = [] - - def parse_helper(self): - proto = self.parse_proto() - desc = self.parse_desc() - ret = self.parse_ret() - return Helper(proto=proto, desc=desc, ret=ret) - - def parse_proto(self): - # Argument can be of shape: - # - "void" - # - "type name" - # - "type *name" - # - Same as above, with "const" and/or "struct" in front of type - # - "..." (undefined number of arguments, for bpf_trace_printk()) - # There is at least one term ("void"), and at most five arguments. - p = re.compile(' \* ?((.+) \**\w+\((((const )?(struct )?(\w+|\.\.\.)( \**\w+)?)(, )?){1,5}\))$') - capture = p.match(self.line) - if not capture: - raise NoHelperFound - self.line = self.reader.readline() - return capture.group(1) - - def parse_desc(self): - p = re.compile(' \* ?(?:\t| {5,8})Description$') - capture = p.match(self.line) - if not capture: - # Helper can have empty description and we might be parsing another - # attribute: return but do not consume. - return '' - # Description can be several lines, some of them possibly empty, and it - # stops when another subsection title is met. - desc = '' - while True: - self.line = self.reader.readline() - if self.line == ' *\n': - desc += '\n' - else: - p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)') - capture = p.match(self.line) - if capture: - desc += capture.group(1) + '\n' - else: - break - return desc - - def parse_ret(self): - p = re.compile(' \* ?(?:\t| {5,8})Return$') - capture = p.match(self.line) - if not capture: - # Helper can have empty retval and we might be parsing another - # attribute: return but do not consume. - return '' - # Return value description can be several lines, some of them possibly - # empty, and it stops when another subsection title is met. - ret = '' - while True: - self.line = self.reader.readline() - if self.line == ' *\n': - ret += '\n' - else: - p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)') - capture = p.match(self.line) - if capture: - ret += capture.group(1) + '\n' - else: - break - return ret - - def run(self): - # Advance to start of helper function descriptions. - offset = self.reader.read().find('* Start of BPF helper function descriptions:') - if offset == -1: - raise Exception('Could not find start of eBPF helper descriptions list') - self.reader.seek(offset) - self.reader.readline() - self.reader.readline() - self.line = self.reader.readline() - - while True: - try: - helper = self.parse_helper() - self.helpers.append(helper) - except NoHelperFound: - break - - self.reader.close() - -############################################################################### - -class Printer(object): - """ - A generic class for printers. Printers should be created with an array of - Helper objects, and implement a way to print them in the desired fashion. - @helpers: array of Helper objects to print to standard output - """ - def __init__(self, helpers): - self.helpers = helpers - - def print_header(self): - pass - - def print_footer(self): - pass - - def print_one(self, helper): - pass - - def print_all(self): - self.print_header() - for helper in self.helpers: - self.print_one(helper) - self.print_footer() - -class PrinterRST(Printer): - """ - A printer for dumping collected information about helpers as a ReStructured - Text page compatible with the rst2man program, which can be used to - generate a manual page for the helpers. - @helpers: array of Helper objects to print to standard output - """ - def print_header(self): - header = '''\ -.. Copyright (C) All BPF authors and contributors from 2014 to present. -.. See git log include/uapi/linux/bpf.h in kernel tree for details. -.. -.. %%%LICENSE_START(VERBATIM) -.. Permission is granted to make and distribute verbatim copies of this -.. manual provided the copyright notice and this permission notice are -.. preserved on all copies. -.. -.. Permission is granted to copy and distribute modified versions of this -.. manual under the conditions for verbatim copying, provided that the -.. entire resulting derived work is distributed under the terms of a -.. permission notice identical to this one. -.. -.. Since the Linux kernel and libraries are constantly changing, this -.. manual page may be incorrect or out-of-date. The author(s) assume no -.. responsibility for errors or omissions, or for damages resulting from -.. the use of the information contained herein. The author(s) may not -.. have taken the same level of care in the production of this manual, -.. which is licensed free of charge, as they might when working -.. professionally. -.. -.. Formatted or processed versions of this manual, if unaccompanied by -.. the source, must acknowledge the copyright and authors of this work. -.. %%%LICENSE_END -.. -.. Please do not edit this file. It was generated from the documentation -.. located in file include/uapi/linux/bpf.h of the Linux kernel sources -.. (helpers description), and from scripts/bpf_helpers_doc.py in the same -.. repository (header and footer). - -=========== -BPF-HELPERS -=========== -------------------------------------------------------------------------------- -list of eBPF helper functions -------------------------------------------------------------------------------- - -:Manual section: 7 - -DESCRIPTION -=========== - -The extended Berkeley Packet Filter (eBPF) subsystem consists in programs -written in a pseudo-assembly language, then attached to one of the several -kernel hooks and run in reaction of specific events. This framework differs -from the older, "classic" BPF (or "cBPF") in several aspects, one of them being -the ability to call special functions (or "helpers") from within a program. -These functions are restricted to a white-list of helpers defined in the -kernel. - -These helpers are used by eBPF programs to interact with the system, or with -the context in which they work. For instance, they can be used to print -debugging messages, to get the time since the system was booted, to interact -with eBPF maps, or to manipulate network packets. Since there are several eBPF -program types, and that they do not run in the same context, each program type -can only call a subset of those helpers. - -Due to eBPF conventions, a helper can not have more than five arguments. - -Internally, eBPF programs call directly into the compiled helper functions -without requiring any foreign-function interface. As a result, calling helpers -introduces no overhead, thus offering excellent performance. - -This document is an attempt to list and document the helpers available to eBPF -developers. They are sorted by chronological order (the oldest helpers in the -kernel at the top). - -HELPERS -======= -''' - print(header) - - def print_footer(self): - footer = ''' -EXAMPLES -======== - -Example usage for most of the eBPF helpers listed in this manual page are -available within the Linux kernel sources, at the following locations: - -* *samples/bpf/* -* *tools/testing/selftests/bpf/* - -LICENSE -======= - -eBPF programs can have an associated license, passed along with the bytecode -instructions to the kernel when the programs are loaded. The format for that -string is identical to the one in use for kernel modules (Dual licenses, such -as "Dual BSD/GPL", may be used). Some helper functions are only accessible to -programs that are compatible with the GNU Privacy License (GPL). - -In order to use such helpers, the eBPF program must be loaded with the correct -license string passed (via **attr**) to the **bpf**\ () system call, and this -generally translates into the C source code of the program containing a line -similar to the following: - -:: - - char ____license[] __attribute__((section("license"), used)) = "GPL"; - -IMPLEMENTATION -============== - -This manual page is an effort to document the existing eBPF helper functions. -But as of this writing, the BPF sub-system is under heavy development. New eBPF -program or map types are added, along with new helper functions. Some helpers -are occasionally made available for additional program types. So in spite of -the efforts of the community, this page might not be up-to-date. If you want to -check by yourself what helper functions exist in your kernel, or what types of -programs they can support, here are some files among the kernel tree that you -may be interested in: - -* *include/uapi/linux/bpf.h* is the main BPF header. It contains the full list - of all helper functions, as well as many other BPF definitions including most - of the flags, structs or constants used by the helpers. -* *net/core/filter.c* contains the definition of most network-related helper - functions, and the list of program types from which they can be used. -* *kernel/trace/bpf_trace.c* is the equivalent for most tracing program-related - helpers. -* *kernel/bpf/verifier.c* contains the functions used to check that valid types - of eBPF maps are used with a given helper function. -* *kernel/bpf/* directory contains other files in which additional helpers are - defined (for cgroups, sockmaps, etc.). -* The bpftool utility can be used to probe the availability of helper functions - on the system (as well as supported program and map types, and a number of - other parameters). To do so, run **bpftool feature probe** (see - **bpftool-feature**\ (8) for details). Add the **unprivileged** keyword to - list features available to unprivileged users. - -Compatibility between helper functions and program types can generally be found -in the files where helper functions are defined. Look for the **struct -bpf_func_proto** objects and for functions returning them: these functions -contain a list of helpers that a given program type can call. Note that the -**default:** label of the **switch ... case** used to filter helpers can call -other functions, themselves allowing access to additional helpers. The -requirement for GPL license is also in those **struct bpf_func_proto**. - -Compatibility between helper functions and map types can be found in the -**check_map_func_compatibility**\ () function in file *kernel/bpf/verifier.c*. - -Helper functions that invalidate the checks on **data** and **data_end** -pointers for network processing are listed in function -**bpf_helper_changes_pkt_data**\ () in file *net/core/filter.c*. - -SEE ALSO -======== - -**bpf**\ (2), -**bpftool**\ (8), -**cgroups**\ (7), -**ip**\ (8), -**perf_event_open**\ (2), -**sendmsg**\ (2), -**socket**\ (7), -**tc-bpf**\ (8)''' - print(footer) - - def print_proto(self, helper): - """ - Format function protocol with bold and italics markers. This makes RST - file less readable, but gives nice results in the manual page. - """ - proto = helper.proto_break_down() - - print('**%s %s%s(' % (proto['ret_type'], - proto['ret_star'].replace('*', '\\*'), - proto['name']), - end='') - - comma = '' - for a in proto['args']: - one_arg = '{}{}'.format(comma, a['type']) - if a['name']: - if a['star']: - one_arg += ' {}**\ '.format(a['star'].replace('*', '\\*')) - else: - one_arg += '** ' - one_arg += '*{}*\\ **'.format(a['name']) - comma = ', ' - print(one_arg, end='') - - print(')**') - - def print_one(self, helper): - self.print_proto(helper) - - if (helper.desc): - print('\tDescription') - # Do not strip all newline characters: formatted code at the end of - # a section must be followed by a blank line. - for line in re.sub('\n$', '', helper.desc, count=1).split('\n'): - print('{}{}'.format('\t\t' if line else '', line)) - - if (helper.ret): - print('\tReturn') - for line in helper.ret.rstrip().split('\n'): - print('{}{}'.format('\t\t' if line else '', line)) - - print('') - -class PrinterHelpers(Printer): - """ - A printer for dumping collected information about helpers as C header to - be included from BPF program. - @helpers: array of Helper objects to print to standard output - """ - - type_fwds = [ - 'struct bpf_fib_lookup', - 'struct bpf_sk_lookup', - 'struct bpf_perf_event_data', - 'struct bpf_perf_event_value', - 'struct bpf_pidns_info', - 'struct bpf_redir_neigh', - 'struct bpf_sock', - 'struct bpf_sock_addr', - 'struct bpf_sock_ops', - 'struct bpf_sock_tuple', - 'struct bpf_spin_lock', - 'struct bpf_sysctl', - 'struct bpf_tcp_sock', - 'struct bpf_tunnel_key', - 'struct bpf_xfrm_state', - 'struct linux_binprm', - 'struct pt_regs', - 'struct sk_reuseport_md', - 'struct sockaddr', - 'struct tcphdr', - 'struct seq_file', - 'struct tcp6_sock', - 'struct tcp_sock', - 'struct tcp_timewait_sock', - 'struct tcp_request_sock', - 'struct udp6_sock', - 'struct task_struct', - - 'struct __sk_buff', - 'struct sk_msg_md', - 'struct xdp_md', - 'struct path', - 'struct btf_ptr', - 'struct inode', - 'struct socket', - 'struct file', - ] - known_types = { - '...', - 'void', - 'const void', - 'char', - 'const char', - 'int', - 'long', - 'unsigned long', - - '__be16', - '__be32', - '__wsum', - - 'struct bpf_fib_lookup', - 'struct bpf_perf_event_data', - 'struct bpf_perf_event_value', - 'struct bpf_pidns_info', - 'struct bpf_redir_neigh', - 'struct bpf_sk_lookup', - 'struct bpf_sock', - 'struct bpf_sock_addr', - 'struct bpf_sock_ops', - 'struct bpf_sock_tuple', - 'struct bpf_spin_lock', - 'struct bpf_sysctl', - 'struct bpf_tcp_sock', - 'struct bpf_tunnel_key', - 'struct bpf_xfrm_state', - 'struct linux_binprm', - 'struct pt_regs', - 'struct sk_reuseport_md', - 'struct sockaddr', - 'struct tcphdr', - 'struct seq_file', - 'struct tcp6_sock', - 'struct tcp_sock', - 'struct tcp_timewait_sock', - 'struct tcp_request_sock', - 'struct udp6_sock', - 'struct task_struct', - 'struct path', - 'struct btf_ptr', - 'struct inode', - 'struct socket', - 'struct file', - } - mapped_types = { - 'u8': '__u8', - 'u16': '__u16', - 'u32': '__u32', - 'u64': '__u64', - 's8': '__s8', - 's16': '__s16', - 's32': '__s32', - 's64': '__s64', - 'size_t': 'unsigned long', - 'struct bpf_map': 'void', - 'struct sk_buff': 'struct __sk_buff', - 'const struct sk_buff': 'const struct __sk_buff', - 'struct sk_msg_buff': 'struct sk_msg_md', - 'struct xdp_buff': 'struct xdp_md', - } - # Helpers overloaded for different context types. - overloaded_helpers = [ - 'bpf_get_socket_cookie', - 'bpf_sk_assign', - ] - - def print_header(self): - header = '''\ -/* This is auto-generated file. See bpf_helpers_doc.py for details. */ - -/* Forward declarations of BPF structs */''' - - print(header) - for fwd in self.type_fwds: - print('%s;' % fwd) - print('') - - def print_footer(self): - footer = '' - print(footer) - - def map_type(self, t): - if t in self.known_types: - return t - if t in self.mapped_types: - return self.mapped_types[t] - print("Unrecognized type '%s', please add it to known types!" % t, - file=sys.stderr) - sys.exit(1) - - seen_helpers = set() - - def print_one(self, helper): - proto = helper.proto_break_down() - - if proto['name'] in self.seen_helpers: - return - self.seen_helpers.add(proto['name']) - - print('/*') - print(" * %s" % proto['name']) - print(" *") - if (helper.desc): - # Do not strip all newline characters: formatted code at the end of - # a section must be followed by a blank line. - for line in re.sub('\n$', '', helper.desc, count=1).split('\n'): - print(' *{}{}'.format(' \t' if line else '', line)) - - if (helper.ret): - print(' *') - print(' * Returns') - for line in helper.ret.rstrip().split('\n'): - print(' *{}{}'.format(' \t' if line else '', line)) - - print(' */') - print('static %s %s(*%s)(' % (self.map_type(proto['ret_type']), - proto['ret_star'], proto['name']), end='') - comma = '' - for i, a in enumerate(proto['args']): - t = a['type'] - n = a['name'] - if proto['name'] in self.overloaded_helpers and i == 0: - t = 'void' - n = 'ctx' - one_arg = '{}{}'.format(comma, self.map_type(t)) - if n: - if a['star']: - one_arg += ' {}'.format(a['star']) - else: - one_arg += ' ' - one_arg += '{}'.format(n) - comma = ', ' - print(one_arg, end='') - - print(') = (void *) %d;' % len(self.seen_helpers)) - print('') - -############################################################################### - -# If script is launched from scripts/ from kernel tree and can access -# ../include/uapi/linux/bpf.h, use it as a default name for the file to parse, -# otherwise the --filename argument will be required from the command line. -script = os.path.abspath(sys.argv[0]) -linuxRoot = os.path.dirname(os.path.dirname(script)) -bpfh = os.path.join(linuxRoot, 'include/uapi/linux/bpf.h') - -argParser = argparse.ArgumentParser(description=""" -Parse eBPF header file and generate documentation for eBPF helper functions. -The RST-formatted output produced can be turned into a manual page with the -rst2man utility. -""") -argParser.add_argument('--header', action='store_true', - help='generate C header file') -if (os.path.isfile(bpfh)): - argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h', - default=bpfh) -else: - argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h') -args = argParser.parse_args() - -# Parse file. -headerParser = HeaderParser(args.filename) -headerParser.run() - -# Print formatted output to standard output. -if args.header: - printer = PrinterHelpers(headerParser.helpers) -else: - printer = PrinterRST(headerParser.helpers) -printer.print_all() -- cgit v1.2.3-71-gd317 From a67882a221e348ab1c925b47efdfec8b11272d3f Mon Sep 17 00:00:00 2001 From: Joe Stringer Date: Tue, 2 Mar 2021 09:19:42 -0800 Subject: scripts/bpf: Add syscall commands printer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new target to bpf_doc.py to support generating the list of syscall commands directly from the UAPI headers. Assuming that developer submissions keep the main header up to date, this should allow the man pages to be automatically generated based on the latest API changes rather than requiring someone to separately go back through the API and describe each command. Signed-off-by: Joe Stringer Signed-off-by: Alexei Starovoitov Reviewed-by: Quentin Monnet Acked-by: Toke Høiland-Jørgensen Link: https://lore.kernel.org/bpf/20210302171947.2268128-11-joe@cilium.io --- scripts/bpf_doc.py | 100 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index 5a4f68aab335..2d94025b38e9 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -14,6 +14,9 @@ import sys, os class NoHelperFound(BaseException): pass +class NoSyscallCommandFound(BaseException): + pass + class ParsingError(BaseException): def __init__(self, line='', reader=None): if reader: @@ -23,18 +26,27 @@ class ParsingError(BaseException): else: BaseException.__init__(self, 'Error parsing line: %s' % line) -class Helper(object): + +class APIElement(object): """ - An object representing the description of an eBPF helper function. - @proto: function prototype of the helper function - @desc: textual description of the helper function - @ret: description of the return value of the helper function + An object representing the description of an aspect of the eBPF API. + @proto: prototype of the API symbol + @desc: textual description of the symbol + @ret: (optional) description of any associated return value """ def __init__(self, proto='', desc='', ret=''): self.proto = proto self.desc = desc self.ret = ret + +class Helper(APIElement): + """ + An object representing the description of an eBPF helper function. + @proto: function prototype of the helper function + @desc: textual description of the helper function + @ret: description of the return value of the helper function + """ def proto_break_down(self): """ Break down helper function protocol into smaller chunks: return type, @@ -61,6 +73,7 @@ class Helper(object): return res + class HeaderParser(object): """ An object used to parse a file in order to extract the documentation of a @@ -73,6 +86,13 @@ class HeaderParser(object): self.reader = open(filename, 'r') self.line = '' self.helpers = [] + self.commands = [] + + def parse_element(self): + proto = self.parse_symbol() + desc = self.parse_desc() + ret = self.parse_ret() + return APIElement(proto=proto, desc=desc, ret=ret) def parse_helper(self): proto = self.parse_proto() @@ -80,6 +100,18 @@ class HeaderParser(object): ret = self.parse_ret() return Helper(proto=proto, desc=desc, ret=ret) + def parse_symbol(self): + p = re.compile(' \* ?(.+)$') + capture = p.match(self.line) + if not capture: + raise NoSyscallCommandFound + end_re = re.compile(' \* ?NOTES$') + end = end_re.match(self.line) + if end: + raise NoSyscallCommandFound + self.line = self.reader.readline() + return capture.group(1) + def parse_proto(self): # Argument can be of shape: # - "void" @@ -141,16 +173,29 @@ class HeaderParser(object): break return ret - def run(self): - # Advance to start of helper function descriptions. - offset = self.reader.read().find('* Start of BPF helper function descriptions:') + def seek_to(self, target, help_message): + self.reader.seek(0) + offset = self.reader.read().find(target) if offset == -1: - raise Exception('Could not find start of eBPF helper descriptions list') + raise Exception(help_message) self.reader.seek(offset) self.reader.readline() self.reader.readline() self.line = self.reader.readline() + def parse_syscall(self): + self.seek_to('* DOC: eBPF Syscall Commands', + 'Could not find start of eBPF syscall descriptions list') + while True: + try: + command = self.parse_element() + self.commands.append(command) + except NoSyscallCommandFound: + break + + def parse_helpers(self): + self.seek_to('* Start of BPF helper function descriptions:', + 'Could not find start of eBPF helper descriptions list') while True: try: helper = self.parse_helper() @@ -158,6 +203,9 @@ class HeaderParser(object): except NoHelperFound: break + def run(self): + self.parse_syscall() + self.parse_helpers() self.reader.close() ############################################################################### @@ -420,6 +468,37 @@ SEE ALSO self.print_elem(helper) +class PrinterSyscallRST(PrinterRST): + """ + A printer for dumping collected information about the syscall API as a + ReStructured Text page compatible with the rst2man program, which can be + used to generate a manual page for the syscall. + @parser: A HeaderParser with APIElement objects to print to standard + output + """ + def __init__(self, parser): + self.elements = parser.commands + + def print_header(self): + header = '''\ +=== +bpf +=== +------------------------------------------------------------------------------- +Perform a command on an extended BPF object +------------------------------------------------------------------------------- + +:Manual section: 2 + +COMMANDS +======== +''' + PrinterRST.print_license(self) + print(header) + + def print_one(self, command): + print('**%s**' % (command.proto)) + self.print_elem(command) class PrinterHelpers(Printer): @@ -620,6 +699,7 @@ bpfh = os.path.join(linuxRoot, 'include/uapi/linux/bpf.h') printers = { 'helpers': PrinterHelpersRST, + 'syscall': PrinterSyscallRST, } argParser = argparse.ArgumentParser(description=""" @@ -644,6 +724,8 @@ headerParser.run() # Print formatted output to standard output. if args.header: + if args.target != 'helpers': + raise NotImplementedError('Only helpers header generation is supported') printer = PrinterHelpers(headerParser) else: printer = printers[args.target](headerParser) -- cgit v1.2.3-71-gd317 From a746fe32cd362c8bba523a97123129ede4f5b75a Mon Sep 17 00:00:00 2001 From: Aditya Srivastava Date: Thu, 25 Feb 2021 20:20:33 +0530 Subject: scripts: kernel-doc: fix typedef support for struct/union parsing Currently, there are ~1290 occurrences in 447 files in the kernel tree 'typedef struct/union' syntax for defining some struct/union. However, kernel-doc currently does not support that syntax. Of the ~1290 occurrences, there are four occurrences in ./include/linux/zstd.h with typedef struct/union syntax and a preceding kernel-doc; all other occurrences have no preceding kernel-doc. Add support for parsing struct/union following this syntax. Signed-off-by: Aditya Srivastava Link: https://lore.kernel.org/r/20210225145033.11431-1-yashsri421@gmail.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 8b5bc7bf4bb8..68df17877384 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1201,12 +1201,23 @@ sub dump_union($$) { sub dump_struct($$) { my $x = shift; my $file = shift; + my $decl_type; + my $members; + my $type = qr{struct|union}; + # For capturing struct/union definition body, i.e. "{members*}qualifiers*" + my $definition_body = qr{\{(.*)\}(?:\s*(?:__packed|__aligned|____cacheline_aligned_in_smp|____cacheline_aligned|__attribute__\s*\(\([a-z0-9,_\s\(\)]*\)\)))*}; - if ($x =~ /(struct|union)\s+(\w+)\s*\{(.*)\}(\s*(__packed|__aligned|____cacheline_aligned_in_smp|____cacheline_aligned|__attribute__\s*\(\([a-z0-9,_\s\(\)]*\)\)))*/) { - my $decl_type = $1; + if ($x =~ /($type)\s+(\w+)\s*$definition_body/) { + $decl_type = $1; $declaration_name = $2; - my $members = $3; + $members = $3; + } elsif ($x =~ /typedef\s+($type)\s*$definition_body\s*(\w+)\s*;/) { + $decl_type = $1; + $declaration_name = $3; + $members = $2; + } + if ($members) { if ($identifier ne $declaration_name) { print STDERR "${file}:$.: warning: expecting prototype for $decl_type $identifier. Prototype was for $decl_type $declaration_name instead\n"; return; -- cgit v1.2.3-71-gd317 From 52178ce01335d9d76611c3a5198b8778cb9b03f5 Mon Sep 17 00:00:00 2001 From: Dwaipayan Ray Date: Fri, 26 Feb 2021 15:08:26 +0530 Subject: checkpatch: add verbose mode Add a new verbose mode to checkpatch.pl to emit additional verbose test descriptions. The verbose mode is optional and can be enabled by the flag -v or --verbose. The test descriptions are parsed from the checkpatch documentation file at `Documentation/dev-tools/checkpatch.rst`. The test descriptions in the docs are kept in a fixed format grouped by usage. Some examples of this format are: **LINE_SPACING** Vertical space is wasted given the limited number of lines an editor window can display when multiple blank lines are used. **MISSING_SIGN_OFF** The patch is missing a Signed-off-by line. A signed-off-by line should be added according to Developer's certificate of Origin. To avoid lengthy output, the verbose description is printed only for the first instance of a particular message type. The --verbose option cannot be used along with the --terse option. Verbose mode can be used with the --list-types option. The --list-types output also supports color coding now. Signed-off-by: Dwaipayan Ray Link: https://lore.kernel.org/r/20210226093827.12700-3-dwaipayanray1@gmail.com Signed-off-by: Jonathan Corbet --- scripts/checkpatch.pl | 133 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 113 insertions(+), 20 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index df8b23dc1eb0..f42e5ba16d9b 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -23,6 +23,9 @@ my $V = '0.32'; use Getopt::Long qw(:config no_auto_abbrev); my $quiet = 0; +my $verbose = 0; +my %verbose_messages = (); +my %verbose_emitted = (); my $tree = 1; my $chk_signoff = 1; my $chk_patch = 1; @@ -61,6 +64,7 @@ my $spelling_file = "$D/spelling.txt"; my $codespell = 0; my $codespellfile = "/usr/share/codespell/dictionary.txt"; my $conststructsfile = "$D/const_structs.checkpatch"; +my $docsfile = "$D/../Documentation/dev-tools/checkpatch.rst"; my $typedefsfile; my $color = "auto"; my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE @@ -78,6 +82,7 @@ Version: $V Options: -q, --quiet quiet + -v, --verbose verbose mode --no-tree run without a kernel tree --no-signoff do not check for 'Signed-off-by' line --patch treat FILE as patchfile (default) @@ -158,15 +163,51 @@ sub list_types { my $text = <$script>; close($script); - my @types = (); + my %types = (); # Also catch when type or level is passed through a variable - for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { - push (@types, $_); + while ($text =~ /(?:(\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { + if (defined($1)) { + if (exists($types{$2})) { + $types{$2} .= ",$1" if ($types{$2} ne $1); + } else { + $types{$2} = $1; + } + } else { + $types{$2} = "UNDETERMINED"; + } } - @types = sort(uniq(@types)); + print("#\tMessage type\n\n"); - foreach my $type (@types) { + if ($color) { + print(" ( Color coding: "); + print(RED . "ERROR" . RESET); + print(" | "); + print(YELLOW . "WARNING" . RESET); + print(" | "); + print(GREEN . "CHECK" . RESET); + print(" | "); + print("Multiple levels / Undetermined"); + print(" )\n\n"); + } + + foreach my $type (sort keys %types) { + my $orig_type = $type; + if ($color) { + my $level = $types{$type}; + if ($level eq "ERROR") { + $type = RED . $type . RESET; + } elsif ($level eq "WARN") { + $type = YELLOW . $type . RESET; + } elsif ($level eq "CHK") { + $type = GREEN . $type . RESET; + } + } print(++$count . "\t" . $type . "\n"); + if ($verbose && exists($verbose_messages{$orig_type})) { + my $message = $verbose_messages{$orig_type}; + $message =~ s/\n/\n\t/g; + print("\t" . $message . "\n\n"); + } } exit($exitcode); @@ -198,6 +239,46 @@ if (-f $conf) { unshift(@ARGV, @conf_args) if @conf_args; } +sub load_docs { + open(my $docs, '<', "$docsfile") + or warn "$P: Can't read the documentation file $docsfile $!\n"; + + my $type = ''; + my $desc = ''; + my $in_desc = 0; + + while (<$docs>) { + chomp; + my $line = $_; + $line =~ s/\s+$//; + + if ($line =~ /^\s*\*\*(.+)\*\*$/) { + if ($desc ne '') { + $verbose_messages{$type} = trim($desc); + } + $type = $1; + $desc = ''; + $in_desc = 1; + } elsif ($in_desc) { + if ($line =~ /^(?:\s{4,}|$)/) { + $line =~ s/^\s{4}//; + $desc .= $line; + $desc .= "\n"; + } else { + $verbose_messages{$type} = trim($desc); + $type = ''; + $desc = ''; + $in_desc = 0; + } + } + } + + if ($desc ne '') { + $verbose_messages{$type} = trim($desc); + } + close($docs); +} + # Perl's Getopt::Long allows options to take optional arguments after a space. # Prevent --color by itself from consuming other arguments foreach (@ARGV) { @@ -208,6 +289,7 @@ foreach (@ARGV) { GetOptions( 'q|quiet+' => \$quiet, + 'v|verbose!' => \$verbose, 'tree!' => \$tree, 'signoff!' => \$chk_signoff, 'patch!' => \$chk_patch, @@ -247,13 +329,27 @@ GetOptions( help(0) if ($help); +die "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix)); +die "$P: --verbose cannot be used with --terse\n" if ($verbose && $terse); + +if ($color =~ /^[01]$/) { + $color = !$color; +} elsif ($color =~ /^always$/i) { + $color = 1; +} elsif ($color =~ /^never$/i) { + $color = 0; +} elsif ($color =~ /^auto$/i) { + $color = (-t STDOUT); +} else { + die "$P: Invalid color mode: $color\n"; +} + +load_docs() if ($verbose); list_types(0) if ($list_types); $fix = 1 if ($fix_inplace); $check_orig = $check; -die "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix)); - my $exit = 0; my $perl_version_ok = 1; @@ -268,18 +364,6 @@ if ($#ARGV < 0) { push(@ARGV, '-'); } -if ($color =~ /^[01]$/) { - $color = !$color; -} elsif ($color =~ /^always$/i) { - $color = 1; -} elsif ($color =~ /^never$/i) { - $color = 0; -} elsif ($color =~ /^auto$/i) { - $color = (-t STDOUT); -} else { - die "$P: Invalid color mode: $color\n"; -} - # skip TAB size 1 to avoid additional checks on $tabsize - 1 die "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2); @@ -2209,7 +2293,16 @@ sub report { splice(@lines, 1, 1); $output = join("\n", @lines); } - $output = (split('\n', $output))[0] . "\n" if ($terse); + + if ($terse) { + $output = (split('\n', $output))[0] . "\n"; + } + + if ($verbose && exists($verbose_messages{$type}) && + !exists($verbose_emitted{$type})) { + $output .= $verbose_messages{$type} . "\n\n"; + $verbose_emitted{$type} = 1; + } push(our @report, $output); -- cgit v1.2.3-71-gd317 From 3fb0fdb3bbe7aed495109b3296b06c2409734023 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Sat, 13 Feb 2021 11:19:44 -0800 Subject: x86/stackprotector/32: Make the canary into a regular percpu variable On 32-bit kernels, the stackprotector canary is quite nasty -- it is stored at %gs:(20), which is nasty because 32-bit kernels use %fs for percpu storage. It's even nastier because it means that whether %gs contains userspace state or kernel state while running kernel code depends on whether stackprotector is enabled (this is CONFIG_X86_32_LAZY_GS), and this setting radically changes the way that segment selectors work. Supporting both variants is a maintenance and testing mess. Merely rearranging so that percpu and the stack canary share the same segment would be messy as the 32-bit percpu address layout isn't currently compatible with putting a variable at a fixed offset. Fortunately, GCC 8.1 added options that allow the stack canary to be accessed as %fs:__stack_chk_guard, effectively turning it into an ordinary percpu variable. This lets us get rid of all of the code to manage the stack canary GDT descriptor and the CONFIG_X86_32_LAZY_GS mess. (That name is special. We could use any symbol we want for the %fs-relative mode, but for CONFIG_SMP=n, gcc refuses to let us use any name other than __stack_chk_guard.) Forcibly disable stackprotector on older compilers that don't support the new options and turn the stack canary into a percpu variable. The "lazy GS" approach is now used for all 32-bit configurations. Also makes load_gs_index() work on 32-bit kernels. On 64-bit kernels, it loads the GS selector and updates the user GSBASE accordingly. (This is unchanged.) On 32-bit kernels, it loads the GS selector and updates GSBASE, which is now always the user base. This means that the overall effect is the same on 32-bit and 64-bit, which avoids some ifdeffery. [ bp: Massage commit message. ] Signed-off-by: Andy Lutomirski Signed-off-by: Borislav Petkov Link: https://lkml.kernel.org/r/c0ff7dba14041c7e5d1cae5d4df052f03759bef3.1613243844.git.luto@kernel.org --- arch/x86/Kconfig | 7 +-- arch/x86/Makefile | 8 ++++ arch/x86/entry/entry_32.S | 56 ++-------------------- arch/x86/include/asm/processor.h | 15 ++---- arch/x86/include/asm/ptrace.h | 5 +- arch/x86/include/asm/segment.h | 30 ++++-------- arch/x86/include/asm/stackprotector.h | 79 +++++++------------------------ arch/x86/include/asm/suspend_32.h | 6 +-- arch/x86/kernel/asm-offsets_32.c | 5 -- arch/x86/kernel/cpu/common.c | 5 +- arch/x86/kernel/doublefault_32.c | 4 +- arch/x86/kernel/head_32.S | 18 +------ arch/x86/kernel/setup_percpu.c | 1 - arch/x86/kernel/tls.c | 8 +--- arch/x86/lib/insn-eval.c | 4 -- arch/x86/platform/pvh/head.S | 14 ------ arch/x86/power/cpu.c | 6 +-- arch/x86/xen/enlighten_pv.c | 1 - scripts/gcc-x86_32-has-stack-protector.sh | 6 ++- 19 files changed, 60 insertions(+), 218 deletions(-) (limited to 'scripts') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 2792879d398e..10cc6199bf67 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -360,10 +360,6 @@ config X86_64_SMP def_bool y depends on X86_64 && SMP -config X86_32_LAZY_GS - def_bool y - depends on X86_32 && !STACKPROTECTOR - config ARCH_SUPPORTS_UPROBES def_bool y @@ -386,7 +382,8 @@ config CC_HAS_SANE_STACKPROTECTOR default $(success,$(srctree)/scripts/gcc-x86_32-has-stack-protector.sh $(CC)) help We have to make sure stack protector is unconditionally disabled if - the compiler produces broken code. + the compiler produces broken code or if it does not let us control + the segment on 32-bit kernels. menu "Processor type and features" diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 2d6d5a28c3bf..952f534ad7b7 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -79,6 +79,14 @@ ifeq ($(CONFIG_X86_32),y) # temporary until string.h is fixed KBUILD_CFLAGS += -ffreestanding + + ifeq ($(CONFIG_STACKPROTECTOR),y) + ifeq ($(CONFIG_SMP),y) + KBUILD_CFLAGS += -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard + else + KBUILD_CFLAGS += -mstack-protector-guard=global + endif + endif else BITS := 64 UTS_MACHINE := x86_64 diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index df8c017e6161..eb0cb662bca5 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S @@ -20,7 +20,7 @@ * 1C(%esp) - %ds * 20(%esp) - %es * 24(%esp) - %fs - * 28(%esp) - %gs saved iff !CONFIG_X86_32_LAZY_GS + * 28(%esp) - unused -- was %gs on old stackprotector kernels * 2C(%esp) - orig_eax * 30(%esp) - %eip * 34(%esp) - %cs @@ -56,14 +56,9 @@ /* * User gs save/restore * - * %gs is used for userland TLS and kernel only uses it for stack - * canary which is required to be at %gs:20 by gcc. Read the comment - * at the top of stackprotector.h for more info. - * - * Local labels 98 and 99 are used. + * This is leftover junk from CONFIG_X86_32_LAZY_GS. A subsequent patch + * will remove it entirely. */ -#ifdef CONFIG_X86_32_LAZY_GS - /* unfortunately push/pop can't be no-op */ .macro PUSH_GS pushl $0 @@ -86,49 +81,6 @@ .macro SET_KERNEL_GS reg .endm -#else /* CONFIG_X86_32_LAZY_GS */ - -.macro PUSH_GS - pushl %gs -.endm - -.macro POP_GS pop=0 -98: popl %gs - .if \pop <> 0 - add $\pop, %esp - .endif -.endm -.macro POP_GS_EX -.pushsection .fixup, "ax" -99: movl $0, (%esp) - jmp 98b -.popsection - _ASM_EXTABLE(98b, 99b) -.endm - -.macro PTGS_TO_GS -98: mov PT_GS(%esp), %gs -.endm -.macro PTGS_TO_GS_EX -.pushsection .fixup, "ax" -99: movl $0, PT_GS(%esp) - jmp 98b -.popsection - _ASM_EXTABLE(98b, 99b) -.endm - -.macro GS_TO_REG reg - movl %gs, \reg -.endm -.macro REG_TO_PTGS reg - movl \reg, PT_GS(%esp) -.endm -.macro SET_KERNEL_GS reg - movl $(__KERNEL_STACK_CANARY), \reg - movl \reg, %gs -.endm - -#endif /* CONFIG_X86_32_LAZY_GS */ /* Unconditionally switch to user cr3 */ .macro SWITCH_TO_USER_CR3 scratch_reg:req @@ -779,7 +731,7 @@ SYM_CODE_START(__switch_to_asm) #ifdef CONFIG_STACKPROTECTOR movl TASK_stack_canary(%edx), %ebx - movl %ebx, PER_CPU_VAR(stack_canary)+stack_canary_offset + movl %ebx, PER_CPU_VAR(__stack_chk_guard) #endif #ifdef CONFIG_RETPOLINE diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index dc6d149bf851..bac2a42796c4 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -439,6 +439,9 @@ struct fixed_percpu_data { * GCC hardcodes the stack canary as %gs:40. Since the * irq_stack is the object at %gs:0, we reserve the bottom * 48 bytes of the irq stack for the canary. + * + * Once we are willing to require -mstack-protector-guard-symbol= + * support for x86_64 stackprotector, we can get rid of this. */ char gs_base[40]; unsigned long stack_canary; @@ -460,17 +463,7 @@ extern asmlinkage void ignore_sysret(void); void current_save_fsgs(void); #else /* X86_64 */ #ifdef CONFIG_STACKPROTECTOR -/* - * Make sure stack canary segment base is cached-aligned: - * "For Intel Atom processors, avoid non zero segment base address - * that is not aligned to cache line boundary at all cost." - * (Optim Ref Manual Assembly/Compiler Coding Rule 15.) - */ -struct stack_canary { - char __pad[20]; /* canary at %gs:20 */ - unsigned long canary; -}; -DECLARE_PER_CPU_ALIGNED(struct stack_canary, stack_canary); +DECLARE_PER_CPU(unsigned long, __stack_chk_guard); #endif DECLARE_PER_CPU(struct irq_stack *, hardirq_stack_ptr); DECLARE_PER_CPU(struct irq_stack *, softirq_stack_ptr); diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index d8324a236696..b2c4c12d237c 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -37,7 +37,10 @@ struct pt_regs { unsigned short __esh; unsigned short fs; unsigned short __fsh; - /* On interrupt, gs and __gsh store the vector number. */ + /* + * On interrupt, gs and __gsh store the vector number. They never + * store gs any more. + */ unsigned short gs; unsigned short __gsh; /* On interrupt, this is the error code. */ diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index 7fdd4facfce7..72044026eb3c 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h @@ -95,7 +95,7 @@ * * 26 - ESPFIX small SS * 27 - per-cpu [ offset to per-cpu data area ] - * 28 - stack_canary-20 [ for stack protector ] <=== cacheline #8 + * 28 - unused * 29 - unused * 30 - unused * 31 - TSS for double fault handler @@ -118,7 +118,6 @@ #define GDT_ENTRY_ESPFIX_SS 26 #define GDT_ENTRY_PERCPU 27 -#define GDT_ENTRY_STACK_CANARY 28 #define GDT_ENTRY_DOUBLEFAULT_TSS 31 @@ -158,12 +157,6 @@ # define __KERNEL_PERCPU 0 #endif -#ifdef CONFIG_STACKPROTECTOR -# define __KERNEL_STACK_CANARY (GDT_ENTRY_STACK_CANARY*8) -#else -# define __KERNEL_STACK_CANARY 0 -#endif - #else /* 64-bit: */ #include @@ -364,22 +357,15 @@ static inline void __loadsegment_fs(unsigned short value) asm("mov %%" #seg ",%0":"=r" (value) : : "memory") /* - * x86-32 user GS accessors: + * x86-32 user GS accessors. This is ugly and could do with some cleaning up. */ #ifdef CONFIG_X86_32 -# ifdef CONFIG_X86_32_LAZY_GS -# define get_user_gs(regs) (u16)({ unsigned long v; savesegment(gs, v); v; }) -# define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v)) -# define task_user_gs(tsk) ((tsk)->thread.gs) -# define lazy_save_gs(v) savesegment(gs, (v)) -# define lazy_load_gs(v) loadsegment(gs, (v)) -# else /* X86_32_LAZY_GS */ -# define get_user_gs(regs) (u16)((regs)->gs) -# define set_user_gs(regs, v) do { (regs)->gs = (v); } while (0) -# define task_user_gs(tsk) (task_pt_regs(tsk)->gs) -# define lazy_save_gs(v) do { } while (0) -# define lazy_load_gs(v) do { } while (0) -# endif /* X86_32_LAZY_GS */ +# define get_user_gs(regs) (u16)({ unsigned long v; savesegment(gs, v); v; }) +# define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v)) +# define task_user_gs(tsk) ((tsk)->thread.gs) +# define lazy_save_gs(v) savesegment(gs, (v)) +# define lazy_load_gs(v) loadsegment(gs, (v)) +# define load_gs_index(v) loadsegment(gs, (v)) #endif /* X86_32 */ #endif /* !__ASSEMBLY__ */ diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h index 7fb482f0f25b..b6ffe58c70fa 100644 --- a/arch/x86/include/asm/stackprotector.h +++ b/arch/x86/include/asm/stackprotector.h @@ -5,30 +5,23 @@ * Stack protector works by putting predefined pattern at the start of * the stack frame and verifying that it hasn't been overwritten when * returning from the function. The pattern is called stack canary - * and unfortunately gcc requires it to be at a fixed offset from %gs. - * On x86_64, the offset is 40 bytes and on x86_32 20 bytes. x86_64 - * and x86_32 use segment registers differently and thus handles this - * requirement differently. + * and unfortunately gcc historically required it to be at a fixed offset + * from the percpu segment base. On x86_64, the offset is 40 bytes. * - * On x86_64, %gs is shared by percpu area and stack canary. All - * percpu symbols are zero based and %gs points to the base of percpu - * area. The first occupant of the percpu area is always - * fixed_percpu_data which contains stack_canary at offset 40. Userland - * %gs is always saved and restored on kernel entry and exit using - * swapgs, so stack protector doesn't add any complexity there. + * The same segment is shared by percpu area and stack canary. On + * x86_64, percpu symbols are zero based and %gs (64-bit) points to the + * base of percpu area. The first occupant of the percpu area is always + * fixed_percpu_data which contains stack_canary at the approproate + * offset. On x86_32, the stack canary is just a regular percpu + * variable. * - * On x86_32, it's slightly more complicated. As in x86_64, %gs is - * used for userland TLS. Unfortunately, some processors are much - * slower at loading segment registers with different value when - * entering and leaving the kernel, so the kernel uses %fs for percpu - * area and manages %gs lazily so that %gs is switched only when - * necessary, usually during task switch. + * Putting percpu data in %fs on 32-bit is a minor optimization compared to + * using %gs. Since 32-bit userspace normally has %fs == 0, we are likely + * to load 0 into %fs on exit to usermode, whereas with percpu data in + * %gs, we are likely to load a non-null %gs on return to user mode. * - * As gcc requires the stack canary at %gs:20, %gs can't be managed - * lazily if stack protector is enabled, so the kernel saves and - * restores userland %gs on kernel entry and exit. This behavior is - * controlled by CONFIG_X86_32_LAZY_GS and accessors are defined in - * system.h to hide the details. + * Once we are willing to require GCC 8.1 or better for 64-bit stackprotector + * support, we can remove some of this complexity. */ #ifndef _ASM_STACKPROTECTOR_H @@ -44,14 +37,6 @@ #include #include -/* - * 24 byte read-only segment initializer for stack canary. Linker - * can't handle the address bit shifting. Address will be set in - * head_32 for boot CPU and setup_per_cpu_areas() for others. - */ -#define GDT_STACK_CANARY_INIT \ - [GDT_ENTRY_STACK_CANARY] = GDT_ENTRY_INIT(0x4090, 0, 0x18), - /* * Initialize the stackprotector canary value. * @@ -86,7 +71,7 @@ static __always_inline void boot_init_stack_canary(void) #ifdef CONFIG_X86_64 this_cpu_write(fixed_percpu_data.stack_canary, canary); #else - this_cpu_write(stack_canary.canary, canary); + this_cpu_write(__stack_chk_guard, canary); #endif } @@ -95,48 +80,16 @@ static inline void cpu_init_stack_canary(int cpu, struct task_struct *idle) #ifdef CONFIG_X86_64 per_cpu(fixed_percpu_data.stack_canary, cpu) = idle->stack_canary; #else - per_cpu(stack_canary.canary, cpu) = idle->stack_canary; -#endif -} - -static inline void setup_stack_canary_segment(int cpu) -{ -#ifdef CONFIG_X86_32 - unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu); - struct desc_struct *gdt_table = get_cpu_gdt_rw(cpu); - struct desc_struct desc; - - desc = gdt_table[GDT_ENTRY_STACK_CANARY]; - set_desc_base(&desc, canary); - write_gdt_entry(gdt_table, GDT_ENTRY_STACK_CANARY, &desc, DESCTYPE_S); -#endif -} - -static inline void load_stack_canary_segment(void) -{ -#ifdef CONFIG_X86_32 - asm("mov %0, %%gs" : : "r" (__KERNEL_STACK_CANARY) : "memory"); + per_cpu(__stack_chk_guard, cpu) = idle->stack_canary; #endif } #else /* STACKPROTECTOR */ -#define GDT_STACK_CANARY_INIT - /* dummy boot_init_stack_canary() is defined in linux/stackprotector.h */ -static inline void setup_stack_canary_segment(int cpu) -{ } - static inline void cpu_init_stack_canary(int cpu, struct task_struct *idle) { } -static inline void load_stack_canary_segment(void) -{ -#ifdef CONFIG_X86_32 - asm volatile ("mov %0, %%gs" : : "r" (0)); -#endif -} - #endif /* STACKPROTECTOR */ #endif /* _ASM_STACKPROTECTOR_H */ diff --git a/arch/x86/include/asm/suspend_32.h b/arch/x86/include/asm/suspend_32.h index fdbd9d7b7bca..7b132d0312eb 100644 --- a/arch/x86/include/asm/suspend_32.h +++ b/arch/x86/include/asm/suspend_32.h @@ -13,12 +13,10 @@ /* image of the saved processor state */ struct saved_context { /* - * On x86_32, all segment registers, with the possible exception of - * gs, are saved at kernel entry in pt_regs. + * On x86_32, all segment registers except gs are saved at kernel + * entry in pt_regs. */ -#ifdef CONFIG_X86_32_LAZY_GS u16 gs; -#endif unsigned long cr0, cr2, cr3, cr4; u64 misc_enable; bool misc_enable_saved; diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c index 6e043f295a60..2b411cd00a4e 100644 --- a/arch/x86/kernel/asm-offsets_32.c +++ b/arch/x86/kernel/asm-offsets_32.c @@ -53,11 +53,6 @@ void foo(void) offsetof(struct cpu_entry_area, tss.x86_tss.sp1) - offsetofend(struct cpu_entry_area, entry_stack_page.stack)); -#ifdef CONFIG_STACKPROTECTOR - BLANK(); - OFFSET(stack_canary_offset, stack_canary, canary); -#endif - BLANK(); DEFINE(EFI_svam, offsetof(efi_runtime_services_t, set_virtual_address_map)); } diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index ab640abe26b6..23cb9d68a56d 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -161,7 +161,6 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { [GDT_ENTRY_ESPFIX_SS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), [GDT_ENTRY_PERCPU] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), - GDT_STACK_CANARY_INIT #endif } }; EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); @@ -599,7 +598,6 @@ void load_percpu_segment(int cpu) __loadsegment_simple(gs, 0); wrmsrl(MSR_GS_BASE, cpu_kernelmode_gs_base(cpu)); #endif - load_stack_canary_segment(); } #ifdef CONFIG_X86_32 @@ -1796,7 +1794,8 @@ DEFINE_PER_CPU(unsigned long, cpu_current_top_of_stack) = EXPORT_PER_CPU_SYMBOL(cpu_current_top_of_stack); #ifdef CONFIG_STACKPROTECTOR -DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary); +DEFINE_PER_CPU(unsigned long, __stack_chk_guard); +EXPORT_PER_CPU_SYMBOL(__stack_chk_guard); #endif #endif /* CONFIG_X86_64 */ diff --git a/arch/x86/kernel/doublefault_32.c b/arch/x86/kernel/doublefault_32.c index 759d392cbe9f..d1d49e3d536b 100644 --- a/arch/x86/kernel/doublefault_32.c +++ b/arch/x86/kernel/doublefault_32.c @@ -100,9 +100,7 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct doublefault_stack, doublefault_stack) = { .ss = __KERNEL_DS, .ds = __USER_DS, .fs = __KERNEL_PERCPU, -#ifndef CONFIG_X86_32_LAZY_GS - .gs = __KERNEL_STACK_CANARY, -#endif + .gs = 0, .__cr3 = __pa_nodebug(swapper_pg_dir), }, diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 7ed84c282233..67f590425d90 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -318,8 +318,8 @@ SYM_FUNC_START(startup_32_smp) movl $(__KERNEL_PERCPU), %eax movl %eax,%fs # set this cpu's percpu - movl $(__KERNEL_STACK_CANARY),%eax - movl %eax,%gs + xorl %eax,%eax + movl %eax,%gs # clear possible garbage in %gs xorl %eax,%eax # Clear LDT lldt %ax @@ -339,20 +339,6 @@ SYM_FUNC_END(startup_32_smp) */ __INIT setup_once: -#ifdef CONFIG_STACKPROTECTOR - /* - * Configure the stack canary. The linker can't handle this by - * relocation. Manually set base address in stack canary - * segment descriptor. - */ - movl $gdt_page,%eax - movl $stack_canary,%ecx - movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax) - shrl $16, %ecx - movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax) - movb %ch, 8 * GDT_ENTRY_STACK_CANARY + 7(%eax) -#endif - andl $0,setup_once_ref /* Once is enough, thanks */ ret diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index fd945ce78554..0941d2f44f2a 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -224,7 +224,6 @@ void __init setup_per_cpu_areas(void) per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu); per_cpu(cpu_number, cpu) = cpu; setup_percpu_segment(cpu); - setup_stack_canary_segment(cpu); /* * Copy data used in early init routines from the * initial arrays to the per cpu data areas. These diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c index 64a496a0687f..3c883e064242 100644 --- a/arch/x86/kernel/tls.c +++ b/arch/x86/kernel/tls.c @@ -164,17 +164,11 @@ int do_set_thread_area(struct task_struct *p, int idx, savesegment(fs, sel); if (sel == modified_sel) loadsegment(fs, sel); - - savesegment(gs, sel); - if (sel == modified_sel) - load_gs_index(sel); #endif -#ifdef CONFIG_X86_32_LAZY_GS savesegment(gs, sel); if (sel == modified_sel) - loadsegment(gs, sel); -#endif + load_gs_index(sel); } else { #ifdef CONFIG_X86_64 if (p->thread.fsindex == modified_sel) diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c index 4229950a5d78..7f89a091f1fb 100644 --- a/arch/x86/lib/insn-eval.c +++ b/arch/x86/lib/insn-eval.c @@ -404,10 +404,6 @@ static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx) case INAT_SEG_REG_FS: return (unsigned short)(regs->fs & 0xffff); case INAT_SEG_REG_GS: - /* - * GS may or may not be in regs as per CONFIG_X86_32_LAZY_GS. - * The macro below takes care of both cases. - */ return get_user_gs(regs); case INAT_SEG_REG_IGNORE: default: diff --git a/arch/x86/platform/pvh/head.S b/arch/x86/platform/pvh/head.S index d2ccadc247e6..b0490701da2a 100644 --- a/arch/x86/platform/pvh/head.S +++ b/arch/x86/platform/pvh/head.S @@ -46,10 +46,8 @@ #define PVH_GDT_ENTRY_CS 1 #define PVH_GDT_ENTRY_DS 2 -#define PVH_GDT_ENTRY_CANARY 3 #define PVH_CS_SEL (PVH_GDT_ENTRY_CS * 8) #define PVH_DS_SEL (PVH_GDT_ENTRY_DS * 8) -#define PVH_CANARY_SEL (PVH_GDT_ENTRY_CANARY * 8) SYM_CODE_START_LOCAL(pvh_start_xen) cld @@ -111,17 +109,6 @@ SYM_CODE_START_LOCAL(pvh_start_xen) #else /* CONFIG_X86_64 */ - /* Set base address in stack canary descriptor. */ - movl $_pa(gdt_start),%eax - movl $_pa(canary),%ecx - movw %cx, (PVH_GDT_ENTRY_CANARY * 8) + 2(%eax) - shrl $16, %ecx - movb %cl, (PVH_GDT_ENTRY_CANARY * 8) + 4(%eax) - movb %ch, (PVH_GDT_ENTRY_CANARY * 8) + 7(%eax) - - mov $PVH_CANARY_SEL,%eax - mov %eax,%gs - call mk_early_pgtbl_32 mov $_pa(initial_page_table), %eax @@ -165,7 +152,6 @@ SYM_DATA_START_LOCAL(gdt_start) .quad GDT_ENTRY(0xc09a, 0, 0xfffff) /* PVH_CS_SEL */ #endif .quad GDT_ENTRY(0xc092, 0, 0xfffff) /* PVH_DS_SEL */ - .quad GDT_ENTRY(0x4090, 0, 0x18) /* PVH_CANARY_SEL */ SYM_DATA_END_LABEL(gdt_start, SYM_L_LOCAL, gdt_end) .balign 16 diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index db1378c6ff26..ef4329d67a5f 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -99,11 +99,8 @@ static void __save_processor_state(struct saved_context *ctxt) /* * segment registers */ -#ifdef CONFIG_X86_32_LAZY_GS savesegment(gs, ctxt->gs); -#endif #ifdef CONFIG_X86_64 - savesegment(gs, ctxt->gs); savesegment(fs, ctxt->fs); savesegment(ds, ctxt->ds); savesegment(es, ctxt->es); @@ -232,7 +229,6 @@ static void notrace __restore_processor_state(struct saved_context *ctxt) wrmsrl(MSR_GS_BASE, ctxt->kernelmode_gs_base); #else loadsegment(fs, __KERNEL_PERCPU); - loadsegment(gs, __KERNEL_STACK_CANARY); #endif /* Restore the TSS, RO GDT, LDT, and usermode-relevant MSRs. */ @@ -255,7 +251,7 @@ static void notrace __restore_processor_state(struct saved_context *ctxt) */ wrmsrl(MSR_FS_BASE, ctxt->fs_base); wrmsrl(MSR_KERNEL_GS_BASE, ctxt->usermode_gs_base); -#elif defined(CONFIG_X86_32_LAZY_GS) +#else loadsegment(gs, ctxt->gs); #endif diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index dc0a337f985b..33e797b48f40 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -1204,7 +1204,6 @@ static void __init xen_setup_gdt(int cpu) pv_ops.cpu.write_gdt_entry = xen_write_gdt_entry_boot; pv_ops.cpu.load_gdt = xen_load_gdt_boot; - setup_stack_canary_segment(cpu); switch_to_new_gdt(cpu); pv_ops.cpu.write_gdt_entry = xen_write_gdt_entry; diff --git a/scripts/gcc-x86_32-has-stack-protector.sh b/scripts/gcc-x86_32-has-stack-protector.sh index f5c119495254..825c75c5b715 100755 --- a/scripts/gcc-x86_32-has-stack-protector.sh +++ b/scripts/gcc-x86_32-has-stack-protector.sh @@ -1,4 +1,8 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 -echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m32 -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs" +# This requires GCC 8.1 or better. Specifically, we require +# -mstack-protector-guard-reg, added by +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81708 + +echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m32 -O0 -fstack-protector -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard - -o - 2> /dev/null | grep -q "%fs" -- cgit v1.2.3-71-gd317 From 084aa00162bda02bcab501c2b0a0ea9252d291b2 Mon Sep 17 00:00:00 2001 From: Aditya Srivastava Date: Sat, 6 Mar 2021 17:05:10 +0530 Subject: scripts: kernel-doc: fix attribute capture in function parsing Currently, kernel-doc warns for function prototype parsing on the presence of attributes "__attribute_const__" and "__flatten" in the definition. There are 166 occurrences in ~70 files in the kernel tree for "__attribute_const__" and 5 occurrences in 4 files for "__flatten". Out of 166, there are 3 occurrences in three different files with "__attribute_const__" and a preceding kernel-doc; and, 1 occurrence in ./mm/percpu.c for "__flatten" with a preceding kernel-doc. All other occurrences have no preceding kernel-doc. Add support for "__attribute_const__" and "__flatten" attributes. A quick evaluation by running 'kernel-doc -none' on kernel-tree reveals that no additional warning or error has been added or removed by the fix. Suggested-by: Lukas Bulwahn Signed-off-by: Aditya Srivastava Link: https://lore.kernel.org/r/20210306113510.31023-1-yashsri421@gmail.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 68df17877384..e1e562b2e2e7 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1766,12 +1766,14 @@ sub dump_function($$) { $prototype =~ s/^noinline +//; $prototype =~ s/__init +//; $prototype =~ s/__init_or_module +//; + $prototype =~ s/__flatten +//; $prototype =~ s/__meminit +//; $prototype =~ s/__must_check +//; $prototype =~ s/__weak +//; $prototype =~ s/__sched +//; $prototype =~ s/__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +//; my $define = $prototype =~ s/^#\s*define\s+//; #ak added + $prototype =~ s/__attribute_const__ +//; $prototype =~ s/__attribute__\s*\(\( (?: [\w\s]++ # attribute name -- cgit v1.2.3-71-gd317 From 0b54c2e34be7987b5e0ffc0aa0e7dced7301cc1f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 3 Mar 2021 09:42:14 +0100 Subject: scripts/kernel-doc: ignore identifier on anonymous enums When anonymous enums are used, the identifier is empty. While, IMO, it should be avoided the usage of such enums, adding support for it is not hard. So, postpone the check for empty identifiers to happen only at the dump phase. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/055ad57879f1b9381b90879e00f72fde1c3a5647.1614760910.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index e1e562b2e2e7..cb92d0e1e932 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1412,9 +1412,14 @@ sub dump_enum($$) { if ($members) { if ($identifier ne $declaration_name) { - print STDERR "${file}:$.: warning: expecting prototype for enum $identifier. Prototype was for enum $declaration_name instead\n"; + if ($identifier eq "") { + print STDERR "${file}:$.: warning: wrong kernel-doc identifier on line:\n"; + } else { + print STDERR "${file}:$.: warning: expecting prototype for enum $identifier. Prototype was for enum $declaration_name instead\n"; + } return; } + $declaration_name = "(anonymous)" if ($declaration_name eq ""); my %_members; @@ -2134,7 +2139,7 @@ sub process_name($$) { ++$warnings; } - if ($identifier eq "") { + if ($identifier eq "" && $decl_type ne "enum") { print STDERR "${file}:$.: warning: wrong kernel-doc identifier on line:\n"; print STDERR $_; ++$warnings; -- cgit v1.2.3-71-gd317 From d1f044103dad70c1cec0a8f3abdf00834fec8b98 Mon Sep 17 00:00:00 2001 From: Eric Snowberg Date: Fri, 22 Jan 2021 13:10:53 -0500 Subject: certs: Add ability to preload revocation certs Add a new Kconfig option called SYSTEM_REVOCATION_KEYS. If set, this option should be the filename of a PEM-formated file containing X.509 certificates to be included in the default blacklist keyring. DH Changes: - Make the new Kconfig option depend on SYSTEM_REVOCATION_LIST. - Fix SYSTEM_REVOCATION_KEYS=n, but CONFIG_SYSTEM_REVOCATION_LIST=y[1][2]. - Use CONFIG_SYSTEM_REVOCATION_LIST for extract-cert[3]. - Use CONFIG_SYSTEM_REVOCATION_LIST for revocation_certificates.o[3]. Signed-off-by: Eric Snowberg Acked-by: Jarkko Sakkinen Signed-off-by: David Howells cc: Randy Dunlap cc: keyrings@vger.kernel.org Link: https://lore.kernel.org/r/e1c15c74-82ce-3a69-44de-a33af9b320ea@infradead.org/ [1] Link: https://lore.kernel.org/r/20210303034418.106762-1-eric.snowberg@oracle.com/ [2] Link: https://lore.kernel.org/r/20210304175030.184131-1-eric.snowberg@oracle.com/ [3] Link: https://lore.kernel.org/r/20200930201508.35113-3-eric.snowberg@oracle.com/ Link: https://lore.kernel.org/r/20210122181054.32635-4-eric.snowberg@oracle.com/ # v5 Link: https://lore.kernel.org/r/161428673564.677100.4112098280028451629.stgit@warthog.procyon.org.uk/ Link: https://lore.kernel.org/r/161433312452.902181.4146169951896577982.stgit@warthog.procyon.org.uk/ # v2 Link: https://lore.kernel.org/r/161529606657.163428.3340689182456495390.stgit@warthog.procyon.org.uk/ # v3 --- certs/Kconfig | 8 ++++++++ certs/Makefile | 19 +++++++++++++++++-- certs/blacklist.c | 21 +++++++++++++++++++++ certs/revocation_certificates.S | 21 +++++++++++++++++++++ scripts/Makefile | 1 + 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 certs/revocation_certificates.S (limited to 'scripts') diff --git a/certs/Kconfig b/certs/Kconfig index 76e469b56a77..ab88d2a7f3c7 100644 --- a/certs/Kconfig +++ b/certs/Kconfig @@ -92,4 +92,12 @@ config SYSTEM_REVOCATION_LIST blacklist keyring and implements a hook whereby a PKCS#7 message can be checked to see if it matches such a certificate. +config SYSTEM_REVOCATION_KEYS + string "X.509 certificates to be preloaded into the system blacklist keyring" + depends on SYSTEM_REVOCATION_LIST + help + If set, this option should be the filename of a PEM-formatted file + containing X.509 certificates to be included in the default blacklist + keyring. + endmenu diff --git a/certs/Makefile b/certs/Makefile index f4b90bad8690..b6db52ebf0be 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -4,7 +4,8 @@ # obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o common.o -obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o +obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o common.o +obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),"") obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o else @@ -29,7 +30,7 @@ $(obj)/x509_certificate_list: scripts/extract-cert $(SYSTEM_TRUSTED_KEYS_SRCPREF $(call if_changed,extract_certs,$(SYSTEM_TRUSTED_KEYS_SRCPREFIX)$(CONFIG_SYSTEM_TRUSTED_KEYS)) endif # CONFIG_SYSTEM_TRUSTED_KEYRING -clean-files := x509_certificate_list .x509.list +clean-files := x509_certificate_list .x509.list x509_revocation_list ifeq ($(CONFIG_MODULE_SIG),y) ############################################################################### @@ -104,3 +105,17 @@ targets += signing_key.x509 $(obj)/signing_key.x509: scripts/extract-cert $(X509_DEP) FORCE $(call if_changed,extract_certs,$(MODULE_SIG_KEY_SRCPREFIX)$(CONFIG_MODULE_SIG_KEY)) endif # CONFIG_MODULE_SIG + +ifeq ($(CONFIG_SYSTEM_REVOCATION_LIST),y) + +$(eval $(call config_filename,SYSTEM_REVOCATION_KEYS)) + +$(obj)/revocation_certificates.o: $(obj)/x509_revocation_list + +quiet_cmd_extract_certs = EXTRACT_CERTS $(patsubst "%",%,$(2)) + cmd_extract_certs = scripts/extract-cert $(2) $@ + +targets += x509_revocation_list +$(obj)/x509_revocation_list: scripts/extract-cert $(SYSTEM_REVOCATION_KEYS_SRCPREFIX)$(SYSTEM_REVOCATION_KEYS_FILENAME) FORCE + $(call if_changed,extract_certs,$(SYSTEM_REVOCATION_KEYS_SRCPREFIX)$(CONFIG_SYSTEM_REVOCATION_KEYS)) +endif diff --git a/certs/blacklist.c b/certs/blacklist.c index 2b8644123d5f..c9a435b15af4 100644 --- a/certs/blacklist.c +++ b/certs/blacklist.c @@ -17,9 +17,15 @@ #include #include #include "blacklist.h" +#include "common.h" static struct key *blacklist_keyring; +#ifdef CONFIG_SYSTEM_REVOCATION_LIST +extern __initconst const u8 revocation_certificate_list[]; +extern __initconst const unsigned long revocation_certificate_list_size; +#endif + /* * The description must be a type prefix, a colon and then an even number of * hex digits. The hash is kept in the description. @@ -220,3 +226,18 @@ static int __init blacklist_init(void) * Must be initialised before we try and load the keys into the keyring. */ device_initcall(blacklist_init); + +#ifdef CONFIG_SYSTEM_REVOCATION_LIST +/* + * Load the compiled-in list of revocation X.509 certificates. + */ +static __init int load_revocation_certificate_list(void) +{ + if (revocation_certificate_list_size) + pr_notice("Loading compiled-in revocation X.509 certificates\n"); + + return load_certificate_list(revocation_certificate_list, revocation_certificate_list_size, + blacklist_keyring); +} +late_initcall(load_revocation_certificate_list); +#endif diff --git a/certs/revocation_certificates.S b/certs/revocation_certificates.S new file mode 100644 index 000000000000..f21aae8a8f0e --- /dev/null +++ b/certs/revocation_certificates.S @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include +#include + + __INITRODATA + + .align 8 + .globl revocation_certificate_list +revocation_certificate_list: +__revocation_list_start: + .incbin "certs/x509_revocation_list" +__revocation_list_end: + + .align 8 + .globl revocation_certificate_list_size +revocation_certificate_list_size: +#ifdef CONFIG_64BIT + .quad __revocation_list_end - __revocation_list_start +#else + .long __revocation_list_end - __revocation_list_start +#endif diff --git a/scripts/Makefile b/scripts/Makefile index b5418ec587fb..bd0718f7c493 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -11,6 +11,7 @@ hostprogs-always-$(CONFIG_ASN1) += asn1_compiler hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file hostprogs-always-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert +hostprogs-always-$(CONFIG_SYSTEM_REVOCATION_LIST) += extract-cert HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include -- cgit v1.2.3-71-gd317 From 3204a7fb98a3bccd0004ea0f2769fbeadc2c2dba Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 28 Feb 2021 15:10:26 +0900 Subject: kbuild: prefix $(srctree)/ to some included Makefiles VPATH is used in Kbuild to make pattern rules search for prerequisites in both $(objtree) and $(srctree). Some of *.c, *.S files are not real sources, but generated by tools such as flex, bison, perl. In contrast, I doubt the benefit of --include-dir=$(abs_srctree) because it is always clear which Makefiles are real sources, and which are not. So, my hope is to add $(srctree)/ prefix to all check-in Makefiles, then remove --include-dir=$(abs_srctree) flag in the future. I am touching only some Kbuild core parts for now. Treewide fixes will be needed to achieve this goal. Signed-off-by: Masahiro Yamada --- Makefile | 8 ++++---- scripts/Makefile.asm-generic | 4 ++-- scripts/Makefile.build | 8 ++++---- scripts/Makefile.clean | 2 +- scripts/Makefile.dtbinst | 2 +- scripts/Makefile.headersinst | 2 +- scripts/Makefile.modinst | 2 +- scripts/Makefile.modpost | 4 ++-- scripts/Makefile.modsign | 2 +- 9 files changed, 17 insertions(+), 17 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index a28bb374663d..93e6e2d28d89 100644 --- a/Makefile +++ b/Makefile @@ -339,14 +339,14 @@ __build_one_by_one: else # !mixed-build -include scripts/Kbuild.include +include $(srctree)/scripts/Kbuild.include # Read KERNELRELEASE from include/config/kernel.release (if it exists) KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null) KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION) export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION -include scripts/subarch.include +include $(srctree)/scripts/subarch.include # Cross compiling and selecting different set of gcc/bin-utils # --------------------------------------------------------------------------- @@ -592,7 +592,7 @@ ifdef config-build # Read arch specific Makefile to set KBUILD_DEFCONFIG as needed. # KBUILD_DEFCONFIG may point out an alternative default configuration # used for 'make defconfig' -include arch/$(SRCARCH)/Makefile +include $(srctree)/arch/$(SRCARCH)/Makefile export KBUILD_DEFCONFIG KBUILD_KCONFIG CC_VERSION_TEXT config: outputmakefile scripts_basic FORCE @@ -679,7 +679,7 @@ RETPOLINE_VDSO_CFLAGS := $(call cc-option,$(RETPOLINE_VDSO_CFLAGS_GCC),$(call cc export RETPOLINE_CFLAGS export RETPOLINE_VDSO_CFLAGS -include arch/$(SRCARCH)/Makefile +include $(srctree)/arch/$(SRCARCH)/Makefile ifdef need-config ifdef may-sync-config diff --git a/scripts/Makefile.asm-generic b/scripts/Makefile.asm-generic index 82ad63dcd62b..1d501c57f9ef 100644 --- a/scripts/Makefile.asm-generic +++ b/scripts/Makefile.asm-generic @@ -14,10 +14,10 @@ src := $(subst /generated,,$(obj)) # $(generic)/Kbuild lists mandatory-y. Exclude um since it is a special case. ifneq ($(SRCARCH),um) -include $(generic)/Kbuild +include $(srctree)/$(generic)/Kbuild endif -include scripts/Kbuild.include +include $(srctree)/scripts/Kbuild.include redundant := $(filter $(mandatory-y) $(generated-y), $(generic-y)) redundant += $(foreach f, $(generic-y), $(if $(wildcard $(srctree)/$(src)/$(f)),$(f))) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 1b6094a13034..750d6d5225af 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -35,27 +35,27 @@ subdir-ccflags-y := # Read auto.conf if it exists, otherwise ignore -include include/config/auto.conf -include scripts/Kbuild.include +include $(srctree)/scripts/Kbuild.include # The filename Kbuild has precedence over Makefile kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile) include $(kbuild-file) -include scripts/Makefile.lib +include $(srctree)/scripts/Makefile.lib # Do not include hostprogs rules unless needed. # $(sort ...) is used here to remove duplicated words and excessive spaces. hostprogs := $(sort $(hostprogs)) ifneq ($(hostprogs),) -include scripts/Makefile.host +include $(srctree)/scripts/Makefile.host endif # Do not include userprogs rules unless needed. # $(sort ...) is used here to remove duplicated words and excessive spaces. userprogs := $(sort $(userprogs)) ifneq ($(userprogs),) -include scripts/Makefile.userprogs +include $(srctree)/scripts/Makefile.userprogs endif ifndef obj diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index 22a8172bce1f..fd6175322470 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -8,7 +8,7 @@ src := $(obj) PHONY := __clean __clean: -include scripts/Kbuild.include +include $(srctree)/scripts/Kbuild.include # The filename Kbuild has precedence over Makefile kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst index ba01f5ba2517..190d781e84f4 100644 --- a/scripts/Makefile.dtbinst +++ b/scripts/Makefile.dtbinst @@ -14,7 +14,7 @@ PHONY := __dtbs_install __dtbs_install: include include/config/auto.conf -include scripts/Kbuild.include +include $(srctree)/scripts/Kbuild.include include $(src)/Makefile dtbs := $(addprefix $(dst)/, $(dtb-y) $(if $(CONFIG_OF_ALL_DTBS),$(dtb-))) diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst index 708fbd08a2c5..029d85bb0b23 100644 --- a/scripts/Makefile.headersinst +++ b/scripts/Makefile.headersinst @@ -12,7 +12,7 @@ PHONY := __headers __headers: -include scripts/Kbuild.include +include $(srctree)/scripts/Kbuild.include src := $(srctree)/$(obj) gen := $(objtree)/$(subst include/,include/generated/,$(obj)) diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 5a4579e76485..ad1981233d0b 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -6,7 +6,7 @@ PHONY := __modinst __modinst: -include scripts/Kbuild.include +include $(srctree)/scripts/Kbuild.include modules := $(sort $(shell cat $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/)modules.order)) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 066beffca09a..df57e259fac3 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -41,10 +41,10 @@ PHONY := __modpost __modpost: include include/config/auto.conf -include scripts/Kbuild.include +include $(srctree)/scripts/Kbuild.include # for ld_flags -include scripts/Makefile.lib +include $(srctree)/scripts/Makefile.lib MODPOST = scripts/mod/modpost \ $(if $(CONFIG_MODVERSIONS),-m) \ diff --git a/scripts/Makefile.modsign b/scripts/Makefile.modsign index d7325cefe709..ddf9b5ca77d7 100644 --- a/scripts/Makefile.modsign +++ b/scripts/Makefile.modsign @@ -6,7 +6,7 @@ PHONY := __modsign __modsign: -include scripts/Kbuild.include +include $(srctree)/scripts/Kbuild.include modules := $(sort $(shell cat modules.order)) -- cgit v1.2.3-71-gd317 From c59773d204cc02cc97b4b8dc4cf87a595204cc9d Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 11 Mar 2021 16:36:40 -0700 Subject: kbuild: Enable DT undocumented compatible checks dt-validate has an option to warn on any compatible strings which don't match any schema. The option has recently been improved to fix false positives, so let's enable the option. This is useful for tracking compatibles which are undocumented or not yet converted to DT schema. Previously, the only check of undocumented compatible strings has been an imperfect checkpatch.pl check. The option is enabled by default for 'dtbs_check'. This will add more warnings, but some platforms are down to only a handful of these warnings (good job!). There's about 100 cases in the binding examples, so the option is disabled until these are fixed. In the meantime, they can be checked with: make DT_CHECKER_FLAGS=-m dt_binding_check Cc: Maxime Ripard Cc: Masahiro Yamada Cc: Michal Marek Cc: linux-kbuild@vger.kernel.org Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20210311233640.1581526-2-robh@kernel.org --- Documentation/devicetree/bindings/Makefile | 3 +++ scripts/Makefile.lib | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile index 81f0b3294c64..bc24ee316726 100644 --- a/Documentation/devicetree/bindings/Makefile +++ b/Documentation/devicetree/bindings/Makefile @@ -55,6 +55,9 @@ override DTC_FLAGS := \ -Wno-graph_child_address \ -Wno-interrupt_provider +# Disable undocumented compatible checks until warning free +override DT_CHECKER_FLAGS ?= + $(obj)/processed-schema-examples.json: $(DT_DOCS) $(src)/.yamllint check_dtschema_version FORCE $(call if_changed_rule,chkdt) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index eee59184de64..34e5fefa8d92 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -339,12 +339,13 @@ $(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE $(call if_changed_dep,dtc) DT_CHECKER ?= dt-validate +DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),,-m) DT_BINDING_DIR := Documentation/devicetree/bindings # DT_TMP_SCHEMA may be overridden from Documentation/devicetree/bindings/Makefile DT_TMP_SCHEMA ?= $(objtree)/$(DT_BINDING_DIR)/processed-schema.json quiet_cmd_dtb_check = CHECK $@ - cmd_dtb_check = $(DT_CHECKER) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ + cmd_dtb_check = $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ define rule_dtc $(call cmd_and_fixdep,dtc) -- cgit v1.2.3-71-gd317 From 2cf3af7aa6df0e173f2bff57b73427bb05b30ba0 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Mon, 22 Mar 2021 17:45:22 -0400 Subject: scripts/recordmcount.pl: Make indent spacing consistent Emacs by default will have perl files have 4 space indents, where 8 spaces are represented with a single tab. There are some places in recordmcount.pl that has 8 spaces where a tab should be used. Replace them to make the file consistent. No functional changes. Cc: "John (Warthog9) Hawley" Signed-off-by: Steven Rostedt (VMware) --- scripts/recordmcount.pl | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 867860ea57da..5652da5e345e 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -266,9 +266,9 @@ if ($arch eq "x86_64") { # force flags for this arch $ld .= " -m shlelf_linux"; if ($endian eq "big") { - $objcopy .= " -O elf32-shbig-linux"; + $objcopy .= " -O elf32-shbig-linux"; } else { - $objcopy .= " -O elf32-sh-linux"; + $objcopy .= " -O elf32-sh-linux"; } } elsif ($arch eq "powerpc") { @@ -289,12 +289,12 @@ if ($arch eq "x86_64") { $ldemulation = "lppc" } if ($bits == 64) { - $type = ".quad"; - $cc .= " -m64 "; - $ld .= " -m elf64".$ldemulation." "; + $type = ".quad"; + $cc .= " -m64 "; + $ld .= " -m elf64".$ldemulation." "; } else { - $cc .= " -m32 "; - $ld .= " -m elf32".$ldemulation." "; + $cc .= " -m32 "; + $ld .= " -m elf32".$ldemulation." "; } } elsif ($arch eq "arm") { @@ -313,7 +313,7 @@ if ($arch eq "x86_64") { $type = "data8"; if ($is_module eq "0") { - $cc .= " -mconstant-gp"; + $cc .= " -mconstant-gp"; } } elsif ($arch eq "sparc64") { # In the objdump output there are giblets like: @@ -530,10 +530,10 @@ while () { $read_function = defined($text_sections{$1}); if (!$read_function) { foreach my $prefix (keys %text_section_prefixes) { - if (substr($1, 0, length $prefix) eq $prefix) { - $read_function = 1; - last; - } + if (substr($1, 0, length $prefix) eq $prefix) { + $read_function = 1; + last; + } } } # print out any recorded offsets -- cgit v1.2.3-71-gd317 From b700fc3a63f16d6e130433fdcbe3f5f223c7662c Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Mon, 22 Mar 2021 17:47:37 -0400 Subject: scripts/recordmcount.pl: Make vim and emacs indent the same By default, emacs indents Perl files with 4 spaces, but will use tabs where 8 spaces are used. Add a vim command of softtabstop=4, to make vim behave the same. This should remove the issue of developers using vim having causing different indentation. "John (Warthog9) Hawley" Signed-off-by: Steven Rostedt (VMware) --- scripts/recordmcount.pl | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 5652da5e345e..a5429b3dac24 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -642,3 +642,5 @@ if ($#converts >= 0) { `$rm $mcount_o $mcount_s`; exit(0); + +# vim: softtabstop=4 -- cgit v1.2.3-71-gd317 From 9ca29e41508e97bec2f45c7f9b79108107d6b3d5 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 10 Mar 2021 11:05:29 +0530 Subject: kbuild: Simplify builds with CONFIG_OF_ALL_DTBS We update 'always-y' based on CONFIG_OF_ALL_DTBS three times. It would be far more straight forward if we rather update dtb-y to include all .dtb files if CONFIG_OF_ALL_DTBS is enabled. Acked-by: Masahiro Yamada Signed-off-by: Viresh Kumar Reviewed-by: Frank Rowand Tested-by: Frank Rowand Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/7fe7e5ef6ed75450ddf6c224b8adb53059e504e2.1615354376.git.viresh.kumar@linaro.org --- scripts/Makefile.lib | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 34e5fefa8d92..441a224689f9 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -73,14 +73,13 @@ always-y += $(userprogs-always-y) $(userprogs-always-m) # DTB # If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built +dtb-$(CONFIG_OF_ALL_DTBS) += $(dtb-) + always-y += $(dtb-y) -always-$(CONFIG_OF_ALL_DTBS) += $(dtb-) ifneq ($(CHECK_DTBS),) always-y += $(patsubst %.dtb,%.dt.yaml, $(dtb-y)) always-y += $(patsubst %.dtbo,%.dt.yaml, $(dtb-y)) -always-$(CONFIG_OF_ALL_DTBS) += $(patsubst %.dtb,%.dt.yaml, $(dtb-)) -always-$(CONFIG_OF_ALL_DTBS) += $(patsubst %.dtbo,%.dt.yaml, $(dtb-)) endif # Add subdir path -- cgit v1.2.3-71-gd317 From 15d16d6dadf6947ac7f9a686c615995c5a426ce2 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 10 Mar 2021 11:05:30 +0530 Subject: kbuild: Add generic rule to apply fdtoverlay Add a generic rule to apply fdtoverlay in Makefile.lib, so every platform doesn't need to carry the complex rule. This also automatically adds "DTC_FLAGS_foo_base += -@" for all base files. The platform's Makefile only needs to have this now: foo-dtbs := foo_base.dtb foo_overlay1.dtbo foo_overlay2.dtbo dtb-y := foo.dtb We don't want to run schema checks on foo.dtb (as foo.dts doesn't exist) and the Makefile is updated accordingly. Acked-by: Masahiro Yamada Signed-off-by: Rob Herring Co-developed-by: Viresh Kumar Signed-off-by: Viresh Kumar Reviewed-by: Frank Rowand Tested-by: Frank Rowand Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20920b0df6b067aca4040459a9677d7d1d6d766a.1615354376.git.viresh.kumar@linaro.org --- scripts/Makefile.lib | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 441a224689f9..ad6938468c11 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -75,11 +75,24 @@ always-y += $(userprogs-always-y) $(userprogs-always-m) # If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built dtb-$(CONFIG_OF_ALL_DTBS) += $(dtb-) +# List all dtbs to be generated by fdtoverlay +overlay-y := $(foreach m,$(dtb-y), $(if $(strip $($(m:.dtb=-dtbs))),$(m),)) + +# Generate symbols for the base files so overlays can be applied to them. +$(foreach m,$(overlay-y), $(eval DTC_FLAGS_$(basename $(firstword $($(m:.dtb=-dtbs)))) += -@)) + +# Add base dtb and overlay dtbo +dtb-y += $(foreach m,$(overlay-y), $($(m:.dtb=-dtbs))) + always-y += $(dtb-y) ifneq ($(CHECK_DTBS),) -always-y += $(patsubst %.dtb,%.dt.yaml, $(dtb-y)) -always-y += $(patsubst %.dtbo,%.dt.yaml, $(dtb-y)) +# Don't run schema checks for dtbs created by fdtoverlay as they don't +# have corresponding dts files. +dt-yaml-y := $(filter-out $(overlay-y),$(dtb-y)) + +always-y += $(patsubst %.dtb,%.dt.yaml, $(dt-yaml-y)) +always-y += $(patsubst %.dtbo,%.dt.yaml, $(dt-yaml-y)) endif # Add subdir path @@ -337,6 +350,15 @@ $(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE $(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE $(call if_changed_dep,dtc) +overlay-y := $(addprefix $(obj)/, $(overlay-y)) + +quiet_cmd_fdtoverlay = DTOVL $@ + cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(real-prereqs) + +$(overlay-y): FORCE + $(call if_changed,fdtoverlay) +$(call multi_depend, $(overlay-y), .dtb, -dtbs) + DT_CHECKER ?= dt-validate DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),,-m) DT_BINDING_DIR := Documentation/devicetree/bindings -- cgit v1.2.3-71-gd317 From 89145649b0d0d51e90a85de23ca881c97d3a71a4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 14 Mar 2021 04:48:24 +0900 Subject: kconfig: split randconfig setup code into set_randconfig_seed() This code is too big to be placed in the switch statement. Move the code into a new helper function. I slightly refactor the code without changing the behavior. Signed-off-by: Masahiro Yamada --- scripts/kconfig/conf.c | 54 +++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 23 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 957d2a0832f7..063c9e7a34c1 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -82,6 +82,36 @@ static void xfgets(char *str, int size, FILE *in) printf("%s", str); } +static void set_randconfig_seed(void) +{ + unsigned int seed; + char *env; + bool seed_set = false; + + env = getenv("KCONFIG_SEED"); + if (env && *env) { + char *endp; + + seed = strtol(env, &endp, 0); + if (*endp == '\0') + seed_set = true; + } + + if (!seed_set) { + struct timeval now; + + /* + * Use microseconds derived seed, compensate for systems where it may + * be zero. + */ + gettimeofday(&now, NULL); + seed = (now.tv_sec + 1) * (now.tv_usec + 1); + } + + printf("KCONFIG_SEED=0x%X\n", seed); + srand(seed); +} + static int conf_askvalue(struct symbol *sym, const char *def) { if (!sym_has_value(sym)) @@ -515,30 +545,8 @@ int main(int ac, char **av) defconfig_file = optarg; break; case randconfig: - { - struct timeval now; - unsigned int seed; - char *seed_env; - - /* - * Use microseconds derived seed, - * compensate for systems where it may be zero - */ - gettimeofday(&now, NULL); - seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1)); - - seed_env = getenv("KCONFIG_SEED"); - if( seed_env && *seed_env ) { - char *endp; - int tmp = (int)strtol(seed_env, &endp, 0); - if (*endp == '\0') { - seed = tmp; - } - } - fprintf( stderr, "KCONFIG_SEED=0x%X\n", seed ); - srand(seed); + set_randconfig_seed(); break; - } case oldaskconfig: case oldconfig: case allnoconfig: -- cgit v1.2.3-71-gd317 From ed562c53104fbe097f012bec5a30196334e52d78 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 14 Mar 2021 04:48:25 +0900 Subject: kconfig: refactor option parse code The current option parse code is clumsy. The 's' option is separately handled in an if-conditional due to the following code: input_mode = (enum input_mode)opt; If 's' is moved to the switch statement, the invalid value 's' would be assigned to the input_mode. Another potential problem is that we are mixing 'enum input_mode' and ASCII characters. They could overwrap if we add more input modes. To separate them out, set the flag field of long options to a pointer of input_mode_opt. For mode select options, getopt_long() returns 0, which never causes overwrap with ASCII characters that represent short options. Signed-off-by: Masahiro Yamada --- scripts/kconfig/conf.c | 91 ++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 48 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 063c9e7a34c1..dc1a67fd35a9 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -37,7 +37,7 @@ enum input_mode { mod2yesconfig, }; static enum input_mode input_mode = oldaskconfig; - +static int input_mode_opt; static int indent = 1; static int tty_stdio; static int sync_kconfig; @@ -474,21 +474,21 @@ static void check_conf(struct menu *menu) } static struct option long_opts[] = { - {"oldaskconfig", no_argument, NULL, oldaskconfig}, - {"oldconfig", no_argument, NULL, oldconfig}, - {"syncconfig", no_argument, NULL, syncconfig}, - {"defconfig", required_argument, NULL, defconfig}, - {"savedefconfig", required_argument, NULL, savedefconfig}, - {"allnoconfig", no_argument, NULL, allnoconfig}, - {"allyesconfig", no_argument, NULL, allyesconfig}, - {"allmodconfig", no_argument, NULL, allmodconfig}, - {"alldefconfig", no_argument, NULL, alldefconfig}, - {"randconfig", no_argument, NULL, randconfig}, - {"listnewconfig", no_argument, NULL, listnewconfig}, - {"helpnewconfig", no_argument, NULL, helpnewconfig}, - {"olddefconfig", no_argument, NULL, olddefconfig}, - {"yes2modconfig", no_argument, NULL, yes2modconfig}, - {"mod2yesconfig", no_argument, NULL, mod2yesconfig}, + {"oldaskconfig", no_argument, &input_mode_opt, oldaskconfig}, + {"oldconfig", no_argument, &input_mode_opt, oldconfig}, + {"syncconfig", no_argument, &input_mode_opt, syncconfig}, + {"defconfig", required_argument, &input_mode_opt, defconfig}, + {"savedefconfig", required_argument, &input_mode_opt, savedefconfig}, + {"allnoconfig", no_argument, &input_mode_opt, allnoconfig}, + {"allyesconfig", no_argument, &input_mode_opt, allyesconfig}, + {"allmodconfig", no_argument, &input_mode_opt, allmodconfig}, + {"alldefconfig", no_argument, &input_mode_opt, alldefconfig}, + {"randconfig", no_argument, &input_mode_opt, randconfig}, + {"listnewconfig", no_argument, &input_mode_opt, listnewconfig}, + {"helpnewconfig", no_argument, &input_mode_opt, helpnewconfig}, + {"olddefconfig", no_argument, &input_mode_opt, olddefconfig}, + {"yes2modconfig", no_argument, &input_mode_opt, yes2modconfig}, + {"mod2yesconfig", no_argument, &input_mode_opt, mod2yesconfig}, {NULL, 0, NULL, 0} }; @@ -526,43 +526,38 @@ int main(int ac, char **av) tty_stdio = isatty(0) && isatty(1); while ((opt = getopt_long(ac, av, "hs", long_opts, NULL)) != -1) { - if (opt == 's') { - conf_set_message_callback(NULL); - continue; - } - input_mode = (enum input_mode)opt; switch (opt) { - case syncconfig: - /* - * syncconfig is invoked during the build stage. - * Suppress distracting "configuration written to ..." - */ - conf_set_message_callback(NULL); - sync_kconfig = 1; - break; - case defconfig: - case savedefconfig: - defconfig_file = optarg; - break; - case randconfig: - set_randconfig_seed(); - break; - case oldaskconfig: - case oldconfig: - case allnoconfig: - case allyesconfig: - case allmodconfig: - case alldefconfig: - case listnewconfig: - case helpnewconfig: - case olddefconfig: - case yes2modconfig: - case mod2yesconfig: - break; case 'h': conf_usage(progname); exit(1); break; + case 's': + conf_set_message_callback(NULL); + break; + case 0: + input_mode = input_mode_opt; + switch (input_mode) { + case syncconfig: + /* + * syncconfig is invoked during the build stage. + * Suppress distracting + * "configuration written to ..." + */ + conf_set_message_callback(NULL); + sync_kconfig = 1; + break; + case defconfig: + case savedefconfig: + defconfig_file = optarg; + break; + case randconfig: + set_randconfig_seed(); + break; + default: + break; + } + default: + break; } } if (ac == optind) { -- cgit v1.2.3-71-gd317 From bafc479132160a5fa66efa1748c995e699655803 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 14 Mar 2021 04:48:26 +0900 Subject: kconfig: add long options --help and --silent They are long options for -h and -s, respectively. Signed-off-by: Masahiro Yamada --- scripts/kconfig/conf.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index dc1a67fd35a9..aac76acfd100 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -474,6 +474,8 @@ static void check_conf(struct menu *menu) } static struct option long_opts[] = { + {"help", no_argument, NULL, 'h'}, + {"silent", no_argument, NULL, 's'}, {"oldaskconfig", no_argument, &input_mode_opt, oldaskconfig}, {"oldconfig", no_argument, &input_mode_opt, oldconfig}, {"syncconfig", no_argument, &input_mode_opt, syncconfig}, -- cgit v1.2.3-71-gd317 From ee4c6f00dcee1bffcb06ffa274251c1467d3efaa Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 14 Mar 2021 04:48:27 +0900 Subject: kconfig: add help messages for --help (-h) and --silent (-s) Add missing options and make the help message more readable. Signed-off-by: Masahiro Yamada --- scripts/kconfig/conf.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index aac76acfd100..9ebc1acaf1ae 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -496,9 +496,13 @@ static struct option long_opts[] = { static void conf_usage(const char *progname) { - - printf("Usage: %s [-s] [option] \n", progname); - printf("[option] is _one_ of the following:\n"); + printf("Usage: %s [options] \n", progname); + printf("\n"); + printf("Generic options:\n"); + printf(" -h, --help Print this message and exit.\n"); + printf(" -s, --silent Do not print log.\n"); + printf("\n"); + printf("Mode options:\n"); printf(" --listnewconfig List new options\n"); printf(" --helpnewconfig List new options and help text\n"); printf(" --oldaskconfig Start a new configuration using a line-oriented program\n"); -- cgit v1.2.3-71-gd317 From 9a3c3bc820be102f8bb1ca0e9700633d5b3aeb1f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 14 Mar 2021 04:48:28 +0900 Subject: kconfig: remove assignment for Kconfig file Pass av[optind] to conf_parse() directly. Signed-off-by: Masahiro Yamada --- scripts/kconfig/conf.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 9ebc1acaf1ae..42d35da86604 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -571,8 +571,7 @@ int main(int ac, char **av) conf_usage(progname); exit(1); } - name = av[optind]; - conf_parse(name); + conf_parse(av[optind]); //zconfdump(stdout); switch (input_mode) { -- cgit v1.2.3-71-gd317 From 15e68d09458f1b417f3129674b89ff91a1070f15 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 14 Mar 2021 04:48:29 +0900 Subject: kconfig: move conf_rewrite_mod_or_yes() to conf.c This function is only used in conf.c. Signed-off-by: Masahiro Yamada --- scripts/kconfig/conf.c | 15 +++++++++++++++ scripts/kconfig/confdata.c | 15 --------------- scripts/kconfig/lkc.h | 1 - 3 files changed, 15 insertions(+), 16 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 42d35da86604..89c9ba83f9e7 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -112,6 +112,21 @@ static void set_randconfig_seed(void) srand(seed); } +static void conf_rewrite_mod_or_yes(enum conf_def_mode mode) +{ + struct symbol *sym; + int i; + tristate old_val = (mode == def_y2m) ? yes : mod; + tristate new_val = (mode == def_y2m) ? mod : yes; + + for_all_symbols(i, sym) { + if (sym_get_type(sym) == S_TRISTATE && + sym->def[S_DEF_USER].tri == old_val) + sym->def[S_DEF_USER].tri = new_val; + } + sym_clear_all_valid(); +} + static int conf_askvalue(struct symbol *sym, const char *def) { if (!sym_has_value(sym)) diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 2568dbe16ed6..a828622cb2d0 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -1322,18 +1322,3 @@ bool conf_set_all_new_symbols(enum conf_def_mode mode) return has_changed; } - -void conf_rewrite_mod_or_yes(enum conf_def_mode mode) -{ - struct symbol *sym; - int i; - tristate old_val = (mode == def_y2m) ? yes : mod; - tristate new_val = (mode == def_y2m) ? mod : yes; - - for_all_symbols(i, sym) { - if (sym_get_type(sym) == S_TRISTATE && - sym->def[S_DEF_USER].tri == old_val) - sym->def[S_DEF_USER].tri = new_val; - } - sym_clear_all_valid(); -} diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index bee2413bda63..f946ab49ef50 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -58,7 +58,6 @@ const char *conf_get_configname(void); void sym_set_change_count(int count); void sym_add_change_count(int count); bool conf_set_all_new_symbols(enum conf_def_mode mode); -void conf_rewrite_mod_or_yes(enum conf_def_mode mode); void set_all_choice_values(struct symbol *csym); /* confdata.c and expr.c */ -- cgit v1.2.3-71-gd317 From 8d295fbad687a61eaa0cf14958c284a3ddbf2173 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 25 Mar 2021 19:14:25 +0100 Subject: kernel-doc: better handle '::' sequences Right now, if one of the following headers end with a '::', the kernel-doc script will do the wrong thing: description|context|returns?|notes?|examples? The real issue is with examples, as people could try to write something like: example:: /* Some C code */ and this won't be properly evaluated. So, improve the regex to not catch '\w+::' regex for the above identifiers. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/2cf44cf1fa42588632735d4fbc8e84304bdc235f.1616696051.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index cb92d0e1e932..0ecd71477a16 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -392,7 +392,7 @@ my $doc_com_body = '\s*\* ?'; my $doc_decl = $doc_com . '(\w+)'; # @params and a strictly limited set of supported section names my $doc_sect = $doc_com . - '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:(.*)'; + '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:([^:]*)$'; my $doc_content = $doc_com_body . '(.*)'; my $doc_block = $doc_com . 'DOC:\s*(.*)?'; my $doc_inline_start = '^\s*/\*\*\s*$'; -- cgit v1.2.3-71-gd317 From 212209cff89fe497bc47abcd017aa95e4e8a5196 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 26 Mar 2021 13:16:35 -0600 Subject: docs: kernel-doc: properly recognize parameter lines with colons The previous attempt to properly handle literal blocks broke parsing of parameter lines containing colons; fix it by tweaking the regex to specifically exclude the "::" pattern while accepting lines containing colons in general. Add a little documentation to the regex while in the neighborhood. Reported-by: Stephen Rothwell Fixes: 8d295fbad687 ("kernel-doc: better handle '::' sequences") Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 0ecd71477a16..d6d2b6e0b4eb 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -391,8 +391,14 @@ my $doc_com = '\s*\*\s*'; my $doc_com_body = '\s*\* ?'; my $doc_decl = $doc_com . '(\w+)'; # @params and a strictly limited set of supported section names +# Specifically: +# Match @word: +# @...: +# @{section-name}: +# while trying to not match literal block starts like "example::" +# my $doc_sect = $doc_com . - '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:([^:]*)$'; + '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:([^:].*)?$'; my $doc_content = $doc_com_body . '(.*)'; my $doc_block = $doc_com . 'DOC:\s*(.*)?'; my $doc_inline_start = '^\s*/\*\*\s*$'; -- cgit v1.2.3-71-gd317 From 40635128fee8c762b4b3e8ab805a15f01d60b859 Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Fri, 26 Mar 2021 14:44:43 +0530 Subject: scripts/spdxcheck.py: Fix a typo s/Initilize/Initialize/ Signed-off-by: Bhaskar Chowdhury Link: https://lore.kernel.org/r/20210326091443.26525-1-unixbhaskar@gmail.com Signed-off-by: Greg Kroah-Hartman --- scripts/spdxcheck.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/spdxcheck.py b/scripts/spdxcheck.py index cbdb5c83c08f..3e784cf9f401 100755 --- a/scripts/spdxcheck.py +++ b/scripts/spdxcheck.py @@ -243,7 +243,7 @@ if __name__ == '__main__': # Initialize SPDX data spdx = read_spdxdata(repo) - # Initilize the parser + # Initialize the parser parser = id_parser(spdx) except SPDXException as se: -- cgit v1.2.3-71-gd317 From 3e58e839150db0857dfcb3a0bb3d4af4c6ac1abf Mon Sep 17 00:00:00 2001 From: Aditya Srivastava Date: Mon, 29 Mar 2021 14:59:45 +0530 Subject: scripts: kernel-doc: add warning for comment not following kernel-doc syntax Currently, kernel-doc start parsing the comment as a kernel-doc comment if it starts with '/**', but does not take into account if the content inside the comment too, adheres with the expected format. This results in unexpected and unclear warnings for the user. E.g., running scripts/kernel-doc -none mm/memcontrol.c emits: "mm/memcontrol.c:961: warning: expecting prototype for do not fallback to current(). Prototype was for get_mem_cgroup_from_current() instead" Here kernel-doc parses the corresponding comment as a kernel-doc comment and expects prototype for it in the next lines, and as a result causing this warning. Provide a clearer warning message to the users regarding the same, if the content inside the comment does not follow the kernel-doc expected format. Signed-off-by: Aditya Srivastava Link: https://lore.kernel.org/r/20210329092945.13152-1-yashsri421@gmail.com Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index d6d2b6e0b4eb..888913528185 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2109,15 +2109,17 @@ sub process_name($$) { } } elsif (/$doc_decl/o) { $identifier = $1; - if (/\s*([\w\s]+?)(\(\))?\s*([-:].*)?$/) { + my $is_kernel_comment = 0; + if (/^\s*\*\s*([\w\s]+?)(\(\))?\s*([-:].*)?$/) { $identifier = $1; + $decl_type = 'function'; + $identifier =~ s/^define\s+//; + $is_kernel_comment = 1; } if ($identifier =~ m/^(struct|union|enum|typedef)\b\s*(\S*)/) { $decl_type = $1; $identifier = $2; - } else { - $decl_type = 'function'; - $identifier =~ s/^define\s+//; + $is_kernel_comment = 1; } $identifier =~ s/\s+$//; @@ -2139,6 +2141,13 @@ sub process_name($$) { $declaration_purpose = ""; } + if (!$is_kernel_comment) { + print STDERR "${file}:$.: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst\n"; + print STDERR $_; + ++$warnings; + $state = STATE_NORMAL; + } + if (($declaration_purpose eq "") && $verbose) { print STDERR "${file}:$.: warning: missing initial short description on line:\n"; print STDERR $_; -- cgit v1.2.3-71-gd317 From 7d0bc44bd0ea163a251d4aa778d1b6fcf6174d22 Mon Sep 17 00:00:00 2001 From: Carlos de Paula Date: Tue, 16 Mar 2021 13:02:43 -0300 Subject: kbuild: buildtar: add riscv support Make 'make tar-pkg' and 'tarbz2-pkg' work on riscv. Signed-off-by: Carlos de Paula Signed-off-by: Palmer Dabbelt --- scripts/package/buildtar | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'scripts') diff --git a/scripts/package/buildtar b/scripts/package/buildtar index 936198a90477..221aa7df008d 100755 --- a/scripts/package/buildtar +++ b/scripts/package/buildtar @@ -125,6 +125,14 @@ case "${ARCH}" in fi done ;; + riscv) + for i in Image.bz2 Image.gz Image; do + if [ -f "${objtree}/arch/riscv/boot/${i}" ] ; then + cp -v -- "${objtree}/arch/riscv/boot/${i}" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}" + break + fi + done + ;; *) [ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-kbuild-${KERNELRELEASE}" echo "" >&2 -- cgit v1.2.3-71-gd317 From b0f9580a88803472d7c05d89365902a64f076df4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 25 Mar 2021 11:38:22 +0100 Subject: scripts: get_abi.pl: better handle escape chars on what: The parser for the symbols defined on What: doesn't cover all chars that need to be scaped, like '{' and '}'. Change the logic to be more generic, and ensure that the same regex will be used on both What: and when parsing the cross-references. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/29cb56def89b508fe605bcd2ba74a4376cc08e35.1616668017.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/get_abi.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 92d9aa6cc4f5..a9348b9bdaa4 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -283,6 +283,7 @@ sub create_labels { # \b doesn't work well with paths. So, we need to define something else my $bondary = qr { (? $len); } @@ -395,7 +396,7 @@ sub output_rest { if (defined($data{$s}) && defined($data{$s}->{label})) { my $xref = $s; - $xref =~ s/([\x00-\x1f\x21-\x2f\x3a-\x40\x7b-\xff])/\\$1/g; + $xref =~ s/$symbols/\\$1/g; $xref = ":ref:`$xref <" . $data{$s}->{label} . ">`"; $desc =~ s,$bondary$s$bondary,$xref,g; -- cgit v1.2.3-71-gd317 From d3e6b2235e46a34f3d6b08283d1a817aeff0c757 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 25 Mar 2021 11:38:23 +0100 Subject: get_abi.pl: seek for all occurrences for Documentation/ABI Instead of retrieving just one match at most, ensure that the entire description will be parsed. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/17019b73e106d1b1b353b8880ed189bad3604c13.1616668017.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/get_abi.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index a9348b9bdaa4..3c82cd188368 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -380,7 +380,7 @@ sub output_rest { $desc =~ s,Documentation/(?!devicetree)(\S+)\.rst,:doc:`/$1`,g; - my @matches = $desc =~ m,Documentation/ABI/([\w\/\-]+),; + my @matches = $desc =~ m,Documentation/ABI/([\w\/\-]+),g; foreach my $f (@matches) { my $xref = $f; my $path = $f; -- cgit v1.2.3-71-gd317 From 50ebf8f4933ec27f0dc8c3b46c72894b14de0018 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 25 Mar 2021 11:38:24 +0100 Subject: get_abi.pl: fix xref boundaries There are some issues with the regex that seeks for What: cross references: basically, it is mis-identifying the start and the end boundaries of the regex, which causes :ref: to be inseerted for the wrong symbols at the wrong places. Fix it. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/79a14d2518499b76931b5f29c50979987108152d.1616668017.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/get_abi.pl | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index 3c82cd188368..e87028257d1c 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -281,8 +281,11 @@ sub create_labels { # Outputs the book on ReST format # -# \b doesn't work well with paths. So, we need to define something else -my $bondary = qr { (?{label})) { my $xref = $s; $xref =~ s/$symbols/\\$1/g; $xref = ":ref:`$xref <" . $data{$s}->{label} . ">`"; - $desc =~ s,$bondary$s$bondary,$xref,g; + $desc =~ s,$start$s$bondary,$1$xref$2,g; } } -- cgit v1.2.3-71-gd317 From 87ec9ea1fc27a6475ef09cf221c42943fa418f47 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 25 Mar 2021 11:38:25 +0100 Subject: scripts: get_abi.pl: extend xref match to other types Currently, there are "What:" symbols for more than just /sys. Extend the regex to also cover configfs, /proc /dev and /kvd symbols. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/a1c7e2b2c37ed6e111dfc8641deb37ed96375a63.1616668017.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/get_abi.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index e87028257d1c..eb1a23103afa 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -285,7 +285,7 @@ sub create_labels { # Boundaries are punct characters, spaces and end-of-line my $start = qr {(^|\s|\() }x; my $bondary = qr { ([,.:;\)\s]|\z) }x; -my $xref_match = qr { $start(\/sys\/[^,.:;\)\s]+)$bondary }x; +my $xref_match = qr { $start(\/(sys|config|proc|dev|kvd)\/[^,.:;\)\s]+)$bondary }x; my $symbols = qr { ([\x01-\x08\x0e-\x1f\x21-\x2f\x3a-\x40\x7b-\xff]) }x; sub output_rest { -- cgit v1.2.3-71-gd317 From c27c2e34412f8ca36ed1d8beb248d132aaf0016a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 25 Mar 2021 11:38:26 +0100 Subject: scripts: get_abi.pl: parse description line per line Change the description parsing logic in rst mode in order to parse it line per line. The end result is the same, but doing line per line allows to add some code to escape literal blocks when seeking for cross-references. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/d33cfa2e59ecf8f28d4ed7de7402468cf2168921.1616668017.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/get_abi.pl | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index eb1a23103afa..e5d1da492c1e 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -381,34 +381,41 @@ sub output_rest { # Enrich text by creating cross-references - $desc =~ s,Documentation/(?!devicetree)(\S+)\.rst,:doc:`/$1`,g; - - my @matches = $desc =~ m,Documentation/ABI/([\w\/\-]+),g; - foreach my $f (@matches) { - my $xref = $f; - my $path = $f; - $path =~ s,.*/(.*/.*),$1,;; - $path =~ s,[/\-],_,g;; - $xref .= " "; - $desc =~ s,\bDocumentation/ABI/$f\b,:ref:`$xref`,g; - } + my $new_desc = ""; + open(my $fh, "+<", \$desc); + while (my $d = <$fh>) { + $d =~ s,Documentation/(?!devicetree)(\S+)\.rst,:doc:`/$1`,g; + + my @matches = $d =~ m,Documentation/ABI/([\w\/\-]+),g; + foreach my $f (@matches) { + my $xref = $f; + my $path = $f; + $path =~ s,.*/(.*/.*),$1,;; + $path =~ s,[/\-],_,g;; + $xref .= " "; + $d =~ s,\bDocumentation/ABI/$f\b,:ref:`$xref`,g; + } - # Seek for cross reference symbols like /sys/... - @matches = $desc =~ m/$xref_match/g; + # Seek for cross reference symbols like /sys/... + @matches = $d =~ m/$xref_match/g; - foreach my $s (@matches) { - next if (!($s =~ m,/,)); - if (defined($data{$s}) && defined($data{$s}->{label})) { - my $xref = $s; + foreach my $s (@matches) { + next if (!($s =~ m,/,)); + if (defined($data{$s}) && defined($data{$s}->{label})) { + my $xref = $s; - $xref =~ s/$symbols/\\$1/g; - $xref = ":ref:`$xref <" . $data{$s}->{label} . ">`"; + $xref =~ s/$symbols/\\$1/g; + $xref = ":ref:`$xref <" . $data{$s}->{label} . ">`"; - $desc =~ s,$start$s$bondary,$1$xref$2,g; + $d =~ s,$start$s$bondary,$1$xref$2,g; + } } + $new_desc .= $d; } + close $fh; + - print "$desc\n\n"; + print "$new_desc\n\n"; } else { $desc =~ s/^\s+//; -- cgit v1.2.3-71-gd317 From 2ae7bb570e5d8b2da4b281fe7fae5c3de411f287 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 25 Mar 2021 11:38:27 +0100 Subject: scripts: get_abi: ignore code blocks for cross-references The script should not generate cross-references inside literal blocks. Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/a590f994f8a5742db333bde69e88241a080e4fe0.1616668017.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- scripts/get_abi.pl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'scripts') diff --git a/scripts/get_abi.pl b/scripts/get_abi.pl index e5d1da492c1e..d7aa82094296 100755 --- a/scripts/get_abi.pl +++ b/scripts/get_abi.pl @@ -382,8 +382,27 @@ sub output_rest { # Enrich text by creating cross-references my $new_desc = ""; + my $init_indent = -1; + my $literal_indent = -1; + open(my $fh, "+<", \$desc); while (my $d = <$fh>) { + my $indent = $d =~ m/^(\s+)/; + my $spaces = length($indent); + $init_indent = $indent if ($init_indent < 0); + if ($literal_indent >= 0) { + if ($spaces > $literal_indent) { + $new_desc .= $d; + next; + } else { + $literal_indent = -1; + } + } else { + if ($d =~ /()::$/ && !($d =~ /^\s*\.\./)) { + $literal_indent = $spaces; + } + } + $d =~ s,Documentation/(?!devicetree)(\S+)\.rst,:doc:`/$1`,g; my @matches = $d =~ m,Documentation/ABI/([\w\/\-]+),g; -- cgit v1.2.3-71-gd317 From 56ddc4cd4c8f9d65c0ac5544df4645376b327cbc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 1 Apr 2021 14:17:49 +0200 Subject: docs: dt: update writing-schema.rst references Changeset b83db5b84900 ("docs: dt: Group DT docs into relevant sub-sections") renamed: Documentation/devicetree/writing-schema.rst to: Documentation/devicetree/bindings/writing-schema.rst. Update the cross-references accordingly. Fixes: b83db5b84900 ("docs: dt: Group DT docs into relevant sub-sections") Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/7cfddf303f1508d26f90d87546d3812faebfc5ba.1617279356.git.mchehab+huawei@kernel.org Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/submitting-patches.rst | 2 +- scripts/checkpatch.pl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/Documentation/devicetree/bindings/submitting-patches.rst b/Documentation/devicetree/bindings/submitting-patches.rst index 51c459909575..a36c142249cc 100644 --- a/Documentation/devicetree/bindings/submitting-patches.rst +++ b/Documentation/devicetree/bindings/submitting-patches.rst @@ -25,7 +25,7 @@ I. For patch submitters make dt_binding_check - See Documentation/devicetree/writing-schema.rst for more details about + See Documentation/devicetree/bindings/writing-schema.rst for more details about schema and tools setup. 3) DT binding files should be dual licensed. The preferred license tag is diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index df8b23dc1eb0..3e8da40634b3 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3152,7 +3152,7 @@ sub process { ($line =~ /^new file mode\s*\d+\s*$/) && ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) { WARN("DT_SCHEMA_BINDING_PATCH", - "DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n"); + "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n"); } # Check for wrappage within a valid hunk of the file -- cgit v1.2.3-71-gd317 From cf68fffb66d60d96209446bfc4a15291dc5a5d41 Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Thu, 8 Apr 2021 11:28:26 -0700 Subject: add support for Clang CFI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change adds support for Clang’s forward-edge Control Flow Integrity (CFI) checking. With CONFIG_CFI_CLANG, the compiler injects a runtime check before each indirect function call to ensure the target is a valid function with the correct static type. This restricts possible call targets and makes it more difficult for an attacker to exploit bugs that allow the modification of stored function pointers. For more details, see: https://clang.llvm.org/docs/ControlFlowIntegrity.html Clang requires CONFIG_LTO_CLANG to be enabled with CFI to gain visibility to possible call targets. Kernel modules are supported with Clang’s cross-DSO CFI mode, which allows checking between independently compiled components. With CFI enabled, the compiler injects a __cfi_check() function into the kernel and each module for validating local call targets. For cross-module calls that cannot be validated locally, the compiler calls the global __cfi_slowpath_diag() function, which determines the target module and calls the correct __cfi_check() function. This patch includes a slowpath implementation that uses __module_address() to resolve call targets, and with CONFIG_CFI_CLANG_SHADOW enabled, a shadow map that speeds up module look-ups by ~3x. Clang implements indirect call checking using jump tables and offers two methods of generating them. With canonical jump tables, the compiler renames each address-taken function to .cfi and points the original symbol to a jump table entry, which passes __cfi_check() validation. This isn’t compatible with stand-alone assembly code, which the compiler doesn’t instrument, and would result in indirect calls to assembly code to fail. Therefore, we default to using non-canonical jump tables instead, where the compiler generates a local jump table entry .cfi_jt for each address-taken function, and replaces all references to the function with the address of the jump table entry. Note that because non-canonical jump table addresses are local to each component, they break cross-module function address equality. Specifically, the address of a global function will be different in each module, as it's replaced with the address of a local jump table entry. If this address is passed to a different module, it won’t match the address of the same function taken there. This may break code that relies on comparing addresses passed from other components. CFI checking can be disabled in a function with the __nocfi attribute. Additionally, CFI can be disabled for an entire compilation unit by filtering out CC_FLAGS_CFI. By default, CFI failures result in a kernel panic to stop a potential exploit. CONFIG_CFI_PERMISSIVE enables a permissive mode, where the kernel prints out a rate-limited warning instead, and allows execution to continue. This option is helpful for locating type mismatches, but should only be enabled during development. Signed-off-by: Sami Tolvanen Reviewed-by: Kees Cook Tested-by: Nathan Chancellor Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20210408182843.1754385-2-samitolvanen@google.com --- Makefile | 17 ++ arch/Kconfig | 45 ++++++ include/asm-generic/bug.h | 16 ++ include/asm-generic/vmlinux.lds.h | 20 ++- include/linux/cfi.h | 41 +++++ include/linux/compiler-clang.h | 2 + include/linux/compiler_types.h | 4 + include/linux/init.h | 2 +- include/linux/module.h | 13 +- init/Kconfig | 2 +- kernel/Makefile | 4 + kernel/cfi.c | 329 ++++++++++++++++++++++++++++++++++++++ kernel/module.c | 43 +++++ scripts/Makefile.modfinal | 2 +- 14 files changed, 534 insertions(+), 6 deletions(-) create mode 100644 include/linux/cfi.h create mode 100644 kernel/cfi.c (limited to 'scripts') diff --git a/Makefile b/Makefile index cc77fd45ca64..427f75249d5e 100644 --- a/Makefile +++ b/Makefile @@ -920,6 +920,23 @@ KBUILD_AFLAGS += -fno-lto export CC_FLAGS_LTO endif +ifdef CONFIG_CFI_CLANG +CC_FLAGS_CFI := -fsanitize=cfi \ + -fsanitize-cfi-cross-dso \ + -fno-sanitize-cfi-canonical-jump-tables \ + -fno-sanitize-trap=cfi \ + -fno-sanitize-blacklist + +ifdef CONFIG_CFI_PERMISSIVE +CC_FLAGS_CFI += -fsanitize-recover=cfi +endif + +# If LTO flags are filtered out, we must also filter out CFI. +CC_FLAGS_LTO += $(CC_FLAGS_CFI) +KBUILD_CFLAGS += $(CC_FLAGS_CFI) +export CC_FLAGS_CFI +endif + ifdef CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_32B KBUILD_CFLAGS += -falign-functions=32 endif diff --git a/arch/Kconfig b/arch/Kconfig index ecfd3520b676..f6a85ba6cba2 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -692,6 +692,51 @@ config LTO_CLANG_THIN If unsure, say Y. endchoice +config ARCH_SUPPORTS_CFI_CLANG + bool + help + An architecture should select this option if it can support Clang's + Control-Flow Integrity (CFI) checking. + +config CFI_CLANG + bool "Use Clang's Control Flow Integrity (CFI)" + depends on LTO_CLANG && ARCH_SUPPORTS_CFI_CLANG + # Clang >= 12: + # - https://bugs.llvm.org/show_bug.cgi?id=46258 + # - https://bugs.llvm.org/show_bug.cgi?id=47479 + depends on CLANG_VERSION >= 120000 + select KALLSYMS + help + This option enables Clang’s forward-edge Control Flow Integrity + (CFI) checking, where the compiler injects a runtime check to each + indirect function call to ensure the target is a valid function with + the correct static type. This restricts possible call targets and + makes it more difficult for an attacker to exploit bugs that allow + the modification of stored function pointers. More information can be + found from Clang's documentation: + + https://clang.llvm.org/docs/ControlFlowIntegrity.html + +config CFI_CLANG_SHADOW + bool "Use CFI shadow to speed up cross-module checks" + default y + depends on CFI_CLANG && MODULES + help + If you select this option, the kernel builds a fast look-up table of + CFI check functions in loaded modules to reduce performance overhead. + + If unsure, say Y. + +config CFI_PERMISSIVE + bool "Use CFI in permissive mode" + depends on CFI_CLANG + help + When selected, Control Flow Integrity (CFI) violations result in a + warning instead of a kernel panic. This option should only be used + for finding indirect call type mismatches during development. + + If unsure, say N. + config HAVE_ARCH_WITHIN_STACK_FRAMES bool help diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 76a10e0dca9f..b402494883b6 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -241,6 +241,22 @@ void __warn(const char *file, int line, void *caller, unsigned taint, # define WARN_ON_SMP(x) ({0;}) #endif +/* + * WARN_ON_FUNCTION_MISMATCH() warns if a value doesn't match a + * function address, and can be useful for catching issues with + * callback functions, for example. + * + * With CONFIG_CFI_CLANG, the warning is disabled because the + * compiler replaces function addresses taken in C code with + * local jump table addresses, which breaks cross-module function + * address equality. + */ +#if defined(CONFIG_CFI_CLANG) && defined(CONFIG_MODULES) +# define WARN_ON_FUNCTION_MISMATCH(x, fn) ({ 0; }) +#else +# define WARN_ON_FUNCTION_MISMATCH(x, fn) WARN_ON_ONCE((x) != (fn)) +#endif + #endif /* __ASSEMBLY__ */ #endif diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 0331d5d49551..40a9c101565e 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -544,6 +544,22 @@ . = ALIGN((align)); \ __end_rodata = .; + +/* + * .text..L.cfi.jumptable.* contain Control-Flow Integrity (CFI) + * jump table entries. + */ +#ifdef CONFIG_CFI_CLANG +#define TEXT_CFI_JT \ + . = ALIGN(PMD_SIZE); \ + __cfi_jt_start = .; \ + *(.text..L.cfi.jumptable .text..L.cfi.jumptable.*) \ + . = ALIGN(PMD_SIZE); \ + __cfi_jt_end = .; +#else +#define TEXT_CFI_JT +#endif + /* * Non-instrumentable text section */ @@ -570,6 +586,7 @@ NOINSTR_TEXT \ *(.text..refcount) \ *(.ref.text) \ + TEXT_CFI_JT \ MEM_KEEP(init.text*) \ MEM_KEEP(exit.text*) \ @@ -974,7 +991,8 @@ * keep any .init_array.* sections. * https://bugs.llvm.org/show_bug.cgi?id=46478 */ -#if defined(CONFIG_GCOV_KERNEL) || defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KCSAN) +#if defined(CONFIG_GCOV_KERNEL) || defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KCSAN) || \ + defined(CONFIG_CFI_CLANG) # ifdef CONFIG_CONSTRUCTORS # define SANITIZER_DISCARDS \ *(.eh_frame) diff --git a/include/linux/cfi.h b/include/linux/cfi.h new file mode 100644 index 000000000000..879744aaa6e0 --- /dev/null +++ b/include/linux/cfi.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Clang Control Flow Integrity (CFI) support. + * + * Copyright (C) 2021 Google LLC + */ +#ifndef _LINUX_CFI_H +#define _LINUX_CFI_H + +#ifdef CONFIG_CFI_CLANG +typedef void (*cfi_check_fn)(uint64_t id, void *ptr, void *diag); + +/* Compiler-generated function in each module, and the kernel */ +extern void __cfi_check(uint64_t id, void *ptr, void *diag); + +/* + * Force the compiler to generate a CFI jump table entry for a function + * and store the jump table address to __cfi_jt_. + */ +#define __CFI_ADDRESSABLE(fn, __attr) \ + const void *__cfi_jt_ ## fn __visible __attr = (void *)&fn + +#ifdef CONFIG_CFI_CLANG_SHADOW + +extern void cfi_module_add(struct module *mod, unsigned long base_addr); +extern void cfi_module_remove(struct module *mod, unsigned long base_addr); + +#else + +static inline void cfi_module_add(struct module *mod, unsigned long base_addr) {} +static inline void cfi_module_remove(struct module *mod, unsigned long base_addr) {} + +#endif /* CONFIG_CFI_CLANG_SHADOW */ + +#else /* !CONFIG_CFI_CLANG */ + +#define __CFI_ADDRESSABLE(fn, __attr) + +#endif /* CONFIG_CFI_CLANG */ + +#endif /* _LINUX_CFI_H */ diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h index d217c382b02d..6de9d0c9377e 100644 --- a/include/linux/compiler-clang.h +++ b/include/linux/compiler-clang.h @@ -61,3 +61,5 @@ #if __has_feature(shadow_call_stack) # define __noscs __attribute__((__no_sanitize__("shadow-call-stack"))) #endif + +#define __nocfi __attribute__((__no_sanitize__("cfi"))) diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index e5dd5a4ae946..796935a37e37 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -242,6 +242,10 @@ struct ftrace_likely_data { # define __noscs #endif +#ifndef __nocfi +# define __nocfi +#endif + #ifndef asm_volatile_goto #define asm_volatile_goto(x...) asm goto(x) #endif diff --git a/include/linux/init.h b/include/linux/init.h index 31f54de58429..b3ea15348fbd 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -47,7 +47,7 @@ /* These are for everybody (although not all archs will actually discard it in modules) */ -#define __init __section(".init.text") __cold __latent_entropy __noinitretpoline +#define __init __section(".init.text") __cold __latent_entropy __noinitretpoline __nocfi #define __initdata __section(".init.data") #define __initconst __section(".init.rodata") #define __exitdata __section(".exit.data") diff --git a/include/linux/module.h b/include/linux/module.h index da4b6fbe8ebe..8100bb477d86 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -128,13 +129,17 @@ extern void cleanup_module(void); #define module_init(initfn) \ static inline initcall_t __maybe_unused __inittest(void) \ { return initfn; } \ - int init_module(void) __copy(initfn) __attribute__((alias(#initfn))); + int init_module(void) __copy(initfn) \ + __attribute__((alias(#initfn))); \ + __CFI_ADDRESSABLE(init_module, __initdata); /* This is only required if you want to be unloadable. */ #define module_exit(exitfn) \ static inline exitcall_t __maybe_unused __exittest(void) \ { return exitfn; } \ - void cleanup_module(void) __copy(exitfn) __attribute__((alias(#exitfn))); + void cleanup_module(void) __copy(exitfn) \ + __attribute__((alias(#exitfn))); \ + __CFI_ADDRESSABLE(cleanup_module, __exitdata); #endif @@ -376,6 +381,10 @@ struct module { const s32 *crcs; unsigned int num_syms; +#ifdef CONFIG_CFI_CLANG + cfi_check_fn cfi_check; +#endif + /* Kernel parameters. */ #ifdef CONFIG_SYSFS struct mutex param_lock; diff --git a/init/Kconfig b/init/Kconfig index 5f5c776ef192..5babea38e346 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2296,7 +2296,7 @@ endif # MODULES config MODULES_TREE_LOOKUP def_bool y - depends on PERF_EVENTS || TRACING + depends on PERF_EVENTS || TRACING || CFI_CLANG config INIT_ALL_POSSIBLE bool diff --git a/kernel/Makefile b/kernel/Makefile index 320f1f3941b7..e8a6715f38dc 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -41,6 +41,9 @@ KCSAN_SANITIZE_kcov.o := n UBSAN_SANITIZE_kcov.o := n CFLAGS_kcov.o := $(call cc-option, -fno-conserve-stack) -fno-stack-protector +# Don't instrument error handlers +CFLAGS_REMOVE_cfi.o := $(CC_FLAGS_CFI) + obj-y += sched/ obj-y += locking/ obj-y += power/ @@ -111,6 +114,7 @@ obj-$(CONFIG_BPF) += bpf/ obj-$(CONFIG_KCSAN) += kcsan/ obj-$(CONFIG_SHADOW_CALL_STACK) += scs.o obj-$(CONFIG_HAVE_STATIC_CALL_INLINE) += static_call.o +obj-$(CONFIG_CFI_CLANG) += cfi.o obj-$(CONFIG_PERF_EVENTS) += events/ diff --git a/kernel/cfi.c b/kernel/cfi.c new file mode 100644 index 000000000000..e17a56639766 --- /dev/null +++ b/kernel/cfi.c @@ -0,0 +1,329 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Clang Control Flow Integrity (CFI) error and slowpath handling. + * + * Copyright (C) 2021 Google LLC + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Compiler-defined handler names */ +#ifdef CONFIG_CFI_PERMISSIVE +#define cfi_failure_handler __ubsan_handle_cfi_check_fail +#else +#define cfi_failure_handler __ubsan_handle_cfi_check_fail_abort +#endif + +static inline void handle_cfi_failure(void *ptr) +{ + if (IS_ENABLED(CONFIG_CFI_PERMISSIVE)) + WARN_RATELIMIT(1, "CFI failure (target: %pS):\n", ptr); + else + panic("CFI failure (target: %pS)\n", ptr); +} + +#ifdef CONFIG_MODULES +#ifdef CONFIG_CFI_CLANG_SHADOW +/* + * Index type. A 16-bit index can address at most (2^16)-2 pages (taking + * into account SHADOW_INVALID), i.e. ~256M with 4k pages. + */ +typedef u16 shadow_t; +#define SHADOW_INVALID ((shadow_t)~0UL) + +struct cfi_shadow { + /* Page index for the beginning of the shadow */ + unsigned long base; + /* An array of __cfi_check locations (as indices to the shadow) */ + shadow_t shadow[1]; +} __packed; + +/* + * The shadow covers ~128M from the beginning of the module region. If + * the region is larger, we fall back to __module_address for the rest. + */ +#define __SHADOW_RANGE (_UL(SZ_128M) >> PAGE_SHIFT) + +/* The in-memory size of struct cfi_shadow, always at least one page */ +#define __SHADOW_PAGES ((__SHADOW_RANGE * sizeof(shadow_t)) >> PAGE_SHIFT) +#define SHADOW_PAGES max(1UL, __SHADOW_PAGES) +#define SHADOW_SIZE (SHADOW_PAGES << PAGE_SHIFT) + +/* The actual size of the shadow array, minus metadata */ +#define SHADOW_ARR_SIZE (SHADOW_SIZE - offsetof(struct cfi_shadow, shadow)) +#define SHADOW_ARR_SLOTS (SHADOW_ARR_SIZE / sizeof(shadow_t)) + +static DEFINE_MUTEX(shadow_update_lock); +static struct cfi_shadow __rcu *cfi_shadow __read_mostly; + +/* Returns the index in the shadow for the given address */ +static inline int ptr_to_shadow(const struct cfi_shadow *s, unsigned long ptr) +{ + unsigned long index; + unsigned long page = ptr >> PAGE_SHIFT; + + if (unlikely(page < s->base)) + return -1; /* Outside of module area */ + + index = page - s->base; + + if (index >= SHADOW_ARR_SLOTS) + return -1; /* Cannot be addressed with shadow */ + + return (int)index; +} + +/* Returns the page address for an index in the shadow */ +static inline unsigned long shadow_to_ptr(const struct cfi_shadow *s, + int index) +{ + if (unlikely(index < 0 || index >= SHADOW_ARR_SLOTS)) + return 0; + + return (s->base + index) << PAGE_SHIFT; +} + +/* Returns the __cfi_check function address for the given shadow location */ +static inline unsigned long shadow_to_check_fn(const struct cfi_shadow *s, + int index) +{ + if (unlikely(index < 0 || index >= SHADOW_ARR_SLOTS)) + return 0; + + if (unlikely(s->shadow[index] == SHADOW_INVALID)) + return 0; + + /* __cfi_check is always page aligned */ + return (s->base + s->shadow[index]) << PAGE_SHIFT; +} + +static void prepare_next_shadow(const struct cfi_shadow __rcu *prev, + struct cfi_shadow *next) +{ + int i, index, check; + + /* Mark everything invalid */ + memset(next->shadow, 0xFF, SHADOW_ARR_SIZE); + + if (!prev) + return; /* No previous shadow */ + + /* If the base address didn't change, an update is not needed */ + if (prev->base == next->base) { + memcpy(next->shadow, prev->shadow, SHADOW_ARR_SIZE); + return; + } + + /* Convert the previous shadow to the new address range */ + for (i = 0; i < SHADOW_ARR_SLOTS; ++i) { + if (prev->shadow[i] == SHADOW_INVALID) + continue; + + index = ptr_to_shadow(next, shadow_to_ptr(prev, i)); + if (index < 0) + continue; + + check = ptr_to_shadow(next, + shadow_to_check_fn(prev, prev->shadow[i])); + if (check < 0) + continue; + + next->shadow[index] = (shadow_t)check; + } +} + +static void add_module_to_shadow(struct cfi_shadow *s, struct module *mod, + unsigned long min_addr, unsigned long max_addr) +{ + int check_index; + unsigned long check = (unsigned long)mod->cfi_check; + unsigned long ptr; + + if (unlikely(!PAGE_ALIGNED(check))) { + pr_warn("cfi: not using shadow for module %s\n", mod->name); + return; + } + + check_index = ptr_to_shadow(s, check); + if (check_index < 0) + return; /* Module not addressable with shadow */ + + /* For each page, store the check function index in the shadow */ + for (ptr = min_addr; ptr <= max_addr; ptr += PAGE_SIZE) { + int index = ptr_to_shadow(s, ptr); + + if (index >= 0) { + /* Each page must only contain one module */ + WARN_ON_ONCE(s->shadow[index] != SHADOW_INVALID); + s->shadow[index] = (shadow_t)check_index; + } + } +} + +static void remove_module_from_shadow(struct cfi_shadow *s, struct module *mod, + unsigned long min_addr, unsigned long max_addr) +{ + unsigned long ptr; + + for (ptr = min_addr; ptr <= max_addr; ptr += PAGE_SIZE) { + int index = ptr_to_shadow(s, ptr); + + if (index >= 0) + s->shadow[index] = SHADOW_INVALID; + } +} + +typedef void (*update_shadow_fn)(struct cfi_shadow *, struct module *, + unsigned long min_addr, unsigned long max_addr); + +static void update_shadow(struct module *mod, unsigned long base_addr, + update_shadow_fn fn) +{ + struct cfi_shadow *prev; + struct cfi_shadow *next; + unsigned long min_addr, max_addr; + + next = vmalloc(SHADOW_SIZE); + + mutex_lock(&shadow_update_lock); + prev = rcu_dereference_protected(cfi_shadow, + mutex_is_locked(&shadow_update_lock)); + + if (next) { + next->base = base_addr >> PAGE_SHIFT; + prepare_next_shadow(prev, next); + + min_addr = (unsigned long)mod->core_layout.base; + max_addr = min_addr + mod->core_layout.text_size; + fn(next, mod, min_addr & PAGE_MASK, max_addr & PAGE_MASK); + + set_memory_ro((unsigned long)next, SHADOW_PAGES); + } + + rcu_assign_pointer(cfi_shadow, next); + mutex_unlock(&shadow_update_lock); + synchronize_rcu(); + + if (prev) { + set_memory_rw((unsigned long)prev, SHADOW_PAGES); + vfree(prev); + } +} + +void cfi_module_add(struct module *mod, unsigned long base_addr) +{ + update_shadow(mod, base_addr, add_module_to_shadow); +} + +void cfi_module_remove(struct module *mod, unsigned long base_addr) +{ + update_shadow(mod, base_addr, remove_module_from_shadow); +} + +static inline cfi_check_fn ptr_to_check_fn(const struct cfi_shadow __rcu *s, + unsigned long ptr) +{ + int index; + + if (unlikely(!s)) + return NULL; /* No shadow available */ + + index = ptr_to_shadow(s, ptr); + if (index < 0) + return NULL; /* Cannot be addressed with shadow */ + + return (cfi_check_fn)shadow_to_check_fn(s, index); +} + +static inline cfi_check_fn find_shadow_check_fn(unsigned long ptr) +{ + cfi_check_fn fn; + + rcu_read_lock_sched(); + fn = ptr_to_check_fn(rcu_dereference_sched(cfi_shadow), ptr); + rcu_read_unlock_sched(); + + return fn; +} + +#else /* !CONFIG_CFI_CLANG_SHADOW */ + +static inline cfi_check_fn find_shadow_check_fn(unsigned long ptr) +{ + return NULL; +} + +#endif /* CONFIG_CFI_CLANG_SHADOW */ + +static inline cfi_check_fn find_module_check_fn(unsigned long ptr) +{ + cfi_check_fn fn = NULL; + struct module *mod; + + rcu_read_lock_sched(); + mod = __module_address(ptr); + if (mod) + fn = mod->cfi_check; + rcu_read_unlock_sched(); + + return fn; +} + +static inline cfi_check_fn find_check_fn(unsigned long ptr) +{ + cfi_check_fn fn = NULL; + + if (is_kernel_text(ptr)) + return __cfi_check; + + /* + * Indirect call checks can happen when RCU is not watching. Both + * the shadow and __module_address use RCU, so we need to wake it + * up if necessary. + */ + RCU_NONIDLE({ + if (IS_ENABLED(CONFIG_CFI_CLANG_SHADOW)) + fn = find_shadow_check_fn(ptr); + + if (!fn) + fn = find_module_check_fn(ptr); + }); + + return fn; +} + +void __cfi_slowpath_diag(uint64_t id, void *ptr, void *diag) +{ + cfi_check_fn fn = find_check_fn((unsigned long)ptr); + + if (likely(fn)) + fn(id, ptr, diag); + else /* Don't allow unchecked modules */ + handle_cfi_failure(ptr); +} +EXPORT_SYMBOL(__cfi_slowpath_diag); + +#else /* !CONFIG_MODULES */ + +void __cfi_slowpath_diag(uint64_t id, void *ptr, void *diag) +{ + handle_cfi_failure(ptr); /* No modules */ +} +EXPORT_SYMBOL(__cfi_slowpath_diag); + +#endif /* CONFIG_MODULES */ + +void cfi_failure_handler(void *data, void *ptr, void *vtable) +{ + handle_cfi_failure(ptr); +} +EXPORT_SYMBOL(cfi_failure_handler); diff --git a/kernel/module.c b/kernel/module.c index 30479355ab85..20fb004e7d8d 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2146,6 +2146,8 @@ void __weak module_arch_freeing_init(struct module *mod) { } +static void cfi_cleanup(struct module *mod); + /* Free a module, remove from lists, etc. */ static void free_module(struct module *mod) { @@ -2187,6 +2189,9 @@ static void free_module(struct module *mod) synchronize_rcu(); mutex_unlock(&module_mutex); + /* Clean up CFI for the module. */ + cfi_cleanup(mod); + /* This may be empty, but that's OK */ module_arch_freeing_init(mod); module_memfree(mod->init_layout.base); @@ -3866,6 +3871,8 @@ static int unknown_module_param_cb(char *param, char *val, const char *modname, return 0; } +static void cfi_init(struct module *mod); + /* * Allocate and load the module: note that size of section 0 is always * zero, and we rely on this for optional sections. @@ -3997,6 +4004,9 @@ static int load_module(struct load_info *info, const char __user *uargs, flush_module_icache(mod); + /* Setup CFI for the module. */ + cfi_init(mod); + /* Now copy in args */ mod->args = strndup_user(uargs, ~0UL >> 1); if (IS_ERR(mod->args)) { @@ -4070,6 +4080,7 @@ static int load_module(struct load_info *info, const char __user *uargs, synchronize_rcu(); kfree(mod->args); free_arch_cleanup: + cfi_cleanup(mod); module_arch_cleanup(mod); free_modinfo: free_modinfo(mod); @@ -4415,6 +4426,38 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, #endif /* CONFIG_LIVEPATCH */ #endif /* CONFIG_KALLSYMS */ +static void cfi_init(struct module *mod) +{ +#ifdef CONFIG_CFI_CLANG + initcall_t *init; + exitcall_t *exit; + + rcu_read_lock_sched(); + mod->cfi_check = (cfi_check_fn) + find_kallsyms_symbol_value(mod, "__cfi_check"); + init = (initcall_t *) + find_kallsyms_symbol_value(mod, "__cfi_jt_init_module"); + exit = (exitcall_t *) + find_kallsyms_symbol_value(mod, "__cfi_jt_cleanup_module"); + rcu_read_unlock_sched(); + + /* Fix init/exit functions to point to the CFI jump table */ + if (init) + mod->init = *init; + if (exit) + mod->exit = *exit; + + cfi_module_add(mod, module_addr_min); +#endif +} + +static void cfi_cleanup(struct module *mod) +{ +#ifdef CONFIG_CFI_CLANG + cfi_module_remove(mod, module_addr_min); +#endif +} + /* Maximum number of characters written by module_flags() */ #define MODULE_FLAGS_BUF_SIZE (TAINT_FLAGS_COUNT + 4) diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 735e11e9041b..dd87cea9fba7 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -23,7 +23,7 @@ modname = $(notdir $(@:.mod.o=)) part-of-module = y quiet_cmd_cc_o_c = CC [M] $@ - cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< + cmd_cc_o_c = $(CC) $(filter-out $(CC_FLAGS_CFI), $(c_flags)) -c -o $@ $< %.mod.o: %.mod.c FORCE $(call if_changed_dep,cc_o_c) -- cgit v1.2.3-71-gd317 From 28aad1c29053195b1a9f56742e64b679d61e786b Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Thu, 8 Apr 2021 11:28:29 -0700 Subject: module: ensure __cfi_check alignment CONFIG_CFI_CLANG_SHADOW assumes the __cfi_check() function is page aligned and at the beginning of the .text section. While Clang would normally align the function correctly, it fails to do so for modules with no executable code. This change ensures the correct __cfi_check() location and alignment. It also discards the .eh_frame section, which Clang can generate with certain sanitizers, such as CFI. Link: https://bugs.llvm.org/show_bug.cgi?id=46293 Signed-off-by: Sami Tolvanen Reviewed-by: Kees Cook Acked-by: Jessica Yu Tested-by: Nathan Chancellor Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20210408182843.1754385-5-samitolvanen@google.com --- scripts/module.lds.S | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/module.lds.S b/scripts/module.lds.S index 2c52535f9b56..04c5685c25cf 100644 --- a/scripts/module.lds.S +++ b/scripts/module.lds.S @@ -3,10 +3,20 @@ * Archs are free to supply their own linker scripts. ld will * combine them automatically. */ +#ifdef CONFIG_CFI_CLANG +# include +# define ALIGN_CFI ALIGN(PAGE_SIZE) +# define SANITIZER_DISCARDS *(.eh_frame) +#else +# define ALIGN_CFI +# define SANITIZER_DISCARDS +#endif + SECTIONS { /DISCARD/ : { *(.discard) *(.discard.*) + SANITIZER_DISCARDS } __ksymtab 0 : { *(SORT(___ksymtab+*)) } @@ -41,7 +51,14 @@ SECTIONS { *(.rodata..L*) } - .text : { *(.text .text.[0-9a-zA-Z_]*) } + /* + * With CONFIG_CFI_CLANG, we assume __cfi_check is at the beginning + * of the .text section, and is aligned to PAGE_SIZE. + */ + .text : ALIGN_CFI { + *(.text.__cfi_check) + *(.text .text.[0-9a-zA-Z_]* .text..L.cfi*) + } #endif } -- cgit v1.2.3-71-gd317 From db16c1fe92d7ba7d39061faef897842baee2c887 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Tue, 13 Apr 2021 21:00:43 +0200 Subject: bpf: Generate BTF_KIND_FLOAT when linking vmlinux pahole v1.21 supports the --btf_gen_floats flag, which makes it generate the information about the floating-point types [1]. Adjust link-vmlinux.sh to pass this flag to pahole in case it's supported, which is determined using a simple version check. [1] https://lore.kernel.org/dwarves/YHRiXNX1JUF2Az0A@kernel.org/ Signed-off-by: Ilya Leoshkevich Signed-off-by: Andrii Nakryiko Acked-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20210413190043.21918-1-iii@linux.ibm.com --- scripts/link-vmlinux.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 3b261b0f74f0..667aacb9261c 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -213,6 +213,7 @@ vmlinux_link() gen_btf() { local pahole_ver + local extra_paholeopt= if ! [ -x "$(command -v ${PAHOLE})" ]; then echo >&2 "BTF: ${1}: pahole (${PAHOLE}) is not available" @@ -227,8 +228,12 @@ gen_btf() vmlinux_link ${1} + if [ "${pahole_ver}" -ge "121" ]; then + extra_paholeopt="${extra_paholeopt} --btf_gen_floats" + fi + info "BTF" ${2} - LLVM_OBJCOPY=${OBJCOPY} ${PAHOLE} -J ${1} + LLVM_OBJCOPY=${OBJCOPY} ${PAHOLE} -J ${extra_paholeopt} ${1} # Create ${2} which contains just .BTF section but no symbols. Add # SHF_ALLOC because .BTF will be part of the vmlinux image. --strip-all -- cgit v1.2.3-71-gd317 From 98f8475c78697f6c1155f93d3a346d9027deb5aa Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 14 Mar 2021 04:48:30 +0900 Subject: kconfig: move conf_set_all_new_symbols() to conf.c This function is only used in conf.c. Move it there together with the randomize_choice_values() helper. Define 'enum conf_def_mode' locally in conf.c as well. Signed-off-by: Masahiro Yamada --- scripts/kconfig/conf.c | 193 +++++++++++++++++++++++++++++++++++++++++++++ scripts/kconfig/confdata.c | 176 ----------------------------------------- scripts/kconfig/lkc.h | 11 --- 3 files changed, 193 insertions(+), 187 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 89c9ba83f9e7..10958f1e41d6 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -112,6 +112,199 @@ static void set_randconfig_seed(void) srand(seed); } +static bool randomize_choice_values(struct symbol *csym) +{ + struct property *prop; + struct symbol *sym; + struct expr *e; + int cnt, def; + + /* + * If choice is mod then we may have more items selected + * and if no then no-one. + * In both cases stop. + */ + if (csym->curr.tri != yes) + return false; + + prop = sym_get_choice_prop(csym); + + /* count entries in choice block */ + cnt = 0; + expr_list_for_each_sym(prop->expr, e, sym) + cnt++; + + /* + * find a random value and set it to yes, + * set the rest to no so we have only one set + */ + def = rand() % cnt; + + cnt = 0; + expr_list_for_each_sym(prop->expr, e, sym) { + if (def == cnt++) { + sym->def[S_DEF_USER].tri = yes; + csym->def[S_DEF_USER].val = sym; + } else { + sym->def[S_DEF_USER].tri = no; + } + sym->flags |= SYMBOL_DEF_USER; + /* clear VALID to get value calculated */ + sym->flags &= ~SYMBOL_VALID; + } + csym->flags |= SYMBOL_DEF_USER; + /* clear VALID to get value calculated */ + csym->flags &= ~SYMBOL_VALID; + + return true; +} + +enum conf_def_mode { + def_default, + def_yes, + def_mod, + def_y2m, + def_m2y, + def_no, + def_random +}; + +static bool conf_set_all_new_symbols(enum conf_def_mode mode) +{ + struct symbol *sym, *csym; + int i, cnt; + /* + * can't go as the default in switch-case below, otherwise gcc whines + * about -Wmaybe-uninitialized + */ + int pby = 50; /* probability of bool = y */ + int pty = 33; /* probability of tristate = y */ + int ptm = 33; /* probability of tristate = m */ + bool has_changed = false; + + if (mode == def_random) { + int n, p[3]; + char *env = getenv("KCONFIG_PROBABILITY"); + + n = 0; + while (env && *env) { + char *endp; + int tmp = strtol(env, &endp, 10); + + if (tmp >= 0 && tmp <= 100) { + p[n++] = tmp; + } else { + errno = ERANGE; + perror("KCONFIG_PROBABILITY"); + exit(1); + } + env = (*endp == ':') ? endp + 1 : endp; + if (n >= 3) + break; + } + switch (n) { + case 1: + pby = p[0]; + ptm = pby / 2; + pty = pby - ptm; + break; + case 2: + pty = p[0]; + ptm = p[1]; + pby = pty + ptm; + break; + case 3: + pby = p[0]; + pty = p[1]; + ptm = p[2]; + break; + } + + if (pty + ptm > 100) { + errno = ERANGE; + perror("KCONFIG_PROBABILITY"); + exit(1); + } + } + + for_all_symbols(i, sym) { + if (sym_has_value(sym) || sym->flags & SYMBOL_VALID) + continue; + switch (sym_get_type(sym)) { + case S_BOOLEAN: + case S_TRISTATE: + has_changed = true; + switch (mode) { + case def_yes: + sym->def[S_DEF_USER].tri = yes; + break; + case def_mod: + sym->def[S_DEF_USER].tri = mod; + break; + case def_no: + if (sym->flags & SYMBOL_ALLNOCONFIG_Y) + sym->def[S_DEF_USER].tri = yes; + else + sym->def[S_DEF_USER].tri = no; + break; + case def_random: + sym->def[S_DEF_USER].tri = no; + cnt = rand() % 100; + if (sym->type == S_TRISTATE) { + if (cnt < pty) + sym->def[S_DEF_USER].tri = yes; + else if (cnt < pty + ptm) + sym->def[S_DEF_USER].tri = mod; + } else if (cnt < pby) + sym->def[S_DEF_USER].tri = yes; + break; + default: + continue; + } + if (!(sym_is_choice(sym) && mode == def_random)) + sym->flags |= SYMBOL_DEF_USER; + break; + default: + break; + } + + } + + sym_clear_all_valid(); + + /* + * We have different type of choice blocks. + * If curr.tri equals to mod then we can select several + * choice symbols in one block. + * In this case we do nothing. + * If curr.tri equals yes then only one symbol can be + * selected in a choice block and we set it to yes, + * and the rest to no. + */ + if (mode != def_random) { + for_all_symbols(i, csym) { + if ((sym_is_choice(csym) && !sym_has_value(csym)) || + sym_is_choice_value(csym)) + csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES; + } + } + + for_all_symbols(i, csym) { + if (sym_has_value(csym) || !sym_is_choice(csym)) + continue; + + sym_calc_value(csym); + if (mode == def_random) + has_changed |= randomize_choice_values(csym); + else { + set_all_choice_values(csym); + has_changed = true; + } + } + + return has_changed; +} + static void conf_rewrite_mod_or_yes(enum conf_def_mode mode) { struct symbol *sym; diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index a828622cb2d0..198f70957fbf 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -1127,54 +1127,6 @@ void conf_set_changed_callback(void (*fn)(void)) conf_changed_callback = fn; } -static bool randomize_choice_values(struct symbol *csym) -{ - struct property *prop; - struct symbol *sym; - struct expr *e; - int cnt, def; - - /* - * If choice is mod then we may have more items selected - * and if no then no-one. - * In both cases stop. - */ - if (csym->curr.tri != yes) - return false; - - prop = sym_get_choice_prop(csym); - - /* count entries in choice block */ - cnt = 0; - expr_list_for_each_sym(prop->expr, e, sym) - cnt++; - - /* - * find a random value and set it to yes, - * set the rest to no so we have only one set - */ - def = (rand() % cnt); - - cnt = 0; - expr_list_for_each_sym(prop->expr, e, sym) { - if (def == cnt++) { - sym->def[S_DEF_USER].tri = yes; - csym->def[S_DEF_USER].val = sym; - } - else { - sym->def[S_DEF_USER].tri = no; - } - sym->flags |= SYMBOL_DEF_USER; - /* clear VALID to get value calculated */ - sym->flags &= ~SYMBOL_VALID; - } - csym->flags |= SYMBOL_DEF_USER; - /* clear VALID to get value calculated */ - csym->flags &= ~(SYMBOL_VALID); - - return true; -} - void set_all_choice_values(struct symbol *csym) { struct property *prop; @@ -1194,131 +1146,3 @@ void set_all_choice_values(struct symbol *csym) /* clear VALID to get value calculated */ csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES); } - -bool conf_set_all_new_symbols(enum conf_def_mode mode) -{ - struct symbol *sym, *csym; - int i, cnt, pby, pty, ptm; /* pby: probability of bool = y - * pty: probability of tristate = y - * ptm: probability of tristate = m - */ - - pby = 50; pty = ptm = 33; /* can't go as the default in switch-case - * below, otherwise gcc whines about - * -Wmaybe-uninitialized */ - if (mode == def_random) { - int n, p[3]; - char *env = getenv("KCONFIG_PROBABILITY"); - n = 0; - while( env && *env ) { - char *endp; - int tmp = strtol( env, &endp, 10 ); - if( tmp >= 0 && tmp <= 100 ) { - p[n++] = tmp; - } else { - errno = ERANGE; - perror( "KCONFIG_PROBABILITY" ); - exit( 1 ); - } - env = (*endp == ':') ? endp+1 : endp; - if( n >=3 ) { - break; - } - } - switch( n ) { - case 1: - pby = p[0]; ptm = pby/2; pty = pby-ptm; - break; - case 2: - pty = p[0]; ptm = p[1]; pby = pty + ptm; - break; - case 3: - pby = p[0]; pty = p[1]; ptm = p[2]; - break; - } - - if( pty+ptm > 100 ) { - errno = ERANGE; - perror( "KCONFIG_PROBABILITY" ); - exit( 1 ); - } - } - bool has_changed = false; - - for_all_symbols(i, sym) { - if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID)) - continue; - switch (sym_get_type(sym)) { - case S_BOOLEAN: - case S_TRISTATE: - has_changed = true; - switch (mode) { - case def_yes: - sym->def[S_DEF_USER].tri = yes; - break; - case def_mod: - sym->def[S_DEF_USER].tri = mod; - break; - case def_no: - if (sym->flags & SYMBOL_ALLNOCONFIG_Y) - sym->def[S_DEF_USER].tri = yes; - else - sym->def[S_DEF_USER].tri = no; - break; - case def_random: - sym->def[S_DEF_USER].tri = no; - cnt = rand() % 100; - if (sym->type == S_TRISTATE) { - if (cnt < pty) - sym->def[S_DEF_USER].tri = yes; - else if (cnt < (pty+ptm)) - sym->def[S_DEF_USER].tri = mod; - } else if (cnt < pby) - sym->def[S_DEF_USER].tri = yes; - break; - default: - continue; - } - if (!(sym_is_choice(sym) && mode == def_random)) - sym->flags |= SYMBOL_DEF_USER; - break; - default: - break; - } - - } - - sym_clear_all_valid(); - - /* - * We have different type of choice blocks. - * If curr.tri equals to mod then we can select several - * choice symbols in one block. - * In this case we do nothing. - * If curr.tri equals yes then only one symbol can be - * selected in a choice block and we set it to yes, - * and the rest to no. - */ - if (mode != def_random) { - for_all_symbols(i, csym) { - if ((sym_is_choice(csym) && !sym_has_value(csym)) || - sym_is_choice_value(csym)) - csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES; - } - } - - for_all_symbols(i, csym) { - if (sym_has_value(csym) || !sym_is_choice(csym)) - continue; - - sym_calc_value(csym); - if (mode == def_random) - has_changed |= randomize_choice_values(csym); - else { - set_all_choice_values(csym); - has_changed = true; - } - } - - return has_changed; -} diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index f946ab49ef50..1c15e3c98bdf 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -34,16 +34,6 @@ static inline const char *CONFIG_prefix(void) #undef CONFIG_ #define CONFIG_ CONFIG_prefix() -enum conf_def_mode { - def_default, - def_yes, - def_mod, - def_y2m, - def_m2y, - def_no, - def_random -}; - extern int yylineno; void zconfdump(FILE *out); void zconf_starthelp(void); @@ -57,7 +47,6 @@ const char *zconf_curname(void); const char *conf_get_configname(void); void sym_set_change_count(int count); void sym_add_change_count(int count); -bool conf_set_all_new_symbols(enum conf_def_mode mode); void set_all_choice_values(struct symbol *csym); /* confdata.c and expr.c */ -- cgit v1.2.3-71-gd317 From 406616213bb776a6e6ec69192df39ab1042690f1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 14 Mar 2021 04:48:31 +0900 Subject: kconfig: move JUMP_NB to mconf.c This macro is only used in mconf.c. Signed-off-by: Masahiro Yamada --- scripts/kconfig/expr.h | 2 -- scripts/kconfig/mconf.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 5c3443692f34..bbca80a0dc24 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -281,8 +281,6 @@ struct jump_key { int index; }; -#define JUMP_NB 9 - extern struct file *file_list; extern struct file *current_file; struct file *lookup_file(const char *name); diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 4063dbc1b927..01b6c27224e2 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -22,6 +22,8 @@ #include "lkc.h" #include "lxdialog/dialog.h" +#define JUMP_NB 9 + static const char mconf_readme[] = "Overview\n" "--------\n" -- cgit v1.2.3-71-gd317 From b75b0a819af9f78fc395b189cddd40f590194d20 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 14 Mar 2021 04:48:32 +0900 Subject: kconfig: change defconfig_list option to environment variable "defconfig_list" is a weird option that defines a static symbol that declares the list of base config files in case the .config does not exist yet. This is quite different from other normal symbols; we just abused the "string" type and the "default" properties to list out the input files. They must be fixed values since these are searched for and loaded in the parse stage. It is an ugly hack, and should not exist in the first place. Providing this feature as an environment variable is a saner approach. Signed-off-by: Masahiro Yamada --- Documentation/kbuild/kconfig-language.rst | 5 ---- Documentation/kbuild/kconfig.rst | 8 +++++++ init/Kconfig | 9 -------- scripts/kconfig/Makefile | 10 ++++++++ scripts/kconfig/confdata.c | 38 +++++++++++++++++++++++-------- scripts/kconfig/expr.h | 1 - scripts/kconfig/lexer.l | 1 - scripts/kconfig/lkc.h | 1 - scripts/kconfig/menu.c | 9 -------- scripts/kconfig/parser.y | 6 ----- scripts/kconfig/symbol.c | 1 - scripts/kconfig/tests/conftest.py | 4 ++++ 12 files changed, 50 insertions(+), 43 deletions(-) (limited to 'scripts') diff --git a/Documentation/kbuild/kconfig-language.rst b/Documentation/kbuild/kconfig-language.rst index 226ae072da7d..3cbccfc42798 100644 --- a/Documentation/kbuild/kconfig-language.rst +++ b/Documentation/kbuild/kconfig-language.rst @@ -229,11 +229,6 @@ applicable everywhere (see syntax). which can modify the behaviour of the menu entry and its config symbol. These options are currently possible: - - "defconfig_list" - This declares a list of default entries which can be used when - looking for the default configuration (which is used when the main - .config doesn't exists yet.) - - "modules" This declares the symbol to be used as the MODULES symbol, which enables the third modular state for all config symbols. diff --git a/Documentation/kbuild/kconfig.rst b/Documentation/kbuild/kconfig.rst index dce6801d66c9..5967c79c3baa 100644 --- a/Documentation/kbuild/kconfig.rst +++ b/Documentation/kbuild/kconfig.rst @@ -41,6 +41,14 @@ KCONFIG_CONFIG This environment variable can be used to specify a default kernel config file name to override the default name of ".config". +KCONFIG_DEFCONFIG_LIST +---------------------- + +This environment variable specifies a list of config files which can be used +as a base configuration in case the .config does not exist yet. Entries in +the list are separated with whitespaces to each other, and the first one +that exists is used. + KCONFIG_OVERWRITECONFIG ----------------------- If you set KCONFIG_OVERWRITECONFIG in the environment, Kconfig will not diff --git a/init/Kconfig b/init/Kconfig index 5f5c776ef192..8578c6009674 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1,13 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -config DEFCONFIG_LIST - string - depends on !UML - option defconfig_list - default "/lib/modules/$(shell,uname -r)/.config" - default "/etc/kernel-config" - default "/boot/config-$(shell,uname -r)" - default "arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)" - config CC_VERSION_TEXT string default "$(CC_VERSION_TEXT)" diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 8c19b82c6035..31c5735663c8 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -13,6 +13,16 @@ ifeq ($(quiet),silent_) silent := -s endif +export KCONFIG_DEFCONFIG_LIST := +ifneq ($(SRCARCH),um) +kernel-release := $(shell uname -r) +KCONFIG_DEFCONFIG_LIST := \ + /lib/modules/$(kernel-release)/.config \ + /etc/kernel-config \ + /boot/config-$(kernel-release) \ + arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) +endif + # We need this, in case the user has it in its environment unexport CONFIG_ diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 198f70957fbf..f3998d5ddd02 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -360,28 +360,46 @@ int conf_read_simple(const char *name, int def) if (name) { in = zconf_fopen(name); } else { - struct property *prop; + char *env; name = conf_get_configname(); in = zconf_fopen(name); if (in) goto load; sym_add_change_count(1); - if (!sym_defconfig_list) + + env = getenv("KCONFIG_DEFCONFIG_LIST"); + if (!env) return 1; - for_all_defaults(sym_defconfig_list, prop) { - if (expr_calc_value(prop->visible.expr) == no || - prop->expr->type != E_SYMBOL) - continue; - sym_calc_value(prop->expr->left.sym); - name = sym_get_string_value(prop->expr->left.sym); - in = zconf_fopen(name); + while (1) { + bool is_last; + + while (isspace(*env)) + env++; + + if (!*env) + break; + + p = env; + while (*p && !isspace(*p)) + p++; + + is_last = (*p == '\0'); + + *p = '\0'; + + in = zconf_fopen(env); if (in) { conf_message("using defaults found in %s", - name); + env); goto load; } + + if (is_last) + break; + + env = p + 1; } } if (!in) diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index bbca80a0dc24..dc17152b1f14 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -287,7 +287,6 @@ struct file *lookup_file(const char *name); extern struct symbol symbol_yes, symbol_no, symbol_mod; extern struct symbol *modules_sym; -extern struct symbol *sym_defconfig_list; extern int cdebug; struct expr *expr_alloc_symbol(struct symbol *sym); struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l index 9c22cb554673..e918950f94a6 100644 --- a/scripts/kconfig/lexer.l +++ b/scripts/kconfig/lexer.l @@ -99,7 +99,6 @@ n [A-Za-z0-9_-] "def_bool" return T_DEF_BOOL; "def_tristate" return T_DEF_TRISTATE; "default" return T_DEFAULT; -"defconfig_list" return T_DEFCONFIG_LIST; "depends" return T_DEPENDS; "endchoice" return T_ENDCHOICE; "endif" return T_ENDIF; diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 1c15e3c98bdf..7378e966add5 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -96,7 +96,6 @@ struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); void menu_add_option_modules(void); -void menu_add_option_defconfig_list(void); void menu_add_option_allnoconfig_y(void); void menu_finalize(struct menu *parent); void menu_set_type(int type); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index a5fbd6ccc006..5dcfc173da41 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -219,15 +219,6 @@ void menu_add_option_modules(void) modules_sym = current_entry->sym; } -void menu_add_option_defconfig_list(void) -{ - if (!sym_defconfig_list) - sym_defconfig_list = current_entry->sym; - else if (sym_defconfig_list != current_entry->sym) - zconf_error("trying to redefine defconfig symbol"); - sym_defconfig_list->flags |= SYMBOL_NO_WRITE; -} - void menu_add_option_allnoconfig_y(void) { current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y index 190f1117f35a..f11d8382e9e6 100644 --- a/scripts/kconfig/parser.y +++ b/scripts/kconfig/parser.y @@ -53,7 +53,6 @@ static struct menu *current_menu, *current_entry; %token T_COMMENT %token T_CONFIG %token T_DEFAULT -%token T_DEFCONFIG_LIST %token T_DEF_BOOL %token T_DEF_TRISTATE %token T_DEPENDS @@ -223,11 +222,6 @@ config_option: T_OPTION T_MODULES T_EOL menu_add_option_modules(); }; -config_option: T_OPTION T_DEFCONFIG_LIST T_EOL -{ - menu_add_option_defconfig_list(); -}; - config_option: T_OPTION T_ALLNOCONFIG_Y T_EOL { menu_add_option_allnoconfig_y(); diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index fe38e6fd2c2a..36b0fcb18117 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -35,7 +35,6 @@ static struct symbol symbol_empty = { .flags = SYMBOL_VALID, }; -struct symbol *sym_defconfig_list; struct symbol *modules_sym; static tristate modules_val; diff --git a/scripts/kconfig/tests/conftest.py b/scripts/kconfig/tests/conftest.py index 0345ef6e3273..af8774a5697c 100644 --- a/scripts/kconfig/tests/conftest.py +++ b/scripts/kconfig/tests/conftest.py @@ -53,6 +53,10 @@ class Conf: # Override 'srctree' environment to make the test as the top directory extra_env['srctree'] = self._test_dir + # Clear KCONFIG_DEFCONFIG_LIST to keep unit tests from being affected + # by the user's environment. + extra_env['KCONFIG_DEFCONFIG_LIST'] = '' + # Run Kconfig in a temporary directory. # This directory is automatically removed when done. with tempfile.TemporaryDirectory() as temp_dir: -- cgit v1.2.3-71-gd317 From dd4659963a4d2dde9756e31ffe5d7c639bcaa26e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 14 Mar 2021 04:48:33 +0900 Subject: kconfig: move default KBUILD_DEFCONFIG back to scripts/kconfig/Makefile This is a partial revert of commit 2a86f6612164 ("kbuild: use KBUILD_DEFCONFIG as the fallback for DEFCONFIG_LIST"). Now that the reference to $(DEFCONFIG_LIST) was removed from init/Kconfig, the default KBUILD_DEFCONFIG can go back home. Signed-off-by: Masahiro Yamada --- Makefile | 3 --- scripts/kconfig/Makefile | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index a28bb374663d..f1093b972708 100644 --- a/Makefile +++ b/Makefile @@ -396,9 +396,6 @@ endif KCONFIG_CONFIG ?= .config export KCONFIG_CONFIG -# Default file for 'make defconfig'. This may be overridden by arch-Makefile. -export KBUILD_DEFCONFIG := defconfig - # SHELL used by kbuild CONFIG_SHELL := sh diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 31c5735663c8..7df3c0e4c52e 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -9,6 +9,10 @@ else Kconfig := Kconfig endif +ifndef KBUILD_DEFCONFIG +KBUILD_DEFCONFIG := defconfig +endif + ifeq ($(quiet),silent_) silent := -s endif -- cgit v1.2.3-71-gd317 From f8f0d06438e5c810d1e13b5f8c2fed501fe36e9c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 14 Mar 2021 04:48:34 +0900 Subject: kconfig: do not use allnoconfig_y option allnoconfig_y is an ugly hack that sets a symbol to 'y' by allnoconfig. allnoconfig does not mean a minimal set of CONFIG options because a bunch of prompts are hidden by 'if EMBEDDED' or 'if EXPERT', but I do not like to hack Kconfig this way. Use the pre-existing feature, KCONFIG_ALLCONFIG, to provide a one liner config fragment. CONFIG_EMBEDDED=y is still forced when allnoconfig is invoked as a part of tinyconfig. No change in the .config file produced by 'make tinyconfig'. The output of 'make allnoconfig' will be changed; we will get CONFIG_EMBEDDED=n because allnoconfig literally sets all symbols to n. Signed-off-by: Masahiro Yamada --- init/Kconfig | 1 - kernel/configs/tiny-base.config | 1 + scripts/kconfig/Makefile | 3 ++- 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 kernel/configs/tiny-base.config (limited to 'scripts') diff --git a/init/Kconfig b/init/Kconfig index 8578c6009674..b5c65653d665 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1768,7 +1768,6 @@ config DEBUG_RSEQ config EMBEDDED bool "Embedded system" - option allnoconfig_y select EXPERT help This option should be enabled if compiling the kernel for diff --git a/kernel/configs/tiny-base.config b/kernel/configs/tiny-base.config new file mode 100644 index 000000000000..2f0e6bf6db2c --- /dev/null +++ b/kernel/configs/tiny-base.config @@ -0,0 +1 @@ +CONFIG_EMBEDDED=y diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 7df3c0e4c52e..46f2465177f0 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -102,7 +102,8 @@ configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/c PHONY += tinyconfig tinyconfig: - $(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config + $(Q)KCONFIG_ALLCONFIG=kernel/configs/tiny-base.config $(MAKE) -f $(srctree)/Makefile allnoconfig + $(Q)$(MAKE) -f $(srctree)/Makefile tiny.config # CHECK: -o cache_dir= working? PHONY += testconfig -- cgit v1.2.3-71-gd317 From ab838577aaaeda12242b7f1e2da3f25c9b4cec3a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 14 Mar 2021 04:48:35 +0900 Subject: kconfig: remove allnoconfig_y option Now that the only user, CONFIG_EMBEDDED has stopped using this option, remove it entirely. Signed-off-by: Masahiro Yamada --- Documentation/kbuild/kconfig-language.rst | 4 ---- scripts/kconfig/conf.c | 5 +---- scripts/kconfig/expr.h | 3 --- scripts/kconfig/lexer.l | 1 - scripts/kconfig/lkc.h | 1 - scripts/kconfig/menu.c | 5 ----- scripts/kconfig/parser.y | 6 ------ 7 files changed, 1 insertion(+), 24 deletions(-) (limited to 'scripts') diff --git a/Documentation/kbuild/kconfig-language.rst b/Documentation/kbuild/kconfig-language.rst index 3cbccfc42798..4a796c601446 100644 --- a/Documentation/kbuild/kconfig-language.rst +++ b/Documentation/kbuild/kconfig-language.rst @@ -234,10 +234,6 @@ applicable everywhere (see syntax). enables the third modular state for all config symbols. At most one symbol may have the "modules" option set. - - "allnoconfig_y" - This declares the symbol as one that should have the value y when - using "allnoconfig". Used for symbols that hide other symbols. - Menu dependencies ----------------- diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 10958f1e41d6..bfa1ea8f5f98 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -242,10 +242,7 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode) sym->def[S_DEF_USER].tri = mod; break; case def_no: - if (sym->flags & SYMBOL_ALLNOCONFIG_Y) - sym->def[S_DEF_USER].tri = yes; - else - sym->def[S_DEF_USER].tri = no; + sym->def[S_DEF_USER].tri = no; break; case def_random: sym->def[S_DEF_USER].tri = no; diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index dc17152b1f14..9c9caca5bd5f 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -156,9 +156,6 @@ struct symbol { /* choice values need to be set before calculating this symbol value */ #define SYMBOL_NEED_SET_CHOICE_VALUES 0x100000 -/* Set symbol to y if allnoconfig; used for symbols that hide others */ -#define SYMBOL_ALLNOCONFIG_Y 0x200000 - #define SYMBOL_MAXLENGTH 256 #define SYMBOL_HASHSIZE 9973 diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l index e918950f94a6..08c96a6ffe05 100644 --- a/scripts/kconfig/lexer.l +++ b/scripts/kconfig/lexer.l @@ -91,7 +91,6 @@ n [A-Za-z0-9_-] [ \t]* /* whitespaces */ \\\n /* escaped new line */ \n return T_EOL; -"allnoconfig_y" return T_ALLNOCONFIG_Y; "bool" return T_BOOL; "choice" return T_CHOICE; "comment" return T_COMMENT; diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 7378e966add5..679ebad15197 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -96,7 +96,6 @@ struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); void menu_add_option_modules(void); -void menu_add_option_allnoconfig_y(void); void menu_finalize(struct menu *parent); void menu_set_type(int type); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 5dcfc173da41..d50d0de55222 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -219,11 +219,6 @@ void menu_add_option_modules(void) modules_sym = current_entry->sym; } -void menu_add_option_allnoconfig_y(void) -{ - current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; -} - static int menu_validate_number(struct symbol *sym, struct symbol *sym2) { return sym2->type == S_INT || sym2->type == S_HEX || diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y index f11d8382e9e6..2ada169c8b5d 100644 --- a/scripts/kconfig/parser.y +++ b/scripts/kconfig/parser.y @@ -45,7 +45,6 @@ static struct menu *current_menu, *current_entry; %token T_HELPTEXT %token T_WORD %token T_WORD_QUOTE -%token T_ALLNOCONFIG_Y %token T_BOOL %token T_CHOICE %token T_CLOSE_PAREN @@ -222,11 +221,6 @@ config_option: T_OPTION T_MODULES T_EOL menu_add_option_modules(); }; -config_option: T_OPTION T_ALLNOCONFIG_Y T_EOL -{ - menu_add_option_allnoconfig_y(); -}; - /* choice entry */ choice: T_CHOICE word_opt T_EOL -- cgit v1.2.3-71-gd317 From 6dd85ff178cd76851e2184b13e545f5a88d1be30 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 14 Mar 2021 04:48:36 +0900 Subject: kconfig: change "modules" from sub-option to first-level attribute Now "modules" is the only member of the "option" property. Remove "option", and move "modules" to the top level property. Signed-off-by: Masahiro Yamada --- Documentation/kbuild/kconfig-language.rst | 14 ++++---------- init/Kconfig | 2 +- scripts/kconfig/lexer.l | 1 - scripts/kconfig/lkc.h | 1 - scripts/kconfig/menu.c | 8 -------- scripts/kconfig/parser.y | 8 +++++--- scripts/kconfig/tests/choice/Kconfig | 2 +- scripts/kconfig/tests/choice_value_with_m_dep/Kconfig | 2 +- scripts/kconfig/tests/inter_choice/Kconfig | 2 +- 9 files changed, 13 insertions(+), 27 deletions(-) (limited to 'scripts') diff --git a/Documentation/kbuild/kconfig-language.rst b/Documentation/kbuild/kconfig-language.rst index 4a796c601446..98c24183d8c3 100644 --- a/Documentation/kbuild/kconfig-language.rst +++ b/Documentation/kbuild/kconfig-language.rst @@ -223,16 +223,10 @@ applicable everywhere (see syntax). the indentation level, this means it ends at the first line which has a smaller indentation than the first line of the help text. -- misc options: "option" [=] - - Various less common options can be defined via this option syntax, - which can modify the behaviour of the menu entry and its config - symbol. These options are currently possible: - - - "modules" - This declares the symbol to be used as the MODULES symbol, which - enables the third modular state for all config symbols. - At most one symbol may have the "modules" option set. +- module attribute: "modules" + This declares the symbol to be used as the MODULES symbol, which + enables the third modular state for all config symbols. + At most one symbol may have the "modules" option set. Menu dependencies ----------------- diff --git a/init/Kconfig b/init/Kconfig index b5c65653d665..ab9a284e6078 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2042,7 +2042,7 @@ config MODULE_SIG_FORMAT menuconfig MODULES bool "Enable loadable module support" - option modules + modules help Kernel modules are small pieces of compiled code which can be inserted in the running kernel, rather than being diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l index 08c96a6ffe05..312cbad2d34d 100644 --- a/scripts/kconfig/lexer.l +++ b/scripts/kconfig/lexer.l @@ -112,7 +112,6 @@ n [A-Za-z0-9_-] "menuconfig" return T_MENUCONFIG; "modules" return T_MODULES; "on" return T_ON; -"option" return T_OPTION; "optional" return T_OPTIONAL; "prompt" return T_PROMPT; "range" return T_RANGE; diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 679ebad15197..01666f558fe9 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -95,7 +95,6 @@ void menu_add_visibility(struct expr *dep); struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); -void menu_add_option_modules(void); void menu_finalize(struct menu *parent); void menu_set_type(int type); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index d50d0de55222..8b2108b74821 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -211,14 +211,6 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) menu_add_prop(type, expr_alloc_symbol(sym), dep); } -void menu_add_option_modules(void) -{ - if (modules_sym) - zconf_error("symbol '%s' redefines option 'modules' already defined by symbol '%s'", - current_entry->sym->name, modules_sym->name); - modules_sym = current_entry->sym; -} - static int menu_validate_number(struct symbol *sym, struct symbol *sym2) { return sym2->type == S_INT || sym2->type == S_HEX || diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y index 2ada169c8b5d..e46ce21a2fc4 100644 --- a/scripts/kconfig/parser.y +++ b/scripts/kconfig/parser.y @@ -69,7 +69,6 @@ static struct menu *current_menu, *current_entry; %token T_MODULES %token T_ON %token T_OPEN_PAREN -%token T_OPTION %token T_OPTIONAL %token T_PLUS_EQUAL %token T_PROMPT @@ -216,9 +215,12 @@ config_option: T_RANGE symbol symbol if_expr T_EOL printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); }; -config_option: T_OPTION T_MODULES T_EOL +config_option: T_MODULES T_EOL { - menu_add_option_modules(); + if (modules_sym) + zconf_error("symbol '%s' redefines option 'modules' already defined by symbol '%s'", + current_entry->sym->name, modules_sym->name); + modules_sym = current_entry->sym; }; /* choice entry */ diff --git a/scripts/kconfig/tests/choice/Kconfig b/scripts/kconfig/tests/choice/Kconfig index a412205b1b0c..0930eb65e932 100644 --- a/scripts/kconfig/tests/choice/Kconfig +++ b/scripts/kconfig/tests/choice/Kconfig @@ -2,7 +2,7 @@ config MODULES bool "Enable loadable module support" - option modules + modules default y choice diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig b/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig index 7106c26bb3a8..bd970cec07d6 100644 --- a/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig +++ b/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig @@ -2,7 +2,7 @@ config MODULES def_bool y - option modules + modules config DEP tristate diff --git a/scripts/kconfig/tests/inter_choice/Kconfig b/scripts/kconfig/tests/inter_choice/Kconfig index 5698a4018dd0..26c25f68695b 100644 --- a/scripts/kconfig/tests/inter_choice/Kconfig +++ b/scripts/kconfig/tests/inter_choice/Kconfig @@ -2,7 +2,7 @@ config MODULES def_bool y - option modules + modules choice prompt "Choice" -- cgit v1.2.3-71-gd317 From a69b191f6297310ff140f2868b89fe2a2f355b90 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Mon, 15 Mar 2021 14:55:44 +0800 Subject: kconfig: use true and false for bool variable fixed the following coccicheck: ./scripts/kconfig/confdata.c:36:9-10: WARNING: return of 0/1 in function 'is_dir' with return type bool Reported-by: Abaci Robot Signed-off-by: Yang Li Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index f3998d5ddd02..c796d402665e 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -33,7 +33,7 @@ static bool is_dir(const char *path) struct stat st; if (stat(path, &st)) - return 0; + return false; return S_ISDIR(st.st_mode); } -- cgit v1.2.3-71-gd317 From 21f8b32fbdbc1cf94e285384daf490d9c4ae5ae3 Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Fri, 26 Mar 2021 11:31:22 +0530 Subject: kconfig: streamline_config.pl: Couple of typo fixes s/configuraton/configuration/ s/orignal/original/ Signed-off-by: Bhaskar Chowdhury Signed-off-by: Masahiro Yamada --- scripts/kconfig/streamline_config.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index 1c78ba49ca99..911c72a2dbc4 100755 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -21,7 +21,7 @@ # 1. Boot up the kernel that you want to stream line the config on. # 2. Change directory to the directory holding the source of the # kernel that you just booted. -# 3. Copy the configuraton file to this directory as .config +# 3. Copy the configuration file to this directory as .config # 4. Have all your devices that you need modules for connected and # operational (make sure that their corresponding modules are loaded) # 5. Run this script redirecting the output to some other file @@ -481,7 +481,7 @@ sub parse_config_depends # The idea is we look at all the configs that select it. If one # is already in our list of configs to enable, then there's nothing # else to do. If there isn't, we pick the first config that was -# enabled in the orignal config and use that. +# enabled in the original config and use that. sub parse_config_selects { my ($config, $p) = @_; -- cgit v1.2.3-71-gd317 From bffbf6e2ad6a8c9fbf78f3561404527fe69ef23d Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Sat, 27 Mar 2021 02:48:57 +0530 Subject: kconfig: lxdialog: A spello fix and a punctuation added s/propperly/properly/ s/thats/that\'s/ Signed-off-by: Bhaskar Chowdhury Signed-off-by: Masahiro Yamada --- scripts/kconfig/lxdialog/util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c index 1b490d4af0d3..3f78fb265136 100644 --- a/scripts/kconfig/lxdialog/util.c +++ b/scripts/kconfig/lxdialog/util.c @@ -363,7 +363,7 @@ void print_title(WINDOW *dialog, const char *title, int width) /* * Print a string of text in a window, automatically wrap around to the * next line if the string is too long to fit on one line. Newline - * characters '\n' are propperly processed. We start on a new line + * characters '\n' are properly processed. We start on a new line * if there is no room for at least 4 nonblanks following a double-space. */ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) @@ -541,7 +541,7 @@ int first_alpha(const char *string, const char *exempt) * lxdialog suggest which is correctly translated to two * times esc. But then we need to ignore the second esc to avoid stepping * out one menu too much. Filter away all escaped key sequences since - * keypad(FALSE) turn off ncurses support for escape sequences - and thats + * keypad(FALSE) turn off ncurses support for escape sequences - and that's * needed to make notimeout() do as expected. */ int on_key_esc(WINDOW *win) -- cgit v1.2.3-71-gd317 From 1f035a52918a4c97b99c5d9f0d5023fe659bccaa Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 10 Apr 2021 15:52:46 +0900 Subject: kconfig: nconf: fix core dump when searching in empty menu The following code in get_mext_match(): index = (index + items_num) % items_num; ... makes the program crash when items_num is zero (that is, the menu is empty). A menu can be empty when all the options in it are hidden by unmet 'depends on'. For example, menu "This menu will be empty" config FOO bool "foo" depends on BROKEN endmenu If you visit this menu and press a '/' key and then another key, nconf crashes with: Floating point exception (core dumped) When the number of items is zero, it does not make sense to search in the menu. In this case, current_item() returns NULL, and item_index() ERR, but get_mext_match() does not check it. Let's make get_mext_match() just return if the menu is empty. While I am here, change items_num from 'int' to 'unsigned int' because it should never become negative. Signed-off-by: Masahiro Yamada --- scripts/kconfig/nconf.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index e0f965529166..0fb48f171b66 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -268,7 +268,7 @@ static int mwin_max_cols; static MENU *curses_menu; static ITEM *curses_menu_items[MAX_MENU_ITEMS]; static struct mitem k_menu_items[MAX_MENU_ITEMS]; -static int items_num; +static unsigned int items_num; static int global_exit; /* the currently selected button */ static const char *current_instructions = menu_instructions; @@ -496,8 +496,12 @@ typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN, /* return the index of the matched item, or -1 if no such item exists */ static int get_mext_match(const char *match_str, match_f flag) { - int match_start = item_index(current_item(curses_menu)); - int index; + int match_start, index; + + /* Do not search if the menu is empty (i.e. items_num == 0) */ + match_start = item_index(current_item(curses_menu)); + if (match_start == ERR) + return -1; if (flag == FIND_NEXT_MATCH_DOWN) ++match_start; -- cgit v1.2.3-71-gd317 From 5ee546594025fc9337e4cc8b79db89f1258cf480 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 10 Apr 2021 15:57:22 +0900 Subject: kconfig: change sym_change_count to a boolean flag sym_change_count has no good reason to be 'int' type. sym_set_change_count() compares the old and new values after casting both of them to (bool). I do not see any practical diffrence between sym_set_change_count(1) and sym_add_change_count(1). Use the boolean flag, conf_changed. Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 31 +++++++++++++------------------ scripts/kconfig/lkc.h | 2 -- scripts/kconfig/lkc_proto.h | 1 + scripts/kconfig/mconf.c | 2 +- scripts/kconfig/nconf.c | 2 +- scripts/kconfig/parser.y | 2 +- scripts/kconfig/symbol.c | 2 +- 7 files changed, 18 insertions(+), 24 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index c796d402665e..a8339871ef79 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -366,7 +366,7 @@ int conf_read_simple(const char *name, int def) in = zconf_fopen(name); if (in) goto load; - sym_add_change_count(1); + conf_set_changed(true); env = getenv("KCONFIG_DEFCONFIG_LIST"); if (!env) @@ -444,7 +444,7 @@ load: if (def == S_DEF_USER) { sym = sym_find(line + 2 + strlen(CONFIG_)); if (!sym) { - sym_add_change_count(1); + conf_set_changed(true); continue; } } else { @@ -487,7 +487,7 @@ load: */ conf_touch_dep(line + strlen(CONFIG_)); else - sym_add_change_count(1); + conf_set_changed(true); continue; } @@ -535,7 +535,7 @@ int conf_read(const char *name) int conf_unsaved = 0; int i; - sym_set_change_count(0); + conf_set_changed(false); if (conf_read_simple(name, S_DEF_USER)) { sym_calc_value(modules_sym); @@ -593,7 +593,8 @@ int conf_read(const char *name) } } - sym_add_change_count(conf_warnings || conf_unsaved); + if (conf_warnings || conf_unsaved) + conf_set_changed(true); return 0; } @@ -938,7 +939,7 @@ next: if (is_same(name, tmpname)) { conf_message("No change to %s", name); unlink(tmpname); - sym_set_change_count(0); + conf_set_changed(false); return 0; } @@ -950,7 +951,7 @@ next: conf_message("configuration written to %s", name); - sym_set_change_count(0); + conf_set_changed(false); return 0; } @@ -1118,26 +1119,20 @@ int conf_write_autoconf(int overwrite) return 0; } -static int sym_change_count; +static bool conf_changed; static void (*conf_changed_callback)(void); -void sym_set_change_count(int count) +void conf_set_changed(bool val) { - int _sym_change_count = sym_change_count; - sym_change_count = count; - if (conf_changed_callback && - (bool)_sym_change_count != (bool)count) + if (conf_changed_callback && conf_changed != val) conf_changed_callback(); -} -void sym_add_change_count(int count) -{ - sym_set_change_count(count + sym_change_count); + conf_changed = val; } bool conf_get_changed(void) { - return sym_change_count; + return conf_changed; } void conf_set_changed_callback(void (*fn)(void)) diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 01666f558fe9..45599c52478d 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -45,8 +45,6 @@ const char *zconf_curname(void); /* confdata.c */ const char *conf_get_configname(void); -void sym_set_change_count(int count); -void sym_add_change_count(int count); void set_all_choice_values(struct symbol *csym); /* confdata.c and expr.c */ diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 9e81be33c40f..a11626bdc421 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -8,6 +8,7 @@ int conf_read_simple(const char *name, int); int conf_write_defconfig(const char *name); int conf_write(const char *name); int conf_write_autoconf(int overwrite); +void conf_set_changed(bool val); bool conf_get_changed(void); void conf_set_changed_callback(void (*fn)(void)); void conf_set_message_callback(void (*fn)(const char *s)); diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 01b6c27224e2..4cfbe62938cd 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -910,7 +910,7 @@ static void conf_load(void) return; if (!conf_read(dialog_input_result)) { set_config_filename(dialog_input_result); - sym_set_change_count(1); + conf_set_changed(true); return; } show_textbox(NULL, "File does not exist!", 5, 38); diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 0fb48f171b66..0cce69ccb611 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -1408,7 +1408,7 @@ static void conf_load(void) return; if (!conf_read(dialog_input_result)) { set_config_filename(dialog_input_result); - sym_set_change_count(1); + conf_set_changed(true); return; } btn_dialog(main_window, "File does not exist!", 0); diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y index e46ce21a2fc4..e90889edf5b3 100644 --- a/scripts/kconfig/parser.y +++ b/scripts/kconfig/parser.y @@ -507,7 +507,7 @@ void conf_parse(const char *name) } if (yynerrs) exit(1); - sym_set_change_count(1); + conf_set_changed(true); } static bool zconf_endtoken(const char *tokenname, diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 36b0fcb18117..5844d636d38f 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -472,7 +472,7 @@ void sym_clear_all_valid(void) for_all_symbols(i, sym) sym->flags &= ~SYMBOL_VALID; - sym_add_change_count(1); + conf_set_changed(true); sym_calc_value(modules_sym); } -- cgit v1.2.3-71-gd317 From f02aa48dde8b96eef5998b049ad11547bfc16080 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 10 Apr 2021 23:31:58 +0900 Subject: kconfig: use /boot/config-* etc. as DEFCONFIG_LIST only for native build When the .config file is missing, 'make config', 'make menuconfig', etc. uses a file listed in DEFCONFIG_LIST, if found, as base configuration. Ususally, /boot/config-$(uname -r) exists, and is used as default. However, when you are cross-compiling the kernel, it does not make sense to use /boot/config-* on the build host. It should default to arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG). UML previously did not use DEFCONFIG_LIST at all, but it should be able to use arch/um/configs/$(KBUILD_DEFCONFIG) as a base config file. Signed-off-by: Masahiro Yamada --- Makefile | 5 +++++ scripts/kconfig/Makefile | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index f1093b972708..697eaf6c550e 100644 --- a/Makefile +++ b/Makefile @@ -393,6 +393,11 @@ ifeq ($(ARCH),sh64) SRCARCH := sh endif +export cross_compiling := +ifneq ($(SRCARCH),$(SUBARCH)) +cross_compiling := 1 +endif + KCONFIG_CONFIG ?= .config export KCONFIG_CONFIG diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 46f2465177f0..1d1a7f83ee8d 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -18,14 +18,14 @@ silent := -s endif export KCONFIG_DEFCONFIG_LIST := -ifneq ($(SRCARCH),um) +ifndef cross_compiling kernel-release := $(shell uname -r) -KCONFIG_DEFCONFIG_LIST := \ +KCONFIG_DEFCONFIG_LIST += \ /lib/modules/$(kernel-release)/.config \ /etc/kernel-config \ - /boot/config-$(kernel-release) \ - arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) + /boot/config-$(kernel-release) endif +KCONFIG_DEFCONFIG_LIST += arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) # We need this, in case the user has it in its environment unexport CONFIG_ -- cgit v1.2.3-71-gd317 From 68876c38c4b30653c1779414954ce747a455253c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 11 Apr 2021 04:45:30 +0900 Subject: kconfig: mconf,nconf: remove unneeded '\0' termination after snprintf() snprintf() always terminates the destination buffer with '\0' even if the buffer is not long enough. (In this case, the last element of the buffer becomes '\0'.) The explicit termination is unneeded. Signed-off-by: Masahiro Yamada --- scripts/kconfig/mconf.c | 11 +++-------- scripts/kconfig/nconf.c | 12 +++--------- 2 files changed, 6 insertions(+), 17 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 4cfbe62938cd..9d3cf510562f 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -299,17 +299,12 @@ static char filename[PATH_MAX+1]; static void set_config_filename(const char *config_filename) { static char menu_backtitle[PATH_MAX+128]; - int size; - size = snprintf(menu_backtitle, sizeof(menu_backtitle), - "%s - %s", config_filename, rootmenu.prompt->text); - if (size >= sizeof(menu_backtitle)) - menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; + snprintf(menu_backtitle, sizeof(menu_backtitle), "%s - %s", + config_filename, rootmenu.prompt->text); set_dialog_backtitle(menu_backtitle); - size = snprintf(filename, sizeof(filename), "%s", config_filename); - if (size >= sizeof(filename)) - filename[sizeof(filename)-1] = '\0'; + snprintf(filename, sizeof(filename), "%s", config_filename); } struct subtitle_part { diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 0cce69ccb611..06ebe16e4a38 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -633,16 +633,10 @@ static char filename[PATH_MAX+1]; static char menu_backtitle[PATH_MAX+128]; static const char *set_config_filename(const char *config_filename) { - int size; + snprintf(menu_backtitle, sizeof(menu_backtitle), "%s - %s", + config_filename, rootmenu.prompt->text); - size = snprintf(menu_backtitle, sizeof(menu_backtitle), - "%s - %s", config_filename, rootmenu.prompt->text); - if (size >= sizeof(menu_backtitle)) - menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; - - size = snprintf(filename, sizeof(filename), "%s", config_filename); - if (size >= sizeof(filename)) - filename[sizeof(filename)-1] = '\0'; + snprintf(filename, sizeof(filename), "%s", config_filename); return menu_backtitle; } -- cgit v1.2.3-71-gd317 From 7f5ff55bf8eb99e42c10388ccffdfbb0a0caac67 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 11 Apr 2021 04:45:31 +0900 Subject: kconfig: nconf: fix NORMAL attributes The lower 8-bit of attributes should be 0, but this code wrongly sets it to NORMAL (=1). The correct one is A_NORMAL. Signed-off-by: Masahiro Yamada --- scripts/kconfig/nconf.gui.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index 77f525a8617c..a914f81092d7 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -70,7 +70,7 @@ static void normal_color_theme(void) /* automatically add color... */ #define mkattr(name, attr) do { \ attributes[name] = attr | COLOR_PAIR(name); } while (0) - mkattr(NORMAL, NORMAL); + mkattr(NORMAL, A_NORMAL); mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE); mkattr(MAIN_MENU_FORE, A_REVERSE); @@ -102,7 +102,7 @@ static void no_colors_theme(void) /* automatically add highlight, no color */ #define mkattrn(name, attr) { attributes[name] = attr; } - mkattrn(NORMAL, NORMAL); + mkattrn(NORMAL, A_NORMAL); mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE); mkattrn(MAIN_MENU_FORE, A_STANDOUT); -- cgit v1.2.3-71-gd317 From 2ba50da9ec34196a895b4947dc6bb1dbf1ace670 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 11 Apr 2021 04:45:32 +0900 Subject: kconfig: nconf: get rid of (void) casts from wattrset() calls This reverts commit 10175ba65fde ("nconfig: Silence unused return values from wattrset"). With this patch applied, recent GCC versions can cleanly build nconf without "value computed is not used" warnings. The wattrset() used to be implemented as a macro, like this: #define wattrset(win,at) \ (NCURSES_OK_ADDR(win) \ ? ((win)->_attrs = NCURSES_CAST(attr_t, at), \ OK) \ : ERR) The GCC bugzilla [1] reported a false-positive -Wunused-value warning in a similar test case. It was fixed by GCC 4.4.1. Let's revert that commit, and see if somebody will claim the issue. [1]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39889 Signed-off-by: Masahiro Yamada --- scripts/kconfig/nconf.c | 14 +++++++------- scripts/kconfig/nconf.gui.c | 20 ++++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 06ebe16e4a38..bcfcf0b87a7a 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -370,18 +370,18 @@ static void print_function_line(void) int lines = getmaxy(stdscr); for (i = 0; i < function_keys_num; i++) { - (void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]); + wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]); mvwprintw(main_window, lines-3, offset, "%s", function_keys[i].key_str); - (void) wattrset(main_window, attributes[FUNCTION_TEXT]); + wattrset(main_window, attributes[FUNCTION_TEXT]); offset += strlen(function_keys[i].key_str); mvwprintw(main_window, lines-3, offset, "%s", function_keys[i].func); offset += strlen(function_keys[i].func) + skip; } - (void) wattrset(main_window, attributes[NORMAL]); + wattrset(main_window, attributes[NORMAL]); } /* help */ @@ -954,16 +954,16 @@ static void show_menu(const char *prompt, const char *instructions, current_instructions = instructions; clear(); - (void) wattrset(main_window, attributes[NORMAL]); + wattrset(main_window, attributes[NORMAL]); print_in_middle(stdscr, 1, 0, getmaxx(stdscr), menu_backtitle, attributes[MAIN_HEADING]); - (void) wattrset(main_window, attributes[MAIN_MENU_BOX]); + wattrset(main_window, attributes[MAIN_MENU_BOX]); box(main_window, 0, 0); - (void) wattrset(main_window, attributes[MAIN_MENU_HEADING]); + wattrset(main_window, attributes[MAIN_MENU_HEADING]); mvwprintw(main_window, 0, 3, " %s ", prompt); - (void) wattrset(main_window, attributes[NORMAL]); + wattrset(main_window, attributes[NORMAL]); set_menu_items(curses_menu, curses_menu_items); diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index a914f81092d7..180d3158d380 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -167,7 +167,7 @@ void print_in_middle(WINDOW *win, length = strlen(string); temp = (width - length) / 2; x = startx + (int)temp; - (void) wattrset(win, color); + wattrset(win, color); mvwprintw(win, y, x, "%s", string); refresh(); } @@ -297,11 +297,11 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) set_menu_fore(menu, attributes[DIALOG_MENU_FORE]); set_menu_back(menu, attributes[DIALOG_MENU_BACK]); - (void) wattrset(win, attributes[DIALOG_BOX]); + wattrset(win, attributes[DIALOG_BOX]); box(win, 0, 0); /* print message */ - (void) wattrset(msg_win, attributes[DIALOG_TEXT]); + wattrset(msg_win, attributes[DIALOG_TEXT]); fill_window(msg_win, msg); set_menu_win(menu, win); @@ -405,16 +405,16 @@ int dialog_inputbox(WINDOW *main_window, form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); keypad(form_win, TRUE); - (void) wattrset(form_win, attributes[INPUT_FIELD]); + wattrset(form_win, attributes[INPUT_FIELD]); - (void) wattrset(win, attributes[INPUT_BOX]); + wattrset(win, attributes[INPUT_BOX]); box(win, 0, 0); - (void) wattrset(win, attributes[INPUT_HEADING]); + wattrset(win, attributes[INPUT_HEADING]); if (title) mvwprintw(win, 0, 3, "%s", title); /* print message */ - (void) wattrset(prompt_win, attributes[INPUT_TEXT]); + wattrset(prompt_win, attributes[INPUT_TEXT]); fill_window(prompt_win, prompt); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); @@ -576,7 +576,7 @@ void show_scroll_win(WINDOW *main_window, /* create the pad */ pad = newpad(total_lines+10, total_cols+10); - (void) wattrset(pad, attributes[SCROLLWIN_TEXT]); + wattrset(pad, attributes[SCROLLWIN_TEXT]); fill_window(pad, text); win_lines = min(total_lines+4, lines-2); @@ -591,9 +591,9 @@ void show_scroll_win(WINDOW *main_window, win = newwin(win_lines, win_cols, y, x); keypad(win, TRUE); /* show the help in the help window, and show the help panel */ - (void) wattrset(win, attributes[SCROLLWIN_BOX]); + wattrset(win, attributes[SCROLLWIN_BOX]); box(win, 0, 0); - (void) wattrset(win, attributes[SCROLLWIN_HEADING]); + wattrset(win, attributes[SCROLLWIN_HEADING]); mvwprintw(win, 0, 3, " %s ", title); panel = new_panel(win); -- cgit v1.2.3-71-gd317 From 16b0e10238b45251790ea1a2683855d4f8f3c1a3 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 11 Apr 2021 04:45:33 +0900 Subject: kconfig: nconf: remove unneeded default for menu prompt The rootmenu always has a prompt even if the 'mainmenu' statement is missing in the top Kconfig file. conf_parse() calls menu_add_prompt(P_MENU, "Main menu", NULL) in this case. So, every 'menu' has a prompt. Signed-off-by: Masahiro Yamada --- scripts/kconfig/nconf.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index bcfcf0b87a7a..8187a2ef837d 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -1066,7 +1066,6 @@ static int do_match(int key, struct match_state *state, int *ans) static void conf(struct menu *menu) { struct menu *submenu = NULL; - const char *prompt = menu_get_prompt(menu); struct symbol *sym; int res; int current_index = 0; @@ -1084,9 +1083,8 @@ static void conf(struct menu *menu) if (!child_count) break; - show_menu(prompt ? prompt : "Main Menu", - menu_instructions, - current_index, &last_top_row); + show_menu(menu_get_prompt(menu), menu_instructions, + current_index, &last_top_row); keypad((menu_win(curses_menu)), TRUE); while (!global_exit) { if (match_state.in_search) { -- cgit v1.2.3-71-gd317 From 93487b17b147f22400378240d06f33badc3368da Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 11 Apr 2021 04:45:34 +0900 Subject: kconfig: nconf: refactor attributes setup code The current attributes setup code is strange; the array attribute[] is set to values outside the range of the attribute_t enum. At least, attributes_t attributes[ATTR_MAX+1] = {0}; ... should be int attribute[ATTR_MAX+1] = {0}; Also, there is no need to hard-code the color-pair numbers in attributes_t. The current code is messy. Rewrite it. Signed-off-by: Masahiro Yamada --- scripts/kconfig/nconf.c | 22 ++-- scripts/kconfig/nconf.gui.c | 253 ++++++++++++++++++++------------------------ scripts/kconfig/nconf.h | 44 ++++---- 3 files changed, 144 insertions(+), 175 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 8187a2ef837d..e86d3511b939 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -370,18 +370,18 @@ static void print_function_line(void) int lines = getmaxy(stdscr); for (i = 0; i < function_keys_num; i++) { - wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]); + wattrset(main_window, attr_function_highlight); mvwprintw(main_window, lines-3, offset, "%s", function_keys[i].key_str); - wattrset(main_window, attributes[FUNCTION_TEXT]); + wattrset(main_window, attr_function_text); offset += strlen(function_keys[i].key_str); mvwprintw(main_window, lines-3, offset, "%s", function_keys[i].func); offset += strlen(function_keys[i].func) + skip; } - wattrset(main_window, attributes[NORMAL]); + wattrset(main_window, attr_normal); } /* help */ @@ -954,16 +954,16 @@ static void show_menu(const char *prompt, const char *instructions, current_instructions = instructions; clear(); - wattrset(main_window, attributes[NORMAL]); + wattrset(main_window, attr_normal); print_in_middle(stdscr, 1, 0, getmaxx(stdscr), menu_backtitle, - attributes[MAIN_HEADING]); + attr_main_heading); - wattrset(main_window, attributes[MAIN_MENU_BOX]); + wattrset(main_window, attr_main_menu_box); box(main_window, 0, 0); - wattrset(main_window, attributes[MAIN_MENU_HEADING]); + wattrset(main_window, attr_main_menu_heading); mvwprintw(main_window, 0, 3, " %s ", prompt); - wattrset(main_window, attributes[NORMAL]); + wattrset(main_window, attr_normal); set_menu_items(curses_menu, curses_menu_items); @@ -1519,9 +1519,9 @@ int main(int ac, char **av) menu_opts_on(curses_menu, O_NONCYCLIC); menu_opts_on(curses_menu, O_IGNORECASE); set_menu_mark(curses_menu, " "); - set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); - set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); - set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]); + set_menu_fore(curses_menu, attr_main_menu_fore); + set_menu_back(curses_menu, attr_main_menu_back); + set_menu_grey(curses_menu, attr_main_menu_grey); set_config_filename(conf_get_configname()); setup_windows(); diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index 180d3158d380..e747590cee17 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -7,141 +7,114 @@ #include "nconf.h" #include "lkc.h" -/* a list of all the different widgets we use */ -attributes_t attributes[ATTR_MAX+1] = {0}; - -/* available colors: - COLOR_BLACK 0 - COLOR_RED 1 - COLOR_GREEN 2 - COLOR_YELLOW 3 - COLOR_BLUE 4 - COLOR_MAGENTA 5 - COLOR_CYAN 6 - COLOR_WHITE 7 - */ -static void set_normal_colors(void) -{ - init_pair(NORMAL, -1, -1); - init_pair(MAIN_HEADING, COLOR_MAGENTA, -1); - - /* FORE is for the selected item */ - init_pair(MAIN_MENU_FORE, -1, -1); - /* BACK for all the rest */ - init_pair(MAIN_MENU_BACK, -1, -1); - init_pair(MAIN_MENU_GREY, -1, -1); - init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1); - init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1); - - init_pair(SCROLLWIN_TEXT, -1, -1); - init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1); - init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1); - - init_pair(DIALOG_TEXT, -1, -1); - init_pair(DIALOG_BOX, COLOR_YELLOW, -1); - init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1); - init_pair(DIALOG_MENU_FORE, COLOR_RED, -1); - - init_pair(INPUT_BOX, COLOR_YELLOW, -1); - init_pair(INPUT_HEADING, COLOR_GREEN, -1); - init_pair(INPUT_TEXT, -1, -1); - init_pair(INPUT_FIELD, -1, -1); - - init_pair(FUNCTION_HIGHLIGHT, -1, -1); - init_pair(FUNCTION_TEXT, COLOR_YELLOW, -1); -} - -/* available attributes: - A_NORMAL Normal display (no highlight) - A_STANDOUT Best highlighting mode of the terminal. - A_UNDERLINE Underlining - A_REVERSE Reverse video - A_BLINK Blinking - A_DIM Half bright - A_BOLD Extra bright or bold - A_PROTECT Protected mode - A_INVIS Invisible or blank mode - A_ALTCHARSET Alternate character set - A_CHARTEXT Bit-mask to extract a character - COLOR_PAIR(n) Color-pair number n - */ -static void normal_color_theme(void) -{ - /* automatically add color... */ -#define mkattr(name, attr) do { \ -attributes[name] = attr | COLOR_PAIR(name); } while (0) - mkattr(NORMAL, A_NORMAL); - mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE); - - mkattr(MAIN_MENU_FORE, A_REVERSE); - mkattr(MAIN_MENU_BACK, A_NORMAL); - mkattr(MAIN_MENU_GREY, A_NORMAL); - mkattr(MAIN_MENU_HEADING, A_BOLD); - mkattr(MAIN_MENU_BOX, A_NORMAL); - - mkattr(SCROLLWIN_TEXT, A_NORMAL); - mkattr(SCROLLWIN_HEADING, A_BOLD); - mkattr(SCROLLWIN_BOX, A_BOLD); - - mkattr(DIALOG_TEXT, A_BOLD); - mkattr(DIALOG_BOX, A_BOLD); - mkattr(DIALOG_MENU_FORE, A_STANDOUT); - mkattr(DIALOG_MENU_BACK, A_NORMAL); - - mkattr(INPUT_BOX, A_NORMAL); - mkattr(INPUT_HEADING, A_BOLD); - mkattr(INPUT_TEXT, A_NORMAL); - mkattr(INPUT_FIELD, A_UNDERLINE); - - mkattr(FUNCTION_HIGHLIGHT, A_BOLD); - mkattr(FUNCTION_TEXT, A_REVERSE); -} - -static void no_colors_theme(void) -{ - /* automatically add highlight, no color */ -#define mkattrn(name, attr) { attributes[name] = attr; } - - mkattrn(NORMAL, A_NORMAL); - mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE); - - mkattrn(MAIN_MENU_FORE, A_STANDOUT); - mkattrn(MAIN_MENU_BACK, A_NORMAL); - mkattrn(MAIN_MENU_GREY, A_NORMAL); - mkattrn(MAIN_MENU_HEADING, A_BOLD); - mkattrn(MAIN_MENU_BOX, A_NORMAL); - - mkattrn(SCROLLWIN_TEXT, A_NORMAL); - mkattrn(SCROLLWIN_HEADING, A_BOLD); - mkattrn(SCROLLWIN_BOX, A_BOLD); - - mkattrn(DIALOG_TEXT, A_NORMAL); - mkattrn(DIALOG_BOX, A_BOLD); - mkattrn(DIALOG_MENU_FORE, A_STANDOUT); - mkattrn(DIALOG_MENU_BACK, A_NORMAL); - - mkattrn(INPUT_BOX, A_BOLD); - mkattrn(INPUT_HEADING, A_BOLD); - mkattrn(INPUT_TEXT, A_NORMAL); - mkattrn(INPUT_FIELD, A_UNDERLINE); - - mkattrn(FUNCTION_HIGHLIGHT, A_BOLD); - mkattrn(FUNCTION_TEXT, A_REVERSE); -} +int attr_normal; +int attr_main_heading; +int attr_main_menu_box; +int attr_main_menu_fore; +int attr_main_menu_back; +int attr_main_menu_grey; +int attr_main_menu_heading; +int attr_scrollwin_text; +int attr_scrollwin_heading; +int attr_scrollwin_box; +int attr_dialog_text; +int attr_dialog_menu_fore; +int attr_dialog_menu_back; +int attr_dialog_box; +int attr_input_box; +int attr_input_heading; +int attr_input_text; +int attr_input_field; +int attr_function_text; +int attr_function_highlight; + +#define COLOR_ATTR(_at, _fg, _bg, _hl) \ + { .attr = &(_at), .has_color = true, .color_fg = _fg, .color_bg = _bg, .highlight = _hl } +#define NO_COLOR_ATTR(_at, _hl) \ + { .attr = &(_at), .has_color = false, .highlight = _hl } +#define COLOR_DEFAULT -1 + +struct nconf_attr_param { + int *attr; + bool has_color; + int color_fg; + int color_bg; + int highlight; +}; + +static const struct nconf_attr_param color_theme_params[] = { + COLOR_ATTR(attr_normal, COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_main_heading, COLOR_MAGENTA, COLOR_DEFAULT, A_BOLD | A_UNDERLINE), + COLOR_ATTR(attr_main_menu_box, COLOR_YELLOW, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_main_menu_fore, COLOR_DEFAULT, COLOR_DEFAULT, A_REVERSE), + COLOR_ATTR(attr_main_menu_back, COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_main_menu_grey, COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_main_menu_heading, COLOR_GREEN, COLOR_DEFAULT, A_BOLD), + COLOR_ATTR(attr_scrollwin_text, COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_scrollwin_heading, COLOR_GREEN, COLOR_DEFAULT, A_BOLD), + COLOR_ATTR(attr_scrollwin_box, COLOR_YELLOW, COLOR_DEFAULT, A_BOLD), + COLOR_ATTR(attr_dialog_text, COLOR_DEFAULT, COLOR_DEFAULT, A_BOLD), + COLOR_ATTR(attr_dialog_menu_fore, COLOR_RED, COLOR_DEFAULT, A_STANDOUT), + COLOR_ATTR(attr_dialog_menu_back, COLOR_YELLOW, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_dialog_box, COLOR_YELLOW, COLOR_DEFAULT, A_BOLD), + COLOR_ATTR(attr_input_box, COLOR_YELLOW, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_input_heading, COLOR_GREEN, COLOR_DEFAULT, A_BOLD), + COLOR_ATTR(attr_input_text, COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_input_field, COLOR_DEFAULT, COLOR_DEFAULT, A_UNDERLINE), + COLOR_ATTR(attr_function_text, COLOR_YELLOW, COLOR_DEFAULT, A_REVERSE), + COLOR_ATTR(attr_function_highlight, COLOR_DEFAULT, COLOR_DEFAULT, A_BOLD), + { /* sentinel */ } +}; + +static const struct nconf_attr_param no_color_theme_params[] = { + NO_COLOR_ATTR(attr_normal, A_NORMAL), + NO_COLOR_ATTR(attr_main_heading, A_BOLD | A_UNDERLINE), + NO_COLOR_ATTR(attr_main_menu_box, A_NORMAL), + NO_COLOR_ATTR(attr_main_menu_fore, A_STANDOUT), + NO_COLOR_ATTR(attr_main_menu_back, A_NORMAL), + NO_COLOR_ATTR(attr_main_menu_grey, A_NORMAL), + NO_COLOR_ATTR(attr_main_menu_heading, A_BOLD), + NO_COLOR_ATTR(attr_scrollwin_text, A_NORMAL), + NO_COLOR_ATTR(attr_scrollwin_heading, A_BOLD), + NO_COLOR_ATTR(attr_scrollwin_box, A_BOLD), + NO_COLOR_ATTR(attr_dialog_text, A_NORMAL), + NO_COLOR_ATTR(attr_dialog_menu_fore, A_STANDOUT), + NO_COLOR_ATTR(attr_dialog_menu_back, A_NORMAL), + NO_COLOR_ATTR(attr_dialog_box, A_BOLD), + NO_COLOR_ATTR(attr_input_box, A_BOLD), + NO_COLOR_ATTR(attr_input_heading, A_BOLD), + NO_COLOR_ATTR(attr_input_text, A_NORMAL), + NO_COLOR_ATTR(attr_input_field, A_UNDERLINE), + NO_COLOR_ATTR(attr_function_text, A_REVERSE), + NO_COLOR_ATTR(attr_function_highlight, A_BOLD), + { /* sentinel */ } +}; void set_colors(void) { - start_color(); - use_default_colors(); - set_normal_colors(); + const struct nconf_attr_param *p; + int pair = 0; + if (has_colors()) { - normal_color_theme(); + start_color(); + use_default_colors(); + p = color_theme_params; } else { - /* give defaults */ - no_colors_theme(); + p = no_color_theme_params; } -} + for (; p->attr; p++) { + int attr = p->highlight; + + if (p->has_color) { + pair++; + init_pair(pair, p->color_fg, p->color_bg); + attr |= COLOR_PAIR(pair); + } + + *p->attr = attr; + } +} /* this changes the windows attributes !!! */ void print_in_middle(WINDOW *win, @@ -294,14 +267,14 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) msg_win = derwin(win, win_rows-2, msg_width, 1, 1+(total_width+2-msg_width)/2); - set_menu_fore(menu, attributes[DIALOG_MENU_FORE]); - set_menu_back(menu, attributes[DIALOG_MENU_BACK]); + set_menu_fore(menu, attr_dialog_menu_fore); + set_menu_back(menu, attr_dialog_menu_back); - wattrset(win, attributes[DIALOG_BOX]); + wattrset(win, attr_dialog_box); box(win, 0, 0); /* print message */ - wattrset(msg_win, attributes[DIALOG_TEXT]); + wattrset(msg_win, attr_dialog_text); fill_window(msg_win, msg); set_menu_win(menu, win); @@ -405,16 +378,16 @@ int dialog_inputbox(WINDOW *main_window, form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); keypad(form_win, TRUE); - wattrset(form_win, attributes[INPUT_FIELD]); + wattrset(form_win, attr_input_field); - wattrset(win, attributes[INPUT_BOX]); + wattrset(win, attr_input_box); box(win, 0, 0); - wattrset(win, attributes[INPUT_HEADING]); + wattrset(win, attr_input_heading); if (title) mvwprintw(win, 0, 3, "%s", title); /* print message */ - wattrset(prompt_win, attributes[INPUT_TEXT]); + wattrset(prompt_win, attr_input_text); fill_window(prompt_win, prompt); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); @@ -576,7 +549,7 @@ void show_scroll_win(WINDOW *main_window, /* create the pad */ pad = newpad(total_lines+10, total_cols+10); - wattrset(pad, attributes[SCROLLWIN_TEXT]); + wattrset(pad, attr_scrollwin_text); fill_window(pad, text); win_lines = min(total_lines+4, lines-2); @@ -591,9 +564,9 @@ void show_scroll_win(WINDOW *main_window, win = newwin(win_lines, win_cols, y, x); keypad(win, TRUE); /* show the help in the help window, and show the help panel */ - wattrset(win, attributes[SCROLLWIN_BOX]); + wattrset(win, attr_scrollwin_box); box(win, 0, 0); - wattrset(win, attributes[SCROLLWIN_HEADING]); + wattrset(win, attr_scrollwin_heading); mvwprintw(win, 0, 3, " %s ", title); panel = new_panel(win); @@ -607,7 +580,7 @@ void show_scroll_win(WINDOW *main_window, 0, text_cols, "", - attributes[DIALOG_MENU_FORE]); + attr_dialog_menu_fore); wrefresh(win); res = wgetch(win); diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h index fa5245eb93a7..90a1ae331878 100644 --- a/scripts/kconfig/nconf.h +++ b/scripts/kconfig/nconf.h @@ -32,30 +32,26 @@ typeof(b) _b = b;\ _a < _b ? _a : _b; }) -typedef enum { - NORMAL = 1, - MAIN_HEADING, - MAIN_MENU_BOX, - MAIN_MENU_FORE, - MAIN_MENU_BACK, - MAIN_MENU_GREY, - MAIN_MENU_HEADING, - SCROLLWIN_TEXT, - SCROLLWIN_HEADING, - SCROLLWIN_BOX, - DIALOG_TEXT, - DIALOG_MENU_FORE, - DIALOG_MENU_BACK, - DIALOG_BOX, - INPUT_BOX, - INPUT_HEADING, - INPUT_TEXT, - INPUT_FIELD, - FUNCTION_TEXT, - FUNCTION_HIGHLIGHT, - ATTR_MAX -} attributes_t; -extern attributes_t attributes[]; +extern int attr_normal; +extern int attr_main_heading; +extern int attr_main_menu_box; +extern int attr_main_menu_fore; +extern int attr_main_menu_back; +extern int attr_main_menu_grey; +extern int attr_main_menu_heading; +extern int attr_scrollwin_text; +extern int attr_scrollwin_heading; +extern int attr_scrollwin_box; +extern int attr_dialog_text; +extern int attr_dialog_menu_fore; +extern int attr_dialog_menu_back; +extern int attr_dialog_box; +extern int attr_input_box; +extern int attr_input_heading; +extern int attr_input_text; +extern int attr_input_field; +extern int attr_function_text; +extern int attr_function_highlight; typedef enum { F_HELP = 1, -- cgit v1.2.3-71-gd317 From ecdb733f8fa843f632f4306939a5c3704be4a2dd Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 12 Apr 2021 10:12:25 +0900 Subject: kconfig: nconf: change set_config_filename() to void function No one uses the return value of this function. Signed-off-by: Masahiro Yamada --- scripts/kconfig/nconf.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index e86d3511b939..d8a6ab5fb521 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -631,13 +631,12 @@ static int item_is_tag(char tag) static char filename[PATH_MAX+1]; static char menu_backtitle[PATH_MAX+128]; -static const char *set_config_filename(const char *config_filename) +static void set_config_filename(const char *config_filename) { snprintf(menu_backtitle, sizeof(menu_backtitle), "%s - %s", config_filename, rootmenu.prompt->text); snprintf(filename, sizeof(filename), "%s", config_filename); - return menu_backtitle; } /* return = 0 means we are successful. -- cgit v1.2.3-71-gd317 From 0a94768cfda6a77c42e5373d264c96c77ef1a2e5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 12 Apr 2021 10:12:26 +0900 Subject: kconfig: nconf: remove meaningless wattrset() call from show_menu() This attribute is not used because it will be overridden some lines below: wattrset(main_window, attr_main_menu_box); Signed-off-by: Masahiro Yamada --- scripts/kconfig/nconf.c | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index d8a6ab5fb521..5209a18eeacb 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -953,7 +953,6 @@ static void show_menu(const char *prompt, const char *instructions, current_instructions = instructions; clear(); - wattrset(main_window, attr_normal); print_in_middle(stdscr, 1, 0, getmaxx(stdscr), menu_backtitle, attr_main_heading); -- cgit v1.2.3-71-gd317 From 08718745d8610c2ed9870568b8d9c01b7f103efb Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 12 Apr 2021 10:12:27 +0900 Subject: kconfig: nconf: refactor in print_in_middle() This helper is the same as the sample code in the NCURSES HOWTO [1], but it is over-engineering to be used for nconf. I do not see any good reason to use the 'float' type just for the division by 2. All the call-sites pass a non-NULL pointer to the first argument, so 'if (win == NULL) win = stdscr;' is dead code. 'if (startx != 0) x = startx;' is dead code because 'x' will be overridden some lines below, by 'x = startx + (int)temp;'. All the call-sites pass a non-zero value to the second argument, so 'if (starty != 0)' is always true. getyx(win, y, x) is also dead-code because both 'y' and 'x' are overridden. All the call-sites pass 0 to the third parameter, so 'startx' can be removed. All the call-sites pass a non-zero value to the fourth parameter, so 'if (width == 0) width = 80;' is dead code. The window will be refreshed later, so there is no need to call refresh() in this function. Change the type of the last parameter from 'chtype' to 'int' to be aligned with the prototype, 'int wattrset(WINDOW *win, int attrs);' I also slightly cleaned up the indentation style. [1]: https://tldp.org/HOWTO/NCURSES-Programming-HOWTO/color.html Signed-off-by: Masahiro Yamada --- scripts/kconfig/nconf.c | 2 +- scripts/kconfig/nconf.gui.c | 31 ++++--------------------------- scripts/kconfig/nconf.h | 7 +------ 3 files changed, 6 insertions(+), 34 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 5209a18eeacb..b11b75f83f7e 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -953,7 +953,7 @@ static void show_menu(const char *prompt, const char *instructions, current_instructions = instructions; clear(); - print_in_middle(stdscr, 1, 0, getmaxx(stdscr), + print_in_middle(stdscr, 1, getmaxx(stdscr), menu_backtitle, attr_main_heading); diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index e747590cee17..9aedf40f1dc0 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -117,32 +117,10 @@ void set_colors(void) } /* this changes the windows attributes !!! */ -void print_in_middle(WINDOW *win, - int starty, - int startx, - int width, - const char *string, - chtype color) -{ int length, x, y; - float temp; - - - if (win == NULL) - win = stdscr; - getyx(win, y, x); - if (startx != 0) - x = startx; - if (starty != 0) - y = starty; - if (width == 0) - width = 80; - - length = strlen(string); - temp = (width - length) / 2; - x = startx + (int)temp; - wattrset(win, color); - mvwprintw(win, y, x, "%s", string); - refresh(); +void print_in_middle(WINDOW *win, int y, int width, const char *str, int attrs) +{ + wattrset(win, attrs); + mvwprintw(win, y, (width - strlen(str)) / 2, "%s", str); } int get_line_no(const char *text) @@ -577,7 +555,6 @@ void show_scroll_win(WINDOW *main_window, text_cols, 0); print_in_middle(win, text_lines+2, - 0, text_cols, "", attr_dialog_menu_fore); diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h index 90a1ae331878..6f925bc74eb3 100644 --- a/scripts/kconfig/nconf.h +++ b/scripts/kconfig/nconf.h @@ -68,12 +68,7 @@ typedef enum { void set_colors(void); /* this changes the windows attributes !!! */ -void print_in_middle(WINDOW *win, - int starty, - int startx, - int width, - const char *string, - chtype color); +void print_in_middle(WINDOW *win, int y, int width, const char *str, int attrs); int get_line_length(const char *line); int get_line_no(const char *text); const char *get_line(const char *text, int line_no); -- cgit v1.2.3-71-gd317 From a77a05dc9cf24a8c88b9d9c70e8984f936d075f3 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 14 Apr 2021 00:08:17 +0900 Subject: kconfig: split menu.c out of parser.y Compile menu.c as an independent compilation unit. Signed-off-by: Masahiro Yamada --- scripts/kconfig/Makefile | 4 ++-- scripts/kconfig/internal.h | 9 +++++++++ scripts/kconfig/menu.c | 1 + scripts/kconfig/parser.y | 5 ++--- 4 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 scripts/kconfig/internal.h (limited to 'scripts') diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 1d1a7f83ee8d..5a215880b268 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -143,8 +143,8 @@ help: # =========================================================================== # object files used by all kconfig flavours -common-objs := confdata.o expr.o lexer.lex.o parser.tab.o preprocess.o \ - symbol.o util.o +common-objs := confdata.o expr.o lexer.lex.o menu.o parser.tab.o \ + preprocess.o symbol.o util.o $(obj)/lexer.lex.o: $(obj)/parser.tab.h HOSTCFLAGS_lexer.lex.o := -I $(srctree)/$(src) diff --git a/scripts/kconfig/internal.h b/scripts/kconfig/internal.h new file mode 100644 index 000000000000..2f7298c21b64 --- /dev/null +++ b/scripts/kconfig/internal.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef INTERNAL_H +#define INTERNAL_H + +struct menu; + +extern struct menu *current_menu, *current_entry; + +#endif /* INTERNAL_H */ diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 8b2108b74821..606ba8a63c24 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -9,6 +9,7 @@ #include #include "lkc.h" +#include "internal.h" static const char nohelp_text[] = "There is no help available for this option."; diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y index e90889edf5b3..2af7ce4e1531 100644 --- a/scripts/kconfig/parser.y +++ b/scripts/kconfig/parser.y @@ -12,6 +12,7 @@ #include #include "lkc.h" +#include "internal.h" #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) @@ -28,7 +29,7 @@ static bool zconf_endtoken(const char *tokenname, struct symbol *symbol_hash[SYMBOL_HASHSIZE]; -static struct menu *current_menu, *current_entry; +struct menu *current_menu, *current_entry; %} @@ -713,5 +714,3 @@ void zconfdump(FILE *out) } } } - -#include "menu.c" -- cgit v1.2.3-71-gd317 From f9bbc12ccb35ac8b3fa01cec1a19cb523a7707c7 Mon Sep 17 00:00:00 2001 From: Aditya Srivastava Date: Thu, 15 Apr 2021 00:55:29 +0530 Subject: scripts: kernel-doc: improve parsing for kernel-doc comments syntax Currently kernel-doc does not identify some cases of probable kernel doc comments, for e.g. pointer used as declaration type for identifier, space separated identifier, etc. Some example of these cases in files can be: i)" * journal_t * jbd2_journal_init_dev() - creates and initialises a journal structure" in fs/jbd2/journal.c ii) "* dget, dget_dlock - get a reference to a dentry" in include/linux/dcache.h iii) " * DEFINE_SEQLOCK(sl) - Define a statically allocated seqlock_t" in include/linux/seqlock.h Also improve identification for non-kerneldoc comments. For e.g., i) " * The following functions allow us to read data using a swap map" in kernel/power/swap.c does follow the kernel-doc like syntax, but the content inside does not adheres to the expected format. Improve parsing by adding support for these probable attempts to write kernel-doc comment. Suggested-by: Jonathan Corbet Link: https://lore.kernel.org/lkml/87mtujktl2.fsf@meer.lwn.net Signed-off-by: Aditya Srivastava Link: https://lore.kernel.org/r/20210414192529.9080-1-yashsri421@gmail.com [ jc: fixed some line-length issues ] Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 888913528185..2a85d34fdcd0 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2110,17 +2110,28 @@ sub process_name($$) { } elsif (/$doc_decl/o) { $identifier = $1; my $is_kernel_comment = 0; - if (/^\s*\*\s*([\w\s]+?)(\(\))?\s*([-:].*)?$/) { + my $decl_start = qr{\s*\*}; + # test for pointer declaration type, foo * bar() - desc + my $fn_type = qr{\w+\s*\*\s*}; + my $parenthesis = qr{\(\w*\)}; + my $decl_end = qr{[-:].*}; + if (/^$decl_start\s*([\w\s]+?)$parenthesis?\s*$decl_end?$/) { $identifier = $1; - $decl_type = 'function'; - $identifier =~ s/^define\s+//; - $is_kernel_comment = 1; } if ($identifier =~ m/^(struct|union|enum|typedef)\b\s*(\S*)/) { $decl_type = $1; $identifier = $2; $is_kernel_comment = 1; } + # Look for foo() or static void foo() - description; or misspelt + # identifier + elsif (/^$decl_start\s*$fn_type?(\w+)\s*$parenthesis?\s*$decl_end?$/ || + /^$decl_start\s*$fn_type?(\w+.*)$parenthesis?\s*$decl_end$/) { + $identifier = $1; + $decl_type = 'function'; + $identifier =~ s/^define\s+//; + $is_kernel_comment = 1; + } $identifier =~ s/\s+$//; $state = STATE_BODY; -- cgit v1.2.3-71-gd317 From e9dfeed2518671e94779a6103301cded67fae0e2 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 Apr 2021 16:01:50 -0600 Subject: docs: sphinx-pre-install: don't barf on beta Sphinx releases sphinx-pre-install is picky when it comes to parsing sphinx versions; it failed when run with sphinx 4.0.0b1. Tweak the regex to tolerate a trailing "bN" on the version number. Signed-off-by: Jonathan Corbet --- scripts/sphinx-pre-install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install index b5f9fd5b2880..fe92020d67e3 100755 --- a/scripts/sphinx-pre-install +++ b/scripts/sphinx-pre-install @@ -259,7 +259,7 @@ sub get_sphinx_version($) open IN, "$cmd --version 2>&1 |"; while () { - if (m/^\s*sphinx-build\s+([\d\.]+)(\+\/[\da-f]+)?$/) { + if (m/^\s*sphinx-build\s+([\d\.]+)((\+\/[\da-f]+)|(b\d+))?$/) { $ver=$1; last; } -- cgit v1.2.3-71-gd317 From 8c94b430b9f6213dec84e309bb480a71778c4213 Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Thu, 15 Apr 2021 09:28:03 +0200 Subject: kconfig: nconf: stop endless search loops If the user selects the very first entry in a page and performs a search-up operation, or selects the very last entry in a page and performs a search-down operation that will not succeed (e.g., via [/]asdfzzz[Up Arrow]), nconf will never terminate searching the page. The reason is that in this case, the starting point will be set to -1 or n, which is then translated into (n - 1) (i.e., the last entry of the page) or 0 (i.e., the first entry of the page) and finally the search begins. This continues to work fine until the index reaches 0 or (n - 1), at which point it will be decremented to -1 or incremented to n, but not checked against the starting point right away. Instead, it's wrapped around to the bottom or top again, after which the starting point check occurs... and naturally fails. My original implementation added another check for -1 before wrapping the running index variable around, but Masahiro Yamada pointed out that the actual issue is that the comparison point (starting point) exceeds bounds (i.e., the [0,n-1] interval) in the first place and that, instead, the starting point should be fixed. This has the welcome side-effect of also fixing the case where the starting point was n while searching down, which also lead to an infinite loop. OTOH, this code is now essentially all his work. Amazingly, nobody seems to have been hit by this for 11 years - or at the very least nobody bothered to debug and fix this. Signed-off-by: Mihai Moldovan Signed-off-by: Masahiro Yamada --- scripts/kconfig/nconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index b11b75f83f7e..7b371bd7fb36 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -508,8 +508,8 @@ static int get_mext_match(const char *match_str, match_f flag) else if (flag == FIND_NEXT_MATCH_UP) --match_start; + match_start = (match_start + items_num) % items_num; index = match_start; - index = (index + items_num) % items_num; while (true) { char *str = k_menu_items[index].str; if (strcasestr(str, match_str) != NULL) -- cgit v1.2.3-71-gd317 From 5c595ac4c776c44b5c59de22ab43b3fe256d9fbb Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 16 Apr 2021 15:45:57 -0700 Subject: kasan: fix hwasan build for gcc gcc-11 adds support for -fsanitize=kernel-hwaddress, so it becomes possible to enable CONFIG_KASAN_SW_TAGS. Unfortunately this fails to build at the moment, because the corresponding command line arguments use llvm specific syntax. Change it to use the cc-param macro instead, which works on both clang and gcc. [elver@google.com: fixup for "kasan: fix hwasan build for gcc"] Link: https://lkml.kernel.org/r/YHQZVfVVLE/LDK2v@elver.google.com Link: https://lkml.kernel.org/r/20210323124112.1229772-1-arnd@kernel.org Signed-off-by: Arnd Bergmann Signed-off-by: Marco Elver Reviewed-by: Marco Elver Acked-by: Andrey Konovalov Cc: Masahiro Yamada Cc: Michal Marek Cc: Andrey Ryabinin Cc: Nathan Chancellor Cc: Nick Desaulniers Cc: Alexander Potapenko Cc: Dmitry Vyukov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/Makefile.kasan | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan index 1e000cc2e7b4..127012f45166 100644 --- a/scripts/Makefile.kasan +++ b/scripts/Makefile.kasan @@ -2,6 +2,8 @@ CFLAGS_KASAN_NOSANITIZE := -fno-builtin KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET) +cc-param = $(call cc-option, -mllvm -$(1), $(call cc-option, --param $(1))) + ifdef CONFIG_KASAN_GENERIC ifdef CONFIG_KASAN_INLINE @@ -12,8 +14,6 @@ endif CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address -cc-param = $(call cc-option, -mllvm -$(1), $(call cc-option, --param $(1))) - # -fasan-shadow-offset fails without -fsanitize CFLAGS_KASAN_SHADOW := $(call cc-option, -fsanitize=kernel-address \ -fasan-shadow-offset=$(KASAN_SHADOW_OFFSET), \ @@ -36,14 +36,14 @@ endif # CONFIG_KASAN_GENERIC ifdef CONFIG_KASAN_SW_TAGS ifdef CONFIG_KASAN_INLINE - instrumentation_flags := -mllvm -hwasan-mapping-offset=$(KASAN_SHADOW_OFFSET) + instrumentation_flags := $(call cc-param,hwasan-mapping-offset=$(KASAN_SHADOW_OFFSET)) else - instrumentation_flags := -mllvm -hwasan-instrument-with-calls=1 + instrumentation_flags := $(call cc-param,hwasan-instrument-with-calls=1) endif CFLAGS_KASAN := -fsanitize=kernel-hwaddress \ - -mllvm -hwasan-instrument-stack=$(CONFIG_KASAN_STACK) \ - -mllvm -hwasan-use-short-granules=0 \ + $(call cc-param,hwasan-instrument-stack=$(CONFIG_KASAN_STACK)) \ + $(call cc-param,hwasan-use-short-granules=0) \ $(instrumentation_flags) endif # CONFIG_KASAN_SW_TAGS -- cgit v1.2.3-71-gd317 From 02c587733c8161355a43e6e110c2e29bd0acff72 Mon Sep 17 00:00:00 2001 From: Walter Wu Date: Fri, 16 Apr 2021 15:46:00 -0700 Subject: kasan: remove redundant config option CONFIG_KASAN_STACK and CONFIG_KASAN_STACK_ENABLE both enable KASAN stack instrumentation, but we should only need one config, so that we remove CONFIG_KASAN_STACK_ENABLE and make CONFIG_KASAN_STACK workable. see [1]. When enable KASAN stack instrumentation, then for gcc we could do no prompt and default value y, and for clang prompt and default value n. This patch fixes the following compilation warning: include/linux/kasan.h:333:30: warning: 'CONFIG_KASAN_STACK' is not defined, evaluates to 0 [-Wundef] [akpm@linux-foundation.org: fix merge snafu] Link: https://bugzilla.kernel.org/show_bug.cgi?id=210221 [1] Link: https://lkml.kernel.org/r/20210226012531.29231-1-walter-zh.wu@mediatek.com Fixes: d9b571c885a8 ("kasan: fix KASAN_STACK dependency for HW_TAGS") Signed-off-by: Walter Wu Suggested-by: Dmitry Vyukov Reviewed-by: Nathan Chancellor Acked-by: Arnd Bergmann Reviewed-by: Andrey Konovalov Cc: Andrey Ryabinin Cc: Dmitry Vyukov Cc: Alexander Potapenko Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm64/kernel/sleep.S | 2 +- arch/x86/kernel/acpi/wakeup_64.S | 2 +- include/linux/kasan.h | 2 +- lib/Kconfig.kasan | 9 ++------- mm/kasan/common.c | 2 +- mm/kasan/kasan.h | 2 +- mm/kasan/report_generic.c | 2 +- scripts/Makefile.kasan | 10 ++++++++-- security/Kconfig.hardening | 4 ++-- 9 files changed, 18 insertions(+), 17 deletions(-) (limited to 'scripts') diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S index 5bfd9b87f85d..4ea9392f86e0 100644 --- a/arch/arm64/kernel/sleep.S +++ b/arch/arm64/kernel/sleep.S @@ -134,7 +134,7 @@ SYM_FUNC_START(_cpu_resume) */ bl cpu_do_resume -#if defined(CONFIG_KASAN) && CONFIG_KASAN_STACK +#if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK) mov x0, sp bl kasan_unpoison_task_stack_below #endif diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S index 56b6865afb2a..d5d8a352eafa 100644 --- a/arch/x86/kernel/acpi/wakeup_64.S +++ b/arch/x86/kernel/acpi/wakeup_64.S @@ -115,7 +115,7 @@ SYM_FUNC_START(do_suspend_lowlevel) movq pt_regs_r14(%rax), %r14 movq pt_regs_r15(%rax), %r15 -#if defined(CONFIG_KASAN) && CONFIG_KASAN_STACK +#if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK) /* * The suspend path may have poisoned some areas deeper in the stack, * which we now need to unpoison. diff --git a/include/linux/kasan.h b/include/linux/kasan.h index b91732bd05d7..14f72ec96492 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -330,7 +330,7 @@ static inline bool kasan_check_byte(const void *address) #endif /* CONFIG_KASAN */ -#if defined(CONFIG_KASAN) && CONFIG_KASAN_STACK +#if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK) void kasan_unpoison_task_stack(struct task_struct *task); #else static inline void kasan_unpoison_task_stack(struct task_struct *task) {} diff --git a/lib/Kconfig.kasan b/lib/Kconfig.kasan index fba9909e31b7..cffc2ebbf185 100644 --- a/lib/Kconfig.kasan +++ b/lib/Kconfig.kasan @@ -138,9 +138,10 @@ config KASAN_INLINE endchoice -config KASAN_STACK_ENABLE +config KASAN_STACK bool "Enable stack instrumentation (unsafe)" if CC_IS_CLANG && !COMPILE_TEST depends on KASAN_GENERIC || KASAN_SW_TAGS + default y if CC_IS_GCC help The LLVM stack address sanitizer has a know problem that causes excessive stack usage in a lot of functions, see @@ -154,12 +155,6 @@ config KASAN_STACK_ENABLE CONFIG_COMPILE_TEST. On gcc it is assumed to always be safe to use and enabled by default. -config KASAN_STACK - int - depends on KASAN_GENERIC || KASAN_SW_TAGS - default 1 if KASAN_STACK_ENABLE || CC_IS_GCC - default 0 - config KASAN_SW_TAGS_IDENTIFY bool "Enable memory corruption identification" depends on KASAN_SW_TAGS diff --git a/mm/kasan/common.c b/mm/kasan/common.c index b5e08d4cefec..7b53291dafa1 100644 --- a/mm/kasan/common.c +++ b/mm/kasan/common.c @@ -63,7 +63,7 @@ void __kasan_unpoison_range(const void *address, size_t size) kasan_unpoison(address, size); } -#if CONFIG_KASAN_STACK +#ifdef CONFIG_KASAN_STACK /* Unpoison the entire stack for a task. */ void kasan_unpoison_task_stack(struct task_struct *task) { diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h index 8c55634d6edd..3436c6bf7c0c 100644 --- a/mm/kasan/kasan.h +++ b/mm/kasan/kasan.h @@ -231,7 +231,7 @@ void *kasan_find_first_bad_addr(void *addr, size_t size); const char *kasan_get_bug_type(struct kasan_access_info *info); void kasan_metadata_fetch_row(char *buffer, void *row); -#if defined(CONFIG_KASAN_GENERIC) && CONFIG_KASAN_STACK +#if defined(CONFIG_KASAN_GENERIC) && defined(CONFIG_KASAN_STACK) void kasan_print_address_stack_frame(const void *addr); #else static inline void kasan_print_address_stack_frame(const void *addr) { } diff --git a/mm/kasan/report_generic.c b/mm/kasan/report_generic.c index 41f374585144..de732bc341c5 100644 --- a/mm/kasan/report_generic.c +++ b/mm/kasan/report_generic.c @@ -128,7 +128,7 @@ void kasan_metadata_fetch_row(char *buffer, void *row) memcpy(buffer, kasan_mem_to_shadow(row), META_BYTES_PER_ROW); } -#if CONFIG_KASAN_STACK +#ifdef CONFIG_KASAN_STACK static bool __must_check tokenize_frame_descr(const char **frame_descr, char *token, size_t max_tok_len, unsigned long *value) diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan index 127012f45166..3d791908ed36 100644 --- a/scripts/Makefile.kasan +++ b/scripts/Makefile.kasan @@ -4,6 +4,12 @@ KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET) cc-param = $(call cc-option, -mllvm -$(1), $(call cc-option, --param $(1))) +ifdef CONFIG_KASAN_STACK + stack_enable := 1 +else + stack_enable := 0 +endif + ifdef CONFIG_KASAN_GENERIC ifdef CONFIG_KASAN_INLINE @@ -27,7 +33,7 @@ else CFLAGS_KASAN := $(CFLAGS_KASAN_SHADOW) \ $(call cc-param,asan-globals=1) \ $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ - $(call cc-param,asan-stack=$(CONFIG_KASAN_STACK)) \ + $(call cc-param,asan-stack=$(stack_enable)) \ $(call cc-param,asan-instrument-allocas=1) endif @@ -42,7 +48,7 @@ else endif CFLAGS_KASAN := -fsanitize=kernel-hwaddress \ - $(call cc-param,hwasan-instrument-stack=$(CONFIG_KASAN_STACK)) \ + $(call cc-param,hwasan-instrument-stack=$(stack_enable)) \ $(call cc-param,hwasan-use-short-granules=0) \ $(instrumentation_flags) diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening index 269967c4fc1b..a56c36470cb1 100644 --- a/security/Kconfig.hardening +++ b/security/Kconfig.hardening @@ -64,7 +64,7 @@ choice config GCC_PLUGIN_STRUCTLEAK_BYREF bool "zero-init structs passed by reference (strong)" depends on GCC_PLUGINS - depends on !(KASAN && KASAN_STACK=1) + depends on !(KASAN && KASAN_STACK) select GCC_PLUGIN_STRUCTLEAK help Zero-initialize any structures on the stack that may @@ -82,7 +82,7 @@ choice config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL bool "zero-init anything passed by reference (very strong)" depends on GCC_PLUGINS - depends on !(KASAN && KASAN_STACK=1) + depends on !(KASAN && KASAN_STACK) select GCC_PLUGIN_STRUCTLEAK help Zero-initialize any stack variables that may be passed -- cgit v1.2.3-71-gd317 From 989e5d4b576f010de4bacb9fdad0cb879c75e9d7 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 17 Apr 2021 23:50:36 +0900 Subject: kconfig: remove unused PACKAGE definition Commit 3b9fa0931dd8 ("[PATCH] Kconfig i18n support") added this code, and then commit ("kconfig: drop localization support") removed the i18n support entirely. Remove the left-over. Signed-off-by: Masahiro Yamada --- scripts/kconfig/lkc.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 45599c52478d..fa8c010aa683 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -20,10 +20,6 @@ extern "C" { #define SRCTREE "srctree" -#ifndef PACKAGE -#define PACKAGE "linux" -#endif - #ifndef CONFIG_ #define CONFIG_ "CONFIG_" #endif -- cgit v1.2.3-71-gd317 From ed63ef7796979835d7cfb4dc2d108b6eeeb2b7c2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 17 Apr 2021 23:50:37 +0900 Subject: kconfig: gconf: remove unused code Remove the unused inclusion, and commented out lines. Signed-off-by: Masahiro Yamada --- scripts/kconfig/gconf.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 5527482c3077..7698eea6fb6e 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -3,10 +3,6 @@ * Copyright (C) 2002-2003 Romain Lievin */ -#ifdef HAVE_CONFIG_H -# include -#endif - #include #include "lkc.h" #include "images.h" @@ -1452,9 +1448,6 @@ int main(int ac, char *av[]) gtk_init(&ac, &av); glade_init(); - //add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps"); - //add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps"); - /* Determine GUI path */ env = getenv(SRCTREE); if (env) -- cgit v1.2.3-71-gd317 From 5fb35ec10bb0665080c8de8a360fb4dba9a0f73f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 17 Apr 2021 22:51:22 -0700 Subject: kconfig: highlight gconfig 'comment' lines with '***' Mark Kconfig "comment" lines with "*** ***" so that it is clear that these lines are comments and not some kconfig item that cannot be modified. This is helpful in some menus to be able to provide a menu "sub-heading" for groups of similar config items. This also makes the comments be presented in a way that is similar to menuconfig and nconfig. Signed-off-by: Randy Dunlap Signed-off-by: Masahiro Yamada --- scripts/kconfig/gconf.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 7698eea6fb6e..17adabfd6e6b 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -1044,8 +1044,13 @@ static gchar **fill_row(struct menu *menu) g_free(row[i]); bzero(row, sizeof(row)); + ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; + row[COL_OPTION] = - g_strdup_printf("%s %s", menu_get_prompt(menu), + g_strdup_printf("%s %s %s %s", + ptype == P_COMMENT ? "***" : "", + menu_get_prompt(menu), + ptype == P_COMMENT ? "***" : "", sym && !sym_has_value(sym) ? "(NEW)" : ""); if (opt_mode == OPT_ALL && !menu_is_visible(menu)) @@ -1056,7 +1061,6 @@ static gchar **fill_row(struct menu *menu) else row[COL_COLOR] = g_strdup("Black"); - ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; switch (ptype) { case P_MENU: row[COL_PIXBUF] = (gchar *) xpm_menu; -- cgit v1.2.3-71-gd317 From 92f8a9217a1215cc3d71e82d5d1cde0793cf0501 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 17 Apr 2021 22:51:23 -0700 Subject: kconfig: highlight xconfig 'comment' lines with '***' Mark Kconfig "comment" lines with "*** ***" so that it is clear that these lines are comments and not some kconfig item that cannot be modified. This is helpful in some menus to be able to provide a menu "sub-heading" for groups of similar config items. This also makes the comments be presented in a way that is similar to menuconfig and nconfig. Signed-off-by: Randy Dunlap Signed-off-by: Masahiro Yamada --- scripts/kconfig/qconf.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index d000869b787c..78087b2d9ac6 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -122,6 +122,7 @@ void ConfigItem::updateMenu(void) goto set_prompt; case P_COMMENT: setIcon(promptColIdx, QIcon()); + prompt = "*** " + prompt + " ***"; goto set_prompt; default: ; -- cgit v1.2.3-71-gd317 From 57fd251c789647552d32d2fc51bedd4f90d70f9f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 28 Feb 2021 15:10:27 +0900 Subject: kbuild: split cc-option and friends to scripts/Makefile.compiler scripts/Kbuild.include is included everywhere, but macros such as cc-option are needed by build targets only. For example, when 'make clean' traverses the tree, it does not need to evaluate $(call cc-option,). Split cc-option, ld-option, etc. to scripts/Makefile.compiler, which is only included from the top Makefile and scripts/Makefile.build. Signed-off-by: Masahiro Yamada --- Makefile | 4 +++ scripts/Kbuild.include | 80 ----------------------------------------------- scripts/Makefile.build | 1 + scripts/Makefile.compiler | 75 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 80 deletions(-) create mode 100644 scripts/Makefile.compiler (limited to 'scripts') diff --git a/Makefile b/Makefile index 93e6e2d28d89..80bae8a1341f 100644 --- a/Makefile +++ b/Makefile @@ -584,6 +584,10 @@ KBUILD_AFLAGS += $(CLANG_FLAGS) export CLANG_FLAGS endif +# Include this also for config targets because some architectures need +# cc-cross-prefix to determine CROSS_COMPILE. +include $(srctree)/scripts/Makefile.compiler + ifdef config-build # =========================================================================== # *config targets only - make sure prerequisites are updated, and descend diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 509e0856d653..82dd1b65b7a8 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -67,86 +67,6 @@ define filechk fi endef -###### -# gcc support functions -# See documentation in Documentation/kbuild/makefiles.rst - -# cc-cross-prefix -# Usage: CROSS_COMPILE := $(call cc-cross-prefix, m68k-linux-gnu- m68k-linux-) -# Return first where a gcc is found in PATH. -# If no gcc found in PATH with listed prefixes return nothing -# -# Note: '2>/dev/null' is here to force Make to invoke a shell. Otherwise, it -# would try to directly execute the shell builtin 'command'. This workaround -# should be kept for a long time since this issue was fixed only after the -# GNU Make 4.2.1 release. -cc-cross-prefix = $(firstword $(foreach c, $(1), \ - $(if $(shell command -v -- $(c)gcc 2>/dev/null), $(c)))) - -# output directory for tests below -TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$ - -# try-run -# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise) -# Exit code chooses option. "$$TMP" serves as a temporary file and is -# automatically cleaned up. -try-run = $(shell set -e; \ - TMP=$(TMPOUT)/tmp; \ - TMPO=$(TMPOUT)/tmp.o; \ - mkdir -p $(TMPOUT); \ - trap "rm -rf $(TMPOUT)" EXIT; \ - if ($(1)) >/dev/null 2>&1; \ - then echo "$(2)"; \ - else echo "$(3)"; \ - fi) - -# as-option -# Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,) - -as-option = $(call try-run,\ - $(CC) $(KBUILD_CFLAGS) $(1) -c -x assembler /dev/null -o "$$TMP",$(1),$(2)) - -# as-instr -# Usage: cflags-y += $(call as-instr,instr,option1,option2) - -as-instr = $(call try-run,\ - printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3)) - -# __cc-option -# Usage: MY_CFLAGS += $(call __cc-option,$(CC),$(MY_CFLAGS),-march=winchip-c6,-march=i586) -__cc-option = $(call try-run,\ - $(1) -Werror $(2) $(3) -c -x c /dev/null -o "$$TMP",$(3),$(4)) - -# cc-option -# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) - -cc-option = $(call __cc-option, $(CC),\ - $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS),$(1),$(2)) - -# cc-option-yn -# Usage: flag := $(call cc-option-yn,-march=winchip-c6) -cc-option-yn = $(call try-run,\ - $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) - -# cc-disable-warning -# Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable) -cc-disable-warning = $(call try-run,\ - $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) - -# cc-ifversion -# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) -cc-ifversion = $(shell [ $(CONFIG_GCC_VERSION)0 $(1) $(2)000 ] && echo $(3) || echo $(4)) - -# ld-option -# Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y) -ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3)) - -# ld-ifversion -# Usage: $(call ld-ifversion, -ge, 22252, y) -ld-ifversion = $(shell [ $(CONFIG_LD_VERSION)0 $(1) $(2)0 ] && echo $(3) || echo $(4)) - -###### - ### # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj= # Usage: diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 750d6d5225af..d74d3383666e 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -36,6 +36,7 @@ subdir-ccflags-y := -include include/config/auto.conf include $(srctree)/scripts/Kbuild.include +include $(srctree)/scripts/Makefile.compiler # The filename Kbuild has precedence over Makefile kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler new file mode 100644 index 000000000000..3f2f3665216f --- /dev/null +++ b/scripts/Makefile.compiler @@ -0,0 +1,75 @@ +# SPDX-License-Identifier: GPL-2.0-only + +# cc-cross-prefix +# Usage: CROSS_COMPILE := $(call cc-cross-prefix, m68k-linux-gnu- m68k-linux-) +# Return first where a gcc is found in PATH. +# If no gcc found in PATH with listed prefixes return nothing +# +# Note: '2>/dev/null' is here to force Make to invoke a shell. Otherwise, it +# would try to directly execute the shell builtin 'command'. This workaround +# should be kept for a long time since this issue was fixed only after the +# GNU Make 4.2.1 release. +cc-cross-prefix = $(firstword $(foreach c, $(1), \ + $(if $(shell command -v -- $(c)gcc 2>/dev/null), $(c)))) + +# output directory for tests below +TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$ + +# try-run +# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise) +# Exit code chooses option. "$$TMP" serves as a temporary file and is +# automatically cleaned up. +try-run = $(shell set -e; \ + TMP=$(TMPOUT)/tmp; \ + TMPO=$(TMPOUT)/tmp.o; \ + mkdir -p $(TMPOUT); \ + trap "rm -rf $(TMPOUT)" EXIT; \ + if ($(1)) >/dev/null 2>&1; \ + then echo "$(2)"; \ + else echo "$(3)"; \ + fi) + +# as-option +# Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,) + +as-option = $(call try-run,\ + $(CC) $(KBUILD_CFLAGS) $(1) -c -x assembler /dev/null -o "$$TMP",$(1),$(2)) + +# as-instr +# Usage: cflags-y += $(call as-instr,instr,option1,option2) + +as-instr = $(call try-run,\ + printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3)) + +# __cc-option +# Usage: MY_CFLAGS += $(call __cc-option,$(CC),$(MY_CFLAGS),-march=winchip-c6,-march=i586) +__cc-option = $(call try-run,\ + $(1) -Werror $(2) $(3) -c -x c /dev/null -o "$$TMP",$(3),$(4)) + +# cc-option +# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) + +cc-option = $(call __cc-option, $(CC),\ + $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS),$(1),$(2)) + +# cc-option-yn +# Usage: flag := $(call cc-option-yn,-march=winchip-c6) +cc-option-yn = $(call try-run,\ + $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) + +# cc-disable-warning +# Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable) +cc-disable-warning = $(call try-run,\ + $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) + +# cc-ifversion +# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) +cc-ifversion = $(shell [ $(CONFIG_GCC_VERSION)0 $(1) $(2)000 ] && echo $(3) || echo $(4)) + +# ld-option +# Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y) +ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3)) + +# ld-ifversion +# Usage: $(call ld-ifversion, -ge, 22252, y) +ld-ifversion = $(shell [ $(CONFIG_LD_VERSION)0 $(1) $(2)0 ] && echo $(3) || echo $(4)) -- cgit v1.2.3-71-gd317 From 5cc1247204616528b427e276c97c5bc4c9612347 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Fri, 5 Mar 2021 10:27:07 +0100 Subject: kbuild: add CONFIG_VMLINUX_MAP expert option It can be quite useful to have ld emit a link map file, in order to debug or verify that special sections end up where they are supposed to, and to see what LD_DEAD_CODE_DATA_ELIMINATION manages to get rid of. The only reason I'm not just adding this unconditionally is that the .map file can be rather large (several MB), and that's a waste of space when one isn't interested in these things. Also make it depend on CONFIG_EXPERT. Signed-off-by: Rasmus Villemoes Signed-off-by: Masahiro Yamada --- .gitignore | 1 + Documentation/dontdiff | 1 + lib/Kconfig.debug | 10 ++++++++++ scripts/link-vmlinux.sh | 8 ++++++++ 4 files changed, 20 insertions(+) (limited to 'scripts') diff --git a/.gitignore b/.gitignore index 3af66272d6f1..3adea59847ce 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,7 @@ modules.order /linux /vmlinux /vmlinux.32 +/vmlinux.map /vmlinux.symvers /vmlinux-gdb.py /vmlinuz diff --git a/Documentation/dontdiff b/Documentation/dontdiff index e361fc95ca29..ac42ad8d430d 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff @@ -252,6 +252,7 @@ vmlinux-* vmlinux.aout vmlinux.bin.all vmlinux.lds +vmlinux.map vmlinux.symvers vmlinuz voffset.h diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 2779c29d9981..b479ae609a31 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -449,6 +449,16 @@ config VMLINUX_VALIDATION depends on STACK_VALIDATION && DEBUG_ENTRY && !PARAVIRT default y +config VMLINUX_MAP + bool "Generate vmlinux.map file when linking" + depends on EXPERT + help + Selecting this option will pass "-Map=vmlinux.map" to ld + when linking vmlinux. That file can be useful for verifying + and debugging magic section games, and for seeing which + pieces of code get eliminated with + CONFIG_LD_DEAD_CODE_DATA_ELIMINATION. + config DEBUG_FORCE_WEAK_PER_CPU bool "Force weak per-cpu definitions" depends on DEBUG_KERNEL diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 3b261b0f74f0..855fd4e6f03e 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -155,6 +155,7 @@ vmlinux_link() local output=${1} local objects local strip_debug + local map_option info LD ${output} @@ -166,6 +167,10 @@ vmlinux_link() strip_debug=-Wl,--strip-debug fi + if [ -n "${CONFIG_VMLINUX_MAP}" ]; then + map_option="-Map=${output}.map" + fi + if [ "${SRCARCH}" != "um" ]; then if [ -n "${CONFIG_LTO_CLANG}" ]; then # Use vmlinux.o instead of performing the slow LTO @@ -187,6 +192,7 @@ vmlinux_link() ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} \ ${strip_debug#-Wl,} \ -o ${output} \ + ${map_option} \ -T ${lds} ${objects} else objects="-Wl,--whole-archive \ @@ -200,6 +206,7 @@ vmlinux_link() ${CC} ${CFLAGS_vmlinux} \ ${strip_debug} \ -o ${output} \ + ${map_option:+-Wl,${map_option}} \ -Wl,-T,${lds} \ ${objects} \ -lutil -lrt -lpthread @@ -303,6 +310,7 @@ cleanup() rm -f .tmp_vmlinux* rm -f System.map rm -f vmlinux + rm -f vmlinux.map rm -f vmlinux.o } -- cgit v1.2.3-71-gd317 From 0b956e204132ce3fe4221a062638bf83a30e6200 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Fri, 5 Mar 2021 11:02:12 +0100 Subject: kbuild: apply fixdep logic to link-vmlinux.sh The patch adding CONFIG_VMLINUX_MAP revealed a small defect in the build system: link-vmlinux.sh takes decisions based on CONFIG_* options, but changing one of those does not always lead to vmlinux being linked again. For most of the CONFIG_* knobs referenced previously, this has probably been hidden by those knobs also affecting some object file, hence indirectly also vmlinux. But CONFIG_VMLINUX_MAP is only handled inside link-vmlinux.sh, and changing CONFIG_VMLINUX_MAP=n to CONFIG_VMLINUX_MAP=y does not cause the build system to re-link (and hence have vmlinux.map emitted). Since that map file is mostly a debugging aid, this is merely a nuisance which is easily worked around by just deleting vmlinux and building again. But one could imagine other (possibly future) CONFIG options that actually do affect the vmlinux binary but which are not captured through some object file dependency. To fix this, make link-vmlinux.sh emit a .vmlinux.d file in the same format as the dependency files generated by gcc, and apply the fixdep logic to that. I've tested that this correctly works with both in-tree and out-of-tree builds. Signed-off-by: Rasmus Villemoes Signed-off-by: Masahiro Yamada --- Makefile | 2 +- scripts/link-vmlinux.sh | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 80c82155ebb6..03e3ee982f14 100644 --- a/Makefile +++ b/Makefile @@ -1213,7 +1213,7 @@ cmd_link-vmlinux = \ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE - +$(call if_changed,link-vmlinux) + +$(call if_changed_dep,link-vmlinux) targets := vmlinux diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 855fd4e6f03e..e9516bdfcc6f 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -312,6 +312,7 @@ cleanup() rm -f vmlinux rm -f vmlinux.map rm -f vmlinux.o + rm -f .vmlinux.d } on_exit() @@ -449,3 +450,6 @@ if [ -n "${CONFIG_KALLSYMS}" ]; then exit 1 fi fi + +# For fixdep +echo "vmlinux: $0" > .vmlinux.d -- cgit v1.2.3-71-gd317 From a6601e01cd54838fc01e3c355476f67e7c887a67 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 6 Mar 2021 15:11:20 +0900 Subject: kbuild: rename multi-used-* to multi-obj-* I think multi-obj-* is clearer, and more consistent with real-obj-*. Rename as follows: multi-used-y -> multi-obj-y multi-used-m -> multi-obj-m multi-used -> multi-obj-ym Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 6 +++--- scripts/Makefile.lib | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index d74d3383666e..e47c054d3db2 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -445,11 +445,11 @@ quiet_cmd_link_multi-m = LD [M] $@ cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ $(filter %.o,$^) endif -$(multi-used-m): FORCE +$(multi-obj-m): FORCE $(call if_changed,link_multi-m) -$(call multi_depend, $(multi-used-m), .o, -objs -y -m) +$(call multi_depend, $(multi-obj-m), .o, -objs -y -m) -targets += $(multi-used-m) +targets += $(multi-obj-m) targets := $(filter-out $(PHONY), $(targets)) # Add intermediate targets: diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 8cd67b1b6d15..bc611c11e28a 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -48,9 +48,9 @@ endif suffix-search = $(foreach s,$(2),$($(1:.o=$s))) # If $(foo-objs), $(foo-y), $(foo-m), or $(foo-) exists, foo.o is a composite object multi-search = $(sort $(foreach m,$(1), $(if $(strip $(call suffix-search,$(m),$(2) -)), $(m)))) -multi-used-y := $(call multi-search,$(obj-y),-objs -y) -multi-used-m := $(call multi-search,$(obj-m),-objs -y -m) -multi-used := $(multi-used-y) $(multi-used-m) +multi-obj-y := $(call multi-search,$(obj-y),-objs -y) +multi-obj-m := $(call multi-search,$(obj-m),-objs -y -m) +multi-obj-ym := $(multi-obj-y) $(multi-obj-m) # Replace multi-part objects by their individual parts, # including built-in.a from subdirectories @@ -92,12 +92,12 @@ obj-m := $(addprefix $(obj)/,$(obj-m)) lib-y := $(addprefix $(obj)/,$(lib-y)) real-obj-y := $(addprefix $(obj)/,$(real-obj-y)) real-obj-m := $(addprefix $(obj)/,$(real-obj-m)) -multi-used-m := $(addprefix $(obj)/,$(multi-used-m)) +multi-obj-m := $(addprefix $(obj)/, $(multi-obj-m)) subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) # Finds the multi-part object the current object will be linked into. # If the object belongs to two or more multi-part objects, list them all. -modname-multi = $(sort $(foreach m,$(multi-used),\ +modname-multi = $(sort $(foreach m,$(multi-obj-ym),\ $(if $(filter $*.o, $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$(m:.o=)))) __modname = $(if $(modname-multi),$(modname-multi),$(basetarget)) -- cgit v1.2.3-71-gd317 From a34e6d1e4a49035203819425694349caa004992a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 6 Mar 2021 15:11:21 +0900 Subject: kbuild: move $(strip ) to suffix-search definition Move $(strip ...) to the callee from the callers of suffix-search. It shortens the code slightly. Adding a space after a comma will not be a matter. I also dropped parentheses from single character variables. Signed-off-by: Masahiro Yamada --- scripts/Makefile.lib | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index bc611c11e28a..a4fbaf8880b9 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -45,16 +45,16 @@ obj-y := $(filter-out %/, $(obj-y)) endif # Expand $(foo-objs) $(foo-y) by calling $(call suffix-search,foo.o,-objs -y) -suffix-search = $(foreach s,$(2),$($(1:.o=$s))) +suffix-search = $(strip $(foreach s, $2, $($(1:.o=$s)))) # If $(foo-objs), $(foo-y), $(foo-m), or $(foo-) exists, foo.o is a composite object -multi-search = $(sort $(foreach m,$(1), $(if $(strip $(call suffix-search,$(m),$(2) -)), $(m)))) +multi-search = $(sort $(foreach m, $1, $(if $(call suffix-search, $m, $2 -), $m))) multi-obj-y := $(call multi-search,$(obj-y),-objs -y) multi-obj-m := $(call multi-search,$(obj-m),-objs -y -m) multi-obj-ym := $(multi-obj-y) $(multi-obj-m) # Replace multi-part objects by their individual parts, # including built-in.a from subdirectories -real-search = $(foreach m,$(1), $(if $(strip $(call suffix-search,$(m),$(2) -)),$(call suffix-search,$(m),$(2)),$(m))) +real-search = $(foreach m, $1, $(if $(call suffix-search, $m, $2 -), $(call suffix-search, $m, $2), $m)) real-obj-y := $(call real-search, $(obj-y),-objs -y) real-obj-m := $(call real-search, $(obj-m),-objs -y -m) -- cgit v1.2.3-71-gd317 From e24b3ffcf4216d819b52618b6f17ba7410d1d845 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 16 Mar 2021 01:12:55 +0900 Subject: kbuild: collect minimum tool versions into scripts/min-tool-version.sh The kernel build uses various tools, many of which are provided by the same software suite, for example, LLVM and Binutils. When you raise the minimum version of Clang/LLVM, you need to update clang_min_version in scripts/cc-version.sh and also lld_min_version in scripts/ld-version.sh. Kbuild can handle CC=clang and LD=ld.lld independently, but it does not make much sense to maintain their versions separately. Let's create a central place of minimum tool versions so you do not need to touch multiple files. scripts/min-tool-version.sh prints the minimum version of the given tool. Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor Acked-by: Miguel Ojeda Tested-by: Sedat Dilek --- scripts/cc-version.sh | 20 +++++--------------- scripts/ld-version.sh | 11 ++++------- scripts/min-tool-version.sh | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 22 deletions(-) create mode 100755 scripts/min-tool-version.sh (limited to 'scripts') diff --git a/scripts/cc-version.sh b/scripts/cc-version.sh index 3f2ee885b116..f1952c522466 100755 --- a/scripts/cc-version.sh +++ b/scripts/cc-version.sh @@ -6,18 +6,6 @@ set -e -# When you raise the minimum compiler version, please update -# Documentation/process/changes.rst as well. -gcc_min_version=4.9.0 -clang_min_version=10.0.1 -icc_min_version=16.0.3 # temporary - -# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63293 -# https://lore.kernel.org/r/20210107111841.GN1551@shell.armlinux.org.uk -if [ "$SRCARCH" = arm64 ]; then - gcc_min_version=5.1.0 -fi - # Print the compiler name and some version components. get_compiler_info() { @@ -48,18 +36,20 @@ set -- $(get_compiler_info "$@") name=$1 +min_tool_version=$(dirname $0)/min-tool-version.sh + case "$name" in GCC) version=$2.$3.$4 - min_version=$gcc_min_version + min_version=$($min_tool_version gcc) ;; Clang) version=$2.$3.$4 - min_version=$clang_min_version + min_version=$($min_tool_version llvm) ;; ICC) version=$(($2 / 100)).$(($2 % 100)).$3 - min_version=$icc_min_version + min_version=$($min_tool_version icc) ;; *) echo "$orig_args: unknown compiler" >&2 diff --git a/scripts/ld-version.sh b/scripts/ld-version.sh index 1bf3aadde9de..a78b804b680c 100755 --- a/scripts/ld-version.sh +++ b/scripts/ld-version.sh @@ -6,11 +6,6 @@ set -e -# When you raise the minimum linker version, please update -# Documentation/process/changes.rst as well. -bfd_min_version=2.23.0 -lld_min_version=10.0.1 - # Convert the version string x.y.z to a canonical 5 or 6-digit form. get_canonical_version() { @@ -35,10 +30,12 @@ set -- $(LC_ALL=C "$@" --version) IFS=' ' set -- $1 +min_tool_version=$(dirname $0)/min-tool-version.sh + if [ "$1" = GNU -a "$2" = ld ]; then shift $(($# - 1)) version=$1 - min_version=$bfd_min_version + min_version=$($min_tool_version binutils) name=BFD disp_name="GNU ld" elif [ "$1" = GNU -a "$2" = gold ]; then @@ -51,7 +48,7 @@ else if [ "$1" = LLD ]; then version=$2 - min_version=$lld_min_version + min_version=$($min_tool_version llvm) name=LLD disp_name=LLD else diff --git a/scripts/min-tool-version.sh b/scripts/min-tool-version.sh new file mode 100755 index 000000000000..d22cf91212b0 --- /dev/null +++ b/scripts/min-tool-version.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +# +# Print the minimum supported version of the given tool. +# When you raise the minimum version, please update +# Documentation/process/changes.rst as well. + +set -e + +if [ $# != 1 ]; then + echo "Usage: $0 toolname" >&2 + exit 1 +fi + +case "$1" in +binutils) + echo 2.23.0 + ;; +gcc) + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63293 + # https://lore.kernel.org/r/20210107111841.GN1551@shell.armlinux.org.uk + if [ "$SRCARCH" = arm64 ]; then + echo 5.1.0 + else + echo 4.9.0 + fi + ;; +icc) + # temporary + echo 16.0.3 + ;; +llvm) + echo 10.0.1 + ;; +*) + echo "$1: unknown tool" >&2 + exit 1 + ;; +esac -- cgit v1.2.3-71-gd317 From ba64beb17493a4bfec563100c86a462a15926f24 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 16 Mar 2021 01:12:56 +0900 Subject: kbuild: check the minimum assembler version in Kconfig Documentation/process/changes.rst defines the minimum assembler version (binutils version), but we have never checked it in the build time. Kbuild never invokes 'as' directly because all assembly files in the kernel tree are *.S, hence must be preprocessed. I do not expect raw assembly source files (*.s) would be added to the kernel tree. Therefore, we always use $(CC) as the assembler driver, and commit aa824e0c962b ("kbuild: remove AS variable") removed 'AS'. However, we are still interested in the version of the assembler acting behind. As usual, the --version option prints the version string. $ as --version | head -n 1 GNU assembler (GNU Binutils for Ubuntu) 2.35.1 But, we do not have $(AS). So, we can add the -Wa prefix so that $(CC) passes --version down to the backing assembler. $ gcc -Wa,--version | head -n 1 gcc: fatal error: no input files compilation terminated. OK, we need to input something to satisfy gcc. $ gcc -Wa,--version -c -x assembler /dev/null -o /dev/null | head -n 1 GNU assembler (GNU Binutils for Ubuntu) 2.35.1 The combination of Clang and GNU assembler works in the same way: $ clang -no-integrated-as -Wa,--version -c -x assembler /dev/null -o /dev/null | head -n 1 GNU assembler (GNU Binutils for Ubuntu) 2.35.1 Clang with the integrated assembler fails like this: $ clang -integrated-as -Wa,--version -c -x assembler /dev/null -o /dev/null | head -n 1 clang: error: unsupported argument '--version' to option 'Wa,' For the last case, checking the error message is fragile. If the proposal for -Wa,--version support [1] is accepted, this may not be even an error in the future. One easy way is to check if -integrated-as is present in the passed arguments. We did not pass -integrated-as to CLANG_FLAGS before, but we can make it explicit. Nathan pointed out -integrated-as is the default for all of the architectures/targets that the kernel cares about, but it goes along with "explicit is better than implicit" policy. [2] With all this in my mind, I implemented scripts/as-version.sh to check the assembler version in Kconfig time. $ scripts/as-version.sh gcc GNU 23501 $ scripts/as-version.sh clang -no-integrated-as GNU 23501 $ scripts/as-version.sh clang -integrated-as LLVM 0 [1]: https://github.com/ClangBuiltLinux/linux/issues/1320 [2]: https://lore.kernel.org/linux-kbuild/20210307044253.v3h47ucq6ng25iay@archlinux-ax161/ Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor --- Makefile | 4 ++- arch/Kconfig | 3 +- init/Kconfig | 12 ++++++++ scripts/Kconfig.include | 6 ++++ scripts/as-version.sh | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ scripts/dummy-tools/gcc | 6 ++++ 6 files changed, 110 insertions(+), 3 deletions(-) create mode 100755 scripts/as-version.sh (limited to 'scripts') diff --git a/Makefile b/Makefile index cc5b7e39fde4..2b161f5a5a66 100644 --- a/Makefile +++ b/Makefile @@ -580,7 +580,9 @@ ifneq ($(findstring clang,$(CC_VERSION_TEXT)),) ifneq ($(CROSS_COMPILE),) CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%)) endif -ifneq ($(LLVM_IAS),1) +ifeq ($(LLVM_IAS),1) +CLANG_FLAGS += -integrated-as +else CLANG_FLAGS += -no-integrated-as GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE)) diff --git a/arch/Kconfig b/arch/Kconfig index ecfd3520b676..555b4f09a9b2 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -631,8 +631,7 @@ config ARCH_SUPPORTS_LTO_CLANG_THIN config HAS_LTO_CLANG def_bool y # Clang >= 11: https://github.com/ClangBuiltLinux/linux/issues/510 - depends on CC_IS_CLANG && CLANG_VERSION >= 110000 && LD_IS_LLD - depends on $(success,test $(LLVM_IAS) -eq 1) + depends on CC_IS_CLANG && CLANG_VERSION >= 110000 && LD_IS_LLD && AS_IS_LLVM depends on $(success,$(NM) --help | head -n 1 | grep -qi llvm) depends on $(success,$(AR) --help | head -n 1 | grep -qi llvm) depends on ARCH_SUPPORTS_LTO_CLANG diff --git a/init/Kconfig b/init/Kconfig index 5f5c776ef192..019c1874e609 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -41,6 +41,18 @@ config CLANG_VERSION default $(cc-version) if CC_IS_CLANG default 0 +config AS_IS_GNU + def_bool $(success,test "$(as-name)" = GNU) + +config AS_IS_LLVM + def_bool $(success,test "$(as-name)" = LLVM) + +config AS_VERSION + int + # Use clang version if this is the integrated assembler + default CLANG_VERSION if AS_IS_LLVM + default $(as-version) + config LD_IS_BFD def_bool $(success,test "$(ld-name)" = BFD) diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include index 58fdb5308725..0496efd6e117 100644 --- a/scripts/Kconfig.include +++ b/scripts/Kconfig.include @@ -45,6 +45,12 @@ $(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this compiler is not su cc-name := $(shell,set -- $(cc-info) && echo $1) cc-version := $(shell,set -- $(cc-info) && echo $2) +# Get the assembler name, version, and error out if it is not supported. +as-info := $(shell,$(srctree)/scripts/as-version.sh $(CC) $(CLANG_FLAGS)) +$(error-if,$(success,test -z "$(as-info)"),Sorry$(comma) this assembler is not supported.) +as-name := $(shell,set -- $(as-info) && echo $1) +as-version := $(shell,set -- $(as-info) && echo $2) + # Get the linker name, version, and error out if it is not supported. ld-info := $(shell,$(srctree)/scripts/ld-version.sh $(LD)) $(error-if,$(success,test -z "$(ld-info)"),Sorry$(comma) this linker is not supported.) diff --git a/scripts/as-version.sh b/scripts/as-version.sh new file mode 100755 index 000000000000..8b9410e329df --- /dev/null +++ b/scripts/as-version.sh @@ -0,0 +1,82 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +# +# Print the assembler name and its version in a 5 or 6-digit form. +# Also, perform the minimum version check. +# (If it is the integrated assembler, return 0 as the version, and +# skip the version check.) + +set -e + +# Convert the version string x.y.z to a canonical 5 or 6-digit form. +get_canonical_version() +{ + IFS=. + set -- $1 + + # If the 2nd or 3rd field is missing, fill it with a zero. + # + # The 4th field, if present, is ignored. + # This occurs in development snapshots as in 2.35.1.20201116 + echo $((10000 * $1 + 100 * ${2:-0} + ${3:-0})) +} + +# Clang fails to handle -Wa,--version unless -no-integrated-as is given. +# We check -(f)integrated-as, expecting it is explicitly passed in for the +# integrated assembler case. +check_integrated_as() +{ + while [ $# -gt 0 ]; do + if [ "$1" = -integrated-as -o "$1" = -fintegrated-as ]; then + # For the intergrated assembler, we do not check the + # version here. It is the same as the clang version, and + # it has been already checked by scripts/cc-version.sh. + echo LLVM 0 + exit 0 + fi + shift + done +} + +check_integrated_as "$@" + +orig_args="$@" + +# Get the first line of the --version output. +IFS=' +' +set -- $(LC_ALL=C "$@" -Wa,--version -c -x assembler /dev/null -o /dev/null 2>/dev/null) + +# Split the line on spaces. +IFS=' ' +set -- $1 + +min_tool_version=$(dirname $0)/min-tool-version.sh + +if [ "$1" = GNU -a "$2" = assembler ]; then + shift $(($# - 1)) + version=$1 + min_version=$($min_tool_version binutils) + name=GNU +else + echo "$orig_args: unknown assembler invoked" >&2 + exit 1 +fi + +# Some distributions append a package release number, as in 2.34-4.fc32 +# Trim the hyphen and any characters that follow. +version=${version%-*} + +cversion=$(get_canonical_version $version) +min_cversion=$(get_canonical_version $min_version) + +if [ "$cversion" -lt "$min_cversion" ]; then + echo >&2 "***" + echo >&2 "*** Assembler is too old." + echo >&2 "*** Your $name assembler version: $version" + echo >&2 "*** Minimum $name assembler version: $min_version" + echo >&2 "***" + exit 1 +fi + +echo $name $cversion diff --git a/scripts/dummy-tools/gcc b/scripts/dummy-tools/gcc index 39e65fee59bd..f6d543725f1e 100755 --- a/scripts/dummy-tools/gcc +++ b/scripts/dummy-tools/gcc @@ -67,6 +67,12 @@ if arg_contain -E "$@"; then fi fi +# To set CONFIG_AS_IS_GNU +if arg_contain -Wa,--version "$@"; then + echo "GNU assembler (scripts/dummy-tools) 2.50" + exit 0 +fi + if arg_contain -S "$@"; then # For scripts/gcc-x86-*-has-stack-protector.sh if arg_contain -fstack-protector "$@"; then -- cgit v1.2.3-71-gd317 From 2e98815794fb51250da4528f67fc2f699d5e3c37 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 16 Mar 2021 01:12:57 +0900 Subject: kbuild: dwarf: use AS_VERSION instead of test_dwarf5_support.sh The test code in scripts/test_dwarf5_support.sh is somewhat difficult to understand, but after all, we want to check binutils >= 2.35.2 From the former discussion, the requirement for generating DWARF v5 from C code is as follows: - gcc + gnu as -> requires gcc 5.0+ (but 7.0+ for full support) - clang + gnu as -> requires binutils 2.35.2+ - clang + integrated as -> OK Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor Reviewed-by: Nick Desaulniers --- lib/Kconfig.debug | 3 +-- scripts/test_dwarf5_support.sh | 8 -------- 2 files changed, 1 insertion(+), 10 deletions(-) delete mode 100755 scripts/test_dwarf5_support.sh (limited to 'scripts') diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index b479ae609a31..c85d5f7a1aeb 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -284,8 +284,7 @@ config DEBUG_INFO_DWARF4 config DEBUG_INFO_DWARF5 bool "Generate DWARF Version 5 debuginfo" - depends on GCC_VERSION >= 50000 || CC_IS_CLANG - depends on CC_IS_GCC || $(success,$(srctree)/scripts/test_dwarf5_support.sh $(CC) $(CLANG_FLAGS)) + depends on GCC_VERSION >= 50000 || (CC_IS_CLANG && (AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502))) depends on !DEBUG_INFO_BTF help Generate DWARF v5 debug info. Requires binutils 2.35.2, gcc 5.0+ (gcc diff --git a/scripts/test_dwarf5_support.sh b/scripts/test_dwarf5_support.sh deleted file mode 100755 index c46e2456b47a..000000000000 --- a/scripts/test_dwarf5_support.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 - -# Test that the assembler doesn't need -Wa,-gdwarf-5 when presented with DWARF -# v5 input, such as `.file 0` and `md5 0x00`. Should be fixed in GNU binutils -# 2.35.2. https://sourceware.org/bugzilla/show_bug.cgi?id=25611 -echo '.file 0 "filename" md5 0x7a0b65214090b6693bd1dc24dd248245' | \ - $* -gdwarf-5 -Wno-unused-command-line-argument -c -x assembler -o /dev/null - -- cgit v1.2.3-71-gd317 From 69bc8d386aebbd91a6bb44b6d33f77c8dfa9ed8c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 26 Mar 2021 03:54:09 +0900 Subject: kbuild: generate Module.symvers only when vmlinux exists The external module build shows the following warning if Module.symvers is missing in the kernel tree. WARNING: Symbol version dump "Module.symvers" is missing. Modules may not have dependencies or modversions. I think this is an important heads-up because the resulting modules may not work as expected. This happens when you did not build the entire kernel tree, for example, you might have prepared the minimal setups for external modules by 'make defconfig && make modules_preapre'. A problem is that 'make modules' creates Module.symvers even without vmlinux. In this case, that warning is suppressed since Module.symvers already exists in spite of its incomplete content. The incomplete (i.e. invalid) Module.symvers should not be created. This commit changes the second pass of modpost to dump symbols into modules-only.symvers. The final Module.symvers is created by concatenating vmlinux.symvers and modules-only.symvers if both exist. Module.symvers is supposed to collect symbols from both vmlinux and modules. It might be a bit confusing, and I am not quite sure if it is an official interface, but presumably it is difficult to rename it because some tools (e.g. kmod) parse it. Signed-off-by: Masahiro Yamada --- .gitignore | 1 + Documentation/dontdiff | 1 + Makefile | 2 +- scripts/Makefile.modpost | 15 ++++++++++++++- scripts/mod/modpost.c | 15 +-------------- 5 files changed, 18 insertions(+), 16 deletions(-) (limited to 'scripts') diff --git a/.gitignore b/.gitignore index 3adea59847ce..df8d3146a43f 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ modules.order /tags /TAGS /linux +/modules-only.symvers /vmlinux /vmlinux.32 /vmlinux.map diff --git a/Documentation/dontdiff b/Documentation/dontdiff index ac42ad8d430d..910b30a2a7d9 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff @@ -178,6 +178,7 @@ mktables mktree mkutf8data modpost +modules-only.symvers modules.builtin modules.builtin.modinfo modules.nsdeps diff --git a/Makefile b/Makefile index 2b161f5a5a66..ed8bd815e8a3 100644 --- a/Makefile +++ b/Makefile @@ -1532,7 +1532,7 @@ endif # CONFIG_MODULES # make distclean Remove editor backup files, patch leftover files and the like # Directories & files removed with 'make clean' -CLEAN_FILES += include/ksym vmlinux.symvers \ +CLEAN_FILES += include/ksym vmlinux.symvers modules-only.symvers \ modules.builtin modules.builtin.modinfo modules.nsdeps \ compile_commands.json .thinlto-cache diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index df57e259fac3..3f5b09a09aef 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -68,7 +68,20 @@ else ifeq ($(KBUILD_EXTMOD),) input-symdump := vmlinux.symvers -output-symdump := Module.symvers +output-symdump := modules-only.symvers + +quiet_cmd_cat = GEN $@ + cmd_cat = cat $(real-prereqs) > $@ + +ifneq ($(wildcard vmlinux.symvers),) + +__modpost: Module.symvers +Module.symvers: vmlinux.symvers modules-only.symvers FORCE + $(call if_changed,cat) + +targets += Module.symvers + +endif else diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 24725e50c7b4..10c3fba26f03 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2423,19 +2423,6 @@ fail: fatal("parse error in symbol dump file\n"); } -/* For normal builds always dump all symbols. - * For external modules only dump symbols - * that are not read from kernel Module.symvers. - **/ -static int dump_sym(struct symbol *sym) -{ - if (!external_module) - return 1; - if (sym->module->from_dump) - return 0; - return 1; -} - static void write_dump(const char *fname) { struct buffer buf = { }; @@ -2446,7 +2433,7 @@ static void write_dump(const char *fname) for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { symbol = symbolhash[n]; while (symbol) { - if (dump_sym(symbol)) { + if (!symbol->module->from_dump) { namespace = symbol->namespace; buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n", symbol->crc, symbol->name, -- cgit v1.2.3-71-gd317 From 5ab70ff4286f74732c082b65366bad39146d2b10 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 26 Mar 2021 03:54:10 +0900 Subject: kbuild: do not set -w for vmlinux.o modpost The -w option is meaningless for the first pass of modpost (vmlinux.o). We know there are unresolved symbols in vmlinux.o, hence we skip check_exports() and other checks when mod->is_vmlinux is set. See the following part in the for-loop. if (mod->is_vmlinux || mod->from_dump) continue; Signed-off-by: Masahiro Yamada --- scripts/Makefile.modpost | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 3f5b09a09aef..b3e08fb1fd56 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -32,8 +32,6 @@ # Step 4 is solely used to allow module versioning in external modules, # where the CRC of each module is retrieved from the Module.symvers file. -# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined -# symbols in the final module linking stage # KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. # This is solely useful to speed up test compiles @@ -50,7 +48,6 @@ MODPOST = scripts/mod/modpost \ $(if $(CONFIG_MODVERSIONS),-m) \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \ $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ - $(if $(KBUILD_MODPOST_WARN),-w) \ -o $@ ifdef MODPOST_VMLINUX @@ -136,6 +133,11 @@ endif modules := $(sort $(shell cat $(MODORDER))) +# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined symbols +ifneq ($(KBUILD_MODPOST_WARN),) +MODPOST += -w +endif + # Read out modules.order to pass in modpost. # Otherwise, allmodconfig would fail with "Argument list too long". quiet_cmd_modpost = MODPOST $@ -- cgit v1.2.3-71-gd317 From 4475dff55c54d855ef0179a055b3ce20a9c1ab3e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 26 Mar 2021 03:54:11 +0900 Subject: kbuild: fix false-positive modpost warning when all symbols are trimmed Nathan reports that the mips defconfig emits the following warning: WARNING: modpost: Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped. This false-positive happens when CONFIG_TRIM_UNUSED_KSYMS is enabled, but no CONFIG option is set to 'm'. Commit a0590473c5e6 ("nfs: fix PNFS_FLEXFILE_LAYOUT Kconfig default") turned the last 'm' into 'y' for the mips defconfig, and uncovered this issue. In this case, the module feature itself is enabled, but we have no module to build. As a result, CONFIG_TRIM_UNUSED_KSYMS drops all the instances of EXPORT_SYMBOL. Then, modpost wrongly assumes vmlinux is missing because vmlinux.symvers is empty. (As another false-positive case, you can create a module that does not use any symbol of vmlinux). The current behavior is to entirely suppress the unresolved symbol warnings when vmlinux is missing just because there are too many. I found the origin of this code in the historical git tree. [1] If this is a matter of noisiness, I think modpost can display the first 10 warnings, and the number of suppressed warnings at the end. You will get a bit noisier logs when you run 'make modules' without vmlinux, but such warnings are better to show because you never know the resulting modules are actually loadable or not. This commit changes the following: - If any of input *.symver files is missing, pass -w option to let the module build keep going with warnings instead of errors. - If there are too many (10+) unresolved symbol warnings, show only the first 10, and also the number of suppressed warnings. [1]: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=1cc0e0529569bf6a94f6d49770aa6d4b599d2c46 Reported-by: Nathan Chancellor Signed-off-by: Masahiro Yamada --- scripts/Makefile.modpost | 7 +++++-- scripts/mod/modpost.c | 25 ++++++++++++------------- 2 files changed, 17 insertions(+), 15 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index b3e08fb1fd56..c383ba33d837 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -98,9 +98,11 @@ output-symdump := $(KBUILD_EXTMOD)/Module.symvers endif +existing-input-symdump := $(wildcard $(input-symdump)) + # modpost options for modules (both in-kernel and external) MODPOST += \ - $(addprefix -i ,$(wildcard $(input-symdump))) \ + $(addprefix -i ,$(existing-input-symdump)) \ $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \ $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) @@ -114,6 +116,7 @@ VPATH := $(input-symdump): @echo >&2 'WARNING: Symbol version dump "$@" is missing.' @echo >&2 ' Modules may not have dependencies or modversions.' + @echo >&2 ' You may get many unresolved symbol warnings.' ifdef CONFIG_LTO_CLANG # With CONFIG_LTO_CLANG, .o files might be LLVM bitcode, so we need to run @@ -134,7 +137,7 @@ endif modules := $(sort $(shell cat $(MODORDER))) # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined symbols -ifneq ($(KBUILD_MODPOST_WARN),) +ifneq ($(KBUILD_MODPOST_WARN)$(filter-out $(existing-input-symdump), $(input-symdump)),) MODPOST += -w endif diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 10c3fba26f03..7c6bec78fa34 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -23,8 +23,6 @@ /* Are we using CONFIG_MODVERSIONS? */ static int modversions = 0; -/* Warn about undefined symbols? (do so if we have vmlinux) */ -static int have_vmlinux = 0; /* Is CONFIG_MODULE_SRCVERSION_ALL set? */ static int all_versions = 0; /* If we are modposting external module set to 1 */ @@ -41,6 +39,13 @@ static int allow_missing_ns_imports; static bool error_occurred; +/* + * Cut off the warnings when there are too many. This typically occurs when + * vmlinux is missing. ('make modules' without building vmlinux.) + */ +#define MAX_UNRESOLVED_REPORTS 10 +static unsigned int nr_unresolved; + enum export { export_plain, export_gpl, @@ -177,9 +182,6 @@ static struct module *new_module(const char *modname) mod->next = modules; modules = mod; - if (mod->is_vmlinux) - have_vmlinux = 1; - return mod; } @@ -2141,7 +2143,7 @@ static void check_exports(struct module *mod) const char *basename; exp = find_symbol(s->name); if (!exp || exp->module == mod) { - if (have_vmlinux && !s->weak) + if (!s->weak && nr_unresolved++ < MAX_UNRESOLVED_REPORTS) modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR, "\"%s\" [%s.ko] undefined!\n", s->name, mod->name); @@ -2545,13 +2547,6 @@ int main(int argc, char **argv) if (files_source) read_symbols_from_files(files_source); - /* - * When there's no vmlinux, don't print warnings about - * unresolved symbols (since there'll be too many ;) - */ - if (!have_vmlinux) - warn("Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.\n"); - for (mod = modules; mod; mod = mod->next) { char fname[PATH_MAX]; @@ -2595,6 +2590,10 @@ int main(int argc, char **argv) } } + if (nr_unresolved > MAX_UNRESOLVED_REPORTS) + warn("suppressed %u unresolved symbol warnings because there were too many)\n", + nr_unresolved - MAX_UNRESOLVED_REPORTS); + free(buf.p); return error_occurred ? 1 : 0; -- cgit v1.2.3-71-gd317 From f3945833e436d79d9a97e776c4986af8c9cbb483 Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Fri, 26 Mar 2021 11:22:19 +0530 Subject: scripts: modpost.c: Fix a few typos s/agorithm/algorithm/ s/criterias/criteria/ s/targetting/targeting/ ....two different places. Signed-off-by: Bhaskar Chowdhury Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 7c6bec78fa34..20aab6960559 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -204,7 +204,7 @@ struct symbol { static struct symbol *symbolhash[SYMBOL_HASH_SIZE]; -/* This is based on the hash agorithm from gdbm, via tdb */ +/* This is based on the hash algorithm from gdbm, via tdb */ static inline unsigned int tdb_hash(const char *name) { unsigned value; /* Used to compute the hash value. */ @@ -987,7 +987,7 @@ enum mismatch { }; /** - * Describe how to match sections on different criterias: + * Describe how to match sections on different criteria: * * @fromsec: Array of sections to be matched. * @@ -995,12 +995,12 @@ enum mismatch { * this array is forbidden (black-list). Can be empty. * * @good_tosec: Relocations applied to a section in @fromsec must be - * targetting sections in this array (white-list). Can be empty. + * targeting sections in this array (white-list). Can be empty. * * @mismatch: Type of mismatch. * * @symbol_white_list: Do not match a relocation to a symbol in this list - * even if it is targetting a section in @bad_to_sec. + * even if it is targeting a section in @bad_to_sec. * * @handler: Specific handler to call when a match is found. If NULL, * default_mismatch_handler() will be called. -- cgit v1.2.3-71-gd317 From 1a998be620a10000c1e1240026e4bd6bc3378c96 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 31 Mar 2021 22:38:05 +0900 Subject: kbuild: check module name conflict for external modules as well If there are multiple modules with the same name in the same external module tree, there is ambiguity about which one will be loaded, and very likely something odd is happening. Signed-off-by: Masahiro Yamada --- Makefile | 10 +++++----- scripts/modules-check.sh | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index a6f73335757d..b5ff4753eba8 100644 --- a/Makefile +++ b/Makefile @@ -1459,10 +1459,6 @@ endif PHONY += modules modules: $(if $(KBUILD_BUILTIN),vmlinux) modules_check modules_prepare -PHONY += modules_check -modules_check: modules.order - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/modules-check.sh $< - cmd_modules_order = $(AWK) '!x[$$0]++' $(real-prereqs) > $@ modules.order: $(subdir-modorder) FORCE @@ -1775,9 +1771,13 @@ PHONY += modules modules_install ifdef CONFIG_MODULES -modules: $(MODORDER) +modules: modules_check $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost +PHONY += modules_check +modules_check: $(MODORDER) + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/modules-check.sh $< + quiet_cmd_depmod = DEPMOD $(MODLIB) cmd_depmod = $(CONFIG_SHELL) $(srctree)/scripts/depmod.sh $(DEPMOD) \ $(KERNELRELEASE) diff --git a/scripts/modules-check.sh b/scripts/modules-check.sh index 43de226071ae..e06327722263 100755 --- a/scripts/modules-check.sh +++ b/scripts/modules-check.sh @@ -13,10 +13,10 @@ exit_code=0 # Check uniqueness of module names check_same_name_modules() { - for m in $(sed 's:.*/::' $1 | sort | uniq -d) + for m in $(sed 's:.*/::' "$1" | sort | uniq -d) do echo "error: the following would cause module name conflict:" >&2 - sed -n "/\/$m/s:^: :p" modules.order >&2 + sed -n "/\/$m/s:^: :p" "$1" >&2 exit_code=1 done } -- cgit v1.2.3-71-gd317 From ccae4cfa7bfbec323abc399228e0ada7c377b16b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 31 Mar 2021 22:38:07 +0900 Subject: kbuild: refactor scripts/Makefile.modinst scripts/Makefile.modinst is ugly and weird in multiple ways; it specifies real files $(modules) as phony, makes directory manipulation needlessly too complicated. Clean up the Makefile code, and show the full path of installed modules in the log. Signed-off-by: Masahiro Yamada --- Makefile | 2 +- scripts/Makefile.modinst | 40 ++++++++++++++++++++++------------------ 2 files changed, 23 insertions(+), 19 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index e3c2bd1b6f42..88e5c15e1186 100644 --- a/Makefile +++ b/Makefile @@ -1141,7 +1141,7 @@ endif # CONFIG_BPF PHONY += prepare0 -extmod_prefix = $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/) +export extmod_prefix = $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/) export MODORDER := $(extmod_prefix)modules.order export MODULES_NSDEPS := $(extmod_prefix)modules.nsdeps diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index ad1981233d0b..8e9debb781d1 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -8,28 +8,32 @@ __modinst: include $(srctree)/scripts/Kbuild.include -modules := $(sort $(shell cat $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/)modules.order)) +modules := $(sort $(shell cat $(MODORDER))) + +ifeq ($(KBUILD_EXTMOD),) +dst := $(MODLIB)/kernel +else +INSTALL_MOD_DIR ?= extra +dst := $(MODLIB)/$(INSTALL_MOD_DIR) +endif + +modules := $(patsubst $(extmod_prefix)%, $(dst)/%, $(modules)) -PHONY += $(modules) __modinst: $(modules) @: # Don't stop modules_install if we can't sign external modules. -quiet_cmd_modules_install = INSTALL $@ - cmd_modules_install = \ - mkdir -p $(2) ; \ - cp $@ $(2) ; \ - $(mod_strip_cmd) $(2)/$(notdir $@) ; \ - $(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD)) ; \ - $(mod_compress_cmd) $(2)/$(notdir $@) - -# Modules built outside the kernel source tree go into extra by default -INSTALL_MOD_DIR ?= extra -ext-mod-dir = $(INSTALL_MOD_DIR)$(subst $(patsubst %/,%,$(KBUILD_EXTMOD)),,$(@D)) - -modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D)) - -$(modules): - $(call cmd,modules_install,$(MODLIB)/$(modinst_dir)) +quiet_cmd_install = INSTALL $@ + cmd_install = \ + mkdir -p $(dir $@); cp $< $@; \ + $(mod_strip_cmd) $@; \ + $(mod_sign_cmd) $@ $(patsubst %,|| true,$(KBUILD_EXTMOD)) ; \ + $(mod_compress_cmd) $@ + +$(modules): $(dst)/%: $(extmod_prefix)% FORCE + $(call cmd,install) + +PHONY += FORCE +FORCE: .PHONY: $(PHONY) -- cgit v1.2.3-71-gd317 From 65ce9c38326e2588fcd1a3a4817c14b4660f430b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 31 Mar 2021 22:38:08 +0900 Subject: kbuild: move module strip/compression code into scripts/Makefile.modinst Both mod_strip_cmd and mod_compress_cmd are only used in scripts/Makefile.modinst, hence there is no good reason to define them in the top Makefile. Move the relevant code to scripts/Makefile.modinst. Also, show separate log messages for each of install, strip, sign, and compress. Signed-off-by: Masahiro Yamada --- Makefile | 32 -------------------- scripts/Makefile.modinst | 76 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 68 insertions(+), 40 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 88e5c15e1186..f96ae09d111b 100644 --- a/Makefile +++ b/Makefile @@ -1063,38 +1063,6 @@ export INSTALL_DTBS_PATH ?= $(INSTALL_PATH)/dtbs/$(KERNELRELEASE) MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) export MODLIB -# -# INSTALL_MOD_STRIP, if defined, will cause modules to be -# stripped after they are installed. If INSTALL_MOD_STRIP is '1', then -# the default option --strip-debug will be used. Otherwise, -# INSTALL_MOD_STRIP value will be used as the options to the strip command. - -ifdef INSTALL_MOD_STRIP -ifeq ($(INSTALL_MOD_STRIP),1) -mod_strip_cmd = $(STRIP) --strip-debug -else -mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP) -endif # INSTALL_MOD_STRIP=1 -else -mod_strip_cmd = true -endif # INSTALL_MOD_STRIP -export mod_strip_cmd - -# CONFIG_MODULE_COMPRESS, if defined, will cause module to be compressed -# after they are installed in agreement with CONFIG_MODULE_COMPRESS_GZIP -# or CONFIG_MODULE_COMPRESS_XZ. - -mod_compress_cmd = true -ifdef CONFIG_MODULE_COMPRESS - ifdef CONFIG_MODULE_COMPRESS_GZIP - mod_compress_cmd = $(KGZIP) -n -f - endif # CONFIG_MODULE_COMPRESS_GZIP - ifdef CONFIG_MODULE_COMPRESS_XZ - mod_compress_cmd = $(XZ) --lzma2=dict=2MiB -f - endif # CONFIG_MODULE_COMPRESS_XZ -endif # CONFIG_MODULE_COMPRESS -export mod_compress_cmd - ifdef CONFIG_MODULE_SIG_ALL $(eval $(call config_filename,MODULE_SIG_KEY)) diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 8e9debb781d1..84696ef99df7 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -6,6 +6,7 @@ PHONY := __modinst __modinst: +include include/config/auto.conf include $(srctree)/scripts/Kbuild.include modules := $(sort $(shell cat $(MODORDER))) @@ -17,21 +18,80 @@ INSTALL_MOD_DIR ?= extra dst := $(MODLIB)/$(INSTALL_MOD_DIR) endif -modules := $(patsubst $(extmod_prefix)%, $(dst)/%, $(modules)) +suffix-y := +suffix-$(CONFIG_MODULE_COMPRESS_GZIP) := .gz +suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz + +modules := $(patsubst $(extmod_prefix)%, $(dst)/%$(suffix-y), $(modules)) __modinst: $(modules) @: -# Don't stop modules_install if we can't sign external modules. +quiet_cmd_none = + cmd_none = : + +# +# Installation +# quiet_cmd_install = INSTALL $@ - cmd_install = \ - mkdir -p $(dir $@); cp $< $@; \ - $(mod_strip_cmd) $@; \ - $(mod_sign_cmd) $@ $(patsubst %,|| true,$(KBUILD_EXTMOD)) ; \ - $(mod_compress_cmd) $@ + cmd_install = mkdir -p $(dir $@); cp $< $@ + +# Strip +# +# INSTALL_MOD_STRIP, if defined, will cause modules to be stripped after they +# are installed. If INSTALL_MOD_STRIP is '1', then the default option +# --strip-debug will be used. Otherwise, INSTALL_MOD_STRIP value will be used +# as the options to the strip command. +ifdef INSTALL_MOD_STRIP + +ifeq ($(INSTALL_MOD_STRIP),1) +strip-option := --strip-debug +else +strip-option := $(INSTALL_MOD_STRIP) +endif + +quiet_cmd_strip = STRIP $@ + cmd_strip = $(STRIP) $(strip-option) $@ + +else -$(modules): $(dst)/%: $(extmod_prefix)% FORCE +quiet_cmd_strip = + cmd_strip = : + +endif + +# +# Signing +# Don't stop modules_install even if we can't sign external modules. +# +ifeq ($(CONFIG_MODULE_SIG_ALL),y) +quiet_cmd_sign = SIGN $@ +$(eval $(call config_filename,MODULE_SIG_KEY)) + cmd_sign = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODULE_SIG_KEY_SRCPREFIX)$(CONFIG_MODULE_SIG_KEY) certs/signing_key.x509 $@ \ + $(if $(KBUILD_EXTMOD),|| true) +else +quiet_cmd_sign := + cmd_sign := : +endif + +$(dst)/%.ko: $(extmod_prefix)%.ko FORCE $(call cmd,install) + $(call cmd,strip) + $(call cmd,sign) + +# +# Compression +# +quiet_cmd_gzip = GZIP $@ + cmd_gzip = $(KGZIP) -n -f $< +quiet_cmd_xz = XZ $@ + cmd_xz = $(XZ) --lzma2=dict=2MiB -f $< + +$(dst)/%.ko.gz: $(dst)/%.ko FORCE + $(call cmd,gzip) + +$(dst)/%.ko.xz: $(dst)/%.ko FORCE + $(call cmd,xz) PHONY += FORCE FORCE: -- cgit v1.2.3-71-gd317 From 961ab4a3cd66c285951cf4c8ec10bc8d9a4b0232 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 31 Mar 2021 22:38:09 +0900 Subject: kbuild: merge scripts/Makefile.modsign to scripts/Makefile.modinst scripts/Makefile.modsign is a subset of scripts/Makefile.modinst, and duplicates the code. Let's merge them. By the way, you do not need to run 'make modules_sign' explicitly because modules are signed as a part of 'make modules_install' when CONFIG_MODULE_SIG_ALL=y. If CONFIG_MODULE_SIG_ALL=n, mod_sign_cmd is set to 'true', so 'make modules_sign' is not functional. In my understanding, the reason of still keeping this is to handle corner cases like commit 64178cb62c32 ("builddeb: fix stripped module signatures if CONFIG_DEBUG_INFO and CONFIG_MODULE_SIG_ALL are set"). Signed-off-by: Masahiro Yamada --- Makefile | 36 ++++++++++++++++++++---------------- scripts/Makefile.modinst | 9 +++++++++ scripts/Makefile.modsign | 29 ----------------------------- 3 files changed, 29 insertions(+), 45 deletions(-) delete mode 100644 scripts/Makefile.modsign (limited to 'scripts') diff --git a/Makefile b/Makefile index f96ae09d111b..b14483742a67 100644 --- a/Makefile +++ b/Makefile @@ -1063,15 +1063,6 @@ export INSTALL_DTBS_PATH ?= $(INSTALL_PATH)/dtbs/$(KERNELRELEASE) MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) export MODLIB -ifdef CONFIG_MODULE_SIG_ALL -$(eval $(call config_filename,MODULE_SIG_KEY)) - -mod_sign_cmd = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODULE_SIG_KEY_SRCPREFIX)$(CONFIG_MODULE_SIG_KEY) certs/signing_key.x509 -else -mod_sign_cmd = true -endif -export mod_sign_cmd - HOST_LIBELF_LIBS = $(shell pkg-config libelf --libs 2>/dev/null || echo -lelf) has_libelf = $(call try-run,\ @@ -1439,7 +1430,26 @@ PHONY += modules_prepare modules_prepare: prepare $(Q)$(MAKE) $(build)=scripts scripts/module.lds -modules_install: __modinst_pre +export modules_sign_only := + +ifeq ($(CONFIG_MODULE_SIG),y) +PHONY += modules_sign +modules_sign: modules_install + @: + +# modules_sign is a subset of modules_install. +# 'make modules_install modules_sign' is equivalent to 'make modules_install'. +ifeq ($(filter modules_install,$(MAKECMDGOALS)),) +modules_sign_only := y +endif +endif + +modinst_pre := +ifneq ($(filter modules_install,$(MAKECMDGOALS)),) +modinst_pre := __modinst_pre +endif + +modules_install: $(modinst_pre) PHONY += __modinst_pre __modinst_pre: @rm -rf $(MODLIB)/kernel @@ -1454,12 +1464,6 @@ __modinst_pre: @cp -f modules.builtin $(MODLIB)/ @cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/ -ifeq ($(CONFIG_MODULE_SIG), y) -PHONY += modules_sign -modules_sign: - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modsign -endif - endif # CONFIG_MODULES ### diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 84696ef99df7..191408f7a91a 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -74,11 +74,20 @@ quiet_cmd_sign := cmd_sign := : endif +ifeq ($(modules_sign_only),) + $(dst)/%.ko: $(extmod_prefix)%.ko FORCE $(call cmd,install) $(call cmd,strip) $(call cmd,sign) +else + +$(dst)/%.ko: FORCE + $(call cmd,sign) + +endif + # # Compression # diff --git a/scripts/Makefile.modsign b/scripts/Makefile.modsign deleted file mode 100644 index ddf9b5ca77d7..000000000000 --- a/scripts/Makefile.modsign +++ /dev/null @@ -1,29 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# ========================================================================== -# Signing modules -# ========================================================================== - -PHONY := __modsign -__modsign: - -include $(srctree)/scripts/Kbuild.include - -modules := $(sort $(shell cat modules.order)) - -PHONY += $(modules) -__modsign: $(modules) - @: - -quiet_cmd_sign_ko = SIGN [M] $(2)/$(notdir $@) - cmd_sign_ko = $(mod_sign_cmd) $(2)/$(notdir $@) - -# Modules built outside the kernel source tree go into extra by default -INSTALL_MOD_DIR ?= extra -ext-mod-dir = $(INSTALL_MOD_DIR)$(subst $(patsubst %/,%,$(KBUILD_EXTMOD)),,$(@D)) - -modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D)) - -$(modules): - $(call cmd,sign_ko,$(MODLIB)/$(modinst_dir)) - -.PHONY: $(PHONY) -- cgit v1.2.3-71-gd317 From c3d7ef377eb2564b165b1e8fdb4646952c90ac17 Mon Sep 17 00:00:00 2001 From: Piotr Gorski Date: Wed, 7 Apr 2021 18:09:27 +0200 Subject: kbuild: add support for zstd compressed modules kmod 28 supports modules compressed in zstd format so let's add this possibility to kernel. Signed-off-by: Piotr Gorski Reviewed-by: Oleksandr Natalenko Signed-off-by: Masahiro Yamada --- init/Kconfig | 8 +++++++- scripts/Makefile.modinst | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/init/Kconfig b/init/Kconfig index 510f6fcd9b7f..b5744d32c4df 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2242,7 +2242,7 @@ choice Please note that the tool used to load modules needs to support the corresponding algorithm. module-init-tools MAY support gzip, and kmod - MAY support gzip and xz. + MAY support gzip, xz and zstd. Your build system needs to provide the appropriate compression tool to compress the modules. @@ -2267,6 +2267,12 @@ config MODULE_COMPRESS_XZ Compress modules with XZ. The installed modules are suffixed with .ko.xz. +config MODULE_COMPRESS_ZSTD + bool "ZSTD" + help + Compress modules with ZSTD. The installed modules are suffixed + with .ko.zst. + endchoice config MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 191408f7a91a..ff9b09e4cfca 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -21,6 +21,7 @@ endif suffix-y := suffix-$(CONFIG_MODULE_COMPRESS_GZIP) := .gz suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz +suffix-$(CONFIG_MODULE_COMPRESS_ZSTD) := .zst modules := $(patsubst $(extmod_prefix)%, $(dst)/%$(suffix-y), $(modules)) @@ -95,6 +96,8 @@ quiet_cmd_gzip = GZIP $@ cmd_gzip = $(KGZIP) -n -f $< quiet_cmd_xz = XZ $@ cmd_xz = $(XZ) --lzma2=dict=2MiB -f $< +quiet_cmd_zstd = ZSTD $@ + cmd_zstd = $(ZSTD) -T0 --rm -f -q $< $(dst)/%.ko.gz: $(dst)/%.ko FORCE $(call cmd,gzip) @@ -102,6 +105,9 @@ $(dst)/%.ko.gz: $(dst)/%.ko FORCE $(dst)/%.ko.xz: $(dst)/%.ko FORCE $(call cmd,xz) +$(dst)/%.ko.zst: $(dst)/%.ko FORCE + $(call cmd,zstd) + PHONY += FORCE FORCE: -- cgit v1.2.3-71-gd317 From 1fdd7433a98a2f5511f49ad3f3b82bdd6f77265c Mon Sep 17 00:00:00 2001 From: Yonghong Song Date: Thu, 1 Apr 2021 16:27:23 -0700 Subject: kbuild: add an elfnote for whether vmlinux is built with lto Currently, clang LTO built vmlinux won't work with pahole. LTO introduced cross-cu dwarf tag references and broke current pahole model which handles one cu as a time. The solution is to merge all cu's as one pahole cu as in [1]. We would like to do this merging only if cross-cu dwarf references happens. The LTO build mode is a pretty good indication for that. In earlier version of this patch ([2]), clang flag -grecord-gcc-switches is proposed to add to compilation flags so pahole could detect "-flto" and then merging cu's. This will increate the binary size of 1% without LTO though. Arnaldo suggested to use a note to indicate the vmlinux is built with LTO. Such a cheap way to get whether the vmlinux is built with LTO or not helps pahole but is also useful for tracing as LTO may inline/delete/demote global functions, promote static functions, etc. So this patch added an elfnote with a new type LINUX_ELFNOTE_LTO_INFO. The owner of the note is "Linux". With gcc 8.4.1 and clang trunk, without LTO, I got $ readelf -n vmlinux Displaying notes found in: .notes Owner Data size Description ... Linux 0x00000004 func description data: 00 00 00 00 ... With "readelf -x ".notes" vmlinux", I can verify the above "func" with type code 0x101. With clang thin-LTO, I got the same as above except the following: description data: 01 00 00 00 which indicates the vmlinux is built with LTO. [1] https://lore.kernel.org/bpf/20210325065316.3121287-1-yhs@fb.com/ [2] https://lore.kernel.org/bpf/20210331001623.2778934-1-yhs@fb.com/ Suggested-by: Arnaldo Carvalho de Melo Signed-off-by: Yonghong Song Reviewed-by: Nick Desaulniers Tested-by: Sedat Dilek # LLVM/Clang v12.0.0-rc4 (x86-64) Tested-by: Arnaldo Carvalho de Melo Signed-off-by: Masahiro Yamada --- include/linux/elfnote-lto.h | 14 ++++++++++++++ init/version.c | 2 ++ scripts/mod/modpost.c | 2 ++ 3 files changed, 18 insertions(+) create mode 100644 include/linux/elfnote-lto.h (limited to 'scripts') diff --git a/include/linux/elfnote-lto.h b/include/linux/elfnote-lto.h new file mode 100644 index 000000000000..d4635a3ecc4f --- /dev/null +++ b/include/linux/elfnote-lto.h @@ -0,0 +1,14 @@ +#ifndef __ELFNOTE_LTO_H +#define __ELFNOTE_LTO_H + +#include + +#define LINUX_ELFNOTE_LTO_INFO 0x101 + +#ifdef CONFIG_LTO +#define BUILD_LTO_INFO ELFNOTE32("Linux", LINUX_ELFNOTE_LTO_INFO, 1) +#else +#define BUILD_LTO_INFO ELFNOTE32("Linux", LINUX_ELFNOTE_LTO_INFO, 0) +#endif + +#endif /* __ELFNOTE_LTO_H */ diff --git a/init/version.c b/init/version.c index 92afc782b043..1a356f5493e8 100644 --- a/init/version.c +++ b/init/version.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -45,3 +46,4 @@ const char linux_proc_banner[] = " (" LINUX_COMPILER ") %s\n"; BUILD_SALT; +BUILD_LTO_INFO; diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 20aab6960559..3e623ccc020b 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2193,10 +2193,12 @@ static void add_header(struct buffer *b, struct module *mod) */ buf_printf(b, "#define INCLUDE_VERMAGIC\n"); buf_printf(b, "#include \n"); + buf_printf(b, "#include \n"); buf_printf(b, "#include \n"); buf_printf(b, "#include \n"); buf_printf(b, "\n"); buf_printf(b, "BUILD_SALT;\n"); + buf_printf(b, "BUILD_LTO_INFO;\n"); buf_printf(b, "\n"); buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n"); -- cgit v1.2.3-71-gd317 From e3456056f1d935491ee9148dbae98c6b95f58910 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 15 Apr 2021 16:26:59 +0900 Subject: kbuild: remove TMPO from try-run TMPO is only used by arch/x86/Makefile. Change arch/x86/Makefile to use $$TMPO.o and remove TMPO from scripts/Makefile.compiler. Signed-off-by: Masahiro Yamada --- arch/x86/Makefile | 4 ++-- scripts/Makefile.compiler | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 2d6d5a28c3bf..c55da2833fe8 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -129,8 +129,8 @@ ifdef CONFIG_X86_X32 x32_ld_ok := $(call try-run,\ /bin/echo -e '1: .quad 1b' | \ $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" - && \ - $(OBJCOPY) -O elf32-x86-64 "$$TMP" "$$TMPO" && \ - $(LD) -m elf32_x86_64 "$$TMPO" -o "$$TMP",y,n) + $(OBJCOPY) -O elf32-x86-64 "$$TMP" "$$TMP.o" && \ + $(LD) -m elf32_x86_64 "$$TMP.o" -o "$$TMP",y,n) ifeq ($(x32_ld_ok),y) CONFIG_X86_X32_ABI := y KBUILD_AFLAGS += -DCONFIG_X86_X32_ABI diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler index 3f2f3665216f..86ecd2ac874c 100644 --- a/scripts/Makefile.compiler +++ b/scripts/Makefile.compiler @@ -21,7 +21,6 @@ TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$ # automatically cleaned up. try-run = $(shell set -e; \ TMP=$(TMPOUT)/tmp; \ - TMPO=$(TMPOUT)/tmp.o; \ mkdir -p $(TMPOUT); \ trap "rm -rf $(TMPOUT)" EXIT; \ if ($(1)) >/dev/null 2>&1; \ -- cgit v1.2.3-71-gd317 From 0e0345b77ac4605d5447b252d220e4a2ee118da7 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Thu, 15 Apr 2021 20:36:07 +0300 Subject: kbuild: redo fake deps at include/config/*.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make include/config/foo/bar.h fake deps files generation simpler. * delete .h suffix those aren't header files, shorten filenames, * delete tolower() Linux filesystems can deal with both upper and lowercase filenames very well, * put everything in 1 directory Presumably 'mkdir -p' split is from dark times when filesystems handled huge directories badly, disks were round adding to seek times. x86_64 allmodconfig lists 12364 files in include/config. ../obj/include/config/ ├── 104_QUAD_8 ├── 60XX_WDT ├── 64BIT ... ├── ZSWAP_DEFAULT_ON ├── ZSWAP_ZPOOL_DEFAULT └── ZSWAP_ZPOOL_DEFAULT_ZBUD 0 directories, 12364 files Signed-off-by: Alexey Dobriyan Signed-off-by: Masahiro Yamada --- include/linux/compiler-version.h | 2 +- init/Kconfig | 2 +- kernel/gen_kheaders.sh | 2 +- scripts/Makefile.build | 4 ++-- scripts/basic/fixdep.c | 43 ++++++---------------------------------- scripts/kconfig/confdata.c | 15 +++++--------- 6 files changed, 16 insertions(+), 52 deletions(-) (limited to 'scripts') diff --git a/include/linux/compiler-version.h b/include/linux/compiler-version.h index 2b2972c77c62..573fa85b6c0c 100644 --- a/include/linux/compiler-version.h +++ b/include/linux/compiler-version.h @@ -9,6 +9,6 @@ * This header exists to force full rebuild when the compiler is upgraded. * * When fixdep scans this, it will find this string "CONFIG_CC_VERSION_TEXT" - * and add dependency on include/config/cc/version/text.h, which is touched + * and add dependency on include/config/CC_VERSION_TEXT, which is touched * by Kconfig when the version string from the compiler changes. */ diff --git a/init/Kconfig b/init/Kconfig index b5744d32c4df..c2339da03468 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -21,7 +21,7 @@ config CC_VERSION_TEXT - Ensure full rebuild when the compiler is updated include/linux/compiler-version.h contains this option in the comment - line so fixdep adds include/config/cc/version/text.h into the + line so fixdep adds include/config/CC_VERSION_TEXT into the auto-generated dependency. When the compiler is updated, syncconfig will touch it and then every file will be rebuilt. diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh index c1510f0ab3ea..34a1dc2abc7d 100755 --- a/kernel/gen_kheaders.sh +++ b/kernel/gen_kheaders.sh @@ -36,7 +36,7 @@ all_dirs="$all_dirs $dir_list" # # When Kconfig regenerates include/generated/autoconf.h, its timestamp is # updated, but the contents might be still the same. When any CONFIG option is -# changed, Kconfig touches the corresponding timestamp file include/config/*.h. +# changed, Kconfig touches the corresponding timestamp file include/config/*. # Hence, the md5sum detects the configuration change anyway. We do not need to # check include/generated/autoconf.h explicitly. # diff --git a/scripts/Makefile.build b/scripts/Makefile.build index e47c054d3db2..5e39b0517186 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -239,8 +239,8 @@ endif # CONFIG_STACK_VALIDATION # Rebuild all objects when objtool changes, or is enabled/disabled. objtool_dep = $(objtool_obj) \ - $(wildcard include/config/orc/unwinder.h \ - include/config/stack/validation.h) + $(wildcard include/config/ORC_UNWINDER \ + include/config/STACK_VALIDATION) ifdef CONFIG_TRIM_UNUSED_KSYMS cmd_gen_ksymdeps = \ diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index d98540552941..44e887cff49b 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -34,7 +34,7 @@ * the config symbols are rebuilt. * * So if the user changes his CONFIG_HIS_DRIVER option, only the objects - * which depend on "include/config/his/driver.h" will be rebuilt, + * which depend on "include/config/HIS_DRIVER" will be rebuilt, * so most likely only his driver ;-) * * The idea above dates, by the way, back to Michael E Chastain, AFAIK. @@ -74,7 +74,7 @@ * * and then basically copies the ..d file to stdout, in the * process filtering out the dependency on autoconf.h and adding - * dependencies on include/config/my/option.h for every + * dependencies on include/config/MY_OPTION for every * CONFIG_MY_OPTION encountered in any of the prerequisites. * * We don't even try to really parse the header files, but @@ -107,8 +107,8 @@ static void usage(void) /* * In the intended usage of this program, the stdout is redirected to .*.cmd - * files. The return value of printf() and putchar() must be checked to catch - * any error, e.g. "No space left on device". + * files. The return value of printf() must be checked to catch any error, + * e.g. "No space left on device". */ static void xprintf(const char *format, ...) { @@ -124,38 +124,6 @@ static void xprintf(const char *format, ...) va_end(ap); } -static void xputchar(int c) -{ - int ret; - - ret = putchar(c); - if (ret == EOF) { - perror("fixdep"); - exit(1); - } -} - -/* - * Print out a dependency path from a symbol name - */ -static void print_dep(const char *m, int slen, const char *dir) -{ - int c, prev_c = '/', i; - - xprintf(" $(wildcard %s/", dir); - for (i = 0; i < slen; i++) { - c = m[i]; - if (c == '_') - c = '/'; - else - c = tolower(c); - if (c != '/' || prev_c != '/') - xputchar(c); - prev_c = c; - } - xprintf(".h) \\\n"); -} - struct item { struct item *next; unsigned int len; @@ -220,7 +188,8 @@ static void use_config(const char *m, int slen) return; define_config(m, slen, hash); - print_dep(m, slen, "include/config"); + /* Print out a dependency path from a symbol name. */ + xprintf(" $(wildcard include/config/%.*s) \\\n", slen, m); } /* test if s ends in sub */ diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 2568dbe16ed6..c7b7e1c62a9c 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -130,19 +130,14 @@ static size_t depfile_prefix_len; static int conf_touch_dep(const char *name) { int fd, ret; - const char *s; - char *d, c; + char *d; - /* check overflow: prefix + name + ".h" + '\0' must fit in buffer. */ - if (depfile_prefix_len + strlen(name) + 3 > sizeof(depfile_path)) + /* check overflow: prefix + name + '\0' must fit in buffer. */ + if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path)) return -1; d = depfile_path + depfile_prefix_len; - s = name; - - while ((c = *s++)) - *d++ = (c == '_') ? '/' : tolower(c); - strcpy(d, ".h"); + strcpy(d, name); /* Assume directory path already exists. */ fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); @@ -465,7 +460,7 @@ load: * Reading from include/config/auto.conf * If CONFIG_FOO previously existed in * auto.conf but it is missing now, - * include/config/foo.h must be touched. + * include/config/FOO must be touched. */ conf_touch_dep(line + strlen(CONFIG_)); else -- cgit v1.2.3-71-gd317 From 82526ef43399a7556b860538041802042b3872c1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 20 Apr 2021 02:05:05 +0900 Subject: kbuild: deb-pkg: change the source package name to linux-upstream Change the source package name from 'linux-$(KERNELRELEASE)' to 'linux-upstream'. Initially, I tried to use 'linux' to be aligned with the Debian kernel package, but Ben suggested 'linux-upstream' so that it is clearly distinguished from distribution packages. [1] The filenames will be changed as follows: [Before] linux-5.12.0-rc3+_5.12.0-rc3+-1.dsc linux-5.12.0-rc3+_5.12.0-rc3+.orig.tar.gz linux-5.12.0-rc3+_5.12.0-rc3+-1.diff.gz [After] linux-upstream_5.12.0-rc3+-1.dsc linux-upstream_5.12.0-rc3+.orig.tar.gz linux-upstream_5.12.0-rc3+-1.diff.gz Commit 3716001bcb7f ("deb-pkg: add source package") introduced KDEB_SOURCENAME. If you are unhappy with the default name, you can override it via KDEB_SOURCENAME. [1]: https://lore.kernel.org/linux-kbuild/06ffa2a690d57f867b4bc1b42f0026917b1dd3cd.camel@decadent.org.uk/T/#m2c4afa0eca5ced5e57795b002f2dbcb05d7a4a44 Suggested-by: Ben Hutchings Signed-off-by: Masahiro Yamada --- scripts/Makefile.package | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.package b/scripts/Makefile.package index f952fb64789d..b74c65284fb2 100644 --- a/scripts/Makefile.package +++ b/scripts/Makefile.package @@ -25,7 +25,7 @@ include $(srctree)/scripts/Kbuild.include # Remove hyphens since they have special meaning in RPM filenames KERNELPATH := kernel-$(subst -,_,$(KERNELRELEASE)) -KDEB_SOURCENAME ?= linux-$(KERNELRELEASE) +KDEB_SOURCENAME ?= linux-upstream KBUILD_PKG_ROOTCMD ?="fakeroot -u" export KDEB_SOURCENAME # Include only those top-level files that are needed by make, plus the GPL copy -- cgit v1.2.3-71-gd317 From 8ac27f2c6eac1f140531411e404fb3ba23339ba5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 24 Apr 2021 22:55:24 +0900 Subject: kconfig: refactor .gitignore Add '/' prefix to clarify that the generated files exist right under scripts/kconfig/, but not in any sub-directory. Replace '*conf-cfg' with '[gmnq]conf-cfg' to make it explicit, and still short enough. Use '[gmnq]conf' to combine gconf, mconf, nconf, and qconf. Signed-off-by: Masahiro Yamada --- scripts/kconfig/.gitignore | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore index c3d537cd0275..500e7424b3ef 100644 --- a/scripts/kconfig/.gitignore +++ b/scripts/kconfig/.gitignore @@ -1,12 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only +/conf +/[gmnq]conf +/[gmnq]conf-cfg /qconf-moc.cc -*conf-cfg - -# -# configuration programs -# -conf -mconf -nconf -qconf -gconf -- cgit v1.2.3-71-gd317 From 2f095504f4b9cf75856d6a9cf90299cf75aa46c5 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Thu, 25 Mar 2021 15:38:05 -0700 Subject: scripts/recordmcount.pl: Fix RISC-V regex for clang Clang can generate R_RISCV_CALL_PLT relocations to _mcount: $ llvm-objdump -dr build/riscv/init/main.o | rg mcount 000000000000000e: R_RISCV_CALL_PLT _mcount 000000000000004e: R_RISCV_CALL_PLT _mcount After this, the __start_mcount_loc section is properly generated and function tracing still works. Link: https://github.com/ClangBuiltLinux/linux/issues/1331 Signed-off-by: Nathan Chancellor Reviewed-by: Fangrui Song Signed-off-by: Palmer Dabbelt --- scripts/recordmcount.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 867860ea57da..a36df04cfa09 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -392,7 +392,7 @@ if ($arch eq "x86_64") { $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; } elsif ($arch eq "riscv") { $function_regex = "^([0-9a-fA-F]+)\\s+<([^.0-9][0-9a-zA-Z_\\.]+)>:"; - $mcount_regex = "^\\s*([0-9a-fA-F]+):\\sR_RISCV_CALL\\s_mcount\$"; + $mcount_regex = "^\\s*([0-9a-fA-F]+):\\sR_RISCV_CALL(_PLT)?\\s_mcount\$"; $type = ".quad"; $alignment = 2; } elsif ($arch eq "nds32") { -- cgit v1.2.3-71-gd317 From 7ce04771503074a7de7f539cc43f5e1b385cb99b Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Thu, 25 Mar 2021 15:38:06 -0700 Subject: riscv: Workaround mcount name prior to clang-13 Prior to clang 13.0.0, the RISC-V name for the mcount symbol was "mcount", which differs from the GCC version of "_mcount", which results in the following errors: riscv64-linux-gnu-ld: init/main.o: in function `__traceiter_initcall_level': main.c:(.text+0xe): undefined reference to `mcount' riscv64-linux-gnu-ld: init/main.o: in function `__traceiter_initcall_start': main.c:(.text+0x4e): undefined reference to `mcount' riscv64-linux-gnu-ld: init/main.o: in function `__traceiter_initcall_finish': main.c:(.text+0x92): undefined reference to `mcount' riscv64-linux-gnu-ld: init/main.o: in function `.LBB32_28': main.c:(.text+0x30c): undefined reference to `mcount' riscv64-linux-gnu-ld: init/main.o: in function `free_initmem': main.c:(.text+0x54c): undefined reference to `mcount' This has been corrected in https://reviews.llvm.org/D98881 but the minimum supported clang version is 10.0.1. To avoid build errors and to gain a working function tracer, adjust the name of the mcount symbol for older versions of clang in mount.S and recordmcount.pl. Link: https://github.com/ClangBuiltLinux/linux/issues/1331 Signed-off-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/ftrace.h | 14 ++++++++++++-- arch/riscv/kernel/mcount.S | 10 +++++----- scripts/recordmcount.pl | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h index 845002cc2e57..04dad3380041 100644 --- a/arch/riscv/include/asm/ftrace.h +++ b/arch/riscv/include/asm/ftrace.h @@ -13,9 +13,19 @@ #endif #define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR +/* + * Clang prior to 13 had "mcount" instead of "_mcount": + * https://reviews.llvm.org/D98881 + */ +#if defined(CONFIG_CC_IS_GCC) || CONFIG_CLANG_VERSION >= 130000 +#define MCOUNT_NAME _mcount +#else +#define MCOUNT_NAME mcount +#endif + #define ARCH_SUPPORTS_FTRACE_OPS 1 #ifndef __ASSEMBLY__ -void _mcount(void); +void MCOUNT_NAME(void); static inline unsigned long ftrace_call_adjust(unsigned long addr) { return addr; @@ -36,7 +46,7 @@ struct dyn_arch_ftrace { * both auipc and jalr at the same time. */ -#define MCOUNT_ADDR ((unsigned long)_mcount) +#define MCOUNT_ADDR ((unsigned long)MCOUNT_NAME) #define JALR_SIGN_MASK (0x00000800) #define JALR_OFFSET_MASK (0x00000fff) #define AUIPC_OFFSET_MASK (0xfffff000) diff --git a/arch/riscv/kernel/mcount.S b/arch/riscv/kernel/mcount.S index 8a5593ff9ff3..6d462681c9c0 100644 --- a/arch/riscv/kernel/mcount.S +++ b/arch/riscv/kernel/mcount.S @@ -47,8 +47,8 @@ ENTRY(ftrace_stub) #ifdef CONFIG_DYNAMIC_FTRACE - .global _mcount - .set _mcount, ftrace_stub + .global MCOUNT_NAME + .set MCOUNT_NAME, ftrace_stub #endif ret ENDPROC(ftrace_stub) @@ -78,7 +78,7 @@ ENDPROC(return_to_handler) #endif #ifndef CONFIG_DYNAMIC_FTRACE -ENTRY(_mcount) +ENTRY(MCOUNT_NAME) la t4, ftrace_stub #ifdef CONFIG_FUNCTION_GRAPH_TRACER la t0, ftrace_graph_return @@ -124,6 +124,6 @@ do_trace: jalr t5 RESTORE_ABI_STATE ret -ENDPROC(_mcount) +ENDPROC(MCOUNT_NAME) #endif -EXPORT_SYMBOL(_mcount) +EXPORT_SYMBOL(MCOUNT_NAME) diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index a36df04cfa09..7b83a1aaec98 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -392,7 +392,7 @@ if ($arch eq "x86_64") { $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; } elsif ($arch eq "riscv") { $function_regex = "^([0-9a-fA-F]+)\\s+<([^.0-9][0-9a-zA-Z_\\.]+)>:"; - $mcount_regex = "^\\s*([0-9a-fA-F]+):\\sR_RISCV_CALL(_PLT)?\\s_mcount\$"; + $mcount_regex = "^\\s*([0-9a-fA-F]+):\\sR_RISCV_CALL(_PLT)?\\s_?mcount\$"; $type = ".quad"; $alignment = 2; } elsif ($arch eq "nds32") { -- cgit v1.2.3-71-gd317 From 80342d484afceec491bcc85ff1e32c5491c1182f Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 27 Apr 2021 12:48:28 +0100 Subject: kernel-doc: Add support for __deprecated The current linux-next tree has a new error: ./Documentation/gpu/drm-mm:445: ./drivers/gpu/drm/drm_prime.c:994: WARNING: Error in declarator or parameters Invalid C declaration: Expecting "(" in parameters. [error at 17] int __deprecated drm_prime_sg_to_page_array (struct sg_table *sgt, struct page **pages, int max_entries) -----------------^ While we might consider that documenting a deprecated interface is not necessarily best practice, removing the error is easy. Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20210427114828.GY235567@casper.infradead.org Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 2a85d34fdcd0..4840e748fca8 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1777,6 +1777,7 @@ sub dump_function($$) { $prototype =~ s/^noinline +//; $prototype =~ s/__init +//; $prototype =~ s/__init_or_module +//; + $prototype =~ s/__deprecated +//; $prototype =~ s/__flatten +//; $prototype =~ s/__meminit +//; $prototype =~ s/__must_check +//; -- cgit v1.2.3-71-gd317 From 439baedad52d3242ec1d2ed728bc195fd5577c05 Mon Sep 17 00:00:00 2001 From: Tom Saeger Date: Thu, 29 Apr 2021 22:53:53 -0700 Subject: scripts/spelling.txt: add entries for recent discoveries Add a few entries for recent spelling fixes found. Opportunistically de-dupe: exeeds||exceeds Link: https://lore.kernel.org/lkml/31acb3239b7ab8989db0c9951e8740050aef0205.1616727528.git.tom.saeger@oracle.com/ Link: https://lore.kernel.org/lkml/fa193b3c9e346ff3fc157b54802c29b25f79c402.1615597995.git.tom.saeger@oracle.com/ Link: https://lkml.kernel.org/r/4a594a9e1536b1d9e5ba57f684c1e41457dd383b.1616861645.git.tom.saeger@oracle.com Signed-off-by: Tom Saeger Cc: Jens Axboe Cc: Colin Ian King Cc: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/spelling.txt | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/spelling.txt b/scripts/spelling.txt index 2e3ba91a5072..7beb4262f719 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -84,6 +84,7 @@ againt||against agaist||against aggreataon||aggregation aggreation||aggregation +ajust||adjust albumns||albums alegorical||allegorical algined||aligned @@ -161,10 +162,13 @@ asign||assign asser||assert assertation||assertion assertting||asserting +assgined||assigned assiged||assigned assigment||assignment assigments||assignments assistent||assistant +assocaited||associated +assocating||associating assocation||association associcated||associated assotiated||associated @@ -177,9 +181,11 @@ asynchnous||asynchronous asynchromous||asynchronous asymetric||asymmetric asymmeric||asymmetric +atleast||at least atomatically||automatically atomicly||atomically atempt||attempt +atrributes||attributes attachement||attachment attatch||attach attched||attached @@ -315,6 +321,7 @@ comminucation||communication commited||committed commiting||committing committ||commit +commnunication||communication commoditiy||commodity comsume||consume comsumer||consumer @@ -349,6 +356,7 @@ condtion||condition conected||connected conector||connector configration||configuration +configred||configured configuartion||configuration configuation||configuration configued||configured @@ -402,6 +410,7 @@ cunter||counter curently||currently cylic||cyclic dafault||default +deactive||deactivate deafult||default deamon||daemon debouce||debounce @@ -417,6 +426,7 @@ deffered||deferred defferred||deferred definate||definite definately||definitely +definiation||definition defintion||definition defintions||definitions defualt||default @@ -571,8 +581,9 @@ errror||error estbalishment||establishment etsablishment||establishment etsbalishment||establishment +evalute||evaluate +evalutes||evaluates evalution||evaluation -exeeds||exceeds excecutable||executable exceded||exceeded exceds||exceeds @@ -696,6 +707,7 @@ hardare||hardware harware||hardware havind||having heirarchically||hierarchically +heirarchy||hierarchy helpfull||helpful heterogenous||heterogeneous hexdecimal||hexadecimal @@ -796,6 +808,7 @@ interanl||internal interchangable||interchangeable interferring||interfering interger||integer +intergrated||integrated intermittant||intermittent internel||internal interoprability||interoperability @@ -808,6 +821,7 @@ interrup||interrupt interrups||interrupts interruptted||interrupted interupted||interrupted +intiailized||initialized intial||initial intialisation||initialisation intialised||initialised @@ -1091,11 +1105,14 @@ preemptable||preemptible prefered||preferred prefferably||preferably prefitler||prefilter +preform||perform premption||preemption prepaired||prepared preperation||preparation preprare||prepare pressre||pressure +presuambly||presumably +previosuly||previously primative||primitive princliple||principle priorty||priority @@ -1265,6 +1282,7 @@ scarch||search schdule||schedule seach||search searchs||searches +secion||section secquence||sequence secund||second segement||segment @@ -1312,6 +1330,8 @@ singed||signed sleeped||slept sliped||slipped softwares||software +soley||solely +souce||source speach||speech specfic||specific specfield||specified @@ -1320,7 +1340,9 @@ specifc||specific specifed||specified specificatin||specification specificaton||specification +specificed||specified specifing||specifying +specifiy||specify specifiying||specifying speficied||specified speicify||specify @@ -1436,6 +1458,7 @@ timout||timeout tmis||this toogle||toggle torerable||tolerable +traget||target traking||tracking tramsmitted||transmitted tramsmit||transmit @@ -1558,6 +1581,7 @@ wiil||will wirte||write withing||within wnat||want +wont||won't workarould||workaround writeing||writing writting||writing -- cgit v1.2.3-71-gd317 From 21917bded72cf33bdf02a153f7b477ab186a52ee Mon Sep 17 00:00:00 2001 From: Wan Jiabing Date: Thu, 29 Apr 2021 22:53:56 -0700 Subject: scripts: a new script for checking duplicate struct declaration checkdeclares: find struct declared more than once. Inspired by checkincludes.pl. This script checks for duplicate struct declares. Note that this will not take into consideration macros, so you should run this only if you know you do have real dups and do not have them under #ifdef's. You could also just review the results. [akpm@linux-foundation.org: fix usage message, grammar] Link: https://lkml.kernel.org/r/20210401110943.1010796-1-wanjiabing@vivo.com Signed-off-by: Wan Jiabing Cc: Masahiro Yamada Cc: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkdeclares.pl | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 scripts/checkdeclares.pl (limited to 'scripts') diff --git a/scripts/checkdeclares.pl b/scripts/checkdeclares.pl new file mode 100644 index 000000000000..f6d551c84fc6 --- /dev/null +++ b/scripts/checkdeclares.pl @@ -0,0 +1,53 @@ +#!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 +# +# checkdeclares: find struct declared more than once +# +# Copyright 2021 Wan Jiabing +# Inspired by checkincludes.pl +# +# This script checks for duplicate struct declares. +# Note that this will not take into consideration macros so +# you should run this only if you know you do have real dups +# and do not have them under #ifdef's. +# You could also just review the results. + +use strict; + +sub usage { + print "Usage: checkdeclares.pl file1.h ...\n"; + print "Warns of struct declaration duplicates\n"; + exit 1; +} + +if ($#ARGV < 0) { + usage(); +} + +my $dup_counter = 0; + +foreach my $file (@ARGV) { + open(my $f, '<', $file) + or die "Cannot open $file: $!.\n"; + + my %declaredstructs = (); + + while (<$f>) { + if (m/^\s*struct\s*(\w*);$/o) { + ++$declaredstructs{$1}; + } + } + + close($f); + + foreach my $structname (keys %declaredstructs) { + if ($declaredstructs{$structname} > 1) { + print "$file: struct $structname is declared more than once.\n"; + ++$dup_counter; + } + } +} + +if ($dup_counter == 0) { + print "No duplicate struct declares found.\n"; +} -- cgit v1.2.3-71-gd317 From 3787b7da5d3e2c849fe8ffed987922a4e6dd6cfd Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 24 Apr 2021 20:55:53 +0900 Subject: kbuild: add comment about why cmd_shipped uses 'cat' cmd_shipped uses 'cat' instead of 'cp' for copying a file. The reason is explained in the commit [1], but it was in the pre-git era. $ touch a $ chmod -w a $ cp a b $ cp a b cp: cannot create regular file 'b': Permission denied Add comments so that you can see the reason without looking into the history. [1]: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=a70dba8086160449cc94c5bdaff78419b6b8e3c8 Signed-off-by: Masahiro Yamada --- scripts/Makefile.lib | 3 +++ 1 file changed, 3 insertions(+) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 64daf37e874b..c0982b8b2b6d 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -252,6 +252,9 @@ quiet_cmd_copy = COPY $@ # Shipped files # =========================================================================== +# 'cp' preserves permissions. If you use it to copy a file in read-only srctree, +# the copy would be read-only as well, leading to an error when executing the +# rule next time. Use 'cat' instead in order to generate a writable file. quiet_cmd_shipped = SHIPPED $@ cmd_shipped = cat $< > $@ -- cgit v1.2.3-71-gd317 From 382243f346416f5ed14cc2517d8a3947bf25d628 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 24 Apr 2021 21:08:29 +0900 Subject: genksyms: fix stale comment (shipped source) is a stale comment. Since commit 833e62245943 ("genksyms: generate lexer and parser during build instead of shipping"), there is no source file to be shipped in this directory. Signed-off-by: Masahiro Yamada --- scripts/genksyms/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile index ce4f99935de5..d6a422a63b6a 100644 --- a/scripts/genksyms/Makefile +++ b/scripts/genksyms/Makefile @@ -22,7 +22,7 @@ $(obj)/pars%.tab.c $(obj)/pars%.tab.h: $(src)/pars%.y FORCE endif -# -I needed for generated C source (shipped source) +# -I needed for generated C source to include headers in source tree HOSTCFLAGS_parse.tab.o := -I $(srctree)/$(src) HOSTCFLAGS_lex.lex.o := -I $(srctree)/$(src) -- cgit v1.2.3-71-gd317 From 1476fee5c53e24e06cfc436110cdefbc1868e8c1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 25 Apr 2021 16:07:12 +0900 Subject: kbuild: add a script to remove stale generated files We maintain .gitignore and Makefiles so build artifacts are properly ignored by Git, and cleaned up by 'make clean'. However, the code is always changing; generated files are often moved to another directory, or removed when they become unnecessary. Such garbage files tend to be left over in the source tree because people usually git-pull without cleaning the tree. This is not only the noise for 'git status', but also a build issue in some cases. One solution is to remove a stale file like commit 223c24a7dba9 ("kbuild: Automatically remove stale file") did. Such workaround should be removed after a while, but we forget about that if we scatter the workaround code in random places. So, this commit adds a new script to collect cleanings of stale files. As a start point, move the code in arch/arm/boot/compressed/Makefile into this script. Signed-off-by: Masahiro Yamada --- Makefile | 6 +++++- arch/arm/boot/compressed/Makefile | 7 ------- scripts/remove-stale-files | 31 +++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 8 deletions(-) create mode 100755 scripts/remove-stale-files (limited to 'scripts') diff --git a/Makefile b/Makefile index 6eafedd7efc6..9f5a3cac63e7 100644 --- a/Makefile +++ b/Makefile @@ -1225,7 +1225,7 @@ PHONY += prepare archprepare archprepare: outputmakefile archheaders archscripts scripts include/config/kernel.release \ asm-generic $(version_h) $(autoksyms_h) include/generated/utsrelease.h \ - include/generated/autoconf.h + include/generated/autoconf.h remove-stale-files prepare0: archprepare $(Q)$(MAKE) $(build)=scripts/mod @@ -1234,6 +1234,10 @@ prepare0: archprepare # All the preparing.. prepare: prepare0 prepare-objtool prepare-resolve_btfids +PHONY += remove-stale-files +remove-stale-files: + $(Q)$(srctree)/scripts/remove-stale-files + # Support for using generic headers in asm-generic asm-generic := -f $(srctree)/scripts/Makefile.asm-generic obj diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index fd94e27ba4fa..182b300e3f8a 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -96,13 +96,6 @@ endif $(foreach o, $(libfdt_objs) atags_to_fdt.o fdt_check_mem_start.o, \ $(eval CFLAGS_$(o) := -I $(srctree)/scripts/dtc/libfdt -fno-stack-protector)) -# These were previously generated C files. When you are building the kernel -# with O=, make sure to remove the stale files in the output tree. Otherwise, -# the build system wrongly compiles the stale ones. -ifdef building_out_of_srctree -$(shell rm -f $(addprefix $(obj)/, fdt_rw.c fdt_ro.c fdt_wip.c fdt.c)) -endif - targets := vmlinux vmlinux.lds piggy_data piggy.o \ lib1funcs.o ashldi3.o bswapsdi2.o \ head.o $(OBJS) diff --git a/scripts/remove-stale-files b/scripts/remove-stale-files new file mode 100755 index 000000000000..c3eb81c3f7de --- /dev/null +++ b/scripts/remove-stale-files @@ -0,0 +1,31 @@ +#!/bin/sh + +set -e + +# When you move, remove or rename generated files, you probably also update +# .gitignore and cleaning rules in the Makefile. This is the right thing +# to do. However, people usually do 'git pull', 'git bisect', etc. without +# running 'make clean'. Then, the stale generated files are left over, often +# causing build issues. +# +# Also, 'git status' shows such stale build artifacts as untracked files. +# What is worse, some people send a wrong patch to get them back to .gitignore +# without checking the commit history. +# +# So, when you (re)move generated files, please move the cleaning rules from +# the Makefile to this script. This is run before Kbuild starts building +# anything, so people will not be annoyed by such garbage files. +# +# This script is not intended to grow endlessly. Rather, it is a temporary scrap +# yard. Stale files stay in this file for a while (for some release cycles?), +# then will be really dead and removed from the code base entirely. + +# These were previously generated source files. When you are building the kernel +# with O=, make sure to remove the stale files in the output tree. Otherwise, +# the build system wrongly compiles the stale ones. +if [ -n "${building_out_of_srctree}" ]; then + for f in fdt_rw.c fdt_ro.c fdt_wip.c fdt.c + do + rm -f arch/arm/boot/compressed/${f} + done +fi -- cgit v1.2.3-71-gd317 From 77a88274dc1a2cf3a775161d9a3242bc798ee680 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 30 Apr 2021 10:56:27 +0900 Subject: kbuild: replace LANG=C with LC_ALL=C LANG gives a weak default to each LC_* in case it is not explicitly defined. LC_ALL, if set, overrides all other LC_* variables. LANG < LC_CTYPE, LC_COLLATE, LC_MONETARY, LC_NUMERIC, ... < LC_ALL This is why documentation such as [1] suggests to set LC_ALL in build scripts to get the deterministic result. LANG=C is not strong enough to override LC_* that may be set by end users. [1]: https://reproducible-builds.org/docs/locales/ Signed-off-by: Masahiro Yamada Acked-by: Michael Ellerman (powerpc) Reviewed-by: Matthias Maennich Acked-by: Matthieu Baerts (mptcp) Reviewed-by: Greg Kroah-Hartman --- arch/powerpc/boot/wrapper | 2 +- scripts/nsdeps | 2 +- scripts/recordmcount.pl | 2 +- scripts/setlocalversion | 2 +- scripts/tags.sh | 2 +- tools/testing/selftests/net/mptcp/mptcp_connect.sh | 2 +- usr/gen_initramfs.sh | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index 41fa0a8715e3..cdb796b76e2e 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -191,7 +191,7 @@ if [ -z "$kernel" ]; then kernel=vmlinux fi -LANG=C elfformat="`${CROSS}objdump -p "$kernel" | grep 'file format' | awk '{print $4}'`" +LC_ALL=C elfformat="`${CROSS}objdump -p "$kernel" | grep 'file format' | awk '{print $4}'`" case "$elfformat" in elf64-powerpcle) format=elf64lppc ;; elf64-powerpc) format=elf32ppc ;; diff --git a/scripts/nsdeps b/scripts/nsdeps index e8ce2a4d704a..04c4b96e95ec 100644 --- a/scripts/nsdeps +++ b/scripts/nsdeps @@ -44,7 +44,7 @@ generate_deps() { for source_file in $mod_source_files; do sed '/MODULE_IMPORT_NS/Q' $source_file > ${source_file}.tmp offset=$(wc -l ${source_file}.tmp | awk '{print $1;}') - cat $source_file | grep MODULE_IMPORT_NS | LANG=C sort -u >> ${source_file}.tmp + cat $source_file | grep MODULE_IMPORT_NS | LC_ALL=C sort -u >> ${source_file}.tmp tail -n +$((offset +1)) ${source_file} | grep -v MODULE_IMPORT_NS >> ${source_file}.tmp if ! diff -q ${source_file} ${source_file}.tmp; then mv ${source_file}.tmp ${source_file} diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 867860ea57da..0a7fc9507d6f 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -497,7 +497,7 @@ sub update_funcs # # Step 2: find the sections and mcount call sites # -open(IN, "LANG=C $objdump -hdr $inputfile|") || die "error running $objdump"; +open(IN, "LC_ALL=C $objdump -hdr $inputfile|") || die "error running $objdump"; my $text; diff --git a/scripts/setlocalversion b/scripts/setlocalversion index bb709eda96cd..db941f6d9591 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -126,7 +126,7 @@ scm_version() fi # Check for svn and a svn repo. - if rev=$(LANG= LC_ALL= LC_MESSAGES=C svn info 2>/dev/null | grep '^Last Changed Rev'); then + if rev=$(LC_ALL=C svn info 2>/dev/null | grep '^Last Changed Rev'); then rev=$(echo $rev | awk '{print $NF}') printf -- '-svn%s' "$rev" diff --git a/scripts/tags.sh b/scripts/tags.sh index fd96734deff1..db8ba411860a 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -326,5 +326,5 @@ esac # Remove structure forward declarations. if [ -n "$remove_structs" ]; then - LANG=C sed -i -e '/^\([a-zA-Z_][a-zA-Z0-9_]*\)\t.*\t\/\^struct \1;.*\$\/;"\tx$/d' $1 + LC_ALL=C sed -i -e '/^\([a-zA-Z_][a-zA-Z0-9_]*\)\t.*\t\/\^struct \1;.*\$\/;"\tx$/d' $1 fi diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.sh b/tools/testing/selftests/net/mptcp/mptcp_connect.sh index 9236609731b1..3c4cb72ed8a4 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh @@ -274,7 +274,7 @@ check_mptcp_disabled() ip netns exec ${disabled_ns} sysctl -q net.mptcp.enabled=0 local err=0 - LANG=C ip netns exec ${disabled_ns} ./mptcp_connect -p 10000 -s MPTCP 127.0.0.1 < "$cin" 2>&1 | \ + LC_ALL=C ip netns exec ${disabled_ns} ./mptcp_connect -p 10000 -s MPTCP 127.0.0.1 < "$cin" 2>&1 | \ grep -q "^socket: Protocol not available$" && err=1 ip netns delete ${disabled_ns} diff --git a/usr/gen_initramfs.sh b/usr/gen_initramfs.sh index 8ae831657e5d..63476bb70b41 100755 --- a/usr/gen_initramfs.sh +++ b/usr/gen_initramfs.sh @@ -147,7 +147,7 @@ dir_filelist() { header "$1" srcdir=$(echo "$1" | sed -e 's://*:/:g') - dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | LANG=C sort) + dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | LC_ALL=C sort) # If $dirlist is only one line, then the directory is empty if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then -- cgit v1.2.3-71-gd317 From 9009b455811b0fa1f6b0adfa94db136984db5a38 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 30 Apr 2021 11:03:08 +0900 Subject: .gitignore: prefix local generated files with a slash The pattern prefixed with '/' matches files in the same directory, but not ones in sub-directories. Signed-off-by: Masahiro Yamada Acked-by: Miguel Ojeda Acked-by: Rob Herring Acked-by: Andra Paraschiv Acked-by: Greg Kroah-Hartman Acked-by: Gabriel Krisman Bertazi --- Documentation/devicetree/bindings/.gitignore | 4 ++-- arch/.gitignore | 4 ++-- certs/.gitignore | 4 ++-- drivers/memory/.gitignore | 2 +- drivers/tty/vt/.gitignore | 6 +++--- fs/unicode/.gitignore | 4 ++-- kernel/.gitignore | 2 +- lib/.gitignore | 10 +++++----- samples/auxdisplay/.gitignore | 2 +- samples/binderfs/.gitignore | 3 ++- samples/connector/.gitignore | 2 +- samples/hidraw/.gitignore | 2 +- samples/mei/.gitignore | 2 +- samples/nitro_enclaves/.gitignore | 2 +- samples/pidfd/.gitignore | 2 +- samples/seccomp/.gitignore | 8 ++++---- samples/timers/.gitignore | 2 +- samples/vfs/.gitignore | 4 ++-- samples/watch_queue/.gitignore | 3 ++- samples/watchdog/.gitignore | 2 +- scripts/.gitignore | 18 +++++++++--------- scripts/basic/.gitignore | 2 +- scripts/dtc/.gitignore | 4 ++-- scripts/gcc-plugins/.gitignore | 2 +- scripts/genksyms/.gitignore | 2 +- scripts/mod/.gitignore | 8 ++++---- usr/.gitignore | 4 ++-- 27 files changed, 56 insertions(+), 54 deletions(-) (limited to 'scripts') diff --git a/Documentation/devicetree/bindings/.gitignore b/Documentation/devicetree/bindings/.gitignore index 3a05b99bfa26..a77719968a7e 100644 --- a/Documentation/devicetree/bindings/.gitignore +++ b/Documentation/devicetree/bindings/.gitignore @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only *.example.dts -processed-schema*.yaml -processed-schema*.json +/processed-schema*.yaml +/processed-schema*.json diff --git a/arch/.gitignore b/arch/.gitignore index 4191da401dbb..756c19c34f99 100644 --- a/arch/.gitignore +++ b/arch/.gitignore @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only -i386 -x86_64 +/i386/ +/x86_64/ diff --git a/certs/.gitignore b/certs/.gitignore index 6cbd1f1a5837..8c3763f80be3 100644 --- a/certs/.gitignore +++ b/certs/.gitignore @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only -x509_certificate_list -x509_revocation_list +/x509_certificate_list +/x509_revocation_list diff --git a/drivers/memory/.gitignore b/drivers/memory/.gitignore index caedc4c7d2db..5e84bee05ef8 100644 --- a/drivers/memory/.gitignore +++ b/drivers/memory/.gitignore @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -ti-emif-asm-offsets.h +/ti-emif-asm-offsets.h diff --git a/drivers/tty/vt/.gitignore b/drivers/tty/vt/.gitignore index 3ecf42234d89..0221709b177d 100644 --- a/drivers/tty/vt/.gitignore +++ b/drivers/tty/vt/.gitignore @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -conmakehash -consolemap_deftbl.c -defkeymap.c +/conmakehash +/consolemap_deftbl.c +/defkeymap.c diff --git a/fs/unicode/.gitignore b/fs/unicode/.gitignore index 9b2467e77b2d..361294571ab0 100644 --- a/fs/unicode/.gitignore +++ b/fs/unicode/.gitignore @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only -mkutf8data -utf8data.h +/mkutf8data +/utf8data.h diff --git a/kernel/.gitignore b/kernel/.gitignore index dafdce3d18c5..c6b299a6b786 100644 --- a/kernel/.gitignore +++ b/kernel/.gitignore @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only /config_data -kheaders.md5 +/kheaders.md5 diff --git a/lib/.gitignore b/lib/.gitignore index 327cb2c7f2c9..5e7fa54c4536 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only -gen_crc32table -gen_crc64table -crc32table.h -crc64table.h -oid_registry_data.c +/crc32table.h +/crc64table.h +/gen_crc32table +/gen_crc64table +/oid_registry_data.c diff --git a/samples/auxdisplay/.gitignore b/samples/auxdisplay/.gitignore index 2ed744c0e741..d023816849bd 100644 --- a/samples/auxdisplay/.gitignore +++ b/samples/auxdisplay/.gitignore @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -cfag12864b-example +/cfag12864b-example diff --git a/samples/binderfs/.gitignore b/samples/binderfs/.gitignore index eb60241e8087..8fa415a3640b 100644 --- a/samples/binderfs/.gitignore +++ b/samples/binderfs/.gitignore @@ -1 +1,2 @@ -binderfs_example +# SPDX-License-Identifier: GPL-2.0 +/binderfs_example diff --git a/samples/connector/.gitignore b/samples/connector/.gitignore index d86f2ff9c947..0e26039f39b5 100644 --- a/samples/connector/.gitignore +++ b/samples/connector/.gitignore @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -ucon +/ucon diff --git a/samples/hidraw/.gitignore b/samples/hidraw/.gitignore index d7a6074ebcf9..5233ab63262e 100644 --- a/samples/hidraw/.gitignore +++ b/samples/hidraw/.gitignore @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -hid-example +/hid-example diff --git a/samples/mei/.gitignore b/samples/mei/.gitignore index db5e802f041e..fe894bcb6a62 100644 --- a/samples/mei/.gitignore +++ b/samples/mei/.gitignore @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -mei-amt-version +/mei-amt-version diff --git a/samples/nitro_enclaves/.gitignore b/samples/nitro_enclaves/.gitignore index 827934129c90..6a718eec71f4 100644 --- a/samples/nitro_enclaves/.gitignore +++ b/samples/nitro_enclaves/.gitignore @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0 -ne_ioctl_sample +/ne_ioctl_sample diff --git a/samples/pidfd/.gitignore b/samples/pidfd/.gitignore index eea857fca736..d4cfa3176b1b 100644 --- a/samples/pidfd/.gitignore +++ b/samples/pidfd/.gitignore @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -pidfd-metadata +/pidfd-metadata diff --git a/samples/seccomp/.gitignore b/samples/seccomp/.gitignore index 4a5a5b7db30b..a6df0da77c5d 100644 --- a/samples/seccomp/.gitignore +++ b/samples/seccomp/.gitignore @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -bpf-direct -bpf-fancy -dropper -user-trap +/bpf-direct +/bpf-fancy +/dropper +/user-trap diff --git a/samples/timers/.gitignore b/samples/timers/.gitignore index 40510c33cf08..cd9ff7b95383 100644 --- a/samples/timers/.gitignore +++ b/samples/timers/.gitignore @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -hpet_example +/hpet_example diff --git a/samples/vfs/.gitignore b/samples/vfs/.gitignore index 8fdabf7e5373..79212d91285b 100644 --- a/samples/vfs/.gitignore +++ b/samples/vfs/.gitignore @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only -test-fsmount -test-statx +/test-fsmount +/test-statx diff --git a/samples/watch_queue/.gitignore b/samples/watch_queue/.gitignore index 2aa3c7e56a1a..823b351d3db9 100644 --- a/samples/watch_queue/.gitignore +++ b/samples/watch_queue/.gitignore @@ -1 +1,2 @@ -watch_test +# SPDX-License-Identifier: GPL-2.0-only +/watch_test diff --git a/samples/watchdog/.gitignore b/samples/watchdog/.gitignore index 74153b831244..a70a0150ed9f 100644 --- a/samples/watchdog/.gitignore +++ b/samples/watchdog/.gitignore @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -watchdog-simple +/watchdog-simple diff --git a/scripts/.gitignore b/scripts/.gitignore index a6c11316c969..e83c620ef52c 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -1,11 +1,11 @@ # SPDX-License-Identifier: GPL-2.0-only -bin2c -kallsyms -unifdef -recordmcount -sorttable -asn1_compiler -extract-cert -sign-file -insert-sys-cert +/asn1_compiler +/bin2c +/extract-cert +/insert-sys-cert +/kallsyms /module.lds +/recordmcount +/sign-file +/sorttable +/unifdef diff --git a/scripts/basic/.gitignore b/scripts/basic/.gitignore index 98ae1f509592..961c91c8a884 100644 --- a/scripts/basic/.gitignore +++ b/scripts/basic/.gitignore @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -fixdep +/fixdep diff --git a/scripts/dtc/.gitignore b/scripts/dtc/.gitignore index 8a8b62bf3d3c..e0b5c1d2464a 100644 --- a/scripts/dtc/.gitignore +++ b/scripts/dtc/.gitignore @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only -dtc -fdtoverlay +/dtc +/fdtoverlay diff --git a/scripts/gcc-plugins/.gitignore b/scripts/gcc-plugins/.gitignore index b04e0f0f033e..5cc385b9eb97 100644 --- a/scripts/gcc-plugins/.gitignore +++ b/scripts/gcc-plugins/.gitignore @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -randomize_layout_seed.h +/randomize_layout_seed.h diff --git a/scripts/genksyms/.gitignore b/scripts/genksyms/.gitignore index 999af710f83d..0b275abf9405 100644 --- a/scripts/genksyms/.gitignore +++ b/scripts/genksyms/.gitignore @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -genksyms +/genksyms diff --git a/scripts/mod/.gitignore b/scripts/mod/.gitignore index 07e4a39f90a6..0465ec33c9bf 100644 --- a/scripts/mod/.gitignore +++ b/scripts/mod/.gitignore @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -elfconfig.h -mk_elfconfig -modpost -devicetable-offsets.h +/devicetable-offsets.h +/elfconfig.h +/mk_elfconfig +/modpost diff --git a/usr/.gitignore b/usr/.gitignore index 935442ed1eb2..8996e7a88902 100644 --- a/usr/.gitignore +++ b/usr/.gitignore @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -gen_init_cpio -initramfs_data.cpio +/gen_init_cpio +/initramfs_data.cpio /initramfs_inc_data -- cgit v1.2.3-71-gd317 From f5169f713e0c02333e770c9045a00fa54ac98220 Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Fri, 23 Apr 2021 18:32:59 +0530 Subject: Removed the oprofiled version option Removed the oprofiled version option Signed-off-by: Bhaskar Chowdhury Link: https://lore.kernel.org/r/c98fa38b74bdd8ab16d35862895dac5f5a535f94.1619181632.git.unixbhaskar@gmail.com Signed-off-by: Jonathan Corbet --- scripts/ver_linux | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts') diff --git a/scripts/ver_linux b/scripts/ver_linux index a92acc703f9b..1a8ee4ff0e32 100755 --- a/scripts/ver_linux +++ b/scripts/ver_linux @@ -47,7 +47,6 @@ BEGIN { printversion("Net-tools", version("ifconfig --version")) printversion("Kbd", version("loadkeys -V")) printversion("Console-tools", version("loadkeys -V")) - printversion("Oprofile", version("oprofiled --version")) printversion("Sh-utils", version("expr --v")) printversion("Udev", version("udevadm --version")) printversion("Wireless-tools", version("iwconfig --version")) -- cgit v1.2.3-71-gd317 From 44f87191d105519cdf37fb0d4988006ea04eb34e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 3 May 2021 03:09:55 +0900 Subject: kbuild: parameterize the .o part of suffix-search The suffix-search macro hard-codes the suffix, '.o'. Make it a parameter so that the multi-search and real-search macros can be reused for foo-dtbs syntax introduced by commit 15d16d6dadf6 ("kbuild: Add generic rule to apply fdtoverlay"). Signed-off-by: Masahiro Yamada --- scripts/Makefile.lib | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index c0982b8b2b6d..0c8d146879eb 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -44,19 +44,22 @@ else obj-y := $(filter-out %/, $(obj-y)) endif -# Expand $(foo-objs) $(foo-y) by calling $(call suffix-search,foo.o,-objs -y) -suffix-search = $(strip $(foreach s, $2, $($(1:.o=$s)))) +# Expand $(foo-objs) $(foo-y) etc. by replacing their individuals +suffix-search = $(strip $(foreach s, $3, $($(1:%$(strip $2)=%$s)))) +# List composite targets that are constructed by combining other targets +multi-search = $(sort $(foreach m, $1, $(if $(call suffix-search, $m, $2, $3 -), $m))) +# List primitive targets that are compiled from source files +real-search = $(foreach m, $1, $(if $(call suffix-search, $m, $2, $3 -), $(call suffix-search, $m, $2, $3), $m)) + # If $(foo-objs), $(foo-y), $(foo-m), or $(foo-) exists, foo.o is a composite object -multi-search = $(sort $(foreach m, $1, $(if $(call suffix-search, $m, $2 -), $m))) -multi-obj-y := $(call multi-search,$(obj-y),-objs -y) -multi-obj-m := $(call multi-search,$(obj-m),-objs -y -m) +multi-obj-y := $(call multi-search, $(obj-y), .o, -objs -y) +multi-obj-m := $(call multi-search, $(obj-m), .o, -objs -y -m) multi-obj-ym := $(multi-obj-y) $(multi-obj-m) # Replace multi-part objects by their individual parts, # including built-in.a from subdirectories -real-search = $(foreach m, $1, $(if $(call suffix-search, $m, $2 -), $(call suffix-search, $m, $2), $m)) -real-obj-y := $(call real-search, $(obj-y),-objs -y) -real-obj-m := $(call real-search, $(obj-m),-objs -y -m) +real-obj-y := $(call real-search, $(obj-y), .o, -objs -y) +real-obj-m := $(call real-search, $(obj-m), .o, -objs -y -m) always-y += $(always-m) -- cgit v1.2.3-71-gd317 From bcf0c6642833673830ee9d9b40862a4c476d1565 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 3 May 2021 03:09:56 +0900 Subject: kbuild: refactor fdtoverlay rule Rename overlay-y to multi-dtb-y, which is a consistent name with multi-obj-y. Also, use multi-search to avoid code duplication. Introduce real-dtb-y, which is a consistent name with real-obj-y, to contain primitive blobs compiled from *.dts. This is used to calculate the list of *.dt.yaml files. Set -@ to base DTB without using $(eval ). Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 2 +- scripts/Makefile.lib | 33 +++++++++++++++------------------ 2 files changed, 16 insertions(+), 19 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 5e39b0517186..949f723efe53 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -354,7 +354,7 @@ $(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE targets += $(filter-out $(subdir-builtin), $(real-obj-y)) targets += $(filter-out $(subdir-modorder), $(real-obj-m)) -targets += $(lib-y) $(always-y) $(MAKECMDGOALS) +targets += $(real-dtb-y) $(lib-y) $(always-y) $(MAKECMDGOALS) # Linker scripts preprocessor (.lds.S -> .lds) # --------------------------------------------------------------------------- diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 0c8d146879eb..deac60727e48 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -78,24 +78,18 @@ always-y += $(userprogs-always-y) $(userprogs-always-m) # If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built dtb-$(CONFIG_OF_ALL_DTBS) += $(dtb-) -# List all dtbs to be generated by fdtoverlay -overlay-y := $(foreach m,$(dtb-y), $(if $(strip $($(m:.dtb=-dtbs))),$(m),)) - -# Generate symbols for the base files so overlays can be applied to them. -$(foreach m,$(overlay-y), $(eval DTC_FLAGS_$(basename $(firstword $($(m:.dtb=-dtbs)))) += -@)) - -# Add base dtb and overlay dtbo -dtb-y += $(foreach m,$(overlay-y), $($(m:.dtb=-dtbs))) +# Composite DTB (i.e. DTB constructed by overlay) +multi-dtb-y := $(call multi-search, $(dtb-y), .dtb, -dtbs) +# Primitive DTB compiled from *.dts +real-dtb-y := $(call real-search, $(dtb-y), .dtb, -dtbs) +# Base DTB that overlay is applied onto (each first word of $(*-dtbs) expansion) +base-dtb-y := $(foreach m, $(multi-dtb-y), $(firstword $(call suffix-search, $m, .dtb, -dtbs))) always-y += $(dtb-y) ifneq ($(CHECK_DTBS),) -# Don't run schema checks for dtbs created by fdtoverlay as they don't -# have corresponding dts files. -dt-yaml-y := $(filter-out $(overlay-y),$(dtb-y)) - -always-y += $(patsubst %.dtb,%.dt.yaml, $(dt-yaml-y)) -always-y += $(patsubst %.dtbo,%.dt.yaml, $(dt-yaml-y)) +always-y += $(patsubst %.dtb,%.dt.yaml, $(real-dtb-y)) +always-y += $(patsubst %.dtbo,%.dt.yaml, $(real-dtb-y)) endif # Add subdir path @@ -108,6 +102,8 @@ lib-y := $(addprefix $(obj)/,$(lib-y)) real-obj-y := $(addprefix $(obj)/,$(real-obj-y)) real-obj-m := $(addprefix $(obj)/,$(real-obj-m)) multi-obj-m := $(addprefix $(obj)/, $(multi-obj-m)) +multi-dtb-y := $(addprefix $(obj)/, $(multi-dtb-y)) +real-dtb-y := $(addprefix $(obj)/, $(real-dtb-y)) subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) # Finds the multi-part object the current object will be linked into. @@ -325,6 +321,9 @@ endif DTC_FLAGS += $(DTC_FLAGS_$(basetarget)) +# Set -@ if the target is a base DTB that overlay is applied onto +DTC_FLAGS += $(if $(filter $(patsubst $(obj)/%,%,$@), $(base-dtb-y)), -@) + # Generate an assembly file to wrap the output of the device tree compiler quiet_cmd_dt_S_dtb= DTB $@ cmd_dt_S_dtb= \ @@ -356,14 +355,12 @@ $(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE $(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE $(call if_changed_dep,dtc) -overlay-y := $(addprefix $(obj)/, $(overlay-y)) - quiet_cmd_fdtoverlay = DTOVL $@ cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(real-prereqs) -$(overlay-y): FORCE +$(multi-dtb-y): FORCE $(call if_changed,fdtoverlay) -$(call multi_depend, $(overlay-y), .dtb, -dtbs) +$(call multi_depend, $(multi-dtb-y), .dtb, -dtbs) DT_CHECKER ?= dt-validate DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),,-m) -- cgit v1.2.3-71-gd317 From d4452837ffbeb59e18f2499ef907579a618d623d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 3 May 2021 03:09:57 +0900 Subject: kbuild: refactor modname-multi by using suffix-search Improve the readability slightly. Signed-off-by: Masahiro Yamada --- scripts/Makefile.lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index deac60727e48..10950559b223 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -109,7 +109,7 @@ subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) # Finds the multi-part object the current object will be linked into. # If the object belongs to two or more multi-part objects, list them all. modname-multi = $(sort $(foreach m,$(multi-obj-ym),\ - $(if $(filter $*.o, $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$(m:.o=)))) + $(if $(filter $*.o, $(call suffix-search, $m, .o, -objs -y -m)),$(m:.o=)))) __modname = $(if $(modname-multi),$(modname-multi),$(basetarget)) -- cgit v1.2.3-71-gd317 From 51eb95e2da41802454f48b9afeb4d96a77295035 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 4 May 2021 20:35:27 -0700 Subject: kbuild: Don't remove link-vmlinux temporary files on exit/signal Keep them around until they are cleaned up by make clean. This uses a bit more disk space, but makes it easier to debug any problems with the kernel link process. Suggested-by: Masahiro Yamada Signed-off-by: Andi Kleen Signed-off-by: Masahiro Yamada --- scripts/link-vmlinux.sh | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'scripts') diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 7d112681f332..f4de4c97015b 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -320,20 +320,6 @@ cleanup() rm -f .vmlinux.d } -on_exit() -{ - if [ $? -ne 0 ]; then - cleanup - fi -} -trap on_exit EXIT - -on_signals() -{ - exit 1 -} -trap on_signals HUP INT QUIT TERM - # Use "make V=1" to debug this script case "${KBUILD_VERBOSE}" in *1*) -- cgit v1.2.3-71-gd317 From fbe745416d11b1a17c35a7c7f0ef6f4dbe5a7573 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 6 May 2021 18:03:55 -0700 Subject: checkpatch: warn when missing newline in return sysfs_emit() formats return sysfs_emit() uses should include a newline. Suggest adding a newline when one is missing. Add one using --fix too. Link: https://lkml.kernel.org/r/aa1819fa5faf786573df298e5e2e7d357ba7d4ad.camel@perches.com Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index ccb412a74725..3870c8a01987 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -7198,6 +7198,17 @@ sub process { "Using $1 should generally have parentheses around the comparison\n" . $herecurr); } +# return sysfs_emit(foo, fmt, ...) fmt without newline + if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ && + substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) { + my $offset = $+[6] - 1; + if (WARN("SYSFS_EMIT", + "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) && + $fix) { + substr($fixed[$fixlinenr], $offset, 0) = '\\n'; + } + } + # nested likely/unlikely calls if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) { WARN("LIKELY_MISUSE", -- cgit v1.2.3-71-gd317 From 7b844345fc2a9c46f8bb8cdb7408c766dfcdd83d Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Thu, 6 May 2021 18:03:58 -0700 Subject: checkpatch: exclude four preprocessor sub-expressions from MACRO_ARG_REUSE __must_be_array, offsetof, sizeof_field and __stringify are all preprocessor macros and do not evaluate their arguments. As such, it is safe not to warn when arguments are being reused in those four sub-expressions. Exclude those so that they can pass checkpatch. Link: https://lkml.kernel.org/r/20210407105042.25380-1-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 3870c8a01987..44b9dc330ac6 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -5829,7 +5829,7 @@ sub process { next if ($arg =~ /\.\.\./); next if ($arg =~ /^type$/i); my $tmp_stmt = $define_stmt; - $tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; + $tmp_stmt =~ s/\b(__must_be_array|offsetof|sizeof|sizeof_field|__stringify|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; $tmp_stmt =~ s/\#+\s*$arg\b//g; $tmp_stmt =~ s/\b$arg\s*\#\#//g; my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; -- cgit v1.2.3-71-gd317 From 7e6cdd7fd94380a3b87b2ce087903b3722b3d0d6 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 6 May 2021 18:04:01 -0700 Subject: checkpatch: improve ALLOC_ARRAY_ARGS test The devm_ variant of 'kcalloc()' and 'kmalloc_array()' are not tested Add the corresponding check. Link: https://lkml.kernel.org/r/205fc4847972fb6779abcc8818f39c14d1b45af1.1618595794.git.christophe.jaillet@wanadoo.fr Signed-off-by: Christophe JAILLET Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 44b9dc330ac6..23697a6b1eaa 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -7006,7 +7006,7 @@ sub process { } # check for alloc argument mismatch - if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { + if ($line =~ /\b((?:devm_)?(?:kcalloc|kmalloc_array))\s*\(\s*sizeof\b/) { WARN("ALLOC_ARRAY_ARGS", "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); } -- cgit v1.2.3-71-gd317 From 23921540d2c0a4d8530078f6f64fc3e28444ca9d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 6 May 2021 18:05:03 -0700 Subject: gdb: lx-symbols: store the abspath() If we store the relative path, the user might later cd to a different directory, and that would break the automatic symbol resolving that happens when a module is loaded into the target kernel. Fix this by storing the abspath() of each path given, just like we already do for the cwd (os.getcwd() is absolute.) Link: https://lkml.kernel.org/r/20201217091747.bf4332cf2b35.I10ebbdb7e9b80ab1a5cddebf53d073be8232d656@changeid Signed-off-by: Johannes Berg Reviewed-by: Jan Kiszka Cc: Kieran Bingham Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/gdb/linux/symbols.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py index 1be9763cf8bb..08d264ac328b 100644 --- a/scripts/gdb/linux/symbols.py +++ b/scripts/gdb/linux/symbols.py @@ -164,7 +164,8 @@ lx-symbols command.""" saved_state['breakpoint'].enabled = saved_state['enabled'] def invoke(self, arg, from_tty): - self.module_paths = [os.path.expanduser(p) for p in arg.split()] + self.module_paths = [os.path.abspath(os.path.expanduser(p)) + for p in arg.split()] self.module_paths.append(os.getcwd()) # enforce update -- cgit v1.2.3-71-gd317 From dc9586823f3e06867344e6cf88741688c2c7737f Mon Sep 17 00:00:00 2001 From: Barry Song Date: Thu, 6 May 2021 18:05:06 -0700 Subject: scripts/gdb: document lx_current is only supported by x86 Patch series "scripts/gdb: clarify the platforms supporting lx_current and add arm64 support", v2. lx_current depends on per_cpu current_task variable which exists on x86 only. so it actually works on x86 only. the 1st patch documents this clearly; the 2nd patch adds support for arm64. This patch (of 2): x86 is the only architecture which has per_cpu current_task: arch$ git grep current_task | grep -i per_cpu x86/include/asm/current.h:DECLARE_PER_CPU(struct task_struct *, current_task); x86/kernel/cpu/common.c:DEFINE_PER_CPU(struct task_struct *, current_task) ____cacheline_aligned = x86/kernel/cpu/common.c:EXPORT_PER_CPU_SYMBOL(current_task); x86/kernel/cpu/common.c:DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; x86/kernel/cpu/common.c:EXPORT_PER_CPU_SYMBOL(current_task); x86/kernel/smpboot.c: per_cpu(current_task, cpu) = idle; On other architectures, lx_current() will lead to a python exception: (gdb) p $lx_current().pid Python Exception No symbol "current_task" in current context.: Error occurred in Python: No symbol "current_task" in current context. To avoid more people struggling and wasting time in other architectures, document it. Link: https://lkml.kernel.org/r/20210314203444.15188-1-song.bao.hua@hisilicon.com Link: https://lkml.kernel.org/r/20210314203444.15188-2-song.bao.hua@hisilicon.com Signed-off-by: Barry Song Cc: Jan Kiszka Cc: Kieran Bingham Cc: Jonathan Corbet Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/dev-tools/gdb-kernel-debugging.rst | 2 +- scripts/gdb/linux/cpus.py | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/Documentation/dev-tools/gdb-kernel-debugging.rst b/Documentation/dev-tools/gdb-kernel-debugging.rst index 4756f6b3a04e..1586901b683c 100644 --- a/Documentation/dev-tools/gdb-kernel-debugging.rst +++ b/Documentation/dev-tools/gdb-kernel-debugging.rst @@ -114,7 +114,7 @@ Examples of using the Linux-provided gdb helpers [ 0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved .... -- Examine fields of the current task struct:: +- Examine fields of the current task struct(supported by x86 only):: (gdb) p $lx_current().pid $1 = 4998 diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py index 008e62f3190d..f382762509d3 100644 --- a/scripts/gdb/linux/cpus.py +++ b/scripts/gdb/linux/cpus.py @@ -156,6 +156,13 @@ Note that VAR has to be quoted as string.""" PerCpu() +def get_current_task(cpu): + if utils.is_target_arch("x86"): + var_ptr = gdb.parse_and_eval("¤t_task") + return per_cpu(var_ptr, cpu).dereference() + else: + raise gdb.GdbError("Sorry, obtaining the current task is not yet " + "supported with this arch") class LxCurrentFunc(gdb.Function): """Return current task. @@ -167,8 +174,7 @@ number. If CPU is omitted, the CPU of the current context is used.""" super(LxCurrentFunc, self).__init__("lx_current") def invoke(self, cpu=-1): - var_ptr = gdb.parse_and_eval("¤t_task") - return per_cpu(var_ptr, cpu).dereference() + return get_current_task(cpu) LxCurrentFunc() -- cgit v1.2.3-71-gd317 From 526940e3962620f1a24d5e30c3dac7358194d963 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Thu, 6 May 2021 18:05:09 -0700 Subject: scripts/gdb: add lx_current support for arm64 arm64 uses SP_EL0 to save the current task_struct address. While running in EL0, SP_EL0 is clobbered by userspace. So if the upper bit is not 1 (not TTBR1), the current address is invalid. This patch checks the upper bit of SP_EL0, if the upper bit is 1, lx_current() of arm64 will return the derefrence of current task. Otherwise, lx_current() will tell users they are running in userspace(EL0). While arm64 is running in EL0, it is actually pointless to print current task as the memory of kernel space is not accessible in EL0. Link: https://lkml.kernel.org/r/20210314203444.15188-3-song.bao.hua@hisilicon.com Signed-off-by: Barry Song Cc: Jan Kiszka Cc: Jonathan Corbet Cc: Kieran Bingham Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/dev-tools/gdb-kernel-debugging.rst | 2 +- scripts/gdb/linux/cpus.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/Documentation/dev-tools/gdb-kernel-debugging.rst b/Documentation/dev-tools/gdb-kernel-debugging.rst index 1586901b683c..8e0f1fe8d17a 100644 --- a/Documentation/dev-tools/gdb-kernel-debugging.rst +++ b/Documentation/dev-tools/gdb-kernel-debugging.rst @@ -114,7 +114,7 @@ Examples of using the Linux-provided gdb helpers [ 0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved .... -- Examine fields of the current task struct(supported by x86 only):: +- Examine fields of the current task struct(supported by x86 and arm64 only):: (gdb) p $lx_current().pid $1 = 4998 diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py index f382762509d3..15fc4626d236 100644 --- a/scripts/gdb/linux/cpus.py +++ b/scripts/gdb/linux/cpus.py @@ -16,6 +16,9 @@ import gdb from linux import tasks, utils +task_type = utils.CachedType("struct task_struct") + + MAX_CPUS = 4096 @@ -157,9 +160,19 @@ Note that VAR has to be quoted as string.""" PerCpu() def get_current_task(cpu): + task_ptr_type = task_type.get_type().pointer() + if utils.is_target_arch("x86"): var_ptr = gdb.parse_and_eval("¤t_task") return per_cpu(var_ptr, cpu).dereference() + elif utils.is_target_arch("aarch64"): + current_task_addr = gdb.parse_and_eval("$SP_EL0") + if((current_task_addr >> 63) != 0): + current_task = current_task_addr.cast(task_ptr_type) + return current_task.dereference() + else: + raise gdb.GdbError("Sorry, obtaining the current task is not allowed " + "while running in userspace(EL0)") else: raise gdb.GdbError("Sorry, obtaining the current task is not yet " "supported with this arch") -- cgit v1.2.3-71-gd317 From 702850a45a7798031aa06baa46f9fc2cdd1e747e Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Thu, 6 May 2021 18:06:12 -0700 Subject: scripts/spelling.txt: add "overlfow" Add typo "overlfow" for "overflow". This typo was found and fixed in net/sctp/tsnmap.c. Link: https://lore.kernel.org/netdev/20210304055548.56829-1-drew@beagleboard.org/ Link: https://lkml.kernel.org/r/20210304072657.64577-1-drew@beagleboard.org Signed-off-by: Drew Fustini Suggested-by: Kees Cook Reviewed-by: Kees Cook Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/spelling.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/spelling.txt b/scripts/spelling.txt index 7beb4262f719..8fe0283aae4d 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -1027,6 +1027,7 @@ oustanding||outstanding overaall||overall overhread||overhead overlaping||overlapping +overlfow||overflow overide||override overrided||overridden overriden||overridden -- cgit v1.2.3-71-gd317 From a4799be53775bf2fdc810b897fb89dd0c81e6913 Mon Sep 17 00:00:00 2001 From: zuoqilin Date: Thu, 6 May 2021 18:06:15 -0700 Subject: scripts/spelling.txt: Add "diabled" typo Increase "diabled" spelling error check. Link: https://lkml.kernel.org/r/20210304070106.2313-1-zuoqilin1@163.com Signed-off-by: zuoqilin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/spelling.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/spelling.txt b/scripts/spelling.txt index 8fe0283aae4d..2e6a23088e8e 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -480,6 +480,7 @@ devided||divided deviece||device devision||division diable||disable +diabled||disabled dicline||decline dictionnary||dictionary didnt||didn't -- cgit v1.2.3-71-gd317 From d4e3e52b4dd57b1cfd4b43a20976385463e16126 Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Thu, 6 May 2021 18:06:18 -0700 Subject: scripts/spelling.txt: add "overflw" Add typo "overflw" for "overflow". This typo was found and fixed in drivers/clocksource/timer-pistachio.c. Link: https://lore.kernel.org/lkml/20210305090315.384547-1-drew@beagleboard.org/ Link: https://lkml.kernel.org/r/20210305095151.388182-1-drew@beagleboard.org Signed-off-by: Drew Fustini Suggested-by: Gustavo A. R. Silva Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/spelling.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/spelling.txt b/scripts/spelling.txt index 2e6a23088e8e..7b6a01291598 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -1028,6 +1028,7 @@ oustanding||outstanding overaall||overall overhread||overhead overlaping||overlapping +overflw||overflow overlfow||overflow overide||override overrided||overridden -- cgit v1.2.3-71-gd317