]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
x86/virt/tdx: Avoid indirect calls to TDX assembly functions
authorKai Huang <kai.huang@intel.com>
Fri, 6 Jun 2025 13:07:37 +0000 (01:07 +1200)
committerDave Hansen <dave.hansen@linux.intel.com>
Tue, 10 Jun 2025 19:32:52 +0000 (12:32 -0700)
Two 'static inline' TDX helper functions (sc_retry() and
sc_retry_prerr()) take function pointer arguments which refer to
assembly functions.  Normally, the compiler inlines the TDX helper,
realizes that the function pointer targets are completely static --
thus can be resolved at compile time -- and generates direct call
instructions.

But, other times (like when CONFIG_CC_OPTIMIZE_FOR_SIZE=y), the
compiler declines to inline the helpers and will instead generate
indirect call instructions.

Indirect calls to assembly functions require special annotation (for
various Control Flow Integrity mechanisms).  But TDX assembly
functions lack the special annotations and can only be called
directly.

Annotate both the helpers as '__always_inline' to prod the compiler
into maintaining the direct calls. There is no guarantee here, but
Peter has volunteered to report the compiler bug if this assumption
ever breaks[1].

Fixes: 1e66a7e27539 ("x86/virt/tdx: Handle SEAMCALL no entropy error in common code")
Fixes: df01f5ae07dd ("x86/virt/tdx: Add SEAMCALL error printing for module initialization")
Signed-off-by: Kai Huang <kai.huang@intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/lkml/20250605145914.GW39944@noisy.programming.kicks-ass.net/
Link: https://lore.kernel.org/all/20250606130737.30713-1-kai.huang%40intel.com
arch/x86/include/asm/tdx.h
arch/x86/virt/vmx/tdx/tdx.c

index 8b19294600c4679e44d83c4ff45e0802c139aff1..7ddef3a698668fe9f32bc3b959d8ba99b0b796df 100644 (file)
@@ -106,7 +106,7 @@ void tdx_init(void);
 
 typedef u64 (*sc_func_t)(u64 fn, struct tdx_module_args *args);
 
-static inline u64 sc_retry(sc_func_t func, u64 fn,
+static __always_inline u64 sc_retry(sc_func_t func, u64 fn,
                           struct tdx_module_args *args)
 {
        int retry = RDRAND_RETRY_LOOPS;
index 2457d13c3f9ee6c3c3cac3de5ed68ce8aa151e7e..c7a9a087ccaf50d177557a70eeb269bbfd5b2845 100644 (file)
@@ -75,8 +75,9 @@ static inline void seamcall_err_ret(u64 fn, u64 err,
                        args->r9, args->r10, args->r11);
 }
 
-static inline int sc_retry_prerr(sc_func_t func, sc_err_func_t err_func,
-                                u64 fn, struct tdx_module_args *args)
+static __always_inline int sc_retry_prerr(sc_func_t func,
+                                         sc_err_func_t err_func,
+                                         u64 fn, struct tdx_module_args *args)
 {
        u64 sret = sc_retry(func, fn, args);