Message ID | 269a053607357eedd9a1e8ddf0e7240ae0c3985c.1647167475.git.kai.huang@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | TDX host kernel support | expand |
> From: Kai Huang <kai.huang@intel.com> > Sent: Sunday, March 13, 2022 6:50 PM > > 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. s/isolate/are isolated/ > > A CPU-attested software module (called the 'TDX module') runs in SEAM > VMX root to manage the crypto protected VMs running in SEAM VMX non- > root. > SEAM VMX root is also used to host another CPU-attested software module > (called the 'P-SEAMLDR') to load and update the TDX module. > > Host kernel transits to either the P-SEAMLDR or the TDX module via the > new SEAMCALL instruction. SEAMCALLs are host-side interface functions > defined by the P-SEAMLDR and the TDX module around the new SEAMCALL > instruction. They are similar to a hypercall, except they are made by "SEAMCALLs are ... functions ... around the new SEAMCALL instruction" This is confusing. Probably just: "SEAMCALL functions are defined and handled by the P-SEAMLDR and the TDX module" > host kernel to the SEAM software. > > SEAMCALLs use an ABI different from the x86-64 system-v ABI. Instead, > they share 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, and it can fail with VMfailInvalid, for instance, when the SEAM > software module 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. SEAMCALL is TDX specific, is it? If yes, there is no need to have both TDX and SEAMCALL in one macro, i.e. above can be SEAMCALL_VMFAILINVALID. Thanks Kevin
On Wed, 2022-03-23 at 16:35 +1300, Tian, Kevin wrote: > > From: Kai Huang <kai.huang@intel.com> > > Sent: Sunday, March 13, 2022 6:50 PM > > > > 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. > > s/isolate/are isolated/ OK thanks. > > > > > A CPU-attested software module (called the 'TDX module') runs in SEAM > > VMX root to manage the crypto protected VMs running in SEAM VMX non- > > root. > > SEAM VMX root is also used to host another CPU-attested software module > > (called the 'P-SEAMLDR') to load and update the TDX module. > > > > Host kernel transits to either the P-SEAMLDR or the TDX module via the > > new SEAMCALL instruction. SEAMCALLs are host-side interface functions > > defined by the P-SEAMLDR and the TDX module around the new SEAMCALL > > instruction. They are similar to a hypercall, except they are made by > > "SEAMCALLs are ... functions ... around the new SEAMCALL instruction" > > This is confusing. Probably just: May I ask why is it confusing? > > "SEAMCALL functions are defined and handled by the P-SEAMLDR and > the TDX module" > > > host kernel to the SEAM software. > > > > SEAMCALLs use an ABI different from the x86-64 system-v ABI. Instead, > > they share 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, and it can fail with VMfailInvalid, for instance, when the SEAM > > software module 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. > > SEAMCALL is TDX specific, is it? If yes, there is no need to have both > TDX and SEAMCALL in one macro, i.e. above can be SEAMCALL_VMFAILINVALID. This is defined in TDX guest series. I just use it. https://lore.kernel.org/lkml/20220324152415.grt6xvhblmd4uccu@black.fi.intel.com/T/#md0b1aa563bd003ab625de159612a0d07e3ded7cb
> From: Huang, Kai <kai.huang@intel.com> > Sent: Monday, March 28, 2022 9:42 AM > > > > > > > > > > A CPU-attested software module (called the 'TDX module') runs in SEAM > > > VMX root to manage the crypto protected VMs running in SEAM VMX > non- > > > root. > > > SEAM VMX root is also used to host another CPU-attested software > module > > > (called the 'P-SEAMLDR') to load and update the TDX module. > > > > > > Host kernel transits to either the P-SEAMLDR or the TDX module via the > > > new SEAMCALL instruction. SEAMCALLs are host-side interface functions > > > defined by the P-SEAMLDR and the TDX module around the new > SEAMCALL > > > instruction. They are similar to a hypercall, except they are made by > > > > "SEAMCALLs are ... functions ... around the new SEAMCALL instruction" > > > > This is confusing. Probably just: > > May I ask why is it confusing? SEAMCALL is an instruction. One of its arguments carries the function number.
On Mon, 2022-03-28 at 21:16 +1300, Tian, Kevin wrote: > > From: Huang, Kai <kai.huang@intel.com> > > Sent: Monday, March 28, 2022 9:42 AM > > > > > > > > > > > > > > > A CPU-attested software module (called the 'TDX module') runs in SEAM > > > > VMX root to manage the crypto protected VMs running in SEAM VMX > > non- > > > > root. > > > > SEAM VMX root is also used to host another CPU-attested software > > module > > > > (called the 'P-SEAMLDR') to load and update the TDX module. > > > > > > > > Host kernel transits to either the P-SEAMLDR or the TDX module via the > > > > new SEAMCALL instruction. SEAMCALLs are host-side interface functions > > > > defined by the P-SEAMLDR and the TDX module around the new > > SEAMCALL > > > > instruction. They are similar to a hypercall, except they are made by > > > > > > "SEAMCALLs are ... functions ... around the new SEAMCALL instruction" > > > > > > This is confusing. Probably just: > > > > May I ask why is it confusing? > > SEAMCALL is an instruction. One of its arguments carries the function > number. > To confirm, are you saying the word "SEAMCALLs" is confusing, and we should use "SEAMCALL leaf functions" instead?
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..f31a717c00e0 --- /dev/null +++ b/arch/x86/virt/vmx/seamcall.S @@ -0,0 +1,52 @@ +/* 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 module + * (the P-SEAMLDR or the TDX module) + * + * Transform function call register arguments into the SEAMCALL register + * ABI. Return TDX_SEAMCALL_VMFAILINVALID, or the completion status of + * the SEAMCALL. Additional output operands are saved in @out (if it is + * provided by caller). + * + *------------------------------------------------------------------------- + * 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 + * used by the P-SEAMLDR or 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
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 the 'TDX module') runs in SEAM VMX root to manage the crypto protected VMs running in SEAM VMX non-root. SEAM VMX root is also used to host another CPU-attested software module (called the 'P-SEAMLDR') to load and update the TDX module. Host kernel transits to either the P-SEAMLDR or the TDX module via the new SEAMCALL instruction. SEAMCALLs are host-side interface functions defined by the P-SEAMLDR and the 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, they share 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, and it can fail with VMfailInvalid, for instance, when the SEAM software module 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 | 52 ++++++++++++++++++++++++++++++++++++ arch/x86/virt/vmx/tdx.h | 11 ++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 arch/x86/virt/vmx/seamcall.S create mode 100644 arch/x86/virt/vmx/tdx.h