mirror of
https://github.com/torvalds/linux.git
synced 2026-09-11 20:13:02 +02:00
Rust fixes for v7.3
Toolchain and infrastructure:
- Fix KCFI failures, such as in Rust doctests, by disabling function
merging when CFI is enabled. Gary reported the LLVM bug to upstream
and it is now fixed in their mainline.
- Fix 'objtool' fallthrough warnings under the experimental
'CONFIG_RUST_INLINE_HELPERS' by passing (for the combined Rust and
helpers code) the LLVM options needed to preserve the unreachable
traps that 'rustc' normally emits.
In addition, fix 'objtool' errors when LTO is enabled on top, by
also filtering out the LTO flags (for the combined Rust and helpers
code) so that the traps are kept in place.
- Fix 'objtool' warnings by adding one more 'noreturn' function.
- Fix 'make rusttest' target when the 'rustc-dev' component is
installed and Rust >= 1.82.0, <= 1.87.0 is used.
'kernel' crate:
- 'num' module: fix soundness issue in the 'Bounded' conversion from
'bool' by restricting the conversions to unsigned 'Bounded'.
- 'jump_label' module: fix future 'make rusttest' target failures when
'ARCH=' is set to an arch different than the host's.
- 'list' module: fix incorrect 'pop_back()' comment.
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEPjU5OPd5QIZ9jqqOGXyLc2htIW0FAmqT+BIACgkQGXyLc2ht
IW0vRRAAmR1E04gT5HFDH+iNJgLlyticVsHs0rH46ICYgQWs+gpGGiJsPpnNBJxM
M5+VGauMPch5kIBKYwD/XrUe6cDDNqIfY8Eq+BnJiTxDe6U68K4cSnmPe478wZIn
15AIteCHN2x9vf49KpfI3fH/xoriS5XVEC915bQ9APXOYJv7iXZCFDzxw9dXnYu/
TE3YleA32oJ9COBT3s8ovtzNpEOtZPKhWFd2lOCaGbxBLWygu5X/PSEZs6ikmqgR
BqHrbhzSco8aYKCrbFbQrdgtwFPr3PQ8pRn44TPU6/siZNVBk83IpcxdtXrQ2gRi
wOwZfMsH2K/cEZWMXPz16hp+4onWUr1bgkfLUAzPtyqUX6rOEaBrliSXGs+yCl40
KNx5BefrhzH6UL+/pbLGVXzC5q1VLTsgS6u66piUyvhf52Wmvzc7AExGml/BWA/q
jomwnxpgLiBjO61cH4dnfrm3AtXHAWGzG/dd0BnVcpT+8HEr2W4WWRSydmPtkB+f
hXXmwAOF3sgVueJ2nxlPVcqt3LdsinCwBrQQmO8J+TtPyNW9sh72OfFSOkF/wybw
o5tcqFG7ZSNGR7pli5pYsnG4Gfv3vIraLwhiVciGXZ+es+FkKtOpaOMunUcQwKP6
+uFpdMqXVQmH4l3Adc0rG1lq6zRHnGvZ96R5PlmPhl6RVDZuv0E=
=EBLX
-----END PGP SIGNATURE-----
Merge tag 'rust-fixes-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux
Pull Rust fixes from Miguel Ojeda:
"Toolchain and infrastructure:
- Fix KCFI failures, such as in Rust doctests, by disabling function
merging when CFI is enabled. Gary reported the LLVM bug to upstream
and it is now fixed in their mainline.
- Fix 'objtool' fallthrough warnings under the experimental
'CONFIG_RUST_INLINE_HELPERS' by passing (for the combined Rust and
helpers code) the LLVM options needed to preserve the unreachable
traps that 'rustc' normally emits.
In addition, fix 'objtool' errors when LTO is enabled on top, by
also filtering out the LTO flags (for the combined Rust and helpers
code) so that the traps are kept in place.
- Fix 'objtool' warnings by adding one more 'noreturn' function.
- Fix 'make rusttest' target when the 'rustc-dev' component is
installed and Rust >= 1.82.0, <= 1.87.0 is used.
'kernel' crate:
- 'num' module: fix soundness issue in the 'Bounded' conversion from
'bool' by restricting the conversions to unsigned 'Bounded'.
- 'jump_label' module: fix future 'make rusttest' target failures
when 'ARCH=' is set to an arch different than the host's.
- 'list' module: fix incorrect 'pop_back()' comment"
* tag 'rust-fixes-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux:
rust: kbuild: disambiguate `zerocopy_derive` for `rusttest`
rust: num: restrict bool conversion to unsigned Bounded
kbuild: rust: keep Rust objects out of Clang LTO with inline helpers
kbuild: rust: preserve unreachable traps with inline helpers
rust: cfi: disable function merging if CFI is enabled
rust: jump_label: skip arch-specific asm in `testlib` builds
objtool/rust: add one more `noreturn` Rust function
rust: kernel: list: fix incorrect pop_back example comment
This commit is contained in:
commit
f59c074e76
13
Makefile
13
Makefile
|
|
@ -1083,6 +1083,16 @@ endif
|
|||
export CC_FLAGS_SCS
|
||||
endif
|
||||
|
||||
ifdef CONFIG_RUST_INLINE_HELPERS
|
||||
# `rustc` normally emits traps for unreachable paths during code generation.
|
||||
# With inline helpers, Clang performs code generation from the linked bitcode
|
||||
# instead, so request the same behavior explicitly. Otherwise `objtool` may
|
||||
# follow an impossible Rust path into the next function.
|
||||
CC_FLAGS_RUST_INLINE_HELPERS := -mllvm -trap-unreachable \
|
||||
-mllvm -no-trap-after-noreturn
|
||||
export CC_FLAGS_RUST_INLINE_HELPERS
|
||||
endif
|
||||
|
||||
ifdef CONFIG_LTO_CLANG
|
||||
ifdef CONFIG_LTO_CLANG_FULL
|
||||
CC_FLAGS_LTO := -flto
|
||||
|
|
@ -1118,7 +1128,8 @@ endif
|
|||
ifdef CONFIG_RUST
|
||||
# Always pass -Zsanitizer-cfi-normalize-integers as CONFIG_RUST selects
|
||||
# CONFIG_CFI_ICALL_NORMALIZE_INTEGERS.
|
||||
RUSTC_FLAGS_CFI := -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers
|
||||
# Disable function merging as LLVM incorrectly merges functions with different KCFI types.
|
||||
RUSTC_FLAGS_CFI := -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers -Zmerge-functions=disabled
|
||||
KBUILD_RUSTFLAGS += $(RUSTC_FLAGS_CFI)
|
||||
export RUSTC_FLAGS_CFI
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -354,7 +354,8 @@ rusttestlib-pin_init: $(src)/pin-init/src/lib.rs rusttestlib-macros \
|
|||
rusttestlib-kernel: private rustc_target_flags = --extern ffi \
|
||||
--extern build_error --extern macros --extern pin_init \
|
||||
--extern bindings --extern uapi \
|
||||
--extern zerocopy=$(objtree)/$(obj)/test/libzerocopy.rlib --extern zerocopy_derive
|
||||
--extern zerocopy=$(objtree)/$(obj)/test/libzerocopy.rlib \
|
||||
--extern zerocopy_derive=$(objtree)/$(obj)/test/$(libzerocopy_derive_name)
|
||||
rusttestlib-kernel: $(src)/kernel/lib.rs rusttestlib-bindings rusttestlib-uapi \
|
||||
rusttestlib-build_error rusttestlib-pin_init $(obj)/$(libmacros_name) \
|
||||
$(obj)/bindings.o rusttestlib-zerocopy rusttestlib-zerocopy_derive FORCE
|
||||
|
|
@ -656,7 +657,8 @@ quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L
|
|||
-Zunstable-options \
|
||||
$(if $(link_helper),;$(LLVM_LINK) --internalize --suppress-warnings $(patsubst %.o,%.bc,$@) \
|
||||
$(obj)/helpers/helpers$(if $(part-of-module),_module).bc -o $(patsubst %.o,%.m.bc,$@); \
|
||||
$(CC) $(CLANG_FLAGS) $(KBUILD_CFLAGS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \
|
||||
$(CC) $(CLANG_FLAGS) $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS)) \
|
||||
$(CC_FLAGS_RUST_INLINE_HELPERS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \
|
||||
$(cmd_ld_single)) \
|
||||
$(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) \
|
||||
$(cmd_objtool)
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ macro_rules! static_branch_unlikely {
|
|||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(testlib))]
|
||||
#[cfg(CONFIG_JUMP_LABEL)]
|
||||
macro_rules! arch_static_branch {
|
||||
($key:path, $keytyp:ty, $field:ident, $branch:expr) => {'my_label: {
|
||||
|
|
@ -61,6 +62,17 @@ macro_rules! arch_static_branch {
|
|||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
#[cfg(testlib)]
|
||||
#[cfg(CONFIG_JUMP_LABEL)]
|
||||
macro_rules! arch_static_branch {
|
||||
($key:path, $keytyp:ty, $field:ident, $branch:expr) => {
|
||||
// The asm falls through until patched, which never happens on the host.
|
||||
false
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(CONFIG_JUMP_LABEL)]
|
||||
pub use arch_static_branch;
|
||||
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@
|
|||
/// assert_eq!(list.iter().count(), 3);
|
||||
/// }
|
||||
///
|
||||
/// // Pop the items from the list using `pop_front()` and verify the content.
|
||||
/// // Pop the items from the list using `pop_back()` and verify the content.
|
||||
/// {
|
||||
/// assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 15));
|
||||
/// assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 32));
|
||||
|
|
|
|||
|
|
@ -13,7 +13,10 @@
|
|||
};
|
||||
|
||||
use kernel::{
|
||||
num::Integer,
|
||||
num::{
|
||||
Integer,
|
||||
Unsigned, //
|
||||
},
|
||||
prelude::*, //
|
||||
};
|
||||
|
||||
|
|
@ -174,13 +177,16 @@ fn fits_within<T: Integer>(value: T, num_bits: u32) -> bool {
|
|||
/// // `u8` (regardless of the passed value).
|
||||
/// // let _ = Bounded::<u32, 6>::from(10u8);
|
||||
///
|
||||
/// // Booleans can be converted into single-bit `Bounded`s.
|
||||
/// // Booleans can be converted into unsigned `Bounded`s.
|
||||
///
|
||||
/// let v = Bounded::<u64, 1>::from(false);
|
||||
/// assert_eq!(v.get(), 0);
|
||||
///
|
||||
/// let v = Bounded::<u64, 1>::from(true);
|
||||
/// assert_eq!(v.get(), 1);
|
||||
///
|
||||
/// // This does not build because `i8` is signed.
|
||||
/// // let _ = Bounded::<i8, 2>::from(true);
|
||||
/// ```
|
||||
///
|
||||
/// Infallible conversions from a [`Bounded`] to a primitive integer are also supported, and
|
||||
|
|
@ -203,12 +209,16 @@ fn fits_within<T: Integer>(value: T, num_bits: u32) -> bool {
|
|||
/// let _v = Bounded::<u32, 10>::new::<10>();
|
||||
/// // assert_eq!(u8::from(_v), 10);
|
||||
///
|
||||
/// // Single-bit `Bounded`s can be converted into a boolean.
|
||||
/// // Unsigned single-bit `Bounded`s can be converted into a boolean.
|
||||
/// let v = Bounded::<u8, 1>::new::<1>();
|
||||
/// assert_eq!(bool::from(v), true);
|
||||
///
|
||||
/// let v = Bounded::<u8, 1>::new::<0>();
|
||||
/// assert_eq!(bool::from(v), false);
|
||||
///
|
||||
/// // This does not build because `i8` is signed.
|
||||
/// // let v = Bounded::<i8, 1>::new::<-1>();
|
||||
/// // let _ = bool::from(v);
|
||||
/// ```
|
||||
///
|
||||
/// Fallible conversions from any primitive integer to any [`Bounded`] are also supported using the
|
||||
|
|
@ -1109,31 +1119,33 @@ fn from(value: Bounded<T, N>) -> $type {
|
|||
i8 i16 i32 i64 isize
|
||||
);
|
||||
|
||||
// Single-bit `Bounded`s can be converted from/to a boolean.
|
||||
// Unsigned single-bit `Bounded`s can be converted to a boolean.
|
||||
|
||||
impl<T> From<Bounded<T, 1>> for bool
|
||||
where
|
||||
T: Integer + Zeroable,
|
||||
T: Integer<Signedness = Unsigned> + Zeroable,
|
||||
{
|
||||
fn from(value: Bounded<T, 1>) -> Self {
|
||||
value.get() != Zeroable::zeroed()
|
||||
}
|
||||
}
|
||||
|
||||
// Booleans can be converted to unsigned `Bounded`s.
|
||||
|
||||
impl<T, const N: u32> From<bool> for Bounded<T, N>
|
||||
where
|
||||
T: Integer + From<bool>,
|
||||
T: Integer<Signedness = Unsigned> + From<bool>,
|
||||
{
|
||||
fn from(value: bool) -> Self {
|
||||
// SAFETY: A boolean can be represented using a single bit, and thus fits within any
|
||||
// integer type for any `N` > 0.
|
||||
// SAFETY: A boolean is represented by `0` or `1`, so it fits within any valid unsigned
|
||||
// `Bounded` width.
|
||||
unsafe { Self::__new(T::from(value)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Bounded<T, 1>
|
||||
where
|
||||
T: Integer + Zeroable,
|
||||
T: Integer<Signedness = Unsigned> + Zeroable,
|
||||
{
|
||||
/// Converts this [`Bounded`] into a [`bool`].
|
||||
///
|
||||
|
|
|
|||
|
|
@ -347,7 +347,8 @@ quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
|
|||
cmd_rustc_o_rs = $(rust_common_cmd) --emit=$(if $(CONFIG_RUST_INLINE_HELPERS),llvm-bc=$(patsubst %.o,%.bc,$@),obj=$@) $< \
|
||||
$(if $(CONFIG_RUST_INLINE_HELPERS),;$(LLVM_LINK) --internalize --suppress-warnings $(patsubst %.o,%.bc,$@) \
|
||||
$(objtree)/rust/helpers/helpers$(if $(part-of-module),_module).bc -o $(patsubst %.o,%.m.bc,$@); \
|
||||
$(CC) $(CLANG_FLAGS) $(KBUILD_CFLAGS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \
|
||||
$(CC) $(CLANG_FLAGS) $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS)) \
|
||||
$(CC_FLAGS_RUST_INLINE_HELPERS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \
|
||||
$(cmd_ld_single)) \
|
||||
$(cmd_objtool)
|
||||
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ static bool is_rust_noreturn(const struct symbol *func)
|
|||
return str_ends_with(func->name, "_4core3num20from_str_radix_panic") ||
|
||||
str_ends_with(func->name, "_4core3num22from_ascii_radix_panic") ||
|
||||
str_ends_with(func->name, "_4core3num28from_ascii_bytes_radix_panic") ||
|
||||
str_ends_with(func->name, "_4core3str16slice_error_fail") ||
|
||||
str_ends_with(func->name, "_4core5sliceSp15copy_from_slice17len_mismatch_fail") ||
|
||||
str_ends_with(func->name, "_4core6option13expect_failed") ||
|
||||
str_ends_with(func->name, "_4core6option13unwrap_failed") ||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user