Skip to content

Commit 87e3f45

Browse files
Sean Christophersonbonzini
authored andcommitted
KVM: TDX: Add load_mmu_pgd method for TDX
TDX uses two EPT pointers, one for the private half of the GPA space and one for the shared half. The private half uses the normal EPT_POINTER vmcs field, which is managed in a special way by the TDX module. For TDX, KVM is not allowed to operate on it directly. The shared half uses a new SHARED_EPT_POINTER field and will be managed by the conventional MMU management operations that operate directly on the EPT root. This means for TDX the .load_mmu_pgd() operation will need to know to use the SHARED_EPT_POINTER field instead of the normal one. Add a new wrapper in x86 ops for load_mmu_pgd() that either directs the write to the existing vmx implementation or a TDX one. tdx_load_mmu_pgd() is so much simpler than vmx_load_mmu_pgd() since for the TDX mode of operation, EPT will always be used and KVM does not need to be involved in virtualization of CR3 behavior. So tdx_load_mmu_pgd() can simply write to SHARED_EPT_POINTER. Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> Co-developed-by: Isaku Yamahata <isaku.yamahata@intel.com> Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com> Co-developed-by: Rick Edgecombe <rick.p.edgecombe@intel.com> Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com> Co-developed-by: Yan Zhao <yan.y.zhao@intel.com> Signed-off-by: Yan Zhao <yan.y.zhao@intel.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Message-ID: <20241112073601.22084-1-yan.y.zhao@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent fe1e6d4 commit 87e3f45

File tree

4 files changed

+32
-1
lines changed

4 files changed

+32
-1
lines changed

arch/x86/include/asm/vmx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ enum vmcs_field {
256256
TSC_MULTIPLIER_HIGH = 0x00002033,
257257
TERTIARY_VM_EXEC_CONTROL = 0x00002034,
258258
TERTIARY_VM_EXEC_CONTROL_HIGH = 0x00002035,
259+
SHARED_EPT_POINTER = 0x0000203C,
259260
PID_POINTER_TABLE = 0x00002042,
260261
PID_POINTER_TABLE_HIGH = 0x00002043,
261262
GUEST_PHYSICAL_ADDRESS = 0x00002400,

arch/x86/kvm/vmx/main.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,17 @@ static void vt_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
9898
vmx_vcpu_reset(vcpu, init_event);
9999
}
100100

101+
static void vt_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa,
102+
int pgd_level)
103+
{
104+
if (is_td_vcpu(vcpu)) {
105+
tdx_load_mmu_pgd(vcpu, root_hpa, pgd_level);
106+
return;
107+
}
108+
109+
vmx_load_mmu_pgd(vcpu, root_hpa, pgd_level);
110+
}
111+
101112
static int vt_mem_enc_ioctl(struct kvm *kvm, void __user *argp)
102113
{
103114
if (!is_td(kvm))
@@ -231,7 +242,7 @@ struct kvm_x86_ops vt_x86_ops __initdata = {
231242
.write_tsc_offset = vmx_write_tsc_offset,
232243
.write_tsc_multiplier = vmx_write_tsc_multiplier,
233244

234-
.load_mmu_pgd = vmx_load_mmu_pgd,
245+
.load_mmu_pgd = vt_load_mmu_pgd,
235246

236247
.check_intercept = vmx_check_intercept,
237248
.handle_exit_irqoff = vmx_handle_exit_irqoff,

arch/x86/kvm/vmx/tdx.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
bool enable_tdx __ro_after_init;
3333
module_param_named(tdx, enable_tdx, bool, 0444);
3434

35+
#define TDX_SHARED_BIT_PWL_5 gpa_to_gfn(BIT_ULL(51))
36+
#define TDX_SHARED_BIT_PWL_4 gpa_to_gfn(BIT_ULL(47))
37+
3538
static enum cpuhp_state tdx_cpuhp_state;
3639

3740
static const struct tdx_sys_info *tdx_sysinfo;
@@ -495,6 +498,18 @@ void tdx_vcpu_free(struct kvm_vcpu *vcpu)
495498
tdx->state = VCPU_TD_STATE_UNINITIALIZED;
496499
}
497500

501+
502+
void tdx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int pgd_level)
503+
{
504+
u64 shared_bit = (pgd_level == 5) ? TDX_SHARED_BIT_PWL_5 :
505+
TDX_SHARED_BIT_PWL_4;
506+
507+
if (KVM_BUG_ON(shared_bit != kvm_gfn_direct_bits(vcpu->kvm), vcpu->kvm))
508+
return;
509+
510+
td_vmcs_write64(to_tdx(vcpu), SHARED_EPT_POINTER, root_hpa);
511+
}
512+
498513
static int tdx_get_capabilities(struct kvm_tdx_cmd *cmd)
499514
{
500515
const struct tdx_sys_info_td_conf *td_conf = &tdx_sysinfo->td_conf;

arch/x86/kvm/vmx/x86_ops.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ int tdx_vcpu_create(struct kvm_vcpu *vcpu);
131131
void tdx_vcpu_free(struct kvm_vcpu *vcpu);
132132

133133
int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp);
134+
135+
void tdx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level);
134136
#else
135137
static inline int tdx_vm_init(struct kvm *kvm) { return -EOPNOTSUPP; }
136138
static inline void tdx_mmu_release_hkid(struct kvm *kvm) {}
@@ -141,6 +143,8 @@ static inline int tdx_vcpu_create(struct kvm_vcpu *vcpu) { return -EOPNOTSUPP; }
141143
static inline void tdx_vcpu_free(struct kvm_vcpu *vcpu) {}
142144

143145
static inline int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp) { return -EOPNOTSUPP; }
146+
147+
static inline void tdx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level) {}
144148
#endif
145149

146150
#endif /* __KVM_X86_VMX_X86_OPS_H */

0 commit comments

Comments
 (0)