linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kai Huang <kai.huang@intel.com>
To: x86@kernel.org
Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
	dave.hansen@intel.com, luto@kernel.org, kvm@vger.kernel.org,
	pbonzini@redhat.com, seanjc@google.com, hpa@zytor.com,
	peterz@infradead.org, kirill.shutemov@linux.intel.com,
	sathyanarayanan.kuppuswamy@linux.intel.com, tony.luck@intel.com,
	ak@linux.intel.com, dan.j.williams@intel.com,
	chang.seok.bae@intel.com, keescook@chromium.org,
	hengqi.arch@bytedance.com, laijs@linux.alibaba.com,
	metze@samba.org, linux-kernel@vger.kernel.org,
	kai.huang@intel.com
Subject: [RFC PATCH 03/21] x86/virt/tdx: Implement the SEAMCALL base function
Date: Mon, 28 Feb 2022 15:12:51 +1300	[thread overview]
Message-ID: <67e0161abb0d0363b810d8539ac8aba139ca7403.1646007267.git.kai.huang@intel.com> (raw)
In-Reply-To: <cover.1646007267.git.kai.huang@intel.com>

Secure Arbitration Mode (SEAM) is an extension of VMX architecture.  It
defines a new VMX root operation (SEAM VMX root) and a new VMX non-root
operation (SEAM VMX non-root) which isolate from legacy VMX root and VMX
non-root mode.

A CPU-attested software module (called 'TDX module') runs in SEAM VMX
root to manage the protected VMs running in SEAM VMX non-root.  SEAM VMX
root is also used to host another CPU-attested software module (called
'P-SEAMLDR') to load and update the TDX module.

Host kernel transits to either P-SEAMLDR or TDX module via the new
SEAMCALL instruction.  SEAMCALLs are host-side interface functions
defined by P-SEAMLDR and TDX module around the new SEAMCALL instruction.
They are similar to a hypercall, except they are made by host kernel to
the SEAM software.

SEAMCALLs use an ABI different from the x86-64 system-v ABI.  Instead,
it shares the same ABI with the TDCALL.  %rax is used to carry both the
SEAMCALL leaf function number (input) and the completion status code
(output).  Additional GPRs (%rcx, %rdx, %r8->%r11) may be further used
as both input and output operands in individual leaf SEAMCALLs.

Implement a C function __seamcall() to do SEAMCALL using the assembly
macro used by __tdx_module_call() (the implementation of TDCALL).  The
only exception not covered here is TDENTER leaf function which takes
all GPRs and XMM0-XMM15 as both input and output.  The caller of TDENTER
should implement its own logic to call TDENTER directly instead of using
this function.

SEAMCALL instruction is essentially a VMExit from VMX root to SEAM VMX
root.  It fails with VMfailInvalid when the SEAM software is not loaded.
The C function __seamcall() returns TDX_SEAMCALL_VMFAILINVALID, which
doesn't conflict with any actual error code of SEAMCALLs, to uniquely
represent this case.

Signed-off-by: Kai Huang <kai.huang@intel.com>
---
 arch/x86/virt/vmx/Makefile   |  2 +-
 arch/x86/virt/vmx/seamcall.S | 53 ++++++++++++++++++++++++++++++++++++
 arch/x86/virt/vmx/tdx.h      | 11 ++++++++
 3 files changed, 65 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/virt/vmx/seamcall.S
 create mode 100644 arch/x86/virt/vmx/tdx.h

