odd objtool 'unreachable instruction' warning

From: Linus Torvalds

Date: Tue Oct 28 2025 - 15:29:31 EST


Josh, Peter,
due to another entirely unrelated discussion, I ended up resurrecting
my "make asm readable" patch that I have had in my local tree when I
want to look at the actual generated code for user accesses.

That is a local hack that just removes the alternative noise for the
common ops, so that I actually see the fences and clac/stac
instructions as such, instead of seeing them as nops in the object
file or as horrible noise in the assembler output.

So that patch is not something I'd ever commit in general, but it's
really useful for checking code generation - but it results in odd
objdump warnings these days (I say "these days", because I've used
that patch locally over the years, and the objdump warning hasn't
always been there).

It's a pretty odd warning, because the code looks fine to me, but I
might be missing something obvious.

Anyway, this is clearly not a big and urgent problem, but I'd love for
you to take a look. I'm attaching the patch I use so you can see what
I mean.. Any ideas what triggers that warning? Because I'd love to
keep this patch in my local tree without having objtool be upset with
me....

Linus
From 97c16bd1f44287f95f1be82185631d654a6022d8 Mon Sep 17 00:00:00 2001
From: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
Date: Wed, 3 Apr 2024 10:33:12 -0700
Subject: [PATCH] Avoid alternative assembler noise for common ops

Just hardcode the ones I have for SMP and LFENCE
---
arch/x86/include/asm/alternative.h | 7 +------
arch/x86/include/asm/barrier.h | 2 +-
arch/x86/include/asm/smap.h | 18 ++++++------------
arch/x86/lib/getuser.S | 2 +-
4 files changed, 9 insertions(+), 20 deletions(-)

diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index 15bc07a5ebb3..281c823a869e 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -42,12 +42,7 @@
*/

#ifdef CONFIG_SMP
-#define LOCK_PREFIX_HERE \
- ".pushsection .smp_locks,\"a\"\n" \
- ".balign 4\n" \
- ".long 671f - .\n" /* offset */ \
- ".popsection\n" \
- "671:"
+#define LOCK_PREFIX_HERE

#define LOCK_PREFIX LOCK_PREFIX_HERE "\n\tlock "

diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h
index db70832232d4..2b911c88467b 100644
--- a/arch/x86/include/asm/barrier.h
+++ b/arch/x86/include/asm/barrier.h
@@ -45,7 +45,7 @@
__mask; })

/* Prevent speculative execution past this barrier. */
-#define barrier_nospec() alternative("", "lfence", X86_FEATURE_LFENCE_RDTSC)
+#define barrier_nospec() asm volatile("lfence":::"memory")

#define __dma_rmb() barrier()
#define __dma_wmb() barrier()
diff --git a/arch/x86/include/asm/smap.h b/arch/x86/include/asm/smap.h
index 4f84d421d1cf..613b24a58b26 100644
--- a/arch/x86/include/asm/smap.h
+++ b/arch/x86/include/asm/smap.h
@@ -15,24 +15,20 @@

#ifdef __ASSEMBLER__

-#define ASM_CLAC \
- ALTERNATIVE "", "clac", X86_FEATURE_SMAP
+#define ASM_CLAC "clac"

-#define ASM_STAC \
- ALTERNATIVE "", "stac", X86_FEATURE_SMAP
+#define ASM_STAC "stac"

#else /* __ASSEMBLER__ */

static __always_inline void clac(void)
{
- /* Note: a barrier is implicit in alternative() */
- alternative("", "clac", X86_FEATURE_SMAP);
+ asm volatile("clac": : :"memory");
}

static __always_inline void stac(void)
{
- /* Note: a barrier is implicit in alternative() */
- alternative("", "stac", X86_FEATURE_SMAP);
+ asm volatile("stac": : :"memory");
}

static __always_inline unsigned long smap_save(void)
@@ -58,10 +54,8 @@ static __always_inline void smap_restore(unsigned long flags)
}

/* These macros can be used in asm() statements */
-#define ASM_CLAC \
- ALTERNATIVE("", "clac", X86_FEATURE_SMAP)
-#define ASM_STAC \
- ALTERNATIVE("", "stac", X86_FEATURE_SMAP)
+#define ASM_CLAC "clac"
+#define ASM_STAC "stac"

#define ASM_CLAC_UNSAFE \
ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "clac", X86_FEATURE_SMAP)
diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S
index 9d5654b8a72a..1c5952c637ce 100644
--- a/arch/x86/lib/getuser.S
+++ b/arch/x86/lib/getuser.S
@@ -37,7 +37,7 @@
#include <asm/smap.h>
#include <asm/runtime-const.h>

-#define ASM_BARRIER_NOSPEC ALTERNATIVE "", "lfence", X86_FEATURE_LFENCE_RDTSC
+#define ASM_BARRIER_NOSPEC lfence

.macro check_range size:req
.if IS_ENABLED(CONFIG_X86_64)
--
2.51.1.534.g6d2b4bf2f4