11 Jul, 2021

1 commit

  • Pull Kbuild updates from Masahiro Yamada:

    - Increase the -falign-functions alignment for the debug option.

    - Remove ugly libelf checks from the top Makefile.

    - Make the silent build (-s) more silent.

    - Re-compile the kernel if KBUILD_BUILD_TIMESTAMP is specified.

    - Various script cleanups

    * tag 'kbuild-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild: (27 commits)
    scripts: add generic syscallnr.sh
    scripts: check duplicated syscall number in syscall table
    sparc: syscalls: use pattern rules to generate syscall headers
    parisc: syscalls: use pattern rules to generate syscall headers
    nds32: add arch/nds32/boot/.gitignore
    kbuild: mkcompile_h: consider timestamp if KBUILD_BUILD_TIMESTAMP is set
    kbuild: modpost: Explicitly warn about unprototyped symbols
    kbuild: remove trailing slashes from $(KBUILD_EXTMOD)
    kconfig.h: explain IS_MODULE(), IS_ENABLED()
    kconfig: constify long_opts
    scripts/setlocalversion: simplify the short version part
    scripts/setlocalversion: factor out 12-chars hash construction
    scripts/setlocalversion: add more comments to -dirty flag detection
    scripts/setlocalversion: remove workaround for old make-kpkg
    scripts/setlocalversion: remove mercurial, svn and git-svn supports
    kbuild: clean up ${quiet} checks in shell scripts
    kbuild: sink stdout from cmd for silent build
    init: use $(call cmd,) for generating include/generated/compile.h
    kbuild: merge scripts/mkmakefile to top Makefile
    sh: move core-y in arch/sh/Makefile to arch/sh/Kbuild
    ...

    Linus Torvalds
     

28 May, 2021

1 commit

  • The ccache tool can be used to speed up cross-compilation, by calling the
    compiler and binutils through ccache. For example, following should work:

    $ export ARCH=arm64 CROSS_COMPILE="ccache aarch64-linux-gnu-"

    $ make M=drivers/gpu/drm/rockchip/

    but pahole fails to extract the BTF info from DWARF, breaking the build:

    CC [M] drivers/gpu/drm/rockchip//rockchipdrm.mod.o
    LD [M] drivers/gpu/drm/rockchip//rockchipdrm.ko
    BTF [M] drivers/gpu/drm/rockchip//rockchipdrm.ko
    aarch64-linux-gnu-objcopy: invalid option -- 'J'
    Usage: aarch64-linux-gnu-objcopy [option(s)] in-file [out-file]
    Copies a binary file, possibly transforming it in the process
    ...
    make[1]: *** [scripts/Makefile.modpost:156: __modpost] Error 2
    make: *** [Makefile:1866: modules] Error 2

    this fails because OBJCOPY is set to "ccache aarch64-linux-gnu-copy" and
    later pahole is executed with the following command line:

    LLVM_OBJCOPY=$(OBJCOPY) $(PAHOLE) -J --btf_base vmlinux $@

    which gets expanded to:

    LLVM_OBJCOPY=ccache aarch64-linux-gnu-objcopy pahole -J ...

    instead of:

    LLVM_OBJCOPY="ccache aarch64-linux-gnu-objcopy" pahole -J ...

    Fixes: 5f9ae91f7c0d ("kbuild: Build kernel module BTFs if BTF is enabled and pahole supports it")
    Signed-off-by: Javier Martinez Canillas
    Signed-off-by: Andrii Nakryiko
    Acked-by: Andrii Nakryiko
    Acked-by: Arnaldo Carvalho de Melo
    Link: https://lore.kernel.org/bpf/20210526215228.3729875-1-javierm@redhat.com

    Javier Martinez Canillas
     

24 May, 2021

