Skip to content

Commit c42856a

Browse files
yamahatabonzini
authored andcommitted
KVM: TDX: Add a place holder for handler of TDX hypercalls (TDG.VP.VMCALL)
Add a place holder and related helper functions for preparation of TDG.VP.VMCALL handling. The TDX module specification defines TDG.VP.VMCALL API (TDVMCALL for short) for the guest TD to call hypercall to VMM. When the guest TD issues a TDVMCALL, the guest TD exits to VMM with a new exit reason. The arguments from the guest TD and returned values from the VMM are passed in the guest registers. The guest RCX register indicates which registers are used. Define helper functions to access those registers. A new VMX exit reason TDCALL is added to indicate the exit is due to TDVMCALL from the guest TD. Define the TDCALL exit reason and add a place holder to handle such exit. Some leafs of TDCALL will be morphed to another VMX exit reason instead of EXIT_REASON_TDCALL, add a helper tdcall_to_vmx_exit_reason() as a place holder to do the conversion. Suggested-by: Sean Christopherson <seanjc@google.com> Co-developed-by: Xiaoyao Li <xiaoyao.li@intel.com> Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com> Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com> Co-developed-by: Binbin Wu <binbin.wu@linux.intel.com> Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com> Reviewed-by: Chao Gao <chao.gao@intel.com> Message-ID: <20250222014225.897298-5-binbin.wu@linux.intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 095b71a commit c42856a

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

arch/x86/include/uapi/asm/vmx.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
#define EXIT_REASON_TPAUSE 68
9393
#define EXIT_REASON_BUS_LOCK 74
9494
#define EXIT_REASON_NOTIFY 75
95+
#define EXIT_REASON_TDCALL 77
9596

9697
#define VMX_EXIT_REASONS \
9798
{ EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, \
@@ -155,7 +156,8 @@
155156
{ EXIT_REASON_UMWAIT, "UMWAIT" }, \
156157
{ EXIT_REASON_TPAUSE, "TPAUSE" }, \
157158
{ EXIT_REASON_BUS_LOCK, "BUS_LOCK" }, \
158-
{ EXIT_REASON_NOTIFY, "NOTIFY" }
159+
{ EXIT_REASON_NOTIFY, "NOTIFY" }, \
160+
{ EXIT_REASON_TDCALL, "TDCALL" }
159161

160162
#define VMX_EXIT_REASON_FLAGS \
161163
{ VMX_EXIT_REASONS_FAILED_VMENTRY, "FAILED_VMENTRY" }

arch/x86/kvm/vmx/tdx.c

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,28 @@ static bool tdx_operand_busy(u64 err)
222222
*/
223223
static DEFINE_PER_CPU(struct list_head, associated_tdvcpus);
224224

225+
static __always_inline unsigned long tdvmcall_exit_type(struct kvm_vcpu *vcpu)
226+
{
227+
return to_tdx(vcpu)->vp_enter_args.r10;
228+
}
229+
230+
static __always_inline unsigned long tdvmcall_leaf(struct kvm_vcpu *vcpu)
231+
{
232+
return to_tdx(vcpu)->vp_enter_args.r11;
233+
}
234+
235+
static __always_inline void tdvmcall_set_return_code(struct kvm_vcpu *vcpu,
236+
long val)
237+
{
238+
to_tdx(vcpu)->vp_enter_args.r10 = val;
239+
}
240+
241+
static __always_inline void tdvmcall_set_return_val(struct kvm_vcpu *vcpu,
242+
unsigned long val)
243+
{
244+
to_tdx(vcpu)->vp_enter_args.r11 = val;
245+
}
246+
225247
static inline void tdx_hkid_free(struct kvm_tdx *kvm_tdx)
226248
{
227249
tdx_guest_keyid_free(kvm_tdx->hkid);
@@ -783,9 +805,20 @@ int tdx_vcpu_pre_run(struct kvm_vcpu *vcpu)
783805
return 1;
784806
}
785807

808+
static __always_inline u32 tdcall_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
809+
{
810+
switch (tdvmcall_leaf(vcpu)) {
811+
default:
812+
break;
813+
}
814+
815+
return EXIT_REASON_TDCALL;
816+
}
817+
786818
static __always_inline u32 tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
787819
{
788820
struct vcpu_tdx *tdx = to_tdx(vcpu);
821+
u32 exit_reason;
789822

790823
switch (tdx->vp_enter_ret & TDX_SEAMCALL_STATUS_MASK) {
791824
case TDX_SUCCESS:
@@ -798,7 +831,19 @@ static __always_inline u32 tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
798831
return -1u;
799832
}
800833

801-
return tdx->vp_enter_ret;
834+
exit_reason = tdx->vp_enter_ret;
835+
836+
switch (exit_reason) {
837+
case EXIT_REASON_TDCALL:
838+
if (tdvmcall_exit_type(vcpu))
839+
return EXIT_REASON_VMCALL;
840+
841+
return tdcall_to_vmx_exit_reason(vcpu);
842+
default:
843+
break;
844+
}
845+
846+
return exit_reason;
802847
}
803848

804849
static noinstr void tdx_vcpu_enter_exit(struct kvm_vcpu *vcpu)
@@ -933,6 +978,17 @@ fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit)
933978
return tdx_exit_handlers_fastpath(vcpu);
934979
}
935980

981+
static int handle_tdvmcall(struct kvm_vcpu *vcpu)
982+
{
983+
switch (tdvmcall_leaf(vcpu)) {
984+
default:
985+
break;
986+
}
987+
988+
tdvmcall_set_return_code(vcpu, TDVMCALL_STATUS_INVALID_OPERAND);
989+
return 1;
990+
}
991+
936992
void tdx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int pgd_level)
937993
{
938994
u64 shared_bit = (pgd_level == 5) ? TDX_SHARED_BIT_PWL_5 :
@@ -1291,6 +1347,8 @@ int tdx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t fastpath)
12911347
vcpu->run->exit_reason = KVM_EXIT_SHUTDOWN;
12921348
vcpu->mmio_needed = 0;
12931349
return 0;
1350+
case EXIT_REASON_TDCALL:
1351+
return handle_tdvmcall(vcpu);
12941352
default:
12951353
break;
12961354
}

0 commit comments

Comments
 (0)