All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nathan Chancellor <nathan@kernel.org>
To: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
	 dave.hansen@linux.intel.com
Cc: x86@kernel.org, hpa@zytor.com, ndesaulniers@google.com,
	 morbo@google.com, justinstitt@google.com, song@kernel.org,
	 ribalda@chromium.org, linux-kernel@vger.kernel.org,
	llvm@lists.linux.dev,  patches@lists.linux.dev,
	ns <0n-s@users.noreply.github.com>,
	 Nathan Chancellor <nathan@kernel.org>
Subject: [PATCH 1/2] x86/purgatory: Add a linker script
Date: Wed, 17 Apr 2024 14:53:45 -0700	[thread overview]
Message-ID: <20240417-x86-fix-kexec-with-llvm-18-v1-1-5383121e8fb7@kernel.org> (raw)
In-Reply-To: <20240417-x86-fix-kexec-with-llvm-18-v1-0-5383121e8fb7@kernel.org>

Commit 8652d44f466a ("kexec: support purgatories with .text.hot
sections") added a warning when the purgatory has more than one .text
section, which is unsupported. A couple of changes have been made to the
x86 purgatory's Makefile to prevent the compiler from splitting the
.text section as a result:

  97b6b9cbba40 ("x86/purgatory: remove PGO flags")
  75b2f7e4c9e0 ("x86/purgatory: Remove LTO flags")

Unfortunately, there may be compiler optimizations that add other text
sections that cannot be disabled. For example, starting with LLVM 18,
large text is emitted in '.ltext', which happens for the purgatory due
to commit e16c2983fba0 ("x86/purgatory: Change compiler flags from
-mcmodel=kernel to -mcmodel=large to fix kexec relocation errors"), but
there are out of line assembly files that use '.text'.

  $ llvm-readelf -S arch/x86/purgatory/purgatory.ro | rg ' .[a-z]?text'
    [ 1] .text             PROGBITS        0000000000000000 000040 0000d0 00  AX  0   0 16
    [ 2] .ltext            PROGBITS        0000000000000000 000110 0015a6 00 AXl  0   0 16

To avoid the runtime warning when the purgatory has been built with LLVM
18, add a linker script that explicitly describes the sections of the
purgatory.ro and use it to merge '.ltext' and '.lrodata' back into
'.text' and '.rodata' to match the behavior of GCC and LLVM prior to the
optimization, as the distinction between small and large text is not
important in this case. This results in no warnings with
'--orphan-handling=warn' with either GNU or LLVM toolchains and the
resulting kernels can properly kexec other kernels.

This linker script is based on arch/s390/purgatory/purgatory.lds.S and
Ricardo Ribalda's prior attempt to add one for arch/x86 [1].

As a consequence of this change, the aforementioned flag changes can be
reverted because the '.text.*' sections generated by those options will
be combined properly by the linker script, which avoids the only reason
they were added in the first place. kexec continues to work with LTO
enabled.

[1]: https://lore.kernel.org/20230321-kexec_clang16-v5-2-5563bf7c4173@chromium.org/

Reported-by: ns <0n-s@users.noreply.github.com>
Closes: https://github.com/ClangBuiltLinux/linux/issues/2016
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
---
 arch/x86/purgatory/.gitignore      |  1 +
 arch/x86/purgatory/Makefile        | 19 +++---------
 arch/x86/purgatory/purgatory.lds.S | 63 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+), 14 deletions(-)

diff --git a/arch/x86/purgatory/.gitignore b/arch/x86/purgatory/.gitignore
index d2be1500671d..71bd99d98906 100644
--- a/arch/x86/purgatory/.gitignore
+++ b/arch/x86/purgatory/.gitignore
@@ -1 +1,2 @@
 purgatory.chk
+purgatory.lds
diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile
index bc31863c5ee6..dfc030a4cca9 100644
--- a/arch/x86/purgatory/Makefile
+++ b/arch/x86/purgatory/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 OBJECT_FILES_NON_STANDARD := y
 
-purgatory-y := purgatory.o stack.o setup-x86_$(BITS).o sha256.o entry64.o string.o
+purgatory-y := purgatory.o purgatory.lds stack.o setup-x86_$(BITS).o sha256.o entry64.o string.o
 
 targets += $(purgatory-y)
 PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
@@ -14,20 +14,11 @@ $(obj)/sha256.o: $(srctree)/lib/crypto/sha256.c FORCE
 
 CFLAGS_sha256.o := -D__DISABLE_EXPORTS -D__NO_FORTIFY
 
-# When profile-guided optimization is enabled, llvm emits two different
-# overlapping text sections, which is not supported by kexec. Remove profile
-# optimization flags.
-KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%,$(KBUILD_CFLAGS))
-
-# When LTO is enabled, llvm emits many text sections, which is not supported
-# by kexec. Remove -flto=* flags.
-KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS))
-
 # When linking purgatory.ro with -r unresolved symbols are not checked,
 # also link a purgatory.chk binary without -r to check for unresolved symbols.
