[PATCH v5 09/22] x86/virt/tdx: Detect TDX module by doing module global initialization

From: Kai Huang
Date: Wed Jun 22 2022 - 07:17:41 EST


So far the TDX module hasn't been detected yet. __seamcall() returns
TDX_SEAMCALL_VMFAILINVALID when the target SEAM software module is not
loaded. Just use __seamcall() to the TDX module to detect the TDX
module.

The first step of initializing the module is to call TDH.SYS.INIT once
on any logical cpu to do module global initialization. Just use it to
detect the module since it needs to be done anyway.

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

- v3 -> v5 (no feedback on v4):
- Add detecting TDX module.

---
arch/x86/virt/vmx/tdx/tdx.c | 39 +++++++++++++++++++++++++++++++++++--
arch/x86/virt/vmx/tdx/tdx.h | 1 +
2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index 31ce4522100a..de4efc16ed45 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -180,6 +180,21 @@ static void seamcall_on_each_cpu(struct seamcall_ctx *sc)
on_each_cpu(seamcall_smp_call_function, sc, true);
}

+/*
+ * Do TDX module global initialization. It also detects whether the
+ * module has been loaded or not.
+ */
+static int tdx_module_init_global(void)
+{
+ u64 ret;
+
+ ret = seamcall(TDH_SYS_INIT, 0, 0, 0, 0, NULL);
+ if (ret == TDX_SEAMCALL_VMFAILINVALID)
+ return -ENODEV;
+
+ return ret ? -EFAULT : 0;
+}
+
/*
* Detect and initialize the TDX module.
*
@@ -189,8 +204,28 @@ static void seamcall_on_each_cpu(struct seamcall_ctx *sc)
*/
static int init_tdx_module(void)
{
- /* The TDX module hasn't been detected */
- return -ENODEV;
+ int ret;
+
+ /*
+ * Whether the TDX module is loaded is still unknown. SEAMCALL
+ * instruction fails with VMfailInvalid if the target SEAM
+ * software module is not loaded, so it can be used to detect the
+ * module.
+ *
+ * The first step of initializing the TDX module is module global
+ * initialization. Just use it to detect the module.
+ */
+ ret = tdx_module_init_global();
+ if (ret)
+ goto out;
+
+ /*
+ * Return -EINVAL until all steps of TDX module initialization
+ * process are done.
+ */
+ ret = -EINVAL;
+out:
+ return ret;
}

static void shutdown_tdx_module(void)
diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h
index 95d4eb884134..9e694789eb91 100644
--- a/arch/x86/virt/vmx/tdx/tdx.h
+++ b/arch/x86/virt/vmx/tdx/tdx.h
@@ -49,6 +49,7 @@
/*
* TDX module SEAMCALL leaf functions
*/
+#define TDH_SYS_INIT 33
#define TDH_SYS_LP_SHUTDOWN 44

/*
--
2.36.1