1 commit

  • I do not see a good reason why only the libelf development package must
    be so carefully checked.

    Kbuild generally does not check host tools or libraries.

    For example, x86_64 defconfig fails to build with no libssl development
    package installed.

    scripts/extract-cert.c:21:10: fatal error: openssl/bio.h: No such file or directory
    21 | #include
    | ^~~~~~~~~~~~~~~

    To solve the build error, you need to install libssl-dev or openssl-devel
    package, depending on your distribution.

    'apt-file search', 'dnf provides', etc. is your frined to find a proper
    package to install.

    This commit removes all the libelf checks from the top Makefile.

    If libelf is missing, objtool will fail to build in a similar pattern:

    .../linux/tools/objtool/include/objtool/elf.h:10:10: fatal error: gelf.h: No such file or directory
    10 | #include

    You need to install libelf-dev, libelf-devel, or elfutils-libelf-devel
    to proceed.

    Another remarkable change is, CONFIG_STACK_VALIDATION (without
    CONFIG_UNWINDER_ORC) previously continued to build with a warning,
    but now it will treat missing libelf as an error.

    This is just a one-time installation, so it should not hurt to break
    a build and make a user install the package.

    BTW, the traditional way to handle such checks is autotool, but according
    to [1], I do not expect the kernel build would have similar scripting
    like './configure' does.

    [1]: https://lore.kernel.org/lkml/CA+55aFzr2HTZVOuzpHYDwmtRJLsVzE-yqg2DHpHi_9ePsYp5ug@mail.gmail.com/

    Signed-off-by: Masahiro Yamada
    Acked-by: Andrii Nakryiko

    Masahiro Yamada
     

09 Apr, 2021

1 commit

  • This change adds support for Clang’s forward-edge Control Flow
    Integrity (CFI) checking. With CONFIG_CFI_CLANG, the compiler
    injects a runtime check before each indirect function call to ensure
    the target is a valid function with the correct static type. This
    restricts possible call targets and makes it more difficult for
    an attacker to exploit bugs that allow the modification of stored
    function pointers. For more details, see:

    https://clang.llvm.org/docs/ControlFlowIntegrity.html

    Clang requires CONFIG_LTO_CLANG to be enabled with CFI to gain
    visibility to possible call targets. Kernel modules are supported
    with Clang’s cross-DSO CFI mode, which allows checking between
    independently compiled components.

    With CFI enabled, the compiler injects a __cfi_check() function into
    the kernel and each module for validating local call targets. For
    cross-module calls that cannot be validated locally, the compiler
    calls the global __cfi_slowpath_diag() function, which determines
    the target module and calls the correct __cfi_check() function. This
    patch includes a slowpath implementation that uses __module_address()
    to resolve call targets, and with CONFIG_CFI_CLANG_SHADOW enabled, a
    shadow map that speeds up module look-ups by ~3x.

    Clang implements indirect call checking using jump tables and
    offers two methods of generating them. With canonical jump tables,
    the compiler renames each address-taken function to .cfi
    and points the original symbol to a jump table entry, which passes
    __cfi_check() validation. This isn’t compatible with stand-alone
    assembly code, which the compiler doesn’t instrument, and would
    result in indirect calls to assembly code to fail. Therefore, we
    default to using non-canonical jump tables instead, where the compiler
    generates a local jump table entry .cfi_jt for each
    address-taken function, and replaces all references to the function
    with the address of the jump table entry.

    Note that because non-canonical jump table addresses are local
    to each component, they break cross-module function address
    equality. Specifically, the address of a global function will be
    different in each module, as it's replaced with the address of a local
    jump table entry. If this address is passed to a different module,
    it won’t match the address of the same function taken there. This
    may break code that relies on comparing addresses passed from other
    components.

    CFI checking can be disabled in a function with the __nocfi attribute.
    Additionally, CFI can be disabled for an entire compilation unit by
    filtering out CC_FLAGS_CFI.

    By default, CFI failures result in a kernel panic to stop a potential
    exploit. CONFIG_CFI_PERMISSIVE enables a permissive mode, where the
    kernel prints out a rate-limited warning instead, and allows execution
    to continue. This option is helpful for locating type mismatches, but
    should only be enabled during development.

    Signed-off-by: Sami Tolvanen
    Reviewed-by: Kees Cook
    Tested-by: Nathan Chancellor
    Signed-off-by: Kees Cook
    Link: https://lore.kernel.org/r/20210408182843.1754385-2-samitolvanen@google.com

    Sami Tolvanen
     

24 Feb, 2021

1 commit

  • With LTO, LLVM bitcode won't be compiled into native code until
    modpost_link, or modfinal for modules. This change postpones calls
    to objtool until after these steps, and moves objtool_args to
    Makefile.lib, so the arguments can be reused in Makefile.modfinal.

    As we didn't have objects to process earlier, we use --duplicate
    when processing vmlinux.o. This change also disables unreachable
    instruction warnings with LTO to avoid warnings about the int3
    padding between functions.

    Signed-off-by: Sami Tolvanen
    Reviewed-by: Kees Cook

    Sami Tolvanen
     

15 Jan, 2021

