[PATCH v13 05/22] x86/virt/tdx: Handle SEAMCALL no entropy error in common code

From: Kai Huang
Date: Fri Aug 25 2023 - 08:16:47 EST


Some SEAMCALLs use the RDRAND hardware and can fail for the same reasons
as RDRAND. Use the kernel RDRAND retry logic for them.

There are three __seamcall*() variants. Add a macro to do the SEAMCALL
retry in the common code and define a wrapper for each __seamcall*()
variant.

Signed-off-by: Kai Huang <kai.huang@xxxxxxxxx>
---

v12 -> v13:
- New implementation due to TDCALL assembly series.

---
arch/x86/include/asm/tdx.h | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)

diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
index a252328734c7..cfae8b31a2e9 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -24,6 +24,11 @@
#define TDX_SEAMCALL_GP (TDX_SW_ERROR | X86_TRAP_GP)
#define TDX_SEAMCALL_UD (TDX_SW_ERROR | X86_TRAP_UD)

+/*
+ * TDX module SEAMCALL leaf function error codes
+ */
+#define TDX_RND_NO_ENTROPY 0x8000020300000000ULL
+
#ifndef __ASSEMBLY__

/*
@@ -82,6 +87,28 @@ u64 __seamcall(u64 fn, struct tdx_module_args *args);
u64 __seamcall_ret(u64 fn, struct tdx_module_args *args);
u64 __seamcall_saved_ret(u64 fn, struct tdx_module_args *args);

+#include <asm/archrandom.h>
+
+#define SEAMCALL_NO_ENTROPY_RETRY(__seamcall_func, __fn, __args) \
+({ \
+ int ___retry = RDRAND_RETRY_LOOPS; \
+ u64 ___sret; \
+ \
+ do { \
+ ___sret = __seamcall_func((__fn), (__args)); \
+ } while (___sret == TDX_RND_NO_ENTROPY && --___retry); \
+ ___sret; \
+})
+
+#define seamcall(__fn, __args) \
+ SEAMCALL_NO_ENTROPY_RETRY(__seamcall, (__fn), (__args))
+
+#define seamcall_ret(__fn, __args) \
+ SEAMCALL_NO_ENTROPY_RETRY(__seamcall_ret, (__fn), (__args))
+
+#define seamcall_saved_ret(__fn, __args) \
+ SEAMCALL_NO_ENTROPY_RETRY(__seamcall_saved_ret, (__fn), (__args))
+
bool platform_tdx_enabled(void);
#else
static inline bool platform_tdx_enabled(void) { return false; }
--
2.41.0