Set bits 31:16 to 0 instead of all-1s for KVM's synthesized Exit Reason. KVM is going to support Bus Lock VM exit for TDX, after which bit 26 of the Exit Reason becomes meaningful and indicates that a bus lock happened. The existing synthesized Exit Reason, -1u, will cause a false positive in that case. Change the synthesized Exit Reason from -1u to U16_MAX, so that bits 31:16 are set to 0. This also avoids the potential issues when other bits in 31:16 become valid in the future. As a bonus, the check for synthesized Exit Reason in tdx_failed_vmentry() becomes unnecessary. Drop it. Cc: stable@vger.kernel.org Signed-off-by: Xiaoyao Li --- Note, the checking of (*reason != TDX_INVALID_EXIT_REASON) in tdx_get_exit_info() can cause a false-positive when the real exit reason is EPT_MISCONFIG. This issue is orthogonal to enabling Bus Lock VM exit and it's not urgent since EPT_MISCONFIIG is not supposed to happen unless current KVM code is buggy. We leave the fix for this issue to the future. Note, #2, the checking of tdx_failed_vmentry() seems to miss the case where a real EPT_MISCONFIG happens with failed_vmentry being set. First, in practice, EPT_MISCONFIG cannot happen with failed_vmentry being set. Second, even if it can, this is an pre-existing issue and the next patch can address it. Changes in v3: - split from the patch 2 in v2. - define a MARCO for the synthesized invalid Exit Reason. --- arch/x86/kvm/vmx/tdx.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 7338ac0af693..df23db9430f0 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -921,6 +921,9 @@ static __always_inline u32 tdcall_to_vmx_exit_reason(struct kvm_vcpu *vcpu) return EXIT_REASON_TDCALL; } +/* Synthesized invalid Exit Reason */ +#define TDX_INVALID_EXIT_REASON U16_MAX + static __always_inline u32 tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu) { struct vcpu_tdx *tdx = to_tdx(vcpu); @@ -934,7 +937,12 @@ static __always_inline u32 tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu) case TDX_NON_RECOVERABLE_TD_WRONG_APIC_MODE: break; default: - return -1u; + /* + * Return the synthesized invalid Exit Reason, as the TDX + * module never attempted to run the vCPU, i.e. the Exit + * Reason is undefined, but this is NOT a failed VM-Enter + */ + return TDX_INVALID_EXIT_REASON; } exit_reason = tdx->vp_enter_ret; @@ -950,7 +958,7 @@ static __always_inline u32 tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu) * Defer KVM_BUG_ON() until tdx_handle_exit() because this is in * non-instrumentable code with interrupts disabled. */ - return -1u; + return TDX_INVALID_EXIT_REASON; default: break; } @@ -981,8 +989,7 @@ static noinstr void tdx_vcpu_enter_exit(struct kvm_vcpu *vcpu) static bool tdx_failed_vmentry(struct kvm_vcpu *vcpu) { - return vmx_get_exit_reason(vcpu).failed_vmentry && - vmx_get_exit_reason(vcpu).full != -1u; + return vmx_get_exit_reason(vcpu).failed_vmentry; } static fastpath_t tdx_exit_handlers_fastpath(struct kvm_vcpu *vcpu) @@ -2144,7 +2151,7 @@ void tdx_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason, struct vcpu_tdx *tdx = to_tdx(vcpu); *reason = tdx->vt.exit_reason.full; - if (*reason != -1u) { + if (*reason != TDX_INVALID_EXIT_REASON) { *info1 = vmx_get_exit_qual(vcpu); *info2 = tdx->ext_exit_qualification; *intr_info = vmx_get_intr_info(vcpu); -- 2.43.0