mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 10:33:41 +02:00
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>
This commit is contained in:
parent
fe1e6d483f
commit
87e3f45e80
|
|
@ -256,6 +256,7 @@ enum vmcs_field {
|
|||
TSC_MULTIPLIER_HIGH = 0x00002033,
|
||||
TERTIARY_VM_EXEC_CONTROL = 0x00002034,
|
||||
TERTIARY_VM_EXEC_CONTROL_HIGH = 0x00002035,
|
||||
SHARED_EPT_POINTER = 0x0000203C,
|
||||
PID_POINTER_TABLE = 0x00002042,
|
||||
PID_POINTER_TABLE_HIGH = 0x00002043,
|
||||
GUEST_PHYSICAL_ADDRESS = 0x00002400,
|
||||
|
|
|
|||
|
|
@ -98,6 +98,17 @@ static void vt_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
|
|||
vmx_vcpu_reset(vcpu, init_event);
|
||||
}
|
||||
|
||||
static void vt_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa,
|
||||
int pgd_level)
|
||||
{
|
||||
if (is_td_vcpu(vcpu)) {
|
||||
tdx_load_mmu_pgd(vcpu, root_hpa, pgd_level);
|
||||
return;
|
||||
}
|
||||
|
||||
vmx_load_mmu_pgd(vcpu, root_hpa, pgd_level);
|
||||
}
|
||||
|
||||
static int vt_mem_enc_ioctl(struct kvm *kvm, void __user *argp)
|
||||
{
|
||||
if (!is_td(kvm))
|
||||
|
|
@ -231,7 +242,7 @@ struct kvm_x86_ops vt_x86_ops __initdata = {
|
|||
.write_tsc_offset = vmx_write_tsc_offset,
|
||||
.write_tsc_multiplier = vmx_write_tsc_multiplier,
|
||||
|
||||
.load_mmu_pgd = vmx_load_mmu_pgd,
|
||||
.load_mmu_pgd = vt_load_mmu_pgd,
|
||||
|
||||
.check_intercept = vmx_check_intercept,
|
||||
.handle_exit_irqoff = vmx_handle_exit_irqoff,
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@
|
|||
bool enable_tdx __ro_after_init;
|
||||
module_param_named(tdx, enable_tdx, bool, 0444);
|
||||
|
||||
#define TDX_SHARED_BIT_PWL_5 gpa_to_gfn(BIT_ULL(51))
|
||||
#define TDX_SHARED_BIT_PWL_4 gpa_to_gfn(BIT_ULL(47))
|
||||
|
||||
static enum cpuhp_state tdx_cpuhp_state;
|
||||
|
||||
static const struct tdx_sys_info *tdx_sysinfo;
|
||||
|
|
@ -495,6 +498,18 @@ void tdx_vcpu_free(struct kvm_vcpu *vcpu)
|
|||
tdx->state = VCPU_TD_STATE_UNINITIALIZED;
|
||||
}
|
||||
|
||||
|
||||
void tdx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int pgd_level)
|
||||
{
|
||||
u64 shared_bit = (pgd_level == 5) ? TDX_SHARED_BIT_PWL_5 :
|
||||
TDX_SHARED_BIT_PWL_4;
|
||||
|
||||
if (KVM_BUG_ON(shared_bit != kvm_gfn_direct_bits(vcpu->kvm), vcpu->kvm))
|
||||
return;
|
||||
|
||||
td_vmcs_write64(to_tdx(vcpu), SHARED_EPT_POINTER, root_hpa);
|
||||
}
|
||||
|
||||
static int tdx_get_capabilities(struct kvm_tdx_cmd *cmd)
|
||||
{
|
||||
const struct tdx_sys_info_td_conf *td_conf = &tdx_sysinfo->td_conf;
|
||||
|
|
|
|||
|
|
@ -131,6 +131,8 @@ int tdx_vcpu_create(struct kvm_vcpu *vcpu);
|
|||
void tdx_vcpu_free(struct kvm_vcpu *vcpu);
|
||||
|
||||
int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp);
|
||||
|
||||
void tdx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level);
|
||||
#else
|
||||
static inline int tdx_vm_init(struct kvm *kvm) { return -EOPNOTSUPP; }
|
||||
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; }
|
|||
static inline void tdx_vcpu_free(struct kvm_vcpu *vcpu) {}
|
||||
|
||||
static inline int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp) { return -EOPNOTSUPP; }
|
||||
|
||||
static inline void tdx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level) {}
|
||||
#endif
|
||||
|
||||
#endif /* __KVM_X86_VMX_X86_OPS_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user