Skip to content

Commit

Permalink
Merge tag 'clang-lto-v5.12-rc1-part2' of git://git.kernel.org/pub/scm…
Browse files Browse the repository at this point in the history
…/linux/kernel/git/kees/linux

Pull more clang LTO updates from Kees Cook:
 "Clang LTO x86 enablement.

  Full disclosure: while this has _not_ been in linux-next (since it
  initially looked like the objtool dependencies weren't going to make
  v5.12), it has been under daily build and runtime testing by Sami for
  quite some time. These x86 portions have been discussed on lkml, with
  Peter, Josh, and others helping nail things down.

  The bulk of the changes are to get objtool working happily. The rest
  of the x86 enablement is very small.

  Summary:

   - Generate __mcount_loc in objtool (Peter Zijlstra)

   - Support running objtool against vmlinux.o (Sami Tolvanen)

   - Clang LTO enablement for x86 (Sami Tolvanen)"

Link: https://lore.kernel.org/lkml/[email protected]/
Link: https://lore.kernel.org/lkml/[email protected]/

* tag 'clang-lto-v5.12-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  kbuild: lto: force rebuilds when switching CONFIG_LTO
  x86, build: allow LTO to be selected
  x86, cpu: disable LTO for cpu.c
  x86, vdso: disable LTO only for vDSO
  kbuild: lto: postpone objtool
  objtool: Split noinstr validation from --vmlinux
  x86, build: use objtool mcount
  tracing: add support for objtool mcount
  objtool: Don't autodetect vmlinux.o
  objtool: Fix __mcount_loc generation with Clang's assembler
  objtool: Add a pass for generating __mcount_loc
  • Loading branch information
torvalds committed Feb 23, 2021
2 parents 6dd580b + 5e95325 commit 414eece
Show file tree
Hide file tree
Showing 16 changed files with 195 additions and 33 deletions.
10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,9 @@ ifdef CONFIG_FTRACE_MCOUNT_USE_CC
endif
endif
endif
ifdef CONFIG_FTRACE_MCOUNT_USE_OBJTOOL
CC_FLAGS_USING += -DCC_USING_NOP_MCOUNT
endif
ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
ifdef CONFIG_HAVE_C_RECORDMCOUNT
BUILD_C_RECORDMCOUNT := y
Expand Down Expand Up @@ -909,7 +912,8 @@ KBUILD_LDFLAGS += -mllvm -import-instr-limit=5
endif

ifdef CONFIG_LTO
KBUILD_CFLAGS += $(CC_FLAGS_LTO)
KBUILD_CFLAGS += -fno-lto $(CC_FLAGS_LTO)
KBUILD_AFLAGS += -fno-lto
export CC_FLAGS_LTO
endif

Expand Down Expand Up @@ -1243,6 +1247,10 @@ uapi-asm-generic:
PHONY += prepare-objtool prepare-resolve_btfids
prepare-objtool: $(objtool_target)
ifeq ($(SKIP_STACK_VALIDATION),1)
ifdef CONFIG_FTRACE_MCOUNT_USE_OBJTOOL
@echo "error: Cannot generate __mcount_loc for CONFIG_DYNAMIC_FTRACE=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
@false
endif
ifdef CONFIG_UNWINDER_ORC
@echo "error: Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
@false
Expand Down
3 changes: 3 additions & 0 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ config X86
select ARCH_SUPPORTS_DEBUG_PAGEALLOC
select ARCH_SUPPORTS_NUMA_BALANCING if X86_64
select ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP if NR_CPUS <= 4096
select ARCH_SUPPORTS_LTO_CLANG if X86_64
select ARCH_SUPPORTS_LTO_CLANG_THIN if X86_64
select ARCH_USE_BUILTIN_BSWAP
select ARCH_USE_QUEUED_RWLOCKS
select ARCH_USE_QUEUED_SPINLOCKS
Expand Down Expand Up @@ -169,6 +171,7 @@ config X86
select HAVE_CONTEXT_TRACKING if X86_64
select HAVE_CONTEXT_TRACKING_OFFSTACK if HAVE_CONTEXT_TRACKING
select HAVE_C_RECORDMCOUNT
select HAVE_OBJTOOL_MCOUNT if STACK_VALIDATION
select HAVE_DEBUG_KMEMLEAK
select HAVE_DMA_CONTIGUOUS
select HAVE_DYNAMIC_FTRACE
Expand Down
5 changes: 5 additions & 0 deletions arch/x86/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,11 @@ ifeq ($(ACCUMULATE_OUTGOING_ARGS), 1)
KBUILD_CFLAGS += $(call cc-option,-maccumulate-outgoing-args,)
endif

