]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
x86/tdx: Dump attributes and TD_CTLS on boot
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Mon, 2 Dec 2024 07:24:58 +0000 (09:24 +0200)
committerDave Hansen <dave.hansen@linux.intel.com>
Thu, 5 Dec 2024 18:27:07 +0000 (10:27 -0800)
Dump TD configuration on boot. Attributes and TD_CTLS define TD
behavior. This information is useful for tracking down bugs.

The output ends up looking like this in practice:

[    0.000000] tdx: Guest detected
[    0.000000] tdx: Attributes: SEPT_VE_DISABLE
[    0.000000] tdx: TD_CTLS: PENDING_VE_DISABLE ENUM_TOPOLOGY VIRT_CPUID2 REDUCE_VE

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Nikolay Borisov <nik.borisov@suse.com>
Link: https://lore.kernel.org/all/20241202072458.447455-1-kirill.shutemov%40linux.intel.com
arch/x86/coco/tdx/Makefile
arch/x86/coco/tdx/debug.c [new file with mode: 0644]
arch/x86/coco/tdx/tdx.c
arch/x86/include/asm/shared/tdx.h
arch/x86/include/asm/tdx.h

index 2c7dcbf1458b054e06578e7b80fef018f898d309..b3c47d3700e24af6d84752e4e839f9a7fc88bfe8 100644 (file)
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 
-obj-y += tdx.o tdx-shared.o tdcall.o
+obj-y += debug.o tdcall.o tdx.o tdx-shared.o
diff --git a/arch/x86/coco/tdx/debug.c b/arch/x86/coco/tdx/debug.c
new file mode 100644 (file)
index 0000000..cef847c
--- /dev/null
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#undef pr_fmt
+#define pr_fmt(fmt)     "tdx: " fmt
+
+#include <linux/array_size.h>
+#include <linux/printk.h>
+#include <asm/tdx.h>
+
+#define DEF_TDX_ATTR_NAME(_name) [TDX_ATTR_##_name##_BIT] = __stringify(_name)
+
+static __initdata const char *tdx_attributes[] = {
+       DEF_TDX_ATTR_NAME(DEBUG),
+       DEF_TDX_ATTR_NAME(HGS_PLUS_PROF),
+       DEF_TDX_ATTR_NAME(PERF_PROF),
+       DEF_TDX_ATTR_NAME(PMT_PROF),
+       DEF_TDX_ATTR_NAME(ICSSD),
+       DEF_TDX_ATTR_NAME(LASS),
+       DEF_TDX_ATTR_NAME(SEPT_VE_DISABLE),
+       DEF_TDX_ATTR_NAME(MIGRTABLE),
+       DEF_TDX_ATTR_NAME(PKS),
+       DEF_TDX_ATTR_NAME(KL),
+       DEF_TDX_ATTR_NAME(TPA),
+       DEF_TDX_ATTR_NAME(PERFMON),
+};
+
+#define DEF_TD_CTLS_NAME(_name) [TD_CTLS_##_name##_BIT] = __stringify(_name)
+
+static __initdata const char *tdcs_td_ctls[] = {
+       DEF_TD_CTLS_NAME(PENDING_VE_DISABLE),
+       DEF_TD_CTLS_NAME(ENUM_TOPOLOGY),
+       DEF_TD_CTLS_NAME(VIRT_CPUID2),
+       DEF_TD_CTLS_NAME(REDUCE_VE),
+       DEF_TD_CTLS_NAME(LOCK),
+};
+
+void __init tdx_dump_attributes(u64 td_attr)
+{
+       pr_info("Attributes:");
+
+       for (int i = 0; i < ARRAY_SIZE(tdx_attributes); i++) {
+               if (!tdx_attributes[i])
+                       continue;
+               if (td_attr & BIT(i))
+                       pr_cont(" %s", tdx_attributes[i]);
+               td_attr &= ~BIT(i);
+       }
+
+       if (td_attr)
+               pr_cont(" unknown:%#llx", td_attr);
+       pr_cont("\n");
+
+}
+
+void __init tdx_dump_td_ctls(u64 td_ctls)
+{
+       pr_info("TD_CTLS:");
+
+       for (int i = 0; i < ARRAY_SIZE(tdcs_td_ctls); i++) {
+               if (!tdcs_td_ctls[i])
+                       continue;
+               if (td_ctls & BIT(i))
+                       pr_cont(" %s", tdcs_td_ctls[i]);
+               td_ctls &= ~BIT(i);
+       }
+       if (td_ctls)
+               pr_cont(" unknown:%#llx", td_ctls);
+       pr_cont("\n");
+}
index c0ebe8cc147e50fd2b7c20401e23a9a7674c6a86..32809a06dab46d172ad92b4ac028b37f31a2f0c5 100644 (file)
@@ -32,9 +32,6 @@
 #define VE_GET_PORT_NUM(e)     ((e) >> 16)
 #define VE_IS_IO_STRING(e)     ((e) & BIT(4))
 
