public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: x86@kernel.org
Cc: linux-kernel@vger.kernel.org, peterz@infradead.org,
	alyssa.milburn@intel.com, scott.d.constable@intel.com,
	joao@overdrivepizza.com, andrew.cooper3@citrix.com,
	jpoimboe@kernel.org, jose.marchesi@oracle.com,
	hjl.tools@gmail.com, ndesaulniers@google.com,
	samitolvanen@google.com, nathan@kernel.org, ojeda@kernel.org,
	kees@kernel.org, alexei.starovoitov@gmail.com,
	mhiramat@kernel.org, jmill@asu.edu
Subject: [PATCH v3 10/10] x86/ibt: Optimize fineibt-bhi arity 1 case
Date: Wed, 19 Feb 2025 17:21:17 +0100	[thread overview]
Message-ID: <20250219163515.368430004@infradead.org> (raw)
In-Reply-To: 20250219162107.880673196@infradead.org

Saves a CALL to an out-of-line thunk for the common case of 1
argument.

Suggested-by: Scott Constable <scott.d.constable@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/ibt.h    |    4 ++
 arch/x86/kernel/alternative.c |   61 +++++++++++++++++++++++++++++++++++-------
 2 files changed, 56 insertions(+), 9 deletions(-)

--- a/arch/x86/include/asm/ibt.h
+++ b/arch/x86/include/asm/ibt.h
@@ -70,6 +70,10 @@ static inline bool __is_endbr(u32 val)
 	if (val == gen_endbr_poison())
 		return true;
 
+	/* See cfi_fineibt_bhi_preamble() */
+	if (IS_ENABLED(CONFIG_FINEIBT_BHI) && val == 0x001f0ff5)
+		return true;
+
 	val &= ~0x01000000U; /* ENDBR32 -> ENDBR64 */
 	return val == gen_endbr();
 }
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -1299,6 +1299,55 @@ static int cfi_rand_preamble(s32 *start,
 	return 0;
 }
 
+static void cfi_fineibt_bhi_preamble(void *addr, int arity)
+{
+	bool warn = IS_ENABLED(CONFIG_CFI_PREMISSIVE) || cfi_warn;
+
+	if (!arity)
+		return;
+
+	if (!warn && arity == 1) {
+		/*
+		 * Crazy scheme to allow arity-1 inline:
+		 *
+		 * __cfi_foo:
+		 *  0: f3 0f 1e fa             endbr64
+		 *  4: 41 81 <ea> 78 56 34 12  sub     0x12345678, %r10d
+		 *  b: 49 0f 45 fa             cmovne  %r10, %rdi
+		 *  f: 75 f5                   jne     __cfi_foo+6
+		 * 11: 0f 1f 00                nopl    (%rax)
+		 *
+		 * Code that direct calls to foo()+0, decodes the tail end as:
+		 *
+		 * foo:
+		 *  0: f5                      cmc
+		 *  1: 0f 1f 00                nopl    (%rax)
+		 *
+		 * which clobbers CF, but does not affect anything ABI
+		 * wise.
+		 *
+		 * Notably, this scheme is incompatible with permissive CFI
+		 * because the cmov is unconditional and RDI will have been
+		 * clobbered.
+		 */
+		const u8 magic[9] = {
+			0x49, 0x0f, 0x45, 0xfa,
+			0x75, 0xf5,
+			BYTES_NOP3,
+		};
+
+		text_poke_early(addr + fineibt_preamble_bhi, magic, 9);
+
+		return;
+	}
+
+	text_poke_early(addr + fineibt_preamble_bhi,
+			text_gen_insn(CALL_INSN_OPCODE,
+				      addr + fineibt_preamble_bhi,
+				      __bhi_args[arity]),
+			CALL_INSN_SIZE);
+}
+
 static int cfi_rewrite_preamble(s32 *start, s32 *end)
 {
 	s32 *s;
@@ -1329,14 +1378,8 @@ static int cfi_rewrite_preamble(s32 *sta
 			  "kCFI preamble has wrong register at: %pS %*ph\n",
 			  addr, 5, addr);
 
-		if (!cfi_bhi || !arity)
-			continue;
-
-		text_poke_early(addr + fineibt_preamble_bhi,
-				text_gen_insn(CALL_INSN_OPCODE,
-					      addr + fineibt_preamble_bhi,
-					      __bhi_args[arity]),
-				CALL_INSN_SIZE);
+		if (cfi_bhi)
+			cfi_fineibt_bhi_preamble(addr, arity);
 	}
 
 	return 0;
