kvm: x86/mmu: Add TDP MMU SPTE changed trace point
authorBen Gardon <bgardon@google.com>
Tue, 27 Oct 2020 17:59:44 +0000 (10:59 -0700)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 19 Nov 2020 15:57:16 +0000 (10:57 -0500)
Add an extremely verbose trace point to the TDP MMU to log all SPTE
changes, regardless of callstack / motivation. This is useful when a
complete picture of the paging structure is needed or a change cannot be
explained with the other, existing trace points.

Tested: ran the demand paging selftest on an Intel Skylake machine with
all the trace points used by the TDP MMU enabled and observed
them firing with expected values.

This patch can be viewed in Gerrit at:
https://linux-review.googlesource.com/c/virt/kvm/kvm/+/3813

Signed-off-by: Ben Gardon <bgardon@google.com>
Message-Id: <20201027175944.1183301-2-bgardon@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/mmu/mmutrace.h
arch/x86/kvm/mmu/tdp_mmu.c

index 213699b27b44877ae47cb91864eb08087a5c761c..e798489b56b55dd72f42ceb6e2b9570f915e4b01 100644 (file)
@@ -381,6 +381,35 @@ TRACE_EVENT(
        )
 );
 
+TRACE_EVENT(
+       kvm_tdp_mmu_spte_changed,
+       TP_PROTO(int as_id, gfn_t gfn, int level, u64 old_spte, u64 new_spte),
+       TP_ARGS(as_id, gfn, level, old_spte, new_spte),
+
+       TP_STRUCT__entry(
+               __field(u64, gfn)
+               __field(u64, old_spte)
+               __field(u64, new_spte)
+               /* Level cannot be larger than 5 on x86, so it fits in a u8. */
+               __field(u8, level)
+               /* as_id can only be 0 or 1 x86, so it fits in a u8. */
+               __field(u8, as_id)
+       ),
+
+       TP_fast_assign(
+               __entry->gfn = gfn;
+               __entry->old_spte = old_spte;
+               __entry->new_spte = new_spte;
+               __entry->level = level;
+               __entry->as_id = as_id;
+       ),
+
+       TP_printk("as id %d gfn %llx level %d old_spte %llx new_spte %llx",
+                 __entry->as_id, __entry->gfn, __entry->level,
+                 __entry->old_spte, __entry->new_spte
+       )
+);
+
 #endif /* _TRACE_KVMMMU_H */
 
 #undef TRACE_INCLUDE_PATH
index d6354f3795549760f1c411f14f2a18afa48cb2a7..75db27fda8f345a66a7d3349368ca5c0d728e611 100644 (file)
@@ -248,6 +248,8 @@ static void __handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
        if (old_spte == new_spte)
                return;
 
+       trace_kvm_tdp_mmu_spte_changed(as_id, gfn, level, old_spte, new_spte);
+
        /*
         * The only times a SPTE should be changed from a non-present to
         * non-present state is when an MMIO entry is installed/modified/