[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250605131017.21270-1-kai.huang@intel.com>
Date: Fri, 6 Jun 2025 01:10:17 +1200
From: Kai Huang <kai.huang@...el.com>
To: dave.hansen@...el.com,
peterz@...radead.org,
tglx@...utronix.de,
bp@...en8.de,
mingo@...hat.com,
hpa@...or.com,
kirill.shutemov@...ux.intel.com
Cc: rick.p.edgecombe@...el.com,
x86@...nel.org,
samitolvanen@...gle.com,
linux-kernel@...r.kernel.org
Subject: [PATCH v2] x86/virt/tdx: Annotate TDX assembly to allow indirect calls
A TDX helper function (sc_retry()) passes around function pointers to
assembly functions. Normally, the compiler realizes that the function
pointer targets are completely static, can be resolved at compile time,
and generates direct call instructions.
But, other times (like when CONFIG_CC_OPTIMIZE_FOR_SIZE=y), the compiler
will instead generate indirect call instructions.
Indirect calls to assembly functions require special annotation so that
both hardware and software implementations of Control Flow Integrity
mechanisms can work correctly.
The TDX functions are declared as if they are only called directly (via
SYM_FUNC_START). Move them over to another macro (SYM_TYPED_FUNC_START)
which will annotate them as being called indirectly (see
include/linux/cfi_types.h).
This was found through randconfig testing, presumably setting
CONFIG_CC_OPTIMIZE_FOR_SIZE=1 when objtool spewed a bunch of these:
vmlinux.o: warning: objtool: tdh_mem_range_block+0x7e: relocation to
!ENDBR: __seamcall_ret+0x0
Note that currently only __seamcall() and __seamcall_ret() are called
via sc_retry(). __seamcall_saved_ret() is only called and is directly
called by tdh_vp_enter() since this SEAMCALL doesn't return "running out
of entropy" error which sc_retry() handles.
Using SYM_TYPED_FUNC_START for __seamcall_saved_ret() results in build
error when building the kernel with clang and CONFIG_CFI_CLANG=y:
ld.lld: error: undefined symbol: __kcfi_typeid___seamcall_saved_ret
>>> referenced by usercopy_64.c
>>> vmlinux.o:(__cfi___seamcall_saved_ret)
Making tdh_vp_enter() call __seamcall_saved_ret() via sc_retry() fixes
the error, but don't do this way since tdh_vp_enter() is in performance
critical path. Instead, keep using SYM_FUNC_START for it but only move
to SYM_TYPED_FUNC_START for the other two.
While on it, remove seamcall_saved_ret() since it is not used.
Fixes: 1e66a7e27539 ("x86/virt/tdx: Handle SEAMCALL no entropy error in common code")
Signed-off-by: Kai Huang <kai.huang@...el.com>
---
arch/x86/include/asm/tdx.h | 1 -
arch/x86/virt/vmx/tdx/seamcall.S | 10 ++++++++--
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
index 8b19294600c4..c6ec8601bbb8 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -121,7 +121,6 @@ static inline u64 sc_retry(sc_func_t func, u64 fn,
#define seamcall(_fn, _args) sc_retry(__seamcall, (_fn), (_args))
#define seamcall_ret(_fn, _args) sc_retry(__seamcall_ret, (_fn), (_args))
-#define seamcall_saved_ret(_fn, _args) sc_retry(__seamcall_saved_ret, (_fn), (_args))
int tdx_cpu_enable(void);
int tdx_enable(void);
const char *tdx_dump_mce_info(struct mce *m);
diff --git a/arch/x86/virt/vmx/tdx/seamcall.S b/arch/x86/virt/vmx/tdx/seamcall.S
index 6854c52c374b..552495761b36 100644
--- a/arch/x86/virt/vmx/tdx/seamcall.S
+++ b/arch/x86/virt/vmx/tdx/seamcall.S
@@ -1,9 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/linkage.h>
+#include <linux/cfi_types.h>
#include <asm/frame.h>
#include "tdxcall.S"
+/*
+ * Use SYM_TYPED_FUNC_START() for __seamcall() and __seamcall_ret()
+ * since they can be called via an indirect call.
+ */
+
/*
* __seamcall() - Host-side interface functions to SEAM software
* (the P-SEAMLDR or the TDX module).
@@ -18,7 +24,7 @@
* Return (via RAX) TDX_SEAMCALL_VMFAILINVALID if the SEAMCALL itself
* fails, or the completion status of the SEAMCALL leaf function.
*/
-SYM_FUNC_START(__seamcall)
+SYM_TYPED_FUNC_START(__seamcall)
TDX_MODULE_CALL host=1
SYM_FUNC_END(__seamcall)
@@ -37,7 +43,7 @@ SYM_FUNC_END(__seamcall)
* Return (via RAX) TDX_SEAMCALL_VMFAILINVALID if the SEAMCALL itself
* fails, or the completion status of the SEAMCALL leaf function.
*/
-SYM_FUNC_START(__seamcall_ret)
+SYM_TYPED_FUNC_START(__seamcall_ret)
TDX_MODULE_CALL host=1 ret=1
SYM_FUNC_END(__seamcall_ret)
base-commit: ec7714e4947909190ffb3041a03311a975350fe0
--
2.49.0
Powered by blists - more mailing lists