KVM: x86/mmu: Use kvm_ad_enabled() to determine if TDP MMU SPTEs need wrprot
authorVipin Sharma <vipinsh@google.com>
Tue, 21 Mar 2023 22:00:10 +0000 (15:00 -0700)
committerSean Christopherson <seanjc@google.com>
Tue, 4 Apr 2023 19:37:30 +0000 (12:37 -0700)
Use the constant-after-module-load kvm_ad_enabled() to check if SPTEs in
the TDP MMU need to be write-protected when clearing accessed/dirty status
instead of manually checking every SPTE.  The per-SPTE A/D enabling is
specific to nested EPT MMUs, i.e. when KVM is using EPT A/D bits but L1 is
not, and so cannot happen in the TDP MMU (which is non-nested only).

Keep the original code as sanity checks buried under MMU_WARN_ON().
MMU_WARN_ON() is more or less useless at the moment, but there are plans
to change that.

Link: https://lore.kernel.org/all/Yz4Qi7cn7TWTWQjj@google.com
Signed-off-by: Vipin Sharma <vipinsh@google.com>
[sean: split to separate patch, apply to dirty path, write changelog]
Link: https://lore.kernel.org/r/20230321220021.2119033-3-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/mmu/tdp_mmu.c

index 7c25dbf..5a56426 100644 (file)
@@ -1621,7 +1621,10 @@ retry:
                if (!is_shadow_present_pte(iter.old_spte))
                        continue;
 
-               if (spte_ad_need_write_protect(iter.old_spte)) {
+               MMU_WARN_ON(kvm_ad_enabled() &&
+                           spte_ad_need_write_protect(iter.old_spte));
+
+               if (!kvm_ad_enabled()) {
                        if (is_writable_pte(iter.old_spte))
                                new_spte = iter.old_spte & ~PT_WRITABLE_MASK;
                        else
@@ -1685,13 +1688,16 @@ static void clear_dirty_pt_masked(struct kvm *kvm, struct kvm_mmu_page *root,
                if (!mask)
                        break;
 
+               MMU_WARN_ON(kvm_ad_enabled() &&
+                           spte_ad_need_write_protect(iter.old_spte));
+
                if (iter.level > PG_LEVEL_4K ||
                    !(mask & (1UL << (iter.gfn - gfn))))
                        continue;
 
                mask &= ~(1UL << (iter.gfn - gfn));
 
-               if (wrprot || spte_ad_need_write_protect(iter.old_spte)) {
+               if (wrprot || !kvm_ad_enabled()) {
                        if (is_writable_pte(iter.old_spte))
                                new_spte = iter.old_spte & ~PT_WRITABLE_MASK;
                        else