From d2395bb194ef212b36521ec4fa85e38b45675acb Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 25 Feb 2026 15:07:17 -0700 Subject: genksyms: Fix parsing a declarator with a preceding attribute After commit 07919126ecfc ("netfilter: annotate NAT helper hook pointers with __rcu"), genksyms fails to parse the __rcu annotation when building with CONFIG_DEBUG_INFO_BTF=y, CONFIG_PAHOLE_HAS_BTF_TAG=y, and a version of clang that supports btf_type_tag. $ clang --version | head -1 ClangBuiltLinux clang version 22.1.0 (https://github.com/llvm/llvm-project.git 4434dabb69916856b824f68a64b029c67175e532) $ cat kernel/configs/repro.config CONFIG_BPF_SYSCALL=y CONFIG_MODVERSIONS=y # CONFIG_DEBUG_INFO_NONE is not set CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_DEBUG_INFO_BTF=y $ make -skj"$(nproc)" ARCH=x86_64 LLVM=1 mrproper defconfig repro.config all WARNING: modpost: EXPORT symbol "nf_nat_ftp_hook" [vmlinux] version generation failed, symbol will not be versioned. ... WARNING: modpost: EXPORT symbol "nf_nat_irc_hook" [vmlinux] version generation failed, symbol will not be versioned. ... genksyms falls over parsing the __rcu attribute in the declarator: # Kernel reproducer $ make -skj"$(nproc)" ARCH=x86_64 KCFLAGS=-D__GENKSYMS__ LLVM=1 net/netfilter/nf_conntrack_ftp.i $ scripts/genksyms/genksyms -w :2: syntax error Optionally allow an attribute to precede a declarator to resolve this error and properly generate symbol versions. Fixes: 07919126ecfc ("netfilter: annotate NAT helper hook pointers with __rcu") Link: https://patch.msgid.link/20260225-genksyms-fix-attribute-declarator-v1-1-1b21478663fb@kernel.org Tested-by: Nicolas Schier Reviewed-by: Nicolas Schier Signed-off-by: Nathan Chancellor --- scripts/genksyms/parse.y | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index efdcf07c4eb6..cabcd146f3aa 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -325,8 +325,8 @@ direct_declarator: { $$ = $4; } | direct_declarator BRACKET_PHRASE { $$ = $2; } - | '(' declarator ')' - { $$ = $3; } + | '(' attribute_opt declarator ')' + { $$ = $4; } ; /* Nested declarators differ from regular declarators in that they do -- cgit v1.2.3 From 459cb3c054c2352bb321648744b620259a716b60 Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Thu, 26 Feb 2026 08:41:48 +0100 Subject: kbuild: install-extmod-build: Package resolve_btfids if necessary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When CONFIG_DEBUG_INFO_BTF_MODULES is enabled and vmlinux is available, Makefile.modfinal and gen-btf.sh will try to use resolve_btfids on the module .ko. install-extmod-build currently does not package resolve_btfids, so that step fails. Package resolve_btfids if it may be used. Signed-off-by: Thomas Weißschuh Reviewed-by: Nicolas Schier Link: https://patch.msgid.link/20260226-kbuild-resolve_btfids-v1-1-2bf38b93dfe7@linutronix.de [nathan: Small commit message tweaks] Signed-off-by: Nathan Chancellor --- scripts/package/install-extmod-build | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'scripts') diff --git a/scripts/package/install-extmod-build b/scripts/package/install-extmod-build index 2576cf7902db..f12e1ffe409e 100755 --- a/scripts/package/install-extmod-build +++ b/scripts/package/install-extmod-build @@ -32,6 +32,10 @@ mkdir -p "${destdir}" echo tools/objtool/objtool fi + if is_enabled CONFIG_DEBUG_INFO_BTF_MODULES; then + echo tools/bpf/resolve_btfids/resolve_btfids + fi + echo Module.symvers echo "arch/${SRCARCH}/include/generated" echo include/config/auto.conf -- cgit v1.2.3 From f41941aab3acd33f13d65a2ae496329bc8ae4de0 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Mon, 2 Mar 2026 16:42:35 +0000 Subject: rust: ptr: add projection infrastructure Add a generic infrastructure for performing field and index projections on raw pointers. This will form the basis of performing I/O projections. Pointers manipulations are intentionally using the safe wrapping variants instead of the unsafe variants, as the latter requires pointers to be inside an allocation which is not necessarily true for I/O pointers. This projection macro protects against rogue `Deref` implementation, which can causes the projected pointer to be outside the bounds of starting pointer. This is extremely unlikely and Rust has a lint to catch this, but is unsoundness regardless. The protection works by inducing type inference ambiguity when `Deref` is implemented. This projection macro also stops projecting into unaligned fields (i.e. fields of `#[repr(packed)]` structs), as misaligned pointers require special handling. This is implemented by attempting to create reference to projected field inside a `if false` block. Despite being unreachable, Rust still checks that they're not unaligned fields. The projection macro supports both fallible and infallible index projections. These are described in detail inside the documentation. Signed-off-by: Gary Guo Reviewed-by: Benno Lossin Acked-by: Miguel Ojeda Link: https://patch.msgid.link/20260302164239.284084-3-gary@kernel.org [ * Add intro-doc links where possible, * Fix typos and slightly improve wording, e.g. "as documentation describes" -> "as the documentation of [`Self::proj`] describes", * Add an empty line between regular and safety comments, before examples, and between logically independent comments, * Capitalize various safety comments. - Danilo ] Signed-off-by: Danilo Krummrich --- rust/kernel/lib.rs | 3 + rust/kernel/ptr.rs | 3 + rust/kernel/ptr/projection.rs | 305 ++++++++++++++++++++++++++++++++++++++++++ scripts/Makefile.build | 4 +- 4 files changed, 314 insertions(+), 1 deletion(-) create mode 100644 rust/kernel/ptr/projection.rs (limited to 'scripts') diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 510cc7fe4961..d93292d47420 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -38,6 +38,9 @@ #![feature(const_ptr_write)] #![feature(const_refs_to_cell)] // +// Stable since Rust 1.84.0. +#![feature(strict_provenance)] +// // Expected to become stable. #![feature(arbitrary_self_types)] // diff --git a/rust/kernel/ptr.rs b/rust/kernel/ptr.rs index e91de5f0d78f..bdc2d79ff669 100644 --- a/rust/kernel/ptr.rs +++ b/rust/kernel/ptr.rs @@ -2,6 +2,9 @@ //! Types and functions to work with pointers and addresses. +pub mod projection; +pub use crate::project_pointer as project; + use core::mem::{ align_of, size_of, // diff --git a/rust/kernel/ptr/projection.rs b/rust/kernel/ptr/projection.rs new file mode 100644 index 000000000000..140ea8e21617 --- /dev/null +++ b/rust/kernel/ptr/projection.rs @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Infrastructure for handling projections. + +use core::{ + mem::MaybeUninit, + ops::Deref, // +}; + +use crate::prelude::*; + +/// Error raised when a projection is attempted on an array or slice out of bounds. +pub struct OutOfBound; + +impl From for Error { + #[inline(always)] + fn from(_: OutOfBound) -> Self { + ERANGE + } +} + +/// A helper trait to perform index projection. +/// +/// This is similar to [`core::slice::SliceIndex`], but operates on raw pointers safely and +/// fallibly. +/// +/// # Safety +/// +/// The implementation of `index` and `get` (if [`Some`] is returned) must ensure that, if provided +/// input pointer `slice` and returned pointer `output`, then: +/// - `output` has the same provenance as `slice`; +/// - `output.byte_offset_from(slice)` is between 0 to +/// `KnownSize::size(slice) - KnownSize::size(output)`. +/// +/// This means that if the input pointer is valid, then pointer returned by `get` or `index` is +/// also valid. +#[diagnostic::on_unimplemented(message = "`{Self}` cannot be used to index `{T}`")] +#[doc(hidden)] +pub unsafe trait ProjectIndex: Sized { + type Output: ?Sized; + + /// Returns an index-projected pointer, if in bounds. + fn get(self, slice: *mut T) -> Option<*mut Self::Output>; + + /// Returns an index-projected pointer; fail the build if it cannot be proved to be in bounds. + #[inline(always)] + fn index(self, slice: *mut T) -> *mut Self::Output { + Self::get(self, slice).unwrap_or_else(|| build_error!()) + } +} + +// Forward array impl to slice impl. +// +// SAFETY: Safety requirement guaranteed by the forwarded impl. +unsafe impl ProjectIndex<[T; N]> for I +where + I: ProjectIndex<[T]>, +{ + type Output = >::Output; + + #[inline(always)] + fn get(self, slice: *mut [T; N]) -> Option<*mut Self::Output> { + >::get(self, slice) + } + + #[inline(always)] + fn index(self, slice: *mut [T; N]) -> *mut Self::Output { + >::index(self, slice) + } +} + +// SAFETY: `get`-returned pointer has the same provenance as `slice` and the offset is checked to +// not exceed the required bound. +unsafe impl ProjectIndex<[T]> for usize { + type Output = T; + + #[inline(always)] + fn get(self, slice: *mut [T]) -> Option<*mut T> { + if self >= slice.len() { + None + } else { + Some(slice.cast::().wrapping_add(self)) + } + } +} + +// SAFETY: `get`-returned pointer has the same provenance as `slice` and the offset is checked to +// not exceed the required bound. +unsafe impl ProjectIndex<[T]> for core::ops::Range { + type Output = [T]; + + #[inline(always)] + fn get(self, slice: *mut [T]) -> Option<*mut [T]> { + let new_len = self.end.checked_sub(self.start)?; + if self.end > slice.len() { + return None; + } + Some(core::ptr::slice_from_raw_parts_mut( + slice.cast::().wrapping_add(self.start), + new_len, + )) + } +} + +// SAFETY: Safety requirement guaranteed by the forwarded impl. +unsafe impl ProjectIndex<[T]> for core::ops::RangeTo { + type Output = [T]; + + #[inline(always)] + fn get(self, slice: *mut [T]) -> Option<*mut [T]> { + (0..self.end).get(slice) + } +} + +// SAFETY: Safety requirement guaranteed by the forwarded impl. +unsafe impl ProjectIndex<[T]> for core::ops::RangeFrom { + type Output = [T]; + + #[inline(always)] + fn get(self, slice: *mut [T]) -> Option<*mut [T]> { + (self.start..slice.len()).get(slice) + } +} + +// SAFETY: `get` returned the pointer as is, so it always has the same provenance and offset of 0. +unsafe impl ProjectIndex<[T]> for core::ops::RangeFull { + type Output = [T]; + + #[inline(always)] + fn get(self, slice: *mut [T]) -> Option<*mut [T]> { + Some(slice) + } +} + +/// A helper trait to perform field projection. +/// +/// This trait has a `DEREF` generic parameter so it can be implemented twice for types that +/// implement [`Deref`]. This will cause an ambiguity error and thus block [`Deref`] types being +/// used as base of projection, as they can inject unsoundness. Users therefore must not specify +/// `DEREF` and should always leave it to be inferred. +/// +/// # Safety +/// +/// `proj` may only invoke `f` with a valid allocation, as the documentation of [`Self::proj`] +/// describes. +#[doc(hidden)] +pub unsafe trait ProjectField { + /// Project a pointer to a type to a pointer of a field. + /// + /// `f` may only be invoked with a valid allocation so it can safely obtain raw pointers to + /// fields using `&raw mut`. + /// + /// This is needed because `base` might not point to a valid allocation, while `&raw mut` + /// requires pointers to be in bounds of a valid allocation. + /// + /// # Safety + /// + /// `f` must return a pointer in bounds of the provided pointer. + unsafe fn proj(base: *mut Self, f: impl FnOnce(*mut Self) -> *mut F) -> *mut F; +} + +// NOTE: in theory, this API should work for `T: ?Sized` and `F: ?Sized`, too. However, we cannot +// currently support that as we need to obtain a valid allocation that `&raw const` can operate on. +// +// SAFETY: `proj` invokes `f` with valid allocation. +unsafe impl ProjectField for T { + #[inline(always)] + unsafe fn proj(base: *mut Self, f: impl FnOnce(*mut Self) -> *mut F) -> *mut F { + // Create a valid allocation to start projection, as `base` is not necessarily so. The + // memory is never actually used so it will be optimized out, so it should work even for + // very large `T` (`memoffset` crate also relies on this). To be extra certain, we also + // annotate `f` closure with `#[inline(always)]` in the macro. + let mut place = MaybeUninit::uninit(); + let place_base = place.as_mut_ptr(); + let field = f(place_base); + // SAFETY: `field` is in bounds from `base` per safety requirement. + let offset = unsafe { field.byte_offset_from(place_base) }; + // Use `wrapping_byte_offset` as `base` does not need to be of valid allocation. + base.wrapping_byte_offset(offset).cast() + } +} + +// SAFETY: Vacuously satisfied. +unsafe impl ProjectField for T { + #[inline(always)] + unsafe fn proj(_: *mut Self, _: impl FnOnce(*mut Self) -> *mut F) -> *mut F { + build_error!("this function is a guard against `Deref` impl and is never invoked"); + } +} + +/// Create a projection from a raw pointer. +/// +/// The projected pointer is within the memory region marked by the input pointer. There is no +/// requirement that the input raw pointer needs to be valid, so this macro may be used for +/// projecting pointers outside normal address space, e.g. I/O pointers. However, if the input +/// pointer is valid, the projected pointer is also valid. +/// +/// Supported projections include field projections and index projections. +/// It is not allowed to project into types that implement custom [`Deref`] or +/// [`Index`](core::ops::Index). +/// +/// The macro has basic syntax of `kernel::ptr::project!(ptr, projection)`, where `ptr` is an +/// expression that evaluates to a raw pointer which serves as the base of projection. `projection` +/// can be a projection expression of form `.field` (normally identifier, or numeral in case of +/// tuple structs) or of form `[index]`. +/// +/// If a mutable pointer is needed, the macro input can be prefixed with the `mut` keyword, i.e. +/// `kernel::ptr::project!(mut ptr, projection)`. By default, a const pointer is created. +/// +/// `ptr::project!` macro can perform both fallible indexing and build-time checked indexing. +/// `[index]` form performs build-time bounds checking; if compiler fails to prove `[index]` is in +/// bounds, compilation will fail. `[index]?` can be used to perform runtime bounds checking; +/// `OutOfBound` error is raised via `?` if the index is out of bounds. +/// +/// # Examples +/// +/// Field projections are performed with `.field_name`: +/// +/// ``` +/// struct MyStruct { field: u32, } +/// let ptr: *const MyStruct = core::ptr::dangling(); +/// let field_ptr: *const u32 = kernel::ptr::project!(ptr, .field); +/// +/// struct MyTupleStruct(u32, u32); +/// +/// fn proj(ptr: *const MyTupleStruct) { +/// let field_ptr: *const u32 = kernel::ptr::project!(ptr, .1); +/// } +/// ``` +/// +/// Index projections are performed with `[index]`: +/// +/// ``` +/// fn proj(ptr: *const [u8; 32]) -> Result { +/// let field_ptr: *const u8 = kernel::ptr::project!(ptr, [1]); +/// // The following invocation, if uncommented, would fail the build. +/// // +/// // kernel::ptr::project!(ptr, [128]); +/// +/// // This will raise an `OutOfBound` error (which is convertible to `ERANGE`). +/// kernel::ptr::project!(ptr, [128]?); +/// Ok(()) +/// } +/// ``` +/// +/// If you need to match on the error instead of propagate, put the invocation inside a closure: +/// +/// ``` +/// let ptr: *const [u8; 32] = core::ptr::dangling(); +/// let field_ptr: Result<*const u8> = (|| -> Result<_> { +/// Ok(kernel::ptr::project!(ptr, [128]?)) +/// })(); +/// assert!(field_ptr.is_err()); +/// ``` +/// +/// For mutable pointers, put `mut` as the first token in macro invocation. +/// +/// ``` +/// let ptr: *mut [(u8, u16); 32] = core::ptr::dangling_mut(); +/// let field_ptr: *mut u16 = kernel::ptr::project!(mut ptr, [1].1); +/// ``` +#[macro_export] +macro_rules! project_pointer { + (@gen $ptr:ident, ) => {}; + // Field projection. `$field` needs to be `tt` to support tuple index like `.0`. + (@gen $ptr:ident, .$field:tt $($rest:tt)*) => { + // SAFETY: The provided closure always returns an in-bounds pointer. + let $ptr = unsafe { + $crate::ptr::projection::ProjectField::proj($ptr, #[inline(always)] |ptr| { + // Check unaligned field. Not all users (e.g. DMA) can handle unaligned + // projections. + if false { + let _ = &(*ptr).$field; + } + // SAFETY: `$field` is in bounds, and no implicit `Deref` is possible (if the + // type implements `Deref`, Rust cannot infer the generic parameter `DEREF`). + &raw mut (*ptr).$field + }) + }; + $crate::ptr::project!(@gen $ptr, $($rest)*) + }; + // Fallible index projection. + (@gen $ptr:ident, [$index:expr]? $($rest:tt)*) => { + let $ptr = $crate::ptr::projection::ProjectIndex::get($index, $ptr) + .ok_or($crate::ptr::projection::OutOfBound)?; + $crate::ptr::project!(@gen $ptr, $($rest)*) + }; + // Build-time checked index projection. + (@gen $ptr:ident, [$index:expr] $($rest:tt)*) => { + let $ptr = $crate::ptr::projection::ProjectIndex::index($index, $ptr); + $crate::ptr::project!(@gen $ptr, $($rest)*) + }; + (mut $ptr:expr, $($proj:tt)*) => {{ + let ptr: *mut _ = $ptr; + $crate::ptr::project!(@gen ptr, $($proj)*); + ptr + }}; + ($ptr:expr, $($proj:tt)*) => {{ + let ptr = <*const _>::cast_mut($ptr); + // We currently always project using mutable pointer, as it is not decided whether `&raw + // const` allows the resulting pointer to be mutated (see documentation of `addr_of!`). + $crate::ptr::project!(@gen ptr, $($proj)*); + ptr.cast_const() + }}; +} diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 32e209bc7985..3652b85be545 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -310,16 +310,18 @@ $(obj)/%.lst: $(obj)/%.c FORCE # The features in this list are the ones allowed for non-`rust/` code. # +# - Stable since Rust 1.79.0: `feature(slice_ptr_len)`. # - Stable since Rust 1.81.0: `feature(lint_reasons)`. # - Stable since Rust 1.82.0: `feature(asm_const)`, # `feature(offset_of_nested)`, `feature(raw_ref_op)`. +# - Stable since Rust 1.84.0: `feature(strict_provenance)`. # - Stable since Rust 1.87.0: `feature(asm_goto)`. # - Expected to become stable: `feature(arbitrary_self_types)`. # - To be determined: `feature(used_with_arg)`. # # Please see https://github.com/Rust-for-Linux/linux/issues/2 for details on # the unstable features in use. -rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,lint_reasons,offset_of_nested,raw_ref_op,used_with_arg +rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,lint_reasons,offset_of_nested,raw_ref_op,slice_ptr_len,strict_provenance,used_with_arg # `--out-dir` is required to avoid temporaries being created by `rustc` in the # current working directory, which may be not accessible in the out-of-tree -- cgit v1.2.3 From 3b4a3a00de8770f3a60c1fa483921ce37415132d Mon Sep 17 00:00:00 2001 From: Weizhao Ouyang Date: Mon, 9 Mar 2026 20:15:05 +0800 Subject: scripts: kconfig: merge_config.sh: fix unexpected operator warning Fix a warning for: $ ./scripts/kconfig/merge_config.sh .config extra.config Using .config as base Merging extra.config ./scripts/kconfig/merge_config.sh: 384: [: false: unexpected operator The shellcheck report is also attached: if [ "$STRICT" == "true" ] && [ "$STRICT_MODE_VIOLATED" == "true" ]; then ^-- SC3014 (warning): In POSIX sh, == in place of = is undefined. ^-- SC3014 (warning): In POSIX sh, == in place of = is undefined. Fixes: dfc97e1c5da5 ("scripts: kconfig: merge_config.sh: use awk in checks too") Signed-off-by: Weizhao Ouyang Reviewed-by: Mikko Rapeli Link: https://patch.msgid.link/20260309121505.40454-1-o451686892@gmail.com Signed-off-by: Nathan Chancellor --- scripts/kconfig/merge_config.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 735e1de450c6..073c6bec5245 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -381,7 +381,7 @@ END { STRICT_MODE_VIOLATED=true fi -if [ "$STRICT" == "true" ] && [ "$STRICT_MODE_VIOLATED" == "true" ]; then +if [ "$STRICT" = "true" ] && [ "$STRICT_MODE_VIOLATED" = "true" ]; then echo "Requested and effective config differ" exit 1 fi -- cgit v1.2.3 From 5f47be1b44bf2754c45e8c58ca036b474c9ecbc7 Mon Sep 17 00:00:00 2001 From: Daniel Gomez Date: Tue, 10 Mar 2026 12:36:23 +0100 Subject: scripts: kconfig: merge_config.sh: pass output file as awk variable The refactoring commit 5fa9b82cbcfc5 ("scripts: kconfig: merge_config.sh: refactor from shell/sed/grep to awk") passes $TMP_FILE.new as ARGV[3] to awk, using it as both an output destination and an input file argument. When the base file is empty, nothing is written to ARGV[3] during processing, so awk fails trying to open it for reading: awk: cmd. line:52: fatal: cannot open file `./.tmp.config.grcQin34jb.new' for reading: No such file or directory mv: cannot stat './.tmp.config.grcQin34jb.new': No such file or directory Pass the output path via -v outfile instead and drop the FILENAME == ARGV[3] { nextfile }. Fixes: 5fa9b82cbcfc5 ("scripts: kconfig: merge_config.sh: refactor from shell/sed/grep to awk") Signed-off-by: Daniel Gomez Link: https://patch.msgid.link/20260310-fixes-merge-config-v1-1-beaeeaded6bd@samsung.com Signed-off-by: Nathan Chancellor --- scripts/kconfig/merge_config.sh | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 073c6bec5245..45e6400c68b6 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -151,6 +151,7 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do if ! "$AWK" -v prefix="$CONFIG_PREFIX" \ -v warnoverride="$WARNOVERRIDE" \ -v strict="$STRICT" \ + -v outfile="$TMP_FILE.new" \ -v builtin="$BUILTIN" \ -v warnredun="$WARNREDUN" ' BEGIN { @@ -212,7 +213,7 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do # Not a config or not in merge file - keep it if (cfg == "" || !(cfg in merge_cfg)) { - print $0 >> ARGV[3] + print $0 >> outfile next } @@ -222,7 +223,7 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do # BUILTIN: do not demote y to m if (builtin == "true" && new_val ~ /=m$/ && prev_val ~ /=y$/) { warn_builtin(cfg, prev_val, new_val) - print $0 >> ARGV[3] + print $0 >> outfile skip_merge[merge_cfg_line[cfg]] = 1 next } @@ -235,7 +236,7 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do # "=n" is the same as "is not set" if (prev_val ~ /=n$/ && new_val ~ / is not set$/) { - print $0 >> ARGV[3] + print $0 >> outfile next } @@ -246,25 +247,20 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do } } - # output file, skip all lines - FILENAME == ARGV[3] { - nextfile - } - END { # Newline in case base file lacks trailing newline - print "" >> ARGV[3] + print "" >> outfile # Append merge file, skipping lines marked for builtin preservation for (i = 1; i <= merge_total; i++) { if (!(i in skip_merge)) { - print merge_lines[i] >> ARGV[3] + print merge_lines[i] >> outfile } } if (strict_violated) { exit 1 } }' \ - "$ORIG_MERGE_FILE" "$TMP_FILE" "$TMP_FILE.new"; then + "$ORIG_MERGE_FILE" "$TMP_FILE"; then # awk exited non-zero, strict mode was violated STRICT_MODE_VIOLATED=true fi -- cgit v1.2.3 From 775af5cbb22c1de2ad0f486959739c35cfc55ac8 Mon Sep 17 00:00:00 2001 From: Daniel Gomez Date: Tue, 10 Mar 2026 12:36:24 +0100 Subject: scripts: kconfig: merge_config.sh: fix indentation Replace spaces with tabs for consistency with the rest of the script. Fixes: 5fa9b82cbcfc5 ("scripts: kconfig: merge_config.sh: refactor from shell/sed/grep to awk") Signed-off-by: Daniel Gomez Link: https://patch.msgid.link/20260310-fixes-merge-config-v1-2-beaeeaded6bd@samsung.com Signed-off-by: Nathan Chancellor --- scripts/kconfig/merge_config.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 45e6400c68b6..f08e0863b712 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -196,7 +196,7 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do # First pass: read merge file, store all lines and index FILENAME == ARGV[1] { - mergefile = FILENAME + mergefile = FILENAME merge_lines[FNR] = $0 merge_total = FNR cfg = get_cfg($0) @@ -217,7 +217,7 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do next } - prev_val = $0 + prev_val = $0 new_val = merge_cfg[cfg] # BUILTIN: do not demote y to m -- cgit v1.2.3 From 6f93f7b06810d04acc6b106a7d5ecd6000f80545 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Tue, 10 Mar 2026 16:37:48 -0400 Subject: livepatch/klp-build: Fix inconsistent kernel version If .config hasn't been synced with auto.conf, any recent changes to CONFIG_LOCALVERSION* may not get reflected in the kernel version name. Use "make syncconfig" to force them to sync, and "make -s kernelrelease" to get the version instead of having to construct it manually. Fixes: 24ebfcd65a87 ("livepatch/klp-build: Introduce klp-build script for generating livepatch modules") Closes: https://lore.kernel.org/20260217160645.3434685-10-joe.lawrence@redhat.com Reported-by: Joe Lawrence Signed-off-by: Josh Poimboeuf Signed-off-by: Joe Lawrence Acked-by: Song Liu Link: https://patch.msgid.link/20260310203751.1479229-10-joe.lawrence@redhat.com Signed-off-by: Josh Poimboeuf --- scripts/livepatch/klp-build | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index 809e198a561d..7b82c7503c2b 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -285,15 +285,14 @@ set_module_name() { # application from appending it with '+' due to a dirty git working tree. set_kernelversion() { local file="$SRC/scripts/setlocalversion" - local localversion + local kernelrelease stash_file "$file" - localversion="$(cd "$SRC" && make --no-print-directory kernelversion)" - localversion="$(cd "$SRC" && KERNELVERSION="$localversion" ./scripts/setlocalversion)" - [[ -z "$localversion" ]] && die "setlocalversion failed" + kernelrelease="$(cd "$SRC" && make syncconfig &>/dev/null && make -s kernelrelease)" + [[ -z "$kernelrelease" ]] && die "failed to get kernel version" - sed -i "2i echo $localversion; exit 0" scripts/setlocalversion + sed -i "2i echo $kernelrelease; exit 0" scripts/setlocalversion } get_patch_files() { -- cgit v1.2.3 From 1c7bbaeed110b0fd9e65e173fb4d612f64a20d93 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 20 Mar 2026 10:51:18 -0700 Subject: coccinelle: kmalloc_obj: Remove default GFP_KERNEL arg Remove any GFP_KERNEL arguments found in the new kmalloc_obj-family helpers. This captures the script used in commit 189f164e573e ("Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses"). Link: https://patch.msgid.link/20260320175113.work.016-kees@kernel.org Signed-off-by: Kees Cook --- scripts/coccinelle/api/kmalloc_objs.cocci | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'scripts') diff --git a/scripts/coccinelle/api/kmalloc_objs.cocci b/scripts/coccinelle/api/kmalloc_objs.cocci index db12b7be7247..e9a415b7b6f4 100644 --- a/scripts/coccinelle/api/kmalloc_objs.cocci +++ b/scripts/coccinelle/api/kmalloc_objs.cocci @@ -122,3 +122,14 @@ fresh identifier ALLOC_OBJS = script:python(ALLOC_ARRAY) { alloc_array(ALLOC_ARR - ALLOC(struct_size_t(TYPE, FLEX, COUNT), GFP) + ALLOC_FLEX(TYPE, FLEX, COUNT, GFP) ) + +@drop_gfp_kernel depends on patch && !(file in "tools") && !(file in "samples")@ +identifier ALLOC = {kmalloc_obj,kmalloc_objs,kmalloc_flex, + kzalloc_obj,kzalloc_objs,kzalloc_flex, + kvmalloc_obj,kvmalloc_objs,kvmalloc_flex, + kvzalloc_obj,kvzalloc_objs,kvzalloc_flex}; +@@ + + ALLOC(... +- , GFP_KERNEL + ) -- cgit v1.2.3 From 742de64b62b690a368dbeb846499eb8ac8ceedb9 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 27 Mar 2026 09:30:29 +0100 Subject: kbuild: modules-cpio-pkg: Respect INSTALL_MOD_PATH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The modules-cpio-pkg target added in commit 2a9c8c0b59d3 ("kbuild: add target to build a cpio containing modules") is incompatible with initramfs with merged /lib and /usr/lib directories [1]. "/lib" cannot be a link and directory at the same time. Respect a non-empty INSTALL_MOD_PATH in the modules-cpio-pkg target so that `make INSTALL_MOD_PATH=/usr modules-cpio-pkg` results in the same module install location as `make INSTALL_MOD_PATH=/usr modules_install`. Tested with Fedora distribution initramfs produced by dracut. Link: https://systemd.io/THE_CASE_FOR_THE_USR_MERGE/ [1] Fixes: 2a9c8c0b59d3 ("kbuild: add target to build a cpio containing modules") Cc: stable@vger.kernel.org Reviewed-by: Simon Glass Reviewed-by: Nathan Chancellor Reviewed-by: Thomas Weißschuh Signed-off-by: Janne Grunau Reviewed-by: Nicolas Schier Tested-by: Nicolas Schier Reviewed-by: Ahmad Fatoum Link: https://patch.msgid.link/20260327-kbuild-modules-cpio-pkg-usr-merge-v3-1-ef507dfa006c@jannau.net Signed-off-by: Nathan Chancellor --- scripts/Makefile.package | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.package b/scripts/Makefile.package index 0ec946f9b905..6d36786ba31c 100644 --- a/scripts/Makefile.package +++ b/scripts/Makefile.package @@ -195,7 +195,7 @@ tar%-pkg: linux-$(KERNELRELEASE)-$(ARCH).tar.% FORCE .tmp_modules_cpio: FORCE $(Q)$(MAKE) -f $(srctree)/Makefile $(Q)rm -rf $@ - $(Q)$(MAKE) -f $(srctree)/Makefile INSTALL_MOD_PATH=$@ modules_install + $(Q)$(MAKE) -f $(srctree)/Makefile INSTALL_MOD_PATH=$@/$(INSTALL_MOD_PATH) modules_install quiet_cmd_cpio = CPIO $@ cmd_cpio = $(CONFIG_SHELL) $(srctree)/usr/gen_initramfs.sh -o $@ $< @@ -264,6 +264,7 @@ help: @echo ' tarxz-pkg - Build the kernel as a xz compressed tarball' @echo ' tarzst-pkg - Build the kernel as a zstd compressed tarball' @echo ' modules-cpio-pkg - Build the kernel modules as cpio archive' + @echo ' (uses INSTALL_MOD_PATH inside the archive)' @echo ' perf-tar-src-pkg - Build the perf source tarball with no compression' @echo ' perf-targz-src-pkg - Build the perf source tarball with gzip compression' @echo ' perf-tarbz2-src-pkg - Build the perf source tarball with bz2 compression' -- cgit v1.2.3 From deb4605671cfae3b2803cfbbf4739e7245248398 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 25 Mar 2026 18:20:30 -0700 Subject: modpost: Declare extra_warn with unused attribute A recent strengthening of -Wunused-but-set-variable (enabled with -Wall) in clang under a new subwarning, -Wunused-but-set-global, points out an unused static global variable in scripts/mod/modpost.c: scripts/mod/modpost.c:59:13: error: variable 'extra_warn' set but not used [-Werror,-Wunused-but-set-global] 59 | static bool extra_warn; | ^ This variable has been unused since commit 6c6c1fc09de3 ("modpost: require a MODULE_DESCRIPTION()") but that is expected, as there are currently no extra warnings at W=1 right now. Declare the variable with the unused attribute to make it clear to the compiler that this variable may be unused. Cc: stable@vger.kernel.org Fixes: 6c6c1fc09de3 ("modpost: require a MODULE_DESCRIPTION()") Link: https://patch.msgid.link/20260325-modpost-extra_warn-unused-but-set-global-v1-1-2e84003b7e81@kernel.org Reviewed-by: Nicolas Schier Signed-off-by: Nathan Chancellor --- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 0c25b5ad497b..c3bc801d8b2d 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -56,7 +56,7 @@ static bool allow_missing_ns_imports; static bool error_occurred; -static bool extra_warn; +static bool extra_warn __attribute__((unused)); bool target_is_big_endian; bool host_is_big_endian; -- cgit v1.2.3