Now that handle_changed_spte() can handles all mirror SPTE updates, move the TDP MMU's assertion that it doesn't replace a shadow-present mirror SPTE with another shadow-present SPTE into TDX, in the form of a TODO that calls out that KVM needs to add support for splitting/demoting hugepage. Drop the "!is_leaf" condition so that an unexpected/unsupported update to a shadow-present S-EPT triggers a KVM_BUG_ON(), versus being silently ignored (well, silent until it causes explosions in the future). Signed-off-by: Sean Christopherson --- arch/x86/kvm/mmu/tdp_mmu.c | 9 +-------- arch/x86/kvm/vmx/tdx.c | 5 ++++- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index d49aecba18d8..3b0da898824a 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -572,7 +572,7 @@ static void handle_changed_spte(struct kvm *kvm, int as_id, tdp_ptep_t sptep, if (was_present && !was_leaf && (is_leaf || !is_present || WARN_ON_ONCE(pfn_changed))) handle_removed_pt(kvm, spte_to_child_pt(old_spte, level), shared); - else if (was_leaf && is_mirror_sptep(sptep) && !is_leaf) + else if (was_leaf && is_mirror_sptep(sptep)) KVM_BUG_ON(kvm_x86_call(set_external_spte)(kvm, gfn, old_spte, new_spte, level), kvm); } @@ -704,13 +704,6 @@ static u64 tdp_mmu_set_spte(struct kvm *kvm, int as_id, tdp_ptep_t sptep, handle_changed_spte(kvm, as_id, sptep, gfn, old_spte, new_spte, level, false); - /* - * Users that do non-atomic setting of PTEs don't operate on mirror - * roots. Bug the VM as this path doesn't propagate such writes to the - * external page tables. - */ - KVM_BUG_ON(is_mirror_sptep(sptep) && is_shadow_present_pte(new_spte), kvm); - return old_spte; } diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index e6ac4aca8114..59b7ba36d3d9 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -1850,7 +1850,10 @@ static int tdx_sept_remove_private_spte(struct kvm *kvm, gfn_t gfn, static int tdx_sept_set_private_spte(struct kvm *kvm, gfn_t gfn, u64 old_spte, u64 new_spte, enum pg_level level) { - if (is_shadow_present_pte(old_spte)) + /* TODO: Support replacing huge SPTE with non-leaf SPTE. (a.k.a. demotion). */ + if (KVM_BUG_ON(is_shadow_present_pte(old_spte) && is_shadow_present_pte(new_spte), kvm)) + return -EIO; + else if (is_shadow_present_pte(old_spte)) return tdx_sept_remove_private_spte(kvm, gfn, old_spte, level); if (KVM_BUG_ON(!is_shadow_present_pte(new_spte), kvm)) -- 2.53.0.rc1.217.geba53bf80e-goog