1 commit

  • This change adds build system support for Clang's Link Time
    Optimization (LTO). With -flto, instead of ELF object files, Clang
    produces LLVM bitcode, which is compiled into native code at link
    time, allowing the final binary to be optimized globally. For more
    details, see:

    https://llvm.org/docs/LinkTimeOptimization.html

    The Kconfig option CONFIG_LTO_CLANG is implemented as a choice,
    which defaults to LTO being disabled. To use LTO, the architecture
    must select ARCH_SUPPORTS_LTO_CLANG and support:

    - compiling with Clang,
    - compiling all assembly code with Clang's integrated assembler,
    - and linking with LLD.

    While using CONFIG_LTO_CLANG_FULL results in the best runtime
    performance, the compilation is not scalable in time or
    memory. CONFIG_LTO_CLANG_THIN enables ThinLTO, which allows
    parallel optimization and faster incremental builds. ThinLTO is
    used by default if the architecture also selects
    ARCH_SUPPORTS_LTO_CLANG_THIN:

    https://clang.llvm.org/docs/ThinLTO.html

    To enable LTO, LLVM tools must be used to handle bitcode files, by
    passing LLVM=1 and LLVM_IAS=1 options to make:

    $ make LLVM=1 LLVM_IAS=1 defconfig
    $ scripts/config -e LTO_CLANG_THIN
    $ make LLVM=1 LLVM_IAS=1

    To prepare for LTO support with other compilers, common parts are
    gated behind the CONFIG_LTO option, and LTO can be disabled for
    specific files by filtering out CC_FLAGS_LTO.

    Signed-off-by: Sami Tolvanen
    Reviewed-by: Kees Cook
    Signed-off-by: Kees Cook
    Link: https://lore.kernel.org/r/20201211184633.3213045-3-samitolvanen@google.com

    Sami Tolvanen
     

25 Nov, 2020

1 commit

  • In some modes of operation, Kbuild allows to build modules without having
    vmlinux image around. In such case, generation of module BTF is impossible.
    This patch changes the behavior to emit a warning about impossibility of
    generating kernel module BTF, instead of breaking the build. This is especially
    important for out-of-tree external module builds.

    In vmlinux-less mode:

    $ make clean
    $ make modules_prepare
    $ touch drivers/acpi/button.c
    $ make M=drivers/acpi
    ...
    CC [M] drivers/acpi/button.o
    MODPOST drivers/acpi/Module.symvers
    LD [M] drivers/acpi/button.ko
    BTF [M] drivers/acpi/button.ko
    Skipping BTF generation for drivers/acpi/button.ko due to unavailability of vmlinux
    ...
    $ readelf -S ~/linux-build/default/drivers/acpi/button.ko | grep BTF -A1
    ... empty ...

    Now with normal build:

    $ make all
    ...
    LD [M] drivers/acpi/button.ko
    BTF [M] drivers/acpi/button.ko
    ...
    $ readelf -S ~/linux-build/default/drivers/acpi/button.ko | grep BTF -A1
    [60] .BTF PROGBITS 0000000000000000 00029310
    000000000000ab3f 0000000000000000 0 0 1

    Fixes: 5f9ae91f7c0d ("kbuild: Build kernel module BTFs if BTF is enabled and pahole supports it")
    Reported-by: Bruce Allan
    Signed-off-by: Andrii Nakryiko
    Signed-off-by: Daniel Borkmann
    Cc: Jessica Yu
    Cc: Greg Kroah-Hartman
    Cc: Masahiro Yamada
    Link: https://lore.kernel.org/bpf/20201121070829.2612884-1-andrii@kernel.org

    Andrii Nakryiko
     

11 Nov, 2020