-#define ATTR_DEBUG             BIT(0)
-#define ATTR_SEPT_VE_DISABLE   BIT(28)
-
 /* TDX Module call error codes */
 #define TDCALL_RETURN_CODE(a)  ((a) >> 32)
 #define TDCALL_INVALID_OPERAND 0xc0000100
@@ -200,14 +197,14 @@ static void __noreturn tdx_panic(const char *msg)
  *
  * TDX 1.0 does not allow the guest to disable SEPT #VE on its own. The VMM
  * controls if the guest will receive such #VE with TD attribute
- * ATTR_SEPT_VE_DISABLE.
+ * TDX_ATTR_SEPT_VE_DISABLE.
  *
  * Newer TDX modules allow the guest to control if it wants to receive SEPT
  * violation #VEs.
  *
  * Check if the feature is available and disable SEPT #VE if possible.
  *
- * If the TD is allowed to disable/enable SEPT #VEs, the ATTR_SEPT_VE_DISABLE
+ * If the TD is allowed to disable/enable SEPT #VEs, the TDX_ATTR_SEPT_VE_DISABLE
  * attribute is no longer reliable. It reflects the initial state of the
  * control for the TD, but it will not be updated if someone (e.g. bootloader)
  * changes it before the kernel starts. Kernel must check TDCS_TD_CTLS bit to
@@ -216,14 +213,14 @@ static void __noreturn tdx_panic(const char *msg)
 static void disable_sept_ve(u64 td_attr)
 {
        const char *msg = "TD misconfiguration: SEPT #VE has to be disabled";
-       bool debug = td_attr & ATTR_DEBUG;
+       bool debug = td_attr & TDX_ATTR_DEBUG;
        u64 config, controls;
 
        /* Is this TD allowed to disable SEPT #VE */
        tdg_vm_rd(TDCS_CONFIG_FLAGS, &config);
        if (!(config & TDCS_CONFIG_FLEXIBLE_PENDING_VE)) {
                /* No SEPT #VE controls for the guest: check the attribute */
-               if (td_attr & ATTR_SEPT_VE_DISABLE)
+               if (td_attr & TDX_ATTR_SEPT_VE_DISABLE)
                        return;
 
                /* Relax SEPT_VE_DISABLE check for debug TD for backtraces */
@@ -1040,6 +1037,20 @@ static void tdx_kexec_finish(void)
        }
 }
 
+static __init void tdx_announce(void)
+{
+       struct tdx_module_args args = {};
+       u64 controls;
+
+       pr_info("Guest detected\n");
+
+       tdcall(TDG_VP_INFO, &args);
+       tdx_dump_attributes(args.rdx);
+
+       tdg_vm_rd(TDCS_TD_CTLS, &controls);
+       tdx_dump_td_ctls(controls);
+}
+
 void __init tdx_early_init(void)
 {
        u64 cc_mask;
@@ -1109,5 +1120,5 @@ void __init tdx_early_init(void)
         */
        x86_cpuinit.parallel_bringup = false;
 
-       pr_info("Guest detected\n");
+       tdx_announce();
 }
index a878c7e8347be5705647241708a80a65b8e14ffc..fcbbef484a78e52c762bb2f55bbce7a80b02a55d 100644 (file)
 #define TDG_VM_RD                      7
 #define TDG_VM_WR                      8
 