@@ -1349,7 +1392,7 @@ static void cfi_rewrite_endbr(s32 *start
 	for (s = start; s < end; s++) {
 		void *addr = (void *)s + *s;
 
-		if (!is_endbr(addr + 16))
+		if (!exact_endbr(addr + 16))
 			continue;
 
 		poison_endbr(addr + 16);



  parent reply	other threads:[~2025-02-19 16:36 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-19 16:21 [PATCH v3 00/10] x86/ibt: FineIBT-BHI Peter Zijlstra
2025-02-19 16:21 ` [PATCH v3 01/10] x86/cfi: Add warn option Peter Zijlstra
2025-02-19 17:50   ` Kees Cook
2025-02-19 17:56     ` Peter Zijlstra
2025-02-19 16:21 ` [PATCH v3 02/10] x86/ibt: Add exact_endbr() helper Peter Zijlstra
2025-02-19 17:51   ` Kees Cook
2025-02-19 16:21 ` [PATCH v3 03/10] x86/traps: Decode 0xEA #UD Peter Zijlstra
2025-02-19 16:47   ` Andrew Cooper
2025-02-19 16:49     ` Peter Zijlstra
2025-02-19 17:52   ` Kees Cook
2025-02-19 16:21 ` [PATCH v3 04/10] x86/traps: Allow custom fixups in handle_bug() Peter Zijlstra
2025-02-19 17:55   ` Kees Cook
2025-02-19 18:17     ` Peter Zijlstra
2025-02-19 16:21 ` [PATCH v3 05/10] x86/ibt: Optimize FineIBT sequence Peter Zijlstra
2025-02-19 17:15   ` Andrew Cooper
2025-02-20 18:28     ` Constable, Scott D
2025-02-19 18:01   ` Kees Cook
2025-02-19 18:18     ` Peter Zijlstra
2025-02-19 18:23       ` Kees Cook
2025-02-19 16:21 ` [PATCH v3 06/10] x86/traps: Decode LOCK Jcc.d8 #UD Peter Zijlstra
2025-02-19 16:45   ` Peter Zijlstra
2025-02-19 18:20   ` Kees Cook
2025-02-19 18:33     ` Peter Zijlstra
2025-02-19 19:44       ` Peter Zijlstra
2025-02-19 16:21 ` [PATCH v3 07/10] x86/ibt: Add paranoid FineIBT mode Peter Zijlstra
2025-02-19 17:31   ` Andrew Cooper
2025-02-19 20:07     ` Peter Zijlstra
2025-02-21 13:40     ` David Laight
2025-02-19 18:05   ` Kees Cook
2025-02-19 16:21 ` [PATCH v3 08/10] x86: BHI stubs Peter Zijlstra
2025-02-19 18:07   ` Kees Cook
2025-02-19 18:07     ` Peter Zijlstra
2025-02-19 16:21 ` [PATCH v3 09/10] x86/ibt: Implement FineIBT-BHI mitigation Peter Zijlstra
2025-02-19 18:11   ` Kees Cook
2025-02-19 16:21 ` Peter Zijlstra [this message]
2025-02-19 18:21   ` [PATCH v3 10/10] x86/ibt: Optimize fineibt-bhi arity 1 case Kees Cook
2025-02-19 17:36 ` [PATCH v3 00/10] x86/ibt: FineIBT-BHI Kees Cook
2025-02-20 11:27 ` Peter Zijlstra

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=20250219163515.368430004@infradead.org \
    --to=peterz@infradead.org \
    --cc=alexei.starovoitov@gmail.com \
    --cc=alyssa.milburn@intel.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=hjl.tools@gmail.com \
    --cc=jmill@asu.edu \
    --cc=joao@overdrivepizza.com \
    --cc=jose.marchesi@oracle.com \
    --cc=jpoimboe@kernel.org \
    --cc=kees@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=nathan@kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=ojeda@kernel.org \
    --cc=samitolvanen@google.com \
    --cc=scott.d.constable@intel.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox