[PATCH v2 07/15] KVM: x86/tdp_mmu: Morph !is_frozen_spte() check into a KVM_MMU_WARN_ON()

From: Yan Zhao

Date: Sat May 09 2026 - 04:38:31 EST


From: Rick Edgecombe <rick.p.edgecombe@xxxxxxxxx>

Remove the conditional logic for handling the setting of mirror page table
to frozen in __tdp_mmu_set_spte_atomic() and add it as a warning for both
mirror and direct cases.

The mirror page table needs to propagate PTE changes to the external page
table. This presents a problem for atomic updates which can't update both
page tables at once. So a special value, FROZEN_SPTE, is used as a
temporary state during these updates to prevent concurrent operations on
the PTE. If the TDP MMU tried to install FROZEN_SPTE as a long-term value,
it would confuse these updates.

On the other hand, it would also confuse other threads if FROZEN_SPTE is
installed as a long-term value for direct page tables (e.g., causing
another thread working on atomic zap to wait for a !FROZEN_SPTE value
endlessly).

Therefore, add the warning for installing FROZEN_SPTE as a long-term value
in __tdp_mmu_set_spte_atomic() without differentiating whether it's a
mirror or direct page table.

Suggested-by: Sean Christopherson <seanjc@xxxxxxxxxx>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@xxxxxxxxx>
Signed-off-by: Yan Zhao <yan.y.zhao@xxxxxxxxx>
---
MMU_refactors v2:
- Updated the comment for "KVM_MMU_WARN_ON(is_frozen_spte(new_spte))".
(Yan)
- Explained why the warning also applies to direct page tables. (Yan)
---
arch/x86/kvm/mmu/tdp_mmu.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 401bb49a91ee..345fdb0a89fb 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -609,7 +609,10 @@ static inline int __must_check __tdp_mmu_set_spte_atomic(struct kvm *kvm,
*/
WARN_ON_ONCE(iter->yielded || is_frozen_spte(iter->old_spte));

- if (is_mirror_sptep(iter->sptep) && !is_frozen_spte(new_spte)) {
+ /* Should not set FROZEN_SPTE as a long-term value. */
+ KVM_MMU_WARN_ON(is_frozen_spte(new_spte));
+
+ if (is_mirror_sptep(iter->sptep)) {
int ret;

/*
--
2.43.2