[PATCH v3 00/12] kasan: unify kasan_arch_is_ready() and remove arch-specific implementations
Sabyrzhan Tasbolatov
snovitoll at gmail.com
Thu Jul 17 07:27:20 PDT 2025
This patch series addresses the fragmentation in KASAN initialization
across architectures by introducing a unified approach that eliminates
duplicate static keys and arch-specific kasan_arch_is_ready()
implementations.
The core issue is that different architectures have inconsistent approaches
to KASAN readiness tracking:
- PowerPC, LoongArch, and um arch, each implement own kasan_arch_is_ready()
- Only HW_TAGS mode had a unified static key (kasan_flag_enabled)
- Generic and SW_TAGS modes relied on arch-specific solutions
or always-on behavior
This series implements two-level approach:
1. kasan_enabled() - compile-time check for KASAN configuration
2. kasan_shadow_initialized() - runtime check for shadow memory readiness
Key improvements:
- Unified static key infrastructure across all KASAN modes
- Runtime overhead only for architectures that actually need it
- Compile-time optimization for arch. with early KASAN initialization
- Complete elimination of arch-specific kasan_arch_is_ready()
- Consistent interface and reduced code duplication
Previous v2 thread: https://lore.kernel.org/all/20250626153147.145312-1-snovitoll@gmail.com/
Changes in v3 (sorry for the 3-week gap):
0. Included in TO, CC only KASAN devs and people who commented in v2.
1. Addressed Andrey Konovalov's feedback:
- Kept separate kasan_enabled() and kasan_shadow_initialized() functions
- Added proper __wrapper functions with clean separation
2. Addressed Christophe Leroy's performance comments:
- CONFIG_ARCH_DEFER_KASAN is only selected by architectures that need it
- No static key overhead for architectures that can enable KASAN early
- PowerPC 32-bit and book3e get compile-time optimization
3. Addressed Heiko Carstens and Alexander Gordeev s390 comments:
- s390 doesn't select ARCH_DEFER_KASAN (no unnecessary static key overhead)
- kasan_enable() is a no-op for architectures with early KASAN setup
4. Improved wrapper architecture:
- All existing wrapper functions in include/linux/kasan.h now check both
kasan_enabled() && kasan_shadow_initialized()
- Internal implementation functions focus purely on core functionality
- Shadow readiness logic is centralized in headers per Andrey's guidance
Architecture-specific changes:
- PowerPC radix MMU: selects ARCH_DEFER_KASAN for runtime control
- LoongArch: selects ARCH_DEFER_KASAN, removes custom kasan_early_stage
- um: selects ARCH_DEFER_KASAN, removes kasan_um_is_ready
- Other architectures: get compile-time optimization, no runtime overhead
The series maintains full backward compatibility while providing optimal
performance for each architecture's needs.
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217049
=== Current mainline KUnit status
To see if there is any regression, I've tested via compiling a kernel
with CONFIG_KASAN_KUNIT_TEST and running QEMU VM. There are failing tests
in SW_TAGS and GENERIC modes in arm64:
arm64 CONFIG_KASAN_HW_TAGS:
# kasan: pass:62 fail:0 skip:13 total:75
# Totals: pass:62 fail:0 skip:13 total:75
ok 1 kasan
arm64 CONFIG_KASAN_SW_TAGS=y:
# kasan: pass:65 fail:1 skip:9 total:75
# Totals: pass:65 fail:1 skip:9 total:75
not ok 1 kasan
# kasan_strings: EXPECTATION FAILED at mm/kasan/kasan_test_c.c:1598
KASAN failure expected in "strscpy(ptr, src + KASAN_GRANULE_SIZE, KASAN_GRANULE_SIZE)", but none occurred
arm64 CONFIG_KASAN_GENERIC=y, CONFIG_KASAN_OUTLINE=y:
# kasan: pass:61 fail:1 skip:13 total:75
# Totals: pass:61 fail:1 skip:13 total:75
not ok 1 kasan
# same failure as above
x86_64 CONFIG_KASAN_GENERIC=y:
# kasan: pass:58 fail:0 skip:17 total:75
# Totals: pass:58 fail:0 skip:17 total:75
ok 1 kasan
=== Testing with patches
Testing in v3:
- Compiled every affected arch with no errors:
$ make CC=clang LD=ld.lld AR=llvm-ar NM=llvm-nm STRIP=llvm-strip \
OBJCOPY=llvm-objcopy OBJDUMP=llvm-objdump READELF=llvm-readelf \
HOSTCC=clang HOSTCXX=clang++ HOSTAR=llvm-ar HOSTLD=ld.lld \
ARCH=$ARCH
$ clang --version
ClangBuiltLinux clang version 19.1.4
Target: x86_64-unknown-linux-gnu
Thread model: posix
- make ARCH=um produces the warning during compiling:
MODPOST Module.symvers
WARNING: modpost: vmlinux: section mismatch in reference: \
kasan_init+0x43 (section: .ltext) -> \
kasan_init_generic (section: .init.text)
AFAIU, it's due to the code in arch/um/kernel/mem.c, where kasan_init()
is placed in own section ".kasan_init", which calls kasan_init_generic()
which is marked with "__init".
- Booting via qemu-system- and running KUnit tests:
* arm64 (GENERIC, HW_TAGS, SW_TAGS): no regression, same above results.
* x86_64 (GENERIC): no regression, no errors
Sabyrzhan Tasbolatov (12):
lib/kasan: introduce CONFIG_ARCH_DEFER_KASAN option
kasan: unify static kasan_flag_enabled across modes
kasan/powerpc: select ARCH_DEFER_KASAN and call kasan_init_generic
kasan/arm64: call kasan_init_generic in kasan_init
kasan/arm: call kasan_init_generic in kasan_init
kasan/xtensa: call kasan_init_generic in kasan_init
kasan/loongarch: select ARCH_DEFER_KASAN and call kasan_init_generic
kasan/um: select ARCH_DEFER_KASAN and call kasan_init_generic
kasan/x86: call kasan_init_generic in kasan_init
kasan/s390: call kasan_init_generic in kasan_init
kasan/riscv: call kasan_init_generic in kasan_init
kasan: add shadow checks to wrappers and rename kasan_arch_is_ready
arch/arm/mm/kasan_init.c | 2 +-
arch/arm64/mm/kasan_init.c | 4 +--
arch/loongarch/Kconfig | 1 +
arch/loongarch/include/asm/kasan.h | 7 -----
arch/loongarch/mm/kasan_init.c | 7 ++---
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/kasan.h | 12 --------
arch/powerpc/mm/kasan/init_32.c | 2 +-
arch/powerpc/mm/kasan/init_book3e_64.c | 2 +-
arch/powerpc/mm/kasan/init_book3s_64.c | 6 +---
arch/riscv/mm/kasan_init.c | 1 +
arch/s390/kernel/early.c | 3 +-
arch/um/Kconfig | 1 +
arch/um/include/asm/kasan.h | 5 ---
arch/um/kernel/mem.c | 4 +--
arch/x86/mm/kasan_init_64.c | 2 +-
arch/xtensa/mm/kasan_init.c | 2 +-
include/linux/kasan-enabled.h | 34 ++++++++++++++++-----
include/linux/kasan.h | 42 ++++++++++++++++++++------
lib/Kconfig.kasan | 8 +++++
mm/kasan/common.c | 18 +++++++----
mm/kasan/generic.c | 23 ++++++++------
mm/kasan/hw_tags.c | 9 +-----
mm/kasan/kasan.h | 36 ++++++++++++++++------
mm/kasan/shadow.c | 32 +++++---------------
mm/kasan/sw_tags.c | 2 ++
26 files changed, 146 insertions(+), 120 deletions(-)
--
2.34.1
More information about the linux-riscv
mailing list