diff options
author | Avi Kivity <avi@redhat.com> | 2009-07-06 05:21:32 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-09-10 01:33:09 -0400 |
commit | 07420171593908406c3a59d6f884d426a921a5ea (patch) | |
tree | 987488098509c4687ed8898c44d0bf4e061c1b4f /arch/x86/kvm/paging_tmpl.h | |
parent | dc7e795e3dd2a763e5ceaa1615f307e808cf3932 (diff) |
KVM: MMU: Trace guest pagetable walker
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/paging_tmpl.h')
-rw-r--r-- | arch/x86/kvm/paging_tmpl.h | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 53e129cec5fd..36ac6d70a847 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h | |||
@@ -125,13 +125,15 @@ static int FNAME(walk_addr)(struct guest_walker *walker, | |||
125 | gpa_t pte_gpa; | 125 | gpa_t pte_gpa; |
126 | int rsvd_fault = 0; | 126 | int rsvd_fault = 0; |
127 | 127 | ||
128 | pgprintk("%s: addr %lx\n", __func__, addr); | 128 | trace_kvm_mmu_pagetable_walk(addr, write_fault, user_fault, |
129 | fetch_fault); | ||
129 | walk: | 130 | walk: |
130 | walker->level = vcpu->arch.mmu.root_level; | 131 | walker->level = vcpu->arch.mmu.root_level; |
131 | pte = vcpu->arch.cr3; | 132 | pte = vcpu->arch.cr3; |
132 | #if PTTYPE == 64 | 133 | #if PTTYPE == 64 |
133 | if (!is_long_mode(vcpu)) { | 134 | if (!is_long_mode(vcpu)) { |
134 | pte = kvm_pdptr_read(vcpu, (addr >> 30) & 3); | 135 | pte = kvm_pdptr_read(vcpu, (addr >> 30) & 3); |
136 | trace_kvm_mmu_paging_element(pte, walker->level); | ||
135 | if (!is_present_gpte(pte)) | 137 | if (!is_present_gpte(pte)) |
136 | goto not_present; | 138 | goto not_present; |
137 | --walker->level; | 139 | --walker->level; |
@@ -150,10 +152,9 @@ walk: | |||
150 | pte_gpa += index * sizeof(pt_element_t); | 152 | pte_gpa += index * sizeof(pt_element_t); |
151 | walker->table_gfn[walker->level - 1] = table_gfn; | 153 | walker->table_gfn[walker->level - 1] = table_gfn; |
152 | walker->pte_gpa[walker->level - 1] = pte_gpa; | 154 | walker->pte_gpa[walker->level - 1] = pte_gpa; |
153 | pgprintk("%s: table_gfn[%d] %lx\n", __func__, | ||
154 | walker->level - 1, table_gfn); | ||
155 | 155 | ||
156 | kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte)); | 156 | kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte)); |
157 | trace_kvm_mmu_paging_element(pte, walker->level); | ||
157 | 158 | ||
158 | if (!is_present_gpte(pte)) | 159 | if (!is_present_gpte(pte)) |
159 | goto not_present; | 160 | goto not_present; |
@@ -175,6 +176,8 @@ walk: | |||
175 | #endif | 176 | #endif |
176 | 177 | ||
177 | if (!(pte & PT_ACCESSED_MASK)) { | 178 | if (!(pte & PT_ACCESSED_MASK)) { |
179 | trace_kvm_mmu_set_accessed_bit(table_gfn, index, | ||
180 | sizeof(pte)); | ||
178 | mark_page_dirty(vcpu->kvm, table_gfn); | 181 | mark_page_dirty(vcpu->kvm, table_gfn); |
179 | if (FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, | 182 | if (FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, |
180 | index, pte, pte|PT_ACCESSED_MASK)) | 183 | index, pte, pte|PT_ACCESSED_MASK)) |
@@ -208,6 +211,7 @@ walk: | |||
208 | if (write_fault && !is_dirty_gpte(pte)) { | 211 | if (write_fault && !is_dirty_gpte(pte)) { |
209 | bool ret; | 212 | bool ret; |
210 | 213 | ||
214 | trace_kvm_mmu_set_dirty_bit(table_gfn, index, sizeof(pte)); | ||
211 | mark_page_dirty(vcpu->kvm, table_gfn); | 215 | mark_page_dirty(vcpu->kvm, table_gfn); |
212 | ret = FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, index, pte, | 216 | ret = FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, index, pte, |
213 | pte|PT_DIRTY_MASK); | 217 | pte|PT_DIRTY_MASK); |
@@ -239,6 +243,7 @@ err: | |||
239 | walker->error_code |= PFERR_FETCH_MASK; | 243 | walker->error_code |= PFERR_FETCH_MASK; |
240 | if (rsvd_fault) | 244 | if (rsvd_fault) |
241 | walker->error_code |= PFERR_RSVD_MASK; | 245 | walker->error_code |= PFERR_RSVD_MASK; |
246 | trace_kvm_mmu_walker_error(walker->error_code); | ||
242 | return 0; | 247 | return 0; |
243 | } | 248 | } |
244 | 249 | ||