RE: [PATCH v14 011/113] KVM: TDX: Add C wrapper functions for SEAMCALLs to the TDX module

From: Wang, Wei W
Date: Mon Jun 05 2023 - 11:20:41 EST


On Monday, May 29, 2023 12:19 PM, isaku.yamahata@xxxxxxxxx wrote:
> From: Isaku Yamahata <isaku.yamahata@xxxxxxxxx>
>
> A VMM interacts with the TDX module using a new instruction (SEAMCALL).
> For instance, a TDX VMM does not have full access to the VM control
> structure corresponding to VMX VMCS. Instead, a VMM induces the TDX
> module to act on behalf via SEAMCALLs.
>
> Export __seamcall and define C wrapper functions for SEAMCALLs for
> readability.
>
> Some SEAMCALL APIs donate host pages to TDX module or guest TD, and the
> donated pages are encrypted. Such SEAMCALLs flush cache lines (typically by
> movdir64b instruction), but some don't. Those that don't clear cache lines
> require the VMM to flush the cache lines to avoid cache line alias.
>
> Signed-off-by: Sean Christopherson <sean.j.christopherson@xxxxxxxxx>
> Signed-off-by: Isaku Yamahata <isaku.yamahata@xxxxxxxxx>
> ---
> arch/x86/include/asm/tdx.h | 4 +
> arch/x86/kvm/vmx/tdx_ops.h | 202
> +++++++++++++++++++++++++++++++
> arch/x86/virt/vmx/tdx/seamcall.S | 2 +
> arch/x86/virt/vmx/tdx/tdx.h | 3 -
> 4 files changed, 208 insertions(+), 3 deletions(-) create mode 100644
> arch/x86/kvm/vmx/tdx_ops.h
>
> diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index
> 112a5b9bd5cd..6c01ab572c1f 100644
> --- a/arch/x86/include/asm/tdx.h
> +++ b/arch/x86/include/asm/tdx.h
> @@ -104,10 +104,14 @@ static inline long tdx_kvm_hypercall(unsigned int
> nr, unsigned long p1, bool platform_tdx_enabled(void); int
> tdx_cpu_enable(void); int tdx_enable(void);
> +u64 __seamcall(u64 op, u64 rcx, u64 rdx, u64 r8, u64 r9,
> + struct tdx_module_output *out);
> #else /* !CONFIG_INTEL_TDX_HOST */
> static inline bool platform_tdx_enabled(void) { return false; } static inline int
> tdx_cpu_enable(void) { return -EINVAL; } static inline int tdx_enable(void)
> { return -EINVAL; }
> +static inline u64 __seamcall(u64 op, u64 rcx, u64 rdx, u64 r8, u64 r9,
> + struct tdx_module_output *out) { return
> TDX_SEAMCALL_UD; };
> #endif /* CONFIG_INTEL_TDX_HOST */
>
> #endif /* !__ASSEMBLY__ */
> diff --git a/arch/x86/kvm/vmx/tdx_ops.h b/arch/x86/kvm/vmx/tdx_ops.h
> new file mode 100644 index 000000000000..893cc6c25f3b
> --- /dev/null
> +++ b/arch/x86/kvm/vmx/tdx_ops.h
> @@ -0,0 +1,202 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* constants/data definitions for TDX SEAMCALLs */
> +
> +#ifndef __KVM_X86_TDX_OPS_H
> +#define __KVM_X86_TDX_OPS_H
> +
> +#include <linux/compiler.h>
> +
> +#include <asm/cacheflush.h>
> +#include <asm/asm.h>
> +#include <asm/kvm_host.h>
> +
> +#include "tdx_errno.h"
> +#include "tdx_arch.h"
> +#include "x86.h"
> +
> +static inline u64 kvm_seamcall(u64 op, u64 rcx, u64 rdx, u64 r8, u64 r9,
> + struct tdx_module_output *out) {
> + u64 ret;
> +
> + ret = __seamcall(op, rcx, rdx, r8, r9, out);
> + if (unlikely(ret == TDX_SEAMCALL_UD)) {
> + /*
> + * TDX requires VMXON or #UD. In the case of reboot or
> kexec,
> + * VMX is made off (VMXOFF) by kvm reboot notifier,
> + * kvm_reboot(), while TDs are still running. The callers
> check
> + * the returned error and complain. Suppress it by returning 0.
> + */

Curious how do the callers check the returned error when " Suppress
it by returning 0" here.


> + kvm_spurious_fault();
> + return 0;
> + }
> + return ret;
> +}