x86/tdx: Introduce wrappers to read and write TD metadata
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Mon, 4 Nov 2024 10:38:00 +0000 (12:38 +0200)
committerDave Hansen <dave.hansen@linux.intel.com>
Thu, 7 Nov 2024 18:26:16 +0000 (10:26 -0800)
The TDG_VM_WR TDCALL is used to ask the TDX module to change some
TD-specific VM configuration. There is currently only one user in the
kernel of this TDCALL leaf.  More will be added shortly.

Refactor to make way for more users of TDG_VM_WR who will need to modify
other TD configuration values.

Add a wrapper for the TDG_VM_RD TDCALL that requests TD-specific
metadata from the TDX module. There are currently no users for
TDG_VM_RD. Mark it as __maybe_unused until the first user appears.

This is preparation for enumeration and enabling optional TD features.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Kai Huang <kai.huang@intel.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Link: https://lore.kernel.org/all/20241104103803.195705-2-kirill.shutemov%40linux.intel.com
arch/x86/coco/tdx/tdx.c
arch/x86/include/asm/shared/tdx.h

index 327c45c..c74bb9e 100644 (file)
@@ -78,6 +78,32 @@ static inline void tdcall(u64 fn, struct tdx_module_args *args)
                panic("TDCALL %lld failed (Buggy TDX module!)\n", fn);
 }
 
+/* Read TD-scoped metadata */
+static inline u64 __maybe_unused tdg_vm_rd(u64 field, u64 *value)
+{
+       struct tdx_module_args args = {
+               .rdx = field,
+       };
+       u64 ret;
+
+       ret = __tdcall_ret(TDG_VM_RD, &args);
+       *value = args.r8;
+
+       return ret;
+}
+
+/* Write TD-scoped metadata */
+static inline u64 tdg_vm_wr(u64 field, u64 value, u64 mask)
+{
+       struct tdx_module_args args = {
+               .rdx = field,
+               .r8 = value,
+               .r9 = mask,
+       };
+
+       return __tdcall(TDG_VM_WR, &args);
+}
+
 /**
  * tdx_mcall_get_report0() - Wrapper to get TDREPORT0 (a.k.a. TDREPORT
  *                           subtype 0) using TDG.MR.REPORT TDCALL.
@@ -929,10 +955,6 @@ static void tdx_kexec_finish(void)
 
 void __init tdx_early_init(void)
 {
-       struct tdx_module_args args = {
-               .rdx = TDCS_NOTIFY_ENABLES,
-               .r9 = -1ULL,
-       };
        u64 cc_mask;
        u32 eax, sig[3];
 
@@ -951,7 +973,7 @@ void __init tdx_early_init(void)
        cc_set_mask(cc_mask);
 
        /* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */
-       tdcall(TDG_VM_WR, &args);
+       tdg_vm_wr(TDCS_NOTIFY_ENABLES, 0, -1ULL);
 
        /*
         * All bits above GPA width are reserved and kernel treats shared bit
index fdfd415..7e12cfa 100644 (file)
@@ -16,6 +16,7 @@
 #define TDG_VP_VEINFO_GET              3
 #define TDG_MR_REPORT                  4
 #define TDG_MEM_PAGE_ACCEPT            6
+#define TDG_VM_RD                      7
 #define TDG_VM_WR                      8
 
 /* TDCS fields. To be used by TDG.VM.WR and TDG.VM.RD module calls */