Skip to content

Commit 2bc2694

Browse files
committed
KVM: TDX: Do not retry locally when the retry is caused by invalid memslot
Avoid local retries within the TDX EPT violation handler if a retry is triggered by faulting in an invalid memslot, indicating that the memslot is undergoing a removal process. Faulting in a GPA from an invalid memslot will never succeed, and holding SRCU prevents memslot deletion from succeeding, i.e. retrying when the memslot is being actively deleted will lead to (breakable) deadlock. Opportunistically export kvm_vcpu_gfn_to_memslot() to allow for a per-vCPU lookup (which, strictly speaking, is unnecessary since TDX doesn't support SMM, but aligns the TDX code with the MMU code). Fixes: b0327bb ("KVM: TDX: Retry locally in TDX EPT violation handler on RET_PF_RETRY") Reported-by: Reinette Chatre <[email protected]> Closes: https://lore.kernel.org/all/[email protected] [Yan: Wrote patch log, comment, fixed a minor error, function export] Signed-off-by: Yan Zhao <[email protected]> Link: https://lore.kernel.org/r/[email protected] [sean: massage changelog, relocate and tweak comment] Signed-off-by: Sean Christopherson <[email protected]>
1 parent 3ccbf6f commit 2bc2694

File tree

2 files changed

+12
-0
lines changed

2 files changed

+12
-0
lines changed

arch/x86/kvm/vmx/tdx.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,6 +2002,8 @@ static int tdx_handle_ept_violation(struct kvm_vcpu *vcpu)
20022002
* handle retries locally in their EPT violation handlers.
20032003
*/
20042004
while (1) {
2005+
struct kvm_memory_slot *slot;
2006+
20052007
ret = __vmx_handle_ept_violation(vcpu, gpa, exit_qual);
20062008

20072009
if (ret != RET_PF_RETRY || !local_retry)
@@ -2015,6 +2017,15 @@ static int tdx_handle_ept_violation(struct kvm_vcpu *vcpu)
20152017
break;
20162018
}
20172019

2020+
/*
2021+
* Bail if the memslot is invalid, i.e. is being deleted, as
2022+
* faulting in will never succeed and this task needs to drop
2023+
* SRCU in order to let memslot deletion complete.
2024+
*/
2025+
slot = kvm_vcpu_gfn_to_memslot(vcpu, gpa_to_gfn(gpa));
2026+
if (slot && slot->flags & KVM_MEMSLOT_INVALID)
2027+
break;
2028+
20182029
cond_resched();
20192030
}
20202031
return ret;

virt/kvm/kvm_main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2661,6 +2661,7 @@ struct kvm_memory_slot *kvm_vcpu_gfn_to_memslot(struct kvm_vcpu *vcpu, gfn_t gfn
26612661

26622662
return NULL;
26632663
}
2664+
EXPORT_SYMBOL_GPL(kvm_vcpu_gfn_to_memslot);
26642665

26652666
bool kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn)
26662667
{

0 commit comments

Comments
 (0)