On Wed, Jul 12, 2023 at 08:55:23PM +1200, Kai Huang <kai.huang@xxxxxxxxx> wrote: > Intel Trust Domain Extensions (TDX) protects guest VMs from malicious > host and certain physical attacks. A CPU-attested software module > called 'the TDX module' runs inside a new isolated memory range as a > trusted hypervisor to manage and run protected VMs. > > TDX introduces a new CPU mode: Secure Arbitration Mode (SEAM). This > mode runs only the TDX module itself or other code to load the TDX > module. > > The host kernel communicates with SEAM software via a new SEAMCALL > instruction. This is conceptually similar to a guest->host hypercall, > except it is made from the host to SEAM software instead. The TDX > module establishes a new SEAMCALL ABI which allows the host to > initialize the module and to manage VMs. > > The SEAMCALL ABI is very similar to the TDCALL ABI and leverages much > TDCALL infrastructure. Wire up basic functions to make SEAMCALLs for > the basic TDX support: __seamcall(), __seamcall_ret() and > __seamcall_saved_ret() which is for TDH.VP.ENTER leaf function. Hi. __seamcall_saved_ret() uses struct tdx_module_arg as input and output. For KVM TDH.VP.ENTER case, those arguments are already in unsigned long kvm_vcpu_arch::regs[]. It's silly to move those values twice. From kvm_vcpu_arch::regs to tdx_module_args. From tdx_module_args to real registers. If TDH.VP.ENTER is the only user of __seamcall_saved_ret(), can we make it to take unsigned long kvm_vcpu_argh::regs[NR_VCPU_REGS]? Maybe I can make the change with TDX KVM patch series. Thanks, > To start to support TDX, create a new arch/x86/virt/vmx/tdx/tdx.c for > TDX host kernel support. Add a new Kconfig option CONFIG_INTEL_TDX_HOST > to opt-in TDX host kernel support (to distinguish with TDX guest kernel > support). So far only KVM uses TDX. Make the new config option depend > on KVM_INTEL. > > Signed-off-by: Kai Huang <kai.huang@xxxxxxxxx> > --- > arch/x86/Kconfig | 12 +++++++ > arch/x86/Makefile | 2 ++ > arch/x86/include/asm/tdx.h | 7 +++++ > arch/x86/virt/Makefile | 2 ++ > arch/x86/virt/vmx/Makefile | 2 ++ > arch/x86/virt/vmx/tdx/Makefile | 2 ++ > arch/x86/virt/vmx/tdx/seamcall.S | 54 ++++++++++++++++++++++++++++++++ > 7 files changed, 81 insertions(+) > create mode 100644 arch/x86/virt/Makefile > create mode 100644 arch/x86/virt/vmx/Makefile > create mode 100644 arch/x86/virt/vmx/tdx/Makefile > create mode 100644 arch/x86/virt/vmx/tdx/seamcall.S > > diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig > index 53bab123a8ee..191587f75810 100644 > --- a/arch/x86/Kconfig > +++ b/arch/x86/Kconfig > @@ -1952,6 +1952,18 @@ config X86_SGX > > If unsure, say N. > > +config INTEL_TDX_HOST > + bool "Intel Trust Domain Extensions (TDX) host support" > + depends on CPU_SUP_INTEL > + depends on X86_64 > + depends on KVM_INTEL > + help > + Intel Trust Domain Extensions (TDX) protects guest VMs from malicious > + host and certain physical attacks. This option enables necessary TDX > + support in the host kernel to run confidential VMs. > + > + If unsure, say N. > + > config EFI > bool "EFI runtime service support" > depends on ACPI > diff --git a/arch/x86/Makefile b/arch/x86/Makefile > index b39975977c03..ec0e71d8fa30 100644 > --- a/arch/x86/Makefile > +++ b/arch/x86/Makefile > @@ -252,6 +252,8 @@ archheaders: > > libs-y += arch/x86/lib/ > > +core-y += arch/x86/virt/ > + > # drivers-y are linked after core-y > drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/ > drivers-$(CONFIG_PCI) += arch/x86/pci/ > diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h > index 9b0ad0176e58..a82e5249d079 100644 > --- a/arch/x86/include/asm/tdx.h > +++ b/arch/x86/include/asm/tdx.h > @@ -74,5 +74,12 @@ static inline long tdx_kvm_hypercall(unsigned int nr, unsigned long p1, > return -ENODEV; > } > #endif /* CONFIG_INTEL_TDX_GUEST && CONFIG_KVM_GUEST */ > + > +#ifdef CONFIG_INTEL_TDX_HOST > +u64 __seamcall(u64 fn, struct tdx_module_args *args); > +u64 __seamcall_ret(u64 fn, struct tdx_module_args *args); > +u64 __seamcall_saved_ret(u64 fn, struct tdx_module_args *args); > +#endif /* CONFIG_INTEL_TDX_HOST */ > + > #endif /* !__ASSEMBLY__ */ > #endif /* _ASM_X86_TDX_H */ > diff --git a/arch/x86/virt/Makefile b/arch/x86/virt/Makefile > new file mode 100644 > index 000000000000..1e36502cd738 > --- /dev/null > +++ b/arch/x86/virt/Makefile > @@ -0,0 +1,2 @@ > +# SPDX-License-Identifier: GPL-2.0-only > +obj-y += vmx/ > diff --git a/arch/x86/virt/vmx/Makefile b/arch/x86/virt/vmx/Makefile > new file mode 100644 > index 000000000000..feebda21d793 > --- /dev/null > +++ b/arch/x86/virt/vmx/Makefile > @@ -0,0 +1,2 @@ > +# SPDX-License-Identifier: GPL-2.0-only > +obj-$(CONFIG_INTEL_TDX_HOST) += tdx/ > diff --git a/arch/x86/virt/vmx/tdx/Makefile b/arch/x86/virt/vmx/tdx/Makefile > new file mode 100644 > index 000000000000..46ef8f73aebb > --- /dev/null > +++ b/arch/x86/virt/vmx/tdx/Makefile > @@ -0,0 +1,2 @@ > +# SPDX-License-Identifier: GPL-2.0-only > +obj-y += seamcall.o > diff --git a/arch/x86/virt/vmx/tdx/seamcall.S b/arch/x86/virt/vmx/tdx/seamcall.S > new file mode 100644 > index 000000000000..650a40843afe > --- /dev/null > +++ b/arch/x86/virt/vmx/tdx/seamcall.S > @@ -0,0 +1,54 @@ > +/* 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 > + * (the P-SEAMLDR or the TDX module). > + * > + * __seamcall() function ABI: > + * > + * @fn (RDI) - SEAMCALL Leaf number, moved to RAX > + * @args (RSI) - struct tdx_module_args for input > + * > + * Return (via RAX) TDX_SEAMCALL_VMFAILINVALID if the SEAMCALL itself > + * fails, or the completion status of the SEAMCALL leaf function. > + */ > +SYM_FUNC_START(__seamcall) > + TDX_MODULE_CALL host=1 ret=0 saved=0 > +SYM_FUNC_END(__seamcall) > + > +/* > + * __seamcall_ret() - Host-side interface functions to SEAM software > + * (the P-SEAMLDR or the TDX module). > + * > + * __seamcall_ret() function ABI: > + * > + * @fn (RDI) - SEAMCALL Leaf number, moved to RAX > + * @args (RSI) - struct tdx_module_args for input and output > + * > + * Return (via RAX) TDX_SEAMCALL_VMFAILINVALID if the SEAMCALL itself > + * fails, or the completion status of the SEAMCALL leaf function. > + */ > +SYM_FUNC_START(__seamcall_ret) > + TDX_MODULE_CALL host=1 ret=1 saved=0 > +SYM_FUNC_END(__seamcall_ret) > + > +/* > + * __seamcall_saved_ret() - Host-side interface functions to SEAM software > + * (the P-SEAMLDR or the TDX module) with extra > + * "callee-saved" registers as input/output. > + * > + * __seamcall_saved_ret() function ABI: > + * > + * @fn (RDI) - SEAMCALL Leaf number, moved to RAX > + * @args (RSI) - struct tdx_module_args for input and output > + * > + * Return (via RAX) TDX_SEAMCALL_VMFAILINVALID if the SEAMCALL itself > + * fails, or the completion status of the SEAMCALL leaf function. > + */ > +SYM_FUNC_START(__seamcall_saved_ret) > + TDX_MODULE_CALL host=1 ret=1 saved=0 > +SYM_FUNC_END(__seamcall_saved_ret) > -- > 2.41.0 > -- Isaku Yamahata <isaku.yamahata@xxxxxxxxx>