lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 18 Mar 2021 14:30:53 -0700
From:   Kuppuswamy Sathyanarayanan 
        <sathyanarayanan.kuppuswamy@...ux.intel.com>
To:     Peter Zijlstra <peterz@...radead.org>,
        Andy Lutomirski <luto@...nel.org>,
        Dave Hansen <dave.hansen@...el.com>
Cc:     Andi Kleen <ak@...ux.intel.com>,
        Kirill Shutemov <kirill.shutemov@...ux.intel.com>,
        Kuppuswamy Sathyanarayanan <knsathya@...nel.org>,
        Dan Williams <dan.j.williams@...el.com>,
        Raj Ashok <ashok.raj@...el.com>,
        Sean Christopherson <seanjc@...gle.com>,
        linux-kernel@...r.kernel.org,
        Kuppuswamy Sathyanarayanan 
        <sathyanarayanan.kuppuswamy@...ux.intel.com>
Subject: [PATCH v1 1/1] x86/tdx: Add tdcall() and tdvmcall() helper functions

Implement common helper functions to communicate with
the TDX Module and VMM (using TDCALL instruction).

tdvmcall() function can be used to request services
from VMM.

tdcall() function can be used to communicate with the
TDX Module.

Using common helper functions makes the code more readable
and less error prone compared to distributed and use case
specific inline assembly code. Only downside in using this
approach is, it adds a few extra instructions for every
TDCALL use case when compared to distributed checks. Although
it's a bit less efficient, it's worth it to make the code more
readable.

Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@...ux.intel.com>
---

Hi All,

As you have suggested, I have created common helper functions
for all tdcall() and tdvmcall() use cases. It uses inline
assembly and passes GPRs R8-15 and r[a-c]x registers to TDX
Module/VMM. Please take a look at it and let me know your
comments. If you agree with the design, I can re-submit the
patchset with changes related to using these new APIs. Please
let me know.

 arch/x86/include/asm/tdx.h | 27 ++++++++++++++++++++
 arch/x86/kernel/tdx.c      | 52 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+)

diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
index 0b9d571b1f95..311252a90cfb 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -3,8 +3,27 @@
 #ifndef _ASM_X86_TDX_H
 #define _ASM_X86_TDX_H
 
+#include <linux/types.h>
+
 #define TDX_CPUID_LEAF_ID	0x21
 
+#define TDVMCALL		0
+
+/* TDVMCALL R10 Input */
+#define TDVMCALL_STANDARD	0
+
+/*
+ * TDCALL instruction is newly added in TDX architecture,
+ * used by TD for requesting the host VMM to provide
+ * (untrusted) services. Supported in Binutils >= 2.36
+ */
+#define TDCALL	".byte 0x66,0x0f,0x01,0xcc"
+
+struct tdcall_regs {
+	u64 rax, rcx, rdx;
+	u64 r8, r9, r10, r11, r12, r13, r14, r15;
+};
+
 #ifdef CONFIG_INTEL_TDX_GUEST
 
 /* Common API to check TDX support in decompression and common kernel code. */
@@ -12,6 +31,10 @@ bool is_tdx_guest(void);
 
 void __init tdx_early_init(void);
 
+void tdcall(u64 leafid, struct tdcall_regs *regs);
+
+void tdvmcall(u64 subid, struct tdcall_regs *regs);
+
 #else // !CONFIG_INTEL_TDX_GUEST
 
 static inline bool is_tdx_guest(void)
@@ -21,6 +44,10 @@ static inline bool is_tdx_guest(void)
 
 static inline void tdx_early_init(void) { };
 
+static inline void tdcall(u64 leafid, struct tdcall_regs *regs) { };
+
+static inline void tdvmcall(u64 subid, struct tdcall_regs *regs) { };
+
 #endif /* CONFIG_INTEL_TDX_GUEST */
 
 #endif /* _ASM_X86_TDX_H */
diff --git a/arch/x86/kernel/tdx.c b/arch/x86/kernel/tdx.c
index e44e55d1e519..7ae1d25e272b 100644
--- a/arch/x86/kernel/tdx.c
+++ b/arch/x86/kernel/tdx.c
@@ -4,6 +4,58 @@
 #include <asm/tdx.h>
 #include <asm/cpufeature.h>
 
+void tdcall(u64 leafid, struct tdcall_regs *regs)
+{
+	asm volatile(
+			/* RAX = leafid (TDCALL LEAF ID) */
+			"  movq %0, %%rax;"
+			/* Move regs->r[*] data to regs r[a-c]x,  r8-r5 */
+			"  movq 8(%1), %%rcx;"
+			"  movq 16(%1), %%rdx;"
+			"  movq 24(%1), %%r8;"
+			"  movq 32(%1), %%r9;"
+			"  movq 40(%1), %%r10;"
+			"  movq 48(%1), %%r11;"
+			"  movq 56(%1), %%r12;"
+			"  movq 64(%1), %%r13;"
+			"  movq 72(%1), %%r14;"
+			"  movq 80(%1), %%r15;"
+			TDCALL ";"
+			/* Save TDCALL success/failure to regs->rax */
+			"  movq %%rax, (%1);"
+			/* Save rcx and rdx contents to regs->r[c-d]x */
+			"  movq %%rcx, 8(%1);"
+			"  movq %%rdx, 16(%1);"
+			/* Move content of registers R8-R15 regs->r[8-15] */
+			"  movq %%r8, 24(%1);"
+			"  movq %%r9, 32(%1);"
+			"  movq %%r10, 40(%1);"
+			"  movq %%r11, 48(%1);"
+			"  movq %%r12, 56(%1);"
+			"  movq %%r13, 64(%1);"
+			"  movq %%r14, 72(%1);"
+			"  movq %%r15, 80(%1);"
+
+		:
+		: "r" (leafid), "r" (regs)
+		: "memory", "rax", "rbx", "rcx", "rdx", "r8",
+		  "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+		);
+
+}
+
+void tdvmcall(u64 subid, struct tdcall_regs *regs)
+{
+	/* Expose GPRs R8-R15 to VMM */
+	regs->rcx = 0xff00;
+	/* R10 = 0 (standard TDVMCALL) */
+	regs->r10 = TDVMCALL_STANDARD;
+	/* Save subid to r11 register */
+	regs->r11 = subid;
+
+	tdcall(TDVMCALL, regs);
+}
+
 static inline bool cpuid_has_tdx_guest(void)
 {
 	u32 eax, signature[3];
-- 
2.25.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