Skip to content

Commit 81bf912

Browse files
yamahatabonzini
authored andcommitted
KVM: TDX: Implement TDX vcpu enter/exit path
Implement callbacks to enter/exit a TDX VCPU by calling tdh_vp_enter(). Ensure the TDX VCPU is in a correct state to run. Do not pass arguments from/to vcpu->arch.regs[] unconditionally. Instead, marshall state to/from the appropriate x86 registers only when needed, i.e., to handle some TDVMCALL sub-leaves following KVM's ABI to leverage the existing code. Signed-off-by: Isaku Yamahata <[email protected]> Signed-off-by: Adrian Hunter <[email protected]> Message-ID: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 7172c75 commit 81bf912

File tree

4 files changed

+90
-2
lines changed

4 files changed

+90
-2
lines changed

arch/x86/kvm/vmx/main.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,22 @@ static void vt_update_cpu_dirty_logging(struct kvm_vcpu *vcpu)
145145
vmx_update_cpu_dirty_logging(vcpu);
146146
}
147147

148+
static int vt_vcpu_pre_run(struct kvm_vcpu *vcpu)
149+
{
150+
if (is_td_vcpu(vcpu))
151+
return tdx_vcpu_pre_run(vcpu);
152+
153+
return vmx_vcpu_pre_run(vcpu);
154+
}
155+
156+
static fastpath_t vt_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit)
157+
{
158+
if (is_td_vcpu(vcpu))
159+
return tdx_vcpu_run(vcpu, force_immediate_exit);
160+
161+
return vmx_vcpu_run(vcpu, force_immediate_exit);
162+
}
163+
148164
static void vt_flush_tlb_all(struct kvm_vcpu *vcpu)
149165
{
150166
if (is_td_vcpu(vcpu)) {
@@ -285,8 +301,8 @@ struct kvm_x86_ops vt_x86_ops __initdata = {
285301
.flush_tlb_gva = vt_flush_tlb_gva,
286302
.flush_tlb_guest = vt_flush_tlb_guest,
287303

288-
.vcpu_pre_run = vmx_vcpu_pre_run,
289-
.vcpu_run = vmx_vcpu_run,
304+
.vcpu_pre_run = vt_vcpu_pre_run,
305+
.vcpu_run = vt_vcpu_run,
290306
.handle_exit = vmx_handle_exit,
291307
.skip_emulated_instruction = vmx_skip_emulated_instruction,
292308
.update_emulated_instruction = vmx_update_emulated_instruction,

arch/x86/kvm/vmx/tdx.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include "vmx.h"
1313
#include "mmu/spte.h"
1414
#include "common.h"
15+
#include <trace/events/kvm.h>
16+
#include "trace.h"
1517

1618
#pragma GCC poison to_vmx
1719

@@ -660,6 +662,66 @@ void tdx_vcpu_free(struct kvm_vcpu *vcpu)
660662
tdx->state = VCPU_TD_STATE_UNINITIALIZED;
661663
}
662664

665+
int tdx_vcpu_pre_run(struct kvm_vcpu *vcpu)
666+
{
667+
if (unlikely(to_tdx(vcpu)->state != VCPU_TD_STATE_INITIALIZED ||
668+
to_kvm_tdx(vcpu->kvm)->state != TD_STATE_RUNNABLE))
669+
return -EINVAL;
670+
671+
return 1;
672+
}
673+
674+
static noinstr void tdx_vcpu_enter_exit(struct kvm_vcpu *vcpu)
675+
{
676+
struct vcpu_tdx *tdx = to_tdx(vcpu);
677+
678+
guest_state_enter_irqoff();
679+
680+
tdx->vp_enter_ret = tdh_vp_enter(&tdx->vp, &tdx->vp_enter_args);
681+
682+
guest_state_exit_irqoff();
683+
}
684+
685+
#define TDX_REGS_AVAIL_SET (BIT_ULL(VCPU_EXREG_EXIT_INFO_1) | \
686+
BIT_ULL(VCPU_EXREG_EXIT_INFO_2) | \
687+
BIT_ULL(VCPU_REGS_RAX) | \
688+
BIT_ULL(VCPU_REGS_RBX) | \
689+
BIT_ULL(VCPU_REGS_RCX) | \
690+
BIT_ULL(VCPU_REGS_RDX) | \
691+
BIT_ULL(VCPU_REGS_RBP) | \
692+
BIT_ULL(VCPU_REGS_RSI) | \
693+
BIT_ULL(VCPU_REGS_RDI) | \
694+
BIT_ULL(VCPU_REGS_R8) | \
695+
BIT_ULL(VCPU_REGS_R9) | \
696+
BIT_ULL(VCPU_REGS_R10) | \
697+
BIT_ULL(VCPU_REGS_R11) | \
698+
BIT_ULL(VCPU_REGS_R12) | \
699+
BIT_ULL(VCPU_REGS_R13) | \
700+
BIT_ULL(VCPU_REGS_R14) | \
701+
BIT_ULL(VCPU_REGS_R15))
702+
703+
fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit)
704+
{
705+
/*
706+
* force_immediate_exit requires vCPU entering for events injection with
707+
* an immediately exit followed. But The TDX module doesn't guarantee
708+
* entry, it's already possible for KVM to _think_ it completely entry
709+
* to the guest without actually having done so.
710+
* Since KVM never needs to force an immediate exit for TDX, and can't
711+
* do direct injection, just warn on force_immediate_exit.
712+
*/
713+
WARN_ON_ONCE(force_immediate_exit);
714+
715+
trace_kvm_entry(vcpu, force_immediate_exit);
716+
717+
tdx_vcpu_enter_exit(vcpu);
718+
719+
vcpu->arch.regs_avail &= TDX_REGS_AVAIL_SET;
720+
721+
trace_kvm_exit(vcpu, KVM_ISA_VMX);
722+
723+
return EXIT_FASTPATH_NONE;
724+
}
663725

664726
void tdx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int pgd_level)
665727
{

arch/x86/kvm/vmx/tdx.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,14 @@ enum vcpu_tdx_state {
4848
struct vcpu_tdx {
4949
struct kvm_vcpu vcpu;
5050
struct vcpu_vt vt;
51+
struct tdx_module_args vp_enter_args;
5152

5253
struct tdx_vp vp;
5354

5455
struct list_head cpu_list;
5556

57+
u64 vp_enter_ret;
58+
5659
enum vcpu_tdx_state state;
5760
};
5861

arch/x86/kvm/vmx/x86_ops.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ int tdx_vm_ioctl(struct kvm *kvm, void __user *argp);
131131
int tdx_vcpu_create(struct kvm_vcpu *vcpu);
132132
void tdx_vcpu_free(struct kvm_vcpu *vcpu);
133133
void tdx_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
134+
int tdx_vcpu_pre_run(struct kvm_vcpu *vcpu);
135+
fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit);
134136

135137
int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp);
136138

@@ -157,6 +159,11 @@ static inline int tdx_vm_ioctl(struct kvm *kvm, void __user *argp) { return -EOP
157159
static inline int tdx_vcpu_create(struct kvm_vcpu *vcpu) { return -EOPNOTSUPP; }
158160
static inline void tdx_vcpu_free(struct kvm_vcpu *vcpu) {}
159161
static inline void tdx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) {}
162+
static inline int tdx_vcpu_pre_run(struct kvm_vcpu *vcpu) { return -EOPNOTSUPP; }
163+
static inline fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit)
164+
{
165+
return EXIT_FASTPATH_NONE;
166+
}
160167

161168
static inline int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp) { return -EOPNOTSUPP; }
162169

0 commit comments

Comments
 (0)