@@ -14,6 +14,7 @@
#include <linux/sched/signal.h> /* force_sig_fault() */
/* TDX Module call Leaf IDs */
+#define TDX_GET_INFO 1
#define TDX_GET_VEINFO 3
#define VE_IS_IO_OUT(exit_qual) (((exit_qual) & 8) ? 0 : 1)
@@ -21,6 +22,11 @@
#define VE_GET_PORT_NUM(exit_qual) ((exit_qual) >> 16)
#define VE_IS_IO_STRING(exit_qual) ((exit_qual) & 16 ? 1 : 0)
+static struct {
+ unsigned int gpa_width;
+ unsigned long attributes;
+} td_info __ro_after_init;
+
bool is_tdx_guest(void)
{
static int tdx_guest = -1;
@@ -65,6 +71,31 @@ static inline u64 _tdx_hypercall(u64 fn, u64 r12, u64 r13, u64 r14,
return out->r10;
}
+static void tdx_get_info(void)
+{
+ struct tdx_module_output out;
+ u64 ret;
+
+ /*
+ * TDINFO TDX Module call is used to get the TD
+ * execution environment information like GPA
+ * width, number of available vcpus, debug mode
+ * information, etc. More details about the ABI
+ * can be found in TDX Guest-Host-Communication
+ * Interface (GHCI), sec 2.4.2 TDCALL [TDG.VP.INFO].
+ */
+ ret = __tdx_module_call(TDX_GET_INFO, 0, 0, 0, 0, &out);
+
+ /*
+ * Non zero return means buggy TDX module (which is
+ * fatal). So raise a BUG().
+ */
+ BUG_ON(ret);
+
+ td_info.gpa_width = out.rcx & GENMASK(5, 0);
+ td_info.attributes = out.rdx;
+}
+
static __cpuidle void _tdx_halt(const bool irq_disabled, const bool do_sti)
{
u64 ret;
@@ -466,6 +497,8 @@ void __init tdx_early_init(void)
setup_force_cpu_cap(X86_FEATURE_TDX_GUEST);
+ tdx_get_info();
+
pv_ops.irq.safe_halt = tdx_safe_halt;
pv_ops.irq.halt = tdx_halt;