+/* TDX attributes */
+#define TDX_ATTR_DEBUG_BIT             0
+#define TDX_ATTR_DEBUG                 BIT_ULL(TDX_ATTR_DEBUG_BIT)
+#define TDX_ATTR_HGS_PLUS_PROF_BIT     4
+#define TDX_ATTR_HGS_PLUS_PROF         BIT_ULL(TDX_ATTR_HGS_PLUS_PROF_BIT)
+#define TDX_ATTR_PERF_PROF_BIT         5
+#define TDX_ATTR_PERF_PROF             BIT_ULL(TDX_ATTR_PERF_PROF_BIT)
+#define TDX_ATTR_PMT_PROF_BIT          6
+#define TDX_ATTR_PMT_PROF              BIT_ULL(TDX_ATTR_PMT_PROF_BIT)
+#define TDX_ATTR_ICSSD_BIT             16
+#define TDX_ATTR_ICSSD                 BIT_ULL(TDX_ATTR_ICSSD_BIT)
+#define TDX_ATTR_LASS_BIT              27
+#define TDX_ATTR_LASS                  BIT_ULL(TDX_ATTR_LASS_BIT)
+#define TDX_ATTR_SEPT_VE_DISABLE_BIT   28
+#define TDX_ATTR_SEPT_VE_DISABLE       BIT_ULL(TDX_ATTR_SEPT_VE_DISABLE_BIT)
+#define TDX_ATTR_MIGRTABLE_BIT         29
+#define TDX_ATTR_MIGRTABLE             BIT_ULL(TDX_ATTR_MIGRTABLE_BIT)
+#define TDX_ATTR_PKS_BIT               30
+#define TDX_ATTR_PKS                   BIT_ULL(TDX_ATTR_PKS_BIT)
+#define TDX_ATTR_KL_BIT                        31
+#define TDX_ATTR_KL                    BIT_ULL(TDX_ATTR_KL_BIT)
+#define TDX_ATTR_TPA_BIT               62
+#define TDX_ATTR_TPA                   BIT_ULL(TDX_ATTR_TPA_BIT)
+#define TDX_ATTR_PERFMON_BIT           63
+#define TDX_ATTR_PERFMON               BIT_ULL(TDX_ATTR_PERFMON_BIT)
+
 /* TDX TD-Scope Metadata. To be used by TDG.VM.WR and TDG.VM.RD */
 #define TDCS_CONFIG_FLAGS              0x1110000300000016
 #define TDCS_TD_CTLS                   0x1110000300000017
 #define TDCS_CONFIG_FLEXIBLE_PENDING_VE        BIT_ULL(1)
 
 /* TDCS_TD_CTLS bits */
-#define TD_CTLS_PENDING_VE_DISABLE     BIT_ULL(0)
-#define TD_CTLS_ENUM_TOPOLOGY          BIT_ULL(1)
-#define TD_CTLS_REDUCE_VE              BIT_ULL(3)
+#define TD_CTLS_PENDING_VE_DISABLE_BIT 0
+#define TD_CTLS_PENDING_VE_DISABLE     BIT_ULL(TD_CTLS_PENDING_VE_DISABLE_BIT)
+#define TD_CTLS_ENUM_TOPOLOGY_BIT      1
+#define TD_CTLS_ENUM_TOPOLOGY          BIT_ULL(TD_CTLS_ENUM_TOPOLOGY_BIT)
+#define TD_CTLS_VIRT_CPUID2_BIT                2
+#define TD_CTLS_VIRT_CPUID2            BIT_ULL(TD_CTLS_VIRT_CPUID2_BIT)
+#define TD_CTLS_REDUCE_VE_BIT          3
+#define TD_CTLS_REDUCE_VE              BIT_ULL(TD_CTLS_REDUCE_VE_BIT)
+#define TD_CTLS_LOCK_BIT               63
+#define TD_CTLS_LOCK                   BIT_ULL(TD_CTLS_LOCK_BIT)
 
 /* TDX hypercall Leaf IDs */
 #define TDVMCALL_MAP_GPA               0x10001
index eba178996d8459b2ead1800e83157346f9c50c04..b4b16dafd55edebe43d92e8496d7987627bf92e4 100644 (file)
@@ -66,6 +66,9 @@ int tdx_mcall_get_report0(u8 *reportdata, u8 *tdreport);
 
 u64 tdx_hcall_get_quote(u8 *buf, size_t size);
 
+void __init tdx_dump_attributes(u64 td_attr);
+void __init tdx_dump_td_ctls(u64 td_ctls);
+
 #else
 
 static inline void tdx_early_init(void) { };