Re: [RFC PATCH v2 14/23] KVM: TDX: Split and inhibit huge mappings if a VMExit carries level info

From: Yan Zhao

Date: Thu Nov 13 2025 - 20:45:00 EST


On Tue, Nov 11, 2025 at 06:55:45PM +0800, Huang, Kai wrote:
> On Thu, 2025-08-07 at 17:44 +0800, Yan Zhao wrote:
> > @@ -2044,6 +2091,9 @@ static int tdx_handle_ept_violation(struct kvm_vcpu *vcpu)
> >   */
> >   exit_qual = EPT_VIOLATION_ACC_WRITE;
> >  
> > + if (tdx_check_accept_level(vcpu, gpa_to_gfn(gpa)))
> > + return RET_PF_RETRY;
> > +
>
> I don't think you should return RET_PF_RETRY here.
>
> This is still at very early stage of EPT violation. The caller of
> tdx_handle_ept_violation() is expecting either 0, 1, or negative error code.
Hmm, strictly speaking, the caller of the EPT violation handler is expecting
0, >0, or negative error code.

vcpu_run
|->r = vcpu_enter_guest(vcpu);
| |->r = kvm_x86_call(handle_exit)(vcpu, exit_fastpath);
| | return r;
| if (r <= 0)
| break;

handle_ept_violation
|->return __vmx_handle_ept_violation(vcpu, gpa, exit_qualification);

tdx_handle_ept_violation
|->ret = __vmx_handle_ept_violation(vcpu, gpa, exit_qual);
| return ret;

The current VMX/TDX's EPT violation handlers returns RET_PF_* to the caller
since commit 7c5480386300 ("KVM: x86/mmu: Return RET_PF* instead of 1 in
kvm_mmu_page_fault") for the sake of zero-step mitigation.

This is no problem, because

enum {
RET_PF_CONTINUE = 0,
RET_PF_RETRY,
RET_PF_EMULATE,
RET_PF_WRITE_PROTECTED,
RET_PF_INVALID,
RET_PF_FIXED,
RET_PF_SPURIOUS,
};

/*
* Define RET_PF_CONTINUE as 0 to allow for
* - efficient machine code when checking for CONTINUE, e.g.
* "TEST %rax, %rax, JNZ", as all "stop!" values are non-zero,
* - kvm_mmu_do_page_fault() to return other RET_PF_* as a positive value.
*/
static_assert(RET_PF_CONTINUE == 0);