Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 80632
b: refs/heads/master
c: 12b7d28
h: refs/heads/master
v: v3
  • Loading branch information
Avi Kivity committed Jan 30, 2008
1 parent f24cb69 commit 91a8d9b
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c7addb902054195b995114df154e061c7d604f69
refs/heads/master: 12b7d28fc102b772eb70f98491587ec5ee717baf
1 change: 1 addition & 0 deletions trunk/drivers/kvm/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ struct kvm_vcpu {

gfn_t last_pt_write_gfn;
int last_pt_write_count;
u64 *last_pte_updated;

struct kvm_guest_debug guest_debug;

Expand Down
21 changes: 20 additions & 1 deletion trunk/drivers/kvm/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,15 @@ static void kvm_mmu_put_page(struct kvm_mmu_page *page,
mmu_page_remove_parent_pte(page, parent_pte);
}

static void kvm_mmu_reset_last_pte_updated(struct kvm *kvm)
{
int i;

for (i = 0; i < KVM_MAX_VCPUS; ++i)
if (kvm->vcpus[i])
kvm->vcpus[i]->last_pte_updated = NULL;
}

static void kvm_mmu_zap_page(struct kvm *kvm,
struct kvm_mmu_page *page)
{
Expand All @@ -717,6 +726,7 @@ static void kvm_mmu_zap_page(struct kvm *kvm,
kvm_mmu_free_page(kvm, page);
} else
list_move(&page->link, &kvm->active_mmu_pages);
kvm_mmu_reset_last_pte_updated(kvm);
}

static int kvm_mmu_unprotect_page(struct kvm_vcpu *vcpu, gfn_t gfn)
Expand Down Expand Up @@ -1140,6 +1150,13 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu,
offset_in_pte);
}

static bool last_updated_pte_accessed(struct kvm_vcpu *vcpu)
{
u64 *spte = vcpu->last_pte_updated;

return !!(spte && (*spte & PT_ACCESSED_MASK));
}

void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
const u8 *new, int bytes)
{
Expand All @@ -1160,13 +1177,15 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,

pgprintk("%s: gpa %llx bytes %d\n", __FUNCTION__, gpa, bytes);
kvm_mmu_audit(vcpu, "pre pte write");
if (gfn == vcpu->last_pt_write_gfn) {
if (gfn == vcpu->last_pt_write_gfn
&& !last_updated_pte_accessed(vcpu)) {
++vcpu->last_pt_write_count;
if (vcpu->last_pt_write_count >= 3)
flooded = 1;
} else {
vcpu->last_pt_write_gfn = gfn;
vcpu->last_pt_write_count = 1;
vcpu->last_pte_updated = NULL;
}
index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES;
bucket = &vcpu->kvm->mmu_page_hash[index];
Expand Down
9 changes: 8 additions & 1 deletion trunk/drivers/kvm/paging_tmpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,12 @@ static void FNAME(set_pte_common)(struct kvm_vcpu *vcpu,
FNAME(mark_pagetable_dirty)(vcpu->kvm, walker);
}

spte = PT_PRESENT_MASK | PT_ACCESSED_MASK | PT_DIRTY_MASK;
/*
* We don't set the accessed bit, since we sometimes want to see
* whether the guest actually used the pte (in order to detect
* demand paging).
*/
spte = PT_PRESENT_MASK | PT_DIRTY_MASK;
spte |= gpte & PT64_NX_MASK;
if (!dirty)
access_bits &= ~PT_WRITABLE_MASK;
Expand Down Expand Up @@ -291,6 +296,8 @@ static void FNAME(set_pte_common)(struct kvm_vcpu *vcpu,
page_header_update_slot(vcpu->kvm, shadow_pte, gaddr);
if (!was_rmapped)
rmap_add(vcpu, shadow_pte);
if (!ptwrite || !*ptwrite)
vcpu->last_pte_updated = shadow_pte;
}

static void FNAME(set_pte)(struct kvm_vcpu *vcpu, pt_element_t gpte,
Expand Down

0 comments on commit 91a8d9b

Please sign in to comment.