1 commit

  • Detect if pahole supports split BTF generation, and generate BTF for each
    selected kernel module, if it does. This is exposed to Makefiles and C code as
    CONFIG_DEBUG_INFO_BTF_MODULES flag.

    Kernel module BTF has to be re-generated if either vmlinux's BTF changes or
    module's .ko changes. To achieve that, I needed a helper similar to
    if_changed, but that would allow to filter out vmlinux from the list of
    updated dependencies for .ko building. I've put it next to the only place that
    uses and needs it, but it might be a better idea to just add it along the
    other if_changed variants into scripts/Kbuild.include.

    Each kernel module's BTF deduplication is pretty fast, as it does only
    incremental BTF deduplication on top of already deduplicated vmlinux BTF. To
    show the added build time, I've first ran make only just built kernel (to
    establish the baseline) and then forced only BTF re-generation, without
    regenerating .ko files. The build was performed with -j60 parallelization on
    56-core machine. The final time also includes bzImage building, so it's not
    a pure BTF overhead.

    $ time make -j60
    ...
    make -j60 27.65s user 10.96s system 782% cpu 4.933 total
    $ touch ~/linux-build/default/vmlinux && time make -j60
    ...
    make -j60 123.69s user 27.85s system 1566% cpu 9.675 total

    So 4.6 seconds real time, with noticeable part spent in compressed vmlinux and
    bzImage building.

    To show size savings, I've built my kernel configuration with about 700 kernel
    modules with full BTF per each kernel module (without deduplicating against
    vmlinux) and with split BTF against deduplicated vmlinux (approach in this
    patch). Below are top 10 modules with biggest BTF sizes. And total size of BTF
    data across all kernel modules.

    It shows that split BTF "compresses" 115MB down to 5MB total. And the biggest
    kernel modules get a downsize from 500-570KB down to 200-300KB.

    FULL BTF
    ========

    $ for f in $(find . -name '*.ko'); do size -A -d $f | grep BTF | awk '{print $2}'; done | awk '{ s += $1 } END { print s }'
    115710691

    $ for f in $(find . -name '*.ko'); do printf "%s %d\n" $f $(size -A -d $f | grep BTF | awk '{print $2}'); done | sort -nr -k2 | head -n10
    ./drivers/gpu/drm/i915/i915.ko 570570
    ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko 520240
    ./drivers/gpu/drm/radeon/radeon.ko 503849
    ./drivers/infiniband/hw/mlx5/mlx5_ib.ko 491777
    ./fs/xfs/xfs.ko 411544
    ./drivers/net/ethernet/intel/i40e/i40e.ko 403904
    ./drivers/net/ethernet/broadcom/bnx2x/bnx2x.ko 398754
    ./drivers/infiniband/core/ib_core.ko 397224
    ./fs/cifs/cifs.ko 386249
    ./fs/nfsd/nfsd.ko 379738

    SPLIT BTF
    =========

    $ for f in $(find . -name '*.ko'); do size -A -d $f | grep BTF | awk '{print $2}'; done | awk '{ s += $1 } END { print s }'
    5194047

    $ for f in $(find . -name '*.ko'); do printf "%s %d\n" $f $(size -A -d $f | grep BTF | awk '{print $2}'); done | sort -nr -k2 | head -n10
    ./drivers/gpu/drm/i915/i915.ko 293206
    ./drivers/gpu/drm/radeon/radeon.ko 282103
    ./fs/xfs/xfs.ko 222150
    ./drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko 198503
    ./drivers/infiniband/hw/mlx5/mlx5_ib.ko 198356
    ./drivers/net/ethernet/broadcom/bnx2x/bnx2x.ko 113444
    ./fs/cifs/cifs.ko 109379
    ./arch/x86/kvm/kvm.ko 100225
    ./drivers/gpu/drm/drm.ko 94827
    ./drivers/infiniband/core/ib_core.ko 91188

    Signed-off-by: Andrii Nakryiko
    Signed-off-by: Alexei Starovoitov
    Link: https://lore.kernel.org/bpf/20201110011932.3201430-4-andrii@kernel.org

    Andrii Nakryiko
     

24 Sep, 2020

1 commit

  • There was a request to preprocess the module linker script like we
    do for the vmlinux one. (https://lkml.org/lkml/2020/8/21/512)

    The difference between vmlinux.lds and module.lds is that the latter
    is needed for external module builds, thus must be cleaned up by
    'make mrproper' instead of 'make clean'. Also, it must be created
    by 'make modules_prepare'.

    You cannot put it in arch/$(SRCARCH)/kernel/, which is cleaned up by
    'make clean'. I moved arch/$(SRCARCH)/kernel/module.lds to
    arch/$(SRCARCH)/include/asm/module.lds.h, which is included from
    scripts/module.lds.S.

    scripts/module.lds is fine because 'make clean' keeps all the
    build artifacts under scripts/.

    You can add arch-specific sections in .

    Signed-off-by: Masahiro Yamada
    Tested-by: Jessica Yu
    Acked-by: Will Deacon
    Acked-by: Geert Uytterhoeven
    Acked-by: Palmer Dabbelt
    Reviewed-by: Kees Cook
    Acked-by: Jessica Yu

    Masahiro Yamada
     

22 Aug, 2019

2 commits