-PURGATORY_LDFLAGS := -e purgatory_start -z nodefaultlib
-LDFLAGS_purgatory.ro := -r $(PURGATORY_LDFLAGS)
-LDFLAGS_purgatory.chk := $(PURGATORY_LDFLAGS)
+PURGATORY_LDFLAGS := -z nodefaultlib
+LDFLAGS_purgatory.ro := -r $(PURGATORY_LDFLAGS) -T
+LDFLAGS_purgatory.chk := -e purgatory_start $(PURGATORY_LDFLAGS)
 targets += purgatory.ro purgatory.chk
 
 # Sanitizer, etc. runtimes are unavailable and cannot be linked here.
@@ -80,7 +71,7 @@ CFLAGS_string.o			+= $(PURGATORY_CFLAGS)
 
 asflags-remove-y		+= $(foreach x, -g -gdwarf-4 -gdwarf-5, $(x) -Wa,$(x))
 
-$(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
+$(obj)/purgatory.ro: $(obj)/purgatory.lds $(PURGATORY_OBJS) FORCE
 		$(call if_changed,ld)
 
 $(obj)/purgatory.chk: $(obj)/purgatory.ro FORCE
diff --git a/arch/x86/purgatory/purgatory.lds.S b/arch/x86/purgatory/purgatory.lds.S
new file mode 100644
index 000000000000..4fb155942642
--- /dev/null
+++ b/arch/x86/purgatory/purgatory.lds.S
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <asm-generic/vmlinux.lds.h>
+#include <asm/cache.h>
+
+OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT)
+
+#undef i386
+
+#ifdef CONFIG_X86_64
+OUTPUT_ARCH(i386:x86-64)
+#else
+OUTPUT_ARCH(i386)
+#endif
+
+ENTRY(purgatory_start)
+
+SECTIONS
+{
+	. = 0;
+
+	.kexec-purgatory : {
+		*(.kexec-purgatory)
+	}
+
+	.text : {
+		_text = .;
+		*(.text .text.*)
+		*(.ltext .ltext.*)
+		_etext = .;
+	}
+
+	.rodata : {
+		_rodata = .;
+		*(.rodata .rodata.*)
+		*(.lrodata .lrodata.*)
+		_erodata = .;
+	}
+
+	.data : {
+		_data = .;
+		*(.data .data.*)
+		_edata = .;
+	}
+
+	. = ALIGN(L1_CACHE_BYTES);
+	.bss : {
+		_bss = .;
+		*(.bss .bss.*)
+		*(COMMON)
+		. = ALIGN(8);	/* For convenience during zeroing */
+		_ebss = .;
+	}
+	_end = .;
+
+	ELF_DETAILS
+
+	DISCARDS
+	/DISCARD/ : {
+		*(.note.GNU-stack .note.gnu.property)
+		*(.llvm_addrsig)
+	}
+}

-- 
2.44.0


  reply	other threads:[~2024-04-17 21:54 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-17 21:53 [PATCH 0/2] x86/purgatory: Avoid kexec runtime warning with LLVM 18 Nathan Chancellor
2024-04-17 21:53 ` Nathan Chancellor [this message]
2024-04-17 21:53 ` [PATCH 2/2] x86/purgatory: Enable orphan section warnings Nathan Chancellor
2024-04-18 11:14 ` [PATCH 0/2] x86/purgatory: Avoid kexec runtime warning with LLVM 18 Borislav Petkov
2024-04-18 15:15   ` Nathan Chancellor
2024-04-18 15:44   ` Nick Desaulniers
2024-04-18 15:59     ` Ard Biesheuvel
2024-04-18 17:52       ` Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240417-x86-fix-kexec-with-llvm-18-v1-1-5383121e8fb7@kernel.org \
    --to=nathan@kernel.org \
    --cc=0n-s@users.noreply.github.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=justinstitt@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=llvm@lists.linux.dev \
    --cc=mingo@redhat.com \
    --cc=morbo@google.com \
    --cc=ndesaulniers@google.com \
    --cc=patches@lists.linux.dev \
    --cc=ribalda@chromium.org \
    --cc=song@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.