summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-01-18 17:57:07 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2024-01-18 17:57:07 -0800
commitb5f66ba2d07180706ffa10df07f202335df190f1 (patch)
tree87db99cd5e7014327479606dee2fe1d827eb8bd0
parent2a668d217676c642bec02ee3b5b73a623f194f7a (diff)
parent6185d32170b683abadddf1e68be998e24f3cc5de (diff)
Merge tag 'kbuild-v6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild
Pull Kbuild updates from Masahiro Yamada: - Make Kconfig parse the input .config more precisely - Support W=c and W=e options for Kconfig - Set Kconfig int/hex symbols to zero if the 'default' property is missing - Add .editorconfig - Add scripts/git.orderFile - Add a script to detect backward-incompatible changes in UAPI headers - Resolve the symlink passed to O= option properly - Use the user-supplied mtime for all files in the builtin initramfs, which provides better reproducible builds - Fix the direct execution of debian/rules for Debian package builds - Use build ID instead of the .gnu_debuglink section for the Debian dbg package * tag 'kbuild-v6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild: (53 commits) kbuild: deb-pkg: use debian/<package> for tmpdir kbuild: deb-pkg: move 'make headers' to build-arch kbuild: deb-pkg: do not search for 'scripts' directory under arch/ kbuild: deb-pkg: use build ID instead of debug link for dbg package kbuild: deb-pkg: use more debhelper commands in builddeb kbuild: deb-pkg: remove unneeded '-f $srctree/Makefile' in debian/rules kbuild: deb-pkg: allow to run debian/rules from output directory kbuild: deb-pkg: set DEB_* variables if debian/rules is directly executed kbuild: deb-pkg: squash scripts/package/deb-build-option to debian/rules kbuild: deb-pkg: factor out common Make options in debian/rules kbuild: deb-pkg: hard-code Build-Depends kbuild: deb-pkg: split debian/copyright from the mkdebian script gen_init_cpio: Apply mtime supplied by user to all file types kbuild: resolve symlinks for O= properly docs: dev-tools: Add UAPI checker documentation check-uapi: Introduce check-uapi.sh scripts: Introduce a default git.orderFile kconfig: WERROR unmet symbol dependency Add .editorconfig file for basic formatting kconfig: Use KCONFIG_CONFIG instead of .config ...
-rw-r--r--.editorconfig32
-rw-r--r--.gitignore1
-rw-r--r--Documentation/dev-tools/checkuapi.rst477
-rw-r--r--Documentation/dev-tools/index.rst1
-rw-r--r--Documentation/process/4.Coding.rst4
-rw-r--r--Documentation/process/coding-style.rst4
-rw-r--r--Makefile23
-rw-r--r--arch/sparc/vdso/Makefile18
-rw-r--r--include/linux/export.h18
-rw-r--r--include/linux/init.h7
-rw-r--r--scripts/Makefile.extrawarn9
-rw-r--r--scripts/Makefile.lib4
-rw-r--r--scripts/Makefile.package28
-rwxr-xr-xscripts/check-uapi.sh573
-rw-r--r--scripts/gdb/linux/tasks.py15
-rw-r--r--scripts/genksyms/genksyms.c22
-rw-r--r--scripts/git.orderFile42
-rw-r--r--scripts/head-object-list.txt1
-rw-r--r--scripts/kconfig/Makefile14
-rw-r--r--scripts/kconfig/conf.c6
-rw-r--r--scripts/kconfig/confdata.c161
-rw-r--r--scripts/kconfig/expr.c1
-rw-r--r--scripts/kconfig/lkc.h2
-rw-r--r--scripts/kconfig/lkc_proto.h7
-rw-r--r--scripts/kconfig/mconf.c56
-rw-r--r--scripts/kconfig/menu.c17
-rw-r--r--scripts/kconfig/mnconf-common.c53
-rw-r--r--scripts/kconfig/mnconf-common.h18
-rw-r--r--scripts/kconfig/nconf.c55
-rw-r--r--scripts/kconfig/symbol.c37
-rw-r--r--scripts/kconfig/util.c3
-rw-r--r--scripts/mod/modpost.c17
-rw-r--r--scripts/mod/modpost.h8
-rwxr-xr-xscripts/package/builddeb106
-rwxr-xr-xscripts/package/buildtar8
-rwxr-xr-xscripts/package/deb-build-option14
-rw-r--r--scripts/package/debian/copyright16
-rwxr-xr-xscripts/package/debian/rules35
-rwxr-xr-xscripts/package/install-extmod-build2
-rw-r--r--scripts/package/kernel.spec6
-rwxr-xr-xscripts/package/mkdebian28
-rw-r--r--scripts/package/snapcraft.template2
-rw-r--r--scripts/recordmcount.c1
-rwxr-xr-xscripts/recordmcount.pl7
-rwxr-xr-xscripts/xz_wrap.sh1
-rw-r--r--usr/gen_init_cpio.c33
46 files changed, 1487 insertions, 506 deletions
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000000..854773350cc5
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,32 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+root = true
+
+[{*.{awk,c,dts,dtsi,dtso,h,mk,s,S},Kconfig,Makefile,Makefile.*}]
+charset = utf-8
+end_of_line = lf
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = tab
+indent_size = 8
+
+[*.{json,py,rs}]
+charset = utf-8
+end_of_line = lf
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+
+# this must be below the general *.py to overwrite it
+[tools/{perf,power,rcu,testing/kunit}/**.py,]
+indent_style = tab
+indent_size = 8
+
+[*.yaml]
+charset = utf-8
+end_of_line = lf
+trim_trailing_whitespace = unset
+insert_final_newline = true
+indent_style = space
+indent_size = 2
diff --git a/.gitignore b/.gitignore
index 98274e1160d7..689a4fa3f547 100644
--- a/.gitignore
+++ b/.gitignore
@@ -96,6 +96,7 @@ modules.order
#
!.clang-format
!.cocciconfig
+!.editorconfig
!.get_maintainer.ignore
!.gitattributes
!.gitignore
diff --git a/Documentation/dev-tools/checkuapi.rst b/Documentation/dev-tools/checkuapi.rst
new file mode 100644
index 000000000000..9072f21b50b0
--- /dev/null
+++ b/Documentation/dev-tools/checkuapi.rst
@@ -0,0 +1,477 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+============
+UAPI Checker
+============
+
+The UAPI checker (``scripts/check-uapi.sh``) is a shell script which
+checks UAPI header files for userspace backwards-compatibility across
+the git tree.
+
+Options
+=======
+
+This section will describe the options with which ``check-uapi.sh``
+can be run.
+
+Usage::
+
+ check-uapi.sh [-b BASE_REF] [-p PAST_REF] [-j N] [-l ERROR_LOG] [-i] [-q] [-v]
+
+Available options::
+
+ -b BASE_REF Base git reference to use for comparison. If unspecified or empty,
+ will use any dirty changes in tree to UAPI files. If there are no
+ dirty changes, HEAD will be used.
+ -p PAST_REF Compare BASE_REF to PAST_REF (e.g. -p v6.1). If unspecified or empty,
+ will use BASE_REF^1. Must be an ancestor of BASE_REF. Only headers
+ that exist on PAST_REF will be checked for compatibility.
+ -j JOBS Number of checks to run in parallel (default: number of CPU cores).
+ -l ERROR_LOG Write error log to file (default: no error log is generated).
+ -i Ignore ambiguous changes that may or may not break UAPI compatibility.
+ -q Quiet operation.
+ -v Verbose operation (print more information about each header being checked).
+
+Environmental args::
+
+ ABIDIFF Custom path to abidiff binary
+ CC C compiler (default is "gcc")
+ ARCH Target architecture of C compiler (default is host arch)
+
+Exit codes::
+
+ 0) Success
+ 1) ABI difference detected
+ 2) Prerequisite not met
+
+Examples
+========
+
+Basic Usage
+-----------
+
+First, let's try making a change to a UAPI header file that obviously
+won't break userspace::
+
+ cat << 'EOF' | patch -l -p1
+ --- a/include/uapi/linux/acct.h
+ +++ b/include/uapi/linux/acct.h
+ @@ -21,7 +21,9 @@
+ #include <asm/param.h>
+ #include <asm/byteorder.h>
+
+ -/*
+ +#define FOO
+ +
+ +/*
+ * comp_t is a 16-bit "floating" point number with a 3-bit base 8
+ * exponent and a 13-bit fraction.
+ * comp2_t is 24-bit with 5-bit base 2 exponent and 20 bit fraction
+ diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
+ EOF
+
+Now, let's use the script to validate::
+
+ % ./scripts/check-uapi.sh
+ Installing user-facing UAPI headers from dirty tree... OK
+ Installing user-facing UAPI headers from HEAD... OK
+ Checking changes to UAPI headers between HEAD and dirty tree...
+ All 912 UAPI headers compatible with x86 appear to be backwards compatible
+
+Let's add another change that *might* break userspace::
+
+ cat << 'EOF' | patch -l -p1
+ --- a/include/uapi/linux/bpf.h
+ +++ b/include/uapi/linux/bpf.h
+ @@ -74,7 +74,7 @@ struct bpf_insn {
+ __u8 dst_reg:4; /* dest register */
+ __u8 src_reg:4; /* source register */
+ __s16 off; /* signed offset */
+ - __s32 imm; /* signed immediate constant */
+ + __u32 imm; /* unsigned immediate constant */
+ };
+
+ /* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */
+ EOF
+
+The script will catch this::
+
+ % ./scripts/check-uapi.sh
+ Installing user-facing UAPI headers from dirty tree... OK
+ Installing user-facing UAPI headers from HEAD... OK
+ Checking changes to UAPI headers between HEAD and dirty tree...
+ ==== ABI differences detected in include/linux/bpf.h from HEAD -> dirty tree ====
+ [C] 'struct bpf_insn' changed:
+ type size hasn't changed
+ 1 data member change:
+ type of '__s32 imm' changed:
+ typedef name changed from __s32 to __u32 at int-ll64.h:27:1
+ underlying type 'int' changed:
+ type name changed from 'int' to 'unsigned int'
+ type size hasn't changed
+ ==================================================================================
+
+ error - 1/912 UAPI headers compatible with x86 appear _not_ to be backwards compatible
+
+In this case, the script is reporting the type change because it could
+break a userspace program that passes in a negative number. Now, let's
+say you know that no userspace program could possibly be using a negative
+value in ``imm``, so changing to an unsigned type there shouldn't hurt
+anything. You can pass the ``-i`` flag to the script to ignore changes
+in which the userspace backwards compatibility is ambiguous::
+
+ % ./scripts/check-uapi.sh -i
+ Installing user-facing UAPI headers from dirty tree... OK
+ Installing user-facing UAPI headers from HEAD... OK
+ Checking changes to UAPI headers between HEAD and dirty tree...
+ All 912 UAPI headers compatible with x86 appear to be backwards compatible
+
+Now, let's make a similar change that *will* break userspace::
+
+ cat << 'EOF' | patch -l -p1
+ --- a/include/uapi/linux/bpf.h
+ +++ b/include/uapi/linux/bpf.h
+ @@ -71,8 +71,8 @@ enum {
+
+ struct bpf_insn {
+ __u8 code; /* opcode */
+ - __u8 dst_reg:4; /* dest register */
+ __u8 src_reg:4; /* source register */
+ + __u8 dst_reg:4; /* dest register */
+ __s16 off; /* signed offset */
+ __s32 imm; /* signed immediate constant */
+ };
+ EOF
+
+Since we're re-ordering an existing struct member, there's no ambiguity,
+and the script will report the breakage even if you pass ``-i``::
+
+ % ./scripts/check-uapi.sh -i
+ Installing user-facing UAPI headers from dirty tree... OK
+ Installing user-facing UAPI headers from HEAD... OK
+ Checking changes to UAPI headers between HEAD and dirty tree...
+ ==== ABI differences detected in include/linux/bpf.h from HEAD -> dirty tree ====
+ [C] 'struct bpf_insn' changed:
+ type size hasn't changed
+ 2 data member changes:
+ '__u8 dst_reg' offset changed from 8 to 12 (in bits) (by +4 bits)
+ '__u8 src_reg' offset changed from 12 to 8 (in bits) (by -4 bits)
+ ==================================================================================
+
+ error - 1/912 UAPI headers compatible with x86 appear _not_ to be backwards compatible
+
+Let's commit the breaking change, then commit the innocuous change::
+
+ % git commit -m 'Breaking UAPI change' include/uapi/linux/bpf.h
+ [detached HEAD f758e574663a] Breaking UAPI change
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+ % git commit -m 'Innocuous UAPI change' include/uapi/linux/acct.h
+ [detached HEAD 2e87df769081] Innocuous UAPI change
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+Now, let's run the script again with no arguments::
+
+ % ./scripts/check-uapi.sh
+ Installing user-facing UAPI headers from HEAD... OK
+ Installing user-facing UAPI headers from HEAD^1... OK
+ Checking changes to UAPI headers between HEAD^1 and HEAD...
+ All 912 UAPI headers compatible with x86 appear to be backwards compatible
+
+It doesn't catch any breaking change because, by default, it only
+compares ``HEAD`` to ``HEAD^1``. The breaking change was committed on
+``HEAD~2``. If we wanted the search scope to go back further, we'd have to
+use the ``-p`` option to pass a different past reference. In this case,
+let's pass ``-p HEAD~2`` to the script so it checks UAPI changes between
+``HEAD~2`` and ``HEAD``::
+
+ % ./scripts/check-uapi.sh -p HEAD~2
+ Installing user-facing UAPI headers from HEAD... OK
+ Installing user-facing UAPI headers from HEAD~2... OK
+ Checking changes to UAPI headers between HEAD~2 and HEAD...
+ ==== ABI differences detected in include/linux/bpf.h from HEAD~2 -> HEAD ====
+ [C] 'struct bpf_insn' changed:
+ type size hasn't changed
+ 2 data member changes:
+ '__u8 dst_reg' offset changed from 8 to 12 (in bits) (by +4 bits)
+ '__u8 src_reg' offset changed from 12 to 8 (in bits) (by -4 bits)
+ ==============================================================================
+
+ error - 1/912 UAPI headers compatible with x86 appear _not_ to be backwards compatible
+
+Alternatively, we could have also run with ``-b HEAD~``. This would set the
+base reference to ``HEAD~`` so then the script would compare it to ``HEAD~^1``.
+
+Architecture-specific Headers
+-----------------------------
+
+Consider this change::
+
+ cat << 'EOF' | patch -l -p1
+ --- a/arch/arm64/include/uapi/asm/sigcontext.h
+ +++ b/arch/arm64/include/uapi/asm/sigcontext.h
+ @@ -70,6 +70,7 @@ struct sigcontext {
+ struct _aarch64_ctx {
+ __u32 magic;
+ __u32 size;
+ + __u32 new_var;
+ };
+
+ #define FPSIMD_MAGIC 0x46508001
+ EOF
+
+This is a change to an arm64-specific UAPI header file. In this example, I'm
+running the script from an x86 machine with an x86 compiler, so, by default,
+the script only checks x86-compatible UAPI header files::
+
+ % ./scripts/check-uapi.sh
+ Installing user-facing UAPI headers from dirty tree... OK
+ Installing user-facing UAPI headers from HEAD... OK
+ No changes to UAPI headers were applied between HEAD and dirty tree
+
+With an x86 compiler, we can't check header files in ``arch/arm64``, so the
+script doesn't even try.
+
+If we want to check the header file, we'll have to use an arm64 compiler and
+set ``ARCH`` accordingly::
+
+ % CC=aarch64-linux-gnu-gcc ARCH=arm64 ./scripts/check-uapi.sh
+ Installing user-facing UAPI headers from dirty tree... OK
+ Installing user-facing UAPI headers from HEAD... OK
+ Checking changes to UAPI headers between HEAD and dirty tree...
+ ==== ABI differences detected in include/asm/sigcontext.h from HEAD -> dirty tree ====
+ [C] 'struct _aarch64_ctx' changed:
+ type size changed from 64 to 96 (in bits)
+ 1 data member insertion:
+ '__u32 new_var', at offset 64 (in bits) at sigcontext.h:73:1
+ -- snip --
+ [C] 'struct zt_context' changed:
+ type size changed from 128 to 160 (in bits)
+ 2 data member changes (1 filtered):
+ '__u16 nregs' offset changed from 64 to 96 (in bits) (by +32 bits)
+ '__u16 __reserved[3]' offset changed from 80 to 112 (in bits) (by +32 bits)
+ =======================================================================================
+
+ error - 1/884 UAPI headers compatible with arm64 appear _not_ to be backwards compatible
+
+We can see with ``ARCH`` and ``CC`` set properly for the file, the ABI
+change is reported properly. Also notice that the total number of UAPI
+header files checked by the script changes. This is because the number
+of headers installed for arm64 platforms is different than x86.
+
+Cross-Dependency Breakages
+--------------------------
+
+Consider this change::
+
+ cat << 'EOF' | patch -l -p1
+ --- a/include/uapi/linux/types.h
+ +++ b/include/uapi/linux/types.h
+ @@ -52,7 +52,7 @@ typedef __u32 __bitwise __wsum;
+ #define __aligned_be64 __be64 __attribute__((aligned(8)))
+ #define __aligned_le64 __le64 __attribute__((aligned(8)))
+
+ -typedef unsigned __bitwise __poll_t;
+ +typedef unsigned short __bitwise __poll_t;
+
+ #endif /* __ASSEMBLY__ */
+ #endif /* _UAPI_LINUX_TYPES_H */
+ EOF
+
+Here, we're changing a ``typedef`` in ``types.h``. This doesn't break
+a UAPI in ``types.h``, but other UAPIs in the tree may break due to
+this change::
+
+ % ./scripts/check-uapi.sh
+ Installing user-facing UAPI headers from dirty tree... OK
+ Installing user-facing UAPI headers from HEAD... OK
+ Checking changes to UAPI headers between HEAD and dirty tree...
+ ==== ABI differences detected in include/linux/eventpoll.h from HEAD -> dirty tree ====
+ [C] 'struct epoll_event' changed:
+ type size changed from 96 to 80 (in bits)
+ 2 data member changes:
+ type of '__poll_t events' changed:
+ underlying type 'unsigned int' changed:
+ type name changed from 'unsigned int' to 'unsigned short int'
+ type size changed from 32 to 16 (in bits)
+ '__u64 data' offset changed from 32 to 16 (in bits) (by -16 bits)
+ ========================================================================================
+ include/linux/eventpoll.h did not change between HEAD and dirty tree...
+ It's possible a change to one of the headers it includes caused this error:
+ #include <linux/fcntl.h>
+ #include <linux/types.h>
+
+Note that the script noticed the failing header file did not change,
+so it assumes one of its includes must have caused the breakage. Indeed,
+we can see ``linux/types.h`` is used from ``eventpoll.h``.
+
+UAPI Header Removals
+--------------------
+
+Consider this change::
+
+ cat << 'EOF' | patch -l -p1
+ diff --git a/include/uapi/asm-generic/Kbuild b/include/uapi/asm-generic/Kbuild
+ index ebb180aac74e..a9c88b0a8b3b 100644
+ --- a/include/uapi/asm-generic/Kbuild
+ +++ b/include/uapi/asm-generic/Kbuild
+ @@ -31,6 +31,6 @@ mandatory-y += stat.h
+ mandatory-y += statfs.h
+ mandatory-y += swab.h
+ mandatory-y += termbits.h
+ -mandatory-y += termios.h
+ +#mandatory-y += termios.h
+ mandatory-y += types.h
+ mandatory-y += unistd.h
+ EOF
+
+This script removes a UAPI header file from the install list. Let's run
+the script::
+
+ % ./scripts/check-uapi.sh
+ Installing user-facing UAPI headers from dirty tree... OK
+ Installing user-facing UAPI headers from HEAD... OK
+ Checking changes to UAPI headers between HEAD and dirty tree...
+ ==== UAPI header include/asm/termios.h was removed between HEAD and dirty tree ====
+
+ error - 1/912 UAPI headers compatible with x86 appear _not_ to be backwards compatible
+
+Removing a UAPI header is considered a breaking change, and the script
+will flag it as such.
+
+Checking Historic UAPI Compatibility
+------------------------------------
+
+You can use the ``-b`` and ``-p`` options to examine different chunks of your
+git tree. For example, to check all changed UAPI header files between tags
+v6.0 and v6.1, you'd run::
+
+ % ./scripts/check-uapi.sh -b v6.1 -p v6.0
+ Installing user-facing UAPI headers from v6.1... OK
+ Installing user-facing UAPI headers from v6.0... OK
+ Checking changes to UAPI headers between v6.0 and v6.1...
+
+ --- snip ---
+ error - 37/907 UAPI headers compatible with x86 appear _not_ to be backwards compatible
+
+Note: Before v5.3, a header file needed by the script is not present,
+so the script is unable to check changes before then.
+
+You'll notice that the script detected many UAPI changes that are not
+backwards compatible. Knowing that kernel UAPIs are supposed to be stable
+forever, this is an alarming result. This brings us to the next section:
+caveats.
+
+Caveats
+=======
+
+The UAPI checker makes no assumptions about the author's intention, so some
+types of changes may be flagged even though they intentionally break UAPI.
+
+Removals For Refactoring or Deprecation
+---------------------------------------
+
+Sometimes drivers for very old hardware are removed, such as in this example::
+
+ % ./scripts/check-uapi.sh -b ba47652ba655
+ Installing user-facing UAPI headers from ba47652ba655... OK
+ Installing user-facing UAPI headers from ba47652ba655^1... OK
+ Checking changes to UAPI headers between ba47652ba655^1 and ba47652ba655...
+ ==== UAPI header include/linux/meye.h was removed between ba47652ba655^1 and ba47652ba655 ====
+
+ error - 1/910 UAPI headers compatible with x86 appear _not_ to be backwards compatible
+
+The script will always flag removals (even if they're intentional).
+
+Struct Expansions
+-----------------
+
+Depending on how a structure is handled in kernelspace, a change which
+expands a struct could be non-breaking.
+
+If a struct is used as the argument to an ioctl, then the kernel driver
+must be able to handle ioctl commands of any size. Beyond that, you need
+to be careful when copying data from the user. Say, for example, that
+``struct foo`` is changed like this::
+
+ struct foo {
+ __u64 a; /* added in version 1 */
+ + __u32 b; /* added in version 2 */
+ + __u32 c; /* added in version 2 */
+ }
+
+By default, the script will flag this kind of change for further review::
+
+ [C] 'struct foo' changed:
+ type size changed from 64 to 128 (in bits)
+ 2 data member insertions:
+ '__u32 b', at offset 64 (in bits)
+ '__u32 c', at offset 96 (in bits)
+
+However, it is possible that this change was made safely.
+
+If a userspace program was built with version 1, it will think
+``sizeof(struct foo)`` is 8. That size will be encoded in the
+ioctl value that gets sent to the kernel. If the kernel is built
+with version 2, it will think the ``sizeof(struct foo)`` is 16.
+
+The kernel can use the ``_IOC_SIZE`` macro to get the size encoded
+in the ioctl code that the user passed in and then use
+``copy_struct_from_user()`` to safely copy the value::
+
+ int handle_ioctl(unsigned long cmd, unsigned long arg)
+ {
+ switch _IOC_NR(cmd) {
+ 0x01: {
+ struct foo my_cmd; /* size 16 in the kernel */
+
+ ret = copy_struct_from_user(&my_cmd, arg, sizeof(struct foo), _IOC_SIZE(cmd));
+ ...
+
+``copy_struct_from_user`` will zero the struct in the kernel and then copy
+only the bytes passed in from the user (leaving new members zeroized).
+If the user passed in a larger struct, the extra members are ignored.
+
+If you know this situation is accounted for in the kernel code, you can
+pass ``-i`` to the script, and struct expansions like this will be ignored.
+
+Flex Array Migration
+--------------------
+
+While the script handles expansion into an existing flex array, it does
+still flag initial migration to flex arrays from 1-element fake flex
+arrays. For example::
+
+ struct foo {
+ __u32 x;
+ - __u32 flex[1]; /* fake flex */
+ + __u32 flex[]; /* real flex */
+ };
+
+This change would be flagged by the script::
+
+ [C] 'struct foo' changed:
+ type size changed from 64 to 32 (in bits)
+ 1 data member change:
+ type of '__u32 flex[1]' changed:
+ type name changed from '__u32[1]' to '__u32[]'
+ array type size changed from 32 to 'unknown'
+ array type subrange 1 changed length from 1 to 'unknown'
+
+At this time, there's no way to filter these types of changes, so be
+aware of this possible false positive.
+
+Summary
+-------
+
+While many types of false positives are filtered out by the script,
+it's possible there are some cases where the script flags a change
+which does not break UAPI. It's also possible a change which *does*
+break userspace would not be flagged by this script. While the script
+has been run on much of the kernel history, there could still be corner
+cases that are not accounted for.
+
+The intention is for this script to be used as a quick check for
+maintainers or automated tooling, not as the end-all authority on
+patch compatibility. It's best to remember: use your best judgment
+(and ideally a unit test in userspace) to make sure your UAPI changes
+are backwards-compatible!
diff --git a/Documentation/dev-tools/index.rst b/Documentation/dev-tools/index.rst
index 3d2286c683bc..efa49cdc8e2e 100644
--- a/Documentation/dev-tools/index.rst
+++ b/Documentation/dev-tools/index.rst
@@ -31,6 +31,7 @@ Documentation/dev-tools/testing-overview.rst
kselftest
kunit/index
ktap
+ checkuapi
.. only:: subproject and html
diff --git a/Documentation/process/4.Coding.rst b/Documentation/process/4.Coding.rst
index 1f0d81f44e14..c2046dec0c2f 100644
--- a/Documentation/process/4.Coding.rst
+++ b/Documentation/process/4.Coding.rst
@@ -66,6 +66,10 @@ for aligning variables/macros, for reflowing text and other similar tasks.
See the file :ref:`Documentation/process/clang-format.rst <clangformat>`
for more details.
+Some basic editor settings, such as indentation and line endings, will be
+set automatically if you are using an editor that is compatible with
+EditorConfig. See the official EditorConfig website for more information:
+https://editorconfig.org/
Abstraction layers
******************
diff --git a/Documentation/process/coding-style.rst b/Documentation/process/coding-style.rst
index 6db37a46d305..c48382c6b477 100644
--- a/Documentation/process/coding-style.rst
+++ b/Documentation/process/coding-style.rst
@@ -735,6 +735,10 @@ for aligning variables/macros, for reflowing text and other similar tasks.
See the file :ref:`Documentation/process/clang-format.rst <clangformat>`
for more details.
+Some basic editor settings, such as indentation and line endings, will be
+set automatically if you are using an editor that is compatible with
+EditorConfig. See the official EditorConfig website for more information:
+https://editorconfig.org/
10) Kconfig configuration files
-------------------------------
diff --git a/Makefile b/Makefile
index f1b2fd977275..e5321e45e4e5 100644
--- a/Makefile
+++ b/Makefile
@@ -155,6 +155,15 @@ endif
export KBUILD_EXTMOD
+# backward compatibility
+KBUILD_EXTRA_WARN ?= $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)
+
+ifeq ("$(origin W)", "command line")
+ KBUILD_EXTRA_WARN := $(W)
+endif
+
+export KBUILD_EXTRA_WARN
+
# Kbuild will save output files in the current working directory.
# This does not need to match to the root of the kernel source tree.
#
@@ -181,14 +190,11 @@ ifeq ("$(origin O)", "command line")
endif
ifneq ($(KBUILD_OUTPUT),)
-# Make's built-in functions such as $(abspath ...), $(realpath ...) cannot
-# expand a shell special character '~'. We use a somewhat tedious way here.
-abs_objtree := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) && pwd)
-$(if $(abs_objtree),, \
- $(error failed to create output directory "$(KBUILD_OUTPUT)"))
-
+# $(realpath ...) gets empty if the path does not exist. Run 'mkdir -p' first.
+$(shell mkdir -p "$(KBUILD_OUTPUT)")
# $(realpath ...) resolves symlinks
-abs_objtree := $(realpath $(abs_objtree))
+abs_objtree := $(realpath $(KBUILD_OUTPUT))
+$(if $(abs_objtree),,$(error failed to create output directory "$(KBUILD_OUTPUT)"))
endif # ifneq ($(KBUILD_OUTPUT),)
ifneq ($(words $(subst :, ,$(abs_srctree))), 1)
@@ -609,8 +615,6 @@ export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL KBUILD_RUSTFLAGS_KERNEL
export RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o \
-name CVS -o -name .pc -o -name .hg -o -name .git \) \
-prune -o
-export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn \
- --exclude CVS --exclude .pc --exclude .hg --exclude .git
# ===========================================================================
# Rules shared between *config targets and build targets
@@ -1662,6 +1666,7 @@ help:
@echo ' 1: warnings which may be relevant and do not occur too often'
@echo ' 2: warnings which occur quite often but may still be relevant'
@echo ' 3: more obscure warnings, can most likely be ignored'
+ @echo ' c: extra checks in the configuration stage (Kconfig)'
@echo ' e: warnings are being treated as errors'
@echo ' Multiple levels can be combined with W=12 or W=123'
@$(if $(dtstree), \
diff --git a/arch/sparc/vdso/Makefile b/arch/sparc/vdso/Makefile
index d08c3a0443f3..7f5eedf1f5e0 100644
--- a/arch/sparc/vdso/Makefile
+++ b/arch/sparc/vdso/Makefile
@@ -3,9 +3,6 @@
# Building vDSO images for sparc.
#
-VDSO64-$(CONFIG_SPARC64) := y
-VDSOCOMPAT-$(CONFIG_COMPAT) := y
-
# files to link into the vdso
vobjs-y := vdso-note.o vclock_gettime.o
@@ -13,22 +10,15 @@ vobjs-y := vdso-note.o vclock_gettime.o
obj-y += vma.o
# vDSO images to build
-vdso_img-$(VDSO64-y) += 64
-vdso_img-$(VDSOCOMPAT-y) += 32
+obj-$(CONFIG_SPARC64) += vdso-image-64.o
+obj-$(CONFIG_COMPAT) += vdso-image-32.o
-vobjs := $(foreach F,$(vobjs-y),$(obj)/$F)
+vobjs := $(addprefix $(obj)/, $(vobjs-y))
$(obj)/vdso.o: $(obj)/vdso.so
targets += vdso.lds $(vobjs-y)
-
-# Build the vDSO image C files and link them in.
-vdso_img_objs := $(vdso_img-y:%=vdso-image-%.o)
-vdso_img_cfiles := $(vdso_img-y:%=vdso-image-%.c)
-vdso_img_sodbg := $(vdso_img-y:%=vdso%.so.dbg)
-obj-y += $(vdso_img_objs)
-targets += $(vdso_img_cfiles)
-targets += $(vdso_img_sodbg) $(vdso_img-y:%=vdso%.so)
+targets += $(foreach x, 32 64, vdso-image-$(x).c vdso$(x).so vdso$(x).so.dbg)
CPPFLAGS_vdso.lds += -P -C
diff --git a/include/linux/export.h b/include/linux/export.h
index 9911508a9604..0bbd02fd351d 100644
--- a/include/linux/export.h
+++ b/include/linux/export.h
@@ -7,15 +7,6 @@
#include <linux/stringify.h>
/*
- * Export symbols from the kernel to modules. Forked from module.h
- * to reduce the amount of pointless cruft we feed to gcc when only
- * exporting a simple symbol or two.
- *
- * Try not to add #includes here. It slows compilation and makes kernel
- * hackers place grumpy comments in header files.
- */
-
-/*
* This comment block is used by fixdep. Please do not remove.
*
* When CONFIG_MODVERSIONS is changed from n to y, all source files having
@@ -23,15 +14,6 @@
* side effect of the *.o build rule.
*/
-#ifndef __ASSEMBLY__
-#ifdef MODULE
-extern struct module __this_module;
-#define THIS_MODULE (&__this_module)
-#else
-#define THIS_MODULE ((struct module *)0)
-#endif
-#endif /* __ASSEMBLY__ */
-
#ifdef CONFIG_64BIT
#define __EXPORT_SYMBOL_REF(sym) \
.balign 8 ASM_NL \
diff --git a/include/linux/init.h b/include/linux/init.h
index 01b52c9c7526..3fa3f6241350 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -179,6 +179,13 @@ extern void (*late_time_init)(void);
extern bool initcall_debug;
+#ifdef MODULE
+extern struct module __this_module;
+#define THIS_MODULE (&__this_module)
+#else
+#define THIS_MODULE ((struct module *)0)
+#endif
+
#endif
#ifndef MODULE
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
index c9725685aa76..9b7a37ae28a8 100644
--- a/scripts/Makefile.extrawarn
+++ b/scripts/Makefile.extrawarn
@@ -82,15 +82,6 @@ KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init)
# Warn if there is an enum types mismatch
KBUILD_CFLAGS += $(call cc-option,-Wenum-conversion)
-# backward compatibility
-KBUILD_EXTRA_WARN ?= $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)
-
-ifeq ("$(origin W)", "command line")
- KBUILD_EXTRA_WARN := $(W)
-endif
-
-export KBUILD_EXTRA_WARN
-
#
# W=1 - warnings which may be relevant and do not occur too often
#
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 1a965fe68e01..cd5b181060f1 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -83,8 +83,8 @@ dtb-$(CONFIG_OF_ALL_DTBS) += $(dtb-)
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)))
+# Base DTB that overlay is applied onto
+base-dtb-y := $(filter %.dtb, $(call real-search, $(multi-dtb-y), .dtb, -dtbs))
always-y += $(dtb-y)
diff --git a/scripts/Makefile.package b/scripts/Makefile.package
index 3addd1c0b989..a81dfb1f5181 100644
--- a/scripts/Makefile.package
+++ b/scripts/Makefile.package
@@ -4,27 +4,6 @@
include $(srctree)/scripts/Kbuild.include
include $(srctree)/scripts/Makefile.lib
-KERNELPATH := kernel-$(subst -,_,$(KERNELRELEASE))
-# Include only those top-level files that are needed by make, plus the GPL copy
-TAR_CONTENT := Documentation LICENSES arch block certs crypto drivers fs \
- include init io_uring ipc kernel lib mm net rust \
- samples scripts security sound tools usr virt \
- .config Makefile \
- Kbuild Kconfig COPYING $(wildcard localversion*)
-
-quiet_cmd_src_tar = TAR $(2).tar.gz
- cmd_src_tar = \
-if test "$(objtree)" != "$(srctree)"; then \
- echo >&2; \
- echo >&2 " ERROR:"; \
- echo >&2 " Building source tarball is not possible outside the"; \
- echo >&2 " kernel source tree. Don't set KBUILD_OUTPUT"; \
- echo >&2; \
- false; \
-fi ; \
-tar -I $(KGZIP) -c $(RCS_TAR_IGNORE) -f $(2).tar.gz \
- --transform 's:^:$(2)/:S' $(TAR_CONTENT) $(3)
-
# Git
# ---------------------------------------------------------------------------
@@ -130,8 +109,6 @@ debian-orig: linux.tar$(debian-orig-suffix) debian
cp $< ../$(orig-name); \
fi
-KBUILD_PKG_ROOTCMD ?= 'fakeroot -u'
-
PHONY += deb-pkg srcdeb-pkg bindeb-pkg
deb-pkg: private build-type := source,binary
@@ -146,7 +123,7 @@ deb-pkg srcdeb-pkg bindeb-pkg:
$(if $(findstring source, $(build-type)), \
--unsigned-source --compression=$(KDEB_SOURCE_COMPRESS)) \
$(if $(findstring binary, $(build-type)), \
- --rules-file='$(MAKE) -f debian/rules' --jobs=1 -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch), \
+ -R'$(MAKE) -f debian/rules' -j1 -a$$(cat debian/arch), \
--no-check-builddeps) \
$(DPKG_FLAGS))
@@ -157,9 +134,8 @@ snap-pkg:
rm -rf $(objtree)/snap
mkdir $(objtree)/snap
$(MAKE) clean
- $(call cmd,src_tar,$(KERNELPATH))
sed "s@KERNELRELEASE@$(KERNELRELEASE)@; \
- s@SRCTREE@$(shell realpath $(KERNELPATH).tar.gz)@" \
+ s@SRCTREE@$(abs_srctree)@" \
$(srctree)/scripts/package/snapcraft.template > \
$(objtree)/snap/snapcraft.yaml
cd $(objtree)/snap && \
diff --git a/scripts/check-uapi.sh b/scripts/check-uapi.sh
new file mode 100755
index 000000000000..955581735cb3
--- /dev/null
+++ b/scripts/check-uapi.sh
@@ -0,0 +1,573 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0-only
+# Script to check commits for UAPI backwards compatibility
+
+set -o errexit
+set -o pipefail
+
+print_usage() {
+ name=$(basename "$0")
+ cat << EOF
+$name - check for UAPI header stability across Git commits
+
+By default, the script will check to make sure the latest commit (or current
+dirty changes) did not introduce ABI changes when compared to HEAD^1. You can
+check against additional commit ranges with the -b and -p options.
+
+The script will not check UAPI headers for architectures other than the one
+defined in ARCH.
+
+Usage: $name [-b BASE_REF] [-p PAST_REF] [-j N] [-l ERROR_LOG] [-i] [-q] [-v]
+
+Options:
+ -b BASE_REF Base git reference to use for comparison. If unspecified or empty,
+ will use any dirty changes in tree to UAPI files. If there are no
+ dirty changes, HEAD will be used.
+ -p PAST_REF Compare BASE_REF to PAST_REF (e.g. -p v6.1). If unspecified or empty,
+ will use BASE_REF^1. Must be an ancestor of BASE_REF. Only headers
+ that exist on PAST_REF will be checked for compatibility.
+ -j JOBS Number of checks to run in parallel (default: number of CPU cores).
+ -l ERROR_LOG Write error log to file (default: no error log is generated).
+ -i Ignore ambiguous changes that may or may not break UAPI compatibility.
+ -q Quiet operation.
+ -v Verbose operation (print more information about each header being checked).
+
+Environmental args:
+ ABIDIFF Custom path to abidiff binary
+ CC C compiler (default is "gcc")
+ ARCH Target architecture for the UAPI check (default is host arch)
+
+Exit codes:
+ $SUCCESS) Success
+ $FAIL_ABI) ABI difference detected
+ $FAIL_PREREQ) Prerequisite not met
+EOF
+}
+
+readonly SUCCESS=0
+readonly FAIL_ABI=1
+readonly FAIL_PREREQ=2
+
+# Print to stderr
+eprintf() {
+ # shellcheck disable=SC2059
+ printf "$@" >&2
+}
+
+# Expand an array with a specific character (similar to Python string.join())
+join() {
+ local IFS="$1"
+ shift
+ printf "%s" "$*"
+}
+
+# Create abidiff suppressions
+gen_suppressions() {
+ # Common enum variant names which we don't want to worry about
+ # being shifted when new variants are added.
+ local -a enum_regex=(
+ ".*_AFTER_LAST$"
+ ".*_CNT$"
+ ".*_COUNT$"
+ ".*_END$"
+ ".*_LAST$"
+ ".*_MASK$"
+ ".*_MAX$"
+ ".*_MAX_BIT$"
+ ".*_MAX_BPF_ATTACH_TYPE$"
+ ".*_MAX_ID$"
+ ".*_MAX_SHIFT$"
+ ".*_NBITS$"
+ ".*_NETDEV_NUMHOOKS$"
+ ".*_NFT_META_IIFTYPE$"
+ ".*_NL80211_ATTR$"
+ ".*_NLDEV_NUM_OPS$"
+ ".*_NUM$"
+ ".*_NUM_ELEMS$"
+ ".*_NUM_IRQS$"
+ ".*_SIZE$"
+ ".*_TLSMAX$"
+ "^MAX_.*"
+ "^NUM_.*"
+ )
+
+ # Common padding field names which can be expanded into
+ # without worrying about users.
+ local -a padding_regex=(
+ ".*end$"
+ ".*pad$"
+ ".*pad[0-9]?$"
+ ".*pad_[0-9]?$"
+ ".*padding$"
+ ".*padding[0-9]?$"
+ ".*padding_[0-9]?$"
+ ".*res$"
+ ".*resv$"
+ ".*resv[0-9]?$"
+ ".*resv_[0-9]?$"
+ ".*reserved$"
+ ".*reserved[0-9]?$"
+ ".*reserved_[0-9]?$"
+ ".*rsvd[0-9]?$"
+ ".*unused$"
+ )
+
+ cat << EOF
+[suppress_type]
+ type_kind = enum
+ changed_enumerators_regexp = $(join , "${enum_regex[@]}")
+EOF
+
+ for p in "${padding_regex[@]}"; do
+ cat << EOF
+[suppress_type]
+ type_kind = struct
+ has_data_member_inserted_at = offset_of_first_data_member_regexp(${p})
+EOF
+ done
+
+if [ "$IGNORE_AMBIGUOUS_CHANGES" = "true" ]; then
+ cat << EOF
+[suppress_type]
+ type_kind = struct
+ has_data_member_inserted_at = end
+ has_size_change = yes
+EOF
+fi
+}
+
+# Check if git tree is dirty
+tree_is_dirty() {
+ ! git diff --quiet
+}
+
+# Get list of files installed in $ref
+get_file_list() {
+ local -r ref="$1"
+ local -r tree="$(get_header_tree "$ref")"
+
+ # Print all installed headers, filtering out ones that can't be compiled
+ find "$tree" -type f -name '*.h' -printf '%P\n' | grep -v -f "$INCOMPAT_LIST"
+}
+
+# Add to the list of incompatible headers
+add_to_incompat_list() {
+ local -r ref="$1"
+
+ # Start with the usr/include/Makefile to get a list of the headers
+ # that don't compile using this method.
+ if [ ! -f usr/include/Makefile ]; then
+ eprintf "error - no usr/include/Makefile present at %s\n" "$ref"
+ eprintf "Note: usr/include/Makefile was added in the v5.3 kernel release\n"
+ exit "$FAIL_PREREQ"
+ fi
+ {
+ # shellcheck disable=SC2016
+ printf 'all: ; @echo $(no-header-test)\n'
+ cat usr/include/Makefile
+ } | SRCARCH="$ARCH" make --always-make -f - | tr " " "\n" \
+ | grep -v "asm-generic" >> "$INCOMPAT_LIST"
+
+ # The makefile also skips all asm-generic files, but prints "asm-generic/%"
+ # which won't work for our grep match. Instead, print something grep will match.
+ printf "asm-generic/.*\.h\n" >> "$INCOMPAT_LIST"
+}
+
+# Compile the simple test app
+do_compile() {
+ local -r inc_dir="$1"
+ local -r header="$2"
+ local -r out="$3"
+ printf "int main(void) { return 0; }\n" | \
+ "$CC" -c \
+ -o "$out" \
+ -x c \
+ -O0 \
+ -std=c90 \
+ -fno-eliminate-unused-debug-types \
+ -g \
+ "-I${inc_dir}" \
+ -include "$header" \
+ -
+}
+
+# Run make headers_install
+run_make_headers_install() {
+ local -r ref="$1"
+ local -r install_dir="$(get_header_tree "$ref")"
+ make -j "$MAX_THREADS" ARCH="$ARCH" INSTALL_HDR_PATH="$install_dir" \
+ headers_install > /dev/null
+}
+
+# Install headers for both git refs
+install_headers() {
+ local -r base_ref="$1"
+ local -r past_ref="$2"
+
+ for ref in "$base_ref" "$past_ref"; do
+ printf "Installing user-facing UAPI headers from %s... " "${ref:-dirty tree}"
+ if [ -n "$ref" ]; then
+ git archive --format=tar --prefix="${ref}-archive/" "$ref" \
+ | (cd "$TMP_DIR" && tar xf -)
+ (
+ cd "${TMP_DIR}/${ref}-archive"
+ run_make_headers_install "$ref"
+ add_to_incompat_list "$ref" "$INCOMPAT_LIST"
+ )
+ else
+ run_make_headers_install "$ref"
+ add_to_incompat_list "$ref" "$INCOMPAT_LIST"
+ fi
+ printf "OK\n"
+ done
+ sort -u -o "$INCOMPAT_LIST" "$INCOMPAT_LIST"
+ sed -i -e '/^$/d' "$INCOMPAT_LIST"
+}
+
+# Print the path to the headers_install tree for a given ref
+get_header_tree() {
+ local -r ref="$1"
+ printf "%s" "${TMP_DIR}/${ref}/usr"
+}
+
+# Check file list for UAPI compatibility
+check_uapi_files() {
+ local -r base_ref="$1"
+ local -r past_ref="$2"
+ local -r abi_error_log="$3"
+
+ local passed=0;
+ local failed=0;
+ local -a threads=()
+ set -o errexit
+
+ printf "Checking changes to UAPI headers between %s and %s...\n" "$past_ref" "${base_ref:-dirty tree}"
+ # Loop over all UAPI headers that were installed by $past_ref (if they only exist on $base_ref,
+ # there's no way they're broken and no way to compare anyway)
+ while read -r file; do
+ if [ "${#threads[@]}" -ge "$MAX_THREADS" ]; then
+ if wait "${threads[0]}"; then
+ passed=$((passed + 1))
+ else
+ failed=$((failed + 1))
+ fi
+ threads=("${threads[@]:1}")
+ fi
+
+ check_individual_file "$base_ref" "$past_ref" "$file" &
+ threads+=("$!")
+ done < <(get_file_list "$past_ref")
+
+ for t in "${threads[@]}"; do
+ if wait "$t"; then
+ passed=$((passed + 1))
+ else
+ failed=$((failed + 1))
+ fi
+ done
+
+ if [ -n "$abi_error_log" ]; then
+ printf 'Generated by "%s %s" from git ref %s\n\n' \
+ "$0" "$*" "$(git rev-parse HEAD)" > "$abi_error_log"
+ fi
+
+ while read -r error_file; do
+ {
+ cat "$error_file"
+ printf "\n\n"
+ } | tee -a "${abi_error_log:-/dev/null}" >&2
+ done < <(find "$TMP_DIR" -type f -name '*.error' | sort)
+
+ total="$((passed + failed))"
+ if [ "$failed" -gt 0 ]; then
+ eprintf "error - %d/%d UAPI headers compatible with %s appear _not_ to be backwards compatible\n" \
+ "$failed" "$total" "$ARCH"
+ if [ -n "$abi_error_log" ]; then
+ eprintf "Failure summary saved to %s\n" "$abi_error_log"
+ fi
+ else
+ printf "All %d UAPI headers compatible with %s appear to be backwards compatible\n" \
+ "$total" "$ARCH"
+ fi
+
+ return "$failed"
+}
+
+# Check an individual file for UAPI compatibility
+check_individual_file() {
+ local -r base_ref="$1"
+ local -r past_ref="$2"
+ local -r file="$3"
+
+ local -r base_header="$(get_header_tree "$base_ref")/${file}"
+ local -r past_header="$(get_header_tree "$past_ref")/${file}"
+
+ if [ ! -f "$base_header" ]; then
+ mkdir -p "$(dirname "$base_header")"
+ printf "==== UAPI header %s was removed between %s and %s ====" \
+ "$file" "$past_ref" "$base_ref" \
+ > "${base_header}.error"
+ return 1
+ fi
+
+ compare_abi "$file" "$base_header" "$past_header" "$base_ref" "$past_ref"
+}
+
+# Perform the A/B compilation and compare output ABI
+compare_abi() {
+ local -r file="$1"
+ local -r base_header="$2"
+ local -r past_header="$3"
+ local -r base_ref="$4"
+ local -r past_ref="$5"
+ local -r log="${TMP_DIR}/log/${file}.log"
+ local -r error_log="${TMP_DIR}/log/${file}.error"
+
+ mkdir -p "$(dirname "$log")"
+
+ if ! do_compile "$(get_header_tree "$base_ref")/include" "$base_header" "${base_header}.bin" 2> "$log"; then
+ {
+ warn_str=$(printf "==== Could not compile version of UAPI header %s at %s ====\n" \
+ "$file" "$base_ref")
+ printf "%s\n" "$warn_str"
+ cat "$log"
+ printf -- "=%.0s" $(seq 0 ${#warn_str})
+ } > "$error_log"
+ return 1
+ fi
+
+ if ! do_compile "$(get_header_tree "$past_ref")/include" "$past_header" "${past_header}.bin" 2> "$log"; then
+ {
+ warn_str=$(printf "==== Could not compile version of UAPI header %s at %s ====\n" \
+ "$file" "$past_ref")
+ printf "%s\n" "$warn_str"
+ cat "$log"
+ printf -- "=%.0s" $(seq 0 ${#warn_str})
+ } > "$error_log"
+ return 1
+ fi
+
+ local ret=0
+ "$ABIDIFF" --non-reachable-types \
+ --suppressions "$SUPPRESSIONS" \
+ "${past_header}.bin" "${base_header}.bin" > "$log" || ret="$?"
+ if [ "$ret" -eq 0 ]; then
+ if [ "$VERBOSE" = "true" ]; then
+ printf "No ABI differences detected in %s from %s -> %s\n" \
+ "$file" "$past_ref" "$base_ref"
+ fi
+ else
+ # Bits in abidiff's return code can be used to determine the type of error
+ if [ $((ret & 0x2)) -gt 0 ]; then
+ eprintf "error - abidiff did not run properly\n"
+ exit 1
+ fi
+
+ if [ "$IGNORE_AMBIGUOUS_CHANGES" = "true" ] && [ "$ret" -eq 4 ]; then
+ return 0
+ fi
+
+ # If the only changes were additions (not modifications to existing APIs), then
+ # there's no problem. Ignore these diffs.
+ if grep "Unreachable types summary" "$log" | grep -q "0 removed" &&
+ grep "Unreachable types summary" "$log" | grep -q "0 changed"; then
+ return 0
+ fi
+
+ {
+ warn_str=$(printf "==== ABI differences detected in %s from %s -> %s ====" \
+ "$file" "$past_ref" "$base_ref")
+ printf "%s\n" "$warn_str"
+ sed -e '/summary:/d' -e '/changed type/d' -e '/^$/d' -e 's/^/ /g' "$log"
+ printf -- "=%.0s" $(seq 0 ${#warn_str})
+ if cmp "$past_header" "$base_header" > /dev/null 2>&1; then
+ printf "\n%s did not change between %s and %s...\n" "$file" "$past_ref" "${base_ref:-dirty tree}"
+ printf "It's possible a change to one of the headers it includes caused this error:\n"
+ grep '^#include' "$base_header"
+ printf "\n"
+ fi
+ } > "$error_log"
+
+ return 1
+ fi
+}
+
+# Check that a minimum software version number is satisfied
+min_version_is_satisfied() {
+ local -r min_version="$1"
+ local -r version_installed="$2"
+
+ printf "%s\n%s\n" "$min_version" "$version_installed" \
+ | sort -Vc > /dev/null 2>&1
+}
+
+# Make sure we have the tools we need and the arguments make sense
+check_deps() {
+ ABIDIFF="${ABIDIFF:-abidiff}"
+ CC="${CC:-gcc}"
+ ARCH="${ARCH:-$(uname -m)}"
+ if [ "$ARCH" = "x86_64" ]; then
+ ARCH="x86"
+ fi
+
+ local -r abidiff_min_version="2.4"
+ local -r libdw_min_version_if_clang="0.171"
+
+ if ! command -v "$ABIDIFF" > /dev/null 2>&1; then
+ eprintf "error - abidiff not found!\n"
+ eprintf "Please install abigail-tools version %s or greater\n" "$abidiff_min_version"
+ eprintf "See: https://sourceware.org/libabigail/manual/libabigail-overview.html\n"
+ return 1
+ fi
+
+ local -r abidiff_version="$("$ABIDIFF" --version | cut -d ' ' -f 2)"
+ if ! min_version_is_satisfied "$abidiff_min_version" "$abidiff_version"; then
+ eprintf "error - abidiff version too old: %s\n" "$abidiff_version"
+ eprintf "Please install abigail-tools version %s or greater\n" "$abidiff_min_version"
+ eprintf "See: https://sourceware.org/libabigail/manual/libabigail-overview.html\n"
+ return 1
+ fi
+
+ if ! command -v "$CC" > /dev/null 2>&1; then
+ eprintf 'error - %s not found\n' "$CC"
+ return 1
+ fi
+
+ if "$CC" --version | grep -q clang; then
+ local -r libdw_version="$(ldconfig -v 2>/dev/null | grep -v SKIPPED | grep -m 1 -o 'libdw-[0-9]\+.[0-9]\+' | cut -c 7-)"
+ if ! min_version_is_satisfied "$libdw_min_version_if_clang" "$libdw_version"; then
+ eprintf "error - libdw version too old for use with clang: %s\n" "$libdw_version"
+ eprintf "Please install libdw from elfutils version %s or greater\n" "$libdw_min_version_if_clang"
+ eprintf "See: https://sourceware.org/elfutils/\n"
+ return 1
+ fi
+ fi
+
+ if [ ! -d "arch/${ARCH}" ]; then
+ eprintf 'error - ARCH "%s" is not a subdirectory under arch/\n' "$ARCH"
+ eprintf "Please set ARCH to one of:\n%s\n" "$(find arch -maxdepth 1 -mindepth 1 -type d -printf '%f ' | fmt)"
+ return 1
+ fi
+
+ if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
+ eprintf "error - this script requires the kernel tree to be initialized with Git\n"
+ return 1
+ fi
+
+ if ! git rev-parse --verify "$past_ref" > /dev/null 2>&1; then
+ printf 'error - invalid git reference "%s"\n' "$past_ref"
+ return 1
+ fi
+
+ if [ -n "$base_ref" ]; then
+ if ! git merge-base --is-ancestor "$past_ref" "$base_ref" > /dev/null 2>&1; then
+ printf 'error - "%s" is not an ancestor of base ref "%s"\n' "$past_ref" "$base_ref"
+ return 1
+ fi
+ if [ "$(git rev-parse "$base_ref")" = "$(git rev-parse "$past_ref")" ]; then
+ printf 'error - "%s" and "%s" are the same reference\n' "$past_ref" "$base_ref"
+ return 1
+ fi
+ fi
+}
+
+run() {
+ local base_ref="$1"
+ local past_ref="$2"
+ local abi_error_log="$3"
+ shift 3
+
+ if [ -z "$KERNEL_SRC" ]; then
+ KERNEL_SRC="$(realpath "$(dirname "$0")"/..)"
+ fi
+
+ cd "$KERNEL_SRC"
+
+ if [ -z "$base_ref" ] && ! tree_is_dirty; then
+ base_ref=HEAD
+ fi
+
+ if [ -z "$past_ref" ]; then
+ if [ -n "$base_ref" ]; then
+ past_ref="${base_ref}^1"
+ else
+ past_ref=HEAD
+ fi
+ fi
+
+ if ! check_deps; then
+ exit "$FAIL_PREREQ"
+ fi
+
+ TMP_DIR=$(mktemp -d)
+ readonly TMP_DIR
+ trap 'rm -rf "$TMP_DIR"' EXIT
+
+ readonly INCOMPAT_LIST="${TMP_DIR}/incompat_list.txt"
+ touch "$INCOMPAT_LIST"
+
+ readonly SUPPRESSIONS="${TMP_DIR}/suppressions.txt"
+ gen_suppressions > "$SUPPRESSIONS"
+
+ # Run make install_headers for both refs
+ install_headers "$base_ref" "$past_ref"
+
+ # Check for any differences in the installed header trees
+ if diff -r -q "$(get_header_tree "$base_ref")" "$(get_header_tree "$past_ref")" > /dev/null 2>&1; then
+ printf "No changes to UAPI headers were applied between %s and %s\n" "$past_ref" "${base_ref:-dirty tree}"
+ exit "$SUCCESS"
+ fi
+
+ if ! check_uapi_files "$base_ref" "$past_ref" "$abi_error_log"; then
+ exit "$FAIL_ABI"
+ fi
+}
+
+main() {
+ MAX_THREADS=$(nproc)
+ VERBOSE="false"
+ IGNORE_AMBIGUOUS_CHANGES="false"
+ quiet="false"
+ local base_ref=""
+ while getopts "hb:p:j:l:iqv" opt; do
+ case $opt in
+ h)
+ print_usage
+ exit "$SUCCESS"
+ ;;
+ b)
+ base_ref="$OPTARG"
+ ;;
+ p)
+ past_ref="$OPTARG"
+ ;;
+ j)
+ MAX_THREADS="$OPTARG"
+ ;;
+ l)
+ abi_error_log="$OPTARG"
+ ;;
+ i)
+ IGNORE_AMBIGUOUS_CHANGES="true"
+ ;;
+ q)
+ quiet="true"
+ VERBOSE="false"
+ ;;
+ v)
+ VERBOSE="true"
+ quiet="false"
+ ;;
+ *)
+ exit "$FAIL_PREREQ"
+ esac
+ done
+
+ if [ "$quiet" = "true" ]; then
+ exec > /dev/null 2>&1
+ fi
+
+ run "$base_ref" "$past_ref" "$abi_error_log" "$@"
+}
+
+main "$@"
diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py
index aa5ab6251f76..6793d6e86e77 100644
--- a/scripts/gdb/linux/tasks.py
+++ b/scripts/gdb/linux/tasks.py
@@ -82,21 +82,12 @@ LxPs()
thread_info_type = utils.CachedType("struct thread_info")
-ia64_task_size = None
-
def get_thread_info(task):
thread_info_ptr_type = thread_info_type.get_type().pointer()
- if utils.is_target_arch("ia64"):
- global ia64_task_size
- if ia64_task_size is None:
- ia64_task_size = gdb.parse_and_eval("sizeof(struct task_struct)")
- thread_info_addr = task.address + ia64_task_size
- thread_info = thread_info_addr.cast(thread_info_ptr_type)
- else:
- if task.type.fields()[0].type == thread_info_type.get_type():
- return task['thread_info']
- thread_info = task['stack'].cast(thread_info_ptr_type)
+ if task.type.fields()[0].type == thread_info_type.get_type():
+ return task['thread_info']
+ thread_info = task['stack'].cast(thread_info_ptr_type)
return thread_info.dereference()
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
index f5dfdb9d80e9..f3901c55df23 100644
--- a/scripts/genksyms/genksyms.c
+++ b/scripts/genksyms/genksyms.c
@@ -16,9 +16,7 @@
#include <unistd.h>
#include <assert.h>
#include <stdarg.h>
-#ifdef __GNU_LIBRARY__
#include <getopt.h>
-#endif /* __GNU_LIBRARY__ */
#include "genksyms.h"
/*----------------------------------------------------------------------*/
@@ -718,8 +716,6 @@ void error_with_pos(const char *fmt, ...)
static void genksyms_usage(void)
{
fputs("Usage:\n" "genksyms [-adDTwqhVR] > /path/to/.tmp_obj.ver\n" "\n"
-#ifdef __GNU_LIBRARY__
- " -s, --symbol-prefix Select symbol prefix\n"
" -d, --debug Increment the debug level (repeatable)\n"
" -D, --dump Dump expanded symbol defs (for debugging only)\n"
" -r, --reference file Read reference symbols from a file\n"
@@ -729,18 +725,6 @@ static void genksyms_usage(void)
" -q, --quiet Disable warnings (default)\n"
" -h, --help Print this message\n"
" -V, --version Print the release version\n"
-#else /* __GNU_LIBRARY__ */
- " -s Select symbol prefix\n"
- " -d Increment the debug level (repeatable)\n"
- " -D Dump expanded symbol defs (for debugging only)\n"
- " -r file Read reference symbols from a file\n"
- " -T file Dump expanded types into file\n"
- " -p Preserve reference modversions or fail\n"
- " -w Enable warnings\n"
- " -q Disable warnings (default)\n"
- " -h Print this message\n"
- " -V Print the release version\n"
-#endif /* __GNU_LIBRARY__ */
, stderr);
}
@@ -749,7 +733,6 @@ int main(int argc, char **argv)
FILE *dumpfile = NULL, *ref_file = NULL;
int o;
-#ifdef __GNU_LIBRARY__
struct option long_opts[] = {
{"debug", 0, 0, 'd'},
{"warnings", 0, 0, 'w'},
@@ -763,11 +746,8 @@ int main(int argc, char **argv)
{0, 0, 0, 0}
};
- while ((o = getopt_long(argc, argv, "s:dwqVDr:T:ph",
+ while ((o = getopt_long(argc, argv, "dwqVDr:T:ph",
&long_opts[0], NULL)) != EOF)
-#else /* __GNU_LIBRARY__ */
- while ((o = getopt(argc, argv, "s:dwqVDr:T:ph")) != EOF)
-#endif /* __GNU_LIBRARY__ */
switch (o) {
case 'd':
flag_debug++;
diff --git a/scripts/git.orderFile b/scripts/git.orderFile
new file mode 100644
index 000000000000..5102ba73357f
--- /dev/null
+++ b/scripts/git.orderFile
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# order file for git, to produce patches which are easier to review
+# by diffing the important stuff like header changes first.
+#
+# one-off usage:
+# git diff -O scripts/git.orderFile ...
+#
+# add to git config:
+# git config diff.orderFile scripts/git.orderFile
+#
+
+MAINTAINERS
+
+# Documentation
+Documentation/*
+*.rst
+
+# git-specific
+.gitignore
+scripts/git.orderFile
+
+# build system
+Kconfig*
+*/Kconfig*
+Kbuild*
+*/Kbuild*
+Makefile*
+*/Makefile*
+*.mak
+*.mk
+scripts/*
+
+# semantic patches
+*.cocci
+
+# headers
+*types.h
+*.h
+
+# code
+*.c
diff --git a/scripts/head-object-list.txt b/scripts/head-object-list.txt
index 26359968744e..890f69005bab 100644
--- a/scripts/head-object-list.txt
+++ b/scripts/head-object-list.txt
@@ -17,7 +17,6 @@ arch/arm/kernel/head-nommu.o
arch/arm/kernel/head.o
arch/csky/kernel/head.o
arch/hexagon/kernel/head.o
-arch/ia64/kernel/head.o
arch/loongarch/kernel/head.o
arch/m68k/68000/head.o
arch/m68k/coldfire/head.o
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 4eee155121a8..ea1bf3b3dbde 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -27,6 +27,14 @@ KCONFIG_DEFCONFIG_LIST += \
endif
KCONFIG_DEFCONFIG_LIST += arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)
+ifneq ($(findstring c, $(KBUILD_EXTRA_WARN)),)
+export KCONFIG_WARN_UNKNOWN_SYMBOLS=1
+endif
+
+ifneq ($(findstring e, $(KBUILD_EXTRA_WARN)),)
+export KCONFIG_WERROR=1
+endif
+
# We need this, in case the user has it in its environment
unexport CONFIG_
@@ -99,7 +107,7 @@ config-fragments = $(call configfiles,$@)
%.config: $(obj)/conf
$(if $(config-fragments),, $(error $@ fragment does not exists on this architecture))
- $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(config-fragments)
+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m $(KCONFIG_CONFIG) $(config-fragments)
$(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig
PHONY += tinyconfig
@@ -166,7 +174,7 @@ conf-objs := conf.o $(common-objs)
# nconf: Used for the nconfig target based on ncurses
hostprogs += nconf
-nconf-objs := nconf.o nconf.gui.o $(common-objs)
+nconf-objs := nconf.o nconf.gui.o mnconf-common.o $(common-objs)
HOSTLDLIBS_nconf = $(call read-file, $(obj)/nconf-libs)
HOSTCFLAGS_nconf.o = $(call read-file, $(obj)/nconf-cflags)
@@ -179,7 +187,7 @@ $(obj)/nconf.o $(obj)/nconf.gui.o: | $(obj)/nconf-cflags
hostprogs += mconf
lxdialog := $(addprefix lxdialog/, \
checklist.o inputbox.o menubox.o textbox.o util.o yesno.o)
-mconf-objs := mconf.o $(lxdialog) $(common-objs)
+mconf-objs := mconf.o $(lxdialog) mnconf-common.o $(common-objs)
HOSTLDLIBS_mconf = $(call read-file, $(obj)/mconf-libs)
$(foreach f, mconf.o $(lxdialog), \
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 33d19e419908..662a5e7c37c2 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -827,6 +827,9 @@ int main(int ac, char **av)
break;
}
+ if (conf_errors())
+ exit(1);
+
if (sync_kconfig) {
name = getenv("KCONFIG_NOSILENTUPDATE");
if (name && *name) {
@@ -890,6 +893,9 @@ int main(int ac, char **av)
break;
}
+ if (sym_dep_errors())
+ exit(1);
+
if (input_mode == savedefconfig) {
if (conf_write_defconfig(defconfig_file)) {
fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n",
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 4a6811d77d18..f53dcdd44597 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -155,6 +155,13 @@ static void conf_message(const char *fmt, ...)
static const char *conf_filename;
static int conf_lineno, conf_warnings;
+bool conf_errors(void)
+{
+ if (conf_warnings)
+ return getenv("KCONFIG_WERROR");
+ return false;
+}
+
static void conf_warning(const char *fmt, ...)
{
va_list ap;
@@ -289,16 +296,12 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
#define LINE_GROWTH 16
static int add_byte(int c, char **lineptr, size_t slen, size_t *n)
{
- char *nline;
size_t new_size = slen + 1;
+
if (new_size > *n) {
new_size += LINE_GROWTH - 1;
new_size *= 2;
- nline = xrealloc(*lineptr, new_size);
- if (!nline)
- return -1;
-
- *lineptr = nline;
+ *lineptr = xrealloc(*lineptr, new_size);
*n = new_size;
}
@@ -341,19 +344,37 @@ e_out:
return -1;
}
+/* like getline(), but the newline character is stripped away */
+static ssize_t getline_stripped(char **lineptr, size_t *n, FILE *stream)
+{
+ ssize_t len;
+
+ len = compat_getline(lineptr, n, stream);
+
+ if (len > 0 && (*lineptr)[len - 1] == '\n') {
+ len--;
+ (*lineptr)[len] = '\0';
+
+ if (len > 0 && (*lineptr)[len - 1] == '\r') {
+ len--;
+ (*lineptr)[len] = '\0';
+ }
+ }
+
+ return len;
+}
+
int conf_read_simple(const char *name, int def)
{
FILE *in = NULL;
char *line = NULL;
size_t line_asize = 0;
- char *p, *p2;
+ char *p, *val;
struct symbol *sym;
int i, def_flags;
- const char *warn_unknown;
- const char *werror;
+ const char *warn_unknown, *sym_name;
warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS");
- werror = getenv("KCONFIG_WERROR");
if (name) {
in = zconf_fopen(name);
} else {
@@ -417,8 +438,7 @@ load:
case S_INT:
case S_HEX:
case S_STRING:
- if (sym->def[def].val)
- free(sym->def[def].val);
+ free(sym->def[def].val);
/* fall through */
default:
sym->def[def].val = NULL;
@@ -426,90 +446,68 @@ load:
}
}
- while (compat_getline(&line, &line_asize, in) != -1) {
+ while (getline_stripped(&line, &line_asize, in) != -1) {
conf_lineno++;
- sym = NULL;
+
+ if (!line[0]) /* blank line */
+ continue;
+
if (line[0] == '#') {
- if (memcmp(line + 2, CONFIG_, strlen(CONFIG_)))
+ if (line[1] != ' ')
+ continue;
+ p = line + 2;
+ if (memcmp(p, CONFIG_, strlen(CONFIG_)))
continue;
- p = strchr(line + 2 + strlen(CONFIG_), ' ');
+ sym_name = p + strlen(CONFIG_);
+ p = strchr(sym_name, ' ');
if (!p)
continue;
*p++ = 0;
- if (strncmp(p, "is not set", 10))
+ if (strcmp(p, "is not set"))
continue;
- if (def == S_DEF_USER) {
- sym = sym_find(line + 2 + strlen(CONFIG_));
- if (!sym) {
- if (warn_unknown)
- conf_warning("unknown symbol: %s",
- line + 2 + strlen(CONFIG_));
-
- conf_set_changed(true);
- continue;
- }
- } else {
- sym = sym_lookup(line + 2 + strlen(CONFIG_), 0);
- if (sym->type == S_UNKNOWN)
- sym->type = S_BOOLEAN;
- }
- if (sym->flags & def_flags) {
- conf_warning("override: reassigning to symbol %s", sym->name);
- }
- switch (sym->type) {
- case S_BOOLEAN:
- case S_TRISTATE:
- sym->def[def].tri = no;
- sym->flags |= def_flags;
- break;
- default:
- ;
- }
- } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) {
- p = strchr(line + strlen(CONFIG_), '=');
- if (!p)
+
+ val = "n";
+ } else {
+ if (memcmp(line, CONFIG_, strlen(CONFIG_))) {
+ conf_warning("unexpected data: %s", line);
continue;
- *p++ = 0;
- p2 = strchr(p, '\n');
- if (p2) {
- *p2-- = 0;
- if (*p2 == '\r')
- *p2 = 0;
}
- sym = sym_find(line + strlen(CONFIG_));
- if (!sym) {
- if (def == S_DEF_AUTO) {
- /*
- * Reading from include/config/auto.conf
- * If CONFIG_FOO previously existed in
- * auto.conf but it is missing now,
- * include/config/FOO must be touched.
- */
- conf_touch_dep(line + strlen(CONFIG_));
- } else {
- if (warn_unknown)
- conf_warning("unknown symbol: %s",
- line + strlen(CONFIG_));
-
- conf_set_changed(true);
- }
+ sym_name = line + strlen(CONFIG_);
+ p = strchr(sym_name, '=');
+ if (!p) {
+ conf_warning("unexpected data: %s", line);
continue;
}
+ *p = 0;
+ val = p + 1;
+ }
- if (sym->flags & def_flags) {
- conf_warning("override: reassigning to symbol %s", sym->name);
- }
- if (conf_set_sym_val(sym, def, def_flags, p))
- continue;
- } else {
- if (line[0] != '\r' && line[0] != '\n')
- conf_warning("unexpected data: %.*s",
- (int)strcspn(line, "\r\n"), line);
+ sym = sym_find(sym_name);
+ if (!sym) {
+ if (def == S_DEF_AUTO) {
+ /*
+ * Reading from include/config/auto.conf.
+ * If CONFIG_FOO previously existed in auto.conf
+ * but it is missing now, include/config/FOO
+ * must be touched.
+ */
+ conf_touch_dep(sym_name);
+ } else {
+ if (warn_unknown)
+ conf_warning("unknown symbol: %s", sym_name);
+ conf_set_changed(true);
+ }
continue;
}
+ if (sym->flags & def_flags)
+ conf_warning("override: reassigning to symbol %s", sym->name);
+
+ if (conf_set_sym_val(sym, def, def_flags, val))
+ continue;
+
if (sym && sym_is_choice_value(sym)) {
struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
switch (sym->def[def].tri) {
@@ -533,9 +531,6 @@ load:
free(line);
fclose(in);
- if (conf_warnings && werror)
- exit(1);
-
return 0;
}
@@ -594,7 +589,7 @@ int conf_read(const char *name)
/* Reset a string value if it's out of range */
if (sym_string_within_range(sym, sym->def[S_DEF_USER].val))
break;
- sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
+ sym->flags &= ~SYMBOL_VALID;
conf_unsaved++;
break;
default:
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index 81ebf8108ca7..a290de36307b 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -1131,7 +1131,6 @@ static int expr_compare_type(enum expr_type t1, enum expr_type t2)
default:
return -1;
}
- printf("[%dgt%d?]", t1, t2);
return 0;
}
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 471a59acecec..5cdc8f5e6446 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -99,8 +99,6 @@ bool menu_is_visible(struct menu *menu);
bool menu_has_prompt(struct menu *menu);
const char *menu_get_prompt(struct menu *menu);
struct menu *menu_get_parent_menu(struct menu *menu);
-bool menu_has_help(struct menu *menu);
-const char *menu_get_help(struct menu *menu);
int get_jump_key_char(void);
struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
void menu_get_ext_help(struct menu *menu, struct gstr *help);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index edd1e617b25c..a4ae5e9eadad 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -1,4 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef LKC_PROTO_H
+#define LKC_PROTO_H
+
#include <stdarg.h>
/* confdata.c */
@@ -12,6 +15,7 @@ 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));
+bool conf_errors(void);
/* symbol.c */
extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
@@ -22,6 +26,7 @@ void print_symbol_for_listconfig(struct symbol *sym);
struct symbol ** sym_re_search(const char *pattern);
const char * sym_type_name(enum symbol_type type);
void sym_calc_value(struct symbol *sym);
+bool sym_dep_errors(void);
enum symbol_type sym_get_type(struct symbol *sym);
bool sym_tristate_within_range(struct symbol *sym,tristate tri);
bool sym_set_tristate_value(struct symbol *sym,tristate tri);
@@ -50,3 +55,5 @@ char *expand_one_token(const char **str);
/* expr.c */
void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken);
+
+#endif /* LKC_PROTO_H */
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index eccc87a441e7..5df32148a869 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -21,6 +21,7 @@
#include "lkc.h"
#include "lxdialog/dialog.h"
+#include "mnconf-common.h"
static const char mconf_readme[] =
"Overview\n"
@@ -247,7 +248,7 @@ search_help[] =
" -> PCI support (PCI [=y])\n"
"(1) -> PCI access mode (<choice> [=y])\n"
" Defined at drivers/pci/Kconfig:47\n"
- " Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
+ " Depends on: X86_LOCAL_APIC && X86_IO_APIC\n"
" Selects: LIBCRC32\n"
" Selected by: BAR [=n]\n"
"-----------------------------------------------------------------\n"
@@ -286,7 +287,6 @@ static int single_menu_mode;
static int show_all_options;
static int save_and_exit;
static int silent;
-static int jump_key_char;
static void conf(struct menu *menu, struct menu *active_menu);
@@ -378,58 +378,6 @@ static void show_help(struct menu *menu)
str_free(&help);
}
-struct search_data {
- struct list_head *head;
- struct menu *target;
-};
-
-static int next_jump_key(int key)
-{
- if (key < '1' || key > '9')
- return '1';
-
- key++;
-
- if (key > '9')
- key = '1';
-
- return key;
-}
-
-static int handle_search_keys(int key, size_t start, size_t end, void *_data)
-{
- struct search_data *data = _data;
- struct jump_key *pos;
- int index = 0;
-
- if (key < '1' || key > '9')
- return 0;
-
- list_for_each_entry(pos, data->head, entries) {
- index = next_jump_key(index);
-
- if (pos->offset < start)
- continue;
-
- if (pos->offset >= end)
- break;
-
- if (key == index) {
- data->target = pos->target;
- return 1;
- }
- }
-
- return 0;
-}
-
-int get_jump_key_char(void)
-{
- jump_key_char = next_jump_key(jump_key_char);
-
- return jump_key_char;
-}
-
static void search_conf(void)
{
struct symbol **sym_arr;
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 61c442d84aef..2cce8b651f61 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -673,19 +673,6 @@ struct menu *menu_get_parent_menu(struct menu *menu)
return menu;
}
-bool menu_has_help(struct menu *menu)
-{
- return menu->help != NULL;
-}
-
-const char *menu_get_help(struct menu *menu)
-{
- if (menu->help)
- return menu->help;
- else
- return "";
-}
-
static void get_def_str(struct gstr *r, struct menu *menu)
{
str_printf(r, "Defined at %s:%d\n",
@@ -856,10 +843,10 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help)
struct symbol *sym = menu->sym;
const char *help_text = nohelp_text;
- if (menu_has_help(menu)) {
+ if (menu->help) {
if (sym->name)
str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
- help_text = menu_get_help(menu);
+ help_text = menu->help;
}
str_printf(help, "%s\n", help_text);
if (sym)
diff --git a/scripts/kconfig/mnconf-common.c b/scripts/kconfig/mnconf-common.c
new file mode 100644
index 000000000000..18cb9a6c5aaa
--- /dev/null
+++ b/scripts/kconfig/mnconf-common.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include "expr.h"
+#include "list.h"
+#include "mnconf-common.h"
+
+int jump_key_char;
+
+int next_jump_key(int key)
+{
+ if (key < '1' || key > '9')
+ return '1';
+
+ key++;
+
+ if (key > '9')
+ key = '1';
+
+ return key;
+}
+
+int handle_search_keys(int key, size_t start, size_t end, void *_data)
+{
+ struct search_data *data = _data;
+ struct jump_key *pos;
+ int index = 0;
+
+ if (key < '1' || key > '9')
+ return 0;
+
+ list_for_each_entry(pos, data->head, entries) {
+ index = next_jump_key(index);
+
+ if (pos->offset < start)
+ continue;
+
+ if (pos->offset >= end)
+ break;
+
+ if (key == index) {
+ data->target = pos->target;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int get_jump_key_char(void)
+{
+ jump_key_char = next_jump_key(jump_key_char);
+
+ return jump_key_char;
+}
diff --git a/scripts/kconfig/mnconf-common.h b/scripts/kconfig/mnconf-common.h
new file mode 100644
index 000000000000..ab6292cc4bf2
--- /dev/null
+++ b/scripts/kconfig/mnconf-common.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef MNCONF_COMMON_H
+#define MNCONF_COMMON_H
+
+#include <stddef.h>
+
+struct search_data {
+ struct list_head *head;
+ struct menu *target;
+};
+
+extern int jump_key_char;
+
+int next_jump_key(int key);
+int handle_search_keys(int key, size_t start, size_t end, void *_data);
+int get_jump_key_char(void);
+
+#endif /* MNCONF_COMMON_H */
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index 143a2c351d57..1148163cfa7e 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -12,6 +12,7 @@
#include <stdlib.h>
#include "lkc.h"
+#include "mnconf-common.h"
#include "nconf.h"
#include <ctype.h>
@@ -216,7 +217,7 @@ search_help[] =
"Symbol: FOO [ = m]\n"
"Prompt: Foo bus is used to drive the bar HW\n"
"Defined at drivers/pci/Kconfig:47\n"
-"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
+"Depends on: X86_LOCAL_APIC && X86_IO_APIC\n"
"Location:\n"
" -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
" -> PCI support (PCI [ = y])\n"
@@ -279,7 +280,6 @@ static const char *current_instructions = menu_instructions;
static char *dialog_input_result;
static int dialog_input_result_len;
-static int jump_key_char;
static void selected_conf(struct menu *menu, struct menu *active_menu);
static void conf(struct menu *menu);
@@ -691,57 +691,6 @@ static int do_exit(void)
return 0;
}
-struct search_data {
- struct list_head *head;
- struct menu *target;
-};
-
-static int next_jump_key(int key)
-{
- if (key < '1' || key > '9')
- return '1';
-
- key++;
-
- if (key > '9')
- key = '1';
-
- return key;
-}
-
-static int handle_search_keys(int key, size_t start, size_t end, void *_data)
-{
- struct search_data *data = _data;
- struct jump_key *pos;
- int index = 0;
-
- if (key < '1' || key > '9')
- return 0;
-
- list_for_each_entry(pos, data->head, entries) {
- index = next_jump_key(index);
-
- if (pos->offset < start)
- continue;
-
- if (pos->offset >= end)
- break;
-
- if (key == index) {
- data->target = pos->target;
- return 1;
- }
- }
-
- return 0;
-}
-
-int get_jump_key_char(void)
-{
- jump_key_char = next_jump_key(jump_key_char);
-
- return jump_key_char;
-}
static void search_conf(void)
{
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index a76925b46ce6..3e808528aaea 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -29,14 +29,9 @@ struct symbol symbol_no = {
.flags = SYMBOL_CONST|SYMBOL_VALID,
};
-static struct symbol symbol_empty = {
- .name = "",
- .curr = { "", no },
- .flags = SYMBOL_VALID,
-};
-
struct symbol *modules_sym;
static tristate modules_val;
+static int sym_warnings;
enum symbol_type sym_get_type(struct symbol *sym)
{
@@ -317,6 +312,14 @@ static void sym_warn_unmet_dep(struct symbol *sym)
" Selected by [m]:\n");
fputs(str_get(&gs), stderr);
+ sym_warnings++;
+}
+
+bool sym_dep_errors(void)
+{
+ if (sym_warnings)
+ return getenv("KCONFIG_WERROR");
+ return false;
}
void sym_calc_value(struct symbol *sym)
@@ -344,9 +347,13 @@ void sym_calc_value(struct symbol *sym)
switch (sym->type) {
case S_INT:
+ newval.val = "0";
+ break;
case S_HEX:
+ newval.val = "0x0";
+ break;
case S_STRING:
- newval = symbol_empty.curr;
+ newval.val = "";
break;
case S_BOOLEAN:
case S_TRISTATE:
@@ -697,13 +704,12 @@ const char *sym_get_string_default(struct symbol *sym)
{
struct property *prop;
struct symbol *ds;
- const char *str;
+ const char *str = "";
tristate val;
sym_calc_visibility(sym);
sym_calc_value(modules_sym);
val = symbol_no.curr.tri;
- str = symbol_empty.curr.val;
/* If symbol has a default value look it up */
prop = sym_get_default_prop(sym);
@@ -753,14 +759,17 @@ const char *sym_get_string_default(struct symbol *sym)
case yes: return "y";
}
case S_INT:
+ if (!str[0])
+ str = "0";
+ break;
case S_HEX:
- return str;
- case S_STRING:
- return str;
- case S_UNKNOWN:
+ if (!str[0])
+ str = "0x0";
+ break;
+ default:
break;
}
- return "";
+ return str;
}
const char *sym_get_string_value(struct symbol *sym)
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index b78f114ad48c..92e5b2b9761d 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -42,8 +42,7 @@ struct gstr str_new(void)
/* Free storage for growable string */
void str_free(struct gstr *gs)
{
- if (gs->s)
- free(gs->s);
+ free(gs->s);
gs->s = NULL;
gs->len = 0;
}
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index cb6406f485a9..e2bc180cecc8 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -60,8 +60,7 @@ static unsigned int nr_unresolved;
#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr))
-void __attribute__((format(printf, 2, 3)))
-modpost_log(enum loglevel loglevel, const char *fmt, ...)
+void modpost_log(enum loglevel loglevel, const char *fmt, ...)
{
va_list arglist;
@@ -91,6 +90,9 @@ modpost_log(enum loglevel loglevel, const char *fmt, ...)
error_occurred = true;
}
+void __attribute__((alias("modpost_log")))
+modpost_log_noret(enum loglevel loglevel, const char *fmt, ...);
+
static inline bool strends(const char *str, const char *postfix)
{
if (strlen(str) < strlen(postfix))
@@ -474,11 +476,9 @@ static int parse_elf(struct elf_info *info, const char *filename)
fatal("%s: not relocatable object.", filename);
/* Check if file offset is correct */
- if (hdr->e_shoff > info->size) {
+ if (hdr->e_shoff > info->size)
fatal("section header offset=%lu in file '%s' is bigger than filesize=%zu\n",
(unsigned long)hdr->e_shoff, filename, info->size);
- return 0;
- }
if (hdr->e_shnum == SHN_UNDEF) {
/*
@@ -516,12 +516,11 @@ static int parse_elf(struct elf_info *info, const char *filename)
const char *secname;
int nobits = sechdrs[i].sh_type == SHT_NOBITS;
- if (!nobits && sechdrs[i].sh_offset > info->size) {
+ if (!nobits && sechdrs[i].sh_offset > info->size)
fatal("%s is truncated. sechdrs[i].sh_offset=%lu > sizeof(*hrd)=%zu\n",
filename, (unsigned long)sechdrs[i].sh_offset,
sizeof(*hdr));
- return 0;
- }
+
secname = secstrings + sechdrs[i].sh_name;
if (strcmp(secname, ".modinfo") == 0) {
if (nobits)
@@ -1419,7 +1418,7 @@ static void section_rel(struct module *mod, struct elf_info *elf,
for (rel = start; rel < stop; rel++) {
Elf_Sym *tsym;
- Elf_Addr taddr = 0, r_offset;
+ Elf_Addr taddr, r_offset;
unsigned int r_type, r_sym;
void *loc;
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 69baf014da4f..835cababf1b0 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -197,7 +197,11 @@ enum loglevel {
LOG_FATAL
};
-void modpost_log(enum loglevel loglevel, const char *fmt, ...);
+void __attribute__((format(printf, 2, 3)))
+modpost_log(enum loglevel loglevel, const char *fmt, ...);
+
+void __attribute__((format(printf, 2, 3), noreturn))
+modpost_log_noret(enum loglevel loglevel, const char *fmt, ...);
/*
* warn - show the given message, then let modpost continue running, still
@@ -214,4 +218,4 @@ void modpost_log(enum loglevel loglevel, const char *fmt, ...);
*/
#define warn(fmt, args...) modpost_log(LOG_WARN, fmt, ##args)
#define error(fmt, args...) modpost_log(LOG_ERROR, fmt, ##args)
-#define fatal(fmt, args...) modpost_log(LOG_FATAL, fmt, ##args)
+#define fatal(fmt, args...) modpost_log_noret(LOG_FATAL, fmt, ##args)
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index d7dd0d04c70c..bf96a3c24608 100755
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -25,35 +25,20 @@ if_enabled_echo() {
}
create_package() {
- local pname="$1" pdir="$2"
- local dpkg_deb_opts
-
- mkdir -m 755 -p "$pdir/DEBIAN"
- mkdir -p "$pdir/usr/share/doc/$pname"
- cp debian/copyright "$pdir/usr/share/doc/$pname/"
- cp debian/changelog "$pdir/usr/share/doc/$pname/changelog.Debian"
- gzip -n -9 "$pdir/usr/share/doc/$pname/changelog.Debian"
- sh -c "cd '$pdir'; find . -type f ! -path './DEBIAN/*' -printf '%P\0' \
- | xargs -r0 md5sum > DEBIAN/md5sums"
-
- # Fix ownership and permissions
- if [ "$DEB_RULES_REQUIRES_ROOT" = "no" ]; then
- dpkg_deb_opts="--root-owner-group"
- else
- chown -R root:root "$pdir"
- fi
- # a+rX in case we are in a restrictive umask environment like 0077
- # ug-s in case we build in a setuid/setgid directory
- chmod -R go-w,a+rX,ug-s "$pdir"
-
- # Create the package
- dpkg-gencontrol -p$pname -P"$pdir"
- dpkg-deb $dpkg_deb_opts ${KDEB_COMPRESS:+-Z$KDEB_COMPRESS} --build "$pdir" ..
+ export DH_OPTIONS="-p${1}"
+
+ dh_installdocs
+ dh_installchangelogs
+ dh_compress
+ dh_fixperms
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb -- ${KDEB_COMPRESS:+-Z$KDEB_COMPRESS}
}
install_linux_image () {
- pdir=$1
- pname=$2
+ pname=$1
+ pdir=debian/$1
rm -rf ${pdir}
@@ -62,7 +47,7 @@ install_linux_image () {
${MAKE} -f ${srctree}/Makefile INSTALL_DTBS_PATH="${pdir}/usr/lib/linux-image-${KERNELRELEASE}" dtbs_install
fi
- ${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${pdir}" modules_install
+ ${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${pdir}" INSTALL_MOD_STRIP=1 modules_install
rm -f "${pdir}/lib/modules/${KERNELRELEASE}/build"
# Install the kernel
@@ -122,26 +107,22 @@ install_linux_image () {
}
install_linux_image_dbg () {
- pdir=$1
- image_pdir=$2
+ pdir=debian/$1
rm -rf ${pdir}
- for module in $(find ${image_pdir}/lib/modules/ -name *.ko -printf '%P\n'); do
- module=lib/modules/${module}
- mkdir -p $(dirname ${pdir}/usr/lib/debug/${module})
- # only keep debug symbols in the debug file
- ${OBJCOPY} --only-keep-debug ${image_pdir}/${module} ${pdir}/usr/lib/debug/${module}
- # strip original module from debug symbols
- ${OBJCOPY} --strip-debug ${image_pdir}/${module}
- # then add a link to those
- ${OBJCOPY} --add-gnu-debuglink=${pdir}/usr/lib/debug/${module} ${image_pdir}/${module}
- done
+ # Parse modules.order directly because 'make modules_install' may sign,
+ # compress modules, and then run unneeded depmod.
+ while read -r mod; do
+ mod="${mod%.o}.ko"
+ dbg="${pdir}/usr/lib/debug/lib/modules/${KERNELRELEASE}/kernel/${mod}"
+ buildid=$("${READELF}" -n "${mod}" | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p')
+ link="${pdir}/usr/lib/debug/.build-id/${buildid}.debug"
- # re-sign stripped modules
- if is_enabled CONFIG_MODULE_SIG_ALL; then
- ${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${image_pdir}" modules_sign
- fi
+ mkdir -p "${dbg%/*}" "${link%/*}"
+ "${OBJCOPY}" --only-keep-debug "${mod}" "${dbg}"
+ ln -sf --relative "${dbg}" "${link}"
+ done < modules.order
# Build debug package
# Different tools want the image in different locations
@@ -156,8 +137,8 @@ install_linux_image_dbg () {
}
install_kernel_headers () {
- pdir=$1
- version=$2
+ pdir=debian/$1
+ version=${1#linux-headers-}
rm -rf $pdir
@@ -168,18 +149,16 @@ install_kernel_headers () {
}
install_libc_headers () {
- pdir=$1
+ pdir=debian/$1
rm -rf $pdir
- $MAKE -f $srctree/Makefile headers
$MAKE -f $srctree/Makefile headers_install INSTALL_HDR_PATH=$pdir/usr
# move asm headers to /usr/include/<libc-machine>/asm to match the structure
# used by Debian-based distros (to support multi-arch)
- host_arch=$(dpkg-architecture -a$DEB_HOST_ARCH -qDEB_HOST_MULTIARCH)
- mkdir $pdir/usr/include/$host_arch
- mv $pdir/usr/include/asm $pdir/usr/include/$host_arch/
+ mkdir "$pdir/usr/include/${DEB_HOST_MULTIARCH}"
+ mv "$pdir/usr/include/asm" "$pdir/usr/include/${DEB_HOST_MULTIARCH}"
}
rm -f debian/files
@@ -190,30 +169,13 @@ for package in ${packages_enabled}
do
case ${package} in
*-dbg)
- # This must be done after linux-image, that is, we expect the
- # debug package appears after linux-image in debian/control.
- install_linux_image_dbg debian/linux-image-dbg debian/linux-image;;
- linux-image-*|user-mode-linux-*)
- install_linux_image debian/linux-image ${package};;
- linux-libc-dev)
- install_libc_headers debian/linux-libc-dev;;
- linux-headers-*)
- install_kernel_headers debian/linux-headers ${package#linux-headers-};;
- esac
-done
-
-for package in ${packages_enabled}
-do
- case ${package} in
- *-dbg)
- create_package ${package} debian/linux-image-dbg;;
+ install_linux_image_dbg "${package}";;
linux-image-*|user-mode-linux-*)
- create_package ${package} debian/linux-image;;
+ install_linux_image "${package}";;
linux-libc-dev)
- create_package ${package} debian/linux-libc-dev;;
+ install_libc_headers "${package}";;
linux-headers-*)
- create_package ${package} debian/linux-headers;;
+ install_kernel_headers "${package}";;
esac
+ create_package "${package}"
done
-
-exit 0
diff --git a/scripts/package/buildtar b/scripts/package/buildtar
index 65b4ea502962..72c91a1b832f 100755
--- a/scripts/package/buildtar
+++ b/scripts/package/buildtar
@@ -23,7 +23,6 @@ tmpdir=$1
#
rm -rf -- "${tmpdir}"
mkdir -p -- "${tmpdir}/boot"
-dirs=boot
#
@@ -38,12 +37,9 @@ fi
#
-# Try to install modules
+# Install modules
#
-if grep -q '^CONFIG_MODULES=y' include/config/auto.conf; then
- make ARCH="${ARCH}" -f ${srctree}/Makefile INSTALL_MOD_PATH="${tmpdir}" modules_install
- dirs="$dirs lib"
-fi
+make ARCH="${ARCH}" -f ${srctree}/Makefile INSTALL_MOD_PATH="${tmpdir}" modules_install
#
diff --git a/scripts/package/deb-build-option b/scripts/package/deb-build-option
deleted file mode 100755
index 7950eff01781..000000000000
--- a/scripts/package/deb-build-option
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0-only
-
-# Set up CROSS_COMPILE if not defined yet
-if [ "${CROSS_COMPILE+set}" != "set" -a "${DEB_HOST_ARCH}" != "${DEB_BUILD_ARCH}" ]; then
- echo CROSS_COMPILE=${DEB_HOST_GNU_TYPE}-
-fi
-
-version=$(dpkg-parsechangelog -S Version)
-debian_revision="${version##*-}"
-
-if [ "${version}" != "${debian_revision}" ]; then
- echo KBUILD_BUILD_VERSION=${debian_revision}
-fi
diff --git a/scripts/package/debian/copyright b/scripts/package/debian/copyright
new file mode 100644
index 000000000000..4f1f06221f09
--- /dev/null
+++ b/scripts/package/debian/copyright
@@ -0,0 +1,16 @@
+This is a packaged upstream version of the Linux kernel.
+
+The sources may be found at most Linux archive sites, including:
+https://www.kernel.org/pub/linux/kernel
+
+Copyright: 1991 - 2023 Linus Torvalds and others.
+
+The git repository for mainline kernel development is at:
+git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 dated June, 1991.
+
+On Debian GNU/Linux systems, the complete text of the GNU General Public
+License version 2 can be found in `/usr/share/common-licenses/GPL-2'.
diff --git a/scripts/package/debian/rules b/scripts/package/debian/rules
index 3dafa9496c63..098307780062 100755
--- a/scripts/package/debian/rules
+++ b/scripts/package/debian/rules
@@ -1,33 +1,46 @@
#!/usr/bin/make -f
# SPDX-License-Identifier: GPL-2.0-only
-include debian/rules.vars
+# in case debian/rules is executed directly
+export DEB_RULES_REQUIRES_ROOT := no
-srctree ?= .
+include debian/rules.vars
ifneq (,$(filter-out parallel=1,$(filter parallel=%,$(DEB_BUILD_OPTIONS))))
NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
MAKEFLAGS += -j$(NUMJOBS)
endif
+revision = $(lastword $(subst -, ,$(shell dpkg-parsechangelog -S Version)))
+CROSS_COMPILE ?= $(filter-out $(DEB_BUILD_GNU_TYPE)-, $(DEB_HOST_GNU_TYPE)-)
+make-opts = ARCH=$(ARCH) KERNELRELEASE=$(KERNELRELEASE) KBUILD_BUILD_VERSION=$(revision) $(addprefix CROSS_COMPILE=,$(CROSS_COMPILE))
+
.PHONY: binary binary-indep binary-arch
binary: binary-arch binary-indep
binary-indep: build-indep
binary-arch: build-arch
- $(MAKE) -f $(srctree)/Makefile ARCH=$(ARCH) \
- KERNELRELEASE=$(KERNELRELEASE) \
- run-command KBUILD_RUN_COMMAND=+$(srctree)/scripts/package/builddeb
+ $(MAKE) $(make-opts) \
+ run-command KBUILD_RUN_COMMAND='+$$(srctree)/scripts/package/builddeb'
.PHONY: build build-indep build-arch
build: build-arch build-indep
build-indep:
build-arch:
- $(MAKE) -f $(srctree)/Makefile ARCH=$(ARCH) \
- KERNELRELEASE=$(KERNELRELEASE) \
- $(shell $(srctree)/scripts/package/deb-build-option) \
- olddefconfig all
+ $(MAKE) $(make-opts) olddefconfig
+ $(MAKE) $(make-opts) $(if $(filter um,$(ARCH)),,headers) all
.PHONY: clean
clean:
- rm -rf debian/files debian/linux-*
- $(MAKE) -f $(srctree)/Makefile ARCH=$(ARCH) clean
+ rm -rf debian/files debian/linux-* debian/deb-env.vars*
+ $(MAKE) ARCH=$(ARCH) clean
+
+# If DEB_HOST_ARCH is empty, it is likely that debian/rules was executed
+# directly. Run 'dpkg-architecture --print-set --print-format=make' to
+# generate a makefile construct that exports all DEB_* variables.
+ifndef DEB_HOST_ARCH
+include debian/deb-env.vars
+
+debian/deb-env.vars:
+ dpkg-architecture -a$$(cat debian/arch) --print-set --print-format=make > $@.tmp
+ mv $@.tmp $@
+endif
diff --git a/scripts/package/install-extmod-build b/scripts/package/install-extmod-build
index 8a7051fad087..76e0765dfcd6 100755
--- a/scripts/package/install-extmod-build
+++ b/scripts/package/install-extmod-build
@@ -20,7 +20,7 @@ mkdir -p "${destdir}"
find "arch/${SRCARCH}" -maxdepth 1 -name 'Makefile*'
find include scripts -type f -o -type l
find "arch/${SRCARCH}" -name Kbuild.platforms -o -name Platform
- find "arch/${SRCARCH}" -name include -o -name scripts -type d
+ find "arch/${SRCARCH}" -name include -type d
) | tar -c -f - -C "${srctree}" -T - | tar -xf - -C "${destdir}"
{
diff --git a/scripts/package/kernel.spec b/scripts/package/kernel.spec
index 3eee0143e0c5..89298983a169 100644
--- a/scripts/package/kernel.spec
+++ b/scripts/package/kernel.spec
@@ -56,13 +56,7 @@ patch -p1 < %{SOURCE2}
%install
mkdir -p %{buildroot}/boot
-%ifarch ia64
-mkdir -p %{buildroot}/boot/efi
-cp $(%{make} %{makeflags} -s image_name) %{buildroot}/boot/efi/vmlinuz-%{KERNELRELEASE}
-ln -s efi/vmlinuz-%{KERNELRELEASE} %{buildroot}/boot/
-%else
cp $(%{make} %{makeflags} -s image_name) %{buildroot}/boot/vmlinuz-%{KERNELRELEASE}
-%endif
%{make} %{makeflags} INSTALL_MOD_PATH=%{buildroot} modules_install
%{make} %{makeflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
cp System.map %{buildroot}/boot/System.map-%{KERNELRELEASE}
diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian
index 5044224cf671..070149c985fe 100755
--- a/scripts/package/mkdebian
+++ b/scripts/package/mkdebian
@@ -26,7 +26,7 @@ set_debarch() {
# Attempt to find the correct Debian architecture
case "$UTS_MACHINE" in
- i386|ia64|alpha|m68k|riscv*)
+ i386|alpha|m68k|riscv*)
debarch="$UTS_MACHINE" ;;
x86_64)
debarch=amd64 ;;
@@ -176,8 +176,6 @@ else
fi
echo $debarch > debian/arch
-extra_build_depends=", $(if_enabled_echo CONFIG_UNWINDER_ORC libelf-dev:native)"
-extra_build_depends="$extra_build_depends, $(if_enabled_echo CONFIG_SYSTEM_TRUSTED_KEYRING libssl-dev:native)"
# Generate a simple changelog template
cat <<EOF > debian/changelog
@@ -188,26 +186,6 @@ $sourcename ($packageversion) $distribution; urgency=low
-- $maintainer $(date -R)
EOF
-# Generate copyright file
-cat <<EOF > debian/copyright
-This is a packaged upstream version of the Linux kernel.
-
-The sources may be found at most Linux archive sites, including:
-https://www.kernel.org/pub/linux/kernel
-
-Copyright: 1991 - 2018 Linus Torvalds and others.
-
-The git repository for mainline kernel development is at:
-git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 dated June, 1991.
-
-On Debian GNU/Linux systems, the complete text of the GNU General Public
-License version 2 can be found in \`/usr/share/common-licenses/GPL-2'.
-EOF
-
# Generate a control file
cat <<EOF > debian/control
Source: $sourcename
@@ -215,7 +193,8 @@ Section: kernel
Priority: optional
Maintainer: $maintainer
Rules-Requires-Root: no
-Build-Depends: bc, debhelper, rsync, kmod, cpio, bison, flex $extra_build_depends
+Build-Depends: debhelper-compat (= 12)
+Build-Depends-Arch: bc, bison, cpio, flex, kmod, libelf-dev:native, libssl-dev:native, rsync
Homepage: https://www.kernel.org/
Package: $packagename-$version
@@ -268,6 +247,7 @@ ARCH := ${ARCH}
KERNELRELEASE := ${KERNELRELEASE}
EOF
+cp "${srctree}/scripts/package/debian/copyright" debian/
cp "${srctree}/scripts/package/debian/rules" debian/
exit 0
diff --git a/scripts/package/snapcraft.template b/scripts/package/snapcraft.template
index 626d278e4a5a..85d5e07d1b40 100644
--- a/scripts/package/snapcraft.template
+++ b/scripts/package/snapcraft.template
@@ -10,5 +10,5 @@ parts:
kernel:
plugin: kernel
source: SRCTREE
- source-type: tar
+ source-type: local
kernel-with-firmware: false
diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c
index 40ae6b2c7a6d..3e4f54799cc0 100644
--- a/scripts/recordmcount.c
+++ b/scripts/recordmcount.c
@@ -590,7 +590,6 @@ static int do_file(char const *const fname)
ideal_nop = ideal_nop4_arm64;
is_fake_mcount64 = arm64_is_fake_mcount;
break;
- case EM_IA_64: reltype = R_IA64_IMM64; break;
case EM_MIPS: /* reltype: e_class */ break;
case EM_LOONGARCH: /* reltype: e_class */ break;
case EM_PPC: reltype = R_PPC_ADDR32; break;
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index 6a4645a57976..f84df9e383fd 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -275,13 +275,6 @@ if ($arch eq "x86_64") {
$section_type = '%progbits';
$mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_AARCH64_CALL26\\s+_mcount\$";
$type = ".quad";
-} elsif ($arch eq "ia64") {
- $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
- $type = "data8";
-
- if ($is_module eq "0") {
- $cc .= " -mconstant-gp";
- }
} elsif ($arch eq "sparc64") {
# In the objdump output there are giblets like:
# 0000000000000000 <igmp_net_exit-0x18>:
diff --git a/scripts/xz_wrap.sh b/scripts/xz_wrap.sh
index 76e9cbcfbeab..d06baf626abe 100755
--- a/scripts/xz_wrap.sh
+++ b/scripts/xz_wrap.sh
@@ -15,7 +15,6 @@ LZMA2OPTS=
case $SRCARCH in
x86) BCJ=--x86 ;;
powerpc) BCJ=--powerpc ;;
- ia64) BCJ=--ia64; LZMA2OPTS=pb=4 ;;
arm) BCJ=--arm ;;
sparc) BCJ=--sparc ;;
esac
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
index 61230532fef1..edcdb8abfa31 100644
--- a/usr/gen_init_cpio.c
+++ b/usr/gen_init_cpio.c
@@ -27,6 +27,7 @@
static unsigned int offset;
static unsigned int ino = 721;
static time_t default_mtime;
+static bool do_file_mtime;
static bool do_csum = false;
struct file_handler {
@@ -329,6 +330,7 @@ static int cpio_mkfile(const char *name, const char *location,
int file;
int retval;
int rc = -1;
+ time_t mtime;
int namesize;
unsigned int i;
uint32_t csum = 0;
@@ -347,16 +349,21 @@ static int cpio_mkfile(const char *name, const char *location,
goto error;
}
- if (buf.st_mtime > 0xffffffff) {
- fprintf(stderr, "%s: Timestamp exceeds maximum cpio timestamp, clipping.\n",
- location);
- buf.st_mtime = 0xffffffff;
- }
+ if (do_file_mtime) {
+ mtime = default_mtime;
+ } else {
+ mtime = buf.st_mtime;
+ if (mtime > 0xffffffff) {
+ fprintf(stderr, "%s: Timestamp exceeds maximum cpio timestamp, clipping.\n",
+ location);
+ mtime = 0xffffffff;
+ }
- if (buf.st_mtime < 0) {
- fprintf(stderr, "%s: Timestamp negative, clipping.\n",
- location);
- buf.st_mtime = 0;
+ if (mtime < 0) {
+ fprintf(stderr, "%s: Timestamp negative, clipping.\n",
+ location);
+ mtime = 0;
+ }
}
if (buf.st_size > 0xffffffff) {
@@ -387,7 +394,7 @@ static int cpio_mkfile(const char *name, const char *location,
(long) uid, /* uid */
(long) gid, /* gid */
nlinks, /* nlink */
- (long) buf.st_mtime, /* mtime */
+ (long) mtime, /* mtime */
size, /* filesize */
3, /* major */
1, /* minor */
@@ -536,8 +543,9 @@ static void usage(const char *prog)
"file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0\n"
"\n"
"<timestamp> is time in seconds since Epoch that will be used\n"
- "as mtime for symlinks, special files and directories. The default\n"
- "is to use the current time for these entries.\n"
+ "as mtime for symlinks, directories, regular and special files.\n"
+ "The default is to use the current time for all files, but\n"
+ "preserve modification time for regular files.\n"
"-c: calculate and store 32-bit checksums for file data.\n",
prog);
}
@@ -594,6 +602,7 @@ int main (int argc, char *argv[])
usage(argv[0]);
exit(1);
}
+ do_file_mtime = true;
break;
case 'c':
do_csum = true;