aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/mmu.c17
-rw-r--r--arch/x86/kvm/mmu.h3
-rw-r--r--include/asm-x86/kvm_host.h1
3 files changed, 19 insertions, 2 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 8e449dbcc596..53f1ed852ca2 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -1122,8 +1122,10 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
1122 else 1122 else
1123 kvm_release_pfn_clean(pfn); 1123 kvm_release_pfn_clean(pfn);
1124 } 1124 }
1125 if (!ptwrite || !*ptwrite) 1125 if (speculative) {
1126 vcpu->arch.last_pte_updated = shadow_pte; 1126 vcpu->arch.last_pte_updated = shadow_pte;
1127 vcpu->arch.last_pte_gfn = gfn;
1128 }
1127} 1129}
1128 1130
1129static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) 1131static void nonpaging_new_cr3(struct kvm_vcpu *vcpu)
@@ -1671,6 +1673,18 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
1671 vcpu->arch.update_pte.pfn = pfn; 1673 vcpu->arch.update_pte.pfn = pfn;
1672} 1674}
1673 1675
1676static void kvm_mmu_access_page(struct kvm_vcpu *vcpu, gfn_t gfn)
1677{
1678 u64 *spte = vcpu->arch.last_pte_updated;
1679
1680 if (spte
1681 && vcpu->arch.last_pte_gfn == gfn
1682 && shadow_accessed_mask
1683 && !(*spte & shadow_accessed_mask)
1684 && is_shadow_present_pte(*spte))
1685 set_bit(PT_ACCESSED_SHIFT, (unsigned long *)spte);
1686}
1687
1674void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, 1688void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
1675 const u8 *new, int bytes) 1689 const u8 *new, int bytes)
1676{ 1690{
@@ -1694,6 +1708,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
1694 pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes); 1708 pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes);
1695 mmu_guess_page_from_pte_write(vcpu, gpa, new, bytes); 1709 mmu_guess_page_from_pte_write(vcpu, gpa, new, bytes);
1696 spin_lock(&vcpu->kvm->mmu_lock); 1710 spin_lock(&vcpu->kvm->mmu_lock);
1711 kvm_mmu_access_page(vcpu, gfn);
1697 kvm_mmu_free_some_pages(vcpu); 1712 kvm_mmu_free_some_pages(vcpu);
1698 ++vcpu->kvm->stat.mmu_pte_write; 1713 ++vcpu->kvm->stat.mmu_pte_write;
1699 kvm_mmu_audit(vcpu, "pre pte write"); 1714 kvm_mmu_audit(vcpu, "pre pte write");
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index 1730757bbc7a..258e5d56298e 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -15,7 +15,8 @@
15#define PT_USER_MASK (1ULL << 2) 15#define PT_USER_MASK (1ULL << 2)
16#define PT_PWT_MASK (1ULL << 3) 16#define PT_PWT_MASK (1ULL << 3)
17#define PT_PCD_MASK (1ULL << 4) 17#define PT_PCD_MASK (1ULL << 4)
18#define PT_ACCESSED_MASK (1ULL << 5) 18#define PT_ACCESSED_SHIFT 5
19#define PT_ACCESSED_MASK (1ULL << PT_ACCESSED_SHIFT)
19#define PT_DIRTY_MASK (1ULL << 6) 20#define PT_DIRTY_MASK (1ULL << 6)
20#define PT_PAGE_SIZE_MASK (1ULL << 7) 21#define PT_PAGE_SIZE_MASK (1ULL << 7)
21#define PT_PAT_MASK (1ULL << 7) 22#define PT_PAT_MASK (1ULL << 7)
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index 844f2a89afbc..c2d066e185f4 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -243,6 +243,7 @@ struct kvm_vcpu_arch {
243 gfn_t last_pt_write_gfn; 243 gfn_t last_pt_write_gfn;
244 int last_pt_write_count; 244 int last_pt_write_count;
245 u64 *last_pte_updated; 245 u64 *last_pte_updated;
246 gfn_t last_pte_gfn;
246 247
247 struct { 248 struct {
248 gfn_t gfn; /* presumed gfn during guest pte update */ 249 gfn_t gfn; /* presumed gfn during guest pte update */