else
                        kvm_release_pfn_clean(pfn);
        }
-       if (!ptwrite || !*ptwrite)
+       if (speculative) {
                vcpu->arch.last_pte_updated = shadow_pte;
+               vcpu->arch.last_pte_gfn = gfn;
+       }
 }
 
 static void nonpaging_new_cr3(struct kvm_vcpu *vcpu)
        vcpu->arch.update_pte.pfn = pfn;
 }
 
+static void kvm_mmu_access_page(struct kvm_vcpu *vcpu, gfn_t gfn)
+{
+       u64 *spte = vcpu->arch.last_pte_updated;
+
+       if (spte
+           && vcpu->arch.last_pte_gfn == gfn
+           && shadow_accessed_mask
+           && !(*spte & shadow_accessed_mask)
+           && is_shadow_present_pte(*spte))
+               set_bit(PT_ACCESSED_SHIFT, spte);
+}
+
 void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
                       const u8 *new, int bytes)
 {
        pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes);
        mmu_guess_page_from_pte_write(vcpu, gpa, new, bytes);
        spin_lock(&vcpu->kvm->mmu_lock);
+       kvm_mmu_access_page(vcpu, gfn);
        kvm_mmu_free_some_pages(vcpu);
        ++vcpu->kvm->stat.mmu_pte_write;
        kvm_mmu_audit(vcpu, "pre pte write");
 
 #define PT_USER_MASK (1ULL << 2)
 #define PT_PWT_MASK (1ULL << 3)
 #define PT_PCD_MASK (1ULL << 4)
-#define PT_ACCESSED_MASK (1ULL << 5)
+#define PT_ACCESSED_SHIFT 5
+#define PT_ACCESSED_MASK (1ULL << PT_ACCESSED_SHIFT)
 #define PT_DIRTY_MASK (1ULL << 6)
 #define PT_PAGE_SIZE_MASK (1ULL << 7)
 #define PT_PAT_MASK (1ULL << 7)