ifdef CONFIG_LTO_CLANG
KBUILD_LDFLAGS += -plugin-opt=-code-model=kernel \
-plugin-opt=-stack-alignment=$(if $(CONFIG_X86_32),4,8)
endif

# Workaround for a gcc prelease that unfortunately was shipped in a suse release
KBUILD_CFLAGS += -Wno-sign-compare
#
Expand Down
3 changes: 2 additions & 1 deletion arch/x86/entry/vdso/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ ifneq ($(RETPOLINE_VDSO_CFLAGS),)
endif
endif

$(vobjs): KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL)
$(vobjs): KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO) $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL)

#
# vDSO code runs in userspace and -pg doesn't help with profiling anyway.
Expand Down Expand Up @@ -150,6 +150,7 @@ KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic
KBUILD_CFLAGS_32 += -fno-stack-protector
KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)
Expand Down
4 changes: 4 additions & 0 deletions arch/x86/power/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
# itself be stack-protected
CFLAGS_cpu.o := -fno-stack-protector

# Clang may incorrectly inline functions with stack protector enabled into
# __restore_processor_state(): https://bugs.llvm.org/show_bug.cgi?id=47479
CFLAGS_REMOVE_cpu.o := $(CC_FLAGS_LTO)

obj-$(CONFIG_PM_SLEEP) += cpu.o
obj-$(CONFIG_HIBERNATION) += hibernate_$(BITS).o hibernate_asm_$(BITS).o hibernate.o
13 changes: 13 additions & 0 deletions kernel/trace/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ config HAVE_NOP_MCOUNT
help
Arch supports the gcc options -pg with -mrecord-mcount and -nop-mcount

config HAVE_OBJTOOL_MCOUNT
bool
help
Arch supports objtool --mcount

config HAVE_C_RECORDMCOUNT
bool
help
Expand Down Expand Up @@ -612,10 +617,18 @@ config FTRACE_MCOUNT_USE_CC
depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY
depends on FTRACE_MCOUNT_RECORD

config FTRACE_MCOUNT_USE_OBJTOOL
def_bool y
depends on HAVE_OBJTOOL_MCOUNT
depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY
depends on !FTRACE_MCOUNT_USE_CC
depends on FTRACE_MCOUNT_RECORD

config FTRACE_MCOUNT_USE_RECORDMCOUNT
def_bool y
depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY
depends on !FTRACE_MCOUNT_USE_CC
depends on !FTRACE_MCOUNT_USE_OBJTOOL
depends on FTRACE_MCOUNT_RECORD

config TRACING_MAP
Expand Down
19 changes: 2 additions & 17 deletions scripts/Makefile.build
Original file line number Diff line number Diff line change
Expand Up @@ -218,27 +218,11 @@ cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)),
endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT

ifdef CONFIG_STACK_VALIDATION
ifndef CONFIG_LTO_CLANG
ifneq ($(SKIP_STACK_VALIDATION),1)

__objtool_obj := $(objtree)/tools/objtool/objtool

objtool_args = $(if $(CONFIG_UNWINDER_ORC),orc generate,check)

objtool_args += $(if $(part-of-module), --module,)

ifndef CONFIG_FRAME_POINTER
objtool_args += --no-fp
endif
ifdef CONFIG_GCOV_KERNEL
objtool_args += --no-unreachable
endif
ifdef CONFIG_RETPOLINE
objtool_args += --retpoline
endif
ifdef CONFIG_X86_SMAP
objtool_args += --uaccess
endif

# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file
Expand All @@ -250,6 +234,7 @@ objtool_obj = $(if $(patsubst y%,, \
$(__objtool_obj))

endif # SKIP_STACK_VALIDATION
endif # CONFIG_LTO_CLANG
endif # CONFIG_STACK_VALIDATION

# Rebuild all objects when objtool changes, or is enabled/disabled.
Expand Down
12 changes: 12 additions & 0 deletions scripts/Makefile.lib
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,18 @@ dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \
$(addprefix -I,$(DTC_INCLUDE)) \
-undef -D__DTS__

# Objtool arguments are also needed for modfinal with LTO, so we define
# then here to avoid duplication.
objtool_args = \
$(if $(CONFIG_UNWINDER_ORC),orc generate,check) \
$(if $(part-of-module), --module,) \
$(if $(CONFIG_FRAME_POINTER),, --no-fp) \
$(if $(or $(CONFIG_GCOV_KERNEL),$(CONFIG_LTO_CLANG)), \
--no-unreachable,) \
$(if $(CONFIG_RETPOLINE), --retpoline,) \
$(if $(CONFIG_X86_SMAP), --uaccess,) \
$(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount,)

# Useful for describing the dependency of composite objects
# Usage:
# $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add)
Expand Down
19 changes: 16 additions & 3 deletions scripts/Makefile.modfinal
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ __modfinal:
include include/config/auto.conf
include $(srctree)/scripts/Kbuild.include

# for c_flags
# for c_flags and objtool_args
include $(srctree)/scripts/Makefile.lib

# find all modules listed in modules.order
Expand All @@ -34,10 +34,23 @@ ifdef CONFIG_LTO_CLANG
# With CONFIG_LTO_CLANG, reuse the object file we compiled for modpost to
# avoid a second slow LTO link
prelink-ext := .lto
endif

# ELF processing was skipped earlier because we didn't have native code,
# so let's now process the prelinked binary before we link the module.

ifdef CONFIG_STACK_VALIDATION
ifneq ($(SKIP_STACK_VALIDATION),1)
cmd_ld_ko_o += \
$(objtree)/tools/objtool/objtool $(objtool_args) \
$(@:.ko=$(prelink-ext).o);

endif # SKIP_STACK_VALIDATION
endif # CONFIG_STACK_VALIDATION

endif # CONFIG_LTO_CLANG

quiet_cmd_ld_ko_o = LD [M] $@
cmd_ld_ko_o = \
cmd_ld_ko_o += \
$(LD) -r $(KBUILD_LDFLAGS) \
$(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
-T scripts/module.lds -o $@ $(filter %.o, $^); \
Expand Down
28 changes: 25 additions & 3 deletions scripts/link-vmlinux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,36 @@ modpost_link()

objtool_link()
{
local objtoolcmd;
local objtoolopt;

if [ "${CONFIG_LTO_CLANG} ${CONFIG_STACK_VALIDATION}" = "y y" ]; then
# Don't perform vmlinux validation unless explicitly requested,
# but run objtool on vmlinux.o now that we have an object file.
if [ -n "${CONFIG_UNWINDER_ORC}" ]; then
objtoolcmd="orc generate"
fi

objtoolopt="${objtoolopt} --duplicate"

if [ -n "${CONFIG_FTRACE_MCOUNT_USE_OBJTOOL}" ]; then
objtoolopt="${objtoolopt} --mcount"
fi
fi

if [ -n "${CONFIG_VMLINUX_VALIDATION}" ]; then
objtoolopt="check"
objtoolopt="${objtoolopt} --noinstr"
fi

if [ -n "${objtoolopt}" ]; then
if [ -z "${objtoolcmd}" ]; then
objtoolcmd="check"
fi
objtoolopt="${objtoolopt} --vmlinux"
if [ -z "${CONFIG_FRAME_POINTER}" ]; then
objtoolopt="${objtoolopt} --no-fp"
fi
if [ -n "${CONFIG_GCOV_KERNEL}" ]; then
if [ -n "${CONFIG_GCOV_KERNEL}" ] || [ -n "${CONFIG_LTO_CLANG}" ]; then
objtoolopt="${objtoolopt} --no-unreachable"
fi
if [ -n "${CONFIG_RETPOLINE}" ]; then
Expand All @@ -120,7 +142,7 @@ objtool_link()
objtoolopt="${objtoolopt} --uaccess"
fi
info OBJTOOL ${1}
tools/objtool/objtool ${objtoolopt} ${1}
tools/objtool/objtool ${objtoolcmd} ${objtoolopt} ${1}
fi
}

Expand Down
10 changes: 4 additions & 6 deletions tools/objtool/builtin-check.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <objtool/builtin.h>
#include <objtool/objtool.h>

bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux;
bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux, mcount, noinstr;

static const char * const check_usage[] = {
"objtool check [<options>] file.o",
Expand All @@ -34,13 +34,15 @@ const struct option check_options[] = {
OPT_BOOLEAN('a', "uaccess", &uaccess, "enable uaccess checking"),
OPT_BOOLEAN('s', "stats", &stats, "print statistics"),
OPT_BOOLEAN('d', "duplicate", &validate_dup, "duplicate validation for vmlinux.o"),
OPT_BOOLEAN('n', "noinstr", &noinstr, "noinstr validation for vmlinux.o"),
OPT_BOOLEAN('l', "vmlinux", &vmlinux, "vmlinux.o validation"),
OPT_BOOLEAN('M', "mcount", &mcount, "generate __mcount_loc"),
OPT_END(),
};

int cmd_check(int argc, const char **argv)
{
const char *objname, *s;
const char *objname;
struct objtool_file *file;
int ret;

Expand All @@ -51,10 +53,6 @@ int cmd_check(int argc, const char **argv)

objname = argv[0];

s = strstr(objname, "vmlinux.o");
if (s && !s[9])
vmlinux = true;

file = objtool_open_read(objname);
if (!file)
return 1;
Expand Down
Loading

0 comments on commit 414eece

Please sign in to comment.