Skip to content

Commit 081385d

Browse files
yamahatabonzini
authored andcommitted
KVM: TDX: Handle TDX PV rdmsr/wrmsr hypercall
Morph PV RDMSR/WRMSR hypercall to EXIT_REASON_MSR_{READ,WRITE} and wire up KVM backend functions. For complete_emulated_msr() callback, instead of injecting #GP on error, implement tdx_complete_emulated_msr() to set return code on error. Also set return value on MSR read according to the values from kvm x86 registers. Suggested-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com> Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Message-ID: <20250227012021.1778144-10-binbin.wu@linux.intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent dd50294 commit 081385d

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

arch/x86/kvm/vmx/main.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,14 @@ static void vt_msr_filter_changed(struct kvm_vcpu *vcpu)
235235
vmx_msr_filter_changed(vcpu);
236236
}
237237

238+
static int vt_complete_emulated_msr(struct kvm_vcpu *vcpu, int err)
239+
{
240+
if (is_td_vcpu(vcpu))
241+
return tdx_complete_emulated_msr(vcpu, err);
242+
243+
return kvm_complete_insn_gp(vcpu, err);
244+
}
245+
238246
#ifdef CONFIG_KVM_SMM
239247
static int vt_smi_allowed(struct kvm_vcpu *vcpu, bool for_injection)
240248
{
@@ -686,7 +694,7 @@ struct kvm_x86_ops vt_x86_ops __initdata = {
686694
.migrate_timers = vmx_migrate_timers,
687695

688696
.msr_filter_changed = vt_msr_filter_changed,
689-
.complete_emulated_msr = kvm_complete_insn_gp,
697+
.complete_emulated_msr = vt_complete_emulated_msr,
690698

691699
.vcpu_deliver_sipi_vector = kvm_vcpu_deliver_sipi_vector,
692700

arch/x86/kvm/vmx/tdx.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,8 @@ static __always_inline u32 tdcall_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
877877
case EXIT_REASON_CPUID:
878878
case EXIT_REASON_HLT:
879879
case EXIT_REASON_IO_INSTRUCTION:
880+
case EXIT_REASON_MSR_READ:
881+
case EXIT_REASON_MSR_WRITE:
880882
return tdvmcall_leaf(vcpu);
881883
case EXIT_REASON_EPT_VIOLATION:
882884
return EXIT_REASON_EPT_MISCONFIG;
@@ -1906,6 +1908,20 @@ static int tdx_handle_ept_violation(struct kvm_vcpu *vcpu)
19061908
return ret;
19071909
}
19081910

1911+
int tdx_complete_emulated_msr(struct kvm_vcpu *vcpu, int err)
1912+
{
1913+
if (err) {
1914+
tdvmcall_set_return_code(vcpu, TDVMCALL_STATUS_INVALID_OPERAND);
1915+
return 1;
1916+
}
1917+
1918+
if (vmx_get_exit_reason(vcpu).basic == EXIT_REASON_MSR_READ)
1919+
tdvmcall_set_return_val(vcpu, kvm_read_edx_eax(vcpu));
1920+
1921+
return 1;
1922+
}
1923+
1924+
19091925
int tdx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t fastpath)
19101926
{
19111927
struct vcpu_tdx *tdx = to_tdx(vcpu);
@@ -1971,6 +1987,14 @@ int tdx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t fastpath)
19711987
return tdx_emulate_vmcall(vcpu);
19721988
case EXIT_REASON_IO_INSTRUCTION:
19731989
return tdx_emulate_io(vcpu);
1990+
case EXIT_REASON_MSR_READ:
1991+
kvm_rcx_write(vcpu, tdx->vp_enter_args.r12);
1992+
return kvm_emulate_rdmsr(vcpu);
1993+
case EXIT_REASON_MSR_WRITE:
1994+
kvm_rcx_write(vcpu, tdx->vp_enter_args.r12);
1995+
kvm_rax_write(vcpu, tdx->vp_enter_args.r13 & -1u);
1996+
kvm_rdx_write(vcpu, tdx->vp_enter_args.r13 >> 32);
1997+
return kvm_emulate_wrmsr(vcpu);
19741998
case EXIT_REASON_EPT_MISCONFIG:
19751999
return tdx_emulate_mmio(vcpu);
19762000
case EXIT_REASON_EPT_VIOLATION:

arch/x86/kvm/vmx/tdx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ static __always_inline void td_##lclass##_clearbit##bits(struct vcpu_tdx *tdx, \
173173

174174

175175
bool tdx_interrupt_allowed(struct kvm_vcpu *vcpu);
176+
int tdx_complete_emulated_msr(struct kvm_vcpu *vcpu, int err);
176177

177178
TDX_BUILD_TDVPS_ACCESSORS(16, VMCS, vmcs);
178179
TDX_BUILD_TDVPS_ACCESSORS(32, VMCS, vmcs);
@@ -196,6 +197,7 @@ struct vcpu_tdx {
196197
};
197198

198199
static inline bool tdx_interrupt_allowed(struct kvm_vcpu *vcpu) { return false; }
200+
static inline int tdx_complete_emulated_msr(struct kvm_vcpu *vcpu, int err) { return 0; }
199201

200202
#endif
201203

0 commit comments

Comments
 (0)