static void audit_mappings(struct kvm_vcpu *vcpu, u64 *sptep, int level) { struct kvm_mmu_page *sp; gfn_t gfn; pfn_t pfn; hpa_t hpa; sp = page_header(__pa(sptep)); if (sp->unsync) { if (level != PT_PAGE_TABLE_LEVEL) { audit_printk(vcpu->kvm, "unsync sp: %p " "level = %d\n", sp, level); return; } } if (!is_shadow_present_pte(*sptep) || !is_last_spte(*sptep, level)) return; gfn = kvm_mmu_page_get_gfn(sp, sptep - sp->spt); pfn = gfn_to_pfn_atomic(vcpu->kvm, gfn); if (is_error_pfn(pfn)) { kvm_release_pfn_clean(pfn); return; } hpa = pfn << PAGE_SHIFT; if ((*sptep & PT64_BASE_ADDR_MASK) != hpa) audit_printk(vcpu->kvm, "levels %d pfn %llx hpa %llx " "ent %llxn", vcpu->arch.mmu.root_level, pfn, hpa, *sptep); }
static void __mmu_spte_walk(struct vmmr0_vcpu *vcpu, struct vmmr0_mmu_page *sp, inspect_spte_fn fn, int level) { int i; for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { u64 *ent = sp->spt; fn(vcpu, ent + i, level); if (is_shadow_present_pte(ent[i]) && !is_last_spte(ent[i], level)) { struct vmmr0_mmu_page *child; child = page_header(ent[i] & PT64_BASE_ADDR_MASK); __mmu_spte_walk(vcpu, child, fn, level - 1); } } }
static void audit_sptes_have_rmaps(struct vmmr0_vcpu *vcpu, u64 *sptep, int level) { if (is_shadow_present_pte(*sptep) && is_last_spte(*sptep, level)) inspect_spte_has_rmap(vcpu->vmmr0, sptep); }