[RFC PATCH v5 088/104] KVM: TDX: Add TDG.VP.VMCALL accessors to access guest vcpu registers

isaku.yamahata@intel.com posted 104 patches 3 years, 9 months ago
There is a newer version of this series
[RFC PATCH v5 088/104] KVM: TDX: Add TDG.VP.VMCALL accessors to access guest vcpu registers
Posted by isaku.yamahata@intel.com 3 years, 9 months ago
From: Isaku Yamahata <isaku.yamahata@intel.com>

TDX defines ABI for the TDX guest to call hypercall with TDG.VP.VMCALL API.
To get hypercall arguments and to set return values, add accessors to guest
vcpu registers.

Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
---
 arch/x86/kvm/vmx/tdx.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index dc83414cb72a..8695836ce796 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -88,6 +88,41 @@ static __always_inline unsigned long tdexit_intr_info(struct kvm_vcpu *vcpu)
 	return kvm_r9_read(vcpu);
 }
 
+#define BUILD_TDVMCALL_ACCESSORS(param, gpr)					\
+static __always_inline								\
+unsigned long tdvmcall_##param##_read(struct kvm_vcpu *vcpu)			\
+{										\
+	return kvm_##gpr##_read(vcpu);						\
+}										\
+static __always_inline void tdvmcall_##param##_write(struct kvm_vcpu *vcpu,	\
+						     unsigned long val)		\
+{										\
+	kvm_##gpr##_write(vcpu, val);						\
+}
+BUILD_TDVMCALL_ACCESSORS(p1, r12);
+BUILD_TDVMCALL_ACCESSORS(p2, r13);
+BUILD_TDVMCALL_ACCESSORS(p3, r14);
+BUILD_TDVMCALL_ACCESSORS(p4, r15);
+
+static __always_inline unsigned long tdvmcall_exit_type(struct kvm_vcpu *vcpu)
+{
+	return kvm_r10_read(vcpu);
+}
+static __always_inline unsigned long tdvmcall_exit_reason(struct kvm_vcpu *vcpu)
+{
+	return kvm_r11_read(vcpu);
+}
+static __always_inline void tdvmcall_set_return_code(struct kvm_vcpu *vcpu,
+						     long val)
+{
+	kvm_r10_write(vcpu, val);
+}
+static __always_inline void tdvmcall_set_return_val(struct kvm_vcpu *vcpu,
+						    unsigned long val)
+{
+	kvm_r11_write(vcpu, val);
+}
+
 static inline bool is_td_vcpu_created(struct vcpu_tdx *tdx)
 {
 	return tdx->tdvpr.added;
-- 
2.25.1
Re: [RFC PATCH v5 088/104] KVM: TDX: Add TDG.VP.VMCALL accessors to access guest vcpu registers
Posted by Paolo Bonzini 3 years, 8 months ago
On 3/4/22 20:49, isaku.yamahata@intel.com wrote:
> From: Isaku Yamahata <isaku.yamahata@intel.com>
> 
> TDX defines ABI for the TDX guest to call hypercall with TDG.VP.VMCALL API.
> To get hypercall arguments and to set return values, add accessors to guest
> vcpu registers.
> 
> Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
> ---
>   arch/x86/kvm/vmx/tdx.c | 35 +++++++++++++++++++++++++++++++++++
>   1 file changed, 35 insertions(+)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

> diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
> index dc83414cb72a..8695836ce796 100644
> --- a/arch/x86/kvm/vmx/tdx.c
> +++ b/arch/x86/kvm/vmx/tdx.c
> @@ -88,6 +88,41 @@ static __always_inline unsigned long tdexit_intr_info(struct kvm_vcpu *vcpu)
>   	return kvm_r9_read(vcpu);
>   }
>   
> +#define BUILD_TDVMCALL_ACCESSORS(param, gpr)					\
> +static __always_inline								\
> +unsigned long tdvmcall_##param##_read(struct kvm_vcpu *vcpu)			\
> +{										\
> +	return kvm_##gpr##_read(vcpu);						\
> +}										\
> +static __always_inline void tdvmcall_##param##_write(struct kvm_vcpu *vcpu,	\
> +						     unsigned long val)		\
> +{										\
> +	kvm_##gpr##_write(vcpu, val);						\
> +}
> +BUILD_TDVMCALL_ACCESSORS(p1, r12);
> +BUILD_TDVMCALL_ACCESSORS(p2, r13);
> +BUILD_TDVMCALL_ACCESSORS(p3, r14);
> +BUILD_TDVMCALL_ACCESSORS(p4, r15);
> +
> +static __always_inline unsigned long tdvmcall_exit_type(struct kvm_vcpu *vcpu)
> +{
> +	return kvm_r10_read(vcpu);
> +}
> +static __always_inline unsigned long tdvmcall_exit_reason(struct kvm_vcpu *vcpu)
> +{
> +	return kvm_r11_read(vcpu);
> +}
> +static __always_inline void tdvmcall_set_return_code(struct kvm_vcpu *vcpu,
> +						     long val)
> +{
> +	kvm_r10_write(vcpu, val);
> +}
> +static __always_inline void tdvmcall_set_return_val(struct kvm_vcpu *vcpu,
> +						    unsigned long val)
> +{
> +	kvm_r11_write(vcpu, val);
> +}
> +
>   static inline bool is_td_vcpu_created(struct vcpu_tdx *tdx)
>   {
>   	return tdx->tdvpr.added;
Re: [RFC PATCH v5 088/104] KVM: TDX: Add TDG.VP.VMCALL accessors to access guest vcpu registers
Posted by Kai Huang 3 years, 8 months ago
On Fri, 2022-03-04 at 11:49 -0800, isaku.yamahata@intel.com wrote:
> From: Isaku Yamahata <isaku.yamahata@intel.com>
> 
> TDX defines ABI for the TDX guest to call hypercall with TDG.VP.VMCALL API.
> To get hypercall arguments and to set return values, add accessors to guest
> vcpu registers.
> 
> Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
> ---
>  arch/x86/kvm/vmx/tdx.c | 35 +++++++++++++++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
> 
> diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
> index dc83414cb72a..8695836ce796 100644
> --- a/arch/x86/kvm/vmx/tdx.c
> +++ b/arch/x86/kvm/vmx/tdx.c
> @@ -88,6 +88,41 @@ static __always_inline unsigned long tdexit_intr_info(struct kvm_vcpu *vcpu)
>  	return kvm_r9_read(vcpu);
>  }
>  
> +#define BUILD_TDVMCALL_ACCESSORS(param, gpr)					\
> +static __always_inline								\
> +unsigned long tdvmcall_##param##_read(struct kvm_vcpu *vcpu)			\
> +{										\
> +	return kvm_##gpr##_read(vcpu);						\
> +}										\
> +static __always_inline void tdvmcall_##param##_write(struct kvm_vcpu *vcpu,	\
> +						     unsigned long val)		\
> +{										\
> +	kvm_##gpr##_write(vcpu, val);						\
> +}
> +BUILD_TDVMCALL_ACCESSORS(p1, r12);
> +BUILD_TDVMCALL_ACCESSORS(p2, r13);
> +BUILD_TDVMCALL_ACCESSORS(p3, r14);
> +BUILD_TDVMCALL_ACCESSORS(p4, r15);

Are they needed? Do those helpers provide more information than just using
kvm_{reg}_read/write()?

> +
> +static __always_inline unsigned long tdvmcall_exit_type(struct kvm_vcpu *vcpu)
> +{
> +	return kvm_r10_read(vcpu);
> +}
> +static __always_inline unsigned long tdvmcall_exit_reason(struct kvm_vcpu *vcpu)
> +{
> +	return kvm_r11_read(vcpu);
> +}
> +static __always_inline void tdvmcall_set_return_code(struct kvm_vcpu *vcpu,
> +						     long val)
> +{
> +	kvm_r10_write(vcpu, val);
> +}
> +static __always_inline void tdvmcall_set_return_val(struct kvm_vcpu *vcpu,
> +						    unsigned long val)
> +{
> +	kvm_r11_write(vcpu, val);
> +}
> +
>  static inline bool is_td_vcpu_created(struct vcpu_tdx *tdx)
>  {
>  	return tdx->tdvpr.added;