diff --git a/arch/x86/virt/vmx/Makefile b/arch/x86/virt/vmx/Makefile
index 1bd688684716..fd577619620e 100644
--- a/arch/x86/virt/vmx/Makefile
+++ b/arch/x86/virt/vmx/Makefile
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_INTEL_TDX_HOST)	+= tdx.o
+obj-$(CONFIG_INTEL_TDX_HOST)	+= tdx.o seamcall.o
diff --git a/arch/x86/virt/vmx/seamcall.S b/arch/x86/virt/vmx/seamcall.S
new file mode 100644
index 000000000000..65edec23b5f4
--- /dev/null
+++ b/arch/x86/virt/vmx/seamcall.S
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/linkage.h>
+#include <asm/frame.h>
+
+#include "../tdxcall.S"
+
+/*
+ * __seamcall()  - Host-side interface functions to SEAM software
+ *		   (P-SEAMLDR or TDX module)
+ *
+ * Transform function call register arguments into the SEAMCALL register
+ * ABI.  Return TDX_SEAMCALL_VMFAILINVALID (when SEAM software is not
+ * loaded or SEAMCALLs are made into P-SEAMLDR concurrently), or the
+ * completion status of the SEAMCALL.  Additional output operands are
+ * saved in @out (if it is provided by the user).
+ *
+ *-------------------------------------------------------------------------
+ * SEAMCALL ABI:
+ *-------------------------------------------------------------------------
+ * Input Registers:
+ *
+ * RAX                 - SEAMCALL Leaf number.
+ * RCX,RDX,R8-R9       - SEAMCALL Leaf specific input registers.
+ *
+ * Output Registers:
+ *
+ * RAX                 - SEAMCALL completion status code.
+ * RCX,RDX,R8-R11      - SEAMCALL Leaf specific output registers.
+ *
+ *-------------------------------------------------------------------------
+ *
+ * __seamcall() function ABI:
+ *
+ * @fn  (RDI)          - SEAMCALL Leaf number, moved to RAX
+ * @rcx (RSI)          - Input parameter 1, moved to RCX
+ * @rdx (RDX)          - Input parameter 2, moved to RDX
+ * @r8  (RCX)          - Input parameter 3, moved to R8
+ * @r9  (R8)           - Input parameter 4, moved to R9
+ *
+ * @out (R9)           - struct tdx_module_output pointer
+ *                       stored temporarily in R12 (not
+ *                       shared with the TDX module). It
+ *                       can be NULL.
+ *
+ * Return (via RAX) the completion status of the SEAMCALL, or
+ * TDX_SEAMCALL_VMFAILINVALID.
+ */
+SYM_FUNC_START(__seamcall)
+	FRAME_BEGIN
+	TDX_MODULE_CALL host=1
+	FRAME_END
+	ret
+SYM_FUNC_END(__seamcall)
diff --git a/arch/x86/virt/vmx/tdx.h b/arch/x86/virt/vmx/tdx.h
new file mode 100644
index 000000000000..9d5b6f554c20
--- /dev/null
+++ b/arch/x86/virt/vmx/tdx.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _X86_VIRT_TDX_H
+#define _X86_VIRT_TDX_H
+
+#include <linux/types.h>
+
+struct tdx_module_output;
+u64 __seamcall(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
+	       struct tdx_module_output *out);
+
+#endif
-- 
2.33.1


  parent reply	other threads:[~2022-02-28  2:14 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-28  2:12 [RFC PATCH 00/21] TDX host kernel support Kai Huang
2022-02-28  2:12 ` [RFC PATCH 01/21] x86/virt/tdx: Detect SEAM Kai Huang
2022-02-28  2:12 ` [RFC PATCH 02/21] x86/virt/tdx: Detect TDX private KeyIDs Kai Huang
2022-02-28  2:12 ` Kai Huang [this message]
2022-02-28  2:12 ` [RFC PATCH 04/21] x86/virt/tdx: Add skeleton for detecting and initializing TDX on demand Kai Huang
2022-02-28  2:12 ` [RFC PATCH 05/21] x86/virt/tdx: Detect P-SEAMLDR and TDX module Kai Huang
2022-02-28  2:12 ` [RFC PATCH 06/21] x86/virt/tdx: Shut down TDX module in case of error Kai Huang
2022-02-28  2:12 ` [RFC PATCH 07/21] x86/virt/tdx: Do TDX module global initialization Kai Huang
2022-02-28  2:12 ` [RFC PATCH 08/21] x86/virt/tdx: Do logical-cpu scope TDX module initialization Kai Huang
2022-02-28  2:12 ` [RFC PATCH 09/21] x86/virt/tdx: Get information about TDX module and convertible memory Kai Huang
2022-02-28  2:12 ` [RFC PATCH 10/21] x86/virt/tdx: Add placeholder to coveret all system RAM as TDX memory Kai Huang
2022-02-28  2:12 ` [RFC PATCH 11/21] x86/virt/tdx: Choose to use " Kai Huang
2022-02-28  2:13 ` [RFC PATCH 12/21] x86/virt/tdx: Create TDMRs to cover all system RAM Kai Huang
2022-02-28  2:13 ` [RFC PATCH 13/21] x86/virt/tdx: Allocate and set up PAMTs for TDMRs Kai Huang
2022-02-28  2:13 ` [RFC PATCH 14/21] x86/virt/tdx: Set up reserved areas for all TDMRs Kai Huang
2022-02-28  2:13 ` [RFC PATCH 15/21] x86/virt/tdx: Reserve TDX module global KeyID Kai Huang
2022-02-28  2:13 ` [RFC PATCH 16/21] x86/virt/tdx: Configure TDX module with TDMRs and " Kai Huang
2022-02-28  2:13 ` [RFC PATCH 17/21] x86/virt/tdx: Configure global KeyID on all packages Kai Huang
2022-02-28  2:13 ` [RFC PATCH 18/21] x86/virt/tdx: Initialize all TDMRs Kai Huang
2022-02-28  2:13 ` [RFC PATCH 19/21] x86: Flush cache of TDX private memory during kexec() Kai Huang
2022-02-28  2:13 ` [RFC PATCH 20/21] x86/virt/tdx: Add kernel command line to opt-in TDX host support Kai Huang
2022-02-28  2:13 ` [RFC PATCH 21/21] Documentation/x86: Add documentation for " Kai Huang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=67e0161abb0d0363b810d8539ac8aba139ca7403.1646007267.git.kai.huang@intel.com \
    --to=kai.huang@intel.com \
    --cc=ak@linux.intel.com \
    --cc=bp@alien8.de \
    --cc=chang.seok.bae@intel.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=hengqi.arch@bytedance.com \
    --cc=hpa@zytor.com \
    --cc=keescook@chromium.org \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=laijs@linux.alibaba.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=metze@samba.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=sathyanarayanan.kuppuswamy@linux.intel.com \
    --cc=seanjc@google.com \
    --cc=tglx@linutronix.de \
    --cc=tony.luck@intel.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).