[PATCH v11 06/20] x86/virt/tdx: Handle SEAMCALL running out of entropy error

From: Kai Huang
Date: Sun Jun 04 2023 - 10:30:33 EST


Certain SEAMCALL leaf functions may return error due to running out of
entropy, in which case the SEAMCALL should be retried as suggested by
the TDX spec.

Handle this case in SEAMCALL common function. Mimic the existing
rdrand_long() to retry RDRAND_RETRY_LOOPS times.

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

v10 -> v11:
- New patch

---
arch/x86/virt/vmx/tdx/tdx.c | 15 ++++++++++++++-
arch/x86/virt/vmx/tdx/tdx.h | 17 +++++++++++++++++
2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index e82713dd5d54..e62e978eba1b 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -15,6 +15,7 @@
#include <linux/smp.h>
#include <asm/msr-index.h>
#include <asm/msr.h>
+#include <asm/archrandom.h>
#include <asm/tdx.h>
#include "tdx.h"

@@ -33,12 +34,24 @@ static int __always_unused seamcall(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
struct tdx_module_output *out)
{
int cpu, ret = 0;
+ int retry;
u64 sret;

/* Need a stable CPU id for printing error message */
cpu = get_cpu();

- sret = __seamcall(fn, rcx, rdx, r8, r9, out);
+ /*
+ * Certain SEAMCALL leaf functions may return error due to
+ * running out of entropy, in which case the SEAMCALL should
+ * be retried. Handle this in SEAMCALL common function.
+ *
+ * Mimic the existing rdrand_long() to retry
+ * RDRAND_RETRY_LOOPS times.
+ */
+ retry = RDRAND_RETRY_LOOPS;
+ do {
+ sret = __seamcall(fn, rcx, rdx, r8, r9, out);
+ } while (sret == TDX_RND_NO_ENTROPY && --retry);

/* Save SEAMCALL return code if the caller wants it */
if (seamcall_ret)
diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h
index 48ad1a1ba737..55dbb1b8c971 100644
--- a/arch/x86/virt/vmx/tdx/tdx.h
+++ b/arch/x86/virt/vmx/tdx/tdx.h
@@ -4,6 +4,23 @@

#include <linux/types.h>

+/*
+ * This file contains both macros and data structures defined by the TDX
+ * architecture and Linux defined software data structures and functions.
+ * The two should not be mixed together for better readability. The
+ * architectural definitions come first.
+ */
+
+/*
+ * TDX SEAMCALL error codes
+ */
+#define TDX_RND_NO_ENTROPY 0x8000020300000000ULL
+
+/*
+ * Do not put any hardware-defined TDX structure representations below
+ * this comment!
+ */
+
struct tdx_module_output;
u64 __seamcall(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
struct tdx_module_output *out);
--
2.40.1