diff options
| -rw-r--r-- | drivers/kvm/paging_tmpl.h | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h index b6b90e9e1301..6507ccb1ea2a 100644 --- a/drivers/kvm/paging_tmpl.h +++ b/drivers/kvm/paging_tmpl.h | |||
| @@ -128,8 +128,10 @@ static int FNAME(walk_addr)(struct guest_walker *walker, | |||
| 128 | goto access_error; | 128 | goto access_error; |
| 129 | #endif | 129 | #endif |
| 130 | 130 | ||
| 131 | if (!(*ptep & PT_ACCESSED_MASK)) | 131 | if (!(*ptep & PT_ACCESSED_MASK)) { |
| 132 | *ptep |= PT_ACCESSED_MASK; /* avoid rmw */ | 132 | mark_page_dirty(vcpu->kvm, table_gfn); |
| 133 | *ptep |= PT_ACCESSED_MASK; | ||
| 134 | } | ||
| 133 | 135 | ||
| 134 | if (walker->level == PT_PAGE_TABLE_LEVEL) { | 136 | if (walker->level == PT_PAGE_TABLE_LEVEL) { |
| 135 | walker->gfn = (*ptep & PT_BASE_ADDR_MASK) | 137 | walker->gfn = (*ptep & PT_BASE_ADDR_MASK) |
| @@ -185,6 +187,12 @@ static void FNAME(release_walker)(struct guest_walker *walker) | |||
| 185 | kunmap_atomic(walker->table, KM_USER0); | 187 | kunmap_atomic(walker->table, KM_USER0); |
| 186 | } | 188 | } |
| 187 | 189 | ||
| 190 | static void FNAME(mark_pagetable_dirty)(struct kvm *kvm, | ||
| 191 | struct guest_walker *walker) | ||
| 192 | { | ||
| 193 | mark_page_dirty(kvm, walker->table_gfn[walker->level - 1]); | ||
| 194 | } | ||
| 195 | |||
| 188 | static void FNAME(set_pte)(struct kvm_vcpu *vcpu, u64 guest_pte, | 196 | static void FNAME(set_pte)(struct kvm_vcpu *vcpu, u64 guest_pte, |
| 189 | u64 *shadow_pte, u64 access_bits, gfn_t gfn) | 197 | u64 *shadow_pte, u64 access_bits, gfn_t gfn) |
| 190 | { | 198 | { |
| @@ -348,12 +356,15 @@ static int FNAME(fix_write_pf)(struct kvm_vcpu *vcpu, | |||
| 348 | } else if (kvm_mmu_lookup_page(vcpu, gfn)) { | 356 | } else if (kvm_mmu_lookup_page(vcpu, gfn)) { |
| 349 | pgprintk("%s: found shadow page for %lx, marking ro\n", | 357 | pgprintk("%s: found shadow page for %lx, marking ro\n", |
| 350 | __FUNCTION__, gfn); | 358 | __FUNCTION__, gfn); |
| 359 | mark_page_dirty(vcpu->kvm, gfn); | ||
| 360 | FNAME(mark_pagetable_dirty)(vcpu->kvm, walker); | ||
| 351 | *guest_ent |= PT_DIRTY_MASK; | 361 | *guest_ent |= PT_DIRTY_MASK; |
| 352 | *write_pt = 1; | 362 | *write_pt = 1; |
| 353 | return 0; | 363 | return 0; |
| 354 | } | 364 | } |
| 355 | mark_page_dirty(vcpu->kvm, gfn); | 365 | mark_page_dirty(vcpu->kvm, gfn); |
| 356 | *shadow_ent |= PT_WRITABLE_MASK; | 366 | *shadow_ent |= PT_WRITABLE_MASK; |
| 367 | FNAME(mark_pagetable_dirty)(vcpu->kvm, walker); | ||
| 357 | *guest_ent |= PT_DIRTY_MASK; | 368 | *guest_ent |= PT_DIRTY_MASK; |
| 358 | rmap_add(vcpu, shadow_ent); | 369 | rmap_add(vcpu, shadow_ent); |
| 359 | 370 | ||
